Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion apps/web/components/content/documentation-proposals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,8 @@ export function DocumentationProposals({
{proposal.title}
</span>
<span className="text-muted-foreground text-xs">
{proposal.captured.length} files ·{" "}
{proposal.captured.length}{" "}
{proposal.captured.length === 1 ? "file" : "files"} ·{" "}
{new Date(proposal.createdAt).toLocaleString()}
</span>
</span>
Expand Down
37 changes: 24 additions & 13 deletions apps/web/components/content/documentation-source-manage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -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 {
Expand All @@ -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",
Expand Down Expand Up @@ -324,9 +331,13 @@ export function ManageSource({
onRefresh={onRefresh}
busy={busy}
/>
{(binding.lastDiagnostic || source.sync?.diagnostic) && (
{state.tone !== "info" && (binding.lastDiagnostic || source.sync?.diagnostic) && (
<Callout tone="warning" title="What went wrong">
{binding.lastDiagnostic ?? source.sync?.diagnostic}
{source.sync?.diagnostics.length ? (
<DiagnosticList items={source.sync.diagnostics} />
) : (
(binding.lastDiagnostic ?? source.sync?.diagnostic)
)}
</Callout>
)}
{binding.lastPrReconcileError && (
Expand Down
28 changes: 23 additions & 5 deletions apps/web/components/content/documentation-source.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Check, ExternalLink, Github, GitPullRequest, Loader2 } from "lucide-rea
import {
ManageShell,
ManageSource,
syncInProgress,
} from "@/components/content/documentation-source-manage";
import { Badge } from "@/components/ui/codelit/badge";
import { Button } from "@/components/ui/codelit/button";
Expand Down Expand Up @@ -555,8 +556,24 @@ export function DocumentationSource({
verificationAttempt.current = attempt;
verifyMergedSetup();
}, [migration?.planId, migration?.status, migration?.pullRequest?.status, setupId]);
// While the connected dialog is open, poll: quickly during a sync, and
// slowly otherwise so a sync started by a push is noticed too.
const watching = open && !wizardMode && source?.binding != null;
const pollMs = source && syncInProgress(source) ? 5000 : 30000;
useEffect(() => {
if (!watching) return;
const timer = setInterval(
() =>
void getDocumentationGitSource()
.then(setSource)
.catch(() => {}),
pollMs,
);
return () => clearInterval(timer);
}, [watching, pollMs]);
const repoLabel = migration?.repositoryName ?? repositoryName ?? "your repository";
const fileCount = migration?.total ?? 0;
const filesLabel = `${fileCount} ${fileCount === 1 ? "file" : "files"}`;
const isEmptyRepo = Boolean(migration?.initializeEmptyRepositoryRequired);
const draftCount = migration?.unpublishedDraftCount ?? 0;
const noGitHub = !setupId;
Expand Down Expand Up @@ -601,7 +618,7 @@ export function DocumentationSource({
title: "FrontLit checks the files and connects",
note: "Usually takes a few seconds.",
state: at[2],
waiting: `Checking ${fileCount} files`,
waiting: `Checking ${filesLabel}`,
},
];
};
Expand Down Expand Up @@ -1124,7 +1141,7 @@ export function DocumentationSource({
disabled={busy}
>
{isEmptyRepo
? `I approve adding ${migration.selection.directory}/.gitkeep to ${migration.selection.branch} and opening a pull request with these ${fileCount} files.`
? `I approve adding ${migration.selection.directory}/.gitkeep to ${migration.selection.branch} and opening a pull request with ${fileCount === 1 ? "this file" : `these ${filesLabel}`}.`
: fileCount
? `I approve opening a pull request with ${fileCount === 1 ? "this file" : `these ${fileCount} files`}.`
: `I approve opening a pull request that creates the empty ${migration.selection.directory}/ folder.`}
Expand Down Expand Up @@ -1195,7 +1212,7 @@ export function DocumentationSource({
<StatusBanner>Pull request opened</StatusBanner>
<StepIntro
title="Merge it in GitHub to finish"
lead={`Review the ${fileCount} files and merge when you're happy. FrontLit picks up the merge on its own, so you can close this window.`}
lead={`Review the ${filesLabel} and merge when you're happy. FrontLit picks up the merge on its own, so you can close this window.`}
/>
<div className="flex items-center gap-3.5 rounded-[0.625rem] border border-border p-4">
<span className="grid size-10 shrink-0 place-items-center rounded-[0.625rem] bg-[var(--success-soft)] text-[var(--success)]">
Expand All @@ -1208,7 +1225,7 @@ export function DocumentationSource({
{migration.pullRequest?.pullRequestNumber
? ` · #${migration.pullRequest.pullRequestNumber}`
: ""}{" "}
· {fileCount} files
· {filesLabel}
</span>
</span>
{migration.pullRequest?.pullRequestUrl && (
Expand Down Expand Up @@ -1417,7 +1434,8 @@ export function DocumentationSource({
<Mono>{preflight.directory}/</Mono>
</SummaryRow>
<SummaryRow label="Docs" action={null}>
{preflight.publishedCount} public of {preflight.fileCount} files
{preflight.publishedCount} public of {preflight.fileCount}{" "}
{preflight.fileCount === 1 ? "file" : "files"}
</SummaryRow>
</>
) : (
Expand Down
Loading