mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-16 05:36:00 +02:00
add draggable table column reorder
This commit is contained in:
@@ -9,6 +9,11 @@ import { LibraryItem, QueueSong } from '/@/shared/types/domain-types';
|
||||
import { Play, TableColumn } from '/@/shared/types/types';
|
||||
|
||||
interface UseDefaultItemListControlsArgs {
|
||||
onColumnReordered?: (
|
||||
columnIdFrom: TableColumn,
|
||||
columnIdTo: TableColumn,
|
||||
edge: 'bottom' | 'left' | 'right' | 'top' | null,
|
||||
) => void;
|
||||
onColumnResized?: (columnId: TableColumn, width: number) => void;
|
||||
}
|
||||
|
||||
@@ -16,7 +21,7 @@ export const useDefaultItemListControls = (args?: UseDefaultItemListControlsArgs
|
||||
const player = usePlayerContext();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { onColumnResized } = args || {};
|
||||
const { onColumnReordered, onColumnResized } = args || {};
|
||||
|
||||
const controls: ItemControls = useMemo(() => {
|
||||
return {
|
||||
@@ -153,6 +158,18 @@ export const useDefaultItemListControls = (args?: UseDefaultItemListControlsArgs
|
||||
}
|
||||
},
|
||||
|
||||
onColumnReordered: ({
|
||||
columnIdFrom,
|
||||
columnIdTo,
|
||||
edge,
|
||||
}: {
|
||||
columnIdFrom: TableColumn;
|
||||
columnIdTo: TableColumn;
|
||||
edge: 'bottom' | 'left' | 'right' | 'top' | null;
|
||||
}) => {
|
||||
onColumnReordered?.(columnIdFrom, columnIdTo, edge);
|
||||
},
|
||||
|
||||
onColumnResized: ({ columnId, width }: { columnId: TableColumn; width: number }) => {
|
||||
onColumnResized?.(columnId, width);
|
||||
},
|
||||
@@ -249,7 +266,7 @@ export const useDefaultItemListControls = (args?: UseDefaultItemListControlsArgs
|
||||
player.setRating(item._serverId, [item.id], itemType, newRating);
|
||||
},
|
||||
};
|
||||
}, [onColumnResized, navigate, player]);
|
||||
}, [onColumnReordered, onColumnResized, navigate, player]);
|
||||
|
||||
return controls;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
import type { Edge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';
|
||||
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { useSettingsStore, useSettingsStoreActions } from '/@/renderer/store';
|
||||
import { ItemListKey, TableColumn } from '/@/shared/types/types';
|
||||
|
||||
interface UseItemListColumnReorderProps {
|
||||
itemListKey: ItemListKey;
|
||||
}
|
||||
|
||||
export const useItemListColumnReorder = ({ itemListKey }: UseItemListColumnReorderProps) => {
|
||||
const { setList } = useSettingsStoreActions();
|
||||
|
||||
const handleColumnReordered = useCallback(
|
||||
(columnIdFrom: TableColumn, columnIdTo: TableColumn, edge: Edge | null) => {
|
||||
const columns = useSettingsStore.getState().lists[itemListKey]?.table.columns;
|
||||
|
||||
if (!columns) {
|
||||
return;
|
||||
}
|
||||
|
||||
const indexFrom = columns.findIndex((column) => column.id === columnIdFrom);
|
||||
const indexTo = columns.findIndex((column) => column.id === columnIdTo);
|
||||
|
||||
// If either column not found or dragging to the same position, do nothing
|
||||
if (indexFrom === -1 || indexTo === -1 || indexFrom === indexTo) {
|
||||
return;
|
||||
}
|
||||
|
||||
const targetColumn = columns[indexTo];
|
||||
|
||||
// Create a new array to avoid mutating the original
|
||||
const newColumns = [...columns];
|
||||
|
||||
// Remove the column from its current position
|
||||
const [movedColumn] = newColumns.splice(indexFrom, 1);
|
||||
|
||||
// Update pinned status based on target column
|
||||
// If dragging onto a pinned left column, pin the moved column to left
|
||||
// If dragging onto a pinned right column, pin the moved column to right
|
||||
// If dragging onto an unpinned column, unpin the moved column
|
||||
const updatedMovedColumn =
|
||||
targetColumn.pinned === 'left'
|
||||
? { ...movedColumn, pinned: 'left' as const }
|
||||
: targetColumn.pinned === 'right'
|
||||
? { ...movedColumn, pinned: 'right' as const }
|
||||
: { ...movedColumn, pinned: null };
|
||||
|
||||
// Calculate the new insertion index based on edge
|
||||
// After removing the item, indices shift:
|
||||
// - If removing from before the target, target index decreases by 1
|
||||
// - If removing from after the target, target index stays the same
|
||||
let newIndex: number;
|
||||
|
||||
if (edge === 'left') {
|
||||
// Insert before the target column
|
||||
if (indexFrom < indexTo) {
|
||||
// Removed item was before target, so target shifted left by 1
|
||||
newIndex = indexTo - 1;
|
||||
} else {
|
||||
// Removed item was after target, target index unchanged
|
||||
newIndex = indexTo;
|
||||
}
|
||||
} else if (edge === 'right') {
|
||||
// Insert after the target column
|
||||
if (indexFrom < indexTo) {
|
||||
// Removed item was before target, so target shifted left by 1
|
||||
newIndex = indexTo;
|
||||
} else {
|
||||
// Removed item was after target, target index unchanged
|
||||
newIndex = indexTo + 1;
|
||||
}
|
||||
} else {
|
||||
// No edge specified, default to inserting after the target position
|
||||
if (indexFrom < indexTo) {
|
||||
newIndex = indexTo;
|
||||
} else {
|
||||
newIndex = indexTo + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Insert the column at the new position
|
||||
newColumns.splice(newIndex, 0, updatedMovedColumn);
|
||||
|
||||
setList(itemListKey, {
|
||||
table: {
|
||||
columns: newColumns,
|
||||
},
|
||||
});
|
||||
},
|
||||
[itemListKey, setList],
|
||||
);
|
||||
|
||||
return { handleColumnReordered };
|
||||
};
|
||||
Reference in New Issue
Block a user