Canvas: Migrate to schema (#70205)

This commit is contained in:
Nathan Marrs
2023-06-17 05:56:23 +03:00
committed by GitHub
parent da66aefa87
commit d7a8892f3a
13 changed files with 530 additions and 94 deletions
@@ -0,0 +1,153 @@
---
keywords:
- grafana
- schema
title: CanvasPanelCfg kind
---
> Both documentation generation and kinds schemas are in active development and subject to change without prior notice.
## CanvasPanelCfg
#### Maturity: [experimental](../../../maturity/#experimental)
#### Version: 0.0
| Property | Type | Required | Default | Description |
|-------------------------|----------------------------------|----------|---------|-----------------------------------------------------------------------|
| `BackgroundConfig` | [object](#backgroundconfig) | **Yes** | | |
| `BackgroundImageSize` | string | **Yes** | | Possible values are: `original`, `contain`, `cover`, `fill`, `tile`. |
| `CanvasConnection` | [object](#canvasconnection) | **Yes** | | |
| `CanvasElementOptions` | [object](#canvaselementoptions) | **Yes** | | |
| `ConnectionCoordinates` | [object](#connectioncoordinates) | **Yes** | | |
| `ConnectionPath` | string | **Yes** | | Possible values are: `straight`. |
| `Constraint` | [object](#constraint) | **Yes** | | |
| `HorizontalConstraint` | string | **Yes** | | Possible values are: `left`, `right`, `leftright`, `center`, `scale`. |
| `LineConfig` | [object](#lineconfig) | **Yes** | | |
| `Options` | [object](#options) | **Yes** | | |
| `Placement` | [object](#placement) | **Yes** | | |
| `VerticalConstraint` | string | **Yes** | | Possible values are: `top`, `bottom`, `topbottom`, `center`, `scale`. |
### BackgroundConfig
| Property | Type | Required | Default | Description |
|----------|-----------------------------------------------------|----------|---------|----------------------------------------------------------------------|
| `color` | [ColorDimensionConfig](#colordimensionconfig) | No | | |
| `image` | [ResourceDimensionConfig](#resourcedimensionconfig) | No | | Links to a resource (image/svg path) |
| `size` | string | No | | Possible values are: `original`, `contain`, `cover`, `fill`, `tile`. |
### ColorDimensionConfig
It extends [BaseDimensionConfig](#basedimensionconfig).
| Property | Type | Required | Default | Description |
|----------|--------|----------|---------|--------------------------------------------------------------------------------------------------------------|
| `field` | string | No | | *(Inherited from [BaseDimensionConfig](#basedimensionconfig))*<br/>fixed: T -- will be added by each element |
| `fixed` | string | No | | |
### BaseDimensionConfig
| Property | Type | Required | Default | Description |
|----------|--------|----------|---------|-------------------------------------------|
| `field` | string | No | | fixed: T -- will be added by each element |
### ResourceDimensionConfig
Links to a resource (image/svg path)
It extends [BaseDimensionConfig](#basedimensionconfig).
| Property | Type | Required | Default | Description |
|----------|--------|----------|---------|--------------------------------------------------------------------------------------------------------------|
| `mode` | string | **Yes** | | Possible values are: `fixed`, `field`, `mapping`. |
| `field` | string | No | | *(Inherited from [BaseDimensionConfig](#basedimensionconfig))*<br/>fixed: T -- will be added by each element |
| `fixed` | string | No | | |
### CanvasConnection
| Property | Type | Required | Default | Description |
|--------------|-------------------------------------------------|----------|---------|----------------------------------|
| `path` | string | **Yes** | | Possible values are: `straight`. |
| `source` | [ConnectionCoordinates](#connectioncoordinates) | **Yes** | | |
| `target` | [ConnectionCoordinates](#connectioncoordinates) | **Yes** | | |
| `color` | [ColorDimensionConfig](#colordimensionconfig) | No | | |
| `size` | [ScaleDimensionConfig](#scaledimensionconfig) | No | | |
| `targetName` | string | No | | |
### ConnectionCoordinates
| Property | Type | Required | Default | Description |
|----------|--------|----------|---------|-------------|
| `x` | number | **Yes** | | |
| `y` | number | **Yes** | | |
### ScaleDimensionConfig
It extends [BaseDimensionConfig](#basedimensionconfig).
| Property | Type | Required | Default | Description |
|----------|--------|----------|---------|--------------------------------------------------------------------------------------------------------------|
| `max` | number | **Yes** | | |
| `min` | number | **Yes** | | |
| `field` | string | No | | *(Inherited from [BaseDimensionConfig](#basedimensionconfig))*<br/>fixed: T -- will be added by each element |
| `fixed` | number | No | | |
| `mode` | string | No | | Possible values are: `linear`, `quad`. |
### CanvasElementOptions
| Property | Type | Required | Default | Description |
|---------------|-----------------------------------------|----------|---------|---------------------------------------------------------|
| `name` | string | **Yes** | | |
| `type` | string | **Yes** | | |
| `background` | [BackgroundConfig](#backgroundconfig) | No | | |
| `border` | [LineConfig](#lineconfig) | No | | |
| `config` | | No | | TODO: figure out how to define this (element config(s)) |
| `connections` | [CanvasConnection](#canvasconnection)[] | No | | |
| `constraint` | [Constraint](#constraint) | No | | |
| `placement` | [Placement](#placement) | No | | |
### Constraint
| Property | Type | Required | Default | Description |
|--------------|--------|----------|---------|-----------------------------------------------------------------------|
| `horizontal` | string | No | | Possible values are: `left`, `right`, `leftright`, `center`, `scale`. |
| `vertical` | string | No | | Possible values are: `top`, `bottom`, `topbottom`, `center`, `scale`. |
### LineConfig
| Property | Type | Required | Default | Description |
|----------|-----------------------------------------------|----------|---------|-------------|
| `color` | [ColorDimensionConfig](#colordimensionconfig) | No | | |
| `width` | number | No | | |
### Placement
| Property | Type | Required | Default | Description |
|----------|--------|----------|---------|-------------|
| `bottom` | number | No | | |
| `height` | number | No | | |
| `left` | number | No | | |
| `right` | number | No | | |
| `top` | number | No | | |
| `width` | number | No | | |
### Options
| Property | Type | Required | Default | Description |
|---------------------|-----------------|----------|---------|--------------------------------------------------------------------------------------------------------------------------------------|
| `inlineEditing` | boolean | **Yes** | `true` | Enable inline editing |
| `root` | [object](#root) | **Yes** | | The root element of canvas (frame), where all canvas elements are nested<br/>TODO: Figure out how to define a default value for this |
| `showAdvancedTypes` | boolean | **Yes** | `true` | Show all available element types |
### Root
The root element of canvas (frame), where all canvas elements are nested
TODO: Figure out how to define a default value for this
| Property | Type | Required | Default | Description |
|------------|-------------------------------------------------|----------|---------|----------------------------------------------------------------|
| `elements` | [CanvasElementOptions](#canvaselementoptions)[] | **Yes** | | The list of canvas elements attached to the root element |
| `name` | string | **Yes** | | Name of the root element |
| `type` | string | **Yes** | | Type of root element (frame)<br/>Possible values are: `frame`. |
@@ -0,0 +1,131 @@
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
//
// Generated by:
// public/app/plugins/gen.go
// Using jennies:
// TSTypesJenny
// LatestMajorsOrXJenny
// PluginEachMajorJenny
//
// Run 'make gen-cue' from repository root to regenerate.
import * as ui from '@grafana/schema';
export enum HorizontalConstraint {
Center = 'center',
Left = 'left',
LeftRight = 'leftright',
Right = 'right',
Scale = 'scale',
}
export enum VerticalConstraint {
Bottom = 'bottom',
Center = 'center',
Scale = 'scale',
Top = 'top',
TopBottom = 'topbottom',
}
export interface Constraint {
horizontal?: HorizontalConstraint;
vertical?: VerticalConstraint;
}
export interface Placement {
bottom?: number;
height?: number;
left?: number;
right?: number;
top?: number;
width?: number;
}
export enum BackgroundImageSize {
Contain = 'contain',
Cover = 'cover',
Fill = 'fill',
Original = 'original',
Tile = 'tile',
}
export interface BackgroundConfig {
color?: ui.ColorDimensionConfig;
image?: ui.ResourceDimensionConfig;
size?: BackgroundImageSize;
}
export interface LineConfig {
color?: ui.ColorDimensionConfig;
width?: number;
}
export interface ConnectionCoordinates {
x: number;
y: number;
}
export enum ConnectionPath {
Straight = 'straight',
}
export interface CanvasConnection {
color?: ui.ColorDimensionConfig;
path: ConnectionPath;
size?: ui.ScaleDimensionConfig;
source: ConnectionCoordinates;
target: ConnectionCoordinates;
targetName?: string;
}
export interface CanvasElementOptions {
background?: BackgroundConfig;
border?: LineConfig;
/**
* TODO: figure out how to define this (element config(s))
*/
config?: unknown;
connections?: Array<CanvasConnection>;
constraint?: Constraint;
name: string;
placement?: Placement;
type: string;
}
export const defaultCanvasElementOptions: Partial<CanvasElementOptions> = {
connections: [],
};
export interface Options {
/**
* Enable inline editing
*/
inlineEditing: boolean;
/**
* The root element of canvas (frame), where all canvas elements are nested
* TODO: Figure out how to define a default value for this
*/
root: {
/**
* Name of the root element
*/
name: string;
/**
* Type of root element (frame)
*/
type: 'frame';
/**
* The list of canvas elements attached to the root element
*/
elements: Array<CanvasElementOptions>;
};
/**
* Show all available element types
*/
showAdvancedTypes: boolean;
}
export const defaultOptions: Partial<Options> = {
inlineEditing: true,
showAdvancedTypes: true,
};
@@ -56,6 +56,7 @@ func corePlugins(rt *thema.Runtime) []pfs.ParsedPlugin {
parsePluginOrPanic("public/app/plugins/panel/annolist", "annolist", rt),
parsePluginOrPanic("public/app/plugins/panel/barchart", "barchart", rt),
parsePluginOrPanic("public/app/plugins/panel/bargauge", "bargauge", rt),
parsePluginOrPanic("public/app/plugins/panel/canvas", "canvas", rt),
parsePluginOrPanic("public/app/plugins/panel/dashlist", "dashlist", rt),
parsePluginOrPanic("public/app/plugins/panel/datagrid", "datagrid", rt),
parsePluginOrPanic("public/app/plugins/panel/debug", "debug", rt),
+20 -51
View File
@@ -1,55 +1,14 @@
import { LinkModel } from '@grafana/data/src';
import { ColorDimensionConfig, ResourceDimensionConfig, TextDimensionConfig } from '@grafana/schema';
export interface Placement {
top?: number;
left?: number;
right?: number;
bottom?: number;
width?: number;
height?: number;
}
export interface Constraint {
horizontal?: HorizontalConstraint;
vertical?: VerticalConstraint;
}
export enum HorizontalConstraint {
Left = 'left',
Right = 'right',
LeftRight = 'leftright',
Center = 'center',
Scale = 'scale',
}
export enum VerticalConstraint {
Top = 'top',
Bottom = 'bottom',
TopBottom = 'topbottom',
Center = 'center',
Scale = 'scale',
}
export enum BackgroundImageSize {
Original = 'original',
Contain = 'contain',
Cover = 'cover',
Fill = 'fill',
Tile = 'tile',
}
export interface BackgroundConfig {
color?: ColorDimensionConfig;
image?: ResourceDimensionConfig;
size?: BackgroundImageSize;
}
export interface LineConfig {
color?: ColorDimensionConfig;
width?: number;
}
import { ColorDimensionConfig, TextDimensionConfig } from '@grafana/schema';
import {
BackgroundImageSize,
Constraint,
HorizontalConstraint,
Placement,
VerticalConstraint,
LineConfig,
BackgroundConfig,
} from 'app/plugins/panel/canvas/panelcfg.gen';
export enum QuickPlacement {
Top = 'top',
@@ -88,3 +47,13 @@ export interface TextConfig {
align: Align;
valign: VAlign;
}
export {
Placement,
Constraint,
HorizontalConstraint,
VerticalConstraint,
BackgroundImageSize,
LineConfig,
BackgroundConfig,
};
-1
View File
@@ -24,7 +24,6 @@ import (
)
var skipPlugins = map[string]bool{
"canvas": true,
"candlestick": true,
"influxdb": true, // plugin.json fails validation (defaultMatchFormat)
"mixed": true, // plugin.json fails validation (mixed)
@@ -11,7 +11,7 @@ import { PanelEditEnteredEvent, PanelEditExitedEvent } from 'app/types/events';
import { SetBackground } from './components/SetBackground';
import { InlineEdit } from './editor/inline/InlineEdit';
import { Options } from './models.gen';
import { Options } from './panelcfg.gen';
import { AnchorPoint, CanvasTooltipPayload, ConnectionState } from './types';
interface Props extends PanelProps<Options> {}
@@ -7,7 +7,7 @@ import { Field, HorizontalGroup, Icon, InlineField, InlineFieldRow, Select, Vert
import { NumberInput } from 'app/core/components/OptionsUI/NumberInput';
import { HorizontalConstraint, Placement, VerticalConstraint } from 'app/features/canvas';
import { Options } from '../../models.gen';
import { Options } from '../../panelcfg.gen';
import { ConstraintSelectionBox } from './ConstraintSelectionBox';
import { QuickPositioning } from './QuickPositioning';
@@ -10,7 +10,7 @@ import { AddLayerButton } from 'app/core/components/Layers/AddLayerButton';
import { ElementState } from 'app/features/canvas/runtime/element';
import { getGlobalStyles } from '../../globalStyles';
import { Options } from '../../models.gen';
import { Options } from '../../panelcfg.gen';
import { DragNode, DropNode } from '../../types';
import { doSelect, getElementTypes, onAddItem } from '../../utils';
import { TreeViewEditorProps } from '../element/elementEditor';
@@ -1,6 +1,6 @@
import { PanelModel } from '@grafana/data';
import { Options } from './models.gen';
import { Options } from './panelcfg.gen';
export const canvasMigrationHandler = (panel: PanelModel): Partial<Options> => {
const pluginVersion = panel?.pluginVersion ?? '';
@@ -1,26 +0,0 @@
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// NOTE: This file will be auto generated from models.cue
// It is currently hand written but will serve as the target for cuetsy
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import { CanvasFrameOptions, DEFAULT_CANVAS_ELEMENT_CONFIG } from 'app/features/canvas';
export const modelVersion = Object.freeze([1, 0]);
export interface Options {
inlineEditing: boolean;
showAdvancedTypes: boolean;
root: CanvasFrameOptions;
}
export const defaultOptions: Options = {
inlineEditing: true,
showAdvancedTypes: false,
root: {
elements: [
{
...DEFAULT_CANVAS_ELEMENT_CONFIG,
},
],
} as unknown as CanvasFrameOptions,
};
+1 -1
View File
@@ -6,7 +6,7 @@ import { getConnectionEditor } from './editor/connectionEditor';
import { getElementEditor } from './editor/element/elementEditor';
import { getLayerEditor } from './editor/layer/layerEditor';
import { canvasMigrationHandler } from './migrations';
import { Options } from './models.gen';
import { Options } from './panelcfg.gen';
export const addStandardCanvasEditorOptions = (builder: PanelOptionsEditorBuilder<Options>) => {
builder.addBooleanSwitch({
+88 -11
View File
@@ -1,4 +1,4 @@
// Copyright 2021 Grafana Labs
// Copyright 2023 Grafana Labs
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,14 +14,91 @@
package grafanaplugin
composableKinds: PanelCfg: lineage: {
schemas: [{
version: [0, 0]
schema: {
Options: {
...
} @cuetsy(kind="interface")
}
}]
lenses: []
import (
ui "github.com/grafana/grafana/packages/grafana-schema/src/common"
)
composableKinds: PanelCfg: {
maturity: "experimental"
lineage: {
schemas: [{
version: [0, 0]
schema: {
HorizontalConstraint: "left" | "right" | "leftright" | "center" | "scale" @cuetsy(kind="enum", memberNames="Left|Right|LeftRight|Center|Scale")
VerticalConstraint: "top" | "bottom" | "topbottom" | "center" | "scale" @cuetsy(kind="enum", memberNames="Top|Bottom|TopBottom|Center|Scale")
Constraint: {
horizontal?: HorizontalConstraint
vertical?: VerticalConstraint
} @cuetsy(kind="interface")
Placement: {
top?: float64
left?: float64
right?: float64
bottom?: float64
width?: float64
height?: float64
} @cuetsy(kind="interface")
BackgroundImageSize: "original" | "contain" | "cover" | "fill" | "tile" @cuetsy(kind="enum", memberNames="Original|Contain|Cover|Fill|Tile")
BackgroundConfig: {
color?: ui.ColorDimensionConfig
image?: ui.ResourceDimensionConfig
size?: BackgroundImageSize
} @cuetsy(kind="interface")
LineConfig: {
color?: ui.ColorDimensionConfig
width?: float64
} @cuetsy(kind="interface")
ConnectionCoordinates: {
x: float64
y: float64
} @cuetsy(kind="interface")
ConnectionPath: "straight" @cuetsy(kind="enum", memberNames="Straight")
CanvasConnection: {
source: ConnectionCoordinates
target: ConnectionCoordinates
targetName?: string
path: ConnectionPath
color?: ui.ColorDimensionConfig
size?: ui.ScaleDimensionConfig
} @cuetsy(kind="interface")
CanvasElementOptions: {
name: string
type: string
// TODO: figure out how to define this (element config(s))
config?: _
constraint?: Constraint
placement?: Placement
background?: BackgroundConfig
border?: LineConfig
connections?: [...CanvasConnection]
} @cuetsy(kind="interface")
Options: {
// Enable inline editing
inlineEditing: bool | *true
// Show all available element types
showAdvancedTypes: bool | *true
// The root element of canvas (frame), where all canvas elements are nested
// TODO: Figure out how to define a default value for this
root: {
// Name of the root element
name: string
// Type of root element (frame)
type: "frame"
// The list of canvas elements attached to the root element
elements: [...CanvasElementOptions]
} @cuetsy(kind="interface")
} @cuetsy(kind="interface")
}
}]
lenses: []
}
}
@@ -0,0 +1,132 @@
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
//
// Generated by:
// public/app/plugins/gen.go
// Using jennies:
// TSTypesJenny
// PluginTSTypesJenny
//
// Run 'make gen-cue' from repository root to regenerate.
import * as ui from '@grafana/schema';
export const PanelCfgModelVersion = Object.freeze([0, 0]);
export enum HorizontalConstraint {
Center = 'center',
Left = 'left',
LeftRight = 'leftright',
Right = 'right',
Scale = 'scale',
}
export enum VerticalConstraint {
Bottom = 'bottom',
Center = 'center',
Scale = 'scale',
Top = 'top',
TopBottom = 'topbottom',
}
export interface Constraint {
horizontal?: HorizontalConstraint;
vertical?: VerticalConstraint;
}
export interface Placement {
bottom?: number;
height?: number;
left?: number;
right?: number;
top?: number;
width?: number;
}
export enum BackgroundImageSize {
Contain = 'contain',
Cover = 'cover',
Fill = 'fill',
Original = 'original',
Tile = 'tile',
}
export interface BackgroundConfig {
color?: ui.ColorDimensionConfig;
image?: ui.ResourceDimensionConfig;
size?: BackgroundImageSize;
}
export interface LineConfig {
color?: ui.ColorDimensionConfig;
width?: number;
}
export interface ConnectionCoordinates {
x: number;
y: number;
}
export enum ConnectionPath {
Straight = 'straight',
}
export interface CanvasConnection {
color?: ui.ColorDimensionConfig;
path: ConnectionPath;
size?: ui.ScaleDimensionConfig;
source: ConnectionCoordinates;
target: ConnectionCoordinates;
targetName?: string;
}
export interface CanvasElementOptions {
background?: BackgroundConfig;
border?: LineConfig;
/**
* TODO: figure out how to define this (element config(s))
*/
config?: unknown;
connections?: Array<CanvasConnection>;
constraint?: Constraint;
name: string;
placement?: Placement;
type: string;
}
export const defaultCanvasElementOptions: Partial<CanvasElementOptions> = {
connections: [],
};
export interface Options {
/**
* Enable inline editing
*/
inlineEditing: boolean;
/**
* The root element of canvas (frame), where all canvas elements are nested
* TODO: Figure out how to define a default value for this
*/
root: {
/**
* Name of the root element
*/
name: string;
/**
* Type of root element (frame)
*/
type: 'frame';
/**
* The list of canvas elements attached to the root element
*/
elements: Array<CanvasElementOptions>;
};
/**
* Show all available element types
*/
showAdvancedTypes: boolean;
}
export const defaultOptions: Partial<Options> = {
inlineEditing: true,
showAdvancedTypes: true,
};