From 517101c4475498976fbf4a3cacf8b408cee545e8 Mon Sep 17 00:00:00 2001 From: crupest Date: Fri, 20 Nov 2020 20:14:12 +0800 Subject: ... --- FrontEnd/src/app/http/user.ts | 10 +- FrontEnd/src/app/views/admin/UserAdmin.tsx | 213 +++++++++++++++++++++-------- 2 files changed, 165 insertions(+), 58 deletions(-) (limited to 'FrontEnd/src') diff --git a/FrontEnd/src/app/http/user.ts b/FrontEnd/src/app/http/user.ts index 243846d1..929956d0 100644 --- a/FrontEnd/src/app/http/user.ts +++ b/FrontEnd/src/app/http/user.ts @@ -12,10 +12,14 @@ import { convertToNotModified, } from "./common"; +export const kUserManagement = "UserManagement"; +export const kAllTimelineManagement = "AllTimelineManagement"; +export const kHighlightTimelineManagement = "HighlightTimelineManagement"; + export const kUserPermissionList = [ - "UserManagement", - "AllTimelineManagement", - "HighlightTimelineManagement", + kUserManagement, + kAllTimelineManagement, + kHighlightTimelineManagement, ] as const; export type UserPermission = typeof kUserPermissionList[number]; diff --git a/FrontEnd/src/app/views/admin/UserAdmin.tsx b/FrontEnd/src/app/views/admin/UserAdmin.tsx index 65cd3b74..bd60381f 100644 --- a/FrontEnd/src/app/views/admin/UserAdmin.tsx +++ b/FrontEnd/src/app/views/admin/UserAdmin.tsx @@ -1,64 +1,20 @@ import React, { useState, useEffect } from "react"; +import clsx from "clsx"; import { ListGroup, Row, Col, Spinner, Button } from "react-bootstrap"; import InlineSVG from "react-inlinesvg"; import PencilSquareIcon from "bootstrap-icons/icons/pencil-square.svg"; -import OperationDialog from "../common/OperationDialog"; +import OperationDialog, { + OperationBoolInputInfo, +} from "../common/OperationDialog"; import { User, AuthUser } from "@/services/user"; -import { getHttpUserClient, HttpUser } from "@/http/user"; -import clsx from "clsx"; - -const kModify = "modify"; -const kDelete = "delete"; - -type TModify = typeof kModify; -type TDelete = typeof kDelete; - -type ContextMenuItem = TModify | TDelete; - -interface UserCardProps { - on: { [key in ContextMenuItem]: () => void }; - user: User; -} - -const UserItem: React.FC = ({ user, on }) => { - const [editMaskVisible, setEditMaskVisible] = React.useState(false); - - return ( - - setEditMaskVisible(true)} - /> -

{user.username}

-
nickname: {user.nickname}
-
unique id: {user.uniqueId}
-
- permissions:{" "} - {user.permissions.map((permission) => { - return ( - - {permission}{" "} - - ); - })} -
-
setEditMaskVisible(false)} - > - - -
-
- ); -}; +import { + getHttpUserClient, + HttpUser, + kUserPermissionList, + UserPermission, +} from "@/http/user"; interface DialogProps { open: boolean; @@ -167,6 +123,127 @@ const UserModifyDialog: React.FC> = ({ open, close, token, data: { username, permissions }, onSuccess }) => { + const oldPermissionBoolList: boolean[] = kUserPermissionList.map( + (permission) => permissions.includes(permission) + ); + + return ( + ( + <> + You are modify permission of user + {username} ! + + )} + 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, + token + ); + } else { + await getHttpUserClient().deleteUserPermission( + username, + permission, + token + ); + } + } + 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: User; +} + +const UserItem: React.FC = ({ user, on }) => { + const [editMaskVisible, setEditMaskVisible] = React.useState(false); + + return ( + + setEditMaskVisible(true)} + /> +

{user.username}

+
nickname: {user.nickname}
+
unique id: {user.uniqueId}
+
+ permissions:{" "} + {user.permissions.map((permission) => { + return ( + + {permission}{" "} + + ); + })} +
+
setEditMaskVisible(false)} + > + + + +
+
+ ); +}; + interface UserAdminProps { user: AuthUser; } @@ -181,6 +258,11 @@ const UserAdmin: React.FC = (props) => { type: TModify; user: HttpUser; } + | { + type: TModifyPermission; + username: string; + permissions: UserPermission[]; + } | { type: TDelete; username: string }; const [users, setUsers] = useState(null); @@ -220,7 +302,7 @@ const UserAdmin: React.FC = (props) => { /> ); break; - case "delete": + case kDelete: dialogNode = ( = (props) => { /> ); break; + case kModifyPermission: + dialogNode = ( + setDialog(null)} + token={token} + data={{ + username: dialog.username, + permissions: dialog.permissions, + }} + onSuccess={updateUsers} + /> + ); + break; } } @@ -258,6 +354,13 @@ const UserAdmin: React.FC = (props) => { user, }); }, + permission: () => { + setDialog({ + type: kModifyPermission, + username: user.username, + permissions: user.permissions, + }); + }, delete: () => { setDialog({ type: "delete", -- cgit v1.2.3