mirror of https://github.com/grafana/grafana.git
WIP
This commit is contained in:
parent
f166968357
commit
141885acae
|
@ -127,6 +127,8 @@ DataTopic: "series" | "annotations" | "alertStates" @cog(kind="enum",memberNames
|
|||
DataTransformerConfig: {
|
||||
// Unique identifier of transformer
|
||||
id: string
|
||||
// Unique identifier of the instance of the transformer
|
||||
refId?: string
|
||||
// Disabled transformations are skipped
|
||||
disabled?: bool
|
||||
// Optional frame matcher. When missing it will be applied to all results
|
||||
|
|
|
@ -76,7 +76,7 @@ func (c *DashboardClient) Patch(ctx context.Context, identifier resource.Identif
|
|||
return c.client.Patch(ctx, identifier, req, opts)
|
||||
}
|
||||
|
||||
func (c *DashboardClient) UpdateStatus(ctx context.Context, newStatus DashboardStatus, opts resource.UpdateOptions) (*Dashboard, error) {
|
||||
func (c *DashboardClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus DashboardStatus, opts resource.UpdateOptions) (*Dashboard, error) {
|
||||
return c.client.Update(ctx, &Dashboard{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: DashboardKind().Kind(),
|
||||
|
@ -84,6 +84,8 @@ func (c *DashboardClient) UpdateStatus(ctx context.Context, newStatus DashboardS
|
|||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
ResourceVersion: opts.ResourceVersion,
|
||||
Namespace: identifier.Namespace,
|
||||
Name: identifier.Name,
|
||||
},
|
||||
Status: newStatus,
|
||||
}, resource.UpdateOptions{
|
||||
|
|
|
@ -516,6 +516,8 @@ lineage: schemas: [{
|
|||
#DataTransformerConfig: {
|
||||
// Unique identifier of transformer
|
||||
id: string
|
||||
// Unique identifier of the instance of the transformer
|
||||
refId?: string
|
||||
// Disabled transformations are skipped
|
||||
disabled?: bool
|
||||
// Optional frame matcher. When missing it will be applied to all results
|
||||
|
|
|
@ -76,7 +76,7 @@ func (c *DashboardClient) Patch(ctx context.Context, identifier resource.Identif
|
|||
return c.client.Patch(ctx, identifier, req, opts)
|
||||
}
|
||||
|
||||
func (c *DashboardClient) UpdateStatus(ctx context.Context, newStatus DashboardStatus, opts resource.UpdateOptions) (*Dashboard, error) {
|
||||
func (c *DashboardClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus DashboardStatus, opts resource.UpdateOptions) (*Dashboard, error) {
|
||||
return c.client.Update(ctx, &Dashboard{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: DashboardKind().Kind(),
|
||||
|
@ -84,6 +84,8 @@ func (c *DashboardClient) UpdateStatus(ctx context.Context, newStatus DashboardS
|
|||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
ResourceVersion: opts.ResourceVersion,
|
||||
Namespace: identifier.Namespace,
|
||||
Name: identifier.Name,
|
||||
},
|
||||
Status: newStatus,
|
||||
}, resource.UpdateOptions{
|
||||
|
|
|
@ -516,6 +516,8 @@ lineage: schemas: [{
|
|||
#DataTransformerConfig: {
|
||||
// Unique identifier of transformer
|
||||
id: string
|
||||
// Unique identifier of the instance of the transformer
|
||||
refId?: string
|
||||
// Disabled transformations are skipped
|
||||
disabled?: bool
|
||||
// Optional frame matcher. When missing it will be applied to all results
|
||||
|
|
|
@ -76,7 +76,7 @@ func (c *DashboardClient) Patch(ctx context.Context, identifier resource.Identif
|
|||
return c.client.Patch(ctx, identifier, req, opts)
|
||||
}
|
||||
|
||||
func (c *DashboardClient) UpdateStatus(ctx context.Context, newStatus DashboardStatus, opts resource.UpdateOptions) (*Dashboard, error) {
|
||||
func (c *DashboardClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus DashboardStatus, opts resource.UpdateOptions) (*Dashboard, error) {
|
||||
return c.client.Update(ctx, &Dashboard{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: DashboardKind().Kind(),
|
||||
|
@ -84,6 +84,8 @@ func (c *DashboardClient) UpdateStatus(ctx context.Context, newStatus DashboardS
|
|||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
ResourceVersion: opts.ResourceVersion,
|
||||
Namespace: identifier.Namespace,
|
||||
Name: identifier.Name,
|
||||
},
|
||||
Status: newStatus,
|
||||
}, resource.UpdateOptions{
|
||||
|
|
|
@ -76,7 +76,7 @@ func (c *DashboardClient) Patch(ctx context.Context, identifier resource.Identif
|
|||
return c.client.Patch(ctx, identifier, req, opts)
|
||||
}
|
||||
|
||||
func (c *DashboardClient) UpdateStatus(ctx context.Context, newStatus DashboardStatus, opts resource.UpdateOptions) (*Dashboard, error) {
|
||||
func (c *DashboardClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus DashboardStatus, opts resource.UpdateOptions) (*Dashboard, error) {
|
||||
return c.client.Update(ctx, &Dashboard{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: DashboardKind().Kind(),
|
||||
|
@ -84,6 +84,8 @@ func (c *DashboardClient) UpdateStatus(ctx context.Context, newStatus DashboardS
|
|||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
ResourceVersion: opts.ResourceVersion,
|
||||
Namespace: identifier.Namespace,
|
||||
Name: identifier.Name,
|
||||
},
|
||||
Status: newStatus,
|
||||
}, resource.UpdateOptions{
|
||||
|
|
|
@ -131,6 +131,8 @@ DataTopic: "series" | "annotations" | "alertStates" @cog(kind="enum",memberNames
|
|||
DataTransformerConfig: {
|
||||
// Unique identifier of transformer
|
||||
id: string
|
||||
// Unique identifier of the instance of the transformer
|
||||
refId?: string
|
||||
// Disabled transformations are skipped
|
||||
disabled?: bool
|
||||
// Optional frame matcher. When missing it will be applied to all results
|
||||
|
|
|
@ -225,6 +225,8 @@ func NewDashboardTransformationKind() *DashboardTransformationKind {
|
|||
type DashboardDataTransformerConfig struct {
|
||||
// Unique identifier of transformer
|
||||
Id string `json:"id"`
|
||||
// Unique identifier of the instance of the transformer
|
||||
RefId *string `json:"refId,omitempty"`
|
||||
// Disabled transformations are skipped
|
||||
Disabled *bool `json:"disabled,omitempty"`
|
||||
// Optional frame matcher. When missing it will be applied to all results
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/grafana/grafana-app-sdk/app"
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/kube-openapi/pkg/spec3"
|
||||
|
||||
v0alpha1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v0alpha1"
|
||||
v1beta1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v1beta1"
|
||||
|
@ -19,6 +20,8 @@ import (
|
|||
v2beta1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1"
|
||||
)
|
||||
|
||||
var ()
|
||||
|
||||
var appManifestData = app.ManifestData{
|
||||
AppName: "dashboard",
|
||||
Group: "dashboard.grafana.app",
|
||||
|
@ -34,6 +37,10 @@ var appManifestData = app.ManifestData{
|
|||
Conversion: false,
|
||||
},
|
||||
},
|
||||
Routes: app.ManifestVersionRoutes{
|
||||
Namespaced: map[string]spec3.PathProps{},
|
||||
Cluster: map[string]spec3.PathProps{},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
|
@ -47,6 +54,10 @@ var appManifestData = app.ManifestData{
|
|||
Conversion: false,
|
||||
},
|
||||
},
|
||||
Routes: app.ManifestVersionRoutes{
|
||||
Namespaced: map[string]spec3.PathProps{},
|
||||
Cluster: map[string]spec3.PathProps{},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
|
@ -60,6 +71,10 @@ var appManifestData = app.ManifestData{
|
|||
Conversion: false,
|
||||
},
|
||||
},
|
||||
Routes: app.ManifestVersionRoutes{
|
||||
Namespaced: map[string]spec3.PathProps{},
|
||||
Cluster: map[string]spec3.PathProps{},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
|
@ -73,6 +88,10 @@ var appManifestData = app.ManifestData{
|
|||
Conversion: false,
|
||||
},
|
||||
},
|
||||
Routes: app.ManifestVersionRoutes{
|
||||
Namespaced: map[string]spec3.PathProps{},
|
||||
Cluster: map[string]spec3.PathProps{},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -104,6 +123,7 @@ var customRouteToGoResponseType = map[string]any{}
|
|||
// ManifestCustomRouteResponsesAssociator returns the associated response go type for a given kind, version, custom route path, and method, if one exists.
|
||||
// kind may be empty for custom routes which are not kind subroutes. Leading slashes are removed from subroute paths.
|
||||
// If there is no association for the provided kind, version, custom route path, and method, exists will return false.
|
||||
// Resource routes (those without a kind) should prefix their route with "<namespace>/" if the route is namespaced (otherwise the route is assumed to be cluster-scope)
|
||||
func ManifestCustomRouteResponsesAssociator(kind, version, path, verb string) (goType any, exists bool) {
|
||||
if len(path) > 0 && path[0] == '/' {
|
||||
path = path[1:]
|
||||
|
@ -122,8 +142,22 @@ func ManifestCustomRouteQueryAssociator(kind, version, path, verb string) (goTyp
|
|||
return goType, exists
|
||||
}
|
||||
|
||||
var customRouteToGoRequestBodyType = map[string]any{}
|
||||
|
||||
func ManifestCustomRouteRequestBodyAssociator(kind, version, path, verb string) (goType any, exists bool) {
|
||||
if len(path) > 0 && path[0] == '/' {
|
||||
path = path[1:]
|
||||
}
|
||||
goType, exists = customRouteToGoRequestBodyType[fmt.Sprintf("%s|%s|%s|%s", version, kind, path, strings.ToUpper(verb))]
|
||||
return goType, exists
|
||||
}
|
||||
|
||||
type GoTypeAssociator struct{}
|
||||
|
||||
func NewGoTypeAssociator() *GoTypeAssociator {
|
||||
return &GoTypeAssociator{}
|
||||
}
|
||||
|
||||
func (g *GoTypeAssociator) KindToGoType(kind, version string) (goType resource.Kind, exists bool) {
|
||||
return ManifestGoTypeAssociator(kind, version)
|
||||
}
|
||||
|
@ -133,3 +167,6 @@ func (g *GoTypeAssociator) CustomRouteReturnGoType(kind, version, path, verb str
|
|||
func (g *GoTypeAssociator) CustomRouteQueryGoType(kind, version, path, verb string) (goType runtime.Object, exists bool) {
|
||||
return ManifestCustomRouteQueryAssociator(kind, version, path, verb)
|
||||
}
|
||||
func (g *GoTypeAssociator) CustomRouteRequestBodyGoType(kind, version, path, verb string) (goType any, exists bool) {
|
||||
return ManifestCustomRouteRequestBodyAssociator(kind, version, path, verb)
|
||||
}
|
||||
|
|
|
@ -512,6 +512,8 @@ lineage: schemas: [{
|
|||
#DataTransformerConfig: {
|
||||
// Unique identifier of transformer
|
||||
id: string
|
||||
// Unique identifier of the instance of the transformer
|
||||
refId?: string
|
||||
// Disabled transformations are skipped
|
||||
disabled?: bool
|
||||
// Optional frame matcher. When missing it will be applied to all results
|
||||
|
|
|
@ -746,6 +746,10 @@ export interface DataTransformerConfig {
|
|||
* Valid options depend on the transformer id
|
||||
*/
|
||||
options: unknown;
|
||||
/**
|
||||
* Unique identifier of the instance of the transformer
|
||||
*/
|
||||
refId?: string;
|
||||
/**
|
||||
* Where to pull DataFrames from as input to transformation
|
||||
*/
|
||||
|
|
|
@ -176,6 +176,8 @@ export const defaultTransformationKind = (): TransformationKind => ({
|
|||
export interface DataTransformerConfig {
|
||||
// Unique identifier of transformer
|
||||
id: string;
|
||||
// Unique identifier of the instance of the transformer
|
||||
refId?: string;
|
||||
// Disabled transformations are skipped
|
||||
disabled?: boolean;
|
||||
// Optional frame matcher. When missing it will be applied to all results
|
||||
|
|
|
@ -312,6 +312,8 @@ const DashboardLinkPlacement = "inControlsMenu"
|
|||
type DataTransformerConfig struct {
|
||||
// Unique identifier of transformer
|
||||
Id string `json:"id"`
|
||||
// Unique identifier of the instance of the transformer
|
||||
RefId *string `json:"refId,omitempty"`
|
||||
// Disabled transformations are skipped
|
||||
Disabled *bool `json:"disabled,omitempty"`
|
||||
// Optional frame matcher. When missing it will be applied to all results
|
||||
|
|
|
@ -72,7 +72,7 @@ export const QueryOperationRowHeader = ({
|
|||
// this is just to provide a better experience for mouse users
|
||||
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
|
||||
<div className={styles.titleWrapper} onClick={onRowToggle}>
|
||||
<div className={cx(styles.title, disabled && styles.disabled)}>{title}</div>
|
||||
<div className={cx(styles.title, disabled && styles.disabled)}>{title} test</div>
|
||||
</div>
|
||||
)}
|
||||
{headerElement}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable no-restricted-syntax */
|
||||
import { css } from '@emotion/css';
|
||||
import { useState } from 'react';
|
||||
import { useFormContext, useWatch } from 'react-hook-form';
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { css, cx } from '@emotion/css';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useToggle } from 'react-use';
|
||||
import { mergeMap } from 'rxjs';
|
||||
|
@ -10,11 +11,12 @@ import {
|
|||
getFrameMatchers,
|
||||
transformDataFrame,
|
||||
DataFrame,
|
||||
GrafanaTheme2,
|
||||
} from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { t } from '@grafana/i18n';
|
||||
import { t, Trans } from '@grafana/i18n';
|
||||
import { getTemplateSrv, reportInteraction } from '@grafana/runtime';
|
||||
import { ConfirmModal } from '@grafana/ui';
|
||||
import { ConfirmModal, FieldValidationMessage, Icon, Input, useStyles2 } from '@grafana/ui';
|
||||
import {
|
||||
QueryOperationAction,
|
||||
QueryOperationToggleAction,
|
||||
|
@ -48,9 +50,11 @@ export const TransformationOperationRow = ({
|
|||
uiConfig,
|
||||
onChange,
|
||||
}: TransformationOperationRowProps) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
const [showDeleteModal, setShowDeleteModal] = useToggle(false);
|
||||
const [showDebug, toggleShowDebug] = useToggle(false);
|
||||
const [showHelp, toggleShowHelp] = useToggle(false);
|
||||
const [isRefIdEditing, toggleIsRefIdEditing] = useToggle(false);
|
||||
const disabled = !!configs[index].transformation.disabled;
|
||||
const topic = configs[index].transformation.topic;
|
||||
const showFilterEditor = configs[index].transformation.filter != null || topic != null;
|
||||
|
@ -157,6 +161,45 @@ export const TransformationOperationRow = ({
|
|||
};
|
||||
}, [index, data, configs]);
|
||||
|
||||
const renderHeader = () => {
|
||||
///** <!--{validationError && <FieldValidationMessage horizontal>{validationError}</FieldValidationMessage>}-->
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
{!isRefIdEditing && (
|
||||
<button
|
||||
className={styles.queryNameWrapper}
|
||||
title={t('query.query-editor-row-header.query-name-div-title-edit-query-name', 'Edit transformation name')}
|
||||
onClick={() => toggleIsRefIdEditing()}
|
||||
data-testid="query-name-div"
|
||||
type="button"
|
||||
>
|
||||
<span className={styles.queryName}>{configs[index].refId}</span>
|
||||
<Icon name="pen" className={styles.queryEditIcon} size="sm" />
|
||||
</button>
|
||||
)}
|
||||
|
||||
{isRefIdEditing && (
|
||||
<>
|
||||
<Input
|
||||
type="text"
|
||||
defaultValue={configs[index].refId}
|
||||
//onBlur={onEditQueryBlur}
|
||||
autoFocus
|
||||
//onKeyDown={onKeyDown}
|
||||
//onFocus={onFocus}
|
||||
//invalid={validationError !== null}
|
||||
onChange={(input) => {
|
||||
onChange(index, { ...configs[index].transformation, refId: input.currentTarget.value });
|
||||
}}
|
||||
className={styles.queryNameInput}
|
||||
data-testid="query-name-input"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const renderActions = () => {
|
||||
return (
|
||||
<>
|
||||
|
@ -232,6 +275,7 @@ export const TransformationOperationRow = ({
|
|||
title={`${index + 1} - ${uiConfig.name}`}
|
||||
draggable
|
||||
actions={renderActions}
|
||||
headerElement={renderHeader}
|
||||
disabled={disabled}
|
||||
expanderMessages={{
|
||||
close: 'Collapse transformation row',
|
||||
|
@ -263,3 +307,59 @@ export const TransformationOperationRow = ({
|
|||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => {
|
||||
return {
|
||||
wrapper: css({
|
||||
label: 'Wrapper',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
marginLeft: theme.spacing(0.5),
|
||||
overflow: 'hidden',
|
||||
}),
|
||||
queryNameWrapper: css({
|
||||
display: 'flex',
|
||||
cursor: 'pointer',
|
||||
border: '1px solid transparent',
|
||||
borderRadius: theme.shape.radius.default,
|
||||
alignItems: 'center',
|
||||
padding: theme.spacing(0, 0, 0, 0.5),
|
||||
margin: 0,
|
||||
background: 'transparent',
|
||||
overflow: 'hidden',
|
||||
|
||||
'&:hover': {
|
||||
background: theme.colors.action.hover,
|
||||
border: `1px dashed ${theme.colors.border.strong}`,
|
||||
},
|
||||
|
||||
'&:focus': {
|
||||
border: `2px solid ${theme.colors.primary.border}`,
|
||||
},
|
||||
|
||||
'&:hover, &:focus': {
|
||||
'.query-name-edit-icon': {
|
||||
visibility: 'visible',
|
||||
},
|
||||
},
|
||||
}),
|
||||
queryName: css({
|
||||
fontWeight: theme.typography.fontWeightMedium,
|
||||
color: theme.colors.primary.text,
|
||||
cursor: 'pointer',
|
||||
overflow: 'hidden',
|
||||
marginLeft: theme.spacing(0.5),
|
||||
}),
|
||||
queryEditIcon: cx(
|
||||
css({
|
||||
marginLeft: theme.spacing(2),
|
||||
visibility: 'hidden',
|
||||
}),
|
||||
'query-name-edit-icon'
|
||||
),
|
||||
queryNameInput: css({
|
||||
maxWidth: '300px',
|
||||
margin: '-4px 0',
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
|
|
@ -276,6 +276,16 @@ class UnThemedTransformationsEditor extends React.PureComponent<TransformationsE
|
|||
renderTransformationEditors = () => {
|
||||
const { data, transformations } = this.state;
|
||||
|
||||
const transformationNoRefIdIdxs = transformations
|
||||
.map((t, i) => {
|
||||
return t.refId === undefined ? i : undefined;
|
||||
})
|
||||
.filter((idx) => idx !== undefined);
|
||||
|
||||
transformationNoRefIdIdxs.forEach((tIdx, i) => {
|
||||
transformations[tIdx].refId = `T-${i}`;
|
||||
});
|
||||
|
||||
return (
|
||||
<DragDropContext onDragEnd={this.onDragEnd}>
|
||||
<Droppable droppableId="transformations-list" direction="vertical">
|
||||
|
|
|
@ -2,5 +2,6 @@ import { DataTransformerConfig } from '@grafana/data';
|
|||
|
||||
export interface TransformationsEditorTransformation {
|
||||
transformation: DataTransformerConfig;
|
||||
refId?: string;
|
||||
id: string;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue