-
Notifications
You must be signed in to change notification settings - Fork 115
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add import/index documents ui (#131)
- Loading branch information
Showing
31 changed files
with
800 additions
and
212 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
src/app/(main)/(admin)/documents/components/data-table-column-header.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { | ||
ArrowDownIcon, | ||
ArrowUpIcon, | ||
CaretSortIcon, | ||
EyeNoneIcon, | ||
} from "@radix-ui/react-icons" | ||
import { Column } from "@tanstack/react-table" | ||
|
||
import { cn } from "@/lib/utils" | ||
import { Button } from "@/components/ui/button" | ||
import { | ||
DropdownMenu, | ||
DropdownMenuContent, | ||
DropdownMenuItem, | ||
DropdownMenuSeparator, | ||
DropdownMenuTrigger, | ||
} from "@/components/ui/dropdown-menu" | ||
|
||
interface DataTableColumnHeaderProps<TData, TValue> | ||
extends React.HTMLAttributes<HTMLDivElement> { | ||
column: Column<TData, TValue> | ||
title: string | ||
} | ||
|
||
export function DataTableColumnHeader<TData, TValue>({ | ||
column, | ||
title, | ||
className, | ||
}: DataTableColumnHeaderProps<TData, TValue>) { | ||
if (!column.getCanSort()) { | ||
return <div className={cn(className)}>{title}</div> | ||
} | ||
|
||
return ( | ||
<div className={cn("flex items-center space-x-2", className)}> | ||
<DropdownMenu> | ||
<DropdownMenuTrigger asChild> | ||
<Button | ||
variant="ghost" | ||
size="sm" | ||
className="-ml-3 h-8 data-[state=open]:bg-accent" | ||
> | ||
<span>{title}</span> | ||
{column.getIsSorted() === "desc" ? ( | ||
<ArrowDownIcon className="ml-2 h-4 w-4" /> | ||
) : column.getIsSorted() === "asc" ? ( | ||
<ArrowUpIcon className="ml-2 h-4 w-4" /> | ||
) : ( | ||
<CaretSortIcon className="ml-2 h-4 w-4" /> | ||
)} | ||
</Button> | ||
</DropdownMenuTrigger> | ||
<DropdownMenuContent align="start"> | ||
<DropdownMenuItem onClick={() => column.toggleSorting(false)}> | ||
<ArrowUpIcon className="mr-2 h-3.5 w-3.5 text-muted-foreground/70" /> | ||
Asc | ||
</DropdownMenuItem> | ||
<DropdownMenuItem onClick={() => column.toggleSorting(true)}> | ||
<ArrowDownIcon className="mr-2 h-3.5 w-3.5 text-muted-foreground/70" /> | ||
Desc | ||
</DropdownMenuItem> | ||
<DropdownMenuSeparator /> | ||
<DropdownMenuItem onClick={() => column.toggleVisibility(false)}> | ||
<EyeNoneIcon className="mr-2 h-3.5 w-3.5 text-muted-foreground/70" /> | ||
Hide | ||
</DropdownMenuItem> | ||
</DropdownMenuContent> | ||
</DropdownMenu> | ||
</div> | ||
) | ||
} |
56 changes: 56 additions & 0 deletions
56
src/app/(main)/(admin)/documents/components/data-table-row-actions.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
"use client" | ||
|
||
import {BuildDocumentIndexDialog} from "@/app/(main)/(admin)/documents/components/dialogs/build-document-index-dialog"; | ||
import type {Document} from "@/core/repositories/document"; | ||
import { DotsHorizontalIcon } from "@radix-ui/react-icons" | ||
import { Row } from "@tanstack/react-table" | ||
|
||
import { Button } from "@/components/ui/button" | ||
import { | ||
DropdownMenu, | ||
DropdownMenuContent, | ||
DropdownMenuItem, | ||
DropdownMenuSeparator, | ||
DropdownMenuShortcut, | ||
DropdownMenuTrigger, | ||
} from "@/components/ui/dropdown-menu" | ||
import {useState} from "react"; | ||
|
||
|
||
interface DataTableRowActionsProps { | ||
row: Row<Document> | ||
} | ||
|
||
export function DataTableRowActions<TData>(props: DataTableRowActionsProps) { | ||
const [dialogOpen, setDialogOpen] = useState(false); | ||
|
||
return ( | ||
<> | ||
<DropdownMenu> | ||
<DropdownMenuTrigger asChild> | ||
<Button | ||
variant="ghost" | ||
className="flex h-8 w-8 p-0 data-[state=open]:bg-muted" | ||
> | ||
<DotsHorizontalIcon className="h-4 w-4" /> | ||
<span className="sr-only">Open menu</span> | ||
</Button> | ||
</DropdownMenuTrigger> | ||
<DropdownMenuContent align="end" className="w-[160px]"> | ||
<DropdownMenuItem onSelect={() => setDialogOpen(true)}>Build Index</DropdownMenuItem> | ||
<DropdownMenuSeparator /> | ||
<DropdownMenuItem disabled={true}> | ||
Delete | ||
<DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut> | ||
</DropdownMenuItem> | ||
</DropdownMenuContent> | ||
</DropdownMenu> | ||
<BuildDocumentIndexDialog | ||
documentRows={[props.row]} | ||
trigger={null} | ||
open={dialogOpen} | ||
handleOpenChange={setDialogOpen} | ||
/> | ||
</> | ||
) | ||
} |
73 changes: 73 additions & 0 deletions
73
src/app/(main)/(admin)/documents/components/data-table-toolbar.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
"use client" | ||
|
||
import {DataTableViewOptions} from "@/app/(main)/(admin)/documents/components/data-table-view-options"; | ||
import {ImportDocumentsDialog} from "@/app/(main)/(admin)/documents/components/dialogs/import-documents-dialog"; | ||
import {BuildDocumentIndexDialog} from "@/app/(main)/(admin)/documents/components/dialogs/build-document-index-dialog"; | ||
import { Cross2Icon } from "@radix-ui/react-icons" | ||
import {Row, Table} from "@tanstack/react-table" | ||
import type {Document} from "@/core/repositories/document"; | ||
|
||
import { Button } from "@/components/ui/button" | ||
import { Input } from "@/components/ui/input" | ||
import {useState} from "react"; | ||
|
||
interface DataTableToolbarProps { | ||
table: Table<Document> | ||
} | ||
|
||
const documentMap = new Map<string, Row<Document>>(); | ||
|
||
export function DataTableToolbar({ table }: DataTableToolbarProps) { | ||
const isFiltered = table.getState().columnFilters.length > 0; | ||
const selectedRowIds = Object.keys(table.getState().rowSelection); | ||
const nSelectedRows = selectedRowIds.length; | ||
const isSelected = nSelectedRows > 0; | ||
|
||
const documentRows = table.getSelectedRowModel().rows; | ||
for (let documentRow of documentRows) { | ||
documentMap.set(documentRow.id, documentRow) | ||
} | ||
|
||
const [dialogOpen, setDialogOpen] = useState(false); | ||
|
||
return ( | ||
<div className="flex items-center justify-between"> | ||
<div className="flex flex-1 items-center space-x-2"> | ||
<Input | ||
placeholder="Filter documents..." | ||
value={(table.getColumn("name")?.getFilterValue() as string) ?? ""} | ||
onChange={(event: { target: { value: any } }) => | ||
table.getColumn("name")?.setFilterValue(event.target.value) | ||
} | ||
className="h-8 w-[150px] lg:w-[250px]" | ||
/> | ||
{isFiltered && ( | ||
<Button | ||
variant="ghost" | ||
onClick={() => table.resetColumnFilters()} | ||
className="h-8 px-2 lg:px-3" | ||
> | ||
Reset | ||
<Cross2Icon className="ml-2 h-4 w-4" /> | ||
</Button> | ||
)} | ||
</div> | ||
<div className="flex flex-1 items-center space-x-2"> | ||
<DataTableViewOptions table={table} /> | ||
<ImportDocumentsDialog trigger={<Button size="sm">Import documents</Button>}/> | ||
{ | ||
isSelected && ( | ||
<BuildDocumentIndexDialog | ||
documentRows={selectedRowIds.map(id => documentMap.get(id) as Row<Document>)} | ||
open={dialogOpen} | ||
handleOpenChange={setDialogOpen} | ||
trigger={ | ||
<Button size="sm">Build Indexes ({nSelectedRows})</Button> | ||
} | ||
/> | ||
) | ||
} | ||
</div> | ||
</div> | ||
) | ||
} |
59 changes: 59 additions & 0 deletions
59
src/app/(main)/(admin)/documents/components/data-table-view-options.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
"use client" | ||
|
||
import { DropdownMenuTrigger } from "@radix-ui/react-dropdown-menu" | ||
import { MixerHorizontalIcon } from "@radix-ui/react-icons" | ||
import { Table } from "@tanstack/react-table" | ||
|
||
import { Button } from "@/components/ui/button" | ||
import { | ||
DropdownMenu, | ||
DropdownMenuCheckboxItem, | ||
DropdownMenuContent, | ||
DropdownMenuLabel, | ||
DropdownMenuSeparator, | ||
} from "@/components/ui/dropdown-menu" | ||
|
||
interface DataTableViewOptionsProps<TData> { | ||
table: Table<TData> | ||
} | ||
|
||
export function DataTableViewOptions<TData>({ | ||
table, | ||
}: DataTableViewOptionsProps<TData>) { | ||
return ( | ||
<DropdownMenu> | ||
<DropdownMenuTrigger asChild> | ||
<Button | ||
variant="outline" | ||
size="sm" | ||
className="ml-auto hidden h-8 lg:flex" | ||
> | ||
<MixerHorizontalIcon className="mr-2 h-4 w-4" /> | ||
View | ||
</Button> | ||
</DropdownMenuTrigger> | ||
<DropdownMenuContent align="end" className="w-[150px]"> | ||
<DropdownMenuLabel>Toggle columns</DropdownMenuLabel> | ||
<DropdownMenuSeparator /> | ||
{table | ||
.getAllColumns() | ||
.filter( | ||
(column) => | ||
typeof column.accessorFn !== "undefined" && column.getCanHide() | ||
) | ||
.map((column) => { | ||
return ( | ||
<DropdownMenuCheckboxItem | ||
key={column.id} | ||
className="capitalize" | ||
checked={column.getIsVisible()} | ||
onCheckedChange={(value) => column.toggleVisibility(!!value)} | ||
> | ||
{column.id} | ||
</DropdownMenuCheckboxItem> | ||
) | ||
})} | ||
</DropdownMenuContent> | ||
</DropdownMenu> | ||
) | ||
} |
Oops, something went wrong.