import React, { useState, useEffect } from "react"; import classnames from "classnames"; import OperationDialog, { OperationDialogBoolInput, } from "../common/dailog/OperationDialog"; import { AuthUser } from "@/services/user"; import { getHttpUserClient, HttpUser, kUserPermissionList, UserPermission, } from "@/http/user"; import { Trans, useTranslation } from "react-i18next"; import Button from "../common/button/Button"; import TextButton from "../common/button/TextButton"; import Spinner from "../common/Spinner"; interface DialogProps { open: boolean; close: () => void; data: TData; onSuccess: (data: TReturn) => void; } const CreateUserDialog: React.FC> = ({ open, close, onSuccess, }) => { return ( getHttpUserClient().post({ username, password, }) } onClose={close} open={open} onSuccessAndClose={onSuccess} /> ); }; const UsernameLabel: React.FC = (props) => { return {props.children}; }; const UserDeleteDialog: React.FC> = ({ open, close, data: { username }, onSuccess }) => { return ( ( 0{username}2 )} onProcess={() => getHttpUserClient().delete(username)} onSuccessAndClose={onSuccess} /> ); }; const UserModifyDialog: React.FC< DialogProps< { oldUser: HttpUser; }, HttpUser > > = ({ open, close, data: { oldUser }, onSuccess }) => { return ( ( 0{oldUser.username}2 )} inputScheme={ [ { type: "text", label: "admin:user.username", initValue: oldUser.username, }, { type: "text", label: "admin:user.password" }, { type: "text", label: "admin:user.nickname", initValue: oldUser.nickname, }, ] as const } onProcess={([username, password, nickname]) => getHttpUserClient().patch(oldUser.username, { username: username !== oldUser.username ? username : undefined, password: password !== "" ? password : undefined, nickname: nickname !== oldUser.nickname ? nickname : undefined, }) } onSuccessAndClose={onSuccess} /> ); }; const UserPermissionModifyDialog: React.FC< DialogProps< { username: string; permissions: UserPermission[]; }, UserPermission[] > > = ({ open, close, data: { username, permissions }, onSuccess }) => { const oldPermissionBoolList: boolean[] = kUserPermissionList.map( (permission) => permissions.includes(permission) ); return ( ( 0{username}2 )} inputScheme={kUserPermissionList.map( (permission, index) => ({ type: "bool", label: permission, initValue: oldPermissionBoolList[index], }) )} onProcess={async (newPermissionBoolList): Promise => { for (let index = 0; index < kUserPermissionList.length; index++) { const oldValue = oldPermissionBoolList[index]; const newValue = newPermissionBoolList[index]; const permission = kUserPermissionList[index]; if (oldValue === newValue) continue; if (newValue) { await getHttpUserClient().putUserPermission(username, permission); } else { await getHttpUserClient().deleteUserPermission( username, permission ); } } return newPermissionBoolList; }} onSuccessAndClose={(newPermissionBoolList: boolean[]) => { const permissions: UserPermission[] = []; for (let index = 0; index < kUserPermissionList.length; index++) { if (newPermissionBoolList[index]) { permissions.push(kUserPermissionList[index]); } } onSuccess(permissions); }} /> ); }; const kModify = "modify"; const kModifyPermission = "permission"; const kDelete = "delete"; type TModify = typeof kModify; type TModifyPermission = typeof kModifyPermission; type TDelete = typeof kDelete; type ContextMenuItem = TModify | TModifyPermission | TDelete; interface UserItemProps { on: { [key in ContextMenuItem]: () => void }; user: HttpUser; } const UserItem: React.FC = ({ user, on }) => { const { t } = useTranslation(); const [editMaskVisible, setEditMaskVisible] = React.useState(false); return (
setEditMaskVisible(true)} />

{user.username}

{t("admin:user.nickname")} {user.nickname}
{t("admin:user.uniqueId")} {user.uniqueId}
{t("admin:user.permissions")} {user.permissions.map((permission) => { return ( {permission}{" "} ); })}
setEditMaskVisible(false)} >
); }; interface UserAdminProps { user: AuthUser; } const UserAdmin: React.FC = () => { type DialogInfo = | null | { type: "create"; } | { type: TModify; user: HttpUser; } | { type: TModifyPermission; username: string; permissions: UserPermission[]; } | { type: TDelete; username: string }; const [users, setUsers] = useState(null); const [dialog, setDialog] = useState(null); const [usersVersion, setUsersVersion] = useState(0); const updateUsers = (): void => { setUsersVersion(usersVersion + 1); }; useEffect(() => { let subscribe = true; void getHttpUserClient() .list() .then((us) => { if (subscribe) { setUsers(us); } }); return () => { subscribe = false; }; }, [usersVersion]); let dialogNode: React.ReactNode; if (dialog) { switch (dialog.type) { case "create": dialogNode = ( setDialog(null)} data={undefined} onSuccess={updateUsers} /> ); break; case kDelete: dialogNode = ( setDialog(null)} data={{ username: dialog.username }} onSuccess={updateUsers} /> ); break; case kModify: dialogNode = ( setDialog(null)} data={{ oldUser: dialog.user }} onSuccess={updateUsers} /> ); break; case kModifyPermission: dialogNode = ( setDialog(null)} data={{ username: dialog.username, permissions: dialog.permissions, }} onSuccess={updateUsers} /> ); break; } } if (users) { const userComponents = users.map((user) => { return ( { setDialog({ type: "modify", user, }); }, permission: () => { setDialog({ type: kModifyPermission, username: user.username, permissions: user.permissions, }); }, delete: () => { setDialog({ type: "delete", username: user.username, }); }, }} /> ); }); return ( <>
{userComponents} {dialogNode} ); } else { return ; } }; export default UserAdmin;