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") {
|
export async function deleteRecords(ids: number[], pathname: "/story" | "/publication" | "/submission") {
|
||||||
const table = tableMap[pathname]
|
const table = tableMap[pathname]
|
||||||
ids.forEach(async (id) => {
|
ids.forEach(async (id) => {
|
||||||
const res = await prisma.story.delete({
|
const res = await prisma[table].delete({
|
||||||
where: { id }
|
where: { id }
|
||||||
})
|
})
|
||||||
console.log(`deleted from ${table}: ${res.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;
|
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 {
|
*, ::before, ::after {
|
||||||
--tw-border-spacing-x: 0;
|
--tw-border-spacing-x: 0;
|
||||||
--tw-border-spacing-y: 0;
|
--tw-border-spacing-y: 0;
|
||||||
|
@ -652,22 +706,6 @@ video {
|
||||||
z-index: 100;
|
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 {
|
.m-auto {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
@ -872,6 +910,10 @@ video {
|
||||||
width: 1rem;
|
width: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.w-40 {
|
||||||
|
width: 10rem;
|
||||||
|
}
|
||||||
|
|
||||||
.w-5\/6 {
|
.w-5\/6 {
|
||||||
width: 83.333333%;
|
width: 83.333333%;
|
||||||
}
|
}
|
||||||
|
@ -917,14 +959,6 @@ video {
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
.w-36 {
|
|
||||||
width: 9rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w-40 {
|
|
||||||
width: 10rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.min-w-\[8rem\] {
|
.min-w-\[8rem\] {
|
||||||
min-width: 8rem;
|
min-width: 8rem;
|
||||||
}
|
}
|
||||||
|
@ -938,11 +972,6 @@ video {
|
||||||
min-width: fit-content;
|
min-width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
.min-w-min {
|
|
||||||
min-width: -moz-min-content;
|
|
||||||
min-width: min-content;
|
|
||||||
}
|
|
||||||
|
|
||||||
.max-w-full {
|
.max-w-full {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
@ -1023,10 +1052,6 @@ video {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid-cols-12 {
|
|
||||||
grid-template-columns: repeat(12, minmax(0, 1fr));
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex-row {
|
.flex-row {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
|
@ -1055,10 +1080,6 @@ video {
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.justify-start {
|
|
||||||
justify-content: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.justify-end {
|
.justify-end {
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
|
@ -1394,6 +1415,10 @@ video {
|
||||||
padding-right: 0.5rem;
|
padding-right: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pr-4 {
|
||||||
|
padding-right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
.pr-8 {
|
.pr-8 {
|
||||||
padding-right: 2rem;
|
padding-right: 2rem;
|
||||||
}
|
}
|
||||||
|
@ -1402,10 +1427,6 @@ video {
|
||||||
padding-top: 0.25rem;
|
padding-top: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pr-4 {
|
|
||||||
padding-right: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-left {
|
.text-left {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
@ -1668,6 +1689,194 @@ video {
|
||||||
animation-duration: 200ms;
|
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 {
|
.file\:border-0::file-selector-button {
|
||||||
border-width: 0px;
|
border-width: 0px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,9 +11,12 @@ export default function FormContextMenu({ pathname, row }) {
|
||||||
return (
|
return (
|
||||||
<Dialog>
|
<Dialog>
|
||||||
<ContextMenuContent >
|
<ContextMenuContent >
|
||||||
|
{pathname !== "/submission" ?
|
||||||
<Link href={`${pathname}/${row.original.id}`}>
|
<Link href={`${pathname}/${row.original.id}`}>
|
||||||
<ContextMenuItem>Inspect</ContextMenuItem>
|
<ContextMenuItem>Inspect</ContextMenuItem>
|
||||||
</Link>
|
</Link>
|
||||||
|
: ""
|
||||||
|
}
|
||||||
<ContextMenuSeparator />
|
<ContextMenuSeparator />
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<ContextMenuItem className="text-destructive">Delete</ContextMenuItem>
|
<ContextMenuItem className="text-destructive">Delete</ContextMenuItem>
|
||||||
|
|
|
@ -42,6 +42,8 @@ import { usePathname } from "next/navigation"
|
||||||
import FormContextMenu from "./contextMenu"
|
import FormContextMenu from "./contextMenu"
|
||||||
import { deleteRecords } from "app/lib/del"
|
import { deleteRecords } from "app/lib/del"
|
||||||
import { Pathname } from "app/types"
|
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> {
|
interface DataTableProps<TData, TValue> {
|
||||||
columns: ColumnDef<TData, TValue>[]
|
columns: ColumnDef<TData, TValue>[]
|
||||||
|
@ -118,17 +120,36 @@ export function DataTable<TData, TValue>({
|
||||||
|
|
||||||
{children}
|
{children}
|
||||||
|
|
||||||
<Button variant="destructive" disabled={!table.getIsSomeRowsSelected()}
|
<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={() => {
|
onClick={() => {
|
||||||
const selectedRows = table.getState().rowSelection
|
const selectedRows = table.getState().rowSelection
|
||||||
const rowIds = Object.keys(selectedRows)
|
const rowIds = Object.keys(selectedRows)
|
||||||
const recordIds = rowIds.map(id => Number(table.getRow(id).original.id))
|
const recordIds = rowIds.map(id => Number(table.getRow(id).original.id))
|
||||||
console.table(recordIds)
|
console.table(recordIds)
|
||||||
deleteRecords(recordIds, pathname)
|
deleteRecords(recordIds, pathname)
|
||||||
}}
|
}}>
|
||||||
>
|
Yes, delete them!</Button>
|
||||||
<Trash2 />
|
</DialogClose>
|
||||||
</Button>
|
</DialogFooter>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
|
|
Loading…
Reference in New Issue