import set from "lodash/set"; import { action, computed, makeObservable, observable } from "mobx"; import { computedFn } from "mobx-utils"; import { IEstimate as IEstimateType, IEstimatePoint as IEstimatePointType, IProject, IWorkspace, TEstimateType, } from "@plane/types"; // services import { EstimateService } from "@/services/project/estimate.service"; // store import { IEstimatePoint, EstimatePoint } from "@/store/estimates/estimate-point"; import { RootStore } from "@/store/root.store"; type TErrorCodes = { status: string; message?: string; }; export interface IEstimate extends IEstimateType { // observables error: TErrorCodes | undefined; estimatePoints: Record; // computed asJson: IEstimateType; EstimatePointIds: string[] | undefined; estimatePointById: (estimateId: string) => IEstimatePointType | undefined; // helper actions // actions updateEstimate: (data: Partial) => Promise; deleteEstimatePoint: (data: Partial) => Promise; } export class Estimate implements IEstimate { // data model observables id: string | undefined = undefined; name: string | undefined = undefined; description: string | undefined = undefined; type: TEstimateType | undefined = undefined; points: IEstimatePointType[] | undefined = undefined; workspace: string | undefined = undefined; workspace_detail: IWorkspace | undefined = undefined; project: string | undefined = undefined; project_detail: IProject | undefined = undefined; created_at: Date | undefined = undefined; updated_at: Date | undefined = undefined; created_by: string | undefined = undefined; updated_by: string | undefined = undefined; // observables error: TErrorCodes | undefined = undefined; estimatePoints: Record = {}; // service service: EstimateService; constructor( private store: RootStore, private data: IEstimateType ) { makeObservable(this, { // data model observables id: observable.ref, name: observable.ref, description: observable.ref, type: observable.ref, points: observable, workspace: observable.ref, workspace_detail: observable, project: observable.ref, project_detail: observable, created_at: observable.ref, updated_at: observable.ref, created_by: observable.ref, updated_by: observable.ref, // observables error: observable.ref, estimatePoints: observable, // computed asJson: computed, EstimatePointIds: computed, // actions updateEstimate: action, deleteEstimatePoint: action, }); this.id = this.data.id; this.name = this.data.name; this.description = this.data.description; this.type = this.data.type; this.points = this.data.points; this.workspace = this.data.workspace; this.workspace_detail = this.data.workspace_detail; this.project = this.data.project; this.project_detail = this.data.project_detail; this.created_at = this.data.created_at; this.updated_at = this.data.updated_at; this.created_by = this.data.created_by; this.updated_by = this.data.updated_by; this.data.points?.forEach((estimationPoint) => { if (estimationPoint.id) set(this.estimatePoints, [estimationPoint.id], new EstimatePoint(this.store, estimationPoint)); }); // service this.service = new EstimateService(); } // computed get asJson() { return { id: this.id, name: this.name, description: this.description, type: this.type, points: this.points, workspace: this.workspace, workspace_detail: this.workspace_detail, project: this.project, project_detail: this.project_detail, created_at: this.created_at, updated_at: this.updated_at, created_by: this.created_by, updated_by: this.updated_by, }; } get EstimatePointIds() { const { estimatePoints } = this; if (!estimatePoints) return undefined; const estimatePointIds = Object.values(estimatePoints) .map((point) => point.estimate && this.id) .filter((id) => id) as string[]; return estimatePointIds ?? undefined; } estimatePointById = computedFn((estimatePointId: string) => { if (!estimatePointId) return undefined; return this.estimatePoints[estimatePointId] ?? undefined; }); // actions updateEstimate = async (estimatePoint: Partial) => { try { const { workspaceSlug, projectId } = this.store.router; if (!workspaceSlug || !projectId || !this.id) return undefined; Object.entries(estimatePoint ?? {}).forEach(([key, value]) => { if (!key || !value) return; set(this, key, value); }); } catch (error) { throw error; } }; deleteEstimatePoint = async () => { try { const { workspaceSlug, projectId } = this.store.router; if (!workspaceSlug || !projectId || !this.id) return; } catch (error) { throw error; } }; }