PMM-15212 Migrate Alert Templates to PMM UI#5635
Draft
matejkubinec wants to merge 15 commits into
Draft
Conversation
Phase 1 of migrating the Alert Templates feature from the Grafana iframe into the native PMM UI. - types/alert-templates.types.ts: Template, ParamDefinition, ParamValue, Filter, CreateRule payload and enums (ParamType, ParamUnit, TemplateSource, FilterType, Severity), modeled from api/alerting/v1. - api/alert-templates.ts: list/create/update/delete templates and create-rule-from-template against /v1/alerting/*. - hooks/api/useAlertTemplates.ts: TanStack Query hooks with list-cache invalidation on mutations. - utils/alert-templates.utils.ts (+ tests): editability, duration and param-type helpers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BCjDFAPWc5qPGonYSQ7bhY
Phases 2-6 of migrating the Alert Templates feature from the Grafana iframe into the native PMM UI. - Listing (pages/alerting/templates): percona-ui Table with source chip, created-at, and row actions; edit/delete gated to USER_API templates and PMM admins. - Create/Edit/Delete template modals: react-hook-form + zod, shared YAML editor field with .yaml file upload; YAML-only per the backend. - Create alert from template (pages/alerting/create-rule): sectioned react-hook-form page with template select, dynamic float/bool/string param inputs, severity/duration, folder (from useFolders) + group + interval, and a filters field array; builds the CreateRule payload. - Routing: alerting/alert-rule-templates and alerting/new-from-template wired into router.tsx; NAV_ALERTS_TEMPLATES repointed from the Grafana iframe to the native routes. - Tests: list rendering + editability gating, and payload/defaults units. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BCjDFAPWc5qPGonYSQ7bhY
- Row actions moved into a vertical-dots (⋮) menu with Create alert rule / Edit / Delete items; edit & delete shown only for editable (USER_API) templates. - "Created at" column now includes the time (formatTimestampWithTime). - Create-alert-from-template: folder select gains a "+ Create new folder…" option that reveals a "New folder name" field; the folder is created on submit (via new useCreateFolder hook), then the rule. Group and evaluation interval continue to be created with the rule. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BCjDFAPWc5qPGonYSQ7bhY
Built-in and SaaS templates carry no creation time; the backend serializes it as Go's zero time (0001-01-01...) rather than an empty string, so the created-at column rendered "January 1, 1 at 12:00 AM". Add formatCreatedAt() which treats empty, zero-time, and invalid values as an em dash. Verified against a live PMM server. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BCjDFAPWc5qPGonYSQ7bhY
1 task
Remove the material-react-table "Show/Hide columns" toolbar button and
the per-column hide option by passing enableHiding={false}, matching the
pattern used by the RTA sessions table.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BCjDFAPWc5qPGonYSQ7bhY
Add a "View" row action (shown for all templates) that opens a read-only modal displaying the template YAML, mirroring the Edit modal without a form. Wire it through TemplateRowActions -> columns -> page state. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BCjDFAPWc5qPGonYSQ7bhY
Add a "Copy to clipboard" action (shown for all templates) to the row actions menu and the View modal, copying the template YAML. Extract a shared copyToClipboard() util (guards navigator.clipboard / isSecureContext) reused by both entry points, with notistack feedback. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BCjDFAPWc5qPGonYSQ7bhY
Change the create-alert-from-template evaluation interval from a raw seconds number to a Grafana-style Prometheus duration string with quick-pick presets (10s/30s/1m/5m/10m/15m/30m/1h) and matching validation (valid duration, >= 10s, multiple of 10s). The interval is still submitted to the backend as "<seconds>s". Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BCjDFAPWc5qPGonYSQ7bhY
Match Grafana's evaluation-group behavior in create-alert-from-template:
- Fetch existing evaluation groups for the selected folder from the
Grafana ruler API (GET /ruler/grafana/api/v1/rules/{folderUid}).
- The group is chosen from a combobox; selecting an existing group
auto-fills and locks the interval to that group's interval, shown as
read-only text ("All rules in the selected group are evaluated
every X").
- The interval is only editable when creating a new group, via a
"New evaluation group" modal (name + duration-string interval with
quick-picks and >=10s / multiple-of-10s validation).
- The group control is disabled until a target folder is chosen.
Adds api/alert-rule-groups + useFolderRuleGroups; extracts a shared
getIntervalError validator reused by the form schema and the modal.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BCjDFAPWc5qPGonYSQ7bhY
- Replace the "create new folder" select option with a dedicated "New folder" button next to the folder select, matching Grafana; the folder is created immediately via a modal (POST /api/folders) and selected. Drops the deferred newFolderTitle / sentinel handling. - Put "New evaluation group" inline (to the right) of the group select. - Fix the label/placeholder overlap when no folder/group is selected by dropping the custom displayEmpty/renderValue placeholder and relying on the field label (MUI standard behavior). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BCjDFAPWc5qPGonYSQ7bhY
The folder and evaluation-group selects are laid out in a row with
their action buttons; pass formControlProps={{ fullWidth: true }} so
each select fills the available space instead of collapsing.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BCjDFAPWc5qPGonYSQ7bhY
- Create-rule folder & evaluation: vertically center the "New folder" and "New evaluation group" buttons with their inputs (mt:0), and add an "or" separator before the "New folder" button to match the group row. - New folder modal: full-width input, wider (sm) so the form fills the content. - Alert templates list: add a Category dropdown that filters templates by technology (MySQL / MongoDB / PostgreSQL / ProxySQL / HAProxy / Valkey / PMM), inferred from the template name/summary. - Move the toolbar action cluster (Category + Add template) to the right like the RTA sessions table (muiTopToolbarProps row-reverse). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BCjDFAPWc5qPGonYSQ7bhY
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ticket number: PMM-15212
Feature build: SUBMODULES-4468
Summary
Migrates the Alert Templates feature out of the Grafana iframe and into the native PMM UI (
ui/apps/pmm). All four flows are reimplemented as native React pages: listing, create, edit, and create alert rule from template (plus delete). TheAlert templatesnav item is repointed from/graph/alerting/alert-rule-templatesto the new native routes.Built with
@percona/percona-uicomponents first, MUI where percona-ui has no equivalent,react-hook-form+zodfor all forms, and TanStack Query for server state. Each component is split into.tsx/.types.ts/.schema.ts/.messages.ts/.constants.ts/.utils.tsrather than inlining logic.Changes
types/alert-templates.types.ts,api/alert-templates.ts,hooks/api/useAlertTemplates.ts,utils/alert-templates.utils.ts, modeled fromapi/alerting/v1. Calls/v1/alerting/templatesand/v1/alerting/rules.pages/alerting/templates) — percona-uiTablewith source chip, created-at (with time; templates without a creation time show an em dash) and a per-row ⋮ actions menu (Create alert rule / Edit / Delete). Edit/Delete are offered only forUSER_API-source templates and PMM admins.Dialog-based modals; a shared YAML editor field with.yamlfile upload. Create/Edit are YAML-only, matching the backend.pages/alerting/create-rule) — sectioned form: template select, dynamic float/bool/string param inputs (with min/max validation), severity/duration, folder (viauseFolders) with an inline "Create new folder…" option, evaluation group + interval, filters field array, and a read-only expression view. Builds theCreateRulepayload; a new folder (if requested) is created on submit, then the rule.alerting/alert-rule-templatesandalerting/new-from-templateadded torouter.tsx;NAV_ALERTS_TEMPLATESrepointed to the native routes.Screenshots
Alert templates — add
Row actions ⋮ menu
Create alert rule from template
Verification
Ran against
ui/apps/pmm: typecheck, lint and format:check pass; full test suite green (278+ passed, 0 failed). Additionally exercised end-to-end against a live PMM server (make env-updev container, admin/admin) — the listing renders the 42 real built-in templates and the create-rule form correctly seeds params/severity/duration and the read-only expression from a real template. This run surfaced and fixed a created-at bug (backend sends Go zero-time for built-in templates).Notes for reviewers
CreateTemplate/UpdateTemplateaccept a raw YAML string).custom_labelsis omitted from the create-rule form (as in the legacy UI), which also avoidsaxios-case-convertermangling user-defined label map keys.API documentation
This PR does not add, remove, or alter API endpoints (it consumes existing
/v1/alerting/*and Grafana folder endpoints).Related work
claude/alert-templates-pmm-migration-bw7vfmexist inpercona/grafanaandpercona/percona-uibut currently carry no changes.🤖 Generated with Claude Code
https://claude.ai/code/session_01BCjDFAPWc5qPGonYSQ7bhY