All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			
		
			
				
	
	
		
			196 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			196 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import CancelIcon from "@mui/icons-material/Close";
 | |
| import DeleteIcon from "@mui/icons-material/DeleteOutlined";
 | |
| import EditIcon from "@mui/icons-material/Edit";
 | |
| import SaveIcon from "@mui/icons-material/Save";
 | |
| import {
 | |
|   DataGrid,
 | |
|   GridActionsCellItem,
 | |
|   GridColDef,
 | |
|   GridRowId,
 | |
|   GridRowModes,
 | |
|   GridRowModesModel,
 | |
| } from "@mui/x-data-grid";
 | |
| import React from "react";
 | |
| import { FamilyApi, FamilyUser } from "../../api/FamilyApi";
 | |
| import { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
 | |
| import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider";
 | |
| import { AsyncWidget } from "../../widgets/AsyncWidget";
 | |
| import { useUser } from "../../widgets/BaseAuthenticatedPage";
 | |
| import { useFamily } from "../../widgets/BaseFamilyRoute";
 | |
| import { FamilyPageTitle } from "../../widgets/FamilyPageTitle";
 | |
| import { TimeWidget } from "../../widgets/TimeWidget";
 | |
| 
 | |
| export function FamilyUsersListRoute(): React.ReactElement {
 | |
|   const family = useFamily();
 | |
| 
 | |
|   const [users, setUsers] = React.useState<FamilyUser[] | null>(null);
 | |
| 
 | |
|   const key = React.useRef(1);
 | |
| 
 | |
|   const load = async () => {
 | |
|     setUsers(await FamilyApi.GetUsersList(family.family.family_id));
 | |
|   };
 | |
| 
 | |
|   const reload = async () => {
 | |
|     key.current += 1;
 | |
|     setUsers(null);
 | |
|   };
 | |
| 
 | |
|   return (
 | |
|     <AsyncWidget
 | |
|       loadKey={`${family.family.family_id}-${key.current}`}
 | |
|       errMsg="Echec du chargement de la liste des utilisateurs de la famille !"
 | |
|       load={load}
 | |
|       ready={users !== null}
 | |
|       build={() => (
 | |
|         <>
 | |
|           <FamilyPageTitle title="Utilisateurs de la famille" />
 | |
|           <UsersTable users={users!} onReload={reload} />
 | |
|         </>
 | |
|       )}
 | |
|     />
 | |
|   );
 | |
| }
 | |
| 
 | |
| function UsersTable(p: {
 | |
|   users: FamilyUser[];
 | |
|   onReload: () => void;
 | |
| }): React.ReactElement {
 | |
|   const alert = useAlert();
 | |
|   const confirm = useConfirm();
 | |
|   const user = useUser();
 | |
|   const family = useFamily();
 | |
| 
 | |
|   const [rowModesModel, setRowModesModel] = React.useState<GridRowModesModel>(
 | |
|     {}
 | |
|   );
 | |
| 
 | |
|   const handleEditClick = (id: GridRowId) => () => {
 | |
|     setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.Edit } });
 | |
|   };
 | |
| 
 | |
|   const handleSaveClick = (id: GridRowId) => () => {
 | |
|     setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.View } });
 | |
|   };
 | |
| 
 | |
|   // Remove a membership
 | |
|   const handleDeleteClick = (id: GridRowId) => async () => {
 | |
|     try {
 | |
|       const user = p.users.find((u) => u.user_id === id)!;
 | |
|       if (
 | |
|         !(await confirm(
 | |
|           `Voulez-vous vraiment retirer ${user.user_name} de cette famille ?`
 | |
|         ))
 | |
|       )
 | |
|         return;
 | |
| 
 | |
|       await FamilyApi.RemoveUser(user);
 | |
|       p.onReload();
 | |
|     } catch (e) {
 | |
|       console.error(e);
 | |
|       alert("Echec de la suppression de l'utilisateur !");
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   const handleCancelClick = (id: GridRowId) => () => {
 | |
|     setRowModesModel({
 | |
|       ...rowModesModel,
 | |
|       [id]: { mode: GridRowModes.View, ignoreModifications: true },
 | |
|     });
 | |
|   };
 | |
| 
 | |
|   const columns: GridColDef[] = [
 | |
|     { field: "user_id", headerName: "#", flex: 1 },
 | |
|     { field: "user_mail", headerName: "Adresse mail", flex: 5 },
 | |
|     { field: "user_name", headerName: "Nom d'utilisateur", flex: 5 },
 | |
|     {
 | |
|       field: "time_create",
 | |
|       headerName: "Date d'ajout",
 | |
|       flex: 5,
 | |
|       renderCell(params) {
 | |
|         return <TimeWidget time={params.row.time_create} />;
 | |
|       },
 | |
|     },
 | |
|     {
 | |
|       field: "is_admin",
 | |
|       headerName: "Admin",
 | |
|       flex: 2,
 | |
|       type: "boolean",
 | |
|       editable: family.family.is_admin,
 | |
|     },
 | |
|   ];
 | |
| 
 | |
|   if (family.family.is_admin)
 | |
|     columns.push({
 | |
|       field: "actions",
 | |
|       type: "actions",
 | |
|       headerName: "Actions",
 | |
|       flex: 2,
 | |
|       cellClassName: "actions",
 | |
|       getActions: ({ id }) => {
 | |
|         const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit;
 | |
| 
 | |
|         if (id === user.user.id) return [];
 | |
| 
 | |
|         if (isInEditMode) {
 | |
|           return [
 | |
|             <GridActionsCellItem
 | |
|               icon={<SaveIcon />}
 | |
|               label="Save"
 | |
|               material={{
 | |
|                 sx: {
 | |
|                   color: 'primary.main',
 | |
|                 },
 | |
|               }}
 | |
|               onClick={handleSaveClick(id)}
 | |
|             />,
 | |
|             <GridActionsCellItem
 | |
|               icon={<CancelIcon />}
 | |
|               label="Cancel"
 | |
|               className="textPrimary"
 | |
|               onClick={handleCancelClick(id)}
 | |
|               color="inherit"
 | |
|             />,
 | |
|           ];
 | |
|         }
 | |
| 
 | |
|         return [
 | |
|           <GridActionsCellItem
 | |
|             icon={<EditIcon />}
 | |
|             label="Edit"
 | |
|             className="textPrimary"
 | |
|             onClick={handleEditClick(id)}
 | |
|             color="inherit"
 | |
|           />,
 | |
|           <GridActionsCellItem
 | |
|             icon={<DeleteIcon />}
 | |
|             label="Delete"
 | |
|             onClick={handleDeleteClick(id)}
 | |
|             color="inherit"
 | |
|           />,
 | |
|         ];
 | |
|       },
 | |
|     });
 | |
| 
 | |
|   return (
 | |
|     <DataGrid
 | |
|       style={{ flex: "1" }}
 | |
|       rows={p.users}
 | |
|       columns={columns}
 | |
|       autoPageSize
 | |
|       editMode="row"
 | |
|       rowModesModel={rowModesModel}
 | |
|       getRowId={(c) => c.user_id}
 | |
|       isCellEditable={(params) => params.row.user_id !== user.user.id}
 | |
|       processRowUpdate={async (n: FamilyUser) => {
 | |
|         await FamilyApi.UpdateUser(n);
 | |
|         return n;
 | |
|       }}
 | |
|       onProcessRowUpdateError={(e) => {
 | |
|         console.error(e);
 | |
|         alert("Échec de la mise à jour des informations utilisateurs !");
 | |
|       }}
 | |
|     />
 | |
|   );
 | |
| }
 |