mirror of https://github.com/grafana/grafana
Kindsys: Unify plugins, pfs with kind framework (#61192)
* New pfs impl * Reached codegen parity with old system * Update all models.cue inputs * Rename all models.cue files * Remove unused prefixfs * Changes Queries->DataQuery schema interface * Recodegen * All tests passing, nearly good now * Add SchemaInterface to kindsys props * Add pascal name deriver * Relocate plugin cue files again * Clarify use of injected fields * Remove unnecessary aliasing * Move DataQuery into mudball * Allow forcing ExpandReferences on go type generation * Move DataQuery def into kindsys, add generator to copy it to common * Fix copy generator to replace package name correctly * Fix duplicate type, test failure * Fix linting issuesivana/log-sample-docs
parent
6a7cbeae6c
commit
3b3059c9ce
@ -0,0 +1,46 @@ |
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT. |
||||
// |
||||
// Generated by: |
||||
// kinds/gen.go |
||||
// Using jennies: |
||||
// CommonSchemaJenny |
||||
// |
||||
// Run 'make gen-cue' from repository root to regenerate. |
||||
|
||||
package common |
||||
|
||||
// Canonically defined in pkg/kindsys/dataquery.cue FOR NOW to avoid having any external imports |
||||
// in kindsys. Code generation copies this file to the common schemas in packages/grafana-schema/src/common. |
||||
// |
||||
// NOTE make gen-cue must be run twice when updating this file |
||||
|
||||
// These are the common properties available to all queries in all datasources. |
||||
// Specific implementations will *extend* this interface, adding the required |
||||
// properties for the given context. |
||||
DataQuery: { |
||||
// A - Z |
||||
refId: string |
||||
|
||||
// true if query is disabled (ie should not be returned to the dashboard) |
||||
hide?: bool |
||||
|
||||
// Unique, guid like, string used in explore mode |
||||
key?: string |
||||
|
||||
// Specify the query flavor |
||||
// TODO make this required and give it a default |
||||
queryType?: string |
||||
|
||||
// For mixed data sources the selected datasource is on the query level. |
||||
// For non mixed scenarios this is undefined. |
||||
// TODO find a better way to do this ^ that's friendly to schema |
||||
// TODO this shouldn't be unknown but DataSourceRef | null |
||||
datasource?: _ |
||||
} @cuetsy(kind="interface") |
||||
|
||||
DataSourceRef: { |
||||
// The plugin type-id |
||||
type?: string |
||||
// Specific datasource instance |
||||
uid?: string |
||||
} @cuetsy(kind="interface") |
@ -0,0 +1,8 @@ |
||||
import * as raw from '../common/common.gen'; |
||||
|
||||
export interface DataQuery extends raw.DataQuery { |
||||
// TODO remove explicit nulls
|
||||
datasource?: raw.DataSourceRef | null; |
||||
} |
||||
|
||||
export * from '../common/common.gen'; |
@ -1,31 +0,0 @@ |
||||
{{ template "autogen_header.tmpl" .Header -}} |
||||
package corelist |
||||
|
||||
import ( |
||||
"fmt" |
||||
"io/fs" |
||||
"sync" |
||||
"github.com/grafana/grafana" |
||||
"github.com/grafana/grafana/pkg/plugins/pfs" |
||||
"github.com/grafana/thema" |
||||
) |
||||
|
||||
func makeTreeOrPanic(path string, pkgname string, rt *thema.Runtime) *pfs.Tree { |
||||
sub, err := fs.Sub(grafana.CueSchemaFS, path) |
||||
if err != nil { |
||||
panic("could not create fs sub to " + path) |
||||
} |
||||
tree, err := pfs.ParsePluginFS(sub, rt) |
||||
if err != nil { |
||||
panic(fmt.Sprintf("error parsing plugin metadata for %s: %s", pkgname, err)) |
||||
} |
||||
return tree |
||||
} |
||||
|
||||
func coreTreeList(rt *thema.Runtime) pfs.TreeList{ |
||||
return pfs.TreeList{ |
||||
{{- range .Plugins }} |
||||
makeTreeOrPanic("{{ .Path }}", "{{ .PkgName }}", rt), |
||||
{{- end }} |
||||
} |
||||
} |
@ -0,0 +1,48 @@ |
||||
package kindsys |
||||
|
||||
import ( |
||||
"github.com/grafana/thema" |
||||
) |
||||
|
||||
var _ Composable = genericComposable{} |
||||
|
||||
type genericComposable struct { |
||||
decl Decl[ComposableProperties] |
||||
lin thema.Lineage |
||||
} |
||||
|
||||
func (k genericComposable) Props() SomeKindProperties { |
||||
return k.decl.Properties |
||||
} |
||||
|
||||
func (k genericComposable) Name() string { |
||||
return k.decl.Properties.Name |
||||
} |
||||
|
||||
func (k genericComposable) MachineName() string { |
||||
return k.decl.Properties.MachineName |
||||
} |
||||
|
||||
func (k genericComposable) Maturity() Maturity { |
||||
return k.decl.Properties.Maturity |
||||
} |
||||
|
||||
func (k genericComposable) Decl() Decl[ComposableProperties] { |
||||
return k.decl |
||||
} |
||||
|
||||
func (k genericComposable) Lineage() thema.Lineage { |
||||
return k.lin |
||||
} |
||||
|
||||
func BindComposable(rt *thema.Runtime, decl Decl[ComposableProperties], opts ...thema.BindOption) (Composable, error) { |
||||
lin, err := decl.Some().BindKindLineage(rt, opts...) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
return genericComposable{ |
||||
decl: decl, |
||||
lin: lin, |
||||
}, nil |
||||
} |
@ -0,0 +1,37 @@ |
||||
package kindsys |
||||
|
||||
// Canonically defined in pkg/kindsys/dataquery.cue FOR NOW to avoid having any external imports |
||||
// in kindsys. Code generation copies this file to the common schemas in packages/grafana-schema/src/common. |
||||
// |
||||
// NOTE make gen-cue must be run twice when updating this file |
||||
|
||||
// These are the common properties available to all queries in all datasources. |
||||
// Specific implementations will *extend* this interface, adding the required |
||||
// properties for the given context. |
||||
DataQuery: { |
||||
// A - Z |
||||
refId: string |
||||
|
||||
// true if query is disabled (ie should not be returned to the dashboard) |
||||
hide?: bool |
||||
|
||||
// Unique, guid like, string used in explore mode |
||||
key?: string |
||||
|
||||
// Specify the query flavor |
||||
// TODO make this required and give it a default |
||||
queryType?: string |
||||
|
||||
// For mixed data sources the selected datasource is on the query level. |
||||
// For non mixed scenarios this is undefined. |
||||
// TODO find a better way to do this ^ that's friendly to schema |
||||
// TODO this shouldn't be unknown but DataSourceRef | null |
||||
datasource?: _ |
||||
} @cuetsy(kind="interface") |
||||
|
||||
DataSourceRef: { |
||||
// The plugin type-id |
||||
type?: string |
||||
// Specific datasource instance |
||||
uid?: string |
||||
} @cuetsy(kind="interface") |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,25 @@ |
||||
package grafanaplugin |
||||
|
||||
import ( |
||||
"github.com/grafana/thema" |
||||
"github.com/grafana/grafana/kinds/dashboard:kind" |
||||
) |
||||
|
||||
_dummy: coremodel.slots |
||||
|
||||
composableKinds: PanelCfg: { |
||||
lineage: { |
||||
name: "disallowed_cue_import" |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
{ |
||||
PanelOptions: { |
||||
foo: string |
||||
} @cuetsy(kind="interface") |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
||||
} |
@ -1,23 +0,0 @@ |
||||
package grafanaplugin |
||||
|
||||
import ( |
||||
"github.com/grafana/thema" |
||||
"github.com/grafana/grafana/kinds/dashboard:kind" |
||||
) |
||||
|
||||
_dummy: coremodel.slots |
||||
|
||||
Panel: thema.#Lineage & { |
||||
name: "disallowed_cue_import" |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
{ |
||||
PanelOptions: { |
||||
foo: string |
||||
} @cuetsy(kind="interface") |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
@ -1,14 +0,0 @@ |
||||
{ |
||||
"type": "panel", |
||||
"name": "Slot impl testing", |
||||
"id": "mismatch-panel", |
||||
"backend": true, |
||||
"state": "alpha", |
||||
"info": { |
||||
"description": "Test", |
||||
"author": { |
||||
"name": "Grafana Labs", |
||||
"url": "https://grafana.com" |
||||
} |
||||
} |
||||
} |
@ -1,9 +1,6 @@ |
||||
package grafanaplugin |
||||
|
||||
import "github.com/grafana/thema" |
||||
|
||||
Query: thema.#Lineage & { |
||||
name: "missing_kind_datasource" |
||||
composableKinds: DataQuery: lineage: { |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
@ -1,8 +1,6 @@ |
||||
package grafanaplugin |
||||
|
||||
import "github.com/grafana/thema" |
||||
|
||||
Panel: thema.#Lineage & { |
||||
composableKinds: PanelCfg: lineage: { |
||||
name: "doesnamatch" |
||||
seqs: [ |
||||
{ |
@ -0,0 +1,25 @@ |
||||
package grafanaplugin |
||||
|
||||
import "github.com/grafana/thema" |
||||
|
||||
composableKinds: PanelCfg: { |
||||
lineage: { |
||||
joinSchema: { |
||||
PanelOptions: {...} |
||||
PanelFieldConfig: string |
||||
} |
||||
name: "panel_conflicting_joinschema" |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
{ |
||||
PanelOptions: { |
||||
foo: string |
||||
} @cuetsy(kind="interface") |
||||
PanelFieldConfig: string |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
||||
} |
@ -1,23 +0,0 @@ |
||||
package grafanaplugin |
||||
|
||||
import "github.com/grafana/thema" |
||||
|
||||
Panel: thema.#Lineage & { |
||||
joinSchema: { |
||||
PanelOptions: {...} |
||||
PanelFieldConfig: string |
||||
} |
||||
name: "panel_conflicting_joinschema" |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
{ |
||||
PanelOptions: { |
||||
foo: string |
||||
} @cuetsy(kind="interface") |
||||
PanelFieldConfig: string |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
@ -0,0 +1,21 @@ |
||||
package grafanaplugin |
||||
|
||||
import "github.com/grafana/thema" |
||||
|
||||
composableKinds: PanelCfg: { |
||||
lineage: { |
||||
name: "panel_does_not_follow_slot_joinschema" |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
{ |
||||
PanelOptions: { |
||||
foo: string |
||||
} @cuetsy(kind="interface") |
||||
PanelFieldConfig: string |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
||||
} |
@ -1,19 +0,0 @@ |
||||
package grafanaplugin |
||||
|
||||
import "github.com/grafana/thema" |
||||
|
||||
Panel: thema.#Lineage & { |
||||
name: "panel_does_not_follow_slot_joinschema" |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
{ |
||||
PanelOptions: { |
||||
foo: string |
||||
} @cuetsy(kind="interface") |
||||
PanelFieldConfig: string |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
@ -0,0 +1,13 @@ |
||||
package grafanaplugin |
||||
|
||||
composableKinds: DataQuery: lineage: { |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
{ |
||||
foo: string |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
@ -0,0 +1,18 @@ |
||||
package grafanaplugin |
||||
|
||||
composableKinds: DataSourceCfg: lineage: { |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
{ |
||||
Options: { |
||||
foo: string |
||||
} |
||||
SecureOptions: { |
||||
bar: string |
||||
} |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
@ -1,34 +0,0 @@ |
||||
package grafanaplugin |
||||
|
||||
import "github.com/grafana/thema" |
||||
|
||||
Query: thema.#Lineage & { |
||||
name: "valid_model_datasource" |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
{ |
||||
foo: string |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
||||
|
||||
DSOptions: thema.#Lineage & { |
||||
name: "valid_model_datasource" |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
{ |
||||
Options: { |
||||
foo: string |
||||
} |
||||
SecureOptions: { |
||||
bar: string |
||||
} |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
@ -1,9 +1,6 @@ |
||||
package grafanaplugin |
||||
|
||||
import "github.com/grafana/thema" |
||||
|
||||
Panel: thema.#Lineage & { |
||||
name: "mismatch" |
||||
composableKinds: PanelCfg: lineage: { |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
@ -1,18 +0,0 @@ |
||||
package grafanaplugin |
||||
|
||||
import "github.com/grafana/thema" |
||||
|
||||
Panel: thema.#Lineage & { |
||||
name: "valid_model_panel" |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
{ |
||||
PanelOptions: { |
||||
foo: string |
||||
} @cuetsy(kind="interface") |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
@ -1,31 +0,0 @@ |
||||
package grafanaplugin |
||||
|
||||
import "github.com/grafana/thema" |
||||
|
||||
Query: thema.#Lineage & { |
||||
name: "wrong_slot_panel" |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
{ |
||||
foo: string |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
||||
|
||||
Panel: thema.#Lineage & { |
||||
name: "wrong_slot_panel" |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
{ |
||||
PanelOptions: { |
||||
foo: string |
||||
} @cuetsy(kind="interface") |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
@ -1,14 +0,0 @@ |
||||
{ |
||||
"type": "panel", |
||||
"name": "Wrong slot for type", |
||||
"id": "wrong-slot-panel", |
||||
"backend": true, |
||||
"state": "alpha", |
||||
"info": { |
||||
"description": "Test", |
||||
"author": { |
||||
"name": "Grafana Labs", |
||||
"url": "https://grafana.com" |
||||
} |
||||
} |
||||
} |
@ -1,3 +1,3 @@ |
||||
// Package pfs ("Plugin FS") defines a virtual filesystem representation of Grafana plugins.
|
||||
// Package pfs ("ParsedPlugin FS") defines a virtual filesystem representation of Grafana plugins.
|
||||
|
||||
package pfs |
||||
|
@ -0,0 +1,31 @@ |
||||
package pfs |
||||
|
||||
import ( |
||||
"github.com/grafana/grafana/pkg/kindsys" |
||||
) |
||||
|
||||
// GrafanaPlugin specifies what plugins may declare in .cue files in a |
||||
// `grafanaplugin` CUE package in the plugin root directory (adjacent to plugin.json). |
||||
GrafanaPlugin: { |
||||
// id and pascalName are injected from plugin.json. Plugin authors can write |
||||
// values for them in .cue files, but the only valid values will be the ones |
||||
// given in plugin.json. |
||||
id: string |
||||
pascalName: string |
||||
|
||||
// A plugin defines its Composable kinds under this key. |
||||
// |
||||
// This struct is open for forwards compatibility - older versions of Grafana (or |
||||
// dependent tooling) should not break if new versions introduce additional schema interfaces. |
||||
composableKinds?: [Iface=string]: kindsys.Composable & { |
||||
name: pascalName + Iface |
||||
schemaInterface: Iface |
||||
lineage: name: pascalName + Iface |
||||
} |
||||
|
||||
// A plugin defines its Custom kinds under this key. |
||||
customKinds?: [Name=string]: kindsys.Custom & { |
||||
name: Name |
||||
} |
||||
... |
||||
} |
@ -0,0 +1,48 @@ |
||||
package pfs |
||||
|
||||
import ( |
||||
"cuelang.org/go/cue/ast" |
||||
"github.com/grafana/grafana/pkg/kindsys" |
||||
"github.com/grafana/grafana/pkg/plugins/plugindef" |
||||
) |
||||
|
||||
// ParsedPlugin represents everything knowable about a single plugin from static
|
||||
// analysis of its filesystem tree contents, as performed by [ParsePluginFS].
|
||||
//
|
||||
// Guarantees described in the below comments only exist for instances of this
|
||||
// struct returned from [ParsePluginFS].
|
||||
type ParsedPlugin struct { |
||||
// Properties contains the plugin's definition, as declared in plugin.json.
|
||||
Properties plugindef.PluginDef |
||||
|
||||
// ComposableKinds is a map of all the composable kinds declared in this plugin.
|
||||
// Keys are the name of the [kindsys.SchemaInterface] implemented by the value.
|
||||
//
|
||||
// Composable kind defs are only populated in this map by [ParsePluginFS] if
|
||||
// they are implementations of a known schema interface, or are for
|
||||
// an unknown schema interface.
|
||||
ComposableKinds map[string]kindsys.Composable |
||||
|
||||
// CustomKinds is a map of all the custom kinds declared in this plugin.
|
||||
// Keys are the machineName of the custom kind.
|
||||
// CustomKinds map[string]kindsys.Custom
|
||||
|
||||
// CUEImports lists the CUE import statements in the plugin's grafanaplugin CUE
|
||||
// package, if any.
|
||||
CUEImports []*ast.ImportSpec |
||||
} |
||||
|
||||
// TODO is this static approach worth using, akin to core generated registries? instead of the ParsedPlugins.ComposableKinds map? in addition to it?
|
||||
// ComposableKinds represents all the possible composable kinds that may be
|
||||
// defined in a Grafana plugin.
|
||||
//
|
||||
// The value of each field, if non-nil, is a standard [kindsys.Decl]
|
||||
// representing a CUE definition of a composable kind that implements the
|
||||
// schema interface corresponding to the field's name. (This invariant is
|
||||
// only enforced in [ComposableKinds] returned from [ParsePluginFS].)
|
||||
//
|
||||
// type ComposableKinds struct {
|
||||
// PanelCfg kindsys.Decl[kindsys.ComposableProperties]
|
||||
// Queries kindsys.Decl[kindsys.ComposableProperties]
|
||||
// DSCfg kindsys.Decl[kindsys.ComposableProperties]
|
||||
// }
|
@ -0,0 +1,31 @@ |
||||
package pfs |
||||
|
||||
import ( |
||||
"sort" |
||||
"testing" |
||||
|
||||
"github.com/google/go-cmp/cmp" |
||||
"github.com/grafana/grafana/pkg/kindsys" |
||||
) |
||||
|
||||
// This is a brick-dumb test that just ensures known schema interfaces are being
|
||||
// loaded correctly from their declarations in .cue files.
|
||||
//
|
||||
// If this test fails, it's either because:
|
||||
// - They're not being loaded correctly - there's a bug in kindsys or pfs somewhere, fix it
|
||||
// - The set of schema interfaces has been modified - update the static list here
|
||||
func TestSchemaInterfacesAreLoaded(t *testing.T) { |
||||
knownSI := []string{"PanelCfg", "DataQuery", "DataSourceCfg"} |
||||
all := kindsys.SchemaInterfaces(nil) |
||||
var loadedSI []string |
||||
for k := range all { |
||||
loadedSI = append(loadedSI, k) |
||||
} |
||||
|
||||
sort.Strings(knownSI) |
||||
sort.Strings(loadedSI) |
||||
|
||||
if diff := cmp.Diff(knownSI, loadedSI); diff != "" { |
||||
t.Fatalf("kindsys cue-declared schema interfaces differ from ComposableKinds go struct:\n%s", diff) |
||||
} |
||||
} |
@ -0,0 +1,43 @@ |
||||
package plugindef |
||||
|
||||
import ( |
||||
"testing" |
||||
|
||||
"github.com/stretchr/testify/require" |
||||
) |
||||
|
||||
func TestDerivePascal(t *testing.T) { |
||||
table := []struct { |
||||
id, name, out string |
||||
}{ |
||||
{ |
||||
name: "-- Grafana --", |
||||
out: "Grafana", |
||||
}, |
||||
{ |
||||
name: "A weird/Thing", |
||||
out: "AWeirdThing", |
||||
}, |
||||
{ |
||||
name: "/", |
||||
out: "Empty", |
||||
}, |
||||
{ |
||||
name: "some really Long thing WHY would38883 anyone do this i don't know but hey It seems like it this is just going on and", |
||||
out: "SomeReallyLongThingWHYWouldAnyoneDoThisIDonTKnowButHeyItSeemsLi", |
||||
}, |
||||
} |
||||
|
||||
for _, row := range table { |
||||
if row.id == "" { |
||||
row.id = "default-empty-panel" |
||||
} |
||||
|
||||
pd := PluginDef{ |
||||
Id: row.id, |
||||
Name: row.name, |
||||
} |
||||
|
||||
require.Equal(t, row.out, DerivePascalName(pd)) |
||||
} |
||||
} |
@ -0,0 +1,81 @@ |
||||
// Copyright 2022 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 grafanaplugin |
||||
|
||||
import ( |
||||
ui "github.com/grafana/grafana/packages/grafana-schema/src/common" |
||||
) |
||||
|
||||
composableKinds: PanelCfg: { |
||||
maturity: "experimental" |
||||
|
||||
lineage: { |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
// v0.0 |
||||
{ |
||||
PanelOptions: { |
||||
ui.OptionsWithLegend |
||||
ui.OptionsWithTooltip |
||||
ui.OptionsWithTextFormatting |
||||
|
||||
// TODO docs |
||||
xField?: string |
||||
// TODO docs |
||||
colorByField?: string |
||||
// TODO docs |
||||
orientation: ui.VizOrientation | *"auto" |
||||
// TODO docs |
||||
barRadius?: float64 & >=0 & <=0.5 | *0 |
||||
// TODO docs |
||||
xTickLabelRotation: int32 & >=-90 & <=90 | *0 |
||||
// TODO docs |
||||
xTickLabelMaxLength: int32 & >=0 |
||||
// TODO docs |
||||
// negative values indicate backwards skipping behavior |
||||
xTickLabelSpacing?: int32 | *0 |
||||
// TODO docs |
||||
stacking: ui.StackingMode | *"none" |
||||
// This controls whether values are shown on top or to the left of bars. |
||||
showValue: ui.VisibilityMode | *"auto" |
||||
// Controls the width of bars. 1 = Max width, 0 = Min width. |
||||
barWidth: float64 & >=0 & <=1 | *0.97 |
||||
// Controls the width of groups. 1 = max with, 0 = min width. |
||||
groupWidth: float64 & >=0 & <=1 | *0.7 |
||||
// Enables mode which highlights the entire bar area and shows tooltip when cursor |
||||
// hovers over highlighted area |
||||
fullHighlight: bool | *false |
||||
} @cuetsy(kind="interface") |
||||
PanelFieldConfig: { |
||||
ui.AxisConfig |
||||
ui.HideableFieldConfig |
||||
|
||||
// Controls line width of the bars. |
||||
lineWidth?: int32 & >=0 & <=10 | *1 |
||||
// Controls the fill opacity of the bars. |
||||
fillOpacity?: int32 & >=0 & <=100 | *80 |
||||
// Set the mode of the gradient fill. Fill gradient is based on the line color. To change the color, use the standard color scheme field option. |
||||
// Gradient appearance is influenced by the Fill opacity setting. |
||||
gradientMode?: ui.GraphGradientMode | *"none" |
||||
// Threshold rendering |
||||
thresholdsStyle?: ui.GraphThresholdsStyleConfig |
||||
} @cuetsy(kind="interface") |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
||||
} |
@ -1,76 +0,0 @@ |
||||
// Copyright 2022 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 grafanaplugin |
||||
|
||||
import ( |
||||
"github.com/grafana/thema" |
||||
ui "github.com/grafana/grafana/packages/grafana-schema/src/common" |
||||
) |
||||
|
||||
Panel: thema.#Lineage & { |
||||
name: "barchart" |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
// v0.0 |
||||
{ |
||||
PanelOptions: { |
||||
ui.OptionsWithLegend |
||||
ui.OptionsWithTooltip |
||||
ui.OptionsWithTextFormatting |
||||
// TODO docs |
||||
xField?: string |
||||
// TODO docs |
||||
colorByField?: string |
||||
// TODO docs |
||||
orientation: ui.VizOrientation | *"auto" |
||||
// TODO docs |
||||
barRadius?: float64 & >= 0 & <= 0.5 | *0 |
||||
// TODO docs |
||||
xTickLabelRotation: int32 & >= -90 & <= 90 | *0 |
||||
// TODO docs |
||||
xTickLabelMaxLength: int32 & >= 0 |
||||
// TODO docs |
||||
// negative values indicate backwards skipping behavior |
||||
xTickLabelSpacing?: int32 | *0 |
||||
// TODO docs |
||||
stacking: ui.StackingMode | *"none" |
||||
// This controls whether values are shown on top or to the left of bars. |
||||
showValue: ui.VisibilityMode | *"auto" |
||||
// Controls the width of bars. 1 = Max width, 0 = Min width. |
||||
barWidth: float64 & >= 0 & <= 1 | *0.97 |
||||
// Controls the width of groups. 1 = max with, 0 = min width. |
||||
groupWidth: float64 & >= 0 & <= 1 | *0.7 |
||||
// Enables mode which highlights the entire bar area and shows tooltip when cursor hovers over highlighted area |
||||
fullHighlight: bool | *false |
||||
} @cuetsy(kind="interface") |
||||
PanelFieldConfig: { |
||||
ui.AxisConfig |
||||
ui.HideableFieldConfig |
||||
// Controls line width of the bars. |
||||
lineWidth?: int32 & >= 0 & <= 10 | *1 |
||||
// Controls the fill opacity of the bars. |
||||
fillOpacity?: int32 & >= 0 & <= 100 | *80 |
||||
// Set the mode of the gradient fill. Fill gradient is based on the line color. To change the color, use the standard color scheme field option. |
||||
// Gradient appearance is influenced by the Fill opacity setting. |
||||
gradientMode?: ui.GraphGradientMode | *"none" |
||||
// Threshold rendering |
||||
thresholdsStyle?: ui.GraphThresholdsStyleConfig |
||||
} @cuetsy(kind="interface") |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
@ -0,0 +1,58 @@ |
||||
// Copyright 2022 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 grafanaplugin |
||||
|
||||
import ( |
||||
ui "github.com/grafana/grafana/packages/grafana-schema/src/common" |
||||
) |
||||
|
||||
composableKinds: PanelCfg: { |
||||
maturity: "experimental" |
||||
|
||||
lineage: { |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
{ |
||||
PanelOptions: { |
||||
ui.OptionsWithLegend |
||||
ui.OptionsWithTooltip |
||||
|
||||
//Size of each bucket |
||||
bucketSize?: int32 |
||||
//Offset buckets by this amount |
||||
bucketOffset?: int32 | *0 |
||||
//Combines multiple series into a single histogram |
||||
combine?: bool |
||||
} @cuetsy(kind="interface") |
||||
|
||||
PanelFieldConfig: { |
||||
ui.AxisConfig |
||||
ui.HideableFieldConfig |
||||
|
||||
// Controls line width of the bars. |
||||
lineWidth?: uint32 & <=10 | *1 |
||||
// Controls the fill opacity of the bars. |
||||
fillOpacity?: uint32 & <=100 | *80 |
||||
// Set the mode of the gradient fill. Fill gradient is based on the line color. To change the color, use the standard color scheme field option. |
||||
// Gradient appearance is influenced by the Fill opacity setting. |
||||
gradientMode?: ui.GraphGradientMode | *"none" |
||||
} @cuetsy(kind="interface") |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
||||
} |
@ -1,54 +0,0 @@ |
||||
// Copyright 2022 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 grafanaplugin |
||||
|
||||
import ( |
||||
"github.com/grafana/thema" |
||||
ui "github.com/grafana/grafana/packages/grafana-schema/src/common" |
||||
) |
||||
|
||||
Panel: thema.#Lineage & { |
||||
name: "histogram" |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
{ |
||||
PanelOptions: { |
||||
ui.OptionsWithLegend |
||||
ui.OptionsWithTooltip |
||||
//Size of each bucket |
||||
bucketSize?: int32 |
||||
//Offset buckets by this amount |
||||
bucketOffset?: int32 | *0 |
||||
//Combines multiple series into a single histogram |
||||
combine?: bool |
||||
} @cuetsy(kind="interface") |
||||
|
||||
PanelFieldConfig: { |
||||
ui.AxisConfig |
||||
ui.HideableFieldConfig |
||||
// Controls line width of the bars. |
||||
lineWidth?: uint32 & <= 10 | *1 |
||||
// Controls the fill opacity of the bars. |
||||
fillOpacity?: uint32 & <= 100 | *80 |
||||
// Set the mode of the gradient fill. Fill gradient is based on the line color. To change the color, use the standard color scheme field option. |
||||
// Gradient appearance is influenced by the Fill opacity setting. |
||||
gradientMode?: ui.GraphGradientMode | *"none" |
||||
} @cuetsy(kind="interface") |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
@ -0,0 +1,58 @@ |
||||
// Copyright 2022 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 grafanaplugin |
||||
|
||||
import ( |
||||
ui "github.com/grafana/grafana/packages/grafana-schema/src/common" |
||||
) |
||||
|
||||
composableKinds: PanelCfg: { |
||||
maturity: "experimental" |
||||
|
||||
lineage: { |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
// v0.0 |
||||
{ |
||||
// Select the pie chart display style. |
||||
PieChartType: "pie" | "donut" @cuetsy(kind="enum") |
||||
// Select labels to display on the pie chart. |
||||
// - Name - The series or field name. |
||||
// - Percent - The percentage of the whole. |
||||
// - Value - The raw numerical value. |
||||
PieChartLabels: "name" | "value" | "percent" @cuetsy(kind="enum") |
||||
// Select values to display in the legend. |
||||
// - Percent: The percentage of the whole. |
||||
// - Value: The raw numerical value. |
||||
PieChartLegendValues: "value" | "percent" @cuetsy(kind="enum") |
||||
PieChartLegendOptions: { |
||||
ui.VizLegendOptions |
||||
values: [...PieChartLegendValues] |
||||
} @cuetsy(kind="interface") |
||||
PanelOptions: { |
||||
ui.OptionsWithTooltip |
||||
ui.SingleStatBaseOptions |
||||
pieType: PieChartType |
||||
displayLabels: [...PieChartLabels] |
||||
legend: PieChartLegendOptions |
||||
} @cuetsy(kind="interface") |
||||
PanelFieldConfig: ui.HideableFieldConfig @cuetsy(kind="interface") |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
||||
} |
@ -1,56 +0,0 @@ |
||||
// Copyright 2022 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 grafanaplugin |
||||
|
||||
import ( |
||||
"github.com/grafana/thema" |
||||
ui "github.com/grafana/grafana/packages/grafana-schema/src/common" |
||||
) |
||||
|
||||
Panel: thema.#Lineage & { |
||||
name: "piechart" |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
// v0.0 |
||||
{ |
||||
// Select the pie chart display style. |
||||
PieChartType: "pie" | "donut" @cuetsy(kind="enum") |
||||
// Select labels to display on the pie chart. |
||||
// - Name - The series or field name. |
||||
// - Percent - The percentage of the whole. |
||||
// - Value - The raw numerical value. |
||||
PieChartLabels: "name" | "value" | "percent" @cuetsy(kind="enum") |
||||
// Select values to display in the legend. |
||||
// - Percent: The percentage of the whole. |
||||
// - Value: The raw numerical value. |
||||
PieChartLegendValues: "value" | "percent" @cuetsy(kind="enum") |
||||
PieChartLegendOptions: { |
||||
ui.VizLegendOptions |
||||
values: [...PieChartLegendValues] |
||||
} @cuetsy(kind="interface") |
||||
PanelOptions: { |
||||
ui.OptionsWithTooltip |
||||
ui.SingleStatBaseOptions |
||||
pieType: PieChartType |
||||
displayLabels: [...PieChartLabels] |
||||
legend: PieChartLegendOptions |
||||
} @cuetsy(kind="interface") |
||||
PanelFieldConfig: ui.HideableFieldConfig @cuetsy(kind="interface") |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
@ -0,0 +1,51 @@ |
||||
// 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 grafanaplugin |
||||
|
||||
import ( |
||||
ui "github.com/grafana/grafana/packages/grafana-schema/src/common" |
||||
) |
||||
|
||||
composableKinds: PanelCfg: { |
||||
lineage: { |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
{ |
||||
TimelineMode: "changes" | "samples" @cuetsy(kind="enum") |
||||
TimelineValueAlignment: "center" | "left" | "right" @cuetsy(kind="type") |
||||
PanelOptions: { |
||||
// FIXME ts comments indicate this shouldn't be in the saved model, but currently is emitted |
||||
mode?: TimelineMode |
||||
ui.OptionsWithLegend |
||||
ui.OptionsWithTooltip |
||||
ui.OptionsWithTimezones |
||||
showValue: ui.VisibilityMode | *"auto" |
||||
rowHeight: number | *0.9 |
||||
colWidth?: number |
||||
mergeValues?: bool | *true |
||||
alignValue?: TimelineValueAlignment | *"left" |
||||
} @cuetsy(kind="interface") |
||||
PanelFieldConfig: { |
||||
ui.HideableFieldConfig |
||||
lineWidth?: number | *0 |
||||
fillOpacity?: number | *70 |
||||
} @cuetsy(kind="interface") |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
||||
} |
@ -1,51 +0,0 @@ |
||||
// 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 grafanaplugin |
||||
|
||||
import ( |
||||
"github.com/grafana/thema" |
||||
ui "github.com/grafana/grafana/packages/grafana-schema/src/common" |
||||
) |
||||
|
||||
Panel: thema.#Lineage & { |
||||
name: "state-timeline" |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
{ |
||||
TimelineMode: "changes" | "samples" @cuetsy(kind="enum") |
||||
TimelineValueAlignment: "center" | "left" | "right" @cuetsy(kind="type") |
||||
PanelOptions: { |
||||
// FIXME ts comments indicate this shouldn't be in the saved model, but currently is emitted |
||||
mode?: TimelineMode |
||||
ui.OptionsWithLegend |
||||
ui.OptionsWithTooltip |
||||
ui.OptionsWithTimezones |
||||
showValue: ui.VisibilityMode | *"auto" |
||||
rowHeight: number | *0.9 |
||||
colWidth?: number |
||||
mergeValues?: bool | *true |
||||
alignValue?: TimelineValueAlignment | *"left" |
||||
} @cuetsy(kind="interface") |
||||
PanelFieldConfig: { |
||||
ui.HideableFieldConfig |
||||
lineWidth?: number | *0 |
||||
fillOpacity?: number | *70 |
||||
} @cuetsy(kind="interface") |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
@ -0,0 +1,46 @@ |
||||
// 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 grafanaplugin |
||||
|
||||
import ( |
||||
ui "github.com/grafana/grafana/packages/grafana-schema/src/common" |
||||
) |
||||
|
||||
composableKinds: PanelCfg: { |
||||
lineage: { |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
{ |
||||
PanelOptions: { |
||||
ui.OptionsWithLegend |
||||
ui.OptionsWithTooltip |
||||
ui.OptionsWithTimezones |
||||
showValue: ui.VisibilityMode |
||||
rowHeight: number |
||||
colWidth?: number |
||||
alignValue: "center" | *"left" | "right" |
||||
} @cuetsy(kind="interface") |
||||
PanelFieldConfig: { |
||||
ui.HideableFieldConfig |
||||
lineWidth?: number | *1 |
||||
fillOpacity?: number | *70 |
||||
} @cuetsy(kind="interface") |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
||||
} |
@ -1,46 +0,0 @@ |
||||
// 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 grafanaplugin |
||||
|
||||
import ( |
||||
"github.com/grafana/thema" |
||||
ui "github.com/grafana/grafana/packages/grafana-schema/src/common" |
||||
) |
||||
|
||||
Panel: thema.#Lineage & { |
||||
name: "status-history" |
||||
seqs: [ |
||||
{ |
||||
schemas: [ |
||||
{ |
||||
PanelOptions: { |
||||
ui.OptionsWithLegend |
||||
ui.OptionsWithTooltip |
||||
ui.OptionsWithTimezones |
||||
showValue: ui.VisibilityMode |
||||
rowHeight: number |
||||
colWidth?: number |
||||
alignValue: "center" | *"left" | "right" |
||||
} @cuetsy(kind="interface") |
||||
PanelFieldConfig: { |
||||
ui.HideableFieldConfig |
||||
lineWidth?: number | *1 |
||||
fillOpacity?: number | *70 |
||||
} @cuetsy(kind="interface") |
||||
}, |
||||
] |
||||
}, |
||||
] |
||||
} |
Loading…
Reference in new issue