Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions packages/settings-ui/src/strings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,20 @@ export const SETTINGS_STRINGS = {
notificationsRoutineFail: "Failed deliveries",
notificationsSaveAction: "Save",
notificationsSaveHonesty:
"Draft only — per-user notification prefs are not stored on the hub yet.",
"Draft only — notification choices aren't saved yet.",

settingsSavedToast: "Settings saved",

benchNoneSelectedTitle: "No workbench selected",
benchNoneSelectedDescription: "Choose a workbench from the switcher first.",

accountSectionTitle: "General",
accountSectionDescription: "How the hub identifies you.",
accountSectionDescription: "Your name and email on this workbench.",
accountNameLabel: "Name",
accountEmailLabel: "Email",
accountLoadError: "your account",
accountReadOnlyNote:
"Managed through the authentication API; editing from this screen has not been built yet.",
"These details come from how you sign in. Editing them here isn't available yet.",
accountSignOutAction: "Sign out",
accountDetailsHeading: "Account details",
accountCopyEmailAction: "Copy email",
Expand Down Expand Up @@ -75,9 +75,9 @@ export const SETTINGS_STRINGS = {
peopleRemoveError: "Couldn't remove that person — try again.",
peopleUnnamedAgent: "Unnamed agent",
peopleRoleNone: "none",
peopleKindUser: "user",
peopleKindAgent: "agent",
peopleKindWorkflow: "workflow",
peopleKindUser: "Person",
peopleKindAgent: "Agent",
peopleKindWorkflow: "Workflow",
peopleRoleChangeError: "Couldn't change that person's role — try again.",
peopleLastOwnerError:
"This workbench needs at least one owner — make someone else an owner first.",
Expand Down Expand Up @@ -112,7 +112,7 @@ export const SETTINGS_STRINGS = {
accessPolicyNote:
"Closed by default: no open signup, no self-serve sub-workbenches. These settings apply to this workbench.",
accessPolicyEnvOverrideNotice:
"The operator has sign-up switched off at the server level, so people still can't create an account yet — even though this setting would otherwise allow it. Ask whoever manages this deployment to enable self-signup.",
"Sign-up is switched off at a higher level, so people still can't create an account yet — even though this setting would otherwise allow it. Ask whoever controls this install's environment to enable self-signup.",

rolesSectionTitle: "Roles",
rolesSectionDescription:
Expand Down Expand Up @@ -198,7 +198,7 @@ export const SETTINGS_STRINGS = {
connectionsStatusNeedsAttention: "Needs attention",
connectionsStatusNotConfigured: "Needs setup",
connectionsNotConfiguredHint:
"An operator needs to register an OAuth app for this connector before anyone can connect it.",
"An OAuth app needs to be registered for this connector before anyone can connect it.",
connectionsConnectAction: "Connect",
connectionsReconnectAction: "Reconnect",
connectionsDisconnectAction: "Disconnect",
Expand All @@ -208,16 +208,16 @@ export const SETTINGS_STRINGS = {
connectionsDefaultModelLabel: "Default model:",
connectionsSetDefaultModelError:
"Couldn't set the default model — try again.",
connectionsPinnedByPrefix: "Used by workflows: ",
connectionsPinnedByNone: "Available to any workflow",
connectionsPinnedByPrefix: "Used by: ",
connectionsPinnedByNone: "Not pinned by any workflow",
connectionsPinnedByApproximationNote:
"Based on each workflow's declared tool-package pins, not a live query against deployed definitions — may lag a workflow's actual tool usage.",
"Based on declared pins, not live usage — may lag actual tool usage.",
connectionsDialogConnectTitle: (name: string) => `Connect ${name}`,
connectionsDialogReconnectTitle: (name: string) => `Reconnect ${name}`,
connectionsDialogDescription:
"Sealed on save — this key is never shown again after create. A bad key never gets saved; connecting surfaces the problem right here.",
connectionsDialogUrlDescription:
"The base address of the instance to connect. A bad address never gets saved; connecting surfaces the problem right here.",
"The base address of the service to connect. A bad address never gets saved; connecting surfaces the problem right here.",
connectionsKeyLabel: "API key",
connectionsUrlLabel: "Base URL",
connectionsConnectDialogAction: "Connect",
Expand Down
10 changes: 6 additions & 4 deletions packages/settings-ui/test/grants-section.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type { Root } from "react-dom/client";
import { renderToStaticMarkup } from "react-dom/server";

import { CreateGrantDialog, GrantsTable } from "../src/grants-section";
import { PRINCIPAL_KIND_LABEL, PRINCIPAL_KIND_ORDER } from "../src/identity";

const timestamps = {
createdAt: "2026-01-01T00:00:00.000Z",
Expand Down Expand Up @@ -130,10 +131,11 @@ describe("CreateGrantDialog", () => {
act(() => (principalCard as HTMLButtonElement).click());

const optgroups = [...document.body.querySelectorAll("optgroup")];
expect(optgroups.map((group) => group.label)).toEqual([
"user",
"agent",
"workflow",
expect(optgroups.map((group) => group.label)).toEqual(
PRINCIPAL_KIND_ORDER.map((kind) => PRINCIPAL_KIND_LABEL[kind]),
);
expect(optgroups.map((group) => group.label)).not.toEqual([
...PRINCIPAL_KIND_ORDER,
]);
} finally {
act(() => root.unmount());
Expand Down
5 changes: 4 additions & 1 deletion packages/settings-ui/test/identity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,13 @@ describe("principalLabel", () => {
// person's account. Every picker groups or annotates by this shared label.
describe("PRINCIPAL_KIND_LABEL", () => {
test("covers every kind in PRINCIPAL_KIND_ORDER with a distinct, honest label", () => {
expect(PRINCIPAL_KIND_ORDER).toEqual(["user", "agent", "workflow"]);
const labels = PRINCIPAL_KIND_ORDER.map(
(kind) => PRINCIPAL_KIND_LABEL[kind],
);
expect(labels).toEqual(["user", "agent", "workflow"]);
expect(labels).toHaveLength(PRINCIPAL_KIND_ORDER.length);
expect(new Set(labels).size).toBe(labels.length);
expect(labels).toEqual(["Person", "Agent", "Workflow"]);
expect(labels).not.toEqual([...PRINCIPAL_KIND_ORDER]);
});
});
9 changes: 7 additions & 2 deletions packages/settings-ui/test/roles-section.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import { describe, expect, test } from "bun:test";
import { renderToStaticMarkup } from "react-dom/server";

import { PRINCIPAL_KIND_LABEL, PRINCIPAL_KIND_ORDER } from "../src/identity";
import { RoleAssignments } from "../src/roles-section";

const timestamps = {
Expand Down Expand Up @@ -56,7 +57,10 @@ describe("RoleAssignments picker", () => {
const groupOrder = [...markup.matchAll(/<optgroup label="([^"]+)"/g)].map(
(match) => match[1],
);
expect(groupOrder).toEqual(["user", "agent", "workflow"]);
expect(groupOrder).toEqual(
PRINCIPAL_KIND_ORDER.map((kind) => PRINCIPAL_KIND_LABEL[kind]),
);
expect(groupOrder).not.toEqual([...PRINCIPAL_KIND_ORDER]);
});

test("omits an empty kind group entirely rather than an empty optgroup", () => {
Expand All @@ -71,6 +75,7 @@ describe("RoleAssignments picker", () => {
const groupOrder = [...markup.matchAll(/<optgroup label="([^"]+)"/g)].map(
(match) => match[1],
);
expect(groupOrder).toEqual(["user"]);
expect(groupOrder).toEqual([PRINCIPAL_KIND_LABEL.user]);
expect(groupOrder).not.toEqual(["user"]);
});
});
28 changes: 28 additions & 0 deletions packages/settings-ui/test/strings.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { describe, expect, test } from "bun:test";

import { SETTINGS_STRINGS } from "../src/strings";

function stringValues(value: unknown): string[] {
if (typeof value === "string") return [value];
if (typeof value === "function" || value === null || value === undefined) {
return [];
}
if (typeof value === "object") {
return Object.values(value).flatMap(stringValues);
}
return [];
}

describe("SETTINGS_STRINGS", () => {
test("person-facing values drop intern chrome", () => {
const values = stringValues(SETTINGS_STRINGS);
expect(values.length).toBeGreaterThan(0);
for (const text of values) {
expect(text).not.toMatch(/auth API/i);
expect(text).not.toMatch(/\bhub\b/i);
expect(text).not.toMatch(/\bInference\b/);
expect(text).not.toMatch(/\boperators?\b/i);
expect(text).not.toMatch(/\bdeployments?\b/i);
}
});
});
Loading