import { useRouter } from "next/router"; import { TIssue, TIssueGroupByOptions, TIssueOrderByOptions } from "@plane/types"; import { TOAST_TYPE, setToast } from "@plane/ui"; import { GroupDropLocation, handleGroupDragDrop } from "@/components/issues/issue-layouts/utils"; import { EIssuesStoreType } from "@/constants/issue"; import { ISSUE_FILTER_DEFAULT_DATA } from "@/store/issue/helpers/issue-helper.store"; import { useIssueDetail, useIssues } from "./store"; import { useIssuesActions } from "./use-issues-actions"; type DNDStoreType = | EIssuesStoreType.PROJECT | EIssuesStoreType.MODULE | EIssuesStoreType.CYCLE | EIssuesStoreType.PROJECT_VIEW | EIssuesStoreType.DRAFT | EIssuesStoreType.PROFILE | EIssuesStoreType.ARCHIVED; export const useGroupIssuesDragNDrop = ( storeType: DNDStoreType, orderBy: TIssueOrderByOptions | undefined, groupBy: TIssueGroupByOptions | undefined, subGroupBy?: TIssueGroupByOptions ) => { const router = useRouter(); const { workspaceSlug } = router.query; const { issue: { getIssueById }, } = useIssueDetail(); const { updateIssue } = useIssuesActions(storeType); const { issues: { getIssueIds }, } = useIssues(storeType); const { issues: { addCycleToIssue, removeCycleFromIssue }, } = useIssues(EIssuesStoreType.CYCLE); const { issues: { changeModulesInIssue }, } = useIssues(EIssuesStoreType.MODULE); /** * update Issue on Drop, checks if modules or cycles are changed and then calls appropriate functions * @param projectId * @param issueId * @param data * @param issueUpdates */ const updateIssueOnDrop = async ( projectId: string, issueId: string, data: Partial, issueUpdates: { [groupKey: string]: { ADD: string[]; REMOVE: string[]; }; } ) => { const errorToastProps = { type: TOAST_TYPE.ERROR, title: "Error!", message: "Error while updating issue", }; const moduleKey = ISSUE_FILTER_DEFAULT_DATA["module"]; const cycleKey = ISSUE_FILTER_DEFAULT_DATA["cycle"]; const isModuleChanged = Object.keys(data).includes(moduleKey); const isCycleChanged = Object.keys(data).includes(cycleKey); if (isCycleChanged && workspaceSlug) { if (data[cycleKey]) { addCycleToIssue(workspaceSlug.toString(), projectId, data[cycleKey], issueId).catch(() => setToast(errorToastProps) ); } else { removeCycleFromIssue(workspaceSlug.toString(), projectId, issueId).catch(() => setToast(errorToastProps)); } delete data[cycleKey]; } if (isModuleChanged && workspaceSlug && issueUpdates[moduleKey]) { changeModulesInIssue( workspaceSlug.toString(), projectId, issueId, issueUpdates[moduleKey].ADD, issueUpdates[moduleKey].REMOVE ).catch(() => setToast(errorToastProps)); delete data[moduleKey]; } updateIssue && updateIssue(projectId, issueId, data).catch(() => setToast(errorToastProps)); }; const handleOnDrop = async (source: GroupDropLocation, destination: GroupDropLocation) => { if ( source.columnId && destination.columnId && destination.columnId === source.columnId && destination.id === source.id ) return; await handleGroupDragDrop( source, destination, getIssueById, getIssueIds, updateIssueOnDrop, groupBy, subGroupBy, orderBy !== "sort_order" ).catch((err) => { setToast({ title: "Error!", type: TOAST_TYPE.ERROR, message: err?.detail ?? "Failed to perform this action", }); }); }; return handleOnDrop; };