import {useCallback, useContext, useEffect, useRef, useState} from "react"; import {Link, useNavigate, useParams} from "react-router-dom"; import {LocaleContext} from "shared/locale"; import SearchField from "shared/elements/search-field"; import React from "react"; import {sprintf} from "sprintf-js"; import {DataTable, ControlsColumn, NumericColumn, StringColumn} from "shared/elements/data-table"; import EditIcon from "@mui/icons-material/Edit"; import usePagination from "shared/hooks/pagination"; import Dialog from "shared/elements/dialog"; import {FormControl, FormLabel, TextField, Button, CircularProgress, Box, Grid} from "@mui/material"; import {Add, Delete, KeyboardArrowLeft, Save} from "@mui/icons-material"; import {MuiColorInput} from "mui-color-input"; import ButtonBar from "../../elements/button-bar"; import ViewContent from "../../elements/view-content"; import FormGroup from "../../elements/form-group"; const defaultGroupData = { name: "", color: "#ccc", members: [] }; export default function EditGroupView(props) { const {translate: L, requestModules, currentLocale} = useContext(LocaleContext); const { groupId } = useParams(); const navigate = useNavigate(); const isNewGroup = groupId === "new"; const pagination = usePagination(); const api = props.api; const showDialog = props.showDialog; // data const [fetchGroup, setFetchGroup] = useState(!isNewGroup); const [group, setGroup] = useState(isNewGroup ? defaultGroupData : null); const [members, setMembers] = useState([]); const selectedUserRef = useRef(null); // ui const [dialogData, setDialogData] = useState({open: false}); const [isSaving, setSaving] = useState(false); useEffect(() => { requestModules(props.api, ["general", "account"], currentLocale).then(data => { if (!data.success) { showDialog(data.msg, "Error fetching localization"); } }); }, [currentLocale]); const onFetchGroup = useCallback((force = false) => { if (force || fetchGroup) { setFetchGroup(false); api.getGroup(groupId).then(res => { if (!res.success) { showDialog(res.msg, "Error fetching group"); navigate("/admin/groups"); } else { setGroup(res.group); } }); } }, [api, fetchGroup]); const onFetchMembers = useCallback(async (page, count, orderBy, sortOrder) => { api.fetchGroupMembers(groupId, page, count, orderBy, sortOrder).then((res) => { if (res.success) { setMembers(res.users); pagination.update(res.pagination); } else { showDialog(res.msg, L("account.fetch_group_members_error")); return null; } }); }, [api, showDialog, pagination, groupId]); const onRemoveMember = useCallback(userId => { api.removeGroupMember(groupId, userId).then(data => { if (data.success) { let newMembers = members.filter(u => u.id !== userId); setMembers(newMembers); } else { showDialog(data.msg, L("account.remove_group_member_error")); } }); }, [api, showDialog, groupId, members]); const onAddMember = useCallback(() => { if (selectedUserRef.current) { api.addGroupMember(groupId, selectedUserRef.current.id).then(data => { if (!data.success) { showDialog(data.msg, L("account.add_group_member_error")); } else { let newMembers = [...members]; newMembers.push(selectedUserRef.current); setMembers(newMembers); } selectedUserRef.current = null; }); } }, [api, showDialog, groupId, selectedUserRef, members]) const onSave = useCallback(() => { setSaving(true); if (isNewGroup) { api.createGroup(group.name, group.color).then(data => { setSaving(false); if (!data.success) { showDialog(data.msg, L("account.create_group_error")); } else { navigate(`/admin/group/${data.id}`) } }); } else { api.updateGroup(groupId, group.name, group.color).then(data => { setSaving(false); if (!data.success) { showDialog(data.msg, L("account.update_group_error")); } }); } }, [api, showDialog, groupId, isNewGroup, group]); const onSearchUser = useCallback((async (query) => { let data = await api.searchUser(query); if (!data.success) { showDialog(data.msg, L("account.search_users_error")); return []; } return data.users; }), [api, showDialog]); const onDeleteGroup = useCallback(() => { api.deleteGroup(groupId).then(data => { if (!data.success) { showDialog(data.msg, L("account.delete_group_error")); } else { navigate("/admin/groups"); } }); }, [api, showDialog, groupId]); const onOpenMemberDialog = useCallback(() => { setDialogData({ open: true, title: L("account.add_group_member_title"), message: L("account.add_group_member_text"), inputs: [ { type: "custom", name: "search", size: "small", key: "search", element: SearchField, onSearch: v => onSearchUser(v), onSelect: u => { selectedUserRef.current = u }, getOptionLabel: u => u.fullName || u.name } ], onOption: (option) => { if(option === 1) { onAddMember() } else { selectedUserRef.current = null } } }); }, [onAddMember, onSearchUser, selectedUserRef, setDialogData]); useEffect(() => { onFetchGroup(); }, []); if (group === null) { return } return <> Home, {L("account.group")}, {isNewGroup ? L("general.new") : groupId}, ]}> {L("account.group_name")} setGroup({...group, name: e.target.value})}/> {L("account.color")} setGroup({...group, color: color})} /> { !isNewGroup && } {!isNewGroup && api.hasPermission("groups/getMembers") ?

{L("account.members")}

navigate(`/admin/user/${entry.id}`) }, { label: L("general.remove"), element: Delete, disabled: !api.hasPermission("groups/removeMember"), color: "error", onClick: (entry) => setDialogData({ open: true, title: L("account.remove_group_member_title"), message: sprintf(L("account.remove_group_member_text"), entry.fullName || entry.name), onOption: (option) => option === 1 ? onRemoveMember(entry.id) : true }) } ]), ]} buttons={[{ key: "btn-add-member", color: "primary", startIcon: , disabled: !api.hasPermission("groups/addMember"), children: L("general.add"), onClick: onOpenMemberDialog }]} />
: <> }
setDialogData({open: false})} title={dialogData.title} message={dialogData.message} onOption={dialogData.onOption} inputs={dialogData.inputs} options={[L("general.cancel"), L("general.ok")]} /> }