mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
chore: user stores
This commit is contained in:
parent
e629977ad6
commit
7dd7de40b7
@ -4,7 +4,7 @@ import { observer } from "mobx-react-lite";
|
||||
import { mutate } from "swr";
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
// hooks
|
||||
import { useApplication, useUser, useWorkspace } from "hooks/store";
|
||||
import { useApplication, useProject, useUser, useWorkspace } from "hooks/store";
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
import useToast from "hooks/use-toast";
|
||||
import useLocalStorage from "hooks/use-local-storage";
|
||||
@ -73,7 +73,6 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = observer((prop
|
||||
};
|
||||
// store hooks
|
||||
const {
|
||||
project: projectStore,
|
||||
projectIssues: projectIssueStore,
|
||||
viewIssues: projectViewIssueStore,
|
||||
workspaceProfileIssues: profileIssueStore,
|
||||
@ -85,6 +84,7 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = observer((prop
|
||||
} = useApplication();
|
||||
const { currentUser } = useUser();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { workspaceProjects } = useProject();
|
||||
|
||||
const issueStores = {
|
||||
[EProjectStore.PROJECT]: {
|
||||
@ -116,8 +116,6 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = observer((prop
|
||||
|
||||
const { store: currentIssueStore, viewId, dataIdToUpdate } = issueStores[currentStore];
|
||||
|
||||
const projects = workspaceSlug ? projectStore.projects[workspaceSlug.toString()] : undefined;
|
||||
|
||||
const { setValue: setValueInLocalStorage, clearValue: clearLocalStorageValue } = useLocalStorage<any>(
|
||||
"draftedIssue",
|
||||
{}
|
||||
@ -213,9 +211,9 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = observer((prop
|
||||
|
||||
// if data is not present, set active project to the project
|
||||
// in the url. This has the least priority.
|
||||
if (projects && projects.length > 0 && !activeProject)
|
||||
setActiveProject(projects?.find((p) => p.id === projectId)?.id ?? projects?.[0].id ?? null);
|
||||
}, [data, projectId, projects, isOpen, activeProject]);
|
||||
if (workspaceProjects && workspaceProjects.length > 0 && !activeProject)
|
||||
setActiveProject(projectId ?? workspaceProjects?.[0] ?? null);
|
||||
}, [data, projectId, workspaceProjects, isOpen, activeProject]);
|
||||
|
||||
const addIssueToCycle = async (issue: IIssue, cycleId: string) => {
|
||||
if (!workspaceSlug || !activeProject) return;
|
||||
@ -382,7 +380,7 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = observer((prop
|
||||
if (onSubmit) await onSubmit(payload);
|
||||
};
|
||||
|
||||
if (!projects || projects.length === 0) return null;
|
||||
if (!workspaceProjects || workspaceProjects.length === 0) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -7,6 +7,7 @@ import {
|
||||
useApplication,
|
||||
useCycle,
|
||||
useLabel,
|
||||
useMember,
|
||||
useModule,
|
||||
useProject,
|
||||
useProjectState,
|
||||
@ -29,7 +30,6 @@ export const ProjectAuthWrapper: FC<IProjectAuthWrapper> = observer((props) => {
|
||||
const { children } = props;
|
||||
// store
|
||||
const {
|
||||
projectMember: { fetchProjectMembers },
|
||||
projectEstimates: { fetchProjectEstimates },
|
||||
inbox: { fetchInboxesList, isInboxEnabled },
|
||||
} = useMobxStore();
|
||||
@ -43,6 +43,9 @@ export const ProjectAuthWrapper: FC<IProjectAuthWrapper> = observer((props) => {
|
||||
const { fetchAllCycles } = useCycle();
|
||||
const { fetchModules } = useModule();
|
||||
const { fetchViews } = useProjectView();
|
||||
const {
|
||||
project: { fetchProjectMembers },
|
||||
} = useMember();
|
||||
const { fetchProjectStates } = useProjectState();
|
||||
const {
|
||||
project: { fetchProjectLabels },
|
||||
|
@ -4,8 +4,7 @@ import Link from "next/link";
|
||||
import useSWR from "swr";
|
||||
import { observer } from "mobx-react-lite";
|
||||
// hooks
|
||||
import { useLabel, useProject, useUser } from "hooks/store";
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
import { useLabel, useMember, useProject, useUser } from "hooks/store";
|
||||
// icons
|
||||
import { Button, Spinner } from "@plane/ui";
|
||||
|
||||
@ -16,13 +15,11 @@ export interface IWorkspaceAuthWrapper {
|
||||
export const WorkspaceAuthWrapper: FC<IWorkspaceAuthWrapper> = observer((props) => {
|
||||
const { children } = props;
|
||||
// store hooks
|
||||
const {
|
||||
workspaceMember: { fetchWorkspaceMembers, fetchWorkspaceUserProjectsRole },
|
||||
} = useMobxStore();
|
||||
const {
|
||||
membership: { currentWorkspaceMemberInfo, hasPermissionToCurrentWorkspace, fetchUserWorkspaceInfo },
|
||||
} = useUser();
|
||||
const { membership } = useUser();
|
||||
const { fetchProjects } = useProject();
|
||||
const {
|
||||
workspace: { fetchWorkspaceMembers },
|
||||
} = useMember();
|
||||
const {
|
||||
workspace: { fetchWorkspaceLabels },
|
||||
} = useLabel();
|
||||
@ -32,7 +29,7 @@ export const WorkspaceAuthWrapper: FC<IWorkspaceAuthWrapper> = observer((props)
|
||||
// fetching user workspace information
|
||||
useSWR(
|
||||
workspaceSlug ? `WORKSPACE_MEMBERS_ME_${workspaceSlug}` : null,
|
||||
workspaceSlug ? () => fetchUserWorkspaceInfo(workspaceSlug.toString()) : null
|
||||
workspaceSlug ? () => membership.fetchUserWorkspaceInfo(workspaceSlug.toString()) : null
|
||||
);
|
||||
// fetching workspace projects
|
||||
useSWR(
|
||||
@ -52,21 +49,29 @@ export const WorkspaceAuthWrapper: FC<IWorkspaceAuthWrapper> = observer((props)
|
||||
// fetch workspace user projects role
|
||||
useSWR(
|
||||
workspaceSlug ? `WORKSPACE_PROJECTS_ROLE_${workspaceSlug}` : null,
|
||||
workspaceSlug ? () => fetchWorkspaceUserProjectsRole(workspaceSlug.toString()) : null
|
||||
workspaceSlug ? () => membership.fetchUserWorkspaceProjectsRole(workspaceSlug.toString()) : null
|
||||
);
|
||||
|
||||
console.log("workspaceMemberInfo", membership.workspaceMemberInfo);
|
||||
console.log("currentWorkspaceMemberInfo", membership.currentWorkspaceMemberInfo);
|
||||
console.log("hasPermissionToCurrentWorkspace", membership.hasPermissionToCurrentWorkspace);
|
||||
|
||||
// while data is being loaded
|
||||
if (!currentWorkspaceMemberInfo && hasPermissionToCurrentWorkspace === undefined) {
|
||||
if (!membership.currentWorkspaceMemberInfo && membership.hasPermissionToCurrentWorkspace === undefined) {
|
||||
return (
|
||||
<div className="grid h-screen place-items-center bg-custom-background-100 p-4">
|
||||
<div className="flex flex-col items-center gap-3 text-center">
|
||||
<Spinner />
|
||||
{/* <Spinner /> */}
|
||||
Not allowed
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
// while user does not have access to view that workspace
|
||||
if (hasPermissionToCurrentWorkspace !== undefined && hasPermissionToCurrentWorkspace === false) {
|
||||
if (
|
||||
membership.hasPermissionToCurrentWorkspace !== undefined &&
|
||||
membership.hasPermissionToCurrentWorkspace === false
|
||||
) {
|
||||
return (
|
||||
<div className={`h-screen w-full overflow-hidden bg-custom-background-100`}>
|
||||
<div className="grid h-full place-items-center p-4">
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { computed, observable, makeObservable } from "mobx";
|
||||
import { observable, makeObservable, action } from "mobx";
|
||||
import { RootStore } from "../root.store";
|
||||
// types
|
||||
import { IIssueLabel } from "types";
|
||||
@ -29,7 +29,7 @@ export class LabelRootStore implements ILabelRootStore {
|
||||
// observables
|
||||
labelMap: observable,
|
||||
// computed actions
|
||||
getLabelById: computed,
|
||||
getLabelById: action,
|
||||
});
|
||||
|
||||
// root store
|
||||
|
@ -56,7 +56,7 @@ export class ProjectLabelStore implements IProjectLabelStore {
|
||||
|
||||
// root store
|
||||
this.rootStore = _rootStore;
|
||||
this.labelMap = this.rootStore.labelRoot.labelMap;
|
||||
this.labelMap = this.rootStore.labelRoot?.labelMap;
|
||||
// services
|
||||
this.issueLabelService = new IssueLabelService();
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ export class WorkspaceLabelStore implements IWorkspaceLabelStore {
|
||||
|
||||
// root store
|
||||
this.rootStore = _rootStore;
|
||||
this.labelMap = this.rootStore.labelRoot.labelMap;
|
||||
this.labelMap = this.rootStore.labelRoot?.labelMap;
|
||||
// services
|
||||
this.issueLabelService = new IssueLabelService();
|
||||
}
|
||||
|
@ -9,8 +9,8 @@ export interface IMemberRootStore {
|
||||
// observables
|
||||
memberMap: Record<string, IUserLite>;
|
||||
// sub-stores
|
||||
workspaceMember: IWorkspaceMemberStore;
|
||||
projectMember: IProjectMemberStore;
|
||||
workspace: IWorkspaceMemberStore;
|
||||
project: IProjectMemberStore;
|
||||
}
|
||||
|
||||
export class MemberRootStore implements IMemberRootStore {
|
||||
@ -19,8 +19,8 @@ export class MemberRootStore implements IMemberRootStore {
|
||||
// root store
|
||||
rootStore: RootStore;
|
||||
// sub-stores
|
||||
workspaceMember: IWorkspaceMemberStore;
|
||||
projectMember: IProjectMemberStore;
|
||||
workspace: IWorkspaceMemberStore;
|
||||
project: IProjectMemberStore;
|
||||
|
||||
constructor(_rootStore: RootStore) {
|
||||
makeObservable(this, {
|
||||
@ -31,7 +31,7 @@ export class MemberRootStore implements IMemberRootStore {
|
||||
// root store
|
||||
this.rootStore = _rootStore;
|
||||
// sub-stores
|
||||
this.workspaceMember = new WorkspaceMemberStore(_rootStore);
|
||||
this.projectMember = new ProjectMemberStore(_rootStore);
|
||||
this.workspace = new WorkspaceMemberStore(_rootStore);
|
||||
this.project = new ProjectMemberStore(_rootStore);
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ export class ProjectMemberStore implements IProjectMemberStore {
|
||||
|
||||
// root store
|
||||
this.rootStore = _rootStore;
|
||||
this.memberMap = this.rootStore.memberRoot.memberMap;
|
||||
this.memberMap = this.rootStore.memberRoot?.memberMap;
|
||||
// services
|
||||
this.projectMemberService = new ProjectMemberService();
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ export class WorkspaceMemberStore implements IWorkspaceMemberStore {
|
||||
|
||||
// root store
|
||||
this.rootStore = _rootStore;
|
||||
this.memberMap = this.rootStore.memberRoot.memberMap;
|
||||
this.memberMap = this.rootStore.memberRoot?.memberMap;
|
||||
// services
|
||||
this.workspaceService = new WorkspaceService();
|
||||
}
|
||||
|
@ -1,16 +1,17 @@
|
||||
// mobx
|
||||
import { action, observable, runInAction, makeObservable, computed } from "mobx";
|
||||
import { set } from "lodash";
|
||||
// services
|
||||
import { ProjectMemberService } from "services/project";
|
||||
import { UserService } from "services/user.service";
|
||||
import { WorkspaceService } from "services/workspace.service";
|
||||
// interfaces
|
||||
import { IWorkspaceMemberMe, IProjectMember } from "types";
|
||||
import { IWorkspaceMemberMe, IProjectMember, IUserProjectsRole } from "types";
|
||||
import { RootStore } from "../root.store";
|
||||
import { EUserProjectRoles } from "constants/project";
|
||||
import { EUserWorkspaceRoles } from "constants/workspace";
|
||||
|
||||
export interface IUserMembershipStore {
|
||||
// observables
|
||||
workspaceMemberInfo: {
|
||||
[workspaceSlug: string]: IWorkspaceMemberMe;
|
||||
};
|
||||
@ -23,7 +24,8 @@ export interface IUserMembershipStore {
|
||||
hasPermissionToProject: {
|
||||
[projectId: string]: boolean | null;
|
||||
};
|
||||
|
||||
workspaceProjectsRole: { [workspaceSlug: string]: IUserProjectsRole };
|
||||
// computed
|
||||
currentProjectMemberInfo: IProjectMember | undefined;
|
||||
currentWorkspaceMemberInfo: IWorkspaceMemberMe | undefined;
|
||||
currentProjectRole: EUserProjectRoles | undefined;
|
||||
@ -31,13 +33,14 @@ export interface IUserMembershipStore {
|
||||
|
||||
hasPermissionToCurrentWorkspace: boolean | undefined;
|
||||
hasPermissionToCurrentProject: boolean | undefined;
|
||||
|
||||
// actions
|
||||
fetchUserWorkspaceInfo: (workspaceSlug: string) => Promise<IWorkspaceMemberMe>;
|
||||
fetchUserProjectInfo: (workspaceSlug: string, projectId: string) => Promise<IProjectMember>;
|
||||
|
||||
leaveWorkspace: (workspaceSlug: string) => Promise<void>;
|
||||
joinProject: (workspaceSlug: string, projectIds: string[]) => Promise<any>;
|
||||
leaveProject: (workspaceSlug: string, projectId: string) => Promise<void>;
|
||||
fetchUserWorkspaceProjectsRole: (workspaceSlug: string) => Promise<IUserProjectsRole>;
|
||||
}
|
||||
|
||||
export class UserMembershipStore implements IUserMembershipStore {
|
||||
@ -53,6 +56,7 @@ export class UserMembershipStore implements IUserMembershipStore {
|
||||
hasPermissionToProject: {
|
||||
[projectId: string]: boolean;
|
||||
} = {};
|
||||
workspaceProjectsRole: { [workspaceSlug: string]: IUserProjectsRole } = {};
|
||||
// stores
|
||||
router;
|
||||
// services
|
||||
@ -62,24 +66,26 @@ export class UserMembershipStore implements IUserMembershipStore {
|
||||
|
||||
constructor(_rootStore: RootStore) {
|
||||
makeObservable(this, {
|
||||
// observable
|
||||
workspaceMemberInfo: observable.ref,
|
||||
hasPermissionToWorkspace: observable.ref,
|
||||
projectMemberInfo: observable.ref,
|
||||
hasPermissionToProject: observable.ref,
|
||||
// action
|
||||
// observables
|
||||
workspaceMemberInfo: observable,
|
||||
hasPermissionToWorkspace: observable,
|
||||
projectMemberInfo: observable,
|
||||
hasPermissionToProject: observable,
|
||||
workspaceProjectsRole: observable,
|
||||
// computed
|
||||
currentWorkspaceMemberInfo: computed,
|
||||
currentWorkspaceRole: computed,
|
||||
currentProjectMemberInfo: computed,
|
||||
currentProjectRole: computed,
|
||||
hasPermissionToCurrentWorkspace: computed,
|
||||
hasPermissionToCurrentProject: computed,
|
||||
// actions
|
||||
fetchUserWorkspaceInfo: action,
|
||||
fetchUserProjectInfo: action,
|
||||
leaveWorkspace: action,
|
||||
joinProject: action,
|
||||
leaveProject: action,
|
||||
// computed
|
||||
currentProjectMemberInfo: computed,
|
||||
currentWorkspaceMemberInfo: computed,
|
||||
currentProjectRole: computed,
|
||||
currentWorkspaceRole: computed,
|
||||
hasPermissionToCurrentWorkspace: computed,
|
||||
hasPermissionToCurrentProject: computed,
|
||||
fetchUserWorkspaceProjectsRole: action,
|
||||
});
|
||||
this.router = _rootStore.app.router;
|
||||
// services
|
||||
@ -122,23 +128,23 @@ export class UserMembershipStore implements IUserMembershipStore {
|
||||
try {
|
||||
const response = await this.workspaceService.workspaceMemberMe(workspaceSlug);
|
||||
|
||||
console.log("response", response);
|
||||
|
||||
let memberInfo = this.workspaceMemberInfo;
|
||||
if (!memberInfo) memberInfo = {};
|
||||
memberInfo[workspaceSlug] = { ...response };
|
||||
|
||||
runInAction(() => {
|
||||
this.workspaceMemberInfo = {
|
||||
...this.workspaceMemberInfo,
|
||||
[workspaceSlug]: response,
|
||||
};
|
||||
this.hasPermissionToWorkspace = {
|
||||
...this.hasPermissionToWorkspace,
|
||||
[workspaceSlug]: true,
|
||||
};
|
||||
this.workspaceMemberInfo = memberInfo;
|
||||
// set(this.workspaceMemberInfo, [workspaceSlug], response);
|
||||
set(this.hasPermissionToWorkspace, [workspaceSlug], true);
|
||||
});
|
||||
|
||||
// console.log("this.workspaceMemberInfo", this.workspaceMemberInfo);
|
||||
return response;
|
||||
} catch (error) {
|
||||
runInAction(() => {
|
||||
this.hasPermissionToWorkspace = {
|
||||
...this.hasPermissionToWorkspace,
|
||||
[workspaceSlug]: false,
|
||||
};
|
||||
set(this.hasPermissionToWorkspace, [workspaceSlug], false);
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
@ -223,4 +229,17 @@ export class UserMembershipStore implements IUserMembershipStore {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
fetchUserWorkspaceProjectsRole = async (workspaceSlug: string) => {
|
||||
try {
|
||||
const response = await this.workspaceService.getWorkspaceUserProjectsRole(workspaceSlug);
|
||||
|
||||
runInAction(() => {
|
||||
set(this.workspaceProjectsRole, [workspaceSlug], response);
|
||||
});
|
||||
return response;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
3
web/types/users.d.ts
vendored
3
web/types/users.d.ts
vendored
@ -1,3 +1,4 @@
|
||||
import { EUserProjectRoles } from "constants/project";
|
||||
import { IIssueActivity, IIssueLite, TStateGroups } from ".";
|
||||
|
||||
export interface IUser {
|
||||
@ -162,7 +163,7 @@ export interface IUserProfileProjectSegregation {
|
||||
}
|
||||
|
||||
export interface IUserProjectsRole {
|
||||
[project_id: string]: number;
|
||||
[project_id: string]: EUserProjectRoles;
|
||||
}
|
||||
|
||||
// export interface ICurrentUser {
|
||||
|
Loading…
Reference in New Issue
Block a user