fix: project loaders for mobx store (#3356)
* add loaders to all the dropdowns outside project wrpper * fix build errors * minor refactor for project states color --------- Co-authored-by: Rahul R <rahulr@Rahuls-MacBook-Pro.local>
This commit is contained in:
parent
151c355177
commit
9789068880
11 changed files with 112 additions and 53 deletions
|
|
@ -12,6 +12,8 @@ import { IssueService } from "services/issue";
|
|||
import { CycleService } from "services/cycle.service";
|
||||
|
||||
export interface ICycleStore {
|
||||
//Loaders
|
||||
fetchedMap: Record<string, boolean>;
|
||||
// observables
|
||||
cycleMap: Record<string, ICycle>;
|
||||
activeCycleIdMap: Record<string, boolean>;
|
||||
|
|
@ -50,6 +52,8 @@ export class CycleStore implements ICycleStore {
|
|||
// observables
|
||||
cycleMap: Record<string, ICycle> = {};
|
||||
activeCycleIdMap: Record<string, boolean> = {};
|
||||
//loaders
|
||||
fetchedMap: Record<string, boolean> = {};
|
||||
// root store
|
||||
rootStore;
|
||||
// services
|
||||
|
|
@ -62,6 +66,7 @@ export class CycleStore implements ICycleStore {
|
|||
// observables
|
||||
cycleMap: observable,
|
||||
activeCycleIdMap: observable,
|
||||
fetchedMap: observable,
|
||||
// computed
|
||||
currentProjectCycleIds: computed,
|
||||
currentProjectCompletedCycleIds: computed,
|
||||
|
|
@ -96,11 +101,11 @@ export class CycleStore implements ICycleStore {
|
|||
*/
|
||||
get currentProjectCycleIds() {
|
||||
const projectId = this.rootStore.app.router.projectId;
|
||||
if (!projectId) return null;
|
||||
if (!projectId || !this.fetchedMap[projectId]) return null;
|
||||
let allCycles = Object.values(this.cycleMap ?? {}).filter((c) => c?.project === projectId);
|
||||
allCycles = sortBy(allCycles, [(c) => !c.is_favorite, (c) => c.name.toLowerCase()]);
|
||||
const allCycleIds = allCycles.map((c) => c.id);
|
||||
return allCycleIds || null;
|
||||
return allCycleIds;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -108,14 +113,14 @@ export class CycleStore implements ICycleStore {
|
|||
*/
|
||||
get currentProjectCompletedCycleIds() {
|
||||
const projectId = this.rootStore.app.router.projectId;
|
||||
if (!projectId) return null;
|
||||
if (!projectId || !this.fetchedMap[projectId]) return null;
|
||||
let completedCycles = Object.values(this.cycleMap ?? {}).filter((c) => {
|
||||
const hasEndDatePassed = isPast(new Date(c.end_date ?? ""));
|
||||
return c.project === projectId && hasEndDatePassed;
|
||||
});
|
||||
completedCycles = sortBy(completedCycles, [(c) => !c.is_favorite, (c) => c.name.toLowerCase()]);
|
||||
const completedCycleIds = completedCycles.map((c) => c.id);
|
||||
return completedCycleIds || null;
|
||||
return completedCycleIds;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -123,14 +128,14 @@ export class CycleStore implements ICycleStore {
|
|||
*/
|
||||
get currentProjectUpcomingCycleIds() {
|
||||
const projectId = this.rootStore.app.router.projectId;
|
||||
if (!projectId) return null;
|
||||
if (!projectId || !this.fetchedMap[projectId]) return null;
|
||||
let upcomingCycles = Object.values(this.cycleMap ?? {}).filter((c) => {
|
||||
const isStartDateUpcoming = isFuture(new Date(c.start_date ?? ""));
|
||||
return c.project === projectId && isStartDateUpcoming;
|
||||
});
|
||||
upcomingCycles = sortBy(upcomingCycles, [(c) => !c.is_favorite, (c) => c.name.toLowerCase()]);
|
||||
const upcomingCycleIds = upcomingCycles.map((c) => c.id);
|
||||
return upcomingCycleIds || null;
|
||||
return upcomingCycleIds;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -138,14 +143,14 @@ export class CycleStore implements ICycleStore {
|
|||
*/
|
||||
get currentProjectIncompleteCycleIds() {
|
||||
const projectId = this.rootStore.app.router.projectId;
|
||||
if (!projectId) return null;
|
||||
if (!projectId || !this.fetchedMap[projectId]) return null;
|
||||
let incompleteCycles = Object.values(this.cycleMap ?? {}).filter((c) => {
|
||||
const hasEndDatePassed = isPast(new Date(c.end_date ?? ""));
|
||||
return c.project === projectId && !hasEndDatePassed;
|
||||
});
|
||||
incompleteCycles = sortBy(incompleteCycles, [(c) => !c.is_favorite, (c) => c.name.toLowerCase()]);
|
||||
const incompleteCycleIds = incompleteCycles.map((c) => c.id);
|
||||
return incompleteCycleIds || null;
|
||||
return incompleteCycleIds;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -153,13 +158,13 @@ export class CycleStore implements ICycleStore {
|
|||
*/
|
||||
get currentProjectDraftCycleIds() {
|
||||
const projectId = this.rootStore.app.router.projectId;
|
||||
if (!projectId) return null;
|
||||
if (!projectId || !this.fetchedMap[projectId]) return null;
|
||||
let draftCycles = Object.values(this.cycleMap ?? {}).filter(
|
||||
(c) => c.project === projectId && !c.start_date && !c.end_date
|
||||
);
|
||||
draftCycles = sortBy(draftCycles, [(c) => !c.is_favorite, (c) => c.name.toLowerCase()]);
|
||||
const draftCycleIds = draftCycles.map((c) => c.id);
|
||||
return draftCycleIds || null;
|
||||
return draftCycleIds;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -194,6 +199,8 @@ export class CycleStore implements ICycleStore {
|
|||
* @param projectId
|
||||
*/
|
||||
getProjectCycleIds = (projectId: string): string[] | null => {
|
||||
if (!this.fetchedMap[projectId]) return null;
|
||||
|
||||
let cycles = Object.values(this.cycleMap ?? {}).filter((c) => c.project === projectId);
|
||||
cycles = sortBy(cycles, [(c) => !c.is_favorite, (c) => c.name.toLowerCase()]);
|
||||
const cycleIds = cycles.map((c) => c.id);
|
||||
|
|
@ -222,6 +229,7 @@ export class CycleStore implements ICycleStore {
|
|||
response.forEach((cycle) => {
|
||||
set(this.cycleMap, [cycle.id], cycle);
|
||||
});
|
||||
set(this.fetchedMap, projectId, true);
|
||||
});
|
||||
return response;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { action, computed, makeObservable, runInAction } from "mobx";
|
||||
import { action, computed, makeObservable, observable, runInAction } from "mobx";
|
||||
import set from "lodash/set";
|
||||
// services
|
||||
import { IssueLabelService } from "services/issue";
|
||||
|
|
@ -10,9 +10,13 @@ import { IIssueLabel, IIssueLabelTree } from "@plane/types";
|
|||
import { ILabelRootStore } from "store/label";
|
||||
|
||||
export interface IProjectLabelStore {
|
||||
//Loaders
|
||||
fetchedMap: Record<string, boolean>;
|
||||
// computed
|
||||
projectLabels: IIssueLabel[] | undefined;
|
||||
projectLabelsTree: IIssueLabelTree[] | undefined;
|
||||
//computed actions
|
||||
getProjectLabels: (projectId: string) => IIssueLabel[] | undefined;
|
||||
// fetch actions
|
||||
fetchProjectLabels: (workspaceSlug: string, projectId: string) => Promise<IIssueLabel[]>;
|
||||
// crud actions
|
||||
|
|
@ -40,15 +44,21 @@ export class ProjectLabelStore implements IProjectLabelStore {
|
|||
rootStore;
|
||||
// root store labelMap
|
||||
labelMap: Record<string, IIssueLabel> = {};
|
||||
//loaders
|
||||
fetchedMap: Record<string, boolean> = {};
|
||||
// services
|
||||
issueLabelService;
|
||||
|
||||
constructor(_labelRoot: ILabelRootStore, _rootStore: RootStore) {
|
||||
makeObservable(this, {
|
||||
labelMap: observable,
|
||||
fetchedMap: observable,
|
||||
// computed
|
||||
projectLabels: computed,
|
||||
projectLabelsTree: computed,
|
||||
// actions
|
||||
getProjectLabels: action,
|
||||
|
||||
fetchProjectLabels: action,
|
||||
createLabel: action,
|
||||
updateLabel: action,
|
||||
|
|
@ -68,7 +78,7 @@ export class ProjectLabelStore implements IProjectLabelStore {
|
|||
*/
|
||||
get projectLabels() {
|
||||
const projectId = this.rootStore.app.router.projectId;
|
||||
if (!projectId || !this.labelMap) return;
|
||||
if (!projectId || !this.fetchedMap[projectId] || !this.labelMap) return;
|
||||
return Object.values(this.labelMap ?? {}).filter((label) => label.project === projectId);
|
||||
}
|
||||
|
||||
|
|
@ -80,6 +90,11 @@ export class ProjectLabelStore implements IProjectLabelStore {
|
|||
return buildTree(this.projectLabels);
|
||||
}
|
||||
|
||||
getProjectLabels = (projectId: string) => {
|
||||
if (!this.fetchedMap[projectId] || !this.labelMap) return;
|
||||
return Object.values(this.labelMap ?? {}).filter((label) => label.project === projectId);
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetches all the labelMap belongs to a specific project
|
||||
* @param workspaceSlug
|
||||
|
|
@ -92,6 +107,7 @@ export class ProjectLabelStore implements IProjectLabelStore {
|
|||
response.forEach((label) => {
|
||||
set(this.labelMap, [label.id], label);
|
||||
});
|
||||
set(this.fetchedMap, projectId, true);
|
||||
});
|
||||
return response;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -120,7 +120,8 @@ export class ProjectMemberStore implements IProjectMemberStore {
|
|||
* @param projectId
|
||||
*/
|
||||
getProjectMemberIds = (projectId: string): string[] | null => {
|
||||
let members = Object.values(this.projectMemberMap?.[projectId] ?? {});
|
||||
if (!this.projectMemberMap?.[projectId]) return null;
|
||||
let members = Object.values(this.projectMemberMap?.[projectId]);
|
||||
members = sortBy(members, [
|
||||
(m) => m.member !== this.userStore.currentUser?.id,
|
||||
(m) => this.memberRoot?.memberMap?.[m.member]?.display_name?.toLowerCase(),
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import { IModule, ILinkDetails } from "@plane/types";
|
|||
import { RootStore } from "store/root.store";
|
||||
|
||||
export interface IModuleStore {
|
||||
//Loaders
|
||||
fetchedMap: Record<string, boolean>;
|
||||
// observables
|
||||
moduleMap: Record<string, IModule>;
|
||||
// computed
|
||||
|
|
@ -51,6 +53,8 @@ export interface IModuleStore {
|
|||
export class ModulesStore implements IModuleStore {
|
||||
// observables
|
||||
moduleMap: Record<string, IModule> = {};
|
||||
//loaders
|
||||
fetchedMap: Record<string, boolean> = {};
|
||||
// root store
|
||||
rootStore;
|
||||
// services
|
||||
|
|
@ -61,6 +65,7 @@ export class ModulesStore implements IModuleStore {
|
|||
makeObservable(this, {
|
||||
// observables
|
||||
moduleMap: observable,
|
||||
fetchedMap: observable,
|
||||
// computed
|
||||
projectModuleIds: computed,
|
||||
// computed actions
|
||||
|
|
@ -92,7 +97,7 @@ export class ModulesStore implements IModuleStore {
|
|||
*/
|
||||
get projectModuleIds() {
|
||||
const projectId = this.rootStore.app.router.projectId;
|
||||
if (!projectId) return null;
|
||||
if (!projectId || !this.fetchedMap[projectId]) return null;
|
||||
let projectModules = Object.values(this.moduleMap).filter((m) => m.project === projectId);
|
||||
projectModules = sortBy(projectModules, [(m) => !m.is_favorite, (m) => m.name.toLowerCase()]);
|
||||
const projectModuleIds = projectModules.map((m) => m.id);
|
||||
|
|
@ -111,10 +116,12 @@ export class ModulesStore implements IModuleStore {
|
|||
* @param projectId
|
||||
*/
|
||||
getProjectModuleIds = (projectId: string) => {
|
||||
if (!this.fetchedMap[projectId]) return null;
|
||||
|
||||
let projectModules = Object.values(this.moduleMap).filter((m) => m.project === projectId);
|
||||
projectModules = sortBy(projectModules, [(m) => !m.is_favorite, (m) => m.name.toLowerCase()]);
|
||||
const projectModuleIds = projectModules.map((m) => m.id);
|
||||
return projectModuleIds || null;
|
||||
return projectModuleIds;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -129,6 +136,7 @@ export class ModulesStore implements IModuleStore {
|
|||
response.forEach((module) => {
|
||||
set(this.moduleMap, [module.id], { ...this.moduleMap[module.id], ...module });
|
||||
});
|
||||
set(this.fetchedMap, projectId, true);
|
||||
});
|
||||
return response;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ import { RootStore } from "store/root.store";
|
|||
import { IProjectView } from "@plane/types";
|
||||
|
||||
export interface IProjectViewStore {
|
||||
//Loaders
|
||||
fetchedMap: Record<string, boolean>;
|
||||
// observables
|
||||
viewMap: Record<string, IProjectView>;
|
||||
// computed
|
||||
|
|
@ -33,6 +35,8 @@ export interface IProjectViewStore {
|
|||
export class ProjectViewStore implements IProjectViewStore {
|
||||
// observables
|
||||
viewMap: Record<string, IProjectView> = {};
|
||||
//loaders
|
||||
fetchedMap: Record<string, boolean> = {};
|
||||
// root store
|
||||
rootStore;
|
||||
// services
|
||||
|
|
@ -42,6 +46,7 @@ export class ProjectViewStore implements IProjectViewStore {
|
|||
makeObservable(this, {
|
||||
// observables
|
||||
viewMap: observable,
|
||||
fetchedMap: observable,
|
||||
// computed
|
||||
projectViewIds: computed,
|
||||
// computed actions
|
||||
|
|
@ -68,7 +73,7 @@ export class ProjectViewStore implements IProjectViewStore {
|
|||
*/
|
||||
get projectViewIds() {
|
||||
const projectId = this.rootStore.app.router.projectId;
|
||||
if (!projectId) return null;
|
||||
if (!projectId || !this.fetchedMap[projectId]) return null;
|
||||
const viewIds = Object.keys(this.viewMap ?? {})?.filter((viewId) => this.viewMap?.[viewId]?.project === projectId);
|
||||
return viewIds;
|
||||
}
|
||||
|
|
@ -90,6 +95,7 @@ export class ProjectViewStore implements IProjectViewStore {
|
|||
response.forEach((view) => {
|
||||
set(this.viewMap, [view.id], view);
|
||||
});
|
||||
set(this.fetchedMap, projectId, true);
|
||||
});
|
||||
return response;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import { IState } from "@plane/types";
|
|||
import { ProjectStateService } from "services/project";
|
||||
|
||||
export interface IStateStore {
|
||||
//Loaders
|
||||
fetchedMap: Record<string, boolean>;
|
||||
// observables
|
||||
stateMap: Record<string, IState>;
|
||||
// computed
|
||||
|
|
@ -16,7 +18,7 @@ export interface IStateStore {
|
|||
groupedProjectStates: Record<string, IState[]> | undefined;
|
||||
// computed actions
|
||||
getStateById: (stateId: string) => IState | undefined;
|
||||
getProjectStates: (projectId: string) => IState[];
|
||||
getProjectStates: (projectId: string) => IState[] | undefined;
|
||||
// fetch actions
|
||||
fetchProjectStates: (workspaceSlug: string, projectId: string) => Promise<IState[]>;
|
||||
// crud actions
|
||||
|
|
@ -40,6 +42,8 @@ export interface IStateStore {
|
|||
|
||||
export class StateStore implements IStateStore {
|
||||
stateMap: Record<string, IState> = {};
|
||||
//loaders
|
||||
fetchedMap: Record<string, boolean> = {};
|
||||
router;
|
||||
stateService;
|
||||
|
||||
|
|
@ -47,6 +51,7 @@ export class StateStore implements IStateStore {
|
|||
makeObservable(this, {
|
||||
// observables
|
||||
stateMap: observable,
|
||||
fetchedMap: observable,
|
||||
// computed
|
||||
projectStates: computed,
|
||||
groupedProjectStates: computed,
|
||||
|
|
@ -71,7 +76,8 @@ export class StateStore implements IStateStore {
|
|||
* Returns the stateMap belongs to a specific project
|
||||
*/
|
||||
get projectStates() {
|
||||
if (!this.router.query?.projectId) return;
|
||||
const projectId = this.router.query?.projectId?.toString();
|
||||
if (!projectId || !this.fetchedMap[projectId]) return;
|
||||
return Object.values(this.stateMap).filter((state) => state.project === this.router.query.projectId);
|
||||
}
|
||||
|
||||
|
|
@ -97,7 +103,10 @@ export class StateStore implements IStateStore {
|
|||
* @param projectId
|
||||
* @returns IState[]
|
||||
*/
|
||||
getProjectStates = (projectId: string) => Object.values(this.stateMap).filter((state) => state.project === projectId);
|
||||
getProjectStates = (projectId: string) => {
|
||||
if (!projectId || !this.fetchedMap[projectId]) return;
|
||||
return Object.values(this.stateMap).filter((state) => state.project === projectId);
|
||||
};
|
||||
|
||||
/**
|
||||
* fetches the stateMap of a project
|
||||
|
|
@ -111,6 +120,7 @@ export class StateStore implements IStateStore {
|
|||
statesResponse.forEach((state) => {
|
||||
set(this.stateMap, [state.id], state);
|
||||
});
|
||||
set(this.fetchedMap, projectId, true);
|
||||
});
|
||||
return statesResponse;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue