mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
add modified stores for projects, cycles, modules and views
This commit is contained in:
parent
d0688e5287
commit
31e9705afb
370
web/store/cycle.store.ts
Normal file
370
web/store/cycle.store.ts
Normal file
@ -0,0 +1,370 @@
|
|||||||
|
import { action, computed, observable, makeObservable, runInAction } from "mobx";
|
||||||
|
// types
|
||||||
|
import { ICycle, TCycleView, CycleDateCheckData } from "types";
|
||||||
|
// mobx
|
||||||
|
import { RootStore } from "store/root.store";
|
||||||
|
// services
|
||||||
|
import { ProjectService } from "services/project";
|
||||||
|
import { IssueService } from "services/issue";
|
||||||
|
import { CycleService } from "services/cycle.service";
|
||||||
|
|
||||||
|
export interface ICycleStore {
|
||||||
|
loader: boolean;
|
||||||
|
error: any | null;
|
||||||
|
|
||||||
|
cycleView: TCycleView;
|
||||||
|
|
||||||
|
cycleId: string | null;
|
||||||
|
cycleMap: {
|
||||||
|
[projectId: string]: {
|
||||||
|
[cycleId: string]: ICycle;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
cycles: {
|
||||||
|
[projectId: string]: {
|
||||||
|
[filterType: string]: string[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// computed
|
||||||
|
getCycleById: (cycleId: string) => ICycle | null;
|
||||||
|
projectCycles: string[] | null;
|
||||||
|
projectCompletedCycles: string[] | null;
|
||||||
|
projectUpcomingCycles: string[] | null;
|
||||||
|
projectDraftCycles: string[] | null;
|
||||||
|
|
||||||
|
// actions
|
||||||
|
validateDate: (workspaceSlug: string, projectId: string, payload: CycleDateCheckData) => Promise<any>;
|
||||||
|
|
||||||
|
fetchCycles: (
|
||||||
|
workspaceSlug: string,
|
||||||
|
projectId: string,
|
||||||
|
params: "all" | "current" | "upcoming" | "draft" | "completed" | "incomplete"
|
||||||
|
) => Promise<void>;
|
||||||
|
fetchCycleDetails: (workspaceSlug: string, projectId: string, cycleId: string) => Promise<ICycle>;
|
||||||
|
|
||||||
|
createCycle: (workspaceSlug: string, projectId: string, data: Partial<ICycle>) => Promise<ICycle>;
|
||||||
|
updateCycleDetails: (
|
||||||
|
workspaceSlug: string,
|
||||||
|
projectId: string,
|
||||||
|
cycleId: string,
|
||||||
|
data: Partial<ICycle>
|
||||||
|
) => Promise<ICycle>;
|
||||||
|
deleteCycle: (workspaceSlug: string, projectId: string, cycleId: string) => Promise<void>;
|
||||||
|
|
||||||
|
addCycleToFavorites: (workspaceSlug: string, projectId: string, cycleId: string) => Promise<any>;
|
||||||
|
removeCycleFromFavorites: (workspaceSlug: string, projectId: string, cycleId: string) => Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CycleStore implements ICycleStore {
|
||||||
|
loader: boolean = false;
|
||||||
|
error: any | null = null;
|
||||||
|
|
||||||
|
cycleView: TCycleView = "all";
|
||||||
|
|
||||||
|
cycleId: string | null = null;
|
||||||
|
cycleMap: {
|
||||||
|
[projectId: string]: {
|
||||||
|
[cycleId: string]: ICycle;
|
||||||
|
};
|
||||||
|
} = {};
|
||||||
|
cycles: {
|
||||||
|
[projectId: string]: {
|
||||||
|
[filterType: string]: string[];
|
||||||
|
};
|
||||||
|
} = {};
|
||||||
|
|
||||||
|
// root store
|
||||||
|
rootStore;
|
||||||
|
// services
|
||||||
|
projectService;
|
||||||
|
issueService;
|
||||||
|
cycleService;
|
||||||
|
|
||||||
|
constructor(_rootStore: RootStore) {
|
||||||
|
makeObservable(this, {
|
||||||
|
loader: observable,
|
||||||
|
error: observable.ref,
|
||||||
|
|
||||||
|
cycleId: observable.ref,
|
||||||
|
cycleMap: observable.ref,
|
||||||
|
cycles: observable.ref,
|
||||||
|
|
||||||
|
// computed
|
||||||
|
projectCycles: computed,
|
||||||
|
projectCompletedCycles: computed,
|
||||||
|
projectUpcomingCycles: computed,
|
||||||
|
projectDraftCycles: computed,
|
||||||
|
|
||||||
|
// actions
|
||||||
|
getCycleById: action,
|
||||||
|
|
||||||
|
fetchCycles: action,
|
||||||
|
fetchCycleDetails: action,
|
||||||
|
|
||||||
|
createCycle: action,
|
||||||
|
updateCycleDetails: action,
|
||||||
|
deleteCycle: action,
|
||||||
|
|
||||||
|
addCycleToFavorites: action,
|
||||||
|
removeCycleFromFavorites: action,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.rootStore = _rootStore;
|
||||||
|
this.projectService = new ProjectService();
|
||||||
|
this.issueService = new IssueService();
|
||||||
|
this.cycleService = new CycleService();
|
||||||
|
}
|
||||||
|
|
||||||
|
// computed
|
||||||
|
get projectCycles() {
|
||||||
|
const projectId = this.rootStore.project.projectId;
|
||||||
|
|
||||||
|
if (!projectId) return null;
|
||||||
|
return this.cycles[projectId]?.all || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
get projectCompletedCycles() {
|
||||||
|
const projectId = this.rootStore.project.projectId;
|
||||||
|
|
||||||
|
if (!projectId) return null;
|
||||||
|
|
||||||
|
return this.cycles[projectId]?.completed || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
get projectUpcomingCycles() {
|
||||||
|
const projectId = this.rootStore.project.projectId;
|
||||||
|
|
||||||
|
if (!projectId) return null;
|
||||||
|
|
||||||
|
return this.cycles[projectId]?.upcoming || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
get projectDraftCycles() {
|
||||||
|
const projectId = this.rootStore.project.projectId;
|
||||||
|
|
||||||
|
if (!projectId) return null;
|
||||||
|
|
||||||
|
return this.cycles[projectId]?.draft || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
getCycleById = (cycleId: string) => this.cycleMap[this.rootStore.project][cycleId] || null;
|
||||||
|
|
||||||
|
// actions
|
||||||
|
setCycleView = (_cycleView: TCycleView) => (this.cycleView = _cycleView);
|
||||||
|
|
||||||
|
validateDate = async (workspaceSlug: string, projectId: string, payload: CycleDateCheckData) => {
|
||||||
|
try {
|
||||||
|
const response = await this.cycleService.cycleDateCheck(workspaceSlug, projectId, payload);
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Failed to validate cycle dates", error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchCycles = async (
|
||||||
|
workspaceSlug: string,
|
||||||
|
projectId: string,
|
||||||
|
params: "all" | "current" | "upcoming" | "draft" | "completed" | "incomplete"
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
this.loader = true;
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
const cyclesResponse = await this.cycleService.getCyclesWithParams(workspaceSlug, projectId, params);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.cycleMap = {
|
||||||
|
...this.cycleMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.cycleMap[projectId],
|
||||||
|
...cyclesResponse,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
this.cycles = {
|
||||||
|
...this.cycles,
|
||||||
|
[projectId]: { ...this.cycles[projectId], [params]: Object.keys(cyclesResponse) },
|
||||||
|
};
|
||||||
|
this.loader = false;
|
||||||
|
this.error = null;
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to fetch project cycles in project store", error);
|
||||||
|
this.loader = false;
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchCycleDetails = async (workspaceSlug: string, projectId: string, cycleId: string) => {
|
||||||
|
try {
|
||||||
|
const response = await this.cycleService.getCycleDetails(workspaceSlug, projectId, cycleId);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.cycleMap = {
|
||||||
|
...this.cycleMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.cycleMap[projectId],
|
||||||
|
[response?.id]: response,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Failed to fetch cycle detail from cycle store");
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
createCycle = async (workspaceSlug: string, projectId: string, data: Partial<ICycle>) => {
|
||||||
|
try {
|
||||||
|
const response = await this.cycleService.createCycle(workspaceSlug, projectId, data);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.cycleMap = {
|
||||||
|
...this.cycleMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.cycleMap[projectId],
|
||||||
|
[response?.id]: response,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const _currentView = this.cycleView === "active" ? "current" : this.cycleView;
|
||||||
|
this.fetchCycles(workspaceSlug, projectId, _currentView);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Failed to create cycle from cycle store");
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
updateCycleDetails = async (workspaceSlug: string, projectId: string, cycleId: string, data: Partial<ICycle>) => {
|
||||||
|
try {
|
||||||
|
const _response = await this.cycleService.patchCycle(workspaceSlug, projectId, cycleId, data);
|
||||||
|
|
||||||
|
const currentCycle = this.cycleMap[projectId][cycleId];
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.cycleMap = {
|
||||||
|
...this.cycleMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.cycleMap[projectId],
|
||||||
|
[cycleId]: { ...currentCycle, ...data },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const _currentView = this.cycleView === "active" ? "current" : this.cycleView;
|
||||||
|
this.fetchCycles(workspaceSlug, projectId, _currentView);
|
||||||
|
|
||||||
|
return _response;
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Failed to patch cycle from cycle store");
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
deleteCycle = async (workspaceSlug: string, projectId: string, cycleId: string) => {
|
||||||
|
try {
|
||||||
|
const currentProjectCycles = this.cycleMap[projectId];
|
||||||
|
delete currentProjectCycles[cycleId];
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.cycleMap = {
|
||||||
|
...this.cycleMap,
|
||||||
|
[projectId]: currentProjectCycles,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const _response = await this.cycleService.deleteCycle(workspaceSlug, projectId, cycleId);
|
||||||
|
|
||||||
|
return _response;
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Failed to delete cycle from cycle store");
|
||||||
|
|
||||||
|
const _currentView = this.cycleView === "active" ? "current" : this.cycleView;
|
||||||
|
this.fetchCycles(workspaceSlug, projectId, _currentView);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
addCycleToFavorites = async (workspaceSlug: string, projectId: string, cycleId: string) => {
|
||||||
|
try {
|
||||||
|
const currentCycle = this.cycleMap[projectId][cycleId];
|
||||||
|
|
||||||
|
if (currentCycle.is_favorite) return;
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.cycleMap = {
|
||||||
|
...this.cycleMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.cycleMap[projectId],
|
||||||
|
[cycleId]: { ...currentCycle, is_favorite: true },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// updating through api.
|
||||||
|
const response = await this.cycleService.addCycleToFavorites(workspaceSlug, projectId, { cycle: cycleId });
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Failed to add cycle to favorites in the cycles store", error);
|
||||||
|
|
||||||
|
// reset on error
|
||||||
|
const currentCycle = this.cycleMap[projectId][cycleId];
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.cycleMap = {
|
||||||
|
...this.cycleMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.cycleMap[projectId],
|
||||||
|
[cycleId]: { ...currentCycle, is_favorite: false },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
removeCycleFromFavorites = async (workspaceSlug: string, projectId: string, cycleId: string) => {
|
||||||
|
try {
|
||||||
|
const currentCycle = this.cycleMap[projectId][cycleId];
|
||||||
|
|
||||||
|
if (!currentCycle.is_favorite) return;
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.cycleMap = {
|
||||||
|
...this.cycleMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.cycleMap[projectId],
|
||||||
|
[cycleId]: { ...currentCycle, is_favorite: false },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await this.cycleService.removeCycleFromFavorites(workspaceSlug, projectId, cycleId);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Failed to remove cycle from favorites - Cycle Store", error);
|
||||||
|
|
||||||
|
// reset on error
|
||||||
|
const currentCycle = this.cycleMap[projectId][cycleId];
|
||||||
|
runInAction(() => {
|
||||||
|
this.cycleMap = {
|
||||||
|
...this.cycleMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.cycleMap[projectId],
|
||||||
|
[cycleId]: { ...currentCycle, is_favorite: true },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
446
web/store/module.store.ts
Normal file
446
web/store/module.store.ts
Normal file
@ -0,0 +1,446 @@
|
|||||||
|
import { action, computed, observable, makeObservable, runInAction } from "mobx";
|
||||||
|
// services
|
||||||
|
import { ProjectService } from "services/project";
|
||||||
|
import { ModuleService } from "services/module.service";
|
||||||
|
// types
|
||||||
|
import { IModule, ILinkDetails } from "types";
|
||||||
|
import { RootStore } from "store/root.store";
|
||||||
|
|
||||||
|
export interface IModuleStore {
|
||||||
|
// states
|
||||||
|
loader: boolean;
|
||||||
|
error: any | null;
|
||||||
|
|
||||||
|
// observables
|
||||||
|
moduleId: string | null;
|
||||||
|
moduleMap: {
|
||||||
|
[project_id: string]: {
|
||||||
|
[module_id: string]: IModule;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// actions
|
||||||
|
getModuleById: (moduleId: string) => IModule | null;
|
||||||
|
|
||||||
|
fetchModules: (workspaceSlug: string, projectId: string) => void;
|
||||||
|
fetchModuleDetails: (workspaceSlug: string, projectId: string, moduleId: string) => Promise<IModule>;
|
||||||
|
|
||||||
|
createModule: (workspaceSlug: string, projectId: string, data: Partial<IModule>) => Promise<IModule>;
|
||||||
|
updateModuleDetails: (
|
||||||
|
workspaceSlug: string,
|
||||||
|
projectId: string,
|
||||||
|
moduleId: string,
|
||||||
|
data: Partial<IModule>
|
||||||
|
) => Promise<IModule>;
|
||||||
|
deleteModule: (workspaceSlug: string, projectId: string, moduleId: string) => Promise<void>;
|
||||||
|
|
||||||
|
createModuleLink: (
|
||||||
|
workspaceSlug: string,
|
||||||
|
projectId: string,
|
||||||
|
moduleId: string,
|
||||||
|
data: Partial<ILinkDetails>
|
||||||
|
) => Promise<ILinkDetails>;
|
||||||
|
updateModuleLink: (
|
||||||
|
workspaceSlug: string,
|
||||||
|
projectId: string,
|
||||||
|
moduleId: string,
|
||||||
|
linkId: string,
|
||||||
|
data: Partial<ILinkDetails>
|
||||||
|
) => Promise<ILinkDetails>;
|
||||||
|
deleteModuleLink: (workspaceSlug: string, projectId: string, moduleId: string, linkId: string) => Promise<void>;
|
||||||
|
|
||||||
|
addModuleToFavorites: (workspaceSlug: string, projectId: string, moduleId: string) => Promise<void>;
|
||||||
|
removeModuleFromFavorites: (workspaceSlug: string, projectId: string, moduleId: string) => Promise<void>;
|
||||||
|
|
||||||
|
// computed
|
||||||
|
projectModules: string[] | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ModulesStore implements IModuleStore {
|
||||||
|
// states
|
||||||
|
loader: boolean = false;
|
||||||
|
error: any | null = null;
|
||||||
|
|
||||||
|
// observables
|
||||||
|
moduleId: string | null = null;
|
||||||
|
moduleMap: {
|
||||||
|
[project_id: string]: {
|
||||||
|
[module_id: string]: IModule;
|
||||||
|
};
|
||||||
|
} = {};
|
||||||
|
|
||||||
|
// root store
|
||||||
|
rootStore;
|
||||||
|
|
||||||
|
// services
|
||||||
|
projectService;
|
||||||
|
moduleService;
|
||||||
|
|
||||||
|
constructor(_rootStore: RootStore) {
|
||||||
|
makeObservable(this, {
|
||||||
|
// states
|
||||||
|
loader: observable,
|
||||||
|
error: observable.ref,
|
||||||
|
|
||||||
|
// observables
|
||||||
|
moduleId: observable.ref,
|
||||||
|
moduleMap: observable.ref,
|
||||||
|
|
||||||
|
// actions
|
||||||
|
getModuleById: action,
|
||||||
|
|
||||||
|
fetchModules: action,
|
||||||
|
fetchModuleDetails: action,
|
||||||
|
|
||||||
|
createModule: action,
|
||||||
|
updateModuleDetails: action,
|
||||||
|
deleteModule: action,
|
||||||
|
|
||||||
|
createModuleLink: action,
|
||||||
|
updateModuleLink: action,
|
||||||
|
deleteModuleLink: action,
|
||||||
|
|
||||||
|
addModuleToFavorites: action,
|
||||||
|
removeModuleFromFavorites: action,
|
||||||
|
|
||||||
|
// computed
|
||||||
|
projectModules: computed,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.rootStore = _rootStore;
|
||||||
|
|
||||||
|
// services
|
||||||
|
this.projectService = new ProjectService();
|
||||||
|
this.moduleService = new ModuleService();
|
||||||
|
}
|
||||||
|
|
||||||
|
// computed
|
||||||
|
get projectModules() {
|
||||||
|
if (!this.rootStore.project.projectId) return null;
|
||||||
|
|
||||||
|
return Object.keys(this.moduleMap[this.rootStore.project.projectId]) || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
getModuleById = (moduleId: string) => this.moduleMap[this.rootStore.project.projectId][moduleId] || null;
|
||||||
|
|
||||||
|
// actions
|
||||||
|
|
||||||
|
fetchModules = async (workspaceSlug: string, projectId: string) => {
|
||||||
|
try {
|
||||||
|
runInAction(() => {
|
||||||
|
this.loader = true;
|
||||||
|
this.error = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
const modulesResponse = await this.moduleService.getModules(workspaceSlug, projectId);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.moduleMap = {
|
||||||
|
...this.moduleMap,
|
||||||
|
[projectId]: modulesResponse,
|
||||||
|
};
|
||||||
|
this.loader = false;
|
||||||
|
this.error = null;
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to fetch modules list in module store", error);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.loader = false;
|
||||||
|
this.error = error;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchModuleDetails = async (workspaceSlug: string, projectId: string, moduleId: string) => {
|
||||||
|
try {
|
||||||
|
runInAction(() => {
|
||||||
|
this.loader = true;
|
||||||
|
this.error = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await this.moduleService.getModuleDetails(workspaceSlug, projectId, moduleId);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.moduleMap = {
|
||||||
|
...this.moduleMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.moduleMap[projectId],
|
||||||
|
[moduleId]: response,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
this.loader = false;
|
||||||
|
this.error = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to fetch module details in module store", error);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.loader = false;
|
||||||
|
this.error = error;
|
||||||
|
});
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
createModule = async (workspaceSlug: string, projectId: string, data: Partial<IModule>) => {
|
||||||
|
try {
|
||||||
|
const response = await this.moduleService.createModule(workspaceSlug, projectId, data);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.moduleMap = {
|
||||||
|
...this.moduleMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.moduleMap[projectId],
|
||||||
|
[response.id]: response,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
this.loader = false;
|
||||||
|
this.error = null;
|
||||||
|
});
|
||||||
|
this.fetchModules(workspaceSlug, projectId);
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to create module in module store", error);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.loader = false;
|
||||||
|
this.error = error;
|
||||||
|
});
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
updateModuleDetails = async (workspaceSlug: string, projectId: string, moduleId: string, data: Partial<IModule>) => {
|
||||||
|
try {
|
||||||
|
const currentModule = this.moduleMap[projectId][moduleId];
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.moduleMap = {
|
||||||
|
...this.moduleMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.moduleMap[projectId],
|
||||||
|
[moduleId]: { ...currentModule, ...data },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await this.moduleService.patchModule(workspaceSlug, projectId, moduleId, data);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to update module in module store", error);
|
||||||
|
|
||||||
|
this.fetchModules(workspaceSlug, projectId);
|
||||||
|
this.fetchModuleDetails(workspaceSlug, projectId, moduleId);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.error = error;
|
||||||
|
});
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
deleteModule = async (workspaceSlug: string, projectId: string, moduleId: string) => {
|
||||||
|
try {
|
||||||
|
const currentProjectModules = this.moduleMap[projectId];
|
||||||
|
delete currentProjectModules[moduleId];
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.moduleMap = {
|
||||||
|
...this.moduleMap,
|
||||||
|
[projectId]: currentProjectModules,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.moduleService.deleteModule(workspaceSlug, projectId, moduleId);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to delete module in module store", error);
|
||||||
|
|
||||||
|
this.fetchModules(workspaceSlug, projectId);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.error = error;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
createModuleLink = async (
|
||||||
|
workspaceSlug: string,
|
||||||
|
projectId: string,
|
||||||
|
moduleId: string,
|
||||||
|
data: Partial<ILinkDetails>
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const response = await this.moduleService.createModuleLink(workspaceSlug, projectId, moduleId, data);
|
||||||
|
|
||||||
|
const currentModule = this.moduleMap[projectId][moduleId];
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.moduleMap = {
|
||||||
|
...this.moduleMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.moduleMap[projectId],
|
||||||
|
[moduleId]: { ...currentModule, link_module: [response, ...currentModule.link_module] },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to create module link in module store", error);
|
||||||
|
|
||||||
|
this.fetchModules(workspaceSlug, projectId);
|
||||||
|
this.fetchModuleDetails(workspaceSlug, projectId, moduleId);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.error = error;
|
||||||
|
});
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
updateModuleLink = async (
|
||||||
|
workspaceSlug: string,
|
||||||
|
projectId: string,
|
||||||
|
moduleId: string,
|
||||||
|
linkId: string,
|
||||||
|
data: Partial<ILinkDetails>
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const response = await this.moduleService.updateModuleLink(workspaceSlug, projectId, moduleId, linkId, data);
|
||||||
|
|
||||||
|
const currentModule = this.moduleMap[projectId][moduleId];
|
||||||
|
const linkModules = currentModule.link_module.map((link) => (link.id === linkId ? response : link));
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.moduleMap = {
|
||||||
|
...this.moduleMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.moduleMap[projectId],
|
||||||
|
[moduleId]: { ...currentModule, link_module: linkModules },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to update module link in module store", error);
|
||||||
|
|
||||||
|
this.fetchModules(workspaceSlug, projectId);
|
||||||
|
this.fetchModuleDetails(workspaceSlug, projectId, moduleId);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.error = error;
|
||||||
|
});
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
deleteModuleLink = async (workspaceSlug: string, projectId: string, moduleId: string, linkId: string) => {
|
||||||
|
try {
|
||||||
|
const currentModule = this.moduleMap[projectId][moduleId];
|
||||||
|
const linkModules = currentModule.link_module.filter((link) => link.id !== linkId);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.moduleMap = {
|
||||||
|
...this.moduleMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.moduleMap[projectId],
|
||||||
|
[moduleId]: { ...currentModule, link_module: linkModules },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.moduleService.deleteModuleLink(workspaceSlug, projectId, moduleId, linkId);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to delete module link in module store", error);
|
||||||
|
|
||||||
|
this.fetchModules(workspaceSlug, projectId);
|
||||||
|
this.fetchModuleDetails(workspaceSlug, projectId, moduleId);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.error = error;
|
||||||
|
});
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
addModuleToFavorites = async (workspaceSlug: string, projectId: string, moduleId: string) => {
|
||||||
|
try {
|
||||||
|
const currentModule = this.moduleMap[projectId][moduleId];
|
||||||
|
|
||||||
|
if (currentModule.is_favorite) return;
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.moduleMap = {
|
||||||
|
...this.moduleMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.moduleMap[projectId],
|
||||||
|
[moduleId]: { ...currentModule, is_favorite: true },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.moduleService.addModuleToFavorites(workspaceSlug, projectId, {
|
||||||
|
module: moduleId,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to add module to favorites in module store", error);
|
||||||
|
|
||||||
|
const currentModule = this.moduleMap[projectId][moduleId];
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.moduleMap = {
|
||||||
|
...this.moduleMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.moduleMap[projectId],
|
||||||
|
[moduleId]: { ...currentModule, is_favorite: false },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
removeModuleFromFavorites = async (workspaceSlug: string, projectId: string, moduleId: string) => {
|
||||||
|
try {
|
||||||
|
const currentModule = this.moduleMap[projectId][moduleId];
|
||||||
|
|
||||||
|
if (!currentModule.is_favorite) return;
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.moduleMap = {
|
||||||
|
...this.moduleMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.moduleMap[projectId],
|
||||||
|
[moduleId]: { ...currentModule, is_favorite: false },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.moduleService.removeModuleFromFavorites(workspaceSlug, projectId, moduleId);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to remove module from favorites in module store", error);
|
||||||
|
|
||||||
|
const currentModule = this.moduleMap[projectId][moduleId];
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.moduleMap = {
|
||||||
|
...this.moduleMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.moduleMap[projectId],
|
||||||
|
[moduleId]: { ...currentModule, is_favorite: true },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
290
web/store/project-view.store.ts
Normal file
290
web/store/project-view.store.ts
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
import { observable, action, makeObservable, runInAction } from "mobx";
|
||||||
|
// services
|
||||||
|
import { ViewService } from "services/view.service";
|
||||||
|
import { RootStore } from "store/root.store";
|
||||||
|
// types
|
||||||
|
import { IProjectView } from "types";
|
||||||
|
|
||||||
|
export interface IProjectViewsStore {
|
||||||
|
// states
|
||||||
|
loader: boolean;
|
||||||
|
error: any | null;
|
||||||
|
|
||||||
|
// observables
|
||||||
|
viewId: string | null;
|
||||||
|
viewMap: {
|
||||||
|
[projectId: string]: {
|
||||||
|
[viewId: string]: IProjectView;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// actions
|
||||||
|
fetchViews: (workspaceSlug: string, projectId: string) => Promise<IProjectView[]>;
|
||||||
|
fetchViewDetails: (workspaceSlug: string, projectId: string, viewId: string) => Promise<IProjectView>;
|
||||||
|
createView: (workspaceSlug: string, projectId: string, data: Partial<IProjectView>) => Promise<IProjectView>;
|
||||||
|
updateView: (
|
||||||
|
workspaceSlug: string,
|
||||||
|
projectId: string,
|
||||||
|
viewId: string,
|
||||||
|
data: Partial<IProjectView>
|
||||||
|
) => Promise<IProjectView>;
|
||||||
|
deleteView: (workspaceSlug: string, projectId: string, viewId: string) => Promise<any>;
|
||||||
|
addViewToFavorites: (workspaceSlug: string, projectId: string, viewId: string) => Promise<any>;
|
||||||
|
removeViewFromFavorites: (workspaceSlug: string, projectId: string, viewId: string) => Promise<any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ProjectViewsStore implements IProjectViewsStore {
|
||||||
|
// states
|
||||||
|
loader: boolean = false;
|
||||||
|
error: any | null = null;
|
||||||
|
|
||||||
|
// observables
|
||||||
|
viewId: string | null = null;
|
||||||
|
viewMap: {
|
||||||
|
[projectId: string]: {
|
||||||
|
[viewId: string]: IProjectView;
|
||||||
|
};
|
||||||
|
} = {};
|
||||||
|
|
||||||
|
// root store
|
||||||
|
rootStore;
|
||||||
|
|
||||||
|
// services
|
||||||
|
viewService;
|
||||||
|
|
||||||
|
constructor(_rootStore: RootStore) {
|
||||||
|
makeObservable(this, {
|
||||||
|
// states
|
||||||
|
loader: observable.ref,
|
||||||
|
error: observable.ref,
|
||||||
|
|
||||||
|
// observables
|
||||||
|
viewId: observable.ref,
|
||||||
|
viewMap: observable.ref,
|
||||||
|
|
||||||
|
// actions
|
||||||
|
fetchViews: action,
|
||||||
|
fetchViewDetails: action,
|
||||||
|
createView: action,
|
||||||
|
updateView: action,
|
||||||
|
deleteView: action,
|
||||||
|
addViewToFavorites: action,
|
||||||
|
removeViewFromFavorites: action,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.rootStore = _rootStore;
|
||||||
|
|
||||||
|
this.viewService = new ViewService();
|
||||||
|
}
|
||||||
|
|
||||||
|
setViewId = (viewId: string | null) => {
|
||||||
|
this.viewId = viewId;
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchViews = async (workspaceSlug: string, projectId: string): Promise<IProjectView[]> => {
|
||||||
|
try {
|
||||||
|
runInAction(() => {
|
||||||
|
this.loader = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await this.viewService.getViews(workspaceSlug, projectId);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.loader = false;
|
||||||
|
this.viewMap = {
|
||||||
|
...this.viewMap,
|
||||||
|
[projectId]: response,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
runInAction(() => {
|
||||||
|
this.loader = false;
|
||||||
|
this.error = error;
|
||||||
|
});
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchViewDetails = async (workspaceSlug: string, projectId: string, viewId: string): Promise<IProjectView> => {
|
||||||
|
try {
|
||||||
|
runInAction(() => {
|
||||||
|
this.loader = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await this.viewService.getViewDetails(workspaceSlug, projectId, viewId);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.loader = false;
|
||||||
|
this.viewMap = {
|
||||||
|
...this.viewMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.viewMap[projectId],
|
||||||
|
[response.id]: response,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
runInAction(() => {
|
||||||
|
this.loader = false;
|
||||||
|
this.error = error;
|
||||||
|
});
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
createView = async (workspaceSlug: string, projectId: string, data: Partial<IProjectView>): Promise<IProjectView> => {
|
||||||
|
try {
|
||||||
|
const response = await this.viewService.createView(workspaceSlug, projectId, data);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.loader = false;
|
||||||
|
this.viewMap = {
|
||||||
|
...this.viewMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.viewMap[projectId],
|
||||||
|
[response.id]: response,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
runInAction(() => {
|
||||||
|
this.error = error;
|
||||||
|
});
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
updateView = async (
|
||||||
|
workspaceSlug: string,
|
||||||
|
projectId: string,
|
||||||
|
viewId: string,
|
||||||
|
data: Partial<IProjectView>
|
||||||
|
): Promise<IProjectView> => {
|
||||||
|
try {
|
||||||
|
const currentView = this.viewMap[projectId][viewId];
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.viewMap = {
|
||||||
|
...this.viewMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.viewMap[projectId],
|
||||||
|
[viewId]: { ...currentView, ...data },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await this.viewService.patchView(workspaceSlug, projectId, viewId, data);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
this.fetchViewDetails(workspaceSlug, projectId, viewId);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.error = error;
|
||||||
|
});
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
deleteView = async (workspaceSlug: string, projectId: string, viewId: string): Promise<any> => {
|
||||||
|
try {
|
||||||
|
const currentProjectViews = this.viewMap[projectId];
|
||||||
|
delete currentProjectViews[viewId];
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.viewMap = {
|
||||||
|
...this.viewMap,
|
||||||
|
[projectId]: currentProjectViews,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.viewService.deleteView(workspaceSlug, projectId, viewId);
|
||||||
|
} catch (error) {
|
||||||
|
this.fetchViews(workspaceSlug, projectId);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.error = error;
|
||||||
|
});
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
addViewToFavorites = async (workspaceSlug: string, projectId: string, viewId: string) => {
|
||||||
|
try {
|
||||||
|
const currentView = this.viewMap[projectId][viewId];
|
||||||
|
|
||||||
|
if (currentView.is_favorite) return;
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.viewMap = {
|
||||||
|
...this.viewMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.viewMap[projectId],
|
||||||
|
[viewId]: { ...currentView, is_favorite: true },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.viewService.addViewToFavorites(workspaceSlug, projectId, {
|
||||||
|
view: viewId,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to add view to favorites in view store", error);
|
||||||
|
|
||||||
|
const currentView = this.viewMap[projectId][viewId];
|
||||||
|
runInAction(() => {
|
||||||
|
this.viewMap = {
|
||||||
|
...this.viewMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.viewMap[projectId],
|
||||||
|
[viewId]: { ...currentView, is_favorite: false },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
removeViewFromFavorites = async (workspaceSlug: string, projectId: string, viewId: string) => {
|
||||||
|
try {
|
||||||
|
const currentView = this.viewMap[projectId][viewId];
|
||||||
|
|
||||||
|
if (!currentView.is_favorite) return;
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.viewMap = {
|
||||||
|
...this.viewMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.viewMap[projectId],
|
||||||
|
[viewId]: { ...currentView, is_favorite: false },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.viewService.removeViewFromFavorites(workspaceSlug, projectId, viewId);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to remove view from favorites in view store", error);
|
||||||
|
|
||||||
|
const currentView = this.viewMap[projectId][viewId];
|
||||||
|
runInAction(() => {
|
||||||
|
this.viewMap = {
|
||||||
|
...this.viewMap,
|
||||||
|
[projectId]: {
|
||||||
|
...this.viewMap[projectId],
|
||||||
|
[viewId]: { ...currentView, is_favorite: true },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
13
web/store/project/index.ts
Normal file
13
web/store/project/index.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { ProjectsStore } from "./projects.store";
|
||||||
|
import { ProjectPublishStore } from "./project-publish.store";
|
||||||
|
import { RootStore } from "store/root.store";
|
||||||
|
|
||||||
|
export class ProjectRootStore {
|
||||||
|
projects: ProjectsStore;
|
||||||
|
publish: ProjectPublishStore;
|
||||||
|
|
||||||
|
constructor(_root: RootStore) {
|
||||||
|
this.projects = new ProjectsStore(_root);
|
||||||
|
this.publish = new ProjectPublishStore(this);
|
||||||
|
}
|
||||||
|
}
|
265
web/store/project/project-publish.store.ts
Normal file
265
web/store/project/project-publish.store.ts
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
import { observable, action, makeObservable, runInAction } from "mobx";
|
||||||
|
// types
|
||||||
|
import { ProjectRootStore } from "./";
|
||||||
|
// services
|
||||||
|
import { ProjectPublishService } from "services/project";
|
||||||
|
|
||||||
|
export type TProjectPublishViews = "list" | "gantt" | "kanban" | "calendar" | "spreadsheet";
|
||||||
|
|
||||||
|
export type TProjectPublishViewsSettings = {
|
||||||
|
[key in TProjectPublishViews]: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface IProjectPublishSettings {
|
||||||
|
id?: string;
|
||||||
|
project?: string;
|
||||||
|
comments: boolean;
|
||||||
|
reactions: boolean;
|
||||||
|
votes: boolean;
|
||||||
|
views: TProjectPublishViewsSettings;
|
||||||
|
inbox: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IProjectPublishStore {
|
||||||
|
generalLoader: boolean;
|
||||||
|
fetchSettingsLoader: boolean;
|
||||||
|
error: any | null;
|
||||||
|
|
||||||
|
projectPublishSettings: IProjectPublishSettings | "not-initialized";
|
||||||
|
|
||||||
|
getProjectSettingsAsync: (workspaceSlug: string, projectId: string) => Promise<void>;
|
||||||
|
publishProject: (workspaceSlug: string, projectId: string, data: IProjectPublishSettings) => Promise<void>;
|
||||||
|
updateProjectSettingsAsync: (
|
||||||
|
workspaceSlug: string,
|
||||||
|
projectId: string,
|
||||||
|
projectPublishId: string,
|
||||||
|
data: IProjectPublishSettings
|
||||||
|
) => Promise<void>;
|
||||||
|
unPublishProject: (workspaceSlug: string, projectId: string, projectPublishId: string) => Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ProjectPublishStore implements IProjectPublishStore {
|
||||||
|
// states
|
||||||
|
generalLoader: boolean = false;
|
||||||
|
fetchSettingsLoader: boolean = false;
|
||||||
|
error: any | null = null;
|
||||||
|
|
||||||
|
// actions
|
||||||
|
project_id: string | null = null;
|
||||||
|
projectPublishSettings: IProjectPublishSettings | "not-initialized" = "not-initialized";
|
||||||
|
|
||||||
|
// root store
|
||||||
|
projectRootStore: ProjectRootStore;
|
||||||
|
|
||||||
|
// services
|
||||||
|
projectPublishService;
|
||||||
|
|
||||||
|
constructor(_projectRootStore: ProjectRootStore) {
|
||||||
|
makeObservable(this, {
|
||||||
|
// states
|
||||||
|
generalLoader: observable,
|
||||||
|
fetchSettingsLoader: observable,
|
||||||
|
error: observable,
|
||||||
|
|
||||||
|
// observables
|
||||||
|
project_id: observable,
|
||||||
|
projectPublishSettings: observable.ref,
|
||||||
|
|
||||||
|
// actions
|
||||||
|
getProjectSettingsAsync: action,
|
||||||
|
publishProject: action,
|
||||||
|
updateProjectSettingsAsync: action,
|
||||||
|
unPublishProject: action,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.projectRootStore = _projectRootStore;
|
||||||
|
|
||||||
|
// services
|
||||||
|
this.projectPublishService = new ProjectPublishService();
|
||||||
|
}
|
||||||
|
|
||||||
|
getProjectSettingsAsync = async (workspaceSlug: string, projectId: string) => {
|
||||||
|
try {
|
||||||
|
runInAction(() => {
|
||||||
|
this.fetchSettingsLoader = true;
|
||||||
|
this.error = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await this.projectPublishService.getProjectSettingsAsync(workspaceSlug, projectId);
|
||||||
|
|
||||||
|
if (response && response.length > 0) {
|
||||||
|
const _projectPublishSettings: IProjectPublishSettings = {
|
||||||
|
id: response[0]?.id,
|
||||||
|
comments: response[0]?.comments,
|
||||||
|
reactions: response[0]?.reactions,
|
||||||
|
votes: response[0]?.votes,
|
||||||
|
views: {
|
||||||
|
list: response[0]?.views?.list || false,
|
||||||
|
kanban: response[0]?.views?.kanban || false,
|
||||||
|
calendar: response[0]?.views?.calendar || false,
|
||||||
|
gantt: response[0]?.views?.gantt || false,
|
||||||
|
spreadsheet: response[0]?.views?.spreadsheet || false,
|
||||||
|
},
|
||||||
|
inbox: response[0]?.inbox || null,
|
||||||
|
project: response[0]?.project || null,
|
||||||
|
};
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.projectPublishSettings = _projectPublishSettings;
|
||||||
|
this.fetchSettingsLoader = false;
|
||||||
|
this.error = null;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
runInAction(() => {
|
||||||
|
this.projectPublishSettings = "not-initialized";
|
||||||
|
this.fetchSettingsLoader = false;
|
||||||
|
this.error = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
runInAction(() => {
|
||||||
|
this.fetchSettingsLoader = false;
|
||||||
|
this.error = error;
|
||||||
|
});
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
publishProject = async (workspaceSlug: string, projectId: string, data: IProjectPublishSettings) => {
|
||||||
|
try {
|
||||||
|
runInAction(() => {
|
||||||
|
this.generalLoader = true;
|
||||||
|
this.error = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await this.projectPublishService.createProjectSettingsAsync(workspaceSlug, projectId, data);
|
||||||
|
|
||||||
|
if (response) {
|
||||||
|
const _projectPublishSettings: IProjectPublishSettings = {
|
||||||
|
id: response?.id || null,
|
||||||
|
comments: response?.comments || false,
|
||||||
|
reactions: response?.reactions || false,
|
||||||
|
votes: response?.votes || false,
|
||||||
|
views: { ...response?.views },
|
||||||
|
inbox: response?.inbox || null,
|
||||||
|
project: response?.project || null,
|
||||||
|
};
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.projectPublishSettings = _projectPublishSettings;
|
||||||
|
this.projectRootStore.projects.projectsMap = {
|
||||||
|
...this.projectRootStore.projects.projectsMap,
|
||||||
|
[workspaceSlug]: {
|
||||||
|
...this.projectRootStore.projects.projectsMap[workspaceSlug],
|
||||||
|
[projectId]: {
|
||||||
|
...this.projectRootStore.projects.projectsMap[workspaceSlug][projectId],
|
||||||
|
is_deployed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
this.generalLoader = false;
|
||||||
|
this.error = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
runInAction(() => {
|
||||||
|
this.generalLoader = false;
|
||||||
|
this.error = error;
|
||||||
|
});
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
updateProjectSettingsAsync = async (
|
||||||
|
workspaceSlug: string,
|
||||||
|
projectId: string,
|
||||||
|
projectPublishId: string,
|
||||||
|
data: IProjectPublishSettings
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
runInAction(() => {
|
||||||
|
this.generalLoader = true;
|
||||||
|
this.error = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await this.projectPublishService.updateProjectSettingsAsync(
|
||||||
|
workspaceSlug,
|
||||||
|
projectId,
|
||||||
|
projectPublishId,
|
||||||
|
data
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response) {
|
||||||
|
const _projectPublishSettings: IProjectPublishSettings = {
|
||||||
|
id: response?.id || null,
|
||||||
|
comments: response?.comments || false,
|
||||||
|
reactions: response?.reactions || false,
|
||||||
|
votes: response?.votes || false,
|
||||||
|
views: { ...response?.views },
|
||||||
|
inbox: response?.inbox || null,
|
||||||
|
project: response?.project || null,
|
||||||
|
};
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.projectPublishSettings = _projectPublishSettings;
|
||||||
|
this.generalLoader = false;
|
||||||
|
this.error = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
runInAction(() => {
|
||||||
|
this.generalLoader = false;
|
||||||
|
this.error = error;
|
||||||
|
});
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
unPublishProject = async (workspaceSlug: string, projectId: string, projectPublishId: string) => {
|
||||||
|
try {
|
||||||
|
runInAction(() => {
|
||||||
|
this.generalLoader = true;
|
||||||
|
this.error = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await this.projectPublishService.deleteProjectSettingsAsync(
|
||||||
|
workspaceSlug,
|
||||||
|
projectId,
|
||||||
|
projectPublishId
|
||||||
|
);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.projectPublishSettings = "not-initialized";
|
||||||
|
this.projectRootStore.projects.projectsMap = {
|
||||||
|
...this.projectRootStore.projects.projectsMap,
|
||||||
|
[workspaceSlug]: {
|
||||||
|
...this.projectRootStore.projects.projectsMap[workspaceSlug],
|
||||||
|
[projectId]: {
|
||||||
|
...this.projectRootStore.projects.projectsMap[workspaceSlug][projectId],
|
||||||
|
is_deployed: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
this.generalLoader = false;
|
||||||
|
this.error = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
runInAction(() => {
|
||||||
|
this.generalLoader = false;
|
||||||
|
this.error = error;
|
||||||
|
});
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
360
web/store/project/projects.store.ts
Normal file
360
web/store/project/projects.store.ts
Normal file
@ -0,0 +1,360 @@
|
|||||||
|
import { observable, action, computed, makeObservable, runInAction } from "mobx";
|
||||||
|
import { IssueLabelService, IssueService } from "services/issue";
|
||||||
|
import { ProjectService, ProjectStateService } from "services/project";
|
||||||
|
import { RootStore } from "store/root.store";
|
||||||
|
|
||||||
|
import { IProject } from "types";
|
||||||
|
|
||||||
|
export interface IProjectsStore {
|
||||||
|
loader: boolean;
|
||||||
|
error: any | null;
|
||||||
|
|
||||||
|
searchQuery: string;
|
||||||
|
projectId: string | null;
|
||||||
|
projectsMap: {
|
||||||
|
[workspaceSlug: string]: {
|
||||||
|
[projectId: string]: IProject; // projectId: project Info
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// computed
|
||||||
|
searchedProjects: string[];
|
||||||
|
workspaceProjects: string[] | null;
|
||||||
|
joinedProjects: string[];
|
||||||
|
favoriteProjects: string[];
|
||||||
|
currentProjectDetails: IProject | undefined;
|
||||||
|
|
||||||
|
// actions
|
||||||
|
setSearchQuery: (query: string) => void;
|
||||||
|
getProjectById: (workspaceSlug: string, projectId: string) => IProject | null;
|
||||||
|
|
||||||
|
fetchProjects: (workspaceSlug: string) => Promise<void>;
|
||||||
|
fetchProjectDetails: (workspaceSlug: string, projectId: string) => Promise<any>;
|
||||||
|
|
||||||
|
addProjectToFavorites: (workspaceSlug: string, projectId: string) => Promise<any>;
|
||||||
|
removeProjectFromFavorites: (workspaceSlug: string, projectId: string) => Promise<any>;
|
||||||
|
|
||||||
|
orderProjectsWithSortOrder: (sourceIndex: number, destinationIndex: number, projectId: string) => number;
|
||||||
|
updateProjectView: (workspaceSlug: string, projectId: string, viewProps: any) => Promise<any>;
|
||||||
|
|
||||||
|
createProject: (workspaceSlug: string, data: any) => Promise<any>;
|
||||||
|
updateProject: (workspaceSlug: string, projectId: string, data: Partial<IProject>) => Promise<any>;
|
||||||
|
deleteProject: (workspaceSlug: string, projectId: string) => Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ProjectsStore implements IProjectsStore {
|
||||||
|
loader: boolean = false;
|
||||||
|
error: any | null = null;
|
||||||
|
|
||||||
|
projectId: string | null = null;
|
||||||
|
searchQuery: string = "";
|
||||||
|
projectsMap: {
|
||||||
|
[workspaceSlug: string]: {
|
||||||
|
[projectId: string]: IProject; // projectId: project Info
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// root store
|
||||||
|
rootStore: RootStore;
|
||||||
|
// service
|
||||||
|
projectService;
|
||||||
|
issueLabelService;
|
||||||
|
issueService;
|
||||||
|
stateService;
|
||||||
|
|
||||||
|
constructor(_rootStore: RootStore) {
|
||||||
|
makeObservable(this, {
|
||||||
|
// observable
|
||||||
|
loader: observable,
|
||||||
|
error: observable,
|
||||||
|
|
||||||
|
searchQuery: observable.ref,
|
||||||
|
projectId: observable.ref,
|
||||||
|
projectsMap: observable.ref,
|
||||||
|
|
||||||
|
// computed
|
||||||
|
searchedProjects: computed,
|
||||||
|
workspaceProjects: computed,
|
||||||
|
|
||||||
|
currentProjectDetails: computed,
|
||||||
|
|
||||||
|
joinedProjects: computed,
|
||||||
|
favoriteProjects: computed,
|
||||||
|
|
||||||
|
// action
|
||||||
|
setSearchQuery: action,
|
||||||
|
fetchProjects: action,
|
||||||
|
fetchProjectDetails: action,
|
||||||
|
|
||||||
|
addProjectToFavorites: action,
|
||||||
|
removeProjectFromFavorites: action,
|
||||||
|
|
||||||
|
orderProjectsWithSortOrder: action,
|
||||||
|
updateProjectView: action,
|
||||||
|
createProject: action,
|
||||||
|
updateProject: action,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.rootStore = _rootStore;
|
||||||
|
|
||||||
|
this.projectService = new ProjectService();
|
||||||
|
this.issueService = new IssueService();
|
||||||
|
this.issueLabelService = new IssueLabelService();
|
||||||
|
this.stateService = new ProjectStateService();
|
||||||
|
}
|
||||||
|
|
||||||
|
get searchedProjects() {
|
||||||
|
if (!this.rootStore.workspace.workspaceSlug) return [];
|
||||||
|
|
||||||
|
const currentProjectsMap = this.projectsMap[this.rootStore.workspace.workspaceSlug];
|
||||||
|
const projectIds = Object.keys(currentProjectsMap);
|
||||||
|
return this.searchQuery === ""
|
||||||
|
? projectIds
|
||||||
|
: projectIds?.filter((projectId) => {
|
||||||
|
currentProjectsMap[projectId].name.toLowerCase().includes(this.searchQuery.toLowerCase()) ||
|
||||||
|
currentProjectsMap[projectId].identifier.toLowerCase().includes(this.searchQuery.toLowerCase());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get workspaceProjects() {
|
||||||
|
if (!this.rootStore.workspace.workspaceSlug) return null;
|
||||||
|
const currentProjectsMap = this.projectsMap[this.rootStore.workspace.workspaceSlug];
|
||||||
|
|
||||||
|
const projectIds = Object.keys(currentProjectsMap);
|
||||||
|
if (!projectIds) return null;
|
||||||
|
return projectIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
get currentProjectDetails() {
|
||||||
|
if (!this.projectId || !this.rootStore.workspace.workspaceSlug) return;
|
||||||
|
return this.projectsMap[this.rootStore.workspace.workspaceSlug][this.projectId];
|
||||||
|
}
|
||||||
|
|
||||||
|
get joinedProjects() {
|
||||||
|
if (!this.rootStore.workspace.workspaceSlug) return [];
|
||||||
|
|
||||||
|
const currentProjectsMap = this.projectsMap[this.rootStore.workspace.workspaceSlug];
|
||||||
|
const projectIds = Object.keys(currentProjectsMap);
|
||||||
|
|
||||||
|
return projectIds?.filter((projectId) => currentProjectsMap[projectId].is_member);
|
||||||
|
}
|
||||||
|
|
||||||
|
get favoriteProjects() {
|
||||||
|
if (!this.rootStore.workspace.workspaceSlug) return [];
|
||||||
|
|
||||||
|
const currentProjectsMap = this.projectsMap[this.rootStore.workspace.workspaceSlug];
|
||||||
|
const projectIds = Object.keys(currentProjectsMap);
|
||||||
|
|
||||||
|
return projectIds?.filter((projectId) => currentProjectsMap[projectId].is_favorite);
|
||||||
|
}
|
||||||
|
|
||||||
|
setSearchQuery = (query: string) => {
|
||||||
|
this.searchQuery = query;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get Workspace projects using workspace slug
|
||||||
|
* @param workspaceSlug
|
||||||
|
* @returns
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
fetchProjects = async (workspaceSlug: string) => {
|
||||||
|
try {
|
||||||
|
const currentProjectsMap = await this.projectService.getProjects(workspaceSlug);
|
||||||
|
runInAction(() => {
|
||||||
|
this.projectsMap = {
|
||||||
|
...this.projectsMap,
|
||||||
|
[workspaceSlug]: currentProjectsMap,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Failed to fetch project from workspace store");
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchProjectDetails = async (workspaceSlug: string, projectId: string) => {
|
||||||
|
try {
|
||||||
|
const response = await this.projectService.getProject(workspaceSlug, projectId);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.projectsMap = {
|
||||||
|
...this.projectsMap,
|
||||||
|
[workspaceSlug]: {
|
||||||
|
...this.projectsMap[workspaceSlug],
|
||||||
|
[projectId]: response,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Error while fetching project details", error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
getProjectById = (workspaceSlug: string, projectId: string) => {
|
||||||
|
const currentProjectsMap = this.projectsMap?.[workspaceSlug];
|
||||||
|
if (!currentProjectsMap) return null;
|
||||||
|
|
||||||
|
const projectInfo: IProject | null = currentProjectsMap[projectId] || null;
|
||||||
|
return projectInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
addProjectToFavorites = async (workspaceSlug: string, projectId: string) => {
|
||||||
|
try {
|
||||||
|
const currentProject = this.projectsMap?.[workspaceSlug]?.[projectId];
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.projectsMap = {
|
||||||
|
...this.projectsMap,
|
||||||
|
[workspaceSlug]: {
|
||||||
|
...this.projectsMap[workspaceSlug],
|
||||||
|
[projectId]: { ...currentProject, is_favorite: true },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await this.projectService.addProjectToFavorites(workspaceSlug, projectId);
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Failed to add project to favorite");
|
||||||
|
await this.fetchProjects(workspaceSlug);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
removeProjectFromFavorites = async (workspaceSlug: string, projectId: string) => {
|
||||||
|
try {
|
||||||
|
const currentProject = this.projectsMap?.[workspaceSlug]?.[projectId];
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.projectsMap = {
|
||||||
|
...this.projectsMap,
|
||||||
|
[workspaceSlug]: {
|
||||||
|
...this.projectsMap[workspaceSlug],
|
||||||
|
[projectId]: { ...currentProject, is_favorite: false },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await this.projectService.removeProjectFromFavorites(workspaceSlug, projectId);
|
||||||
|
await this.fetchProjects(workspaceSlug);
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Failed to add project to favorite");
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
orderProjectsWithSortOrder = (sortIndex: number, destinationIndex: number, projectId: string) => {
|
||||||
|
try {
|
||||||
|
const workspaceSlug = this.rootStore.workspace.workspaceSlug;
|
||||||
|
if (!workspaceSlug) return 0;
|
||||||
|
|
||||||
|
const projectsList = Object.values(this.projectsMap[workspaceSlug] || {}) || [];
|
||||||
|
let updatedSortOrder = projectsList[sortIndex].sort_order;
|
||||||
|
|
||||||
|
if (destinationIndex === 0) updatedSortOrder = (projectsList[0].sort_order as number) - 1000;
|
||||||
|
else if (destinationIndex === projectsList.length - 1)
|
||||||
|
updatedSortOrder = (projectsList[projectsList.length - 1].sort_order as number) + 1000;
|
||||||
|
else {
|
||||||
|
const destinationSortingOrder = projectsList[destinationIndex].sort_order as number;
|
||||||
|
const relativeDestinationSortingOrder =
|
||||||
|
sortIndex < destinationIndex
|
||||||
|
? (projectsList[destinationIndex + 1].sort_order as number)
|
||||||
|
: (projectsList[destinationIndex - 1].sort_order as number);
|
||||||
|
|
||||||
|
updatedSortOrder = (destinationSortingOrder + relativeDestinationSortingOrder) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentProject = this.projectsMap?.[workspaceSlug]?.[projectId];
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.projectsMap = {
|
||||||
|
...this.projectsMap,
|
||||||
|
[workspaceSlug]: {
|
||||||
|
...this.projectsMap[workspaceSlug],
|
||||||
|
[projectId]: { ...currentProject, sort_order: updatedSortOrder },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return updatedSortOrder;
|
||||||
|
} catch (error) {
|
||||||
|
console.log("failed to update sort order of the projects");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
updateProjectView = async (workspaceSlug: string, projectId: string, viewProps: any) => {
|
||||||
|
try {
|
||||||
|
const response = await this.projectService.setProjectView(workspaceSlug, projectId, viewProps);
|
||||||
|
await this.fetchProjects(workspaceSlug);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Failed to update sort order of the projects");
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
createProject = async (workspaceSlug: string, data: any) => {
|
||||||
|
try {
|
||||||
|
const response = await this.projectService.createProject(workspaceSlug, data);
|
||||||
|
runInAction(() => {
|
||||||
|
this.projectsMap = {
|
||||||
|
...this.projectsMap,
|
||||||
|
[workspaceSlug]: { ...this.projectsMap[workspaceSlug], [response.id]: response },
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Failed to create project from project store");
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
updateProject = async (workspaceSlug: string, projectId: string, data: Partial<IProject>) => {
|
||||||
|
try {
|
||||||
|
const currentProject = this.projectsMap?.[workspaceSlug]?.[projectId];
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.projectsMap = {
|
||||||
|
...this.projectsMap,
|
||||||
|
[workspaceSlug]: { ...this.projectsMap[workspaceSlug], [projectId]: { ...currentProject, ...data } },
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await this.projectService.updateProject(workspaceSlug, projectId, data);
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Failed to create project from project store");
|
||||||
|
|
||||||
|
this.fetchProjects(workspaceSlug);
|
||||||
|
this.fetchProjectDetails(workspaceSlug, projectId);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
deleteProject = async (workspaceSlug: string, projectId: string) => {
|
||||||
|
try {
|
||||||
|
const workspaceProjects = { ...this.projectsMap[workspaceSlug] };
|
||||||
|
|
||||||
|
delete workspaceProjects[projectId];
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.projectsMap = {
|
||||||
|
...this.projectsMap,
|
||||||
|
[workspaceSlug]: { ...workspaceProjects },
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.projectService.deleteProject(workspaceSlug, projectId);
|
||||||
|
await this.fetchProjects(workspaceSlug);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Failed to delete project from project store");
|
||||||
|
this.fetchProjects(workspaceSlug);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -1,6 +1,10 @@
|
|||||||
import { enableStaticRendering } from "mobx-react-lite";
|
import { enableStaticRendering } from "mobx-react-lite";
|
||||||
// root stores
|
// root stores
|
||||||
import { AppRootStore } from "./application";
|
import { AppRootStore } from "./application";
|
||||||
|
import { ProjectRootStore } from "./project";
|
||||||
|
import { CycleStore } from "./cycle.store";
|
||||||
|
import { ProjectViewsStore } from "./project-view.store";
|
||||||
|
import { ModulesStore } from "./module.store";
|
||||||
|
|
||||||
enableStaticRendering(typeof window === "undefined");
|
enableStaticRendering(typeof window === "undefined");
|
||||||
|
|
||||||
@ -15,16 +19,16 @@ export class RootStore {
|
|||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.app = new AppRootStore();
|
this.app = new AppRootStore();
|
||||||
this.user = new UserRootStore();
|
// this.user = new UserRootStore();
|
||||||
this.workspace = new WorkspaceRootStore();
|
// this.workspace = new WorkspaceRootStore();
|
||||||
this.project = new ProjectRootStore();
|
this.project = new ProjectRootStore(this);
|
||||||
this.cycle = new CycleRootStore();
|
this.cycle = new CycleStore(this);
|
||||||
this.module = new ModuleRootStore();
|
this.module = new ModulesStore(this);
|
||||||
this.projectView = new ProjectViewRootStore();
|
this.projectView = new ProjectViewsStore(this);
|
||||||
this.page = new PageRootStore();
|
// this.page = new PageRootStore();
|
||||||
this.issue = new IssueRootStore();
|
// this.issue = new IssueRootStore();
|
||||||
// independent stores
|
// // independent stores
|
||||||
this.label = new labelStore();
|
// this.label = new labelStore();
|
||||||
this.state = new stateStore();
|
// this.state = new stateStore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ import { action, computed, observable, makeObservable, runInAction } from "mobx"
|
|||||||
import { ProjectService } from "services/project";
|
import { ProjectService } from "services/project";
|
||||||
import { ModuleService } from "services/module.service";
|
import { ModuleService } from "services/module.service";
|
||||||
// types
|
// types
|
||||||
import { RootStore } from "../root";
|
|
||||||
import { IIssue, IModule, ILinkDetails } from "types";
|
import { IIssue, IModule, ILinkDetails } from "types";
|
||||||
import {
|
import {
|
||||||
IIssueGroupWithSubGroupsStructure,
|
IIssueGroupWithSubGroupsStructure,
|
||||||
@ -11,6 +11,7 @@ import {
|
|||||||
IIssueUnGroupedStructure,
|
IIssueUnGroupedStructure,
|
||||||
} from "../issue/issue.store";
|
} from "../issue/issue.store";
|
||||||
import { IBlockUpdateData } from "components/gantt-chart";
|
import { IBlockUpdateData } from "components/gantt-chart";
|
||||||
|
import { RootStore } from "store/root.store";
|
||||||
|
|
||||||
export interface IModuleStore {
|
export interface IModuleStore {
|
||||||
// states
|
// states
|
||||||
|
Loading…
Reference in New Issue
Block a user