CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history
log-tail.tsx
Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.
| abfa9ad | 1 | /** |
| 2 | * LogTail — SSR component that renders a <pre> and streams live workflow-run | |
| 3 | * step-log chunks into it via SSE. | |
| 4 | * | |
| 5 | * The initial <pre> is pre-populated with `fallbackLogs` (the DB row's stored | |
| 6 | * logs blob so a viewer with JS disabled, an unsupported browser, or a | |
| 7 | * blocked SSE endpoint still sees whatever was already persisted). Once the | |
| 8 | * inline script connects to `/live-events/workflow-run-<runId>`, it appends | |
| 9 | * step-log chunks as plain escaped text and reloads the page on run-done so | |
| 10 | * the static view takes over. | |
| 11 | */ | |
| 12 | ||
| 13 | import { raw } from "hono/html"; | |
| 14 | import { liveLogTailScript } from "../lib/sse-client"; | |
| 15 | ||
| 16 | export function LogTail(props: { | |
| 17 | runId: string; | |
| 18 | jobId?: string; | |
| 19 | fallbackLogs?: string | null; | |
| 20 | height?: string; | |
| 21 | reloadOnRunDone?: boolean; | |
| 2316901 | 22 | }) { |
| abfa9ad | 23 | const elementId = `log-tail-${props.runId}${props.jobId ? "-" + props.jobId : ""}`; |
| 24 | const topic = `workflow-run-${props.runId}`; | |
| 25 | const script = liveLogTailScript({ | |
| 26 | topic, | |
| 27 | targetElementId: elementId, | |
| 28 | jobId: props.jobId, | |
| 29 | onRunDone: | |
| 30 | props.reloadOnRunDone === false ? undefined : "location.reload()", | |
| 31 | }); | |
| 32 | ||
| 33 | return ( | |
| 34 | <div> | |
| 35 | <div | |
| 36 | style="display: flex; justify-content: space-between; align-items: center; padding: 6px 10px; background: var(--bg-tertiary); border-top-left-radius: 6px; border-top-right-radius: 6px; font-size: 11px; color: var(--text-muted); font-family: monospace" | |
| 37 | > | |
| 38 | <span>● live log</span> | |
| 39 | <span id={`${elementId}-status`}>connecting…</span> | |
| 40 | </div> | |
| 41 | <pre | |
| 42 | id={elementId} | |
| 4127ecf | 43 | style={`margin: 0; padding: 12px 14px; background: var(--bg-tertiary); color: var(--text); font-size: 12px; line-height: 1.45; overflow: auto; max-height: ${props.height || "480px"}; border-bottom-left-radius: 6px; border-bottom-right-radius: 6px`} |
| abfa9ad | 44 | > |
| 45 | {props.fallbackLogs || ""} | |
| 46 | </pre> | |
| 47 | <script dangerouslySetInnerHTML={{ __html: script }} /> | |
| 48 | </div> | |
| 49 | ); | |
| 50 | } |