feat: impl file table selection

This commit is contained in:
2025-09-17 23:19:37 +00:00
parent a445bba183
commit 341fb9661b
2 changed files with 35 additions and 13 deletions

View File

@@ -67,7 +67,7 @@ const columns: ColumnDef<DirectoryItem>[] = [
cell: ({ row }) => ( cell: ({ row }) => (
<Checkbox <Checkbox
checked={row.getIsSelected()} checked={row.getIsSelected()}
onCheckedChange={(value) => row.toggleSelected(!!value)} onCheckedChange={row.getToggleSelectedHandler()}
aria-label="Select row" aria-label="Select row"
/> />
), ),
@@ -129,6 +129,7 @@ export function FileTableContextMenu({
children: React.ReactNode children: React.ReactNode
}) { }) {
const store = useStore() const store = useStore()
const target = useAtomValue(contextMenuTargeItemAtom)
const setOptimisticDeletedItems = useSetAtom(optimisticDeletedItemsAtom) const setOptimisticDeletedItems = useSetAtom(optimisticDeletedItemsAtom)
const moveToTrashMutation = useContextMutation(api.files.moveToTrash) const moveToTrashMutation = useContextMutation(api.files.moveToTrash)
const { mutate: moveToTrash } = useMutation({ const { mutate: moveToTrash } = useMutation({
@@ -167,16 +168,18 @@ export function FileTableContextMenu({
return ( return (
<ContextMenu> <ContextMenu>
<ContextMenuTrigger asChild>{children}</ContextMenuTrigger> <ContextMenuTrigger asChild>{children}</ContextMenuTrigger>
<ContextMenuContent> {target && (
<ContextMenuItem onClick={handleRename}> <ContextMenuContent key={target?.doc._id}>
<TextCursorInputIcon /> <ContextMenuItem onClick={handleRename}>
Rename <TextCursorInputIcon />
</ContextMenuItem> Rename
<ContextMenuItem onClick={handleDelete}> </ContextMenuItem>
<TrashIcon /> <ContextMenuItem onClick={handleDelete}>
Move to trash <TrashIcon />
</ContextMenuItem> Move to trash
</ContextMenuContent> </ContextMenuItem>
</ContextMenuContent>
)}
</ContextMenu> </ContextMenu>
) )
} }
@@ -185,12 +188,19 @@ export function FileTableContent({ path }: { path: string }) {
const directory = useQuery(api.files.fetchDirectoryContent, { path }) const directory = useQuery(api.files.fetchDirectoryContent, { path })
const optimisticDeletedItems = useAtomValue(optimisticDeletedItemsAtom) const optimisticDeletedItems = useAtomValue(optimisticDeletedItemsAtom)
const setContextMenuTargetItem = useSetAtom(contextMenuTargeItemAtom) const setContextMenuTargetItem = useSetAtom(contextMenuTargeItemAtom)
const store = useStore()
const handleRowContextMenu = ( const handleRowContextMenu = (
row: Row<DirectoryItem>, row: Row<DirectoryItem>,
event: React.MouseEvent, _event: React.MouseEvent,
) => { ) => {
setContextMenuTargetItem(row.original) const target = store.get(contextMenuTargeItemAtom)
if (target === row.original) {
setContextMenuTargetItem(null)
} else {
selectRow(row)
setContextMenuTargetItem(row.original)
}
} }
const table = useReactTable({ const table = useReactTable({
@@ -202,8 +212,14 @@ export function FileTableContent({ path }: { path: string }) {
globalFilterFn: (row, _columnId, _filterValue, _addMeta) => { globalFilterFn: (row, _columnId, _filterValue, _addMeta) => {
return !optimisticDeletedItems.has(row.original.doc._id) return !optimisticDeletedItems.has(row.original.doc._id)
}, },
getRowId: (row) => row.doc._id,
}) })
const selectRow = (row: Row<DirectoryItem>) => {
table.toggleAllPageRowsSelected(false)
row.toggleSelected(true)
}
if (!directory) { if (!directory) {
return null return null
} }
@@ -237,6 +253,9 @@ export function FileTableContent({ path }: { path: string }) {
<TableRow <TableRow
key={row.id} key={row.id}
data-state={row.getIsSelected() && "selected"} data-state={row.getIsSelected() && "selected"}
onClick={() => {
selectRow(row)
}}
onContextMenu={(e) => { onContextMenu={(e) => {
handleRowContextMenu(row, e) handleRowContextMenu(row, e)
}} }}

View File

@@ -3,6 +3,7 @@ import type {
DirectoryItem, DirectoryItem,
DirectoryItemKind, DirectoryItemKind,
} from "@fileone/convex/model/directories" } from "@fileone/convex/model/directories"
import type { RowSelectionState } from "@tanstack/react-table"
import { atom } from "jotai" import { atom } from "jotai"
export const contextMenuTargeItemAtom = atom<DirectoryItem | null>(null) export const contextMenuTargeItemAtom = atom<DirectoryItem | null>(null)
@@ -10,4 +11,6 @@ export const optimisticDeletedItemsAtom = atom(
new Set<Id<"files"> | Id<"directories">>(), new Set<Id<"files"> | Id<"directories">>(),
) )
export const selectedFileRowsAtom = atom<RowSelectionState>({})
export const newItemKindAtom = atom<DirectoryItemKind | null>(null) export const newItemKindAtom = atom<DirectoryItemKind | null>(null)