mirror of
https://github.com/docmost/docmost.git
synced 2026-09-01 03:15:32 +08:00
feat(bases): reorder kanban columns via drag, persisting choiceOrder
This commit is contained in:
@@ -14,6 +14,7 @@ import {
|
||||
} from "@/features/base/queries/base-row-query";
|
||||
import { resolveCardDrop } from "@/features/base/hooks/resolve-card-drop";
|
||||
import type { CardDropPayload } from "@/features/base/hooks/use-kanban-card-drag";
|
||||
import type { ColumnReorderPayload } from "@/features/base/hooks/use-kanban-column-reorder";
|
||||
import { triggerPostMoveFlash } from "@atlaskit/pragmatic-drag-and-drop-flourish/trigger-post-move-flash";
|
||||
import * as liveRegion from "@atlaskit/pragmatic-drag-and-drop-live-region";
|
||||
import { KanbanColumn } from "./kanban-column";
|
||||
@@ -139,6 +140,34 @@ export function BaseKanban({
|
||||
});
|
||||
};
|
||||
|
||||
const handleColumnReorder = useCallback(
|
||||
(payload: ColumnReorderPayload) => {
|
||||
if (!effectiveView) return;
|
||||
const current = columns.map((c) => c.key);
|
||||
const fromIdx = current.indexOf(payload.draggedColumnKey);
|
||||
const toIdx = current.indexOf(payload.targetColumnKey);
|
||||
if (fromIdx === -1 || toIdx === -1) return;
|
||||
const next = current.slice();
|
||||
next.splice(fromIdx, 1);
|
||||
const insertAt =
|
||||
payload.edge === "left"
|
||||
? toIdx > fromIdx
|
||||
? toIdx - 1
|
||||
: toIdx
|
||||
: toIdx > fromIdx
|
||||
? toIdx
|
||||
: toIdx + 1;
|
||||
next.splice(insertAt, 0, payload.draggedColumnKey);
|
||||
|
||||
updateViewMutation.mutate({
|
||||
viewId: effectiveView.id,
|
||||
pageId: base.id,
|
||||
config: { ...effectiveView.config, choiceOrder: next },
|
||||
});
|
||||
},
|
||||
[base.id, columns, effectiveView, updateViewMutation],
|
||||
);
|
||||
|
||||
if (!isGroupable) {
|
||||
return <KanbanEmptyState base={base} onPick={handlePickProperty} />;
|
||||
}
|
||||
@@ -153,6 +182,7 @@ export function BaseKanban({
|
||||
onCardClick={onCardClick}
|
||||
onAddCard={handleAddCard}
|
||||
onCardDrop={handleCardDrop}
|
||||
onColumnReorder={handleColumnReorder}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -1,19 +1,36 @@
|
||||
import { Badge, Text } from "@mantine/core";
|
||||
import {
|
||||
useKanbanColumnReorder,
|
||||
type ColumnReorderPayload,
|
||||
} from "@/features/base/hooks/use-kanban-column-reorder";
|
||||
import { BaseDropEdgeIndicator } from "@/features/base/components/grid/base-drop-edge-indicator";
|
||||
import classes from "@/features/base/styles/kanban.module.css";
|
||||
|
||||
type KanbanColumnHeaderProps = {
|
||||
columnKey: string;
|
||||
name: string;
|
||||
color: string | null;
|
||||
count: number;
|
||||
onReorderDrop: (payload: ColumnReorderPayload) => void;
|
||||
};
|
||||
|
||||
export function KanbanColumnHeader({
|
||||
columnKey,
|
||||
name,
|
||||
color,
|
||||
count,
|
||||
onReorderDrop,
|
||||
}: KanbanColumnHeaderProps) {
|
||||
const { ref, isDragging, closestEdge } = useKanbanColumnReorder({
|
||||
columnKey,
|
||||
onDrop: onReorderDrop,
|
||||
});
|
||||
return (
|
||||
<div className={classes.columnHeader}>
|
||||
<div
|
||||
ref={ref}
|
||||
className={classes.columnHeader}
|
||||
data-dragging={isDragging || undefined}
|
||||
>
|
||||
<div className={classes.columnHeaderLeft}>
|
||||
{color ? (
|
||||
<Badge color={color} variant="light" size="sm">
|
||||
@@ -26,6 +43,7 @@ export function KanbanColumnHeader({
|
||||
)}
|
||||
<span className={classes.columnCount}>{count}</span>
|
||||
</div>
|
||||
{closestEdge && <BaseDropEdgeIndicator edge={closestEdge} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { KanbanCard } from "./kanban-card";
|
||||
import { KanbanColumnHeader } from "./kanban-column-header";
|
||||
import { KanbanAddCardButton } from "./kanban-add-card-button";
|
||||
import type { CardDropPayload } from "@/features/base/hooks/use-kanban-card-drag";
|
||||
import type { ColumnReorderPayload } from "@/features/base/hooks/use-kanban-column-reorder";
|
||||
import { useKanbanColumnDrop } from "@/features/base/hooks/use-kanban-column-drop";
|
||||
import classes from "@/features/base/styles/kanban.module.css";
|
||||
|
||||
@@ -13,6 +14,7 @@ type KanbanColumnProps = {
|
||||
onCardClick: (rowId: string) => void;
|
||||
onAddCard: (columnKey: string) => void;
|
||||
onCardDrop: (payload: CardDropPayload) => void;
|
||||
onColumnReorder: (payload: ColumnReorderPayload) => void;
|
||||
};
|
||||
|
||||
export function KanbanColumn({
|
||||
@@ -21,6 +23,7 @@ export function KanbanColumn({
|
||||
onCardClick,
|
||||
onAddCard,
|
||||
onCardDrop,
|
||||
onColumnReorder,
|
||||
}: KanbanColumnProps) {
|
||||
const { ref: bodyRef, isOver } = useKanbanColumnDrop({
|
||||
columnKey: column.key,
|
||||
@@ -30,9 +33,11 @@ export function KanbanColumn({
|
||||
return (
|
||||
<div className={classes.column} data-column-key={column.key}>
|
||||
<KanbanColumnHeader
|
||||
columnKey={column.key}
|
||||
name={column.name}
|
||||
color={column.color}
|
||||
count={column.rows.length}
|
||||
onReorderDrop={onColumnReorder}
|
||||
/>
|
||||
<div
|
||||
ref={bodyRef}
|
||||
|
||||
Reference in New Issue
Block a user