From 2493232c8491b51c26e3841f99ae5a18d23f8560 Mon Sep 17 00:00:00 2001 From: crupest Date: Tue, 17 Nov 2020 17:31:42 +0800 Subject: ... --- FrontEnd/src/app/views/admin/UserAdmin.tsx | 352 ++++++++++------------------- 1 file changed, 115 insertions(+), 237 deletions(-) (limited to 'FrontEnd/src/app/views/admin/UserAdmin.tsx') diff --git a/FrontEnd/src/app/views/admin/UserAdmin.tsx b/FrontEnd/src/app/views/admin/UserAdmin.tsx index 856e6136..3432cddf 100644 --- a/FrontEnd/src/app/views/admin/UserAdmin.tsx +++ b/FrontEnd/src/app/views/admin/UserAdmin.tsx @@ -1,5 +1,4 @@ import React, { useState, useEffect } from "react"; -import axios from "axios"; import { ListGroup, Row, @@ -13,77 +12,22 @@ import OperationDialog from "../common/OperationDialog"; import AdminSubPage from "./AdminSubPage"; import { User, AuthUser } from "@/services/user"; -import { getHttpUserClient } from "@/http/user"; +import { getHttpUserClient, HttpUser } from "@/http/user"; -const apiBaseUrl = "/api"; - -interface CreateUserInfo { - username: string; - password: string; -} - -async function createUser(user: CreateUserInfo, token: string): Promise { - const res = await axios.post( - `${apiBaseUrl}/userop/createuser?token=${token}`, - user - ); - return res.data; -} - -function deleteUser(username: string, token: string): Promise { - return axios.delete(`${apiBaseUrl}/users/${username}?token=${token}`); -} - -function changeUsername( - oldUsername: string, - newUsername: string, - token: string -): Promise { - return axios.patch(`${apiBaseUrl}/users/${oldUsername}?token=${token}`, { - username: newUsername, - }); -} - -function changePassword( - username: string, - newPassword: string, - token: string -): Promise { - return axios.patch(`${apiBaseUrl}/users/${username}?token=${token}`, { - password: newPassword, - }); -} - -const kChangeUsername = "changeusername"; -const kChangePassword = "changepassword"; -const kChangePermission = "changepermission"; +const kModify = "modify"; const kDelete = "delete"; -type TChangeUsername = typeof kChangeUsername; -type TChangePassword = typeof kChangePassword; -type TChangePermission = typeof kChangePermission; +type TModify = typeof kModify; type TDelete = typeof kDelete; -type ContextMenuItem = - | TChangeUsername - | TChangePassword - | TChangePermission - | TDelete; +type ContextMenuItem = TModify | TDelete; interface UserCardProps { - onContextMenu: (item: ContextMenuItem) => void; + on: { [key in ContextMenuItem]: () => void }; user: User; } -const UserItem: React.FC = (props) => { - const user = props.user; - - const createClickCallback = (item: ContextMenuItem): (() => void) => { - return () => { - props.onContextMenu(item); - }; - }; - +const UserItem: React.FC = ({ user, on }) => { return ( @@ -101,19 +45,8 @@ const UserItem: React.FC = (props) => { Manage - - Change Username - - - Change Password - - - Change Permission - - + Modify + Delete @@ -124,16 +57,20 @@ const UserItem: React.FC = (props) => { ); }; -interface DialogProps { +interface DialogProps { open: boolean; close: () => void; + token: string; + data: TData; + onSuccess: (data: TReturn) => void; } -interface CreateUserDialogProps extends DialogProps { - process: (user: CreateUserInfo) => Promise; -} - -const CreateUserDialog: React.FC = (props) => { +const CreateUserDialog: React.FC> = ({ + open, + close, + token, + onSuccess, +}) => { return ( = (props) => { ] as const } onProcess={([username, password]) => - props.process({ - username: username, - password: password, - }) + getHttpUserClient().createUser( + { + username, + password, + }, + token + ) } - close={props.close} - open={props.open} + close={close} + open={open} + onSuccessAndClose={onSuccess} /> ); }; @@ -161,110 +102,64 @@ const UsernameLabel: React.FC = (props) => { return {props.children}; }; -interface UserDeleteDialogProps extends DialogProps { - username: string; - process: () => Promise; -} - -const UserDeleteDialog: React.FC = (props) => { +const UserDeleteDialog: React.FC> = ({ open, close, token, data: { username }, onSuccess }) => { return ( ( <> - {"You are deleting user "} - {props.username} - {" !"} + You are deleting user {username} ! )} - onProcess={props.process} + onProcess={() => getHttpUserClient().delete(username, token)} + onSuccessAndClose={onSuccess} /> ); }; -interface UserModifyDialogProps extends DialogProps { - username: string; - process: (value: T) => Promise; -} - -const UserChangeUsernameDialog: React.FC> = ( - props -) => { +const UserModifyDialog: React.FC> = ({ open, close, token, data: { oldUser }, onSuccess }) => { return ( ( <> - {"You are change the username of user "} - {props.username} - {" !"} + You are change the password of user + {oldUser.username} ! )} - inputScheme={[{ type: "text", label: "New Username" }]} - onProcess={([newUsername]) => { - return props.process(newUsername); - }} - /> - ); -}; - -const UserChangePasswordDialog: React.FC> = ( - props -) => { - return ( - ( - <> - {"You are change the password of user "} - {props.username} - {" !"} - - )} - inputScheme={[{ type: "text", label: "New Password" }]} - onProcess={([newPassword]) => { - return props.process(newPassword); - }} - /> - ); -}; - -interface UserChangePermissionDialogProps extends DialogProps { - username: string; - newPermission: boolean; - process: () => Promise; -} - -const UserChangePermissionDialog: React.FC = ( - props -) => { - return ( - ( - <> - {"You are change user "} - {props.username} - {" to "} - - {props.newPermission ? "administrator" : "normal user"} - - {" !"} - - )} - onProcess={props.process} + inputScheme={ + [ + { type: "text", label: "New Username", initValue: oldUser.username }, + { type: "text", label: "New Password" }, + { type: "text", label: "New 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, + }, + token + ) + } + onSuccessAndClose={onSuccess} /> ); }; @@ -279,23 +174,18 @@ const UserAdmin: React.FC = (props) => { | { type: "create"; } - | { type: TDelete; username: string } | { - type: TChangeUsername; - username: string; + type: TModify; + user: HttpUser; } - | { - type: TChangePassword; - username: string; - } - | { - type: TChangePermission; - username: string; - newPermission: boolean; - }; + | { 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); + }; const token = props.user.token; @@ -311,20 +201,19 @@ const UserAdmin: React.FC = (props) => { return () => { subscribe = false; }; - }, []); + }, [usersVersion]); let dialogNode: React.ReactNode; - if (dialog) + if (dialog) { switch (dialog.type) { case "create": dialogNode = ( setDialog(null)} - process={async (user) => { - const u = await createUser(user, token); - setUsers((oldUsers) => [...(oldUsers ?? []), u]); - }} + token={token} + data={undefined} + onSuccess={updateUsers} /> ); break; @@ -333,52 +222,25 @@ const UserAdmin: React.FC = (props) => { setDialog(null)} - username={dialog.username} - process={async () => { - await deleteUser(dialog.username, token); - setUsers((oldUsers) => - (oldUsers ?? []).filter((u) => u.username !== dialog.username) - ); - }} - /> - ); - break; - case kChangeUsername: - dialogNode = ( - setDialog(null)} - username={dialog.username} - process={async (newUsername) => { - await changeUsername(dialog.username, newUsername, token); - setUsers((oldUsers) => { - const users = (oldUsers ?? []).slice(); - const findedUser = users.find( - (u) => u.username === dialog.username - ); - if (findedUser) findedUser.username = newUsername; - return users; - }); - }} + token={token} + data={{ username: dialog.username }} + onSuccess={updateUsers} /> ); break; - case kChangePassword: + case kModify: dialogNode = ( - setDialog(null)} - username={dialog.username} - process={async (newPassword) => { - await changePassword(dialog.username, newPassword, token); - }} + token={token} + data={{ oldUser: dialog.user }} + onSuccess={updateUsers} /> ); break; - case kChangePermission: { - break; - } } + } if (users) { const userComponents = users.map((user) => { @@ -386,24 +248,40 @@ const UserAdmin: React.FC = (props) => { {}} + on={{ + modify: () => { + setDialog({ + type: "modify", + user, + }); + }, + delete: () => { + setDialog({ + type: "delete", + username: user.username, + }); + }, + }} /> ); }); return ( - + + + + + {userComponents} {dialogNode} -- cgit v1.2.3