perf(ui): narrow session switch fanout
Keep sidebar rows independent from the active sync directory by moving export history loading behind an explicit-directory command. Make active-project selection preserve project topology and remove activeProjectId from mounted group render props. Reuse a per-session-array ID index so subscription snapshots do not repeatedly scan session lists.
This commit is contained in:
@@ -20,6 +20,26 @@ describe("useProjectsStore settings synchronization", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("useProjectsStore selection identity", () => {
|
||||
test("changes only the active project id", () => {
|
||||
const first = { id: "project-a", path: "/repo-a", lastOpenedAt: 10 } as ProjectEntry
|
||||
const second = { id: "project-b", path: "/repo-b", lastOpenedAt: 20 } as ProjectEntry
|
||||
const projects = [first, second]
|
||||
useProjectsStore.setState({
|
||||
projects,
|
||||
activeProjectId: first.id,
|
||||
manualProjectOrder: projects.map((project) => project.id),
|
||||
})
|
||||
|
||||
useProjectsStore.getState().setActiveProjectIdOnly(second.id)
|
||||
|
||||
const state = useProjectsStore.getState()
|
||||
expect(state.activeProjectId).toBe(second.id)
|
||||
expect(state.projects).toBe(projects)
|
||||
expect(state.projects.map((project) => project.lastOpenedAt)).toEqual([10, 20])
|
||||
})
|
||||
})
|
||||
|
||||
describe("useProjectsStore default model and thinking level", () => {
|
||||
const seed = (project: ProjectEntry) => {
|
||||
useProjectsStore.setState({
|
||||
|
||||
@@ -357,13 +357,7 @@ const readPersistedActiveProjectId = (): string | null => {
|
||||
return null;
|
||||
};
|
||||
|
||||
const cacheProjects = (projects: ProjectEntry[], activeProjectId: string | null) => {
|
||||
try {
|
||||
safeStorage.setItem(getProjectsStorageKey(), JSON.stringify(projects));
|
||||
} catch {
|
||||
// ignored
|
||||
}
|
||||
|
||||
const cacheActiveProjectId = (activeProjectId: string | null) => {
|
||||
try {
|
||||
const activeProjectStorageKey = getActiveProjectStorageKey();
|
||||
if (activeProjectId) {
|
||||
@@ -376,6 +370,15 @@ const cacheProjects = (projects: ProjectEntry[], activeProjectId: string | null)
|
||||
}
|
||||
};
|
||||
|
||||
const cacheProjects = (projects: ProjectEntry[], activeProjectId: string | null) => {
|
||||
try {
|
||||
safeStorage.setItem(getProjectsStorageKey(), JSON.stringify(projects));
|
||||
} catch {
|
||||
// ignored
|
||||
}
|
||||
cacheActiveProjectId(activeProjectId);
|
||||
};
|
||||
|
||||
const persistProjects = (projects: ProjectEntry[], activeProjectId: string | null, manualOrder?: string[]) => {
|
||||
cacheProjects(projects, activeProjectId);
|
||||
if (manualOrder) {
|
||||
@@ -693,18 +696,13 @@ export const useProjectsStore = create<ProjectsStore>()(
|
||||
if (activeProjectId === id) {
|
||||
return;
|
||||
}
|
||||
const target = projects.find((project) => project.id === id);
|
||||
if (!target) {
|
||||
if (!projects.some((project) => project.id === id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const now = Date.now();
|
||||
const nextProjects = projects.map((project) =>
|
||||
project.id === id ? { ...project, lastOpenedAt: now } : project
|
||||
);
|
||||
|
||||
set({ projects: nextProjects, activeProjectId: id });
|
||||
persistProjects(nextProjects, id, get().manualProjectOrder);
|
||||
set({ activeProjectId: id });
|
||||
cacheActiveProjectId(id);
|
||||
void updateDesktopSettings({ activeProjectId: id });
|
||||
},
|
||||
|
||||
renameProject: (id: string, label: string) => {
|
||||
|
||||
Reference in New Issue
Block a user