mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
Merge branch 'refactor/mobx-store' of github.com:makeplane/plane into refactor/mobx-store
This commit is contained in:
commit
4101a92f2e
@ -132,7 +132,7 @@ export class ModuleService extends APIService {
|
|||||||
workspaceSlug: string,
|
workspaceSlug: string,
|
||||||
projectId: string,
|
projectId: string,
|
||||||
moduleId: string,
|
moduleId: string,
|
||||||
data: ModuleLink
|
data: Partial<ModuleLink>
|
||||||
): Promise<ILinkDetails> {
|
): Promise<ILinkDetails> {
|
||||||
return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/modules/${moduleId}/module-links/`, data)
|
return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/modules/${moduleId}/module-links/`, data)
|
||||||
.then((response) => response?.data)
|
.then((response) => response?.data)
|
||||||
@ -146,7 +146,7 @@ export class ModuleService extends APIService {
|
|||||||
projectId: string,
|
projectId: string,
|
||||||
moduleId: string,
|
moduleId: string,
|
||||||
linkId: string,
|
linkId: string,
|
||||||
data: ModuleLink
|
data: Partial<ModuleLink>
|
||||||
): Promise<ILinkDetails> {
|
): Promise<ILinkDetails> {
|
||||||
return this.patch(
|
return this.patch(
|
||||||
`/api/workspaces/${workspaceSlug}/projects/${projectId}/modules/${moduleId}/module-links/${linkId}/`,
|
`/api/workspaces/${workspaceSlug}/projects/${projectId}/modules/${moduleId}/module-links/${linkId}/`,
|
||||||
|
@ -50,6 +50,14 @@ export class PageService extends APIService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getProjectPages(workspaceSlug: string, projectId: string) {
|
||||||
|
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/pages/`)
|
||||||
|
.then((response) => response?.data)
|
||||||
|
.catch((error) => {
|
||||||
|
throw error?.response?.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async getPagesWithParams(
|
async getPagesWithParams(
|
||||||
workspaceSlug: string,
|
workspaceSlug: string,
|
||||||
projectId: string,
|
projectId: string,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { action, computed, makeObservable, observable } from "mobx";
|
import { action, makeObservable, observable, computed } from "mobx";
|
||||||
import { ParsedUrlQuery } from "querystring";
|
import { ParsedUrlQuery } from "node:querystring";
|
||||||
|
|
||||||
export interface IRouterStore {
|
export interface IRouterStore {
|
||||||
query: ParsedUrlQuery;
|
query: ParsedUrlQuery;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { action, computed, observable, makeObservable, runInAction } from "mobx";
|
import { action, computed, observable, makeObservable, runInAction } from "mobx";
|
||||||
|
import set from "lodash/set";
|
||||||
// types
|
// types
|
||||||
import { ICycle, TCycleView, CycleDateCheckData } from "types";
|
import { ICycle, TCycleView, CycleDateCheckData } from "types";
|
||||||
// mobx
|
// mobx
|
||||||
@ -87,8 +88,8 @@ export class CycleStore implements ICycleStore {
|
|||||||
error: observable.ref,
|
error: observable.ref,
|
||||||
|
|
||||||
cycleId: observable.ref,
|
cycleId: observable.ref,
|
||||||
cycleMap: observable.ref,
|
cycleMap: observable,
|
||||||
cycles: observable.ref,
|
cycles: observable,
|
||||||
|
|
||||||
// computed
|
// computed
|
||||||
projectCycles: computed,
|
projectCycles: computed,
|
||||||
@ -118,14 +119,14 @@ export class CycleStore implements ICycleStore {
|
|||||||
|
|
||||||
// computed
|
// computed
|
||||||
get projectCycles() {
|
get projectCycles() {
|
||||||
const projectId = this.rootStore.project.projectId;
|
const projectId = this.rootStore.app.router.projectId;
|
||||||
|
|
||||||
if (!projectId) return null;
|
if (!projectId) return null;
|
||||||
return this.cycles[projectId]?.all || null;
|
return this.cycles[projectId]?.all || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
get projectCompletedCycles() {
|
get projectCompletedCycles() {
|
||||||
const projectId = this.rootStore.project.projectId;
|
const projectId = this.rootStore.app.router.projectId;
|
||||||
|
|
||||||
if (!projectId) return null;
|
if (!projectId) return null;
|
||||||
|
|
||||||
@ -133,7 +134,7 @@ export class CycleStore implements ICycleStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get projectUpcomingCycles() {
|
get projectUpcomingCycles() {
|
||||||
const projectId = this.rootStore.project.projectId;
|
const projectId = this.rootStore.app.router.projectId;
|
||||||
|
|
||||||
if (!projectId) return null;
|
if (!projectId) return null;
|
||||||
|
|
||||||
@ -141,18 +142,22 @@ export class CycleStore implements ICycleStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get projectDraftCycles() {
|
get projectDraftCycles() {
|
||||||
const projectId = this.rootStore.project.projectId;
|
const projectId = this.rootStore.app.router.projectId;
|
||||||
|
|
||||||
if (!projectId) return null;
|
if (!projectId) return null;
|
||||||
|
|
||||||
return this.cycles[projectId]?.draft || null;
|
return this.cycles[projectId]?.draft || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getCycleById = (cycleId: string) => this.cycleMap[this.rootStore.project][cycleId] || null;
|
getCycleById = (cycleId: string) => {
|
||||||
|
const projectId = this.rootStore.app.router.projectId;
|
||||||
|
|
||||||
|
if (!projectId) return null;
|
||||||
|
|
||||||
|
return this.cycleMap?.[projectId]?.[cycleId] || null;
|
||||||
|
};
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
setCycleView = (_cycleView: TCycleView) => (this.cycleView = _cycleView);
|
|
||||||
|
|
||||||
validateDate = async (workspaceSlug: string, projectId: string, payload: CycleDateCheckData) => {
|
validateDate = async (workspaceSlug: string, projectId: string, payload: CycleDateCheckData) => {
|
||||||
try {
|
try {
|
||||||
const response = await this.cycleService.cycleDateCheck(workspaceSlug, projectId, payload);
|
const response = await this.cycleService.cycleDateCheck(workspaceSlug, projectId, payload);
|
||||||
@ -174,18 +179,12 @@ export class CycleStore implements ICycleStore {
|
|||||||
|
|
||||||
const cyclesResponse = await this.cycleService.getCyclesWithParams(workspaceSlug, projectId, params);
|
const cyclesResponse = await this.cycleService.getCyclesWithParams(workspaceSlug, projectId, params);
|
||||||
|
|
||||||
|
const _cycleMap = set(this.cycleMap, [projectId], cyclesResponse);
|
||||||
|
const _cycles = set(this.cycles, [projectId, params], Object.keys(cyclesResponse));
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.cycleMap = {
|
this.cycleMap = _cycleMap;
|
||||||
...this.cycleMap,
|
this.cycles = _cycles;
|
||||||
[projectId]: {
|
|
||||||
...this.cycleMap[projectId],
|
|
||||||
...cyclesResponse,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
this.cycles = {
|
|
||||||
...this.cycles,
|
|
||||||
[projectId]: { ...this.cycles[projectId], [params]: Object.keys(cyclesResponse) },
|
|
||||||
};
|
|
||||||
this.loader = false;
|
this.loader = false;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
});
|
});
|
||||||
@ -200,14 +199,9 @@ export class CycleStore implements ICycleStore {
|
|||||||
try {
|
try {
|
||||||
const response = await this.cycleService.getCycleDetails(workspaceSlug, projectId, cycleId);
|
const response = await this.cycleService.getCycleDetails(workspaceSlug, projectId, cycleId);
|
||||||
|
|
||||||
|
const _cycleMap = set(this.cycleMap, [projectId, response?.id], response);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.cycleMap = {
|
this.cycleMap = _cycleMap;
|
||||||
...this.cycleMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.cycleMap[projectId],
|
|
||||||
[response?.id]: response,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
@ -221,14 +215,9 @@ export class CycleStore implements ICycleStore {
|
|||||||
try {
|
try {
|
||||||
const response = await this.cycleService.createCycle(workspaceSlug, projectId, data);
|
const response = await this.cycleService.createCycle(workspaceSlug, projectId, data);
|
||||||
|
|
||||||
|
const _cycleMap = set(this.cycleMap, [projectId, response?.id], response);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.cycleMap = {
|
this.cycleMap = _cycleMap;
|
||||||
...this.cycleMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.cycleMap[projectId],
|
|
||||||
[response?.id]: response,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const _currentView = this.cycleView === "active" ? "current" : this.cycleView;
|
const _currentView = this.cycleView === "active" ? "current" : this.cycleView;
|
||||||
@ -247,14 +236,9 @@ export class CycleStore implements ICycleStore {
|
|||||||
|
|
||||||
const currentCycle = this.cycleMap[projectId][cycleId];
|
const currentCycle = this.cycleMap[projectId][cycleId];
|
||||||
|
|
||||||
|
const _cycleMap = set(this.cycleMap, [projectId, cycleId], { ...currentCycle, ...data });
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.cycleMap = {
|
this.cycleMap = _cycleMap;
|
||||||
...this.cycleMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.cycleMap[projectId],
|
|
||||||
[cycleId]: { ...currentCycle, ...data },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const _currentView = this.cycleView === "active" ? "current" : this.cycleView;
|
const _currentView = this.cycleView === "active" ? "current" : this.cycleView;
|
||||||
@ -272,11 +256,9 @@ export class CycleStore implements ICycleStore {
|
|||||||
const currentProjectCycles = this.cycleMap[projectId];
|
const currentProjectCycles = this.cycleMap[projectId];
|
||||||
delete currentProjectCycles[cycleId];
|
delete currentProjectCycles[cycleId];
|
||||||
|
|
||||||
|
const _cycleMap = set(this.cycleMap, [projectId], currentProjectCycles);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.cycleMap = {
|
this.cycleMap = _cycleMap;
|
||||||
...this.cycleMap,
|
|
||||||
[projectId]: currentProjectCycles,
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const _response = await this.cycleService.deleteCycle(workspaceSlug, projectId, cycleId);
|
const _response = await this.cycleService.deleteCycle(workspaceSlug, projectId, cycleId);
|
||||||
@ -294,17 +276,11 @@ export class CycleStore implements ICycleStore {
|
|||||||
addCycleToFavorites = async (workspaceSlug: string, projectId: string, cycleId: string) => {
|
addCycleToFavorites = async (workspaceSlug: string, projectId: string, cycleId: string) => {
|
||||||
try {
|
try {
|
||||||
const currentCycle = this.cycleMap[projectId][cycleId];
|
const currentCycle = this.cycleMap[projectId][cycleId];
|
||||||
|
|
||||||
if (currentCycle.is_favorite) return;
|
if (currentCycle.is_favorite) return;
|
||||||
|
|
||||||
|
const _cycleMap = set(this.cycleMap, [projectId, cycleId, "is_favorite"], true);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.cycleMap = {
|
this.cycleMap = _cycleMap;
|
||||||
...this.cycleMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.cycleMap[projectId],
|
|
||||||
[cycleId]: { ...currentCycle, is_favorite: true },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// updating through api.
|
// updating through api.
|
||||||
@ -315,16 +291,9 @@ export class CycleStore implements ICycleStore {
|
|||||||
console.log("Failed to add cycle to favorites in the cycles store", error);
|
console.log("Failed to add cycle to favorites in the cycles store", error);
|
||||||
|
|
||||||
// reset on error
|
// reset on error
|
||||||
const currentCycle = this.cycleMap[projectId][cycleId];
|
const _cycleMap = set(this.cycleMap, [projectId, cycleId, "is_favorite"], false);
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.cycleMap = {
|
this.cycleMap = _cycleMap;
|
||||||
...this.cycleMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.cycleMap[projectId],
|
|
||||||
[cycleId]: { ...currentCycle, is_favorite: false },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
throw error;
|
throw error;
|
||||||
@ -337,14 +306,9 @@ export class CycleStore implements ICycleStore {
|
|||||||
|
|
||||||
if (!currentCycle.is_favorite) return;
|
if (!currentCycle.is_favorite) return;
|
||||||
|
|
||||||
|
const _cycleMap = set(this.cycleMap, [projectId, cycleId, "is_favorite"], false);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.cycleMap = {
|
this.cycleMap = _cycleMap;
|
||||||
...this.cycleMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.cycleMap[projectId],
|
|
||||||
[cycleId]: { ...currentCycle, is_favorite: false },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = await this.cycleService.removeCycleFromFavorites(workspaceSlug, projectId, cycleId);
|
const response = await this.cycleService.removeCycleFromFavorites(workspaceSlug, projectId, cycleId);
|
||||||
@ -354,16 +318,11 @@ export class CycleStore implements ICycleStore {
|
|||||||
console.log("Failed to remove cycle from favorites - Cycle Store", error);
|
console.log("Failed to remove cycle from favorites - Cycle Store", error);
|
||||||
|
|
||||||
// reset on error
|
// reset on error
|
||||||
const currentCycle = this.cycleMap[projectId][cycleId];
|
const _cycleMap = set(this.cycleMap, [projectId, cycleId, "is_favorite"], true);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.cycleMap = {
|
this.cycleMap = _cycleMap;
|
||||||
...this.cycleMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.cycleMap[projectId],
|
|
||||||
[cycleId]: { ...currentCycle, is_favorite: true },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { makeObservable, observable, action, runInAction, computed } from "mobx";
|
import { makeObservable, observable, action, runInAction, computed } from "mobx";
|
||||||
import keyBy from "lodash/keyBy";
|
import keyBy from "lodash/keyBy";
|
||||||
import omit from "lodash/omit";
|
import set from "lodash/set";
|
||||||
// services
|
// services
|
||||||
import { IssueLabelService } from "services/issue";
|
import { IssueLabelService } from "services/issue";
|
||||||
// types
|
// types
|
||||||
@ -11,7 +11,7 @@ import { buildTree } from "helpers/array.helper";
|
|||||||
import { RootStore } from "./root.store";
|
import { RootStore } from "./root.store";
|
||||||
|
|
||||||
export interface ILabelStore {
|
export interface ILabelStore {
|
||||||
labels: Record<string, IIssueLabel>;
|
labelMap: Record<string, IIssueLabel>;
|
||||||
projectLabels: IIssueLabel[] | undefined;
|
projectLabels: IIssueLabel[] | undefined;
|
||||||
projectLabelsTree: IIssueLabelTree[] | undefined;
|
projectLabelsTree: IIssueLabelTree[] | undefined;
|
||||||
fetchProjectLabels: (workspaceSlug: string, projectId: string) => Promise<IIssueLabel[]>;
|
fetchProjectLabels: (workspaceSlug: string, projectId: string) => Promise<IIssueLabel[]>;
|
||||||
@ -35,14 +35,14 @@ export interface ILabelStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class LabelStore {
|
export class LabelStore {
|
||||||
labels: Record<string, IIssueLabel> = {};
|
labelMap: Record<string, IIssueLabel> = {};
|
||||||
issueLabelService;
|
issueLabelService;
|
||||||
router;
|
router;
|
||||||
|
|
||||||
constructor(_rootStore: RootStore) {
|
constructor(_rootStore: RootStore) {
|
||||||
makeObservable(this, {
|
makeObservable(this, {
|
||||||
// observables
|
// observables
|
||||||
labels: observable.ref,
|
labelMap: observable,
|
||||||
// computed
|
// computed
|
||||||
projectLabels: computed,
|
projectLabels: computed,
|
||||||
projectLabelsTree: computed,
|
projectLabelsTree: computed,
|
||||||
@ -57,15 +57,15 @@ export class LabelStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the labels belongs to a specific project
|
* Returns the labelMap belongs to a specific project
|
||||||
*/
|
*/
|
||||||
get projectLabels() {
|
get projectLabels() {
|
||||||
if (!this.router.query?.projectId) return;
|
if (!this.router.query?.projectId) return;
|
||||||
return Object.values(this.labels).filter((label) => label.project === this.router.query.projectId);
|
return Object.values(this.labelMap).filter((label) => label.project === this.router.query.projectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the labels in a tree format
|
* Returns the labelMap in a tree format
|
||||||
*/
|
*/
|
||||||
get projectLabelsTree() {
|
get projectLabelsTree() {
|
||||||
if (!this.projectLabels) return;
|
if (!this.projectLabels) return;
|
||||||
@ -73,7 +73,7 @@ export class LabelStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches all the labels belongs to a specific project
|
* Fetches all the labelMap belongs to a specific project
|
||||||
* @param workspaceSlug
|
* @param workspaceSlug
|
||||||
* @param projectId
|
* @param projectId
|
||||||
* @returns Promise<IIssueLabel[]>
|
* @returns Promise<IIssueLabel[]>
|
||||||
@ -81,8 +81,9 @@ export class LabelStore {
|
|||||||
fetchProjectLabels = async (workspaceSlug: string, projectId: string) => {
|
fetchProjectLabels = async (workspaceSlug: string, projectId: string) => {
|
||||||
const response = await this.issueLabelService.getProjectIssueLabels(workspaceSlug, projectId);
|
const response = await this.issueLabelService.getProjectIssueLabels(workspaceSlug, projectId);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.labels = {
|
//todo add iteratively without modifying original reference
|
||||||
...this.labels,
|
this.labelMap = {
|
||||||
|
...this.labelMap,
|
||||||
...keyBy(response, "id"),
|
...keyBy(response, "id"),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@ -98,11 +99,10 @@ export class LabelStore {
|
|||||||
*/
|
*/
|
||||||
createLabel = async (workspaceSlug: string, projectId: string, data: Partial<IIssueLabel>) => {
|
createLabel = async (workspaceSlug: string, projectId: string, data: Partial<IIssueLabel>) => {
|
||||||
const response = await this.issueLabelService.createIssueLabel(workspaceSlug, projectId, data);
|
const response = await this.issueLabelService.createIssueLabel(workspaceSlug, projectId, data);
|
||||||
|
|
||||||
|
const _labelMap = set(this.labelMap, [response.id], response);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.labels = {
|
this.labelMap = _labelMap;
|
||||||
...this.labels,
|
|
||||||
[response.id]: response,
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
return response;
|
return response;
|
||||||
};
|
};
|
||||||
@ -116,22 +116,22 @@ export class LabelStore {
|
|||||||
* @returns Promise<IIssueLabel>
|
* @returns Promise<IIssueLabel>
|
||||||
*/
|
*/
|
||||||
updateLabel = async (workspaceSlug: string, projectId: string, labelId: string, data: Partial<IIssueLabel>) => {
|
updateLabel = async (workspaceSlug: string, projectId: string, labelId: string, data: Partial<IIssueLabel>) => {
|
||||||
const originalLabel = this.labels[labelId];
|
const originalLabel = this.labelMap[labelId];
|
||||||
try {
|
try {
|
||||||
|
const _labelMap = set(this.labelMap, [labelId], { ...this.labelMap[labelId], ...data });
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.labels = {
|
this.labelMap = _labelMap;
|
||||||
...this.labels,
|
|
||||||
[labelId]: { ...this.labels[labelId], ...data },
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = await this.issueLabelService.patchIssueLabel(workspaceSlug, projectId, labelId, data);
|
const response = await this.issueLabelService.patchIssueLabel(workspaceSlug, projectId, labelId, data);
|
||||||
return response;
|
return response;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Failed to update label from project store");
|
console.log("Failed to update label from project store");
|
||||||
|
const _labelMap = set(this.labelMap, [labelId], { ...this.labelMap[labelId], ...data });
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.labels = {
|
this.labelMap = {
|
||||||
...this.labels,
|
...this.labelMap,
|
||||||
[labelId]: { ...this.labels[labelId], ...originalLabel },
|
[labelId]: { ...this.labelMap[labelId], ...originalLabel },
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
throw error;
|
throw error;
|
||||||
@ -158,7 +158,7 @@ export class LabelStore {
|
|||||||
isSameParent: boolean,
|
isSameParent: boolean,
|
||||||
prevIndex: number | undefined
|
prevIndex: number | undefined
|
||||||
) => {
|
) => {
|
||||||
const currLabel = this.labels?.[labelId];
|
const currLabel = this.labelMap?.[labelId];
|
||||||
const labelTree = this.projectLabelsTree;
|
const labelTree = this.projectLabelsTree;
|
||||||
|
|
||||||
let currentArray: IIssueLabel[];
|
let currentArray: IIssueLabel[];
|
||||||
@ -189,7 +189,7 @@ export class LabelStore {
|
|||||||
|
|
||||||
let sortOrder: number;
|
let sortOrder: number;
|
||||||
|
|
||||||
//based on the next and previous labels calculate current sort order
|
//based on the next and previous labelMap calculate current sort order
|
||||||
if (prevSortOrder && nextSortOrder) {
|
if (prevSortOrder && nextSortOrder) {
|
||||||
sortOrder = (prevSortOrder + nextSortOrder) / 2;
|
sortOrder = (prevSortOrder + nextSortOrder) / 2;
|
||||||
} else if (nextSortOrder) {
|
} else if (nextSortOrder) {
|
||||||
@ -205,27 +205,29 @@ export class LabelStore {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete the label from the project and remove it from the labels object
|
* Delete the label from the project and remove it from the labelMap object
|
||||||
* @param workspaceSlug
|
* @param workspaceSlug
|
||||||
* @param projectId
|
* @param projectId
|
||||||
* @param labelId
|
* @param labelId
|
||||||
*/
|
*/
|
||||||
deleteLabel = async (workspaceSlug: string, projectId: string, labelId: string) => {
|
deleteLabel = async (workspaceSlug: string, projectId: string, labelId: string) => {
|
||||||
const originalLabel = this.labels[labelId];
|
const originalLabel = this.labelMap[labelId];
|
||||||
runInAction(() => {
|
|
||||||
this.labels = omit(this.labels, labelId);
|
|
||||||
});
|
|
||||||
try {
|
try {
|
||||||
|
const _labelMap = this.labelMap;
|
||||||
|
delete _labelMap[labelId];
|
||||||
|
runInAction(() => {
|
||||||
|
this.labelMap = _labelMap;
|
||||||
|
});
|
||||||
|
|
||||||
// deleting using api
|
// deleting using api
|
||||||
await this.issueLabelService.deleteIssueLabel(workspaceSlug, projectId, labelId);
|
await this.issueLabelService.deleteIssueLabel(workspaceSlug, projectId, labelId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Failed to delete label from project store");
|
console.log("Failed to delete label from project store");
|
||||||
// reverting back to original label list
|
// reverting back to original label list
|
||||||
|
const labelMap = set(this.labelMap, [labelId], originalLabel);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.labels = {
|
this.labelMap = labelMap;
|
||||||
...this.labels,
|
|
||||||
[labelId]: originalLabel,
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { action, computed, observable, makeObservable, runInAction } from "mobx";
|
import { action, computed, observable, makeObservable, runInAction } from "mobx";
|
||||||
|
import set from "lodash/set";
|
||||||
// services
|
// services
|
||||||
import { ProjectService } from "services/project";
|
import { ProjectService } from "services/project";
|
||||||
import { ModuleService } from "services/module.service";
|
import { ModuleService } from "services/module.service";
|
||||||
@ -79,12 +80,12 @@ export class ModulesStore implements IModuleStore {
|
|||||||
constructor(_rootStore: RootStore) {
|
constructor(_rootStore: RootStore) {
|
||||||
makeObservable(this, {
|
makeObservable(this, {
|
||||||
// states
|
// states
|
||||||
loader: observable,
|
loader: observable.ref,
|
||||||
error: observable.ref,
|
error: observable.ref,
|
||||||
|
|
||||||
// observables
|
// observables
|
||||||
moduleId: observable.ref,
|
moduleId: observable.ref,
|
||||||
moduleMap: observable.ref,
|
moduleMap: observable,
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
getModuleById: action,
|
getModuleById: action,
|
||||||
@ -116,12 +117,16 @@ export class ModulesStore implements IModuleStore {
|
|||||||
|
|
||||||
// computed
|
// computed
|
||||||
get projectModules() {
|
get projectModules() {
|
||||||
if (!this.rootStore.project.projectId) return null;
|
if (!this.rootStore.app.router.projectId) return null;
|
||||||
|
|
||||||
return Object.keys(this.moduleMap[this.rootStore.project.projectId]) || null;
|
return Object.keys(this.moduleMap[this.rootStore.app.router.projectId]) || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getModuleById = (moduleId: string) => this.moduleMap[this.rootStore.project.projectId][moduleId] || null;
|
getModuleById = (moduleId: string) => {
|
||||||
|
if (!this.rootStore.app.router.projectId) return null;
|
||||||
|
|
||||||
|
return this.moduleMap?.[this.rootStore.app.router.projectId]?.[moduleId] || null;
|
||||||
|
};
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
|
|
||||||
@ -134,11 +139,9 @@ export class ModulesStore implements IModuleStore {
|
|||||||
|
|
||||||
const modulesResponse = await this.moduleService.getModules(workspaceSlug, projectId);
|
const modulesResponse = await this.moduleService.getModules(workspaceSlug, projectId);
|
||||||
|
|
||||||
|
const _moduleMap = set(this.moduleMap, [projectId], modulesResponse);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.moduleMap = {
|
this.moduleMap = _moduleMap;
|
||||||
...this.moduleMap,
|
|
||||||
[projectId]: modulesResponse,
|
|
||||||
};
|
|
||||||
this.loader = false;
|
this.loader = false;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
});
|
});
|
||||||
@ -161,14 +164,9 @@ export class ModulesStore implements IModuleStore {
|
|||||||
|
|
||||||
const response = await this.moduleService.getModuleDetails(workspaceSlug, projectId, moduleId);
|
const response = await this.moduleService.getModuleDetails(workspaceSlug, projectId, moduleId);
|
||||||
|
|
||||||
|
const _moduleMap = set(this.moduleMap, [projectId, moduleId], response);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.moduleMap = {
|
this.moduleMap = _moduleMap;
|
||||||
...this.moduleMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.moduleMap[projectId],
|
|
||||||
[moduleId]: response,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
this.loader = false;
|
this.loader = false;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
});
|
});
|
||||||
@ -190,14 +188,9 @@ export class ModulesStore implements IModuleStore {
|
|||||||
try {
|
try {
|
||||||
const response = await this.moduleService.createModule(workspaceSlug, projectId, data);
|
const response = await this.moduleService.createModule(workspaceSlug, projectId, data);
|
||||||
|
|
||||||
|
const _moduleMap = set(this.moduleMap, [projectId, response?.id], response);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.moduleMap = {
|
this.moduleMap = _moduleMap;
|
||||||
...this.moduleMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.moduleMap[projectId],
|
|
||||||
[response.id]: response,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
this.loader = false;
|
this.loader = false;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
});
|
});
|
||||||
@ -219,14 +212,9 @@ export class ModulesStore implements IModuleStore {
|
|||||||
try {
|
try {
|
||||||
const currentModule = this.moduleMap[projectId][moduleId];
|
const currentModule = this.moduleMap[projectId][moduleId];
|
||||||
|
|
||||||
|
const _moduleMap = set(this.moduleMap, [projectId, moduleId], { ...currentModule, ...data });
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.moduleMap = {
|
this.moduleMap = _moduleMap;
|
||||||
...this.moduleMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.moduleMap[projectId],
|
|
||||||
[moduleId]: { ...currentModule, ...data },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = await this.moduleService.patchModule(workspaceSlug, projectId, moduleId, data);
|
const response = await this.moduleService.patchModule(workspaceSlug, projectId, moduleId, data);
|
||||||
@ -251,11 +239,9 @@ export class ModulesStore implements IModuleStore {
|
|||||||
const currentProjectModules = this.moduleMap[projectId];
|
const currentProjectModules = this.moduleMap[projectId];
|
||||||
delete currentProjectModules[moduleId];
|
delete currentProjectModules[moduleId];
|
||||||
|
|
||||||
|
const _moduleMap = set(this.moduleMap, [projectId], currentProjectModules);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.moduleMap = {
|
this.moduleMap = _moduleMap;
|
||||||
...this.moduleMap,
|
|
||||||
[projectId]: currentProjectModules,
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.moduleService.deleteModule(workspaceSlug, projectId, moduleId);
|
await this.moduleService.deleteModule(workspaceSlug, projectId, moduleId);
|
||||||
@ -281,14 +267,13 @@ export class ModulesStore implements IModuleStore {
|
|||||||
|
|
||||||
const currentModule = this.moduleMap[projectId][moduleId];
|
const currentModule = this.moduleMap[projectId][moduleId];
|
||||||
|
|
||||||
|
const _moduleMap = set(
|
||||||
|
this.moduleMap,
|
||||||
|
[projectId, moduleId, "link_module"],
|
||||||
|
[response, ...currentModule.link_module]
|
||||||
|
);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.moduleMap = {
|
this.moduleMap = _moduleMap;
|
||||||
...this.moduleMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.moduleMap[projectId],
|
|
||||||
[moduleId]: { ...currentModule, link_module: [response, ...currentModule.link_module] },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
@ -319,14 +304,9 @@ export class ModulesStore implements IModuleStore {
|
|||||||
const currentModule = this.moduleMap[projectId][moduleId];
|
const currentModule = this.moduleMap[projectId][moduleId];
|
||||||
const linkModules = currentModule.link_module.map((link) => (link.id === linkId ? response : link));
|
const linkModules = currentModule.link_module.map((link) => (link.id === linkId ? response : link));
|
||||||
|
|
||||||
|
const _moduleMap = set(this.moduleMap, [projectId, moduleId, "link_module"], linkModules);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.moduleMap = {
|
this.moduleMap = _moduleMap;
|
||||||
...this.moduleMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.moduleMap[projectId],
|
|
||||||
[moduleId]: { ...currentModule, link_module: linkModules },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
@ -349,14 +329,9 @@ export class ModulesStore implements IModuleStore {
|
|||||||
const currentModule = this.moduleMap[projectId][moduleId];
|
const currentModule = this.moduleMap[projectId][moduleId];
|
||||||
const linkModules = currentModule.link_module.filter((link) => link.id !== linkId);
|
const linkModules = currentModule.link_module.filter((link) => link.id !== linkId);
|
||||||
|
|
||||||
|
const _moduleMap = set(this.moduleMap, [projectId, moduleId, "link_module"], linkModules);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.moduleMap = {
|
this.moduleMap = _moduleMap;
|
||||||
...this.moduleMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.moduleMap[projectId],
|
|
||||||
[moduleId]: { ...currentModule, link_module: linkModules },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.moduleService.deleteModuleLink(workspaceSlug, projectId, moduleId, linkId);
|
await this.moduleService.deleteModuleLink(workspaceSlug, projectId, moduleId, linkId);
|
||||||
@ -380,14 +355,9 @@ export class ModulesStore implements IModuleStore {
|
|||||||
|
|
||||||
if (currentModule.is_favorite) return;
|
if (currentModule.is_favorite) return;
|
||||||
|
|
||||||
|
const _moduleMap = set(this.moduleMap, [projectId, moduleId, "is_favorite"], true);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.moduleMap = {
|
this.moduleMap = _moduleMap;
|
||||||
...this.moduleMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.moduleMap[projectId],
|
|
||||||
[moduleId]: { ...currentModule, is_favorite: true },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.moduleService.addModuleToFavorites(workspaceSlug, projectId, {
|
await this.moduleService.addModuleToFavorites(workspaceSlug, projectId, {
|
||||||
@ -396,16 +366,9 @@ export class ModulesStore implements IModuleStore {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to add module to favorites in module store", error);
|
console.error("Failed to add module to favorites in module store", error);
|
||||||
|
|
||||||
const currentModule = this.moduleMap[projectId][moduleId];
|
const _moduleMap = set(this.moduleMap, [projectId, moduleId, "is_favorite"], false);
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.moduleMap = {
|
this.moduleMap = _moduleMap;
|
||||||
...this.moduleMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.moduleMap[projectId],
|
|
||||||
[moduleId]: { ...currentModule, is_favorite: false },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -416,30 +379,18 @@ export class ModulesStore implements IModuleStore {
|
|||||||
|
|
||||||
if (!currentModule.is_favorite) return;
|
if (!currentModule.is_favorite) return;
|
||||||
|
|
||||||
|
const _moduleMap = set(this.moduleMap, [projectId, moduleId, "is_favorite"], false);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.moduleMap = {
|
this.moduleMap = _moduleMap;
|
||||||
...this.moduleMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.moduleMap[projectId],
|
|
||||||
[moduleId]: { ...currentModule, is_favorite: false },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.moduleService.removeModuleFromFavorites(workspaceSlug, projectId, moduleId);
|
await this.moduleService.removeModuleFromFavorites(workspaceSlug, projectId, moduleId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to remove module from favorites in module store", error);
|
console.error("Failed to remove module from favorites in module store", error);
|
||||||
|
|
||||||
const currentModule = this.moduleMap[projectId][moduleId];
|
const _moduleMap = set(this.moduleMap, [projectId, moduleId, "is_favorite"], true);
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.moduleMap = {
|
this.moduleMap = _moduleMap;
|
||||||
...this.moduleMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.moduleMap[projectId],
|
|
||||||
[moduleId]: { ...currentModule, is_favorite: true },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
196
web/store/page.store.ts
Normal file
196
web/store/page.store.ts
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
import { action, computed, makeObservable, observable, runInAction } from "mobx";
|
||||||
|
import keyBy from "lodash/keyBy";
|
||||||
|
import isToday from "date-fns/isToday";
|
||||||
|
import isThisWeek from "date-fns/isThisWeek";
|
||||||
|
import isYesterday from "date-fns/isYesterday";
|
||||||
|
// services
|
||||||
|
import { PageService } from "services/page.service";
|
||||||
|
// types
|
||||||
|
import { IPage, IRecentPages } from "types";
|
||||||
|
// store
|
||||||
|
import { RootStore } from "./root.store";
|
||||||
|
|
||||||
|
export interface IPageStore {
|
||||||
|
pages: Record<string, IPage>;
|
||||||
|
archivedPages: Record<string, IPage>;
|
||||||
|
|
||||||
|
projectPages: IPage[] | undefined;
|
||||||
|
favoriteProjectPages: IPage[] | undefined;
|
||||||
|
privateProjectPages: IPage[] | undefined;
|
||||||
|
sharedProjectPages: IPage[] | undefined;
|
||||||
|
|
||||||
|
fetchProjectPages: (workspaceSlug: string, projectId: string) => Promise<IPage[]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PageStore {
|
||||||
|
pages: Record<string, IPage> = {};
|
||||||
|
archivedPages: Record<string, IPage> = {};
|
||||||
|
// services
|
||||||
|
pageService;
|
||||||
|
// stores
|
||||||
|
router;
|
||||||
|
|
||||||
|
constructor(_rootStore: RootStore) {
|
||||||
|
makeObservable(this, {
|
||||||
|
pages: observable.ref,
|
||||||
|
archivedPages: observable.ref,
|
||||||
|
// computed
|
||||||
|
projectPages: computed,
|
||||||
|
favoriteProjectPages: computed,
|
||||||
|
sharedProjectPages: computed,
|
||||||
|
privateProjectPages: computed,
|
||||||
|
// actions
|
||||||
|
fetchProjectPages: action,
|
||||||
|
});
|
||||||
|
// stores
|
||||||
|
this.router = _rootStore.app.router;
|
||||||
|
// services
|
||||||
|
this.pageService = new PageService();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieves all pages for a projectId that is available in the url.
|
||||||
|
*/
|
||||||
|
get projectPages() {
|
||||||
|
if (!this.router.projectId) return;
|
||||||
|
return Object.values(this.pages).filter((page) => page.project === this.router.query.projectId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieves all favorite pages for a projectId that is available in the url.
|
||||||
|
*/
|
||||||
|
get favoriteProjectPages() {
|
||||||
|
if (!this.projectPages) return;
|
||||||
|
return this.projectPages.filter((page) => page.is_favorite);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieves all private pages for a projectId that is available in the url.
|
||||||
|
*/
|
||||||
|
get privateProjectPages() {
|
||||||
|
if (!this.projectPages) return;
|
||||||
|
return this.projectPages.filter((page) => page.access === 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieves all shared pages which are public to everyone in the project for a projectId that is available in the url.
|
||||||
|
*/
|
||||||
|
get sharedProjectPages() {
|
||||||
|
if (!this.projectPages) return;
|
||||||
|
return this.projectPages.filter((page) => page.access === 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieves all recent pages for a projectId that is available in the url.
|
||||||
|
* In format where today, yesterday, this_week, older are keys.
|
||||||
|
*/
|
||||||
|
get recentProjectPages() {
|
||||||
|
if (!this.projectPages) return;
|
||||||
|
const data: IRecentPages = { today: [], yesterday: [], this_week: [], older: [] };
|
||||||
|
data.today = this.projectPages.filter((p) => isToday(new Date(p.created_at))) || [];
|
||||||
|
data.yesterday = this.projectPages.filter((p) => isYesterday(new Date(p.created_at))) || [];
|
||||||
|
data.this_week =
|
||||||
|
this.projectPages.filter(
|
||||||
|
(p) =>
|
||||||
|
isThisWeek(new Date(p.created_at)) && !isToday(new Date(p.created_at)) && !isYesterday(new Date(p.created_at))
|
||||||
|
) || [];
|
||||||
|
data.older =
|
||||||
|
this.projectPages.filter((p) => !isThisWeek(new Date(p.created_at)) && !isYesterday(new Date(p.created_at))) ||
|
||||||
|
[];
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieves all archived pages for a projectId that is available in the url.
|
||||||
|
*/
|
||||||
|
get archivedProjectPages() {
|
||||||
|
if (!this.router.projectId) return;
|
||||||
|
return Object.values(this.archivedPages).filter((page) => page.project === this.router.projectId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fetches all pages for a project.
|
||||||
|
* @param workspaceSlug
|
||||||
|
* @param projectId
|
||||||
|
* @returns Promise<IPage[]>
|
||||||
|
*/
|
||||||
|
async fetchProjectPages(workspaceSlug: string, projectId: string) {
|
||||||
|
const response = await this.pageService.getProjectPages(workspaceSlug, projectId);
|
||||||
|
runInAction(() => {
|
||||||
|
this.pages = {
|
||||||
|
...this.pages,
|
||||||
|
...keyBy(response, "id"),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fetches all archived pages for a project.
|
||||||
|
* @param workspaceSlug
|
||||||
|
* @param projectId
|
||||||
|
* @returns Promise<IPage[]>
|
||||||
|
*/
|
||||||
|
async fetchArchivedProjectPages(workspaceSlug: string, projectId: string) {
|
||||||
|
const response = await this.pageService.getArchivedPages(workspaceSlug, projectId);
|
||||||
|
runInAction(() => {
|
||||||
|
this.archivedPages = {
|
||||||
|
...this.archivedPages,
|
||||||
|
...keyBy(response, "id"),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Page to users favorites list
|
||||||
|
* @param workspaceSlug
|
||||||
|
* @param projectId
|
||||||
|
* @param pageId
|
||||||
|
*/
|
||||||
|
addToFavorites = async (workspaceSlug: string, projectId: string, pageId: string) => {
|
||||||
|
try {
|
||||||
|
runInAction(() => {
|
||||||
|
this.pages = {
|
||||||
|
...this.pages,
|
||||||
|
[pageId]: { ...this.pages[pageId], is_favorite: true },
|
||||||
|
};
|
||||||
|
});
|
||||||
|
await this.pageService.addPageToFavorites(workspaceSlug, projectId, pageId);
|
||||||
|
} catch (error) {
|
||||||
|
runInAction(() => {
|
||||||
|
this.pages = {
|
||||||
|
...this.pages,
|
||||||
|
[pageId]: { ...this.pages[pageId], is_favorite: false },
|
||||||
|
};
|
||||||
|
});
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove page from the users favorites list
|
||||||
|
* @param workspaceSlug
|
||||||
|
* @param projectId
|
||||||
|
* @param pageId
|
||||||
|
*/
|
||||||
|
removeFromFavorites = async (workspaceSlug: string, projectId: string, pageId: string) => {
|
||||||
|
try {
|
||||||
|
runInAction(() => {
|
||||||
|
this.pages = {
|
||||||
|
...this.pages,
|
||||||
|
[pageId]: { ...this.pages[pageId], is_favorite: false },
|
||||||
|
};
|
||||||
|
});
|
||||||
|
await this.pageService.removePageFromFavorites(workspaceSlug, projectId, pageId);
|
||||||
|
} catch (error) {
|
||||||
|
runInAction(() => {
|
||||||
|
this.pages = {
|
||||||
|
...this.pages,
|
||||||
|
[pageId]: { ...this.pages[pageId], is_favorite: true },
|
||||||
|
};
|
||||||
|
});
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
import set from "lodash/set";
|
||||||
import { observable, action, makeObservable, runInAction } from "mobx";
|
import { observable, action, makeObservable, runInAction } from "mobx";
|
||||||
// services
|
// services
|
||||||
import { ViewService } from "services/view.service";
|
import { ViewService } from "services/view.service";
|
||||||
@ -60,7 +61,7 @@ export class ProjectViewsStore implements IProjectViewsStore {
|
|||||||
|
|
||||||
// observables
|
// observables
|
||||||
viewId: observable.ref,
|
viewId: observable.ref,
|
||||||
viewMap: observable.ref,
|
viewMap: observable,
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
fetchViews: action,
|
fetchViews: action,
|
||||||
@ -89,12 +90,10 @@ export class ProjectViewsStore implements IProjectViewsStore {
|
|||||||
|
|
||||||
const response = await this.viewService.getViews(workspaceSlug, projectId);
|
const response = await this.viewService.getViews(workspaceSlug, projectId);
|
||||||
|
|
||||||
|
const _viewMap = set(this.viewMap, [projectId], response);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.loader = false;
|
this.loader = false;
|
||||||
this.viewMap = {
|
this.viewMap = _viewMap;
|
||||||
...this.viewMap,
|
|
||||||
[projectId]: response,
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
@ -116,15 +115,10 @@ export class ProjectViewsStore implements IProjectViewsStore {
|
|||||||
|
|
||||||
const response = await this.viewService.getViewDetails(workspaceSlug, projectId, viewId);
|
const response = await this.viewService.getViewDetails(workspaceSlug, projectId, viewId);
|
||||||
|
|
||||||
|
const _viewMap = set(this.viewMap, [projectId, viewId], response);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.loader = false;
|
this.loader = false;
|
||||||
this.viewMap = {
|
this.viewMap = _viewMap;
|
||||||
...this.viewMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.viewMap[projectId],
|
|
||||||
[response.id]: response,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
@ -142,15 +136,10 @@ export class ProjectViewsStore implements IProjectViewsStore {
|
|||||||
try {
|
try {
|
||||||
const response = await this.viewService.createView(workspaceSlug, projectId, data);
|
const response = await this.viewService.createView(workspaceSlug, projectId, data);
|
||||||
|
|
||||||
|
const _viewMap = set(this.viewMap, [projectId, response.id], response);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.loader = false;
|
this.loader = false;
|
||||||
this.viewMap = {
|
this.viewMap = _viewMap;
|
||||||
...this.viewMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.viewMap[projectId],
|
|
||||||
[response.id]: response,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
@ -172,14 +161,9 @@ export class ProjectViewsStore implements IProjectViewsStore {
|
|||||||
try {
|
try {
|
||||||
const currentView = this.viewMap[projectId][viewId];
|
const currentView = this.viewMap[projectId][viewId];
|
||||||
|
|
||||||
|
const _viewMap = set(this.viewMap, [projectId, viewId], { ...currentView, ...data });
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.viewMap = {
|
this.viewMap = _viewMap;
|
||||||
...this.viewMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.viewMap[projectId],
|
|
||||||
[viewId]: { ...currentView, ...data },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = await this.viewService.patchView(workspaceSlug, projectId, viewId, data);
|
const response = await this.viewService.patchView(workspaceSlug, projectId, viewId, data);
|
||||||
@ -201,11 +185,9 @@ export class ProjectViewsStore implements IProjectViewsStore {
|
|||||||
const currentProjectViews = this.viewMap[projectId];
|
const currentProjectViews = this.viewMap[projectId];
|
||||||
delete currentProjectViews[viewId];
|
delete currentProjectViews[viewId];
|
||||||
|
|
||||||
|
const _viewMap = set(this.viewMap, [projectId], currentProjectViews);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.viewMap = {
|
this.viewMap = _viewMap;
|
||||||
...this.viewMap,
|
|
||||||
[projectId]: currentProjectViews,
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.viewService.deleteView(workspaceSlug, projectId, viewId);
|
await this.viewService.deleteView(workspaceSlug, projectId, viewId);
|
||||||
@ -226,14 +208,9 @@ export class ProjectViewsStore implements IProjectViewsStore {
|
|||||||
|
|
||||||
if (currentView.is_favorite) return;
|
if (currentView.is_favorite) return;
|
||||||
|
|
||||||
|
const _viewMap = set(this.viewMap, [projectId, viewId, "is_favorite"], true);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.viewMap = {
|
this.viewMap = _viewMap;
|
||||||
...this.viewMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.viewMap[projectId],
|
|
||||||
[viewId]: { ...currentView, is_favorite: true },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.viewService.addViewToFavorites(workspaceSlug, projectId, {
|
await this.viewService.addViewToFavorites(workspaceSlug, projectId, {
|
||||||
@ -242,15 +219,9 @@ export class ProjectViewsStore implements IProjectViewsStore {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to add view to favorites in view store", error);
|
console.error("Failed to add view to favorites in view store", error);
|
||||||
|
|
||||||
const currentView = this.viewMap[projectId][viewId];
|
const _viewMap = set(this.viewMap, [projectId, viewId, "is_favorite"], false);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.viewMap = {
|
this.viewMap = _viewMap;
|
||||||
...this.viewMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.viewMap[projectId],
|
|
||||||
[viewId]: { ...currentView, is_favorite: false },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -261,29 +232,18 @@ export class ProjectViewsStore implements IProjectViewsStore {
|
|||||||
|
|
||||||
if (!currentView.is_favorite) return;
|
if (!currentView.is_favorite) return;
|
||||||
|
|
||||||
|
const _viewMap = set(this.viewMap, [projectId, viewId, "is_favorite"], false);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.viewMap = {
|
this.viewMap = _viewMap;
|
||||||
...this.viewMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.viewMap[projectId],
|
|
||||||
[viewId]: { ...currentView, is_favorite: false },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.viewService.removeViewFromFavorites(workspaceSlug, projectId, viewId);
|
await this.viewService.removeViewFromFavorites(workspaceSlug, projectId, viewId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to remove view from favorites in view store", error);
|
console.error("Failed to remove view from favorites in view store", error);
|
||||||
|
|
||||||
const currentView = this.viewMap[projectId][viewId];
|
const _viewMap = set(this.viewMap, [projectId, viewId, "is_favorite"], true);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.viewMap = {
|
this.viewMap = _viewMap;
|
||||||
...this.viewMap,
|
|
||||||
[projectId]: {
|
|
||||||
...this.viewMap[projectId],
|
|
||||||
[viewId]: { ...currentView, is_favorite: true },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { observable, action, makeObservable, runInAction } from "mobx";
|
import { observable, action, makeObservable, runInAction } from "mobx";
|
||||||
|
import set from "lodash/set";
|
||||||
// types
|
// types
|
||||||
import { ProjectRootStore } from "./";
|
import { ProjectRootStore } from "./";
|
||||||
// services
|
// services
|
||||||
@ -57,12 +58,12 @@ export class ProjectPublishStore implements IProjectPublishStore {
|
|||||||
constructor(_projectRootStore: ProjectRootStore) {
|
constructor(_projectRootStore: ProjectRootStore) {
|
||||||
makeObservable(this, {
|
makeObservable(this, {
|
||||||
// states
|
// states
|
||||||
generalLoader: observable,
|
generalLoader: observable.ref,
|
||||||
fetchSettingsLoader: observable,
|
fetchSettingsLoader: observable.ref,
|
||||||
error: observable,
|
error: observable.ref,
|
||||||
|
|
||||||
// observables
|
// observables
|
||||||
project_id: observable,
|
project_id: observable.ref,
|
||||||
projectPublishSettings: observable.ref,
|
projectPublishSettings: observable.ref,
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
@ -147,18 +148,14 @@ export class ProjectPublishStore implements IProjectPublishStore {
|
|||||||
project: response?.project || null,
|
project: response?.project || null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const _projectMap = set(
|
||||||
|
this.projectRootStore.projects.projectMap,
|
||||||
|
[workspaceSlug, projectId, "is_deployed"],
|
||||||
|
true
|
||||||
|
);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.projectPublishSettings = _projectPublishSettings;
|
this.projectPublishSettings = _projectPublishSettings;
|
||||||
this.projectRootStore.projects.projectsMap = {
|
this.projectRootStore.projects.projectMap = _projectMap;
|
||||||
...this.projectRootStore.projects.projectsMap,
|
|
||||||
[workspaceSlug]: {
|
|
||||||
...this.projectRootStore.projects.projectsMap[workspaceSlug],
|
|
||||||
[projectId]: {
|
|
||||||
...this.projectRootStore.projects.projectsMap[workspaceSlug][projectId],
|
|
||||||
is_deployed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
this.generalLoader = false;
|
this.generalLoader = false;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
});
|
});
|
||||||
@ -236,18 +233,14 @@ export class ProjectPublishStore implements IProjectPublishStore {
|
|||||||
projectPublishId
|
projectPublishId
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const _projectMap = set(
|
||||||
|
this.projectRootStore.projects.projectMap,
|
||||||
|
[workspaceSlug, projectId, "is_deployed"],
|
||||||
|
false
|
||||||
|
);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.projectPublishSettings = "not-initialized";
|
this.projectPublishSettings = "not-initialized";
|
||||||
this.projectRootStore.projects.projectsMap = {
|
this.projectRootStore.projects.projectMap = _projectMap;
|
||||||
...this.projectRootStore.projects.projectsMap,
|
|
||||||
[workspaceSlug]: {
|
|
||||||
...this.projectRootStore.projects.projectsMap[workspaceSlug],
|
|
||||||
[projectId]: {
|
|
||||||
...this.projectRootStore.projects.projectsMap[workspaceSlug][projectId],
|
|
||||||
is_deployed: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
this.generalLoader = false;
|
this.generalLoader = false;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
});
|
});
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
import set from "lodash/set";
|
||||||
import { observable, action, computed, makeObservable, runInAction } from "mobx";
|
import { observable, action, computed, makeObservable, runInAction } from "mobx";
|
||||||
|
//types
|
||||||
|
import { RootStore } from "../root.store";
|
||||||
|
import { IProject } from "types";
|
||||||
|
//services
|
||||||
import { IssueLabelService, IssueService } from "services/issue";
|
import { IssueLabelService, IssueService } from "services/issue";
|
||||||
import { ProjectService, ProjectStateService } from "services/project";
|
import { ProjectService, ProjectStateService } from "services/project";
|
||||||
import { RootStore } from "store/root.store";
|
|
||||||
|
|
||||||
import { IProject } from "types";
|
|
||||||
|
|
||||||
export interface IProjectsStore {
|
export interface IProjectsStore {
|
||||||
loader: boolean;
|
loader: boolean;
|
||||||
@ -11,7 +13,7 @@ export interface IProjectsStore {
|
|||||||
|
|
||||||
searchQuery: string;
|
searchQuery: string;
|
||||||
projectId: string | null;
|
projectId: string | null;
|
||||||
projectsMap: {
|
projectMap: {
|
||||||
[workspaceSlug: string]: {
|
[workspaceSlug: string]: {
|
||||||
[projectId: string]: IProject; // projectId: project Info
|
[projectId: string]: IProject; // projectId: project Info
|
||||||
};
|
};
|
||||||
@ -48,11 +50,11 @@ export class ProjectsStore implements IProjectsStore {
|
|||||||
|
|
||||||
projectId: string | null = null;
|
projectId: string | null = null;
|
||||||
searchQuery: string = "";
|
searchQuery: string = "";
|
||||||
projectsMap: {
|
projectMap: {
|
||||||
[workspaceSlug: string]: {
|
[workspaceSlug: string]: {
|
||||||
[projectId: string]: IProject; // projectId: project Info
|
[projectId: string]: IProject; // projectId: project Info
|
||||||
};
|
};
|
||||||
};
|
} = {};
|
||||||
|
|
||||||
// root store
|
// root store
|
||||||
rootStore: RootStore;
|
rootStore: RootStore;
|
||||||
@ -65,12 +67,12 @@ export class ProjectsStore implements IProjectsStore {
|
|||||||
constructor(_rootStore: RootStore) {
|
constructor(_rootStore: RootStore) {
|
||||||
makeObservable(this, {
|
makeObservable(this, {
|
||||||
// observable
|
// observable
|
||||||
loader: observable,
|
loader: observable.ref,
|
||||||
error: observable,
|
error: observable.ref,
|
||||||
|
|
||||||
searchQuery: observable.ref,
|
searchQuery: observable.ref,
|
||||||
projectId: observable.ref,
|
projectId: observable.ref,
|
||||||
projectsMap: observable.ref,
|
projectMap: observable,
|
||||||
|
|
||||||
// computed
|
// computed
|
||||||
searchedProjects: computed,
|
searchedProjects: computed,
|
||||||
@ -104,48 +106,48 @@ export class ProjectsStore implements IProjectsStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get searchedProjects() {
|
get searchedProjects() {
|
||||||
if (!this.rootStore.app.router.query.workspaceSlug) return [];
|
if (!this.rootStore.app.router.workspaceSlug) return [];
|
||||||
|
|
||||||
const currentProjectsMap = this.projectsMap[this.rootStore.app.router.query.workspaceSlug.toString()];
|
const currentProjectMap = this.projectMap[this.rootStore.app.router.workspaceSlug];
|
||||||
const projectIds = Object.keys(currentProjectsMap);
|
const projectIds = Object.keys(currentProjectMap);
|
||||||
return this.searchQuery === ""
|
return this.searchQuery === ""
|
||||||
? projectIds
|
? projectIds
|
||||||
: projectIds?.filter((projectId) => {
|
: projectIds?.filter((projectId) => {
|
||||||
currentProjectsMap[projectId].name.toLowerCase().includes(this.searchQuery.toLowerCase()) ||
|
currentProjectMap[projectId].name.toLowerCase().includes(this.searchQuery.toLowerCase()) ||
|
||||||
currentProjectsMap[projectId].identifier.toLowerCase().includes(this.searchQuery.toLowerCase());
|
currentProjectMap[projectId].identifier.toLowerCase().includes(this.searchQuery.toLowerCase());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get workspaceProjects() {
|
get workspaceProjects() {
|
||||||
if (!this.rootStore.app.router.workspaceSlug) return null;
|
if (!this.rootStore.app.router.workspaceSlug) return null;
|
||||||
const currentProjectsMap = this.projectsMap[this.rootStore.app.router.query.workspaceSlug.toString()];
|
const currentProjectMap = this.projectMap[this.rootStore.app.router.workspaceSlug];
|
||||||
|
|
||||||
const projectIds = Object.keys(currentProjectsMap);
|
const projectIds = Object.keys(currentProjectMap);
|
||||||
if (!projectIds) return null;
|
if (!projectIds) return null;
|
||||||
return projectIds;
|
return projectIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
get currentProjectDetails() {
|
get currentProjectDetails() {
|
||||||
if (!this.rootStore.app.router.query.projectId || !this.rootStore.app.router.query.workspaceSlug) return;
|
if (!this.rootStore.app.router.projectId || !this.rootStore.app.router.workspaceSlug) return;
|
||||||
return this.projectsMap[!this.rootStore.app.router.query.workspaceSlug][this.projectId];
|
return this.projectMap[this.rootStore.app.router.workspaceSlug][this.rootStore.app.router.projectId];
|
||||||
}
|
}
|
||||||
|
|
||||||
get joinedProjects() {
|
get joinedProjects() {
|
||||||
if (!this.rootStore.workspace.workspaceSlug) return [];
|
if (!this.rootStore.app.router.workspaceSlug) return [];
|
||||||
|
|
||||||
const currentProjectsMap = this.projectsMap[this.rootStore.workspace.workspaceSlug];
|
const currentProjectMap = this.projectMap[this.rootStore.app.router.workspaceSlug];
|
||||||
const projectIds = Object.keys(currentProjectsMap);
|
const projectIds = Object.keys(currentProjectMap);
|
||||||
|
|
||||||
return projectIds?.filter((projectId) => currentProjectsMap[projectId].is_member);
|
return projectIds?.filter((projectId) => currentProjectMap[projectId].is_member);
|
||||||
}
|
}
|
||||||
|
|
||||||
get favoriteProjects() {
|
get favoriteProjects() {
|
||||||
if (!this.rootStore.workspace.workspaceSlug) return [];
|
if (!this.rootStore.app.router.workspaceSlug) return [];
|
||||||
|
|
||||||
const currentProjectsMap = this.projectsMap[this.rootStore.workspace.workspaceSlug];
|
const currentProjectMap = this.projectMap[this.rootStore.app.router.workspaceSlug];
|
||||||
const projectIds = Object.keys(currentProjectsMap);
|
const projectIds = Object.keys(currentProjectMap);
|
||||||
|
|
||||||
return projectIds?.filter((projectId) => currentProjectsMap[projectId].is_favorite);
|
return projectIds?.filter((projectId) => currentProjectMap[projectId].is_favorite);
|
||||||
}
|
}
|
||||||
|
|
||||||
setSearchQuery = (query: string) => {
|
setSearchQuery = (query: string) => {
|
||||||
@ -160,12 +162,11 @@ export class ProjectsStore implements IProjectsStore {
|
|||||||
*/
|
*/
|
||||||
fetchProjects = async (workspaceSlug: string) => {
|
fetchProjects = async (workspaceSlug: string) => {
|
||||||
try {
|
try {
|
||||||
const currentProjectsMap = await this.projectService.getProjects(workspaceSlug);
|
const currentProjectMap = await this.projectService.getProjects(workspaceSlug);
|
||||||
|
|
||||||
|
const _projectMap = set(this.projectMap, [workspaceSlug], currentProjectMap);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.projectsMap = {
|
this.projectMap = _projectMap;
|
||||||
...this.projectsMap,
|
|
||||||
[workspaceSlug]: currentProjectsMap,
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Failed to fetch project from workspace store");
|
console.log("Failed to fetch project from workspace store");
|
||||||
@ -177,14 +178,9 @@ export class ProjectsStore implements IProjectsStore {
|
|||||||
try {
|
try {
|
||||||
const response = await this.projectService.getProject(workspaceSlug, projectId);
|
const response = await this.projectService.getProject(workspaceSlug, projectId);
|
||||||
|
|
||||||
|
const _projectMap = set(this.projectMap, [workspaceSlug, projectId], response);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.projectsMap = {
|
this.projectMap = _projectMap;
|
||||||
...this.projectsMap,
|
|
||||||
[workspaceSlug]: {
|
|
||||||
...this.projectsMap[workspaceSlug],
|
|
||||||
[projectId]: response,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
return response;
|
return response;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -194,48 +190,47 @@ export class ProjectsStore implements IProjectsStore {
|
|||||||
};
|
};
|
||||||
|
|
||||||
getProjectById = (workspaceSlug: string, projectId: string) => {
|
getProjectById = (workspaceSlug: string, projectId: string) => {
|
||||||
const currentProjectsMap = this.projectsMap?.[workspaceSlug];
|
const currentProjectMap = this.projectMap?.[workspaceSlug];
|
||||||
if (!currentProjectsMap) return null;
|
if (!currentProjectMap) return null;
|
||||||
|
|
||||||
const projectInfo: IProject | null = currentProjectsMap[projectId] || null;
|
const projectInfo: IProject | null = currentProjectMap[projectId] || null;
|
||||||
return projectInfo;
|
return projectInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
addProjectToFavorites = async (workspaceSlug: string, projectId: string) => {
|
addProjectToFavorites = async (workspaceSlug: string, projectId: string) => {
|
||||||
try {
|
try {
|
||||||
const currentProject = this.projectsMap?.[workspaceSlug]?.[projectId];
|
const currentProject = this.projectMap?.[workspaceSlug]?.[projectId];
|
||||||
|
|
||||||
|
if (currentProject.is_favorite) return;
|
||||||
|
|
||||||
|
const _projectMap = set(this.projectMap, [workspaceSlug, projectId, "is_favorite"], true);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.projectsMap = {
|
this.projectMap = _projectMap;
|
||||||
...this.projectsMap,
|
|
||||||
[workspaceSlug]: {
|
|
||||||
...this.projectsMap[workspaceSlug],
|
|
||||||
[projectId]: { ...currentProject, is_favorite: true },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = await this.projectService.addProjectToFavorites(workspaceSlug, projectId);
|
const response = await this.projectService.addProjectToFavorites(workspaceSlug, projectId);
|
||||||
return response;
|
return response;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Failed to add project to favorite");
|
console.log("Failed to add project to favorite");
|
||||||
await this.fetchProjects(workspaceSlug);
|
|
||||||
|
const _projectMap = set(this.projectMap, [workspaceSlug, projectId, "is_favorite"], false);
|
||||||
|
runInAction(() => {
|
||||||
|
this.projectMap = _projectMap;
|
||||||
|
});
|
||||||
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
removeProjectFromFavorites = async (workspaceSlug: string, projectId: string) => {
|
removeProjectFromFavorites = async (workspaceSlug: string, projectId: string) => {
|
||||||
try {
|
try {
|
||||||
const currentProject = this.projectsMap?.[workspaceSlug]?.[projectId];
|
const currentProject = this.projectMap?.[workspaceSlug]?.[projectId];
|
||||||
|
|
||||||
|
if (!currentProject.is_favorite) return;
|
||||||
|
|
||||||
|
const _projectMap = set(this.projectMap, [workspaceSlug, projectId, "is_favorite"], false);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.projectsMap = {
|
this.projectMap = _projectMap;
|
||||||
...this.projectsMap,
|
|
||||||
[workspaceSlug]: {
|
|
||||||
...this.projectsMap[workspaceSlug],
|
|
||||||
[projectId]: { ...currentProject, is_favorite: false },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = await this.projectService.removeProjectFromFavorites(workspaceSlug, projectId);
|
const response = await this.projectService.removeProjectFromFavorites(workspaceSlug, projectId);
|
||||||
@ -243,16 +238,21 @@ export class ProjectsStore implements IProjectsStore {
|
|||||||
return response;
|
return response;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Failed to add project to favorite");
|
console.log("Failed to add project to favorite");
|
||||||
|
|
||||||
|
const _projectMap = set(this.projectMap, [workspaceSlug, projectId, "is_favorite"], true);
|
||||||
|
runInAction(() => {
|
||||||
|
this.projectMap = _projectMap;
|
||||||
|
});
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
orderProjectsWithSortOrder = (sortIndex: number, destinationIndex: number, projectId: string) => {
|
orderProjectsWithSortOrder = (sortIndex: number, destinationIndex: number, projectId: string) => {
|
||||||
try {
|
try {
|
||||||
const workspaceSlug = this.rootStore.workspace.workspaceSlug;
|
const workspaceSlug = this.rootStore.app.router.workspaceSlug;
|
||||||
if (!workspaceSlug) return 0;
|
if (!workspaceSlug) return 0;
|
||||||
|
|
||||||
const projectsList = Object.values(this.projectsMap[workspaceSlug] || {}) || [];
|
const projectsList = Object.values(this.projectMap[workspaceSlug] || {}) || [];
|
||||||
let updatedSortOrder = projectsList[sortIndex].sort_order;
|
let updatedSortOrder = projectsList[sortIndex].sort_order;
|
||||||
|
|
||||||
if (destinationIndex === 0) updatedSortOrder = (projectsList[0].sort_order as number) - 1000;
|
if (destinationIndex === 0) updatedSortOrder = (projectsList[0].sort_order as number) - 1000;
|
||||||
@ -268,16 +268,9 @@ export class ProjectsStore implements IProjectsStore {
|
|||||||
updatedSortOrder = (destinationSortingOrder + relativeDestinationSortingOrder) / 2;
|
updatedSortOrder = (destinationSortingOrder + relativeDestinationSortingOrder) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentProject = this.projectsMap?.[workspaceSlug]?.[projectId];
|
const _projectMap = set(this.projectMap, [workspaceSlug, projectId, "sort_order"], updatedSortOrder);
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.projectsMap = {
|
this.projectMap = _projectMap;
|
||||||
...this.projectsMap,
|
|
||||||
[workspaceSlug]: {
|
|
||||||
...this.projectsMap[workspaceSlug],
|
|
||||||
[projectId]: { ...currentProject, sort_order: updatedSortOrder },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return updatedSortOrder;
|
return updatedSortOrder;
|
||||||
@ -302,12 +295,12 @@ export class ProjectsStore implements IProjectsStore {
|
|||||||
createProject = async (workspaceSlug: string, data: any) => {
|
createProject = async (workspaceSlug: string, data: any) => {
|
||||||
try {
|
try {
|
||||||
const response = await this.projectService.createProject(workspaceSlug, data);
|
const response = await this.projectService.createProject(workspaceSlug, data);
|
||||||
|
|
||||||
|
const _projectMap = set(this.projectMap, [workspaceSlug, response.id], response);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.projectsMap = {
|
this.projectMap = _projectMap;
|
||||||
...this.projectsMap,
|
|
||||||
[workspaceSlug]: { ...this.projectsMap[workspaceSlug], [response.id]: response },
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Failed to create project from project store");
|
console.log("Failed to create project from project store");
|
||||||
@ -317,13 +310,11 @@ export class ProjectsStore implements IProjectsStore {
|
|||||||
|
|
||||||
updateProject = async (workspaceSlug: string, projectId: string, data: Partial<IProject>) => {
|
updateProject = async (workspaceSlug: string, projectId: string, data: Partial<IProject>) => {
|
||||||
try {
|
try {
|
||||||
const currentProject = this.projectsMap?.[workspaceSlug]?.[projectId];
|
const currentProject = this.projectMap?.[workspaceSlug]?.[projectId];
|
||||||
|
|
||||||
|
const _projectMap = set(this.projectMap, [workspaceSlug, projectId], { ...currentProject, ...data });
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.projectsMap = {
|
this.projectMap = _projectMap;
|
||||||
...this.projectsMap,
|
|
||||||
[workspaceSlug]: { ...this.projectsMap[workspaceSlug], [projectId]: { ...currentProject, ...data } },
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = await this.projectService.updateProject(workspaceSlug, projectId, data);
|
const response = await this.projectService.updateProject(workspaceSlug, projectId, data);
|
||||||
@ -339,15 +330,13 @@ export class ProjectsStore implements IProjectsStore {
|
|||||||
|
|
||||||
deleteProject = async (workspaceSlug: string, projectId: string) => {
|
deleteProject = async (workspaceSlug: string, projectId: string) => {
|
||||||
try {
|
try {
|
||||||
const workspaceProjects = { ...this.projectsMap[workspaceSlug] };
|
const workspaceProjects = { ...this.projectMap[workspaceSlug] };
|
||||||
|
|
||||||
delete workspaceProjects[projectId];
|
delete workspaceProjects[projectId];
|
||||||
|
|
||||||
|
const _projectMap = set(this.projectMap, [workspaceSlug], workspaceProjects);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.projectsMap = {
|
this.projectMap = _projectMap;
|
||||||
...this.projectsMap,
|
|
||||||
[workspaceSlug]: { ...workspaceProjects },
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.projectService.deleteProject(workspaceSlug, projectId);
|
await this.projectService.deleteProject(workspaceSlug, projectId);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { makeObservable, observable, computed, action, runInAction } from "mobx";
|
import { makeObservable, observable, computed, action, runInAction } from "mobx";
|
||||||
import groupBy from "lodash/groupBy";
|
import groupBy from "lodash/groupBy";
|
||||||
import keyBy from "lodash/keyBy";
|
import keyBy from "lodash/keyBy";
|
||||||
import omit from "lodash/omit";
|
import set from "lodash/set";
|
||||||
// store
|
// store
|
||||||
import { RootStore } from "./root.store";
|
import { RootStore } from "./root.store";
|
||||||
// types
|
// types
|
||||||
@ -10,20 +10,20 @@ import { IState } from "types";
|
|||||||
import { ProjectStateService } from "services/project";
|
import { ProjectStateService } from "services/project";
|
||||||
|
|
||||||
export interface IStateStore {
|
export interface IStateStore {
|
||||||
states: Record<string, IState>;
|
stateMap: Record<string, IState>;
|
||||||
projectStates: IState[] | undefined;
|
projectStates: IState[] | undefined;
|
||||||
groupedProjectStates: Record<string, IState[]> | undefined;
|
groupedProjectStates: Record<string, IState[]> | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class StateStore implements IStateStore {
|
export class StateStore implements IStateStore {
|
||||||
states: Record<string, IState> = {};
|
stateMap: Record<string, IState> = {};
|
||||||
router;
|
router;
|
||||||
stateService;
|
stateService;
|
||||||
|
|
||||||
constructor(_rootStore: RootStore) {
|
constructor(_rootStore: RootStore) {
|
||||||
makeObservable(this, {
|
makeObservable(this, {
|
||||||
// observables
|
// observables
|
||||||
states: observable.ref,
|
stateMap: observable,
|
||||||
// computed
|
// computed
|
||||||
projectStates: computed,
|
projectStates: computed,
|
||||||
groupedProjectStates: computed,
|
groupedProjectStates: computed,
|
||||||
@ -39,15 +39,15 @@ export class StateStore implements IStateStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the states belongs to a specific project
|
* Returns the stateMap belongs to a specific project
|
||||||
*/
|
*/
|
||||||
get projectStates() {
|
get projectStates() {
|
||||||
if (!this.router.query?.projectId) return;
|
if (!this.router.query?.projectId) return;
|
||||||
return Object.values(this.states).filter((state) => state.project === this.router.query.projectId);
|
return Object.values(this.stateMap).filter((state) => state.project === this.router.query.projectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the states belongs to a specific project grouped by group
|
* Returns the stateMap belongs to a specific project grouped by group
|
||||||
*/
|
*/
|
||||||
get groupedProjectStates() {
|
get groupedProjectStates() {
|
||||||
if (!this.router.query?.projectId) return;
|
if (!this.router.query?.projectId) return;
|
||||||
@ -55,29 +55,30 @@ export class StateStore implements IStateStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the states belongs to a project by projectId
|
* Returns the stateMap belongs to a project by projectId
|
||||||
* @param projectId
|
* @param projectId
|
||||||
* @returns IState[]
|
* @returns IState[]
|
||||||
*/
|
*/
|
||||||
getProjectStates(projectId: string) {
|
getProjectStates(projectId: string) {
|
||||||
return Object.values(this.states).filter((state) => state.project === projectId);
|
return Object.values(this.stateMap).filter((state) => state.project === projectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fetches the states of a project
|
* fetches the stateMap of a project
|
||||||
* @param workspaceSlug
|
* @param workspaceSlug
|
||||||
* @param projectId
|
* @param projectId
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
fetchProjectStates = async (workspaceSlug: string, projectId: string) => {
|
fetchProjectStates = async (workspaceSlug: string, projectId: string) => {
|
||||||
const states = await this.stateService.getStates(workspaceSlug, projectId);
|
const stateMap = await this.stateService.getStates(workspaceSlug, projectId);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.states = {
|
//todo add iteratively without modifying original reference
|
||||||
...this.states,
|
this.stateMap = {
|
||||||
...keyBy(states, "id"),
|
...this.stateMap,
|
||||||
|
...keyBy(stateMap, "id"),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
return states;
|
return stateMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -89,11 +90,10 @@ export class StateStore implements IStateStore {
|
|||||||
*/
|
*/
|
||||||
createState = async (workspaceSlug: string, projectId: string, data: Partial<IState>) => {
|
createState = async (workspaceSlug: string, projectId: string, data: Partial<IState>) => {
|
||||||
const response = await this.stateService.createState(workspaceSlug, projectId, data);
|
const response = await this.stateService.createState(workspaceSlug, projectId, data);
|
||||||
|
|
||||||
|
const _stateMap = set(this.stateMap, [response?.id], response);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.states = {
|
this.stateMap = _stateMap;
|
||||||
...this.states,
|
|
||||||
[response?.id]: response,
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
return response;
|
return response;
|
||||||
};
|
};
|
||||||
@ -107,20 +107,18 @@ export class StateStore implements IStateStore {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
updateState = async (workspaceSlug: string, projectId: string, stateId: string, data: Partial<IState>) => {
|
updateState = async (workspaceSlug: string, projectId: string, stateId: string, data: Partial<IState>) => {
|
||||||
const originalState = this.states[stateId];
|
const originalState = this.stateMap[stateId];
|
||||||
try {
|
try {
|
||||||
|
const _stateMap = set(this.stateMap, [stateId], { ...this.stateMap?.[stateId], ...data });
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.states = {
|
this.stateMap = _stateMap;
|
||||||
...this.states,
|
|
||||||
[stateId]: { ...this.states?.[stateId], ...data },
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
const response = await this.stateService.patchState(workspaceSlug, projectId, stateId, data);
|
const response = await this.stateService.patchState(workspaceSlug, projectId, stateId, data);
|
||||||
return response;
|
return response;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.states = {
|
this.stateMap = {
|
||||||
...this.states,
|
...this.stateMap,
|
||||||
[stateId]: originalState,
|
[stateId]: originalState,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@ -135,15 +133,18 @@ export class StateStore implements IStateStore {
|
|||||||
* @param stateId
|
* @param stateId
|
||||||
*/
|
*/
|
||||||
deleteState = async (workspaceSlug: string, projectId: string, stateId: string) => {
|
deleteState = async (workspaceSlug: string, projectId: string, stateId: string) => {
|
||||||
const originalStates = this.states;
|
const originalStates = this.stateMap;
|
||||||
try {
|
try {
|
||||||
|
const _stateMap = this.stateMap;
|
||||||
|
delete this.stateMap[stateId];
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.states = omit(this.states, stateId);
|
this.stateMap = _stateMap;
|
||||||
});
|
});
|
||||||
await this.stateService.deleteState(workspaceSlug, projectId, stateId);
|
await this.stateService.deleteState(workspaceSlug, projectId, stateId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.states = originalStates;
|
this.stateMap = originalStates;
|
||||||
});
|
});
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
@ -156,18 +157,17 @@ export class StateStore implements IStateStore {
|
|||||||
* @param stateId
|
* @param stateId
|
||||||
*/
|
*/
|
||||||
markStateAsDefault = async (workspaceSlug: string, projectId: string, stateId: string) => {
|
markStateAsDefault = async (workspaceSlug: string, projectId: string, stateId: string) => {
|
||||||
const originalStates = this.states;
|
const originalStates = this.stateMap;
|
||||||
try {
|
try {
|
||||||
|
const _stateMap = set(this.stateMap, [stateId, "default"], true);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.states = {
|
this.stateMap = _stateMap;
|
||||||
...this.states,
|
|
||||||
[stateId]: { ...this.states[stateId], default: true },
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.stateService.markDefault(workspaceSlug, projectId, stateId);
|
await this.stateService.markDefault(workspaceSlug, projectId, stateId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.states = originalStates;
|
this.stateMap = originalStates;
|
||||||
});
|
});
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
@ -189,12 +189,12 @@ export class StateStore implements IStateStore {
|
|||||||
groupIndex: number
|
groupIndex: number
|
||||||
) => {
|
) => {
|
||||||
const SEQUENCE_GAP = 15000;
|
const SEQUENCE_GAP = 15000;
|
||||||
const originalStates = this.states;
|
const originalStates = this.stateMap;
|
||||||
try {
|
try {
|
||||||
let newSequence = SEQUENCE_GAP;
|
let newSequence = SEQUENCE_GAP;
|
||||||
const states = this.projectStates || [];
|
const stateMap = this.projectStates || [];
|
||||||
const selectedState = states?.find((state) => state.id === stateId);
|
const selectedState = stateMap?.find((state) => state.id === stateId);
|
||||||
const groupStates = states?.filter((state) => state.group === selectedState?.group);
|
const groupStates = stateMap?.filter((state) => state.group === selectedState?.group);
|
||||||
const groupLength = groupStates.length;
|
const groupLength = groupStates.length;
|
||||||
if (direction === "up") {
|
if (direction === "up") {
|
||||||
if (groupIndex === 1) newSequence = groupStates[0].sequence - SEQUENCE_GAP;
|
if (groupIndex === 1) newSequence = groupStates[0].sequence - SEQUENCE_GAP;
|
||||||
@ -203,18 +203,18 @@ export class StateStore implements IStateStore {
|
|||||||
if (groupIndex === groupLength - 2) newSequence = groupStates[groupLength - 1].sequence + SEQUENCE_GAP;
|
if (groupIndex === groupLength - 2) newSequence = groupStates[groupLength - 1].sequence + SEQUENCE_GAP;
|
||||||
else newSequence = (groupStates[groupIndex + 2].sequence + groupStates[groupIndex + 1].sequence) / 2;
|
else newSequence = (groupStates[groupIndex + 2].sequence + groupStates[groupIndex + 1].sequence) / 2;
|
||||||
}
|
}
|
||||||
// updating using api
|
|
||||||
|
const _stateMap = set(this.stateMap, [stateId, "sequence"], newSequence);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.states = {
|
this.stateMap = _stateMap;
|
||||||
...this.states,
|
|
||||||
[stateId]: { ...this.states[stateId], sequence: newSequence },
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// updating using api
|
||||||
await this.stateService.patchState(workspaceSlug, projectId, stateId, { sequence: newSequence });
|
await this.stateService.patchState(workspaceSlug, projectId, stateId, { sequence: newSequence });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// reverting back to old state group if api fails
|
// reverting back to old state group if api fails
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.states = originalStates;
|
this.stateMap = originalStates;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -87,33 +87,33 @@ export class UserMembershipStore implements IUserMembershipStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get currentWorkspaceMemberInfo() {
|
get currentWorkspaceMemberInfo() {
|
||||||
if (!this.router.query?.workspaceSlug) return;
|
if (!this.router.workspaceSlug) return;
|
||||||
return this.workspaceMemberInfo[this.router.query?.workspaceSlug];
|
return this.workspaceMemberInfo[this.router.workspaceSlug];
|
||||||
}
|
}
|
||||||
|
|
||||||
get currentWorkspaceRole() {
|
get currentWorkspaceRole() {
|
||||||
if (!this.router.query?.workspaceSlug) return;
|
if (!this.router.workspaceSlug) return;
|
||||||
return this.workspaceMemberInfo[this.router.query?.workspaceSlug]?.role;
|
return this.workspaceMemberInfo[this.router.workspaceSlug]?.role;
|
||||||
}
|
}
|
||||||
|
|
||||||
get currentProjectMemberInfo() {
|
get currentProjectMemberInfo() {
|
||||||
if (!this.router.query?.projectId) return;
|
if (!this.router.projectId) return;
|
||||||
return this.projectMemberInfo[this.router.query?.projectId];
|
return this.projectMemberInfo[this.router.projectId];
|
||||||
}
|
}
|
||||||
|
|
||||||
get currentProjectRole() {
|
get currentProjectRole() {
|
||||||
if (!this.router.query?.projectId) return;
|
if (!this.router.projectId) return;
|
||||||
return this.projectMemberInfo[this.router.query?.projectId]?.role;
|
return this.projectMemberInfo[this.router.projectId]?.role;
|
||||||
}
|
}
|
||||||
|
|
||||||
get hasPermissionToCurrentWorkspace() {
|
get hasPermissionToCurrentWorkspace() {
|
||||||
if (!this.router.query?.workspaceSlug) return;
|
if (!this.router.workspaceSlug) return;
|
||||||
return this.hasPermissionToWorkspace[this.router.query?.workspaceSlug];
|
return this.hasPermissionToWorkspace[this.router.workspaceSlug];
|
||||||
}
|
}
|
||||||
|
|
||||||
get hasPermissionToCurrentProject() {
|
get hasPermissionToCurrentProject() {
|
||||||
if (!this.router.query?.projectId) return;
|
if (!this.router.projectId) return;
|
||||||
return this.hasPermissionToProject[this.router.query?.projectId];
|
return this.hasPermissionToProject[this.router.projectId];
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchUserWorkspaceInfo = async (workspaceSlug: string) => {
|
fetchUserWorkspaceInfo = async (workspaceSlug: string) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user