forked from github/plane
af8804eb12
* refactor: remove estimates from project store * chore: update all the instances of the old store * chore: update store declaration structure
189 lines
5.3 KiB
TypeScript
189 lines
5.3 KiB
TypeScript
import { observable, action, makeObservable, runInAction, computed } 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;
|
|
|
|
// 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>;
|
|
updateEstimate: (
|
|
workspaceSlug: string,
|
|
projectId: string,
|
|
estimateId: string,
|
|
data: IEstimateFormData
|
|
) => Promise<IEstimate>;
|
|
deleteEstimate: (workspaceSlug: string, projectId: string, estimateId: string) => Promise<void>;
|
|
|
|
// computed
|
|
projectEstimates: IEstimate[] | undefined;
|
|
}
|
|
|
|
export class ProjectEstimatesStore implements IProjectEstimateStore {
|
|
loader: boolean = false;
|
|
error: any | null = null;
|
|
|
|
// observables
|
|
estimates: {
|
|
[projectId: string]: IEstimate[]; // projectId: estimates
|
|
} | null = {};
|
|
|
|
// root store
|
|
rootStore;
|
|
|
|
// service
|
|
projectService;
|
|
estimateService;
|
|
|
|
constructor(_rootStore: RootStore) {
|
|
makeObservable(this, {
|
|
// observable
|
|
loader: observable,
|
|
error: observable,
|
|
|
|
estimates: observable.ref,
|
|
|
|
// actions
|
|
getProjectEstimateById: action,
|
|
fetchProjectEstimates: action,
|
|
createEstimate: action,
|
|
updateEstimate: action,
|
|
deleteEstimate: action,
|
|
|
|
// computed
|
|
projectEstimates: computed,
|
|
});
|
|
|
|
this.rootStore = _rootStore;
|
|
this.projectService = new ProjectService();
|
|
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) => {
|
|
try {
|
|
const response = await this.estimateService.createEstimate(workspaceSlug, projectId, data);
|
|
|
|
const responseEstimate = {
|
|
...response.estimate,
|
|
points: response.estimate_points,
|
|
};
|
|
|
|
runInAction(() => {
|
|
this.estimates = {
|
|
...this.estimates,
|
|
[projectId]: [responseEstimate, ...(this.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.getProjectEstimateById(estimateId);
|
|
|
|
runInAction(() => {
|
|
this.estimates = {
|
|
...this.estimates,
|
|
[projectId]: (this.estimates?.[projectId] || [])?.map((estimate) =>
|
|
estimate.id === estimateId ? { ...estimate, ...data.estimate } : estimate
|
|
),
|
|
};
|
|
});
|
|
|
|
try {
|
|
const response = await this.estimateService.patchEstimate(workspaceSlug, projectId, estimateId, data);
|
|
await this.fetchProjectEstimates(workspaceSlug, projectId);
|
|
|
|
return response;
|
|
} catch (error) {
|
|
console.log("Failed to update estimate from project store");
|
|
runInAction(() => {
|
|
this.estimates = {
|
|
...this.estimates,
|
|
[projectId]: (this.estimates?.[projectId] || [])?.map((estimate) =>
|
|
estimate.id === estimateId ? { ...estimate, ...originalEstimates } : estimate
|
|
),
|
|
};
|
|
});
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
deleteEstimate = async (workspaceSlug: string, projectId: string, estimateId: string) => {
|
|
const originalEstimateList = this.projectEstimates || [];
|
|
|
|
runInAction(() => {
|
|
this.estimates = {
|
|
...this.estimates,
|
|
[projectId]: (this.estimates?.[projectId] || [])?.filter((estimate) => estimate.id !== estimateId),
|
|
};
|
|
});
|
|
|
|
try {
|
|
// deleting using api
|
|
await this.estimateService.deleteEstimate(workspaceSlug, projectId, estimateId);
|
|
} catch (error) {
|
|
console.log("Failed to delete estimate from project store");
|
|
// reverting back to original estimate list
|
|
runInAction(() => {
|
|
this.estimates = {
|
|
...this.estimates,
|
|
[projectId]: originalEstimateList,
|
|
};
|
|
});
|
|
}
|
|
};
|
|
}
|