forked from github/plane
refactor: project estimates store (#2801)
* refactor: remove estimates from project store * chore: update all the instances of the old store * chore: update store declaration structure
This commit is contained in:
parent
9a704458b3
commit
29f3e02adc
@ -42,7 +42,9 @@ export const CreateUpdateEstimateModal: React.FC<Props> = observer((props) => {
|
|||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
// store
|
// store
|
||||||
const { projectEstimates: projectEstimatesStore } = useMobxStore();
|
const {
|
||||||
|
projectEstimates: { createEstimate, updateEstimate },
|
||||||
|
} = useMobxStore();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
formState: { errors, isSubmitting },
|
formState: { errors, isSubmitting },
|
||||||
@ -60,11 +62,10 @@ export const CreateUpdateEstimateModal: React.FC<Props> = observer((props) => {
|
|||||||
|
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
const createEstimate = async (payload: IEstimateFormData) => {
|
const handleCreateEstimate = async (payload: IEstimateFormData) => {
|
||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
|
|
||||||
await projectEstimatesStore
|
await createEstimate(workspaceSlug.toString(), projectId.toString(), payload)
|
||||||
.createEstimate(workspaceSlug.toString(), projectId.toString(), payload)
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
onClose();
|
onClose();
|
||||||
})
|
})
|
||||||
@ -83,13 +84,12 @@ export const CreateUpdateEstimateModal: React.FC<Props> = observer((props) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateEstimate = async (payload: IEstimateFormData) => {
|
const handleUpdateEstimate = async (payload: IEstimateFormData) => {
|
||||||
if (!workspaceSlug || !projectId || !data) return;
|
if (!workspaceSlug || !projectId || !data) return;
|
||||||
|
|
||||||
await projectEstimatesStore
|
await updateEstimate(workspaceSlug.toString(), projectId.toString(), data.id, payload)
|
||||||
.updateEstimate(workspaceSlug.toString(), projectId.toString(), data.id, payload)
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
handleClose();
|
onClose();
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
const error = err?.error;
|
const error = err?.error;
|
||||||
@ -101,8 +101,6 @@ export const CreateUpdateEstimateModal: React.FC<Props> = observer((props) => {
|
|||||||
message: errorString ?? "Estimate could not be updated. Please try again.",
|
message: errorString ?? "Estimate could not be updated. Please try again.",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
onClose();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSubmit = async (formData: FormValues) => {
|
const onSubmit = async (formData: FormValues) => {
|
||||||
@ -171,8 +169,8 @@ export const CreateUpdateEstimateModal: React.FC<Props> = observer((props) => {
|
|||||||
else payload.estimate_points.push({ ...point });
|
else payload.estimate_points.push({ ...point });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data) await updateEstimate(payload);
|
if (data) await handleUpdateEstimate(payload);
|
||||||
else await createEstimate(payload);
|
else await handleCreateEstimate(payload);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -28,28 +28,27 @@ export const EstimateListItem: React.FC<Props> = observer((props) => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
// store
|
// store
|
||||||
const { project: projectStore } = useMobxStore();
|
const {
|
||||||
const { currentProjectDetails } = projectStore;
|
project: { currentProjectDetails, updateProject },
|
||||||
|
} = useMobxStore();
|
||||||
// hooks
|
// hooks
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
const handleUseEstimate = async () => {
|
const handleUseEstimate = async () => {
|
||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
|
|
||||||
await projectStore
|
await updateProject(workspaceSlug.toString(), projectId.toString(), {
|
||||||
.updateProject(workspaceSlug.toString(), projectId.toString(), {
|
estimate: estimate.id,
|
||||||
estimate: estimate.id,
|
}).catch((err) => {
|
||||||
})
|
const error = err?.error;
|
||||||
.catch((err) => {
|
const errorString = Array.isArray(error) ? error[0] : error;
|
||||||
const error = err?.error;
|
|
||||||
const errorString = Array.isArray(error) ? error[0] : error;
|
|
||||||
|
|
||||||
setToastAlert({
|
setToastAlert({
|
||||||
type: "error",
|
type: "error",
|
||||||
title: "Error!",
|
title: "Error!",
|
||||||
message: errorString ?? "Estimate points could not be used. Please try again.",
|
message: errorString ?? "Estimate points could not be used. Please try again.",
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -69,7 +68,7 @@ export const EstimateListItem: React.FC<Props> = observer((props) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
{currentProjectDetails?.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} size="sm">
|
||||||
Use
|
Use
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
@ -23,8 +23,10 @@ export const EstimatesList: React.FC = observer(() => {
|
|||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
// store
|
// store
|
||||||
const { project: projectStore } = useMobxStore();
|
const {
|
||||||
const { currentProjectDetails } = projectStore;
|
project: { currentProjectDetails, updateProject },
|
||||||
|
projectEstimates: { projectEstimates, getProjectEstimateById },
|
||||||
|
} = useMobxStore();
|
||||||
// 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);
|
||||||
@ -32,7 +34,7 @@ export const EstimatesList: React.FC = observer(() => {
|
|||||||
// hooks
|
// hooks
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
// derived values
|
// derived values
|
||||||
const estimatesList = projectStore.projectEstimates;
|
const estimatesList = projectEstimates;
|
||||||
|
|
||||||
const editEstimate = (estimate: IEstimate) => {
|
const editEstimate = (estimate: IEstimate) => {
|
||||||
setEstimateFormOpen(true);
|
setEstimateFormOpen(true);
|
||||||
@ -42,7 +44,7 @@ export const EstimatesList: React.FC = observer(() => {
|
|||||||
const disableEstimates = () => {
|
const disableEstimates = () => {
|
||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
|
|
||||||
projectStore.updateProject(workspaceSlug.toString(), projectId.toString(), { estimate: null }).catch((err) => {
|
updateProject(workspaceSlug.toString(), projectId.toString(), { estimate: null }).catch((err) => {
|
||||||
const error = err?.error;
|
const error = err?.error;
|
||||||
const errorString = Array.isArray(error) ? error[0] : error;
|
const errorString = Array.isArray(error) ? error[0] : error;
|
||||||
|
|
||||||
@ -68,7 +70,7 @@ export const EstimatesList: React.FC = observer(() => {
|
|||||||
<DeleteEstimateModal
|
<DeleteEstimateModal
|
||||||
isOpen={!!estimateToDelete}
|
isOpen={!!estimateToDelete}
|
||||||
handleClose={() => setEstimateToDelete(null)}
|
handleClose={() => setEstimateToDelete(null)}
|
||||||
data={projectStore.getProjectEstimateById(estimateToDelete!)}
|
data={getProjectEstimateById(estimateToDelete!)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<section className="flex items-center justify-between py-3.5 border-b border-custom-border-100">
|
<section className="flex items-center justify-between py-3.5 border-b border-custom-border-100">
|
||||||
@ -81,11 +83,12 @@ export const EstimatesList: React.FC = observer(() => {
|
|||||||
setEstimateFormOpen(true);
|
setEstimateFormOpen(true);
|
||||||
setEstimateToUpdate(undefined);
|
setEstimateToUpdate(undefined);
|
||||||
}}
|
}}
|
||||||
|
size="sm"
|
||||||
>
|
>
|
||||||
Add Estimate
|
Add Estimate
|
||||||
</Button>
|
</Button>
|
||||||
{currentProjectDetails?.estimate && (
|
{currentProjectDetails?.estimate && (
|
||||||
<Button variant="neutral-primary" onClick={disableEstimates}>
|
<Button variant="neutral-primary" onClick={disableEstimates} size="sm">
|
||||||
Disable Estimates
|
Disable Estimates
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
@ -1,4 +1,5 @@
|
|||||||
export * from "./create-update-estimate-modal";
|
export * from "./create-update-estimate-modal";
|
||||||
export * from "./delete-estimate-modal";
|
export * from "./delete-estimate-modal";
|
||||||
export * from "./estimate-select";
|
|
||||||
export * from "./estimate-list-item";
|
export * from "./estimate-list-item";
|
||||||
|
export * from "./estimate-select";
|
||||||
|
export * from "./estimates-list";
|
||||||
|
@ -22,6 +22,7 @@ export const ArchivedIssueListLayout: FC = observer(() => {
|
|||||||
projectLabel: { projectLabels },
|
projectLabel: { projectLabels },
|
||||||
projectMember: { projectMembers },
|
projectMember: { projectMembers },
|
||||||
projectState: projectStateStore,
|
projectState: projectStateStore,
|
||||||
|
projectEstimates: { projectEstimates },
|
||||||
archivedIssues: archivedIssueStore,
|
archivedIssues: archivedIssueStore,
|
||||||
archivedIssueFilters: archivedIssueFiltersStore,
|
archivedIssueFilters: archivedIssueFiltersStore,
|
||||||
} = useMobxStore();
|
} = useMobxStore();
|
||||||
@ -48,9 +49,7 @@ export const ArchivedIssueListLayout: 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
|
projectDetails?.estimate !== null ? projectEstimates?.find((e) => e.id === projectDetails?.estimate) || null : null;
|
||||||
? projectStore.projectEstimates?.find((e) => e.id === projectDetails?.estimate) || null
|
|
||||||
: null;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative w-full h-full bg-custom-background-90">
|
<div className="relative w-full h-full bg-custom-background-90">
|
||||||
|
@ -24,6 +24,7 @@ export const CycleListLayout: React.FC = observer(() => {
|
|||||||
projectLabel: { projectLabels },
|
projectLabel: { projectLabels },
|
||||||
projectMember: { projectMembers },
|
projectMember: { projectMembers },
|
||||||
projectState: projectStateStore,
|
projectState: projectStateStore,
|
||||||
|
projectEstimates: { projectEstimates },
|
||||||
issueFilter: issueFilterStore,
|
issueFilter: issueFilterStore,
|
||||||
cycleIssue: cycleIssueStore,
|
cycleIssue: cycleIssueStore,
|
||||||
issueDetail: issueDetailStore,
|
issueDetail: issueDetailStore,
|
||||||
@ -64,7 +65,7 @@ export const CycleListLayout: React.FC = observer(() => {
|
|||||||
const projects = workspaceSlug ? projectStore?.projects[workspaceSlug.toString()] || null : null;
|
const projects = workspaceSlug ? projectStore?.projects[workspaceSlug.toString()] || null : null;
|
||||||
const estimates =
|
const estimates =
|
||||||
currentProjectDetails?.estimate !== null
|
currentProjectDetails?.estimate !== null
|
||||||
? projectStore.projectEstimates?.find((e) => e.id === currentProjectDetails?.estimate) || null
|
? projectEstimates?.find((e) => e.id === currentProjectDetails?.estimate) || null
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -24,6 +24,7 @@ export const ModuleListLayout: React.FC = observer(() => {
|
|||||||
projectLabel: { projectLabels },
|
projectLabel: { projectLabels },
|
||||||
projectMember: { projectMembers },
|
projectMember: { projectMembers },
|
||||||
projectState: projectStateStore,
|
projectState: projectStateStore,
|
||||||
|
projectEstimates: { projectEstimates },
|
||||||
issueFilter: issueFilterStore,
|
issueFilter: issueFilterStore,
|
||||||
moduleIssue: moduleIssueStore,
|
moduleIssue: moduleIssueStore,
|
||||||
issueDetail: issueDetailStore,
|
issueDetail: issueDetailStore,
|
||||||
@ -64,7 +65,7 @@ export const ModuleListLayout: React.FC = observer(() => {
|
|||||||
const projects = workspaceSlug ? projectStore?.projects[workspaceSlug.toString()] || null : null;
|
const projects = workspaceSlug ? projectStore?.projects[workspaceSlug.toString()] || null : null;
|
||||||
const estimates =
|
const estimates =
|
||||||
currentProjectDetails?.estimate !== null
|
currentProjectDetails?.estimate !== null
|
||||||
? projectStore.projectEstimates?.find((e) => e.id === currentProjectDetails?.estimate) || null
|
? projectEstimates?.find((e) => e.id === currentProjectDetails?.estimate) || null
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -23,6 +23,7 @@ export const ListLayout: FC = observer(() => {
|
|||||||
projectLabel: { projectLabels },
|
projectLabel: { projectLabels },
|
||||||
projectMember: { projectMembers },
|
projectMember: { projectMembers },
|
||||||
projectState: projectStateStore,
|
projectState: projectStateStore,
|
||||||
|
projectEstimates: { projectEstimates },
|
||||||
issue: issueStore,
|
issue: issueStore,
|
||||||
issueDetail: issueDetailStore,
|
issueDetail: issueDetailStore,
|
||||||
issueFilter: issueFilterStore,
|
issueFilter: issueFilterStore,
|
||||||
@ -54,7 +55,7 @@ export const ListLayout: FC = observer(() => {
|
|||||||
const projects = workspaceSlug ? projectStore?.projects[workspaceSlug.toString()] || null : null;
|
const projects = workspaceSlug ? projectStore?.projects[workspaceSlug.toString()] || null : null;
|
||||||
const estimates =
|
const estimates =
|
||||||
currentProjectDetails?.estimate !== null
|
currentProjectDetails?.estimate !== null
|
||||||
? projectStore.projectEstimates?.find((e) => e.id === currentProjectDetails?.estimate) || null
|
? projectEstimates?.find((e) => e.id === currentProjectDetails?.estimate) || null
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -52,11 +52,14 @@ export const IssuePropertyEstimates: React.FC<IIssuePropertyEstimates> = observe
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const { project: projectStore } = useMobxStore();
|
const {
|
||||||
|
project: { project_details },
|
||||||
|
projectEstimates: { projectEstimates },
|
||||||
|
} = useMobxStore();
|
||||||
|
|
||||||
const projectDetails = projectId ? projectStore.project_details[projectId] : null;
|
const projectDetails = projectId ? project_details[projectId] : null;
|
||||||
const isEstimateEnabled = projectDetails?.estimate !== null;
|
const isEstimateEnabled = projectDetails?.estimate !== null;
|
||||||
const estimates = projectId ? projectStore.estimates?.[projectId] : null;
|
const estimates = projectEstimates;
|
||||||
const estimatePoints =
|
const estimatePoints =
|
||||||
projectDetails && isEstimateEnabled ? estimates?.find((e) => e.id === projectDetails.estimate)?.points : null;
|
projectDetails && isEstimateEnabled ? estimates?.find((e) => e.id === projectDetails.estimate)?.points : null;
|
||||||
|
|
||||||
|
@ -20,10 +20,11 @@ export const ProjectAuthWrapper: FC<IProjectAuthWrapper> = observer((props) => {
|
|||||||
// store
|
// store
|
||||||
const {
|
const {
|
||||||
user: { fetchUserProjectInfo, projectMemberInfo, hasPermissionToProject },
|
user: { fetchUserProjectInfo, projectMemberInfo, hasPermissionToProject },
|
||||||
project: { fetchProjectDetails, fetchProjectEstimates, workspaceProjects },
|
project: { fetchProjectDetails, workspaceProjects },
|
||||||
projectLabel: { fetchProjectLabels },
|
projectLabel: { fetchProjectLabels },
|
||||||
projectMember: { fetchProjectMembers },
|
projectMember: { fetchProjectMembers },
|
||||||
projectState: { fetchProjectStates },
|
projectState: { fetchProjectStates },
|
||||||
|
projectEstimates: { fetchProjectEstimates },
|
||||||
cycle: { fetchCycles },
|
cycle: { fetchCycles },
|
||||||
module: { fetchModules },
|
module: { fetchModules },
|
||||||
projectViews: { fetchAllViews },
|
projectViews: { fetchAllViews },
|
||||||
|
@ -4,7 +4,7 @@ import { AppLayout } from "layouts/app-layout";
|
|||||||
import { ProjectSettingLayout } from "layouts/settings-layout";
|
import { ProjectSettingLayout } from "layouts/settings-layout";
|
||||||
// components
|
// components
|
||||||
import { ProjectSettingHeader } from "components/headers";
|
import { ProjectSettingHeader } from "components/headers";
|
||||||
import { EstimatesList } from "components/estimates/estimate-list";
|
import { EstimatesList } from "components/estimates";
|
||||||
// types
|
// types
|
||||||
import { NextPageWithLayout } from "types/app";
|
import { NextPageWithLayout } from "types/app";
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { observable, action, makeObservable, runInAction } from "mobx";
|
import { observable, action, makeObservable, runInAction, computed } from "mobx";
|
||||||
// types
|
// types
|
||||||
import { RootStore } from "../root";
|
import { RootStore } from "../root";
|
||||||
import { IEstimate, IEstimateFormData } from "types";
|
import { IEstimate, IEstimateFormData } from "types";
|
||||||
@ -9,7 +9,14 @@ export interface IProjectEstimateStore {
|
|||||||
loader: boolean;
|
loader: boolean;
|
||||||
error: any | null;
|
error: any | null;
|
||||||
|
|
||||||
// estimates
|
// observables
|
||||||
|
estimates: {
|
||||||
|
[projectId: string]: IEstimate[] | null; // project_id: members
|
||||||
|
} | null;
|
||||||
|
|
||||||
|
// actions
|
||||||
|
getProjectEstimateById: (estimateId: string) => IEstimate | null;
|
||||||
|
fetchProjectEstimates: (workspaceSlug: string, projectId: string) => Promise<void>;
|
||||||
createEstimate: (workspaceSlug: string, projectId: string, data: IEstimateFormData) => Promise<IEstimate>;
|
createEstimate: (workspaceSlug: string, projectId: string, data: IEstimateFormData) => Promise<IEstimate>;
|
||||||
updateEstimate: (
|
updateEstimate: (
|
||||||
workspaceSlug: string,
|
workspaceSlug: string,
|
||||||
@ -18,14 +25,23 @@ export interface IProjectEstimateStore {
|
|||||||
data: IEstimateFormData
|
data: IEstimateFormData
|
||||||
) => Promise<IEstimate>;
|
) => Promise<IEstimate>;
|
||||||
deleteEstimate: (workspaceSlug: string, projectId: string, estimateId: string) => Promise<void>;
|
deleteEstimate: (workspaceSlug: string, projectId: string, estimateId: string) => Promise<void>;
|
||||||
|
|
||||||
|
// computed
|
||||||
|
projectEstimates: IEstimate[] | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ProjectEstimatesStore implements IProjectEstimateStore {
|
export class ProjectEstimatesStore implements IProjectEstimateStore {
|
||||||
loader: boolean = false;
|
loader: boolean = false;
|
||||||
error: any | null = null;
|
error: any | null = null;
|
||||||
|
|
||||||
|
// observables
|
||||||
|
estimates: {
|
||||||
|
[projectId: string]: IEstimate[]; // projectId: estimates
|
||||||
|
} | null = {};
|
||||||
|
|
||||||
// root store
|
// root store
|
||||||
rootStore;
|
rootStore;
|
||||||
|
|
||||||
// service
|
// service
|
||||||
projectService;
|
projectService;
|
||||||
estimateService;
|
estimateService;
|
||||||
@ -36,10 +52,17 @@ export class ProjectEstimatesStore implements IProjectEstimateStore {
|
|||||||
loader: observable,
|
loader: observable,
|
||||||
error: observable,
|
error: observable,
|
||||||
|
|
||||||
// estimates
|
estimates: observable.ref,
|
||||||
|
|
||||||
|
// actions
|
||||||
|
getProjectEstimateById: action,
|
||||||
|
fetchProjectEstimates: action,
|
||||||
createEstimate: action,
|
createEstimate: action,
|
||||||
updateEstimate: action,
|
updateEstimate: action,
|
||||||
deleteEstimate: action,
|
deleteEstimate: action,
|
||||||
|
|
||||||
|
// computed
|
||||||
|
projectEstimates: computed,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.rootStore = _rootStore;
|
this.rootStore = _rootStore;
|
||||||
@ -47,6 +70,43 @@ export class ProjectEstimatesStore implements IProjectEstimateStore {
|
|||||||
this.estimateService = new ProjectEstimateService();
|
this.estimateService = new ProjectEstimateService();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get projectEstimates() {
|
||||||
|
const projectId = this.rootStore.project.projectId;
|
||||||
|
|
||||||
|
if (!projectId) return undefined;
|
||||||
|
return this.estimates?.[projectId] || undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
getProjectEstimateById = (estimateId: string) => {
|
||||||
|
const estimates = this.projectEstimates;
|
||||||
|
if (!estimates) return null;
|
||||||
|
const estimateInfo: IEstimate | null = estimates.find((estimate) => estimate.id === estimateId) || null;
|
||||||
|
return estimateInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchProjectEstimates = async (workspaceSlug: string, projectId: string) => {
|
||||||
|
try {
|
||||||
|
this.loader = true;
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
const estimatesResponse = await this.estimateService.getEstimatesList(workspaceSlug, projectId);
|
||||||
|
const _estimates = {
|
||||||
|
...this.estimates,
|
||||||
|
[projectId]: estimatesResponse,
|
||||||
|
};
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.estimates = _estimates;
|
||||||
|
this.loader = false;
|
||||||
|
this.error = null;
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
this.loader = false;
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
createEstimate = async (workspaceSlug: string, projectId: string, data: IEstimateFormData) => {
|
createEstimate = async (workspaceSlug: string, projectId: string, data: IEstimateFormData) => {
|
||||||
try {
|
try {
|
||||||
const response = await this.estimateService.createEstimate(workspaceSlug, projectId, data);
|
const response = await this.estimateService.createEstimate(workspaceSlug, projectId, data);
|
||||||
@ -57,9 +117,9 @@ export class ProjectEstimatesStore implements IProjectEstimateStore {
|
|||||||
};
|
};
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.rootStore.project.estimates = {
|
this.estimates = {
|
||||||
...this.rootStore.project.estimates,
|
...this.estimates,
|
||||||
[projectId]: [responseEstimate, ...(this.rootStore.project.estimates?.[projectId] || [])],
|
[projectId]: [responseEstimate, ...(this.estimates?.[projectId] || [])],
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -71,12 +131,12 @@ export class ProjectEstimatesStore implements IProjectEstimateStore {
|
|||||||
};
|
};
|
||||||
|
|
||||||
updateEstimate = async (workspaceSlug: string, projectId: string, estimateId: string, data: IEstimateFormData) => {
|
updateEstimate = async (workspaceSlug: string, projectId: string, estimateId: string, data: IEstimateFormData) => {
|
||||||
const originalEstimates = this.rootStore.project.getProjectEstimateById(estimateId);
|
const originalEstimates = this.getProjectEstimateById(estimateId);
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.rootStore.project.estimates = {
|
this.estimates = {
|
||||||
...this.rootStore.project.estimates,
|
...this.estimates,
|
||||||
[projectId]: (this.rootStore.project.estimates?.[projectId] || [])?.map((estimate) =>
|
[projectId]: (this.estimates?.[projectId] || [])?.map((estimate) =>
|
||||||
estimate.id === estimateId ? { ...estimate, ...data.estimate } : estimate
|
estimate.id === estimateId ? { ...estimate, ...data.estimate } : estimate
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
@ -84,15 +144,15 @@ export class ProjectEstimatesStore implements IProjectEstimateStore {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await this.estimateService.patchEstimate(workspaceSlug, projectId, estimateId, data);
|
const response = await this.estimateService.patchEstimate(workspaceSlug, projectId, estimateId, data);
|
||||||
await this.rootStore.project.fetchProjectEstimates(workspaceSlug, projectId);
|
await this.fetchProjectEstimates(workspaceSlug, projectId);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Failed to update estimate from project store");
|
console.log("Failed to update estimate from project store");
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.rootStore.project.estimates = {
|
this.estimates = {
|
||||||
...this.rootStore.project.estimates,
|
...this.estimates,
|
||||||
[projectId]: (this.rootStore.project.estimates?.[projectId] || [])?.map((estimate) =>
|
[projectId]: (this.estimates?.[projectId] || [])?.map((estimate) =>
|
||||||
estimate.id === estimateId ? { ...estimate, ...originalEstimates } : estimate
|
estimate.id === estimateId ? { ...estimate, ...originalEstimates } : estimate
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
@ -102,14 +162,12 @@ export class ProjectEstimatesStore implements IProjectEstimateStore {
|
|||||||
};
|
};
|
||||||
|
|
||||||
deleteEstimate = async (workspaceSlug: string, projectId: string, estimateId: string) => {
|
deleteEstimate = async (workspaceSlug: string, projectId: string, estimateId: string) => {
|
||||||
const originalEstimateList = this.rootStore.project.projectEstimates || [];
|
const originalEstimateList = this.projectEstimates || [];
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.rootStore.project.estimates = {
|
this.estimates = {
|
||||||
...this.rootStore.project.estimates,
|
...this.estimates,
|
||||||
[projectId]: (this.rootStore.project.estimates?.[projectId] || [])?.filter(
|
[projectId]: (this.estimates?.[projectId] || [])?.filter((estimate) => estimate.id !== estimateId),
|
||||||
(estimate) => estimate.id !== estimateId
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -120,8 +178,8 @@ export class ProjectEstimatesStore implements IProjectEstimateStore {
|
|||||||
console.log("Failed to delete estimate from project store");
|
console.log("Failed to delete estimate from project store");
|
||||||
// reverting back to original estimate list
|
// reverting back to original estimate list
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.rootStore.project.estimates = {
|
this.estimates = {
|
||||||
...this.rootStore.project.estimates,
|
...this.estimates,
|
||||||
[projectId]: originalEstimateList,
|
[projectId]: originalEstimateList,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { observable, action, computed, makeObservable, runInAction } from "mobx";
|
import { observable, action, computed, makeObservable, runInAction } from "mobx";
|
||||||
// types
|
// types
|
||||||
import { RootStore } from "../root";
|
import { RootStore } from "../root";
|
||||||
import { IProject, IEstimate } from "types";
|
import { IProject } from "types";
|
||||||
// services
|
// services
|
||||||
import { ProjectService, ProjectStateService, ProjectEstimateService } from "services/project";
|
import { ProjectService, ProjectStateService } from "services/project";
|
||||||
import { IssueService, IssueLabelService } from "services/issue";
|
import { IssueService, IssueLabelService } from "services/issue";
|
||||||
|
|
||||||
export interface IProjectStore {
|
export interface IProjectStore {
|
||||||
@ -16,14 +16,10 @@ export interface IProjectStore {
|
|||||||
project_details: {
|
project_details: {
|
||||||
[projectId: string]: IProject; // projectId: project Info
|
[projectId: string]: IProject; // projectId: project Info
|
||||||
};
|
};
|
||||||
estimates: {
|
|
||||||
[projectId: string]: IEstimate[] | null; // project_id: members
|
|
||||||
} | null;
|
|
||||||
|
|
||||||
// computed
|
// computed
|
||||||
searchedProjects: IProject[];
|
searchedProjects: IProject[];
|
||||||
workspaceProjects: IProject[] | null;
|
workspaceProjects: IProject[] | null;
|
||||||
projectEstimates: IEstimate[] | null;
|
|
||||||
joinedProjects: IProject[];
|
joinedProjects: IProject[];
|
||||||
favoriteProjects: IProject[];
|
favoriteProjects: IProject[];
|
||||||
currentProjectDetails: IProject | undefined;
|
currentProjectDetails: IProject | undefined;
|
||||||
@ -34,10 +30,8 @@ export interface IProjectStore {
|
|||||||
|
|
||||||
getProjectById: (workspaceSlug: string, projectId: string) => IProject | null;
|
getProjectById: (workspaceSlug: string, projectId: string) => IProject | null;
|
||||||
|
|
||||||
getProjectEstimateById: (estimateId: string) => IEstimate | null;
|
|
||||||
fetchProjects: (workspaceSlug: string) => Promise<void>;
|
fetchProjects: (workspaceSlug: string) => Promise<void>;
|
||||||
fetchProjectDetails: (workspaceSlug: string, projectId: string) => Promise<any>;
|
fetchProjectDetails: (workspaceSlug: string, projectId: string) => Promise<any>;
|
||||||
fetchProjectEstimates: (workspaceSlug: string, projectId: string) => Promise<any>;
|
|
||||||
|
|
||||||
addProjectToFavorites: (workspaceSlug: string, projectId: string) => Promise<any>;
|
addProjectToFavorites: (workspaceSlug: string, projectId: string) => Promise<any>;
|
||||||
removeProjectFromFavorites: (workspaceSlug: string, projectId: string) => Promise<any>;
|
removeProjectFromFavorites: (workspaceSlug: string, projectId: string) => Promise<any>;
|
||||||
@ -62,9 +56,6 @@ export class ProjectStore implements IProjectStore {
|
|||||||
project_details: {
|
project_details: {
|
||||||
[projectId: string]: IProject; // projectId: project
|
[projectId: string]: IProject; // projectId: project
|
||||||
} = {};
|
} = {};
|
||||||
estimates: {
|
|
||||||
[projectId: string]: IEstimate[]; // projectId: estimates
|
|
||||||
} | null = {};
|
|
||||||
|
|
||||||
// root store
|
// root store
|
||||||
rootStore;
|
rootStore;
|
||||||
@ -73,7 +64,6 @@ export class ProjectStore implements IProjectStore {
|
|||||||
issueLabelService;
|
issueLabelService;
|
||||||
issueService;
|
issueService;
|
||||||
stateService;
|
stateService;
|
||||||
estimateService;
|
|
||||||
|
|
||||||
constructor(_rootStore: RootStore) {
|
constructor(_rootStore: RootStore) {
|
||||||
makeObservable(this, {
|
makeObservable(this, {
|
||||||
@ -86,14 +76,10 @@ export class ProjectStore implements IProjectStore {
|
|||||||
projects: observable.ref,
|
projects: observable.ref,
|
||||||
project_details: observable.ref,
|
project_details: observable.ref,
|
||||||
|
|
||||||
estimates: observable.ref,
|
|
||||||
|
|
||||||
// computed
|
// computed
|
||||||
searchedProjects: computed,
|
searchedProjects: computed,
|
||||||
workspaceProjects: computed,
|
workspaceProjects: computed,
|
||||||
|
|
||||||
projectEstimates: computed,
|
|
||||||
|
|
||||||
currentProjectDetails: computed,
|
currentProjectDetails: computed,
|
||||||
|
|
||||||
joinedProjects: computed,
|
joinedProjects: computed,
|
||||||
@ -106,9 +92,6 @@ export class ProjectStore implements IProjectStore {
|
|||||||
fetchProjectDetails: action,
|
fetchProjectDetails: action,
|
||||||
|
|
||||||
getProjectById: action,
|
getProjectById: action,
|
||||||
getProjectEstimateById: action,
|
|
||||||
|
|
||||||
fetchProjectEstimates: action,
|
|
||||||
|
|
||||||
addProjectToFavorites: action,
|
addProjectToFavorites: action,
|
||||||
removeProjectFromFavorites: action,
|
removeProjectFromFavorites: action,
|
||||||
@ -125,7 +108,6 @@ export class ProjectStore implements IProjectStore {
|
|||||||
this.issueService = new IssueService();
|
this.issueService = new IssueService();
|
||||||
this.issueLabelService = new IssueLabelService();
|
this.issueLabelService = new IssueLabelService();
|
||||||
this.stateService = new ProjectStateService();
|
this.stateService = new ProjectStateService();
|
||||||
this.estimateService = new ProjectEstimateService();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get searchedProjects() {
|
get searchedProjects() {
|
||||||
@ -164,11 +146,6 @@ export class ProjectStore implements IProjectStore {
|
|||||||
return this.projects?.[this.rootStore.workspace.workspaceSlug]?.filter((p) => p.is_favorite);
|
return this.projects?.[this.rootStore.workspace.workspaceSlug]?.filter((p) => p.is_favorite);
|
||||||
}
|
}
|
||||||
|
|
||||||
get projectEstimates() {
|
|
||||||
if (!this.projectId) return null;
|
|
||||||
return this.estimates?.[this.projectId] || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
setProjectId = (projectId: string | null) => {
|
setProjectId = (projectId: string | null) => {
|
||||||
this.projectId = projectId;
|
this.projectId = projectId;
|
||||||
@ -223,37 +200,6 @@ export class ProjectStore implements IProjectStore {
|
|||||||
return projectInfo;
|
return projectInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
getProjectEstimateById = (estimateId: string) => {
|
|
||||||
if (!this.projectId) return null;
|
|
||||||
const estimates = this.projectEstimates;
|
|
||||||
if (!estimates) return null;
|
|
||||||
const estimateInfo: IEstimate | null = estimates.find((estimate) => estimate.id === estimateId) || null;
|
|
||||||
return estimateInfo;
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchProjectEstimates = async (workspaceSlug: string, projectId: string) => {
|
|
||||||
try {
|
|
||||||
this.loader = true;
|
|
||||||
this.error = null;
|
|
||||||
|
|
||||||
const estimatesResponse = await this.estimateService.getEstimatesList(workspaceSlug, projectId);
|
|
||||||
const _estimates = {
|
|
||||||
...this.estimates,
|
|
||||||
[projectId]: estimatesResponse,
|
|
||||||
};
|
|
||||||
|
|
||||||
runInAction(() => {
|
|
||||||
this.estimates = _estimates;
|
|
||||||
this.loader = false;
|
|
||||||
this.error = null;
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
this.loader = false;
|
|
||||||
this.error = error;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
addProjectToFavorites = async (workspaceSlug: string, projectId: string) => {
|
addProjectToFavorites = async (workspaceSlug: string, projectId: string) => {
|
||||||
try {
|
try {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
|
Loading…
Reference in New Issue
Block a user