implement controlled edit / delete dialogs

This commit is contained in:
andrzej 2024-08-07 15:46:14 +02:00
parent 17578d50d6
commit 89e338a0ac
5 changed files with 84 additions and 121 deletions

Binary file not shown.

View File

@ -706,22 +706,6 @@ body {
z-index: 100;
}
.col-span-full {
grid-column: 1 / -1;
}
.col-start-1 {
grid-column-start: 1;
}
.col-start-3 {
grid-column-start: 3;
}
.col-end-3 {
grid-column-end: 3;
}
.m-auto {
margin: auto;
}
@ -975,18 +959,6 @@ body {
width: 100vw;
}
.w-1 {
width: 0.25rem;
}
.w-6 {
width: 1.5rem;
}
.w-32 {
width: 8rem;
}
.min-w-\[8rem\] {
min-width: 8rem;
}
@ -1012,10 +984,6 @@ body {
max-width: 24rem;
}
.max-w-28 {
max-width: 7rem;
}
.max-w-xs {
max-width: 20rem;
}
@ -1088,10 +1056,6 @@ body {
user-select: none;
}
.grid-cols-12 {
grid-template-columns: repeat(12, minmax(0, 1fr));
}
.flex-row {
flex-direction: row;
}
@ -1132,10 +1096,6 @@ body {
justify-content: space-between;
}
.justify-around {
justify-content: space-around;
}
.gap-1 {
gap: 0.25rem;
}
@ -1148,14 +1108,6 @@ body {
gap: 1rem;
}
.gap-3 {
gap: 0.75rem;
}
.gap-44 {
gap: 11rem;
}
.gap-x-16 {
-moz-column-gap: 4rem;
column-gap: 4rem;
@ -1169,10 +1121,6 @@ body {
row-gap: 2rem;
}
.gap-y-4 {
row-gap: 1rem;
}
.space-x-1 > :not([hidden]) ~ :not([hidden]) {
--tw-space-x-reverse: 0;
margin-right: calc(0.25rem * var(--tw-space-x-reverse));

View File

@ -8,80 +8,40 @@ import { Row, Table, TableState } from "@tanstack/react-table"
import { tableNameToItemName } from "app/lib/nameMaps"
import EditSubmissionDialog from "app/submission/edit"
export default function FormContextMenu({ table, row }: ComponentProps<"div"> & { table: Table<any>, row: Row<any> }) {
export default function FormContextMenu({ table, row, openEditDialog, openDeleteDialog }: ComponentProps<"div"> & { table: Table<any>, row: Row<any>, openEditDialog: (row: Row<any>) => void, openDeleteDialog: (row: Row<any>) => void }) {
const pathname = table.options.meta.pathname
const selectedRows = table.getSelectedRowModel().flatRows
const [dialog, setDialog] = useState<"edit" | "delete" | null>("delete")
return (
<Dialog modal={true}>
<ContextMenuContent >
{pathname !== "/submission" && selectedRows.length <= 1 ?
<ContextMenuContent >
{pathname !== "/submission" && selectedRows.length <= 1 ?
<>
<Link href={`${pathname}/${row.original.id}`}>
<ContextMenuItem>Inspect</ContextMenuItem>
</Link>
</>
: ""
}
{
pathname === "/submission" ?
<>
<Link href={`${pathname}/${row.original.id}`}>
<ContextMenuItem>Inspect</ContextMenuItem>
</Link>
<ContextMenuItem onClick={() => openEditDialog(row)}>
Edit
</ContextMenuItem>
</>
: ""
}
}
{
pathname === "/submission" ?
<>
<DialogTrigger asChild>
<ContextMenuItem onClick={() => setDialog("edit")}>
Edit
</ContextMenuItem>
</DialogTrigger>
</>
: ""
}
{
selectedRows.length > 0 ?
<ContextMenuItem onClick={() => { table.resetRowSelection() }}>Deselect</ContextMenuItem>
: ""
}
<ContextMenuSeparator />
<DialogTrigger asChild>
<ContextMenuItem className="text-destructive" onClick={() => setDialog("delete")}>Delete</ContextMenuItem>
</DialogTrigger>
</ContextMenuContent>
<DialogContent>
{
dialog === "delete" ?
<>
<DialogHeader>
<DialogTitle>Are you sure?</DialogTitle>
<DialogDescription>
Deleting a {tableNameToItemName(table.options.meta.tableName)} cannot be undone!
</DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose asChild>
<Button variant="destructive"
onClick={() => {
deleteRecord(row.original.id, pathname)
}}>Yes, delete it!
</Button>
</DialogClose>
</DialogFooter>
</>
: dialog === "edit" ?
<EditSubmissionDialog
stories={table.options.meta.stories}
pubs={table.options.meta.pubs}
responses={table.options.meta.responses}
defaults={row.original}
/>
:
<>
<DialogTitle>Edit/delete dialog</DialogTitle>
</>
}
</DialogContent>
</Dialog>
{
selectedRows.length > 0 ?
<ContextMenuItem onClick={() => { table.resetRowSelection() }}>Deselect</ContextMenuItem>
: ""
}
<ContextMenuSeparator />
<ContextMenuItem className="text-destructive" onClick={() => openDeleteDialog(row)}>Delete</ContextMenuItem>
</ContextMenuContent>
)
}

View File

@ -26,7 +26,8 @@ import {
getFilteredRowModel,
getCoreRowModel,
getPaginationRowModel,
useReactTable
useReactTable,
Row
} from "@tanstack/react-table"
import {
@ -40,13 +41,15 @@ import {
import { EyeIcon, Trash2 } from "lucide-react"
import { usePathname } from "next/navigation"
import FormContextMenu from "./contextMenu"
import { deleteRecords } from "app/lib/del"
import { deleteRecord, deleteRecords } from "app/lib/del"
import { Pathname } from "app/types"
import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTrigger } from "@/components/ui/dialog"
import pluralize from "app/lib/pluralize"
import { updateField } from "app/lib/update"
import { tableNameToItemName } from "app/lib/nameMaps"
import { Genre, Pub, Response, Story } from "@prisma/client"
import EditSubmissionDialog from "app/submission/edit"
import { DialogTitle } from "@radix-ui/react-dialog"
export interface DataTableProps<TData, TValue> {
columns: ColumnDef<TData, TValue>[]
@ -65,6 +68,9 @@ export function DataTable<TData, TValue>({
genres
}: DataTableProps<TData, TValue> & ComponentProps<"div"> & { tableName: string, stories?: Story[], pubs?: Pub[], responses?: Response[], genres?: Genre[] }) {
//STATE
const [isEditDialogVisible, setIsEditDialogVisible] = useState<boolean>(false)
const [isDeleteDialogVisible, setIsDeleteDialogVisible] = useState<boolean>(false)
const [dialogRow, SetDialogRow] = useState<Row<any> | null>(null)
const [sorting, setSorting] = useState<SortingState>([])
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>(
[]
@ -103,6 +109,14 @@ export function DataTable<TData, TValue>({
})
function openEditDialog(row) {
setIsEditDialogVisible(true)
SetDialogRow(row)
}
function openDeleteDialog(row) {
setIsDeleteDialogVisible(true)
SetDialogRow(row)
}
const [filterBy, setFilterBy] = useState(table.getAllColumns()[0])
@ -143,6 +157,39 @@ export function DataTable<TData, TValue>({
{children}
<Dialog open={isEditDialogVisible} onOpenChange={setIsEditDialogVisible}>
<DialogContent>
<EditSubmissionDialog
stories={stories}
pubs={pubs}
responses={responses}
defaults={dialogRow?.original}
/>
</DialogContent>
</Dialog>
<Dialog open={isDeleteDialogVisible} onOpenChange={setIsDeleteDialogVisible}>
<DialogContent>
<DialogHeader>
<DialogTitle>Are you sure?</DialogTitle>
<DialogDescription>
Deleting a {tableNameToItemName(tableName)} cannot be undone!
</DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose asChild>
<Button variant="destructive"
onClick={() => {
deleteRecord(dialogRow.original.id, pathname)
}}>Yes, delete it!
</Button>
</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
<Dialog>
<DialogTrigger asChild>
<Button variant="destructive" disabled={!(table.getIsSomeRowsSelected() || table.getIsAllRowsSelected())}>
@ -227,12 +274,18 @@ export function DataTable<TData, TValue>({
<TableBody>
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<ContextMenu onOpenChange={open => setIsContextMenuOpen(open)} key={row.id + "contextMenu"}>
<ContextMenu key={row.id + "contextMenu"}>
<ContextMenuTrigger asChild>
<TableRow
key={row.id}
data-state={row.getIsSelected() && "selected"}
tabIndex={0}
onDoubleClick={() => {
if (tableName === "sub") {
openEditDialog(row)
}
}
}
>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id}>
@ -243,6 +296,8 @@ export function DataTable<TData, TValue>({
key={"formContextMenu" + row.id}
row={row}
table={table}
openEditDialog={openEditDialog}
openDeleteDialog={openDeleteDialog}
/>
</TableRow>
</ContextMenuTrigger>

View File

@ -83,7 +83,7 @@ export function TextInputCell(props: CellContext<any, any>) {
<FormControl
>
<Input
className="w-fit"
className="w-full"
type="text"
autoFocus={true}
{...field}