Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
27ef355
Support inline renaming across sidebar items
brsbl Sep 20, 2026
91fa230
Merge remote-tracking branch 'origin/main' into bb/plan-design-suppor…
brsbl Sep 20, 2026
6b519e3
Preserve inline editors while menus release focus
brsbl Sep 20, 2026
6be97a1
Load sidebar rename editor on demand
brsbl Sep 20, 2026
797fc9d
Wait for editor loading in row interaction tests
brsbl Sep 20, 2026
012b5a2
Start sidebar editors after menus release focus
brsbl Sep 20, 2026
6bcb651
Preserve sidebar rename focus when opening a thread
brsbl Sep 20, 2026
fc9a0ef
Exercise composer autofocus with the supported test props
brsbl Sep 20, 2026
4291b09
Include environment headings in sidebar rename stories
brsbl Sep 20, 2026
4328609
Keep machine rename controls accessible while dragging is disabled
brsbl Sep 20, 2026
926d6ef
Align sidebar rename actions to the row edge
brsbl Sep 21, 2026
893a237
Show section rename in the production sidebar story
brsbl Sep 21, 2026
3b87275
Remove save and cancel buttons from inline rename
brsbl Sep 21, 2026
cd73a6a
Preserve sidebar label typography while renaming
brsbl Sep 21, 2026
033921b
Merge main and preserve disabled inline rename touch menus
brsbl Sep 21, 2026
6735281
Remove the outline from sidebar rename fields
brsbl Sep 21, 2026
21b9c74
Allow one KiB of boot budget for inline sidebar renaming
brsbl Sep 21, 2026
f9317db
Use a background highlight for focused sidebar threads
brsbl Sep 21, 2026
f246154
Merge main and preserve sidebar rename with hidden groups
brsbl Sep 21, 2026
6adaacf
Update section rename fixture for persistent group order
brsbl Sep 21, 2026
b20d27c
Account for measured sidebar boot payload after merging main
brsbl Sep 21, 2026
6b949d3
Simplify sidebar rename state and remove superseded dialogs
brsbl Sep 21, 2026
6102e1a
Drop duplicate rename test using a synthetic menu
brsbl Sep 21, 2026
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
116 changes: 116 additions & 0 deletions apps/app/.ladle/sidebar-rename-fixtures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import type { Host } from "@bb/domain";
import {
updateEnvironmentRequestSchema,
updateHostRequestSchema,
updateProjectRequestSchema,
updateThreadRequestSchema,
updateThreadSectionRequestSchema,
type SidebarBootstrapResponse,
} from "@bb/server-contract";
import { makeThreadResponse } from "../src/test/fixtures/thread-responses";
import { makeEnvironment } from "./story-fixtures";

export function installSidebarRenameStoryApi({
navigation: initialNavigation,
hosts: initialHosts,
failNextSave,
}: {
navigation: SidebarBootstrapResponse;
hosts: Host[];
failNextSave: () => boolean;
}) {
let navigation = structuredClone(initialNavigation);
const hosts = structuredClone(initialHosts);
const originalFetch = globalThis.fetch;
globalThis.fetch = async (input, init) => {
const request = new Request(input, init);
const path = new URL(request.url).pathname;
if (request.method === "GET" && path === "/api/v1/sidebar-bootstrap") {
return Response.json(navigation);
}
if (request.method === "GET" && path === "/api/v1/hosts") {
return Response.json(hosts);
}
if (
request.method === "GET" &&
hosts.some(
(host) => path === `/api/v1/hosts/${host.id}/provider-clis/status`,
)
) {
return Response.json({});
}
const projects = [...navigation.projects, navigation.personalProject];
const threads = projects.flatMap((project) => project.threads);
const id = decodeURIComponent(path.split("/").at(-1) ?? "");
const thread = threads.find((item) => item.id === id);
const project = projects.find((item) => item.id === id);
const host = hosts.find((item) => item.id === id);
const environmentThread = threads.find((item) => item.environmentId === id);
const isSection = path === "/api/v1/thread-sections";
if (
request.method !== "PATCH" ||
!(thread || project || host || environmentThread || isSection)
) {
return originalFetch(input, init);
}
await new Promise((resolve) => window.setTimeout(resolve, 700));
if (failNextSave()) {
return Response.json(
{ error: "Could not save the name. Try again.", code: "unavailable" },
{ status: 503 },
);
}
const body: unknown = await request.json();
if (thread) {
const { title } = updateThreadRequestSchema.parse(body);
if (title !== undefined) thread.title = title;
return Response.json(makeThreadResponse({ ...thread, runtime: {} }));
}
if (project) {
const { name } = updateProjectRequestSchema.parse(body);
if (name !== undefined) project.name = name;
return Response.json(project);
}
if (host) {
host.name = updateHostRequestSchema.parse(body).name;
return Response.json(host);
}
if (environmentThread) {
const { name } = updateEnvironmentRequestSchema.parse(body);
for (const item of threads) {
if (item.environmentId === id && name !== undefined)
item.environmentName = name;
}
return Response.json(
makeEnvironment({
id,
name: environmentThread.environmentName,
projectId: environmentThread.projectId,
branchName: environmentThread.environmentBranchName,
}),
);
}
const section = updateThreadSectionRequestSchema.parse(body);
const name = section.name.trim();
if (
navigation.sections.some(
(item) => item.id !== section.id && item.name === name,
)
) {
return Response.json(
{ error: "Section name already exists", code: "section_name_conflict" },
{ status: 409 },
);
}
navigation = {
...navigation,
sections: navigation.sections.map((item) =>
item.id === section.id ? { ...item, name } : item,
),
};
return Response.json({ id: section.id, name, updatedThreadCount: 0 });
};
return () => {
globalThis.fetch = originalFetch;
};
}
2 changes: 1 addition & 1 deletion apps/app/bundle-budget.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"`node scripts/why-eager.mjs --from=views/SplitWorkspaceRoute.tsx <package>`",
"to print the static chain that pulled a package into the closure."
],
"maxBootBytes": 1730080,
"maxBootBytes": 1737248,
"maxBootBrotliBytes": 429072,
"forbiddenBootPackages": [
"@pierre/diffs",
Expand Down
102 changes: 0 additions & 102 deletions apps/app/src/components/dialogs/EnvironmentRenameDialog.stories.tsx

This file was deleted.

94 changes: 0 additions & 94 deletions apps/app/src/components/dialogs/EnvironmentRenameDialog.tsx

This file was deleted.

53 changes: 0 additions & 53 deletions apps/app/src/components/dialogs/ThreadSectionCreateDialog.test.tsx

This file was deleted.

Loading
Loading