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: {
|
DataTransformerConfig: {
|
||||||
// Unique identifier of transformer
|
// Unique identifier of transformer
|
||||||
id: string
|
id: string
|
||||||
|
// Unique identifier of the instance of the transformer
|
||||||
|
refId?: string
|
||||||
// Disabled transformations are skipped
|
// Disabled transformations are skipped
|
||||||
disabled?: bool
|
disabled?: bool
|
||||||
// Optional frame matcher. When missing it will be applied to all results
|
// 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)
|
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{
|
return c.client.Update(ctx, &Dashboard{
|
||||||
TypeMeta: metav1.TypeMeta{
|
TypeMeta: metav1.TypeMeta{
|
||||||
Kind: DashboardKind().Kind(),
|
Kind: DashboardKind().Kind(),
|
||||||
|
@ -84,6 +84,8 @@ func (c *DashboardClient) UpdateStatus(ctx context.Context, newStatus DashboardS
|
||||||
},
|
},
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
ResourceVersion: opts.ResourceVersion,
|
ResourceVersion: opts.ResourceVersion,
|
||||||
|
Namespace: identifier.Namespace,
|
||||||
|
Name: identifier.Name,
|
||||||
},
|
},
|
||||||
Status: newStatus,
|
Status: newStatus,
|
||||||
}, resource.UpdateOptions{
|
}, resource.UpdateOptions{
|
||||||
|
|
|
@ -516,6 +516,8 @@ lineage: schemas: [{
|
||||||
#DataTransformerConfig: {
|
#DataTransformerConfig: {
|
||||||
// Unique identifier of transformer
|
// Unique identifier of transformer
|
||||||
id: string
|
id: string
|
||||||
|
// Unique identifier of the instance of the transformer
|
||||||
|
refId?: string
|
||||||
// Disabled transformations are skipped
|
// Disabled transformations are skipped
|
||||||
disabled?: bool
|
disabled?: bool
|
||||||
// Optional frame matcher. When missing it will be applied to all results
|
// 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)
|
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{
|
return c.client.Update(ctx, &Dashboard{
|
||||||
TypeMeta: metav1.TypeMeta{
|
TypeMeta: metav1.TypeMeta{
|
||||||
Kind: DashboardKind().Kind(),
|
Kind: DashboardKind().Kind(),
|
||||||
|
@ -84,6 +84,8 @@ func (c *DashboardClient) UpdateStatus(ctx context.Context, newStatus DashboardS
|
||||||
},
|
},
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
ResourceVersion: opts.ResourceVersion,
|
ResourceVersion: opts.ResourceVersion,
|
||||||
|
Namespace: identifier.Namespace,
|
||||||
|
Name: identifier.Name,
|
||||||
},
|
},
|
||||||
Status: newStatus,
|
Status: newStatus,
|
||||||
}, resource.UpdateOptions{
|
}, resource.UpdateOptions{
|
||||||
|
|
|
@ -516,6 +516,8 @@ lineage: schemas: [{
|
||||||
#DataTransformerConfig: {
|
#DataTransformerConfig: {
|
||||||
// Unique identifier of transformer
|
// Unique identifier of transformer
|
||||||
id: string
|
id: string
|
||||||
|
// Unique identifier of the instance of the transformer
|
||||||
|
refId?: string
|
||||||
// Disabled transformations are skipped
|
// Disabled transformations are skipped
|
||||||
disabled?: bool
|
disabled?: bool
|
||||||
// Optional frame matcher. When missing it will be applied to all results
|
// 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)
|
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{
|
return c.client.Update(ctx, &Dashboard{
|
||||||
TypeMeta: metav1.TypeMeta{
|
TypeMeta: metav1.TypeMeta{
|
||||||
Kind: DashboardKind().Kind(),
|
Kind: DashboardKind().Kind(),
|
||||||
|
@ -84,6 +84,8 @@ func (c *DashboardClient) UpdateStatus(ctx context.Context, newStatus DashboardS
|
||||||
},
|
},
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
ResourceVersion: opts.ResourceVersion,
|
ResourceVersion: opts.ResourceVersion,
|
||||||
|
Namespace: identifier.Namespace,
|
||||||
|
Name: identifier.Name,
|
||||||
},
|
},
|
||||||
Status: newStatus,
|
Status: newStatus,
|
||||||
}, resource.UpdateOptions{
|
}, resource.UpdateOptions{
|
||||||
|
|
|
@ -76,7 +76,7 @@ func (c *DashboardClient) Patch(ctx context.Context, identifier resource.Identif
|
||||||
return c.client.Patch(ctx, identifier, req, opts)
|
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{
|
return c.client.Update(ctx, &Dashboard{
|
||||||
TypeMeta: metav1.TypeMeta{
|
TypeMeta: metav1.TypeMeta{
|
||||||
Kind: DashboardKind().Kind(),
|
Kind: DashboardKind().Kind(),
|
||||||
|
@ -84,6 +84,8 @@ func (c *DashboardClient) UpdateStatus(ctx context.Context, newStatus DashboardS
|
||||||
},
|
},
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
ResourceVersion: opts.ResourceVersion,
|
ResourceVersion: opts.ResourceVersion,
|
||||||
|
Namespace: identifier.Namespace,
|
||||||
|
Name: identifier.Name,
|
||||||
},
|
},
|
||||||
Status: newStatus,
|
Status: newStatus,
|
||||||
}, resource.UpdateOptions{
|
}, resource.UpdateOptions{
|
||||||
|
|
|
@ -131,6 +131,8 @@ DataTopic: "series" | "annotations" | "alertStates" @cog(kind="enum",memberNames
|
||||||
DataTransformerConfig: {
|
DataTransformerConfig: {
|
||||||
// Unique identifier of transformer
|
// Unique identifier of transformer
|
||||||
id: string
|
id: string
|
||||||
|
// Unique identifier of the instance of the transformer
|
||||||
|
refId?: string
|
||||||
// Disabled transformations are skipped
|
// Disabled transformations are skipped
|
||||||
disabled?: bool
|
disabled?: bool
|
||||||
// Optional frame matcher. When missing it will be applied to all results
|
// Optional frame matcher. When missing it will be applied to all results
|
||||||
|
|
|
@ -225,6 +225,8 @@ func NewDashboardTransformationKind() *DashboardTransformationKind {
|
||||||
type DashboardDataTransformerConfig struct {
|
type DashboardDataTransformerConfig struct {
|
||||||
// Unique identifier of transformer
|
// Unique identifier of transformer
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
|
// Unique identifier of the instance of the transformer
|
||||||
|
RefId *string `json:"refId,omitempty"`
|
||||||
// Disabled transformations are skipped
|
// Disabled transformations are skipped
|
||||||
Disabled *bool `json:"disabled,omitempty"`
|
Disabled *bool `json:"disabled,omitempty"`
|
||||||
// Optional frame matcher. When missing it will be applied to all results
|
// 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/app"
|
||||||
"github.com/grafana/grafana-app-sdk/resource"
|
"github.com/grafana/grafana-app-sdk/resource"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/kube-openapi/pkg/spec3"
|
||||||
|
|
||||||
v0alpha1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v0alpha1"
|
v0alpha1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v0alpha1"
|
||||||
v1beta1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v1beta1"
|
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"
|
v2beta1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ()
|
||||||
|
|
||||||
var appManifestData = app.ManifestData{
|
var appManifestData = app.ManifestData{
|
||||||
AppName: "dashboard",
|
AppName: "dashboard",
|
||||||
Group: "dashboard.grafana.app",
|
Group: "dashboard.grafana.app",
|
||||||
|
@ -34,6 +37,10 @@ var appManifestData = app.ManifestData{
|
||||||
Conversion: false,
|
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,
|
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,
|
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,
|
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.
|
// 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.
|
// 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.
|
// 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) {
|
func ManifestCustomRouteResponsesAssociator(kind, version, path, verb string) (goType any, exists bool) {
|
||||||
if len(path) > 0 && path[0] == '/' {
|
if len(path) > 0 && path[0] == '/' {
|
||||||
path = path[1:]
|
path = path[1:]
|
||||||
|
@ -122,8 +142,22 @@ func ManifestCustomRouteQueryAssociator(kind, version, path, verb string) (goTyp
|
||||||
return goType, exists
|
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{}
|
type GoTypeAssociator struct{}
|
||||||
|
|
||||||
|
func NewGoTypeAssociator() *GoTypeAssociator {
|
||||||
|
return &GoTypeAssociator{}
|
||||||
|
}
|
||||||
|
|
||||||
func (g *GoTypeAssociator) KindToGoType(kind, version string) (goType resource.Kind, exists bool) {
|
func (g *GoTypeAssociator) KindToGoType(kind, version string) (goType resource.Kind, exists bool) {
|
||||||
return ManifestGoTypeAssociator(kind, version)
|
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) {
|
func (g *GoTypeAssociator) CustomRouteQueryGoType(kind, version, path, verb string) (goType runtime.Object, exists bool) {
|
||||||
return ManifestCustomRouteQueryAssociator(kind, version, path, verb)
|
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: {
|
#DataTransformerConfig: {
|
||||||
// Unique identifier of transformer
|
// Unique identifier of transformer
|
||||||
id: string
|
id: string
|
||||||
|
// Unique identifier of the instance of the transformer
|
||||||
|
refId?: string
|
||||||
// Disabled transformations are skipped
|
// Disabled transformations are skipped
|
||||||
disabled?: bool
|
disabled?: bool
|
||||||
// Optional frame matcher. When missing it will be applied to all results
|
// 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
|
* Valid options depend on the transformer id
|
||||||
*/
|
*/
|
||||||
options: unknown;
|
options: unknown;
|
||||||
|
/**
|
||||||
|
* Unique identifier of the instance of the transformer
|
||||||
|
*/
|
||||||
|
refId?: string;
|
||||||
/**
|
/**
|
||||||
* Where to pull DataFrames from as input to transformation
|
* Where to pull DataFrames from as input to transformation
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -176,6 +176,8 @@ export const defaultTransformationKind = (): TransformationKind => ({
|
||||||
export interface DataTransformerConfig {
|
export interface DataTransformerConfig {
|
||||||
// Unique identifier of transformer
|
// Unique identifier of transformer
|
||||||
id: string;
|
id: string;
|
||||||
|
// Unique identifier of the instance of the transformer
|
||||||
|
refId?: string;
|
||||||
// Disabled transformations are skipped
|
// Disabled transformations are skipped
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
// Optional frame matcher. When missing it will be applied to all results
|
// Optional frame matcher. When missing it will be applied to all results
|
||||||
|
|
|
@ -312,6 +312,8 @@ const DashboardLinkPlacement = "inControlsMenu"
|
||||||
type DataTransformerConfig struct {
|
type DataTransformerConfig struct {
|
||||||
// Unique identifier of transformer
|
// Unique identifier of transformer
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
|
// Unique identifier of the instance of the transformer
|
||||||
|
RefId *string `json:"refId,omitempty"`
|
||||||
// Disabled transformations are skipped
|
// Disabled transformations are skipped
|
||||||
Disabled *bool `json:"disabled,omitempty"`
|
Disabled *bool `json:"disabled,omitempty"`
|
||||||
// Optional frame matcher. When missing it will be applied to all results
|
// 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
|
// 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
|
// 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={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>
|
</div>
|
||||||
)}
|
)}
|
||||||
{headerElement}
|
{headerElement}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* eslint-disable no-restricted-syntax */
|
||||||
import { css } from '@emotion/css';
|
import { css } from '@emotion/css';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useFormContext, useWatch } from 'react-hook-form';
|
import { useFormContext, useWatch } from 'react-hook-form';
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { css, cx } from '@emotion/css';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { useToggle } from 'react-use';
|
import { useToggle } from 'react-use';
|
||||||
import { mergeMap } from 'rxjs';
|
import { mergeMap } from 'rxjs';
|
||||||
|
@ -10,11 +11,12 @@ import {
|
||||||
getFrameMatchers,
|
getFrameMatchers,
|
||||||
transformDataFrame,
|
transformDataFrame,
|
||||||
DataFrame,
|
DataFrame,
|
||||||
|
GrafanaTheme2,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { selectors } from '@grafana/e2e-selectors';
|
import { selectors } from '@grafana/e2e-selectors';
|
||||||
import { t } from '@grafana/i18n';
|
import { t, Trans } from '@grafana/i18n';
|
||||||
import { getTemplateSrv, reportInteraction } from '@grafana/runtime';
|
import { getTemplateSrv, reportInteraction } from '@grafana/runtime';
|
||||||
import { ConfirmModal } from '@grafana/ui';
|
import { ConfirmModal, FieldValidationMessage, Icon, Input, useStyles2 } from '@grafana/ui';
|
||||||
import {
|
import {
|
||||||
QueryOperationAction,
|
QueryOperationAction,
|
||||||
QueryOperationToggleAction,
|
QueryOperationToggleAction,
|
||||||
|
@ -48,9 +50,11 @@ export const TransformationOperationRow = ({
|
||||||
uiConfig,
|
uiConfig,
|
||||||
onChange,
|
onChange,
|
||||||
}: TransformationOperationRowProps) => {
|
}: TransformationOperationRowProps) => {
|
||||||
|
const styles = useStyles2(getStyles);
|
||||||
const [showDeleteModal, setShowDeleteModal] = useToggle(false);
|
const [showDeleteModal, setShowDeleteModal] = useToggle(false);
|
||||||
const [showDebug, toggleShowDebug] = useToggle(false);
|
const [showDebug, toggleShowDebug] = useToggle(false);
|
||||||
const [showHelp, toggleShowHelp] = useToggle(false);
|
const [showHelp, toggleShowHelp] = useToggle(false);
|
||||||
|
const [isRefIdEditing, toggleIsRefIdEditing] = useToggle(false);
|
||||||
const disabled = !!configs[index].transformation.disabled;
|
const disabled = !!configs[index].transformation.disabled;
|
||||||
const topic = configs[index].transformation.topic;
|
const topic = configs[index].transformation.topic;
|
||||||
const showFilterEditor = configs[index].transformation.filter != null || topic != null;
|
const showFilterEditor = configs[index].transformation.filter != null || topic != null;
|
||||||
|
@ -157,6 +161,45 @@ export const TransformationOperationRow = ({
|
||||||
};
|
};
|
||||||
}, [index, data, configs]);
|
}, [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 = () => {
|
const renderActions = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -232,6 +275,7 @@ export const TransformationOperationRow = ({
|
||||||
title={`${index + 1} - ${uiConfig.name}`}
|
title={`${index + 1} - ${uiConfig.name}`}
|
||||||
draggable
|
draggable
|
||||||
actions={renderActions}
|
actions={renderActions}
|
||||||
|
headerElement={renderHeader}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
expanderMessages={{
|
expanderMessages={{
|
||||||
close: 'Collapse transformation row',
|
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 = () => {
|
renderTransformationEditors = () => {
|
||||||
const { data, transformations } = this.state;
|
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 (
|
return (
|
||||||
<DragDropContext onDragEnd={this.onDragEnd}>
|
<DragDropContext onDragEnd={this.onDragEnd}>
|
||||||
<Droppable droppableId="transformations-list" direction="vertical">
|
<Droppable droppableId="transformations-list" direction="vertical">
|
||||||
|
|
|
@ -2,5 +2,6 @@ import { DataTransformerConfig } from '@grafana/data';
|
||||||
|
|
||||||
export interface TransformationsEditorTransformation {
|
export interface TransformationsEditorTransformation {
|
||||||
transformation: DataTransformerConfig;
|
transformation: DataTransformerConfig;
|
||||||
|
refId?: string;
|
||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue