implement controlled edit / delete dialogs
This commit is contained in:
parent
e5d2aba207
commit
a204eec776
BIN
prisma/dev.db
BIN
prisma/dev.db
Binary file not shown.
|
@ -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));
|
||||
|
|
|
@ -8,14 +8,12 @@ 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 ?
|
||||
<>
|
||||
|
@ -29,11 +27,9 @@ export default function FormContextMenu({ table, row }: ComponentProps<"div"> &
|
|||
{
|
||||
pathname === "/submission" ?
|
||||
<>
|
||||
<DialogTrigger asChild>
|
||||
<ContextMenuItem onClick={() => setDialog("edit")}>
|
||||
<ContextMenuItem onClick={() => openEditDialog(row)}>
|
||||
Edit
|
||||
</ContextMenuItem>
|
||||
</DialogTrigger>
|
||||
</>
|
||||
: ""
|
||||
}
|
||||
|
@ -44,44 +40,8 @@ export default function FormContextMenu({ table, row }: ComponentProps<"div"> &
|
|||
: ""
|
||||
}
|
||||
<ContextMenuSeparator />
|
||||
<DialogTrigger asChild>
|
||||
<ContextMenuItem className="text-destructive" onClick={() => setDialog("delete")}>Delete</ContextMenuItem>
|
||||
</DialogTrigger>
|
||||
<ContextMenuItem className="text-destructive" onClick={() => openDeleteDialog(row)}>Delete</ContextMenuItem>
|
||||
</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>
|
||||
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -83,7 +83,7 @@ export function TextInputCell(props: CellContext<any, any>) {
|
|||
<FormControl
|
||||
>
|
||||
<Input
|
||||
className="w-fit"
|
||||
className="w-full"
|
||||
type="text"
|
||||
autoFocus={true}
|
||||
{...field}
|
||||
|
|
Loading…
Reference in New Issue