diff --git a/apps/web/components/content/documentation-proposals.tsx b/apps/web/components/content/documentation-proposals.tsx
index f163d8a..c84a3c5 100644
--- a/apps/web/components/content/documentation-proposals.tsx
+++ b/apps/web/components/content/documentation-proposals.tsx
@@ -607,7 +607,8 @@ export function DocumentationProposals({
{proposal.title}
- {proposal.captured.length} files ·{" "}
+ {proposal.captured.length}{" "}
+ {proposal.captured.length === 1 ? "file" : "files"} ·{" "}
{new Date(proposal.createdAt).toLocaleString()}
diff --git a/apps/web/components/content/documentation-source-manage.tsx b/apps/web/components/content/documentation-source-manage.tsx
index 652f190..9fdc373 100644
--- a/apps/web/components/content/documentation-source-manage.tsx
+++ b/apps/web/components/content/documentation-source-manage.tsx
@@ -21,7 +21,10 @@ import {
SummaryRow,
} from "@/components/content/documentation-connect-parts";
import type { DocumentationGitSource } from "@/lib/api";
-import { PagesSourceSection } from "@/components/content/pages-source-section";
+import {
+ DiagnosticList,
+ PagesSourceSection,
+} from "@/components/content/pages-source-section";
import { ApiReferenceSourceSection } from "@/components/content/api-reference-source-section";
import { cn } from "@/lib/utils";
@@ -84,6 +87,11 @@ type Health = {
body: string;
};
+/** A sync is underway ("Syncing"); the dialog polls until it settles. */
+export function syncInProgress(source: DocumentationGitSource) {
+ return Boolean(source.binding) && health(source, source.binding!).tone === "info";
+}
+
function health(source: DocumentationGitSource, binding: Binding): Health {
if (source.status === "access_lost")
return {
@@ -103,22 +111,21 @@ function health(source: DocumentationGitSource, binding: Binding): Health {
title: "Sync paused",
body: "New commits aren't being picked up. Your site keeps showing the last good version.",
};
+ const syncing: Health = {
+ tone: "info",
+ title: "Syncing",
+ body: `Checking the newest commit on ${binding.branch}. Your site still shows the previous version.`,
+ };
+ // A new run goes first: retrying after a failure must show (and poll) as syncing.
+ if (source.sync?.status === "queued" || source.sync?.status === "running")
+ return syncing;
if (source.sync?.status === "failed" || binding.lastDiagnostic)
return {
tone: "warning",
title: "Latest sync didn't go live",
body: "Your site keeps showing the last good version. Fix the problem in GitHub and sync again.",
};
- if (
- source.sync?.status === "queued" ||
- source.sync?.status === "running" ||
- binding.observedSha !== binding.liveSha
- )
- return {
- tone: "info",
- title: "Syncing",
- body: `Checking the newest commit on ${binding.branch}. Your site still shows the previous version.`,
- };
+ if (binding.observedSha !== binding.liveSha) return syncing;
return {
tone: "success",
title: "In sync",
@@ -324,9 +331,13 @@ export function ManageSource({
onRefresh={onRefresh}
busy={busy}
/>
- {(binding.lastDiagnostic || source.sync?.diagnostic) && (
+ {state.tone !== "info" && (binding.lastDiagnostic || source.sync?.diagnostic) && (