Skip to content

test(alerts): combined preview of the alerting UX stack (do not merge) - #2466

Closed
Makisuo wants to merge 116 commits into
mainfrom
ux/alerting-preview
Closed

Makisuo wants to merge 116 commits into
mainfrom
ux/alerting-preview

Conversation

@Makisuo

@Makisuo Makisuo commented Nov 10, 2026 •

Copy link
Copy Markdown
Collaborator

Not for merge. This branch is main plus the seven alerting UX PRs merged together, so one preview deploy can test them as they will land:

It also carries #2464 so the build passes while main is missing that import fix. Closed once the preview test is done; results are posted on each PR.


Autofix with [code]smith
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.

The query panel's where clause now edits as [field] [operator] [values] rows by default, with a Builder/Text switch back to the text editor. Rows map both ways to the same where-clause string (parse/print over the existing grammar), and every edit leaves as the existing whereClause text change, so previews and saving are unchanged. A clause the rows can't show stays in the text editor with a note.

Fields come from the editor's autocomplete vocabulary: common fields, then resource and source attributes in a drill-down picker (new kit ComboboxPicker). Several values OR only on attribute fields, the only filters the query engine ORs; 'is not' AND-s any number. Adds /lab/condition-builder.
- Kit: rightSheet over the Dialog Submodel (672px form size, scrolling body,
  sticky footer, slide dropped under reduced motion) with followUrl/isDismissed;
  page/kit/sheet-param holds the ?sheet= helpers (push to open, replace to close).
- Sidebar group labels fold their rows (sidebarGroupToggle, aria-expanded),
  saved to localStorage; the group holding the current page and the collapsed
  rail always show every row.
- Footer on-call pill from the schedules list's on_call_now and the session
  user: on call until the handoff, not on call, or hidden without schedules.
  Re-read at each handoff; a dot with a tooltip on the rail.
- /lab/shell shows all three, with a demo form in the sheet.
- Sheet: opening pushes a history entry marked as this tab's; dismissing
  goes back past it, and only a deep link replaces the param. Kit renamed
  to sidePanelSheet, footer receives close; sheet-param tests sit beside it.
- On-call pill: a shift past its end reads as unknown; reads again at the
  handoff, hourly while off call, on focus and visibility, and with backoff
  (60s doubling, capped) after a stale or failed answer, keeping the last
  good data. Schedule and override writes announce a re-read.
- An org with no schedules is cached per org for a day and skips the request;
  a schedule write clears it.
- "until" uses the viewer's time zone with a short zone name.
- Sidebar: the collapsed rail renders plain labels (no tab stops); the group
  holding the current page can fold and keeps only that row. The pill uses
  aria-label on the rail instead of a title.
Operators come from one engine table (where-key-rules, held to the clause handlers by test), so the builder offers only clauses the query applies. Text mode is explicit state once typed in. Edits rewrite only their own clause and Add condition emits nothing. Single-value rows use a single picker; product-events excludes and user/group ids take one value; values with both quote kinds are refused. Traces intrinsics are named fields and root_only is left to the span select. Rows lay out on a grid where only the values cell wraps, controls carry row-specific labels, and builder state clears when rows re-parse.
…ries

Replaces the numbered stepper with When / Alert when / Notify / Name cards on a connected rail. A complete card closes to a one-line summary derived from the form; a card with something missing stays open. The live chart sits above the cards as the preview.
… side panel

- Each hub section has its own path (/alerts/rules, /alerts/uptime, /alerts/slos,
  /alerts/silences, /alerts/maintenance, /alerts/on-call, /alerts/routing); /alerts
  stays the Inbox. One page instance serves them all, so a section change reads
  nothing it already has.
- Old /alerts?tab= links replace themselves with the section's path and keep
  their other params ("oncall" and "settings" map to on-call and routing).
- The sidebar's Alerts row lists the sections when active and replaces the hub's
  own section rail. Sub-item aria-current now follows the most specific match.
- New silence opens in a URL-held side panel (?sheet=silence) with a sticky
  Cancel / Save footer; Back, Cancel, Escape and a save close it.
  sidePanelSheet gains onSubmit so the panel is a form.
Card issues come from saveIssues with the query timing, so a slow SQL check opens Alert when; destination and chain names are loading, found or removed; a critical-only route reads "Critical: ..."; the Alert when summary shares the action bar's checks phrase and says recovery and no data. Cards keep the lead as the heading with the summary as a disclosure (cardButton), move focus on open and close, render their body only when open, and wrap summaries on phones.
- The silence panel clears ?sheet= in the model as soon as it closes itself,
  so a clock tick before the URL change can't reopen it. It opens only on the
  Silences section, and a viewer who can't manage loses a linked ?sheet= once
  the grants load (replaced away).
- A rule lives at /alerts/rules/<ruleId>; /alerts/<ruleId> (notifications, the
  apps) replaces itself with it, keeping its tab and window. The rule page and
  editor go back to Rules and their crumbs go through it.
- Settings automation and setup health link to the new section paths.
- The sidebar reveals the open section, every sub-item past the edge fades, on
  each route change; sub-rows are tighter, thin rules split the former groups,
  and the Inbox shows its unacknowledged count from the alert_incidents
  collection, read only while an alerts page is open.
- One AlertsTab schema next to AlertsSection; the sheet commands answer with a
  clock read instead of a no-op message.
… page

The schedule editor renders the draft with the server's renderOnCall
(alerting-core/oncall) on every edit: a lane per layer, the final lane
with No one gap bars, a gap summary with links that focus each gap,
weekend shading, a now line and a 1/2/4 week range. The detail page
draws the same timeline from the server's shifts.
Escalation chains move out of the Routing dialog into
/alerts/escalation-chains/new and /alerts/escalation-chains/:chainId.
The chain reads as a column of sentence cards (start, steps, repeat)
with a + between cards to insert a step and a per-step menu to move,
duplicate or remove it. The aside holds the name, notes, a one-line
preview, the rules that use the chain, and delete, whose confirm lists
those rules. Validation moved from the dialog into a shared form module;
the data model and API are unchanged. Routing and the rule editor link to
the new pages and the dialog is deleted.
/lab/escalation-editor renders the editor page over fixtures: new,
populated, a step inserted, invalid, and the delete confirm.
Safety and state:
- Drop returnTo and its helper: no caller passed it, and it could be
  steered off-site.
- Ask before leaving with unsaved edits (link, Back or Cancel). A clean
  form, or one put back to how it was, leaves at once.
- Save and Create go back to Routing with the toast, so the list shows
  the saved name and rules.
- A chain deleted elsewhere reads as not found with the way back, and a
  save that hits it says the chain no longer exists.
- A delete the API refuses reads the chain again, so the dialog names
  the rule that took it and holds its Delete.
- Viewers without alerts:manage read the chain and who uses it; nothing
  can be edited, saved or deleted. Nothing renders until the session
  answers.
- Step edits move focus: a new or duplicated step to its Add button, a
  removed step to the one before it or the leading +.
- Remove the unused step messages.

Layout:
- A step is two lines: "Notify" with its targets as inline chips and an
  Add chip, then the wait. A three-step chain fits in 800px.
- Targets draw their own mark: the destination's logo, a person's
  avatar, a schedule's calendar with who is on call now.
- The last step of a chain that does not repeat reads "then stop".
- The picker says what is still loading and where to make a
  destination; someone removed from the org reads "Unavailable member".
- The connector is a 24px line whose + shows on hover, focus and touch.
- Delete is a quiet destructive button under the details; a paused rule
  says so in Used by.

Kit: pickChips, chainConnector, and a destructive-ghost button variant.
… fit, narrow day headers

A gap is a hollow, hatched bar in the error tone instead of a warning
wash. A bar hides its label under 3.75rem and shows initials when two
characters fit. Layer rows can leave the tab order. Day headers stack
and thin out their dates as days narrow, and the label column sizes to
the timeline's own width.
- The detail calendar draws a skeleton until the shifts for the picked
  range land, instead of old shifts read as one long gap.
- A wholly past range says its gaps are not checked; a draft cannot
  step back from today.
- A layer with a half-typed window does not preview as always active.
- The preview redraws only when the zone, layers, members, minute or
  range change.
- An uncovered schedule says nobody is on call; a gap cut off by the
  range's end has no end time.
- The start note shows only for a new schedule started on an earlier
  day and names who is on call now.
- The editor is two columns from 46rem of room, the preview held in
  view while the form scrolls.
- One shared focus command for gap links.
Select takes alignItemWithTrigger={false} to open below its trigger. The chips field takes a size. ComboboxPicker's list is 360px wide and its trigger takes a tooltip. A popup with its own search input keeps focus there when an option is pressed, so typing, Enter and Escape go on working after a mouse pick that leaves the list open.
Rows read as sentences: the field and operator are as wide as their text, the field shows its key without the attr./resource. prefix (the group named only when two fields read the same, the full key in the tooltip and label). A narrow editor puts each row on two lines so the field name always shows, and value inputs are 16px on phones. Every row has one value control of one height: chips where it may hold several values, a combobox with suggestions otherwise.

The field list is 360px wide, always has a highlight (the first option on open, the picked field after drilling in), and Enter picks it. The operator list opens below its trigger. The Builder/Text switch is a 28px control at the top right, level with the first row. A clause the rows can't show gets one line saying why, and the dropped OR group warning says only that it is not applied.
…size

- A `scrim-panel` token (12% black, 24% in dark) with no blur sits beside a
  side panel, so the page it edits stays readable. Dialogs and other sheets
  keep `scrim`.
- `sidePanelSheet` takes `size`: `compact` (28rem) for a few short fields,
  `form` (42rem, the default) or `wide`.
@Makisuo

Makisuo commented Nov 10, 2026

Copy link
Copy Markdown
Collaborator Author

Closing: this branch existed only to test the seven alerting UX PRs together on one preview. The preview test and the end-to-end suite both passed here, and the results are posted on each PR (#2419, #2426, #2435, #2436, #2451, #2420, #2425).

@Makisuo Makisuo closed this Nov 10, 2026
@Makisuo
Makisuo deployed to preview-tinybird November 10, 2026 14:01 — with GitHub Actions Active

This branch was successfully deployed

1 active and 1 inactive deployments
preview-tinybird — b3169db6 Deployed Nov 10, 2026 by Makisuo via branch #859
pr-preview — b3169db6 Deployed Nov 10, 2026 by Makisuo via deploy-pr-preview #11293
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

preview Deploy a full PR preview stack (Cloudflare + AWS ingest); removing it tears it down

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant