diff --git a/web/store/dataMaps/index.ts b/web/store/dataMaps/index.ts new file mode 100644 index 000000000..f944843e3 --- /dev/null +++ b/web/store/dataMaps/index.ts @@ -0,0 +1,11 @@ +import { IWorkspaceData, WorkspaceData } from "./workspace.data.store"; + +export class DataStore { + workspaceData: IWorkspaceData; + + constructor() { + this.workspaceData = new WorkspaceData(this); + } + + resetOnSignout() {} +} diff --git a/web/store/dataMaps/workspace.data.store.ts b/web/store/dataMaps/workspace.data.store.ts new file mode 100644 index 000000000..a6c93bf13 --- /dev/null +++ b/web/store/dataMaps/workspace.data.store.ts @@ -0,0 +1,39 @@ +import { makeObservable, observable } from "mobx"; +import { WorkspaceModel } from "store/workspace.model"; +import { DataStore } from "."; +import { IWorkspace } from "@plane/types"; +import { set } from "lodash"; + +export interface IWorkspaceData { + workspaceMap: Record; + + addWorkspaces: (workspaces: IWorkspace[]) => void; + deleteWorkspace: (workspaceId: string) => void; + getWorkspacebyId: (workspaceId: string) => WorkspaceModel | undefined; +} + +export class WorkspaceData implements IWorkspaceData { + workspaceMap: Record = {}; + + // data store + dataStore; + + constructor(_dataStore: DataStore) { + makeObservable(this, { + workspaceMap: observable, + }); + this.dataStore = _dataStore; + } + + addWorkspaces = (workspaces: IWorkspace[]) => { + workspaces.forEach((workspace) => { + set(this.workspaceMap, [workspace.id], new WorkspaceModel(workspace, this.dataStore)); + }); + }; + + deleteWorkspace = (workspaceId: string) => { + delete this.workspaceMap[workspaceId]; + }; + + getWorkspacebyId = (workspaceId: string) => this.workspaceMap[workspaceId]; +} diff --git a/web/store/root.store.ts b/web/store/root.store.ts new file mode 100644 index 000000000..60e718aa6 --- /dev/null +++ b/web/store/root.store.ts @@ -0,0 +1,16 @@ +import { DataStore } from "./dataMaps"; +import { IUserModel, UserModel } from "./user.model"; + +export class RootStore { + data: DataStore; + + user: IUserModel; + + constructor() { + this.data = new DataStore(); + + this.user = new UserModel(this.data); + } + + resetOnSignout() {} +} diff --git a/web/store/user.model.ts b/web/store/user.model.ts new file mode 100644 index 000000000..72ab984f7 --- /dev/null +++ b/web/store/user.model.ts @@ -0,0 +1,76 @@ +import { makeObservable, observable, runInAction } from "mobx"; +import { WorkspaceService } from "services/workspace.service"; +import set from "lodash/set"; +import { IWorkspace } from "@plane/types"; +import { DataStore } from "./dataMaps"; +import { IWorkspaceModel } from "./workspace.model"; + +export interface IUserModel { + workspaces: Record; +} + +export class UserModel implements IUserModel { + workspaces: Record = {}; + + // data store + dataStore; + // services + workspaceService; + + constructor(_dataStore: DataStore) { + makeObservable(this, { + workspaces: observable, + }); + this.dataStore = _dataStore; + this.workspaceService = new WorkspaceService(); + } + + /** + * get workspace info from the array of workspaces in the store using workspace slug + * @param workspaceSlug + */ + getWorkspaceBySlug = (workspaceSlug: string) => + Object.values(this.workspaces ?? {})?.find((w) => w.slug == workspaceSlug) || null; + + /** + * fetch user workspaces from API + */ + fetchWorkspaces = async () => { + const workspaceResponse = await this.workspaceService.userWorkspaces(); + + this.dataStore.workspaceData.addWorkspaces(workspaceResponse); + runInAction(() => { + workspaceResponse.forEach((workspace) => { + set(this.workspaces, [workspace.id], this.dataStore.workspaceData.workspaceMap[workspace.id]); + }); + }); + return workspaceResponse; + }; + + /** + * create workspace using the workspace data + * @param data + */ + createWorkspace = async (data: Partial) => + await this.workspaceService.createWorkspace(data).then((response) => { + this.dataStore.workspaceData.addWorkspaces([response]); + runInAction(() => { + set(this.workspaces, [response.id], this.dataStore.workspaceData.workspaceMap[response.id]); + }); + return response; + }); + + /** + * delete workspace using the workspace slug + * @param workspaceSlug + */ + deleteWorkspace = async (workspaceSlug: string) => + await this.workspaceService.deleteWorkspace(workspaceSlug).then(() => { + const updatedWorkspacesList = this.workspaces; + const workspaceId = this.getWorkspaceBySlug(workspaceSlug)?.id; + this.dataStore.workspaceData.deleteWorkspace(`${workspaceId}`); + runInAction(() => { + delete updatedWorkspacesList[`${workspaceId}`]; + }); + }); +} diff --git a/web/store/workspace.model.ts b/web/store/workspace.model.ts new file mode 100644 index 000000000..f9517fcc6 --- /dev/null +++ b/web/store/workspace.model.ts @@ -0,0 +1,61 @@ +import { makeObservable, observable } from "mobx"; +import { IUser, IWorkspace } from "@plane/types"; +import { DataStore } from "./dataMaps"; + +export interface IWorkspaceModel { + id: string; + owner: IUser; + created_at: Date; + updated_at: Date; + name: string; + url: string; + logo: string | null; + total_members: number; + slug: string; + created_by: string; + updated_by: string; + organization_size: string; + total_issues: number; +} + +export class WorkspaceModel implements IWorkspaceModel { + id: string; + owner: IUser; + created_at: Date; + updated_at: Date; + name: string; + url: string; + logo: string | null; + total_members: number; + slug: string; + created_by: string; + updated_by: string; + organization_size: string; + total_issues: number; + + // root store + dataStore; + + constructor(workspace: IWorkspace, _dataStore: DataStore) { + makeObservable(this, { + name: observable.ref, + url: observable.ref, + logo: observable.ref, + }); + this.dataStore = _dataStore; + + this.id = workspace.id; + this.owner = workspace.owner; + this.created_at = workspace.created_at; + this.updated_at = workspace.updated_at; + this.name = workspace.name; + this.url = workspace.url; + this.logo = workspace.logo; + this.total_members = workspace.total_members; + this.slug = workspace.slug; + this.created_by = workspace.created_by; + this.updated_by = workspace.updated_by; + this.organization_size = workspace.organization_size; + this.total_issues = workspace.total_issues; + } +}