Fix manual company switch route sync

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Dotta
2026-03-12 16:04:28 -05:00
parent f3c18db7dd
commit c9259bbec0
4 changed files with 63 additions and 3 deletions

View File

@@ -22,6 +22,7 @@ import { useTheme } from "../context/ThemeContext";
import { useKeyboardShortcuts } from "../hooks/useKeyboardShortcuts";
import { useCompanyPageMemory } from "../hooks/useCompanyPageMemory";
import { healthApi } from "../api/health";
import { shouldSyncCompanySelectionFromRoute } from "../lib/company-selection";
import { queryKeys } from "../lib/queryKeys";
import { cn } from "../lib/utils";
import { NotFoundPage } from "../pages/NotFound";
@@ -36,6 +37,7 @@ export function Layout() {
loading: companiesLoading,
selectedCompany,
selectedCompanyId,
selectionSource,
setSelectedCompanyId,
} = useCompany();
const { theme, toggleTheme } = useTheme();
@@ -88,7 +90,13 @@ export function Layout() {
return;
}
if (selectedCompanyId !== matchedCompany.id) {
if (
shouldSyncCompanySelectionFromRoute({
selectionSource,
selectedCompanyId,
routeCompanyId: matchedCompany.id,
})
) {
setSelectedCompanyId(matchedCompany.id, { source: "route_sync" });
}
}, [
@@ -99,6 +107,7 @@ export function Layout() {
location.pathname,
location.search,
navigate,
selectionSource,
selectedCompanyId,
setSelectedCompanyId,
]);

View File

@@ -12,8 +12,7 @@ import type { Company } from "@paperclipai/shared";
import { companiesApi } from "../api/companies";
import { ApiError } from "../api/client";
import { queryKeys } from "../lib/queryKeys";
type CompanySelectionSource = "manual" | "route_sync" | "bootstrap";
import type { CompanySelectionSource } from "../lib/company-selection";
type CompanySelectionOptions = { source?: CompanySelectionSource };
interface CompanyContextValue {

View File

@@ -0,0 +1,34 @@
import { describe, expect, it } from "vitest";
import { shouldSyncCompanySelectionFromRoute } from "./company-selection";
describe("shouldSyncCompanySelectionFromRoute", () => {
it("does not resync when selection already matches the route", () => {
expect(
shouldSyncCompanySelectionFromRoute({
selectionSource: "route_sync",
selectedCompanyId: "pap",
routeCompanyId: "pap",
}),
).toBe(false);
});
it("defers route sync while a manual company switch is in flight", () => {
expect(
shouldSyncCompanySelectionFromRoute({
selectionSource: "manual",
selectedCompanyId: "pap",
routeCompanyId: "ret",
}),
).toBe(false);
});
it("syncs back to the route company for non-manual mismatches", () => {
expect(
shouldSyncCompanySelectionFromRoute({
selectionSource: "route_sync",
selectedCompanyId: "pap",
routeCompanyId: "ret",
}),
).toBe(true);
});
});

View File

@@ -0,0 +1,18 @@
export type CompanySelectionSource = "manual" | "route_sync" | "bootstrap";
export function shouldSyncCompanySelectionFromRoute(params: {
selectionSource: CompanySelectionSource;
selectedCompanyId: string | null;
routeCompanyId: string;
}): boolean {
const { selectionSource, selectedCompanyId, routeCompanyId } = params;
if (selectedCompanyId === routeCompanyId) return false;
// Let manual company switches finish their remembered-path navigation first.
if (selectionSource === "manual" && selectedCompanyId) {
return false;
}
return true;
}