plane/web/hooks/use-group-dragndrop.ts
2024-06-10 13:36:10 +05:30

126 lines
3.6 KiB
TypeScript

"use client";
import { useParams } from "next/navigation";
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 { workspaceSlug } = useParams();
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<TIssue>,
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;
};