feat(settings): one page per section with a grouped nav and search
Settings moves from a tab bar to /settings/<section>: a left nav grouped General / Agents / Routing / Git / Projects (a select on narrow screens), a search box over every section (Ctrl/Cmd+F, Enter opens the first match), and row primitives. Each AI tool has its page under agents/<id>, the AI Tools modal becomes the Agents page, Pricing shows every vendor, Git → Worktrees sets which untracked worktrees the sidebar lists, and each project gets a page with its own worktree override and Forget all. ?tool= and #ai-tools links redirect to the path form.
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* @file settingsSearch.test.ts
|
||||
* @description `rankSettings`: an empty query matches nothing, a section title
|
||||
* outranks an entry title, which outranks a description and a keyword, exact
|
||||
* beats prefix beats substring, and a query matching nothing returns nothing.
|
||||
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
||||
*/
|
||||
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { rankSettings, type SettingsEntry } from "../settingsSearch";
|
||||
|
||||
const entries: SettingsEntry[] = [
|
||||
{ section: "pricing", title: "Pricing", sectionTitle: true },
|
||||
{ section: "claude", title: "Claude Code", sectionTitle: true },
|
||||
{ section: "claude", title: "Model Pricing" },
|
||||
{ section: "about", title: "About", description: "Server pricing info" },
|
||||
{ section: "kw", title: "Other", keywords: ["pricing"] },
|
||||
{ section: "prefix", title: "Pricing tables", sectionTitle: true },
|
||||
];
|
||||
|
||||
describe("rankSettings", () => {
|
||||
it("returns nothing for an empty or blank query", () => {
|
||||
expect(rankSettings("", entries)).toEqual([]);
|
||||
expect(rankSettings(" ", entries)).toEqual([]);
|
||||
});
|
||||
|
||||
it("orders by field tier, then exact > prefix > substring", () => {
|
||||
expect(rankSettings("Pricing", entries)).toEqual([
|
||||
{ section: "pricing", score: 900 },
|
||||
{ section: "prefix", score: 850 },
|
||||
{ section: "claude", score: 600 },
|
||||
{ section: "about", score: 400 },
|
||||
{ section: "kw", score: 300 },
|
||||
]);
|
||||
});
|
||||
|
||||
it("returns nothing when no field matches", () => {
|
||||
expect(rankSettings("zzz", entries)).toEqual([]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user