diff --git a/web/store/webhook.store.ts b/web/store/webhook.store.ts new file mode 100644 index 000000000..8e6a84870 --- /dev/null +++ b/web/store/webhook.store.ts @@ -0,0 +1,125 @@ +import { action, computed, makeObservable, observable, runInAction } from "mobx"; +import set from "lodash/set"; +import { DataStore } from "./dataMaps"; +// services +import { WebhookService } from "services/webhook.service"; +// types +import { IWebhook } from "@plane/types"; + +export interface IWebhookModel { + // model observables + created_at: string; + cycle: boolean; + id: string; + is_active: boolean; + issue: boolean; + issue_comment: boolean; + module: boolean; + project: boolean; + secret_key?: string; + updated_at: string; + url: string; + // computed + asJSON: IWebhook; + // actions + updateWebhook: (workspaceSlug: string, data: Partial) => Promise; +} + +export class WebhookModel implements IWebhookModel { + // model observables + created_at: string; + cycle: boolean; + id: string; + is_active: boolean; + issue: boolean; + issue_comment: boolean; + module: boolean; + project: boolean; + secret_key?: string; + updated_at: string; + url: string; + // root store + dataStore; + // services + webhookService; + + constructor(webhook: IWebhook, _dataStore: DataStore) { + makeObservable(this, { + // model observables + cycle: observable.ref, + is_active: observable.ref, + issue: observable.ref, + issue_comment: observable.ref, + module: observable.ref, + project: observable.ref, + url: observable.ref, + // computed + asJSON: computed, + // actions + updateWebhook: action, + }); + this.dataStore = _dataStore; + + // services + this.webhookService = new WebhookService(); + + this.created_at = webhook.created_at; + this.cycle = webhook.cycle; + this.id = webhook.id; + this.is_active = webhook.is_active; + this.issue = webhook.issue; + this.issue_comment = webhook.issue_comment; + this.module = webhook.module; + this.project = webhook.project; + this.secret_key = webhook.secret_key; + this.updated_at = webhook.updated_at; + this.url = webhook.url; + } + + /** + * @description returns the webhook data in JSON format + */ + get asJSON() { + return { + created_at: this.created_at, + cycle: this.cycle, + id: this.id, + is_active: this.is_active, + issue: this.issue, + issue_comment: this.issue_comment, + module: this.module, + project: this.project, + secret_key: this.secret_key, + updated_at: this.updated_at, + url: this.url, + }; + } + + /** + * @description update a webhook using the data + * @param workspaceSlug + * @param data + */ + updateWebhook = async (workspaceSlug: string, data: Partial) => { + const originalData = { ...this }; + // optimistically update the store + runInAction(() => { + Object.entries(data).forEach(([key, value]) => { + set(this, [key], value); + }); + }); + + try { + const response = await this.webhookService.updateWebhook(workspaceSlug, this.id, data); + return response; + } catch (error) { + // revert the store back to the original state + runInAction(() => { + Object.keys(data).forEach((key) => { + set(this, [key], originalData[key as keyof IWebhook]); + }); + }); + throw error; + } + }; +} diff --git a/web/store/workspace.store.ts b/web/store/workspace.store.ts index ea3c261bc..23cf2eba8 100644 --- a/web/store/workspace.store.ts +++ b/web/store/workspace.store.ts @@ -1,79 +1,136 @@ -import { makeObservable, observable } from "mobx"; -import { IUser, IWorkspace } from "@plane/types"; +import { action, computed, makeObservable, observable, runInAction } from "mobx"; +import set from "lodash/set"; import { DataStore } from "./dataMaps"; +// services +import { WorkspaceService } from "services/workspace.service"; +// types +import { IUser, IWorkspace } from "@plane/types"; export interface IWorkspaceModel { - id: string; - owner: IUser; + // model observables created_at: Date; - updated_at: Date; - name: string; - url: string; - logo: string | null; - total_members: number; - slug: string; created_by: string; - updated_by: string; + id: string; + logo: string | null; + name: string; organization_size: string; + owner: IUser; + slug: string; total_issues: number; + total_members: number; + url: string; + updated_at: Date; + updated_by: string; + // computed + toJSON: IWorkspace; + // actions + updateWorkspace: (data: Partial) => Promise; } 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; + id: string; + logo: string | null; + name: string; organization_size: string; + owner: IUser; + slug: string; total_issues: number; - + total_members: number; + updated_at: Date; + updated_by: string; + url: string; // root store dataStore; + // services + workspaceService; constructor(workspace: IWorkspace, _dataStore: DataStore) { makeObservable(this, { - name: observable.ref, - url: observable.ref, + // model observables + created_at: observable.ref, + created_by: observable.ref, + id: observable.ref, logo: observable.ref, + name: observable.ref, + organization_size: observable.ref, + owner: observable.ref, + slug: observable.ref, + total_issues: observable.ref, + total_members: observable.ref, + updated_at: observable.ref, + updated_by: observable.ref, + url: observable.ref, + // computed + toJSON: computed, + // actions + updateWorkspace: action, }); this.dataStore = _dataStore; + // services + this.workspaceService = new WorkspaceService(); - 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.id = workspace.id; + this.logo = workspace.logo; + this.name = workspace.name; this.organization_size = workspace.organization_size; + this.owner = workspace.owner; + this.slug = workspace.slug; this.total_issues = workspace.total_issues; + this.total_members = workspace.total_members; + this.updated_at = workspace.updated_at; + this.updated_by = workspace.updated_by; + this.url = workspace.url; } + /** + * @description returns the workspace data in JSON format + */ get toJSON() { return { - id: this.id, - owner: this.owner, created_at: this.created_at, - updated_at: this.updated_at, - name: this.name, - url: this.url, - logo: this.logo, - total_members: this.total_members, - slug: this.slug, created_by: this.created_by, - updated_by: this.updated_by, + id: this.id, + logo: this.logo, + name: this.name, organization_size: this.organization_size, + owner: this.owner, + slug: this.slug, total_issues: this.total_issues, + total_members: this.total_members, + updated_at: this.updated_at, + updated_by: this.updated_by, + url: this.url, }; } + + /** + * @description update workspace using the new workspace data + * @param data + */ + updateWorkspace = async (data: Partial) => { + const originalData = { ...this }; + // optimistically update the store + runInAction(() => { + Object.entries(data).forEach(([key, value]) => { + set(this, [key], value); + }); + }); + + try { + const response = await this.workspaceService.updateWorkspace(this.slug, data); + return response; + } catch (error) { + // revert the store back to the original state + runInAction(() => { + Object.keys(data).forEach((key) => { + set(this, [key], originalData[key as keyof IWorkspace]); + }); + }); + throw error; + } + }; }