feat: add team members functionality and modal
- Introduced `onViewMembers` prop in `TreeItemRow` to handle viewing team members. - Added `TeamMembersModal` to display members of a selected team. - Implemented state management for team members in `TeamsManagement`, including fetching and updating stats. - Enhanced `AdminManagementService` with methods to fetch and remove team members.
This commit is contained in:
@@ -35,6 +35,7 @@ import {
|
||||
TreeSearchControls,
|
||||
TeamMetrics,
|
||||
} from "@/components/admin";
|
||||
import { TeamMembersModal } from "@/components/admin/management/team-members-modal";
|
||||
|
||||
interface TeamsManagementProps {
|
||||
teams: TeamType[];
|
||||
@@ -55,6 +56,8 @@ export function TeamsManagement({
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false);
|
||||
const [isEditDialogOpen, setIsEditDialogOpen] = useState(false);
|
||||
const [isMembersModalOpen, setIsMembersModalOpen] = useState(false);
|
||||
const [selectedTeam, setSelectedTeam] = useState<any>(null);
|
||||
const [editingTeam, setEditingTeam] = useState<any>(null);
|
||||
const [teamFormData, setTeamFormData] = useState<TeamFormData>({
|
||||
name: "",
|
||||
@@ -67,7 +70,8 @@ export function TeamsManagement({
|
||||
new Set()
|
||||
);
|
||||
|
||||
// État pour gérer la liste des équipes
|
||||
// État local pour les stats des équipes
|
||||
const [localTeamStats, setLocalTeamStats] = useState<TeamStats[]>(teamStats);
|
||||
|
||||
// Grouper les teams par direction et filtrer en fonction de la recherche
|
||||
const filteredTeamsByDirection = useMemo(() => {
|
||||
@@ -129,8 +133,8 @@ export function TeamsManagement({
|
||||
[]
|
||||
);
|
||||
|
||||
const getTeamStats = (teamId: string) => {
|
||||
return teamStats.find((stats) => stats.teamId === teamId);
|
||||
const getTeamStats = (teamId: string): TeamStats | undefined => {
|
||||
return localTeamStats.find((stats) => stats.teamId === teamId);
|
||||
};
|
||||
|
||||
// Charger les teams depuis l'API
|
||||
@@ -149,6 +153,18 @@ export function TeamsManagement({
|
||||
}
|
||||
};
|
||||
|
||||
// Rafraîchir les stats des équipes depuis l'API des équipes
|
||||
const refreshTeamStats = async () => {
|
||||
try {
|
||||
const teamsData = await AdminManagementService.getTeams();
|
||||
// Fusionner avec les stats existantes pour préserver les métriques
|
||||
const updatedStats = mergeTeamStats(localTeamStats, teamsData);
|
||||
setLocalTeamStats(updatedStats);
|
||||
} catch (error) {
|
||||
console.error("Error refreshing team stats:", error);
|
||||
}
|
||||
};
|
||||
|
||||
// Charger les teams au montage du composant
|
||||
useEffect(() => {
|
||||
fetchTeams();
|
||||
@@ -205,6 +221,41 @@ export function TeamsManagement({
|
||||
setIsEditDialogOpen(true);
|
||||
};
|
||||
|
||||
const handleViewMembers = (team: any) => {
|
||||
setSelectedTeam(team);
|
||||
setIsMembersModalOpen(true);
|
||||
};
|
||||
|
||||
// Fonction pour mettre à jour les stats d'une équipe après suppression d'un membre
|
||||
const updateTeamStatsAfterMemberRemoval = (teamId: string) => {
|
||||
setLocalTeamStats((prev) =>
|
||||
prev.map((stats) =>
|
||||
stats.teamId === teamId
|
||||
? { ...stats, totalMembers: Math.max(0, stats.totalMembers - 1) }
|
||||
: stats
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
// Fonction pour fusionner les stats existantes avec les nouvelles données
|
||||
const mergeTeamStats = (existingStats: TeamStats[], newTeams: Team[]) => {
|
||||
return newTeams.map((team) => {
|
||||
const existingStat = existingStats.find(
|
||||
(stat) => stat.teamId === team.id
|
||||
);
|
||||
return {
|
||||
teamId: team.id,
|
||||
teamName: team.name,
|
||||
direction: team.direction,
|
||||
totalMembers: team.memberCount,
|
||||
averageSkillLevel: existingStat?.averageSkillLevel || 0,
|
||||
skillCoverage: existingStat?.skillCoverage || 0,
|
||||
topSkillsCount: existingStat?.topSkillsCount || 0,
|
||||
topSkills: existingStat?.topSkills || [],
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
const handleUpdateTeam = async () => {
|
||||
if (!editingTeam || !teamFormData.name || !teamFormData.direction) {
|
||||
toast({
|
||||
@@ -466,8 +517,10 @@ export function TeamsManagement({
|
||||
}
|
||||
onEdit={() => handleEditTeam(team)}
|
||||
onDelete={() => handleDeleteTeam(team.id)}
|
||||
onViewMembers={() => handleViewMembers(team)}
|
||||
canDelete={!stats || stats.totalMembers === 0}
|
||||
showSeparator={teamIndex > 0}
|
||||
hasMembers={stats ? stats.totalMembers > 0 : false}
|
||||
additionalInfo={
|
||||
stats ? (
|
||||
<TeamMetrics
|
||||
@@ -542,6 +595,27 @@ export function TeamsManagement({
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{/* Modal des membres d'équipe */}
|
||||
{selectedTeam && (
|
||||
<TeamMembersModal
|
||||
teamId={selectedTeam.id}
|
||||
teamName={selectedTeam.name}
|
||||
isOpen={isMembersModalOpen}
|
||||
onClose={() => {
|
||||
setIsMembersModalOpen(false);
|
||||
setSelectedTeam(null);
|
||||
// Rafraîchir les stats depuis l'API pour s'assurer de la cohérence
|
||||
refreshTeamStats();
|
||||
}}
|
||||
onMemberRemoved={() => {
|
||||
// Mettre à jour les stats localement
|
||||
if (selectedTeam) {
|
||||
updateTeamStatsAfterMemberRemoval(selectedTeam.id);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user