139 lines
4.2 KiB
TypeScript
139 lines
4.2 KiB
TypeScript
|
|
import { createColumnHelper } from '@tanstack/react-table';
|
||
|
|
import { ItemWithSelection } from './defs';
|
||
|
|
import { useAtomValue, useSetAtom } from 'jotai';
|
||
|
|
import { currentItemSelectionAtom, itemSelectionSetActionAtom } from '@/state/atoms';
|
||
|
|
import { useMemo } from 'react';
|
||
|
|
import { StatsColumns } from '../columns';
|
||
|
|
|
||
|
|
const ch = createColumnHelper<ItemWithSelection>();
|
||
|
|
|
||
|
|
const columns = {
|
||
|
|
icon: ch.display({
|
||
|
|
id: 'icon',
|
||
|
|
header: function Component(col) {
|
||
|
|
return <div className="flex flex-row justify-center"></div>
|
||
|
|
},
|
||
|
|
cell: function Component({ row }){
|
||
|
|
const setItemSelection= useSetAtom(itemSelectionSetActionAtom);
|
||
|
|
const c = useAtomValue(currentItemSelectionAtom);
|
||
|
|
const selected = useMemo(()=> {
|
||
|
|
return c[0].has(row.original.item.id);
|
||
|
|
}, [c])
|
||
|
|
return <div
|
||
|
|
className={`no-select flex flex-row ${ row.original.status?.selected ? "animate-pulse" : ""}`}
|
||
|
|
onClick={(e)=>{
|
||
|
|
setItemSelection({
|
||
|
|
[row.original.item.id]: selected ? undefined : row.original.item.item_count,
|
||
|
|
})
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
<div className="flex flex-row w-6 h-6 justify-center">
|
||
|
|
<img src={row.original.item.item_image || ""} alt="icon" className="select-none object-contain select-none"/>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
},
|
||
|
|
}),
|
||
|
|
count: ch.display({
|
||
|
|
id: 'count',
|
||
|
|
header: function Component(col){
|
||
|
|
return <div className="flex flex-row justify-center">#</div>
|
||
|
|
},
|
||
|
|
cell: function Component({ row }){
|
||
|
|
const c = useAtomValue(currentItemSelectionAtom);
|
||
|
|
const setItemSelection= useSetAtom(itemSelectionSetActionAtom);
|
||
|
|
const currentValue = useMemo(()=> {
|
||
|
|
const got = c[0].get(row.original.item.id);
|
||
|
|
if(got !== undefined) {
|
||
|
|
return got.toString();
|
||
|
|
}
|
||
|
|
return ""
|
||
|
|
}, [c])
|
||
|
|
const itemCount = row.original.item.item_count
|
||
|
|
return <div
|
||
|
|
className={`flex flex-row select-none ${ row.original.status?.selected ? "bg-gray-200" : ""}`}
|
||
|
|
>
|
||
|
|
<input
|
||
|
|
className="w-10 text-center "
|
||
|
|
value={currentValue}
|
||
|
|
onChange={(e)=>{
|
||
|
|
if(e.target.value === ""){
|
||
|
|
setItemSelection({[row.original.item.id]: undefined});
|
||
|
|
return
|
||
|
|
}
|
||
|
|
if(e.target.value === "-"){
|
||
|
|
setItemSelection({
|
||
|
|
[row.original.item.id]: itemCount,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
let parsedInt = parseInt(e.target.value);
|
||
|
|
if (isNaN(parsedInt)) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if(parsedInt > itemCount){
|
||
|
|
parsedInt = itemCount;
|
||
|
|
}
|
||
|
|
setItemSelection({
|
||
|
|
[row.original.item.id]: parsedInt,
|
||
|
|
})
|
||
|
|
}}
|
||
|
|
placeholder={itemCount.toString()} />
|
||
|
|
</div>
|
||
|
|
},
|
||
|
|
}),
|
||
|
|
name: ch.display({
|
||
|
|
id: 'name',
|
||
|
|
header: (col)=> {
|
||
|
|
return <div
|
||
|
|
className="flex flex-row text-sm"
|
||
|
|
>name</div>
|
||
|
|
},
|
||
|
|
cell: function Component({ row }){
|
||
|
|
return <div className="flex flex-row whitespace-pre">
|
||
|
|
<span>{row.original.item.item_name}</span>
|
||
|
|
</div>
|
||
|
|
},
|
||
|
|
}),
|
||
|
|
slots: ch.display({
|
||
|
|
id: 'slots',
|
||
|
|
header: (col)=>{
|
||
|
|
return <div
|
||
|
|
className="flex flex-row text-sm"
|
||
|
|
>slots</div>
|
||
|
|
},
|
||
|
|
cell: function Component({ row }){
|
||
|
|
return <div className="flex flex-row justify-center">
|
||
|
|
<span>{row.original.item.item_slots}</span>
|
||
|
|
</div>
|
||
|
|
},
|
||
|
|
}),
|
||
|
|
stats: ch.group({
|
||
|
|
id: 'stats',
|
||
|
|
header: (col)=>{
|
||
|
|
return <div
|
||
|
|
className="flex flex-row text-sm"
|
||
|
|
>stats</div>
|
||
|
|
},
|
||
|
|
columns: [
|
||
|
|
...StatsColumns.map((c)=>{
|
||
|
|
return ch.display({
|
||
|
|
id: 'stats.'+c,
|
||
|
|
header: (col)=>{
|
||
|
|
return <div
|
||
|
|
className="flex flex-row text-sm justify-center"
|
||
|
|
>{c}</div>
|
||
|
|
},
|
||
|
|
cell: function Component({ row }){
|
||
|
|
const stats = row.original.item.stats
|
||
|
|
const stat = stats ? stats[c] : ""
|
||
|
|
return <div className={`flex flex-row justify-start ${stat ? "border" : ""}`}>
|
||
|
|
<span>{stat}</span>
|
||
|
|
</div>
|
||
|
|
},
|
||
|
|
})
|
||
|
|
})
|
||
|
|
]
|
||
|
|
}),
|
||
|
|
} as const;
|
||
|
|
|
||
|
|
export const InventoryColumns = columns;
|