feat: port the demo redesign with Manage and Settings tabs

This commit is contained in:
LukeGus committed 2026-10-05 16:23:21 -05:00
1 parent f8151cb885
commit 35c954b79a
128 files changed
+13262 -8143

No files matched your search

@@ -155,11 +155,7 @@ describe("FeatureSettingsSection", () => {
const save = screen.getByText("common.save").closest("button")!;
expect(save.disabled).toBe(true);
fireEvent.click(
screen
.getAllByRole("button")
.find((b) => b !== save && b.textContent === "")!,
);
fireEvent.click(screen.getByRole("switch"));
fireEvent.click(save);
await waitFor(() =>
@@ -0,0 +1,88 @@
import { afterEach, describe, expect, it, vi } from "vitest";
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
const saved = vi.hoisted(() => ({ value: null as string | null }));
vi.mock("@/api/open-tabs-api", async (importOriginal) => ({
...(await importOriginal<Record<string, unknown>>()),
getUserPreferences: async () => ({ customKeybindings: saved.value }),
}));
vi.mock("@/main-axios", () => ({ saveUserPreferences: vi.fn() }));
const { KeybindingsSettings } = await import("@/settings/KeybindingsSettings");
const { SurfaceScope } = await import("@/components/surface/surface-scope");
function renderSettings() {
return render(
<SurfaceScope>
<KeybindingsSettings />
</SurfaceScope>,
);
}
const {
registerKeybindingAction,
registerKeybindingDefault,
resetKeybindingRegistry,
} = await import("../../shell/keybinding-registry");
afterEach(() => {
cleanup();
resetKeybindingRegistry();
saved.value = null;
});
const combo = {
key: "k",
isCode: false,
ctrl: true,
alt: false,
shift: false,
meta: false,
};
describe("KeybindingsSettings", () => {
it("lists registered defaults and keeps a binding whose plugin is off", async () => {
registerKeybindingDefault({
id: "default-x",
pluginId: "sample",
combo,
descriptionKey: "sample:builtInX",
});
saved.value = JSON.stringify([
{
id: "a",
combo,
action: { type: "gone.action" },
enabled: true,
createdAt: "",
updatedAt: "",
},
]);
renderSettings();
expect(await screen.findByText("sample:builtInX")).toBeTruthy();
expect(
await screen.findByText("newUi.sidebar.keybindings.unavailableAction"),
).toBeTruthy();
});
it("offers every registered action and draws the chosen one's editor", async () => {
registerKeybindingAction({
id: "sample.send",
pluginId: "sample",
labelKey: "sample:send",
scope: "session",
editor: () => <span>sample editor</span>,
});
renderSettings();
fireEvent.click(
await screen.findByText("newUi.sidebar.keybindings.addBinding"),
);
const select = (await screen.findByRole("option", { name: "sample:send" }))
.parentElement as HTMLSelectElement;
expect([...select.options].map((option) => option.value)).toContain(
"nextTab",
);
fireEvent.change(select, { target: { value: "sample.send" } });
expect(await screen.findByText("sample editor")).toBeTruthy();
});
});
@@ -55,7 +55,7 @@ describe("field types", () => {
{ enabled: false },
);
const toggle = screen.getByRole("button");
const toggle = screen.getByRole("switch");
fireEvent.click(toggle);
expect(setValue).toHaveBeenCalledWith("enabled", true);
@@ -297,7 +297,7 @@ describe("HostPluginSections", () => {
/>,
);
fireEvent.click(screen.getAllByRole("button")[0]);
fireEvent.click(screen.getAllByRole("switch")[0]);
expect(setValue).toHaveBeenCalledWith("docker", "enableDocker", true);
});
@@ -373,7 +373,7 @@ describe("HostFeatureFields", () => {
expect(screen.getAllByText("Docker")).toHaveLength(1);
expect(screen.queryByText("Warpgate")).toBeNull();
fireEvent.click(screen.getAllByRole("button")[0]);
fireEvent.click(screen.getAllByRole("switch")[0]);
const patch = updateForm.mock.calls[0][0];
expect(patch(form).pluginSettings).toEqual({
docker: { enableDocker: true },
@@ -0,0 +1,60 @@
import { describe, expect, it } from "vitest";
import en from "@/locales/en.json";
import {
CORE_SETTINGS_PAGES,
searchSettingsPages,
visibleSettingsPages,
} from "@/settings/settings-pages";
import { SETTINGS_SEARCH_INDEX } from "@/settings/settings-search-index";
function translate(key: string): string {
let node: unknown = en;
for (const part of key.split(".")) {
node = (node as Record<string, unknown> | undefined)?.[part];
}
return typeof node === "string" ? node : key;
}
describe("settings pages", () => {
it("hides admin pages from users and browser-only pages on desktop", () => {
const user = visibleSettingsPages(CORE_SETTINGS_PAGES, {
isAdmin: false,
isElectron: true,
}).map((page) => page.id);
expect(user).not.toContain("admin-users");
expect(user).not.toContain("security");
expect(user).toContain("account");
const admin = visibleSettingsPages(CORE_SETTINGS_PAGES, {
isAdmin: true,
isElectron: false,
}).map((page) => page.id);
expect(admin).toContain("admin-users");
expect(admin).toContain("security");
});
it("finds a page by a label shown on it, not only its name", () => {
const hits = searchSettingsPages(CORE_SETTINGS_PAGES, "theme", translate);
expect(hits.some((hit) => hit.page.id === "appearance")).toBe(true);
expect(
hits.find((hit) => hit.page.id === "appearance")?.match,
).toBeTruthy();
});
it("lists every page for an empty query", () => {
expect(
searchSettingsPages(CORE_SETTINGS_PAGES, " ", translate),
).toHaveLength(CORE_SETTINGS_PAGES.length);
});
it("gives every core page labels to search, all of them real keys", () => {
for (const page of CORE_SETTINGS_PAGES) {
expect(translate(page.labelKey)).not.toBe(page.labelKey);
expect(page.searchKeys.length).toBeGreaterThan(0);
}
const missing = Object.values(SETTINGS_SEARCH_INDEX)
.flat()
.filter((key) => translate(key) === key);
expect(missing).toEqual([]);
});
});