From 78c7a016e30447d8c258c811b3bffa0dc61eb687 Mon Sep 17 00:00:00 2001 From: Rahul R Date: Mon, 22 Jan 2024 11:54:04 +0530 Subject: [PATCH] refactor issue dropdown logic to help work properly with issues on global level --- web/components/core/activity.tsx | 4 +- web/components/dropdowns/estimate.tsx | 11 +-- .../dropdowns/member/project-member.tsx | 8 +- web/components/dropdowns/state.tsx | 7 +- web/components/headers/cycle-issues.tsx | 4 +- web/components/headers/global-issues.tsx | 4 +- web/components/headers/module-issues.tsx | 4 +- .../headers/project-archived-issues.tsx | 4 +- .../headers/project-draft-issues.tsx | 4 +- web/components/headers/project-issues.tsx | 4 +- .../headers/project-view-issues.tsx | 4 +- .../issues/issue-detail/label/root.tsx | 4 +- .../label/select/label-select.tsx | 8 +- .../applied-filters/roots/archived-issue.tsx | 4 +- .../applied-filters/roots/cycle-root.tsx | 4 +- .../applied-filters/roots/draft-issue.tsx | 4 +- .../roots/global-view-root.tsx | 4 +- .../applied-filters/roots/module-root.tsx | 4 +- .../roots/profile-issues-root.tsx | 7 +- .../applied-filters/roots/project-root.tsx | 4 +- .../roots/project-view-root.tsx | 4 +- .../issues/issue-layouts/kanban/default.tsx | 4 +- .../issues/issue-layouts/kanban/swimlanes.tsx | 12 +-- .../issues/issue-layouts/list/default.tsx | 4 +- .../issue-layouts/properties/labels.tsx | 13 +-- .../roots/all-issue-layout-root.tsx | 4 +- web/components/issues/issue-layouts/utils.tsx | 12 +-- web/components/issues/issue-modal/form.tsx | 18 ++-- web/components/issues/issue-modal/modal.tsx | 9 +- web/components/issues/select/label.tsx | 10 +- .../issues/view-select/estimate.tsx | 2 +- web/components/labels/create-label-modal.tsx | 4 +- .../labels/create-update-label-inline.tsx | 4 +- web/components/labels/delete-label-modal.tsx | 4 +- web/components/labels/labels-list-modal.tsx | 4 +- .../labels/project-setting-label-item.tsx | 4 +- .../labels/project-setting-label-list.tsx | 4 +- .../profile/profile-issues-filter.tsx | 4 +- web/components/views/form.tsx | 4 +- web/components/workspace/views/form.tsx | 4 +- web/hooks/store/use-label.ts | 6 +- web/hooks/use-worskspace-issue-properties.ts | 28 ++++++ web/layouts/auth-layout/project-wrapper.tsx | 4 +- web/layouts/auth-layout/workspace-wrapper.tsx | 8 -- web/package.json | 1 + .../project/project-estimate.service.ts | 8 ++ web/services/project/project-state.service.ts | 8 ++ web/store/estimate.store.ts | 91 ++++++++++++------- .../project-label.store.ts => label.store.ts} | 61 ++++++++++--- web/store/label/index.ts | 42 --------- web/store/label/workspace-label.store.ts | 64 ------------- web/store/member/project-member.store.ts | 12 +-- web/store/project/project.store.ts | 6 +- web/store/root.store.ts | 6 +- web/store/state.store.ts | 37 ++++++-- yarn.lock | 27 +++--- 56 files changed, 280 insertions(+), 358 deletions(-) create mode 100644 web/hooks/use-worskspace-issue-properties.ts rename web/store/{label/project-label.store.ts => label.store.ts} (76%) delete mode 100644 web/store/label/index.ts delete mode 100644 web/store/label/workspace-label.store.ts diff --git a/web/components/core/activity.tsx b/web/components/core/activity.tsx index 99396dda2..e49205459 100644 --- a/web/components/core/activity.tsx +++ b/web/components/core/activity.tsx @@ -72,9 +72,7 @@ const UserLink = ({ activity }: { activity: IIssueActivity }) => { const LabelPill = observer(({ labelId, workspaceSlug }: { labelId: string; workspaceSlug: string }) => { // store hooks - const { - workspace: { workspaceLabels, fetchWorkspaceLabels }, - } = useLabel(); + const { workspaceLabels, fetchWorkspaceLabels } = useLabel(); useEffect(() => { if (!workspaceLabels) fetchWorkspaceLabels(workspaceSlug); diff --git a/web/components/dropdowns/estimate.tsx b/web/components/dropdowns/estimate.tsx index 9138b2bea..241a695fa 100644 --- a/web/components/dropdowns/estimate.tsx +++ b/web/components/dropdowns/estimate.tsx @@ -158,17 +158,12 @@ export const EstimateDropdown: React.FC = observer((props) => { const filteredOptions = query === "" ? options : options?.filter((o) => o.query.toLowerCase().includes(query.toLowerCase())); - // fetch cycles of the project if not already present in the store - useEffect(() => { - if (!workspaceSlug) return; - - if (!activeEstimate) fetchProjectEstimates(workspaceSlug, projectId); - }, [activeEstimate, fetchProjectEstimates, projectId, workspaceSlug]); - - const selectedEstimate = value !== null ? getEstimatePointValue(value) : null; + const selectedEstimate = value !== null ? getEstimatePointValue(value, projectId) : null; const openDropdown = () => { setIsOpen(true); + + if (!activeEstimate && workspaceSlug) fetchProjectEstimates(workspaceSlug, projectId); if (referenceElement) referenceElement.focus(); }; const closeDropdown = () => setIsOpen(false); diff --git a/web/components/dropdowns/member/project-member.tsx b/web/components/dropdowns/member/project-member.tsx index 1e6856274..581978d9d 100644 --- a/web/components/dropdowns/member/project-member.tsx +++ b/web/components/dropdowns/member/project-member.tsx @@ -93,14 +93,10 @@ export const ProjectMemberDropdown: React.FC = observer((props) => { }; if (multiple) comboboxProps.multiple = true; - useEffect(() => { - if (!workspaceSlug) return; - - if (!projectMemberIds) fetchProjectMembers(workspaceSlug, projectId); - }, [fetchProjectMembers, projectId, projectMemberIds, workspaceSlug]); - const openDropdown = () => { setIsOpen(true); + + if (!projectMemberIds && workspaceSlug) fetchProjectMembers(workspaceSlug, projectId); if (referenceElement) referenceElement.focus(); }; const closeDropdown = () => setIsOpen(false); diff --git a/web/components/dropdowns/state.tsx b/web/components/dropdowns/state.tsx index ba48af4bd..25073901a 100644 --- a/web/components/dropdowns/state.tsx +++ b/web/components/dropdowns/state.tsx @@ -142,17 +142,12 @@ export const StateDropdown: React.FC = observer((props) => { const filteredOptions = query === "" ? options : options?.filter((o) => o.query.toLowerCase().includes(query.toLowerCase())); - // fetch states of the project if not already present in the store - useEffect(() => { - if (!workspaceSlug) return; - - if (!statesList) fetchProjectStates(workspaceSlug, projectId); - }, [fetchProjectStates, projectId, statesList, workspaceSlug]); const selectedState = getStateById(value); const openDropdown = () => { setIsOpen(true); + if (!statesList && workspaceSlug) fetchProjectStates(workspaceSlug, projectId); if (referenceElement) referenceElement.focus(); }; const closeDropdown = () => setIsOpen(false); diff --git a/web/components/headers/cycle-issues.tsx b/web/components/headers/cycle-issues.tsx index a616e4470..f97be5244 100644 --- a/web/components/headers/cycle-issues.tsx +++ b/web/components/headers/cycle-issues.tsx @@ -75,9 +75,7 @@ export const CycleIssuesHeader: React.FC = observer(() => { } = useUser(); const { currentProjectDetails } = useProject(); const { projectStates } = useProjectState(); - const { - project: { projectLabels }, - } = useLabel(); + const { projectLabels } = useLabel(); const { project: { projectMemberIds }, } = useMember(); diff --git a/web/components/headers/global-issues.tsx b/web/components/headers/global-issues.tsx index aa9a32bc9..b6aeda154 100644 --- a/web/components/headers/global-issues.tsx +++ b/web/components/headers/global-issues.tsx @@ -45,9 +45,7 @@ export const GlobalIssuesHeader: React.FC = observer((props) => { const { membership: { currentWorkspaceRole }, } = useUser(); - const { - workspace: { workspaceLabels }, - } = useLabel(); + const { workspaceLabels } = useLabel(); const { workspace: { workspaceMemberIds }, } = useMember(); diff --git a/web/components/headers/module-issues.tsx b/web/components/headers/module-issues.tsx index 9cfc9c1b3..3b60e69ab 100644 --- a/web/components/headers/module-issues.tsx +++ b/web/components/headers/module-issues.tsx @@ -77,9 +77,7 @@ export const ModuleIssuesHeader: React.FC = observer(() => { membership: { currentProjectRole }, } = useUser(); const { currentProjectDetails } = useProject(); - const { - project: { projectLabels }, - } = useLabel(); + const { projectLabels } = useLabel(); const { projectStates } = useProjectState(); const { project: { projectMemberIds }, diff --git a/web/components/headers/project-archived-issues.tsx b/web/components/headers/project-archived-issues.tsx index e20687ec0..76eaa2eb6 100644 --- a/web/components/headers/project-archived-issues.tsx +++ b/web/components/headers/project-archived-issues.tsx @@ -25,9 +25,7 @@ export const ProjectArchivedIssuesHeader: FC = observer(() => { } = useIssues(EIssuesStoreType.ARCHIVED); const { currentProjectDetails } = useProject(); const { projectStates } = useProjectState(); - const { - project: { projectLabels }, - } = useLabel(); + const { projectLabels } = useLabel(); const { project: { projectMemberIds }, } = useMember(); diff --git a/web/components/headers/project-draft-issues.tsx b/web/components/headers/project-draft-issues.tsx index dcbfbe0a4..16a6b7691 100644 --- a/web/components/headers/project-draft-issues.tsx +++ b/web/components/headers/project-draft-issues.tsx @@ -22,9 +22,7 @@ export const ProjectDraftIssueHeader: FC = observer(() => { } = useIssues(EIssuesStoreType.DRAFT); const { currentProjectDetails } = useProject(); const { projectStates } = useProjectState(); - const { - project: { projectLabels }, - } = useLabel(); + const { projectLabels } = useLabel(); const { project: { projectMemberIds }, } = useMember(); diff --git a/web/components/headers/project-issues.tsx b/web/components/headers/project-issues.tsx index e79022570..c756b4410 100644 --- a/web/components/headers/project-issues.tsx +++ b/web/components/headers/project-issues.tsx @@ -42,9 +42,7 @@ export const ProjectIssuesHeader: React.FC = observer(() => { } = useUser(); const { currentProjectDetails } = useProject(); const { projectStates } = useProjectState(); - const { - project: { projectLabels }, - } = useLabel(); + const { projectLabels } = useLabel(); const activeLayout = issueFilters?.displayFilters?.layout; diff --git a/web/components/headers/project-view-issues.tsx b/web/components/headers/project-view-issues.tsx index 48e38491b..14d3996b1 100644 --- a/web/components/headers/project-view-issues.tsx +++ b/web/components/headers/project-view-issues.tsx @@ -49,9 +49,7 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => { const { currentProjectDetails } = useProject(); const { projectViewIds, getViewById } = useProjectView(); const { projectStates } = useProjectState(); - const { - project: { projectLabels }, - } = useLabel(); + const { projectLabels } = useLabel(); const { project: { projectMemberIds }, } = useMember(); diff --git a/web/components/issues/issue-detail/label/root.tsx b/web/components/issues/issue-detail/label/root.tsx index 93e303f61..2ef9bec6e 100644 --- a/web/components/issues/issue-detail/label/root.tsx +++ b/web/components/issues/issue-detail/label/root.tsx @@ -24,9 +24,7 @@ export const IssueLabel: FC = observer((props) => { const { workspaceSlug, projectId, issueId, disabled = false } = props; // hooks const { updateIssue } = useIssueDetail(); - const { - project: { createLabel }, - } = useLabel(); + const { createLabel } = useLabel(); const { setToastAlert } = useToast(); const labelOperations: TLabelOperations = useMemo( diff --git a/web/components/issues/issue-detail/label/select/label-select.tsx b/web/components/issues/issue-detail/label/select/label-select.tsx index c553ef333..4af089d5e 100644 --- a/web/components/issues/issue-detail/label/select/label-select.tsx +++ b/web/components/issues/issue-detail/label/select/label-select.tsx @@ -20,9 +20,7 @@ export const IssueLabelSelect: React.FC = observer((props) => const { issue: { getIssueById }, } = useIssueDetail(); - const { - project: { fetchProjectLabels, projectLabels }, - } = useLabel(); + const { fetchProjectLabels, getProjectLabels } = useLabel(); // states const [referenceElement, setReferenceElement] = useState(null); const [popperElement, setPopperElement] = useState(null); @@ -30,10 +28,12 @@ export const IssueLabelSelect: React.FC = observer((props) => const [query, setQuery] = useState(""); const issue = getIssueById(issueId); + const projectLabels = getProjectLabels(projectId); const fetchLabels = () => { setIsLoading(true); - if (workspaceSlug && projectId) fetchProjectLabels(workspaceSlug, projectId).then(() => setIsLoading(false)); + if (!projectLabels && workspaceSlug && projectId) + fetchProjectLabels(workspaceSlug, projectId).then(() => setIsLoading(false)); }; const options = (projectLabels ?? []).map((label) => ({ diff --git a/web/components/issues/issue-layouts/filters/applied-filters/roots/archived-issue.tsx b/web/components/issues/issue-layouts/filters/applied-filters/roots/archived-issue.tsx index b09bc7628..227dc025b 100644 --- a/web/components/issues/issue-layouts/filters/applied-filters/roots/archived-issue.tsx +++ b/web/components/issues/issue-layouts/filters/applied-filters/roots/archived-issue.tsx @@ -17,9 +17,7 @@ export const ArchivedIssueAppliedFiltersRoot: React.FC = observer(() => { const { issuesFilter: { issueFilters, updateFilters }, } = useIssues(EIssuesStoreType.ARCHIVED); - const { - project: { projectLabels }, - } = useLabel(); + const { projectLabels } = useLabel(); const { projectStates } = useProjectState(); // derived values const userFilters = issueFilters?.filters; diff --git a/web/components/issues/issue-layouts/filters/applied-filters/roots/cycle-root.tsx b/web/components/issues/issue-layouts/filters/applied-filters/roots/cycle-root.tsx index f402c9807..827382da7 100644 --- a/web/components/issues/issue-layouts/filters/applied-filters/roots/cycle-root.tsx +++ b/web/components/issues/issue-layouts/filters/applied-filters/roots/cycle-root.tsx @@ -21,9 +21,7 @@ export const CycleAppliedFiltersRoot: React.FC = observer(() => { issuesFilter: { issueFilters, updateFilters }, } = useIssues(EIssuesStoreType.CYCLE); - const { - project: { projectLabels }, - } = useLabel(); + const { projectLabels } = useLabel(); const { projectStates } = useProjectState(); // derived values const userFilters = issueFilters?.filters; diff --git a/web/components/issues/issue-layouts/filters/applied-filters/roots/draft-issue.tsx b/web/components/issues/issue-layouts/filters/applied-filters/roots/draft-issue.tsx index f650c0bd5..e9024afeb 100644 --- a/web/components/issues/issue-layouts/filters/applied-filters/roots/draft-issue.tsx +++ b/web/components/issues/issue-layouts/filters/applied-filters/roots/draft-issue.tsx @@ -16,9 +16,7 @@ export const DraftIssueAppliedFiltersRoot: React.FC = observer(() => { const { issuesFilter: { issueFilters, updateFilters }, } = useIssues(EIssuesStoreType.DRAFT); - const { - project: { projectLabels }, - } = useLabel(); + const { projectLabels } = useLabel(); const { projectStates } = useProjectState(); // derived values const userFilters = issueFilters?.filters; diff --git a/web/components/issues/issue-layouts/filters/applied-filters/roots/global-view-root.tsx b/web/components/issues/issue-layouts/filters/applied-filters/roots/global-view-root.tsx index 4d8ad5196..0dae3c8bd 100644 --- a/web/components/issues/issue-layouts/filters/applied-filters/roots/global-view-root.tsx +++ b/web/components/issues/issue-layouts/filters/applied-filters/roots/global-view-root.tsx @@ -25,9 +25,7 @@ export const GlobalViewsAppliedFiltersRoot = observer((props: Props) => { const { issuesFilter: { filters, updateFilters }, } = useIssues(EIssuesStoreType.GLOBAL); - const { - workspace: { workspaceLabels }, - } = useLabel(); + const { workspaceLabels } = useLabel(); const { globalViewMap, updateGlobalView } = useGlobalView(); const { membership: { currentWorkspaceRole }, diff --git a/web/components/issues/issue-layouts/filters/applied-filters/roots/module-root.tsx b/web/components/issues/issue-layouts/filters/applied-filters/roots/module-root.tsx index a9a7832c6..b823a4bd1 100644 --- a/web/components/issues/issue-layouts/filters/applied-filters/roots/module-root.tsx +++ b/web/components/issues/issue-layouts/filters/applied-filters/roots/module-root.tsx @@ -20,9 +20,7 @@ export const ModuleAppliedFiltersRoot: React.FC = observer(() => { const { issuesFilter: { issueFilters, updateFilters }, } = useIssues(EIssuesStoreType.MODULE); - const { - project: { projectLabels }, - } = useLabel(); + const { projectLabels } = useLabel(); const { projectStates } = useProjectState(); // derived values const userFilters = issueFilters?.filters; diff --git a/web/components/issues/issue-layouts/filters/applied-filters/roots/profile-issues-root.tsx b/web/components/issues/issue-layouts/filters/applied-filters/roots/profile-issues-root.tsx index 0c45c025e..7b483ef98 100644 --- a/web/components/issues/issue-layouts/filters/applied-filters/roots/profile-issues-root.tsx +++ b/web/components/issues/issue-layouts/filters/applied-filters/roots/profile-issues-root.tsx @@ -7,19 +7,20 @@ import { AppliedFiltersList } from "components/issues"; // types import { IIssueFilterOptions } from "@plane/types"; import { EIssueFilterType, EIssuesStoreType } from "constants/issue"; +import { useWorskspaceIssueProperties } from "hooks/use-worskspace-issue-properties"; export const ProfileIssuesAppliedFiltersRoot: React.FC = observer(() => { // router const router = useRouter(); const { workspaceSlug, userId } = router.query; + //swr hook for fetching issue properties + useWorskspaceIssueProperties(workspaceSlug); // store hooks const { issuesFilter: { issueFilters, updateFilters }, } = useIssues(EIssuesStoreType.PROFILE); - const { - workspace: { workspaceLabels }, - } = useLabel(); + const { workspaceLabels } = useLabel(); // derived values const userFilters = issueFilters?.filters; diff --git a/web/components/issues/issue-layouts/filters/applied-filters/roots/project-root.tsx b/web/components/issues/issue-layouts/filters/applied-filters/roots/project-root.tsx index 98ecf50b4..68b5e6727 100644 --- a/web/components/issues/issue-layouts/filters/applied-filters/roots/project-root.tsx +++ b/web/components/issues/issue-layouts/filters/applied-filters/roots/project-root.tsx @@ -19,9 +19,7 @@ export const ProjectAppliedFiltersRoot: React.FC = observer(() => { projectId: string; }; // store hooks - const { - project: { projectLabels }, - } = useLabel(); + const { projectLabels } = useLabel(); const { issuesFilter: { issueFilters, updateFilters }, } = useIssues(EIssuesStoreType.PROJECT); diff --git a/web/components/issues/issue-layouts/filters/applied-filters/roots/project-view-root.tsx b/web/components/issues/issue-layouts/filters/applied-filters/roots/project-view-root.tsx index c10de461a..0768064ec 100644 --- a/web/components/issues/issue-layouts/filters/applied-filters/roots/project-view-root.tsx +++ b/web/components/issues/issue-layouts/filters/applied-filters/roots/project-view-root.tsx @@ -23,9 +23,7 @@ export const ProjectViewAppliedFiltersRoot: React.FC = observer(() => { const { issuesFilter: { issueFilters, updateFilters }, } = useIssues(EIssuesStoreType.PROJECT_VIEW); - const { - project: { projectLabels }, - } = useLabel(); + const { projectLabels } = useLabel(); const { projectStates } = useProjectState(); const { viewMap, updateView } = useProjectView(); // derived values diff --git a/web/components/issues/issue-layouts/kanban/default.tsx b/web/components/issues/issue-layouts/kanban/default.tsx index 5b5dc3ead..48aa445c3 100644 --- a/web/components/issues/issue-layouts/kanban/default.tsx +++ b/web/components/issues/issue-layouts/kanban/default.tsx @@ -71,10 +71,10 @@ const GroupByKanBan: React.FC = observer((props) => { const member = useMember(); const project = useProject(); - const projectLabel = useLabel(); + const label = useLabel(); const projectState = useProjectState(); - const list = getGroupByColumns(group_by as GroupByColumnTypes, project, projectLabel, projectState, member); + const list = getGroupByColumns(group_by as GroupByColumnTypes, project, label, projectState, member); if (!list) return null; diff --git a/web/components/issues/issue-layouts/kanban/swimlanes.tsx b/web/components/issues/issue-layouts/kanban/swimlanes.tsx index 33126d17b..1b9f27828 100644 --- a/web/components/issues/issue-layouts/kanban/swimlanes.tsx +++ b/web/components/issues/issue-layouts/kanban/swimlanes.tsx @@ -208,17 +208,11 @@ export const KanBanSwimLanes: React.FC = observer((props) => { const member = useMember(); const project = useProject(); - const projectLabel = useLabel(); + const label = useLabel(); const projectState = useProjectState(); - const groupByList = getGroupByColumns(group_by as GroupByColumnTypes, project, projectLabel, projectState, member); - const subGroupByList = getGroupByColumns( - sub_group_by as GroupByColumnTypes, - project, - projectLabel, - projectState, - member - ); + const groupByList = getGroupByColumns(group_by as GroupByColumnTypes, project, label, projectState, member); + const subGroupByList = getGroupByColumns(sub_group_by as GroupByColumnTypes, project, label, projectState, member); if (!groupByList || !subGroupByList) return null; diff --git a/web/components/issues/issue-layouts/list/default.tsx b/web/components/issues/issue-layouts/list/default.tsx index df9103817..95e31b758 100644 --- a/web/components/issues/issue-layouts/list/default.tsx +++ b/web/components/issues/issue-layouts/list/default.tsx @@ -59,10 +59,10 @@ const GroupByList: React.FC = (props) => { // store hooks const member = useMember(); const project = useProject(); - const projectLabel = useLabel(); + const label = useLabel(); const projectState = useProjectState(); - const list = getGroupByColumns(group_by as GroupByColumnTypes, project, projectLabel, projectState, member, true); + const list = getGroupByColumns(group_by as GroupByColumnTypes, project, label, projectState, member, true); if (!list) return null; diff --git a/web/components/issues/issue-layouts/properties/labels.tsx b/web/components/issues/issue-layouts/properties/labels.tsx index 67295af0f..d38ff577b 100644 --- a/web/components/issues/issue-layouts/properties/labels.tsx +++ b/web/components/issues/issue-layouts/properties/labels.tsx @@ -53,13 +53,14 @@ export const IssuePropertyLabels: React.FC = observer((pro const { router: { workspaceSlug }, } = useApplication(); - const { - project: { fetchProjectLabels, projectLabels: storeLabels }, - } = useLabel(); + const { fetchProjectLabels, getProjectLabels } = useLabel(); - const fetchLabels = () => { + const storeLabels = getProjectLabels(projectId); + + const openDropDown = () => { setIsLoading(true); - if (workspaceSlug && projectId) fetchProjectLabels(workspaceSlug, projectId).then(() => setIsLoading(false)); + if (!storeLabels && workspaceSlug && projectId) + fetchProjectLabels(workspaceSlug, projectId).then(() => setIsLoading(false)); }; const { styles, attributes } = usePopper(referenceElement, popperElement, { @@ -182,7 +183,7 @@ export const IssuePropertyLabels: React.FC = observer((pro ? "cursor-pointer" : "cursor-pointer hover:bg-custom-background-80" } ${buttonClassName}`} - onClick={() => !storeLabels && fetchLabels()} + onClick={openDropDown} > {label} {!hideDropdownArrow && !disabled &&