@grafana/scenes 3.7.0 β 3.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/dist/esm/components/layout/grid/SceneGridRow.js +6 -1
- package/dist/esm/components/layout/grid/SceneGridRow.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFilterBuilder.js +2 -2
- package/dist/esm/variables/adhoc/AdHocFilterBuilder.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFilterRenderer.js +9 -1
- package/dist/esm/variables/adhoc/AdHocFilterRenderer.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFiltersVariable.js +3 -2
- package/dist/esm/variables/adhoc/AdHocFiltersVariable.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +20 -6
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,33 @@
|
|
|
1
|
+
# v3.8.1 (Wed Feb 28 2024)
|
|
2
|
+
|
|
3
|
+
#### π Bug Fix
|
|
4
|
+
|
|
5
|
+
- Group row title and actions together on the left side [#624](https://github.com/grafana/scenes/pull/624) ([@mdvictor](https://github.com/mdvictor))
|
|
6
|
+
|
|
7
|
+
#### Authors: 1
|
|
8
|
+
|
|
9
|
+
- Victor Marin ([@mdvictor](https://github.com/mdvictor))
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# v3.8.0 (Mon Feb 26 2024)
|
|
14
|
+
|
|
15
|
+
#### π Enhancement
|
|
16
|
+
|
|
17
|
+
- AdHocFilters: Auto focus value when key is selected [#614](https://github.com/grafana/scenes/pull/614) ([@torkelo](https://github.com/torkelo) [@darrenjaneczek](https://github.com/darrenjaneczek))
|
|
18
|
+
|
|
19
|
+
#### π Bug Fix
|
|
20
|
+
|
|
21
|
+
- feat: allow label for adhoc filter add button [#619](https://github.com/grafana/scenes/pull/619) ([@darrenjaneczek](https://github.com/darrenjaneczek))
|
|
22
|
+
- fix: adhoc filter placeholder to "Select value" [#620](https://github.com/grafana/scenes/pull/620) ([@darrenjaneczek](https://github.com/darrenjaneczek))
|
|
23
|
+
|
|
24
|
+
#### Authors: 2
|
|
25
|
+
|
|
26
|
+
- Darren Janeczek ([@darrenjaneczek](https://github.com/darrenjaneczek))
|
|
27
|
+
- Torkel Γdegaard ([@torkelo](https://github.com/torkelo))
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
1
31
|
# v3.7.0 (Fri Feb 23 2024)
|
|
2
32
|
|
|
3
33
|
#### π Enhancement
|
|
@@ -69,6 +69,8 @@ function SceneGridRowRenderer({ model }) {
|
|
|
69
69
|
const layoutDragClass = model.getGridLayout().getDragClass();
|
|
70
70
|
return /* @__PURE__ */ React.createElement("div", {
|
|
71
71
|
className: cx(styles.row, isCollapsed && styles.rowCollapsed)
|
|
72
|
+
}, /* @__PURE__ */ React.createElement("div", {
|
|
73
|
+
className: styles.rowTitleAndActionsGroup
|
|
72
74
|
}, /* @__PURE__ */ React.createElement("button", {
|
|
73
75
|
onClick: model.onCollapseToggle,
|
|
74
76
|
className: styles.rowTitleButton,
|
|
@@ -80,7 +82,7 @@ function SceneGridRowRenderer({ model }) {
|
|
|
80
82
|
role: "heading"
|
|
81
83
|
}, sceneGraph.interpolate(model, title, void 0, "text"))), actions && /* @__PURE__ */ React.createElement(actions.Component, {
|
|
82
84
|
model: actions
|
|
83
|
-
}), isDraggable && isCollapsed && /* @__PURE__ */ React.createElement("div", {
|
|
85
|
+
})), isDraggable && isCollapsed && /* @__PURE__ */ React.createElement("div", {
|
|
84
86
|
className: cx(styles.dragHandle, layoutDragClass)
|
|
85
87
|
}, /* @__PURE__ */ React.createElement(Icon, {
|
|
86
88
|
name: "draggabledots"
|
|
@@ -117,6 +119,9 @@ const getSceneGridRowStyles = (theme) => {
|
|
|
117
119
|
alignItems: "center",
|
|
118
120
|
flexGrow: 1
|
|
119
121
|
}),
|
|
122
|
+
rowTitleAndActionsGroup: css({
|
|
123
|
+
display: "flex"
|
|
124
|
+
}),
|
|
120
125
|
dragHandle: css({
|
|
121
126
|
display: "flex",
|
|
122
127
|
padding: theme.spacing(0, 1),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SceneGridRow.js","sources":["../../../../../src/components/layout/grid/SceneGridRow.tsx"],"sourcesContent":["import { css, cx } from '@emotion/css';\nimport React from 'react';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { Icon, useStyles2 } from '@grafana/ui';\n\nimport { SceneObjectBase } from '../../../core/SceneObjectBase';\nimport { SceneComponentProps, SceneObject, SceneObjectUrlValues } from '../../../core/types';\n\nimport { SceneGridLayout } from './SceneGridLayout';\nimport { GRID_COLUMN_COUNT } from './constants';\nimport { SceneGridItemLike, SceneGridItemStateLike } from './types';\nimport { sceneGraph } from '../../../core/sceneGraph';\n\nexport interface SceneGridRowState extends SceneGridItemStateLike {\n title: string;\n isCollapsible?: boolean;\n isCollapsed?: boolean;\n actions?: SceneObject;\n children: SceneGridItemLike[];\n}\n\nexport class SceneGridRow extends SceneObjectBase<SceneGridRowState> {\n public static Component = SceneGridRowRenderer;\n\n public constructor(state: Partial<SceneGridRowState>) {\n super({\n children: state.children || [],\n isCollapsible: state.isCollapsible || true,\n title: state.title || '',\n ...state,\n x: 0,\n height: 1,\n width: GRID_COLUMN_COUNT,\n });\n }\n\n public getGridLayout(): SceneGridLayout {\n const layout = this.parent;\n\n if (!layout || !(layout instanceof SceneGridLayout)) {\n throw new Error('SceneGridRow must be a child of SceneGridLayout');\n }\n\n return layout;\n }\n\n public onCollapseToggle = () => {\n if (!this.state.isCollapsible) {\n return;\n }\n\n this.getGridLayout().toggleRow(this);\n };\n\n public getUrlState() {\n return { rowc: this.state.isCollapsed ? '1' : '0' };\n }\n\n public updateFromUrl(values: SceneObjectUrlValues) {\n if (values.rowc == null) {\n return;\n }\n\n if (values.rowc !== this.getUrlState().rowc) {\n this.onCollapseToggle();\n }\n }\n}\n\nexport function SceneGridRowRenderer({ model }: SceneComponentProps<SceneGridRow>) {\n const styles = useStyles2(getSceneGridRowStyles);\n const { isCollapsible, isCollapsed, title, isDraggable, actions } = model.useState();\n const layoutDragClass = model.getGridLayout().getDragClass();\n\n return (\n <div className={cx(styles.row, isCollapsed && styles.rowCollapsed)}>\n <button\n
|
|
1
|
+
{"version":3,"file":"SceneGridRow.js","sources":["../../../../../src/components/layout/grid/SceneGridRow.tsx"],"sourcesContent":["import { css, cx } from '@emotion/css';\nimport React from 'react';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { Icon, useStyles2 } from '@grafana/ui';\n\nimport { SceneObjectBase } from '../../../core/SceneObjectBase';\nimport { SceneComponentProps, SceneObject, SceneObjectUrlValues } from '../../../core/types';\n\nimport { SceneGridLayout } from './SceneGridLayout';\nimport { GRID_COLUMN_COUNT } from './constants';\nimport { SceneGridItemLike, SceneGridItemStateLike } from './types';\nimport { sceneGraph } from '../../../core/sceneGraph';\n\nexport interface SceneGridRowState extends SceneGridItemStateLike {\n title: string;\n isCollapsible?: boolean;\n isCollapsed?: boolean;\n actions?: SceneObject;\n children: SceneGridItemLike[];\n}\n\nexport class SceneGridRow extends SceneObjectBase<SceneGridRowState> {\n public static Component = SceneGridRowRenderer;\n\n public constructor(state: Partial<SceneGridRowState>) {\n super({\n children: state.children || [],\n isCollapsible: state.isCollapsible || true,\n title: state.title || '',\n ...state,\n x: 0,\n height: 1,\n width: GRID_COLUMN_COUNT,\n });\n }\n\n public getGridLayout(): SceneGridLayout {\n const layout = this.parent;\n\n if (!layout || !(layout instanceof SceneGridLayout)) {\n throw new Error('SceneGridRow must be a child of SceneGridLayout');\n }\n\n return layout;\n }\n\n public onCollapseToggle = () => {\n if (!this.state.isCollapsible) {\n return;\n }\n\n this.getGridLayout().toggleRow(this);\n };\n\n public getUrlState() {\n return { rowc: this.state.isCollapsed ? '1' : '0' };\n }\n\n public updateFromUrl(values: SceneObjectUrlValues) {\n if (values.rowc == null) {\n return;\n }\n\n if (values.rowc !== this.getUrlState().rowc) {\n this.onCollapseToggle();\n }\n }\n}\n\nexport function SceneGridRowRenderer({ model }: SceneComponentProps<SceneGridRow>) {\n const styles = useStyles2(getSceneGridRowStyles);\n const { isCollapsible, isCollapsed, title, isDraggable, actions } = model.useState();\n const layoutDragClass = model.getGridLayout().getDragClass();\n\n return (\n <div className={cx(styles.row, isCollapsed && styles.rowCollapsed)}>\n <div className={styles.rowTitleAndActionsGroup}>\n <button\n onClick={model.onCollapseToggle}\n className={styles.rowTitleButton}\n aria-label={isCollapsed ? 'Expand row' : 'Collapse row'}\n >\n {isCollapsible && <Icon name={isCollapsed ? 'angle-right' : 'angle-down'} />}\n <span className={styles.rowTitle} role=\"heading\">\n {sceneGraph.interpolate(model, title, undefined, 'text')}\n </span>\n </button>\n {actions && <actions.Component model={actions} />}\n </div>\n {isDraggable && isCollapsed && (\n <div className={cx(styles.dragHandle, layoutDragClass)}>\n <Icon name=\"draggabledots\" />\n </div>\n )}\n </div>\n );\n}\n\nexport const getSceneGridRowStyles = (theme: GrafanaTheme2) => {\n return {\n row: css({\n width: '100%',\n height: '30px',\n display: 'flex',\n justifyContent: 'space-between',\n gap: theme.spacing(1),\n }),\n rowTitleButton: css({\n display: 'flex',\n alignItems: 'center',\n cursor: 'pointer',\n background: 'transparent',\n border: 'none',\n gap: theme.spacing(1),\n }),\n rowCollapsed: css({\n borderBottom: `1px solid ${theme.colors.border.weak}`,\n }),\n rowTitle: css({\n fontSize: theme.typography.h5.fontSize,\n fontWeight: theme.typography.fontWeightMedium,\n }),\n collapsedInfo: css({\n fontSize: theme.typography.bodySmall.fontSize,\n color: theme.colors.text.secondary,\n display: 'flex',\n alignItems: 'center',\n flexGrow: 1,\n }),\n rowTitleAndActionsGroup: css({\n display: 'flex',\n }),\n dragHandle: css({\n display: 'flex',\n padding: theme.spacing(0, 1),\n alignItems: 'center',\n justifyContent: 'flex-end',\n cursor: 'move',\n color: theme.colors.text.secondary,\n '&:hover': {\n color: theme.colors.text.primary,\n },\n }),\n };\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { AdHocFilterRenderer } from './AdHocFilterRenderer.js';
|
|
3
3
|
import { Button } from '@grafana/ui';
|
|
4
4
|
|
|
5
|
-
function AdHocFilterBuilder({ model }) {
|
|
5
|
+
function AdHocFilterBuilder({ model, addFilterButtonText }) {
|
|
6
6
|
const { _wip } = model.useState();
|
|
7
7
|
if (!_wip) {
|
|
8
8
|
return /* @__PURE__ */ React.createElement(Button, {
|
|
@@ -12,7 +12,7 @@ function AdHocFilterBuilder({ model }) {
|
|
|
12
12
|
"aria-label": "Add filter",
|
|
13
13
|
"data-testid": `AdHocFilter-add`,
|
|
14
14
|
onClick: () => model._addWip()
|
|
15
|
-
});
|
|
15
|
+
}, addFilterButtonText);
|
|
16
16
|
}
|
|
17
17
|
return /* @__PURE__ */ React.createElement(AdHocFilterRenderer, {
|
|
18
18
|
filter: _wip,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdHocFilterBuilder.js","sources":["../../../../src/variables/adhoc/AdHocFilterBuilder.tsx"],"sourcesContent":["import React from 'react';\n\nimport { AdHocFilterRenderer } from './AdHocFilterRenderer';\nimport { AdHocFiltersVariable } from './AdHocFiltersVariable';\nimport { Button } from '@grafana/ui';\n\ninterface Props {\n model: AdHocFiltersVariable;\n}\n\nexport function AdHocFilterBuilder({ model }: Props) {\n const { _wip } = model.useState();\n\n if (!_wip) {\n return (\n <Button\n variant=\"secondary\"\n icon=\"plus\"\n title={'Add filter'}\n aria-label=\"Add filter\"\n data-testid={`AdHocFilter-add`}\n onClick={() => model._addWip()}\n
|
|
1
|
+
{"version":3,"file":"AdHocFilterBuilder.js","sources":["../../../../src/variables/adhoc/AdHocFilterBuilder.tsx"],"sourcesContent":["import React from 'react';\n\nimport { AdHocFilterRenderer } from './AdHocFilterRenderer';\nimport { AdHocFiltersVariable } from './AdHocFiltersVariable';\nimport { Button } from '@grafana/ui';\n\ninterface Props {\n model: AdHocFiltersVariable;\n addFilterButtonText?: string;\n}\n\nexport function AdHocFilterBuilder({ model, addFilterButtonText }: Props) {\n const { _wip } = model.useState();\n\n if (!_wip) {\n return (\n <Button\n variant=\"secondary\"\n icon=\"plus\"\n title={'Add filter'}\n aria-label=\"Add filter\"\n data-testid={`AdHocFilter-add`}\n onClick={() => model._addWip()}\n >{addFilterButtonText}</Button>\n );\n }\n\n return <AdHocFilterRenderer filter={_wip} model={model} />;\n}\n"],"names":[],"mappings":";;;;AAWO,SAAS,kBAAmB,CAAA,EAAE,KAAO,EAAA,mBAAA,EAA8B,EAAA;AACxE,EAAA,MAAM,EAAE,IAAA,EAAS,GAAA,KAAA,CAAM,QAAS,EAAA,CAAA;AAEhC,EAAA,IAAI,CAAC,IAAM,EAAA;AACT,IAAA,uBACG,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,MACC,OAAQ,EAAA,WAAA;AAAA,MACR,IAAK,EAAA,MAAA;AAAA,MACL,KAAO,EAAA,YAAA;AAAA,MACP,YAAW,EAAA,YAAA;AAAA,MACX,aAAa,EAAA,CAAA,eAAA,CAAA;AAAA,MACb,OAAA,EAAS,MAAM,KAAA,CAAM,OAAQ,EAAA;AAAA,KAAA,EAC7B,mBAAoB,CAAA,CAAA;AAAA,GAE1B;AAEA,EAAA,uBAAQ,KAAA,CAAA,aAAA,CAAA,mBAAA,EAAA;AAAA,IAAoB,MAAQ,EAAA,IAAA;AAAA,IAAM,KAAA;AAAA,GAAc,CAAA,CAAA;AAC1D;;;;"}
|
|
@@ -34,11 +34,13 @@ function AdHocFilterRenderer({ filter, model }) {
|
|
|
34
34
|
className: state.isKeysOpen ? styles.widthWhenOpen : void 0,
|
|
35
35
|
width: "auto",
|
|
36
36
|
value: valueValue,
|
|
37
|
-
placeholder: "value",
|
|
37
|
+
placeholder: "Select value",
|
|
38
38
|
options: state.values,
|
|
39
39
|
onChange: (v) => model._updateFilter(filter, "value", v.value),
|
|
40
40
|
isOpen: state.isValuesOpen,
|
|
41
41
|
isLoading: state.isValuesLoading,
|
|
42
|
+
autoFocus: filter.key !== "" && filter.value === "",
|
|
43
|
+
openMenuOnFocus: true,
|
|
42
44
|
onOpenMenu: async () => {
|
|
43
45
|
setState(__spreadProps(__spreadValues({}, state), { isValuesLoading: true }));
|
|
44
46
|
const values = await model._getValuesFor(filter);
|
|
@@ -49,6 +51,7 @@ function AdHocFilterRenderer({ filter, model }) {
|
|
|
49
51
|
}
|
|
50
52
|
});
|
|
51
53
|
const keySelect = /* @__PURE__ */ React.createElement(Select, {
|
|
54
|
+
key: `${state.isValuesLoading ? "loading" : "loaded"}`,
|
|
52
55
|
disabled: model.state.readOnly,
|
|
53
56
|
className: state.isKeysOpen ? styles.widthWhenOpen : void 0,
|
|
54
57
|
width: "auto",
|
|
@@ -67,6 +70,11 @@ function AdHocFilterRenderer({ filter, model }) {
|
|
|
67
70
|
onCloseMenu: () => {
|
|
68
71
|
setState(__spreadProps(__spreadValues({}, state), { isKeysOpen: false }));
|
|
69
72
|
},
|
|
73
|
+
onBlur: () => {
|
|
74
|
+
if (filter.key === "") {
|
|
75
|
+
model._removeFilter(filter);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
70
78
|
openMenuOnFocus: true
|
|
71
79
|
});
|
|
72
80
|
if (model.state.layout === "vertical") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdHocFilterRenderer.js","sources":["../../../../src/variables/adhoc/AdHocFilterRenderer.tsx"],"sourcesContent":["import React, { useState } from 'react';\n\nimport { AdHocFiltersVariable } from './AdHocFiltersVariable';\nimport { AdHocVariableFilter, GrafanaTheme2, SelectableValue, toOption } from '@grafana/data';\nimport { Button, Field, Select, useStyles2 } from '@grafana/ui';\nimport { css } from '@emotion/css';\nimport { ControlsLabel } from '../../utils/ControlsLabel';\n\ninterface Props {\n filter: AdHocVariableFilter;\n model: AdHocFiltersVariable;\n}\n\nexport function AdHocFilterRenderer({ filter, model }: Props) {\n const styles = useStyles2(getStyles);\n\n // there's a bug in react-select where the menu doesn't recalculate its position when the options are loaded asynchronously\n // see https://github.com/grafana/grafana/issues/63558\n // instead, we explicitly control the menu visibility and prevent showing it until the options have fully loaded\n\n const [state, setState] = useState<{\n keys?: SelectableValue[];\n values?: SelectableValue[];\n isKeysLoading?: boolean;\n isValuesLoading?: boolean;\n isKeysOpen?: boolean;\n isValuesOpen?: boolean;\n }>({});\n\n const keyValue = filter.key !== '' ? toOption(filter.key) : null;\n const valueValue = filter.value !== '' ? toOption(filter.value) : null;\n\n const valueSelect = (\n <Select\n disabled={model.state.readOnly}\n className={state.isKeysOpen ? styles.widthWhenOpen : undefined}\n width=\"auto\"\n value={valueValue}\n placeholder={'value'}\n options={state.values}\n onChange={(v) => model._updateFilter(filter, 'value', v.value)}\n isOpen={state.isValuesOpen}\n isLoading={state.isValuesLoading}\n onOpenMenu={async () => {\n setState({ ...state, isValuesLoading: true });\n const values = await model._getValuesFor(filter);\n setState({ ...state, isValuesLoading: false, isValuesOpen: true, values });\n }}\n onCloseMenu={() => {\n setState({ ...state, isValuesOpen: false });\n }}\n />\n );\n\n const keySelect = (\n <Select\n disabled={model.state.readOnly}\n className={state.isKeysOpen ? styles.widthWhenOpen : undefined}\n width=\"auto\"\n value={keyValue}\n placeholder={'Select label'}\n options={state.keys}\n onChange={(v) => model._updateFilter(filter, 'key', v.value)}\n autoFocus={filter.key === ''}\n isOpen={state.isKeysOpen}\n isLoading={state.isKeysLoading}\n onOpenMenu={async () => {\n setState({ ...state, isKeysLoading: true });\n const keys = await model._getKeys(filter.key);\n setState({ ...state, isKeysLoading: false, isKeysOpen: true, keys });\n }}\n onCloseMenu={() => {\n setState({ ...state, isKeysOpen: false });\n }}\n openMenuOnFocus={true}\n />\n );\n\n if (model.state.layout === 'vertical') {\n if (filter.key) {\n const label = (\n <ControlsLabel layout=\"vertical\" label={filter.key ?? ''} onRemove={() => model._removeFilter(filter)} />\n );\n\n return (\n <Field label={label} data-testid={`AdHocFilter-${filter.key}`} className={styles.field}>\n {valueSelect}\n </Field>\n );\n } else {\n return (\n <Field label={'Select label'} data-testid={`AdHocFilter-${filter.key}`} className={styles.field}>\n {keySelect}\n </Field>\n );\n }\n }\n\n return (\n <div className={styles.wrapper} data-testid={`AdHocFilter-${filter.key}`}>\n {keySelect}\n <Select\n value={filter.operator}\n disabled={model.state.readOnly}\n options={model._getOperators()}\n width=\"auto\"\n onChange={(v) => model._updateFilter(filter, 'operator', v.value)}\n />\n {valueSelect}\n <Button\n variant=\"secondary\"\n aria-label=\"Remove filter\"\n title=\"Remove filter\"\n className={styles.removeButton}\n icon=\"times\"\n data-testid={`AdHocFilter-remove-${filter.key ?? ''}`}\n onClick={() => model._removeFilter(filter)}\n />\n </div>\n );\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n field: css({\n marginBottom: 0,\n }),\n wrapper: css({\n display: 'flex',\n '> *': {\n '&:not(:first-child)': {\n // Negative margin hides the double-border on adjacent selects\n marginLeft: -1,\n },\n\n '&:first-child': {\n borderTopRightRadius: 0,\n borderBottomRightRadius: 0,\n },\n\n '&:last-child': {\n borderTopLeftRadius: 0,\n borderBottomLeftRadius: 0,\n },\n\n '&:not(:first-child):not(:last-child)': {\n borderRadius: 0,\n },\n\n // Fix focus state zIndex issues\n position: 'relative',\n zIndex: 0,\n\n // Adjacent borders are overlapping, so raise children up when hovering etc\n // so all that child's borders are visible.\n '&:hover': {\n zIndex: 1,\n },\n\n '&:focus-within': {\n zIndex: 2,\n },\n },\n }),\n widthWhenOpen: css({\n minWidth: theme.spacing(16),\n }),\n removeButton: css({\n paddingLeft: theme.spacing(3 / 2),\n paddingRight: theme.spacing(3 / 2),\n borderLeft: 'none',\n // To not have button background and last select border intersect\n position: 'relative',\n left: '1px',\n }),\n});\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AdHocFilterRenderer.js","sources":["../../../../src/variables/adhoc/AdHocFilterRenderer.tsx"],"sourcesContent":["import React, { useState } from 'react';\n\nimport { AdHocFiltersVariable } from './AdHocFiltersVariable';\nimport { AdHocVariableFilter, GrafanaTheme2, SelectableValue, toOption } from '@grafana/data';\nimport { Button, Field, Select, useStyles2 } from '@grafana/ui';\nimport { css } from '@emotion/css';\nimport { ControlsLabel } from '../../utils/ControlsLabel';\n\ninterface Props {\n filter: AdHocVariableFilter;\n model: AdHocFiltersVariable;\n}\n\nexport function AdHocFilterRenderer({ filter, model }: Props) {\n const styles = useStyles2(getStyles);\n\n // there's a bug in react-select where the menu doesn't recalculate its position when the options are loaded asynchronously\n // see https://github.com/grafana/grafana/issues/63558\n // instead, we explicitly control the menu visibility and prevent showing it until the options have fully loaded\n\n const [state, setState] = useState<{\n keys?: SelectableValue[];\n values?: SelectableValue[];\n isKeysLoading?: boolean;\n isValuesLoading?: boolean;\n isKeysOpen?: boolean;\n isValuesOpen?: boolean;\n }>({});\n\n const keyValue = filter.key !== '' ? toOption(filter.key) : null;\n const valueValue = filter.value !== '' ? toOption(filter.value) : null;\n\n const valueSelect = (\n <Select\n disabled={model.state.readOnly}\n className={state.isKeysOpen ? styles.widthWhenOpen : undefined}\n width=\"auto\"\n value={valueValue}\n placeholder={'Select value'}\n options={state.values}\n onChange={(v) => model._updateFilter(filter, 'value', v.value)}\n isOpen={state.isValuesOpen}\n isLoading={state.isValuesLoading}\n autoFocus={filter.key !== '' && filter.value === ''}\n openMenuOnFocus={true}\n onOpenMenu={async () => {\n setState({ ...state, isValuesLoading: true });\n const values = await model._getValuesFor(filter);\n setState({ ...state, isValuesLoading: false, isValuesOpen: true, values });\n }}\n onCloseMenu={() => {\n setState({ ...state, isValuesOpen: false });\n }}\n />\n );\n\n const keySelect = (\n <Select\n // By changing the key, we reset the Select component,\n // to ensure that the loaded values are shown after they are loaded\n key={`${state.isValuesLoading ? 'loading' : 'loaded'}`}\n disabled={model.state.readOnly}\n className={state.isKeysOpen ? styles.widthWhenOpen : undefined}\n width=\"auto\"\n value={keyValue}\n placeholder={'Select label'}\n options={state.keys}\n onChange={(v) => model._updateFilter(filter, 'key', v.value)}\n autoFocus={filter.key === ''}\n isOpen={state.isKeysOpen}\n isLoading={state.isKeysLoading}\n onOpenMenu={async () => {\n setState({ ...state, isKeysLoading: true });\n const keys = await model._getKeys(filter.key);\n setState({ ...state, isKeysLoading: false, isKeysOpen: true, keys });\n }}\n onCloseMenu={() => {\n setState({ ...state, isKeysOpen: false });\n }}\n onBlur={() => {\n if (filter.key === '') {\n model._removeFilter(filter);\n }\n }}\n openMenuOnFocus={true}\n />\n );\n\n if (model.state.layout === 'vertical') {\n if (filter.key) {\n const label = (\n <ControlsLabel layout=\"vertical\" label={filter.key ?? ''} onRemove={() => model._removeFilter(filter)} />\n );\n\n return (\n <Field label={label} data-testid={`AdHocFilter-${filter.key}`} className={styles.field}>\n {valueSelect}\n </Field>\n );\n } else {\n return (\n <Field label={'Select label'} data-testid={`AdHocFilter-${filter.key}`} className={styles.field}>\n {keySelect}\n </Field>\n );\n }\n }\n\n return (\n <div className={styles.wrapper} data-testid={`AdHocFilter-${filter.key}`}>\n {keySelect}\n <Select\n value={filter.operator}\n disabled={model.state.readOnly}\n options={model._getOperators()}\n width=\"auto\"\n onChange={(v) => model._updateFilter(filter, 'operator', v.value)}\n />\n {valueSelect}\n <Button\n variant=\"secondary\"\n aria-label=\"Remove filter\"\n title=\"Remove filter\"\n className={styles.removeButton}\n icon=\"times\"\n data-testid={`AdHocFilter-remove-${filter.key ?? ''}`}\n onClick={() => model._removeFilter(filter)}\n />\n </div>\n );\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n field: css({\n marginBottom: 0,\n }),\n wrapper: css({\n display: 'flex',\n '> *': {\n '&:not(:first-child)': {\n // Negative margin hides the double-border on adjacent selects\n marginLeft: -1,\n },\n\n '&:first-child': {\n borderTopRightRadius: 0,\n borderBottomRightRadius: 0,\n },\n\n '&:last-child': {\n borderTopLeftRadius: 0,\n borderBottomLeftRadius: 0,\n },\n\n '&:not(:first-child):not(:last-child)': {\n borderRadius: 0,\n },\n\n // Fix focus state zIndex issues\n position: 'relative',\n zIndex: 0,\n\n // Adjacent borders are overlapping, so raise children up when hovering etc\n // so all that child's borders are visible.\n '&:hover': {\n zIndex: 1,\n },\n\n '&:focus-within': {\n zIndex: 2,\n },\n },\n }),\n widthWhenOpen: css({\n minWidth: theme.spacing(16),\n }),\n removeButton: css({\n paddingLeft: theme.spacing(3 / 2),\n paddingRight: theme.spacing(3 / 2),\n borderLeft: 'none',\n // To not have button background and last select border intersect\n position: 'relative',\n left: '1px',\n }),\n});\n"],"names":[],"mappings":"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"}
|
|
@@ -174,7 +174,7 @@ function renderExpression(state) {
|
|
|
174
174
|
return ((_a = state.expressionBuilder) != null ? _a : renderPrometheusLabelFilters)((_b = state.filters) != null ? _b : []);
|
|
175
175
|
}
|
|
176
176
|
function AdHocFiltersVariableRenderer({ model }) {
|
|
177
|
-
const { filters, readOnly } = model.useState();
|
|
177
|
+
const { filters, readOnly, addFilterButtonText } = model.useState();
|
|
178
178
|
const styles = useStyles2(getStyles);
|
|
179
179
|
return /* @__PURE__ */ React.createElement("div", {
|
|
180
180
|
className: styles.wrapper
|
|
@@ -185,7 +185,8 @@ function AdHocFiltersVariableRenderer({ model }) {
|
|
|
185
185
|
model
|
|
186
186
|
}))), !readOnly && /* @__PURE__ */ React.createElement(AdHocFilterBuilder, {
|
|
187
187
|
model,
|
|
188
|
-
key: "'builder"
|
|
188
|
+
key: "'builder",
|
|
189
|
+
addFilterButtonText
|
|
189
190
|
}));
|
|
190
191
|
}
|
|
191
192
|
const getStyles = (theme) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdHocFiltersVariable.js","sources":["../../../../src/variables/adhoc/AdHocFiltersVariable.tsx"],"sourcesContent":["import React from 'react';\nimport { AdHocVariableFilter, GrafanaTheme2, MetricFindValue, SelectableValue } from '@grafana/data';\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { SceneVariable, SceneVariableState, SceneVariableValueChangedEvent, VariableValue } from '../types';\nimport { ControlsLayout, SceneComponentProps } from '../../core/types';\nimport { DataSourceRef } from '@grafana/schema';\nimport { renderPrometheusLabelFilters } from '../utils';\nimport { patchGetAdhocFilters } from './patchGetAdhocFilters';\nimport { useStyles2 } from '@grafana/ui';\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { DataQueryExtended, SceneQueryRunner } from '../../querying/SceneQueryRunner';\nimport { AdHocFilterBuilder } from './AdHocFilterBuilder';\nimport { AdHocFilterRenderer } from './AdHocFilterRenderer';\nimport { getDataSourceSrv } from '@grafana/runtime';\nimport { AdHocFiltersVariableUrlSyncHandler } from './AdHocFiltersVariableUrlSyncHandler';\nimport { css } from '@emotion/css';\n\nexport interface AdHocFiltersVariableState extends SceneVariableState {\n /** The visible filters */\n filters: AdHocVariableFilter[];\n /** Base filters to always apply when looking up keys*/\n baseFilters?: AdHocVariableFilter[];\n /** Datasource to use for getTagKeys and getTagValues and also controls which scene queries the filters should apply to */\n datasource: DataSourceRef | null;\n /** Controls if the filters can be changed */\n readOnly?: boolean;\n /**\n * @experimental\n * Controls the layout and design of the label.\n * Vertical layout does not yet support operator selector.\n */\n layout?: ControlsLayout;\n /**\n * Defaults to automatic which means filters will automatically be applied to all queries with the same data source as this AdHocFilterSet.\n * In manual mode you either have to use the filters programmatically or as a variable inside query expressions.\n */\n applyMode: 'auto' | 'manual';\n /**\n * Filter out the keys that do not match the regex.\n */\n tagKeyRegexFilter?: RegExp;\n /**\n * Extension hook for customizing the key lookup.\n * Return replace: true if you want to override the default lookup\n * Return replace: false if you want to combine the results with the default lookup\n */\n getTagKeysProvider?: getTagKeysProvider;\n /**\n * Extension hook for customizing the value lookup.\n * Return replace: true if you want to override the default lookup.\n * Return replace: false if you want to combine the results with the default lookup\n */\n getTagValuesProvider?: getTagValuesProvider;\n\n /**\n * This is the expression that the filters resulted in. Defaults to\n * Prometheus / Loki compatible label filter expression\n */\n filterExpression?: string;\n\n /**\n * The default builder creates a Prometheus/Loki compatible filter expression,\n * this can be overridden to create a different expression based on the current filters.\n */\n expressionBuilder?: (filters: AdHocVariableFilter[]) => string;\n\n /**\n * @internal state of the new filter being added\n */\n _wip?: AdHocVariableFilter;\n}\n\nexport type getTagKeysProvider = (\n variable: AdHocFiltersVariable,\n currentKey: string | null\n) => Promise<{ replace?: boolean; values: MetricFindValue[] }>;\n\nexport type getTagValuesProvider = (\n variable: AdHocFiltersVariable,\n filter: AdHocVariableFilter\n) => Promise<{ replace?: boolean; values: MetricFindValue[] }>;\n\nexport type AdHocFiltersVariableCreateHelperArgs = AdHocFiltersVariableState;\n\nexport class AdHocFiltersVariable\n extends SceneObjectBase<AdHocFiltersVariableState>\n implements SceneVariable<AdHocFiltersVariableState>\n{\n static Component = AdHocFiltersVariableRenderer;\n\n private _scopedVars = { __sceneObject: { value: this } };\n private _dataSourceSrv = getDataSourceSrv();\n\n protected _urlSync = new AdHocFiltersVariableUrlSyncHandler(this);\n\n public constructor(state: Partial<AdHocFiltersVariableState>) {\n super({\n type: 'adhoc',\n name: state.name ?? 'Filters',\n filters: [],\n datasource: null,\n applyMode: 'auto',\n filterExpression: state.filterExpression ?? renderExpression(state),\n ...state,\n });\n\n if (this.state.applyMode === 'auto') {\n patchGetAdhocFilters(this);\n }\n\n // Subscribe to filter changes and up the variable value (filterExpression)\n this.addActivationHandler(() => {\n this._subs.add(\n this.subscribeToState((newState, prevState) => {\n if (newState.filters !== prevState.filters) {\n this._updateFilterExpression(newState, true);\n }\n })\n );\n\n this._updateFilterExpression(this.state, false);\n });\n }\n\n public getValue(): VariableValue | undefined {\n return this.state.filterExpression;\n }\n\n private _updateFilterExpression(state: Partial<AdHocFiltersVariableState>, publishEvent: boolean) {\n let expr = renderExpression(state);\n\n if (expr === this.state.filterExpression) {\n return;\n }\n\n this.setState({ filterExpression: expr });\n\n if (publishEvent) {\n this.publishEvent(new SceneVariableValueChangedEvent(this), true);\n }\n }\n\n public _updateFilter(filter: AdHocVariableFilter, prop: keyof AdHocVariableFilter, value: string | undefined | null) {\n if (value == null) {\n return;\n }\n\n const { filters, _wip } = this.state;\n\n if (filter === _wip) {\n // If we set value we are done with this \"work in progress\" filter and we can add it\n if (prop === 'value') {\n this.setState({ filters: [...filters, { ..._wip, [prop]: value }], _wip: undefined });\n } else {\n this.setState({ _wip: { ...filter, [prop]: value } });\n }\n return;\n }\n\n const updatedFilters = this.state.filters.map((f) => {\n if (f === filter) {\n return { ...f, [prop]: value };\n }\n return f;\n });\n\n this.setState({ filters: updatedFilters });\n }\n\n public _removeFilter(filter: AdHocVariableFilter) {\n if (filter === this.state._wip) {\n this.setState({ _wip: undefined });\n return;\n }\n\n this.setState({ filters: this.state.filters.filter((f) => f !== filter) });\n }\n\n /**\n * Get possible keys given current filters. Do not call from plugins directly\n */\n public async _getKeys(currentKey: string | null): Promise<Array<SelectableValue<string>>> {\n const override = await this.state.getTagKeysProvider?.(this, currentKey);\n\n if (override && override.replace) {\n return override.values.map(toSelectableValue);\n }\n\n const ds = await this._dataSourceSrv.get(this.state.datasource, this._scopedVars);\n if (!ds || !ds.getTagKeys) {\n return [];\n }\n\n const otherFilters = this.state.filters.filter((f) => f.key !== currentKey).concat(this.state.baseFilters ?? []);\n const queries = this._getSceneQueries();\n // @ts-expect-error TODO: remove this once 10.4.0 is released\n let keys = await ds.getTagKeys({ filters: otherFilters, queries });\n\n if (override) {\n keys = keys.concat(override.values);\n }\n\n const tagKeyRegexFilter = this.state.tagKeyRegexFilter;\n if (tagKeyRegexFilter) {\n keys = keys.filter((f) => f.text.match(tagKeyRegexFilter));\n }\n\n return keys.map(toSelectableValue);\n }\n\n /**\n * Get possible key values for a specific key given current filters. Do not call from plugins directly\n */\n public async _getValuesFor(filter: AdHocVariableFilter): Promise<Array<SelectableValue<string>>> {\n const override = await this.state.getTagValuesProvider?.(this, filter);\n\n if (override && override.replace) {\n return override.values.map(toSelectableValue);\n }\n\n const ds = await this._dataSourceSrv.get(this.state.datasource, this._scopedVars);\n\n if (!ds || !ds.getTagValues) {\n return [];\n }\n\n // Filter out the current filter key from the list of all filters\n const otherFilters = this.state.filters.filter((f) => f.key !== filter.key).concat(this.state.baseFilters ?? []);\n\n const timeRange = sceneGraph.getTimeRange(this).state.value;\n let values = await ds.getTagValues({ key: filter.key, filters: otherFilters, timeRange });\n\n if (override) {\n values = values.concat(override.values);\n }\n\n return values.map(toSelectableValue);\n }\n\n public _addWip() {\n this.setState({ _wip: { key: '', value: '', operator: '=', condition: '' } });\n }\n\n public _getOperators() {\n return ['=', '!=', '<', '>', '=~', '!~'].map<SelectableValue<string>>((value) => ({\n label: value,\n value,\n }));\n }\n\n /**\n * Get all queries in the scene that have the same datasource as this AdHocFilterSet\n */\n private _getSceneQueries(): DataQueryExtended[] {\n const runners = sceneGraph.findAllObjects(\n this.getRoot(),\n (o) => o instanceof SceneQueryRunner\n ) as SceneQueryRunner[];\n\n const applicableRunners = runners.filter((r) => r.state.datasource?.uid === this.state.datasource?.uid);\n\n if (applicableRunners.length === 0) {\n return [];\n }\n\n const result: DataQueryExtended[] = [];\n applicableRunners.forEach((r) => {\n result.push(...r.state.queries);\n });\n\n return result;\n }\n}\n\nfunction renderExpression(state: Partial<AdHocFiltersVariableState>) {\n return (state.expressionBuilder ?? renderPrometheusLabelFilters)(state.filters ?? []);\n}\n\nexport function AdHocFiltersVariableRenderer({ model }: SceneComponentProps<AdHocFiltersVariable>) {\n const { filters, readOnly } = model.useState();\n const styles = useStyles2(getStyles);\n\n return (\n <div className={styles.wrapper}>\n {filters.map((filter, index) => (\n <React.Fragment key={index}>\n <AdHocFilterRenderer filter={filter} model={model} />\n </React.Fragment>\n ))}\n\n {!readOnly && <AdHocFilterBuilder model={model} key=\"'builder\" />}\n </div>\n );\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n wrapper: css({\n display: 'flex',\n gap: theme.spacing(2),\n alignItems: 'flex-end',\n }),\n filterIcon: css({\n color: theme.colors.text.secondary,\n paddingRight: theme.spacing(0.5),\n }),\n});\n\nfunction toSelectableValue({ text, value }: MetricFindValue): SelectableValue<string> {\n return {\n label: text,\n value: String(value ?? text),\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AdHocFiltersVariable.js","sources":["../../../../src/variables/adhoc/AdHocFiltersVariable.tsx"],"sourcesContent":["import React from 'react';\nimport { AdHocVariableFilter, GrafanaTheme2, MetricFindValue, SelectableValue } from '@grafana/data';\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { SceneVariable, SceneVariableState, SceneVariableValueChangedEvent, VariableValue } from '../types';\nimport { ControlsLayout, SceneComponentProps } from '../../core/types';\nimport { DataSourceRef } from '@grafana/schema';\nimport { renderPrometheusLabelFilters } from '../utils';\nimport { patchGetAdhocFilters } from './patchGetAdhocFilters';\nimport { useStyles2 } from '@grafana/ui';\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { DataQueryExtended, SceneQueryRunner } from '../../querying/SceneQueryRunner';\nimport { AdHocFilterBuilder } from './AdHocFilterBuilder';\nimport { AdHocFilterRenderer } from './AdHocFilterRenderer';\nimport { getDataSourceSrv } from '@grafana/runtime';\nimport { AdHocFiltersVariableUrlSyncHandler } from './AdHocFiltersVariableUrlSyncHandler';\nimport { css } from '@emotion/css';\n\nexport interface AdHocFiltersVariableState extends SceneVariableState {\n /** Optional text to display on the 'add filter' button */\n addFilterButtonText?: string;\n /** The visible filters */\n filters: AdHocVariableFilter[];\n /** Base filters to always apply when looking up keys*/\n baseFilters?: AdHocVariableFilter[];\n /** Datasource to use for getTagKeys and getTagValues and also controls which scene queries the filters should apply to */\n datasource: DataSourceRef | null;\n /** Controls if the filters can be changed */\n readOnly?: boolean;\n /**\n * @experimental\n * Controls the layout and design of the label.\n * Vertical layout does not yet support operator selector.\n */\n layout?: ControlsLayout;\n /**\n * Defaults to automatic which means filters will automatically be applied to all queries with the same data source as this AdHocFilterSet.\n * In manual mode you either have to use the filters programmatically or as a variable inside query expressions.\n */\n applyMode: 'auto' | 'manual';\n /**\n * Filter out the keys that do not match the regex.\n */\n tagKeyRegexFilter?: RegExp;\n /**\n * Extension hook for customizing the key lookup.\n * Return replace: true if you want to override the default lookup\n * Return replace: false if you want to combine the results with the default lookup\n */\n getTagKeysProvider?: getTagKeysProvider;\n /**\n * Extension hook for customizing the value lookup.\n * Return replace: true if you want to override the default lookup.\n * Return replace: false if you want to combine the results with the default lookup\n */\n getTagValuesProvider?: getTagValuesProvider;\n\n /**\n * This is the expression that the filters resulted in. Defaults to\n * Prometheus / Loki compatible label filter expression\n */\n filterExpression?: string;\n\n /**\n * The default builder creates a Prometheus/Loki compatible filter expression,\n * this can be overridden to create a different expression based on the current filters.\n */\n expressionBuilder?: (filters: AdHocVariableFilter[]) => string;\n\n /**\n * @internal state of the new filter being added\n */\n _wip?: AdHocVariableFilter;\n}\n\nexport type getTagKeysProvider = (\n variable: AdHocFiltersVariable,\n currentKey: string | null\n) => Promise<{ replace?: boolean; values: MetricFindValue[] }>;\n\nexport type getTagValuesProvider = (\n variable: AdHocFiltersVariable,\n filter: AdHocVariableFilter\n) => Promise<{ replace?: boolean; values: MetricFindValue[] }>;\n\nexport type AdHocFiltersVariableCreateHelperArgs = AdHocFiltersVariableState;\n\nexport class AdHocFiltersVariable\n extends SceneObjectBase<AdHocFiltersVariableState>\n implements SceneVariable<AdHocFiltersVariableState>\n{\n static Component = AdHocFiltersVariableRenderer;\n\n private _scopedVars = { __sceneObject: { value: this } };\n private _dataSourceSrv = getDataSourceSrv();\n\n protected _urlSync = new AdHocFiltersVariableUrlSyncHandler(this);\n\n public constructor(state: Partial<AdHocFiltersVariableState>) {\n super({\n type: 'adhoc',\n name: state.name ?? 'Filters',\n filters: [],\n datasource: null,\n applyMode: 'auto',\n filterExpression: state.filterExpression ?? renderExpression(state),\n ...state,\n });\n\n if (this.state.applyMode === 'auto') {\n patchGetAdhocFilters(this);\n }\n\n // Subscribe to filter changes and up the variable value (filterExpression)\n this.addActivationHandler(() => {\n this._subs.add(\n this.subscribeToState((newState, prevState) => {\n if (newState.filters !== prevState.filters) {\n this._updateFilterExpression(newState, true);\n }\n })\n );\n\n this._updateFilterExpression(this.state, false);\n });\n }\n\n public getValue(): VariableValue | undefined {\n return this.state.filterExpression;\n }\n\n private _updateFilterExpression(state: Partial<AdHocFiltersVariableState>, publishEvent: boolean) {\n let expr = renderExpression(state);\n\n if (expr === this.state.filterExpression) {\n return;\n }\n\n this.setState({ filterExpression: expr });\n\n if (publishEvent) {\n this.publishEvent(new SceneVariableValueChangedEvent(this), true);\n }\n }\n\n public _updateFilter(filter: AdHocVariableFilter, prop: keyof AdHocVariableFilter, value: string | undefined | null) {\n if (value == null) {\n return;\n }\n\n const { filters, _wip } = this.state;\n\n if (filter === _wip) {\n // If we set value we are done with this \"work in progress\" filter and we can add it\n if (prop === 'value') {\n this.setState({ filters: [...filters, { ..._wip, [prop]: value }], _wip: undefined });\n } else {\n this.setState({ _wip: { ...filter, [prop]: value } });\n }\n return;\n }\n\n const updatedFilters = this.state.filters.map((f) => {\n if (f === filter) {\n return { ...f, [prop]: value };\n }\n return f;\n });\n\n this.setState({ filters: updatedFilters });\n }\n\n public _removeFilter(filter: AdHocVariableFilter) {\n if (filter === this.state._wip) {\n this.setState({ _wip: undefined });\n return;\n }\n\n this.setState({ filters: this.state.filters.filter((f) => f !== filter) });\n }\n\n /**\n * Get possible keys given current filters. Do not call from plugins directly\n */\n public async _getKeys(currentKey: string | null): Promise<Array<SelectableValue<string>>> {\n const override = await this.state.getTagKeysProvider?.(this, currentKey);\n\n if (override && override.replace) {\n return override.values.map(toSelectableValue);\n }\n\n const ds = await this._dataSourceSrv.get(this.state.datasource, this._scopedVars);\n if (!ds || !ds.getTagKeys) {\n return [];\n }\n\n const otherFilters = this.state.filters.filter((f) => f.key !== currentKey).concat(this.state.baseFilters ?? []);\n const queries = this._getSceneQueries();\n // @ts-expect-error TODO: remove this once 10.4.0 is released\n let keys = await ds.getTagKeys({ filters: otherFilters, queries });\n\n if (override) {\n keys = keys.concat(override.values);\n }\n\n const tagKeyRegexFilter = this.state.tagKeyRegexFilter;\n if (tagKeyRegexFilter) {\n keys = keys.filter((f) => f.text.match(tagKeyRegexFilter));\n }\n\n return keys.map(toSelectableValue);\n }\n\n /**\n * Get possible key values for a specific key given current filters. Do not call from plugins directly\n */\n public async _getValuesFor(filter: AdHocVariableFilter): Promise<Array<SelectableValue<string>>> {\n const override = await this.state.getTagValuesProvider?.(this, filter);\n\n if (override && override.replace) {\n return override.values.map(toSelectableValue);\n }\n\n const ds = await this._dataSourceSrv.get(this.state.datasource, this._scopedVars);\n\n if (!ds || !ds.getTagValues) {\n return [];\n }\n\n // Filter out the current filter key from the list of all filters\n const otherFilters = this.state.filters.filter((f) => f.key !== filter.key).concat(this.state.baseFilters ?? []);\n\n const timeRange = sceneGraph.getTimeRange(this).state.value;\n let values = await ds.getTagValues({ key: filter.key, filters: otherFilters, timeRange });\n\n if (override) {\n values = values.concat(override.values);\n }\n\n return values.map(toSelectableValue);\n }\n\n public _addWip() {\n this.setState({ _wip: { key: '', value: '', operator: '=', condition: '' } });\n }\n\n public _getOperators() {\n return ['=', '!=', '<', '>', '=~', '!~'].map<SelectableValue<string>>((value) => ({\n label: value,\n value,\n }));\n }\n\n /**\n * Get all queries in the scene that have the same datasource as this AdHocFilterSet\n */\n private _getSceneQueries(): DataQueryExtended[] {\n const runners = sceneGraph.findAllObjects(\n this.getRoot(),\n (o) => o instanceof SceneQueryRunner\n ) as SceneQueryRunner[];\n\n const applicableRunners = runners.filter((r) => r.state.datasource?.uid === this.state.datasource?.uid);\n\n if (applicableRunners.length === 0) {\n return [];\n }\n\n const result: DataQueryExtended[] = [];\n applicableRunners.forEach((r) => {\n result.push(...r.state.queries);\n });\n\n return result;\n }\n}\n\nfunction renderExpression(state: Partial<AdHocFiltersVariableState>) {\n return (state.expressionBuilder ?? renderPrometheusLabelFilters)(state.filters ?? []);\n}\n\nexport function AdHocFiltersVariableRenderer({ model }: SceneComponentProps<AdHocFiltersVariable>) {\n const { filters, readOnly, addFilterButtonText } = model.useState();\n const styles = useStyles2(getStyles);\n\n return (\n <div className={styles.wrapper}>\n {filters.map((filter, index) => (\n <React.Fragment key={index}>\n <AdHocFilterRenderer filter={filter} model={model} />\n </React.Fragment>\n ))}\n\n {!readOnly && <AdHocFilterBuilder model={model} key=\"'builder\" addFilterButtonText={addFilterButtonText}/>}\n </div>\n );\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n wrapper: css({\n display: 'flex',\n gap: theme.spacing(2),\n alignItems: 'flex-end',\n }),\n filterIcon: css({\n color: theme.colors.text.secondary,\n paddingRight: theme.spacing(0.5),\n }),\n});\n\nfunction toSelectableValue({ text, value }: MetricFindValue): SelectableValue<string> {\n return {\n label: text,\n value: String(value ?? text),\n };\n}\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -465,6 +465,8 @@ declare class AdHocFiltersVariableUrlSyncHandler implements SceneObjectUrlSyncHa
|
|
|
465
465
|
}
|
|
466
466
|
|
|
467
467
|
interface AdHocFiltersVariableState extends SceneVariableState {
|
|
468
|
+
/** Optional text to display on the 'add filter' button */
|
|
469
|
+
addFilterButtonText?: string;
|
|
468
470
|
/** The visible filters */
|
|
469
471
|
filters: AdHocVariableFilter[];
|
|
470
472
|
/** Base filters to always apply when looking up keys*/
|
package/dist/index.js
CHANGED
|
@@ -4055,11 +4055,13 @@ function AdHocFilterRenderer({ filter, model }) {
|
|
|
4055
4055
|
className: state.isKeysOpen ? styles.widthWhenOpen : void 0,
|
|
4056
4056
|
width: "auto",
|
|
4057
4057
|
value: valueValue,
|
|
4058
|
-
placeholder: "value",
|
|
4058
|
+
placeholder: "Select value",
|
|
4059
4059
|
options: state.values,
|
|
4060
4060
|
onChange: (v) => model._updateFilter(filter, "value", v.value),
|
|
4061
4061
|
isOpen: state.isValuesOpen,
|
|
4062
4062
|
isLoading: state.isValuesLoading,
|
|
4063
|
+
autoFocus: filter.key !== "" && filter.value === "",
|
|
4064
|
+
openMenuOnFocus: true,
|
|
4063
4065
|
onOpenMenu: async () => {
|
|
4064
4066
|
setState(__spreadProps$g(__spreadValues$q({}, state), { isValuesLoading: true }));
|
|
4065
4067
|
const values = await model._getValuesFor(filter);
|
|
@@ -4070,6 +4072,7 @@ function AdHocFilterRenderer({ filter, model }) {
|
|
|
4070
4072
|
}
|
|
4071
4073
|
});
|
|
4072
4074
|
const keySelect = /* @__PURE__ */ React__default["default"].createElement(ui.Select, {
|
|
4075
|
+
key: `${state.isValuesLoading ? "loading" : "loaded"}`,
|
|
4073
4076
|
disabled: model.state.readOnly,
|
|
4074
4077
|
className: state.isKeysOpen ? styles.widthWhenOpen : void 0,
|
|
4075
4078
|
width: "auto",
|
|
@@ -4088,6 +4091,11 @@ function AdHocFilterRenderer({ filter, model }) {
|
|
|
4088
4091
|
onCloseMenu: () => {
|
|
4089
4092
|
setState(__spreadProps$g(__spreadValues$q({}, state), { isKeysOpen: false }));
|
|
4090
4093
|
},
|
|
4094
|
+
onBlur: () => {
|
|
4095
|
+
if (filter.key === "") {
|
|
4096
|
+
model._removeFilter(filter);
|
|
4097
|
+
}
|
|
4098
|
+
},
|
|
4091
4099
|
openMenuOnFocus: true
|
|
4092
4100
|
});
|
|
4093
4101
|
if (model.state.layout === "vertical") {
|
|
@@ -4172,7 +4180,7 @@ const getStyles$7 = (theme) => ({
|
|
|
4172
4180
|
})
|
|
4173
4181
|
});
|
|
4174
4182
|
|
|
4175
|
-
function AdHocFilterBuilder({ model }) {
|
|
4183
|
+
function AdHocFilterBuilder({ model, addFilterButtonText }) {
|
|
4176
4184
|
const { _wip } = model.useState();
|
|
4177
4185
|
if (!_wip) {
|
|
4178
4186
|
return /* @__PURE__ */ React__default["default"].createElement(ui.Button, {
|
|
@@ -4182,7 +4190,7 @@ function AdHocFilterBuilder({ model }) {
|
|
|
4182
4190
|
"aria-label": "Add filter",
|
|
4183
4191
|
"data-testid": `AdHocFilter-add`,
|
|
4184
4192
|
onClick: () => model._addWip()
|
|
4185
|
-
});
|
|
4193
|
+
}, addFilterButtonText);
|
|
4186
4194
|
}
|
|
4187
4195
|
return /* @__PURE__ */ React__default["default"].createElement(AdHocFilterRenderer, {
|
|
4188
4196
|
filter: _wip,
|
|
@@ -4418,7 +4426,7 @@ function renderExpression(state) {
|
|
|
4418
4426
|
return ((_a = state.expressionBuilder) != null ? _a : renderPrometheusLabelFilters)((_b = state.filters) != null ? _b : []);
|
|
4419
4427
|
}
|
|
4420
4428
|
function AdHocFiltersVariableRenderer({ model }) {
|
|
4421
|
-
const { filters, readOnly } = model.useState();
|
|
4429
|
+
const { filters, readOnly, addFilterButtonText } = model.useState();
|
|
4422
4430
|
const styles = ui.useStyles2(getStyles$6);
|
|
4423
4431
|
return /* @__PURE__ */ React__default["default"].createElement("div", {
|
|
4424
4432
|
className: styles.wrapper
|
|
@@ -4429,7 +4437,8 @@ function AdHocFiltersVariableRenderer({ model }) {
|
|
|
4429
4437
|
model
|
|
4430
4438
|
}))), !readOnly && /* @__PURE__ */ React__default["default"].createElement(AdHocFilterBuilder, {
|
|
4431
4439
|
model,
|
|
4432
|
-
key: "'builder"
|
|
4440
|
+
key: "'builder",
|
|
4441
|
+
addFilterButtonText
|
|
4433
4442
|
}));
|
|
4434
4443
|
}
|
|
4435
4444
|
const getStyles$6 = (theme) => ({
|
|
@@ -7908,6 +7917,8 @@ function SceneGridRowRenderer({ model }) {
|
|
|
7908
7917
|
const layoutDragClass = model.getGridLayout().getDragClass();
|
|
7909
7918
|
return /* @__PURE__ */ React__default["default"].createElement("div", {
|
|
7910
7919
|
className: css.cx(styles.row, isCollapsed && styles.rowCollapsed)
|
|
7920
|
+
}, /* @__PURE__ */ React__default["default"].createElement("div", {
|
|
7921
|
+
className: styles.rowTitleAndActionsGroup
|
|
7911
7922
|
}, /* @__PURE__ */ React__default["default"].createElement("button", {
|
|
7912
7923
|
onClick: model.onCollapseToggle,
|
|
7913
7924
|
className: styles.rowTitleButton,
|
|
@@ -7919,7 +7930,7 @@ function SceneGridRowRenderer({ model }) {
|
|
|
7919
7930
|
role: "heading"
|
|
7920
7931
|
}, sceneGraph.interpolate(model, title, void 0, "text"))), actions && /* @__PURE__ */ React__default["default"].createElement(actions.Component, {
|
|
7921
7932
|
model: actions
|
|
7922
|
-
}), isDraggable && isCollapsed && /* @__PURE__ */ React__default["default"].createElement("div", {
|
|
7933
|
+
})), isDraggable && isCollapsed && /* @__PURE__ */ React__default["default"].createElement("div", {
|
|
7923
7934
|
className: css.cx(styles.dragHandle, layoutDragClass)
|
|
7924
7935
|
}, /* @__PURE__ */ React__default["default"].createElement(ui.Icon, {
|
|
7925
7936
|
name: "draggabledots"
|
|
@@ -7956,6 +7967,9 @@ const getSceneGridRowStyles = (theme) => {
|
|
|
7956
7967
|
alignItems: "center",
|
|
7957
7968
|
flexGrow: 1
|
|
7958
7969
|
}),
|
|
7970
|
+
rowTitleAndActionsGroup: css.css({
|
|
7971
|
+
display: "flex"
|
|
7972
|
+
}),
|
|
7959
7973
|
dragHandle: css.css({
|
|
7960
7974
|
display: "flex",
|
|
7961
7975
|
padding: theme.spacing(0, 1),
|