From b9975dfa24746746458e29ff14ccbbe30fba3759 Mon Sep 17 00:00:00 2001 From: Dakshesh Jain Date: Fri, 11 Aug 2023 14:05:32 +0530 Subject: [PATCH] refactor: typed context and using observer hoc --- .../labels/create-update-label-inline.tsx | 28 +++++------ apps/app/lib/mobx/store-provider.tsx | 2 +- .../projects/[projectId]/settings/labels.tsx | 46 ++++++++++++------- apps/app/store/labels.ts | 11 +++-- apps/app/store/root.ts | 4 +- 5 files changed, 56 insertions(+), 35 deletions(-) diff --git a/apps/app/components/labels/create-update-label-inline.tsx b/apps/app/components/labels/create-update-label-inline.tsx index ca4fdf3dc..98bb40508 100644 --- a/apps/app/components/labels/create-update-label-inline.tsx +++ b/apps/app/components/labels/create-update-label-inline.tsx @@ -4,8 +4,13 @@ import { useRouter } from "next/router"; import { mutate } from "swr"; +// mobx +import { useObserver } from "mobx-react-lite"; + // react-hook-form import { Controller, SubmitHandler, useForm } from "react-hook-form"; +// store +import labelStore from "store/labels"; // hooks import useUserAuth from "hooks/use-user-auth"; // react-color @@ -58,20 +63,17 @@ export const CreateUpdateLabelInline = forwardRef(function CreateUpd defaultValues, }); - const handleLabelCreate: SubmitHandler = async (formData) => { - if (!workspaceSlug || !projectId || isSubmitting) return; + const { createLabel } = useObserver(() => ({ + createLabel: labelStore.createLabel, + })); - await issuesService - .createIssueLabel(workspaceSlug as string, projectId as string, formData, user) - .then((res) => { - mutate( - PROJECT_ISSUE_LABELS(projectId as string), - (prevData) => [res, ...(prevData ?? [])], - false - ); - reset(defaultValues); - setLabelForm(false); - }); + const handleLabelCreate: SubmitHandler = async (formData) => { + if (!workspaceSlug || !projectId || isSubmitting || !user) return; + + await createLabel(workspaceSlug.toString(), projectId.toString(), formData, user).then(() => { + reset(defaultValues); + setLabelForm(false); + }); }; const handleLabelUpdate: SubmitHandler = async (formData) => { diff --git a/apps/app/lib/mobx/store-provider.tsx b/apps/app/lib/mobx/store-provider.tsx index 244968028..c8e0b08a5 100644 --- a/apps/app/lib/mobx/store-provider.tsx +++ b/apps/app/lib/mobx/store-provider.tsx @@ -4,7 +4,7 @@ import { RootStore } from "store/root"; let rootStore: any = null; -export const MobxStoreContext = createContext(null); +export const MobxStoreContext = createContext({} as RootStore); const initializeStore = () => { const _rootStore = rootStore ?? new RootStore(); diff --git a/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/labels.tsx b/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/labels.tsx index 3f4495ef5..9ea1a7aa1 100644 --- a/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/labels.tsx +++ b/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/labels.tsx @@ -1,14 +1,17 @@ -import React, { useState, useRef } from "react"; +import React, { useState, useRef, useEffect } from "react"; import { useRouter } from "next/router"; import useSWR from "swr"; +// mobx +import { observer } from "mobx-react-lite"; + // hooks import useUserAuth from "hooks/use-user-auth"; +import { useMobxStore } from "lib/mobx/store-provider"; // services import projectService from "services/project.service"; -import issuesService from "services/issues.service"; // layouts import { ProjectAuthorizationWrapper } from "layouts/auth-layout"; // components @@ -31,7 +34,7 @@ import emptyLabel from "public/empty-state/label.svg"; import { IIssueLabels } from "types"; import type { NextPage } from "next"; // fetch-keys -import { PROJECT_DETAILS, PROJECT_ISSUE_LABELS } from "constants/fetch-keys"; +import { PROJECT_DETAILS } from "constants/fetch-keys"; // helper import { truncateText } from "helpers/string.helper"; @@ -57,6 +60,9 @@ const LabelsSettings: NextPage = () => { const scrollToRef = useRef(null); + const { labelStore } = useMobxStore(); + const { isLabelsLoading: isLoading, labels } = labelStore; + const { data: projectDetails } = useSWR( workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null, workspaceSlug && projectId @@ -64,13 +70,6 @@ const LabelsSettings: NextPage = () => { : null ); - const { data: issueLabels } = useSWR( - workspaceSlug && projectId ? PROJECT_ISSUE_LABELS(projectId as string) : null, - workspaceSlug && projectId - ? () => issuesService.getIssueLabels(workspaceSlug as string, projectId as string) - : null - ); - const newLabel = () => { setIsUpdating(false); setLabelForm(true); @@ -87,6 +86,11 @@ const LabelsSettings: NextPage = () => { setLabelToUpdate(label); }; + useEffect(() => { + if (workspaceSlug && projectId) + labelStore.loadLabels(workspaceSlug.toString(), projectId.toString()); + }, [workspaceSlug, projectId, labelStore]); + return ( <> { /> )} <> - {issueLabels ? ( - issueLabels.length > 0 ? ( - issueLabels.map((label) => { - const children = issueLabels?.filter((l) => l.parent === label.id); + {!isLoading ? ( + labels.length > 0 ? ( + labels.map((label) => { + const children = labels?.filter((l) => l.parent === label.id); if (children && children.length === 0) { if (!label.parent) @@ -148,7 +152,17 @@ const LabelsSettings: NextPage = () => { addLabelToGroup(label)} + addLabelToGroup={() => { + addLabelToGroup(label); + // if (!workspaceSlug || !projectId || !user) return; + // labelStore.updateLabel( + // workspaceSlug.toString(), + // projectId.toString(), + // label.id, + // { parent: label.id }, + // user + // ); + }} editLabel={(label) => { editLabel(label); scrollToRef.current?.scrollIntoView({ @@ -205,4 +219,4 @@ const LabelsSettings: NextPage = () => { ); }; -export default LabelsSettings; +export default observer(LabelsSettings); diff --git a/apps/app/store/labels.ts b/apps/app/store/labels.ts index 9e3452d1c..d1af512b1 100644 --- a/apps/app/store/labels.ts +++ b/apps/app/store/labels.ts @@ -1,5 +1,5 @@ // mobx -import { action, observable, runInAction, makeObservable } from "mobx"; +import { action, observable, runInAction, makeAutoObservable } from "mobx"; // services import issueService from "services/issues.service"; @@ -9,12 +9,14 @@ import type { IIssueLabels, LabelForm, ICurrentUserResponse } from "types"; class LabelStore { labels: IIssueLabels[] = []; + isLabelsLoading: boolean = false; rootStore: any | null = null; constructor(_rootStore: any | null = null) { - makeObservable(this, { + makeAutoObservable(this, { labels: observable.ref, loadLabels: action, + isLabelsLoading: observable, createLabel: action, updateLabel: action, deleteLabel: action, @@ -24,6 +26,7 @@ class LabelStore { } loadLabels = async (workspaceSlug: string, projectId: string) => { + this.isLabelsLoading = true; try { const labelsResponse: IIssueLabels[] = await issueService.getIssueLabels( workspaceSlug, @@ -31,8 +34,10 @@ class LabelStore { ); runInAction(() => { this.labels = labelsResponse; + this.isLabelsLoading = false; }); } catch (error) { + this.isLabelsLoading = false; console.error("Fetching labels error", error); } }; @@ -62,7 +67,7 @@ class LabelStore { workspaceSlug: string, projectId: string, labelId: string, - labelForm: LabelForm, + labelForm: Partial, user: ICurrentUserResponse ) => { try { diff --git a/apps/app/store/root.ts b/apps/app/store/root.ts index 4d081650e..a61ad8a8d 100644 --- a/apps/app/store/root.ts +++ b/apps/app/store/root.ts @@ -10,11 +10,11 @@ enableStaticRendering(typeof window === "undefined"); export class RootStore { user; theme; - labels; + labelStore: LabelStore; constructor() { this.user = new UserStore(this); this.theme = new ThemeStore(this); - this.labels = new LabelStore(this); + this.labelStore = new LabelStore(this); } }