From d6f3c2515a24d27847a5bce47fe026d94254c5b8 Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Date: Wed, 26 Jul 2023 23:20:44 +0530 Subject: [PATCH] fix: fetch states only when the dropdown is opened (#1684) --- .../automation/auto-close-automation.tsx | 7 +++---- .../issue/change-issue-state.tsx | 2 +- apps/app/components/core/views/all-views.tsx | 2 +- apps/app/components/core/views/issues-view.tsx | 17 +++++++++++------ apps/app/components/issues/select/state.tsx | 4 ++-- .../components/issues/sidebar-select/state.tsx | 2 +- .../app/components/issues/view-select/state.tsx | 11 +++++------ apps/app/components/views/form.tsx | 2 +- apps/app/components/views/select-filters.tsx | 4 ++-- apps/app/helpers/state.helper.ts | 15 ++++++++++++--- apps/app/hooks/use-issues-view.tsx | 15 ++++++++------- .../projects/[projectId]/settings/states.tsx | 8 ++++---- 12 files changed, 51 insertions(+), 38 deletions(-) diff --git a/apps/app/components/automation/auto-close-automation.tsx b/apps/app/components/automation/auto-close-automation.tsx index 3023328e7..3e71b8329 100644 --- a/apps/app/components/automation/auto-close-automation.tsx +++ b/apps/app/components/automation/auto-close-automation.tsx @@ -37,8 +37,7 @@ export const AutoCloseAutomation: React.FC = ({ projectDetails, handleCha ? () => stateService.getStates(workspaceSlug as string, projectId as string) : null ); - - const states = getStatesList(stateGroups ?? {}); + const states = getStatesList(stateGroups); const options = states ?.filter((state) => state.group === "cancelled") @@ -53,14 +52,14 @@ export const AutoCloseAutomation: React.FC = ({ projectDetails, handleCha ), })); - const multipleOptions = options.length > 1; + const multipleOptions = (options ?? []).length > 1; const defaultState = stateGroups && stateGroups.cancelled ? stateGroups.cancelled[0].id : null; const selectedOption = states?.find( (s) => s.id === projectDetails?.default_state ?? defaultState ); - const currentDefaultState = states.find((s) => s.id === defaultState); + const currentDefaultState = states?.find((s) => s.id === defaultState); const initialValues: Partial = { close_in: 1, diff --git a/apps/app/components/command-palette/issue/change-issue-state.tsx b/apps/app/components/command-palette/issue/change-issue-state.tsx index 00c9745be..30e2cdb77 100644 --- a/apps/app/components/command-palette/issue/change-issue-state.tsx +++ b/apps/app/components/command-palette/issue/change-issue-state.tsx @@ -34,7 +34,7 @@ export const ChangeIssueState: React.FC = ({ setIsPaletteOpen, issue, use ? () => stateService.getStates(workspaceSlug as string, projectId as string) : null ); - const states = getStatesList(stateGroups ?? {}); + const states = getStatesList(stateGroups); const submitChanges = useCallback( async (formData: Partial) => { diff --git a/apps/app/components/core/views/all-views.tsx b/apps/app/components/core/views/all-views.tsx index b37cb433b..60d3c88f6 100644 --- a/apps/app/components/core/views/all-views.tsx +++ b/apps/app/components/core/views/all-views.tsx @@ -75,7 +75,7 @@ export const AllViews: React.FC = ({ ? () => stateService.getStates(workspaceSlug as string, projectId as string) : null ); - const states = getStatesList(stateGroups ?? {}); + const states = getStatesList(stateGroups); const handleTrashBox = useCallback( (isDragging: boolean) => { diff --git a/apps/app/components/core/views/issues-view.tsx b/apps/app/components/core/views/issues-view.tsx index a84aab1d2..b2183f4db 100644 --- a/apps/app/components/core/views/issues-view.tsx +++ b/apps/app/components/core/views/issues-view.tsx @@ -29,7 +29,7 @@ import { PlusIcon } from "@heroicons/react/24/outline"; import { getStatesList } from "helpers/state.helper"; import { orderArrayBy } from "helpers/array.helper"; // types -import { IIssue, IIssueFilterOptions } from "types"; +import { IIssue, IIssueFilterOptions, IState } from "types"; // fetch-keys import { CYCLE_DETAILS, @@ -96,7 +96,7 @@ export const IssuesView: React.FC = ({ ? () => stateService.getStates(workspaceSlug as string, projectId as string) : null ); - const states = getStatesList(stateGroups ?? {}); + const states = getStatesList(stateGroups); const { data: labels } = useSWR( workspaceSlug && projectId ? PROJECT_ISSUE_LABELS(projectId.toString()) : null, @@ -184,7 +184,10 @@ export const IssuesView: React.FC = ({ // dragged item(or issue) if (selectedGroup === "priority") draggedItem.priority = destinationGroup; - else if (selectedGroup === "state") draggedItem.state = destinationGroup; + else if (selectedGroup === "state") { + draggedItem.state = destinationGroup; + draggedItem.state_detail = states?.find((s) => s.id === destinationGroup) as IState; + } } const sourceGroup = source.droppableId; // source group id @@ -200,8 +203,8 @@ export const IssuesView: React.FC = ({ (prevData) => { if (!prevData) return prevData; - const sourceGroupArray = prevData[sourceGroup]; - const destinationGroupArray = groupedByIssues[destinationGroup]; + const sourceGroupArray = [...groupedByIssues[sourceGroup]]; + const destinationGroupArray = [...groupedByIssues[destinationGroup]]; sourceGroupArray.splice(source.index, 1); destinationGroupArray.splice(destination.index, 0, draggedItem); @@ -229,7 +232,9 @@ export const IssuesView: React.FC = ({ user ) .then((response) => { - const sourceStateBeforeDrag = states.find((state) => state.name === source.droppableId); + const sourceStateBeforeDrag = states?.find( + (state) => state.name === source.droppableId + ); if ( sourceStateBeforeDrag?.group !== "completed" && diff --git a/apps/app/components/issues/select/state.tsx b/apps/app/components/issues/select/state.tsx index 99c4140b2..d62daba76 100644 --- a/apps/app/components/issues/select/state.tsx +++ b/apps/app/components/issues/select/state.tsx @@ -34,7 +34,7 @@ export const IssueStateSelect: React.FC = ({ setIsOpen, value, onChange, ? () => stateService.getStates(workspaceSlug as string, projectId) : null ); - const states = getStatesList(stateGroups ?? {}); + const states = getStatesList(stateGroups); const options = states?.map((state) => ({ value: state.id, @@ -48,7 +48,7 @@ export const IssueStateSelect: React.FC = ({ setIsOpen, value, onChange, })); const selectedOption = states?.find((s) => s.id === value); - const currentDefaultState = states.find((s) => s.default); + const currentDefaultState = states?.find((s) => s.default); return ( = ({ ? () => stateService.getStates(workspaceSlug as string, projectId as string) : null ); - const states = getStatesList(stateGroups ?? {}); + const states = getStatesList(stateGroups); const selectedState = states?.find((s) => s.id === value); diff --git a/apps/app/components/issues/view-select/state.tsx b/apps/app/components/issues/view-select/state.tsx index 2de7fe52a..7f5844697 100644 --- a/apps/app/components/issues/view-select/state.tsx +++ b/apps/app/components/issues/view-select/state.tsx @@ -52,7 +52,7 @@ export const ViewStateSelect: React.FC = ({ ? () => stateService.getStates(workspaceSlug as string, issue.project) : null ); - const states = getStatesList(stateGroups ?? {}); + const states = getStatesList(stateGroups); const options = states?.map((state) => ({ value: state.id, @@ -88,11 +88,13 @@ export const ViewStateSelect: React.FC = ({ className={className} value={issue.state} onChange={(data: string) => { + const oldState = states?.find((s) => s.id === issue.state); + const newState = states?.find((s) => s.id === data); + partialUpdateIssue( { state: data, - priority: issue.priority, - target_date: issue.target_date, + state_detail: newState, }, issue ); @@ -109,9 +111,6 @@ export const ViewStateSelect: React.FC = ({ user ); - const oldState = states.find((s) => s.id === issue.state); - const newState = states.find((s) => s.id === data); - if (oldState?.group !== "completed" && newState?.group !== "completed") { trackEventServices.trackIssueMarkedAsDoneEvent( { diff --git a/apps/app/components/views/form.tsx b/apps/app/components/views/form.tsx index ec6fadd0a..7001bbab7 100644 --- a/apps/app/components/views/form.tsx +++ b/apps/app/components/views/form.tsx @@ -67,7 +67,7 @@ export const ViewForm: React.FC = ({ ? () => stateService.getStates(workspaceSlug as string, projectId as string) : null ); - const states = getStatesList(stateGroups ?? {}); + const states = getStatesList(stateGroups); const { data: labels } = useSWR( workspaceSlug && projectId && (filters.labels ?? []).length > 0 diff --git a/apps/app/components/views/select-filters.tsx b/apps/app/components/views/select-filters.tsx index c76060e13..2397a18a8 100644 --- a/apps/app/components/views/select-filters.tsx +++ b/apps/app/components/views/select-filters.tsx @@ -49,7 +49,7 @@ export const SelectFilters: React.FC = ({ ? () => stateService.getStates(workspaceSlug as string, projectId as string) : null ); - const statesList = getStatesList(states ?? {}); + const statesList = getStatesList(states); const { data: members } = useSWR( projectId ? PROJECT_MEMBERS(projectId as string) : null, @@ -103,7 +103,7 @@ export const SelectFilters: React.FC = ({ label: "State", value: statesList, hasChildren: true, - children: statesList.map((state) => ({ + children: statesList?.map((state) => ({ id: state.id, label: (
diff --git a/apps/app/helpers/state.helper.ts b/apps/app/helpers/state.helper.ts index 512da4f19..edf740c10 100644 --- a/apps/app/helpers/state.helper.ts +++ b/apps/app/helpers/state.helper.ts @@ -1,16 +1,25 @@ // types import { IState, IStateResponse } from "types"; -export const orderStateGroups = (unorderedStateGroups: IStateResponse) => - Object.assign( +export const orderStateGroups = ( + unorderedStateGroups: IStateResponse | undefined +): IStateResponse | undefined => { + if (!unorderedStateGroups) return undefined; + + return Object.assign( { backlog: [], unstarted: [], started: [], completed: [], cancelled: [] }, unorderedStateGroups ); +}; + +export const getStatesList = (stateGroups: IStateResponse | undefined): IState[] | undefined => { + if (!stateGroups) return undefined; -export const getStatesList = (stateGroups: any): IState[] => { // order the unordered state groups first const orderedStateGroups = orderStateGroups(stateGroups); + if (!orderedStateGroups) return undefined; + // extract states from the groups and return them return Object.keys(orderedStateGroups) .map((group) => [...orderedStateGroups[group].map((state: IState) => state)]) diff --git a/apps/app/hooks/use-issues-view.tsx b/apps/app/hooks/use-issues-view.tsx index 85c756efc..ef9c14918 100644 --- a/apps/app/hooks/use-issues-view.tsx +++ b/apps/app/hooks/use-issues-view.tsx @@ -125,21 +125,22 @@ const useIssuesView = () => { ? () => stateService.getStates(workspaceSlug as string, projectId as string) : null ); - const statesList = getStatesList(states ?? {}); - const activeStatesList = statesList.filter( + const statesList = getStatesList(states); + const activeStatesList = statesList?.filter( (state) => state.group === "started" || state.group === "unstarted" ); - const backlogStatesList = statesList.filter((state) => state.group === "backlog"); + const backlogStatesList = statesList?.filter((state) => state.group === "backlog"); const stateIds = filters && filters?.type === "active" - ? activeStatesList.map((state) => state.id) + ? activeStatesList?.map((state) => state.id) : filters?.type === "backlog" - ? backlogStatesList.map((state) => state.id) - : statesList.map((state) => state.id); + ? backlogStatesList?.map((state) => state.id) + : statesList?.map((state) => state.id); const filteredStateIds = - filters && filters?.state ? stateIds.filter((s) => filters.state?.includes(s)) : stateIds; + (filters && filters?.state ? stateIds?.filter((s) => filters.state?.includes(s)) : stateIds) ?? + []; const emptyStatesObject: { [key: string]: [] } = {}; for (let i = 0; i < filteredStateIds.length; i++) { diff --git a/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/states.tsx b/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/states.tsx index fa71bb8c1..0b7b0fb72 100644 --- a/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/states.tsx +++ b/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/states.tsx @@ -49,8 +49,8 @@ const StatesSettings: NextPage = () => { ? () => stateService.getStates(workspaceSlug as string, projectId as string) : null ); - const orderedStateGroups = orderStateGroups(states ?? {}); - const statesList = getStatesList(orderedStateGroups ?? {}); + const orderedStateGroups = orderStateGroups(states); + const statesList = getStatesList(orderedStateGroups); return ( <> @@ -79,7 +79,7 @@ const StatesSettings: NextPage = () => {

Manage the states of this project.

- {states && projectDetails ? ( + {states && projectDetails && orderedStateGroups ? ( Object.keys(orderedStateGroups).map((key) => { if (orderedStateGroups[key].length !== 0) return ( @@ -114,7 +114,7 @@ const StatesSettings: NextPage = () => { key={state.id} index={index} state={state} - statesList={statesList} + statesList={statesList ?? []} handleEditState={() => setSelectedState(state.id)} handleDeleteState={() => setSelectDeleteState(state.id)} user={user}