PMM-15180 Replace local custom SVG icons with peak-ui and MUI components (2nd try) - #5742
PMM-15180 Replace local custom SVG icons with peak-ui and MUI components (2nd try)#5742pmcf-percona wants to merge 7 commits into
Conversation
Replace PMM's bundled SVG icons with design-system and Material components and adopt the @percona/percona-ui -> @percona/peak-ui rename (@percona/peak-ui@1.0.25). - 7 brand icons + 14 custom glyphs -> @percona/peak-ui components - 24 standard glyphs -> @mui/icons-material - RTA empty state -> RealTimeDatabaseOffIllustration - remove 3 unreferenced icons + the dead `node` map alias - src/icons/ trimmed to the status icons and PMM logos, kept by design Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GvaaWAnYeGgjBFDcrFv9Jx
Signed-off-by: Claude <noreply@anthropic.com>
Signed-off-by: Claude <noreply@anthropic.com>
WalkthroughPMM updates its UI dependency from ChangesPeak UI migration
Possibly related PRs
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
ui/apps/pmm/package.json (1)
29-29: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMake it so: update the stale PMM UI guidance.
@percona/peak-ui@1.0.25is declared, locked, and used by the application. Replace obsolete@percona/percona-uireferences inAGENTS.md,ui/AGENTS.md,ui/apps/pmm/README.md, andui/apps/pmm/vite.config.ts. Before merge, runcd ui && make lintand complete live PMM verification for the theme, snackbar, and icon changes.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@ui/apps/pmm/package.json` at line 29, Update the stale PMM UI guidance by replacing all `@percona/percona-ui` references with `@percona/peak-ui` in AGENTS.md, ui/AGENTS.md, ui/apps/pmm/README.md, and ui/apps/pmm/vite.config.ts, keeping the declared 1.0.25 dependency consistent. Before merging, run cd ui && make lint and complete live PMM verification for the theme, snackbar, and icon changes.Source: Coding guidelines
ui/apps/pmm/src/pages/rta/overview/RealtimeOverview.tsx (1)
8-18: 🎯 Functional Correctness | 🔵 TrivialComplete the required UI validation before release.
Run
cd ui && make lint. Then run PMM on a live server with real RTA data. Verify pause, resume, refresh, export, and all-sessions controls in light and dark themes. Verify keyboard focus and accessible labels.As per coding guidelines:
**/*.{go,ts,tsx,json}changes require the matching linter, and user-visible changes require PMM on a live server with real data.Also applies to: 152-152, 170-170, 183-183, 210-210
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@ui/apps/pmm/src/pages/rta/overview/RealtimeOverview.tsx` around lines 8 - 18, Validate the RealtimeOverview controls before release: run the matching UI lint, then test pause, resume, refresh, export, and all-sessions behavior on a live PMM server with real RTA data in both light and dark themes. Verify keyboard focus and accessible labels for the controls associated with DynamicFeed, FileDownloadOutlined, Pause, PlayArrow, and Refresh.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@ui/apps/pmm/src/pages/rta/overview/auto-refresh-select/AutoRefreshSelect.tsx`:
- Around line 42-47: Add fontSize="inherit" to the ElectricBoltIcon rendered in
AutoRefreshSelect, matching ElectricBoltOffIcon so both electric-bolt states
inherit the button’s size while preserving the existing animation and color.
In
`@ui/apps/pmm/src/pages/updates/change-log/release-notes/ReleaseNotes.constants.tsx`:
- Around line 17-18: Update the release-note icon definitions for danger and
note in ReleaseNotes.constants.tsx to use theme-aware MUI color props or sx
values instead of fixed htmlColor values. Match the corresponding alert style
tokens already used in ReleaseNotes.tsx, preserving the existing icon mappings.
---
Nitpick comments:
In `@ui/apps/pmm/package.json`:
- Line 29: Update the stale PMM UI guidance by replacing all `@percona/percona-ui`
references with `@percona/peak-ui` in AGENTS.md, ui/AGENTS.md,
ui/apps/pmm/README.md, and ui/apps/pmm/vite.config.ts, keeping the declared
1.0.25 dependency consistent. Before merging, run cd ui && make lint and
complete live PMM verification for the theme, snackbar, and icon changes.
In `@ui/apps/pmm/src/pages/rta/overview/RealtimeOverview.tsx`:
- Around line 8-18: Validate the RealtimeOverview controls before release: run
the matching UI lint, then test pause, resume, refresh, export, and all-sessions
behavior on a live PMM server with real RTA data in both light and dark themes.
Verify keyboard focus and accessible labels for the controls associated with
DynamicFeed, FileDownloadOutlined, Pause, PlayArrow, and Refresh.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 5b4c62a3-da71-4c8b-8667-a66e87a21a6d
⛔ Files ignored due to path filters (50)
ui/apps/pmm/src/icons/account.svgis excluded by!**/*.svgui/apps/pmm/src/icons/alerts.svgis excluded by!**/*.svgui/apps/pmm/src/icons/arrow-link.svgis excluded by!**/*.svgui/apps/pmm/src/icons/backups.svgis excluded by!**/*.svgui/apps/pmm/src/icons/bottom-panel-close.svgis excluded by!**/*.svgui/apps/pmm/src/icons/bottom-panel-open.svgis excluded by!**/*.svgui/apps/pmm/src/icons/browse-dashboards.svgis excluded by!**/*.svgui/apps/pmm/src/icons/check.svgis excluded by!**/*.svgui/apps/pmm/src/icons/cluster.svgis excluded by!**/*.svgui/apps/pmm/src/icons/collapse-content.svgis excluded by!**/*.svgui/apps/pmm/src/icons/configuration.svgis excluded by!**/*.svgui/apps/pmm/src/icons/dashboards.svgis excluded by!**/*.svgui/apps/pmm/src/icons/dynamic-feed.svgis excluded by!**/*.svgui/apps/pmm/src/icons/electric-bolt-off.svgis excluded by!**/*.svgui/apps/pmm/src/icons/electric-bolt.svgis excluded by!**/*.svgui/apps/pmm/src/icons/expand-content.svgis excluded by!**/*.svgui/apps/pmm/src/icons/explore.svgis excluded by!**/*.svgui/apps/pmm/src/icons/file-download.svgis excluded by!**/*.svgui/apps/pmm/src/icons/graph-6.svgis excluded by!**/*.svgui/apps/pmm/src/icons/haproxy.svgis excluded by!**/*.svgui/apps/pmm/src/icons/help-fill.svgis excluded by!**/*.svgui/apps/pmm/src/icons/help.svgis excluded by!**/*.svgui/apps/pmm/src/icons/high-availability.svgis excluded by!**/*.svgui/apps/pmm/src/icons/home.svgis excluded by!**/*.svgui/apps/pmm/src/icons/inventory.svgis excluded by!**/*.svgui/apps/pmm/src/icons/knowledge-base.svgis excluded by!**/*.svgui/apps/pmm/src/icons/memory.svgis excluded by!**/*.svgui/apps/pmm/src/icons/my-organization.svgis excluded by!**/*.svgui/apps/pmm/src/icons/network.svgis excluded by!**/*.svgui/apps/pmm/src/icons/operating-system.svgis excluded by!**/*.svgui/apps/pmm/src/icons/overview.svgis excluded by!**/*.svgui/apps/pmm/src/icons/pause.svgis excluded by!**/*.svgui/apps/pmm/src/icons/percona-intelligence.svgis excluded by!**/*.svgui/apps/pmm/src/icons/percona-mo.svgis excluded by!**/*.svgui/apps/pmm/src/icons/percona-my.svgis excluded by!**/*.svgui/apps/pmm/src/icons/percona-po.svgis excluded by!**/*.svgui/apps/pmm/src/icons/percona-va.svgis excluded by!**/*.svgui/apps/pmm/src/icons/percona.svgis excluded by!**/*.svgui/apps/pmm/src/icons/play-arrow.svgis excluded by!**/*.svgui/apps/pmm/src/icons/proxysql.svgis excluded by!**/*.svgui/apps/pmm/src/icons/qan.svgis excluded by!**/*.svgui/apps/pmm/src/icons/real-time-database-off.svgis excluded by!**/*.svgui/apps/pmm/src/icons/refresh.svgis excluded by!**/*.svgui/apps/pmm/src/icons/search.svgis excluded by!**/*.svgui/apps/pmm/src/icons/sign-out.svgis excluded by!**/*.svgui/apps/pmm/src/icons/summary.svgis excluded by!**/*.svgui/apps/pmm/src/icons/theme-dark.svgis excluded by!**/*.svgui/apps/pmm/src/icons/theme-light.svgis excluded by!**/*.svgui/apps/pmm/src/icons/users-and-access.svgis excluded by!**/*.svgui/yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (40)
ui/apps/pmm/package.jsonui/apps/pmm/src/App.tsxui/apps/pmm/src/components/app-bar/AppBar.tsxui/apps/pmm/src/components/details-pane/DataPoint.tsxui/apps/pmm/src/components/feature-check/FeatureCheck.tsxui/apps/pmm/src/components/ha-icon/HighAvailabilityIcon.tsxui/apps/pmm/src/components/icon/Icon.constants.tsui/apps/pmm/src/components/sidebar/nav-item/SidebarNavItem.test.tsxui/apps/pmm/src/components/sidebar/nav-item/SidebarNavItem.tsxui/apps/pmm/src/components/sidebar/nav-item/nav-item-icon/NavItemIcon.test.tsxui/apps/pmm/src/contexts/navigation/navigation.constants.tsui/apps/pmm/src/contexts/navigation/navigation.utils.tsxui/apps/pmm/src/hooks/theme.tsui/apps/pmm/src/pages/alerting/status/AlertsPage.tsxui/apps/pmm/src/pages/alerting/status/details-pane/AlertDetailsPane.tsxui/apps/pmm/src/pages/alerting/status/details-pane/details/AlertDetailsTab.tsxui/apps/pmm/src/pages/alerting/status/details-pane/raw-data/RawDataTab.tsxui/apps/pmm/src/pages/alerting/status/table/AlertStatusTable.constants.tsxui/apps/pmm/src/pages/alerting/status/table/AlertStatusTable.tsxui/apps/pmm/src/pages/help-center/help-center-card/HelpCenterCard.tsxui/apps/pmm/src/pages/help-center/help-center-card/HelpCenterCard.types.tsui/apps/pmm/src/pages/rta/overview/RealtimeOverview.tsxui/apps/pmm/src/pages/rta/overview/auto-refresh-select/AutoRefreshSelect.tsxui/apps/pmm/src/pages/rta/overview/details-pane/DetailsPane.tsxui/apps/pmm/src/pages/rta/overview/details-pane/QueryAndDetails.tsxui/apps/pmm/src/pages/rta/overview/table/OverviewTable.tsxui/apps/pmm/src/pages/rta/overview/table/query-cell/QueryCell.tsxui/apps/pmm/src/pages/rta/selection/empty-state/RealtimeSelectionViewerEmptyState.tsxui/apps/pmm/src/pages/rta/sessions/sessions-table/SessionsTable.tsxui/apps/pmm/src/pages/rta/sessions/sessions-table/modal-new-session/NewSessionModal.tsxui/apps/pmm/src/pages/rta/sessions/sessions-table/modal-stop-multiple-sessions/StopMultipleSessionsModal.tsxui/apps/pmm/src/pages/rta/sessions/sessions-table/modal-stop-session/StopSessionModal.tsxui/apps/pmm/src/pages/settings/components/advanced/AdvancedSettingsForm.tsxui/apps/pmm/src/pages/settings/components/metrics-resolution/MetricsResolutionForm.tsxui/apps/pmm/src/pages/settings/components/ssh-key/SshKeyForm.tsxui/apps/pmm/src/pages/update-clients/UpdateClients.tsxui/apps/pmm/src/pages/updates/change-log/code-block/CodeBlock.tsxui/apps/pmm/src/pages/updates/change-log/release-notes/ReleaseNotes.constants.tsxui/apps/pmm/src/utils/testWrapper.tsxui/apps/pmm/vitest.config.ts
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
percona/pmm-qa(manual)percona/pmm(manual)
| <ElectricBoltIcon | ||
| color="inherit" | ||
| sx={{ animation: `${fadeInOut} 1.2s infinite` }} | ||
| /> | ||
| ) : ( | ||
| <Icon name="electric-bolt-off" color="inherit" fontSize="inherit" /> | ||
| <ElectricBoltOffIcon color="inherit" fontSize="inherit" /> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- target file ---'
cat -n ui/apps/pmm/src/pages/rta/overview/auto-refresh-select/AutoRefreshSelect.tsx
printf '%s\n' '--- icon imports and related usages ---'
rg -n -C 3 'ElectricBolt(Off)?Icon|AutoRefreshSelect' ui/apps/pmm/src ui/packages ui 2>/dev/null | head -240
printf '%s\n' '--- relevant package declarations ---'
rg -n -C 2 '"`@mui/material`"|"`@mui/icons-material`"|"`@percona/percona-ui`"|"`@percona/peak-ui`"' ui/package.json ui/apps/pmm/package.json ui/*/package.json 2>/dev/null || trueRepository: percona/pmm
Length of output: 16808
🏁 Script executed:
#!/bin/bash
set -eu
cat -n ui/apps/pmm/src/pages/rta/overview/auto-refresh-select/AutoRefreshSelect.tsx
rg -n -C 3 'ElectricBolt(Off)?Icon|AutoRefreshSelect' ui/apps/pmm/src ui 2>/dev/null | head -240
rg -n -C 2 '"`@mui/material`"|"`@mui/icons-material`"|"`@percona/percona-ui`"|"`@percona/peak-ui`"' ui/package.json ui/apps/pmm/package.json ui/*/package.json 2>/dev/null || trueRepository: percona/pmm
Length of output: 16710
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- repository references to Peak UI package metadata ---'
rg -n -C 2 '`@percona/peak-ui`|ElectricBoltIcon|ElectricBoltOffIcon' . \
-g '!ui/apps/pmm/src/pages/rta/overview/auto-refresh-select/AutoRefreshSelect.tsx' \
-g '!ui/apps/pmm/src/pages/rta/overview/auto-refresh-select/AutoRefreshSelect.test.tsx' \
-g '!*lock*' | head -240
printf '%s\n' '--- test expectations for the component ---'
cat -n ui/apps/pmm/src/pages/rta/overview/auto-refresh-select/AutoRefreshSelect.test.tsx
printf '%s\n' '--- lockfile entries ---'
rg -n -C 4 '`@percona/peak-ui`' ui/pnpm-lock.yaml pnpm-lock.yaml package-lock.json yarn.lock 2>/dev/null || trueRepository: percona/pmm
Length of output: 20039
🏁 Script executed (no clone):
#!/bin/bash
set -eu
url='https://registry.npmjs.org/@percona%2Fpeak-ui/1.0.25'
json=$(curl -fsSL "$url")
printf '%s\n' "$json" | jq -r '.dist.tarball'
printf '%s\n' "$json" | jq -r '.repository, .homepage, .types, .main, .module'
Length of output: 337
🌐 Web query:
@percona/peak-ui 1.0.25 ElectricBoltIcon ElectricBoltOffIcon
💡 Result:
There is no publicly available NPM package named @percona/peak-ui [1][2][3]. Percona maintains a UI library typically referred to as Percona UI or documented under the scope @percona/platform-core [1][2][3]. The components ElectricBoltIcon and ElectricBoltOffIcon are not standard or recognized components within Percona's public UI documentation or repositories [4][5][6][7]. These specific icon names (ElectricBoltIcon, ElectricBoltOffIcon) are common naming conventions found in various React icon libraries, such as Material UI (MUI) or other generic SVG-based icon sets [8][9][10][11]. If you are working within a Percona codebase, these icons are likely either custom SVG imports or part of a third-party icon library dependency (e.g., @mui/icons-material) integrated into your project, rather than being provided by a package named @percona/peak-ui [12].
Citations:
- 1: https://github.com/percona/percona-ui
- 2: https://registry.npmjs.org/%40percona%2Fplatform-core
- 3: https://github.com/percona/core-ui
- 4: https://docs.percona.com/percona-monitoring-and-management/3/reference/ui/ui_components.html
- 5: https://docs.percona.com/percona-monitoring-and-management/3/index.html
- 6: https://docs.percona.com/percona-monitoring-and-management/2/details/interface.html
- 7: https://docs.percona.com/
- 8: https://jsr.io/@preact-icons/md/doc/~/MdElectricBolt
- 9: https://www.shadcn.io/icon/proicons-bolt
- 10: https://www.shadcn.io/icon/prime-bolt
- 11: https://www.shadcn.io/icon/pepicons-pencil-electricity-off
- 12: a22b4e9
🏁 Script executed:
#!/bin/bash
set -eu
rg -n -C 2 '`@percona/peak-ui`|ElectricBoltIcon|ElectricBoltOffIcon' . \
-g '!ui/apps/pmm/src/pages/rta/overview/auto-refresh-select/AutoRefreshSelect.tsx' \
-g '!ui/apps/pmm/src/pages/rta/overview/auto-refresh-select/AutoRefreshSelect.test.tsx' \
-g '!*lock*' | head -240
cat -n ui/apps/pmm/src/pages/rta/overview/auto-refresh-select/AutoRefreshSelect.test.tsx
rg -n -C 4 '`@percona/peak-ui`' ui/pnpm-lock.yaml pnpm-lock.yaml package-lock.json yarn.lock 2>/dev/null || trueRepository: percona/pmm
Length of output: 19912
🏁 Script executed (no clone):
#!/bin/bash
set -eu
tmp=$(mktemp)
trap 'rm -f "$tmp"' EXIT
curl -fsSL 'http://10.0.0.28:4873/@percona/peak-ui/-/peak-ui-1.0.25.tgz' -o "$tmp"
printf '%s\n' '--- package contents relevant to icon exports ---'
tar -tzf "$tmp" | grep -E '(^|/)(index|.*icon|.*Icon).*\\.(js|d\\.ts|map)$' | head -200 || true
printf '%s\n' '--- declarations containing electric-bolt icons ---'
tar -xOzf "$tmp" package/dist/index.d.ts | grep -n -C 5 'ElectricBolt' || true
printf '%s\n' '--- implementation containing electric-bolt icons ---'
tar -xOzf "$tmp" package/dist/index.js | grep -o -E '.{0,240}ElectricBolt(Off)?Icon.{0,500}' | head -20 || true
Length of output: 5105
🏁 Script executed (no clone):
#!/bin/bash
set -eu
for url in \
'https://raw.githubusercontent.com/percona/peak-ui/main/packages/peak-ui/src/index.ts' \
'https://raw.githubusercontent.com/percona/peak-ui/master/packages/peak-ui/src/index.ts' \
'https://api.github.com/repos/percona/peak-ui/contents'; do
printf '\n--- %s ---\n' "$url"
curl -fsSL "$url" | head -80 || true
done
Length of output: 525
🏁 Script executed (no clone):
#!/bin/bash
set -eu
tmp=$(mktemp)
trap 'rm -f "$tmp"' EXIT
curl -fsSL 'http://10.0.0.28:4873/@percona/peak-ui/-/peak-ui-1.0.25.tgz' -o "$tmp"
tar -tzf "$tmp" | grep -E '(^|/)(index|.*icon|.*Icon).*\\.(js|d\\.ts|map)$' | head -200 || true
tar -xOzf "$tmp" package/dist/index.d.ts | grep -n -C 5 'ElectricBolt' || true
tar -xOzf "$tmp" package/dist/index.js | grep -o -E '.{0,240}ElectricBolt(Off)?Icon.{0,500}' | head -20 || true
Length of output: 4949
🏁 Script executed (no clone):
#!/bin/bash
set -eu
tmp=$(mktemp)
trap 'rm -f "$tmp"' EXIT
curl -fsSL 'http://10.0.0.28:4873/@percona/peak-ui/-/peak-ui-1.0.25.tgz' -o "$tmp"
printf '%s\n' '--- package files ---'
tar -tzf "$tmp" | head -120
printf '%s\n' '--- package metadata ---'
tar -xOzf "$tmp" package/package.json | jq '{name,version,main,module,types,dependencies,peerDependencies}'
printf '%s\n' '--- icon implementation anchors ---'
tar -xOzf "$tmp" package/dist/index.js > /tmp/peak-ui-index.js
python3 - <<'PY'
from pathlib import Path
s = Path('/tmp/peak-ui-index.js').read_text()
for needle in ('Nn=', 'Zn=', 'ElectricBoltIcon', 'ElectricBoltOffIcon'):
print(f'--- {needle} ---')
start = 0
count = 0
while True:
i = s.find(needle, start)
if i < 0 or count >= 5:
break
print(s[max(0, i-500):i+1200])
start = i + len(needle)
count += 1
PY
rm -f /tmp/peak-ui-index.js
Length of output: 8140
🌐 Web query:
MUI SvgIcon fontSize inherit default medium implementation
💡 Result:
In Material UI (MUI), the fontSize prop for the SvgIcon component controls the size of the icon [1][2]. The valid values for the fontSize prop are 'inherit', 'large', 'medium', and 'small' [1][2]. The component defaults to 'medium' [1][2][3]. Regarding the values mentioned: 1. 'medium': This is the default value for the fontSize prop [1][2][3]. In the MUI implementation, it maps to a font size of 24px (specifically theme.typography.pxToRem(24)) [1][3]. 2. 'default': The value 'default' was previously used but was deprecated and replaced by 'medium' [4]. 3. 'inherit': When set to 'inherit', the icon inherits the font-size of its parent element [1][2]. Implementation Details: The SvgIcon component uses the fontSize prop to determine which CSS class and styles to apply [3]. Internally, MUI maps these prop values to specific CSS font-size values using the theme's typography utility [3]: - inherit: inherit - small: theme.typography.pxToRem(20) - medium: theme.typography.pxToRem(24) - large: theme.typography.pxToRem(35) The component applies a class based on the prop value (e.g., MuiSvgIcon-fontSizeMedium for the 'medium' size) to style the root element [1][3]. Note that historically, there was no MuiSvgIcon-fontSizeMedium class for the default value, as classes were not always provided for default states, though this has evolved in the library's design [5][3].
Citations:
- 1: https://mui.com/material-ui/api/svg-icon/
- 2: https://cdn.jsdelivr.net/npm/@mui/material@6.4.8/SvgIcon/SvgIcon.d.ts
- 3: https://github.com/mui/material-ui/blob/e0cdcd130db60d252c4382570844ea7278649a08/packages/mui-material/src/SvgIcon/SvgIcon.js
- 4: [Icons] deprecate
defaultvalue forfontSizein favor ofmediummui/material-ui#23951 - 5: SvgIcon fontSizeMedium CSS rule name mui/material-ui#28221
🏁 Script executed (no clone):
#!/bin/bash
set -eu
tmp=$(mktemp)
trap 'rm -f "$tmp"' EXIT
curl -fsSL 'http://10.0.0.28:4873/@percona/peak-ui/-/peak-ui-1.0.25.tgz' -o "$tmp"
tar -tzf "$tmp" | head -120
tar -xOzf "$tmp" package/package.json | jq '{name,version,main,module,types,dependencies,peerDependencies}'
tar -xOzf "$tmp" package/dist/index.js > /tmp/peak-ui-index.js
python3 - <<'PY'
from pathlib import Path
s = Path('/tmp/peak-ui-index.js').read_text()
for needle in ('Nn=', 'Zn=', 'ElectricBoltIcon', 'ElectricBoltOffIcon'):
print(f'--- {needle} ---')
start = 0
count = 0
while True:
i = s.find(needle, start)
if i < 0 or count >= 5:
break
print(s[max(0, i-500):i+1200])
start = i + len(needle)
count += 1
PY
rm -f /tmp/peak-ui-index.js
Length of output: 7602
🏁 Script executed (no clone):
#!/bin/bash
set -eu
tmp=$(mktemp)
trap 'rm -f "$tmp"' EXIT
curl -fsSL 'http://10.0.0.28:4873/@percona/peak-ui/-/peak-ui-1.0.25.tgz' -o "$tmp"
tar -xOzf "$tmp" package/dist/index.js.map > /tmp/peak-ui-index.js.map
python3 - <<'PY'
import json
from pathlib import Path
m = json.loads(Path('/tmp/peak-ui-index.js.map').read_text())
print('sources:', len(m.get('sources', [])))
print('sourcesContent:', len(m.get('sourcesContent', [])))
for i, (src, content) in enumerate(zip(m.get('sources', []), m.get('sourcesContent', []))):
if 'electric' in src.lower() or (content and 'ElectricBolt' in content):
print(f'--- source {i}: {src} ---')
print(content[:12000])
PY
rm -f /tmp/peak-ui-index.js.map
Length of output: 12213
🏁 Script executed (no clone):
#!/bin/bash
set -eu
tmp=$(mktemp)
trap 'rm -f "$tmp"' EXIT
curl -fsSL 'http://10.0.0.28:4873/@percona/peak-ui/-/peak-ui-1.0.25.tgz' -o "$tmp"
tar -xOzf "$tmp" package/dist/index.js.map > /tmp/peak-ui-index.js.map
python3 - <<'PY'
import json
from pathlib import Path
m = json.loads(Path('/tmp/peak-ui-index.js.map').read_text())
for src, content in zip(m.get('sources', []), m.get('sourcesContent', [])):
if content and ('ElectricBoltIcon' in content or 'ElectricBoltOffIcon' in content):
print(f'--- source: {src} ---')
for needle in ('ElectricBoltIcon', 'ElectricBoltOffIcon'):
start = 0
while True:
i = content.find(needle, start)
if i < 0:
break
print(content[max(0, i-700):i+1400])
start = i + len(needle)
PY
rm -f /tmp/peak-ui-index.js.map
Length of output: 2451
🏁 Script executed (no clone):
#!/bin/bash
set -eu
tmp=$(mktemp)
trap 'rm -f "$tmp"' EXIT
curl -fsSL 'http://10.0.0.28:4873/@percona/peak-ui/-/peak-ui-1.0.25.tgz' -o "$tmp"
tar -xOzf "$tmp" package/dist/components/icons/peak/index.d.ts
tar -xOzf "$tmp" package/dist/components/icons/peak/peak.d.ts | grep -n -C 3 'ElectricBolt'
Length of output: 699
🏁 Script executed:
#!/bin/bash
set -eu
python3 - <<'PY'
from pathlib import Path
import re
target = Path('ui/apps/pmm/src/pages/rta/overview/auto-refresh-select/AutoRefreshSelect.tsx').read_text()
active = re.search(r'<ElectricBoltIcon\b(?P<props>.*?)\/>', target, re.S)
inactive = re.search(r'<ElectricBoltOffIcon\b(?P<props>.*?)\/>', target, re.S)
assert active and inactive
assert 'fontSize="inherit"' not in active.group('props')
assert 'fontSize="inherit"' in inactive.group('props')
print('active ElectricBoltIcon: no fontSize prop; MUI default applies')
print('inactive ElectricBoltOffIcon: fontSize="inherit"')
PYRepository: percona/pmm
Length of output: 261
Set both electric-bolt states to inherit the button size.
ElectricBoltIcon defaults to MUI’s medium size, while ElectricBoltOffIcon uses inherit. Add fontSize="inherit" to ElectricBoltIcon. Make it so.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@ui/apps/pmm/src/pages/rta/overview/auto-refresh-select/AutoRefreshSelect.tsx`
around lines 42 - 47, Add fontSize="inherit" to the ElectricBoltIcon rendered in
AutoRefreshSelect, matching ElectricBoltOffIcon so both electric-bolt states
inherit the button’s size while preserving the existing animation and color.
| danger: <Dangerous htmlColor="#ff1744" />, | ||
| note: <Edit htmlColor="#448aff" />, |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- target file ---'
cat -n ui/apps/pmm/src/pages/updates/change-log/release-notes/ReleaseNotes.constants.tsx
printf '%s\n' '--- applicable guidance files ---'
find .. -name AGENTS.md -print 2>/dev/null | sort | while read -r f; do
printf '\n--- %s ---\n' "$f"
cat "$f"
done
printf '%s\n' '--- nearby release-notes files ---'
find ui/apps/pmm/src/pages/updates/change-log/release-notes -maxdepth 2 -type f -print | sort
printf '%s\n' '--- icon color patterns in the PMM UI ---'
rg -n --glob '*.{ts,tsx}' \
'htmlColor=|color=["'"'"'](error|info|warning|success|primary|secondary)|sx=\{\{[^}]*color|color:\s*theme\.' \
ui/apps/pmm/src/pages ui/apps/pmm/src/components 2>/dev/null | head -200Repository: percona/pmm
Length of output: 50370
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- IconMap references ---'
rg -n -C 5 --glob '*.{ts,tsx}' '\bIconMap\b|\bDangerous\b|\bEdit\b' ui/apps/pmm/src
printf '%s\n' '--- exact htmlColor usage ---'
rg -n -C 3 --glob '*.{ts,tsx}' 'htmlColor=' ui/apps/pmm/src | head -160
printf '%s\n' '--- theme palette and color-token references ---'
rg -n -C 3 --glob '*.{ts,tsx}' \
'pmmThemeOptions|palette\.(error|info|warning|success)|theme\.palette|color="(error|info|warning|success)"|color:\s*['"'"'](error|info|warning|success)' \
ui/apps/pmm/src ui/packages 2>/dev/null | head -240
printf '%s\n' '--- target file history summary and diff against parent ---'
git diff --stat
git diff -- ui/apps/pmm/src/pages/updates/change-log/release-notes/ReleaseNotes.constants.tsxRepository: percona/pmm
Length of output: 30224
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- release-note renderer ---'
cat -n ui/apps/pmm/src/pages/updates/change-log/release-notes/ReleaseNotes.tsx | sed -n '1,105p'
printf '%s\n' '--- release-note tests and fixtures ---'
find ui/apps/pmm/src/pages/updates/change-log/release-notes -maxdepth 2 -type f \
\( -name '*test*' -o -name '*spec*' -o -name '*.md' \) -print -exec sh -c 'echo "--- $1"; sed -n "1,180p" "$1"' _ {} \;
printf '%s\n' '--- parent implementation ---'
git show HEAD^:ui/apps/pmm/src/pages/updates/change-log/release-notes/ReleaseNotes.constants.tsx 2>/dev/null | cat -n || true
printf '%s\n' '--- MUI package declarations ---'
rg -n -C 2 '"`@mui/`(material|icons-material)"' ui/package.json ui/**/package.json package.json 2>/dev/null | head -80
printf '%s\n' '--- focused deterministic verifier ---'
python3 - <<'PY'
from pathlib import Path
import re
path = Path("ui/apps/pmm/src/pages/updates/change-log/release-notes/ReleaseNotes.constants.tsx")
text = path.read_text()
entries = dict(re.findall(r"^\s*(danger|note):\s*<[^>]+\s+htmlColor=\"([^\"]+)\"", text, re.M))
print("entries:", entries)
print("all_colors_are_literals:", all(value.startswith("#") for value in entries.values()))
print("uses_theme_palette_icon_props:", bool(re.search(r"<(?:Dangerous|Edit)[^>]+\bcolor=\"(?:error|info|warning|success|primary|secondary)\"", text)))
PYRepository: percona/pmm
Length of output: 5261
Use theme tokens for release-note icon colors.
These fixed htmlColor values do not respond to light/dark palette changes. Replace them with MUI color props or theme-aware sx values. Use matching tokens for the related alert styles in ReleaseNotes.tsx.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@ui/apps/pmm/src/pages/updates/change-log/release-notes/ReleaseNotes.constants.tsx`
around lines 17 - 18, Update the release-note icon definitions for danger and
note in ReleaseNotes.constants.tsx to use theme-aware MUI color props or sx
values instead of fixed htmlColor values. Match the corresponding alert style
tokens already used in ReleaseNotes.tsx, preserving the existing icon mappings.
Source: Coding guidelines
Note: accidentally merged, then reverted, and now formed as a new PR here.
Ticket number: PMM-15180
Feature build: Percona-Lab/pmm-submodules#4509
Summary
PMM kept its own copies of ~50 brand and UI icons as local SVGs in
src/icons/, wired through a localIconcomponent andDYNAMIC_ICON_IMPORT_MAP. Most duplicated icons the design system or Material already provide. This PR sources them properly instead.The design system was renamed from
@percona/percona-uito@percona/peak-ui, so this also adopts@percona/peak-ui@1.0.25(the first release carrying the custom Peak Design icon suite) and repoints every existing import.Also in this PR:
@percona/peak-uicomponents (PerconaIcon,HaproxyIcon,ProxyIcon,PerconaMyIcon/MoIcon/PoIcon/VaIcon), and the RTA empty state usesRealTimeDatabaseOffIllustrationfrom the design system in place of a local 192px SVG.@mui/icons-materialacross the sidebar, theme toggle, app bar, release notes and RTA controls.collapse-content,expand-content,bottom-panel-open) and the deadnodemap alias.perconamarker is now a theme-aware monochrome icon instead of a fixed orange–gold gradient, matching the other markers.How to test
In both light and dark themes, scan the left sidebar (MySQL/MongoDB/PostgreSQL/Valkey, OS, HAProxy/ProxySQL, Dashboards, Explore, Alerts, Advisors, Inventory, Backups, Configuration, Users and access, Account, Help, theme toggle) plus the app-bar logo and support icon. Then check the Help Center "PMM docs" card, the Updates → release-notes icons, and Real-Time Analysis (overview play/pause/refresh/export, the auto-refresh bolt, the details-pane collapse button, and the empty-state illustration).
No API changes.
Related work:
@percona/peak-ui@1.0.25.Testing screenshots: