Skip to content

Rich webhook event subscription input - #3326

Open
benjaminleonard wants to merge 5 commits into
webhooksfrom
webhooks-input
Open

Rich webhook event subscription input#3326
benjaminleonard wants to merge 5 commits into
webhooksfrom
webhooks-input

Conversation

@benjaminleonard

Copy link
Copy Markdown
Contributor

Rich event subscription input. Will require a bit of QA to check for robustness but the UX pattern feels satisfying. Good for both quickly adding classes and discoverability of the glob pattern matching.

Tag style input with chips for each of the subscription globs. Colour-coded to distinguish between exact and broad classes.

Dropdown opens on focus, showing the full catalog with name and description per row, subscribed classes sorted to the top (order is frozen while open so rows don't jump mid-picking). Rows are checkboxes: ticking commits an exact class without resetting the query, so multiple picks are cheap. Row states:

  • pending — matches the glob being typed, labeled with the pattern (HARDWARE.*.FAULT)
  • near miss — one segment too deep for the typed glob, labeled with the ** widening that would cover it
  • covered — matched by a committed glob; locked with a via hardware.** label so it can't be double-added
  • Plain-text queries substring-filter with the match emphasized. Zero matches shows an empty state with a Clear button. An incomplete glob like *. shows the whole catalog rather than no results.
CleanShot 2026-08-14 at 12 02 44

Enter commits the query or toggles the highlighted row. Up/Down navigate rows, skipping covered ones. Backspace on an empty query arms the last chip; a second press deletes it. Left/Right move the armed selection so any chip can be deleted, and typing disarms.

Adding or removing chips can wrap the input to a new line, which would shift the dropdown; a ResizeObserver scrolls the page by the height delta so the panel and the line you're typing on stay put.


Also included:

subscriptionRegex moved from the mock handlers into app/api/util.ts (with tests) since the field now matches globs client side against a single catalog fetch.

  • Mock catalog expanded with system-level classes (hardware.sled.*, hardware.disk.*, system.update.*, etc.) modeled on the existing PSU classes and RFD 538's FMA framing. Mock-only; Omicron still defines just three.
  • Info message above the field explaining glob syntax, linking the webhooks guide and API docs. Note: the guide URL (guides/operator/webhooks) doesn't exist yet and needs to before release.
  • E2E coverage for the full interaction set; the detail page's add-subscription modal is unchanged.

@vercel

vercel Bot commented Aug 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
console Ready Ready Preview Aug 14, 2026 1:03pm

Request Review

Comment on lines +125 to +127
Event subscriptions may include simple globs to subscribe to multiple categories of
events. E.g. <code className={globCode}>hardware.**</code> or{' '}
<code className={globCode}>**.fault</code>.{' '}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we call these "Alerts" and "alert classes" rather than "events"? This is the language used in the API and in the documentation.

Suggested change
Event subscriptions may include simple globs to subscribe to multiple categories of
events. E.g. <code className={globCode}>hardware.**</code> or{' '}
<code className={globCode}>**.fault</code>.{' '}
Alert subscriptions may include simple globs to subscribe to multiple classes of
alerts. E.g. <code className={globCode}>hardware.**</code> or{' '}
<code className={globCode}>**.fault</code>.{' '}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, we talked about this on a call yesterday after the FMA sync. also saying “subscriptions” as appropriate

Comment on lines +128 to +134
<a
href={links.webhooksGuide}
target="_blank"
rel="noreferrer"
className="mt-1 inline-block"
>
Read the Webhooks guide

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this link to the section on globing in the alerts guide?

},
{
"label": "New webhook receiver",
"path": "/system/alerts-new",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the name "alerts new" makes sense here. We aren't creating a new alert, we are creating a new webhook receiver, which is a kind of alert receiver.

Comment thread app/util/links.ts
Comment on lines +31 to +32
// TODO: this guide does not exist yet; make sure it does before release
webhooksGuide: 'https://docs.oxide.computer/guides/operator/webhooks',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this might be out of date: we could link to the top level alerts guide at https://docs.oxide.computer/guides/alerts/overview (which contains the explanation of alert classes and how glob patterns match them), and/or the webhooks guide at https://docs.oxide.computer/guides/alerts/webhooks (which discusses secrets and other details of how alerts are sent to webhooks receivers), as appropriate

Comment thread app/api/util.spec.ts

describe('subscriptionRegex', () => {
it('matches exact class names', () => {
expect(subscriptionRegex('probe').test('probe')).toBe(true)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'probe' is not a valid alert class to subscribe to, and the server will reject attempts to subscribe to the probe class with a 400 error. it's not treated as a "real" alert class. i think we shouldn't be testing with it if the API will reject it; we might want to explicitly include that rule in client side validation.

@hawkw

hawkw commented Aug 14, 2026

Copy link
Copy Markdown
Member

Backspace on an empty query arms the last chip

what does this, uh. mean?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants