import { observable, action, makeObservable, runInAction } from "mobx"; // services import { ProjectService } from "services/project"; import { WorkspaceService } from "services/workspace.service"; // types import { RootStore } from "../root"; import { IWorkspaceView } from "types/workspace-views"; export interface IGlobalViewsStore { // states loader: boolean; error: any | null; // observables globalViewId: string | null; globalViewsList: IWorkspaceView[] | null; globalViewDetails: { [viewId: string]: IWorkspaceView; }; // actions setGlobalViewId: (viewId: string | null) => void; 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 GlobalViewsStore implements IGlobalViewsStore { // states loader: boolean = false; error: any | null = null; // observables globalViewId: string | null = null; globalViewsList: IWorkspaceView[] | null = null; globalViewDetails: { [viewId: string]: IWorkspaceView } = {}; // root store rootStore; // services projectService; workspaceService; constructor(_rootStore: RootStore) { makeObservable(this, { // states loader: observable.ref, error: observable.ref, // observables globalViewId: observable.ref, globalViewsList: observable.ref, globalViewDetails: observable.ref, // actions setGlobalViewId: action, fetchAllGlobalViews: action, fetchGlobalViewDetails: action, createGlobalView: action, updateGlobalView: action, deleteGlobalView: action, }); this.rootStore = _rootStore; this.projectService = new ProjectService(); this.workspaceService = new WorkspaceService(); } setGlobalViewId = (viewId: string | null) => { this.globalViewId = viewId; }; fetchAllGlobalViews = async (workspaceSlug: string): Promise => { try { runInAction(() => { this.loader = true; }); const response = await this.workspaceService.getAllViews(workspaceSlug); runInAction(() => { this.loader = false; this.globalViewsList = response; }); return response; } catch (error) { runInAction(() => { this.loader = false; this.error = error; }); throw error; } }; fetchGlobalViewDetails = async (workspaceSlug: string, viewId: string): Promise => { try { runInAction(() => { this.loader = true; }); const response = await this.workspaceService.getViewDetails(workspaceSlug, viewId); runInAction(() => { this.loader = false; this.globalViewDetails = { ...this.globalViewDetails, [response.id]: response, }; }); return response; } catch (error) { runInAction(() => { this.loader = false; this.error = error; }); throw error; } }; createGlobalView = async (workspaceSlug: string, data: Partial): Promise => { try { const response = await this.workspaceService.createView(workspaceSlug, data); runInAction(() => { this.globalViewsList = [response, ...(this.globalViewsList ?? [])]; this.globalViewDetails = { ...this.globalViewDetails, [response.id]: response, }; }); return response; } catch (error) { runInAction(() => { this.error = error; }); throw error; } }; updateGlobalView = async ( workspaceSlug: string, viewId: string, data: Partial ): Promise => { const viewToUpdate = { ...this.globalViewDetails[viewId], ...data }; try { runInAction(() => { this.globalViewsList = (this.globalViewsList ?? []).map((view) => { if (view.id === viewId) return viewToUpdate; return view; }); this.globalViewDetails = { ...this.globalViewDetails, [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; } }; deleteGlobalView = async (workspaceSlug: string, viewId: string): Promise => { const newViewsList = (this.globalViewsList ?? []).filter((view) => view.id !== viewId); try { runInAction(() => { this.globalViewsList = newViewsList; }); await this.workspaceService.deleteView(workspaceSlug, viewId); } catch (error) { this.fetchAllGlobalViews(workspaceSlug); runInAction(() => { this.error = error; }); throw error; } }; }