Schema: get all devenv dashboards passing validation (#37857)

* Strip nulls (again)

* Add stripnulls script

* Add transformations field

* Close FieldConfig struct; proper plugin validating

* s/graph/viz/ field in histogram dashboard

* Use ui.GraphFieldConfig in histogram model

* Add models for stat, gauge, barguage panel plugins

Also toss necessary shared types into cue/ui/gen.cue, with TODOs to move
them appropriately later.

* Add required license headers

* Heap of updates to cue UI components

* Fix barchart types and one old devenv input

* Use the GraphFieldConfig directly for timeseries

* Add models.cue for a few panel plugins

Barchart, state-timeline, and status-history

* Enable the test validating all devenv dashboards!!

* Fix effects of not checking after making comments

* Update packages/grafana-ui/src/options/models.gen.ts

Co-authored-by: Ryan McKinley <ryantxu@gmail.com>

* Realign and unalign cue with ts types

* Update devenv test to sniff for null errors

Best option we have right now for helping people to know they need to
strip nulls from devenv dashboards.

* Add speculative default for barchart stacking

* Fixup some dated devenv dashboards

timeline-modes needed to be regenerated with the appropriate tooltip
values included, per typing requirements, and timeline-demo needed to
have the `mode` field removed, as it is not intended to be persisted.

* Add necessary missing options for various panels

* Regenerate devenv dashboards

Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
This commit is contained in:
sam boyer 2021-08-17 07:11:57 -04:00 committed by GitHub
parent 368da73ac4
commit 6aba592741
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 521 additions and 99 deletions

View File

@ -113,6 +113,13 @@ Family: scuemata.#Family & {
steps: [...#Threshold]
} @cuetsy(targetType="interface")
// TODO docs
// FIXME this is extremely underspecfied; wasn't obvious which typescript types corresponded to it
#Transformation: {
id: string
options: {...}
}
// Schema for panel targets is specified by datasource
// plugins. We use a placeholder definition, which the Go
// schema loader either left open/as-is with the Base
@ -197,6 +204,8 @@ Family: scuemata.#Family & {
// TODO docs
timeRegions?: [...]
transformations: [...#Transformation]
// TODO docs
// TODO tighter constraint
interval?: string
@ -209,8 +218,10 @@ Family: scuemata.#Family & {
// TODO tighter constraint
timeShift?: string
// The values depend on panel type
options: {...}
// The allowable options are specified by the panel plugin's
// schema.
// FIXME same conundrum as with the closed validation for fieldConfig.
options: {}
fieldConfig: {
defaults: {
@ -282,7 +293,7 @@ Family: scuemata.#Family & {
// Can always exist. Valid fields within this are
// defined by the panel plugin - that's the
// PanelFieldConfig that comes from the plugin.
custom?: {...}
custom?: {}
}
overrides: [...{
matcher: {

View File

@ -1,21 +1,22 @@
package grafanaschema
// FIXME can't write enums as structs, must use disjunctions
TableCellDisplayMode: {
Auto: "auto",
ColorText: "color-text",
ColorBackground: "color-background",
GradientGauge: "gradient-gauge",
LcdGauge: "lcd-gauge",
JSONView: "json-view",
BasicGauge: "basic",
Image: "image",
Auto: "auto",
ColorText: "color-text",
ColorBackground: "color-background",
GradientGauge: "gradient-gauge",
LcdGauge: "lcd-gauge",
JSONView: "json-view",
BasicGauge: "basic",
Image: "image",
} @cuetsy(targetType="enum")
TableFieldOptions: {
width?: number
align: FieldTextAlignment | *"auto"
displayMode: TableCellDisplayMode | *"auto"
hidden?: bool // ?? default is missing or false ??
width?: number
align: FieldTextAlignment | *"auto"
displayMode: TableCellDisplayMode | *"auto"
hidden?: bool // ?? default is missing or false ??
} @cuetsy(targetType="interface")
TableSortByFieldState: {
@ -31,6 +32,11 @@ DrawStyle: "line" | "bars" | "points" @c
LineInterpolation: "linear" | "smooth" | "stepBefore" | "stepAfter" @cuetsy(targetType="enum")
ScaleDistribution: "linear" | "log" @cuetsy(targetType="enum")
GraphGradientMode: "none" | "opacity" | "hue" | "scheme" @cuetsy(targetType="enum")
StackingMode: "none" | "normal" | "percent" @cuetsy(targetType="enum")
BarValueVisibility: "auto" | "never" | "always" @cuetsy(targetType="enum")
BarAlignment: -1 | 0 | 1 @cuetsy(targetType="enum",memberNames="Before|Center|After")
ScaleOrientation: 0 | 1 @cuetsy(targetType="enum",memberNames="Horizontal|Vertical")
ScaleDirection: 1 | 1 | -1 | -1 @cuetsy(targetType="enum",memberNames="Up|Right|Down|Left")
LineStyle: {
fill?: "solid" | "dash" | "dot" | "square"
dash?: [...number]
@ -42,6 +48,11 @@ LineConfig: {
lineStyle?: LineStyle
spanNulls?: bool | number
} @cuetsy(targetType="interface")
BarConfig: {
barAlignment?: BarAlignment
barWidthFactor?: number
barMaxWidth?: number
} @cuetsy(targetType="interface")
FillConfig: {
fillColor?: string
fillOpacity?: number
@ -70,6 +81,20 @@ HideSeriesConfig: {
legend: bool
viz: bool
} @cuetsy(targetType="interface")
StackingConfig: {
mode?: StackingMode
group?: string
} @cuetsy(targetType="interface")
StackableFieldConfig: {
stacking?: StackingConfig
} @cuetsy(targetType="interface")
HideableFieldConfig: {
hideFrom?: HideSeriesConfig
} @cuetsy(targetType="interface")
GraphTresholdsStyleMode: "off" | "line" | "area" | "line+area" | "series" @cuetsy(targetType="enum",memberNames="Off|Line|Area|LineAndArea|Series")
GraphThresholdsStyleConfig: {
mode: GraphTresholdsStyleMode
} @cuetsy(targetType="interface")
LegendPlacement: "bottom" | "right" @cuetsy(targetType="type")
LegendDisplayMode: "list" | "table" | "hidden" @cuetsy(targetType="enum")
TableFieldOptions: {
@ -78,10 +103,17 @@ TableFieldOptions: {
displayMode: TableCellDisplayMode | *"auto"
hidden?: bool
} @cuetsy(targetType="interface")
GraphFieldConfig: LineConfig & FillConfig & PointsConfig & AxisConfig & {
drawStyle?: DrawStyle
gradientMode?: GraphGradientMode
hideFrom?: HideSeriesConfig
GraphFieldConfig: {
LineConfig
FillConfig
PointsConfig
AxisConfig
BarConfig
StackableFieldConfig
HideableFieldConfig
drawStyle?: DrawStyle
gradientMode?: GraphGradientMode
thresholdsStyle?: GraphThresholdsStyleConfig
} @cuetsy(targetType="interface")
VizLegendOptions: {
displayMode: LegendDisplayMode
@ -93,3 +125,54 @@ VizLegendOptions: {
VizTooltipOptions: {
mode: TooltipDisplayMode
} @cuetsy(targetType="interface")
// TODO copy back to appropriate place
SingleStatBaseOptions: {
OptionsWithTextFormatting
reduceOptions: ReduceDataOptions
orientation: VizOrientation
} @cuetsy(targetType="interface")
// TODO copy back to appropriate place
ReduceDataOptions: {
// If true show each row value
values?: bool
// if showing all values limit
limit?: number
// When !values, pick one value for the whole field
calcs: [...string]
// Which fields to show. By default this is only numeric fields
fields?: string
} @cuetsy(targetType="interface")
// TODO copy back to appropriate place
VizOrientation: "auto" | "vertical" | "horizontal" @cuetsy(targetType="enum")
// TODO copy back to appropriate place
OptionsWithTooltip: {
// FIXME this field is non-optional in the corresponding TS type
tooltip?: VizTooltipOptions
} @cuetsy(targetType="interface")
// TODO copy back to appropriate place
OptionsWithLegend: {
// FIXME this field is non-optional in the corresponding TS type
legend?: VizLegendOptions
} @cuetsy(targetType="interface")
// TODO copy back to appropriate place
OptionsWithTextFormatting: {
text?: VizTextDisplayOptions
} @cuetsy(targetType="interface")
// TODO copy back to appropriate place
VizTextDisplayOptions: {
// Explicit title text size
titleSize?: number
// Explicit value text size
valueSize?: number
} @cuetsy(targetType="interface")
// TODO copy back to appropriate place
BigValueColorMode: "value" | "background" | "none" @cuetsy(targetType="enum")
// TODO copy back to appropriate place
BigValueGraphMode: "none" | "line" | "area" @cuetsy(targetType="enum")
// TODO copy back to appropriate place
BigValueJustifyMode: "auto" | "center" @cuetsy(targetType="enum")
// TODO copy back to appropriate place
// TODO does cuetsy handle underscores the expected way?
BigValueTextMode: "auto" | "value" | "value_and_name" | "name" | "none" @cuetsy(targetType="enum")
// TODO copy back to appropriate place
BarGaugeDisplayMode: "basic" | "lcd" | "gradient" @cuetsy(targetType="enum")

View File

@ -354,7 +354,7 @@
"orientation": "auto",
"showValue": "auto",
"text": {
"size": 10,
"titleSize": 10,
"valueSize": 25
},
"tooltip": {

View File

@ -19,12 +19,10 @@
]
},
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"links": [],
"panels": [
{
"datasource": null,
"description": "",
"fieldConfig": {
"defaults": {
@ -66,8 +64,7 @@
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
"color": "green"
},
{
"color": "orange",
@ -112,7 +109,6 @@
"type": "timeseries"
},
{
"datasource": null,
"description": "",
"fieldConfig": {
"defaults": {
@ -154,8 +150,7 @@
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
"color": "green"
},
{
"color": "orange",
@ -200,7 +195,6 @@
"type": "timeseries"
},
{
"datasource": null,
"fieldConfig": {
"defaults": {
"color": {
@ -241,8 +235,7 @@
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
"color": "green"
},
{
"color": "orange",
@ -328,8 +321,7 @@
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
"color": "green"
},
{
"color": "orange",
@ -373,7 +365,6 @@
"type": "timeseries"
},
{
"datasource": null,
"fieldConfig": {
"defaults": {
"color": {
@ -414,8 +405,7 @@
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
"color": "green"
},
{
"color": "orange",
@ -461,7 +451,6 @@
"startValue": 1
}
],
"timeFrom": null,
"title": "Color bars by discrete thresholds",
"type": "timeseries"
},
@ -507,8 +496,7 @@
"mode": "absolute",
"steps": [
{
"color": "blue",
"value": null
"color": "blue"
},
{
"color": "green",
@ -597,8 +585,7 @@
"mode": "absolute",
"steps": [
{
"color": "blue",
"value": null
"color": "blue"
},
{
"color": "green",
@ -687,8 +674,7 @@
"mode": "absolute",
"steps": [
{
"color": "blue",
"value": null
"color": "blue"
},
{
"color": "green",
@ -736,7 +722,6 @@
"type": "timeseries"
},
{
"datasource": null,
"fieldConfig": {
"defaults": {
"color": {
@ -777,8 +762,7 @@
"mode": "absolute",
"steps": [
{
"color": "blue",
"value": null
"color": "blue"
},
{
"color": "green",
@ -859,4 +843,4 @@
"title": "Panel Tests - Graph NG - By value color schemes",
"uid": "aBXrJ0R7z",
"version": 11
}
}

View File

@ -8,6 +8,12 @@
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"target": {
"limit": 100,
"matchAny": false,
"tags": [],
"type": "dashboard"
},
"type": "dashboard"
}
]
@ -42,7 +48,6 @@
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"viz": false,
"legend": false,
"tooltip": false,
"viz": false
@ -149,7 +154,6 @@
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"viz": false,
"legend": false,
"tooltip": false,
"viz": false
@ -265,7 +269,6 @@
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"viz": false,
"legend": false,
"tooltip": false,
"viz": false
@ -400,7 +403,6 @@
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"viz": false,
"legend": false,
"tooltip": false,
"viz": false
@ -507,7 +509,6 @@
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"viz": false,
"legend": false,
"tooltip": false,
"viz": false
@ -623,7 +624,6 @@
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"viz": false,
"legend": false,
"tooltip": false,
"viz": false
@ -758,7 +758,6 @@
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"viz": false,
"legend": false,
"tooltip": false,
"viz": false
@ -902,7 +901,6 @@
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"viz": false,
"legend": false,
"tooltip": false,
"viz": false
@ -1045,7 +1043,6 @@
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"viz": false,
"legend": false,
"tooltip": false,
"viz": false
@ -1232,5 +1229,5 @@
"timezone": "",
"title": "Panel Tests - Graph NG - Gaps and Connected",
"uid": "8mmCAF1Mz",
"version": 12
"version": 2
}

View File

@ -27,7 +27,7 @@
"fillOpacity": 80,
"gradientMode": "none",
"hideFrom": {
"graph": false,
"viz": false,
"legend": false,
"tooltip": false
},
@ -86,7 +86,7 @@
"fillOpacity": 80,
"gradientMode": "none",
"hideFrom": {
"graph": false,
"viz": false,
"legend": false,
"tooltip": false
},
@ -144,7 +144,7 @@
"fillOpacity": 80,
"gradientMode": "none",
"hideFrom": {
"graph": false,
"viz": false,
"legend": false,
"tooltip": false
},
@ -215,7 +215,7 @@
"fillOpacity": 80,
"gradientMode": "none",
"hideFrom": {
"graph": false,
"viz": false,
"legend": false,
"tooltip": false
},

View File

@ -8,6 +8,12 @@
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"target": {
"limit": 100,
"matchAny": false,
"tags": [],
"type": "dashboard"
},
"type": "dashboard"
}
]
@ -79,9 +85,12 @@
"displayMode": "list",
"placement": "bottom"
},
"mode": "changes",
"mergeValues": true,
"rowHeight": 0.98,
"showValue": "always"
"showValue": "always",
"tooltip": {
"mode": "single"
}
},
"pluginVersion": "7.5.0-pre",
"targets": [
@ -168,9 +177,17 @@
"options": {
"alignValue": "center",
"colWidth": 1,
"legend": {
"displayMode": "list",
"placement": "bottom"
},
"mergeValues": true,
"mode": "changes",
"rowHeight": 0.98,
"showValue": "always"
"showValue": "always",
"tooltip": {
"mode": "single"
}
},
"targets": [
{
@ -261,9 +278,17 @@
"options": {
"alignValue": "center",
"colWidth": 1,
"legend": {
"displayMode": "list",
"placement": "bottom"
},
"mergeValues": true,
"mode": "changes",
"rowHeight": 0.98,
"showValue": "always"
"showValue": "always",
"tooltip": {
"mode": "single"
}
},
"targets": [
{
@ -339,9 +364,11 @@
"displayMode": "list",
"placement": "bottom"
},
"mode": "samples",
"rowHeight": 0.98,
"showValue": "always"
"showValue": "always",
"tooltip": {
"mode": "single"
}
},
"pluginVersion": "7.5.0-pre",
"targets": [
@ -400,5 +427,5 @@
"timezone": "utc",
"title": "Timeline Demo",
"uid": "mIJjFy8Kz",
"version": 13
"version": 3
}

View File

@ -8,6 +8,12 @@
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"target": {
"limit": 100,
"matchAny": false,
"tags": [],
"type": "dashboard"
},
"type": "dashboard"
}
]
@ -60,7 +66,10 @@
},
"mergeValues": true,
"rowHeight": 0.9,
"showValue": "always"
"showValue": "always",
"tooltip": {
"mode": "single"
}
},
"pluginVersion": "7.5.0-pre",
"targets": [
@ -233,7 +242,10 @@
},
"mergeValues": true,
"rowHeight": 0.9,
"showValue": "always"
"showValue": "always",
"tooltip": {
"mode": "single"
}
},
"pluginVersion": "7.5.0-pre",
"targets": [
@ -305,7 +317,10 @@
"placement": "bottom"
},
"rowHeight": 0.9,
"showValue": "always"
"showValue": "always",
"tooltip": {
"mode": "single"
}
},
"pluginVersion": "7.5.0-pre",
"targets": [
@ -360,5 +375,5 @@
"timezone": "utc",
"title": "Timeline Modes",
"uid": "mIJjFy8Gz",
"version": 12
"version": 13
}

View File

@ -6,6 +6,11 @@ DrawStyle: "line" | "bars" | "points" @cuetsy(targetType="enum")
LineInterpolation: "linear" | "smooth" | "stepBefore" | "stepAfter" @cuetsy(targetType="enum")
ScaleDistribution: "linear" | "log" | "ordinal" @cuetsy(targetType="enum")
GraphGradientMode: "none" | "opacity" | "hue" | "scheme" @cuetsy(targetType="enum")
StackingMode: "none" | "normal" | "percent" @cuetsy(targetType="enum")
BarValueVisibility: "auto" | "never" | "always" @cuetsy(targetType="enum")
BarAlignment: -1 | 0 | 1 @cuetsy(targetType="enum",memberNames="Before|Center|After")
ScaleOrientation: 0 | 1 @cuetsy(targetType="enum",memberNames="Horizontal|Vertical")
ScaleDirection: 1 | 1 | -1 | -1 @cuetsy(targetType="enum",memberNames="Up|Right|Down|Left")
LineStyle: {
fill?: "solid" | "dash" | "dot" | "square"
@ -20,6 +25,12 @@ LineConfig: {
spanNulls?: bool | number
} @cuetsy(targetType="interface")
BarConfig: {
barAlignment?: BarAlignment
barWidthFactor?: number
barMaxWidth?: number
} @cuetsy(targetType="interface")
FillConfig: {
fillColor?: string
fillOpacity?: number
@ -53,11 +64,34 @@ HideSeriesConfig: {
viz: bool
} @cuetsy(targetType="interface")
// TODO This is the same composition as what's used in the timeseries panel's
// PanelFieldConfig. If that's the only place it's used, it probably shouldn't
// be assembled here, too
GraphFieldConfig: LineConfig & FillConfig & PointsConfig & AxisConfig & {
drawStyle?: DrawStyle
gradientMode?: GraphGradientMode
StackingConfig: {
mode?: StackingMode
group?: string
} @cuetsy(targetType="interface")
StackableFieldConfig: {
stacking?: StackingConfig
} @cuetsy(targetType="interface")
HideableFieldConfig: {
hideFrom?: HideSeriesConfig
} @cuetsy(targetType="interface")
GraphTresholdsStyleMode: "off" | "line" | "area" | "line+area" | "series" @cuetsy(targetType="enum",memberNames="Off|Line|Area|LineAndArea|Series")
GraphThresholdsStyleConfig: {
mode: GraphTresholdsStyleMode
} @cuetsy(targetType="interface")
GraphFieldConfig: {
LineConfig
FillConfig
PointsConfig
AxisConfig
BarConfig
StackableFieldConfig
HideableFieldConfig
drawStyle?: DrawStyle
gradientMode?: GraphGradientMode
thresholdsStyle?: GraphThresholdsStyleConfig
} @cuetsy(targetType="interface")

View File

@ -7,6 +7,7 @@ import (
"io/fs"
"os"
"path/filepath"
"strings"
"testing"
"testing/fstest"
@ -49,17 +50,8 @@ func TestScuemataBasics(t *testing.T) {
}
func TestDevenvDashboardValidity(t *testing.T) {
// TODO un-skip when tests pass on all devenv dashboards
t.Skip()
// validdir := os.DirFS(filepath.Join("..", "..", "..", "devenv", "dev-dashboards"))
validdir := filepath.Join("..", "..", "..", "devenv", "dev-dashboards")
dash, err := BaseDashboardFamily(p)
require.NoError(t, err, "error while loading base dashboard scuemata")
ddash, err := DistDashboardFamily(p)
require.NoError(t, err, "error while loading dist dashboard scuemata")
doTest := func(sch schema.VersionedCueSchema) func(t *testing.T) {
return func(t *testing.T) {
t.Parallel()
@ -87,7 +79,9 @@ func TestDevenvDashboardValidity(t *testing.T) {
return nil
} else {
if !(oldschemav.(float64) > 29) {
t.Logf("schemaVersion is %v, older than 30, skipping %s", oldschemav, path)
if testing.Verbose() {
t.Logf("schemaVersion is %v, older than 30, skipping %s", oldschemav, path)
}
return nil
}
}
@ -96,7 +90,12 @@ func TestDevenvDashboardValidity(t *testing.T) {
err := sch.Validate(schema.Resource{Value: byt, Name: path})
if err != nil {
// Testify trims errors to short length. We want the full text
t.Fatal(errors.Details(err, nil))
errstr := errors.Details(err, nil)
t.Log(errstr)
if strings.Contains(errstr, "null") {
t.Log("validation failure appears to involve nulls - see if scripts/stripnulls.sh has any effect?")
}
t.FailNow()
}
})
@ -107,7 +106,15 @@ func TestDevenvDashboardValidity(t *testing.T) {
// TODO will need to expand this appropriately when the scuemata contain
// more than one schema
t.Run("base", doTest(dash))
// TODO disabled because base variant validation currently must fail in order for
// dist/instance validation to do closed validation of plugin-specified fields
// t.Run("base", doTest(dash))
// dash, err := BaseDashboardFamily(p)
// require.NoError(t, err, "error while loading base dashboard scuemata")
ddash, err := DistDashboardFamily(p)
require.NoError(t, err, "error while loading dist dashboard scuemata")
t.Run("dist", doTest(ddash))
}

View File

@ -0,0 +1,47 @@
// Copyright 2021 Grafana Labs
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package grafanaschema
import (
ui "github.com/grafana/grafana/cue/ui:grafanaschema"
)
Family: {
lineages: [
[
{
PanelOptions: {
ui.OptionsWithLegend
ui.OptionsWithTooltip
ui.OptionsWithTextFormatting
orientation: ui.VizOrientation
// TODO this default is a guess based on common devenv values
stacking: ui.StackingMode | *"none"
showValue: ui.BarValueVisibility
barWidth: number
groupWidth: number
}
PanelFieldConfig: {
ui.AxisConfig
ui.HideableFieldConfig
lineWidth?: number
fillOpacity?: number
gradientMode?: ui.GraphGradientMode
}
}
]
]
migrations: []
}

View File

@ -0,0 +1,32 @@
// Copyright 2021 Grafana Labs
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package grafanaschema
import ui "github.com/grafana/grafana/cue/ui:grafanaschema"
Family: {
lineages: [
[
{
PanelOptions: {
ui.SingleStatBaseOptions
displayMode: ui.BarGaugeDisplayMode
showUnfilled: bool
}
}
]
]
migrations: []
}

View File

@ -0,0 +1,32 @@
// Copyright 2021 Grafana Labs
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package grafanaschema
import ui "github.com/grafana/grafana/cue/ui:grafanaschema"
Family: {
lineages: [
[
{
PanelOptions: {
ui.SingleStatBaseOptions
showThresholdLabels: bool
showThresholdMarkers: bool
}
}
]
]
migrations: []
}

View File

@ -1,16 +1,36 @@
// Copyright 2021 Grafana Labs
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package grafanaschema
import ui "github.com/grafana/grafana/cue/ui:grafanaschema"
Family: {
lineages: [
[
{
PanelOptions: {
ui.OptionsWithLegend
ui.OptionsWithTooltip
bucketSize?: int
bucketOffset: int | *0
combine?: bool
}
// TODO: FieldConfig
PanelFieldConfig: {
ui.GraphFieldConfig
}
}
]
]

View File

@ -0,0 +1,34 @@
// Copyright 2021 Grafana Labs
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package grafanaschema
import ui "github.com/grafana/grafana/cue/ui:grafanaschema"
Family: {
lineages: [
[
{
PanelOptions: {
ui.SingleStatBaseOptions
graphMode: ui.BigValueGraphMode
colorMode: ui.BigValueColorMode
justifyMode: ui.BigValueJustifyMode
textMode: ui.BigValueTextMode
}
}
]
]
migrations: []
}

View File

@ -0,0 +1,47 @@
// Copyright 2021 Grafana Labs
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package grafanaschema
import (
ui "github.com/grafana/grafana/cue/ui:grafanaschema"
)
Family: {
lineages: [
[
{
#TimelineMode: "changes" | "samples" @cuetsy(targetType="enum")
#TimelineValueAlignment: "center" | "left" | "right" @cuetsy(targetType="type")
PanelOptions: {
// FIXME ts comments indicate this shouldn't be in the saved model, but currently is emitted
mode?: #TimelineMode
ui.OptionsWithLegend
ui.OptionsWithTooltip
showValue: ui.BarValueVisibility | *"auto"
rowHeight: number | *0.9
colWidth?: number
mergeValues?: bool | *true
alignValue?: #TimelineValueAlignment | *"left"
}
PanelFieldConfig: {
ui.HideableFieldConfig
lineWidth?: number | *0
fillOpacity?: number | *70
}
}
]
]
migrations: []
}

View File

@ -0,0 +1,42 @@
// Copyright 2021 Grafana Labs
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package grafanaschema
import (
ui "github.com/grafana/grafana/cue/ui:grafanaschema"
)
Family: {
lineages: [
[
{
PanelOptions: {
ui.OptionsWithLegend
ui.OptionsWithTooltip
showValue: ui.BarValueVisibility
rowHeight: number
colWidth?: number
alignValue: "center" | *"left" | "right"
}
PanelFieldConfig: {
ui.HideableFieldConfig
lineWidth?: number | *1
fillOpacity?: number | *70
}
}
]
]
migrations: []
}

View File

@ -23,18 +23,12 @@ Family: {
[
{
PanelOptions: {
// FIXME idk where this is coming from but various devenv dashes have it
graph?: {...}
legend: ui.VizLegendOptions
tooltip: ui.VizTooltipOptions
}
PanelFieldConfig: {
ui.LineConfig
ui.FillConfig
ui.PointsConfig
ui.AxisConfig
drawStyle?: ui.DrawStyle
gradientMode?: ui.GraphGradientMode
hideFrom?: ui.HideSeriesConfig
}
PanelFieldConfig: ui.GraphFieldConfig
}
]
]

16
scripts/stripnulls.sh Executable file
View File

@ -0,0 +1,16 @@
#!/bin/bash
# Strip all null values from dashboards within devenv for some particular
# schema version. Must be run from Grafana root.
# OSX users need to install GNU sed: `brew install gsed`
SED=$(command -v gsed)
SED=${SED:-"sed"}
FILES=$(grep -rl '"schemaVersion": 3[01]' devenv)
set -e
set -x
for DASH in ${FILES}; do echo "${DASH}"; grep -v 'null,$' "${DASH}" > "${DASH}-nulless"; mv "${DASH}-nulless" "${DASH}"; done
for DASH in ${FILES}; do grep -v 'null$' "${DASH}" > "${DASH}-nulless"; mv "${DASH}-nulless" "${DASH}"; done
# shellcheck disable=SC2016,SC2002
for DASH in ${FILES}; do cat "${DASH}" | $SED -E -n 'H; x; s:,(\s*\n\s*}):\1:; P; ${x; p}' | $SED '1 d' > "${DASH}-nulless"; mv "${DASH}-nulless" "${DASH}"; done