import { observable, action, makeObservable, runInAction } from "mobx"; // types import { RootStore } from "../root"; import { IEstimate, IEstimateFormData } from "types"; // services import { ProjectService, ProjectEstimateService } from "services/project"; export interface IProjectEstimateStore { loader: boolean; error: any | null; // estimates createEstimate: (workspaceSlug: string, projectId: string, data: IEstimateFormData) => Promise; updateEstimate: ( workspaceSlug: string, projectId: string, estimateId: string, data: IEstimateFormData ) => Promise; deleteEstimate: (workspaceSlug: string, projectId: string, estimateId: string) => Promise; } export class ProjectEstimatesStore implements IProjectEstimateStore { loader: boolean = false; error: any | null = null; // root store rootStore; // service projectService; estimateService; constructor(_rootStore: RootStore) { makeObservable(this, { // observable loader: observable, error: observable, // estimates createEstimate: action, updateEstimate: action, deleteEstimate: action, }); this.rootStore = _rootStore; this.projectService = new ProjectService(); this.estimateService = new ProjectEstimateService(); } createEstimate = async (workspaceSlug: string, projectId: string, data: IEstimateFormData) => { try { const response = await this.estimateService.createEstimate( workspaceSlug, projectId, data, this.rootStore.user.currentUser! ); const responseEstimate = { ...response.estimate, points: response.estimate_points, }; runInAction(() => { this.rootStore.project.estimates = { ...this.rootStore.project.estimates, [projectId]: [responseEstimate, ...(this.rootStore.project.estimates?.[projectId] || [])], }; }); return response; } catch (error) { console.log("Failed to create estimate from project store"); throw error; } }; updateEstimate = async (workspaceSlug: string, projectId: string, estimateId: string, data: IEstimateFormData) => { const originalEstimates = this.rootStore.project.getProjectEstimateById(estimateId); runInAction(() => { this.rootStore.project.estimates = { ...this.rootStore.project.estimates, [projectId]: (this.rootStore.project.estimates?.[projectId] || [])?.map((estimate) => estimate.id === estimateId ? { ...estimate, ...data.estimate } : estimate ), }; }); try { const response = await this.estimateService.patchEstimate( workspaceSlug, projectId, estimateId, data, this.rootStore.user.currentUser! ); await this.rootStore.project.fetchProjectEstimates(workspaceSlug, projectId); return response; } catch (error) { console.log("Failed to update estimate from project store"); runInAction(() => { this.rootStore.project.estimates = { ...this.rootStore.project.estimates, [projectId]: (this.rootStore.project.estimates?.[projectId] || [])?.map((estimate) => estimate.id === estimateId ? { ...estimate, ...originalEstimates } : estimate ), }; }); throw error; } }; deleteEstimate = async (workspaceSlug: string, projectId: string, estimateId: string) => { const originalEstimateList = this.rootStore.project.projectEstimates || []; runInAction(() => { this.rootStore.project.estimates = { ...this.rootStore.project.estimates, [projectId]: (this.rootStore.project.estimates?.[projectId] || [])?.filter( (estimate) => estimate.id !== estimateId ), }; }); try { // deleting using api await this.estimateService.deleteEstimate(workspaceSlug, projectId, estimateId, this.rootStore.user.currentUser!); } catch (error) { console.log("Failed to delete estimate from project store"); // reverting back to original estimate list runInAction(() => { this.rootStore.project.estimates = { ...this.rootStore.project.estimates, [projectId]: originalEstimateList, }; }); } }; }