mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Introduce "scuemata" system for CUE-based specification of Grafana objects (#32527)
This commit is contained in:
@@ -2,7 +2,7 @@ import React, { Component } from 'react';
|
||||
|
||||
import { Select, Table } from '@grafana/ui';
|
||||
import { DataFrame, FieldMatcherID, getFrameDisplayName, PanelProps, SelectableValue } from '@grafana/data';
|
||||
import { Options } from './types';
|
||||
import { PanelOptions } from './models.gen';
|
||||
import { css } from '@emotion/css';
|
||||
import { config } from 'app/core/config';
|
||||
import { FilterItem, TableSortByFieldState } from '@grafana/ui/src/components/Table/types';
|
||||
@@ -10,7 +10,7 @@ import { dispatch } from '../../../store/store';
|
||||
import { applyFilterFromTable } from '../../../features/variables/adhoc/actions';
|
||||
import { getDashboardSrv } from '../../../features/dashboard/services/DashboardSrv';
|
||||
|
||||
interface Props extends PanelProps<Options> {}
|
||||
interface Props extends PanelProps<PanelOptions> {}
|
||||
|
||||
export class TablePanel extends Component<Props> {
|
||||
constructor(props: Props) {
|
||||
|
||||
@@ -11,14 +11,14 @@ import omitBy from 'lodash/omitBy';
|
||||
import isNil from 'lodash/isNil';
|
||||
import isNumber from 'lodash/isNumber';
|
||||
import defaultTo from 'lodash/defaultTo';
|
||||
import { Options } from './types';
|
||||
import { PanelOptions } from './models.gen';
|
||||
|
||||
/**
|
||||
* At 7.0, the `table` panel was swapped from an angular implementation to a react one.
|
||||
* The models do not match, so this process will delegate to the old implementation when
|
||||
* a saved table configuration exists.
|
||||
*/
|
||||
export const tableMigrationHandler = (panel: PanelModel<Options>): Partial<Options> => {
|
||||
export const tableMigrationHandler = (panel: PanelModel<PanelOptions>): Partial<PanelOptions> => {
|
||||
// Table was saved as an angular table, lets just swap to the 'table-old' panel
|
||||
if (!panel.pluginVersion && (panel as any).columns) {
|
||||
console.log('Was angular table', panel);
|
||||
@@ -74,7 +74,7 @@ const generateThresholds = (thresholds: string[], colors: string[]) => {
|
||||
};
|
||||
|
||||
const migrateTransformations = (
|
||||
panel: PanelModel<Partial<Options>> | any,
|
||||
panel: PanelModel<Partial<PanelOptions>> | any,
|
||||
oldOpts: { columns: any; transform: Transformations }
|
||||
) => {
|
||||
const transformations: Transformation[] = panel.transformations ?? [];
|
||||
@@ -221,7 +221,7 @@ const migrateDefaults = (prevDefaults: Style) => {
|
||||
* This is called when the panel changes from another panel
|
||||
*/
|
||||
export const tablePanelChangedHandler = (
|
||||
panel: PanelModel<Partial<Options>> | any,
|
||||
panel: PanelModel<Partial<PanelOptions>> | any,
|
||||
prevPluginId: string,
|
||||
prevOptions: any
|
||||
) => {
|
||||
|
||||
26
public/app/plugins/panel/table/models.cue
Normal file
26
public/app/plugins/panel/table/models.cue
Normal file
@@ -0,0 +1,26 @@
|
||||
package grafanaschema
|
||||
|
||||
import (
|
||||
ui "github.com/grafana/grafana/cue/ui:grafanaschema"
|
||||
)
|
||||
|
||||
Family: {
|
||||
lineages: [
|
||||
[
|
||||
{
|
||||
PanelOptions: {
|
||||
frameIndex: number | *0
|
||||
showHeader: bool | *true
|
||||
sortBy?: [...ui.TableSortByFieldState]
|
||||
}
|
||||
PanelFieldConfig: {
|
||||
width?: int
|
||||
align?: *null | string
|
||||
displayMode?: string | *"auto" // TODO? TableCellDisplayMode
|
||||
filterable?: bool
|
||||
}
|
||||
},
|
||||
]
|
||||
]
|
||||
migrations: []
|
||||
}
|
||||
34
public/app/plugins/panel/table/models.gen.ts
Normal file
34
public/app/plugins/panel/table/models.gen.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// NOTE: This file will be auto generated from models.cue
|
||||
// It is currenty hand written but will serve as the target for cuetsy
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
import { TableCellDisplayMode, TableSortByFieldState } from '@grafana/ui';
|
||||
|
||||
// Only the latest schema version is translated to TypeScript, on the premise
|
||||
// that either the dashboard loading process, or (eventually) CUE-defined
|
||||
// migrations ensure that bulk of the frontend application only ever
|
||||
// need directly consider the most recent version of the schema.
|
||||
export const modelVersion = Object.freeze([1, 0]);
|
||||
|
||||
export interface PanelOptions {
|
||||
frameIndex: number;
|
||||
showHeader: boolean;
|
||||
sortBy?: TableSortByFieldState[];
|
||||
}
|
||||
|
||||
export const defaultPanelOptions: PanelOptions = {
|
||||
frameIndex: 0,
|
||||
showHeader: true,
|
||||
};
|
||||
|
||||
export interface PanelFieldConfig {
|
||||
width?: number;
|
||||
align?: string;
|
||||
displayMode?: TableCellDisplayMode;
|
||||
filterable?: boolean;
|
||||
}
|
||||
|
||||
export const defaultPanelFieldConfig: PanelFieldConfig = {
|
||||
displayMode: TableCellDisplayMode.Auto,
|
||||
};
|
||||
@@ -1,10 +1,10 @@
|
||||
import { PanelPlugin } from '@grafana/data';
|
||||
import { TablePanel } from './TablePanel';
|
||||
import { CustomFieldConfig, Options } from './types';
|
||||
import { PanelOptions, PanelFieldConfig, defaultPanelOptions, defaultPanelFieldConfig } from './models.gen';
|
||||
import { tableMigrationHandler, tablePanelChangedHandler } from './migrations';
|
||||
import { TableCellDisplayMode } from '@grafana/ui';
|
||||
|
||||
export const plugin = new PanelPlugin<Options, CustomFieldConfig>(TablePanel)
|
||||
export const plugin = new PanelPlugin<PanelOptions, PanelFieldConfig>(TablePanel)
|
||||
.setPanelChangeHandler(tablePanelChangedHandler)
|
||||
.setMigrationHandler(tableMigrationHandler)
|
||||
.setNoPadding()
|
||||
@@ -20,6 +20,7 @@ export const plugin = new PanelPlugin<Options, CustomFieldConfig>(TablePanel)
|
||||
max: 300,
|
||||
},
|
||||
shouldApply: () => true,
|
||||
defaultValue: defaultPanelFieldConfig.width,
|
||||
})
|
||||
.addRadio({
|
||||
path: 'align',
|
||||
@@ -32,7 +33,7 @@ export const plugin = new PanelPlugin<Options, CustomFieldConfig>(TablePanel)
|
||||
{ label: 'right', value: 'right' },
|
||||
],
|
||||
},
|
||||
defaultValue: null,
|
||||
defaultValue: defaultPanelFieldConfig.align,
|
||||
})
|
||||
.addSelect({
|
||||
path: 'displayMode',
|
||||
@@ -51,12 +52,13 @@ export const plugin = new PanelPlugin<Options, CustomFieldConfig>(TablePanel)
|
||||
{ value: TableCellDisplayMode.Image, label: 'Image' },
|
||||
],
|
||||
},
|
||||
defaultValue: defaultPanelFieldConfig.displayMode,
|
||||
})
|
||||
.addBooleanSwitch({
|
||||
path: 'filterable',
|
||||
name: 'Column filter',
|
||||
description: 'Enables/disables field filters in table',
|
||||
defaultValue: false,
|
||||
defaultValue: defaultPanelFieldConfig.filterable,
|
||||
});
|
||||
},
|
||||
})
|
||||
@@ -65,6 +67,6 @@ export const plugin = new PanelPlugin<Options, CustomFieldConfig>(TablePanel)
|
||||
path: 'showHeader',
|
||||
name: 'Show header',
|
||||
description: "To display table's header or not to display",
|
||||
defaultValue: true,
|
||||
defaultValue: defaultPanelOptions.showHeader,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
"name": "Table",
|
||||
"id": "table",
|
||||
|
||||
"models": {
|
||||
"version": [1, 0],
|
||||
"changed": "2021/03/30"
|
||||
},
|
||||
|
||||
"info": {
|
||||
"description": "Table Panel for Grafana",
|
||||
"author": {
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import { TableSortByFieldState } from '@grafana/ui';
|
||||
|
||||
export interface Options {
|
||||
frameIndex: number;
|
||||
showHeader: boolean;
|
||||
sortBy?: TableSortByFieldState[];
|
||||
}
|
||||
|
||||
export interface TableSortBy {
|
||||
displayName: string;
|
||||
desc: boolean;
|
||||
}
|
||||
|
||||
export interface CustomFieldConfig {
|
||||
width: number;
|
||||
displayMode: string;
|
||||
}
|
||||
Reference in New Issue
Block a user