| 
									
										
										
										
											2024-12-13 17:20:22 +08:00
										 |  |  | import { Dashboard } from '@grafana/schema'; | 
					
						
							| 
									
										
										
										
											2025-01-16 20:18:47 +08:00
										 |  |  | import { DashboardV2Spec } from '@grafana/schema/dist/esm/schema/dashboard/v2alpha0'; | 
					
						
							| 
									
										
										
										
											2025-01-09 23:14:41 +08:00
										 |  |  | import { AnnoKeyDashboardSnapshotOriginalUrl } from 'app/features/apiserver/types'; | 
					
						
							|  |  |  | import { DashboardWithAccessInfo } from 'app/features/dashboard/api/types'; | 
					
						
							| 
									
										
										
										
											2024-12-13 17:20:22 +08:00
										 |  |  | import { SaveDashboardAsOptions } from 'app/features/dashboard/components/SaveDashboard/types'; | 
					
						
							| 
									
										
										
										
											2025-02-13 03:23:09 +08:00
										 |  |  | import { DASHBOARD_SCHEMA_VERSION } from 'app/features/dashboard/state/DashboardMigrator'; | 
					
						
							| 
									
										
										
										
											2025-01-03 00:33:16 +08:00
										 |  |  | import { | 
					
						
							|  |  |  |   getPanelPluginCounts, | 
					
						
							|  |  |  |   getV1SchemaVariables, | 
					
						
							|  |  |  |   getV2SchemaVariables, | 
					
						
							|  |  |  | } from 'app/features/dashboard/utils/tracking'; | 
					
						
							| 
									
										
										
										
											2025-01-09 23:14:41 +08:00
										 |  |  | import { DashboardMeta, SaveDashboardResponseDTO } from 'app/types'; | 
					
						
							| 
									
										
										
										
											2024-12-13 17:20:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-19 19:00:59 +08:00
										 |  |  | import { getRawDashboardChanges, getRawDashboardV2Changes } from '../saving/getDashboardChanges'; | 
					
						
							| 
									
										
										
										
											2024-12-13 17:20:22 +08:00
										 |  |  | import { DashboardChangeInfo } from '../saving/shared'; | 
					
						
							|  |  |  | import { DashboardScene } from '../scene/DashboardScene'; | 
					
						
							| 
									
										
										
										
											2025-03-07 01:59:27 +08:00
										 |  |  | import { getVizPanelKeyForPanelId } from '../utils/utils'; | 
					
						
							| 
									
										
										
										
											2024-12-13 17:20:22 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import { transformSceneToSaveModel } from './transformSceneToSaveModel'; | 
					
						
							|  |  |  | import { transformSceneToSaveModelSchemaV2 } from './transformSceneToSaveModelSchemaV2'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-13 01:43:32 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * T is the type of the save model | 
					
						
							|  |  |  |  * M is the type of the metadata | 
					
						
							|  |  |  |  * I is the type of the initial save model. By default it's the same as T. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | export interface DashboardSceneSerializerLike<T, M, I = T> { | 
					
						
							| 
									
										
										
										
											2024-12-13 17:20:22 +08:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * The save model which the dashboard scene was originally created from | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2025-03-13 01:43:32 +08:00
										 |  |  |   initialSaveModel?: I; | 
					
						
							| 
									
										
										
										
											2025-01-09 23:14:41 +08:00
										 |  |  |   metadata?: M; | 
					
						
							| 
									
										
										
										
											2025-03-21 02:45:25 +08:00
										 |  |  |   initializeElementMapping(saveModel: T | undefined): void; | 
					
						
							|  |  |  |   initializeDSReferencesMapping(saveModel: T | undefined): void; | 
					
						
							| 
									
										
										
										
											2024-12-13 17:20:22 +08:00
										 |  |  |   getSaveModel: (s: DashboardScene) => T; | 
					
						
							|  |  |  |   getSaveAsModel: (s: DashboardScene, options: SaveDashboardAsOptions) => T; | 
					
						
							|  |  |  |   getDashboardChangesFromScene: ( | 
					
						
							|  |  |  |     scene: DashboardScene, | 
					
						
							|  |  |  |     options: { | 
					
						
							|  |  |  |       saveTimeRange?: boolean; | 
					
						
							|  |  |  |       saveVariables?: boolean; | 
					
						
							|  |  |  |       saveRefresh?: boolean; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   ) => DashboardChangeInfo; | 
					
						
							|  |  |  |   onSaveComplete(saveModel: T, result: SaveDashboardResponseDTO): void; | 
					
						
							| 
									
										
										
										
											2025-01-03 00:33:16 +08:00
										 |  |  |   getTrackingInformation: (s: DashboardScene) => DashboardTrackingInfo | undefined; | 
					
						
							| 
									
										
										
										
											2024-12-19 23:09:19 +08:00
										 |  |  |   getSnapshotUrl: () => string | undefined; | 
					
						
							| 
									
										
										
										
											2025-03-07 01:59:27 +08:00
										 |  |  |   getPanelIdForElement: (elementId: string) => number | undefined; | 
					
						
							|  |  |  |   getElementIdForPanel: (panelId: number) => string | undefined; | 
					
						
							|  |  |  |   getElementPanelMapping: () => Map<string, number>; | 
					
						
							| 
									
										
										
										
											2025-03-21 02:45:25 +08:00
										 |  |  |   getDSReferencesMapping: () => DSReferencesMapping; | 
					
						
							| 
									
										
										
										
											2024-12-13 17:20:22 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | interface DashboardTrackingInfo { | 
					
						
							|  |  |  |   uid?: string; | 
					
						
							|  |  |  |   title?: string; | 
					
						
							|  |  |  |   schemaVersion: number; | 
					
						
							|  |  |  |   panels_count: number; | 
					
						
							|  |  |  |   settings_nowdelay?: number; | 
					
						
							|  |  |  |   settings_livenow?: boolean; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-26 23:59:34 +08:00
										 |  |  | export interface DSReferencesMapping { | 
					
						
							| 
									
										
										
										
											2025-03-21 02:45:25 +08:00
										 |  |  |   panels: Map<string, Set<string>>; | 
					
						
							|  |  |  |   variables: Set<string>; | 
					
						
							|  |  |  |   annotations: Set<string>; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-09 23:14:41 +08:00
										 |  |  | export class V1DashboardSerializer implements DashboardSceneSerializerLike<Dashboard, DashboardMeta> { | 
					
						
							| 
									
										
										
										
											2024-12-13 17:20:22 +08:00
										 |  |  |   initialSaveModel?: Dashboard; | 
					
						
							| 
									
										
										
										
											2025-01-09 23:14:41 +08:00
										 |  |  |   metadata?: DashboardMeta; | 
					
						
							| 
									
										
										
										
											2025-03-07 01:59:27 +08:00
										 |  |  |   protected elementPanelMap = new Map<string, number>(); | 
					
						
							| 
									
										
										
										
											2025-03-21 02:45:25 +08:00
										 |  |  |   protected defaultDsReferencesMap = { | 
					
						
							|  |  |  |     panels: new Map<string, Set<string>>(), // refIds as keys
 | 
					
						
							|  |  |  |     variables: new Set<string>(), // variable names as keys
 | 
					
						
							|  |  |  |     annotations: new Set<string>(), // annotation names as keys
 | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2025-03-07 01:59:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-21 02:45:25 +08:00
										 |  |  |   initializeElementMapping(saveModel: Dashboard | undefined) { | 
					
						
							| 
									
										
										
										
											2025-03-07 01:59:27 +08:00
										 |  |  |     this.elementPanelMap.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!saveModel || !saveModel.panels) { | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     saveModel.panels?.forEach((panel) => { | 
					
						
							|  |  |  |       if (panel.id) { | 
					
						
							|  |  |  |         const elementKey = getVizPanelKeyForPanelId(panel.id); | 
					
						
							|  |  |  |         this.elementPanelMap.set(elementKey, panel.id); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   getElementPanelMapping() { | 
					
						
							|  |  |  |     return this.elementPanelMap; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-21 02:45:25 +08:00
										 |  |  |   initializeDSReferencesMapping(saveModel: Dashboard | undefined) { | 
					
						
							|  |  |  |     // To be implemented in a different PR
 | 
					
						
							|  |  |  |     return {}; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   getDSReferencesMapping() { | 
					
						
							|  |  |  |     return this.defaultDsReferencesMap; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-07 01:59:27 +08:00
										 |  |  |   getPanelIdForElement(elementId: string) { | 
					
						
							|  |  |  |     return this.elementPanelMap.get(elementId); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   getElementIdForPanel(panelId: number) { | 
					
						
							|  |  |  |     // First try to find an existing mapping
 | 
					
						
							|  |  |  |     for (const [elementId, id] of this.elementPanelMap.entries()) { | 
					
						
							|  |  |  |       if (id === panelId) { | 
					
						
							|  |  |  |         return elementId; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // For runtime-created panels, generate a new element identifier
 | 
					
						
							|  |  |  |     const newElementId = getVizPanelKeyForPanelId(panelId); | 
					
						
							|  |  |  |     // Store the new mapping for future lookups
 | 
					
						
							|  |  |  |     this.elementPanelMap.set(newElementId, panelId); | 
					
						
							|  |  |  |     return newElementId; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2024-12-13 17:20:22 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   getSaveModel(s: DashboardScene) { | 
					
						
							|  |  |  |     return transformSceneToSaveModel(s); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   getSaveAsModel(s: DashboardScene, options: SaveDashboardAsOptions) { | 
					
						
							|  |  |  |     const saveModel = this.getSaveModel(s); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       ...saveModel, | 
					
						
							|  |  |  |       id: null, | 
					
						
							|  |  |  |       uid: '', | 
					
						
							|  |  |  |       title: options.title || '', | 
					
						
							| 
									
										
										
										
											2025-02-08 01:47:07 +08:00
										 |  |  |       description: options.description || undefined, | 
					
						
							| 
									
										
										
										
											2024-12-13 17:20:22 +08:00
										 |  |  |       tags: options.isNew || options.copyTags ? saveModel.tags : [], | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   getDashboardChangesFromScene( | 
					
						
							|  |  |  |     scene: DashboardScene, | 
					
						
							|  |  |  |     options: { saveTimeRange?: boolean; saveVariables?: boolean; saveRefresh?: boolean } | 
					
						
							|  |  |  |   ) { | 
					
						
							|  |  |  |     const changedSaveModel = this.getSaveModel(scene); | 
					
						
							|  |  |  |     const changeInfo = getRawDashboardChanges( | 
					
						
							|  |  |  |       this.initialSaveModel!, | 
					
						
							|  |  |  |       changedSaveModel, | 
					
						
							|  |  |  |       options.saveTimeRange, | 
					
						
							|  |  |  |       options.saveVariables, | 
					
						
							|  |  |  |       options.saveRefresh | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const hasFolderChanges = scene.getInitialState()?.meta.folderUid !== scene.state.meta.folderUid; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       ...changeInfo, | 
					
						
							|  |  |  |       hasFolderChanges, | 
					
						
							|  |  |  |       hasChanges: changeInfo.hasChanges || hasFolderChanges, | 
					
						
							| 
									
										
										
										
											2025-03-13 01:43:32 +08:00
										 |  |  |       hasMigratedToV2: false, | 
					
						
							| 
									
										
										
										
											2024-12-13 17:20:22 +08:00
										 |  |  |     }; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   onSaveComplete(saveModel: Dashboard, result: SaveDashboardResponseDTO): void { | 
					
						
							|  |  |  |     this.initialSaveModel = { | 
					
						
							|  |  |  |       ...saveModel, | 
					
						
							|  |  |  |       id: result.id, | 
					
						
							|  |  |  |       uid: result.uid, | 
					
						
							|  |  |  |       version: result.version, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   getTrackingInformation(): DashboardTrackingInfo | undefined { | 
					
						
							| 
									
										
										
										
											2025-01-03 00:33:16 +08:00
										 |  |  |     const panelTypes = this.initialSaveModel?.panels?.map((p) => p.type) || []; | 
					
						
							|  |  |  |     const panels = getPanelPluginCounts(panelTypes); | 
					
						
							| 
									
										
										
										
											2024-12-13 17:20:22 +08:00
										 |  |  |     const variables = getV1SchemaVariables(this.initialSaveModel?.templating?.list || []); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (this.initialSaveModel) { | 
					
						
							|  |  |  |       return { | 
					
						
							|  |  |  |         uid: this.initialSaveModel.uid, | 
					
						
							|  |  |  |         title: this.initialSaveModel.title, | 
					
						
							|  |  |  |         schemaVersion: this.initialSaveModel.schemaVersion, | 
					
						
							|  |  |  |         panels_count: this.initialSaveModel.panels?.length || 0, | 
					
						
							|  |  |  |         settings_nowdelay: undefined, | 
					
						
							|  |  |  |         settings_livenow: !!this.initialSaveModel.liveNow, | 
					
						
							|  |  |  |         ...panels, | 
					
						
							|  |  |  |         ...variables, | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return undefined; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2024-12-19 23:09:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   getSnapshotUrl() { | 
					
						
							|  |  |  |     return this.initialSaveModel?.snapshot?.originalUrl; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2024-12-13 17:20:22 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-09 23:14:41 +08:00
										 |  |  | export class V2DashboardSerializer | 
					
						
							| 
									
										
										
										
											2025-03-13 01:43:32 +08:00
										 |  |  |   implements | 
					
						
							|  |  |  |     DashboardSceneSerializerLike< | 
					
						
							|  |  |  |       DashboardV2Spec, | 
					
						
							|  |  |  |       DashboardWithAccessInfo<DashboardV2Spec>['metadata'], | 
					
						
							|  |  |  |       Dashboard | DashboardV2Spec | 
					
						
							|  |  |  |     > | 
					
						
							| 
									
										
										
										
											2025-01-09 23:14:41 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-03-13 01:43:32 +08:00
										 |  |  |   initialSaveModel?: DashboardV2Spec | Dashboard; | 
					
						
							| 
									
										
										
										
											2025-01-09 23:14:41 +08:00
										 |  |  |   metadata?: DashboardWithAccessInfo<DashboardV2Spec>['metadata']; | 
					
						
							| 
									
										
										
										
											2025-03-07 01:59:27 +08:00
										 |  |  |   protected elementPanelMap = new Map<string, number>(); | 
					
						
							| 
									
										
										
										
											2025-03-21 02:45:25 +08:00
										 |  |  |   // map of elementId that will contain all the queries, variables and annotations that dont have a ds defined
 | 
					
						
							|  |  |  |   protected defaultDsReferencesMap = { | 
					
						
							|  |  |  |     panels: new Map<string, Set<string>>(), // refIds as keys
 | 
					
						
							|  |  |  |     variables: new Set<string>(), // variable names as keys
 | 
					
						
							|  |  |  |     annotations: new Set<string>(), // annotation names as keys
 | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2025-03-07 01:59:27 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   getElementPanelMapping() { | 
					
						
							|  |  |  |     return this.elementPanelMap; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-21 02:45:25 +08:00
										 |  |  |   initializeElementMapping(saveModel: DashboardV2Spec | undefined) { | 
					
						
							| 
									
										
										
										
											2025-03-07 01:59:27 +08:00
										 |  |  |     this.elementPanelMap.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!saveModel || !saveModel.elements) { | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const elementKeys = Object.keys(saveModel.elements); | 
					
						
							|  |  |  |     elementKeys.forEach((key) => { | 
					
						
							|  |  |  |       const elementPanel = saveModel.elements[key]; | 
					
						
							|  |  |  |       if (elementPanel.kind === 'Panel') { | 
					
						
							|  |  |  |         this.elementPanelMap.set(key, elementPanel.spec.id); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-21 02:45:25 +08:00
										 |  |  |   initializeDSReferencesMapping(saveModel: DashboardV2Spec | undefined) { | 
					
						
							|  |  |  |     // initialize the object
 | 
					
						
							|  |  |  |     this.defaultDsReferencesMap = { | 
					
						
							|  |  |  |       panels: new Map<string, Set<string>>(), | 
					
						
							|  |  |  |       variables: new Set<string>(), | 
					
						
							|  |  |  |       annotations: new Set<string>(), | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // get all the element keys
 | 
					
						
							|  |  |  |     const elementKeys = Object.keys(saveModel?.elements || {}); | 
					
						
							|  |  |  |     elementKeys.forEach((key) => { | 
					
						
							|  |  |  |       const elementPanel = saveModel?.elements[key]; | 
					
						
							|  |  |  |       if (elementPanel?.kind === 'Panel') { | 
					
						
							|  |  |  |         // check if the elementPanel.spec.datasource is defined
 | 
					
						
							|  |  |  |         const panelQueries = elementPanel.spec.data.spec.queries; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (const query of panelQueries) { | 
					
						
							|  |  |  |           if (!query.spec.datasource) { | 
					
						
							|  |  |  |             const elementId = this.getElementIdForPanel(elementPanel.spec.id); | 
					
						
							|  |  |  |             if (!this.defaultDsReferencesMap.panels.has(elementId)) { | 
					
						
							|  |  |  |               this.defaultDsReferencesMap.panels.set(elementId, new Set()); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             const panelDsqueries = this.defaultDsReferencesMap.panels.get(elementId)!; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             panelDsqueries.add(query.spec.refId); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2025-03-26 23:59:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // initialize autossigned variable ds references map
 | 
					
						
							|  |  |  |     if (saveModel?.variables) { | 
					
						
							|  |  |  |       for (const variable of saveModel.variables) { | 
					
						
							|  |  |  |         // for query variables that dont have a ds defined add them to the list
 | 
					
						
							|  |  |  |         if (variable.kind === 'QueryVariable' && !variable.spec.datasource) { | 
					
						
							|  |  |  |           this.defaultDsReferencesMap.variables.add(variable.spec.name); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-03-21 02:45:25 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   getDSReferencesMapping() { | 
					
						
							|  |  |  |     return this.defaultDsReferencesMap; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-07 01:59:27 +08:00
										 |  |  |   getPanelIdForElement(elementId: string) { | 
					
						
							|  |  |  |     return this.elementPanelMap.get(elementId); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   getElementIdForPanel(panelId: number) { | 
					
						
							|  |  |  |     // First try to find an existing mapping
 | 
					
						
							|  |  |  |     for (const [elementId, id] of this.elementPanelMap.entries()) { | 
					
						
							|  |  |  |       if (id === panelId) { | 
					
						
							|  |  |  |         return elementId; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // For runtime-created panels, generate a new element identifier
 | 
					
						
							|  |  |  |     const newElementId = getVizPanelKeyForPanelId(panelId); | 
					
						
							|  |  |  |     // Store the new mapping for future lookups
 | 
					
						
							|  |  |  |     this.elementPanelMap.set(newElementId, panelId); | 
					
						
							|  |  |  |     return newElementId; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2024-12-13 17:20:22 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   getSaveModel(s: DashboardScene) { | 
					
						
							|  |  |  |     return transformSceneToSaveModelSchemaV2(s); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   getSaveAsModel(s: DashboardScene, options: SaveDashboardAsOptions) { | 
					
						
							| 
									
										
										
										
											2025-01-27 21:14:19 +08:00
										 |  |  |     const saveModel = this.getSaveModel(s); | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       ...saveModel, | 
					
						
							|  |  |  |       title: options.title || '', | 
					
						
							|  |  |  |       description: options.description || '', | 
					
						
							|  |  |  |       tags: options.isNew || options.copyTags ? saveModel.tags : [], | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2024-12-13 17:20:22 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-19 19:00:59 +08:00
										 |  |  |   getDashboardChangesFromScene( | 
					
						
							|  |  |  |     scene: DashboardScene, | 
					
						
							|  |  |  |     options: { saveTimeRange?: boolean; saveVariables?: boolean; saveRefresh?: boolean } | 
					
						
							|  |  |  |   ) { | 
					
						
							|  |  |  |     const changedSaveModel = this.getSaveModel(scene); | 
					
						
							|  |  |  |     const changeInfo = getRawDashboardV2Changes( | 
					
						
							|  |  |  |       this.initialSaveModel!, | 
					
						
							|  |  |  |       changedSaveModel, | 
					
						
							|  |  |  |       options.saveTimeRange, | 
					
						
							|  |  |  |       options.saveVariables, | 
					
						
							|  |  |  |       options.saveRefresh | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const hasFolderChanges = scene.getInitialState()?.meta.folderUid !== scene.state.meta.folderUid; | 
					
						
							| 
									
										
										
										
											2025-01-27 18:18:06 +08:00
										 |  |  |     const isNew = !Boolean(scene.getInitialState()?.uid); | 
					
						
							| 
									
										
										
										
											2024-12-19 19:00:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       ...changeInfo, | 
					
						
							|  |  |  |       hasFolderChanges, | 
					
						
							|  |  |  |       hasChanges: changeInfo.hasChanges || hasFolderChanges, | 
					
						
							|  |  |  |       isNew, | 
					
						
							| 
									
										
										
										
											2025-03-13 01:43:32 +08:00
										 |  |  |       hasMigratedToV2: !!changeInfo.hasMigratedToV2, | 
					
						
							| 
									
										
										
										
											2024-12-19 19:00:59 +08:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2024-12-13 17:20:22 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   onSaveComplete(saveModel: DashboardV2Spec, result: SaveDashboardResponseDTO): void { | 
					
						
							| 
									
										
										
										
											2025-01-27 21:14:19 +08:00
										 |  |  |     this.initialSaveModel = { | 
					
						
							|  |  |  |       ...saveModel, | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2024-12-13 17:20:22 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-03 00:33:16 +08:00
										 |  |  |   getTrackingInformation(s: DashboardScene): DashboardTrackingInfo | undefined { | 
					
						
							| 
									
										
										
										
											2025-03-13 01:43:32 +08:00
										 |  |  |     if (!this.initialSaveModel) { | 
					
						
							|  |  |  |       return undefined; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-03 00:33:16 +08:00
										 |  |  |     const panelPluginIds = | 
					
						
							| 
									
										
										
										
											2025-03-13 01:43:32 +08:00
										 |  |  |       'elements' in this.initialSaveModel | 
					
						
							|  |  |  |         ? Object.values(this.initialSaveModel.elements) | 
					
						
							|  |  |  |             .filter((e) => e.kind === 'Panel') | 
					
						
							|  |  |  |             .map((p) => p.spec.vizConfig.kind) | 
					
						
							|  |  |  |         : []; | 
					
						
							| 
									
										
										
										
											2025-01-03 00:33:16 +08:00
										 |  |  |     const panels = getPanelPluginCounts(panelPluginIds); | 
					
						
							| 
									
										
										
										
											2025-03-13 01:43:32 +08:00
										 |  |  |     const variables = | 
					
						
							|  |  |  |       'variables' in this.initialSaveModel! ? getV2SchemaVariables(this.initialSaveModel.variables) : []; | 
					
						
							| 
									
										
										
										
											2025-01-03 00:33:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-13 01:43:32 +08:00
										 |  |  |     return { | 
					
						
							|  |  |  |       schemaVersion: DASHBOARD_SCHEMA_VERSION, | 
					
						
							|  |  |  |       uid: s.state.uid, | 
					
						
							|  |  |  |       title: this.initialSaveModel.title, | 
					
						
							|  |  |  |       panels_count: panelPluginIds.length || 0, | 
					
						
							|  |  |  |       settings_nowdelay: undefined, | 
					
						
							|  |  |  |       settings_livenow: !!this.initialSaveModel.liveNow, | 
					
						
							|  |  |  |       ...panels, | 
					
						
							|  |  |  |       ...variables, | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2024-12-13 17:20:22 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2024-12-19 23:09:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   getSnapshotUrl() { | 
					
						
							| 
									
										
										
										
											2025-01-09 23:14:41 +08:00
										 |  |  |     return this.metadata?.annotations?.[AnnoKeyDashboardSnapshotOriginalUrl]; | 
					
						
							| 
									
										
										
										
											2024-12-19 23:09:19 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2024-12-13 17:20:22 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-13 01:43:32 +08:00
										 |  |  | export function getDashboardSceneSerializer(): DashboardSceneSerializerLike<Dashboard, DashboardMeta>; | 
					
						
							|  |  |  | export function getDashboardSceneSerializer(version: 'v1'): DashboardSceneSerializerLike<Dashboard, DashboardMeta>; | 
					
						
							|  |  |  | export function getDashboardSceneSerializer( | 
					
						
							|  |  |  |   version: 'v2' | 
					
						
							|  |  |  | ): DashboardSceneSerializerLike<DashboardV2Spec, DashboardWithAccessInfo<DashboardV2Spec>['metadata']>; | 
					
						
							|  |  |  | export function getDashboardSceneSerializer( | 
					
						
							|  |  |  |   version?: 'v1' | 'v2' | 
					
						
							|  |  |  | ): DashboardSceneSerializerLike< | 
					
						
							| 
									
										
										
										
											2025-01-09 23:14:41 +08:00
										 |  |  |   Dashboard | DashboardV2Spec, | 
					
						
							|  |  |  |   DashboardMeta | DashboardWithAccessInfo<DashboardV2Spec>['metadata'] | 
					
						
							|  |  |  | > { | 
					
						
							| 
									
										
										
										
											2025-03-13 01:43:32 +08:00
										 |  |  |   if (version === 'v2') { | 
					
						
							| 
									
										
										
										
											2024-12-13 17:20:22 +08:00
										 |  |  |     return new V2DashboardSerializer(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return new V1DashboardSerializer(); | 
					
						
							|  |  |  | } |