feat: impl file table selection
This commit is contained in:
@@ -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,7 +168,8 @@ export function FileTableContextMenu({
|
|||||||
return (
|
return (
|
||||||
<ContextMenu>
|
<ContextMenu>
|
||||||
<ContextMenuTrigger asChild>{children}</ContextMenuTrigger>
|
<ContextMenuTrigger asChild>{children}</ContextMenuTrigger>
|
||||||
<ContextMenuContent>
|
{target && (
|
||||||
|
<ContextMenuContent key={target?.doc._id}>
|
||||||
<ContextMenuItem onClick={handleRename}>
|
<ContextMenuItem onClick={handleRename}>
|
||||||
<TextCursorInputIcon />
|
<TextCursorInputIcon />
|
||||||
Rename
|
Rename
|
||||||
@@ -177,6 +179,7 @@ export function FileTableContextMenu({
|
|||||||
Move to trash
|
Move to trash
|
||||||
</ContextMenuItem>
|
</ContextMenuItem>
|
||||||
</ContextMenuContent>
|
</ContextMenuContent>
|
||||||
|
)}
|
||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -185,13 +188,20 @@ 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,
|
||||||
) => {
|
) => {
|
||||||
|
const target = store.get(contextMenuTargeItemAtom)
|
||||||
|
if (target === row.original) {
|
||||||
|
setContextMenuTargetItem(null)
|
||||||
|
} else {
|
||||||
|
selectRow(row)
|
||||||
setContextMenuTargetItem(row.original)
|
setContextMenuTargetItem(row.original)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const table = useReactTable({
|
const table = useReactTable({
|
||||||
data: directory || [],
|
data: directory || [],
|
||||||
@@ -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)
|
||||||
}}
|
}}
|
||||||
|
@@ -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)
|
||||||
|
Reference in New Issue
Block a user