mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
chore: setup workspace store and sub-stores
This commit is contained in:
parent
92326def36
commit
8ed9c6a2fd
184
web/store/workspace/api-token.store.ts
Normal file
184
web/store/workspace/api-token.store.ts
Normal file
@ -0,0 +1,184 @@
|
||||
// mobx
|
||||
import { action, observable, makeObservable, runInAction } from "mobx";
|
||||
import { APITokenService } from "services/api_token.service";
|
||||
import { RootStore } from "../root.store";
|
||||
// types
|
||||
import { IApiToken } from "types/api_token";
|
||||
|
||||
export interface IApiTokenStore {
|
||||
// states
|
||||
loader: boolean;
|
||||
error: any | null;
|
||||
|
||||
// observables
|
||||
apiTokens: Record<string, IApiToken> | null;
|
||||
|
||||
// computed actions
|
||||
getApiTokenById: (apiTokenId: string) => IApiToken | null;
|
||||
|
||||
// actions
|
||||
fetchApiTokens: (workspaceSlug: string) => Promise<IApiToken[]>;
|
||||
fetchApiTokenDetails: (workspaceSlug: string, tokenId: string) => Promise<IApiToken>;
|
||||
createApiToken: (workspaceSlug: string, data: Partial<IApiToken>) => Promise<IApiToken>;
|
||||
deleteApiToken: (workspaceSlug: string, tokenId: string) => Promise<void>;
|
||||
}
|
||||
|
||||
export class ApiTokenStore implements IApiTokenStore {
|
||||
// states
|
||||
loader: boolean = false;
|
||||
error: any | null = null;
|
||||
|
||||
// observables
|
||||
apiTokens: Record<string, IApiToken> | null = null;
|
||||
|
||||
// services
|
||||
apiTokenService;
|
||||
// root store
|
||||
rootStore;
|
||||
|
||||
constructor(_rootStore: RootStore) {
|
||||
makeObservable(this, {
|
||||
// states
|
||||
loader: observable.ref,
|
||||
error: observable.ref,
|
||||
|
||||
// observables
|
||||
apiTokens: observable,
|
||||
|
||||
// computed actions
|
||||
getApiTokenById: action,
|
||||
|
||||
// actions
|
||||
fetchApiTokens: action,
|
||||
fetchApiTokenDetails: action,
|
||||
createApiToken: action,
|
||||
deleteApiToken: action,
|
||||
});
|
||||
|
||||
// services
|
||||
this.apiTokenService = new APITokenService();
|
||||
// root store
|
||||
this.rootStore = _rootStore;
|
||||
}
|
||||
|
||||
/**
|
||||
* get API token by id
|
||||
* @param apiTokenId
|
||||
*/
|
||||
getApiTokenById = (apiTokenId: string) => {
|
||||
if (!this.apiTokens) return null;
|
||||
|
||||
return this.apiTokens[apiTokenId] || null;
|
||||
};
|
||||
|
||||
/**
|
||||
* fetch all the API tokens for a workspace
|
||||
* @param workspaceSlug
|
||||
*/
|
||||
fetchApiTokens = async (workspaceSlug: string) => {
|
||||
try {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
|
||||
const response = await this.apiTokenService.getApiTokens(workspaceSlug);
|
||||
|
||||
const apiTokensObject: { [apiTokenId: string]: IApiToken } = response.reduce((accumulator, currentWebhook) => {
|
||||
if (currentWebhook && currentWebhook.id) {
|
||||
return { ...accumulator, [currentWebhook.id]: currentWebhook };
|
||||
}
|
||||
return accumulator;
|
||||
}, {});
|
||||
|
||||
runInAction(() => {
|
||||
this.apiTokens = apiTokensObject;
|
||||
});
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
runInAction(() => {
|
||||
this.error = error;
|
||||
});
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* fetch API token details using token id
|
||||
* @param workspaceSlug
|
||||
* @param tokenId
|
||||
*/
|
||||
fetchApiTokenDetails = async (workspaceSlug: string, tokenId: string) => {
|
||||
try {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
|
||||
const response = await this.apiTokenService.retrieveApiToken(workspaceSlug, tokenId);
|
||||
|
||||
runInAction(() => {
|
||||
this.apiTokens = { ...this.apiTokens, [response.id]: response };
|
||||
});
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
runInAction(() => {
|
||||
this.error = error;
|
||||
});
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* create API token using data
|
||||
* @param workspaceSlug
|
||||
* @param data
|
||||
*/
|
||||
createApiToken = async (workspaceSlug: string, data: Partial<IApiToken>) => {
|
||||
try {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
|
||||
const response = await this.apiTokenService.createApiToken(workspaceSlug, data);
|
||||
|
||||
runInAction(() => {
|
||||
this.apiTokens = { ...this.apiTokens, [response.id]: response };
|
||||
});
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
runInAction(() => {
|
||||
this.error = error;
|
||||
});
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* delete API token using token id
|
||||
* @param workspaceSlug
|
||||
* @param tokenId
|
||||
*/
|
||||
deleteApiToken = async (workspaceSlug: string, tokenId: string) => {
|
||||
try {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
|
||||
await this.apiTokenService.deleteApiToken(workspaceSlug, tokenId);
|
||||
|
||||
const updatedApiTokens = { ...this.apiTokens };
|
||||
delete updatedApiTokens[tokenId];
|
||||
|
||||
runInAction(() => {
|
||||
this.apiTokens = updatedApiTokens;
|
||||
});
|
||||
} catch (error) {
|
||||
runInAction(() => {
|
||||
this.error = error;
|
||||
});
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
}
|
245
web/store/workspace/index.ts
Normal file
245
web/store/workspace/index.ts
Normal file
@ -0,0 +1,245 @@
|
||||
import { action, computed, observable, makeObservable, runInAction } from "mobx";
|
||||
import { RootStore } from "../root.store";
|
||||
// types
|
||||
import { IWorkspace } from "types";
|
||||
// services
|
||||
import { WorkspaceService } from "services/workspace.service";
|
||||
// sub-stores
|
||||
import { WebhookStore } from "./webhook.store";
|
||||
import { ApiTokenStore } from "./api-token.store";
|
||||
|
||||
export interface IWorkspaceStore {
|
||||
// states
|
||||
loader: boolean;
|
||||
error: any | null;
|
||||
|
||||
// observables
|
||||
workspaces: IWorkspace[] | undefined;
|
||||
|
||||
// computed
|
||||
currentWorkspace: IWorkspace | null;
|
||||
workspacesCreatedByCurrentUser: IWorkspace[] | null;
|
||||
|
||||
// computed actions
|
||||
getWorkspaceBySlug: (workspaceSlug: string) => IWorkspace | null;
|
||||
getWorkspaceById: (workspaceId: string) => IWorkspace | null;
|
||||
|
||||
// actions
|
||||
fetchWorkspaces: () => Promise<IWorkspace[]>;
|
||||
createWorkspace: (data: Partial<IWorkspace>) => Promise<IWorkspace>;
|
||||
updateWorkspace: (workspaceSlug: string, data: Partial<IWorkspace>) => Promise<IWorkspace>;
|
||||
deleteWorkspace: (workspaceSlug: string) => Promise<void>;
|
||||
|
||||
// sub-stores
|
||||
webhook: WebhookStore;
|
||||
apiToken: ApiTokenStore;
|
||||
}
|
||||
|
||||
export class WorkspaceStore implements IWorkspaceStore {
|
||||
// states
|
||||
loader: boolean = false;
|
||||
error: any | null = null;
|
||||
|
||||
// observables
|
||||
workspaces: IWorkspace[] | undefined = [];
|
||||
|
||||
// services
|
||||
workspaceService;
|
||||
// root store
|
||||
rootStore;
|
||||
// sub-stores
|
||||
webhook: WebhookStore;
|
||||
apiToken: ApiTokenStore;
|
||||
|
||||
constructor(_rootStore: RootStore) {
|
||||
makeObservable(this, {
|
||||
// states
|
||||
loader: observable.ref,
|
||||
error: observable.ref,
|
||||
|
||||
// observables
|
||||
workspaces: observable,
|
||||
|
||||
// computed
|
||||
currentWorkspace: computed,
|
||||
workspacesCreatedByCurrentUser: computed,
|
||||
|
||||
// computed actions
|
||||
getWorkspaceBySlug: action,
|
||||
getWorkspaceById: action,
|
||||
|
||||
// actions
|
||||
fetchWorkspaces: action,
|
||||
createWorkspace: action,
|
||||
updateWorkspace: action,
|
||||
deleteWorkspace: action,
|
||||
});
|
||||
|
||||
// services
|
||||
this.workspaceService = new WorkspaceService();
|
||||
// root store
|
||||
this.rootStore = _rootStore;
|
||||
// sub-stores
|
||||
this.webhook = new WebhookStore(_rootStore);
|
||||
this.apiToken = new ApiTokenStore(_rootStore);
|
||||
}
|
||||
|
||||
/**
|
||||
* computed value of current workspace based on workspace slug saved in the query store
|
||||
*/
|
||||
get currentWorkspace() {
|
||||
const workspaceSlug = this.rootStore.app.router.query?.workspaceSlug;
|
||||
|
||||
if (!workspaceSlug) return null;
|
||||
|
||||
return this.workspaces?.find((workspace) => workspace.slug === workspaceSlug.toString()) || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* computed value of all the workspaces created by the current logged in user
|
||||
*/
|
||||
get workspacesCreatedByCurrentUser() {
|
||||
if (!this.workspaces) return null;
|
||||
|
||||
const user = this.rootStore.user.currentUser;
|
||||
|
||||
if (!user) return null;
|
||||
|
||||
return this.workspaces.filter((w) => w.created_by === user?.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* get workspace info from the array of workspaces in the store using workspace slug
|
||||
* @param workspaceSlug
|
||||
*/
|
||||
getWorkspaceBySlug = (workspaceSlug: string) => this.workspaces?.find((w) => w.slug == workspaceSlug) || null;
|
||||
|
||||
/**
|
||||
* get workspace info from the array of workspaces in the store using workspace id
|
||||
* @param workspaceId
|
||||
*/
|
||||
getWorkspaceById = (workspaceId: string) => this.workspaces?.find((w) => w.id == workspaceId) || null;
|
||||
|
||||
/**
|
||||
* fetch user workspaces from API
|
||||
*/
|
||||
fetchWorkspaces = async () => {
|
||||
try {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
|
||||
const workspaceResponse = await this.workspaceService.userWorkspaces();
|
||||
|
||||
runInAction(() => {
|
||||
this.workspaces = workspaceResponse;
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
});
|
||||
|
||||
return workspaceResponse;
|
||||
} catch (error) {
|
||||
console.log("Failed to fetch user workspaces in workspace store", error);
|
||||
|
||||
runInAction(() => {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
this.workspaces = [];
|
||||
});
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* create workspace using the workspace data
|
||||
* @param data
|
||||
*/
|
||||
createWorkspace = async (data: Partial<IWorkspace>) => {
|
||||
try {
|
||||
runInAction(() => {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
});
|
||||
|
||||
const response = await this.workspaceService.createWorkspace(data);
|
||||
|
||||
runInAction(() => {
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
this.workspaces = [...(this.workspaces ?? []), response];
|
||||
});
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
runInAction(() => {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
});
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* update workspace using the workspace slug and new workspace data
|
||||
* @param workspaceSlug
|
||||
* @param data
|
||||
*/
|
||||
updateWorkspace = async (workspaceSlug: string, data: Partial<IWorkspace>) => {
|
||||
const newWorkspaces = this.workspaces?.map((w) => (w.slug === workspaceSlug ? { ...w, ...data } : w));
|
||||
|
||||
try {
|
||||
runInAction(() => {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
});
|
||||
|
||||
const response = await this.workspaceService.updateWorkspace(workspaceSlug, data);
|
||||
|
||||
runInAction(() => {
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
this.workspaces = newWorkspaces;
|
||||
});
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
runInAction(() => {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
});
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* delete workspace using the workspace slug
|
||||
* @param workspaceSlug
|
||||
*/
|
||||
deleteWorkspace = async (workspaceSlug: string) => {
|
||||
const newWorkspaces = this.workspaces?.filter((w) => w.slug !== workspaceSlug);
|
||||
|
||||
try {
|
||||
runInAction(() => {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
});
|
||||
|
||||
await this.workspaceService.deleteWorkspace(workspaceSlug);
|
||||
|
||||
runInAction(() => {
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
this.workspaces = newWorkspaces;
|
||||
});
|
||||
} catch (error) {
|
||||
runInAction(() => {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
});
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
}
|
261
web/store/workspace/webhook.store.ts
Normal file
261
web/store/workspace/webhook.store.ts
Normal file
@ -0,0 +1,261 @@
|
||||
// mobx
|
||||
import { action, observable, makeObservable, computed, runInAction } from "mobx";
|
||||
import { IWebhook } from "types";
|
||||
import { WebhookService } from "services/webhook.service";
|
||||
import { RootStore } from "../root.store";
|
||||
|
||||
export interface IWebhookStore {
|
||||
// states
|
||||
loader: boolean;
|
||||
error: any | null;
|
||||
|
||||
// observables
|
||||
webhooks: Record<string, IWebhook> | null;
|
||||
webhookSecretKey: string | null;
|
||||
|
||||
// computed
|
||||
currentWebhook: IWebhook | null;
|
||||
|
||||
// computed actions
|
||||
getWebhookById: (webhookId: string) => IWebhook | null;
|
||||
|
||||
// actions
|
||||
fetchWebhooks: (workspaceSlug: string) => Promise<IWebhook[]>;
|
||||
fetchWebhookById: (workspaceSlug: string, webhookId: string) => Promise<IWebhook>;
|
||||
createWebhook: (
|
||||
workspaceSlug: string,
|
||||
data: Partial<IWebhook>
|
||||
) => Promise<{ webHook: IWebhook; secretKey: string | null }>;
|
||||
updateWebhook: (workspaceSlug: string, webhookId: string, data: Partial<IWebhook>) => Promise<IWebhook>;
|
||||
removeWebhook: (workspaceSlug: string, webhookId: string) => Promise<void>;
|
||||
regenerateSecretKey: (
|
||||
workspaceSlug: string,
|
||||
webhookId: string
|
||||
) => Promise<{ webHook: IWebhook; secretKey: string | null }>;
|
||||
clearSecretKey: () => void;
|
||||
}
|
||||
|
||||
export class WebhookStore implements IWebhookStore {
|
||||
// states
|
||||
loader: boolean = false;
|
||||
error: any | null = null;
|
||||
|
||||
// observables
|
||||
webhooks: Record<string, IWebhook> | null = null;
|
||||
webhookSecretKey: string | null = null;
|
||||
|
||||
// services
|
||||
webhookService;
|
||||
// root store
|
||||
rootStore;
|
||||
|
||||
constructor(_rootStore: RootStore) {
|
||||
makeObservable(this, {
|
||||
// states
|
||||
loader: observable.ref,
|
||||
error: observable.ref,
|
||||
|
||||
// observables
|
||||
webhooks: observable,
|
||||
webhookSecretKey: observable.ref,
|
||||
|
||||
// computed
|
||||
currentWebhook: computed,
|
||||
|
||||
// computed actions
|
||||
getWebhookById: action,
|
||||
|
||||
// actions
|
||||
fetchWebhooks: action,
|
||||
fetchWebhookById: action,
|
||||
createWebhook: action,
|
||||
updateWebhook: action,
|
||||
removeWebhook: action,
|
||||
regenerateSecretKey: action,
|
||||
clearSecretKey: action,
|
||||
});
|
||||
|
||||
// services
|
||||
this.webhookService = new WebhookService();
|
||||
// root store
|
||||
this.rootStore = _rootStore;
|
||||
}
|
||||
|
||||
/**
|
||||
* computed value of current webhook based on webhook id saved in the query store
|
||||
*/
|
||||
get currentWebhook() {
|
||||
const webhookId = this.rootStore.app.router.query?.webhookId;
|
||||
|
||||
if (!webhookId) return null;
|
||||
|
||||
const currentWebhook = this.webhooks?.[webhookId] ?? null;
|
||||
return currentWebhook;
|
||||
}
|
||||
|
||||
/**
|
||||
* get webhook info from the object of webhooks in the store using webhook id
|
||||
* @param webhookId
|
||||
*/
|
||||
getWebhookById = (webhookId: string) => this.webhooks?.[webhookId] || null;
|
||||
|
||||
/**
|
||||
* fetch all the webhooks for a workspace
|
||||
* @param workspaceSlug
|
||||
*/
|
||||
fetchWebhooks = async (workspaceSlug: string) => {
|
||||
try {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
|
||||
const webhookResponse = await this.webhookService.fetchWebhooksList(workspaceSlug);
|
||||
|
||||
const webHookObject: { [webhookId: string]: IWebhook } = webhookResponse.reduce((accumulator, currentWebhook) => {
|
||||
if (currentWebhook && currentWebhook.id) {
|
||||
return { ...accumulator, [currentWebhook.id]: currentWebhook };
|
||||
}
|
||||
return accumulator;
|
||||
}, {});
|
||||
|
||||
runInAction(() => {
|
||||
this.webhooks = webHookObject;
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
});
|
||||
|
||||
return webhookResponse;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* fetch webhook info from API using webhook id
|
||||
* @param workspaceSlug
|
||||
* @param webhookId
|
||||
*/
|
||||
fetchWebhookById = async (workspaceSlug: string, webhookId: string) => {
|
||||
try {
|
||||
const webhookResponse = await this.webhookService.fetchWebhookDetails(workspaceSlug, webhookId);
|
||||
|
||||
runInAction(() => {
|
||||
this.webhooks = {
|
||||
...this.webhooks,
|
||||
[webhookResponse.id]: webhookResponse,
|
||||
};
|
||||
});
|
||||
|
||||
return webhookResponse;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* create a new webhook for a workspace using the data
|
||||
* @param workspaceSlug
|
||||
* @param data
|
||||
*/
|
||||
createWebhook = async (workspaceSlug: string, data: Partial<IWebhook>) => {
|
||||
try {
|
||||
const webhookResponse = await this.webhookService.createWebhook(workspaceSlug, data);
|
||||
|
||||
const _secretKey = webhookResponse?.secret_key ?? null;
|
||||
delete webhookResponse?.secret_key;
|
||||
const _webhooks = this.webhooks;
|
||||
|
||||
if (webhookResponse && webhookResponse.id && _webhooks) _webhooks[webhookResponse.id] = webhookResponse;
|
||||
|
||||
runInAction(() => {
|
||||
this.webhookSecretKey = _secretKey || null;
|
||||
this.webhooks = _webhooks;
|
||||
});
|
||||
|
||||
return { webHook: webhookResponse, secretKey: _secretKey };
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* update a webhook using the data
|
||||
* @param workspaceSlug
|
||||
* @param webhookId
|
||||
* @param data
|
||||
*/
|
||||
updateWebhook = async (workspaceSlug: string, webhookId: string, data: Partial<IWebhook>) => {
|
||||
try {
|
||||
let _webhooks = this.webhooks;
|
||||
|
||||
if (webhookId && _webhooks && this.webhooks)
|
||||
_webhooks = { ..._webhooks, [webhookId]: { ...this.webhooks[webhookId], ...data } };
|
||||
|
||||
runInAction(() => {
|
||||
this.webhooks = _webhooks;
|
||||
});
|
||||
|
||||
const webhookResponse = await this.webhookService.updateWebhook(workspaceSlug, webhookId, data);
|
||||
|
||||
return webhookResponse;
|
||||
} catch (error) {
|
||||
this.fetchWebhooks(workspaceSlug);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* delete a webhook using webhook id
|
||||
* @param workspaceSlug
|
||||
* @param webhookId
|
||||
*/
|
||||
removeWebhook = async (workspaceSlug: string, webhookId: string) => {
|
||||
try {
|
||||
await this.webhookService.deleteWebhook(workspaceSlug, webhookId);
|
||||
|
||||
const _webhooks = this.webhooks ?? {};
|
||||
delete _webhooks[webhookId];
|
||||
runInAction(() => {
|
||||
this.webhooks = _webhooks;
|
||||
});
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* regenerate secret key for a webhook using webhook id
|
||||
* @param workspaceSlug
|
||||
* @param webhookId
|
||||
*/
|
||||
regenerateSecretKey = async (workspaceSlug: string, webhookId: string) => {
|
||||
try {
|
||||
const webhookResponse = await this.webhookService.regenerateSecretKey(workspaceSlug, webhookId);
|
||||
|
||||
const _secretKey = webhookResponse?.secret_key ?? null;
|
||||
delete webhookResponse?.secret_key;
|
||||
const _webhooks = this.webhooks;
|
||||
|
||||
if (_webhooks && webhookResponse && webhookResponse.id) {
|
||||
_webhooks[webhookResponse.id] = webhookResponse;
|
||||
}
|
||||
|
||||
runInAction(() => {
|
||||
this.webhookSecretKey = _secretKey || null;
|
||||
this.webhooks = _webhooks;
|
||||
});
|
||||
return { webHook: webhookResponse, secretKey: _secretKey };
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* clear secret key from the store
|
||||
*/
|
||||
clearSecretKey = () => {
|
||||
this.webhookSecretKey = null;
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user