mirror of
https://github.com/grafana/grafana.git
synced 2026-01-15 05:35:41 +00:00
Compare commits
5 Commits
ash/react-
...
KD/panel-i
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
00e11fa4d2 | ||
|
|
c3502eed0b | ||
|
|
34e8cfef52 | ||
|
|
fbf4be69ae | ||
|
|
5df7d43f8c |
@@ -46,7 +46,7 @@
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 1,
|
||||
"id": 23,
|
||||
"options": {
|
||||
"content": "This dashboard demonstrates various monitoring components for application observability and performance metrics.\n",
|
||||
"mode": "markdown"
|
||||
@@ -77,7 +77,7 @@
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 23,
|
||||
"id": 24,
|
||||
"panels": [],
|
||||
"targets": [
|
||||
{
|
||||
|
||||
@@ -31,53 +31,6 @@
|
||||
"cursorSync": "Off",
|
||||
"editable": false,
|
||||
"elements": {
|
||||
"panel-1": {
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"id": 1,
|
||||
"title": "Application Monitoring",
|
||||
"description": "",
|
||||
"links": [],
|
||||
"data": {
|
||||
"kind": "QueryGroup",
|
||||
"spec": {
|
||||
"queries": [
|
||||
{
|
||||
"kind": "PanelQuery",
|
||||
"spec": {
|
||||
"query": {
|
||||
"kind": "prometheus",
|
||||
"spec": {}
|
||||
},
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"refId": "A",
|
||||
"hidden": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"transformations": [],
|
||||
"queryOptions": {}
|
||||
}
|
||||
},
|
||||
"vizConfig": {
|
||||
"kind": "text",
|
||||
"spec": {
|
||||
"pluginVersion": "",
|
||||
"options": {
|
||||
"content": "This dashboard demonstrates various monitoring components for application observability and performance metrics.\n",
|
||||
"mode": "markdown"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {},
|
||||
"overrides": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"panel-10": {
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
@@ -1024,6 +977,53 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"panel-23": {
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"id": 23,
|
||||
"title": "Application Monitoring",
|
||||
"description": "",
|
||||
"links": [],
|
||||
"data": {
|
||||
"kind": "QueryGroup",
|
||||
"spec": {
|
||||
"queries": [
|
||||
{
|
||||
"kind": "PanelQuery",
|
||||
"spec": {
|
||||
"query": {
|
||||
"kind": "prometheus",
|
||||
"spec": {}
|
||||
},
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"refId": "A",
|
||||
"hidden": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"transformations": [],
|
||||
"queryOptions": {}
|
||||
}
|
||||
},
|
||||
"vizConfig": {
|
||||
"kind": "text",
|
||||
"spec": {
|
||||
"pluginVersion": "",
|
||||
"options": {
|
||||
"content": "This dashboard demonstrates various monitoring components for application observability and performance metrics.\n",
|
||||
"mode": "markdown"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {},
|
||||
"overrides": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"panel-6": {
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
@@ -1259,7 +1259,7 @@
|
||||
"height": 3,
|
||||
"element": {
|
||||
"kind": "ElementReference",
|
||||
"name": "panel-1"
|
||||
"name": "panel-23"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,55 +32,6 @@
|
||||
"cursorSync": "Off",
|
||||
"editable": false,
|
||||
"elements": {
|
||||
"panel-1": {
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"id": 1,
|
||||
"title": "Application Monitoring",
|
||||
"description": "",
|
||||
"links": [],
|
||||
"data": {
|
||||
"kind": "QueryGroup",
|
||||
"spec": {
|
||||
"queries": [
|
||||
{
|
||||
"kind": "PanelQuery",
|
||||
"spec": {
|
||||
"query": {
|
||||
"kind": "DataQuery",
|
||||
"group": "prometheus",
|
||||
"version": "v0",
|
||||
"datasource": {
|
||||
"name": "default-ds-uid"
|
||||
},
|
||||
"spec": {}
|
||||
},
|
||||
"refId": "A",
|
||||
"hidden": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"transformations": [],
|
||||
"queryOptions": {}
|
||||
}
|
||||
},
|
||||
"vizConfig": {
|
||||
"kind": "VizConfig",
|
||||
"group": "text",
|
||||
"version": "",
|
||||
"spec": {
|
||||
"options": {
|
||||
"content": "This dashboard demonstrates various monitoring components for application observability and performance metrics.\n",
|
||||
"mode": "markdown"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {},
|
||||
"overrides": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"panel-10": {
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
@@ -1067,6 +1018,55 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"panel-23": {
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
"id": 23,
|
||||
"title": "Application Monitoring",
|
||||
"description": "",
|
||||
"links": [],
|
||||
"data": {
|
||||
"kind": "QueryGroup",
|
||||
"spec": {
|
||||
"queries": [
|
||||
{
|
||||
"kind": "PanelQuery",
|
||||
"spec": {
|
||||
"query": {
|
||||
"kind": "DataQuery",
|
||||
"group": "prometheus",
|
||||
"version": "v0",
|
||||
"datasource": {
|
||||
"name": "default-ds-uid"
|
||||
},
|
||||
"spec": {}
|
||||
},
|
||||
"refId": "A",
|
||||
"hidden": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"transformations": [],
|
||||
"queryOptions": {}
|
||||
}
|
||||
},
|
||||
"vizConfig": {
|
||||
"kind": "VizConfig",
|
||||
"group": "text",
|
||||
"version": "",
|
||||
"spec": {
|
||||
"options": {
|
||||
"content": "This dashboard demonstrates various monitoring components for application observability and performance metrics.\n",
|
||||
"mode": "markdown"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {},
|
||||
"overrides": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"panel-6": {
|
||||
"kind": "Panel",
|
||||
"spec": {
|
||||
@@ -1310,7 +1310,7 @@
|
||||
"height": 3,
|
||||
"element": {
|
||||
"kind": "ElementReference",
|
||||
"name": "panel-1"
|
||||
"name": "panel-23"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -432,6 +432,21 @@ func getPanels(dashboard map[string]interface{}) []map[string]interface{} {
|
||||
}
|
||||
}
|
||||
|
||||
// Also get panels from rows
|
||||
if rows, ok := dashboard["rows"].([]interface{}); ok {
|
||||
for _, rowInterface := range rows {
|
||||
if row, ok := rowInterface.(map[string]interface{}); ok {
|
||||
if rowPanels, ok := row["panels"].([]interface{}); ok {
|
||||
for _, panelInterface := range rowPanels {
|
||||
if panel, ok := panelInterface.(map[string]interface{}); ok {
|
||||
panels = append(panels, panel)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return panels
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,8 @@ func upgradeToGridLayout(dashboard map[string]interface{}) {
|
||||
widthFactor := gridColumnCount / 12.0
|
||||
|
||||
// Find max panel ID (lines 1014-1021 in TS)
|
||||
maxPanelID := getMaxPanelID(rows)
|
||||
// Also check top-level panels which may have been assigned IDs by ensurePanelsHaveUniqueIds
|
||||
maxPanelID := getMaxPanelID(dashboard, rows)
|
||||
nextRowID := maxPanelID + 1
|
||||
|
||||
// Match frontend: dashboard.panels already exists with top-level panels
|
||||
@@ -269,10 +270,25 @@ func (r *rowArea) getPanelPosition(panelHeight int, panelWidth int) map[string]i
|
||||
return r.getPanelPosition(panelHeight, panelWidth)
|
||||
}
|
||||
|
||||
func getMaxPanelID(rows []interface{}) int {
|
||||
func getMaxPanelID(dashboard map[string]interface{}, rows []interface{}) int {
|
||||
maxID := 0
|
||||
hasValidID := false
|
||||
|
||||
// Check top-level panels first (these may have been assigned IDs by ensurePanelsHaveUniqueIds)
|
||||
if panels, ok := dashboard["panels"].([]interface{}); ok {
|
||||
for _, panelInterface := range panels {
|
||||
if panel, ok := panelInterface.(map[string]interface{}); ok {
|
||||
if id := GetIntValue(panel, "id", 0); id > 0 {
|
||||
hasValidID = true
|
||||
if id > maxID {
|
||||
maxID = id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Also check panels inside rows
|
||||
for _, rowInterface := range rows {
|
||||
if row, ok := rowInterface.(map[string]interface{}); ok {
|
||||
if panels, ok := row["panels"].([]interface{}); ok {
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 1,
|
||||
"id": 23,
|
||||
"options": {
|
||||
"content": "This dashboard demonstrates various monitoring components for application observability and performance metrics.\n",
|
||||
"mode": "markdown"
|
||||
@@ -71,7 +71,7 @@
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 23,
|
||||
"id": 24,
|
||||
"panels": [],
|
||||
"targets": [
|
||||
{
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 1,
|
||||
"id": 23,
|
||||
"options": {
|
||||
"content": "This dashboard demonstrates various monitoring components for application observability and performance metrics.\n",
|
||||
"mode": "markdown"
|
||||
@@ -51,7 +51,7 @@
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 23,
|
||||
"id": 24,
|
||||
"panels": [],
|
||||
"title": "Application Service",
|
||||
"type": "row"
|
||||
|
||||
@@ -816,14 +816,17 @@ export class DashboardMigrator {
|
||||
let yPos = 0;
|
||||
const widthFactor = GRID_COLUMN_COUNT / 12;
|
||||
|
||||
const maxPanelId =
|
||||
max(
|
||||
flattenDeep(
|
||||
map(old.rows, (row) => {
|
||||
return map(row.panels, 'id');
|
||||
})
|
||||
).filter((id) => id != null)
|
||||
) || 0;
|
||||
// Find max panel ID from both rows and existing top-level panels
|
||||
// Top-level panels may have been assigned IDs by ensurePanelsHaveUniqueIds
|
||||
const rowPanelIds = flattenDeep(
|
||||
map(old.rows, (row) => {
|
||||
return map(row.panels, 'id');
|
||||
})
|
||||
).filter((id) => id != null);
|
||||
|
||||
const topLevelPanelIds = map(this.dashboard.panels, 'id').filter((id) => id != null);
|
||||
|
||||
const maxPanelId = max([...rowPanelIds, ...topLevelPanelIds]) || 0;
|
||||
let nextRowId = maxPanelId + 1;
|
||||
|
||||
if (!old.rows) {
|
||||
|
||||
@@ -525,6 +525,14 @@ export class DashboardModel implements TimeModel {
|
||||
}
|
||||
}
|
||||
|
||||
// Also check panels in legacy rows (pre-v16 dashboard format)
|
||||
// This ensures unique IDs are assigned before the row upgrade migration runs
|
||||
for (const panel of this.rawPanelIterator()) {
|
||||
if (panel.id > max) {
|
||||
max = panel.id;
|
||||
}
|
||||
}
|
||||
|
||||
return max + 1;
|
||||
}
|
||||
|
||||
@@ -539,6 +547,26 @@ export class DashboardModel implements TimeModel {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over panels from the original raw dashboard data, including legacy rows.
|
||||
* This is needed to find panel IDs before row upgrade migration runs.
|
||||
*/
|
||||
private *rawPanelIterator() {
|
||||
// @ts-expect-error - rows is a legacy property not included in the modern Dashboard schema
|
||||
const rows = this.originalDashboard?.rows;
|
||||
|
||||
if (Array.isArray(rows)) {
|
||||
for (const row of rows) {
|
||||
const rowPanels = row?.panels;
|
||||
if (Array.isArray(rowPanels)) {
|
||||
for (const panel of rowPanels) {
|
||||
yield panel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
forEachPanel(callback: (panel: PanelModel, index: number) => void) {
|
||||
for (let i = 0; i < this.panels.length; i++) {
|
||||
callback(this.panels[i], i);
|
||||
|
||||
Reference in New Issue
Block a user