Skip to content

Commit

Permalink
[BDGR-85] Add buttons to edit/delete show (#682)
Browse files Browse the repository at this point in the history
* [BDGR-85] Add buttons to edit/delete show

* Rogue TODO

* Update tests (and sr-only text)

* more test updates

* Add playwright/.auth to gitignore
  • Loading branch information
markspolakovs authored Oct 17, 2024
1 parent 89949ba commit 31edef0
Show file tree
Hide file tree
Showing 13 changed files with 203 additions and 11 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ node_modules/

coverage/
*/coverage/
playwright/.auth/
36 changes: 36 additions & 0 deletions server/app/shows/[show_id]/DeletButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"use client";

import {
Popover,
PopoverTrigger,
PopoverContent,
} from "@badger/components/popover";
import { useTransition } from "react";
import { deletShow } from "./actions";
import Button from "@badger/components/button";

export function ShowDeletButton(props: { showID: number }) {
const [isPending, startTransition] = useTransition();
return (
<Popover>
<PopoverTrigger asChild>
<Button color="danger">
Delet <span className="sr-only">Show</span>
</Button>
</PopoverTrigger>
<PopoverContent>
<Button
color="danger"
onClick={() => {
startTransition(async () => {
await deletShow(props.showID);
});
}}
disabled={isPending}
>
You sure boss?
</Button>
</PopoverContent>
</Popover>
);
}
8 changes: 6 additions & 2 deletions server/app/shows/[show_id]/ShowItemsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,9 @@ const RundownRow = forwardRef<
</TableCell>
<TableCell>
<Button size="small" asChild>
<Link href={`/shows/${item.showId}/rundown/${item.id}`}>Edit</Link>
<Link href={`/shows/${item.showId}/rundown/${item.id}`}>
Edit <span className="sr-only">Rundown</span>
</Link>
</Button>
</TableCell>
<TableCell>
Expand Down Expand Up @@ -258,7 +260,9 @@ const ContinuityItemRow = forwardRef<
<TableCell>
<Popover open={isEditing} onOpenChange={setIsEditing}>
<PopoverTrigger asChild>
<Button color="primary">Edit</Button>
<Button color="primary">
Edit <span className="sr-only">Continuity Item</span>
</Button>
</PopoverTrigger>
<PopoverContent>
<Form
Expand Down
14 changes: 13 additions & 1 deletion server/app/shows/[show_id]/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { db } from "@/lib/db";
import { revalidatePath } from "next/cache";
import { notFound } from "next/navigation";
import { notFound, redirect } from "next/navigation";
import { z } from "zod";
import { editContinuityItemSchema } from "./schema";
import { FormResponse } from "@/components/Form";
Expand All @@ -21,6 +21,7 @@ import type {
MediaMetaUploadValue,
} from "@/components/Metadata";
import { getPublicTusEndpoint, uploadUrlToPath } from "@/lib/tus";
import { requirePermission } from "@/lib/auth";

export async function revalidateIfChanged(showID: number, version: number) {
const show = await db.show.findUnique({
Expand All @@ -39,6 +40,17 @@ export async function revalidateIfChanged(showID: number, version: number) {
}
}

export async function deletShow(showID: number) {
await requirePermission("ManageShows");
await db.show.delete({
where: {
id: showID,
},
});
revalidatePath("/");
redirect("/");
}

export async function addItem(
showID: number,
type: "rundown" | "continuity_item",
Expand Down
29 changes: 29 additions & 0 deletions server/app/shows/[show_id]/edit/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"use server";

import { schema } from "./schema";
import { revalidatePath } from "next/cache";
import { db } from "@/lib/db";
import { FormResponse } from "@/components/Form";
import { zodErrorResponse } from "@/components/FormServerHelpers";
import { z } from "zod";
import { requirePermission } from "@/lib/auth";

export async function doEdit(
data: z.infer<typeof schema>,
): Promise<FormResponse> {
await requirePermission("ManageShows");
const result = schema.safeParse(data);
if (!result.success) {
return zodErrorResponse(result.error);
}
const res = await db.show.update({
where: { id: result.data.id },
data: {
name: result.data.name,
start: result.data.start,
},
});
revalidatePath(`/`);
revalidatePath(`/shows/${res.id}`);
return { ok: true, id: res.id };
}
35 changes: 35 additions & 0 deletions server/app/shows/[show_id]/edit/form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"use client";

import { Show } from "@badger/prisma/client";
import { schema } from "./schema";
import { DatePickerField, Field, HiddenField } from "@/components/FormFields";
import { doEdit } from "./actions";
import Form from "@/components/Form";
import { useRouter } from "next/navigation";

export function EditShowForm(props: { initialValues: Show }) {
const router = useRouter();
return (
<div>
<h1 className="text-4xl">Edit &apos;{props.initialValues.name}&apos;</h1>
<Form
action={doEdit}
schema={schema}
initialValues={props.initialValues}
onSuccess={(v) => {
router.push(`/shows/${v.id}`);
}}
submitLabel="Save"
>
<HiddenField name="id" value={props.initialValues.id.toString(10)} />
<Field name="name" label="Name" />
<DatePickerField
name="start"
label="Start"
showTimeSelect
timeIntervals={15}
/>
</Form>
</div>
);
}
22 changes: 22 additions & 0 deletions server/app/shows/[show_id]/edit/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { requirePermission } from "@/lib/auth";
import { db } from "@/lib/db";
import { notFound } from "next/navigation";
import { EditShowForm } from "./form";

export default async function EditShowDetailsForm({
params,
}: {
params: { show_id: string };
}) {
await requirePermission("ManageShows");
const show = await db.show.findFirst({
where: {
id: parseInt(params.show_id, 10),
},
});
if (!show) {
notFound();
}

return <EditShowForm initialValues={show} />;
}
10 changes: 10 additions & 0 deletions server/app/shows/[show_id]/edit/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { z } from "zod";
import { zfd } from "zod-form-data";

export const dateFormat = "YYYY-MM-DD HH:mm";

export const schema = zfd.formData({
id: z.coerce.number().int(),
name: z.string(),
start: z.coerce.date(),
});
9 changes: 9 additions & 0 deletions server/app/shows/[show_id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { PermissionGate } from "@/components/PermissionGate";
import Button from "@badger/components/button";
import Link from "next/link";
import { Poll } from "../../../components/Poll";
import { ShowDeletButton } from "./DeletButton";

// TODO: duplicated in rundown/id/page.ts
const pastShowsPromise = cache(
Expand Down Expand Up @@ -132,6 +133,14 @@ export default async function ShowPage(props: { params: { show_id: string } }) {
</Button>
</PermissionGate>
</FlagGate>
<PermissionGate permission="ManageShows">
<Button asChild>
<Link href={`/shows/${show.id}/edit`}>
Edit <span className="sr-only">Show</span>
</Link>
</Button>
<ShowDeletButton showID={show.id} />
</PermissionGate>
<TusEndpointProvider value={getTusEndpoint()}>
<MetadataFields
metadata={show.metadata}
Expand Down
3 changes: 2 additions & 1 deletion server/app/shows/create/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import { db } from "@/lib/db";
import { FormResponse } from "@/components/Form";
import { zodErrorResponse } from "@/components/FormServerHelpers";
import { z } from "zod";
import { requirePermission } from "@/lib/auth";

export async function create(
data: z.infer<typeof schema>,
): Promise<FormResponse> {
"use server";
await requirePermission("ManageShows");
const result = schema.safeParse(data);
if (!result.success) {
return zodErrorResponse(result.error);
Expand Down
18 changes: 12 additions & 6 deletions server/e2e/showItems.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,21 @@ test("add, reorder, remove items", async ({ showPage }) => {
await showPage.keyboard.press("ArrowDown");
await showPage.keyboard.press("Space");

await showPage.getByRole("button", { name: "Delet" }).nth(2).click();
await showPage
.getByRole("button", { name: "Delet", exact: true })
.nth(2)
.click();
await showPage.getByRole("button", { name: "You sure boss?" }).click();
await showPage.getByRole("dialog").waitFor({ state: "hidden" });

await showPage.getByRole("button", { name: "Delet" }).nth(1).click();
await showPage
.getByRole("button", { name: "Delet", exact: true })
.nth(1)
.click();
await showPage.getByRole("button", { name: "You sure boss?" }).click();
await showPage.getByRole("dialog").waitFor({ state: "hidden" });

await showPage.getByRole("button", { name: "Delet" }).click();
await showPage.getByRole("button", { name: "Delet", exact: true }).click();
await showPage.getByRole("button", { name: "You sure boss?" }).click();
await showPage.getByRole("dialog").waitFor({ state: "hidden" });

Expand All @@ -67,7 +73,7 @@ test("add rundown items + check runtime", async ({ showPage }) => {
await showPage.getByTestId("create-rundown").click();
await showPage.locator("body").press("Escape");

await showPage.getByRole("row").nth(1).getByText("Edit").click();
await showPage.getByRole("row").nth(1).getByText("Edit Rundown").click();

await showPage.waitForLoadState("domcontentloaded");

Expand Down Expand Up @@ -216,7 +222,7 @@ test("media/assets for long rundowns", async ({ showPage }) => {
await expect(showPage.getByLabel("Name")).toHaveValue("");
await showPage.locator("body").press("Escape");

await showPage.getByRole("link", { name: "Edit" }).click();
await showPage.getByRole("link", { name: "Edit Rundown" }).click();
await showPage.waitForURL("**/shows/*/rundown/*");

await showPage.getByRole("button", { name: "Add Segment" }).click();
Expand Down Expand Up @@ -291,7 +297,7 @@ test("asset upload failure (BDGR-54)", async ({ showPage }) => {
await expect(showPage.getByLabel("Name")).toHaveValue("");
await showPage.locator("body").press("Escape");

await showPage.getByRole("link", { name: "Edit" }).click();
await showPage.getByRole("link", { name: "Edit Rundown" }).click();
await showPage.waitForURL("**/shows/*/rundown/*");

await showPage.getByRole("button", { name: "New Category" }).click();
Expand Down
27 changes: 27 additions & 0 deletions server/e2e/shows.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,33 @@ test("create show", async ({ page }) => {
await expect(page.getByRole("heading", { name: "Test Show" })).toBeVisible();
});

test("edit show", async ({ page }) => {
await createShowAPI("Test Show");
await page.goto("/");
await page.getByRole("link", { name: "View/Edit" }).click();
await expect(page.getByRole("link", { name: "Edit Show" })).toBeVisible();
await page.getByRole("link", { name: "Edit Show" }).click();

await page.getByLabel("Name").fill("Edited Show");
await page.getByRole("button", { name: "Save" }).click();

await expect(
page.getByRole("heading", { name: "Edited Show" }),
).toBeVisible();
});

test("delet show", async ({ page }) => {
await createShowAPI("Test Show that will be delet shortly");
await page.goto("/");
await page.getByRole("link", { name: "View/Edit" }).click();
await page.getByRole("button", { name: "Delet" }).click();
await page.getByRole("button", { name: "You sure boss?" }).click();
await expect(page.getByRole("heading", { name: "Shows" })).toBeVisible();
await expect(
page.getByText("Test Show that will be delet shortly"),
).not.toBeAttached();
});

test("backwards pagination with many past shows (BDGR-154)", async ({
page,
}) => {
Expand Down
2 changes: 1 addition & 1 deletion server/microserver/scenarios/default/default.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ async function setupTestShow(page: Page) {
await page.getByRole("button", { name: "New Rundown" }).click();
await page.getByTestId("name-rundown").fill("Test Rundown");
await page.getByTestId("create-rundown").click();
await page.getByRole("link", { name: "Edit", exact: true }).click();
await page.getByRole("link", { name: "Edit Rundown", exact: true }).click();

await page.getByRole("button", { name: "Add Segment" }).click();
await page.getByLabel("Name").fill("Test VT");
Expand Down

0 comments on commit 31edef0

Please sign in to comment.