feat(dashboard): rewrite grafana import with migration ledger and con… - #2287
Conversation
…version report - split legacy grafana->n9e conversion into utils/grafanaImport (migrate to schema 42, real 4.0.0 mapping, datasource/variable/panel/ target/option/units modules) - add two-step import: convert and show report (migration ledger, unsupported items, summary) before saving - add ImportGrafanaReport view and i18n for en/ja/ru/zh-CN/zh-HK - drop updateSchema.ts (replaced by migrate.ts) and exclude grafanaImport from check-dashboard-types
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR refactors the legacy Grafana→N9E dashboard import into a dedicated utils/grafanaImport module that (1) migrates classic Grafana dashboards up to schema 42, (2) converts to “true” N9E 4.0.0 dashboard shape, and (3) produces a conversion report (migration ledger + unsupported items) that is shown to users before persisting.
Changes:
- Extract and rewrite Grafana import conversion into
src/pages/dashboard/utils/grafanaImport/*with schema migration (to 42), mapping modules (variables/panels/options/units/datasource), and a structured report API. - Update the dashboard import modal to a two-step flow: convert → show report → confirm save, with new i18n strings for the report UI.
- Remove the old
updateSchema.tsand adjust the dashboard type-check script to exclude the new import implementation from type checks.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/pages/dashboard/utils/index.ts | Removes inlined legacy Grafana conversion code; re-exports new grafanaImport entry points. |
| src/pages/dashboard/utils/grafanaImport/index.ts | Public exports for migration + conversion APIs and related types. |
| src/pages/dashboard/utils/grafanaImport/types.ts | Introduces internal Grafana/import types and report/ledger structures. |
| src/pages/dashboard/utils/grafanaImport/migrate.ts | Implements offline Grafana schema migration pipeline up to schema 42 with a migration ledger. |
| src/pages/dashboard/utils/grafanaImport/migrate.test.ts | Adds unit tests for migration behavior, idempotency, and skipped migrations. |
| src/pages/dashboard/utils/grafanaImport/convert.ts | Adds conversion entry points (with/without report) and output assembly into N9E 4.0.0 shape. |
| src/pages/dashboard/utils/grafanaImport/convert.test.ts | Adds extensive conversion tests (targets, mixed datasource handling, downgrade reporting, etc.). |
| src/pages/dashboard/utils/grafanaImport/datasource.ts | Normalizes Grafana datasource references into N9E runtime-compatible datasource variable references. |
| src/pages/dashboard/utils/grafanaImport/variables.ts | Converts Grafana templating variables into N9E configs.var, with downgrade reporting. |
| src/pages/dashboard/utils/grafanaImport/panels.ts | Converts Grafana panels/rows/targets into N9E panel structures (including mixed-datasource behavior). |
| src/pages/dashboard/utils/grafanaImport/options.ts | Converts shared panel options (units/thresholds/mappings/legend/tooltip/links/overrides) with reporting. |
| src/pages/dashboard/utils/grafanaImport/units.ts | Adds unit/color/macro mapping helpers used by conversion. |
| src/pages/dashboard/updateSchema.ts | Deletes the old Grafana schema update implementation in favor of migrate.ts. |
| src/pages/dashboard/List/Import/index.tsx | Switches Grafana import to a two-step convert+report+confirm flow; resets state on close/tab switch. |
| src/pages/dashboard/List/Import/ImportGrafanaReport.tsx | New report UI to display conversion summary, unsupported items, and migration ledger; supports copying a Markdown report. |
| src/pages/dashboard/locale/en_US.ts | Adds i18n entries for the new conversion report UI; removes old version warning strings. |
| src/pages/dashboard/locale/ja_JP.ts | Adds i18n entries for the new conversion report UI; removes old version warning strings. |
| src/pages/dashboard/locale/ru_RU.ts | Adds i18n entries for the new conversion report UI; removes old version warning strings. |
| src/pages/dashboard/locale/zh_CN.ts | Adds i18n entries for the new conversion report UI; removes old version warning strings. |
| src/pages/dashboard/locale/zh_HK.ts | Adds i18n entries for the new conversion report UI; removes old version warning strings. |
| scripts/check-dashboard-types/index.js | Excludes grafanaImport from dashboard type-check script and reformats some diagnostic logging. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| export function convertDashboardGrafanaToN9EWithReport(source: unknown, options?: ConvertOptions): ConvertResult { | ||
| validateDashboard(source); | ||
| // grafana 导出常为 { dashboard: {...} } 包裹,解包后处理 | ||
| const root: Record<string, any> = 'dashboard' in (source as any) && _.isPlainObject((source as any).dashboard) ? (source as any).dashboard : (source as Record<string, any>); | ||
|
|
| /** 转换单个非 row 面板;类型不支持返回 null */ | ||
| function convertNonRowPanel(panel: GrafanaPanel, ctx: ResolveContext, report: ReportFn, index: number): any | null { | ||
| const id = panel.id !== undefined && panel.id !== null ? String(panel.id) : `panel-${index}`; | ||
| const path = `$.panels[id=${id}]`; | ||
| // 不支持的面板类型:保留为 unknown(渲染器会显示“无效的面板类型”占位),不粗暴丢弃 |
| /** Grafana 面板类型 → N9E 类型;不支持返回 null(丢弃 + 报告,绝不输出 unknown) */ | ||
| function mapPanelType(panel: GrafanaPanel): string | null { | ||
| switch (panel.type) { |
| const handleCopy = async () => { | ||
| try { | ||
| await navigator.clipboard?.writeText(buildMarkdownReport(result)); | ||
| message.success(t('batch.import_grafana_report.copied')); | ||
| } catch (e) { | ||
| message.error(t('batch.import_grafana_report.copy')); | ||
| } | ||
| }; |
…version report