diff --git a/web/services/webhook.service.ts b/web/services/webhook.service.ts index abfe7c46d..11b3971cb 100644 --- a/web/services/webhook.service.ts +++ b/web/services/webhook.service.ts @@ -26,7 +26,7 @@ export class WebhookService extends APIService { }); } - async createWebhook(workspaceSlug: string, data: {}): Promise { + async createWebhook(workspaceSlug: string, data: Partial): Promise { return this.post(`/api/workspaces/${workspaceSlug}/webhooks/`, data) .then((response) => response?.data) .catch((error) => { @@ -34,7 +34,7 @@ export class WebhookService extends APIService { }); } - async updateWebhook(workspaceSlug: string, webhookId: string, data: {}): Promise { + async updateWebhook(workspaceSlug: string, webhookId: string, data: Partial): Promise { return this.patch(`/api/workspaces/${workspaceSlug}/webhooks/${webhookId}/`, data) .then((response) => response?.data) .catch((error) => { diff --git a/web/store/dataMaps/index.ts b/web/store/dataMaps/index.ts index 2dde5613b..6ec8e7c50 100644 --- a/web/store/dataMaps/index.ts +++ b/web/store/dataMaps/index.ts @@ -1,11 +1,14 @@ +import { IWebhookData, WebhookData } from "./webhook.data.store"; import { IWorkspaceData, WorkspaceData } from "./workspace.data.store"; export class DataStore { workspace: IWorkspaceData; + webhook: IWebhookData; constructor() { this.workspace = new WorkspaceData(this); + this.webhook = new WebhookData(this); } - resetOnSignout() {} + resetOnSignOut() {} } diff --git a/web/store/dataMaps/webhook.data.store.ts b/web/store/dataMaps/webhook.data.store.ts new file mode 100644 index 000000000..c80b45e28 --- /dev/null +++ b/web/store/dataMaps/webhook.data.store.ts @@ -0,0 +1,54 @@ +import { action, makeObservable, observable } from "mobx"; +import { computedFn } from "mobx-utils"; +import { set } from "lodash"; +// store +import { DataStore } from "."; +import { WebhookModel } from "store/webhook.store"; +// types +import { IWebhook } from "@plane/types"; + +export interface IWebhookData { + // observables + webhookMap: Record; + // actions + addWebhook: (webhooks: IWebhook) => void; + deleteWebhook: (webhookId: string) => void; + getWebhookById: (webhookId: string) => WebhookModel | undefined; +} + +export class WebhookData implements IWebhookData { + // observables + webhookMap: Record = {}; + // data store + dataStore; + + constructor(_dataStore: DataStore) { + makeObservable(this, { + // observables + webhookMap: observable, + // actions + addWebhook: action, + deleteWebhook: action, + }); + this.dataStore = _dataStore; + } + + /** + * @description add a webhook to the webhook map + * @param {IWebhook} webhook + */ + addWebhook = (webhook: IWebhook) => set(this.webhookMap, [webhook.id], new WebhookModel(webhook, this.dataStore)); + + /** + * @description delete a webhook from the webhook map + * @param {string} webhookId + */ + deleteWebhook = (webhookId: string) => delete this.webhookMap[webhookId]; + + /** + * @description get a webhook model by its id + * @param {string} webhookId + * @returns {WebhookModel | undefined} webhook model + */ + getWebhookById = computedFn((webhookId: string) => this.webhookMap[webhookId]); +} diff --git a/web/store/dataMaps/workspace.data.store.ts b/web/store/dataMaps/workspace.data.store.ts index 801ce458e..245d3557d 100644 --- a/web/store/dataMaps/workspace.data.store.ts +++ b/web/store/dataMaps/workspace.data.store.ts @@ -1,37 +1,55 @@ -import { makeObservable, observable } from "mobx"; -import { WorkspaceModel } from "store/workspace.store"; -import { DataStore } from "."; -import { IWorkspace } from "@plane/types"; +import { action, makeObservable, observable } from "mobx"; +import { computedFn } from "mobx-utils"; import { set } from "lodash"; +// store +import { DataStore } from "."; +import { WorkspaceModel } from "store/workspace.store"; +// types +import { IWorkspace } from "@plane/types"; export interface IWorkspaceData { + // observables workspaceMap: Record; - + // actions addWorkspace: (workspaces: IWorkspace) => void; deleteWorkspace: (workspaceId: string) => void; - getWorkspacebyId: (workspaceId: string) => WorkspaceModel | undefined; + getWorkspaceById: (workspaceId: string) => WorkspaceModel | undefined; } export class WorkspaceData implements IWorkspaceData { + // observables workspaceMap: Record = {}; - // data store dataStore; constructor(_dataStore: DataStore) { makeObservable(this, { + // observables workspaceMap: observable, + // actions + addWorkspace: action, + deleteWorkspace: action, }); this.dataStore = _dataStore; } - addWorkspace = (workspace: IWorkspace) => { + /** + * @description add a workspace to the workspace map + * @param {IWorkspace} workspace + */ + addWorkspace = (workspace: IWorkspace) => set(this.workspaceMap, [workspace.id], new WorkspaceModel(workspace, this.dataStore)); - }; - deleteWorkspace = (workspaceId: string) => { - delete this.workspaceMap[workspaceId]; - }; + /** + * @description delete a workspace from the workspace map + * @param {string} workspaceId + */ + deleteWorkspace = (workspaceId: string) => delete this.workspaceMap[workspaceId]; - getWorkspacebyId = (workspaceId: string) => this.workspaceMap[workspaceId]; + /** + * @description get a workspace model by its id + * @param {string} workspaceId + * @returns {WorkspaceModel | undefined} workspace model + */ + getWorkspaceById = computedFn((workspaceId: string) => this.workspaceMap[workspaceId]); } diff --git a/web/store/root.store.ts b/web/store/root.store.ts index d9dd18a82..3cbb96334 100644 --- a/web/store/root.store.ts +++ b/web/store/root.store.ts @@ -12,5 +12,5 @@ export class RootStore { this.user = new UserModel(this.data); } - resetOnSignout() {} + resetOnSignOut() {} } diff --git a/web/store/user.store.ts b/web/store/user.store.ts index 19a593f9e..3628946f5 100644 --- a/web/store/user.store.ts +++ b/web/store/user.store.ts @@ -26,14 +26,14 @@ export class UserModel implements IUserModel { } /** - * get workspace info from the array of workspaces in the store using workspace slug - * @param workspaceSlug + * @description get workspace info from the array of workspaces in the store using workspace slug + * @param {string} workspaceSlug */ getWorkspaceBySlug = (workspaceSlug: string) => Object.values(this.workspaces ?? {})?.find((w) => w.slug == workspaceSlug) || null; /** - * fetch user workspaces from API + * @description fetch user workspaces from API */ fetchWorkspaces = async () => { const workspaceResponse = await this.workspaceService.userWorkspaces(); @@ -48,8 +48,8 @@ export class UserModel implements IUserModel { }; /** - * create workspace using the workspace data - * @param data + * @description create workspace using the workspace data + * @param {Partial} data */ createWorkspace = async (data: Partial) => await this.workspaceService.createWorkspace(data).then((response) => { @@ -61,8 +61,8 @@ export class UserModel implements IUserModel { }); /** - * delete workspace using the workspace slug - * @param workspaceSlug + * @description delete workspace using the workspace slug + * @param {string} workspaceSlug */ deleteWorkspace = async (workspaceSlug: string) => await this.workspaceService.deleteWorkspace(workspaceSlug).then(() => { diff --git a/web/store/webhook.store.ts b/web/store/webhook.store.ts index 8e6a84870..3644935e5 100644 --- a/web/store/webhook.store.ts +++ b/web/store/webhook.store.ts @@ -97,11 +97,11 @@ export class WebhookModel implements IWebhookModel { /** * @description update a webhook using the data - * @param workspaceSlug - * @param data + * @param {string} workspaceSlug + * @param {Partial} data */ updateWebhook = async (workspaceSlug: string, data: Partial) => { - const originalData = { ...this }; + const originalData = this.asJSON; // optimistically update the store runInAction(() => { Object.entries(data).forEach(([key, value]) => { diff --git a/web/store/workspace.store.ts b/web/store/workspace.store.ts index 23cf2eba8..6995dc01a 100644 --- a/web/store/workspace.store.ts +++ b/web/store/workspace.store.ts @@ -3,8 +3,10 @@ import set from "lodash/set"; import { DataStore } from "./dataMaps"; // services import { WorkspaceService } from "services/workspace.service"; +import { WebhookService } from "services/webhook.service"; // types -import { IUser, IWorkspace } from "@plane/types"; +import { IUser, IWebhook, IWorkspace } from "@plane/types"; +import { IWebhookModel } from "./webhook.store"; export interface IWorkspaceModel { // model observables @@ -21,13 +23,20 @@ export interface IWorkspaceModel { url: string; updated_at: Date; updated_by: string; + // data maps + webhooks: Record; // computed - toJSON: IWorkspace; - // actions + asJSON: IWorkspace; + // workspace actions updateWorkspace: (data: Partial) => Promise; + // webhook actions + fetchWebhooks: () => Promise; + createWebhook: (data: Partial) => Promise; + deleteWebhook: (webhookId: string) => Promise; } export class WorkspaceModel implements IWorkspaceModel { + // model observables created_at: Date; created_by: string; id: string; @@ -41,10 +50,13 @@ export class WorkspaceModel implements IWorkspaceModel { updated_at: Date; updated_by: string; url: string; + // data maps + webhooks: Record = {}; // root store dataStore; // services workspaceService; + webhookService; constructor(workspace: IWorkspace, _dataStore: DataStore) { makeObservable(this, { @@ -62,14 +74,21 @@ export class WorkspaceModel implements IWorkspaceModel { updated_at: observable.ref, updated_by: observable.ref, url: observable.ref, + // data maps + webhooks: observable, // computed - toJSON: computed, - // actions + asJSON: computed, + // workspace actions updateWorkspace: action, + // webhook actions + fetchWebhooks: action, + createWebhook: action, + deleteWebhook: action, }); this.dataStore = _dataStore; // services this.workspaceService = new WorkspaceService(); + this.webhookService = new WebhookService(); this.created_at = workspace.created_at; this.created_by = workspace.created_by; @@ -89,7 +108,7 @@ export class WorkspaceModel implements IWorkspaceModel { /** * @description returns the workspace data in JSON format */ - get toJSON() { + get asJSON() { return { created_at: this.created_at, created_by: this.created_by, @@ -109,10 +128,10 @@ export class WorkspaceModel implements IWorkspaceModel { /** * @description update workspace using the new workspace data - * @param data + * @param {Partial} data */ updateWorkspace = async (data: Partial) => { - const originalData = { ...this }; + const originalData = this.asJSON; // optimistically update the store runInAction(() => { Object.entries(data).forEach(([key, value]) => { @@ -133,4 +152,47 @@ export class WorkspaceModel implements IWorkspaceModel { throw error; } }; + + // webhook actions + + /** + * @description fetch all the webhooks of the workspace + */ + fetchWebhooks = async () => { + const webhooksResponse = await this.webhookService.fetchWebhooksList(this.slug); + + runInAction(() => { + webhooksResponse.forEach((webhook) => { + this.dataStore.webhook.addWebhook(webhook); + set(this.webhooks, [webhook.id], this.dataStore.webhook.webhookMap[webhook.id]); + }); + }); + + return webhooksResponse; + }; + + /** + * @description create webhook using the webhook data + * @param {Partial} data + */ + createWebhook = async (data: Partial) => + await this.webhookService.createWebhook(this.slug, data).then((response) => { + runInAction(() => { + this.dataStore.webhook.addWebhook(response); + set(this.webhooks, [response.id], this.dataStore.webhook.webhookMap[response.id]); + }); + return response; + }); + + /** + * @description delete a webhook using webhook id + * @param {string} webhookId + */ + deleteWebhook = async (webhookId: string) => + await this.webhookService.deleteWebhook(this.slug, webhookId).then(() => { + this.dataStore.webhook.deleteWebhook(webhookId); + runInAction(() => { + delete this.webhooks[webhookId]; + }); + }); }