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; tableKey?: 'detail' | 'main'; } export const useItemListColumnReorder = ({ itemListKey, tableKey = 'main', }: UseItemListColumnReorderProps) => { const { setList } = useSettingsStoreActions(); const handleColumnReordered = useCallback( (columnIdFrom: TableColumn, columnIdTo: TableColumn, edge: Edge | null) => { const list = useSettingsStore.getState().lists[itemListKey]; const columns = tableKey === 'detail' ? list?.detail?.columns : list?.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); if (tableKey === 'detail') { type SetListData = Parameters< ReturnType['setList'] >[1]; setList(itemListKey, { detail: { columns: newColumns } } as SetListData); } else { setList(itemListKey, { table: { columns: newColumns, }, }); } }, [itemListKey, setList, tableKey], ); return { handleColumnReordered }; };