Nasaq
Components

ApmPage

An application performance page - latency percentiles, throughput, error rate with an SLO, slow endpoints and traces with a span waterfall.

PreviewOpen ↗

Code

import { ApmPage } from "@fadymondy/nasaq/web";import { useState } from "react";export function Performance({ service, data }: { service: React.ComponentProps<typeof ApmPage>["service"]; data?: React.ComponentProps<typeof ApmPage>["data"] }) {  const [hours, setHours] = useState(6);  return <ApmPage service={service} data={data} app="api.nasaq.dev" targetMs={500} slo={0.01} period={hours} onPeriodChange={setHours} onConnect={async () => {}} onDisconnect={async () => {}} />;}

Monitoring · beta

Live examples and controls: ApmPage in the lab.

Install

npx shadcn@latest add https://docs.nasaqui.com/r/apm-page.json

The APM page composes MetricTiles (requests, throughput, p95, error rate), LatencyPercentiles, ErrorRatePanel, a throughput TimeSeriesPanel, and tabs for slow endpoints (EndpointTable) and recent traces (TraceList, with a span waterfall). The window is in hours: period is 1, 6 or 24 by default. Until connected it shows AnalyticsConnect.

When to use

  • Watching an API or service after a deploy.
  • Finding slow endpoints and failing requests.

When not to use

Import

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

Quick start

import { ApmPage } from "@fadymondy/nasaq/web";
import { useState } from "react";

export function Performance({ service, data }: { service: React.ComponentProps<typeof ApmPage>["service"]; data?: React.ComponentProps<typeof ApmPage>["data"] }) {
  const [hours, setHours] = useState(6);
  return <ApmPage service={service} data={data} app="api.nasaq.dev" targetMs={500} slo={0.01} period={hours} onPeriodChange={setHours} onConnect={async () => {}} onDisconnect={async () => {}} />;
}

Anatomy

ApmPage                AnalyticsPageFrame
  MetricTiles
  LatencyPercentiles   + ErrorRatePanel
  TimeSeriesPanel      throughput
  Tabs (underline)     Slow endpoints | Traces

API

ApmPage

PropTypeDefaultDescription
serviceIntegrationServicerequiredThe source and its state; anything but connected shows the connect screen.
data…DatanoneThe report. While it is undefined the page shows skeletons.
period / onPeriodChangenumber / (n) => voidrequiredThe reporting period in days (hours for the APM page).
loadingbooleanfalseSkeletons.
error / onRetryReactNode / () => voidnoneShows an error with a retry button.
onRefresh / refreshing / updatedAt() => Promise / boolean / datenoneRefresh button and the updated time.
onConnect / onDisconnect / onSelectAccountasync callbacksrequiredOAuth and account picker hooks; the host does the real work.
classNamestringnoneExtra classes on the root.
appstringnoneThe application, for the subtitle.
slowMsnumber1000Above this an endpoint or trace is slow.
targetMsnumbernoneLatency target line.
slonumbernoneError-rate objective as a fraction.
windowsreadonly number[][1, 6, 24]Window lengths in hours for the toggle.
onEndpointClick / onErrorClick / onTraceSelectcallbacksnoneDrill-down hooks.
labels / frameLabelsPartial<…>nonePage strings and the shared header strings.

ApmData

summary (requests, throughput, p95, errorRate; each { value, previous?, trend? }), latency, latencySummary?, previousLatencySummary?, errors, previousErrorRate?, topErrors?, throughput (rows of date, rpm), previousThroughput?, endpoints and traces.

Examples

Sign-in expired:

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

export const Expired = () => (
  <ApmPage
    service={{ id: "apm", name: "Nasaq APM", scopes: [{ id: "apm.read", label: "Read traces and metrics", required: true }], status: "needs-reauth" }}
    period={6}
    onPeriodChange={() => {}}
    onConnect={async () => {}}
    onDisconnect={async () => {}}
  />
);

Accessibility

The page has one h1; tabs follow the WAI-ARIA tabs pattern (arrow keys move, the panel is labelled by its tab). Charts and tables carry text alternatives. Disconnect asks for confirmation. Localise every string you override through labels.

RTL & i18n

  • The whole page mirrors; charts run right to left.
  • URLs, paths and identifiers stay left-to-right inside Arabic text.
  • Every figure uses the active locale with Western digits and is bidi-isolated (Num), so +12.4% keeps its order in Arabic.
  • Routes, methods, status codes and span names are left-to-right.

Styling & tokens

  • Colours come from tokens (--primary, --nq-success, --nq-warning, --nq-danger, --nq-tag-*); never pass raw hex.
  • Composed from tokens only; extend with className.

Do / Don't

  • Do pass percentiles in milliseconds and rates as fractions.
  • Do attach spans to traces so the waterfall works.
  • Don't show averages instead of percentiles.

Lab

https://docs.nasaqui.com/?path=/docs/components-monitoring-pages-apm--docs

On this page