feat(web): show the publish control on the object detail

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-04 08:41:32 +02:00
parent 34d4ed2fd6
commit 7a8e7ff2d7
2 changed files with 12 additions and 1 deletions
+10 -1
View File
@@ -38,7 +38,9 @@ test("renders inventory-minimum fields, flexible values and visibility", async (
expect(await screen.findByText("Amphora")).toBeInTheDocument(); expect(await screen.findByText("Amphora")).toBeInTheDocument();
expect(screen.getByText("Vault 3")).toBeInTheDocument(); expect(screen.getByText("Vault 3")).toBeInTheDocument();
expect(screen.getByText("Bronze")).toBeInTheDocument(); // flexible field value expect(screen.getByText("Bronze")).toBeInTheDocument(); // flexible field value
expect(screen.getByText("Public")).toBeInTheDocument(); // "Public" appears in both the VisibilityBadge and the PublishControl stepper;
// scope the assertion to the badge element to avoid ambiguity.
expect(document.querySelector("[data-slot='badge']")).toHaveTextContent("Public");
}); });
test("shows a not-found state for a missing object", async () => { test("shows a not-found state for a missing object", async () => {
@@ -46,3 +48,10 @@ test("shows a not-found state for a missing object", async () => {
renderApp(tree(), { route: "/objects/does-not-exist" }); renderApp(tree(), { route: "/objects/does-not-exist" });
expect(await screen.findByText(/object not found/i)).toBeInTheDocument(); expect(await screen.findByText(/object not found/i)).toBeInTheDocument();
}); });
test("detail shows the publish control with the current visibility stepper", async () => {
// default GET /api/admin/objects/:id handler returns amphora (visibility "public")
renderApp(tree(), { route: "/objects/11111111-1111-1111-1111-111111111111" });
expect(await screen.findByText(/visibility/i)).toBeInTheDocument();
expect(await screen.findByRole("button", { name: /unpublish to internal/i })).toBeInTheDocument();
});
+2
View File
@@ -3,6 +3,7 @@ import { useTranslation } from "react-i18next";
import { useObject, useFieldDefinitions } from "../api/queries"; import { useObject, useFieldDefinitions } from "../api/queries";
import { DeleteObjectDialog } from "./delete-object-dialog"; import { DeleteObjectDialog } from "./delete-object-dialog";
import { PublishControl } from "./publish-control";
import { VisibilityBadge } from "./visibility-badge"; import { VisibilityBadge } from "./visibility-badge";
import { Skeleton } from "@/components/ui/skeleton"; import { Skeleton } from "@/components/ui/skeleton";
@@ -90,6 +91,7 @@ export function ObjectDetail() {
))} ))}
</div> </div>
)} )}
<PublishControl object={object} />
</div> </div>
); );
} }