Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
11fa7c69
Unverified
Commit
11fa7c69
authored
Feb 04, 2021
by
Ryan McKinley
Committed by
GitHub
Feb 04, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Transformers: add search to transform selection (#30854)
parent
48334ab8
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
132 additions
and
67 deletions
+132
-67
packages/grafana-e2e-selectors/src/selectors/components.ts
+1
-0
public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.test.tsx
+2
-2
public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.tsx
+129
-65
No files found.
packages/grafana-e2e-selectors/src/selectors/components.ts
View file @
11fa7c69
...
@@ -122,6 +122,7 @@ export const Components = {
...
@@ -122,6 +122,7 @@ export const Components = {
modeLabel
:
'Transform mode label'
,
modeLabel
:
'Transform mode label'
,
calculationsLabel
:
'Transform calculations label'
,
calculationsLabel
:
'Transform calculations label'
,
},
},
searchInput
:
'search transformations'
,
},
},
PageToolbar
:
{
PageToolbar
:
{
container
:
()
=>
'.page-toolbar'
,
container
:
()
=>
'.page-toolbar'
,
...
...
public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.test.tsx
View file @
11fa7c69
...
@@ -51,8 +51,8 @@ describe('TransformationsEditor', () => {
...
@@ -51,8 +51,8 @@ describe('TransformationsEditor', () => {
const
addTransformationButton
=
screen
.
getByText
(
buttonLabel
);
const
addTransformationButton
=
screen
.
getByText
(
buttonLabel
);
userEvent
.
click
(
addTransformationButton
);
userEvent
.
click
(
addTransformationButton
);
const
picker
=
screen
.
getByLabelText
(
selectors
.
components
.
ValuePicker
.
select
(
buttonLabel
)
);
const
search
=
screen
.
getByLabelText
(
selectors
.
components
.
Transforms
.
searchInput
);
expect
(
picker
).
toBeDefined
();
expect
(
search
).
toBeDefined
();
});
});
});
});
...
...
public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.tsx
View file @
11fa7c69
import
React
from
'react'
;
import
React
,
{
ChangeEvent
}
from
'react'
;
import
{
import
{
Alert
,
Alert
,
Button
,
Button
,
...
@@ -8,9 +8,10 @@ import {
...
@@ -8,9 +8,10 @@ import {
Themeable
,
Themeable
,
DismissableFeatureInfoBox
,
DismissableFeatureInfoBox
,
useTheme
,
useTheme
,
ValuePicker
,
VerticalGroup
,
VerticalGroup
,
withTheme
,
withTheme
,
Input
,
IconButton
,
}
from
'@grafana/ui'
;
}
from
'@grafana/ui'
;
import
{
import
{
DataFrame
,
DataFrame
,
...
@@ -40,6 +41,8 @@ interface TransformationsEditorProps extends Themeable {
...
@@ -40,6 +41,8 @@ interface TransformationsEditorProps extends Themeable {
interface
State
{
interface
State
{
data
:
DataFrame
[];
data
:
DataFrame
[];
transformations
:
TransformationsEditorTransformation
[];
transformations
:
TransformationsEditorTransformation
[];
search
:
string
;
showPicker
?:
boolean
;
}
}
class
UnThemedTransformationsEditor
extends
React
.
PureComponent
<
TransformationsEditorProps
,
State
>
{
class
UnThemedTransformationsEditor
extends
React
.
PureComponent
<
TransformationsEditorProps
,
State
>
{
...
@@ -56,9 +59,34 @@ class UnThemedTransformationsEditor extends React.PureComponent<TransformationsE
...
@@ -56,9 +59,34 @@ class UnThemedTransformationsEditor extends React.PureComponent<TransformationsE
id
:
ids
[
i
],
id
:
ids
[
i
],
})),
})),
data
:
[],
data
:
[],
search
:
''
,
};
};
}
}
onSearchChange
=
(
event
:
ChangeEvent
<
HTMLInputElement
>
)
=>
{
this
.
setState
({
search
:
event
.
target
.
value
});
};
onSearchKeyDown
=
(
event
:
React
.
KeyboardEvent
<
HTMLInputElement
>
)
=>
{
if
(
event
.
key
===
'Enter'
)
{
const
{
search
}
=
this
.
state
;
if
(
search
)
{
const
lower
=
search
.
toLowerCase
();
const
filtered
=
standardTransformersRegistry
.
list
().
filter
((
t
)
=>
{
const
txt
=
(
t
.
name
+
t
.
description
).
toLowerCase
();
return
txt
.
indexOf
(
lower
)
>=
0
;
});
if
(
filtered
.
length
>
0
)
{
this
.
onTransformationAdd
({
value
:
filtered
[
0
].
id
});
}
}
}
else
if
(
event
.
keyCode
===
27
)
{
// Escape key
this
.
setState
({
search
:
''
,
showPicker
:
false
});
event
.
stopPropagation
();
// don't exit the editor
}
};
buildTransformationIds
(
transformations
:
DataTransformerConfig
[])
{
buildTransformationIds
(
transformations
:
DataTransformerConfig
[])
{
const
transformationCounters
:
Record
<
string
,
number
>
=
{};
const
transformationCounters
:
Record
<
string
,
number
>
=
{};
const
transformationIds
:
string
[]
=
[];
const
transformationIds
:
string
[]
=
[];
...
@@ -113,6 +141,7 @@ class UnThemedTransformationsEditor extends React.PureComponent<TransformationsE
...
@@ -113,6 +141,7 @@ class UnThemedTransformationsEditor extends React.PureComponent<TransformationsE
const
{
transformations
}
=
this
.
state
;
const
{
transformations
}
=
this
.
state
;
const
nextId
=
this
.
getTransformationNextId
(
selectable
.
value
!
);
const
nextId
=
this
.
getTransformationNextId
(
selectable
.
value
!
);
this
.
setState
({
search
:
''
,
showPicker
:
false
});
this
.
onChange
([
this
.
onChange
([
...
transformations
,
...
transformations
,
{
{
...
@@ -139,33 +168,6 @@ class UnThemedTransformationsEditor extends React.PureComponent<TransformationsE
...
@@ -139,33 +168,6 @@ class UnThemedTransformationsEditor extends React.PureComponent<TransformationsE
this
.
onChange
(
next
);
this
.
onChange
(
next
);
};
};
renderTransformationSelector
=
()
=>
{
const
availableTransformers
=
standardTransformersRegistry
.
list
().
map
((
t
)
=>
{
return
{
value
:
t
.
transformation
.
id
,
label
:
t
.
name
,
description
:
t
.
description
,
};
});
return
(
<
div
className=
{
css
`
max-width: 66%;
`
}
>
<
ValuePicker
size=
"md"
variant=
"secondary"
label=
"Add transformation"
options=
{
availableTransformers
}
onChange=
{
this
.
onTransformationAdd
}
isFullWidth=
{
false
}
/>
</
div
>
);
};
onDragEnd
=
(
result
:
DropResult
)
=>
{
onDragEnd
=
(
result
:
DropResult
)
=>
{
const
{
transformations
}
=
this
.
state
;
const
{
transformations
}
=
this
.
state
;
...
@@ -208,43 +210,106 @@ class UnThemedTransformationsEditor extends React.PureComponent<TransformationsE
...
@@ -208,43 +210,106 @@ class UnThemedTransformationsEditor extends React.PureComponent<TransformationsE
);
);
};
};
renderNoAddedTransformsState
()
{
renderTransformsPicker
()
{
const
{
transformations
,
search
}
=
this
.
state
;
let
suffix
:
React
.
ReactNode
=
null
;
let
xforms
=
standardTransformersRegistry
.
list
();
if
(
search
)
{
const
lower
=
search
.
toLowerCase
();
const
filtered
=
xforms
.
filter
((
t
)
=>
{
const
txt
=
(
t
.
name
+
t
.
description
).
toLowerCase
();
return
txt
.
indexOf
(
lower
)
>=
0
;
});
suffix
=
(
<>
{
filtered
.
length
}
/
{
xforms
.
length
}
<
IconButton
name=
"times"
surface=
"header"
onClick=
{
()
=>
{
this
.
setState
({
search
:
''
});
}
}
/>
</>
);
xforms
=
filtered
;
}
const
noTransforms
=
!
transformations
?.
length
;
const
showPicker
=
noTransforms
||
this
.
state
.
showPicker
;
if
(
!
suffix
&&
showPicker
&&
!
noTransforms
)
{
suffix
=
(
<
IconButton
name=
"times"
surface=
"header"
onClick=
{
()
=>
{
this
.
setState
({
showPicker
:
false
});
}
}
/>
);
}
return
(
return
(
<>
<>
<
Container
grow=
{
1
}
>
{
noTransforms
&&
(
<
DismissableFeatureInfoBox
<
Container
grow=
{
1
}
>
title=
"Transformations"
<
DismissableFeatureInfoBox
className=
{
css
`
title=
"Transformations"
margin-bottom: ${this.props.theme.spacing.lg};
className=
{
css
`
`
}
margin-bottom: ${this.props.theme.spacing.lg};
persistenceId=
"transformationsFeaturesInfoBox"
`
}
url=
{
getDocsLink
(
DocsId
.
Transformations
)
}
persistenceId=
"transformationsFeaturesInfoBox"
url=
{
getDocsLink
(
DocsId
.
Transformations
)
}
>
<
p
>
Transformations allow you to join, calculate, re-order, hide and rename your query results before being
visualized.
<
br
/>
Many transforms are not suitable if you
'
re using the Graph visualization as it currently only
supports time series.
<
br
/>
It can help to switch to Table visualization to understand what a transformation is doing.
<
br
/>
</
p
>
</
DismissableFeatureInfoBox
>
</
Container
>
)
}
{
showPicker
?
(
<
VerticalGroup
>
<
Input
aria
-
label=
{
selectors
.
components
.
Transforms
.
searchInput
}
value=
{
search
??
''
}
autoFocus=
{
!
noTransforms
}
placeholder=
"Add transformation"
onChange=
{
this
.
onSearchChange
}
onKeyDown=
{
this
.
onSearchKeyDown
}
suffix=
{
suffix
}
/>
{
xforms
.
map
((
t
)
=>
{
return
(
<
TransformationCard
key=
{
t
.
name
}
title=
{
t
.
name
}
description=
{
t
.
description
}
actions=
{
<
Button
>
Select
</
Button
>
}
ariaLabel=
{
selectors
.
components
.
TransformTab
.
newTransform
(
t
.
name
)
}
onClick=
{
()
=>
{
this
.
onTransformationAdd
({
value
:
t
.
id
});
}
}
/>
);
})
}
</
VerticalGroup
>
)
:
(
<
Button
icon=
"plus"
variant=
"secondary"
onClick=
{
()
=>
{
this
.
setState
({
showPicker
:
true
});
}
}
>
>
<
p
>
Add transformation
Transformations allow you to join, calculate, re-order, hide and rename your query results before being
</
Button
>
visualized.
<
br
/>
)
}
Many transforms are not suitable if you
'
re using the Graph visualization as it currently only
supports time series.
<
br
/>
It can help to switch to Table visualization to understand what a transformation is doing.
<
br
/>
</
p
>
</
DismissableFeatureInfoBox
>
</
Container
>
<
VerticalGroup
>
{
standardTransformersRegistry
.
list
().
map
((
t
)
=>
{
return
(
<
TransformationCard
key=
{
t
.
name
}
title=
{
t
.
name
}
description=
{
t
.
description
}
actions=
{
<
Button
>
Select
</
Button
>
}
ariaLabel=
{
selectors
.
components
.
TransformTab
.
newTransform
(
t
.
name
)
}
onClick=
{
()
=>
{
this
.
onTransformationAdd
({
value
:
t
.
id
});
}
}
/>
);
})
}
</
VerticalGroup
>
</>
</>
);
);
}
}
...
@@ -271,9 +336,8 @@ class UnThemedTransformationsEditor extends React.PureComponent<TransformationsE
...
@@ -271,9 +336,8 @@ class UnThemedTransformationsEditor extends React.PureComponent<TransformationsE
title=
"Transformations can't be used on a panel with alerts"
title=
"Transformations can't be used on a panel with alerts"
/>
/>
)
:
null
}
)
:
null
}
{
!
hasTransforms
&&
this
.
renderNoAddedTransformsState
()
}
{
hasTransforms
&&
this
.
renderTransformationEditors
()
}
{
hasTransforms
&&
this
.
renderTransformationEditors
()
}
{
hasTransforms
&&
this
.
renderTransformationSelecto
r
()
}
{
this
.
renderTransformsPicke
r
()
}
</
div
>
</
div
>
</
Container
>
</
Container
>
</
CustomScrollbar
>
</
CustomScrollbar
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment