fix: drag and drop function (#815)

* fix: kanban drag and drop

* fix: kanban board issue dnd mutation
This commit is contained in:
Aaryan Khandelwal 2023-04-13 19:09:55 +05:30 committed by GitHub
parent 6de94efc7d
commit 3fa6185b63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 123 additions and 44 deletions

View File

@ -108,7 +108,9 @@ export const SingleBoard: React.FC<Props> = ({
key={issue.id}
draggableId={issue.id}
index={index}
isDragDisabled={isNotAllowed || selectedGroup === "created_by"}
isDragDisabled={
isNotAllowed || selectedGroup === "created_by" || selectedGroup === "labels"
}
>
{(provided, snapshot) => (
<SingleBoardIssue

View File

@ -50,7 +50,6 @@ import {
MODULE_ISSUES_WITH_PARAMS,
PROJECT_ISSUES_LIST_WITH_PARAMS,
} from "constants/fetch-keys";
import useEstimateOption from "hooks/use-estimate-option";
type Props = {
type?: string;
@ -93,8 +92,6 @@ export const SingleBoardIssue: React.FC<Props> = ({
const { orderBy, params } = useIssuesView();
const { estimateValue } = useEstimateOption(issue.estimate_point);
const router = useRouter();
const { workspaceSlug, projectId, cycleId, moduleId } = router.query;
@ -113,7 +110,14 @@ export const SingleBoardIssue: React.FC<Props> = ({
>(
CYCLE_ISSUES_WITH_PARAMS(cycleId as string, params),
(prevData) =>
handleIssuesMutation(formData, groupTitle ?? "", selectedGroup, index, prevData),
handleIssuesMutation(
formData,
groupTitle ?? "",
selectedGroup,
index,
orderBy,
prevData
),
false
);
else if (moduleId)
@ -125,10 +129,17 @@ export const SingleBoardIssue: React.FC<Props> = ({
>(
MODULE_ISSUES_WITH_PARAMS(moduleId as string),
(prevData) =>
handleIssuesMutation(formData, groupTitle ?? "", selectedGroup, index, prevData),
handleIssuesMutation(
formData,
groupTitle ?? "",
selectedGroup,
index,
orderBy,
prevData
),
false
);
else
else {
mutate<
| {
[key: string]: IIssue[];
@ -136,10 +147,21 @@ export const SingleBoardIssue: React.FC<Props> = ({
| IIssue[]
>(
PROJECT_ISSUES_LIST_WITH_PARAMS(projectId as string, params),
(prevData) =>
handleIssuesMutation(formData, groupTitle ?? "", selectedGroup, index, prevData),
(prevData) => {
if (!prevData) return prevData;
return handleIssuesMutation(
formData,
groupTitle ?? "",
selectedGroup,
index,
orderBy,
prevData
);
},
false
);
}
issuesService
.patchIssue(workspaceSlug as string, projectId as string, issue.id, formData)
@ -156,7 +178,18 @@ export const SingleBoardIssue: React.FC<Props> = ({
console.log(error);
});
},
[workspaceSlug, projectId, cycleId, moduleId, issue, groupTitle, index, selectedGroup, params]
[
workspaceSlug,
projectId,
cycleId,
moduleId,
issue,
groupTitle,
index,
selectedGroup,
orderBy,
params,
]
);
const getStyle = (

View File

@ -48,6 +48,7 @@ import {
} from "constants/fetch-keys";
// image
import emptyCycle from "public/empty-state/empty-cycle.svg";
import { orderArrayBy } from "helpers/array.helper";
type Props = {
type?: "issue" | "cycle" | "module";
@ -208,8 +209,8 @@ export const IssuesView: React.FC<Props> = ({
return {
...prevData,
[sourceGroup]: sourceGroupArray,
[destinationGroup]: destinationGroupArray,
[sourceGroup]: orderArrayBy(sourceGroupArray, orderBy),
[destinationGroup]: orderArrayBy(destinationGroupArray, orderBy),
};
},
false
@ -230,8 +231,8 @@ export const IssuesView: React.FC<Props> = ({
return {
...prevData,
[sourceGroup]: sourceGroupArray,
[destinationGroup]: destinationGroupArray,
[sourceGroup]: orderArrayBy(sourceGroupArray, orderBy),
[destinationGroup]: orderArrayBy(destinationGroupArray, orderBy),
};
},
false
@ -250,8 +251,8 @@ export const IssuesView: React.FC<Props> = ({
return {
...prevData,
[sourceGroup]: sourceGroupArray,
[destinationGroup]: destinationGroupArray,
[sourceGroup]: orderArrayBy(sourceGroupArray, orderBy),
[destinationGroup]: orderArrayBy(destinationGroupArray, orderBy),
};
},
false

View File

@ -29,7 +29,7 @@ import {
TrashIcon,
XMarkIcon,
ArrowTopRightOnSquareIcon,
PaperClipIcon
PaperClipIcon,
} from "@heroicons/react/24/outline";
// helpers
import { copyTextToClipboard, truncateText } from "helpers/string.helper";
@ -82,7 +82,7 @@ export const SingleListIssue: React.FC<Props> = ({
const { setToastAlert } = useToast();
const { groupByProperty: selectedGroup, params } = useIssueView();
const { groupByProperty: selectedGroup, orderBy, params } = useIssueView();
const partialUpdateIssue = useCallback(
(formData: Partial<IIssue>) => {
@ -97,7 +97,14 @@ export const SingleListIssue: React.FC<Props> = ({
>(
CYCLE_ISSUES_WITH_PARAMS(cycleId as string, params),
(prevData) =>
handleIssuesMutation(formData, groupTitle ?? "", selectedGroup, index, prevData),
handleIssuesMutation(
formData,
groupTitle ?? "",
selectedGroup,
index,
orderBy,
prevData
),
false
);
@ -110,7 +117,14 @@ export const SingleListIssue: React.FC<Props> = ({
>(
MODULE_ISSUES_WITH_PARAMS(moduleId as string, params),
(prevData) =>
handleIssuesMutation(formData, groupTitle ?? "", selectedGroup, index, prevData),
handleIssuesMutation(
formData,
groupTitle ?? "",
selectedGroup,
index,
orderBy,
prevData
),
false
);
@ -122,7 +136,7 @@ export const SingleListIssue: React.FC<Props> = ({
>(
PROJECT_ISSUES_LIST_WITH_PARAMS(projectId as string, params),
(prevData) =>
handleIssuesMutation(formData, groupTitle ?? "", selectedGroup, index, prevData),
handleIssuesMutation(formData, groupTitle ?? "", selectedGroup, index, orderBy, prevData),
false
);
@ -138,7 +152,18 @@ export const SingleListIssue: React.FC<Props> = ({
} else mutate(PROJECT_ISSUES_LIST_WITH_PARAMS(projectId as string, params));
});
},
[workspaceSlug, projectId, cycleId, moduleId, issue, groupTitle, index, selectedGroup, params]
[
workspaceSlug,
projectId,
cycleId,
moduleId,
issue,
groupTitle,
index,
selectedGroup,
orderBy,
params,
]
);
const handleCopyText = () => {

View File

@ -37,6 +37,7 @@ export const FILTER_ISSUE_OPTIONS: Array<{
},
];
import { orderArrayBy } from "helpers/array.helper";
import { IIssue, TIssueGroupByOptions, TIssueOrderByOptions } from "types";
type THandleIssuesMutation = (
@ -44,6 +45,7 @@ type THandleIssuesMutation = (
oldGroupTitle: string,
selectedGroupBy: TIssueGroupByOptions,
issueIndex: number,
orderBy: TIssueOrderByOptions,
prevData?:
| {
[key: string]: IIssue[];
@ -61,6 +63,7 @@ export const handleIssuesMutation: THandleIssuesMutation = (
oldGroupTitle,
selectedGroupBy,
issueIndex,
orderBy,
prevData
) => {
if (!prevData) return prevData;
@ -89,15 +92,24 @@ export const handleIssuesMutation: THandleIssuesMutation = (
assignees: formData?.assignees_list ?? oldGroup[issueIndex]?.assignees_list,
};
oldGroup.splice(issueIndex, 1);
newGroup.push(updatedIssue);
if (selectedGroupBy !== Object.keys(formData)[0])
return {
...prevData,
[oldGroupTitle ?? ""]: orderArrayBy(
oldGroup.map((i) => (i.id === updatedIssue.id ? updatedIssue : i)),
orderBy
),
};
const groupThatIsUpdated = selectedGroupBy === "priority" ? formData.priority : formData.state;
return {
...prevData,
[oldGroupTitle ?? ""]: oldGroup,
[groupThatIsUpdated ?? ""]: newGroup,
[oldGroupTitle ?? ""]: orderArrayBy(
oldGroup.filter((i) => i.id !== updatedIssue.id),
orderBy
),
[groupThatIsUpdated ?? ""]: orderArrayBy([...newGroup, updatedIssue], orderBy),
};
}
};

View File

@ -12,7 +12,13 @@ export const orderArrayBy = (
key: string,
ordering: "ascending" | "descending" = "ascending"
) => {
if (key[0] === "-") {
ordering = "descending";
key = key.slice(1);
}
const innerKey = key.split("."); // split the key by dot
return array.sort((a, b) => {
const keyA = innerKey.reduce((obj, i) => obj[i], a); // get the value of the inner key
const keyB = innerKey.reduce((obj, i) => obj[i], b); // get the value of the inner key