import { observable, action, makeObservable, runInAction, computed } from "mobx"; import { set } from "lodash"; // services import { WorkspaceService } from "services/workspace.service"; // types import { RootStore } from "store/root.store"; import { IWorkspaceView } from "types/workspace-views"; export interface IGlobalViewStore { // states loader: boolean; error: any | null; // observables globalViewMap: Record; // computed currentWorkspaceViews: string[] | null; // computed actions getViewDetails: (viewId: string) => IWorkspaceView | null; // actions fetchAllGlobalViews: (workspaceSlug: string) => Promise; fetchGlobalViewDetails: (workspaceSlug: string, viewId: string) => Promise; createGlobalView: (workspaceSlug: string, data: Partial) => Promise; updateGlobalView: (workspaceSlug: string, viewId: string, data: Partial) => Promise; deleteGlobalView: (workspaceSlug: string, viewId: string) => Promise; } export class GlobalViewStore implements IGlobalViewStore { // states loader: boolean = false; error: any | null = null; // observables globalViewMap: Record = {}; // root store rootStore; // services workspaceService; constructor(_rootStore: RootStore) { makeObservable(this, { // states loader: observable.ref, error: observable.ref, // observables globalViewMap: observable, // computed currentWorkspaceViews: computed, // computed actions getViewDetails: action, // actions fetchAllGlobalViews: action, fetchGlobalViewDetails: action, createGlobalView: action, updateGlobalView: action, deleteGlobalView: action, }); // root store this.rootStore = _rootStore; // services this.workspaceService = new WorkspaceService(); } /** * @description returns list of views for current workspace */ get currentWorkspaceViews() { const currentWorkspaceDetails = this.rootStore.workspaceRoot.currentWorkspace; if (!currentWorkspaceDetails) return null; return ( Object.keys(this.globalViewMap ?? {})?.filter( (viewId) => this.globalViewMap[viewId]?.workspace === currentWorkspaceDetails.id ) ?? null ); } /** * @description returns view details for given viewId * @param viewId */ getViewDetails = (viewId: string): IWorkspaceView | null => this.globalViewMap[viewId] ?? null; /** * @description fetch all global views for given workspace * @param workspaceSlug */ fetchAllGlobalViews = async (workspaceSlug: string): Promise => { try { runInAction(() => { this.loader = true; }); const response = await this.workspaceService.getAllViews(workspaceSlug); runInAction(() => { this.loader = false; response.forEach((view) => { set(this.globalViewMap, view.id, view); }); }); return response; } catch (error) { runInAction(() => { this.loader = false; this.error = error; }); throw error; } }; /** * @description fetch view details for given viewId * @param viewId */ fetchGlobalViewDetails = async (workspaceSlug: string, viewId: string): Promise => { try { runInAction(() => { this.loader = true; }); const response = await this.workspaceService.getViewDetails(workspaceSlug, viewId); runInAction(() => { this.loader = false; set(this.globalViewMap, viewId, response); }); return response; } catch (error) { runInAction(() => { this.loader = false; this.error = error; }); throw error; } }; /** * @description create new global view * @param workspaceSlug * @param data */ createGlobalView = async (workspaceSlug: string, data: Partial): Promise => { try { const response = await this.workspaceService.createView(workspaceSlug, data); runInAction(() => { set(this.globalViewMap, response.id, response); }); return response; } catch (error) { runInAction(() => { this.error = error; }); throw error; } }; /** * @description update global view * @param workspaceSlug * @param viewId * @param data */ updateGlobalView = async ( workspaceSlug: string, viewId: string, data: Partial ): Promise => { const viewToUpdate = { ...this.getViewDetails(viewId), ...data }; try { runInAction(() => { set(this.globalViewMap, viewId, viewToUpdate); }); const response = await this.workspaceService.updateView(workspaceSlug, viewId, data); return response; } catch (error) { this.fetchGlobalViewDetails(workspaceSlug, viewId); runInAction(() => { this.error = error; }); throw error; } }; /** * @description delete global view * @param workspaceSlug * @param viewId */ deleteGlobalView = async (workspaceSlug: string, viewId: string): Promise => { try { runInAction(() => { delete this.globalViewMap[viewId]; }); await this.workspaceService.deleteView(workspaceSlug, viewId); } catch (error) { this.fetchAllGlobalViews(workspaceSlug); runInAction(() => { this.error = error; }); throw error; } }; }