Nasaq
Components

DeployView

A deploy run as ordered steps with status, live durations, expandable ANSI logs that follow the output, and retry for failed steps.

PreviewOpen ↗

Code

import { DeployView } from "@fadymondy/nasaq/web";export function Deploy() {  return (    <DeployView      title="Deploy api to production"      meta="main · 4f2a91c"      steps={[        { id: "install", name: "Install", command: "pnpm install", status: "success", durationMs: 8200 },        { id: "build", name: "Build", command: "pnpm build", status: "running", startedAt: Date.now() - 4000, logs: "compiling..." },        { id: "ship", name: "Release", status: "pending" },      ]}      onRetry={async (id) => {}}    />  );}

Server Tools · stable

Live examples and controls: DeployView in the lab.

Install

npx shadcn@latest add https://docs.nasaqui.com/r/deploy-view.json

Shows one deploy or pipeline run. The header has the title, meta (commit, branch, who), an overall status badge, the total duration and a progress bar. Under it, each step has a status icon that differs by shape (not just colour), the step name, its command, and a duration that counts up while it runs. A step opens to show its logs (ANSI colours allowed) which follow the newest line while it runs, and a failed step shows its error and a Retry button. Presentational: you update steps as the pipeline advances and handle onRetry and onCancel.

When to use

  • Deploys, CI runs, migrations, installs: any ordered list of steps with output.

When not to use

  • Free-form output: use Terminal.
  • A searchable stream: use LogViewer.
  • A user-facing checklist: use a stepper or CheckoutSteps.

Import

import { DeployView } from "@fadymondy/nasaq/web";
// inside this monorepo: "@nasaq/web"

Quick start

import { DeployView } from "@fadymondy/nasaq/web";

export function Deploy() {
  return (
    <DeployView
      title="Deploy api to production"
      meta="main · 4f2a91c"
      steps={[
        { id: "install", name: "Install", command: "pnpm install", status: "success", durationMs: 8200 },
        { id: "build", name: "Build", command: "pnpm build", status: "running", startedAt: Date.now() - 4000, logs: "compiling..." },
        { id: "ship", name: "Release", status: "pending" },
      ]}
      onRetry={async (id) => {}}
    />
  );
}

Anatomy

DeployView      data-slot="deploy-view"          <section>
├─ header       data-slot="deploy-view-header"   title, meta, status badge, duration, cancel, progress
└─ steps        data-slot="deploy-view-steps"    <ol>
   └─ step      data-slot="deploy-step"          <li> Collapsible: icon, name, command, duration, chevron
      ├─ error  (Alert)                          when failed
      ├─ logs   data-slot="deploy-step-logs"     ANSI text, follows the tail while running
      └─ retry  (Button)                         when failed and onRetry is set

API

PropTypeDefaultDescription
stepsDeployStep[]required{ id, name, command?, status, startedAt?, durationMs?, logs?, error? }.
title?ReactNode"Deploy" / "النشر"What is being deployed.
meta?ReactNodenoneCommit, branch, author.
status?DeployStatusderivedpending running success failed skipped cancelled.
onCancel?() => Promise<DeployResult> | DeployResultnoneShows Cancel while running.
onRetry?(stepId) => Promise<{ error? } | void>noneShows Retry on failed steps. Resolve { error } to keep it failed with a message.
defaultExpanded?string[]failed and runningStep ids open at the start.
maxLogLines?number500Lines kept per step.
logHeight?string"14rem"Height of a step's log.
labels?Partial<DeployViewLabels>built-in en/arTranslations.

Helpers: deriveStatus, stepDuration, totalDuration, formatDuration, tailLines, completedCount.

Examples

Retry

<DeployView steps={steps} onRetry={async (id) => { const r = await api.retry(id); return r.ok ? undefined : { error: r.message }; }} />

Accessibility

KeyAction
TabEach step trigger, then its buttons
Enter / SpaceOpen or close a step
  • Each step trigger is a button with aria-expanded and a name that includes the status text.
  • Status is text and shape, never colour alone. The overall status is a badge with text.
  • The step list is an ordered list. Running durations update once a second, not through a live region.

RTL & i18n

  • Commands and logs are dir="ltr" inside Arabic pages; step names, status text and buttons follow the page.
  • The chevron mirrors. Durations use Latin digits with translated units (1m 04s / 1د 04ث).
  • Built-in Arabic strings; override with labels.

Styling & tokens

  • Status colours: text-nq-success-text, -danger-text, -warning-text, -info-text, text-muted-foreground. Logs on bg-nq-surface-soft.
  • Slots: deploy-view, deploy-view-header, deploy-view-steps, deploy-step, deploy-step-logs. data-status on each step.

Do / Don't

  • Do send startedAt for running steps so the duration is accurate after a refresh.
  • Do return { error } from onRetry instead of throwing.
  • Don't put secrets in logs; mask them at the source.
  • Don't reorder steps while running.

Lab

https://docs.nasaqui.com/?path=/docs/components-server-tools-deploy-view--docs

On this page