fix(app): refresh import availability previews

This commit is contained in:
Mohamed Boudra
2026-07-17 18:10:55 +02:00
parent 5e75e463ec
commit d6bc201f46
3 changed files with 98 additions and 5 deletions

View File

@@ -1,5 +1,14 @@
import type {
ProjectConfigImportPreview,
ProjectConfigRpcError,
} from "@getpaseo/protocol/messages";
export type ProjectConfigImportAvailabilityStatus = "loading" | "none" | "one" | "many";
type ProjectConfigImportOpenablePreview =
| ({ ok: true } & Pick<ProjectConfigImportPreview, "items" | "status">)
| { ok: false; error: Pick<ProjectConfigRpcError, "code"> };
export function projectConfigImportAvailabilityStatus(input: {
availableCount: number;
isLoading: boolean;
@@ -14,9 +23,19 @@ export function projectConfigImportAvailabilityStatus(input: {
}
export function projectConfigImportPreviewIsOpenable(
preview: { ok: true; status: string } | { ok: false; error: { code: string } } | null | undefined,
preview: ProjectConfigImportOpenablePreview | null | undefined,
): boolean {
return preview?.ok === true
? preview.status === "available"
: preview?.error.code === "invalid_source_config";
if (!preview) {
return false;
}
if (!preview.ok) {
return preview.error.code === "invalid_source_config";
}
if (preview.status === "available") {
return true;
}
if (preview.status === "nothing_to_import") {
return preview.items.length > 0;
}
return false;
}

View File

@@ -39,7 +39,7 @@ export function projectConfigImportPreviewQueryInput(input: {
enabled:
input.enabled &&
Boolean(input.client && input.serverId && input.repoRoot && input.protocolSource),
refetchOnMount: false,
refetchOnMount: true,
retry: false,
staleTimeMs: PROJECT_CONFIG_IMPORT_PREVIEW_STALE_MS,
dataShape: "value",

View File

@@ -217,6 +217,61 @@ describe("project config import preview cache keys", () => {
);
});
it("refetches a stale availability preview when the settings page remounts", () => {
const calls: string[] = [];
const client = {
getProjectConfigImport: async (): Promise<
ProjectConfigImportPreview & { ok: true; requestId: string }
> => {
calls.push("preview");
return {
ok: true,
requestId: "preview-current",
repoRoot: "/repo",
source: protocolSource,
status: "available",
sourceRevision: "source-current",
paseoRevision: null,
inputs: [],
items: [],
preview: {},
};
},
};
const input = projectConfigImportPreviewQueryInput({
client,
serverId: "server",
repoRoot: "/repo",
source: fakeSource,
protocolSource,
enabled: true,
});
const queryClient = new QueryClient();
queryClient.setQueryData(
input.queryKey,
{
ok: true,
requestId: "preview-stale",
repoRoot: "/repo",
source: protocolSource,
status: "not_found",
sourceRevision: null,
paseoRevision: null,
inputs: [],
items: [],
preview: null,
},
{ updatedAt: Date.now() - 6_000 },
);
const options = fetchQueryOptions(input);
const observer = new QueryObserver(queryClient, queryClient.defaultQueryOptions(options));
const unsubscribe = observer.subscribe(() => {});
expect(calls).toEqual(["preview"]);
unsubscribe();
});
it("keeps advertised identity separate from the protocol source after opening", async () => {
const sameKindRegistry = createProjectConfigImportSourceRegistry([
{
@@ -319,4 +374,23 @@ describe("project config import availability", () => {
}),
).toBe(false);
});
it("keeps warning-only advertised sources openable", () => {
expect(
projectConfigImportPreviewIsOpenable({
ok: true,
status: "nothing_to_import",
items: [
{ key: "environment_variables", label: "Environment variables", outcome: "unsupported" },
],
}),
).toBe(true);
expect(
projectConfigImportPreviewIsOpenable({
ok: true,
status: "nothing_to_import",
items: [],
}),
).toBe(false);
});
});