v13 should be no-op

This commit is contained in:
Haris Rozajac 2025-10-07 10:38:05 -06:00
parent 5f105e6aea
commit aec271036b
8 changed files with 79 additions and 2081 deletions

View File

@ -1,822 +1,11 @@
package schemaversion
import "context"
import (
"context"
)
// Default field config structure
func getDefaultFieldConfig() map[string]interface{} {
return map[string]interface{}{
"defaults": map[string]interface{}{},
"overrides": []interface{}{},
}
}
// Default color mode for field config
func getDefaultColorMode() map[string]interface{} {
return map[string]interface{}{
"mode": "palette-classic",
}
}
// Default custom properties for field config
func getDefaultCustomProperties() map[string]interface{} {
return map[string]interface{}{
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "points",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": map[string]interface{}{
"legend": false,
"tooltip": false,
"viz": false,
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": map[string]interface{}{
"type": "linear",
},
"showPoints": "auto",
"showValues": false,
"spanNulls": false,
"stacking": map[string]interface{}{
"group": "A",
"mode": "none",
},
"thresholdsStyle": map[string]interface{}{
"mode": "off",
},
}
}
// Default mappings and thresholds
func getDefaultMappings() []interface{} {
return []interface{}{}
}
func getDefaultThresholds() map[string]interface{} {
return map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{},
}
}
// Default legend options
func getDefaultLegendOptions() map[string]interface{} {
return map[string]interface{}{
"calcs": []interface{}{},
"displayMode": "list",
"placement": "bottom",
"showLegend": true,
}
}
// Default tooltip options
func getDefaultTooltipOptions() map[string]interface{} {
return map[string]interface{}{
"hideZeros": false,
"mode": "single",
"sort": "none",
}
}
// Default threshold steps for timeseries
func getDefaultThresholdSteps() []interface{} {
return []interface{}{
map[string]interface{}{
"color": "green",
"value": interface{}(nil), // null in JSON, represents -Infinity
},
map[string]interface{}{
"color": "red",
"value": 80.0,
},
}
}
// V13 migrates graph panels to timeseries panels with complete field config and options conversion.
// This migration replicates the complete graphPanelChangedHandler logic from the frontend, including:
// - Panel type conversion from 'graph' to 'timeseries'
// - Complete field config conversion (y-axis, series overrides, thresholds, etc.)
// - Options conversion (legend, tooltip, etc.)
// - Time regions conversion to annotations
// V13 is a no-op migration
func V13(_ context.Context, dashboard map[string]interface{}) error {
dashboard["schemaVersion"] = 13
panels, ok := dashboard["panels"].([]interface{})
if !ok {
return nil
}
for _, p := range panels {
panel, ok := p.(map[string]interface{})
if !ok {
continue
}
// Only process graph panels (convert them to timeseries)
if panel["type"] != "graph" {
continue
}
// Convert panel type from 'graph' to 'timeseries'
panel["type"] = "timeseries"
// Convert complete field config and options (replicating graphPanelChangedHandler)
convertFieldConfig(panel)
convertOptions(panel)
convertSeriesOverrides(panel)
convertThresholds(panel)
convertTimeRegions(panel)
// Clean up old graph-specific properties
cleanupGraphProperties(panel)
}
return nil
}
// convertFieldConfig converts graph field config to timeseries format
func convertFieldConfig(panel map[string]interface{}) {
// Initialize fieldConfig if it doesn't exist
if panel["fieldConfig"] == nil {
panel["fieldConfig"] = getDefaultFieldConfig()
}
fieldConfig, ok := panel["fieldConfig"].(map[string]interface{})
if !ok {
return
}
defaults, ok := fieldConfig["defaults"].(map[string]interface{})
if !ok {
return
}
// Set default color mode
defaults["color"] = getDefaultColorMode()
// Set default custom properties
defaults["custom"] = getDefaultCustomProperties()
// Set default mappings and thresholds
defaults["mappings"] = getDefaultMappings()
defaults["thresholds"] = getDefaultThresholds()
// Convert y-axis settings to field config
if yaxes, ok := panel["yaxes"].([]interface{}); ok && len(yaxes) > 0 {
if y1, ok := yaxes[0].(map[string]interface{}); ok {
// Convert y-axis properties to field config defaults
if unit, ok := y1["format"].(string); ok {
defaults["unit"] = unit
}
if decimals, ok := y1["decimals"]; ok {
defaults["decimals"] = decimals
}
if min, ok := y1["min"]; ok {
defaults["min"] = min
}
if max, ok := y1["max"]; ok {
defaults["max"] = max
}
if label, ok := y1["label"].(string); ok {
if custom, ok := defaults["custom"].(map[string]interface{}); ok {
custom["axisLabel"] = label
}
}
if show, ok := y1["show"].(bool); ok {
if custom, ok := defaults["custom"].(map[string]interface{}); ok {
if show {
custom["axisPlacement"] = "auto"
} else {
custom["axisPlacement"] = "hidden"
}
}
}
if logBase, ok := y1["logBase"].(float64); ok && (logBase == 2 || logBase == 10) {
if custom, ok := defaults["custom"].(map[string]interface{}); ok {
custom["scaleDistribution"] = map[string]interface{}{
"type": "log",
"log": logBase,
}
}
}
}
}
// Clean up old y-axis properties
delete(panel, "yaxes")
}
// convertOptions converts graph options to timeseries format
func convertOptions(panel map[string]interface{}) {
// Initialize options if it doesn't exist
if panel["options"] == nil {
panel["options"] = map[string]interface{}{}
}
options, ok := panel["options"].(map[string]interface{})
if !ok {
return
}
// Set default legend options
options["legend"] = getDefaultLegendOptions()
// Set default tooltip options
options["tooltip"] = getDefaultTooltipOptions()
// Convert legend settings from old graph format
if legend, ok := panel["legend"].(map[string]interface{}); ok {
legendOptions, ok := options["legend"].(map[string]interface{})
if ok {
if show, ok := legend["show"].(bool); ok && !show {
legendOptions["showLegend"] = false
}
if alignAsTable, ok := legend["alignAsTable"].(bool); ok && alignAsTable {
legendOptions["displayMode"] = "table"
}
if rightSide, ok := legend["rightSide"].(bool); ok && rightSide {
legendOptions["placement"] = "right"
}
if sideWidth, ok := legend["sideWidth"]; ok {
legendOptions["width"] = sideWidth
}
}
delete(panel, "legend")
}
// Convert tooltip settings from old graph format
if tooltip, ok := panel["tooltip"].(map[string]interface{}); ok {
tooltipOptions, ok := options["tooltip"].(map[string]interface{})
if ok {
if shared, ok := tooltip["shared"].(bool); ok {
if shared {
tooltipOptions["mode"] = "multi"
}
}
if sort, ok := tooltip["sort"]; ok && tooltipOptions["mode"] == "multi" {
switch sort {
case float64(1):
tooltipOptions["sort"] = "asc"
case float64(2):
tooltipOptions["sort"] = "desc"
default:
tooltipOptions["sort"] = "none"
}
}
}
delete(panel, "tooltip")
}
}
// convertSeriesOverrides converts graph series overrides to field config overrides
func convertSeriesOverrides(panel map[string]interface{}) {
fieldConfig, ok := panel["fieldConfig"].(map[string]interface{})
if !ok {
return
}
overrides, ok := fieldConfig["overrides"].([]interface{})
if !ok {
overrides = []interface{}{}
}
// Convert aliasColors to overrides
overrides = convertAliasColors(panel, overrides)
// Convert seriesOverrides to field config overrides
overrides = convertSeriesOverridesToFieldConfig(panel, overrides)
fieldConfig["overrides"] = overrides
}
func convertAliasColors(panel map[string]interface{}, overrides []interface{}) []interface{} {
if aliasColors, ok := panel["aliasColors"].(map[string]interface{}); ok {
for alias, color := range aliasColors {
if colorStr, ok := color.(string); ok && colorStr != "" {
override := createColorOverride(alias, colorStr)
overrides = append(overrides, override)
}
}
}
return overrides
}
func createColorOverride(alias, colorStr string) map[string]interface{} {
return map[string]interface{}{
"matcher": map[string]interface{}{
"id": "byName",
"options": alias,
},
"properties": []interface{}{
map[string]interface{}{
"id": "color",
"value": map[string]interface{}{
"mode": "fixed",
"fixedColor": colorStr,
},
},
},
}
}
func convertSeriesOverridesToFieldConfig(panel map[string]interface{}, overrides []interface{}) []interface{} {
if seriesOverrides, ok := panel["seriesOverrides"].([]interface{}); ok {
for _, seriesOverride := range seriesOverrides {
if seriesMap, ok := seriesOverride.(map[string]interface{}); ok {
override := createSeriesOverride(seriesMap)
if override != nil {
overrides = append(overrides, override)
}
}
}
}
return overrides
}
func createSeriesOverride(seriesMap map[string]interface{}) map[string]interface{} {
alias, hasAlias := seriesMap["alias"].(string)
if !hasAlias {
return nil
}
aliasIsRegex := isAliasRegex(alias)
properties := extractSeriesProperties(seriesMap)
if len(properties) == 0 {
return nil
}
return map[string]interface{}{
"matcher": map[string]interface{}{
"id": getMatcherId(aliasIsRegex),
"options": alias,
},
"properties": properties,
}
}
func isAliasRegex(alias string) bool {
if len(alias) <= 2 {
return false
}
firstChar := alias[0]
lastChar := alias[len(alias)-1]
regexChars := []byte{'/', '~', '@', ';', '%', '#', '\''}
for _, char := range regexChars {
if firstChar == char && firstChar == lastChar {
return true
}
}
return false
}
//nolint:gocyclo
func extractSeriesProperties(seriesMap map[string]interface{}) []interface{} {
properties := []interface{}{}
// Fill opacity
if fill, ok := seriesMap["fill"]; ok {
if fillNum, ok := fill.(float64); ok {
properties = append(properties, map[string]interface{}{
"id": "custom.fillOpacity",
"value": fillNum * 10, // was 0-10, new is 0-100
})
}
}
// Fill below to
if fillBelowTo, ok := seriesMap["fillBelowTo"]; ok {
if fillBelowToVal, ok := fillBelowTo.(float64); ok {
properties = append(properties, map[string]interface{}{
"id": "custom.fillBelowTo",
"value": fillBelowToVal,
})
}
}
// Fill gradient
if fillGradient, ok := seriesMap["fillGradient"]; ok {
if fillGradientVal, ok := fillGradient.(float64); ok && fillGradientVal > 0 {
properties = append(properties, map[string]interface{}{
"id": "custom.fillGradient",
"value": "opacity",
})
properties = append(properties, map[string]interface{}{
"id": "custom.fillOpacity",
"value": fillGradientVal * 10,
})
}
}
// Show points
if points, ok := seriesMap["points"]; ok {
if pointsBool, ok := points.(bool); ok {
properties = append(properties, map[string]interface{}{
"id": "custom.showPoints",
"value": pointsBool,
})
}
}
// Draw style (bars)
if bars, ok := seriesMap["bars"]; ok {
if barsBool, ok := bars.(bool); ok {
if barsBool {
properties = append(properties, map[string]interface{}{
"id": "custom.drawStyle",
"value": "bars",
})
properties = append(properties, map[string]interface{}{
"id": "custom.fillOpacity",
"value": 100,
})
} else {
properties = append(properties, map[string]interface{}{
"id": "custom.drawStyle",
"value": "line",
})
}
}
}
// Draw style (lines)
if lines, ok := seriesMap["lines"]; ok {
if linesBool, ok := lines.(bool); ok {
if linesBool {
properties = append(properties, map[string]interface{}{
"id": "custom.drawStyle",
"value": "line",
})
} else {
properties = append(properties, map[string]interface{}{
"id": "custom.lineWidth",
"value": 0,
})
}
}
}
// Line width
if linewidth, ok := seriesMap["linewidth"]; ok {
properties = append(properties, map[string]interface{}{
"id": "custom.lineWidth",
"value": linewidth,
})
}
// Point radius
if pointradius, ok := seriesMap["pointradius"]; ok {
if radius, ok := pointradius.(float64); ok {
properties = append(properties, map[string]interface{}{
"id": "custom.pointSize",
"value": 2 + radius*2,
})
}
}
// Dash length
if dashLength, ok := seriesMap["dashLength"]; ok {
if dashLengthVal, ok := dashLength.(float64); ok {
properties = append(properties, map[string]interface{}{
"id": "custom.dashLength",
"value": dashLengthVal,
})
}
}
// Space length
if spaceLength, ok := seriesMap["spaceLength"]; ok {
if spaceLengthVal, ok := spaceLength.(float64); ok {
properties = append(properties, map[string]interface{}{
"id": "custom.spaceLength",
"value": spaceLengthVal,
})
}
}
// Dashes
if dashes, ok := seriesMap["dashes"]; ok {
if dashesBool, ok := dashes.(bool); ok {
properties = append(properties, map[string]interface{}{
"id": "custom.lineStyle",
"value": map[string]interface{}{
"fill": func() string {
if dashesBool {
return "dash"
}
return "solid"
}(),
},
})
}
}
// Stack
if stack, ok := seriesMap["stack"]; ok {
if stackStr, ok := stack.(string); ok {
properties = append(properties, map[string]interface{}{
"id": "custom.stacking",
"value": stackStr,
})
}
}
// Transform
if transform, ok := seriesMap["transform"]; ok {
if transformStr, ok := transform.(string); ok {
value := "constant"
if transformStr == "negative-Y" {
value = "negative-Y"
}
properties = append(properties, map[string]interface{}{
"id": "custom.transform",
"value": value,
})
}
}
// Color
if color, ok := seriesMap["color"]; ok {
if colorStr, ok := color.(string); ok {
properties = append(properties, map[string]interface{}{
"id": "color",
"value": map[string]interface{}{
"mode": "fixed",
"fixedColor": colorStr,
},
})
}
}
return properties
}
// convertThresholds converts graph thresholds to the new step-based threshold system
func convertThresholds(panel map[string]interface{}) {
fieldConfig, ok := panel["fieldConfig"].(map[string]interface{})
if !ok {
return
}
defaults, ok := fieldConfig["defaults"].(map[string]interface{})
if !ok {
return
}
if oldThresholds, ok := panel["thresholds"].([]interface{}); ok && len(oldThresholds) > 0 {
convertExistingThresholds(defaults, oldThresholds)
} else {
setDefaultThresholds(defaults)
}
// Clean up old thresholds
delete(panel, "thresholds")
}
func convertExistingThresholds(defaults map[string]interface{}, oldThresholds []interface{}) {
area, line := extractThresholdStyles(oldThresholds)
// Sort thresholds by value
sortedThresholds := sortThresholdsByValue(oldThresholds)
// Convert to step-based thresholds
steps := buildThresholdSteps(sortedThresholds)
// Add base transparent step if needed
steps = addBaseTransparentStep(steps)
// Set threshold style mode
setThresholdDisplayMode(defaults, area, line)
// Set the new thresholds
defaults["thresholds"] = map[string]interface{}{
"mode": "absolute",
"steps": steps,
}
}
func extractThresholdStyles(oldThresholds []interface{}) (bool, bool) {
area, line := false, false
for _, t := range oldThresholds {
if threshold, ok := t.(map[string]interface{}); ok {
if !area {
if fill, ok := threshold["fill"].(bool); ok && fill {
area = true
}
}
if !line {
if lineStyle, ok := threshold["line"].(bool); ok && lineStyle {
line = true
}
}
if area && line {
break
}
}
}
return area, line
}
func sortThresholdsByValue(oldThresholds []interface{}) []map[string]interface{} {
sortedThresholds := make([]map[string]interface{}, len(oldThresholds))
for i, t := range oldThresholds {
if threshold, ok := t.(map[string]interface{}); ok {
sortedThresholds[i] = threshold
}
}
// Sort by value
for i := 0; i < len(sortedThresholds)-1; i++ {
for j := i + 1; j < len(sortedThresholds); j++ {
if val1, ok1 := sortedThresholds[i]["value"].(float64); ok1 {
if val2, ok2 := sortedThresholds[j]["value"].(float64); ok2 {
if val1 > val2 {
sortedThresholds[i], sortedThresholds[j] = sortedThresholds[j], sortedThresholds[i]
}
}
}
}
}
return sortedThresholds
}
func buildThresholdSteps(sortedThresholds []map[string]interface{}) []interface{} {
steps := []interface{}{}
for i, threshold := range sortedThresholds {
op, _ := threshold["op"].(string)
value, _ := threshold["value"].(float64)
switch op {
case "gt":
steps = append(steps, map[string]interface{}{
"value": value,
"color": getThresholdColor(threshold),
})
case "lt":
steps = appendLtThresholdSteps(steps, i, threshold, value, sortedThresholds)
}
}
return steps
}
func appendLtThresholdSteps(steps []interface{}, index int, threshold map[string]interface{}, value float64, sortedThresholds []map[string]interface{}) []interface{} {
// Add base transparent step for first lt threshold
if index == 0 {
steps = append(steps, map[string]interface{}{
"value": interface{}(nil), // -Infinity equivalent
"color": "transparent",
})
}
// Check if next threshold is gt and there's a gap
if index+1 < len(sortedThresholds) {
nextThreshold := sortedThresholds[index+1]
if nextOp, ok := nextThreshold["op"].(string); ok && nextOp == "gt" {
if nextValue, ok := nextThreshold["value"].(float64); ok && nextValue > value {
steps = append(steps, map[string]interface{}{
"value": value,
"color": "transparent",
})
}
}
}
return steps
}
func addBaseTransparentStep(steps []interface{}) []interface{} {
if len(steps) == 0 {
return steps
}
if firstStep, ok := steps[0].(map[string]interface{}); ok {
if firstValue, ok := firstStep["value"].(float64); ok && firstValue != -1e308 {
steps = append([]interface{}{
map[string]interface{}{
"color": "transparent",
"value": interface{}(nil),
},
}, steps...)
}
}
return steps
}
func setThresholdDisplayMode(defaults map[string]interface{}, area, line bool) {
displayMode := determineDisplayMode(area, line)
if defaults["custom"] == nil {
defaults["custom"] = map[string]interface{}{}
}
if custom, ok := defaults["custom"].(map[string]interface{}); ok {
custom["thresholdsStyle"] = map[string]interface{}{
"mode": displayMode,
}
}
}
func determineDisplayMode(area, line bool) string {
if area && line {
return "line+area"
} else if area {
return "area"
} else if line {
return "line"
}
return "line"
}
func setDefaultThresholds(defaults map[string]interface{}) {
if defaults["custom"] == nil {
defaults["custom"] = map[string]interface{}{}
}
if custom, ok := defaults["custom"].(map[string]interface{}); ok {
custom["thresholdsStyle"] = map[string]interface{}{
"mode": "off",
}
}
// Add default threshold steps that match the timeseries plugin defaults
defaults["thresholds"] = map[string]interface{}{
"mode": "absolute",
"steps": getDefaultThresholdSteps(),
}
}
// convertTimeRegions converts graph time regions to annotations
func convertTimeRegions(panel map[string]interface{}) {
// This is a simplified version - in the real frontend, time regions get converted to
// dashboard annotations, but for the backend migration we'll just clean them up
delete(panel, "timeRegions")
}
// getThresholdColor extracts the color from a threshold object
func getThresholdColor(threshold map[string]interface{}) string {
if colorMode, ok := threshold["colorMode"].(string); ok {
switch colorMode {
case "critical":
return "red"
case "warning":
return "orange"
case "custom":
if fillColor, ok := threshold["fillColor"].(string); ok && fillColor != "" {
return fillColor
}
if lineColor, ok := threshold["lineColor"].(string); ok && lineColor != "" {
return lineColor
}
}
}
return "red"
}
// cleanupGraphProperties removes old graph-specific properties
func cleanupGraphProperties(panel map[string]interface{}) {
// Remove old graph-specific properties that are no longer needed
delete(panel, "aliasColors")
delete(panel, "seriesOverrides")
delete(panel, "dashes")
delete(panel, "dashLength")
delete(panel, "spaceLength")
delete(panel, "nullPointMode")
delete(panel, "steppedLine")
delete(panel, "points")
delete(panel, "bars")
delete(panel, "lines")
delete(panel, "stack")
delete(panel, "percentage")
delete(panel, "legend")
delete(panel, "tooltip")
delete(panel, "yaxes")
delete(panel, "xaxis")
delete(panel, "grid")
delete(panel, "thresholds")
delete(panel, "timeRegions")
}
func getMatcherId(aliasIsRegex bool) string {
if aliasIsRegex {
return "byRegexp"
}
return "byName"
}

View File

@ -9,565 +9,30 @@ import (
func TestV13(t *testing.T) {
tests := []migrationTestCase{
{
name: "graph panel with grid thresholds gets converted to timeseries with step-based thresholds",
name: "v13 no-op migration, updates schema version only",
input: map[string]interface{}{
"title": "V13 Graph Panel Line Thresholds Test",
"title": "V13 No-Op Migration Test Dashboard",
"schemaVersion": 12,
"panels": []interface{}{
map[string]interface{}{
"type": "graph",
"id": 1,
"grid": map[string]interface{}{
"threshold1": 200,
"threshold2": 400,
"threshold1Color": "yellow",
"threshold2Color": "red",
"thresholdLine": true,
},
"type": "graph",
"title": "Panel remains unchanged",
"id": 1,
},
},
},
expected: map[string]interface{}{
"title": "V13 Graph Panel Line Thresholds Test",
"title": "V13 No-Op Migration Test Dashboard",
"schemaVersion": 13,
"panels": []interface{}{
map[string]interface{}{
"type": "timeseries",
"id": 1,
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"color": map[string]interface{}{
"mode": "palette-classic",
},
"custom": map[string]interface{}{
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "points",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": map[string]interface{}{
"legend": false,
"tooltip": false,
"viz": false,
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": map[string]interface{}{
"type": "linear",
},
"showPoints": "auto",
"showValues": false,
"spanNulls": false,
"stacking": map[string]interface{}{
"group": "A",
"mode": "none",
},
"thresholdsStyle": map[string]interface{}{
"mode": "off",
},
},
"mappings": []interface{}{},
"thresholds": map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{
"color": "green",
"value": nil,
},
map[string]interface{}{
"color": "red",
"value": 80.0,
},
},
},
},
"overrides": []interface{}{},
},
"options": map[string]interface{}{
"legend": map[string]interface{}{
"calcs": []interface{}{},
"displayMode": "list",
"placement": "bottom",
"showLegend": true,
},
"tooltip": map[string]interface{}{
"hideZeros": false,
"mode": "single",
"sort": "none",
},
},
"type": "graph",
"title": "Panel remains unchanged",
"id": 1,
},
},
},
},
{
name: "graph panel with fill thresholds gets converted to timeseries with area thresholds",
input: map[string]interface{}{
"title": "V13 Graph Panel Fill Thresholds Test",
"schemaVersion": 12,
"panels": []interface{}{
map[string]interface{}{
"type": "graph",
"id": 2,
"grid": map[string]interface{}{
"threshold1": 100,
"threshold2": 300,
"threshold1Color": "green",
"threshold2Color": "blue",
"thresholdLine": false,
},
},
},
},
expected: map[string]interface{}{
"title": "V13 Graph Panel Fill Thresholds Test",
"schemaVersion": 13,
"panels": []interface{}{
map[string]interface{}{
"type": "timeseries",
"id": 2,
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"color": map[string]interface{}{
"mode": "palette-classic",
},
"custom": map[string]interface{}{
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "points",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": map[string]interface{}{
"legend": false,
"tooltip": false,
"viz": false,
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": map[string]interface{}{
"type": "linear",
},
"showPoints": "auto",
"showValues": false,
"spanNulls": false,
"stacking": map[string]interface{}{
"group": "A",
"mode": "none",
},
"thresholdsStyle": map[string]interface{}{
"mode": "off",
},
},
"mappings": []interface{}{},
"thresholds": map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{
"color": "green",
"value": nil,
},
map[string]interface{}{
"color": "red",
"value": 80.0,
},
},
},
},
"overrides": []interface{}{},
},
"options": map[string]interface{}{
"legend": map[string]interface{}{
"calcs": []interface{}{},
"displayMode": "list",
"placement": "bottom",
"showLegend": true,
},
"tooltip": map[string]interface{}{
"hideZeros": false,
"mode": "single",
"sort": "none",
},
},
},
},
},
},
{
name: "graph panel with aliasColors gets converted to timeseries with field config overrides",
input: map[string]interface{}{
"title": "V13 Graph Panel Alias Colors Test",
"schemaVersion": 12,
"panels": []interface{}{
map[string]interface{}{
"type": "graph",
"id": 3,
"aliasColors": map[string]interface{}{
"series1": "red",
"series2": "blue",
},
},
},
},
expected: map[string]interface{}{
"title": "V13 Graph Panel Alias Colors Test",
"schemaVersion": 13,
"panels": []interface{}{
map[string]interface{}{
"type": "timeseries",
"id": 3,
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"color": map[string]interface{}{
"mode": "palette-classic",
},
"custom": map[string]interface{}{
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "points",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": map[string]interface{}{
"legend": false,
"tooltip": false,
"viz": false,
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": map[string]interface{}{
"type": "linear",
},
"showPoints": "auto",
"showValues": false,
"spanNulls": false,
"stacking": map[string]interface{}{
"group": "A",
"mode": "none",
},
"thresholdsStyle": map[string]interface{}{
"mode": "off",
},
},
"mappings": []interface{}{},
"thresholds": map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{
"color": "green",
"value": nil,
},
map[string]interface{}{
"color": "red",
"value": 80.0,
},
},
},
},
"overrides": []interface{}{
map[string]interface{}{
"matcher": map[string]interface{}{
"id": "byName",
"options": "series1",
},
"properties": []interface{}{
map[string]interface{}{
"id": "color",
"value": map[string]interface{}{
"mode": "fixed",
"fixedColor": "red",
},
},
},
},
map[string]interface{}{
"matcher": map[string]interface{}{
"id": "byName",
"options": "series2",
},
"properties": []interface{}{
map[string]interface{}{
"id": "color",
"value": map[string]interface{}{
"mode": "fixed",
"fixedColor": "blue",
},
},
},
},
},
},
"options": map[string]interface{}{
"legend": map[string]interface{}{
"calcs": []interface{}{},
"displayMode": "list",
"placement": "bottom",
"showLegend": true,
},
"tooltip": map[string]interface{}{
"hideZeros": false,
"mode": "single",
"sort": "none",
},
},
},
},
},
},
{
name: "graph panel with y-axis configuration gets converted to timeseries with field config",
input: map[string]interface{}{
"title": "V13 Graph Panel Y-Axis Test",
"schemaVersion": 12,
"panels": []interface{}{
map[string]interface{}{
"type": "graph",
"id": 4,
"yaxes": []interface{}{
map[string]interface{}{
"label": "Y-Axis Label",
"show": true,
"logBase": 10.0,
"format": "short",
"decimals": 2,
"min": 0.0,
"max": 100.0,
},
},
},
},
},
expected: map[string]interface{}{
"title": "V13 Graph Panel Y-Axis Test",
"schemaVersion": 13,
"panels": []interface{}{
map[string]interface{}{
"type": "timeseries",
"id": 4,
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"color": map[string]interface{}{
"mode": "palette-classic",
},
"unit": "short",
"decimals": 2,
"min": 0.0,
"max": 100.0,
"custom": map[string]interface{}{
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "Y-Axis Label",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "points",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": map[string]interface{}{
"legend": false,
"tooltip": false,
"viz": false,
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": map[string]interface{}{
"type": "log",
"log": 10.0,
},
"showPoints": "auto",
"showValues": false,
"spanNulls": false,
"stacking": map[string]interface{}{
"group": "A",
"mode": "none",
},
"thresholdsStyle": map[string]interface{}{
"mode": "off",
},
},
"mappings": []interface{}{},
"thresholds": map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{
"color": "green",
"value": nil,
},
map[string]interface{}{
"color": "red",
"value": 80.0,
},
},
},
},
"overrides": []interface{}{},
},
"options": map[string]interface{}{
"legend": map[string]interface{}{
"calcs": []interface{}{},
"displayMode": "list",
"placement": "bottom",
"showLegend": true,
},
"tooltip": map[string]interface{}{
"hideZeros": false,
"mode": "single",
"sort": "none",
},
},
},
},
},
},
{
name: "non-graph panel is unchanged",
input: map[string]interface{}{
"title": "V13 Non-Graph Panel Test",
"schemaVersion": 12,
"panels": []interface{}{
map[string]interface{}{
"type": "singlestat",
"id": 5,
},
},
},
expected: map[string]interface{}{
"title": "V13 Non-Graph Panel Test",
"schemaVersion": 13,
"panels": []interface{}{
map[string]interface{}{
"type": "singlestat",
"id": 5,
},
},
},
},
{
name: "graph panel without grid gets converted to timeseries with basic structure",
input: map[string]interface{}{
"title": "V13 Graph Panel No Grid Test",
"schemaVersion": 12,
"panels": []interface{}{
map[string]interface{}{
"type": "graph",
"id": 6,
},
},
},
expected: map[string]interface{}{
"title": "V13 Graph Panel No Grid Test",
"schemaVersion": 13,
"panels": []interface{}{
map[string]interface{}{
"type": "timeseries",
"id": 6,
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"color": map[string]interface{}{
"mode": "palette-classic",
},
"custom": map[string]interface{}{
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "points",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": map[string]interface{}{
"legend": false,
"tooltip": false,
"viz": false,
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": map[string]interface{}{
"type": "linear",
},
"showPoints": "auto",
"showValues": false,
"spanNulls": false,
"stacking": map[string]interface{}{
"group": "A",
"mode": "none",
},
"thresholdsStyle": map[string]interface{}{
"mode": "off",
},
},
"mappings": []interface{}{},
"thresholds": map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{
"color": "green",
"value": nil,
},
map[string]interface{}{
"color": "red",
"value": 80.0,
},
},
},
},
"overrides": []interface{}{},
},
"options": map[string]interface{}{
"legend": map[string]interface{}{
"calcs": []interface{}{},
"displayMode": "list",
"placement": "bottom",
"showLegend": true,
},
"tooltip": map[string]interface{}{
"hideZeros": false,
"mode": "single",
"sort": "none",
},
},
},
},
},
},
{
name: "dashboard without panels is unchanged",
input: map[string]interface{}{
"title": "V13 No Panels Test",
"schemaVersion": 12,
},
expected: map[string]interface{}{
"title": "V13 No Panels Test",
"schemaVersion": 13,
},
},
}
runMigrationTests(t, tests, schemaversion.V13)
}

View File

@ -21,80 +21,20 @@
"links": [],
"panels": [
{
"autoMigrateFrom": "graph",
"datasource": {
"apiVersion": "v1",
"type": "prometheus",
"uid": "default-ds-uid"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "points",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"showValues": false,
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
"grid": {
"threshold1": 200,
"threshold1Color": "yellow",
"threshold2": 400,
"threshold2Color": "red",
"thresholdLine": true
},
"id": 1,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
@ -109,80 +49,20 @@
"type": "timeseries"
},
{
"autoMigrateFrom": "graph",
"datasource": {
"apiVersion": "v1",
"type": "prometheus",
"uid": "default-ds-uid"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "points",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"showValues": false,
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
"grid": {
"threshold1": 100,
"threshold1Color": "green",
"threshold2": 300,
"threshold2Color": "blue",
"thresholdLine": false
},
"id": 2,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
@ -197,80 +77,18 @@
"type": "timeseries"
},
{
"autoMigrateFrom": "graph",
"datasource": {
"apiVersion": "v1",
"type": "prometheus",
"uid": "default-ds-uid"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "points",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"showValues": false,
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
"grid": {
"threshold1": 150,
"threshold1Color": "orange",
"thresholdLine": true
},
"id": 3,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
@ -285,72 +103,18 @@
"type": "timeseries"
},
{
"autoMigrateFrom": "graph",
"datasource": {
"apiVersion": "v1",
"type": "prometheus",
"uid": "default-ds-uid"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "points",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"showValues": false,
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "line"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": []
}
},
"overrides": []
"grid": {
"threshold1": 200,
"threshold1Color": "yellow",
"thresholdLine": false
},
"id": 4,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
@ -361,6 +125,13 @@
"refId": "A"
}
],
"thresholds": [
{
"color": "purple",
"colorMode": "custom",
"value": 50
}
],
"title": "Graph with Existing Thresholds",
"type": "timeseries"
},

View File

@ -21,79 +21,12 @@
"links": [],
"panels": [
{
"autoMigrateFrom": "graph",
"datasource": {
"type": "prometheus",
"uid": "gdev-prometheus"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "points",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"showValues": false,
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"id": 4,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {

View File

@ -21,286 +21,57 @@
"links": [],
"panels": [
{
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "points",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"showValues": false,
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
"autoMigrateFrom": "graph",
"grid": {
"threshold1": 200,
"threshold1Color": "yellow",
"threshold2": 400,
"threshold2Color": "red",
"thresholdLine": true
},
"id": 1,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "single",
"sort": "none"
}
},
"title": "Graph with Line Thresholds",
"type": "timeseries"
},
{
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "points",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"showValues": false,
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
"autoMigrateFrom": "graph",
"grid": {
"threshold1": 100,
"threshold1Color": "green",
"threshold2": 300,
"threshold2Color": "blue",
"thresholdLine": false
},
"id": 2,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "single",
"sort": "none"
}
},
"title": "Graph with Fill Thresholds",
"type": "timeseries"
},
{
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "points",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"showValues": false,
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
"autoMigrateFrom": "graph",
"grid": {
"threshold1": 150,
"threshold1Color": "orange",
"thresholdLine": true
},
"id": 3,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "single",
"sort": "none"
}
},
"title": "Graph with Single Threshold",
"type": "timeseries"
},
{
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "points",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"showValues": false,
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "line"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": []
}
},
"overrides": []
"autoMigrateFrom": "graph",
"grid": {
"threshold1": 200,
"threshold1Color": "yellow",
"thresholdLine": false
},
"id": 4,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "single",
"sort": "none"
"thresholds": [
{
"color": "purple",
"colorMode": "custom",
"value": 50
}
},
],
"title": "Graph with Existing Thresholds",
"type": "timeseries"
},

View File

@ -21,75 +21,8 @@
"links": [],
"panels": [
{
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "points",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"showValues": false,
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"autoMigrateFrom": "graph",
"id": 4,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {

View File

@ -2549,7 +2549,7 @@
"count": 4
},
"@typescript-eslint/no-explicit-any": {
"count": 24
"count": 21
}
},
"public/app/features/dashboard/state/DashboardModel.repeat.test.ts": {

View File

@ -403,72 +403,8 @@ export class DashboardMigrator {
}
if (oldVersion < 13 && finalTargetVersion >= 13) {
// update graph yaxes changes
panelUpgrades.push((panel: any) => {
if (panel.type !== 'graph') {
return panel;
}
if (!panel.grid) {
return panel;
}
if (!panel.thresholds) {
panel.thresholds = [];
}
const t1: any = {},
t2: any = {};
if (panel.grid.threshold1 !== null) {
t1.value = panel.grid.threshold1;
if (panel.grid.thresholdLine) {
t1.line = true;
t1.lineColor = panel.grid.threshold1Color;
t1.colorMode = 'custom';
} else {
t1.fill = true;
t1.fillColor = panel.grid.threshold1Color;
t1.colorMode = 'custom';
}
}
if (panel.grid.threshold2 !== null) {
t2.value = panel.grid.threshold2;
if (panel.grid.thresholdLine) {
t2.line = true;
t2.lineColor = panel.grid.threshold2Color;
t2.colorMode = 'custom';
} else {
t2.fill = true;
t2.fillColor = panel.grid.threshold2Color;
t2.colorMode = 'custom';
}
}
if (isNumber(t1.value)) {
if (isNumber(t2.value)) {
if (t1.value > t2.value) {
t1.op = t2.op = 'lt';
panel.thresholds.push(t1);
panel.thresholds.push(t2);
} else {
t1.op = t2.op = 'gt';
panel.thresholds.push(t1);
panel.thresholds.push(t2);
}
} else {
t1.op = 'gt';
panel.thresholds.push(t1);
}
}
delete panel.grid.threshold1;
delete panel.grid.threshold1Color;
delete panel.grid.threshold2;
delete panel.grid.threshold2Color;
delete panel.grid.thresholdLine;
return panel;
});
// graph panel auto migrates to either barchart, bargauge, histogram or timeseries (all standard Grafana plugins)
// see public/app/features/dashboard/state/getPanelPluginToMigrateTo.ts
}
if (oldVersion < 14 && finalTargetVersion >= 14) {