add dragging to step list
This commit is contained in:
parent
646bd573cf
commit
575eecfc69
13 changed files with 406 additions and 60 deletions
|
|
@ -0,0 +1,86 @@
|
|||
/**
|
||||
* Desktop editor using drag-and-drop via @dnd-kit
|
||||
*/
|
||||
|
||||
import {
|
||||
DndContext,
|
||||
closestCenter,
|
||||
PointerSensor,
|
||||
useSensor,
|
||||
useSensors,
|
||||
} from "@dnd-kit/core";
|
||||
import {
|
||||
arrayMove,
|
||||
SortableContext,
|
||||
verticalListSortingStrategy,
|
||||
} from "@dnd-kit/sortable";
|
||||
import type { InstructionStepModel } from "../../models/InstructionStepModel";
|
||||
import { InstructionStepDesktopListItem } from "./InstructionStepDesktopListItem";
|
||||
import { useInstructionStepListEditor } from "./InstructionStepListEditor";
|
||||
import Button, { ButtonType } from "../basics/Button";
|
||||
import { Icon } from "../basics/SvgIcon";
|
||||
|
||||
type InstructionStepListDesktopEditorProps = {
|
||||
instructionStepList: InstructionStepModel[];
|
||||
onChange: (steps: InstructionStepModel[]) => void;
|
||||
};
|
||||
|
||||
export function InstructionStepListDesktopEditor({
|
||||
instructionStepList,
|
||||
onChange,
|
||||
}: InstructionStepListDesktopEditorProps) {
|
||||
const { handleUpdate, handleAdd, handleRemove } = useInstructionStepListEditor(
|
||||
instructionStepList,
|
||||
onChange
|
||||
);
|
||||
|
||||
const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 8 } }));
|
||||
|
||||
const handleDragEnd = (event: any) => {
|
||||
const { active, over } = event;
|
||||
if (active.id !== over.id) {
|
||||
/* find element by internal id
|
||||
* Caution! Due to new elements not having a real ID yet, each list item has an internal ID
|
||||
* in order to give it a unique identifier before saving it to the backend. We have to compare
|
||||
* the id of the drag item to the internalId of the list item here!
|
||||
*/
|
||||
const oldIndex = instructionStepList.findIndex((i) => i.internalId === active.id);
|
||||
const newIndex = instructionStepList.findIndex((i) => i.internalId === over.id);
|
||||
// move element to new position
|
||||
const newOrder = arrayMove(instructionStepList, oldIndex, newIndex);
|
||||
onChange(newOrder);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h3 className="subsection-heading mb-3">Zubereitung</h3>
|
||||
<DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
|
||||
<SortableContext
|
||||
items={instructionStepList.map((i) => i.internalId)}
|
||||
strategy={verticalListSortingStrategy}
|
||||
>
|
||||
<div className="flex flex-col gap-3">
|
||||
{instructionStepList.map((step, index) => (
|
||||
<InstructionStepDesktopListItem
|
||||
key={step.internalId}
|
||||
id={step.internalId}
|
||||
index={index}
|
||||
step={step}
|
||||
onUpdate={handleUpdate}
|
||||
onRemove={handleRemove}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</SortableContext>
|
||||
</DndContext>
|
||||
<Button
|
||||
onClick={handleAdd}
|
||||
icon={Icon.Plus}
|
||||
text="Schritt hinzufügen"
|
||||
buttonType={ButtonType.PrimaryButton}
|
||||
className="mt-4"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue