diff --git a/web/src/components/MemberListView.tsx b/web/src/components/MemberListView.tsx index e446c96..f15616f 100644 --- a/web/src/components/MemberListView.tsx +++ b/web/src/components/MemberListView.tsx @@ -1,5 +1,7 @@ -import { useEffect, useState } from "react"; +import { useEffect } from "react"; import { deleteWorkspaceUser, upsertWorkspaceUser } from "../helpers/api"; +import { useAppSelector } from "../store"; +import { unknownWorkspace, unknownWorkspaceUser } from "../store/modules/workspace"; import useLoading from "../hooks/useLoading"; import { workspaceService } from "../services"; import toastHelper from "./Toast"; @@ -11,36 +13,25 @@ const userRoles = ["Admin", "User"]; interface Props { workspaceId: WorkspaceId; - workspaceUser: WorkspaceUser; - userList: WorkspaceUser[]; -} - -interface State { - workspaceUserList: WorkspaceUser[]; } const MemberListView: React.FC = (props: Props) => { - const { workspaceId, workspaceUser: currentUser } = props; - const [state, setState] = useState({ - workspaceUserList: [], - }); + const { workspaceId } = props; + const user = useAppSelector((state) => state.user.user) as User; + const { workspaceList } = useAppSelector((state) => state.workspace); + const workspace = workspaceList.find((workspace) => workspace.id === workspaceId) ?? unknownWorkspace; + const currentUser = workspace.workspaceUserList.find((workspaceUser) => workspaceUser.userId === user.id) ?? unknownWorkspaceUser; const loadingState = useLoading(); - const fetchWorkspaceUserList = async () => { - loadingState.setLoading(); - try { - const [workspaceUserList] = await Promise.all([workspaceService.getWorkspaceUserList(workspaceId)]); - setState({ - workspaceUserList: workspaceUserList, - }); - } finally { - loadingState.setFinish(); - } - }; - useEffect(() => { - fetchWorkspaceUserList(); - }, [props]); + const workspace = workspaceService.getWorkspaceById(workspaceId); + if (!workspace) { + toastHelper.error("workspace not found"); + return; + } + + loadingState.setFinish(); + }, []); const handleWorkspaceUserRoleChange = async (workspaceUser: WorkspaceUser, role: Role) => { if (workspaceUser.userId === currentUser.userId) { @@ -53,20 +44,20 @@ const MemberListView: React.FC = (props: Props) => { userId: workspaceUser.userId, role, }); - await fetchWorkspaceUserList(); + await workspaceService.fetchWorkspaceById(workspaceId); }; const handleDeleteWorkspaceUserButtonClick = (workspaceUser: WorkspaceUser) => { showCommonDialog({ title: "Delete Workspace Member", - content: `Are you sure to delete member \`${workspaceUser.user.name}\` in this workspace?`, + content: `Are you sure to delete member \`${workspaceUser.name}\` in this workspace?`, style: "warning", onConfirm: async () => { await deleteWorkspaceUser({ workspaceId: workspaceId, userId: workspaceUser.userId, }); - await fetchWorkspaceUserList(); + await workspaceService.fetchWorkspaceById(workspaceId); }, }); }; @@ -76,11 +67,11 @@ const MemberListView: React.FC = (props: Props) => { {loadingState.isLoading ? ( <> ) : ( - state.workspaceUserList.map((workspaceUser) => { + workspace.workspaceUserList.map((workspaceUser) => { return (
- {workspaceUser.user.name} + {workspaceUser.name} {currentUser.userId === workspaceUser.userId && (yourself)}
diff --git a/web/src/components/UpsertWorkspaceUserDialog.tsx b/web/src/components/UpsertWorkspaceUserDialog.tsx index a8bedff..870e437 100644 --- a/web/src/components/UpsertWorkspaceUserDialog.tsx +++ b/web/src/components/UpsertWorkspaceUserDialog.tsx @@ -1,5 +1,6 @@ import { Dialog, DialogContent, DialogTitle } from "@mui/material"; import { useState } from "react"; +import { workspaceService } from "../services"; import { UNKNOWN_ID } from "../helpers/consts"; import { upsertWorkspaceUser } from "../helpers/api"; import useLoading from "../hooks/useLoading"; @@ -59,6 +60,8 @@ const UpsertWorkspaceUserDialog: React.FC = (props: Props) => { ...state.workspaceUserUpsert, }); + await workspaceService.fetchWorkspaceById(workspaceId); + if (onConfirm) { onConfirm(); } else { diff --git a/web/src/components/WorkspaceSetting.tsx b/web/src/components/WorkspaceSetting.tsx index f78657f..d20dca6 100644 --- a/web/src/components/WorkspaceSetting.tsx +++ b/web/src/components/WorkspaceSetting.tsx @@ -14,8 +14,6 @@ interface Props { } interface State { - workspace: Workspace; - workspaceUser: WorkspaceUser; showEditWorkspaceDialog: boolean; } @@ -24,11 +22,12 @@ const WorkspaceSetting: React.FC = (props: Props) => { const navigate = useNavigate(); const user = useAppSelector((state) => state.user.user) as User; const [state, setState] = useState({ - workspace: unknownWorkspace, - workspaceUser: unknownWorkspaceUser, showEditWorkspaceDialog: false, }); + const { workspaceList } = useAppSelector((state) => state.workspace); const loadingState = useLoading(); + const workspace = workspaceList.find((workspace) => workspace.id === workspaceId) ?? unknownWorkspace; + const workspaceUser = workspace.workspaceUserList.find((workspaceUser) => workspaceUser.userId === user.id) ?? unknownWorkspaceUser; useEffect(() => { const workspace = workspaceService.getWorkspaceById(workspaceId); @@ -37,18 +36,7 @@ const WorkspaceSetting: React.FC = (props: Props) => { return; } - loadingState.setLoading(); - Promise.all([workspaceService.getWorkspaceUser(workspace.id, user.id)]) - .then(([workspaceUser]) => { - setState({ - ...state, - workspace, - workspaceUser, - }); - }) - .finally(() => { - loadingState.setFinish(); - }); + loadingState.setFinish(); }, []); const handleEditWorkspaceButtonClick = () => { @@ -58,32 +46,22 @@ const WorkspaceSetting: React.FC = (props: Props) => { }); }; - const handleEditWorkspaceDialogConfirm = () => { - const prevWorkspace = state.workspace; - const workspace = workspaceService.getWorkspaceById(workspaceId); - if (!workspace) { - toastHelper.error("workspace not found"); - return; - } - + const handleEditWorkspaceDialogConfirm = async () => { setState({ ...state, - workspace: workspace, showEditWorkspaceDialog: false, }); - - if (prevWorkspace.name !== workspace.name) { - navigate(`/${workspace.name}#setting`); - } + const workspace = await workspaceService.fetchWorkspaceById(workspaceId); + navigate(`/${workspace.name}#setting`); }; const handleDeleteWorkspaceButtonClick = () => { showCommonDialog({ title: "Delete Workspace", - content: `Are you sure to delete workspace \`${state.workspace.name}\`?`, + content: `Are you sure to delete workspace \`${workspace.name}\`?`, style: "warning", onConfirm: async () => { - await workspaceService.deleteWorkspaceById(state.workspace.id); + await workspaceService.deleteWorkspaceById(workspace.id); navigate("/"); }, }); @@ -92,12 +70,12 @@ const WorkspaceSetting: React.FC = (props: Props) => { const handleExitWorkspaceButtonClick = () => { showCommonDialog({ title: "Exit Workspace", - content: `Are you sure to exit workspace \`${state.workspace.name}\`?`, + content: `Are you sure to exit workspace \`${workspace.name}\`?`, style: "warning", onConfirm: async () => { await deleteWorkspaceUser({ - workspaceId: state.workspace.id, - userId: state.workspaceUser.userId, + workspaceId: workspace.id, + userId: workspaceUser.userId, }); navigate("/"); }, @@ -107,11 +85,11 @@ const WorkspaceSetting: React.FC = (props: Props) => { return ( <>
-

{state.workspace.name}

-

{state.workspace.description}

+

{workspace.name}

+

{workspace.description}

- {state.workspaceUser.role === "ADMIN" ? ( + {workspaceUser.role === "ADMIN" ? ( <> - + {workspaceUser.role === "ADMIN" && ( + + )} } actionsClassName="!w-32" @@ -139,17 +123,9 @@ const WorkspaceDetail: React.FC = () => {
) : ( <> - {location.hash === "#shortcuts" && } - {location.hash === "#members" && ( - - )} - {location.hash === "#setting" && } + {location.hash === "#shortcuts" && } + {location.hash === "#members" && } + {location.hash === "#setting" && } )}
@@ -157,7 +133,7 @@ const WorkspaceDetail: React.FC = () => { {state.showCreateShortcutDialog && ( { setState({ ...state, @@ -178,7 +154,7 @@ const WorkspaceDetail: React.FC = () => { {state.showUpsertWorkspaceUserDialog && ( { setState({ ...state, @@ -186,13 +162,10 @@ const WorkspaceDetail: React.FC = () => { }); }} onConfirm={async () => { - const workspaceUserList = await workspaceService.getWorkspaceUserList(state.workspace.id); setState({ ...state, - userList: workspaceUserList, showUpsertWorkspaceUserDialog: false, }); - if (location.hash !== "#members") { navigate("#members"); } diff --git a/web/src/services/workspaceService.ts b/web/src/services/workspaceService.ts index c65fc50..05654e5 100644 --- a/web/src/services/workspaceService.ts +++ b/web/src/services/workspaceService.ts @@ -1,6 +1,6 @@ import * as api from "../helpers/api"; import store from "../store"; -import { createWorkspace, deleteWorkspace, patchWorkspace, setWorkspaceList } from "../store/modules/workspace"; +import { createWorkspace, deleteWorkspace, patchWorkspace, setWorkspaceById, setWorkspaceList } from "../store/modules/workspace"; const convertResponseModelWorkspace = (workspace: Workspace): Workspace => { return { @@ -22,6 +22,13 @@ const workspaceService = { return workspaces; }, + fetchWorkspaceById: async (workspaceId: WorkspaceId) => { + const { data } = (await api.getWorkspaceById(workspaceId)).data; + const workspace = convertResponseModelWorkspace(data); + store.dispatch(setWorkspaceById(workspace)); + return workspace; + }, + getWorkspaceByName: (workspaceName: string) => { const workspaceList = workspaceService.getState().workspaceList; for (const workspace of workspaceList) { diff --git a/web/src/store/modules/workspace.ts b/web/src/store/modules/workspace.ts index 2b1d0d0..d896000 100644 --- a/web/src/store/modules/workspace.ts +++ b/web/src/store/modules/workspace.ts @@ -3,12 +3,14 @@ import { UNKNOWN_ID } from "../../helpers/consts"; export const unknownWorkspace = { id: UNKNOWN_ID, -} as Workspace; + workspaceUserList: [], +} as unknown as Workspace; export const unknownWorkspaceUser = { workspaceId: UNKNOWN_ID, userId: UNKNOWN_ID, -} as WorkspaceUser; + role: "USER", +} as unknown as WorkspaceUser; interface State { workspaceList: Workspace[]; @@ -26,6 +28,18 @@ const workspaceSlice = createSlice({ workspaceList: action.payload, }; }, + setWorkspaceById: (state, action: PayloadAction) => { + return { + ...state, + workspaceList: state.workspaceList.map((s) => { + if (s.id === action.payload.id) { + return action.payload; + } else { + return s; + } + }), + }; + }, createWorkspace: (state, action: PayloadAction) => { return { ...state, @@ -56,6 +70,6 @@ const workspaceSlice = createSlice({ }, }); -export const { setWorkspaceList, createWorkspace, patchWorkspace, deleteWorkspace } = workspaceSlice.actions; +export const { setWorkspaceList, setWorkspaceById, createWorkspace, patchWorkspace, deleteWorkspace } = workspaceSlice.actions; export default workspaceSlice.reducer; diff --git a/web/src/types/modules/WorkspaceUser.d.ts b/web/src/types/modules/WorkspaceUser.d.ts index 3e01593..54d4871 100644 --- a/web/src/types/modules/WorkspaceUser.d.ts +++ b/web/src/types/modules/WorkspaceUser.d.ts @@ -3,10 +3,11 @@ type Role = "ADMIN" | "USER"; interface WorkspaceUser { workspaceId: WorkspaceId; userId: UserId; - user: User; role: Role; createdTs: TimeStamp; updatedTs: TimeStamp; + email: string; + name: string; } interface WorkspaceUserUpsert { diff --git a/web/src/types/modules/workspace.d.ts b/web/src/types/modules/workspace.d.ts index 5937293..4adf4a3 100644 --- a/web/src/types/modules/workspace.d.ts +++ b/web/src/types/modules/workspace.d.ts @@ -10,6 +10,8 @@ interface Workspace { name: string; description: string; + + workspaceUserList: WorkspaceUser[]; } interface WorkspaceCreate {