Skip to content

Commit bc72bed

Browse files
committed
refacto group page, missing users in edit dialog
Signed-off-by: David BRAQUART <[email protected]>
1 parent 7e6b1a8 commit bc72bed

File tree

8 files changed

+309
-86
lines changed

8 files changed

+309
-86
lines changed

src/pages/groups/groups-page.tsx

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright (c) 2024, RTE (http://www.rte-france.com)
3+
* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this
5+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
6+
*/
7+
8+
import { FunctionComponent, useCallback, useRef, useState } from 'react';
9+
import { Grid } from '@mui/material';
10+
import { GridTableRef } from '../../components/Grid';
11+
import { GroupInfos } from '../../services';
12+
import { RowClickedEvent } from 'ag-grid-community';
13+
import GroupModificationDialog from './modification/group-modification-dialog';
14+
import GroupsTable from './groups-table';
15+
import AddGroupDialog from './add-group-dialog';
16+
17+
const GroupsPage: FunctionComponent = () => {
18+
const gridRef = useRef<GridTableRef<GroupInfos>>(null);
19+
const gridContext = gridRef.current?.context;
20+
const [openGroupModificationDialog, setOpenGroupModificationDialog] = useState(false);
21+
const [editingGroup, setEditingGroup] = useState<GroupInfos>();
22+
23+
const [openAddGroupDialog, setOpenAddGroupDialog] = useState(false);
24+
25+
const handleCloseGroupModificationDialog = useCallback(() => {
26+
setOpenGroupModificationDialog(false);
27+
setEditingGroup(undefined);
28+
}, []);
29+
30+
const handleUpdateGroupModificationDialog = useCallback(() => {
31+
gridContext?.refresh?.();
32+
handleCloseGroupModificationDialog();
33+
}, [gridContext, handleCloseGroupModificationDialog]);
34+
35+
const onRowClicked = useCallback((event: RowClickedEvent<GroupInfos>) => {
36+
if (event.data) {
37+
setEditingGroup(event.data);
38+
setOpenGroupModificationDialog(true);
39+
}
40+
}, []);
41+
42+
return (
43+
<Grid item container direction="column" spacing={2} component="section">
44+
<Grid item container xs sx={{ width: 1 }}>
45+
<GroupModificationDialog
46+
groupInfos={editingGroup}
47+
open={openGroupModificationDialog}
48+
onClose={handleCloseGroupModificationDialog}
49+
onUpdate={handleUpdateGroupModificationDialog}
50+
/>
51+
<GroupsTable
52+
gridRef={gridRef}
53+
onRowClicked={onRowClicked}
54+
setOpenAddGroupDialog={setOpenAddGroupDialog}
55+
/>
56+
<AddGroupDialog gridRef={gridRef} open={openAddGroupDialog} setOpen={setOpenAddGroupDialog} />
57+
</Grid>
58+
</Grid>
59+
);
60+
};
61+
export default GroupsPage;
Lines changed: 86 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,43 @@
1-
/*
2-
* Copyright (c) 2025, RTE (http://www.rte-france.com)
1+
/**
2+
* Copyright (c) 2024, RTE (http://www.rte-france.com)
33
* This Source Code Form is subject to the terms of the Mozilla Public
44
* License, v. 2.0. If a copy of the MPL was not distributed with this
55
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
66
*/
77

8-
import { FunctionComponent, useCallback, useEffect, useMemo, useRef, useState } from 'react';
8+
import { FunctionComponent, RefObject, useCallback, useEffect, useMemo, useState } from 'react';
99
import { useIntl } from 'react-intl';
10-
import { Grid } from '@mui/material';
1110
import { GroupAdd } from '@mui/icons-material';
1211
import { GridButton, GridButtonDelete, GridTable, GridTableRef } from '../../components/Grid';
13-
import { UserAdminSrv, GroupInfos, UserInfos, UpdateGroupInfos } from '../../services';
12+
import { GroupInfos, UpdateGroupInfos, UserAdminSrv, UserInfos } from '../../services';
13+
import {
14+
ColDef,
15+
GetRowIdParams,
16+
ICellEditorParams,
17+
RowClickedEvent,
18+
SelectionChangedEvent,
19+
TextFilterParams,
20+
} from 'ag-grid-community';
1421
import { useSnackMessage } from '@gridsuite/commons-ui';
15-
import { ColDef, GetRowIdParams, SelectionChangedEvent, TextFilterParams, ICellEditorParams } from 'ag-grid-community';
1622
import DeleteConfirmationDialog from '../common/delete-confirmation-dialog';
17-
import MultiSelectEditorComponent from '../common/multi-select-editor-component';
23+
import { defaultColDef, defaultRowSelection } from '../common/table-config';
1824
import MultiChipsRendererComponent from '../common/multi-chips-renderer-component';
25+
import MultiSelectEditorComponent from '../common/multi-select-editor-component';
1926
import { UUID } from 'crypto';
20-
import { defaultColDef } from '../common/table-config';
21-
import AddGroupDialog from './add-group-dialog';
2227

23-
function getRowId(params: GetRowIdParams<GroupInfos>): string {
24-
return params.data.name;
28+
export interface GroupsTableProps {
29+
gridRef: RefObject<GridTableRef<GroupInfos>>;
30+
onRowClicked: (event: RowClickedEvent<GroupInfos>) => void;
31+
setOpenAddGroupDialog: (open: boolean) => void;
2532
}
2633

27-
const GroupsPage: FunctionComponent = () => {
34+
const GroupsTable: FunctionComponent<GroupsTableProps> = (props) => {
2835
const intl = useIntl();
2936
const { snackError } = useSnackMessage();
30-
const gridRef = useRef<GridTableRef<GroupInfos>>(null);
31-
const gridContext = gridRef.current?.context;
37+
38+
const [rowsSelection, setRowsSelection] = useState<GroupInfos[]>([]);
39+
const [showDeletionDialog, setShowDeletionDialog] = useState(false);
3240
const [usersOptions, setUsersOptions] = useState<string[]>([]);
33-
const [openAddGroupDialog, setOpenAddGroupDialog] = useState(false);
3441

3542
useEffect(() => {
3643
UserAdminSrv.fetchUsers()
@@ -46,12 +53,43 @@ const GroupsPage: FunctionComponent = () => {
4653
);
4754
}, [snackError]);
4855

56+
function getRowId(params: GetRowIdParams<GroupInfos>): string {
57+
return params.data.name;
58+
}
59+
60+
const onSelectionChanged = useCallback(
61+
(event: SelectionChangedEvent<GroupInfos, {}>) => setRowsSelection(event.api.getSelectedRows() ?? []),
62+
[setRowsSelection]
63+
);
64+
65+
const onAddButton = useCallback(() => props.setOpenAddGroupDialog(true), [props]);
66+
67+
const deleteGroups = useCallback((): Promise<void> | undefined => {
68+
let groupNames = rowsSelection.map((group) => group.name);
69+
return UserAdminSrv.deleteGroups(groupNames)
70+
.catch((error) => {
71+
if (error.status === 422) {
72+
snackError({
73+
headerId: 'groups.table.integrity.error.delete',
74+
});
75+
} else {
76+
snackError({
77+
messageTxt: error.message,
78+
headerId: 'groups.table.error.delete',
79+
});
80+
}
81+
})
82+
.then(() => props.gridRef?.current?.context?.refresh?.());
83+
}, [props.gridRef, rowsSelection, snackError]);
84+
85+
const deleteGroupsDisabled = useMemo(() => rowsSelection.length <= 0, [rowsSelection.length]);
86+
4987
const updateGroupCallback = useCallback(
5088
(id: UUID, name: string, users: string[]) => {
5189
const newData: UpdateGroupInfos = {
5290
id: id,
5391
name: name,
54-
users: users,
92+
users: [],
5593
};
5694
UserAdminSrv.udpateGroup(newData)
5795
.catch((error) =>
@@ -60,9 +98,9 @@ const GroupsPage: FunctionComponent = () => {
6098
headerId: 'groups.table.error.update',
6199
})
62100
)
63-
.then(() => gridContext?.refresh?.());
101+
.then(() => props.gridRef?.current?.context?.refresh?.());
64102
},
65-
[gridContext, snackError]
103+
[props.gridRef, snackError]
66104
);
67105

68106
const columns = useMemo(
@@ -114,70 +152,37 @@ const GroupsPage: FunctionComponent = () => {
114152
[intl, usersOptions, updateGroupCallback]
115153
);
116154

117-
const [rowsSelection, setRowsSelection] = useState<GroupInfos[]>([]);
118-
const deleteGroups = useCallback((): Promise<void> | undefined => {
119-
let groupNames = rowsSelection.map((group) => group.name);
120-
return UserAdminSrv.deleteGroups(groupNames)
121-
.catch((error) => {
122-
if (error.status === 422) {
123-
snackError({
124-
headerId: 'groups.table.integrity.error.delete',
125-
});
126-
} else {
127-
snackError({
128-
messageTxt: error.message,
129-
headerId: 'groups.table.error.delete',
130-
});
131-
}
132-
})
133-
.then(() => gridContext?.refresh?.());
134-
}, [gridContext, rowsSelection, snackError]);
135-
const deleteGroupsDisabled = useMemo(() => rowsSelection.length <= 0, [rowsSelection.length]);
136-
const [showDeletionDialog, setShowDeletionDialog] = useState(false);
137-
138155
return (
139-
<Grid item container direction="column" spacing={2} component="section">
140-
<Grid item container xs sx={{ width: 1 }}>
141-
<GridTable<GroupInfos, {}>
142-
ref={gridRef}
143-
dataLoader={UserAdminSrv.fetchGroups}
144-
columnDefs={columns}
145-
defaultColDef={defaultColDef}
146-
stopEditingWhenCellsLoseFocus={true}
147-
gridId="table-groups"
148-
getRowId={getRowId}
149-
rowSelection={{
150-
mode: 'multiRow',
151-
enableClickSelection: false,
152-
checkboxes: true,
153-
headerCheckbox: true,
154-
hideDisabledCheckboxes: false,
155-
}}
156-
onSelectionChanged={useCallback(
157-
(event: SelectionChangedEvent<GroupInfos, {}>) =>
158-
setRowsSelection(event.api.getSelectedRows() ?? []),
159-
[]
160-
)}
161-
>
162-
<GridButton
163-
labelId="groups.table.toolbar.add.label"
164-
textId="groups.table.toolbar.add"
165-
startIcon={<GroupAdd fontSize="small" />}
166-
color="primary"
167-
onClick={useCallback(() => setOpenAddGroupDialog(true), [])}
168-
/>
169-
<GridButtonDelete onClick={() => setShowDeletionDialog(true)} disabled={deleteGroupsDisabled} />
170-
</GridTable>
171-
<AddGroupDialog gridRef={gridRef} open={openAddGroupDialog} setOpen={setOpenAddGroupDialog} />
172-
<DeleteConfirmationDialog
173-
open={showDeletionDialog}
174-
setOpen={setShowDeletionDialog}
175-
itemType={intl.formatMessage({ id: 'form.delete.dialog.group' })}
176-
itemNames={rowsSelection.map((group) => group.name)}
177-
deleteFunc={deleteGroups}
156+
<>
157+
<GridTable<GroupInfos, {}>
158+
ref={props.gridRef}
159+
dataLoader={UserAdminSrv.fetchGroups}
160+
columnDefs={columns}
161+
defaultColDef={defaultColDef}
162+
gridId="table-groups"
163+
getRowId={getRowId}
164+
rowSelection={defaultRowSelection}
165+
onRowClicked={props.onRowClicked}
166+
onSelectionChanged={onSelectionChanged}
167+
>
168+
<GridButton
169+
labelId="groups.table.toolbar.add.label"
170+
textId="groups.table.toolbar.add"
171+
startIcon={<GroupAdd fontSize="small" />}
172+
color="primary"
173+
onClick={onAddButton}
178174
/>
179-
</Grid>
180-
</Grid>
175+
<GridButtonDelete onClick={() => setShowDeletionDialog(true)} disabled={deleteGroupsDisabled} />
176+
</GridTable>
177+
178+
<DeleteConfirmationDialog
179+
open={showDeletionDialog}
180+
setOpen={setShowDeletionDialog}
181+
itemType={intl.formatMessage({ id: 'form.delete.dialog.group' })}
182+
itemNames={rowsSelection.map((user) => user.name)}
183+
deleteFunc={deleteGroups}
184+
/>
185+
</>
181186
);
182187
};
183-
export default GroupsPage;
188+
export default GroupsTable;

src/pages/groups/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
66
*/
77

8-
export { default as Groups } from './GroupsPage';
8+
export { default as Groups } from './groups-page';

0 commit comments

Comments
 (0)