From c4d54785e39bd480fd3bf6d6cc3b1c4ea980273e Mon Sep 17 00:00:00 2001 From: Prateek Shourya Date: Thu, 21 Dec 2023 11:44:43 +0530 Subject: [PATCH] refactor: mobx store improvements. --- .../pages/pages-list/all-pages-list.tsx | 6 +- .../pages/pages-list/archived-pages-list.tsx | 6 +- .../pages/pages-list/favorite-pages-list.tsx | 6 +- web/components/pages/pages-list/list-view.tsx | 10 +- .../pages/pages-list/private-page-list.tsx | 6 +- .../pages/pages-list/shared-pages-list.tsx | 6 +- web/services/module.service.ts | 3 +- web/services/user.service.ts | 2 +- web/services/workspace.service.ts | 2 +- web/store/estimate.store.ts | 89 ++----- web/store/global-view.store.ts | 115 ++------- web/store/label/project-label.store.ts | 71 ++---- web/store/label/workspace-label.store.ts | 16 +- web/store/member/project-member.store.ts | 74 +++--- web/store/member/workspace-member.store.ts | 90 +++---- web/store/page.store.ts | 223 ++++++------------ web/store/state.store.ts | 122 ++++------ web/store/user/index.ts | 217 ++++++++--------- web/store/user/user-membership.store.ts | 152 ++++++------ web/store/workspace/api-token.store.ts | 97 ++------ web/store/workspace/index.ts | 90 ++----- web/store/workspace/webhook.store.ts | 128 +++------- 22 files changed, 516 insertions(+), 1015 deletions(-) diff --git a/web/components/pages/pages-list/all-pages-list.tsx b/web/components/pages/pages-list/all-pages-list.tsx index 0d757ea91e3..0f02efb5591 100644 --- a/web/components/pages/pages-list/all-pages-list.tsx +++ b/web/components/pages/pages-list/all-pages-list.tsx @@ -9,9 +9,9 @@ import { Loader } from "@plane/ui"; export const AllPagesList: FC = observer(() => { // store - const { projectPages } = usePage(); + const { projectPageIds } = usePage(); - if (!projectPages) + if (!projectPageIds) return ( @@ -20,5 +20,5 @@ export const AllPagesList: FC = observer(() => { ); - return ; + return ; }); diff --git a/web/components/pages/pages-list/archived-pages-list.tsx b/web/components/pages/pages-list/archived-pages-list.tsx index 32d9bbddfb1..b0de1924155 100644 --- a/web/components/pages/pages-list/archived-pages-list.tsx +++ b/web/components/pages/pages-list/archived-pages-list.tsx @@ -8,9 +8,9 @@ import { usePage } from "hooks/store"; import { Loader } from "@plane/ui"; export const ArchivedPagesList: FC = observer(() => { - const { archivedProjectPages } = usePage(); + const { archivedProjectPageIds } = usePage(); - if (!archivedProjectPages) + if (!archivedProjectPageIds) return ( @@ -19,5 +19,5 @@ export const ArchivedPagesList: FC = observer(() => { ); - return ; + return ; }); diff --git a/web/components/pages/pages-list/favorite-pages-list.tsx b/web/components/pages/pages-list/favorite-pages-list.tsx index 013767b06e9..fc2b55cad6a 100644 --- a/web/components/pages/pages-list/favorite-pages-list.tsx +++ b/web/components/pages/pages-list/favorite-pages-list.tsx @@ -8,9 +8,9 @@ import { usePage } from "hooks/store"; import { Loader } from "@plane/ui"; export const FavoritePagesList: FC = observer(() => { - const { favoriteProjectPages } = usePage(); + const { favoriteProjectPageIds } = usePage(); - if (!favoriteProjectPages) + if (!favoriteProjectPageIds) return ( @@ -19,5 +19,5 @@ export const FavoritePagesList: FC = observer(() => { ); - return ; + return ; }); diff --git a/web/components/pages/pages-list/list-view.tsx b/web/components/pages/pages-list/list-view.tsx index 525dc20a159..059a6136f1a 100644 --- a/web/components/pages/pages-list/list-view.tsx +++ b/web/components/pages/pages-list/list-view.tsx @@ -15,11 +15,11 @@ import emptyPage from "public/empty-state/empty_page.png"; import { EUserProjectRoles } from "constants/project"; type IPagesListView = { - pages: string[]; + pageIds: string[]; }; export const PagesListView: FC = observer((props) => { - const { pages } = props; + const { pageIds } = props; // store hooks const { commandPalette: { toggleCreatePageModal }, @@ -35,11 +35,11 @@ export const PagesListView: FC = observer((props) => { return ( <> - {pages && workspaceSlug && projectId ? ( + {pageIds && workspaceSlug && projectId ? (
- {pages.length > 0 ? ( + {pageIds.length > 0 ? (
    - {pages.map((pageId) => ( + {pageIds.map((pageId) => ( { - const { privateProjectPages } = usePage(); + const { privateProjectPageIds } = usePage(); - if (!privateProjectPages) + if (!privateProjectPageIds) return ( @@ -19,5 +19,5 @@ export const PrivatePagesList: FC = observer(() => { ); - return ; + return ; }); diff --git a/web/components/pages/pages-list/shared-pages-list.tsx b/web/components/pages/pages-list/shared-pages-list.tsx index b36625806e4..8b2c56018a5 100644 --- a/web/components/pages/pages-list/shared-pages-list.tsx +++ b/web/components/pages/pages-list/shared-pages-list.tsx @@ -8,9 +8,9 @@ import { usePage } from "hooks/store"; import { Loader } from "@plane/ui"; export const SharedPagesList: FC = observer(() => { - const { publicProjectPages } = usePage(); + const { publicProjectPageIds } = usePage(); - if (!publicProjectPages) + if (!publicProjectPageIds) return ( @@ -19,5 +19,5 @@ export const SharedPagesList: FC = observer(() => { ); - return ; + return ; }); diff --git a/web/services/module.service.ts b/web/services/module.service.ts index 2f3b23296da..05c9bd9f990 100644 --- a/web/services/module.service.ts +++ b/web/services/module.service.ts @@ -1,8 +1,7 @@ // services import { APIService } from "services/api.service"; // types -import type { IModule, IIssue, ILinkDetails, ModuleLink } from "types"; -import { IIssueResponse } from "types"; +import type { IModule, IIssue, ILinkDetails, ModuleLink, IIssueResponse } from "types"; import { API_BASE_URL } from "helpers/common.helper"; export class ModuleService extends APIService { diff --git a/web/services/user.service.ts b/web/services/user.service.ts index 095d6a0c460..449da7659c8 100644 --- a/web/services/user.service.ts +++ b/web/services/user.service.ts @@ -10,10 +10,10 @@ import type { IUserProfileProjectSegregation, IUserSettings, IUserWorkspaceDashboard, + IIssueResponse, } from "types"; // helpers import { API_BASE_URL } from "helpers/common.helper"; -import { IIssueResponse } from "types"; export class UserService extends APIService { constructor() { diff --git a/web/services/workspace.service.ts b/web/services/workspace.service.ts index 7f154975e7e..93301c517e1 100644 --- a/web/services/workspace.service.ts +++ b/web/services/workspace.service.ts @@ -14,9 +14,9 @@ import { IWorkspaceBulkInviteFormData, IWorkspaceViewProps, IUserProjectsRole, + IIssueResponse, } from "types"; import { IWorkspaceView } from "types/workspace-views"; -import { IIssueResponse } from "types"; export class WorkspaceService extends APIService { constructor() { diff --git a/web/store/estimate.store.ts b/web/store/estimate.store.ts index 7c192d26aaf..dadfb36ce66 100644 --- a/web/store/estimate.store.ts +++ b/web/store/estimate.store.ts @@ -8,9 +8,6 @@ import { IEstimate, IEstimateFormData } from "types"; // TODO: rename to IEstimateStore export interface IProjectEstimateStore { - // states - loader: boolean; - error: any | null; // observables estimates: Record; // computed @@ -20,8 +17,9 @@ export interface IProjectEstimateStore { // computed actions getEstimatePointValue: (estimateKey: number | null) => string; getProjectEstimateById: (estimateId: string) => IEstimate | null; - // actions + // fetch actions fetchProjectEstimates: (workspaceSlug: string, projectId: string) => Promise; + // crud actions createEstimate: (workspaceSlug: string, projectId: string, data: IEstimateFormData) => Promise; updateEstimate: ( workspaceSlug: string, @@ -33,9 +31,6 @@ export interface IProjectEstimateStore { } export class ProjectEstimatesStore implements IProjectEstimateStore { - // states - loader: boolean = false; - error: any | null = null; // observables estimates: Record = {}; // root store @@ -45,9 +40,6 @@ export class ProjectEstimatesStore implements IProjectEstimateStore { constructor(_rootStore: RootStore) { makeObservable(this, { - // states - loader: observable, - error: observable, // observables estimates: observable, // computed @@ -75,9 +67,7 @@ export class ProjectEstimatesStore implements IProjectEstimateStore { */ get areEstimatesEnabledForCurrentProject() { const currentProjectDetails = this.rootStore.projectRoot.project.currentProjectDetails; - if (!currentProjectDetails) return false; - return Boolean(currentProjectDetails?.estimate); } @@ -86,7 +76,6 @@ export class ProjectEstimatesStore implements IProjectEstimateStore { */ get projectEstimates() { const projectId = this.rootStore.app.router.projectId; - if (!projectId) return null; return this.estimates?.[projectId] || null; } @@ -96,9 +85,7 @@ export class ProjectEstimatesStore implements IProjectEstimateStore { */ get activeEstimateDetails() { const currentProjectDetails = this.rootStore.projectRoot.project.currentProjectDetails; - if (!currentProjectDetails || !currentProjectDetails?.estimate) return null; - return this.projectEstimates?.find((estimate) => estimate.id === currentProjectDetails?.estimate) || null; } @@ -107,9 +94,7 @@ export class ProjectEstimatesStore implements IProjectEstimateStore { */ getEstimatePointValue = (estimateKey: number | null) => { if (estimateKey === null) return "None"; - const activeEstimate = this.activeEstimateDetails; - return activeEstimate?.points?.find((point) => point.key === estimateKey)?.value || "None"; }; @@ -118,7 +103,6 @@ export class ProjectEstimatesStore implements IProjectEstimateStore { */ getProjectEstimateById = (estimateId: string) => { if (!this.projectEstimates) return null; - const estimateInfo = this.projectEstimates?.find((estimate) => estimate.id === estimateId) || null; return estimateInfo; }; @@ -128,27 +112,13 @@ export class ProjectEstimatesStore implements IProjectEstimateStore { * @param workspaceSlug * @param projectId */ - fetchProjectEstimates = async (workspaceSlug: string, projectId: string) => { - try { - this.loader = true; - this.error = null; - - const estimatesResponse = await this.estimateService.getEstimatesList(workspaceSlug, projectId); - + fetchProjectEstimates = async (workspaceSlug: string, projectId: string) => + await this.estimateService.getEstimatesList(workspaceSlug, projectId).then((response) => { runInAction(() => { - set(this.estimates, projectId, estimatesResponse); - this.loader = false; - this.error = null; + set(this.estimates, projectId, response); }); - - return estimatesResponse; - } catch (error) { - this.loader = false; - this.error = error; - - throw error; - } - }; + return response; + }); /** * @description creates a new estimate for the given project @@ -156,25 +126,17 @@ export class ProjectEstimatesStore implements IProjectEstimateStore { * @param projectId * @param data */ - createEstimate = async (workspaceSlug: string, projectId: string, data: IEstimateFormData) => { - try { - const response = await this.estimateService.createEstimate(workspaceSlug, projectId, data); - + createEstimate = async (workspaceSlug: string, projectId: string, data: IEstimateFormData) => + await this.estimateService.createEstimate(workspaceSlug, projectId, data).then((response) => { const responseEstimate = { ...response.estimate, points: response.estimate_points, }; - runInAction(() => { set(this.estimates, projectId, [responseEstimate, ...(this.estimates?.[projectId] || [])]); }); - return response.estimate; - } catch (error) { - console.log("Failed to create estimate from project store"); - throw error; - } - }; + }); /** * @description updates the given estimate for the given project @@ -183,27 +145,16 @@ export class ProjectEstimatesStore implements IProjectEstimateStore { * @param estimateId * @param data */ - updateEstimate = async (workspaceSlug: string, projectId: string, estimateId: string, data: IEstimateFormData) => { - try { + updateEstimate = async (workspaceSlug: string, projectId: string, estimateId: string, data: IEstimateFormData) => + await this.estimateService.patchEstimate(workspaceSlug, projectId, estimateId, data).then((response) => { const updatedEstimates = (this.estimates?.[projectId] ?? []).map((estimate) => estimate.id === estimateId ? { ...estimate, ...data.estimate } : estimate ); - runInAction(() => { set(this.estimates, projectId, updatedEstimates); }); - - const response = await this.estimateService.patchEstimate(workspaceSlug, projectId, estimateId, data); - return response; - } catch (error) { - console.log("Failed to update estimate from project store"); - - this.fetchProjectEstimates(workspaceSlug, projectId); - - throw error; - } - }; + }); /** * @description deletes the given estimate for the given project @@ -211,19 +162,11 @@ export class ProjectEstimatesStore implements IProjectEstimateStore { * @param projectId * @param estimateId */ - deleteEstimate = async (workspaceSlug: string, projectId: string, estimateId: string) => { - try { + deleteEstimate = async (workspaceSlug: string, projectId: string, estimateId: string) => + await this.estimateService.deleteEstimate(workspaceSlug, projectId, estimateId).then(() => { const updatedEstimates = (this.estimates?.[projectId] ?? []).filter((estimate) => estimate.id !== estimateId); - runInAction(() => { set(this.estimates, projectId, updatedEstimates); }); - - await this.estimateService.deleteEstimate(workspaceSlug, projectId, estimateId); - } catch (error) { - console.log("Failed to delete estimate from project store"); - - this.fetchProjectEstimates(workspaceSlug, projectId); - } - }; + }); } diff --git a/web/store/global-view.store.ts b/web/store/global-view.store.ts index 66bc1656c7d..32b8753d652 100644 --- a/web/store/global-view.store.ts +++ b/web/store/global-view.store.ts @@ -7,9 +7,6 @@ import { RootStore } from "store/root.store"; import { IWorkspaceView } from "types/workspace-views"; export interface IGlobalViewStore { - // states - loader: boolean; - error: any | null; // observables globalViewMap: Record; // computed @@ -17,18 +14,16 @@ export interface IGlobalViewStore { // computed actions getSearchedViews: (searchQuery: string) => string[] | null; getViewDetailsById: (viewId: string) => IWorkspaceView | null; - // actions + // fetch actions fetchAllGlobalViews: (workspaceSlug: string) => Promise; fetchGlobalViewDetails: (workspaceSlug: string, viewId: string) => Promise; + // crud actions createGlobalView: (workspaceSlug: string, data: Partial) => Promise; updateGlobalView: (workspaceSlug: string, viewId: string, data: Partial) => Promise; deleteGlobalView: (workspaceSlug: string, viewId: string) => Promise; } export class GlobalViewStore implements IGlobalViewStore { - // states - loader: boolean = false; - error: any | null = null; // observables globalViewMap: Record = {}; // root store @@ -38,9 +33,6 @@ export class GlobalViewStore implements IGlobalViewStore { constructor(_rootStore: RootStore) { makeObservable(this, { - // states - loader: observable.ref, - error: observable.ref, // observables globalViewMap: observable, // computed @@ -76,6 +68,11 @@ export class GlobalViewStore implements IGlobalViewStore { ); } + /** + * @description returns list of views for current workspace based on search query + * @param searchQuery + * @returns + */ getSearchedViews = (searchQuery: string) => { const currentWorkspaceDetails = this.rootStore.workspaceRoot.currentWorkspace; if (!currentWorkspaceDetails) return null; @@ -99,82 +96,40 @@ export class GlobalViewStore implements IGlobalViewStore { * @description fetch all global views for given workspace * @param workspaceSlug */ - fetchAllGlobalViews = async (workspaceSlug: string): Promise => { - try { - runInAction(() => { - this.loader = true; - }); - - const response = await this.workspaceService.getAllViews(workspaceSlug); - + fetchAllGlobalViews = async (workspaceSlug: string): Promise => + await this.workspaceService.getAllViews(workspaceSlug).then((response) => { runInAction(() => { - this.loader = false; response.forEach((view) => { set(this.globalViewMap, view.id, view); }); }); - return response; - } catch (error) { - runInAction(() => { - this.loader = false; - this.error = error; - }); - - throw error; - } - }; + }); /** * @description fetch view details for given viewId * @param viewId */ - fetchGlobalViewDetails = async (workspaceSlug: string, viewId: string): Promise => { - try { + fetchGlobalViewDetails = async (workspaceSlug: string, viewId: string): Promise => + await this.workspaceService.getViewDetails(workspaceSlug, viewId).then((response) => { runInAction(() => { - this.loader = true; - }); - - const response = await this.workspaceService.getViewDetails(workspaceSlug, viewId); - - runInAction(() => { - this.loader = false; set(this.globalViewMap, viewId, response); }); - return response; - } catch (error) { - runInAction(() => { - this.loader = false; - this.error = error; - }); - - throw error; - } - }; + }); /** * @description create new global view * @param workspaceSlug * @param data */ - createGlobalView = async (workspaceSlug: string, data: Partial): Promise => { - try { - const response = await this.workspaceService.createView(workspaceSlug, data); - + createGlobalView = async (workspaceSlug: string, data: Partial): Promise => + await this.workspaceService.createView(workspaceSlug, data).then((response) => { runInAction(() => { set(this.globalViewMap, response.id, response); }); - return response; - } catch (error) { - runInAction(() => { - this.error = error; - }); - - throw error; - } - }; + }); /** * @description update global view @@ -186,48 +141,24 @@ export class GlobalViewStore implements IGlobalViewStore { workspaceSlug: string, viewId: string, data: Partial - ): Promise => { - const viewToUpdate = { ...this.getViewDetailsById(viewId), ...data }; - - try { + ): Promise => + await this.workspaceService.updateView(workspaceSlug, viewId, data).then((response) => { + const viewToUpdate = { ...this.getViewDetailsById(viewId), ...data }; runInAction(() => { set(this.globalViewMap, viewId, viewToUpdate); }); - - const response = await this.workspaceService.updateView(workspaceSlug, viewId, data); - return response; - } catch (error) { - this.fetchGlobalViewDetails(workspaceSlug, viewId); - - runInAction(() => { - this.error = error; - }); - - throw error; - } - }; + }); /** * @description delete global view * @param workspaceSlug * @param viewId */ - deleteGlobalView = async (workspaceSlug: string, viewId: string): Promise => { - try { + deleteGlobalView = async (workspaceSlug: string, viewId: string): Promise => + await this.workspaceService.deleteView(workspaceSlug, viewId).then(() => { runInAction(() => { delete this.globalViewMap[viewId]; }); - - await this.workspaceService.deleteView(workspaceSlug, viewId); - } catch (error) { - this.fetchAllGlobalViews(workspaceSlug); - - runInAction(() => { - this.error = error; - }); - - throw error; - } - }; + }); } diff --git a/web/store/label/project-label.store.ts b/web/store/label/project-label.store.ts index 92a39f35e50..9ed04fe587a 100644 --- a/web/store/label/project-label.store.ts +++ b/web/store/label/project-label.store.ts @@ -12,8 +12,9 @@ export interface IProjectLabelStore { // computed projectLabels: IIssueLabel[] | undefined; projectLabelsTree: IIssueLabel[] | undefined; - // actions + // fetch actions fetchProjectLabels: (workspaceSlug: string, projectId: string) => Promise; + // crud actions createLabel: (workspaceSlug: string, projectId: string, data: Partial) => Promise; updateLabel: ( workspaceSlug: string, @@ -84,15 +85,15 @@ export class ProjectLabelStore implements IProjectLabelStore { * @param projectId * @returns Promise */ - fetchProjectLabels = async (workspaceSlug: string, projectId: string) => { - const response = await this.issueLabelService.getProjectIssueLabels(workspaceSlug, projectId); - runInAction(() => { - response.forEach((label) => { - set(this.labelMap, [label.id], label); + fetchProjectLabels = async (workspaceSlug: string, projectId: string) => + await this.issueLabelService.getProjectIssueLabels(workspaceSlug, projectId).then((response) => { + runInAction(() => { + response.forEach((label) => { + set(this.labelMap, [label.id], label); + }); }); + return response; }); - return response; - }; /** * Creates a new label for a specific project and add it to the store @@ -101,14 +102,13 @@ export class ProjectLabelStore implements IProjectLabelStore { * @param data * @returns Promise */ - createLabel = async (workspaceSlug: string, projectId: string, data: Partial) => { - const response = await this.issueLabelService.createIssueLabel(workspaceSlug, projectId, data); - - runInAction(() => { - set(this.labelMap, [response.id], response); + createLabel = async (workspaceSlug: string, projectId: string, data: Partial) => + await this.issueLabelService.createIssueLabel(workspaceSlug, projectId, data).then((response) => { + runInAction(() => { + set(this.labelMap, [response.id], response); + }); + return response; }); - return response; - }; /** * Updates a label for a specific project and update it in the store @@ -118,23 +118,13 @@ export class ProjectLabelStore implements IProjectLabelStore { * @param data * @returns Promise */ - updateLabel = async (workspaceSlug: string, projectId: string, labelId: string, data: Partial) => { - const originalLabel = this.labelMap[labelId]; - try { + updateLabel = async (workspaceSlug: string, projectId: string, labelId: string, data: Partial) => + await this.issueLabelService.patchIssueLabel(workspaceSlug, projectId, labelId, data).then((response) => { runInAction(() => { set(this.labelMap, [labelId], { ...this.labelMap[labelId], ...data }); }); - - const response = await this.issueLabelService.patchIssueLabel(workspaceSlug, projectId, labelId, data); return response; - } catch (error) { - console.log("Failed to update label from project store"); - runInAction(() => { - set(this.labelMap, [labelId], originalLabel); - }); - throw error; - } - }; + }); /** * updates the sort order of a label and updates the label information using API. @@ -158,7 +148,6 @@ export class ProjectLabelStore implements IProjectLabelStore { ) => { const currLabel = this.labelMap?.[labelId]; const labelTree = this.projectLabelsTree; - let currentArray: IIssueLabel[]; if (!currLabel || !labelTree) return; @@ -170,7 +159,6 @@ export class ProjectLabelStore implements IProjectLabelStore { //Add the array at the destination if (isSameParent && prevIndex !== undefined) currentArray.splice(prevIndex, 1); - currentArray.splice(index, 0, currLabel); //if currently adding to a new array, then let backend assign a sort order @@ -180,13 +168,11 @@ export class ProjectLabelStore implements IProjectLabelStore { if (typeof currentArray[index - 1] !== "undefined") { prevSortOrder = currentArray[index - 1].sort_order; } - if (typeof currentArray[index + 1] !== "undefined") { nextSortOrder = currentArray[index + 1].sort_order; } let sortOrder: number; - //based on the next and previous labelMap calculate current sort order if (prevSortOrder && nextSortOrder) { sortOrder = (prevSortOrder + nextSortOrder) / 2; @@ -195,10 +181,8 @@ export class ProjectLabelStore implements IProjectLabelStore { } else { sortOrder = prevSortOrder! / 2; } - data.sort_order = sortOrder; } - return this.updateLabel(workspaceSlug, projectId, labelId, data); }; @@ -209,23 +193,12 @@ export class ProjectLabelStore implements IProjectLabelStore { * @param labelId */ deleteLabel = async (workspaceSlug: string, projectId: string, labelId: string) => { - const originalLabel = this.labelMap[labelId]; - - try { - if (!this.labelMap[labelId]) return; - + if (!this.labelMap[labelId]) return; + // deleting using api + await this.issueLabelService.deleteIssueLabel(workspaceSlug, projectId, labelId).then(() => { runInAction(() => { delete this.labelMap[labelId]; }); - - // deleting using api - await this.issueLabelService.deleteIssueLabel(workspaceSlug, projectId, labelId); - } catch (error) { - console.log("Failed to delete label from project store"); - // reverting back to original label list - runInAction(() => { - set(this.labelMap, [labelId], originalLabel); - }); - } + }); }; } diff --git a/web/store/label/workspace-label.store.ts b/web/store/label/workspace-label.store.ts index c75934d07a8..538584db908 100644 --- a/web/store/label/workspace-label.store.ts +++ b/web/store/label/workspace-label.store.ts @@ -9,7 +9,7 @@ import { IIssueLabel } from "types"; export interface IWorkspaceLabelStore { // computed workspaceLabels: IIssueLabel[] | undefined; - // actions + // fetch actions fetchWorkspaceLabels: (workspaceSlug: string) => Promise; } @@ -51,13 +51,13 @@ export class WorkspaceLabelStore implements IWorkspaceLabelStore { * @param projectId * @returns Promise */ - fetchWorkspaceLabels = async (workspaceSlug: string) => { - const response = await this.issueLabelService.getWorkspaceIssueLabels(workspaceSlug); - runInAction(() => { - response.forEach((label) => { - set(this.labelMap, [label.id], label); + fetchWorkspaceLabels = async (workspaceSlug: string) => + await this.issueLabelService.getWorkspaceIssueLabels(workspaceSlug).then((response) => { + runInAction(() => { + response.forEach((label) => { + set(this.labelMap, [label.id], label); + }); }); + return response; }); - return response; - }; } diff --git a/web/store/member/project-member.store.ts b/web/store/member/project-member.store.ts index 453ad7a56ea..2f6b4157418 100644 --- a/web/store/member/project-member.store.ts +++ b/web/store/member/project-member.store.ts @@ -25,13 +25,15 @@ export interface IProjectMemberStore { projectMemberIds: string[] | null; // computed actions getProjectMemberDetails: (projectMemberId: string) => IProjectMemberDetails | null; - // actions + // fetch actions fetchProjectMembers: (workspaceSlug: string, projectId: string) => Promise; + // bulk operation actions bulkAddMembersToProject: ( workspaceSlug: string, projectId: string, data: IProjectBulkAddFormData ) => Promise; + // crud actions updateMember: ( workspaceSlug: string, projectId: string, @@ -106,28 +108,33 @@ export class ProjectMemberStore implements IProjectMemberStore { * @param workspaceSlug * @param projectId */ - fetchProjectMembers = async (workspaceSlug: string, projectId: string) => { - const response = await this.projectMemberService.fetchProjectMembers(workspaceSlug, projectId); - runInAction(() => { - response.forEach((member) => { - set(this.projectMemberMap, [projectId, member.member], member); + fetchProjectMembers = async (workspaceSlug: string, projectId: string) => + await this.projectMemberService.fetchProjectMembers(workspaceSlug, projectId).then((response) => { + runInAction(() => { + response.forEach((member) => { + set(this.projectMemberMap, [projectId, member.member], member); + }); }); + return response; }); - return response; - }; - bulkAddMembersToProject = async (workspaceSlug: string, projectId: string, data: IProjectBulkAddFormData) => { - const response = await this.projectMemberService.bulkAddMembersToProject(workspaceSlug, projectId, data); - - runInAction(() => { - response.forEach((member) => { - set(this.projectMemberMap, [projectId, member.member], member); + /** + * @description bulk add members to a project + * @param workspaceSlug + * @param projectId + * @param data + * @returns Promise + */ + bulkAddMembersToProject = async (workspaceSlug: string, projectId: string, data: IProjectBulkAddFormData) => + await this.projectMemberService.bulkAddMembersToProject(workspaceSlug, projectId, data).then((response) => { + runInAction(() => { + response.forEach((member) => { + set(this.projectMemberMap, [projectId, member.member], member); + }); }); + return response; }); - return response; - }; - /** * @description update the role of a member in a project * @param workspaceSlug @@ -143,26 +150,14 @@ export class ProjectMemberStore implements IProjectMemberStore { ) => { const memberDetails = this.getProjectMemberDetails(userId); if (!memberDetails) throw new Error("Member not found"); - // original data to revert back in case of error - const originalProjectMemberData = this.projectMemberMap?.[projectId]?.[userId]; - try { - runInAction(() => { - set(this.projectMemberMap, [projectId, userId, "role"], data.role); + return await this.projectMemberService + .updateProjectMember(workspaceSlug, projectId, memberDetails?.id, data) + .then((response) => { + runInAction(() => { + set(this.projectMemberMap, [projectId, userId, "role"], data.role); + }); + return response; }); - const response = await this.projectMemberService.updateProjectMember( - workspaceSlug, - projectId, - memberDetails?.id, - data - ); - return response; - } catch (error) { - // revert back to original members in case of error - runInAction(() => { - set(this.projectMemberMap, [projectId, userId], originalProjectMemberData); - }); - throw error; - } }; /** @@ -174,9 +169,10 @@ export class ProjectMemberStore implements IProjectMemberStore { removeMemberFromProject = async (workspaceSlug: string, projectId: string, userId: string) => { const memberDetails = this.getProjectMemberDetails(userId); if (!memberDetails) throw new Error("Member not found"); - await this.projectMemberService.deleteProjectMember(workspaceSlug, projectId, memberDetails?.id); - runInAction(() => { - delete this.projectMemberMap?.[projectId]?.[userId]; + await this.projectMemberService.deleteProjectMember(workspaceSlug, projectId, memberDetails?.id).then(() => { + runInAction(() => { + delete this.projectMemberMap?.[projectId]?.[userId]; + }); }); }; } diff --git a/web/store/member/workspace-member.store.ts b/web/store/member/workspace-member.store.ts index 427588588d7..1efe5537fee 100644 --- a/web/store/member/workspace-member.store.ts +++ b/web/store/member/workspace-member.store.ts @@ -28,11 +28,13 @@ export interface IWorkspaceMemberStore { getSearchedWorkspaceInvitationIds: (searchQuery: string) => string[] | null; getWorkspaceMemberDetails: (workspaceMemberId: string) => IWorkspaceMember | null; getWorkspaceInvitationDetails: (invitationId: string) => IWorkspaceMemberInvitation | null; - // actions + // fetch actions fetchWorkspaceMembers: (workspaceSlug: string) => Promise; + fetchWorkspaceMemberInvitations: (workspaceSlug: string) => Promise; + // crud actions updateMember: (workspaceSlug: string, userId: string, data: { role: EUserWorkspaceRoles }) => Promise; removeMemberFromWorkspace: (workspaceSlug: string, userId: string) => Promise; - fetchWorkspaceMemberInvitations: (workspaceSlug: string) => Promise; + // invite actions inviteMembersToWorkspace: (workspaceSlug: string, data: IWorkspaceBulkInviteFormData) => Promise; updateMemberInvitation: ( workspaceSlug: string, @@ -173,20 +175,20 @@ export class WorkspaceMemberStore implements IWorkspaceMemberStore { * @description fetch all the members of a workspace * @param workspaceSlug */ - fetchWorkspaceMembers = async (workspaceSlug: string) => { - const response = await this.workspaceService.fetchWorkspaceMembers(workspaceSlug); - runInAction(() => { - response.forEach((member) => { - set(this.memberRoot?.memberMap, member.member.id, member.member); - set(this.workspaceMemberMap, [workspaceSlug, member.member.id], { - id: member.id, - member: member.member.id, - role: member.role, + fetchWorkspaceMembers = async (workspaceSlug: string) => + await this.workspaceService.fetchWorkspaceMembers(workspaceSlug).then((response) => { + runInAction(() => { + response.forEach((member) => { + set(this.memberRoot?.memberMap, member.member.id, member.member); + set(this.workspaceMemberMap, [workspaceSlug, member.member.id], { + id: member.id, + member: member.member.id, + role: member.role, + }); }); }); + return response; }); - return response; - }; /** * @description update the role of a workspace member @@ -197,20 +199,11 @@ export class WorkspaceMemberStore implements IWorkspaceMemberStore { updateMember = async (workspaceSlug: string, userId: string, data: { role: EUserWorkspaceRoles }) => { const memberDetails = this.getWorkspaceMemberDetails(userId); if (!memberDetails) throw new Error("Member not found"); - // original data to revert back in case of error - const originalProjectMemberData = this.workspaceMemberMap?.[workspaceSlug]?.[userId]; - try { + await this.workspaceService.updateWorkspaceMember(workspaceSlug, memberDetails.id, data).then(() => { runInAction(() => { set(this.workspaceMemberMap, [workspaceSlug, userId, "role"], data.role); }); - await this.workspaceService.updateWorkspaceMember(workspaceSlug, memberDetails.id, data); - } catch (error) { - // revert back to original members in case of error - runInAction(() => { - set(this.workspaceMemberMap, [workspaceSlug, userId], originalProjectMemberData); - }); - throw error; - } + }); }; /** @@ -221,10 +214,11 @@ export class WorkspaceMemberStore implements IWorkspaceMemberStore { removeMemberFromWorkspace = async (workspaceSlug: string, userId: string) => { const memberDetails = this.getWorkspaceMemberDetails(userId); if (!memberDetails) throw new Error("Member not found"); - await this.workspaceService.deleteWorkspaceMember(workspaceSlug, memberDetails?.id); - runInAction(() => { - delete this.memberRoot?.memberMap?.[userId]; - delete this.workspaceMemberMap?.[workspaceSlug]?.[userId]; + await this.workspaceService.deleteWorkspaceMember(workspaceSlug, memberDetails?.id).then(() => { + runInAction(() => { + delete this.memberRoot?.memberMap?.[userId]; + delete this.workspaceMemberMap?.[workspaceSlug]?.[userId]; + }); }); }; @@ -232,13 +226,13 @@ export class WorkspaceMemberStore implements IWorkspaceMemberStore { * @description fetch all the member invitations of a workspace * @param workspaceSlug */ - fetchWorkspaceMemberInvitations = async (workspaceSlug: string) => { - const memberInvitations = await this.workspaceService.workspaceInvitations(workspaceSlug); - runInAction(() => { - set(this.workspaceMemberInvitations, workspaceSlug, memberInvitations); + fetchWorkspaceMemberInvitations = async (workspaceSlug: string) => + await this.workspaceService.workspaceInvitations(workspaceSlug).then((response) => { + runInAction(() => { + set(this.workspaceMemberInvitations, workspaceSlug, response); + }); + return response; }); - return memberInvitations; - }; /** * @description bulk invite members to a workspace @@ -248,7 +242,6 @@ export class WorkspaceMemberStore implements IWorkspaceMemberStore { inviteMembersToWorkspace = async (workspaceSlug: string, data: IWorkspaceBulkInviteFormData) => { const response = await this.workspaceService.inviteWorkspace(workspaceSlug, data); await this.fetchWorkspaceMemberInvitations(workspaceSlug); - return response; }; @@ -264,24 +257,15 @@ export class WorkspaceMemberStore implements IWorkspaceMemberStore { data: Partial ) => { const originalMemberInvitations = [...this.workspaceMemberInvitations?.[workspaceSlug]]; // in case of error, we will revert back to original members - - try { + await this.workspaceService.updateWorkspaceInvitation(workspaceSlug, invitationId, data).then(() => { const memberInvitations = originalMemberInvitations?.map((invitation) => ({ ...invitation, ...(invitation.id === invitationId && data), })); - // optimistic update runInAction(() => { set(this.workspaceMemberInvitations, workspaceSlug, memberInvitations); }); - await this.workspaceService.updateWorkspaceInvitation(workspaceSlug, invitationId, data); - } catch (error) { - // revert back to original members in case of error - runInAction(() => { - set(this.workspaceMemberInvitations, workspaceSlug, originalMemberInvitations); - }); - throw error; - } + }); }; /** @@ -289,12 +273,12 @@ export class WorkspaceMemberStore implements IWorkspaceMemberStore { * @param workspaceSlug * @param memberId */ - deleteMemberInvitation = async (workspaceSlug: string, invitationId: string) => { - await this.workspaceService.deleteWorkspaceInvitations(workspaceSlug.toString(), invitationId); - runInAction(() => { - this.workspaceMemberInvitations[workspaceSlug] = this.workspaceMemberInvitations[workspaceSlug].filter( - (inv) => inv.id !== invitationId - ); + deleteMemberInvitation = async (workspaceSlug: string, invitationId: string) => + await this.workspaceService.deleteWorkspaceInvitations(workspaceSlug.toString(), invitationId).then(() => { + runInAction(() => { + this.workspaceMemberInvitations[workspaceSlug] = this.workspaceMemberInvitations[workspaceSlug].filter( + (inv) => inv.id !== invitationId + ); + }); }); - }; } diff --git a/web/store/page.store.ts b/web/store/page.store.ts index fbc0b5861d3..9f157d158a1 100644 --- a/web/store/page.store.ts +++ b/web/store/page.store.ts @@ -15,12 +15,12 @@ export interface IPageStore { pages: Record; archivedPages: Record; // project computed - projectPages: string[] | null; - favoriteProjectPages: string[] | null; - privateProjectPages: string[] | null; - publicProjectPages: string[] | null; + projectPageIds: string[] | null; + favoriteProjectPageIds: string[] | null; + privateProjectPageIds: string[] | null; + publicProjectPageIds: string[] | null; + archivedProjectPageIds: string[] | null; recentProjectPages: IRecentPages | null; - archivedProjectPages: string[] | null; // fetch page information actions getUnArchivedPageById: (pageId: string) => IPage | null; getArchivedPageById: (pageId: string) => IPage | null; @@ -55,11 +55,11 @@ export class PageStore implements IPageStore { pages: observable, archivedPages: observable, // computed - projectPages: computed, - favoriteProjectPages: computed, - publicProjectPages: computed, - privateProjectPages: computed, - archivedProjectPages: computed, + projectPageIds: computed, + favoriteProjectPageIds: computed, + publicProjectPageIds: computed, + privateProjectPageIds: computed, + archivedProjectPageIds: computed, recentProjectPages: computed, // computed actions getUnArchivedPageById: action, @@ -90,46 +90,37 @@ export class PageStore implements IPageStore { /** * retrieves all pages for a projectId that is available in the url. */ - get projectPages() { + get projectPageIds() { const projectId = this.rootStore.app.router.projectId; - if (!projectId) return null; - - const projectPagesIds = Object.keys(this.pages).filter((pageId) => this.pages?.[pageId]?.project === projectId); - - return projectPagesIds ?? null; + const projectPageIds = Object.keys(this.pages).filter((pageId) => this.pages?.[pageId]?.project === projectId); + return projectPageIds ?? null; } /** * retrieves all favorite pages for a projectId that is available in the url. */ - get favoriteProjectPages() { - if (!this.projectPages) return null; - - const favoritePagesIds = Object.keys(this.projectPages).filter((pageId) => this.pages?.[pageId]?.is_favorite); - + get favoriteProjectPageIds() { + if (!this.projectPageIds) return null; + const favoritePagesIds = Object.keys(this.projectPageIds).filter((pageId) => this.pages?.[pageId]?.is_favorite); return favoritePagesIds ?? null; } /** * retrieves all private pages for a projectId that is available in the url. */ - get privateProjectPages() { - if (!this.projectPages) return null; - - const privatePagesIds = Object.keys(this.projectPages).filter((pageId) => this.pages?.[pageId]?.access === 1); - + get privateProjectPageIds() { + if (!this.projectPageIds) return null; + const privatePagesIds = Object.keys(this.projectPageIds).filter((pageId) => this.pages?.[pageId]?.access === 1); return privatePagesIds ?? null; } /** * retrieves all shared pages which are public to everyone in the project for a projectId that is available in the url. */ - get publicProjectPages() { - if (!this.projectPages) return null; - - const publicPagesIds = Object.keys(this.projectPages).filter((pageId) => this.pages?.[pageId]?.access === 0); - + get publicProjectPageIds() { + if (!this.projectPageIds) return null; + const publicPagesIds = Object.keys(this.projectPageIds).filter((pageId) => this.pages?.[pageId]?.access === 0); return publicPagesIds ?? null; } @@ -138,16 +129,13 @@ export class PageStore implements IPageStore { * In format where today, yesterday, this_week, older are keys. */ get recentProjectPages() { - if (!this.projectPages) return null; - + if (!this.projectPageIds) return null; const data: IRecentPages = { today: [], yesterday: [], this_week: [], older: [] }; - - data.today = this.projectPages.filter((p) => isToday(new Date(this.pages?.[p]?.created_at))) || []; - data.yesterday = this.projectPages.filter((p) => isYesterday(new Date(this.pages?.[p]?.created_at))) || []; + data.today = this.projectPageIds.filter((p) => isToday(new Date(this.pages?.[p]?.created_at))) || []; + data.yesterday = this.projectPageIds.filter((p) => isYesterday(new Date(this.pages?.[p]?.created_at))) || []; data.this_week = - this.projectPages.filter((p) => { + this.projectPageIds.filter((p) => { const pageCreatedAt = this.pages?.[p]?.created_at; - return ( isThisWeek(new Date(pageCreatedAt)) && !isToday(new Date(pageCreatedAt)) && @@ -155,9 +143,8 @@ export class PageStore implements IPageStore { ); }) || []; data.older = - this.projectPages.filter((p) => { + this.projectPageIds.filter((p) => { const pageCreatedAt = this.pages?.[p]?.created_at; - return !isThisWeek(new Date(pageCreatedAt)) && !isYesterday(new Date(pageCreatedAt)); }) || []; return data; @@ -166,16 +153,13 @@ export class PageStore implements IPageStore { /** * retrieves all archived pages for a projectId that is available in the url. */ - get archivedProjectPages() { + get archivedProjectPageIds() { const projectId = this.rootStore.app.router.projectId; - if (!projectId) return null; - - const archivedProjectPagesIds = Object.keys(this.archivedPages).filter( + const archivedProjectPageIds = Object.keys(this.archivedPages).filter( (pageId) => this.archivedPages?.[pageId]?.project === projectId ); - - return archivedProjectPagesIds ?? null; + return archivedProjectPageIds ?? null; } /** @@ -198,21 +182,15 @@ export class PageStore implements IPageStore { * @param projectId * @returns Promise */ - fetchProjectPages = async (workspaceSlug: string, projectId: string) => { - try { - const response = await this.pageService.getProjectPages(workspaceSlug, projectId); - + fetchProjectPages = async (workspaceSlug: string, projectId: string) => + await this.pageService.getProjectPages(workspaceSlug, projectId).then((response) => { runInAction(() => { response.forEach((page) => { set(this.pages, [page.id], page); }); }); - return response; - } catch (error) { - throw error; - } - }; + }); /** * fetches all archived pages for a project. @@ -220,21 +198,15 @@ export class PageStore implements IPageStore { * @param projectId * @returns Promise */ - fetchArchivedProjectPages = async (workspaceSlug: string, projectId: string) => { - try { - const response = await this.pageService.getArchivedPages(workspaceSlug, projectId); - + fetchArchivedProjectPages = async (workspaceSlug: string, projectId: string) => + await this.pageService.getArchivedPages(workspaceSlug, projectId).then((response) => { runInAction(() => { response.forEach((page) => { set(this.archivedPages, [page.id], page); }); }); - return response; - } catch (error) { - throw error; - } - }; + }); /** * Add Page to users favorites list @@ -242,20 +214,12 @@ export class PageStore implements IPageStore { * @param projectId * @param pageId */ - addToFavorites = async (workspaceSlug: string, projectId: string, pageId: string) => { - try { + addToFavorites = async (workspaceSlug: string, projectId: string, pageId: string) => + await this.pageService.addPageToFavorites(workspaceSlug, projectId, pageId).then(() => { runInAction(() => { set(this.pages, [pageId, "is_favorite"], true); }); - - await this.pageService.addPageToFavorites(workspaceSlug, projectId, pageId); - } catch (error) { - runInAction(() => { - set(this.pages, [pageId, "is_favorite"], false); - }); - throw error; - } - }; + }); /** * Remove page from the users favorites list @@ -263,20 +227,12 @@ export class PageStore implements IPageStore { * @param projectId * @param pageId */ - removeFromFavorites = async (workspaceSlug: string, projectId: string, pageId: string) => { - try { + removeFromFavorites = async (workspaceSlug: string, projectId: string, pageId: string) => + await this.pageService.removePageFromFavorites(workspaceSlug, projectId, pageId).then(() => { runInAction(() => { set(this.pages, [pageId, "is_favorite"], false); }); - - await this.pageService.removePageFromFavorites(workspaceSlug, projectId, pageId); - } catch (error) { - runInAction(() => { - set(this.pages, [pageId, "is_favorite"], true); - }); - throw error; - } - }; + }); /** * Creates a new page using the api and updated the local state in store @@ -284,19 +240,13 @@ export class PageStore implements IPageStore { * @param projectId * @param data */ - createPage = async (workspaceSlug: string, projectId: string, data: Partial) => { - try { - const response = await this.pageService.createPage(workspaceSlug, projectId, data); - + createPage = async (workspaceSlug: string, projectId: string, data: Partial) => + await this.pageService.createPage(workspaceSlug, projectId, data).then((response) => { runInAction(() => { set(this.pages, [response.id], response); }); - return response; - } catch (error) { - throw error; - } - }; + }); /** * updates the page using the api and updates the local state in store @@ -306,24 +256,14 @@ export class PageStore implements IPageStore { * @param data * @returns */ - updatePage = async (workspaceSlug: string, projectId: string, pageId: string, data: Partial) => { - const originalPage = this.getUnArchivedPageById(pageId); - - try { + updatePage = async (workspaceSlug: string, projectId: string, pageId: string, data: Partial) => + await this.pageService.patchPage(workspaceSlug, projectId, pageId, data).then((response) => { + const originalPage = this.getUnArchivedPageById(pageId); runInAction(() => { set(this.pages, [pageId], { ...originalPage, ...data }); }); - - const response = await this.pageService.patchPage(workspaceSlug, projectId, pageId, data); - return response; - } catch (error) { - runInAction(() => { - set(this.pages, [pageId], originalPage); - }); - throw error; - } - }; + }); /** * delete a page using the api and updates the local state in store @@ -332,18 +272,13 @@ export class PageStore implements IPageStore { * @param pageId * @returns */ - deletePage = async (workspaceSlug: string, projectId: string, pageId: string) => { - try { - const response = await this.pageService.deletePage(workspaceSlug, projectId, pageId); - + deletePage = async (workspaceSlug: string, projectId: string, pageId: string) => + await this.pageService.deletePage(workspaceSlug, projectId, pageId).then((response) => { runInAction(() => { omit(this.archivedPages, [pageId]); }); return response; - } catch (error) { - throw error; - } - }; + }); /** * make a page public @@ -352,20 +287,12 @@ export class PageStore implements IPageStore { * @param pageId * @returns */ - makePublic = async (workspaceSlug: string, projectId: string, pageId: string) => { - try { + makePublic = async (workspaceSlug: string, projectId: string, pageId: string) => + await this.pageService.patchPage(workspaceSlug, projectId, pageId, { access: 0 }).then(() => { runInAction(() => { set(this.pages, [pageId, "access"], 0); }); - - await this.pageService.patchPage(workspaceSlug, projectId, pageId, { access: 0 }); - } catch (error) { - runInAction(() => { - set(this.pages, [pageId, "access"], 1); - }); - throw error; - } - }; + }); /** * Make a page private @@ -374,20 +301,12 @@ export class PageStore implements IPageStore { * @param pageId * @returns */ - makePrivate = async (workspaceSlug: string, projectId: string, pageId: string) => { - try { + makePrivate = async (workspaceSlug: string, projectId: string, pageId: string) => + await this.pageService.patchPage(workspaceSlug, projectId, pageId, { access: 1 }).then(() => { runInAction(() => { set(this.pages, [pageId, "access"], 1); }); - - await this.pageService.patchPage(workspaceSlug, projectId, pageId, { access: 1 }); - } catch (error) { - runInAction(() => { - set(this.pages, [pageId, "access"], 0); - }); - throw error; - } - }; + }); /** * Mark a page archived @@ -395,14 +314,13 @@ export class PageStore implements IPageStore { * @param projectId * @param pageId */ - archivePage = async (workspaceSlug: string, projectId: string, pageId: string) => { - await this.pageService.archivePage(workspaceSlug, projectId, pageId); - - runInAction(() => { - set(this.archivedPages, [pageId], this.pages[pageId]); - omit(this.pages, [pageId]); + archivePage = async (workspaceSlug: string, projectId: string, pageId: string) => + await this.pageService.archivePage(workspaceSlug, projectId, pageId).then(() => { + runInAction(() => { + set(this.archivedPages, [pageId], this.pages[pageId]); + omit(this.pages, [pageId]); + }); }); - }; /** * Restore a page from archived pages to pages @@ -410,12 +328,11 @@ export class PageStore implements IPageStore { * @param projectId * @param pageId */ - restorePage = async (workspaceSlug: string, projectId: string, pageId: string) => { - await this.pageService.restorePage(workspaceSlug, projectId, pageId); - - runInAction(() => { - set(this.pages, [pageId], this.archivedPages[pageId]); - omit(this.archivedPages, [pageId]); + restorePage = async (workspaceSlug: string, projectId: string, pageId: string) => + await this.pageService.restorePage(workspaceSlug, projectId, pageId).then(() => { + runInAction(() => { + set(this.pages, [pageId], this.archivedPages[pageId]); + omit(this.archivedPages, [pageId]); + }); }); - }; } diff --git a/web/store/state.store.ts b/web/store/state.store.ts index 3fe9a4edd13..dc291ee8da9 100644 --- a/web/store/state.store.ts +++ b/web/store/state.store.ts @@ -17,8 +17,9 @@ export interface IStateStore { groupedProjectStates: Record | undefined; // computed actions getProjectStates: (projectId: string) => IState[]; - // actions + // fetch actions fetchProjectStates: (workspaceSlug: string, projectId: string) => Promise; + // crud actions createState: (workspaceSlug: string, projectId: string, data: Partial) => Promise; updateState: ( workspaceSlug: string, @@ -94,17 +95,17 @@ export class StateStore implements IStateStore { * @param projectId * @returns */ - fetchProjectStates = async (workspaceSlug: string, projectId: string) => { - const stateMap = await this.stateService.getStates(workspaceSlug, projectId); - runInAction(() => { - //todo add iteratively without modifying original reference - this.stateMap = { - ...this.stateMap, - ...keyBy(stateMap, "id"), - }; + fetchProjectStates = async (workspaceSlug: string, projectId: string) => + await this.stateService.getStates(workspaceSlug, projectId).then((response) => { + runInAction(() => { + //TODO: add iteratively without modifying original reference + this.stateMap = { + ...this.stateMap, + ...keyBy(response, "id"), + }; + }); + return response; }); - return stateMap; - }; /** * creates a new state in a project and adds it to the store @@ -113,14 +114,13 @@ export class StateStore implements IStateStore { * @param data * @returns */ - createState = async (workspaceSlug: string, projectId: string, data: Partial) => { - const response = await this.stateService.createState(workspaceSlug, projectId, data); - - runInAction(() => { - set(this.stateMap, [response?.id], response); + createState = async (workspaceSlug: string, projectId: string, data: Partial) => + await this.stateService.createState(workspaceSlug, projectId, data).then((response) => { + runInAction(() => { + set(this.stateMap, [response?.id], response); + }); + return response; }); - return response; - }; /** * Updates the state details in the store, in case of failure reverts back to original state @@ -130,24 +130,13 @@ export class StateStore implements IStateStore { * @param data * @returns */ - updateState = async (workspaceSlug: string, projectId: string, stateId: string, data: Partial) => { - const originalState = this.stateMap[stateId]; - try { + updateState = async (workspaceSlug: string, projectId: string, stateId: string, data: Partial) => + await this.stateService.patchState(workspaceSlug, projectId, stateId, data).then((response) => { runInAction(() => { set(this.stateMap, [stateId], { ...this.stateMap?.[stateId], ...data }); }); - const response = await this.stateService.patchState(workspaceSlug, projectId, stateId, data); return response; - } catch (error) { - runInAction(() => { - this.stateMap = { - ...this.stateMap, - [stateId]: originalState, - }; - }); - throw error; - } - }; + }); /** * deletes the state from the store, incase of failure reverts back to original state @@ -156,21 +145,12 @@ export class StateStore implements IStateStore { * @param stateId */ deleteState = async (workspaceSlug: string, projectId: string, stateId: string) => { - const originalStates = this.stateMap; - try { - if (!this.stateMap?.[stateId]) return; - + if (!this.stateMap?.[stateId]) return; + await this.stateService.deleteState(workspaceSlug, projectId, stateId).then(() => { runInAction(() => { delete this.stateMap[stateId]; }); - - await this.stateService.deleteState(workspaceSlug, projectId, stateId); - } catch (error) { - runInAction(() => { - this.stateMap = originalStates; - }); - throw error; - } + }); }; /** @@ -179,21 +159,12 @@ export class StateStore implements IStateStore { * @param projectId * @param stateId */ - markStateAsDefault = async (workspaceSlug: string, projectId: string, stateId: string) => { - const originalStates = this.stateMap; - try { + markStateAsDefault = async (workspaceSlug: string, projectId: string, stateId: string) => + await this.stateService.markDefault(workspaceSlug, projectId, stateId).then(() => { runInAction(() => { set(this.stateMap, [stateId, "default"], true); }); - - await this.stateService.markDefault(workspaceSlug, projectId, stateId); - } catch (error) { - runInAction(() => { - this.stateMap = originalStates; - }); - throw error; - } - }; + }); /** * updates the sort order of a state and updates the state information using API, in case of failure reverts back to original state @@ -211,32 +182,23 @@ export class StateStore implements IStateStore { groupIndex: number ) => { const SEQUENCE_GAP = 15000; - const originalStates = this.stateMap; - try { - let newSequence = SEQUENCE_GAP; - const stateMap = this.projectStates || []; - const selectedState = stateMap?.find((state) => state.id === stateId); - const groupStates = stateMap?.filter((state) => state.group === selectedState?.group); - const groupLength = groupStates.length; - if (direction === "up") { - if (groupIndex === 1) newSequence = groupStates[0].sequence - SEQUENCE_GAP; - else newSequence = (groupStates[groupIndex - 2].sequence + groupStates[groupIndex - 1].sequence) / 2; - } else { - if (groupIndex === groupLength - 2) newSequence = groupStates[groupLength - 1].sequence + SEQUENCE_GAP; - else newSequence = (groupStates[groupIndex + 2].sequence + groupStates[groupIndex + 1].sequence) / 2; - } - + let newSequence = SEQUENCE_GAP; + const stateMap = this.projectStates || []; + const selectedState = stateMap?.find((state) => state.id === stateId); + const groupStates = stateMap?.filter((state) => state.group === selectedState?.group); + const groupLength = groupStates.length; + if (direction === "up") { + if (groupIndex === 1) newSequence = groupStates[0].sequence - SEQUENCE_GAP; + else newSequence = (groupStates[groupIndex - 2].sequence + groupStates[groupIndex - 1].sequence) / 2; + } else { + if (groupIndex === groupLength - 2) newSequence = groupStates[groupLength - 1].sequence + SEQUENCE_GAP; + else newSequence = (groupStates[groupIndex + 2].sequence + groupStates[groupIndex + 1].sequence) / 2; + } + // updating using api + await this.stateService.patchState(workspaceSlug, projectId, stateId, { sequence: newSequence }).then(() => { runInAction(() => { set(this.stateMap, [stateId, "sequence"], newSequence); }); - - // updating using api - await this.stateService.patchState(workspaceSlug, projectId, stateId, { sequence: newSequence }); - } catch (err) { - // reverting back to old state group if api fails - runInAction(() => { - this.stateMap = originalStates; - }); - } + }); }; } diff --git a/web/store/user/index.ts b/web/store/user/index.ts index b82b56d68d1..6a23f92a0b5 100644 --- a/web/store/user/index.ts +++ b/web/store/user/index.ts @@ -9,22 +9,18 @@ import { RootStore } from "../root.store"; import { IUserMembershipStore, UserMembershipStore } from "./user-membership.store"; export interface IUserStore { - loader: boolean; - currentUserError: any; - isUserLoggedIn: boolean | null; currentUser: IUser | null; isUserInstanceAdmin: boolean | null; currentUserSettings: IUserSettings | null; dashboardInfo: any; - + // fetch actions fetchCurrentUser: () => Promise; fetchCurrentUserInstanceAdminStatus: () => Promise; fetchCurrentUserSettings: () => Promise; - fetchUserDashboardInfo: (workspaceSlug: string, month: number) => Promise; - + // crud actions updateUserOnBoard: () => Promise; updateTourCompleted: () => Promise; updateCurrentUser: (data: Partial) => Promise; @@ -37,9 +33,6 @@ export interface IUserStore { } export class UserStore implements IUserStore { - loader: boolean = false; - currentUserError: any = null; - isUserLoggedIn: boolean | null = null; currentUser: IUser | null = null; isUserInstanceAdmin: boolean | null = null; @@ -57,8 +50,6 @@ export class UserStore implements IUserStore { constructor(_rootStore: RootStore) { makeObservable(this, { // observable - loader: observable.ref, - isUserLoggedIn: observable.ref, currentUser: observable, isUserInstanceAdmin: observable.ref, currentUserSettings: observable, @@ -81,57 +72,46 @@ export class UserStore implements IUserStore { this.membership = new UserMembershipStore(_rootStore); } - fetchCurrentUser = async () => { - try { - const response = await this.userService.currentUser(); - if (response) { - runInAction(() => { - this.currentUserError = null; - this.currentUser = response; - this.isUserLoggedIn = true; - }); - } - return response; - } catch (error) { + /** + * Fetches the current user + * @returns Promise + */ + fetchCurrentUser = async () => + await this.userService.currentUser().then((user) => { runInAction(() => { - this.currentUserError = error; - this.isUserLoggedIn = false; + this.isUserLoggedIn = true; }); - throw error; - } - }; + return user; + }); - fetchCurrentUserInstanceAdminStatus = async () => { - try { - const response = await this.userService.currentUserInstanceAdminStatus(); - if (response) { - runInAction(() => { - this.isUserInstanceAdmin = response.is_instance_admin; - }); - } - return response.is_instance_admin; - } catch (error) { + /** + * Fetches the current user instance admin status + * @returns Promise + */ + fetchCurrentUserInstanceAdminStatus = async () => + await this.userService.currentUserInstanceAdminStatus().then((response) => { runInAction(() => { - this.isUserInstanceAdmin = false; + this.isUserInstanceAdmin = response.is_instance_admin; }); - throw error; - } - }; + return response.is_instance_admin; + }); - fetchCurrentUserSettings = async () => { - try { - const response = await this.userService.currentUserSettings(); - if (response) { - runInAction(() => { - this.currentUserSettings = response; - }); - } + /** + * Fetches the current user settings + * @returns Promise + */ + fetchCurrentUserSettings = async () => + await this.userService.currentUserSettings().then((response) => { + runInAction(() => { + this.currentUserSettings = response; + }); return response; - } catch (error) { - throw error; - } - }; + }); + /** + * Fetches the current user dashboard info + * @returns Promise + */ fetchUserDashboardInfo = async (workspaceSlug: string, month: number) => { try { const response = await this.userService.userWorkspaceDashboard(workspaceSlug, month); @@ -144,109 +124,102 @@ export class UserStore implements IUserStore { } }; + /** + * Updates the user onboarding status + * @returns Promise + */ updateUserOnBoard = async () => { - try { + const user = this.currentUser ?? undefined; + if (!user) return; + await this.userService.updateUserOnBoard().then(() => { runInAction(() => { this.currentUser = { ...this.currentUser, is_onboarded: true, } as IUser; }); - - const user = this.currentUser ?? undefined; - - if (!user) return; - - await this.userService.updateUserOnBoard(); - } catch (error) { - this.fetchCurrentUser(); - - throw error; - } + }); }; + /** + * Updates the user tour completed status + * @returns Promise + */ updateTourCompleted = async () => { - try { - if (this.currentUser) { + if (this.currentUser) { + return await this.userService.updateUserTourCompleted().then(() => { runInAction(() => { this.currentUser = { ...this.currentUser, is_tour_completed: true, } as IUser; }); - - const response = await this.userService.updateUserTourCompleted(); - - return response; - } - } catch (error) { - throw error; + }); } }; - updateCurrentUser = async (data: Partial) => { - try { - runInAction(() => { - this.currentUser = { - ...this.currentUser, - ...data, - } as IUser; - }); - - const response = await this.userService.updateUser(data); - + /** + * Updates the current user + * @param data + * @returns Promise + */ + updateCurrentUser = async (data: Partial) => + await this.userService.updateUser(data).then((response) => { runInAction(() => { this.currentUser = response; }); return response; - } catch (error) { - this.fetchCurrentUser(); - - throw error; - } - }; + }); - updateCurrentUserTheme = async (theme: string) => { - try { - runInAction(() => { - this.currentUser = { - ...this.currentUser, - theme: { - ...this.currentUser?.theme, - theme, - }, - } as IUser; - }); - const response = await this.userService.updateUser({ + /** + * Updates the current user theme + * @param theme + * @returns Promise + */ + updateCurrentUserTheme = async (theme: string) => + await this.userService + .updateUser({ theme: { ...this.currentUser?.theme, theme }, - } as IUser); - return response; - } catch (error) { - throw error; - } - }; + } as IUser) + .then((response) => { + runInAction(() => { + this.currentUser = { + ...this.currentUser, + theme: { + ...this.currentUser?.theme, + theme, + }, + } as IUser; + }); + return response; + }); + /** + * Deactivates the current user + * @returns Promise + */ deactivateAccount = async () => { try { - await this.userService.deactivateAccount(); - this.currentUserError = null; - this.currentUser = null; - this.isUserLoggedIn = false; + await this.userService.deactivateAccount().then(() => { + runInAction(() => { + this.currentUser = null; + this.isUserLoggedIn = false; + }); + }); } catch (error) { throw error; } }; - signOut = async () => { - try { - await this.authService.signOut(); + /** + * Signs out the current user + * @returns Promise + */ + signOut = async () => + await this.authService.signOut().then(() => { runInAction(() => { - this.currentUserError = null; this.currentUser = null; this.isUserLoggedIn = false; }); - } catch (error) { - throw error; - } - }; + }); } diff --git a/web/store/user/user-membership.store.ts b/web/store/user/user-membership.store.ts index 176d49f6927..cc1e2ec4966 100644 --- a/web/store/user/user-membership.store.ts +++ b/web/store/user/user-membership.store.ts @@ -35,14 +35,14 @@ export interface IUserMembershipStore { hasPermissionToCurrentWorkspace: boolean | undefined; hasPermissionToCurrentProject: boolean | undefined; - // actions + // fetch actions fetchUserWorkspaceInfo: (workspaceSlug: string) => Promise; fetchUserProjectInfo: (workspaceSlug: string, projectId: string) => Promise; - + fetchUserWorkspaceProjectsRole: (workspaceSlug: string) => Promise; + // crud actions leaveWorkspace: (workspaceSlug: string) => Promise; joinProject: (workspaceSlug: string, projectIds: string[]) => Promise; leaveProject: (workspaceSlug: string, projectId: string) => Promise; - fetchUserWorkspaceProjectsRole: (workspaceSlug: string) => Promise; } export class UserMembershipStore implements IUserMembershipStore { @@ -97,64 +97,84 @@ export class UserMembershipStore implements IUserMembershipStore { this.projectMemberService = new ProjectMemberService(); } + /** + * Returns the current workspace member info + */ get currentWorkspaceMemberInfo() { if (!this.router.workspaceSlug) return; return this.workspaceMemberInfo[this.router.workspaceSlug]; } + /** + * Returns the current workspace role + */ get currentWorkspaceRole() { if (!this.router.workspaceSlug) return; return this.workspaceMemberInfo[this.router.workspaceSlug]?.role; } + /** + * Returns the current project member info + */ get currentProjectMemberInfo() { if (!this.router.projectId) return; return this.projectMemberInfo[this.router.projectId]; } + /** + * Returns the current project role + */ get currentProjectRole() { if (!this.router.projectId) return; return this.projectMemberInfo[this.router.projectId]?.role; } + /** + * Returns all projects role for the current workspace + */ get currentWorkspaceAllProjectsRole() { if (!this.router.workspaceSlug) return; return this.workspaceProjectsRole?.[this.router.workspaceSlug]; } + /** + * Returns if the user has permission to the current workspace + */ get hasPermissionToCurrentWorkspace() { if (!this.router.workspaceSlug) return; return this.hasPermissionToWorkspace[this.router.workspaceSlug]; } + /** + * Returns if the user has permission to the current project + */ get hasPermissionToCurrentProject() { if (!this.router.projectId) return; return this.hasPermissionToProject[this.router.projectId]; } - fetchUserWorkspaceInfo = async (workspaceSlug: string) => { - try { - const response = await this.workspaceService.workspaceMemberMe(workspaceSlug); - + /** + * Fetches the current user workspace info + * @param workspaceSlug + * @returns Promise + */ + fetchUserWorkspaceInfo = async (workspaceSlug: string) => + await this.workspaceService.workspaceMemberMe(workspaceSlug).then((response) => { runInAction(() => { set(this.workspaceMemberInfo, [workspaceSlug], response); set(this.hasPermissionToWorkspace, [workspaceSlug], true); }); - - // console.log("this.workspaceMemberInfo", this.workspaceMemberInfo); return response; - } catch (error) { - runInAction(() => { - set(this.hasPermissionToWorkspace, [workspaceSlug], false); - }); - throw error; - } - }; - - fetchUserProjectInfo = async (workspaceSlug: string, projectId: string) => { - try { - const response = await this.projectMemberService.projectMemberMe(workspaceSlug, projectId); + }); + /** + * Fetches the current user project info + * @param workspaceSlug + * @param projectId + * @returns Promise + */ + fetchUserProjectInfo = async (workspaceSlug: string, projectId: string) => + await this.projectMemberService.projectMemberMe(workspaceSlug, projectId).then((response) => { runInAction(() => { this.projectMemberInfo = { ...this.projectMemberInfo, @@ -166,81 +186,69 @@ export class UserMembershipStore implements IUserMembershipStore { }; }); return response; - } catch (error: any) { - runInAction(() => { - this.hasPermissionToProject = { - ...this.hasPermissionToProject, - [projectId]: false, - }; - }); - - throw error; - } - }; - - leaveWorkspace = async (workspaceSlug: string) => { - try { - await this.userService.leaveWorkspace(workspaceSlug); + }); + /** + * Leaves a workspace + * @param workspaceSlug + * @returns Promise + */ + leaveWorkspace = async (workspaceSlug: string) => + await this.userService.leaveWorkspace(workspaceSlug).then(() => { runInAction(() => { delete this.workspaceMemberInfo[workspaceSlug]; delete this.hasPermissionToWorkspace[workspaceSlug]; }); - } catch (error) { - throw error; - } - }; - - joinProject = async (workspaceSlug: string, projectIds: string[]) => { - const newPermissions: { [projectId: string]: boolean } = {}; - projectIds.forEach((projectId) => { - newPermissions[projectId] = true; }); - try { - const response = await this.userService.joinProject(workspaceSlug, projectIds); - + /** + * Joins a project + * @param workspaceSlug + * @param projectIds + * @returns Promise + */ + joinProject = async (workspaceSlug: string, projectIds: string[]) => + await this.userService.joinProject(workspaceSlug, projectIds).then(() => { + const newPermissions: { [projectId: string]: boolean } = {}; + projectIds.forEach((projectId) => { + newPermissions[projectId] = true; + }); runInAction(() => { this.hasPermissionToProject = { ...this.hasPermissionToProject, ...newPermissions, }; }); + }); - return response; - } catch (error) { - throw error; - } - }; - - leaveProject = async (workspaceSlug: string, projectId: string) => { - const newPermissions: { [projectId: string]: boolean } = {}; - newPermissions[projectId] = false; - - try { - await this.userService.leaveProject(workspaceSlug, projectId); - + /** + * Leaves a project + * @param workspaceSlug + * @param projectId + * @returns Promise + */ + leaveProject = async (workspaceSlug: string, projectId: string) => + await this.userService.leaveProject(workspaceSlug, projectId).then(() => { + const newPermissions: { [projectId: string]: boolean } = {}; + newPermissions[projectId] = false; runInAction(() => { this.hasPermissionToProject = { ...this.hasPermissionToProject, ...newPermissions, }; }); - } catch (error) { - throw error; - } - }; - - fetchUserWorkspaceProjectsRole = async (workspaceSlug: string) => { - try { - const response = await this.workspaceService.getWorkspaceUserProjectsRole(workspaceSlug); + }); + /** + * Fetches the current user workspace projects role + * @param workspaceSlug + * @returns Promise + */ + fetchUserWorkspaceProjectsRole = async (workspaceSlug: string) => + await this.workspaceService.getWorkspaceUserProjectsRole(workspaceSlug).then((response) => { runInAction(() => { set(this.workspaceProjectsRole, [workspaceSlug], response); }); return response; - } catch (error) { - throw error; - } - }; + }); } diff --git a/web/store/workspace/api-token.store.ts b/web/store/workspace/api-token.store.ts index 69a614062ef..b9530ccdc36 100644 --- a/web/store/workspace/api-token.store.ts +++ b/web/store/workspace/api-token.store.ts @@ -6,31 +6,21 @@ import { RootStore } from "../root.store"; import { IApiToken } from "types/api_token"; export interface IApiTokenStore { - // states - loader: boolean; - error: any | null; - // observables apiTokens: Record | null; - // computed actions getApiTokenById: (apiTokenId: string) => IApiToken | null; - - // actions + // fetch actions fetchApiTokens: (workspaceSlug: string) => Promise; fetchApiTokenDetails: (workspaceSlug: string, tokenId: string) => Promise; + // crud actions createApiToken: (workspaceSlug: string, data: Partial) => Promise; deleteApiToken: (workspaceSlug: string, tokenId: string) => Promise; } export class ApiTokenStore implements IApiTokenStore { - // states - loader: boolean = false; - error: any | null = null; - // observables apiTokens: Record | null = null; - // services apiTokenService; // root store @@ -38,16 +28,10 @@ export class ApiTokenStore implements IApiTokenStore { constructor(_rootStore: RootStore) { makeObservable(this, { - // states - loader: observable.ref, - error: observable.ref, - // observables apiTokens: observable, - // computed actions getApiTokenById: action, - // actions fetchApiTokens: action, fetchApiTokenDetails: action, @@ -67,7 +51,6 @@ export class ApiTokenStore implements IApiTokenStore { */ getApiTokenById = (apiTokenId: string) => { if (!this.apiTokens) return null; - return this.apiTokens[apiTokenId] || null; }; @@ -75,110 +58,58 @@ export class ApiTokenStore implements IApiTokenStore { * 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); - + fetchApiTokens = async (workspaceSlug: string) => + await this.apiTokenService.getApiTokens(workspaceSlug).then((response) => { 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); - + fetchApiTokenDetails = async (workspaceSlug: string, tokenId: string) => + await this.apiTokenService.retrieveApiToken(workspaceSlug, tokenId).then((response) => { 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) => { - try { - this.loader = true; - this.error = null; - - const response = await this.apiTokenService.createApiToken(workspaceSlug, data); - + createApiToken = async (workspaceSlug: string, data: Partial) => + await this.apiTokenService.createApiToken(workspaceSlug, data).then((response) => { 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); - + deleteApiToken = async (workspaceSlug: string, tokenId: string) => + await this.apiTokenService.deleteApiToken(workspaceSlug, tokenId).then(() => { const updatedApiTokens = { ...this.apiTokens }; delete updatedApiTokens[tokenId]; runInAction(() => { this.apiTokens = updatedApiTokens; }); - } catch (error) { - runInAction(() => { - this.error = error; - }); - - throw error; - } - }; + }); } diff --git a/web/store/workspace/index.ts b/web/store/workspace/index.ts index ced70262e61..8a6946587ad 100644 --- a/web/store/workspace/index.ts +++ b/web/store/workspace/index.ts @@ -11,9 +11,6 @@ import { IWebhookStore, WebhookStore } from "./webhook.store"; import { ApiTokenStore, IApiTokenStore } from "./api-token.store"; export interface IWorkspaceRootStore { - // states - loader: boolean; - error: any | null; // observables workspaces: Record; // computed @@ -22,8 +19,9 @@ export interface IWorkspaceRootStore { // computed actions getWorkspaceBySlug: (workspaceSlug: string) => IWorkspace | null; getWorkspaceById: (workspaceId: string) => IWorkspace | null; - // actions + // fetch actions fetchWorkspaces: () => Promise; + // crud actions createWorkspace: (data: Partial) => Promise; updateWorkspace: (workspaceSlug: string, data: Partial) => Promise; deleteWorkspace: (workspaceSlug: string) => Promise; @@ -33,9 +31,6 @@ export interface IWorkspaceRootStore { } export class WorkspaceRootStore implements IWorkspaceRootStore { - // states - loader: boolean = false; - error: any | null = null; // observables workspaces: Record = {}; // services @@ -49,9 +44,6 @@ export class WorkspaceRootStore implements IWorkspaceRootStore { constructor(_rootStore: RootStore) { makeObservable(this, { - // states - loader: observable.ref, - error: observable.ref, // observables workspaces: observable, // computed @@ -114,100 +106,52 @@ export class WorkspaceRootStore implements IWorkspaceRootStore { /** * fetch user workspaces from API */ - fetchWorkspaces = async () => { - const workspaceResponse = await this.workspaceService.userWorkspaces(); - runInAction(() => { - this.workspaces = keyBy(workspaceResponse, "id"); + fetchWorkspaces = async () => + await this.workspaceService.userWorkspaces().then((response) => { + runInAction(() => { + this.workspaces = keyBy(response, "id"); + }); + return response; }); - return workspaceResponse; - }; /** * create workspace using the workspace data * @param data */ - createWorkspace = async (data: Partial) => { - try { - runInAction(() => { - this.loader = true; - this.error = null; - }); - - const response = await this.workspaceService.createWorkspace(data); - + createWorkspace = async (data: Partial) => + await this.workspaceService.createWorkspace(data).then((response) => { runInAction(() => { - this.loader = false; - this.error = null; this.workspaces = set(this.workspaces, response.id, 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) => { - try { - runInAction(() => { - this.loader = true; - this.error = null; - }); - - const response = await this.workspaceService.updateWorkspace(workspaceSlug, data); - + updateWorkspace = async (workspaceSlug: string, data: Partial) => + await this.workspaceService.updateWorkspace(workspaceSlug, data).then((response) => { runInAction(() => { - this.loader = false; - this.error = null; set(this.workspaces, response.id, data); }); - 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) => { - try { - await this.workspaceService.deleteWorkspace(workspaceSlug); - + deleteWorkspace = async (workspaceSlug: string) => + await this.workspaceService.deleteWorkspace(workspaceSlug).then(() => { const updatedWorkspacesList = this.workspaces; const workspaceId = this.getWorkspaceBySlug(workspaceSlug)?.id; delete updatedWorkspacesList[`${workspaceId}`]; runInAction(() => { - this.loader = false; - this.error = null; this.workspaces = updatedWorkspacesList; }); - } catch (error) { - runInAction(() => { - this.loader = false; - this.error = error; - }); - - throw error; - } - }; + }); } diff --git a/web/store/workspace/webhook.store.ts b/web/store/workspace/webhook.store.ts index 08132bb483e..e49a3059173 100644 --- a/web/store/workspace/webhook.store.ts +++ b/web/store/workspace/webhook.store.ts @@ -5,9 +5,6 @@ import { WebhookService } from "services/webhook.service"; import { RootStore } from "../root.store"; export interface IWebhookStore { - // states - loader: boolean; - error: any | null; // observables webhooks: Record | null; webhookSecretKey: string | null; @@ -15,9 +12,10 @@ export interface IWebhookStore { currentWebhook: IWebhook | null; // computed actions getWebhookById: (webhookId: string) => IWebhook | null; - // actions + // fetch actions fetchWebhooks: (workspaceSlug: string) => Promise; fetchWebhookById: (workspaceSlug: string, webhookId: string) => Promise; + // crud actions createWebhook: ( workspaceSlug: string, data: Partial @@ -32,9 +30,6 @@ export interface IWebhookStore { } export class WebhookStore implements IWebhookStore { - // states - loader: boolean = false; - error: any | null = null; // observables webhooks: Record | null = null; webhookSecretKey: string | null = null; @@ -45,9 +40,6 @@ export class WebhookStore implements IWebhookStore { constructor(_rootStore: RootStore) { makeObservable(this, { - // states - loader: observable.ref, - error: observable.ref, // observables webhooks: observable, webhookSecretKey: observable.ref, @@ -76,9 +68,7 @@ export class WebhookStore implements IWebhookStore { */ get currentWebhook() { const webhookId = this.rootStore.app.router.webhookId; - if (!webhookId) return null; - const currentWebhook = this.webhooks?.[webhookId] ?? null; return currentWebhook; } @@ -93,82 +83,53 @@ export class WebhookStore implements IWebhookStore { * 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) => { + fetchWebhooks = async (workspaceSlug: string) => + await this.webhookService.fetchWebhooksList(workspaceSlug).then((response) => { + const webHookObject: { [webhookId: string]: IWebhook } = response.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; - } - }; + return response; + }); /** * 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); - + fetchWebhookById = async (workspaceSlug: string, webhookId: string) => + await this.webhookService.fetchWebhookDetails(workspaceSlug, webhookId).then((response) => { runInAction(() => { this.webhooks = { ...this.webhooks, - [webhookResponse.id]: webhookResponse, + [response.id]: response, }; }); - - return webhookResponse; - } catch (error) { - throw error; - } - }; + return response; + }); /** * create a new webhook for a workspace using the data * @param workspaceSlug * @param data */ - createWebhook = async (workspaceSlug: string, data: Partial) => { - try { - const webhookResponse = await this.webhookService.createWebhook(workspaceSlug, data); - - const _secretKey = webhookResponse?.secret_key ?? null; - delete webhookResponse?.secret_key; + createWebhook = async (workspaceSlug: string, data: Partial) => + await this.webhookService.createWebhook(workspaceSlug, data).then((response) => { + const _secretKey = response?.secret_key ?? null; + delete response?.secret_key; const _webhooks = this.webhooks; - - if (webhookResponse && webhookResponse.id && _webhooks) _webhooks[webhookResponse.id] = webhookResponse; - + if (response && response.id && _webhooks) _webhooks[response.id] = response; runInAction(() => { this.webhookSecretKey = _secretKey || null; this.webhooks = _webhooks; }); - - return { webHook: webhookResponse, secretKey: _secretKey }; - } catch (error) { - throw error; - } - }; + return { webHook: response, secretKey: _secretKey }; + }); /** * update a webhook using the data @@ -176,71 +137,50 @@ export class WebhookStore implements IWebhookStore { * @param webhookId * @param data */ - updateWebhook = async (workspaceSlug: string, webhookId: string, data: Partial) => { - try { + updateWebhook = async (workspaceSlug: string, webhookId: string, data: Partial) => + await this.webhookService.updateWebhook(workspaceSlug, webhookId, data).then((response) => { 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; - } - }; + return response; + }); /** * delete a webhook using webhook id * @param workspaceSlug * @param webhookId */ - removeWebhook = async (workspaceSlug: string, webhookId: string) => { - try { - await this.webhookService.deleteWebhook(workspaceSlug, webhookId); - + removeWebhook = async (workspaceSlug: string, webhookId: string) => + await this.webhookService.deleteWebhook(workspaceSlug, webhookId).then(() => { 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; + regenerateSecretKey = async (workspaceSlug: string, webhookId: string) => + await this.webhookService.regenerateSecretKey(workspaceSlug, webhookId).then((response) => { + const _secretKey = response?.secret_key ?? null; + delete response?.secret_key; const _webhooks = this.webhooks; - - if (_webhooks && webhookResponse && webhookResponse.id) { - _webhooks[webhookResponse.id] = webhookResponse; + if (_webhooks && response && response.id) { + _webhooks[response.id] = response; } - runInAction(() => { this.webhookSecretKey = _secretKey || null; this.webhooks = _webhooks; }); - return { webHook: webhookResponse, secretKey: _secretKey }; - } catch (error) { - throw error; - } - }; + return { webHook: response, secretKey: _secretKey }; + }); /** * clear secret key from the store