Compare commits

...

1 Commits

Author SHA1 Message Date
Jiang Bohan
0713b970ae fix(projects): default project view to compact
The compact view was the original list layout and is what users expect
on this page; the post-#2840 default of comfortable changed long-standing
behavior. Reset the unpersisted default (and the cross-workspace fallback
in `merge`) back to compact. Updates the view-store tests accordingly.

MUL-2464

Co-authored-by: multica-agent <github@multica.ai>
2026-05-21 14:05:14 +08:00
2 changed files with 28 additions and 28 deletions

View File

@@ -26,7 +26,7 @@ beforeAll(() => {
beforeEach(() => {
localStorage.clear();
useProjectViewStore.setState({ viewMode: "comfortable" });
useProjectViewStore.setState({ viewMode: "compact" });
setCurrentWorkspace(null, null);
});
@@ -35,62 +35,62 @@ afterEach(() => {
});
describe("useProjectViewStore", () => {
it("defaults to 'comfortable'", () => {
expect(useProjectViewStore.getState().viewMode).toBe("comfortable");
it("defaults to 'compact'", () => {
expect(useProjectViewStore.getState().viewMode).toBe("compact");
});
it("setViewMode mutates the store", () => {
useProjectViewStore.getState().setViewMode("compact");
expect(useProjectViewStore.getState().viewMode).toBe("compact");
useProjectViewStore.getState().setViewMode("comfortable");
expect(useProjectViewStore.getState().viewMode).toBe("comfortable");
});
it("partialize persists only viewMode under the workspace-namespaced key", async () => {
setCurrentWorkspace("acme", "ws_a");
await flush();
useProjectViewStore.getState().setViewMode("compact");
useProjectViewStore.getState().setViewMode("comfortable");
const raw = localStorage.getItem("multica_projects_view:acme");
expect(raw).not.toBeNull();
const parsed = JSON.parse(raw as string);
expect(parsed.state).toEqual({ viewMode: "compact" });
expect(parsed.state).toEqual({ viewMode: "comfortable" });
});
it("rehydrates a different saved viewMode on workspace switch", async () => {
localStorage.setItem(
"multica_projects_view:acme",
JSON.stringify({ state: { viewMode: "compact" }, version: 0 }),
JSON.stringify({ state: { viewMode: "comfortable" }, version: 0 }),
);
localStorage.setItem(
"multica_projects_view:beta",
JSON.stringify({ state: { viewMode: "compact" }, version: 0 }),
);
setCurrentWorkspace("acme", "ws_a");
await flush();
await flush();
expect(useProjectViewStore.getState().viewMode).toBe("comfortable");
setCurrentWorkspace("beta", "ws_b");
await flush();
await flush();
expect(useProjectViewStore.getState().viewMode).toBe("compact");
});
it("resets to 'compact' when switching to a workspace with no persisted value", async () => {
localStorage.setItem(
"multica_projects_view:acme",
JSON.stringify({ state: { viewMode: "comfortable" }, version: 0 }),
);
setCurrentWorkspace("acme", "ws_a");
await flush();
await flush();
expect(useProjectViewStore.getState().viewMode).toBe("compact");
expect(useProjectViewStore.getState().viewMode).toBe("comfortable");
setCurrentWorkspace("beta", "ws_b");
await flush();
await flush();
expect(useProjectViewStore.getState().viewMode).toBe("comfortable");
});
it("resets to 'comfortable' when switching to a workspace with no persisted value", async () => {
localStorage.setItem(
"multica_projects_view:acme",
JSON.stringify({ state: { viewMode: "compact" }, version: 0 }),
);
setCurrentWorkspace("acme", "ws_a");
await flush();
await flush();
expect(useProjectViewStore.getState().viewMode).toBe("compact");
setCurrentWorkspace("beta", "ws_b");
await flush();
await flush();
expect(useProjectViewStore.getState().viewMode).toBe("comfortable");
expect(localStorage.getItem("multica_projects_view:acme")).not.toBeNull();
});
});

View File

@@ -15,7 +15,7 @@ export interface ProjectViewState {
export const useProjectViewStore = create<ProjectViewState>()(
persist(
(set) => ({
viewMode: "comfortable",
viewMode: "compact",
setViewMode: (mode) => set({ viewMode: mode }),
}),
{
@@ -23,7 +23,7 @@ export const useProjectViewStore = create<ProjectViewState>()(
storage: createJSONStorage(() => createWorkspaceAwareStorage(defaultStorage)),
partialize: (state) => ({ viewMode: state.viewMode }),
merge: (persisted, current) => {
if (!persisted) return { ...current, viewMode: "comfortable" };
if (!persisted) return { ...current, viewMode: "compact" };
return { ...current, ...(persisted as Partial<ProjectViewState>) };
},
}