From b52f2487f46a490c058c8bf488141b21f192f5f1 Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal Date: Tue, 5 Mar 2024 15:32:16 +0530 Subject: [PATCH] chore: init api tokens data store and model --- web/store/api-token.store.ts | 110 +++++++++++++++++++++ web/store/dataMaps/api-token.data.store.ts | 54 ++++++++++ web/store/dataMaps/index.ts | 3 + web/store/webhook.store.ts | 4 + web/store/workspace.store.ts | 60 ++++++++++- 5 files changed, 229 insertions(+), 2 deletions(-) create mode 100644 web/store/api-token.store.ts create mode 100644 web/store/dataMaps/api-token.data.store.ts diff --git a/web/store/api-token.store.ts b/web/store/api-token.store.ts new file mode 100644 index 000000000..1083b583b --- /dev/null +++ b/web/store/api-token.store.ts @@ -0,0 +1,110 @@ +import { computed, makeObservable, observable } from "mobx"; +import { DataStore } from "./dataMaps"; +// services +import { APITokenService } from "services/api_token.service"; +// types +import { IApiToken } from "@plane/types"; + +export interface IAPITokenModel { + // model observables + created_at: string; + created_by: string; + description: string; + expired_at: string | null; + id: string; + is_active: boolean; + label: string; + last_used: string | null; + updated_at: string; + updated_by: string; + user: string; + user_type: number; + token?: string; + workspace: string; + // computed + asJSON: IApiToken; +} + +export class APIModel implements IAPITokenModel { + // model observables + created_at: string; + created_by: string; + description: string; + expired_at: string | null; + id: string; + is_active: boolean; + label: string; + last_used: string | null; + updated_at: string; + updated_by: string; + user: string; + user_type: number; + token?: string; + workspace: string; + // root store + dataStore; + // services + apiTokenService; + + constructor(apiToken: IApiToken, _dataStore: DataStore) { + makeObservable(this, { + // model observables + created_at: observable.ref, + created_by: observable.ref, + description: observable.ref, + expired_at: observable.ref, + id: observable.ref, + is_active: observable.ref, + label: observable.ref, + last_used: observable.ref, + updated_at: observable.ref, + updated_by: observable.ref, + user: observable.ref, + user_type: observable.ref, + token: observable.ref, + workspace: observable.ref, + // computed + asJSON: computed, + }); + this.dataStore = _dataStore; + // services + this.apiTokenService = new APITokenService(); + + this.created_at = apiToken.created_at; + this.created_by = apiToken.created_by; + this.description = apiToken.description; + this.expired_at = apiToken.expired_at; + this.id = apiToken.id; + this.is_active = apiToken.is_active; + this.label = apiToken.label; + this.last_used = apiToken.last_used; + this.updated_at = apiToken.updated_at; + this.updated_by = apiToken.updated_by; + this.user = apiToken.user; + this.user_type = apiToken.user_type; + this.token = apiToken.token; + this.workspace = apiToken.workspace; + } + + /** + * @description returns the API token data in JSON format + */ + get asJSON() { + return { + created_at: this.created_at, + created_by: this.created_by, + description: this.description, + expired_at: this.expired_at, + id: this.id, + is_active: this.is_active, + label: this.label, + last_used: this.last_used, + updated_at: this.updated_at, + updated_by: this.updated_by, + user: this.user, + user_type: this.user_type, + token: this.token, + workspace: this.workspace, + }; + } +} diff --git a/web/store/dataMaps/api-token.data.store.ts b/web/store/dataMaps/api-token.data.store.ts new file mode 100644 index 000000000..b08747b67 --- /dev/null +++ b/web/store/dataMaps/api-token.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 { APIModel } from "store/api-token.store"; +// types +import { IApiToken } from "@plane/types"; + +export interface IAPITokenData { + // observables + apiTokenMap: Record; + // actions + addAPIToken: (apiToken: IApiToken) => void; + deleteAPIToken: (apiTokenId: string) => void; + getAPITokenById: (apiTokenId: string) => APIModel | undefined; +} + +export class APITokenData implements IAPITokenData { + // observables + apiTokenMap: Record = {}; + // data store + dataStore; + + constructor(_dataStore: DataStore) { + makeObservable(this, { + // observables + apiTokenMap: observable, + // actions + addAPIToken: action, + deleteAPIToken: action, + }); + this.dataStore = _dataStore; + } + + /** + * @description add a API token to the API token map + * @param {IApiToken} apiToken + */ + addAPIToken = (apiToken: IApiToken) => set(this.apiTokenMap, [apiToken.id], new APIModel(apiToken, this.dataStore)); + + /** + * @description delete a API token from the API token map + * @param {string} apiTokenId + */ + deleteAPIToken = (apiTokenId: string) => delete this.apiTokenMap[apiTokenId]; + + /** + * @description get a API token model by its id + * @param {string} apiTokenId + * @returns {APIModel | undefined} API token model + */ + getAPITokenById = computedFn((apiTokenId: string) => this.apiTokenMap[apiTokenId]); +} diff --git a/web/store/dataMaps/index.ts b/web/store/dataMaps/index.ts index 6ec8e7c50..479d9a0a8 100644 --- a/web/store/dataMaps/index.ts +++ b/web/store/dataMaps/index.ts @@ -1,13 +1,16 @@ +import { APITokenData, IAPITokenData } from "./api-token.data.store"; import { IWebhookData, WebhookData } from "./webhook.data.store"; import { IWorkspaceData, WorkspaceData } from "./workspace.data.store"; export class DataStore { workspace: IWorkspaceData; webhook: IWebhookData; + apiToken: IAPITokenData; constructor() { this.workspace = new WorkspaceData(this); this.webhook = new WebhookData(this); + this.apiToken = new APITokenData(this); } resetOnSignOut() {} diff --git a/web/store/webhook.store.ts b/web/store/webhook.store.ts index 3644935e5..92eb31671 100644 --- a/web/store/webhook.store.ts +++ b/web/store/webhook.store.ts @@ -46,12 +46,16 @@ export class WebhookModel implements IWebhookModel { constructor(webhook: IWebhook, _dataStore: DataStore) { makeObservable(this, { // model observables + created_at: observable.ref, cycle: observable.ref, + id: observable.ref, is_active: observable.ref, issue: observable.ref, issue_comment: observable.ref, module: observable.ref, project: observable.ref, + secret_key: observable.ref, + updated_at: observable.ref, url: observable.ref, // computed asJSON: computed, diff --git a/web/store/workspace.store.ts b/web/store/workspace.store.ts index 6995dc01a..069ca030d 100644 --- a/web/store/workspace.store.ts +++ b/web/store/workspace.store.ts @@ -4,9 +4,11 @@ import { DataStore } from "./dataMaps"; // services import { WorkspaceService } from "services/workspace.service"; import { WebhookService } from "services/webhook.service"; +import { APITokenService } from "services/api_token.service"; // types -import { IUser, IWebhook, IWorkspace } from "@plane/types"; +import { IApiToken, IUser, IWebhook, IWorkspace } from "@plane/types"; import { IWebhookModel } from "./webhook.store"; +import { IAPITokenModel } from "./api-token.store"; export interface IWorkspaceModel { // model observables @@ -25,6 +27,7 @@ export interface IWorkspaceModel { updated_by: string; // data maps webhooks: Record; + apiTokens: Record; // computed asJSON: IWorkspace; // workspace actions @@ -33,6 +36,10 @@ export interface IWorkspaceModel { fetchWebhooks: () => Promise; createWebhook: (data: Partial) => Promise; deleteWebhook: (webhookId: string) => Promise; + // API token actions + fetchApiTokens: () => Promise; + createApiToken: (data: Partial) => Promise; + deleteApiToken: (tokenId: string) => Promise; } export class WorkspaceModel implements IWorkspaceModel { @@ -52,11 +59,13 @@ export class WorkspaceModel implements IWorkspaceModel { url: string; // data maps webhooks: Record = {}; + apiTokens: Record = {}; // root store dataStore; // services workspaceService; webhookService; + apiTokenService; constructor(workspace: IWorkspace, _dataStore: DataStore) { makeObservable(this, { @@ -76,6 +85,7 @@ export class WorkspaceModel implements IWorkspaceModel { url: observable.ref, // data maps webhooks: observable, + apiTokens: observable, // computed asJSON: computed, // workspace actions @@ -84,11 +94,16 @@ export class WorkspaceModel implements IWorkspaceModel { fetchWebhooks: action, createWebhook: action, deleteWebhook: action, + // API token actions + fetchApiTokens: action, + createApiToken: action, + deleteApiToken: action, }); this.dataStore = _dataStore; // services this.workspaceService = new WorkspaceService(); this.webhookService = new WebhookService(); + this.apiTokenService = new APITokenService(); this.created_at = workspace.created_at; this.created_by = workspace.created_by; @@ -167,7 +182,6 @@ export class WorkspaceModel implements IWorkspaceModel { set(this.webhooks, [webhook.id], this.dataStore.webhook.webhookMap[webhook.id]); }); }); - return webhooksResponse; }; @@ -195,4 +209,46 @@ export class WorkspaceModel implements IWorkspaceModel { delete this.webhooks[webhookId]; }); }); + + // API token actions + + /** + * @description fetch all the API tokens of the workspace + */ + fetchApiTokens = async () => { + const apiTokensResponse = await this.apiTokenService.getApiTokens(this.slug); + + runInAction(() => { + apiTokensResponse.forEach((apiToken) => { + this.dataStore.apiToken.addAPIToken(apiToken); + set(this.apiTokens, [apiToken.id], this.dataStore.apiToken.apiTokenMap[apiToken.id]); + }); + }); + return apiTokensResponse; + }; + + /** + * @description create API token using data + * @param {Partial} data + */ + createApiToken = async (data: Partial) => + await this.apiTokenService.createApiToken(this.slug, data).then((response) => { + runInAction(() => { + this.dataStore.apiToken.addAPIToken(response); + set(this.apiTokens, [response.id], this.dataStore.apiToken.apiTokenMap[response.id]); + }); + return response; + }); + + /** + * @description delete API token using token id + * @param {string} tokenId + */ + deleteApiToken = async (tokenId: string) => + await this.apiTokenService.deleteApiToken(this.slug, tokenId).then(() => { + this.dataStore.apiToken.deleteAPIToken(tokenId); + runInAction(() => { + delete this.apiTokens[tokenId]; + }); + }); }