2025-06-20 05:41:10 +00:00
|
|
|
import { flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table'
|
2025-06-23 06:33:03 +00:00
|
|
|
import { atom, useAtomValue, useSetAtom } from 'jotai'
|
|
|
|
|
import { useEffect, useMemo } from 'react'
|
2025-06-20 05:41:10 +00:00
|
|
|
import { StatsColumns } from '@/lib/columns'
|
|
|
|
|
import { ItemWithSelection } from '@/lib/table/defs'
|
|
|
|
|
import { InventoryColumns } from '@/lib/table/tanstack'
|
2025-06-23 06:33:03 +00:00
|
|
|
import {
|
|
|
|
|
inventoryItemsCurrentPageAtom,
|
|
|
|
|
mouseDragSelectionStateAtom,
|
|
|
|
|
preferenceInventoryTab,
|
|
|
|
|
} from '@/state/atoms'
|
2025-05-25 05:17:41 +00:00
|
|
|
|
2025-06-20 05:41:10 +00:00
|
|
|
const columnVisibilityAtom = atom(get => {
|
2025-05-25 05:17:41 +00:00
|
|
|
const itemTab = get(preferenceInventoryTab)
|
2025-06-20 05:41:10 +00:00
|
|
|
if (!['2', '4'].includes(itemTab)) {
|
|
|
|
|
return Object.fromEntries([...StatsColumns.map(x => [`stats.${x}`, false]), ['slots', false]])
|
2025-05-25 05:17:41 +00:00
|
|
|
}
|
2025-06-20 05:41:10 +00:00
|
|
|
return {}
|
2025-05-25 05:17:41 +00:00
|
|
|
})
|
|
|
|
|
export const InventoryTable = () => {
|
|
|
|
|
const items = useAtomValue(inventoryItemsCurrentPageAtom)
|
2025-06-23 06:33:03 +00:00
|
|
|
const setDragState = useSetAtom(mouseDragSelectionStateAtom)
|
2025-05-25 05:17:41 +00:00
|
|
|
|
2025-06-20 05:41:10 +00:00
|
|
|
const columns = useMemo(() => {
|
|
|
|
|
return [...Object.values(InventoryColumns)]
|
2025-05-25 05:17:41 +00:00
|
|
|
}, [])
|
|
|
|
|
|
|
|
|
|
const columnVisibility = useAtomValue(columnVisibilityAtom)
|
|
|
|
|
|
|
|
|
|
const table = useReactTable<ItemWithSelection>({
|
2025-06-20 05:41:10 +00:00
|
|
|
getRowId: row => row.item.unique_id.toString(),
|
2025-05-25 05:17:41 +00:00
|
|
|
data: items,
|
|
|
|
|
state: {
|
|
|
|
|
columnVisibility,
|
|
|
|
|
},
|
|
|
|
|
columns,
|
|
|
|
|
getCoreRowModel: getCoreRowModel(),
|
|
|
|
|
})
|
|
|
|
|
|
2025-06-23 06:33:03 +00:00
|
|
|
// Handle global mouse up to end drag selection
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const handleMouseUp = () => {
|
|
|
|
|
setDragState(prev => ({ ...prev, isDragging: false }))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
document.addEventListener('mouseup', handleMouseUp)
|
|
|
|
|
return () => {
|
|
|
|
|
document.removeEventListener('mouseup', handleMouseUp)
|
|
|
|
|
}
|
|
|
|
|
}, [setDragState])
|
|
|
|
|
|
2025-05-25 05:17:41 +00:00
|
|
|
return (
|
|
|
|
|
<div className="overflow-y-auto h-full mb-32">
|
|
|
|
|
<table
|
2025-06-20 05:41:10 +00:00
|
|
|
onContextMenu={e => {
|
2025-05-25 05:17:41 +00:00
|
|
|
e.preventDefault()
|
|
|
|
|
return
|
|
|
|
|
}}
|
2025-06-20 05:41:10 +00:00
|
|
|
className="border-spacing-x-2 border-separate"
|
|
|
|
|
>
|
2025-05-25 05:17:41 +00:00
|
|
|
<thead className="sticky top-0 z-10 select-none bg-white">
|
|
|
|
|
{table.getHeaderGroups().map(headerGroup => (
|
2025-06-20 05:41:10 +00:00
|
|
|
<tr className="" key={headerGroup.id}>
|
2025-05-25 05:17:41 +00:00
|
|
|
{headerGroup.headers.map(header => (
|
2025-06-20 05:41:10 +00:00
|
|
|
<th key={header.id} className="text-left">
|
2025-05-25 05:17:41 +00:00
|
|
|
{header.isPlaceholder
|
|
|
|
|
? null
|
2025-06-20 05:41:10 +00:00
|
|
|
: flexRender(header.column.columnDef.header, header.getContext())}
|
2025-05-25 05:17:41 +00:00
|
|
|
</th>
|
|
|
|
|
))}
|
|
|
|
|
</tr>
|
|
|
|
|
))}
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody className="divide-y divide-gray-200">
|
|
|
|
|
{table.getRowModel().rows.map(row => (
|
2025-06-20 05:41:10 +00:00
|
|
|
<tr key={row.id} className={''}>
|
2025-05-25 05:17:41 +00:00
|
|
|
{row.getVisibleCells().map(cell => (
|
2025-06-20 05:41:10 +00:00
|
|
|
<td key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</td>
|
2025-05-25 05:17:41 +00:00
|
|
|
))}
|
|
|
|
|
</tr>
|
|
|
|
|
))}
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
}
|