From a58f7d337096e43745162e1c2836206ebd1e74a9 Mon Sep 17 00:00:00 2001 From: Ethan <39577870+ethanndickson@users.noreply.github.com> Date: Tue, 25 Aug 2026 17:23:08 +0100 Subject: [PATCH] fix(site): clarify chat model permission labels (#28579) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Renames chat model sharing controls to permissions terminology so the UI reflects that administrators are managing model access. Uses “Use” as the user-facing role while preserving the backend `read` ACL value, and updates the Storybook interactions for the new labels. (cherry picked from commit 816f6fbeef0254d49b16fe975a7a499a4ffa699b) --- .../ChatModelSharingDialog.stories.tsx | 57 ++++++++++++------- .../components/ChatModelSharingDialog.tsx | 18 +++--- .../components/ModelForm.stories.tsx | 4 +- .../ModelsPage/components/ModelFormHeader.tsx | 6 +- 4 files changed, 51 insertions(+), 34 deletions(-) diff --git a/site/src/pages/AISettingsPage/ModelsPage/components/ChatModelSharingDialog.stories.tsx b/site/src/pages/AISettingsPage/ModelsPage/components/ChatModelSharingDialog.stories.tsx index 3c3fb612092..568052bcf0d 100644 --- a/site/src/pages/AISettingsPage/ModelsPage/components/ChatModelSharingDialog.stories.tsx +++ b/site/src/pages/AISettingsPage/ModelsPage/components/ChatModelSharingDialog.stories.tsx @@ -92,7 +92,7 @@ const ReopenableSharingDialog = () => { return ( <> { const body = within(canvasElement.ownerDocument.body); expect( - await body.findByText("No shared members or groups yet"), + await body.findByRole("dialog", { name: "Model permissions" }), + ).toHaveAttribute("data-state", "open"); + expect( + body.getByText( + `Manage which organization members and groups can use ${mockGPT5.display_name}.`, + ), ).toBeInTheDocument(); - expect(body.getByRole("button", { name: "Save sharing" })).toBeDisabled(); + expect( + body.getByText("No members or groups have permission yet"), + ).toBeInTheDocument(); + expect( + body.getByRole("button", { name: "Save permissions" }), + ).toBeDisabled(); }, }; @@ -137,7 +147,7 @@ export const Loading: Story = { play: async ({ canvasElement }) => { const body = within(canvasElement.ownerDocument.body); expect(await body.findByRole("status")).toHaveTextContent( - "Loading model sharing", + "Loading model permissions", ); }, }; @@ -147,7 +157,9 @@ export const LoadError: Story = { play: async ({ canvasElement }) => { const body = within(canvasElement.ownerDocument.body); expect(await body.findByText("Unable to load ACL")).toBeInTheDocument(); - expect(body.getByRole("button", { name: "Save sharing" })).toBeDisabled(); + expect( + body.getByRole("button", { name: "Save permissions" }), + ).toBeDisabled(); }, }; @@ -161,12 +173,12 @@ export const AddUser: Story = { new RegExp(MockOrganizationMember2.email, "i"), ); - expect( - body.getByRole("row", { - name: new RegExp(MockOrganizationMember2.username, "i"), - }), - ).toBeVisible(); - const saveButton = body.getByRole("button", { name: "Save sharing" }); + const userRow = body.getByRole("row", { + name: new RegExp(MockOrganizationMember2.username, "i"), + }); + expect(userRow).toBeVisible(); + expect(userRow).toHaveTextContent("Use"); + const saveButton = body.getByRole("button", { name: "Save permissions" }); expect(saveButton).toBeEnabled(); await userEvent.click(saveButton); @@ -197,7 +209,7 @@ export const AddGroup: Story = { name: new RegExp(MockGroup2.display_name || MockGroup2.name, "i"), }), ).toBeVisible(); - const saveButton = body.getByRole("button", { name: "Save sharing" }); + const saveButton = body.getByRole("button", { name: "Save permissions" }); expect(saveButton).toBeEnabled(); await userEvent.click(saveButton); @@ -262,7 +274,9 @@ export const SaveRemovalsAsSparseDelta: Story = { name: `Remove ${MockOrganizationMember2.username}`, }), ); - await userEvent.click(body.getByRole("button", { name: "Save sharing" })); + await userEvent.click( + body.getByRole("button", { name: "Save permissions" }), + ); await waitFor(() => expect(API.experimental.updateChatModelACL).toHaveBeenCalledWith( @@ -298,12 +312,14 @@ export const ReopenUsesFreshACL: Story = { await userEvent.click(body.getByRole("button", { name: "Cancel" })); await waitFor(() => expect( - body.queryByRole("dialog", { name: "Share model" }), + body.queryByRole("dialog", { name: "Model permissions" }), ).not.toBeInTheDocument(), ); currentServerACL = refreshedACL; - await userEvent.click(body.getByRole("button", { name: "Open sharing" })); + await userEvent.click( + body.getByRole("button", { name: "Open permissions" }), + ); expect( await body.findByRole("row", { @@ -337,14 +353,15 @@ export const SaveErrorKeepsEditorOpen: Story = { name: `Remove ${MockGroup.display_name}`, }), ); - await userEvent.click(body.getByRole("button", { name: "Save sharing" })); + await userEvent.click( + body.getByRole("button", { name: "Save permissions" }), + ); const alert = await body.findByRole("alert"); expect(alert).toHaveTextContent("Unable to save ACL"); - expect(body.getByRole("dialog", { name: "Share model" })).toHaveAttribute( - "data-state", - "open", - ); + expect( + body.getByRole("dialog", { name: "Model permissions" }), + ).toHaveAttribute("data-state", "open"); expect(args.onOpenChange).not.toHaveBeenCalledWith(false); }, }; diff --git a/site/src/pages/AISettingsPage/ModelsPage/components/ChatModelSharingDialog.tsx b/site/src/pages/AISettingsPage/ModelsPage/components/ChatModelSharingDialog.tsx index cc5eefff08e..f69b265b01b 100644 --- a/site/src/pages/AISettingsPage/ModelsPage/components/ChatModelSharingDialog.tsx +++ b/site/src/pages/AISettingsPage/ModelsPage/components/ChatModelSharingDialog.tsx @@ -210,7 +210,7 @@ export const ChatModelSharingDialog: FC = ({ }, { onSuccess: () => { - toast.success(`Sharing for "${modelName}" updated.`); + toast.success(`Permissions for "${modelName}" updated.`); close(); }, }, @@ -228,9 +228,9 @@ export const ChatModelSharingDialog: FC = ({ > - Share model + Model permissions - Choose which organization members and groups can use {modelName}. + Manage which organization members and groups can use {modelName}. @@ -244,7 +244,7 @@ export const ChatModelSharingDialog: FC = ({ className="flex items-center justify-center gap-3 py-10" > - Loading model sharing + Loading model permissions ) : !initialized ? null : (
@@ -273,14 +273,14 @@ export const ChatModelSharingDialog: FC = ({ {isEmpty ? (

- No shared members or groups yet + No members or groups have permission yet

Add a member or group using the controls above.

) : ( - +
Member @@ -301,7 +301,7 @@ export const ChatModelSharingDialog: FC = ({ src={group?.avatar_url} /> - Read + Use