feat(app): polish workspace tabs and changes

Size tabs from rendered labels and switch to horizontal overflow once minimum click targets are reached, keeping the add-tab action adjacent until it must remain fixed.

Make Changes an always-expanded document with an optional desktop navigation tree, keep Git actions in their platform-owned headers, remove pinned and inline split shortcuts, and place review tabs beside Changes.
This commit is contained in:
Mohamed Boudra
2026-08-17 21:14:37 +02:00
parent 6d7606160e
commit 75adf53893
41 changed files with 929 additions and 1901 deletions
@@ -28,7 +28,7 @@ describe("loadChangesPreferencesFromStorage", () => {
expect(result).toEqual({
layout: "unified",
viewMode: "flat",
desktopTreeVisible: false,
wrapLines: true,
hideWhitespace: false,
commitsCollapsed: true,
@@ -51,7 +51,7 @@ describe("loadChangesPreferencesFromStorage", () => {
expect(result).toEqual({
layout: "split",
viewMode: "tree",
desktopTreeVisible: true,
hideWhitespace: true,
wrapLines: false,
commitsCollapsed: true,
@@ -95,14 +95,14 @@ describe("saveChangesPreferences", () => {
await saveChangesPreferences({
queryClient,
updates: { layout: "split", viewMode: "tree", hideWhitespace: true },
updates: { layout: "split", desktopTreeVisible: true, hideWhitespace: true },
storage,
});
const expected = {
...DEFAULT_CHANGES_PREFERENCES,
layout: "split",
viewMode: "tree",
desktopTreeVisible: true,
hideWhitespace: true,
};
expect(queryClient.getQueryData(CHANGES_PREFERENCES_QUERY_KEY)).toEqual(expected);
@@ -8,6 +8,8 @@ export const CHANGES_PREFERENCES_QUERY_KEY = ["changes-preferences"];
const changesPreferencesSchema = z.strictObject({
layout: z.enum(["unified", "split"]).optional(),
desktopTreeVisible: z.boolean().optional(),
// Read the former overloaded preference once so existing installations keep their desktop tree.
viewMode: z.enum(["flat", "tree"]).optional(),
wrapLines: z.boolean().optional(),
hideWhitespace: z.boolean().optional(),
@@ -16,7 +18,7 @@ const changesPreferencesSchema = z.strictObject({
export interface ChangesPreferences {
layout: "unified" | "split";
viewMode: "flat" | "tree";
desktopTreeVisible: boolean;
wrapLines: boolean;
hideWhitespace: boolean;
commitsCollapsed: boolean;
@@ -24,7 +26,7 @@ export interface ChangesPreferences {
export const DEFAULT_CHANGES_PREFERENCES: ChangesPreferences = {
layout: "unified",
viewMode: "flat",
desktopTreeVisible: false,
wrapLines: false,
hideWhitespace: false,
commitsCollapsed: true,
@@ -54,7 +56,12 @@ export async function loadChangesPreferencesFromStorage(
changesPreferencesSchema,
);
if (stored) {
return { ...DEFAULT_CHANGES_PREFERENCES, ...stored };
const { viewMode, ...currentPreferences } = stored;
return {
...DEFAULT_CHANGES_PREFERENCES,
...currentPreferences,
desktopTreeVisible: stored.desktopTreeVisible ?? viewMode === "tree",
};
}
const legacyWrapLines = await loadLegacyWrapLinesPreference(storage);