mirror of
https://github.com/grafana/grafana.git
synced 2025-08-01 07:21:50 +08:00
Adapt dashboard schema to validate on some devenv dashboards (#37594)
* Remove null values from JSON * Specify the color field * Add note about openness of custom field's struct * Update schemaVersion * Specify thresholds * Add panel id * Add maxDataPoints and interval * Add mappings, albeit very under-specified * Allow empty string for timezone field This is probably not a good idea - same as allowing nulls. * Allow false for refresh - otherwise, string * Make threshold value optional * Make interval optional * Fix broken and changed decls in ui models * Add models.cue for timeseries panel * Fixups for home dashboard * Add timeShift, timeFrom * Abstract out #Target, rejigger comments
This commit is contained in:
126
cue/data/gen.cue
126
cue/data/gen.cue
@ -22,7 +22,7 @@ Family: scuemata.#Family & {
|
|||||||
// Theme of dashboard.
|
// Theme of dashboard.
|
||||||
style: *"light" | "dark"
|
style: *"light" | "dark"
|
||||||
// Timezone of dashboard,
|
// Timezone of dashboard,
|
||||||
timezone?: *"browser" | "utc"
|
timezone?: *"browser" | "utc" | ""
|
||||||
// Whether a dashboard is editable or not.
|
// Whether a dashboard is editable or not.
|
||||||
editable: bool | *true
|
editable: bool | *true
|
||||||
// 0 for no shared crosshair or tooltip (default).
|
// 0 for no shared crosshair or tooltip (default).
|
||||||
@ -66,14 +66,62 @@ Family: scuemata.#Family & {
|
|||||||
showIn: number | *0
|
showIn: number | *0
|
||||||
}]
|
}]
|
||||||
// Auto-refresh interval.
|
// Auto-refresh interval.
|
||||||
refresh?: string
|
refresh?: string | false
|
||||||
// Version of the JSON schema, incremented each time a Grafana update brings
|
// Version of the JSON schema, incremented each time a Grafana update brings
|
||||||
// changes to said schema.
|
// changes to said schema.
|
||||||
schemaVersion: number | *25
|
// FIXME this is the old schema numbering system, and will be replaced by scuemata
|
||||||
|
schemaVersion: number | *30
|
||||||
// Version of the dashboard, incremented each time the dashboard is updated.
|
// Version of the dashboard, incremented each time the dashboard is updated.
|
||||||
version?: number
|
version?: number
|
||||||
panels?: [...#Panel]
|
panels?: [...#Panel]
|
||||||
|
|
||||||
|
// TODO docs
|
||||||
|
#FieldColorModeId: "thresholds" | "palette-classic" | "palette-saturated" | "continuous-GrYlRd" | "fixed" @cuetsy(targetType="enum")
|
||||||
|
|
||||||
|
// TODO docs
|
||||||
|
#FieldColorSeriesByMode: "min" | "max" | "last" @cuetsy(targetType="type")
|
||||||
|
|
||||||
|
// TODO docs
|
||||||
|
#FieldColor: {
|
||||||
|
// The main color scheme mode
|
||||||
|
mode: #FieldColorModeId | string
|
||||||
|
// Stores the fixed color value if mode is fixed
|
||||||
|
fixedColor?: string
|
||||||
|
// Some visualizations need to know how to assign a series color from by value color schemes
|
||||||
|
seriesBy?: #FieldColorSeriesByMode
|
||||||
|
} @cuetsy(targetType="interface")
|
||||||
|
|
||||||
|
// TODO docs
|
||||||
|
#Threshold: {
|
||||||
|
// TODO docs
|
||||||
|
// FIXME the corresponding typescript field is required/non-optional, but nulls currently appear here when serializing -Infinity to JSON
|
||||||
|
value?: number
|
||||||
|
// TODO docs
|
||||||
|
color: string
|
||||||
|
// TODO docs
|
||||||
|
// TODO are the values here enumerable into a disjunction?
|
||||||
|
// Some seem to be listed in typescript comment
|
||||||
|
state?: string
|
||||||
|
} @cuetsy(targetType="interface")
|
||||||
|
|
||||||
|
#ThresholdsMode: "absolute" | "percentage" @cuetsy(targetType="enum")
|
||||||
|
|
||||||
|
#ThresholdsConfig: {
|
||||||
|
mode: #ThresholdsMode
|
||||||
|
|
||||||
|
// Must be sorted by 'value', first value is always -Infinity
|
||||||
|
steps: [...#Threshold]
|
||||||
|
} @cuetsy(targetType="interface")
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// variant of the Dashboard and Panel families, or filled
|
||||||
|
// with types derived from plugins in the Instance variant.
|
||||||
|
// When working directly from CUE, importers can extend this
|
||||||
|
// type directly to achieve the same effect.
|
||||||
|
#Target: {...}
|
||||||
|
|
||||||
// Dashboard panels. Panels are canonically defined inline
|
// Dashboard panels. Panels are canonically defined inline
|
||||||
// because they share a version timeline with the dashboard
|
// because they share a version timeline with the dashboard
|
||||||
// schema; they do not vary independently. We create a separate,
|
// schema; they do not vary independently. We create a separate,
|
||||||
@ -83,6 +131,15 @@ Family: scuemata.#Family & {
|
|||||||
// The panel plugin type id.
|
// The panel plugin type id.
|
||||||
type: !=""
|
type: !=""
|
||||||
|
|
||||||
|
// TODO docs
|
||||||
|
id?: number
|
||||||
|
|
||||||
|
// FIXME this almost certainly has to be changed in favor of scuemata versions
|
||||||
|
pluginVersion?: string
|
||||||
|
|
||||||
|
// TODO docs
|
||||||
|
tags?: [...string]
|
||||||
|
|
||||||
// Internal - the exact major and minor versions of the panel plugin
|
// Internal - the exact major and minor versions of the panel plugin
|
||||||
// schema. Hidden and therefore not a part of the data model, but
|
// schema. Hidden and therefore not a part of the data model, but
|
||||||
// expected to be filled with panel plugin schema versions so that it's
|
// expected to be filled with panel plugin schema versions so that it's
|
||||||
@ -93,6 +150,9 @@ Family: scuemata.#Family & {
|
|||||||
// TODO 2-tuple list instead of struct?
|
// TODO 2-tuple list instead of struct?
|
||||||
panelSchema?: { maj: number, min: number }
|
panelSchema?: { maj: number, min: number }
|
||||||
|
|
||||||
|
// TODO docs
|
||||||
|
targets?: [...#Target]
|
||||||
|
|
||||||
// Panel title.
|
// Panel title.
|
||||||
title?: string
|
title?: string
|
||||||
// Description.
|
// Description.
|
||||||
@ -115,20 +175,33 @@ Family: scuemata.#Family & {
|
|||||||
static?: bool
|
static?: bool
|
||||||
}
|
}
|
||||||
// Panel links.
|
// Panel links.
|
||||||
// links?: [..._panelLink]
|
// FIXME this is temporarily specified as a closed list so
|
||||||
|
// that validation will pass when no links are present, but
|
||||||
|
// to force a failure as soon as it's checked against there
|
||||||
|
// being anything in the list so it can be fixed in
|
||||||
|
// accordance with that object
|
||||||
|
links?: []
|
||||||
|
|
||||||
// Name of template variable to repeat for.
|
// Name of template variable to repeat for.
|
||||||
repeat?: string
|
repeat?: string
|
||||||
// Direction to repeat in if 'repeat' is set.
|
// Direction to repeat in if 'repeat' is set.
|
||||||
// "h" for horizontal, "v" for vertical.
|
// "h" for horizontal, "v" for vertical.
|
||||||
repeatDirection: *"h" | "v"
|
repeatDirection: *"h" | "v"
|
||||||
// Schema for panel targets is specified by datasource
|
|
||||||
// plugins. We use a placeholder definition, which the Go
|
// TODO docs
|
||||||
// schema loader either left open/as-is with the Base
|
maxDataPoints?: number
|
||||||
// variant of the Dashboard and Panel families, or filled
|
|
||||||
// with types derived from plugins in the Instance variant.
|
// TODO docs
|
||||||
// When working directly from CUE, importers can extend this
|
// TODO tighter constraint
|
||||||
// type directly to achieve the same effect.
|
interval?: string
|
||||||
targets?: [...{...}]
|
|
||||||
|
// TODO docs
|
||||||
|
// TODO tighter constraint
|
||||||
|
timeFrom?: string
|
||||||
|
|
||||||
|
// TODO docs
|
||||||
|
// TODO tighter constraint
|
||||||
|
timeShift?: string
|
||||||
|
|
||||||
// The values depend on panel type
|
// The values depend on panel type
|
||||||
options: {...}
|
options: {...}
|
||||||
@ -166,17 +239,25 @@ Family: scuemata.#Family & {
|
|||||||
min?: number
|
min?: number
|
||||||
max?: number
|
max?: number
|
||||||
|
|
||||||
// // Convert input values into a display string
|
// Convert input values into a display string
|
||||||
// mappings?: ValueMapping[];
|
//
|
||||||
|
// TODO this one corresponds to a complex type with
|
||||||
|
// generics on the typescript side. Ouch. Will
|
||||||
|
// either need special care, or we'll just need to
|
||||||
|
// accept a very loosely specified schema. It's very
|
||||||
|
// unlikely we'll be able to translate cue to
|
||||||
|
// typescript generics in the general case, though
|
||||||
|
// this particular one *may* be able to work.
|
||||||
|
mappings?: [...{...}]
|
||||||
|
|
||||||
// // Map numeric values to states
|
// Map numeric values to states
|
||||||
// thresholds?: ThresholdsConfig;
|
thresholds?: #ThresholdsConfig
|
||||||
|
|
||||||
// // Map values to a display color
|
// // Map values to a display color
|
||||||
// color?: FieldColor;
|
color?: #FieldColor
|
||||||
|
|
||||||
// // Used when reducing field values
|
// // Used when reducing field values
|
||||||
// nullValueMode?: NullValueMode;
|
// nullValueMode?: NullValueMode
|
||||||
|
|
||||||
// // The behavior when clicking on a result
|
// // The behavior when clicking on a result
|
||||||
links?: [...]
|
links?: [...]
|
||||||
@ -184,10 +265,17 @@ Family: scuemata.#Family & {
|
|||||||
// Alternative to empty string
|
// Alternative to empty string
|
||||||
noValue?: string
|
noValue?: string
|
||||||
|
|
||||||
|
// TODO conundrum: marking this struct as open would
|
||||||
|
// - i think - preclude closed validation of
|
||||||
|
// plugin-defined config bits. But, marking it
|
||||||
|
// closed makes it impossible to use just this
|
||||||
|
// schema (the "base" variant) to validate the base
|
||||||
|
// components of a dashboard.
|
||||||
|
//
|
||||||
// Can always exist. Valid fields within this are
|
// Can always exist. Valid fields within this are
|
||||||
// defined by the panel plugin - that's the
|
// defined by the panel plugin - that's the
|
||||||
// PanelFieldConfig that comes from the plugin.
|
// PanelFieldConfig that comes from the plugin.
|
||||||
custom?: {}
|
custom?: {...}
|
||||||
}
|
}
|
||||||
overrides: [...{
|
overrides: [...{
|
||||||
matcher: {
|
matcher: {
|
||||||
|
@ -33,7 +33,7 @@ ScaleDistribution: "linear" | "log" @c
|
|||||||
GraphGradientMode: "none" | "opacity" | "hue" | "scheme" @cuetsy(targetType="enum")
|
GraphGradientMode: "none" | "opacity" | "hue" | "scheme" @cuetsy(targetType="enum")
|
||||||
LineStyle: {
|
LineStyle: {
|
||||||
fill?: "solid" | "dash" | "dot" | "square"
|
fill?: "solid" | "dash" | "dot" | "square"
|
||||||
dash?: [number]
|
dash?: [...number]
|
||||||
} @cuetsy(targetType="interface")
|
} @cuetsy(targetType="interface")
|
||||||
LineConfig: {
|
LineConfig: {
|
||||||
lineColor?: string
|
lineColor?: string
|
||||||
@ -68,7 +68,7 @@ AxisConfig: {
|
|||||||
HideSeriesConfig: {
|
HideSeriesConfig: {
|
||||||
tooltip: bool
|
tooltip: bool
|
||||||
legend: bool
|
legend: bool
|
||||||
graph: bool
|
viz: bool
|
||||||
} @cuetsy(targetType="interface")
|
} @cuetsy(targetType="interface")
|
||||||
LegendPlacement: "bottom" | "right" @cuetsy(targetType="type")
|
LegendPlacement: "bottom" | "right" @cuetsy(targetType="type")
|
||||||
LegendDisplayMode: "list" | "table" | "hidden" @cuetsy(targetType="enum")
|
LegendDisplayMode: "list" | "table" | "hidden" @cuetsy(targetType="enum")
|
||||||
@ -86,7 +86,7 @@ GraphFieldConfig: LineConfig & FillConfig & PointsConfig & AxisConfig & {
|
|||||||
VizLegendOptions: {
|
VizLegendOptions: {
|
||||||
displayMode: LegendDisplayMode
|
displayMode: LegendDisplayMode
|
||||||
placement: LegendPlacement
|
placement: LegendPlacement
|
||||||
calcs: [string]
|
calcs: [...string]
|
||||||
} @cuetsy(targetType="interface")
|
} @cuetsy(targetType="interface")
|
||||||
VizTooltipOptions: {
|
VizTooltipOptions: {
|
||||||
mode: TooltipDisplayMode
|
mode: TooltipDisplayMode
|
||||||
|
@ -50,9 +50,12 @@ AxisConfig: {
|
|||||||
HideSeriesConfig: {
|
HideSeriesConfig: {
|
||||||
tooltip: bool
|
tooltip: bool
|
||||||
legend: bool
|
legend: bool
|
||||||
graph: bool
|
viz: bool
|
||||||
} @cuetsy(targetType="interface")
|
} @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 & {
|
GraphFieldConfig: LineConfig & FillConfig & PointsConfig & AxisConfig & {
|
||||||
drawStyle?: DrawStyle
|
drawStyle?: DrawStyle
|
||||||
gradientMode?: GraphGradientMode
|
gradientMode?: GraphGradientMode
|
||||||
|
42
public/app/plugins/panel/timeseries/models.cue
Normal file
42
public/app/plugins/panel/timeseries/models.cue
Normal 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: {
|
||||||
|
legend: ui.VizLegendOptions
|
||||||
|
tooltip: ui.VizTooltipOptions
|
||||||
|
}
|
||||||
|
PanelFieldConfig: {
|
||||||
|
ui.LineConfig
|
||||||
|
ui.FillConfig
|
||||||
|
ui.PointsConfig
|
||||||
|
ui.AxisConfig
|
||||||
|
drawStyle?: ui.DrawStyle
|
||||||
|
gradientMode?: ui.GraphGradientMode
|
||||||
|
hideFrom?: ui.HideSeriesConfig
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
migrations: []
|
||||||
|
}
|
Reference in New Issue
Block a user