chore: view rootstore update

This commit is contained in:
gurusainath 2024-02-14 20:06:59 +05:30
parent 430d9de722
commit e55d7175dc
4 changed files with 95 additions and 78 deletions

View File

@ -71,12 +71,12 @@ export const GlobalViewRoot: FC<TGlobalViewRoot> = observer((props) => {
// creating new view // creating new view
const currentViewPayload = cloneDeep({ ...currentView, id: uuidV4() }); const currentViewPayload = cloneDeep({ ...currentView, id: uuidV4() });
handleViewOperationsToggle("CREATE", currentViewPayload.id); handleViewOperationsToggle("CREATE", currentViewPayload.id);
viewStore?.localViewCreate(currentViewPayload as TView); viewStore?.localViewCreate(workspaceSlug, projectId, currentViewPayload as TView);
} else { } else {
// if current view is available, create a new view with the same data // if current view is available, create a new view with the same data
const viewPayload = viewLocalPayload; const viewPayload = viewLocalPayload;
handleViewOperationsToggle("CREATE", viewPayload.id); handleViewOperationsToggle("CREATE", viewPayload.id);
viewStore?.localViewCreate(viewPayload as TView); viewStore?.localViewCreate(workspaceSlug, projectId, viewPayload as TView);
} }
} else { } else {
handleViewOperationsToggle("EDIT", viewId); handleViewOperationsToggle("EDIT", viewId);
@ -84,14 +84,14 @@ export const GlobalViewRoot: FC<TGlobalViewRoot> = observer((props) => {
} }
}, },
localViewCreateEditClear: async (viewId: string | undefined) => { localViewCreateEditClear: async (viewId: string | undefined) => {
if (viewDetailCreateEditStore?.is_create && viewId) viewStore?.remove(viewId); if (viewDetailCreateEditStore?.is_create && viewId) viewStore?.remove(workspaceSlug, projectId, viewId);
if (viewDetailCreateEditStore?.is_editable && viewId) viewDetailCreateEditStore.resetChanges(); if (viewDetailCreateEditStore?.is_editable && viewId) viewDetailCreateEditStore.resetChanges();
handleViewOperationsToggle(undefined, undefined); handleViewOperationsToggle(undefined, undefined);
}, },
fetch: async () => { fetch: async () => {
try { try {
await viewStore?.fetch(); await viewStore?.fetch(workspaceSlug, projectId);
} catch { } catch {
setToastAlert({ setToastAlert({
type: "error", type: "error",
@ -102,7 +102,7 @@ export const GlobalViewRoot: FC<TGlobalViewRoot> = observer((props) => {
}, },
create: async (data: Partial<TView>) => { create: async (data: Partial<TView>) => {
try { try {
await viewStore?.create(data); await viewStore?.create(workspaceSlug, projectId, data);
handleViewOperationsToggle(undefined, undefined); handleViewOperationsToggle(undefined, undefined);
setToastAlert({ setToastAlert({
type: "success", type: "success",
@ -119,7 +119,7 @@ export const GlobalViewRoot: FC<TGlobalViewRoot> = observer((props) => {
}, },
remove: async (viewId: string) => { remove: async (viewId: string) => {
try { try {
await viewStore?.remove(viewId); await viewStore?.remove(workspaceSlug, projectId, viewId);
handleViewOperationsToggle(undefined, undefined); handleViewOperationsToggle(undefined, undefined);
setToastAlert({ setToastAlert({
type: "success", type: "success",
@ -152,13 +152,25 @@ export const GlobalViewRoot: FC<TGlobalViewRoot> = observer((props) => {
} }
}, },
}), }),
[viewStore, viewDetailStore, setToastAlert, viewDetailCreateEditStore, handleViewOperationsToggle] [
workspaceSlug,
projectId,
viewStore,
viewDetailStore,
setToastAlert,
viewDetailCreateEditStore,
handleViewOperationsToggle,
]
); );
// fetch all views // fetch all views
useEffect(() => { useEffect(() => {
const fetchViews = async () => { const fetchViews = async () => {
await viewStore?.fetch(viewStore?.viewIds.length > 0 ? "mutation-loader" : "init-loader"); await viewStore?.fetch(
workspaceSlug,
projectId,
viewStore?.viewIds.length > 0 ? "mutation-loader" : "init-loader"
);
}; };
if (workspaceSlug && viewType && viewStore) fetchViews(); if (workspaceSlug && viewType && viewStore) fetchViews();
}, [workspaceSlug, projectId, viewType, viewStore]); }, [workspaceSlug, projectId, viewType, viewStore]);
@ -166,7 +178,7 @@ export const GlobalViewRoot: FC<TGlobalViewRoot> = observer((props) => {
// fetch view by id // fetch view by id
useEffect(() => { useEffect(() => {
const fetchViews = async () => { const fetchViews = async () => {
viewId && (await viewStore?.fetchById(viewId)); viewId && (await viewStore?.fetchById(workspaceSlug, projectId, viewId));
}; };
if (workspaceSlug && viewId && viewType && viewStore) fetchViews(); if (workspaceSlug && viewId && viewType && viewStore) fetchViews();
}, [workspaceSlug, projectId, viewId, viewType, viewStore]); }, [workspaceSlug, projectId, viewId, viewType, viewStore]);

View File

@ -12,7 +12,7 @@ import {
// types // types
import { RootStore } from "store/root.store"; import { RootStore } from "store/root.store";
// constants // constants
import { EViewPageType } from "constants/view"; import { EViewPageType, VIEW_TYPES } from "constants/view";
export class GlobalViewRootStore { export class GlobalViewRootStore {
workspacePrivateViewStore: ViewRootStore; workspacePrivateViewStore: ViewRootStore;
@ -25,25 +25,16 @@ export class GlobalViewRootStore {
{ {
id: "assigned", id: "assigned",
name: "Assigned", name: "Assigned",
filters: {
assignees: store?.user?.currentUser?.id ? [store?.user?.currentUser?.id] : [],
},
is_local_view: true, is_local_view: true,
}, },
{ {
id: "created", id: "created",
name: "Created", name: "Created",
filters: {
created_by: store?.user?.currentUser?.id ? [store?.user?.currentUser?.id] : [],
},
is_local_view: true, is_local_view: true,
}, },
{ {
id: "subscribed", id: "subscribed",
name: "Subscribed", name: "Subscribed",
filters: {
subscriber: store?.user?.currentUser?.id ? [store?.user?.currentUser?.id] : [],
},
is_local_view: true, is_local_view: true,
}, },
]; ];
@ -52,7 +43,6 @@ export class GlobalViewRootStore {
{ {
id: "all-issues", id: "all-issues",
name: "All Issues", name: "All Issues",
filters: {},
is_local_view: true, is_local_view: true,
}, },
]; ];
@ -62,28 +52,32 @@ export class GlobalViewRootStore {
workspacePrivateDefaultViews, workspacePrivateDefaultViews,
new WorkspacePrivateViewService(), new WorkspacePrivateViewService(),
new WorkspaceFiltersService(), new WorkspaceFiltersService(),
EViewPageType.ALL EViewPageType.ALL,
VIEW_TYPES.WORKSPACE_PRIVATE_VIEWS
); );
this.workspacePublicViewStore = new ViewRootStore( this.workspacePublicViewStore = new ViewRootStore(
this.store, this.store,
workspacePublicDefaultViews, workspacePublicDefaultViews,
new WorkspacePublicViewService(), new WorkspacePublicViewService(),
new WorkspaceFiltersService(), new WorkspaceFiltersService(),
EViewPageType.ALL EViewPageType.ALL,
VIEW_TYPES.WORKSPACE_PUBLIC_VIEWS
); );
this.projectPrivateViewStore = new ViewRootStore( this.projectPrivateViewStore = new ViewRootStore(
this.store, this.store,
undefined, undefined,
new ProjectPrivateViewService(), new ProjectPrivateViewService(),
new ProjectFiltersService(), new ProjectFiltersService(),
EViewPageType.PROJECT EViewPageType.PROJECT,
VIEW_TYPES.PROJECT_PRIVATE_VIEWS
); );
this.projectPublicViewStore = new ViewRootStore( this.projectPublicViewStore = new ViewRootStore(
this.store, this.store,
undefined, undefined,
new ProjectPublicViewService(), new ProjectPublicViewService(),
new ProjectFiltersService(), new ProjectFiltersService(),
EViewPageType.PROJECT EViewPageType.PROJECT,
VIEW_TYPES.PROJECT_PUBLIC_VIEWS
); );
} }
} }

View File

@ -8,7 +8,7 @@ import { RootStore } from "store/root.store";
import { ViewStore } from "./view.store"; import { ViewStore } from "./view.store";
// types // types
import { TUserViewService, TViewService } from "services/view/types"; import { TUserViewService, TViewService } from "services/view/types";
import { TView } from "@plane/types"; import { TView, TViewTypes } from "@plane/types";
// constants // constants
import { EViewPageType } from "constants/view"; import { EViewPageType } from "constants/view";
@ -17,30 +17,31 @@ export type TLoader = "init-loader" | "mutation-loader" | "submitting" | undefin
type TViewRootStore = { type TViewRootStore = {
// observables // observables
loader: TLoader; loader: TLoader;
viewMap: Record<string, ViewStore>; viewMap: Record<string, Record<string, Record<string, ViewStore>>>; // workspaceSlug/projectId, public/private, viewId -> ViewStore
// computed // computed
viewIds: string[]; viewIds: string[];
viewById: (viewId: string) => ViewStore | undefined; viewById: (viewId: string) => ViewStore | undefined;
// actions // actions
localViewCreate: (view: TView) => Promise<void>; localViewCreate: (workspaceSlug: string, projectId: string | undefined, view: TView) => Promise<void>;
fetch: (_loader?: TLoader) => Promise<void>; fetch: (workspaceSlug: string, projectId: string | undefined, _loader?: TLoader) => Promise<void>;
fetchById: (viewId: string) => Promise<void>; fetchById: (workspaceSlug: string, projectId: string | undefined, viewId: string) => Promise<void>;
create: (view: Partial<TView>) => Promise<void>; create: (workspaceSlug: string, projectId: string | undefined, view: Partial<TView>) => Promise<void>;
remove: (viewId: string) => Promise<void>; remove: (workspaceSlug: string, projectId: string | undefined, viewId: string) => Promise<void>;
duplicate: (viewId: string) => Promise<void>; duplicate: (workspaceSlug: string, projectId: string | undefined, viewId: string) => Promise<void>;
}; };
export class ViewRootStore implements TViewRootStore { export class ViewRootStore implements TViewRootStore {
// observables // observables
loader: TLoader = "init-loader"; loader: TLoader = "init-loader";
viewMap: Record<string, ViewStore> = {}; viewMap: Record<string, Record<string, Record<string, ViewStore>>> = {};
constructor( constructor(
private store: RootStore, private store: RootStore,
private defaultViews: TView[] = [], private defaultViews: TView[] = [],
private service: TViewService, private service: TViewService,
private userService: TUserViewService, private userService: TUserViewService,
private viewPageType: EViewPageType private viewPageType: EViewPageType,
private viewType: TViewTypes
) { ) {
makeObservable(this, { makeObservable(this, {
// observables // observables
@ -60,7 +61,14 @@ export class ViewRootStore implements TViewRootStore {
// computed // computed
get viewIds() { get viewIds() {
const views = Object.values(this.viewMap); const { workspaceSlug, projectId } = this.store.app.router;
if (!workspaceSlug) return [];
const viewRootSlug = projectId ? projectId : workspaceSlug;
const views = this.viewMap?.[viewRootSlug]?.[this.viewType]
? Object.values(this.viewMap?.[viewRootSlug]?.[this.viewType])
: [];
const localViews = views.filter((view) => view.is_local_view); const localViews = views.filter((view) => view.is_local_view);
let apiViews = views.filter((view) => !view.is_local_view && !view.is_create); let apiViews = views.filter((view) => !view.is_local_view && !view.is_create);
apiViews = reverse(sortBy(apiViews, "sort_order")); apiViews = reverse(sortBy(apiViews, "sort_order"));
@ -68,24 +76,31 @@ export class ViewRootStore implements TViewRootStore {
return _viewIds as string[]; return _viewIds as string[];
} }
viewById = computedFn((viewId: string) => this.viewMap?.[viewId] || undefined); viewById = computedFn((viewId: string) => {
const { workspaceSlug, projectId } = this.store.app.router;
if (!workspaceSlug) return undefined;
const viewRootSlug = projectId ? projectId : workspaceSlug;
return this.viewMap?.[viewRootSlug]?.[this.viewType]?.[viewId] || undefined;
});
// actions // actions
localViewCreate = async (view: TView) => { localViewCreate = async (workspaceSlug: string, projectId: string | undefined, view: TView) => {
const viewRootSlug = projectId ? projectId : workspaceSlug;
runInAction(() => { runInAction(() => {
if (view.id) if (view.id)
set( set(
this.viewMap, this.viewMap,
[view.id], [viewRootSlug, this.viewType, view.id],
new ViewStore(this.store, view, this.service, this.userService, this.viewPageType) new ViewStore(this.store, view, this.service, this.userService, this.viewPageType)
); );
}); });
}; };
fetch = async (_loader: TLoader = "init-loader") => { fetch = async (workspaceSlug: string, projectId: string | undefined, _loader: TLoader = "init-loader") => {
try { try {
const { workspaceSlug, projectId } = this.store.app.router; const viewRootSlug = projectId ? projectId : workspaceSlug;
if (!workspaceSlug) return;
this.loader = _loader; this.loader = _loader;
@ -95,7 +110,7 @@ export class ViewRootStore implements TViewRootStore {
if (view.id) if (view.id)
set( set(
this.viewMap, this.viewMap,
[view.id], [viewRootSlug, this.viewType, view.id],
new ViewStore(this.store, view, this.service, this.userService, this.viewPageType) new ViewStore(this.store, view, this.service, this.userService, this.viewPageType)
); );
}); });
@ -109,7 +124,7 @@ export class ViewRootStore implements TViewRootStore {
if (view.id) if (view.id)
set( set(
this.viewMap, this.viewMap,
[view.id], [viewRootSlug, this.viewType, view.id],
new ViewStore(this.store, view, this.service, this.userService, this.viewPageType) new ViewStore(this.store, view, this.service, this.userService, this.viewPageType)
); );
}); });
@ -118,10 +133,9 @@ export class ViewRootStore implements TViewRootStore {
} catch {} } catch {}
}; };
fetchById = async (viewId: string) => { fetchById = async (workspaceSlug: string, projectId: string | undefined, viewId: string) => {
try { try {
const { workspaceSlug, projectId } = this.store.app.router; const viewRootSlug = projectId ? projectId : workspaceSlug;
if (!workspaceSlug || !viewId) return;
const userView = await this.userService.fetch(workspaceSlug, projectId); const userView = await this.userService.fetch(workspaceSlug, projectId);
if (!userView) return; if (!userView) return;
@ -129,7 +143,7 @@ export class ViewRootStore implements TViewRootStore {
let view: TView | undefined = undefined; let view: TView | undefined = undefined;
if (["all-issues", "assigned", "created", "subscribed"].includes(viewId)) { if (["all-issues", "assigned", "created", "subscribed"].includes(viewId)) {
const currentView = { ...this.viewById(viewId) }; const currentView = { ...this.viewById(viewId) } as TView;
if (!currentView) return; if (!currentView) return;
view = currentView; view = currentView;
@ -150,17 +164,16 @@ export class ViewRootStore implements TViewRootStore {
if (view?.id) if (view?.id)
set( set(
this.viewMap, this.viewMap,
[view.id], [viewRootSlug, this.viewType, view.id],
new ViewStore(this.store, view, this.service, this.userService, this.viewPageType) new ViewStore(this.store, view, this.service, this.userService, this.viewPageType)
); );
}); });
} catch {} } catch {}
}; };
create = async (data: Partial<TView>) => { create = async (workspaceSlug: string, projectId: string | undefined, data: Partial<TView>) => {
try { try {
const { workspaceSlug, projectId } = this.store.app.router; const viewRootSlug = projectId ? projectId : workspaceSlug;
if (!workspaceSlug) return;
const view = await this.service.create(workspaceSlug, data, projectId); const view = await this.service.create(workspaceSlug, data, projectId);
if (!view) return; if (!view) return;
@ -169,33 +182,36 @@ export class ViewRootStore implements TViewRootStore {
if (view.id) if (view.id)
set( set(
this.viewMap, this.viewMap,
[view.id], [viewRootSlug, this.viewType, view.id],
new ViewStore(this.store, view, this.service, this.userService, this.viewPageType) new ViewStore(this.store, view, this.service, this.userService, this.viewPageType)
); );
}); });
if (data.id) this.remove(data.id); if (data.id) this.remove(workspaceSlug, projectId, data.id);
} catch {} } catch {}
}; };
remove = async (viewId: string) => { remove = async (workspaceSlug: string, projectId: string | undefined, viewId: string) => {
try { try {
const { workspaceSlug, projectId } = this.store.app.router; const viewRootSlug = projectId ? projectId : workspaceSlug;
if (!workspaceSlug || !viewId) return;
if (this.viewMap?.[viewId] != undefined && !this.viewMap?.[viewId]?.is_create) if (
this.viewMap?.[viewRootSlug]?.[this.viewType]?.[viewId] != undefined &&
!this.viewMap?.[viewRootSlug]?.[this.viewType]?.[viewId]?.is_create
)
await this.service.remove?.(workspaceSlug, viewId, projectId); await this.service.remove?.(workspaceSlug, viewId, projectId);
runInAction(() => { runInAction(() => {
delete this.viewMap[viewId]; delete this.viewMap?.[viewRootSlug]?.[this.viewType]?.[viewId];
}); });
} catch {} } catch {}
}; };
duplicate = async (viewId: string) => { duplicate = async (workspaceSlug: string, projectId: string | undefined, viewId: string) => {
try { try {
const { workspaceSlug, projectId } = this.store.app.router; if (!this.service.duplicate) return;
if (!workspaceSlug || !this.service.duplicate) return;
const viewRootSlug = projectId ? projectId : workspaceSlug;
const view = await this.service.duplicate(workspaceSlug, viewId, projectId); const view = await this.service.duplicate(workspaceSlug, viewId, projectId);
if (!view) return; if (!view) return;
@ -204,7 +220,7 @@ export class ViewRootStore implements TViewRootStore {
if (view.id) if (view.id)
set( set(
this.viewMap, this.viewMap,
[view.id], [viewRootSlug, this.viewType, view.id],
new ViewStore(this.store, view, this.service, this.userService, this.viewPageType) new ViewStore(this.store, view, this.service, this.userService, this.viewPageType)
); );
}); });

View File

@ -326,14 +326,13 @@ export class ViewStore extends FiltersHelper implements TViewStore {
// actions // actions
update = async (viewData: TUpdateView) => { update = async (viewData: TUpdateView) => {
try { try {
if (!this.workspace || !this.id) return;
runInAction(() => { runInAction(() => {
this.loader = "updating"; this.loader = "updating";
}); });
const { workspaceSlug, projectId } = this.store.app.router; const view = await this.service.update(this.workspace, this.id, viewData, this.project);
if (!workspaceSlug || !this.id) return;
const view = await this.service.update(workspaceSlug, this.id, viewData, projectId);
if (!view) return; if (!view) return;
runInAction(() => { runInAction(() => {
@ -350,10 +349,9 @@ export class ViewStore extends FiltersHelper implements TViewStore {
lockView = async () => { lockView = async () => {
try { try {
const { workspaceSlug, projectId } = this.store.app.router; if (!this.workspace || !this.id || !this.service.lock) return;
if (!workspaceSlug || !this.id || !this.service.lock) return;
const view = await this.service.lock(workspaceSlug, this.id, projectId); const view = await this.service.lock(this.workspace, this.id, this.project);
if (!view) return; if (!view) return;
runInAction(() => { runInAction(() => {
@ -366,10 +364,9 @@ export class ViewStore extends FiltersHelper implements TViewStore {
unlockView = async () => { unlockView = async () => {
try { try {
const { workspaceSlug, projectId } = this.store.app.router; if (!this.workspace || !this.id || !this.service.unlock) return;
if (!workspaceSlug || !this.id || !this.service.unlock) return;
const view = await this.service.unlock(workspaceSlug, this.id, projectId); const view = await this.service.unlock(this.workspace, this.id, this.project);
if (!view) return; if (!view) return;
runInAction(() => { runInAction(() => {
@ -382,10 +379,9 @@ export class ViewStore extends FiltersHelper implements TViewStore {
makeFavorite = async () => { makeFavorite = async () => {
try { try {
const { workspaceSlug, projectId } = this.store.app.router; if (!this.workspace || !this.id || !this.service.makeFavorite) return;
if (!workspaceSlug || !this.id || !this.service.makeFavorite) return;
const view = await this.service.makeFavorite(workspaceSlug, this.id, projectId); const view = await this.service.makeFavorite(this.workspace, this.id, this.project);
if (!view) return; if (!view) return;
runInAction(() => { runInAction(() => {
@ -398,10 +394,9 @@ export class ViewStore extends FiltersHelper implements TViewStore {
removeFavorite = async () => { removeFavorite = async () => {
try { try {
const { workspaceSlug, projectId } = this.store.app.router; if (!this.workspace || !this.id || !this.service.removeFavorite) return;
if (!workspaceSlug || !this.id || !this.service.removeFavorite) return;
const view = await this.service.removeFavorite(workspaceSlug, this.id, projectId); const view = await this.service.removeFavorite(this.workspace, this.id, this.project);
if (!view) return; if (!view) return;
runInAction(() => { runInAction(() => {