forked from github/plane
fix: store level fixes (#2597)
This commit is contained in:
parent
d46eb9c59a
commit
8c620c4f96
@ -24,19 +24,15 @@ type Props = {
|
|||||||
|
|
||||||
export const EstimateListItem: React.FC<Props> = observer((props) => {
|
export const EstimateListItem: React.FC<Props> = observer((props) => {
|
||||||
const { estimate, editEstimate, deleteEstimate } = props;
|
const { estimate, editEstimate, deleteEstimate } = props;
|
||||||
|
|
||||||
// router
|
// router
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
// store
|
// store
|
||||||
const { project: projectStore } = useMobxStore();
|
const { project: projectStore } = useMobxStore();
|
||||||
|
const { currentProjectDetails } = projectStore;
|
||||||
|
// hooks
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
// derived values
|
|
||||||
const projectDetails = projectStore.project_details?.[projectId?.toString()!];
|
|
||||||
|
|
||||||
const handleUseEstimate = async () => {
|
const handleUseEstimate = async () => {
|
||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
|
|
||||||
@ -63,7 +59,7 @@ export const EstimateListItem: React.FC<Props> = observer((props) => {
|
|||||||
<div>
|
<div>
|
||||||
<h6 className="flex w-[40vw] items-center gap-2 truncate text-sm font-medium">
|
<h6 className="flex w-[40vw] items-center gap-2 truncate text-sm font-medium">
|
||||||
{estimate.name}
|
{estimate.name}
|
||||||
{projectDetails?.estimate && projectDetails?.estimate === estimate.id && (
|
{currentProjectDetails?.estimate && currentProjectDetails?.estimate === estimate.id && (
|
||||||
<span className="rounded bg-green-500/20 px-2 py-0.5 text-xs text-green-500">In use</span>
|
<span className="rounded bg-green-500/20 px-2 py-0.5 text-xs text-green-500">In use</span>
|
||||||
)}
|
)}
|
||||||
</h6>
|
</h6>
|
||||||
@ -72,7 +68,7 @@ export const EstimateListItem: React.FC<Props> = observer((props) => {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
{projectDetails?.estimate !== estimate?.id && estimate?.points?.length > 0 && (
|
{currentProjectDetails?.estimate !== estimate?.id && estimate?.points?.length > 0 && (
|
||||||
<Button variant="neutral-primary" onClick={handleUseEstimate}>
|
<Button variant="neutral-primary" onClick={handleUseEstimate}>
|
||||||
Use
|
Use
|
||||||
</Button>
|
</Button>
|
||||||
@ -88,7 +84,7 @@ export const EstimateListItem: React.FC<Props> = observer((props) => {
|
|||||||
<span>Edit estimate</span>
|
<span>Edit estimate</span>
|
||||||
</div>
|
</div>
|
||||||
</CustomMenu.MenuItem>
|
</CustomMenu.MenuItem>
|
||||||
{projectDetails?.estimate !== estimate.id && (
|
{currentProjectDetails?.estimate !== estimate.id && (
|
||||||
<CustomMenu.MenuItem
|
<CustomMenu.MenuItem
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
deleteEstimate(estimate.id);
|
deleteEstimate(estimate.id);
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
|
||||||
// store
|
// store
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { useMobxStore } from "lib/mobx/store-provider";
|
import { useMobxStore } from "lib/mobx/store-provider";
|
||||||
@ -25,18 +24,15 @@ export const EstimatesList: React.FC = observer(() => {
|
|||||||
|
|
||||||
// store
|
// store
|
||||||
const { project: projectStore } = useMobxStore();
|
const { project: projectStore } = useMobxStore();
|
||||||
|
const { currentProjectDetails } = projectStore;
|
||||||
// states
|
// states
|
||||||
const [estimateFormOpen, setEstimateFormOpen] = useState(false);
|
const [estimateFormOpen, setEstimateFormOpen] = useState(false);
|
||||||
const [estimateToDelete, setEstimateToDelete] = useState<string | null>(null);
|
const [estimateToDelete, setEstimateToDelete] = useState<string | null>(null);
|
||||||
const [estimateToUpdate, setEstimateToUpdate] = useState<IEstimate | undefined>();
|
const [estimateToUpdate, setEstimateToUpdate] = useState<IEstimate | undefined>();
|
||||||
|
|
||||||
// hooks
|
// hooks
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
// derived values
|
// derived values
|
||||||
const estimatesList = projectStore.projectEstimates;
|
const estimatesList = projectStore.projectEstimates;
|
||||||
const projectDetails = projectStore.project_details?.[projectId?.toString()!];
|
|
||||||
|
|
||||||
const editEstimate = (estimate: IEstimate) => {
|
const editEstimate = (estimate: IEstimate) => {
|
||||||
setEstimateFormOpen(true);
|
setEstimateFormOpen(true);
|
||||||
@ -88,7 +84,7 @@ export const EstimatesList: React.FC = observer(() => {
|
|||||||
>
|
>
|
||||||
Add Estimate
|
Add Estimate
|
||||||
</Button>
|
</Button>
|
||||||
{projectDetails?.estimate && (
|
{currentProjectDetails?.estimate && (
|
||||||
<Button variant="neutral-primary" onClick={disableEstimates}>
|
<Button variant="neutral-primary" onClick={disableEstimates}>
|
||||||
Disable Estimates
|
Disable Estimates
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -29,10 +29,10 @@ const moduleViewOptions: { type: "list" | "grid" | "gantt_chart"; icon: any }[]
|
|||||||
export const ModulesListHeader: React.FC = observer(() => {
|
export const ModulesListHeader: React.FC = observer(() => {
|
||||||
// router
|
// router
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
|
// store
|
||||||
const { project: projectStore } = useMobxStore();
|
const { project: projectStore } = useMobxStore();
|
||||||
const projectDetails = projectId ? projectStore.project_details[projectId.toString()] : undefined;
|
const { currentProjectDetails } = projectStore;
|
||||||
|
|
||||||
const { storedValue: modulesView, setValue: setModulesView } = useLocalStorage("modules_view", "grid");
|
const { storedValue: modulesView, setValue: setModulesView } = useLocalStorage("modules_view", "grid");
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ export const ModulesListHeader: React.FC = observer(() => {
|
|||||||
</Link>
|
</Link>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<BreadcrumbItem title={`${truncateText(projectDetails?.name ?? "Project", 32)} Modules`} />
|
<BreadcrumbItem title={`${truncateText(currentProjectDetails?.name ?? "Project", 32)} Modules`} />
|
||||||
</Breadcrumbs>
|
</Breadcrumbs>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -17,10 +17,10 @@ export interface IProjectSettingHeader {
|
|||||||
export const ProjectSettingHeader: FC<IProjectSettingHeader> = observer((props) => {
|
export const ProjectSettingHeader: FC<IProjectSettingHeader> = observer((props) => {
|
||||||
const { title } = props;
|
const { title } = props;
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
// store
|
// store
|
||||||
const { project: projectStore } = useMobxStore();
|
const { project: projectStore } = useMobxStore();
|
||||||
const projectDetails = projectId ? projectStore.project_details[projectId.toString()] : null;
|
const { currentProjectDetails } = projectStore;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@ -31,9 +31,9 @@ export const ProjectSettingHeader: FC<IProjectSettingHeader> = observer((props)
|
|||||||
<Breadcrumbs onBack={() => router.back()}>
|
<Breadcrumbs onBack={() => router.back()}>
|
||||||
<BreadcrumbItem
|
<BreadcrumbItem
|
||||||
link={
|
link={
|
||||||
<Link href={`/${workspaceSlug}/projects/${projectDetails?.id}/issues`}>
|
<Link href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}>
|
||||||
<a className={`border-r-2 border-custom-sidebar-border-200 px-3 text-sm `}>
|
<a className={`border-r-2 border-custom-sidebar-border-200 px-3 text-sm `}>
|
||||||
<p className="truncate">{`${truncateText(projectDetails?.name ?? "Project", 32)}`}</p>
|
<p className="truncate">{`${truncateText(currentProjectDetails?.name ?? "Project", 32)}`}</p>
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,10 @@ import { ISSUE_STATE_GROUPS, ISSUE_PRIORITIES } from "constants/issue";
|
|||||||
export interface ICycleKanBanLayout {}
|
export interface ICycleKanBanLayout {}
|
||||||
|
|
||||||
export const CycleKanBanLayout: React.FC = observer(() => {
|
export const CycleKanBanLayout: React.FC = observer(() => {
|
||||||
|
// router
|
||||||
|
const router = useRouter();
|
||||||
|
const { workspaceSlug, cycleId } = router.query;
|
||||||
|
// store
|
||||||
const {
|
const {
|
||||||
project: projectStore,
|
project: projectStore,
|
||||||
cycleIssue: cycleIssueStore,
|
cycleIssue: cycleIssueStore,
|
||||||
@ -25,9 +29,7 @@ export const CycleKanBanLayout: React.FC = observer(() => {
|
|||||||
cycleIssueKanBanView: cycleIssueKanBanViewStore,
|
cycleIssueKanBanView: cycleIssueKanBanViewStore,
|
||||||
issueDetail: issueDetailStore,
|
issueDetail: issueDetailStore,
|
||||||
} = useMobxStore();
|
} = useMobxStore();
|
||||||
|
const { currentProjectDetails } = projectStore;
|
||||||
const router = useRouter();
|
|
||||||
const { workspaceSlug, projectId, cycleId } = router.query;
|
|
||||||
|
|
||||||
const issues = cycleIssueStore?.getIssues;
|
const issues = cycleIssueStore?.getIssues;
|
||||||
|
|
||||||
@ -83,8 +85,6 @@ export const CycleKanBanLayout: React.FC = observer(() => {
|
|||||||
cycleIssueKanBanViewStore.handleKanBanToggle(toggle, value);
|
cycleIssueKanBanViewStore.handleKanBanToggle(toggle, value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const projectDetails = projectId ? projectStore.project_details[projectId.toString()] : null;
|
|
||||||
|
|
||||||
const states = projectStore?.projectStates || null;
|
const states = projectStore?.projectStates || null;
|
||||||
const priorities = ISSUE_PRIORITIES || null;
|
const priorities = ISSUE_PRIORITIES || null;
|
||||||
const labels = projectStore?.projectLabels || null;
|
const labels = projectStore?.projectLabels || null;
|
||||||
@ -92,8 +92,8 @@ export const CycleKanBanLayout: React.FC = observer(() => {
|
|||||||
const stateGroups = ISSUE_STATE_GROUPS || null;
|
const stateGroups = ISSUE_STATE_GROUPS || null;
|
||||||
const projects = workspaceSlug ? projectStore?.projects[workspaceSlug.toString()] || null : null;
|
const projects = workspaceSlug ? projectStore?.projects[workspaceSlug.toString()] || null : null;
|
||||||
const estimates =
|
const estimates =
|
||||||
projectDetails?.estimate !== null
|
currentProjectDetails?.estimate !== null
|
||||||
? projectStore.projectEstimates?.find((e) => e.id === projectDetails?.estimate) || null
|
? projectStore.projectEstimates?.find((e) => e.id === currentProjectDetails?.estimate) || null
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -18,6 +18,9 @@ import { ISSUE_STATE_GROUPS, ISSUE_PRIORITIES } from "constants/issue";
|
|||||||
export interface IModuleKanBanLayout {}
|
export interface IModuleKanBanLayout {}
|
||||||
|
|
||||||
export const ModuleKanBanLayout: React.FC = observer(() => {
|
export const ModuleKanBanLayout: React.FC = observer(() => {
|
||||||
|
const router = useRouter();
|
||||||
|
const { workspaceSlug, moduleId } = router.query;
|
||||||
|
// store
|
||||||
const {
|
const {
|
||||||
project: projectStore,
|
project: projectStore,
|
||||||
moduleIssue: moduleIssueStore,
|
moduleIssue: moduleIssueStore,
|
||||||
@ -25,9 +28,7 @@ export const ModuleKanBanLayout: React.FC = observer(() => {
|
|||||||
moduleIssueKanBanView: moduleIssueKanBanViewStore,
|
moduleIssueKanBanView: moduleIssueKanBanViewStore,
|
||||||
issueDetail: issueDetailStore,
|
issueDetail: issueDetailStore,
|
||||||
} = useMobxStore();
|
} = useMobxStore();
|
||||||
|
const { currentProjectDetails } = projectStore;
|
||||||
const router = useRouter();
|
|
||||||
const { workspaceSlug, projectId, moduleId } = router.query;
|
|
||||||
|
|
||||||
const issues = moduleIssueStore?.getIssues;
|
const issues = moduleIssueStore?.getIssues;
|
||||||
|
|
||||||
@ -83,8 +84,6 @@ export const ModuleKanBanLayout: React.FC = observer(() => {
|
|||||||
moduleIssueKanBanViewStore.handleKanBanToggle(toggle, value);
|
moduleIssueKanBanViewStore.handleKanBanToggle(toggle, value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const projectDetails = projectId ? projectStore.project_details[projectId.toString()] : null;
|
|
||||||
|
|
||||||
const states = projectStore?.projectStates || null;
|
const states = projectStore?.projectStates || null;
|
||||||
const priorities = ISSUE_PRIORITIES || null;
|
const priorities = ISSUE_PRIORITIES || null;
|
||||||
const labels = projectStore?.projectLabels || null;
|
const labels = projectStore?.projectLabels || null;
|
||||||
@ -92,8 +91,8 @@ export const ModuleKanBanLayout: React.FC = observer(() => {
|
|||||||
const stateGroups = ISSUE_STATE_GROUPS || null;
|
const stateGroups = ISSUE_STATE_GROUPS || null;
|
||||||
const projects = workspaceSlug ? projectStore?.projects[workspaceSlug.toString()] || null : null;
|
const projects = workspaceSlug ? projectStore?.projects[workspaceSlug.toString()] || null : null;
|
||||||
const estimates =
|
const estimates =
|
||||||
projectDetails?.estimate !== null
|
currentProjectDetails?.estimate !== null
|
||||||
? projectStore.projectEstimates?.find((e) => e.id === projectDetails?.estimate) || null
|
? projectStore.projectEstimates?.find((e) => e.id === currentProjectDetails?.estimate) || null
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -19,7 +19,7 @@ export interface IKanBanLayout {}
|
|||||||
|
|
||||||
export const KanBanLayout: React.FC = observer(() => {
|
export const KanBanLayout: React.FC = observer(() => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
project: projectStore,
|
project: projectStore,
|
||||||
@ -28,6 +28,7 @@ export const KanBanLayout: React.FC = observer(() => {
|
|||||||
issueKanBanView: issueKanBanViewStore,
|
issueKanBanView: issueKanBanViewStore,
|
||||||
issueDetail: issueDetailStore,
|
issueDetail: issueDetailStore,
|
||||||
} = useMobxStore();
|
} = useMobxStore();
|
||||||
|
const { currentProjectDetails } = projectStore;
|
||||||
|
|
||||||
const issues = issueStore?.getIssues;
|
const issues = issueStore?.getIssues;
|
||||||
|
|
||||||
@ -74,8 +75,6 @@ export const KanBanLayout: React.FC = observer(() => {
|
|||||||
issueKanBanViewStore.handleKanBanToggle(toggle, value);
|
issueKanBanViewStore.handleKanBanToggle(toggle, value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const projectDetails = projectId ? projectStore.project_details[projectId.toString()] : null;
|
|
||||||
|
|
||||||
const states = projectStore?.projectStates || null;
|
const states = projectStore?.projectStates || null;
|
||||||
const priorities = ISSUE_PRIORITIES || null;
|
const priorities = ISSUE_PRIORITIES || null;
|
||||||
const labels = projectStore?.projectLabels || null;
|
const labels = projectStore?.projectLabels || null;
|
||||||
@ -83,8 +82,8 @@ export const KanBanLayout: React.FC = observer(() => {
|
|||||||
const stateGroups = ISSUE_STATE_GROUPS || null;
|
const stateGroups = ISSUE_STATE_GROUPS || null;
|
||||||
const projects = workspaceSlug ? projectStore?.projects[workspaceSlug.toString()] || null : null;
|
const projects = workspaceSlug ? projectStore?.projects[workspaceSlug.toString()] || null : null;
|
||||||
const estimates =
|
const estimates =
|
||||||
projectDetails?.estimate !== null
|
currentProjectDetails?.estimate !== null
|
||||||
? projectStore.projectEstimates?.find((e) => e.id === projectDetails?.estimate) || null
|
? projectStore.projectEstimates?.find((e) => e.id === currentProjectDetails?.estimate) || null
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -17,14 +17,15 @@ export interface ICycleListLayout {}
|
|||||||
|
|
||||||
export const CycleListLayout: React.FC = observer(() => {
|
export const CycleListLayout: React.FC = observer(() => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId, cycleId } = router.query;
|
const { workspaceSlug, cycleId } = router.query;
|
||||||
|
// store
|
||||||
const {
|
const {
|
||||||
project: projectStore,
|
project: projectStore,
|
||||||
issueFilter: issueFilterStore,
|
issueFilter: issueFilterStore,
|
||||||
cycleIssue: cycleIssueStore,
|
cycleIssue: cycleIssueStore,
|
||||||
issueDetail: issueDetailStore,
|
issueDetail: issueDetailStore,
|
||||||
} = useMobxStore();
|
} = useMobxStore();
|
||||||
|
const { currentProjectDetails } = projectStore;
|
||||||
|
|
||||||
const issues = cycleIssueStore?.getIssues;
|
const issues = cycleIssueStore?.getIssues;
|
||||||
|
|
||||||
@ -54,8 +55,6 @@ export const CycleListLayout: React.FC = observer(() => {
|
|||||||
[cycleIssueStore, issueDetailStore, cycleId, workspaceSlug]
|
[cycleIssueStore, issueDetailStore, cycleId, workspaceSlug]
|
||||||
);
|
);
|
||||||
|
|
||||||
const projectDetails = projectId ? projectStore.project_details[projectId.toString()] : null;
|
|
||||||
|
|
||||||
const states = projectStore?.projectStates || null;
|
const states = projectStore?.projectStates || null;
|
||||||
const priorities = ISSUE_PRIORITIES || null;
|
const priorities = ISSUE_PRIORITIES || null;
|
||||||
const labels = projectStore?.projectLabels || null;
|
const labels = projectStore?.projectLabels || null;
|
||||||
@ -63,8 +62,8 @@ export const CycleListLayout: React.FC = observer(() => {
|
|||||||
const stateGroups = ISSUE_STATE_GROUPS || null;
|
const stateGroups = ISSUE_STATE_GROUPS || null;
|
||||||
const projects = workspaceSlug ? projectStore?.projects[workspaceSlug.toString()] || null : null;
|
const projects = workspaceSlug ? projectStore?.projects[workspaceSlug.toString()] || null : null;
|
||||||
const estimates =
|
const estimates =
|
||||||
projectDetails?.estimate !== null
|
currentProjectDetails?.estimate !== null
|
||||||
? projectStore.projectEstimates?.find((e) => e.id === projectDetails?.estimate) || null
|
? projectStore.projectEstimates?.find((e) => e.id === currentProjectDetails?.estimate) || null
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -17,7 +17,7 @@ export interface IModuleListLayout {}
|
|||||||
|
|
||||||
export const ModuleListLayout: React.FC = observer(() => {
|
export const ModuleListLayout: React.FC = observer(() => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId, moduleId } = router.query;
|
const { workspaceSlug, moduleId } = router.query;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
project: projectStore,
|
project: projectStore,
|
||||||
@ -25,6 +25,7 @@ export const ModuleListLayout: React.FC = observer(() => {
|
|||||||
moduleIssue: moduleIssueStore,
|
moduleIssue: moduleIssueStore,
|
||||||
issueDetail: issueDetailStore,
|
issueDetail: issueDetailStore,
|
||||||
} = useMobxStore();
|
} = useMobxStore();
|
||||||
|
const { currentProjectDetails } = projectStore;
|
||||||
|
|
||||||
const issues = moduleIssueStore?.getIssues;
|
const issues = moduleIssueStore?.getIssues;
|
||||||
|
|
||||||
@ -54,8 +55,6 @@ export const ModuleListLayout: React.FC = observer(() => {
|
|||||||
[moduleIssueStore, issueDetailStore, moduleId, workspaceSlug]
|
[moduleIssueStore, issueDetailStore, moduleId, workspaceSlug]
|
||||||
);
|
);
|
||||||
|
|
||||||
const projectDetails = projectId ? projectStore.project_details[projectId.toString()] : null;
|
|
||||||
|
|
||||||
const states = projectStore?.projectStates || null;
|
const states = projectStore?.projectStates || null;
|
||||||
const priorities = ISSUE_PRIORITIES || null;
|
const priorities = ISSUE_PRIORITIES || null;
|
||||||
const labels = projectStore?.projectLabels || null;
|
const labels = projectStore?.projectLabels || null;
|
||||||
@ -63,8 +62,8 @@ export const ModuleListLayout: React.FC = observer(() => {
|
|||||||
const stateGroups = ISSUE_STATE_GROUPS || null;
|
const stateGroups = ISSUE_STATE_GROUPS || null;
|
||||||
const projects = workspaceSlug ? projectStore?.projects[workspaceSlug.toString()] || null : null;
|
const projects = workspaceSlug ? projectStore?.projects[workspaceSlug.toString()] || null : null;
|
||||||
const estimates =
|
const estimates =
|
||||||
projectDetails?.estimate !== null
|
currentProjectDetails?.estimate !== null
|
||||||
? projectStore.projectEstimates?.find((e) => e.id === projectDetails?.estimate) || null
|
? projectStore.projectEstimates?.find((e) => e.id === currentProjectDetails?.estimate) || null
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -15,14 +15,15 @@ import { ISSUE_STATE_GROUPS, ISSUE_PRIORITIES } from "constants/issue";
|
|||||||
|
|
||||||
export const ListLayout: FC = observer(() => {
|
export const ListLayout: FC = observer(() => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
|
// store
|
||||||
const {
|
const {
|
||||||
project: projectStore,
|
project: projectStore,
|
||||||
issue: issueStore,
|
issue: issueStore,
|
||||||
issueDetail: issueDetailStore,
|
issueDetail: issueDetailStore,
|
||||||
issueFilter: issueFilterStore,
|
issueFilter: issueFilterStore,
|
||||||
} = useMobxStore();
|
} = useMobxStore();
|
||||||
|
const { currentProjectDetails } = projectStore;
|
||||||
|
|
||||||
const issues = issueStore?.getIssues;
|
const issues = issueStore?.getIssues;
|
||||||
|
|
||||||
@ -43,8 +44,6 @@ export const ListLayout: FC = observer(() => {
|
|||||||
[issueStore, issueDetailStore, workspaceSlug]
|
[issueStore, issueDetailStore, workspaceSlug]
|
||||||
);
|
);
|
||||||
|
|
||||||
const projectDetails = projectId ? projectStore.project_details[projectId.toString()] : null;
|
|
||||||
|
|
||||||
const states = projectStore?.projectStates || null;
|
const states = projectStore?.projectStates || null;
|
||||||
const priorities = ISSUE_PRIORITIES || null;
|
const priorities = ISSUE_PRIORITIES || null;
|
||||||
const labels = projectStore?.projectLabels || null;
|
const labels = projectStore?.projectLabels || null;
|
||||||
@ -52,8 +51,8 @@ export const ListLayout: FC = observer(() => {
|
|||||||
const stateGroups = ISSUE_STATE_GROUPS || null;
|
const stateGroups = ISSUE_STATE_GROUPS || null;
|
||||||
const projects = workspaceSlug ? projectStore?.projects[workspaceSlug.toString()] || null : null;
|
const projects = workspaceSlug ? projectStore?.projects[workspaceSlug.toString()] || null : null;
|
||||||
const estimates =
|
const estimates =
|
||||||
projectDetails?.estimate !== null
|
currentProjectDetails?.estimate !== null
|
||||||
? projectStore.projectEstimates?.find((e) => e.id === projectDetails?.estimate) || null
|
? projectStore.projectEstimates?.find((e) => e.id === currentProjectDetails?.estimate) || null
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -31,7 +31,8 @@ export const PeekOverviewIssueDetails: FC<IPeekOverviewIssueDetails> = (props) =
|
|||||||
const { workspaceSlug, issue, issueReactions, user, issueUpdate, issueReactionCreate, issueReactionRemove } = props;
|
const { workspaceSlug, issue, issueReactions, user, issueUpdate, issueReactionCreate, issueReactionRemove } = props;
|
||||||
// store
|
// store
|
||||||
const { user: userStore } = useMobxStore();
|
const { user: userStore } = useMobxStore();
|
||||||
const isAllowed = [5, 10].includes(userStore.projectMemberInfo?.role || 0);
|
const { currentProjectRole } = userStore;
|
||||||
|
const isAllowed = [5, 10].includes(currentProjectRole || 0);
|
||||||
// states
|
// states
|
||||||
const [isSubmitting, setIsSubmitting] = useState<"submitting" | "submitted" | "saved">("saved");
|
const [isSubmitting, setIsSubmitting] = useState<"submitting" | "submitted" | "saved">("saved");
|
||||||
const [characterLimit, setCharacterLimit] = useState(false);
|
const [characterLimit, setCharacterLimit] = useState(false);
|
||||||
|
@ -9,12 +9,12 @@ import { ModuleGanttBlock, ModuleGanttSidebarBlock } from "components/modules";
|
|||||||
import { IModule } from "types";
|
import { IModule } from "types";
|
||||||
|
|
||||||
export const ModulesListGanttChartView: React.FC = observer(() => {
|
export const ModulesListGanttChartView: React.FC = observer(() => {
|
||||||
|
// router
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
|
// store
|
||||||
const { project: projectStore, module: moduleStore } = useMobxStore();
|
const { project: projectStore, module: moduleStore } = useMobxStore();
|
||||||
|
const { currentProjectDetails } = projectStore;
|
||||||
const projectDetails = projectId ? projectStore.project_details[projectId.toString()] : undefined;
|
|
||||||
const modules = moduleStore.projectModules;
|
const modules = moduleStore.projectModules;
|
||||||
|
|
||||||
const handleModuleUpdate = (module: IModule, payload: IBlockUpdateData) => {
|
const handleModuleUpdate = (module: IModule, payload: IBlockUpdateData) => {
|
||||||
@ -36,7 +36,7 @@ export const ModulesListGanttChartView: React.FC = observer(() => {
|
|||||||
}))
|
}))
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
const isAllowed = projectDetails?.member_role === 20 || projectDetails?.member_role === 15;
|
const isAllowed = currentProjectDetails?.member_role === 20 || currentProjectDetails?.member_role === 15;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full h-full overflow-y-auto">
|
<div className="w-full h-full overflow-y-auto">
|
||||||
|
@ -26,32 +26,28 @@ type Props = {
|
|||||||
|
|
||||||
export const ProjectMemberListItem: React.FC<Props> = observer((props) => {
|
export const ProjectMemberListItem: React.FC<Props> = observer((props) => {
|
||||||
const { member } = props;
|
const { member } = props;
|
||||||
|
|
||||||
// router
|
// router
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
// states
|
// states
|
||||||
const [selectedRemoveMember, setSelectedRemoveMember] = useState<any | null>(null);
|
const [selectedRemoveMember, setSelectedRemoveMember] = useState<any | null>(null);
|
||||||
const [selectedInviteRemoveMember, setSelectedInviteRemoveMember] = useState<any | null>(null);
|
const [selectedInviteRemoveMember, setSelectedInviteRemoveMember] = useState<any | null>(null);
|
||||||
|
|
||||||
// store
|
// store
|
||||||
const { user: userStore, project: projectStore } = useMobxStore();
|
const { user: userStore, project: projectStore } = useMobxStore();
|
||||||
|
// hooks
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
// fetching project members
|
||||||
useSWR(
|
useSWR(
|
||||||
workspaceSlug && projectId ? `PROJECT_MEMBERS_${projectId.toString().toUpperCase()}` : null,
|
workspaceSlug && projectId ? `PROJECT_MEMBERS_${projectId.toString().toUpperCase()}` : null,
|
||||||
workspaceSlug && projectId
|
workspaceSlug && projectId
|
||||||
? () => projectStore.fetchProjectMembers(workspaceSlug.toString(), projectId.toString())
|
? () => projectStore.fetchProjectMembers(workspaceSlug.toString(), projectId.toString())
|
||||||
: null
|
: null
|
||||||
);
|
);
|
||||||
|
|
||||||
// derived values
|
// derived values
|
||||||
const user = userStore.currentUser;
|
const user = userStore.currentUser;
|
||||||
const memberDetails = userStore.projectMemberInfo;
|
const { currentProjectRole } = userStore;
|
||||||
const isAdmin = memberDetails?.role === 20;
|
const isAdmin = currentProjectRole === 20;
|
||||||
const isOwner = memberDetails?.role === 20;
|
const isOwner = currentProjectRole === 20;
|
||||||
const projectMembers = projectStore.members?.[projectId?.toString()!];
|
const projectMembers = projectStore.members?.[projectId?.toString()!];
|
||||||
const currentUser = projectMembers?.find((item) => item.member.id === user?.id);
|
const currentUser = projectMembers?.find((item) => item.member.id === user?.id);
|
||||||
|
|
||||||
|
@ -25,20 +25,16 @@ export const ProjectSettingsMemberDefaults: React.FC = observer(() => {
|
|||||||
// router
|
// router
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
// store
|
// store
|
||||||
const { user: userStore, project: projectStore } = useMobxStore();
|
const { user: userStore, project: projectStore } = useMobxStore();
|
||||||
|
const { currentProjectDetails } = projectStore;
|
||||||
|
const { currentProjectRole } = userStore;
|
||||||
|
const isAdmin = currentProjectRole === 20;
|
||||||
// hooks
|
// hooks
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
// form info
|
||||||
// derived values
|
|
||||||
const memberDetails = userStore.projectMemberInfo;
|
|
||||||
const isAdmin = memberDetails?.role === 20;
|
|
||||||
const projectDetails = projectStore.project_details[projectId?.toString()!];
|
|
||||||
|
|
||||||
const { reset, control } = useForm<IProject>({ defaultValues });
|
const { reset, control } = useForm<IProject>({ defaultValues });
|
||||||
|
// fetching user members
|
||||||
useSWR(
|
useSWR(
|
||||||
workspaceSlug && projectId ? PROJECT_MEMBERS(projectId.toString()) : null,
|
workspaceSlug && projectId ? PROJECT_MEMBERS(projectId.toString()) : null,
|
||||||
workspaceSlug && projectId
|
workspaceSlug && projectId
|
||||||
@ -47,23 +43,23 @@ export const ProjectSettingsMemberDefaults: React.FC = observer(() => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!projectDetails) return;
|
if (!currentProjectDetails) return;
|
||||||
|
|
||||||
reset({
|
reset({
|
||||||
...projectDetails,
|
...currentProjectDetails,
|
||||||
default_assignee: projectDetails.default_assignee?.id ?? projectDetails.default_assignee,
|
default_assignee: currentProjectDetails.default_assignee?.id ?? currentProjectDetails.default_assignee,
|
||||||
project_lead: (projectDetails.project_lead as IUserLite)?.id ?? projectDetails.project_lead,
|
project_lead: (currentProjectDetails.project_lead as IUserLite)?.id ?? currentProjectDetails.project_lead,
|
||||||
workspace: (projectDetails.workspace as IWorkspace).id,
|
workspace: (currentProjectDetails.workspace as IWorkspace).id,
|
||||||
});
|
});
|
||||||
}, [projectDetails, reset]);
|
}, [currentProjectDetails, reset]);
|
||||||
|
|
||||||
const submitChanges = async (formData: Partial<IProject>) => {
|
const submitChanges = async (formData: Partial<IProject>) => {
|
||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
|
|
||||||
reset({
|
reset({
|
||||||
...projectDetails,
|
...currentProjectDetails,
|
||||||
default_assignee: projectDetails.default_assignee?.id ?? projectDetails.default_assignee,
|
default_assignee: currentProjectDetails?.default_assignee?.id ?? currentProjectDetails?.default_assignee,
|
||||||
project_lead: (projectDetails.project_lead as IUserLite)?.id ?? projectDetails.project_lead,
|
project_lead: (currentProjectDetails?.project_lead as IUserLite)?.id ?? currentProjectDetails?.project_lead,
|
||||||
...formData,
|
...formData,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -96,7 +92,7 @@ export const ProjectSettingsMemberDefaults: React.FC = observer(() => {
|
|||||||
<div className="flex flex-col gap-2 w-1/2">
|
<div className="flex flex-col gap-2 w-1/2">
|
||||||
<h4 className="text-sm">Project Lead</h4>
|
<h4 className="text-sm">Project Lead</h4>
|
||||||
<div className="">
|
<div className="">
|
||||||
{projectDetails ? (
|
{currentProjectDetails ? (
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="project_lead"
|
name="project_lead"
|
||||||
@ -121,7 +117,7 @@ export const ProjectSettingsMemberDefaults: React.FC = observer(() => {
|
|||||||
<div className="flex flex-col gap-2 w-1/2">
|
<div className="flex flex-col gap-2 w-1/2">
|
||||||
<h4 className="text-sm">Default Assignee</h4>
|
<h4 className="text-sm">Default Assignee</h4>
|
||||||
<div className="">
|
<div className="">
|
||||||
{projectDetails ? (
|
{currentProjectDetails ? (
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="default_assignee"
|
name="default_assignee"
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { FC } from "react";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { ContrastIcon, FileText, Inbox, Layers } from "lucide-react";
|
import { ContrastIcon, FileText, Inbox, Layers } from "lucide-react";
|
||||||
@ -18,7 +19,6 @@ const PROJECT_FEATURES_LIST = [
|
|||||||
title: "Cycles",
|
title: "Cycles",
|
||||||
description: "Cycles are enabled for all the projects in this workspace. Access them from the sidebar.",
|
description: "Cycles are enabled for all the projects in this workspace. Access them from the sidebar.",
|
||||||
icon: <ContrastIcon className="h-4 w-4 text-purple-500 flex-shrink-0 rotate-180" />,
|
icon: <ContrastIcon className="h-4 w-4 text-purple-500 flex-shrink-0 rotate-180" />,
|
||||||
|
|
||||||
property: "cycle_view",
|
property: "cycle_view",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -67,32 +67,30 @@ const getEventType = (feature: string, toggle: boolean): MiscellaneousEventType
|
|||||||
// services
|
// services
|
||||||
const trackEventService = new TrackEventService();
|
const trackEventService = new TrackEventService();
|
||||||
|
|
||||||
export const ProjectFeaturesList: React.FC<Props> = observer((props) => {
|
export const ProjectFeaturesList: FC<Props> = observer(() => {
|
||||||
const {} = props;
|
// router
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
// store
|
||||||
const { project: projectStore, user: userStore } = useMobxStore();
|
const { project: projectStore, user: userStore } = useMobxStore();
|
||||||
|
const { currentUser, currentProjectRole } = userStore;
|
||||||
const projectDetails = projectId ? projectStore.project_details[projectId.toString()] : undefined;
|
const { currentProjectDetails } = projectStore;
|
||||||
const user = userStore.currentUser ?? undefined;
|
const isAdmin = currentProjectRole === 20;
|
||||||
const isAdmin = userStore.projectMemberInfo?.role === 20;
|
// hooks
|
||||||
|
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
const handleSubmit = async (formData: Partial<IProject>) => {
|
const handleSubmit = async (formData: Partial<IProject>) => {
|
||||||
if (!workspaceSlug || !projectId || !projectDetails) return;
|
if (!workspaceSlug || !projectId || !currentProjectDetails) return;
|
||||||
|
|
||||||
setToastAlert({
|
setToastAlert({
|
||||||
type: "success",
|
type: "success",
|
||||||
title: "Success!",
|
title: "Success!",
|
||||||
message: "Project feature updated successfully.",
|
message: "Project feature updated successfully.",
|
||||||
});
|
});
|
||||||
|
|
||||||
projectStore.updateProject(workspaceSlug.toString(), projectId.toString(), formData);
|
projectStore.updateProject(workspaceSlug.toString(), projectId.toString(), formData);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!currentUser) return <></>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{PROJECT_FEATURES_LIST.map((feature) => (
|
{PROJECT_FEATURES_LIST.map((feature) => (
|
||||||
@ -108,21 +106,21 @@ export const ProjectFeaturesList: React.FC<Props> = observer((props) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ToggleSwitch
|
<ToggleSwitch
|
||||||
value={projectDetails?.[feature.property as keyof IProject]}
|
value={currentProjectDetails?.[feature.property as keyof IProject]}
|
||||||
onChange={() => {
|
onChange={() => {
|
||||||
trackEventService.trackMiscellaneousEvent(
|
trackEventService.trackMiscellaneousEvent(
|
||||||
{
|
{
|
||||||
workspaceId: (projectDetails?.workspace as any)?.id,
|
workspaceId: (currentProjectDetails?.workspace as any)?.id,
|
||||||
workspaceSlug,
|
workspaceSlug,
|
||||||
projectId,
|
projectId,
|
||||||
projectIdentifier: projectDetails?.identifier,
|
projectIdentifier: currentProjectDetails?.identifier,
|
||||||
projectName: projectDetails?.name,
|
projectName: currentProjectDetails?.name,
|
||||||
},
|
},
|
||||||
getEventType(feature.title, !projectDetails?.[feature.property as keyof IProject]),
|
getEventType(feature.title, !currentProjectDetails?.[feature.property as keyof IProject]),
|
||||||
user
|
currentUser
|
||||||
);
|
);
|
||||||
handleSubmit({
|
handleSubmit({
|
||||||
[feature.property]: !projectDetails?.[feature.property as keyof IProject],
|
[feature.property]: !currentProjectDetails?.[feature.property as keyof IProject],
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
disabled={!isAdmin}
|
disabled={!isAdmin}
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
|
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
|
|
||||||
// store
|
// store
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { useMobxStore } from "lib/mobx/store-provider";
|
import { useMobxStore } from "lib/mobx/store-provider";
|
||||||
@ -22,10 +19,9 @@ export const ProjectSettingStateList: React.FC = observer(() => {
|
|||||||
// router
|
// router
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
// store
|
// store
|
||||||
const { project: projectStore } = useMobxStore();
|
const { project: projectStore } = useMobxStore();
|
||||||
|
const { currentProjectDetails } = projectStore;
|
||||||
// state
|
// state
|
||||||
const [activeGroup, setActiveGroup] = useState<StateGroup>(null);
|
const [activeGroup, setActiveGroup] = useState<StateGroup>(null);
|
||||||
const [selectedState, setSelectedState] = useState<string | null>(null);
|
const [selectedState, setSelectedState] = useState<string | null>(null);
|
||||||
@ -47,7 +43,6 @@ export const ProjectSettingStateList: React.FC = observer(() => {
|
|||||||
|
|
||||||
// derived values
|
// derived values
|
||||||
const states = projectStore.projectStatesByGroups;
|
const states = projectStore.projectStatesByGroups;
|
||||||
const projectDetails = projectStore.project_details[projectId?.toString()!] ?? null;
|
|
||||||
const orderedStateGroups = orderStateGroups(states!);
|
const orderedStateGroups = orderStateGroups(states!);
|
||||||
const statesList = getStatesList(orderedStateGroups);
|
const statesList = getStatesList(orderedStateGroups);
|
||||||
|
|
||||||
@ -60,7 +55,7 @@ export const ProjectSettingStateList: React.FC = observer(() => {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="space-y-8 py-6">
|
<div className="space-y-8 py-6">
|
||||||
{states && projectDetails && orderedStateGroups ? (
|
{states && currentProjectDetails && orderedStateGroups ? (
|
||||||
Object.keys(orderedStateGroups || {}).map((key) => {
|
Object.keys(orderedStateGroups || {}).map((key) => {
|
||||||
if (orderedStateGroups[key].length !== 0)
|
if (orderedStateGroups[key].length !== 0)
|
||||||
return (
|
return (
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useState } from "react";
|
import { useState, FC } from "react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
// mobx store
|
// mobx store
|
||||||
@ -35,20 +35,19 @@ type Props = {
|
|||||||
// services
|
// services
|
||||||
const workspaceService = new WorkspaceService();
|
const workspaceService = new WorkspaceService();
|
||||||
|
|
||||||
export const WorkspaceMembersListItem: React.FC<Props> = (props) => {
|
export const WorkspaceMembersListItem: FC<Props> = (props) => {
|
||||||
const { member } = props;
|
const { member } = props;
|
||||||
|
// router
|
||||||
const [removeMemberModal, setRemoveMemberModal] = useState(false);
|
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
|
// store
|
||||||
const { setToastAlert } = useToast();
|
|
||||||
|
|
||||||
const { workspace: workspaceStore, user: userStore } = useMobxStore();
|
const { workspace: workspaceStore, user: userStore } = useMobxStore();
|
||||||
|
const { currentWorkspaceMemberInfo, currentWorkspaceRole } = userStore;
|
||||||
const user = userStore.workspaceMemberInfo;
|
const isAdmin = currentWorkspaceRole === 20;
|
||||||
const isAdmin = userStore.workspaceMemberInfo?.role === 20;
|
// states
|
||||||
|
const [removeMemberModal, setRemoveMemberModal] = useState(false);
|
||||||
|
// hooks
|
||||||
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
const handleRemoveMember = async () => {
|
const handleRemoveMember = async () => {
|
||||||
if (!workspaceSlug) return;
|
if (!workspaceSlug) return;
|
||||||
@ -83,7 +82,7 @@ export const WorkspaceMembersListItem: React.FC<Props> = (props) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!user) return null;
|
if (!currentWorkspaceMemberInfo) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -141,12 +140,12 @@ export const WorkspaceMembersListItem: React.FC<Props> = (props) => {
|
|||||||
<div className="flex item-center gap-1 px-2 py-0.5 rounded">
|
<div className="flex item-center gap-1 px-2 py-0.5 rounded">
|
||||||
<span
|
<span
|
||||||
className={`flex items-center text-xs font-medium rounded ${
|
className={`flex items-center text-xs font-medium rounded ${
|
||||||
member.memberId !== user.member ? "" : "text-custom-sidebar-text-400"
|
member.memberId !== currentWorkspaceMemberInfo.member ? "" : "text-custom-sidebar-text-400"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{ROLE[member.role as keyof typeof ROLE]}
|
{ROLE[member.role as keyof typeof ROLE]}
|
||||||
</span>
|
</span>
|
||||||
{member.memberId !== user.member && (
|
{member.memberId !== currentWorkspaceMemberInfo.member && (
|
||||||
<span className="grid place-items-center">
|
<span className="grid place-items-center">
|
||||||
<ChevronDown className="h-3 w-3" />
|
<ChevronDown className="h-3 w-3" />
|
||||||
</span>
|
</span>
|
||||||
@ -155,7 +154,7 @@ export const WorkspaceMembersListItem: React.FC<Props> = (props) => {
|
|||||||
}
|
}
|
||||||
value={member.role}
|
value={member.role}
|
||||||
onChange={(value: 5 | 10 | 15 | 20 | undefined) => {
|
onChange={(value: 5 | 10 | 15 | 20 | undefined) => {
|
||||||
if (!workspaceSlug) return;
|
if (!workspaceSlug || !value) return;
|
||||||
|
|
||||||
workspaceStore
|
workspaceStore
|
||||||
.updateMember(workspaceSlug.toString(), member.id, {
|
.updateMember(workspaceSlug.toString(), member.id, {
|
||||||
@ -170,12 +169,15 @@ export const WorkspaceMembersListItem: React.FC<Props> = (props) => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
disabled={
|
disabled={
|
||||||
member.memberId === user.member || !member.status || (user.role !== 20 && user.role < member.role)
|
member.memberId === currentWorkspaceMemberInfo.member ||
|
||||||
|
!member.status ||
|
||||||
|
Boolean(currentWorkspaceRole && currentWorkspaceRole !== 20 && currentWorkspaceRole < member.role)
|
||||||
}
|
}
|
||||||
placement="bottom-end"
|
placement="bottom-end"
|
||||||
>
|
>
|
||||||
{Object.keys(ROLE).map((key) => {
|
{Object.keys(ROLE).map((key) => {
|
||||||
if (user.role !== 20 && user.role < parseInt(key)) return null;
|
if (currentWorkspaceRole && currentWorkspaceRole !== 20 && currentWorkspaceRole < parseInt(key))
|
||||||
|
return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CustomSelect.Option key={key} value={parseInt(key, 10)}>
|
<CustomSelect.Option key={key} value={parseInt(key, 10)}>
|
||||||
@ -185,7 +187,11 @@ export const WorkspaceMembersListItem: React.FC<Props> = (props) => {
|
|||||||
})}
|
})}
|
||||||
</CustomSelect>
|
</CustomSelect>
|
||||||
{isAdmin && (
|
{isAdmin && (
|
||||||
<Tooltip tooltipContent={member.memberId === user.member ? "Leave workspace" : "Remove member"}>
|
<Tooltip
|
||||||
|
tooltipContent={
|
||||||
|
member.memberId === currentWorkspaceMemberInfo.member ? "Leave workspace" : "Remove member"
|
||||||
|
}
|
||||||
|
>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setRemoveMemberModal(true)}
|
onClick={() => setRemoveMemberModal(true)}
|
||||||
|
@ -15,12 +15,11 @@ const workspaceService = new WorkspaceService();
|
|||||||
export const WorkspaceMembersList: React.FC = observer(() => {
|
export const WorkspaceMembersList: React.FC = observer(() => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
|
// store
|
||||||
const { workspace: workspaceStore, user: userStore } = useMobxStore();
|
const { workspace: workspaceStore, user: userStore } = useMobxStore();
|
||||||
|
|
||||||
const workspaceMembers = workspaceStore.workspaceMembers;
|
const workspaceMembers = workspaceStore.workspaceMembers;
|
||||||
const user = userStore.workspaceMemberInfo;
|
const user = userStore.currentWorkspaceMemberInfo;
|
||||||
|
// fetching workspace invitations
|
||||||
const { data: workspaceInvitations } = useSWR(
|
const { data: workspaceInvitations } = useSWR(
|
||||||
workspaceSlug ? `WORKSPACE_INVITATIONS_${workspaceSlug.toString()}` : null,
|
workspaceSlug ? `WORKSPACE_INVITATIONS_${workspaceSlug.toString()}` : null,
|
||||||
workspaceSlug ? () => workspaceService.workspaceInvitations(workspaceSlug.toString()) : null
|
workspaceSlug ? () => workspaceService.workspaceInvitations(workspaceSlug.toString()) : null
|
||||||
|
@ -30,16 +30,20 @@ const defaultValues: Partial<IWorkspace> = {
|
|||||||
const fileService = new FileService();
|
const fileService = new FileService();
|
||||||
|
|
||||||
export const WorkspaceDetails: React.FC = observer(() => {
|
export const WorkspaceDetails: React.FC = observer(() => {
|
||||||
|
// states
|
||||||
const [deleteWorkspaceModal, setDeleteWorkspaceModal] = useState(false);
|
const [deleteWorkspaceModal, setDeleteWorkspaceModal] = useState(false);
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
const [isImageUploading, setIsImageUploading] = useState(false);
|
const [isImageUploading, setIsImageUploading] = useState(false);
|
||||||
const [isImageRemoving, setIsImageRemoving] = useState(false);
|
const [isImageRemoving, setIsImageRemoving] = useState(false);
|
||||||
const [isImageUploadModalOpen, setIsImageUploadModalOpen] = useState(false);
|
const [isImageUploadModalOpen, setIsImageUploadModalOpen] = useState(false);
|
||||||
|
// store
|
||||||
const { workspace: workspaceStore, user: userStore } = useMobxStore();
|
const { workspace: workspaceStore, user: userStore } = useMobxStore();
|
||||||
const activeWorkspace = workspaceStore.currentWorkspace;
|
const activeWorkspace = workspaceStore.currentWorkspace;
|
||||||
|
const { currentWorkspaceRole } = userStore;
|
||||||
|
const isAdmin = currentWorkspaceRole === 20;
|
||||||
|
// hooks
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
// form info
|
||||||
const {
|
const {
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
control,
|
control,
|
||||||
@ -103,8 +107,6 @@ export const WorkspaceDetails: React.FC = observer(() => {
|
|||||||
if (activeWorkspace) reset({ ...activeWorkspace });
|
if (activeWorkspace) reset({ ...activeWorkspace });
|
||||||
}, [activeWorkspace, reset]);
|
}, [activeWorkspace, reset]);
|
||||||
|
|
||||||
const isAdmin = userStore.workspaceMemberInfo?.role === 20;
|
|
||||||
|
|
||||||
if (!activeWorkspace)
|
if (!activeWorkspace)
|
||||||
return (
|
return (
|
||||||
<div className="grid place-items-center h-full w-full px-4 sm:px-0">
|
<div className="grid place-items-center h-full w-full px-4 sm:px-0">
|
||||||
|
@ -16,6 +16,7 @@ export const WorkspaceAuthWrapper: FC<IWorkspaceAuthWrapper> = observer((props)
|
|||||||
const { children } = props;
|
const { children } = props;
|
||||||
// store
|
// store
|
||||||
const { user: userStore, project: projectStore, workspace: workspaceStore } = useMobxStore();
|
const { user: userStore, project: projectStore, workspace: workspaceStore } = useMobxStore();
|
||||||
|
const { currentWorkspaceMemberInfo, hasPermissionToCurrentWorkspace } = userStore;
|
||||||
// router
|
// router
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
@ -43,11 +44,7 @@ export const WorkspaceAuthWrapper: FC<IWorkspaceAuthWrapper> = observer((props)
|
|||||||
);
|
);
|
||||||
|
|
||||||
// while data is being loaded
|
// while data is being loaded
|
||||||
if (
|
if (!currentWorkspaceMemberInfo && hasPermissionToCurrentWorkspace === undefined) {
|
||||||
!userStore.workspaceMemberInfo &&
|
|
||||||
workspaceSlug &&
|
|
||||||
userStore.hasPermissionToWorkspace[workspaceSlug.toString()] === null
|
|
||||||
) {
|
|
||||||
return (
|
return (
|
||||||
<div className="grid h-screen place-items-center p-4 bg-custom-background-100">
|
<div className="grid h-screen place-items-center p-4 bg-custom-background-100">
|
||||||
<div className="flex flex-col items-center gap-3 text-center">
|
<div className="flex flex-col items-center gap-3 text-center">
|
||||||
@ -57,11 +54,7 @@ export const WorkspaceAuthWrapper: FC<IWorkspaceAuthWrapper> = observer((props)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
// while user does not have access to view that workspace
|
// while user does not have access to view that workspace
|
||||||
if (
|
if (hasPermissionToCurrentWorkspace !== undefined && hasPermissionToCurrentWorkspace === false) {
|
||||||
userStore.hasPermissionToWorkspace !== null &&
|
|
||||||
workspaceSlug &&
|
|
||||||
userStore.hasPermissionToWorkspace[workspaceSlug.toString()] === false
|
|
||||||
) {
|
|
||||||
return (
|
return (
|
||||||
<div className={`h-screen w-full overflow-hidden bg-custom-background-100`}>
|
<div className={`h-screen w-full overflow-hidden bg-custom-background-100`}>
|
||||||
<div className="grid h-full place-items-center p-4">
|
<div className="grid h-full place-items-center p-4">
|
||||||
|
@ -27,6 +27,7 @@ const ProjectCyclesPage: NextPage = observer(() => {
|
|||||||
const [createModal, setCreateModal] = useState(false);
|
const [createModal, setCreateModal] = useState(false);
|
||||||
// store
|
// store
|
||||||
const { project: projectStore, cycle: cycleStore } = useMobxStore();
|
const { project: projectStore, cycle: cycleStore } = useMobxStore();
|
||||||
|
const { currentProjectDetails } = projectStore;
|
||||||
// router
|
// router
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId, peekCycle } = router.query as {
|
const { workspaceSlug, projectId, peekCycle } = router.query as {
|
||||||
@ -78,19 +79,18 @@ const ProjectCyclesPage: NextPage = observer(() => {
|
|||||||
}
|
}
|
||||||
}, [projectId, cycleStore, handleCurrentView, handleCurrentLayout]);
|
}, [projectId, cycleStore, handleCurrentView, handleCurrentLayout]);
|
||||||
|
|
||||||
const projectDetails = projectId ? projectStore.project_details[projectId] : null;
|
|
||||||
const cycleView = cycleStore?.cycleView;
|
const cycleView = cycleStore?.cycleView;
|
||||||
const cycleLayout = cycleStore?.cycleLayout;
|
const cycleLayout = cycleStore?.cycleLayout;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout header={<CyclesHeader name={projectDetails?.name} />} withProjectWrapper>
|
<AppLayout header={<CyclesHeader name={currentProjectDetails?.name} />} withProjectWrapper>
|
||||||
<CycleCreateUpdateModal
|
<CycleCreateUpdateModal
|
||||||
workspaceSlug={workspaceSlug}
|
workspaceSlug={workspaceSlug}
|
||||||
projectId={projectId}
|
projectId={projectId}
|
||||||
isOpen={createModal}
|
isOpen={createModal}
|
||||||
handleClose={() => setCreateModal(false)}
|
handleClose={() => setCreateModal(false)}
|
||||||
/>
|
/>
|
||||||
{projectDetails?.total_cycles === 0 ? (
|
{currentProjectDetails?.total_cycles === 0 ? (
|
||||||
<div className="h-full grid place-items-center">
|
<div className="h-full grid place-items-center">
|
||||||
<EmptyState
|
<EmptyState
|
||||||
title="Plan your project with cycles"
|
title="Plan your project with cycles"
|
||||||
|
@ -20,14 +20,14 @@ import { useMobxStore } from "lib/mobx/store-provider";
|
|||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
|
|
||||||
const GeneralSettings: NextPage = observer(() => {
|
const GeneralSettings: NextPage = observer(() => {
|
||||||
|
// store
|
||||||
const { project: projectStore } = useMobxStore();
|
const { project: projectStore } = useMobxStore();
|
||||||
|
const { currentProjectDetails } = projectStore;
|
||||||
// states
|
// states
|
||||||
const [selectProject, setSelectedProject] = useState<string | null>(null);
|
const [selectProject, setSelectedProject] = useState<string | null>(null);
|
||||||
// router
|
// router
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
// derived values
|
|
||||||
const projectDetails = projectId ? projectStore.project_details[projectId.toString()] : null;
|
|
||||||
// api call to fetch project details
|
// api call to fetch project details
|
||||||
useSWR(
|
useSWR(
|
||||||
workspaceSlug && projectId ? "PROJECT_DETAILS" : null,
|
workspaceSlug && projectId ? "PROJECT_DETAILS" : null,
|
||||||
@ -39,30 +39,34 @@ const GeneralSettings: NextPage = observer(() => {
|
|||||||
// const currentNetwork = NETWORK_CHOICES.find((n) => n.key === projectDetails?.network);
|
// const currentNetwork = NETWORK_CHOICES.find((n) => n.key === projectDetails?.network);
|
||||||
// const selectedNetwork = NETWORK_CHOICES.find((n) => n.key === watch("network"));
|
// const selectedNetwork = NETWORK_CHOICES.find((n) => n.key === watch("network"));
|
||||||
|
|
||||||
const isAdmin = projectDetails?.member_role === 20;
|
const isAdmin = currentProjectDetails?.member_role === 20;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout header={<ProjectSettingHeader title="General Settings" />} withProjectWrapper>
|
<AppLayout header={<ProjectSettingHeader title="General Settings" />} withProjectWrapper>
|
||||||
<ProjectSettingLayout>
|
<ProjectSettingLayout>
|
||||||
{projectDetails && (
|
{currentProjectDetails && (
|
||||||
<DeleteProjectModal
|
<DeleteProjectModal
|
||||||
project={projectDetails}
|
project={currentProjectDetails}
|
||||||
isOpen={Boolean(selectProject)}
|
isOpen={Boolean(selectProject)}
|
||||||
onClose={() => setSelectedProject(null)}
|
onClose={() => setSelectedProject(null)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className={`pr-9 py-8 w-full overflow-y-auto ${isAdmin ? "" : "opacity-60"}`}>
|
<div className={`pr-9 py-8 w-full overflow-y-auto ${isAdmin ? "" : "opacity-60"}`}>
|
||||||
{projectDetails && workspaceSlug ? (
|
{currentProjectDetails && workspaceSlug ? (
|
||||||
<ProjectDetailsForm project={projectDetails} workspaceSlug={workspaceSlug.toString()} isAdmin={isAdmin} />
|
<ProjectDetailsForm
|
||||||
|
project={currentProjectDetails}
|
||||||
|
workspaceSlug={workspaceSlug.toString()}
|
||||||
|
isAdmin={isAdmin}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
<ProjectDetailsFormLoader />
|
<ProjectDetailsFormLoader />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{isAdmin && (
|
{isAdmin && (
|
||||||
<DeleteProjectSection
|
<DeleteProjectSection
|
||||||
projectDetails={projectDetails}
|
projectDetails={currentProjectDetails}
|
||||||
handleDelete={() => setSelectedProject(projectDetails.id ?? null)}
|
handleDelete={() => setSelectedProject(currentProjectDetails.id ?? null)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -41,6 +41,8 @@ export interface IProjectStore {
|
|||||||
joinedProjects: IProject[];
|
joinedProjects: IProject[];
|
||||||
favoriteProjects: IProject[];
|
favoriteProjects: IProject[];
|
||||||
|
|
||||||
|
currentProjectDetails: IProject | undefined;
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
setProjectId: (projectId: string) => void;
|
setProjectId: (projectId: string) => void;
|
||||||
setSearchQuery: (query: string) => void;
|
setSearchQuery: (query: string) => void;
|
||||||
@ -137,6 +139,8 @@ export class ProjectStore implements IProjectStore {
|
|||||||
projectMembers: computed,
|
projectMembers: computed,
|
||||||
projectEstimates: computed,
|
projectEstimates: computed,
|
||||||
|
|
||||||
|
currentProjectDetails: computed,
|
||||||
|
|
||||||
joinedProjects: computed,
|
joinedProjects: computed,
|
||||||
favoriteProjects: computed,
|
favoriteProjects: computed,
|
||||||
|
|
||||||
@ -198,6 +202,11 @@ export class ProjectStore implements IProjectStore {
|
|||||||
return this.projects?.[this.rootStore.workspace.workspaceSlug];
|
return this.projects?.[this.rootStore.workspace.workspaceSlug];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get currentProjectDetails() {
|
||||||
|
if (!this.projectId) return;
|
||||||
|
return this.project_details[this.projectId];
|
||||||
|
}
|
||||||
|
|
||||||
get joinedProjects() {
|
get joinedProjects() {
|
||||||
if (!this.rootStore.workspace.workspaceSlug) return [];
|
if (!this.rootStore.workspace.workspaceSlug) return [];
|
||||||
return this.projects?.[this.rootStore.workspace.workspaceSlug]?.filter((p) => p.is_member);
|
return this.projects?.[this.rootStore.workspace.workspaceSlug]?.filter((p) => p.is_member);
|
||||||
|
@ -98,10 +98,7 @@ import {
|
|||||||
InboxStore,
|
InboxStore,
|
||||||
} from "store/inbox";
|
} from "store/inbox";
|
||||||
|
|
||||||
import {
|
import { IMentionsStore, MentionsStore } from "store/editor";
|
||||||
IMentionsStore,
|
|
||||||
MentionsStore
|
|
||||||
} from "store/editor"
|
|
||||||
|
|
||||||
enableStaticRendering(typeof window === "undefined");
|
enableStaticRendering(typeof window === "undefined");
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// mobx
|
// mobx
|
||||||
import { action, observable, runInAction, makeObservable } from "mobx";
|
import { action, observable, runInAction, makeObservable, computed } from "mobx";
|
||||||
// services
|
// services
|
||||||
import { ProjectService } from "services/project";
|
import { ProjectService } from "services/project";
|
||||||
import { UserService } from "services/user.service";
|
import { UserService } from "services/user.service";
|
||||||
@ -7,6 +7,7 @@ import { WorkspaceService } from "services/workspace.service";
|
|||||||
// interfaces
|
// interfaces
|
||||||
import { IUser, IUserSettings } from "types/users";
|
import { IUser, IUserSettings } from "types/users";
|
||||||
import { IWorkspaceMemberMe, IProjectMember } from "types";
|
import { IWorkspaceMemberMe, IProjectMember } from "types";
|
||||||
|
import { RootStore } from "./root";
|
||||||
|
|
||||||
export interface IUserStore {
|
export interface IUserStore {
|
||||||
loader: boolean;
|
loader: boolean;
|
||||||
@ -17,16 +18,28 @@ export interface IUserStore {
|
|||||||
|
|
||||||
dashboardInfo: any;
|
dashboardInfo: any;
|
||||||
|
|
||||||
workspaceMemberInfo: IWorkspaceMemberMe | null;
|
workspaceMemberInfo: {
|
||||||
|
[workspaceSlug: string]: IWorkspaceMemberMe;
|
||||||
|
};
|
||||||
hasPermissionToWorkspace: {
|
hasPermissionToWorkspace: {
|
||||||
[workspaceSlug: string]: boolean | null;
|
[workspaceSlug: string]: boolean | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
projectMemberInfo: IProjectMember | null;
|
projectMemberInfo: {
|
||||||
|
[projectId: string]: IProjectMember;
|
||||||
|
};
|
||||||
hasPermissionToProject: {
|
hasPermissionToProject: {
|
||||||
[projectId: string]: boolean | null;
|
[projectId: string]: boolean | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
currentProjectMemberInfo: IProjectMember | undefined;
|
||||||
|
currentWorkspaceMemberInfo: IWorkspaceMemberMe | undefined;
|
||||||
|
currentProjectRole: number | undefined;
|
||||||
|
currentWorkspaceRole: number | undefined;
|
||||||
|
|
||||||
|
hasPermissionToCurrentWorkspace: boolean | undefined;
|
||||||
|
hasPermissionToCurrentProject: boolean | undefined;
|
||||||
|
|
||||||
fetchCurrentUser: () => Promise<IUser>;
|
fetchCurrentUser: () => Promise<IUser>;
|
||||||
fetchCurrentUserSettings: () => Promise<IUserSettings>;
|
fetchCurrentUserSettings: () => Promise<IUserSettings>;
|
||||||
|
|
||||||
@ -48,14 +61,18 @@ class UserStore implements IUserStore {
|
|||||||
|
|
||||||
dashboardInfo: any = null;
|
dashboardInfo: any = null;
|
||||||
|
|
||||||
workspaceMemberInfo: IWorkspaceMemberMe | null = null;
|
workspaceMemberInfo: {
|
||||||
|
[workspaceSlug: string]: IWorkspaceMemberMe;
|
||||||
|
} = {};
|
||||||
hasPermissionToWorkspace: {
|
hasPermissionToWorkspace: {
|
||||||
[workspaceSlug: string]: boolean | null;
|
[workspaceSlug: string]: boolean;
|
||||||
} = {};
|
} = {};
|
||||||
|
|
||||||
projectMemberInfo: IProjectMember | null = null;
|
projectMemberInfo: {
|
||||||
|
[projectId: string]: IProjectMember;
|
||||||
|
} = {};
|
||||||
hasPermissionToProject: {
|
hasPermissionToProject: {
|
||||||
[projectId: string]: boolean | null;
|
[projectId: string]: boolean;
|
||||||
} = {};
|
} = {};
|
||||||
// root store
|
// root store
|
||||||
rootStore;
|
rootStore;
|
||||||
@ -64,7 +81,7 @@ class UserStore implements IUserStore {
|
|||||||
workspaceService;
|
workspaceService;
|
||||||
projectService;
|
projectService;
|
||||||
|
|
||||||
constructor(_rootStore: any) {
|
constructor(_rootStore: RootStore) {
|
||||||
makeObservable(this, {
|
makeObservable(this, {
|
||||||
// observable
|
// observable
|
||||||
loader: observable.ref,
|
loader: observable.ref,
|
||||||
@ -78,7 +95,19 @@ class UserStore implements IUserStore {
|
|||||||
// action
|
// action
|
||||||
fetchCurrentUser: action,
|
fetchCurrentUser: action,
|
||||||
fetchCurrentUserSettings: action,
|
fetchCurrentUserSettings: action,
|
||||||
|
fetchUserDashboardInfo: action,
|
||||||
|
fetchUserWorkspaceInfo: action,
|
||||||
|
fetchUserProjectInfo: action,
|
||||||
|
updateTourCompleted: action,
|
||||||
|
updateCurrentUser: action,
|
||||||
|
updateCurrentUserTheme: action,
|
||||||
// computed
|
// computed
|
||||||
|
currentProjectMemberInfo: computed,
|
||||||
|
currentWorkspaceMemberInfo: computed,
|
||||||
|
currentProjectRole: computed,
|
||||||
|
currentWorkspaceRole: computed,
|
||||||
|
hasPermissionToCurrentWorkspace: computed,
|
||||||
|
hasPermissionToCurrentProject: computed,
|
||||||
});
|
});
|
||||||
this.rootStore = _rootStore;
|
this.rootStore = _rootStore;
|
||||||
this.userService = new UserService();
|
this.userService = new UserService();
|
||||||
@ -86,6 +115,36 @@ class UserStore implements IUserStore {
|
|||||||
this.projectService = new ProjectService();
|
this.projectService = new ProjectService();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get currentWorkspaceMemberInfo() {
|
||||||
|
if (!this.rootStore.workspace.workspaceSlug) return;
|
||||||
|
return this.workspaceMemberInfo[this.rootStore.workspace.workspaceSlug];
|
||||||
|
}
|
||||||
|
|
||||||
|
get currentWorkspaceRole() {
|
||||||
|
if (!this.rootStore.workspace.workspaceSlug) return;
|
||||||
|
return this.workspaceMemberInfo[this.rootStore.workspace.workspaceSlug].role;
|
||||||
|
}
|
||||||
|
|
||||||
|
get currentProjectMemberInfo() {
|
||||||
|
if (!this.rootStore.project.projectId) return;
|
||||||
|
return this.projectMemberInfo[this.rootStore.project.projectId];
|
||||||
|
}
|
||||||
|
|
||||||
|
get currentProjectRole() {
|
||||||
|
if (!this.rootStore.project.projectId) return;
|
||||||
|
return this.projectMemberInfo[this.rootStore.project.projectId].role;
|
||||||
|
}
|
||||||
|
|
||||||
|
get hasPermissionToCurrentWorkspace() {
|
||||||
|
if (!this.rootStore.workspace.workspaceSlug) return;
|
||||||
|
return this.hasPermissionToWorkspace[this.rootStore.workspace.workspaceSlug];
|
||||||
|
}
|
||||||
|
|
||||||
|
get hasPermissionToCurrentProject() {
|
||||||
|
if (!this.rootStore.project.projectId) return;
|
||||||
|
return this.hasPermissionToProject[this.rootStore.project.projectId];
|
||||||
|
}
|
||||||
|
|
||||||
fetchCurrentUser = async () => {
|
fetchCurrentUser = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await this.userService.currentUser();
|
const response = await this.userService.currentUser();
|
||||||
@ -132,10 +191,13 @@ class UserStore implements IUserStore {
|
|||||||
|
|
||||||
fetchUserWorkspaceInfo = async (workspaceSlug: string) => {
|
fetchUserWorkspaceInfo = async (workspaceSlug: string) => {
|
||||||
try {
|
try {
|
||||||
const response = await this.workspaceService.workspaceMemberMe(workspaceSlug.toString());
|
const response = await this.workspaceService.workspaceMemberMe(workspaceSlug);
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.workspaceMemberInfo = response;
|
this.workspaceMemberInfo = {
|
||||||
|
...this.workspaceMemberInfo,
|
||||||
|
[workspaceSlug]: response,
|
||||||
|
};
|
||||||
this.hasPermissionToWorkspace = {
|
this.hasPermissionToWorkspace = {
|
||||||
...this.hasPermissionToWorkspace,
|
...this.hasPermissionToWorkspace,
|
||||||
[workspaceSlug]: true,
|
[workspaceSlug]: true,
|
||||||
@ -158,7 +220,10 @@ class UserStore implements IUserStore {
|
|||||||
const response = await this.projectService.projectMemberMe(workspaceSlug, projectId);
|
const response = await this.projectService.projectMemberMe(workspaceSlug, projectId);
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.projectMemberInfo = response;
|
this.projectMemberInfo = {
|
||||||
|
...this.projectMemberInfo,
|
||||||
|
[projectId]: response,
|
||||||
|
};
|
||||||
this.hasPermissionToProject = {
|
this.hasPermissionToProject = {
|
||||||
...this.hasPermissionToProject,
|
...this.hasPermissionToProject,
|
||||||
[projectId]: true,
|
[projectId]: true,
|
||||||
|
Loading…
Reference in New Issue
Block a user