fix multi-delete
This commit is contained in:
parent
1fca1a2b81
commit
97a537f5a2
BIN
prisma/dev.db
BIN
prisma/dev.db
Binary file not shown.
|
@ -22,12 +22,12 @@ export async function deleteRecord(id: number, pathname: Pathname) {
|
|||
export async function deleteRecords(ids: number[], pathname: "/story" | "/publication" | "/submission") {
|
||||
const table = tableMap[pathname]
|
||||
ids.forEach(async (id) => {
|
||||
const res = await prisma.story.delete({
|
||||
const res = await prisma[table].delete({
|
||||
where: { id }
|
||||
})
|
||||
console.log(`deleted from ${table}: ${res.id}`)
|
||||
})
|
||||
|
||||
|
||||
revalidatePath(pathname)
|
||||
redirect(pathname)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
export default function pluralize(word: "story" | "publication" | "submission"): string {
|
||||
const map = {
|
||||
story: "stories",
|
||||
publication: "publications",
|
||||
submission: "submissions"
|
||||
}
|
||||
return map[word]
|
||||
}
|
|
@ -446,6 +446,60 @@ video {
|
|||
display: none;
|
||||
}
|
||||
|
||||
:root {
|
||||
--background: 220 0% 96%;
|
||||
--foreground: 222.2 84% 4.9%;
|
||||
--muted: 210 40% 96.1%;
|
||||
--muted-foreground: 215.4 16.3% 46.9%;
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 222.2 84% 4.9%;
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 222.2 84% 4.9%;
|
||||
--border: 214.3 31.8% 91.4%;
|
||||
--input: 214.3 31.8% 91.4%;
|
||||
--primary: 144.91 90% 32%;
|
||||
--primary-foreground: 75 10% 97.84%;
|
||||
--secondary: 240 0% 100%;
|
||||
--secondary-foreground: 150 95% 30%;
|
||||
--accent: 150 55% 95%;
|
||||
--accent-foreground: 155 100% 20%;
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 210 0% 100%;
|
||||
--ring: 150 100% 40%;
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: 222.2 40% 4%;
|
||||
--foreground: 210 40% 98%;
|
||||
--muted: 217.2 32.6% 17.5%;
|
||||
--muted-foreground: 215 20.2% 65.1%;
|
||||
--popover: 230 25% 10%;
|
||||
--popover-foreground: 210 40% 98%;
|
||||
--card: 222.2 20% 6%;
|
||||
--card-foreground: 210 40% 98%;
|
||||
--border: 217.2 20% 10%;
|
||||
--input: 217.2 32.6% 17.5%;
|
||||
--primary: 155 70% 35%;
|
||||
--primary-foreground: 80 10% 97.84%;
|
||||
--secondary: 200 50% 98%;
|
||||
--secondary-foreground: 155 85% 30%;
|
||||
--accent: 170 60% 10%;
|
||||
--accent-foreground: 155 60% 65%;
|
||||
--destructive: 5 90% 65%;
|
||||
--destructive-foreground: 0 100% 10%;
|
||||
--ring: 160 90% 45%;
|
||||
}
|
||||
|
||||
* {
|
||||
border-color: hsl(var(--border));
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: hsl(var(--background));
|
||||
color: hsl(var(--foreground));
|
||||
}
|
||||
|
||||
*, ::before, ::after {
|
||||
--tw-border-spacing-x: 0;
|
||||
--tw-border-spacing-y: 0;
|
||||
|
@ -652,22 +706,6 @@ video {
|
|||
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;
|
||||
}
|
||||
|
@ -872,6 +910,10 @@ video {
|
|||
width: 1rem;
|
||||
}
|
||||
|
||||
.w-40 {
|
||||
width: 10rem;
|
||||
}
|
||||
|
||||
.w-5\/6 {
|
||||
width: 83.333333%;
|
||||
}
|
||||
|
@ -917,14 +959,6 @@ video {
|
|||
width: 100vw;
|
||||
}
|
||||
|
||||
.w-36 {
|
||||
width: 9rem;
|
||||
}
|
||||
|
||||
.w-40 {
|
||||
width: 10rem;
|
||||
}
|
||||
|
||||
.min-w-\[8rem\] {
|
||||
min-width: 8rem;
|
||||
}
|
||||
|
@ -938,11 +972,6 @@ video {
|
|||
min-width: fit-content;
|
||||
}
|
||||
|
||||
.min-w-min {
|
||||
min-width: -moz-min-content;
|
||||
min-width: min-content;
|
||||
}
|
||||
|
||||
.max-w-full {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
@ -1023,10 +1052,6 @@ video {
|
|||
user-select: none;
|
||||
}
|
||||
|
||||
.grid-cols-12 {
|
||||
grid-template-columns: repeat(12, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
@ -1055,10 +1080,6 @@ video {
|
|||
align-items: baseline;
|
||||
}
|
||||
|
||||
.justify-start {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.justify-end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
@ -1394,6 +1415,10 @@ video {
|
|||
padding-right: 0.5rem;
|
||||
}
|
||||
|
||||
.pr-4 {
|
||||
padding-right: 1rem;
|
||||
}
|
||||
|
||||
.pr-8 {
|
||||
padding-right: 2rem;
|
||||
}
|
||||
|
@ -1402,10 +1427,6 @@ video {
|
|||
padding-top: 0.25rem;
|
||||
}
|
||||
|
||||
.pr-4 {
|
||||
padding-right: 1rem;
|
||||
}
|
||||
|
||||
.text-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
@ -1668,6 +1689,194 @@ video {
|
|||
animation-duration: 200ms;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
/* @layer base { */
|
||||
|
||||
/* :root { */
|
||||
|
||||
/* --background: 43 62% 98%; */
|
||||
|
||||
/* --foreground: 43 73% 2%; */
|
||||
|
||||
/* --muted: 43 24% 85%; */
|
||||
|
||||
/* --muted-foreground: 43 10% 37%; */
|
||||
|
||||
/* --popover: 43 62% 98%; */
|
||||
|
||||
/* --popover-foreground: 43 73% 2%; */
|
||||
|
||||
/* --card: 43 62% 98%; */
|
||||
|
||||
/* --card-foreground: 43 73% 2%; */
|
||||
|
||||
/* --border: 43 15% 91%; */
|
||||
|
||||
/* --input: 43 15% 91%; */
|
||||
|
||||
/* --primary: 43 50% 69%; */
|
||||
|
||||
/* --primary-foreground: 43 50% 9%; */
|
||||
|
||||
/* --secondary: 43 6% 92%; */
|
||||
|
||||
/* --secondary-foreground: 43 6% 32%; */
|
||||
|
||||
/* --accent: 43 13% 83%; */
|
||||
|
||||
/* --accent-foreground: 43 13% 23%; */
|
||||
|
||||
/* --destructive: 8 84% 20%; */
|
||||
|
||||
/* --destructive-foreground: 8 84% 80%; */
|
||||
|
||||
/* --ring: 43 50% 69%; */
|
||||
|
||||
/* --radius: 0.5rem; */
|
||||
|
||||
/* } */
|
||||
|
||||
/**/
|
||||
|
||||
/* .dark { */
|
||||
|
||||
/* --background: 43 48% 4%; */
|
||||
|
||||
/* --foreground: 43 26% 97%; */
|
||||
|
||||
/* --muted: 43 24% 15%; */
|
||||
|
||||
/* --muted-foreground: 43 10% 63%; */
|
||||
|
||||
/* --popover: 43 48% 4%; */
|
||||
|
||||
/* --popover-foreground: 43 26% 97%; */
|
||||
|
||||
/* --card: 43 48% 4%; */
|
||||
|
||||
/* --card-foreground: 43 26% 97%; */
|
||||
|
||||
/* --border: 43 15% 13%; */
|
||||
|
||||
/* --input: 43 15% 13%; */
|
||||
|
||||
/* --primary: 43 50% 69%; */
|
||||
|
||||
/* --primary-foreground: 43 50% 9%; */
|
||||
|
||||
/* --secondary: 43 8% 18%; */
|
||||
|
||||
/* --secondary-foreground: 43 8% 78%; */
|
||||
|
||||
/* --accent: 43 14% 23%; */
|
||||
|
||||
/* --accent-foreground: 43 14% 83%; */
|
||||
|
||||
/* --destructive: 8 84% 52%; */
|
||||
|
||||
/* --destructive-foreground: 0 0% 100%; */
|
||||
|
||||
/* --ring: 43 50% 69%; */
|
||||
|
||||
/* } */
|
||||
|
||||
/* } */
|
||||
|
||||
/**/
|
||||
|
||||
/* @layer base { */
|
||||
|
||||
/* :root { */
|
||||
|
||||
/* --background: 258 70% 100%; */
|
||||
|
||||
/* --foreground: 258 77% 0%; */
|
||||
|
||||
/* --muted: 258 29% 85%; */
|
||||
|
||||
/* --muted-foreground: 258 10% 40%; */
|
||||
|
||||
/* --popover: 258 70% 100%; */
|
||||
|
||||
/* --popover-foreground: 258 77% 0%; */
|
||||
|
||||
/* --card: 258 70% 100%; */
|
||||
|
||||
/* --card-foreground: 258 77% 0%; */
|
||||
|
||||
/* --border: 220 13% 91%; */
|
||||
|
||||
/* --input: 220 13% 91%; */
|
||||
|
||||
/* --primary: 258 58% 37%; */
|
||||
|
||||
/* --primary-foreground: 258 58% 97%; */
|
||||
|
||||
/* --secondary: 258 19% 81%; */
|
||||
|
||||
/* --secondary-foreground: 258 19% 21%; */
|
||||
|
||||
/* --accent: 258 19% 81%; */
|
||||
|
||||
/* --accent-foreground: 258 19% 21%; */
|
||||
|
||||
/* --destructive: 19 98% 27%; */
|
||||
|
||||
/* --destructive-foreground: 19 98% 87%; */
|
||||
|
||||
/* --ring: 258 58% 37%; */
|
||||
|
||||
/* --radius: 0.5rem; */
|
||||
|
||||
/* } */
|
||||
|
||||
/**/
|
||||
|
||||
/* .dark { */
|
||||
|
||||
/* --background: 258 53% 3%; */
|
||||
|
||||
/* --foreground: 258 40% 97%; */
|
||||
|
||||
/* --muted: 258 29% 15%; */
|
||||
|
||||
/* --muted-foreground: 258 10% 60%; */
|
||||
|
||||
/* --popover: 258 53% 3%; */
|
||||
|
||||
/* --popover-foreground: 258 40% 97%; */
|
||||
|
||||
/* --card: 258 53% 3%; */
|
||||
|
||||
/* --card-foreground: 258 40% 97%; */
|
||||
|
||||
/* --border: 215 27.9% 16.9%; */
|
||||
|
||||
/* --input: 215 27.9% 16.9%; */
|
||||
|
||||
/* --primary: 258 58% 37%; */
|
||||
|
||||
/* --primary-foreground: 258 58% 97%; */
|
||||
|
||||
/* --secondary: 258 15% 10%; */
|
||||
|
||||
/* --secondary-foreground: 258 15% 70%; */
|
||||
|
||||
/* --accent: 258 15% 10%; */
|
||||
|
||||
/* --accent-foreground: 258 15% 70%; */
|
||||
|
||||
/* --destructive: 19 98% 46%; */
|
||||
|
||||
/* --destructive-foreground: 0 0% 100%; */
|
||||
|
||||
/* --ring: 258 58% 37%; */
|
||||
|
||||
/* } */
|
||||
|
||||
/* } */
|
||||
|
||||
.file\:border-0::file-selector-button {
|
||||
border-width: 0px;
|
||||
}
|
||||
|
|
|
@ -11,9 +11,12 @@ export default function FormContextMenu({ pathname, row }) {
|
|||
return (
|
||||
<Dialog>
|
||||
<ContextMenuContent >
|
||||
<Link href={`${pathname}/${row.original.id}`}>
|
||||
<ContextMenuItem>Inspect</ContextMenuItem>
|
||||
</Link>
|
||||
{pathname !== "/submission" ?
|
||||
<Link href={`${pathname}/${row.original.id}`}>
|
||||
<ContextMenuItem>Inspect</ContextMenuItem>
|
||||
</Link>
|
||||
: ""
|
||||
}
|
||||
<ContextMenuSeparator />
|
||||
<DialogTrigger asChild>
|
||||
<ContextMenuItem className="text-destructive">Delete</ContextMenuItem>
|
||||
|
|
|
@ -42,6 +42,8 @@ import { usePathname } from "next/navigation"
|
|||
import FormContextMenu from "./contextMenu"
|
||||
import { 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"
|
||||
|
||||
interface DataTableProps<TData, TValue> {
|
||||
columns: ColumnDef<TData, TValue>[]
|
||||
|
@ -118,17 +120,36 @@ export function DataTable<TData, TValue>({
|
|||
|
||||
{children}
|
||||
|
||||
<Button variant="destructive" disabled={!table.getIsSomeRowsSelected()}
|
||||
onClick={() => {
|
||||
const selectedRows = table.getState().rowSelection
|
||||
const rowIds = Object.keys(selectedRows)
|
||||
const recordIds = rowIds.map(id => Number(table.getRow(id).original.id))
|
||||
console.table(recordIds)
|
||||
deleteRecords(recordIds, pathname)
|
||||
}}
|
||||
>
|
||||
<Trash2 />
|
||||
</Button>
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Button variant="destructive" disabled={!(table.getIsSomeRowsSelected() || table.getIsAllRowsSelected())}>
|
||||
<Trash2 />
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
{`Delete ${Object.keys(table.getState().rowSelection).length} ${pluralize(pathname.slice(1))}?`}
|
||||
</DialogHeader>
|
||||
<DialogDescription>
|
||||
{`Deleting ${pluralize(pathname.slice(1))} cannot be undone!`}
|
||||
</DialogDescription>
|
||||
<DialogFooter>
|
||||
<DialogClose asChild>
|
||||
<Button variant="destructive"
|
||||
onClick={() => {
|
||||
const selectedRows = table.getState().rowSelection
|
||||
const rowIds = Object.keys(selectedRows)
|
||||
const recordIds = rowIds.map(id => Number(table.getRow(id).original.id))
|
||||
console.table(recordIds)
|
||||
deleteRecords(recordIds, pathname)
|
||||
}}>
|
||||
Yes, delete them!</Button>
|
||||
</DialogClose>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
|
||||
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
|
|
Loading…
Reference in New Issue