feat(web): object-form visibility uses ui/Select (#51)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-08 06:00:21 +02:00
parent 09e9b3f4d4
commit 71d899cbdc
2 changed files with 23 additions and 14 deletions
+6 -5
View File
@@ -1,5 +1,5 @@
import { expect, test, vi } from "vitest";
import { fireEvent, screen, waitFor } from "@testing-library/react";
import { fireEvent, screen, waitFor, within } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { renderApp } from "../test/render";
import { ObjectForm } from "./object-form";
@@ -13,10 +13,11 @@ test("create mode: shows visibility (draft/internal only) and submits assembled
await userEvent.type(screen.getByLabelText(/^name/i), "Amphora");
await userEvent.type(screen.getByLabelText(/inscription/i), "To the gods");
const visibility = screen.getByLabelText(/visibility/i) as HTMLSelectElement;
expect([...visibility.options].map((o) => o.value)).toEqual(expect.arrayContaining(["draft", "internal"]));
expect([...visibility.options].map((o) => o.value)).not.toContain("public");
await userEvent.click(screen.getByRole("combobox", { name: /visibility/i })); // open
expect(await within(document.body).findByRole("option", { name: /draft/i })).toBeInTheDocument();
expect(within(document.body).getByRole("option", { name: /internal/i })).toBeInTheDocument();
expect(within(document.body).queryByRole("option", { name: /public/i })).not.toBeInTheDocument();
await userEvent.keyboard("{Escape}"); // close, keep default draft
await userEvent.click(screen.getByRole("button", { name: /create object/i }));
await waitFor(() => expect(onSubmit).toHaveBeenCalledOnce());
const values = onSubmit.mock.calls[0][0];
+17 -9
View File
@@ -1,5 +1,5 @@
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { Controller, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { useFieldDefinitions } from "../api/queries";
@@ -11,6 +11,7 @@ import { useUnsavedChanges } from "../lib/use-unsaved-changes";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
export type ObjectCore = {
object_number: string;
@@ -176,14 +177,21 @@ export function ObjectForm({
<div className="space-y-1">
<Label htmlFor="visibility">{t("form.visibility")}</Label>
<select
id="visibility"
className="w-full rounded-md border px-2 py-1 text-sm"
{...register("visibility")}
>
<option value="draft">{t("form.draft")}</option>
<option value="internal">{t("form.internal")}</option>
</select>
<Controller
control={form.control}
name="visibility"
render={({ field }) => (
<Select value={field.value} onValueChange={field.onChange}>
<SelectTrigger id="visibility">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="draft">{t("form.draft")}</SelectItem>
<SelectItem value="internal">{t("form.internal")}</SelectItem>
</SelectContent>
</Select>
)}
/>
</div>
)}