@grafana/scenes 4.11.2 → 4.11.3--canary.690.8783271240.0
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/dist/esm/variables/adhoc/AdHocFilterRenderer.js +12 -20
- package/dist/esm/variables/adhoc/AdHocFilterRenderer.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFiltersVariable.js +8 -5
- package/dist/esm/variables/adhoc/AdHocFiltersVariable.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFiltersVariableUrlSyncHandler.js +36 -12
- package/dist/esm/variables/adhoc/AdHocFiltersVariableUrlSyncHandler.js.map +1 -1
- package/dist/index.d.ts +12 -8
- package/dist/index.js +55 -34
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import React, { useState
|
|
2
|
-
import { toSelectableValue } from './AdHocFiltersVariable.js';
|
|
3
|
-
import { toOption } from '@grafana/data';
|
|
1
|
+
import React, { useState } from 'react';
|
|
4
2
|
import { useStyles2, Select, Field, Button } from '@grafana/ui';
|
|
5
3
|
import { css } from '@emotion/css';
|
|
6
4
|
import { ControlsLabel } from '../../utils/ControlsLabel.js';
|
|
@@ -24,24 +22,18 @@ var __spreadValues = (a, b) => {
|
|
|
24
22
|
return a;
|
|
25
23
|
};
|
|
26
24
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
25
|
+
function keyLabelToOption(key, label) {
|
|
26
|
+
return key !== "" ? {
|
|
27
|
+
value: key,
|
|
28
|
+
label: label || key
|
|
29
|
+
} : null;
|
|
30
|
+
}
|
|
27
31
|
function AdHocFilterRenderer({ filter, model }) {
|
|
28
32
|
var _a, _b;
|
|
29
33
|
const styles = useStyles2(getStyles);
|
|
30
34
|
const [state, setState] = useState({});
|
|
31
|
-
const keyValue =
|
|
32
|
-
|
|
33
|
-
if (model.state.defaultKeys) {
|
|
34
|
-
const matchingDefaultKey = model.state.defaultKeys.find((option) => option.value === filter.key);
|
|
35
|
-
if (matchingDefaultKey) {
|
|
36
|
-
return toSelectableValue(matchingDefaultKey);
|
|
37
|
-
}
|
|
38
|
-
} else {
|
|
39
|
-
return toOption(filter.key);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return null;
|
|
43
|
-
}, [filter.key, model.state.defaultKeys]);
|
|
44
|
-
const valueValue = filter.value !== "" ? toOption(filter.value) : null;
|
|
35
|
+
const keyValue = keyLabelToOption(filter.key, filter.keyLabel);
|
|
36
|
+
const valueValue = keyLabelToOption(filter.value, filter.valueLabel);
|
|
45
37
|
const valueSelect = /* @__PURE__ */ React.createElement(Select, {
|
|
46
38
|
allowCustomValue: true,
|
|
47
39
|
formatCreateLabel: (inputValue) => `Use custom value: ${inputValue}`,
|
|
@@ -51,7 +43,7 @@ function AdHocFilterRenderer({ filter, model }) {
|
|
|
51
43
|
value: valueValue,
|
|
52
44
|
placeholder: "Select value",
|
|
53
45
|
options: state.values,
|
|
54
|
-
onChange: (v) => model._updateFilter(filter, "value", v
|
|
46
|
+
onChange: (v) => model._updateFilter(filter, "value", v),
|
|
55
47
|
isOpen: state.isValuesOpen,
|
|
56
48
|
isLoading: state.isValuesLoading,
|
|
57
49
|
autoFocus: filter.key !== "" && filter.value === "",
|
|
@@ -73,7 +65,7 @@ function AdHocFilterRenderer({ filter, model }) {
|
|
|
73
65
|
value: keyValue,
|
|
74
66
|
placeholder: "Select label",
|
|
75
67
|
options: state.keys,
|
|
76
|
-
onChange: (v) => model._updateFilter(filter, "key", v
|
|
68
|
+
onChange: (v) => model._updateFilter(filter, "key", v),
|
|
77
69
|
autoFocus: filter.key === "",
|
|
78
70
|
isOpen: state.isKeysOpen,
|
|
79
71
|
isLoading: state.isKeysLoading,
|
|
@@ -120,7 +112,7 @@ function AdHocFilterRenderer({ filter, model }) {
|
|
|
120
112
|
disabled: model.state.readOnly,
|
|
121
113
|
options: model._getOperators(),
|
|
122
114
|
width: "auto",
|
|
123
|
-
onChange: (v) => model._updateFilter(filter, "operator", v
|
|
115
|
+
onChange: (v) => model._updateFilter(filter, "operator", v)
|
|
124
116
|
}), valueSelect, /* @__PURE__ */ React.createElement(Button, {
|
|
125
117
|
variant: "secondary",
|
|
126
118
|
"aria-label": "Remove filter",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdHocFilterRenderer.js","sources":["../../../../src/variables/adhoc/AdHocFilterRenderer.tsx"],"sourcesContent":["import React, { useMemo, useState } from 'react';\n\nimport { AdHocFiltersVariable, toSelectableValue } 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 = useMemo(() => {\n if (filter.key !== '') {\n if (model.state.defaultKeys) {\n const matchingDefaultKey = model.state.defaultKeys.find(option => option.value === filter.key);\n if (matchingDefaultKey) {\n return toSelectableValue(matchingDefaultKey);\n }\n } else {\n return toOption(filter.key);\n }\n }\n return null;\n }, [filter.key, model.state.defaultKeys])\n const valueValue = filter.value !== '' ? toOption(filter.value) : null;\n\n const valueSelect = (\n <Select\n allowCustomValue\n formatCreateLabel={(inputValue) => `Use custom value: ${inputValue}`}\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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"}
|
|
1
|
+
{"version":3,"file":"AdHocFilterRenderer.js","sources":["../../../../src/variables/adhoc/AdHocFilterRenderer.tsx"],"sourcesContent":["import React, { useState } from 'react';\n\nimport { AdHocFiltersVariable, AdHocFilterWithLabels } from './AdHocFiltersVariable';\nimport { GrafanaTheme2, SelectableValue } 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: AdHocFilterWithLabels;\n model: AdHocFiltersVariable;\n}\n\nfunction keyLabelToOption(key: string, label?: string): SelectableValue | null {\n return key !== ''\n ? {\n value: key,\n label: label || key,\n }\n : null;\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 = keyLabelToOption(filter.key, filter.keyLabel);\n const valueValue = keyLabelToOption(filter.value, filter.valueLabel);\n\n const valueSelect = (\n <Select\n allowCustomValue\n formatCreateLabel={(inputValue) => `Use custom value: ${inputValue}`}\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)}\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)}\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)}\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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"}
|
|
@@ -62,22 +62,23 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
|
62
62
|
getValue() {
|
|
63
63
|
return this.state.filterExpression;
|
|
64
64
|
}
|
|
65
|
-
_updateFilter(filter, prop, value) {
|
|
65
|
+
_updateFilter(filter, prop, { value, label }) {
|
|
66
66
|
if (value == null) {
|
|
67
67
|
return;
|
|
68
68
|
}
|
|
69
69
|
const { filters, _wip } = this.state;
|
|
70
|
+
const propLabelKey = `${prop}Label`;
|
|
70
71
|
if (filter === _wip) {
|
|
71
72
|
if (prop === "value") {
|
|
72
|
-
this.setState({ filters: [...filters, __spreadProps(__spreadValues({}, _wip), { [prop]: value })], _wip: void 0 });
|
|
73
|
+
this.setState({ filters: [...filters, __spreadProps(__spreadValues({}, _wip), { [prop]: value, [propLabelKey]: label })], _wip: void 0 });
|
|
73
74
|
} else {
|
|
74
|
-
this.setState({ _wip: __spreadProps(__spreadValues({}, filter), { [prop]: value }) });
|
|
75
|
+
this.setState({ _wip: __spreadProps(__spreadValues({}, filter), { [prop]: value, [propLabelKey]: label }) });
|
|
75
76
|
}
|
|
76
77
|
return;
|
|
77
78
|
}
|
|
78
79
|
const updatedFilters = this.state.filters.map((f) => {
|
|
79
80
|
if (f === filter) {
|
|
80
|
-
return __spreadProps(__spreadValues({}, f), { [prop]: value });
|
|
81
|
+
return __spreadProps(__spreadValues({}, f), { [prop]: value, [propLabelKey]: label });
|
|
81
82
|
}
|
|
82
83
|
return f;
|
|
83
84
|
});
|
|
@@ -136,7 +137,9 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
|
136
137
|
return values.map(toSelectableValue);
|
|
137
138
|
}
|
|
138
139
|
_addWip() {
|
|
139
|
-
this.setState({
|
|
140
|
+
this.setState({
|
|
141
|
+
_wip: { key: "", keyLabel: "", value: "", valueLabel: "", operator: "=", condition: "" }
|
|
142
|
+
});
|
|
140
143
|
}
|
|
141
144
|
_getOperators() {
|
|
142
145
|
return ["=", "!=", "<", ">", "=~", "!~"].map((value) => ({
|
|
@@ -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 { getQueriesForVariables, renderPrometheusLabelFilters } from '../utils';\nimport { patchGetAdhocFilters } from './patchGetAdhocFilters';\nimport { useStyles2 } from '@grafana/ui';\nimport { sceneGraph } from '../../core/sceneGraph';\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 * Optionally provide an array of static keys that override getTagKeys\n */\n defaultKeys?: MetricFindValue[];\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?: AdHocVariableExpressionBuilderFn;\n\n /**\n * @internal state of the new filter being added\n */\n _wip?: AdHocVariableFilter;\n}\n\nexport type AdHocVariableExpressionBuilderFn = (filters: AdHocVariableFilter[]) => string;\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.expressionBuilder, state.filters),\n ...state,\n });\n\n if (this.state.applyMode === 'auto') {\n patchGetAdhocFilters(this);\n }\n }\n\n public setState(update: Partial<AdHocFiltersVariableState>): void {\n let filterExpressionChanged = false;\n\n if (update.filters && update.filters !== this.state.filters && !update.filterExpression) {\n update.filterExpression = renderExpression(this.state.expressionBuilder, update.filters);\n filterExpressionChanged = update.filterExpression !== this.state.filterExpression;\n }\n\n super.setState(update);\n\n if (filterExpressionChanged) {\n this.publishEvent(new SceneVariableValueChangedEvent(this), true);\n }\n }\n\n public getValue(): VariableValue | undefined {\n return this.state.filterExpression;\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 if (this.state.defaultKeys) {\n return this.state.defaultKeys.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 timeRange = sceneGraph.getTimeRange(this).state.value;\n const queries = getQueriesForVariables(this);\n // @ts-expect-error TODO: remove this once 10.4.0 is released\n let keys = await ds.getTagKeys({ filters: otherFilters, queries, timeRange });\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 const queries = getQueriesForVariables(this);\n // @ts-expect-error TODO: remove this once 11.1.x is released\n let values = await ds.getTagValues({ key: filter.key, filters: otherFilters, timeRange, queries });\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\nfunction renderExpression(\n builder: AdHocVariableExpressionBuilderFn | undefined,\n filters: AdHocVariableFilter[] | undefined\n) {\n return (builder ?? renderPrometheusLabelFilters)(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\nexport function 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 { getQueriesForVariables, renderPrometheusLabelFilters } from '../utils';\nimport { patchGetAdhocFilters } from './patchGetAdhocFilters';\nimport { useStyles2 } from '@grafana/ui';\nimport { sceneGraph } from '../../core/sceneGraph';\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 AdHocFilterWithLabels extends AdHocVariableFilter {\n keyLabel?: string;\n valueLabel?: string;\n}\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: AdHocFilterWithLabels[];\n /** Base filters to always apply when looking up keys*/\n baseFilters?: AdHocFilterWithLabels[];\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 * Optionally provide an array of static keys that override getTagKeys\n */\n defaultKeys?: MetricFindValue[];\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?: AdHocVariableExpressionBuilderFn;\n\n /**\n * @internal state of the new filter being added\n */\n _wip?: AdHocFilterWithLabels;\n}\n\nexport type AdHocVariableExpressionBuilderFn = (filters: AdHocFilterWithLabels[]) => string;\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: AdHocFilterWithLabels\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.expressionBuilder, state.filters),\n ...state,\n });\n\n if (this.state.applyMode === 'auto') {\n patchGetAdhocFilters(this);\n }\n }\n\n public setState(update: Partial<AdHocFiltersVariableState>): void {\n let filterExpressionChanged = false;\n\n if (update.filters && update.filters !== this.state.filters && !update.filterExpression) {\n update.filterExpression = renderExpression(this.state.expressionBuilder, update.filters);\n filterExpressionChanged = update.filterExpression !== this.state.filterExpression;\n }\n\n super.setState(update);\n\n if (filterExpressionChanged) {\n this.publishEvent(new SceneVariableValueChangedEvent(this), true);\n }\n }\n\n public getValue(): VariableValue | undefined {\n return this.state.filterExpression;\n }\n\n public _updateFilter(\n filter: AdHocFilterWithLabels,\n prop: keyof AdHocFilterWithLabels,\n { value, label }: SelectableValue<string | undefined | null>\n ) {\n if (value == null) {\n return;\n }\n\n const { filters, _wip } = this.state;\n\n const propLabelKey = `${prop}Label`;\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, [propLabelKey]: label }], _wip: undefined });\n } else {\n this.setState({ _wip: { ...filter, [prop]: value, [propLabelKey]: label } });\n }\n return;\n }\n\n const updatedFilters = this.state.filters.map((f) => {\n if (f === filter) {\n return { ...f, [prop]: value, [propLabelKey]: label };\n }\n return f;\n });\n\n this.setState({ filters: updatedFilters });\n }\n\n public _removeFilter(filter: AdHocFilterWithLabels) {\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 if (this.state.defaultKeys) {\n return this.state.defaultKeys.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 timeRange = sceneGraph.getTimeRange(this).state.value;\n const queries = getQueriesForVariables(this);\n // @ts-expect-error TODO: remove this once 10.4.0 is released\n let keys = await ds.getTagKeys({ filters: otherFilters, queries, timeRange });\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: AdHocFilterWithLabels): 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 const queries = getQueriesForVariables(this);\n // @ts-expect-error TODO: remove this once 11.1.x is released\n let values = await ds.getTagValues({ key: filter.key, filters: otherFilters, timeRange, queries });\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({\n _wip: { key: '', keyLabel: '', value: '', valueLabel: '', operator: '=', condition: '' },\n });\n }\n\n public _getOperators() {\n return ['=', '!=', '<', '>', '=~', '!~'].map<SelectableValue<string>>((value) => ({\n label: value,\n value,\n }));\n }\n}\n\nfunction renderExpression(\n builder: AdHocVariableExpressionBuilderFn | undefined,\n filters: AdHocFilterWithLabels[] | undefined\n) {\n return (builder ?? renderPrometheusLabelFilters)(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\nexport function 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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"}
|
|
@@ -13,7 +13,7 @@ class AdHocFiltersVariableUrlSyncHandler {
|
|
|
13
13
|
if (filters.length === 0) {
|
|
14
14
|
return { [this.getKey()]: [""] };
|
|
15
15
|
}
|
|
16
|
-
const value = filters.map((filter) => toArray(filter).map(
|
|
16
|
+
const value = filters.map((filter) => toArray(filter).map(escapePipeDelimiters).join("|"));
|
|
17
17
|
return { [this.getKey()]: value };
|
|
18
18
|
}
|
|
19
19
|
updateFromUrl(values) {
|
|
@@ -33,30 +33,54 @@ function deserializeUrlToFilters(value) {
|
|
|
33
33
|
const filter = toFilter(value);
|
|
34
34
|
return filter === null ? [] : [filter];
|
|
35
35
|
}
|
|
36
|
-
function
|
|
36
|
+
function escapePipeDelimiters(value) {
|
|
37
37
|
if (value === null || value === void 0) {
|
|
38
38
|
return "";
|
|
39
39
|
}
|
|
40
|
-
return /\|/g[Symbol.replace](value, "__gfp__");
|
|
40
|
+
return value = /\|/g[Symbol.replace](value, "__gfp__");
|
|
41
41
|
}
|
|
42
|
-
function
|
|
42
|
+
function escapeCommaDelimiters(value) {
|
|
43
43
|
if (value === null || value === void 0) {
|
|
44
44
|
return "";
|
|
45
45
|
}
|
|
46
|
-
return
|
|
46
|
+
return /,/g[Symbol.replace](value, "__gfc__");
|
|
47
|
+
}
|
|
48
|
+
function unescapeDelimiters(value) {
|
|
49
|
+
if (value === null || value === void 0) {
|
|
50
|
+
return "";
|
|
51
|
+
}
|
|
52
|
+
value = /__gfp__/g[Symbol.replace](value, "|");
|
|
53
|
+
value = /__gfc__/g[Symbol.replace](value, ",");
|
|
54
|
+
return value;
|
|
47
55
|
}
|
|
48
56
|
function toArray(filter) {
|
|
49
|
-
return [
|
|
57
|
+
return [
|
|
58
|
+
toCommaDelimitedString(filter.key, filter.keyLabel),
|
|
59
|
+
filter.operator,
|
|
60
|
+
toCommaDelimitedString(filter.value, filter.valueLabel)
|
|
61
|
+
];
|
|
62
|
+
}
|
|
63
|
+
function toCommaDelimitedString(key, label) {
|
|
64
|
+
if (!label || key === label) {
|
|
65
|
+
return escapeCommaDelimiters(key);
|
|
66
|
+
}
|
|
67
|
+
return [key, label].map(escapeCommaDelimiters).join(",");
|
|
50
68
|
}
|
|
51
|
-
function toFilter(
|
|
52
|
-
if (typeof
|
|
69
|
+
function toFilter(urlValue) {
|
|
70
|
+
if (typeof urlValue !== "string" || urlValue.length === 0) {
|
|
53
71
|
return null;
|
|
54
72
|
}
|
|
55
|
-
const
|
|
73
|
+
const [key, keyLabel, operator, _operatorLabel, value, valueLabel] = urlValue.split("|").reduce((acc, v) => {
|
|
74
|
+
const [key2, label] = v.split(",");
|
|
75
|
+
acc.push(key2, label != null ? label : key2);
|
|
76
|
+
return acc;
|
|
77
|
+
}, []).map(unescapeDelimiters);
|
|
56
78
|
return {
|
|
57
|
-
key
|
|
58
|
-
|
|
59
|
-
|
|
79
|
+
key,
|
|
80
|
+
keyLabel,
|
|
81
|
+
operator,
|
|
82
|
+
value,
|
|
83
|
+
valueLabel,
|
|
60
84
|
condition: ""
|
|
61
85
|
};
|
|
62
86
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdHocFiltersVariableUrlSyncHandler.js","sources":["../../../../src/variables/adhoc/AdHocFiltersVariableUrlSyncHandler.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"AdHocFiltersVariableUrlSyncHandler.js","sources":["../../../../src/variables/adhoc/AdHocFiltersVariableUrlSyncHandler.ts"],"sourcesContent":["import { SceneObjectUrlSyncHandler, SceneObjectUrlValue, SceneObjectUrlValues } from '../../core/types';\nimport { AdHocFiltersVariable, AdHocFilterWithLabels } from './AdHocFiltersVariable';\n\nexport class AdHocFiltersVariableUrlSyncHandler implements SceneObjectUrlSyncHandler {\n public constructor(private _variable: AdHocFiltersVariable) {}\n\n private getKey(): string {\n return `var-${this._variable.state.name}`;\n }\n\n public getKeys(): string[] {\n return [this.getKey()];\n }\n\n public getUrlState(): SceneObjectUrlValues {\n const filters = this._variable.state.filters;\n\n if (filters.length === 0) {\n return { [this.getKey()]: [''] };\n }\n\n const value = filters.map((filter) => toArray(filter).map(escapePipeDelimiters).join('|'));\n return { [this.getKey()]: value };\n }\n\n public updateFromUrl(values: SceneObjectUrlValues): void {\n const urlValue = values[this.getKey()];\n\n if (urlValue == null) {\n return;\n }\n\n const filters = deserializeUrlToFilters(urlValue);\n this._variable.setState({ filters });\n }\n}\n\nfunction deserializeUrlToFilters(value: SceneObjectUrlValue): AdHocFilterWithLabels[] {\n if (Array.isArray(value)) {\n const values = value;\n return values.map(toFilter).filter(isFilter);\n }\n\n const filter = toFilter(value);\n return filter === null ? [] : [filter];\n}\n\nfunction escapePipeDelimiters(value: string | undefined): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n // Replace the pipe due to using it as a filter separator\n return (value = /\\|/g[Symbol.replace](value, '__gfp__'));\n}\n\nfunction escapeCommaDelimiters(value: string | undefined): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n // Replace the comma due to using it as a value/label separator\n return /,/g[Symbol.replace](value, '__gfc__');\n}\n\nfunction unescapeDelimiters(value: string | undefined): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n value = /__gfp__/g[Symbol.replace](value, '|');\n value = /__gfc__/g[Symbol.replace](value, ',');\n\n return value;\n}\n\nfunction toArray(filter: AdHocFilterWithLabels): string[] {\n return [\n toCommaDelimitedString(filter.key, filter.keyLabel),\n filter.operator,\n toCommaDelimitedString(filter.value, filter.valueLabel),\n ];\n}\n\nfunction toCommaDelimitedString(key: string, label?: string): string {\n // Omit for identical key/label or when label is not set at all\n if (!label || key === label) {\n return escapeCommaDelimiters(key);\n }\n\n return [key, label].map(escapeCommaDelimiters).join(',');\n}\n\nfunction toFilter(urlValue: string | number | boolean | undefined | null): AdHocFilterWithLabels | null {\n if (typeof urlValue !== 'string' || urlValue.length === 0) {\n return null;\n }\n\n const [key, keyLabel, operator, _operatorLabel, value, valueLabel] = urlValue\n .split('|')\n .reduce<string[]>((acc, v) => {\n const [key, label] = v.split(',');\n\n acc.push(key, label ?? key);\n\n return acc;\n }, [])\n .map(unescapeDelimiters);\n\n return {\n key,\n keyLabel,\n operator,\n value,\n valueLabel,\n condition: '',\n };\n}\n\nfunction isFilter(filter: AdHocFilterWithLabels | null): filter is AdHocFilterWithLabels {\n return filter !== null && typeof filter.key === 'string' && typeof filter.value === 'string';\n}\n"],"names":["key"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -617,13 +617,17 @@ declare class AdHocFiltersVariableUrlSyncHandler implements SceneObjectUrlSyncHa
|
|
|
617
617
|
updateFromUrl(values: SceneObjectUrlValues): void;
|
|
618
618
|
}
|
|
619
619
|
|
|
620
|
+
interface AdHocFilterWithLabels extends AdHocVariableFilter {
|
|
621
|
+
keyLabel?: string;
|
|
622
|
+
valueLabel?: string;
|
|
623
|
+
}
|
|
620
624
|
interface AdHocFiltersVariableState extends SceneVariableState {
|
|
621
625
|
/** Optional text to display on the 'add filter' button */
|
|
622
626
|
addFilterButtonText?: string;
|
|
623
627
|
/** The visible filters */
|
|
624
|
-
filters:
|
|
628
|
+
filters: AdHocFilterWithLabels[];
|
|
625
629
|
/** Base filters to always apply when looking up keys*/
|
|
626
|
-
baseFilters?:
|
|
630
|
+
baseFilters?: AdHocFilterWithLabels[];
|
|
627
631
|
/** Datasource to use for getTagKeys and getTagValues and also controls which scene queries the filters should apply to */
|
|
628
632
|
datasource: DataSourceRef | null;
|
|
629
633
|
/** Controls if the filters can be changed */
|
|
@@ -672,14 +676,14 @@ interface AdHocFiltersVariableState extends SceneVariableState {
|
|
|
672
676
|
/**
|
|
673
677
|
* @internal state of the new filter being added
|
|
674
678
|
*/
|
|
675
|
-
_wip?:
|
|
679
|
+
_wip?: AdHocFilterWithLabels;
|
|
676
680
|
}
|
|
677
|
-
type AdHocVariableExpressionBuilderFn = (filters:
|
|
681
|
+
type AdHocVariableExpressionBuilderFn = (filters: AdHocFilterWithLabels[]) => string;
|
|
678
682
|
type getTagKeysProvider$1 = (variable: AdHocFiltersVariable, currentKey: string | null) => Promise<{
|
|
679
683
|
replace?: boolean;
|
|
680
684
|
values: MetricFindValue[];
|
|
681
685
|
}>;
|
|
682
|
-
type getTagValuesProvider = (variable: AdHocFiltersVariable, filter:
|
|
686
|
+
type getTagValuesProvider = (variable: AdHocFiltersVariable, filter: AdHocFilterWithLabels) => Promise<{
|
|
683
687
|
replace?: boolean;
|
|
684
688
|
values: MetricFindValue[];
|
|
685
689
|
}>;
|
|
@@ -691,8 +695,8 @@ declare class AdHocFiltersVariable extends SceneObjectBase<AdHocFiltersVariableS
|
|
|
691
695
|
constructor(state: Partial<AdHocFiltersVariableState>);
|
|
692
696
|
setState(update: Partial<AdHocFiltersVariableState>): void;
|
|
693
697
|
getValue(): VariableValue | undefined;
|
|
694
|
-
_updateFilter(filter:
|
|
695
|
-
_removeFilter(filter:
|
|
698
|
+
_updateFilter(filter: AdHocFilterWithLabels, prop: keyof AdHocFilterWithLabels, { value, label }: SelectableValue<string | undefined | null>): void;
|
|
699
|
+
_removeFilter(filter: AdHocFilterWithLabels): void;
|
|
696
700
|
/**
|
|
697
701
|
* Get possible keys given current filters. Do not call from plugins directly
|
|
698
702
|
*/
|
|
@@ -700,7 +704,7 @@ declare class AdHocFiltersVariable extends SceneObjectBase<AdHocFiltersVariableS
|
|
|
700
704
|
/**
|
|
701
705
|
* Get possible key values for a specific key given current filters. Do not call from plugins directly
|
|
702
706
|
*/
|
|
703
|
-
_getValuesFor(filter:
|
|
707
|
+
_getValuesFor(filter: AdHocFilterWithLabels): Promise<Array<SelectableValue<string>>>;
|
|
704
708
|
_addWip(): void;
|
|
705
709
|
_getOperators(): SelectableValue<string>[];
|
|
706
710
|
}
|
package/dist/index.js
CHANGED
|
@@ -3145,24 +3145,18 @@ var __spreadValues$y = (a, b) => {
|
|
|
3145
3145
|
return a;
|
|
3146
3146
|
};
|
|
3147
3147
|
var __spreadProps$m = (a, b) => __defProps$m(a, __getOwnPropDescs$m(b));
|
|
3148
|
+
function keyLabelToOption(key, label) {
|
|
3149
|
+
return key !== "" ? {
|
|
3150
|
+
value: key,
|
|
3151
|
+
label: label || key
|
|
3152
|
+
} : null;
|
|
3153
|
+
}
|
|
3148
3154
|
function AdHocFilterRenderer({ filter, model }) {
|
|
3149
3155
|
var _a, _b;
|
|
3150
3156
|
const styles = ui.useStyles2(getStyles$7);
|
|
3151
3157
|
const [state, setState] = React.useState({});
|
|
3152
|
-
const keyValue =
|
|
3153
|
-
|
|
3154
|
-
if (model.state.defaultKeys) {
|
|
3155
|
-
const matchingDefaultKey = model.state.defaultKeys.find((option) => option.value === filter.key);
|
|
3156
|
-
if (matchingDefaultKey) {
|
|
3157
|
-
return toSelectableValue(matchingDefaultKey);
|
|
3158
|
-
}
|
|
3159
|
-
} else {
|
|
3160
|
-
return data.toOption(filter.key);
|
|
3161
|
-
}
|
|
3162
|
-
}
|
|
3163
|
-
return null;
|
|
3164
|
-
}, [filter.key, model.state.defaultKeys]);
|
|
3165
|
-
const valueValue = filter.value !== "" ? data.toOption(filter.value) : null;
|
|
3158
|
+
const keyValue = keyLabelToOption(filter.key, filter.keyLabel);
|
|
3159
|
+
const valueValue = keyLabelToOption(filter.value, filter.valueLabel);
|
|
3166
3160
|
const valueSelect = /* @__PURE__ */ React__default["default"].createElement(ui.Select, {
|
|
3167
3161
|
allowCustomValue: true,
|
|
3168
3162
|
formatCreateLabel: (inputValue) => `Use custom value: ${inputValue}`,
|
|
@@ -3172,7 +3166,7 @@ function AdHocFilterRenderer({ filter, model }) {
|
|
|
3172
3166
|
value: valueValue,
|
|
3173
3167
|
placeholder: "Select value",
|
|
3174
3168
|
options: state.values,
|
|
3175
|
-
onChange: (v) => model._updateFilter(filter, "value", v
|
|
3169
|
+
onChange: (v) => model._updateFilter(filter, "value", v),
|
|
3176
3170
|
isOpen: state.isValuesOpen,
|
|
3177
3171
|
isLoading: state.isValuesLoading,
|
|
3178
3172
|
autoFocus: filter.key !== "" && filter.value === "",
|
|
@@ -3194,7 +3188,7 @@ function AdHocFilterRenderer({ filter, model }) {
|
|
|
3194
3188
|
value: keyValue,
|
|
3195
3189
|
placeholder: "Select label",
|
|
3196
3190
|
options: state.keys,
|
|
3197
|
-
onChange: (v) => model._updateFilter(filter, "key", v
|
|
3191
|
+
onChange: (v) => model._updateFilter(filter, "key", v),
|
|
3198
3192
|
autoFocus: filter.key === "",
|
|
3199
3193
|
isOpen: state.isKeysOpen,
|
|
3200
3194
|
isLoading: state.isKeysLoading,
|
|
@@ -3241,7 +3235,7 @@ function AdHocFilterRenderer({ filter, model }) {
|
|
|
3241
3235
|
disabled: model.state.readOnly,
|
|
3242
3236
|
options: model._getOperators(),
|
|
3243
3237
|
width: "auto",
|
|
3244
|
-
onChange: (v) => model._updateFilter(filter, "operator", v
|
|
3238
|
+
onChange: (v) => model._updateFilter(filter, "operator", v)
|
|
3245
3239
|
}), valueSelect, /* @__PURE__ */ React__default["default"].createElement(ui.Button, {
|
|
3246
3240
|
variant: "secondary",
|
|
3247
3241
|
"aria-label": "Remove filter",
|
|
@@ -3328,7 +3322,7 @@ class AdHocFiltersVariableUrlSyncHandler {
|
|
|
3328
3322
|
if (filters.length === 0) {
|
|
3329
3323
|
return { [this.getKey()]: [""] };
|
|
3330
3324
|
}
|
|
3331
|
-
const value = filters.map((filter) => toArray(filter).map(
|
|
3325
|
+
const value = filters.map((filter) => toArray(filter).map(escapePipeDelimiters).join("|"));
|
|
3332
3326
|
return { [this.getKey()]: value };
|
|
3333
3327
|
}
|
|
3334
3328
|
updateFromUrl(values) {
|
|
@@ -3348,30 +3342,54 @@ function deserializeUrlToFilters(value) {
|
|
|
3348
3342
|
const filter = toFilter(value);
|
|
3349
3343
|
return filter === null ? [] : [filter];
|
|
3350
3344
|
}
|
|
3351
|
-
function
|
|
3345
|
+
function escapePipeDelimiters(value) {
|
|
3352
3346
|
if (value === null || value === void 0) {
|
|
3353
3347
|
return "";
|
|
3354
3348
|
}
|
|
3355
|
-
return /\|/g[Symbol.replace](value, "__gfp__");
|
|
3349
|
+
return value = /\|/g[Symbol.replace](value, "__gfp__");
|
|
3356
3350
|
}
|
|
3357
|
-
function
|
|
3351
|
+
function escapeCommaDelimiters(value) {
|
|
3358
3352
|
if (value === null || value === void 0) {
|
|
3359
3353
|
return "";
|
|
3360
3354
|
}
|
|
3361
|
-
return
|
|
3355
|
+
return /,/g[Symbol.replace](value, "__gfc__");
|
|
3356
|
+
}
|
|
3357
|
+
function unescapeDelimiters(value) {
|
|
3358
|
+
if (value === null || value === void 0) {
|
|
3359
|
+
return "";
|
|
3360
|
+
}
|
|
3361
|
+
value = /__gfp__/g[Symbol.replace](value, "|");
|
|
3362
|
+
value = /__gfc__/g[Symbol.replace](value, ",");
|
|
3363
|
+
return value;
|
|
3362
3364
|
}
|
|
3363
3365
|
function toArray(filter) {
|
|
3364
|
-
return [
|
|
3366
|
+
return [
|
|
3367
|
+
toCommaDelimitedString(filter.key, filter.keyLabel),
|
|
3368
|
+
filter.operator,
|
|
3369
|
+
toCommaDelimitedString(filter.value, filter.valueLabel)
|
|
3370
|
+
];
|
|
3371
|
+
}
|
|
3372
|
+
function toCommaDelimitedString(key, label) {
|
|
3373
|
+
if (!label || key === label) {
|
|
3374
|
+
return escapeCommaDelimiters(key);
|
|
3375
|
+
}
|
|
3376
|
+
return [key, label].map(escapeCommaDelimiters).join(",");
|
|
3365
3377
|
}
|
|
3366
|
-
function toFilter(
|
|
3367
|
-
if (typeof
|
|
3378
|
+
function toFilter(urlValue) {
|
|
3379
|
+
if (typeof urlValue !== "string" || urlValue.length === 0) {
|
|
3368
3380
|
return null;
|
|
3369
3381
|
}
|
|
3370
|
-
const
|
|
3382
|
+
const [key, keyLabel, operator, _operatorLabel, value, valueLabel] = urlValue.split("|").reduce((acc, v) => {
|
|
3383
|
+
const [key2, label] = v.split(",");
|
|
3384
|
+
acc.push(key2, label != null ? label : key2);
|
|
3385
|
+
return acc;
|
|
3386
|
+
}, []).map(unescapeDelimiters);
|
|
3371
3387
|
return {
|
|
3372
|
-
key
|
|
3373
|
-
|
|
3374
|
-
|
|
3388
|
+
key,
|
|
3389
|
+
keyLabel,
|
|
3390
|
+
operator,
|
|
3391
|
+
value,
|
|
3392
|
+
valueLabel,
|
|
3375
3393
|
condition: ""
|
|
3376
3394
|
};
|
|
3377
3395
|
}
|
|
@@ -3430,22 +3448,23 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
|
3430
3448
|
getValue() {
|
|
3431
3449
|
return this.state.filterExpression;
|
|
3432
3450
|
}
|
|
3433
|
-
_updateFilter(filter, prop, value) {
|
|
3451
|
+
_updateFilter(filter, prop, { value, label }) {
|
|
3434
3452
|
if (value == null) {
|
|
3435
3453
|
return;
|
|
3436
3454
|
}
|
|
3437
3455
|
const { filters, _wip } = this.state;
|
|
3456
|
+
const propLabelKey = `${prop}Label`;
|
|
3438
3457
|
if (filter === _wip) {
|
|
3439
3458
|
if (prop === "value") {
|
|
3440
|
-
this.setState({ filters: [...filters, __spreadProps$l(__spreadValues$x({}, _wip), { [prop]: value })], _wip: void 0 });
|
|
3459
|
+
this.setState({ filters: [...filters, __spreadProps$l(__spreadValues$x({}, _wip), { [prop]: value, [propLabelKey]: label })], _wip: void 0 });
|
|
3441
3460
|
} else {
|
|
3442
|
-
this.setState({ _wip: __spreadProps$l(__spreadValues$x({}, filter), { [prop]: value }) });
|
|
3461
|
+
this.setState({ _wip: __spreadProps$l(__spreadValues$x({}, filter), { [prop]: value, [propLabelKey]: label }) });
|
|
3443
3462
|
}
|
|
3444
3463
|
return;
|
|
3445
3464
|
}
|
|
3446
3465
|
const updatedFilters = this.state.filters.map((f) => {
|
|
3447
3466
|
if (f === filter) {
|
|
3448
|
-
return __spreadProps$l(__spreadValues$x({}, f), { [prop]: value });
|
|
3467
|
+
return __spreadProps$l(__spreadValues$x({}, f), { [prop]: value, [propLabelKey]: label });
|
|
3449
3468
|
}
|
|
3450
3469
|
return f;
|
|
3451
3470
|
});
|
|
@@ -3504,7 +3523,9 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
|
3504
3523
|
return values.map(toSelectableValue);
|
|
3505
3524
|
}
|
|
3506
3525
|
_addWip() {
|
|
3507
|
-
this.setState({
|
|
3526
|
+
this.setState({
|
|
3527
|
+
_wip: { key: "", keyLabel: "", value: "", valueLabel: "", operator: "=", condition: "" }
|
|
3528
|
+
});
|
|
3508
3529
|
}
|
|
3509
3530
|
_getOperators() {
|
|
3510
3531
|
return ["=", "!=", "<", ">", "=~", "!~"].map((value) => ({
|