diff --git a/public/app/features/dashboard-scene/serialization/DashboardSceneSerializer.test.ts b/public/app/features/dashboard-scene/serialization/DashboardSceneSerializer.test.ts index 7683b9655ae..20b3d5fe16f 100644 --- a/public/app/features/dashboard-scene/serialization/DashboardSceneSerializer.test.ts +++ b/public/app/features/dashboard-scene/serialization/DashboardSceneSerializer.test.ts @@ -565,9 +565,44 @@ describe('DashboardSceneSerializer', () => { }); }); - it('should throw on getTrackingInformation', () => { - const serializer = new V2DashboardSerializer(); - expect(() => serializer.getTrackingInformation()).toThrow('Method not implemented.'); + describe('tracking information', () => { + it('provides dashboard tracking information with no initial save model', () => { + const dashboard = setupV2(); + const serializer = new V2DashboardSerializer(); + expect(serializer.getTrackingInformation(dashboard)).toBe(undefined); + }); + + it('provides dashboard tracking information with from initial save model', () => { + const dashboard = setupV2({ + timeSettings: { + nowDelay: '10s', + from: '', + to: '', + autoRefresh: '', + autoRefreshIntervals: [], + quickRanges: [], + hideTimepicker: false, + weekStart: '', + fiscalYearStartMonth: 0, + }, + liveNow: true, + }); + + const serializer = new V2DashboardSerializer(); + serializer.initialSaveModel = dashboard.getSaveModel()! as DashboardV2Spec; + + expect(serializer.getTrackingInformation(dashboard)).toEqual({ + uid: 'dashboard-test', + title: 'hello', + schemaVersion: 40, + panels_count: 1, + panel_type__count: 1, + variable_type_custom_count: 1, + settings_nowdelay: undefined, + settings_livenow: false, + version_before_migration: 1, + }); + }); }); it('should throw on getSaveAsModel', () => { diff --git a/public/app/features/dashboard-scene/serialization/DashboardSceneSerializer.ts b/public/app/features/dashboard-scene/serialization/DashboardSceneSerializer.ts index 333ed4ee1dc..57fc8898fd0 100644 --- a/public/app/features/dashboard-scene/serialization/DashboardSceneSerializer.ts +++ b/public/app/features/dashboard-scene/serialization/DashboardSceneSerializer.ts @@ -2,7 +2,12 @@ import { config } from '@grafana/runtime'; import { Dashboard } from '@grafana/schema'; import { DashboardV2Spec } from '@grafana/schema/dist/esm/schema/dashboard/v2alpha0/dashboard.gen'; import { SaveDashboardAsOptions } from 'app/features/dashboard/components/SaveDashboard/types'; -import { getV1SchemaPanelCounts, getV1SchemaVariables } from 'app/features/dashboard/utils/tracking'; +import { + getPanelPluginCounts, + getV1SchemaPanelCounts, + getV1SchemaVariables, + getV2SchemaVariables, +} from 'app/features/dashboard/utils/tracking'; import { SaveDashboardResponseDTO } from 'app/types'; import { getRawDashboardChanges, getRawDashboardV2Changes } from '../saving/getDashboardChanges'; @@ -28,7 +33,7 @@ export interface DashboardSceneSerializerLike { } ) => DashboardChangeInfo; onSaveComplete(saveModel: T, result: SaveDashboardResponseDTO): void; - getTrackingInformation: () => DashboardTrackingInfo | undefined; + getTrackingInformation: (s: DashboardScene) => DashboardTrackingInfo | undefined; getSnapshotUrl: () => string | undefined; } @@ -36,7 +41,7 @@ interface DashboardTrackingInfo { uid?: string; title?: string; schemaVersion: number; - version_before_migration?: number; + version_before_migration?: number | string; panels_count: number; settings_nowdelay?: number; settings_livenow?: boolean; @@ -159,8 +164,29 @@ export class V2DashboardSerializer implements DashboardSceneSerializerLike e.kind === 'Panel') + .map((p) => p.spec.vizConfig.kind) || []; + const panels = getPanelPluginCounts(panelPluginIds); + const variables = getV2SchemaVariables(this.initialSaveModel?.variables || []); + + if (this.initialSaveModel && s) { + return { + // TODO: schemaVersion and version_before_migration are not stored anywhere in the v2 schema + schemaVersion: 2, + version_before_migration: s.state.meta.version, + uid: s.state.uid, + title: this.initialSaveModel.title, + panels_count: panelPluginIds.length || 0, + settings_nowdelay: undefined, + settings_livenow: !!this.initialSaveModel.liveNow, + ...panels, + ...variables, + }; + } + return undefined; } diff --git a/public/app/features/dashboard/utils/tracking.ts b/public/app/features/dashboard/utils/tracking.ts index 847d0600c03..a6dbb4ed1c2 100644 --- a/public/app/features/dashboard/utils/tracking.ts +++ b/public/app/features/dashboard/utils/tracking.ts @@ -4,6 +4,7 @@ import { DashboardInteractions } from 'app/features/dashboard-scene/utils/intera import { DashboardModel } from '../state/DashboardModel'; import { PanelModel } from '../state/PanelModel'; +import { VariableKind } from '@grafana/schema/dist/esm/schema/dashboard/v2alpha0/dashboard.gen'; export function trackDashboardLoaded(dashboard: DashboardModel, duration?: number, versionBeforeMigration?: number) { // Count the different types of variables @@ -38,13 +39,11 @@ export function trackDashboardSceneLoaded(dashboard: DashboardScene, duration?: }); } -export function getV1SchemaPanelCounts(panels: Panel[] | PanelModel[]) { - return panels - .map((p) => p.type) - .reduce((r: Record, p) => { - r[panelName(p)] = 1 + r[panelName(p)] || 1; - return r; - }, {}); +export function getPanelPluginCounts(panels: string[] | string[]) { + return panels.reduce((r: Record, p) => { + r[panelName(p)] = 1 + r[panelName(p)] || 1; + return r; + }, {}); } export function getV1SchemaVariables(variableList: VariableModel[]) { @@ -56,5 +55,38 @@ export function getV1SchemaVariables(variableList: VariableModel[]) { }, {}); } +function mapNewToOldTypes(type: VariableKind['kind']): VariableModel['type'] | undefined { + switch (type) { + case 'AdhocVariable': + return 'adhoc'; + case 'CustomVariable': + return 'custom'; + case 'QueryVariable': + return 'query'; + case 'IntervalVariable': + return 'interval'; + case 'ConstantVariable': + return 'constant'; + case 'DatasourceVariable': + return 'datasource'; + case 'TextVariable': + return 'textbox'; + case 'GroupByVariable': + return 'groupby'; + default: + return undefined; + } +} + +export function getV2SchemaVariables(variableList: VariableKind[]) { + return variableList + .map((v) => mapNewToOldTypes(v.kind)) + .filter((v) => v !== undefined) + .reduce((r: Record, k) => { + r[variableName(k)] = 1 + r[variableName(k)] || 1; + return r; + }, {}); +} + export const variableName = (type: string) => `variable_type_${type}_count`; const panelName = (type: string) => `panel_type_${type}_count`;