From e9c3a0642e7004989a964673efcf1ec0e7aa2650 Mon Sep 17 00:00:00 2001 From: Dakshesh Jain Date: Wed, 16 Aug 2023 17:49:51 +0530 Subject: [PATCH] refactor: using label store to get labels --- .../components/core/filters/filters-list.tsx | 4 +- .../core/views/board-view/board-header.tsx | 297 +++++++++--------- .../app/components/core/views/issues-view.tsx | 29 +- .../core/views/list-view/single-list.tsx | 63 ++-- .../issues/sidebar-select/label.tsx | 71 ++--- .../components/issues/view-select/label.tsx | 54 ++-- apps/app/components/views/form.tsx | 35 +-- apps/app/components/views/select-filters.tsx | 36 +-- .../projects/[projectId]/pages/[pageId].tsx | 24 +- 9 files changed, 307 insertions(+), 306 deletions(-) diff --git a/apps/app/components/core/filters/filters-list.tsx b/apps/app/components/core/filters/filters-list.tsx index ffe596258..038441d18 100644 --- a/apps/app/components/core/filters/filters-list.tsx +++ b/apps/app/components/core/filters/filters-list.tsx @@ -10,7 +10,7 @@ import { replaceUnderscoreIfSnakeCase } from "helpers/string.helper"; // helpers import { renderShortDateWithYearFormat } from "helpers/date-time.helper"; // types -import { IIssueFilterOptions, IIssueLabels, IState, IUserLite, TStateGroups } from "types"; +import { IIssueFilterOptions, IState, IUserLite, TStateGroups, LabelLite } from "types"; // constants import { STATE_GROUP_COLORS } from "constants/state"; @@ -18,7 +18,7 @@ type Props = { filters: Partial; setFilters: (updatedFilter: Partial) => void; clearAllFilters: (...args: any) => void; - labels: IIssueLabels[] | undefined; + labels: LabelLite[] | undefined; members: IUserLite[] | undefined; states: IState[] | undefined; }; diff --git a/apps/app/components/core/views/board-view/board-header.tsx b/apps/app/components/core/views/board-view/board-header.tsx index 919bc36a3..bc8130bf4 100644 --- a/apps/app/components/core/views/board-view/board-header.tsx +++ b/apps/app/components/core/views/board-view/board-header.tsx @@ -1,18 +1,21 @@ -import React from "react"; +import React, { useEffect } from "react"; import { useRouter } from "next/router"; import useSWR from "swr"; +// mobx +import { observer } from "mobx-react-lite"; +import { useMobxStore } from "lib/mobx/store-provider"; + // services -import issuesService from "services/issues.service"; import projectService from "services/project.service"; // hooks import useProjects from "hooks/use-projects"; // component import { Avatar, Icon } from "components/ui"; // icons -import { ArrowsPointingInIcon, ArrowsPointingOutIcon, PlusIcon } from "@heroicons/react/24/outline"; +import { PlusIcon } from "@heroicons/react/24/outline"; import { getPriorityIcon, getStateGroupIcon } from "components/icons"; // helpers import { addSpaceIfCamelCase } from "helpers/string.helper"; @@ -20,7 +23,7 @@ import { renderEmoji } from "helpers/emoji.helper"; // types import { IIssueViewProps, IState } from "types"; // fetch-keys -import { PROJECT_ISSUE_LABELS, PROJECT_MEMBERS } from "constants/fetch-keys"; +import { PROJECT_MEMBERS } from "constants/fetch-keys"; type Props = { currentState?: IState | null; @@ -32,162 +35,164 @@ type Props = { viewProps: IIssueViewProps; }; -export const BoardHeader: React.FC = ({ - currentState, - groupTitle, - addIssueToGroup, - isCollapsed, - setIsCollapsed, - disableUserActions, - viewProps, -}) => { - const router = useRouter(); - const { workspaceSlug, projectId } = router.query; +export const BoardHeader: React.FC = observer( + ({ + currentState, + groupTitle, + addIssueToGroup, + isCollapsed, + setIsCollapsed, + disableUserActions, + viewProps, + }) => { + const router = useRouter(); + const { workspaceSlug, projectId } = router.query; - const { groupedIssues, groupByProperty: selectedGroup } = viewProps; + const { groupedIssues, groupByProperty: selectedGroup } = viewProps; - const { data: issueLabels } = useSWR( - workspaceSlug && projectId && selectedGroup === "labels" - ? PROJECT_ISSUE_LABELS(projectId.toString()) - : null, - workspaceSlug && projectId && selectedGroup === "labels" - ? () => issuesService.getIssueLabels(workspaceSlug.toString(), projectId.toString()) - : null - ); + const { label: labelStore } = useMobxStore(); + const { labels, loadLabels } = labelStore; - const { data: members } = useSWR( - workspaceSlug && projectId && selectedGroup === "created_by" - ? PROJECT_MEMBERS(projectId.toString()) - : null, - workspaceSlug && projectId && selectedGroup === "created_by" - ? () => projectService.projectMembers(workspaceSlug.toString(), projectId.toString()) - : null - ); + const { data: members } = useSWR( + workspaceSlug && projectId && selectedGroup === "created_by" + ? PROJECT_MEMBERS(projectId.toString()) + : null, + workspaceSlug && projectId && selectedGroup === "created_by" + ? () => projectService.projectMembers(workspaceSlug.toString(), projectId.toString()) + : null + ); - const { projects } = useProjects(); + const { projects } = useProjects(); - const getGroupTitle = () => { - let title = addSpaceIfCamelCase(groupTitle); + useEffect(() => { + if (workspaceSlug && projectId) loadLabels(workspaceSlug.toString(), projectId.toString()); + }, [workspaceSlug, projectId, loadLabels]); - switch (selectedGroup) { - case "state": - title = addSpaceIfCamelCase(currentState?.name ?? ""); - break; - case "labels": - title = issueLabels?.find((label) => label.id === groupTitle)?.name ?? "None"; - break; - case "project": - title = projects?.find((p) => p.id === groupTitle)?.name ?? "None"; - break; - case "created_by": - const member = members?.find((member) => member.member.id === groupTitle)?.member; - title = member?.display_name ?? ""; - break; - } + const getGroupTitle = () => { + let title = addSpaceIfCamelCase(groupTitle); - return title; - }; + switch (selectedGroup) { + case "state": + title = addSpaceIfCamelCase(currentState?.name ?? ""); + break; + case "labels": + title = labels?.find((label) => label.id === groupTitle)?.name ?? "None"; + break; + case "project": + title = projects?.find((p) => p.id === groupTitle)?.name ?? "None"; + break; + case "created_by": + const member = members?.find((member) => member.member.id === groupTitle)?.member; + title = member?.display_name ?? ""; + break; + } - const getGroupIcon = () => { - let icon; + return title; + }; - switch (selectedGroup) { - case "state": - icon = - currentState && getStateGroupIcon(currentState.group, "16", "16", currentState.color); - break; - case "state_detail.group": - icon = getStateGroupIcon(groupTitle as any, "16", "16"); - break; - case "priority": - icon = getPriorityIcon(groupTitle, "text-lg"); - break; - case "project": - const project = projects?.find((p) => p.id === groupTitle); - icon = - project && - (project.emoji !== null - ? renderEmoji(project.emoji) - : project.icon_prop !== null - ? renderEmoji(project.icon_prop) - : null); - break; - case "labels": - const labelColor = - issueLabels?.find((label) => label.id === groupTitle)?.color ?? "#000000"; - icon = ( - - ); - break; - case "created_by": - const member = members?.find((member) => member.member.id === groupTitle)?.member; - icon = ; + const getGroupIcon = () => { + let icon; - break; - } - - return icon; - }; - - return ( -
-
-
- {getGroupIcon()} -

- {getGroupTitle()} -

- - {groupedIssues?.[groupTitle].length ?? 0} - -
-
- -
- - {!disableUserActions && selectedGroup !== "created_by" && ( + ); + break; + case "created_by": + const member = members?.find((member) => member.member.id === groupTitle)?.member; + icon = ; + + break; + } + + return icon; + }; + + return ( +
+
+
+ {getGroupIcon()} +

+ {getGroupTitle()} +

+ + {groupedIssues?.[groupTitle].length ?? 0} + +
+
+ +
- )} + {!disableUserActions && selectedGroup !== "created_by" && ( + + )} +
-
- ); -}; + ); + } +); diff --git a/apps/app/components/core/views/issues-view.tsx b/apps/app/components/core/views/issues-view.tsx index d3d76f805..a07f82aef 100644 --- a/apps/app/components/core/views/issues-view.tsx +++ b/apps/app/components/core/views/issues-view.tsx @@ -1,9 +1,13 @@ -import { useCallback, useState } from "react"; +import { useCallback, useState, useEffect } from "react"; import { useRouter } from "next/router"; import useSWR, { mutate } from "swr"; +// mobx +import { observer } from "mobx-react-lite"; +import { useMobxStore } from "lib/mobx/store-provider"; + // react-beautiful-dnd import { DropResult } from "react-beautiful-dnd"; // services @@ -37,7 +41,6 @@ import { MODULE_DETAILS, MODULE_ISSUES_WITH_PARAMS, PROJECT_ISSUES_LIST_WITH_PARAMS, - PROJECT_ISSUE_LABELS, STATES_LIST, } from "constants/fetch-keys"; @@ -46,10 +49,8 @@ type Props = { disableUserActions?: boolean; }; -export const IssuesView: React.FC = ({ - openIssuesListModal, - disableUserActions = false, -}) => { +export const IssuesView: React.FC = observer((props) => { + const { openIssuesListModal, disableUserActions = false } = props; // create issue modal const [createIssueModal, setCreateIssueModal] = useState(false); const [createViewModal, setCreateViewModal] = useState(null); @@ -75,6 +76,9 @@ export const IssuesView: React.FC = ({ const { user } = useUserAuth(); + const { label: labelStore } = useMobxStore(); + const { labels, loadLabels } = labelStore; + const { setToastAlert } = useToast(); const { @@ -99,15 +103,12 @@ export const IssuesView: React.FC = ({ ); const states = getStatesList(stateGroups); - const { data: labels } = useSWR( - workspaceSlug && projectId ? PROJECT_ISSUE_LABELS(projectId.toString()) : null, - workspaceSlug && projectId - ? () => issuesService.getIssueLabels(workspaceSlug.toString(), projectId.toString()) - : null - ); - const { members } = useProjectMembers(workspaceSlug?.toString(), projectId?.toString()); + useEffect(() => { + if (workspaceSlug && projectId) loadLabels(workspaceSlug as string, projectId as string); + }, [loadLabels, projectId, workspaceSlug]); + const handleDeleteIssue = useCallback( (issue: IIssue) => { setDeleteIssueModal(true); @@ -564,4 +565,4 @@ export const IssuesView: React.FC = ({ /> ); -}; +}); diff --git a/apps/app/components/core/views/list-view/single-list.tsx b/apps/app/components/core/views/list-view/single-list.tsx index 5efc93f3c..bd7045408 100644 --- a/apps/app/components/core/views/list-view/single-list.tsx +++ b/apps/app/components/core/views/list-view/single-list.tsx @@ -1,11 +1,16 @@ +import { useEffect } from "react"; + import { useRouter } from "next/router"; import useSWR from "swr"; +// mobx +import { observer } from "mobx-react-lite"; +import { useMobxStore } from "lib/mobx/store-provider"; + // headless ui import { Disclosure, Transition } from "@headlessui/react"; // services -import issuesService from "services/issues.service"; import projectService from "services/project.service"; // hooks import useProjects from "hooks/use-projects"; @@ -20,16 +25,9 @@ import { getPriorityIcon, getStateGroupIcon } from "components/icons"; import { addSpaceIfCamelCase } from "helpers/string.helper"; import { renderEmoji } from "helpers/emoji.helper"; // types -import { - ICurrentUserResponse, - IIssue, - IIssueLabels, - IIssueViewProps, - IState, - UserAuth, -} from "types"; +import { ICurrentUserResponse, IIssue, IIssueViewProps, IState, UserAuth } from "types"; // fetch-keys -import { PROJECT_ISSUE_LABELS, PROJECT_MEMBERS } from "constants/fetch-keys"; +import { PROJECT_MEMBERS } from "constants/fetch-keys"; type Props = { currentState?: IState | null; @@ -44,18 +42,20 @@ type Props = { viewProps: IIssueViewProps; }; -export const SingleList: React.FC = ({ - currentState, - groupTitle, - addIssueToGroup, - handleIssueAction, - openIssuesListModal, - removeIssue, - disableUserActions, - user, - userAuth, - viewProps, -}) => { +export const SingleList: React.FC = observer((props) => { + const { + currentState, + groupTitle, + addIssueToGroup, + handleIssueAction, + openIssuesListModal, + removeIssue, + disableUserActions, + user, + userAuth, + viewProps, + } = props; + const router = useRouter(); const { workspaceSlug, projectId, cycleId, moduleId } = router.query; @@ -65,12 +65,8 @@ export const SingleList: React.FC = ({ const { groupByProperty: selectedGroup, groupedIssues } = viewProps; - 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 { label: labelStore } = useMobxStore(); + const { labels, loadLabels } = labelStore; const { data: members } = useSWR( workspaceSlug && projectId ? PROJECT_MEMBERS(projectId as string) : null, @@ -81,6 +77,10 @@ export const SingleList: React.FC = ({ const { projects } = useProjects(); + useEffect(() => { + if (workspaceSlug && projectId) loadLabels(workspaceSlug.toString(), projectId.toString()); + }, [workspaceSlug, projectId, loadLabels]); + const getGroupTitle = () => { let title = addSpaceIfCamelCase(groupTitle); @@ -89,7 +89,7 @@ export const SingleList: React.FC = ({ title = addSpaceIfCamelCase(currentState?.name ?? ""); break; case "labels": - title = issueLabels?.find((label) => label.id === groupTitle)?.name ?? "None"; + title = labels?.find((label) => label.id === groupTitle)?.name ?? "None"; break; case "project": title = projects?.find((p) => p.id === groupTitle)?.name ?? "None"; @@ -128,8 +128,7 @@ export const SingleList: React.FC = ({ : null); break; case "labels": - const labelColor = - issueLabels?.find((label) => label.id === groupTitle)?.color ?? "#000000"; + const labelColor = labels?.find((label) => label.id === groupTitle)?.color ?? "#000000"; icon = ( = ({ )} ); -}; +}); diff --git a/apps/app/components/issues/sidebar-select/label.tsx b/apps/app/components/issues/sidebar-select/label.tsx index 5f3539c86..2e1b759ca 100644 --- a/apps/app/components/issues/sidebar-select/label.tsx +++ b/apps/app/components/issues/sidebar-select/label.tsx @@ -2,7 +2,9 @@ import React, { useEffect, useState } from "react"; import { useRouter } from "next/router"; -import useSWR from "swr"; +// mobx +import { observer } from "mobx-react-lite"; +import { useMobxStore } from "lib/mobx/store-provider"; // react-hook-form import { Controller, UseFormWatch, useForm } from "react-hook-form"; @@ -10,8 +12,6 @@ import { Controller, UseFormWatch, useForm } from "react-hook-form"; import { TwitterPicker } from "react-color"; // headless ui import { Listbox, Popover, Transition } from "@headlessui/react"; -// services -import issuesService from "services/issues.service"; // hooks import useUser from "hooks/use-user"; // ui @@ -25,9 +25,7 @@ import { XMarkIcon, } from "@heroicons/react/24/outline"; // types -import { IIssue, IIssueLabels } from "types"; -// fetch-keys -import { PROJECT_ISSUE_LABELS } from "constants/fetch-keys"; +import { IIssue, LabelForm } from "types"; type Props = { issueDetails: IIssue | undefined; @@ -38,19 +36,13 @@ type Props = { uneditable: boolean; }; -const defaultValues: Partial = { +const defaultValues: Partial = { name: "", color: "#ff0000", }; -export const SidebarLabelSelect: React.FC = ({ - issueDetails, - issueControl, - watchIssue, - submitChanges, - isNotAllowed, - uneditable, -}) => { +export const SidebarLabelSelect: React.FC = observer((props) => { + const { issueDetails, issueControl, watchIssue, submitChanges, isNotAllowed, uneditable } = props; const [createLabelForm, setCreateLabelForm] = useState(false); const router = useRouter(); @@ -64,33 +56,38 @@ export const SidebarLabelSelect: React.FC = ({ watch, control: labelControl, setFocus, - } = useForm>({ + } = useForm({ defaultValues, }); const { user } = useUser(); - const { data: issueLabels, mutate: issueLabelMutate } = useSWR( - workspaceSlug && projectId ? PROJECT_ISSUE_LABELS(projectId as string) : null, - workspaceSlug && projectId - ? () => issuesService.getIssueLabels(workspaceSlug as string, projectId as string) - : null - ); + const { label: labelStore } = useMobxStore(); + const { + labels, + loadLabels, + createLabel, + getLabelById, + getLabelChildren, + isLabelsLoading: isLoading, + } = labelStore; - const handleNewLabel = async (formData: Partial) => { - if (!workspaceSlug || !projectId || isSubmitting) return; + useEffect(() => { + if (workspaceSlug && projectId) loadLabels(workspaceSlug.toString(), projectId.toString()); + }, [workspaceSlug, projectId, loadLabels]); - await issuesService - .createIssueLabel(workspaceSlug as string, projectId as string, formData, user) - .then((res) => { + const handleNewLabel = async (formData: LabelForm) => { + if (!workspaceSlug || !projectId || isSubmitting || !user) return; + + await createLabel(workspaceSlug.toString(), projectId.toString(), formData, user).then( + (res: any) => { reset(defaultValues); - issueLabelMutate((prevData: any) => [...(prevData ?? []), res], false); - submitChanges({ labels_list: [...(issueDetails?.labels ?? []), res.id] }); setCreateLabelForm(false); - }); + } + ); }; useEffect(() => { @@ -110,7 +107,7 @@ export const SidebarLabelSelect: React.FC = ({
{watchIssue("labels_list")?.map((labelId) => { - const label = issueLabels?.find((l) => l.id === labelId); + const label = getLabelById(labelId); if (label) return ( @@ -168,12 +165,10 @@ export const SidebarLabelSelect: React.FC = ({ >
- {issueLabels ? ( - issueLabels.length > 0 ? ( - issueLabels.map((label: IIssueLabels) => { - const children = issueLabels?.filter( - (l) => l.parent === label.id - ); + {!isLoading ? ( + labels.length > 0 ? ( + labels.map((label) => { + const children = getLabelChildren(label.id); if (children.length === 0) { if (!label.parent) @@ -346,4 +341,4 @@ export const SidebarLabelSelect: React.FC = ({ )}
); -}; +}); diff --git a/apps/app/components/issues/view-select/label.tsx b/apps/app/components/issues/view-select/label.tsx index 3a75763b2..51efa7d0a 100644 --- a/apps/app/components/issues/view-select/label.tsx +++ b/apps/app/components/issues/view-select/label.tsx @@ -1,11 +1,11 @@ -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import { useRouter } from "next/router"; -import useSWR from "swr"; +// mobx +import { observer } from "mobx-react-lite"; +import { useMobxStore } from "lib/mobx/store-provider"; -// services -import issuesService from "services/issues.service"; // component import { CreateLabelModal } from "components/labels"; // ui @@ -13,9 +13,7 @@ import { CustomSearchSelect, Tooltip } from "components/ui"; // icons import { PlusIcon, TagIcon } from "@heroicons/react/24/outline"; // types -import { ICurrentUserResponse, IIssue, IIssueLabels } from "types"; -// fetch-keys -import { PROJECT_ISSUE_LABELS } from "constants/fetch-keys"; +import { ICurrentUserResponse, IIssue } from "types"; type Props = { issue: IIssue; @@ -28,29 +26,31 @@ type Props = { isNotAllowed: boolean; }; -export const ViewLabelSelect: React.FC = ({ - issue, - partialUpdateIssue, - position = "left", - selfPositioned = false, - tooltipPosition = "top", - user, - isNotAllowed, - customButton = false, -}) => { +export const ViewLabelSelect: React.FC = observer((props) => { + const { + issue, + partialUpdateIssue, + position = "left", + selfPositioned = false, + tooltipPosition = "top", + user, + isNotAllowed, + customButton = false, + } = props; + const [labelModal, setLabelModal] = useState(false); const router = useRouter(); const { workspaceSlug, projectId } = router.query; - const { data: issueLabels } = useSWR( - projectId ? PROJECT_ISSUE_LABELS(projectId.toString()) : null, - workspaceSlug && projectId - ? () => issuesService.getIssueLabels(workspaceSlug as string, projectId as string) - : null - ); + const { label: labelStore } = useMobxStore(); + const { labels, loadLabels, getLabelById } = labelStore; - const options = issueLabels?.map((label) => ({ + useEffect(() => { + if (workspaceSlug && projectId) loadLabels(workspaceSlug.toString(), projectId.toString()); + }, [workspaceSlug, projectId, loadLabels]); + + const options = labels?.map((label) => ({ value: label.id, query: label.name, content: ( @@ -74,7 +74,7 @@ export const ViewLabelSelect: React.FC = ({ issue.labels.length > 0 ? issue.labels .map((labelId) => { - const label = issueLabels?.find((l) => l.id === labelId); + const label = getLabelById(labelId); return label?.name ?? ""; }) @@ -90,7 +90,7 @@ export const ViewLabelSelect: React.FC = ({ {issue.labels.length > 0 ? ( <> {issue.labels.slice(0, 4).map((labelId, index) => { - const label = issueLabels?.find((l) => l.id === labelId); + const label = getLabelById(labelId); return (
@@ -154,4 +154,4 @@ export const ViewLabelSelect: React.FC = ({ /> ); -}; +}); diff --git a/apps/app/components/views/form.tsx b/apps/app/components/views/form.tsx index 9191a7b2b..e6ea69e15 100644 --- a/apps/app/components/views/form.tsx +++ b/apps/app/components/views/form.tsx @@ -4,6 +4,10 @@ import { useRouter } from "next/router"; import useSWR from "swr"; +// mobx +import { observer } from "mobx-react-lite"; +import { useMobxStore } from "lib/mobx/store-provider"; + // react-hook-form import { useForm } from "react-hook-form"; // services @@ -20,9 +24,8 @@ import { checkIfArraysHaveSameElements } from "helpers/array.helper"; import { getStatesList } from "helpers/state.helper"; // types import { IQuery, IView } from "types"; -import issuesService from "services/issues.service"; // fetch-keys -import { PROJECT_ISSUE_LABELS, STATES_LIST } from "constants/fetch-keys"; +import { STATES_LIST } from "constants/fetch-keys"; type Props = { handleFormSubmit: (values: IView) => Promise; @@ -37,13 +40,9 @@ const defaultValues: Partial = { description: "", }; -export const ViewForm: React.FC = ({ - handleFormSubmit, - handleClose, - status, - data, - preLoadedData, -}) => { +export const ViewForm: React.FC = observer((props) => { + const { handleFormSubmit, handleClose, status, data, preLoadedData } = props; + const router = useRouter(); const { workspaceSlug, projectId } = router.query; @@ -69,16 +68,16 @@ export const ViewForm: React.FC = ({ ); const states = getStatesList(stateGroups); - const { data: labels } = useSWR( - workspaceSlug && projectId && (filters?.labels ?? []).length > 0 - ? PROJECT_ISSUE_LABELS(projectId.toString()) - : null, - workspaceSlug && projectId && (filters?.labels ?? []).length > 0 - ? () => issuesService.getIssueLabels(workspaceSlug.toString(), projectId.toString()) - : null - ); + const { label: labelStore } = useMobxStore(); + const { labels, loadLabels } = labelStore; + const { members } = useProjectMembers(workspaceSlug?.toString(), projectId?.toString()); + useEffect(() => { + if (workspaceSlug && projectId && (filters?.labels ?? []).length > 0) + loadLabels(workspaceSlug.toString(), projectId.toString()); + }, [workspaceSlug, projectId, loadLabels, filters]); + const handleCreateUpdateView = async (formData: IView) => { await handleFormSubmit(formData); @@ -211,4 +210,4 @@ export const ViewForm: React.FC = ({
); -}; +}); diff --git a/apps/app/components/views/select-filters.tsx b/apps/app/components/views/select-filters.tsx index c621241ca..91d872218 100644 --- a/apps/app/components/views/select-filters.tsx +++ b/apps/app/components/views/select-filters.tsx @@ -1,13 +1,16 @@ -import { useState } from "react"; +import { useState, useEffect } from "react"; import { useRouter } from "next/router"; import useSWR from "swr"; +// mobx +import { observer } from "mobx-react-lite"; +import { useMobxStore } from "lib/mobx/store-provider"; + // services import stateService from "services/state.service"; import projectService from "services/project.service"; -import issuesService from "services/issues.service"; // components import { DueDateFilterModal } from "components/core"; // ui @@ -20,7 +23,7 @@ import { checkIfArraysHaveSameElements } from "helpers/array.helper"; // types import { IIssueFilterOptions, IQuery } from "types"; // fetch-keys -import { PROJECT_ISSUE_LABELS, PROJECT_MEMBERS, STATES_LIST } from "constants/fetch-keys"; +import { PROJECT_MEMBERS, STATES_LIST } from "constants/fetch-keys"; // constants import { PRIORITIES } from "constants/project"; import { DUE_DATES } from "constants/due-dates"; @@ -32,17 +35,17 @@ type Props = { height?: "sm" | "md" | "rg" | "lg"; }; -export const SelectFilters: React.FC = ({ - filters, - onSelect, - direction = "right", - height = "md", -}) => { +export const SelectFilters: React.FC = observer((props) => { + const { filters, onSelect, direction = "right", height = "md" } = props; + const [isDueDateFilterModalOpen, setIsDueDateFilterModalOpen] = useState(false); const router = useRouter(); const { workspaceSlug, projectId } = router.query; + const { label: labelStore } = useMobxStore(); + const { labels, loadLabels } = labelStore; + const { data: states } = useSWR( workspaceSlug && projectId ? STATES_LIST(projectId as string) : null, workspaceSlug && projectId @@ -58,12 +61,9 @@ export const SelectFilters: React.FC = ({ : null ); - const { data: issueLabels } = useSWR( - projectId ? PROJECT_ISSUE_LABELS(projectId.toString()) : null, - workspaceSlug && projectId - ? () => issuesService.getIssueLabels(workspaceSlug as string, projectId.toString()) - : null - ); + useEffect(() => { + if (workspaceSlug && projectId) loadLabels(workspaceSlug.toString(), projectId.toString()); + }, [workspaceSlug, projectId, loadLabels]); return ( <> @@ -160,9 +160,9 @@ export const SelectFilters: React.FC = ({ { id: "labels", label: "Labels", - value: issueLabels, + value: labels, hasChildren: true, - children: issueLabels?.map((label) => ({ + children: labels?.map((label) => ({ id: label.id, label: (
@@ -216,4 +216,4 @@ export const SelectFilters: React.FC = ({ /> ); -}; +}); diff --git a/apps/app/pages/[workspaceSlug]/projects/[projectId]/pages/[pageId].tsx b/apps/app/pages/[workspaceSlug]/projects/[projectId]/pages/[pageId].tsx index 0502e9e87..6dbfe1a4d 100644 --- a/apps/app/pages/[workspaceSlug]/projects/[projectId]/pages/[pageId].tsx +++ b/apps/app/pages/[workspaceSlug]/projects/[projectId]/pages/[pageId].tsx @@ -4,6 +4,10 @@ import { useRouter } from "next/router"; import useSWR, { mutate } from "swr"; +// mobx +import { observer } from "mobx-react-lite"; +import { useMobxStore } from "lib/mobx/store-provider"; + // react-hook-form import { useForm } from "react-hook-form"; // headless ui @@ -16,7 +20,6 @@ import StrictModeDroppable from "components/dnd/StrictModeDroppable"; // services import projectService from "services/project.service"; import pagesService from "services/pages.service"; -import issuesService from "services/issues.service"; // hooks import useToast from "hooks/use-toast"; import useUser from "hooks/use-user"; @@ -56,13 +59,12 @@ import { copyTextToClipboard, truncateText } from "helpers/string.helper"; import { orderArrayBy } from "helpers/array.helper"; // types import type { NextPage } from "next"; -import { IIssueLabels, IPage, IPageBlock, IProjectMember } from "types"; +import { IPage, IPageBlock, IProjectMember } from "types"; // fetch-keys import { PAGE_BLOCKS_LIST, PAGE_DETAILS, PROJECT_DETAILS, - PROJECT_ISSUE_LABELS, USER_PROJECT_VIEW, } from "constants/fetch-keys"; @@ -80,6 +82,9 @@ const SinglePage: NextPage = () => { const { user } = useUser(); + const { label: labelStore } = useMobxStore(); + const { labels, loadLabels } = labelStore; + const { handleSubmit, reset, watch, setValue } = useForm({ defaultValues: { name: "" }, }); @@ -115,13 +120,6 @@ const SinglePage: NextPage = () => { : null ); - const { data: labels } = useSWR( - workspaceSlug && projectId ? PROJECT_ISSUE_LABELS(projectId as string) : null, - workspaceSlug && projectId - ? () => issuesService.getIssueLabels(workspaceSlug as string, projectId as string) - : null - ); - const { data: memberDetails } = useSWR( workspaceSlug && projectId ? USER_PROJECT_VIEW(projectId.toString()) : null, workspaceSlug && projectId @@ -129,6 +127,10 @@ const SinglePage: NextPage = () => { : null ); + useEffect(() => { + if (workspaceSlug && projectId) loadLabels(workspaceSlug.toString(), projectId.toString()); + }, [workspaceSlug, projectId, loadLabels]); + const updatePage = async (formData: IPage) => { if (!workspaceSlug || !projectId || !pageId) return; @@ -691,4 +693,4 @@ const SinglePage: NextPage = () => { ); }; -export default SinglePage; +export default observer(SinglePage);