@grafana/scenes 4.18.0--canary.725.9002029358.0 → 4.18.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/CHANGELOG.md +37 -0
- package/dist/esm/core/SceneObjectBase.js +34 -8
- package/dist/esm/core/SceneObjectBase.js.map +1 -1
- package/dist/esm/querying/SceneDataTransformer.js +12 -40
- package/dist/esm/querying/SceneDataTransformer.js.map +1 -1
- package/dist/esm/querying/SceneQueryRunner.js +4 -2
- package/dist/esm/querying/SceneQueryRunner.js.map +1 -1
- package/dist/esm/variables/VariableValueRecorder.js +16 -7
- package/dist/esm/variables/VariableValueRecorder.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFilterRenderer.js +1 -0
- package/dist/esm/variables/adhoc/AdHocFilterRenderer.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFiltersVariable.js +10 -2
- package/dist/esm/variables/adhoc/AdHocFiltersVariable.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFiltersVariableUrlSyncHandler.js +3 -1
- package/dist/esm/variables/adhoc/AdHocFiltersVariableUrlSyncHandler.js.map +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.js +76 -58
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VariableValueRecorder.js","sources":["../../../src/variables/VariableValueRecorder.ts"],"sourcesContent":["import { sceneGraph } from '../core/sceneGraph';\nimport { SceneObject } from '../core/types';\nimport { SceneVariable, VariableValue } from './types';\nimport { isVariableValueEqual } from './utils';\n\n/**\n * Useful for remembering variable values to know if they have changed\n **/\nexport class VariableValueRecorder {\n private _values = new Map<
|
|
1
|
+
{"version":3,"file":"VariableValueRecorder.js","sources":["../../../src/variables/VariableValueRecorder.ts"],"sourcesContent":["import { sceneGraph } from '../core/sceneGraph';\nimport { SceneObject } from '../core/types';\nimport { SceneVariable, VariableValue } from './types';\nimport { isVariableValueEqual } from './utils';\n\n/**\n * Useful for remembering variable values to know if they have changed\n **/\nexport class VariableValueRecorder {\n private _values = new Map<string, VariableValue | undefined | null>();\n\n public recordCurrentDependencyValuesForSceneObject(sceneObject: SceneObject) {\n this.clearValues();\n\n if (!sceneObject.variableDependency) {\n return;\n }\n\n for (const variableName of sceneObject.variableDependency.getNames()) {\n const variable = sceneGraph.lookupVariable(variableName, sceneObject);\n if (variable) {\n this._values.set(variable.state.name, variable.getValue());\n }\n }\n }\n\n public cloneAndRecordCurrentValuesForSceneObject(sceneObject: SceneObject) {\n const clone = new VariableValueRecorder();\n clone.recordCurrentDependencyValuesForSceneObject(sceneObject);\n return clone;\n }\n\n public clearValues() {\n this._values.clear();\n }\n\n public hasValues(): boolean {\n return !!this._values;\n }\n\n public recordCurrentValue(variable: SceneVariable) {\n this._values.set(variable.state.name, variable.getValue());\n }\n\n public hasRecordedValue(variable: SceneVariable): boolean {\n return this._values.has(variable.state.name);\n }\n\n public hasValueChanged(variable: SceneVariable): boolean {\n if (this._values.has(variable.state.name)) {\n const value = this._values.get(variable.state.name);\n if (!isVariableValueEqual(value, variable.getValue())) {\n return true;\n }\n }\n\n return false;\n }\n\n public hasDependenciesChanged(sceneObject: SceneObject): boolean {\n if (!this._values) {\n return false;\n }\n\n if (!sceneObject.variableDependency) {\n return false;\n }\n\n for (const variableName of sceneObject.variableDependency.getNames()) {\n const variable = sceneGraph.lookupVariable(variableName, sceneObject);\n if (!variable) {\n continue;\n }\n\n const name = variable.state.name;\n\n if (variable && this._values.has(name)) {\n const value = this._values.get(name);\n if (!isVariableValueEqual(value, variable.getValue())) {\n return true;\n }\n }\n }\n\n return false;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -22,6 +22,7 @@ function AdHocFilterRenderer({ filter, model }) {
|
|
|
22
22
|
const valueValue = keyLabelToOption(filter.value, filter.valueLabel);
|
|
23
23
|
const valueSelect = /* @__PURE__ */ React.createElement(Select, {
|
|
24
24
|
allowCustomValue: true,
|
|
25
|
+
isValidNewOption: (inputValue) => inputValue.trim().length > 0,
|
|
25
26
|
allowCreateWhileLoading: true,
|
|
26
27
|
formatCreateLabel: (inputValue) => `Use custom value: ${inputValue}`,
|
|
27
28
|
disabled: model.state.readOnly,
|
|
@@ -1 +1 @@
|
|
|
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 const [keys, setKeys] = useState<SelectableValue[]>([]);\n const [values, setValues] = useState<SelectableValue[]>([]);\n const [isKeysLoading, setIsKeysLoading] = useState(false);\n const [isValuesLoading, setIsValuesLoading] = useState(false);\n const [isKeysOpen, setIsKeysOpen] = useState(false);\n const [isValuesOpen, setIsValuesOpen] = useState(false);\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 allowCreateWhileLoading\n formatCreateLabel={(inputValue) => `Use custom value: ${inputValue}`}\n disabled={model.state.readOnly}\n className={isKeysOpen ? styles.widthWhenOpen : undefined}\n width=\"auto\"\n value={valueValue}\n placeholder={'Select value'}\n options={values}\n onChange={(v) => model._updateFilter(filter, 'value', v)}\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 isOpen={isValuesOpen && !isValuesLoading}\n isLoading={isValuesLoading}\n autoFocus={filter.key !== '' && filter.value === ''}\n openMenuOnFocus={true}\n onOpenMenu={async () => {\n setIsValuesLoading(true);\n setIsValuesOpen(true);\n const values = await model._getValuesFor(filter);\n setIsValuesLoading(false);\n setValues(values);\n }}\n onCloseMenu={() => {\n setIsValuesOpen(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={`${isValuesLoading ? 'loading' : 'loaded'}`}\n disabled={model.state.readOnly}\n className={isKeysOpen ? styles.widthWhenOpen : undefined}\n width=\"auto\"\n value={keyValue}\n placeholder={'Select label'}\n options={keys}\n onChange={(v) => model._updateFilter(filter, 'key', v)}\n autoFocus={filter.key === ''}\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 isOpen={isKeysOpen && !isKeysLoading}\n isLoading={isKeysLoading}\n onOpenMenu={async () => {\n setIsKeysOpen(true);\n setIsKeysLoading(true);\n const keys = await model._getKeys(filter.key);\n setIsKeysLoading(false);\n setKeys(keys);\n }}\n onCloseMenu={() => {\n setIsKeysOpen(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":["values","keys"],"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 const [keys, setKeys] = useState<SelectableValue[]>([]);\n const [values, setValues] = useState<SelectableValue[]>([]);\n const [isKeysLoading, setIsKeysLoading] = useState(false);\n const [isValuesLoading, setIsValuesLoading] = useState(false);\n const [isKeysOpen, setIsKeysOpen] = useState(false);\n const [isValuesOpen, setIsValuesOpen] = useState(false);\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 isValidNewOption={(inputValue) => inputValue.trim().length > 0}\n allowCreateWhileLoading\n formatCreateLabel={(inputValue) => `Use custom value: ${inputValue}`}\n disabled={model.state.readOnly}\n className={isKeysOpen ? styles.widthWhenOpen : undefined}\n width=\"auto\"\n value={valueValue}\n placeholder={'Select value'}\n options={values}\n onChange={(v) => model._updateFilter(filter, 'value', v)}\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 isOpen={isValuesOpen && !isValuesLoading}\n isLoading={isValuesLoading}\n autoFocus={filter.key !== '' && filter.value === ''}\n openMenuOnFocus={true}\n onOpenMenu={async () => {\n setIsValuesLoading(true);\n setIsValuesOpen(true);\n const values = await model._getValuesFor(filter);\n setIsValuesLoading(false);\n setValues(values);\n }}\n onCloseMenu={() => {\n setIsValuesOpen(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={`${isValuesLoading ? 'loading' : 'loaded'}`}\n disabled={model.state.readOnly}\n className={isKeysOpen ? styles.widthWhenOpen : undefined}\n width=\"auto\"\n value={keyValue}\n placeholder={'Select label'}\n options={keys}\n onChange={(v) => model._updateFilter(filter, 'key', v)}\n autoFocus={filter.key === ''}\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 isOpen={isKeysOpen && !isKeysLoading}\n isLoading={isKeysLoading}\n onOpenMenu={async () => {\n setIsKeysOpen(true);\n setIsKeysLoading(true);\n const keys = await model._getKeys(filter.key);\n setIsKeysLoading(false);\n setKeys(keys);\n }}\n onCloseMenu={() => {\n setIsKeysOpen(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":["values","keys"],"mappings":"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"}
|
|
@@ -78,7 +78,12 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
|
78
78
|
}
|
|
79
79
|
const updatedFilters = this.state.filters.map((f) => {
|
|
80
80
|
if (f === filter) {
|
|
81
|
-
|
|
81
|
+
const updatedFilter = __spreadProps(__spreadValues({}, f), { [prop]: value, [propLabelKey]: label });
|
|
82
|
+
if (prop === "key" && filter[prop] !== value) {
|
|
83
|
+
updatedFilter.value = "";
|
|
84
|
+
updatedFilter.valueLabel = "";
|
|
85
|
+
}
|
|
86
|
+
return updatedFilter;
|
|
82
87
|
}
|
|
83
88
|
return f;
|
|
84
89
|
});
|
|
@@ -187,6 +192,9 @@ function toSelectableValue({ text, value }) {
|
|
|
187
192
|
value: String(value != null ? value : text)
|
|
188
193
|
};
|
|
189
194
|
}
|
|
195
|
+
function isFilterComplete(filter) {
|
|
196
|
+
return filter.key !== "" && filter.operator !== "" && filter.value !== "";
|
|
197
|
+
}
|
|
190
198
|
|
|
191
|
-
export { AdHocFiltersVariable, AdHocFiltersVariableRenderer, toSelectableValue };
|
|
199
|
+
export { AdHocFiltersVariable, AdHocFiltersVariableRenderer, isFilterComplete, toSelectableValue };
|
|
192
200
|
//# sourceMappingURL=AdHocFiltersVariable.js.map
|
|
@@ -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 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 * When querying the datasource for label names and values to determine keys and values \n * for this ad hoc filter, consider the queries in the scene and use them as a filter.\n * This queries filter can be used to ensure that only ad hoc filter options that would\n * impact the current queries are presented to the user.\n */\n useQueriesAsFilterForOptions?: boolean\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 = this.state.useQueriesAsFilterForOptions ? getQueriesForVariables(this) : undefined;\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 = this.state.useQueriesAsFilterForOptions ? getQueriesForVariables(this) : undefined;\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 flexWrap: 'wrap',\n alignItems: 'flex-end',\n columnGap: theme.spacing(2),\n rowGap: theme.spacing(1),\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyGO,MAAM,6BACH,eAEV,CAAA;AAAA,EAQS,YAAY,KAA2C,EAAA;AApHhE,IAAA,IAAA,EAAA,EAAA,EAAA,CAAA;AAqHI,IAAM,KAAA,CAAA,cAAA,CAAA;AAAA,MACJ,IAAM,EAAA,OAAA;AAAA,MACN,IAAA,EAAA,CAAM,EAAM,GAAA,KAAA,CAAA,IAAA,KAAN,IAAc,GAAA,EAAA,GAAA,SAAA;AAAA,MACpB,SAAS,EAAC;AAAA,MACV,UAAY,EAAA,IAAA;AAAA,MACZ,SAAW,EAAA,MAAA;AAAA,MACX,gBAAA,EAAA,CAAkB,WAAM,gBAAN,KAAA,IAAA,GAAA,EAAA,GAA0B,iBAAiB,KAAM,CAAA,iBAAA,EAAmB,MAAM,OAAO,CAAA;AAAA,KAAA,EAChG,KACJ,CAAA,CAAA,CAAA;AAdH,IAAA,IAAA,CAAQ,cAAc,EAAE,aAAA,EAAe,EAAE,KAAA,EAAO,MAAO,EAAA,CAAA;AACvD,IAAA,IAAA,CAAQ,iBAAiB,gBAAiB,EAAA,CAAA;AAE1C,IAAU,IAAA,CAAA,QAAA,GAAW,IAAI,kCAAA,CAAmC,IAAI,CAAA,CAAA;AAa9D,IAAI,IAAA,IAAA,CAAK,KAAM,CAAA,SAAA,KAAc,MAAQ,EAAA;AACnC,MAAA,oBAAA,CAAqB,IAAI,CAAA,CAAA;AAAA,KAC3B;AAAA,GACF;AAAA,EAEO,SAAS,MAAkD,EAAA;AAChE,IAAA,IAAI,uBAA0B,GAAA,KAAA,CAAA;AAE9B,IAAI,IAAA,MAAA,CAAO,WAAW,MAAO,CAAA,OAAA,KAAY,KAAK,KAAM,CAAA,OAAA,IAAW,CAAC,MAAA,CAAO,gBAAkB,EAAA;AACvF,MAAA,MAAA,CAAO,mBAAmB,gBAAiB,CAAA,IAAA,CAAK,KAAM,CAAA,iBAAA,EAAmB,OAAO,OAAO,CAAA,CAAA;AACvF,MAA0B,uBAAA,GAAA,MAAA,CAAO,gBAAqB,KAAA,IAAA,CAAK,KAAM,CAAA,gBAAA,CAAA;AAAA,KACnE;AAEA,IAAA,KAAA,CAAM,SAAS,MAAM,CAAA,CAAA;AAErB,IAAA,IAAI,uBAAyB,EAAA;AAC3B,MAAA,IAAA,CAAK,YAAa,CAAA,IAAI,8BAA+B,CAAA,IAAI,GAAG,IAAI,CAAA,CAAA;AAAA,KAClE;AAAA,GACF;AAAA,EAEO,QAAsC,GAAA;AAC3C,IAAA,OAAO,KAAK,KAAM,CAAA,gBAAA,CAAA;AAAA,GACpB;AAAA,EAEO,cACL,MACA,EAAA,IAAA,EACA,EAAE,KAAA,EAAO,OACT,EAAA;AACA,IAAA,IAAI,SAAS,IAAM,EAAA;AACjB,MAAA,OAAA;AAAA,KACF;AAEA,IAAA,MAAM,EAAE,OAAA,EAAS,IAAK,EAAA,GAAI,IAAK,CAAA,KAAA,CAAA;AAE/B,IAAA,MAAM,eAAe,CAAG,EAAA,IAAA,CAAA,KAAA,CAAA,CAAA;AAExB,IAAA,IAAI,WAAW,IAAM,EAAA;AAEnB,MAAA,IAAI,SAAS,OAAS,EAAA;AACpB,QAAA,IAAA,CAAK,SAAS,EAAE,OAAA,EAAS,CAAC,GAAG,OAAA,EAAS,iCAAK,IAAL,CAAA,EAAA,EAAW,CAAC,IAAO,GAAA,KAAA,EAAO,CAAC,YAAe,GAAA,KAAA,GAAO,CAAG,EAAA,IAAA,EAAM,QAAW,CAAA,CAAA;AAAA,OACtG,MAAA;AACL,QAAA,IAAA,CAAK,QAAS,CAAA,EAAE,IAAM,EAAA,aAAA,CAAA,cAAA,CAAA,EAAA,EAAK,MAAL,CAAA,EAAA,EAAa,CAAC,IAAA,GAAO,KAAO,EAAA,CAAC,YAAe,GAAA,KAAA,KAAS,CAAA,CAAA;AAAA,OAC7E;AACA,MAAA,OAAA;AAAA,KACF;AAEA,IAAA,MAAM,iBAAiB,IAAK,CAAA,KAAA,CAAM,OAAQ,CAAA,GAAA,CAAI,CAAC,CAAM,KAAA;AACnD,MAAA,IAAI,MAAM,MAAQ,EAAA;AAChB,QAAO,OAAA,aAAA,CAAA,cAAA,CAAA,EAAA,EAAK,IAAL,EAAQ,CAAC,OAAO,KAAO,EAAA,CAAC,eAAe,KAAM,EAAA,CAAA,CAAA;AAAA,OACtD;AACA,MAAO,OAAA,CAAA,CAAA;AAAA,KACR,CAAA,CAAA;AAED,IAAA,IAAA,CAAK,QAAS,CAAA,EAAE,OAAS,EAAA,cAAA,EAAgB,CAAA,CAAA;AAAA,GAC3C;AAAA,EAEO,cAAc,MAA+B,EAAA;AAClD,IAAI,IAAA,MAAA,KAAW,IAAK,CAAA,KAAA,CAAM,IAAM,EAAA;AAC9B,MAAA,IAAA,CAAK,QAAS,CAAA,EAAE,IAAM,EAAA,KAAA,CAAA,EAAW,CAAA,CAAA;AACjC,MAAA,OAAA;AAAA,KACF;AAEA,IAAA,IAAA,CAAK,QAAS,CAAA,EAAE,OAAS,EAAA,IAAA,CAAK,KAAM,CAAA,OAAA,CAAQ,MAAO,CAAA,CAAC,CAAM,KAAA,CAAA,KAAM,MAAM,CAAA,EAAG,CAAA,CAAA;AAAA,GAC3E;AAAA,EAKA,MAAa,SAAS,UAAoE,EAAA;AApM5F,IAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,CAAA;AAqMI,IAAA,MAAM,WAAW,OAAM,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,IAAA,CAAK,KAAM,EAAA,kBAAA,KAAX,4BAAgC,IAAM,EAAA,UAAA,CAAA,CAAA,CAAA;AAE7D,IAAI,IAAA,QAAA,IAAY,SAAS,OAAS,EAAA;AAChC,MAAO,OAAA,QAAA,CAAS,MAAO,CAAA,GAAA,CAAI,iBAAiB,CAAA,CAAA;AAAA,KAC9C;AAEA,IAAI,IAAA,IAAA,CAAK,MAAM,WAAa,EAAA;AAC1B,MAAA,OAAO,IAAK,CAAA,KAAA,CAAM,WAAY,CAAA,GAAA,CAAI,iBAAiB,CAAA,CAAA;AAAA,KACrD;AAEA,IAAM,MAAA,EAAA,GAAK,MAAM,IAAK,CAAA,cAAA,CAAe,IAAI,IAAK,CAAA,KAAA,CAAM,UAAY,EAAA,IAAA,CAAK,WAAW,CAAA,CAAA;AAChF,IAAA,IAAI,CAAC,EAAA,IAAM,CAAC,EAAA,CAAG,UAAY,EAAA;AACzB,MAAA,OAAO,EAAC,CAAA;AAAA,KACV;AAEA,IAAA,MAAM,eAAe,IAAK,CAAA,KAAA,CAAM,OAAQ,CAAA,MAAA,CAAO,CAAC,CAAM,KAAA,CAAA,CAAE,GAAQ,KAAA,UAAU,EAAE,MAAO,CAAA,CAAA,EAAA,GAAA,IAAA,CAAK,MAAM,WAAX,KAAA,IAAA,GAAA,EAAA,GAA0B,EAAE,CAAA,CAAA;AAC/G,IAAA,MAAM,SAAY,GAAA,UAAA,CAAW,YAAa,CAAA,IAAI,EAAE,KAAM,CAAA,KAAA,CAAA;AACtD,IAAA,MAAM,UAAU,IAAK,CAAA,KAAA,CAAM,4BAA+B,GAAA,sBAAA,CAAuB,IAAI,CAAI,GAAA,KAAA,CAAA,CAAA;AACzF,IAAI,IAAA,IAAA,GAAO,MAAM,EAAG,CAAA,UAAA,CAAW,EAAE,OAAS,EAAA,YAAA,EAAc,OAAS,EAAA,SAAA,EAAW,CAAA,CAAA;AAE5E,IAAA,IAAI,QAAU,EAAA;AACZ,MAAO,IAAA,GAAA,IAAA,CAAK,MAAO,CAAA,QAAA,CAAS,MAAM,CAAA,CAAA;AAAA,KACpC;AAEA,IAAM,MAAA,iBAAA,GAAoB,KAAK,KAAM,CAAA,iBAAA,CAAA;AACrC,IAAA,IAAI,iBAAmB,EAAA;AACrB,MAAO,IAAA,GAAA,IAAA,CAAK,OAAO,CAAC,CAAA,KAAM,EAAE,IAAK,CAAA,KAAA,CAAM,iBAAiB,CAAC,CAAA,CAAA;AAAA,KAC3D;AAEA,IAAO,OAAA,IAAA,CAAK,IAAI,iBAAiB,CAAA,CAAA;AAAA,GACnC;AAAA,EAKA,MAAa,cAAc,MAAwE,EAAA;AAxOrG,IAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,CAAA;AAyOI,IAAA,MAAM,WAAW,OAAM,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,IAAA,CAAK,KAAM,EAAA,oBAAA,KAAX,4BAAkC,IAAM,EAAA,MAAA,CAAA,CAAA,CAAA;AAE/D,IAAI,IAAA,QAAA,IAAY,SAAS,OAAS,EAAA;AAChC,MAAO,OAAA,QAAA,CAAS,MAAO,CAAA,GAAA,CAAI,iBAAiB,CAAA,CAAA;AAAA,KAC9C;AAEA,IAAM,MAAA,EAAA,GAAK,MAAM,IAAK,CAAA,cAAA,CAAe,IAAI,IAAK,CAAA,KAAA,CAAM,UAAY,EAAA,IAAA,CAAK,WAAW,CAAA,CAAA;AAEhF,IAAA,IAAI,CAAC,EAAA,IAAM,CAAC,EAAA,CAAG,YAAc,EAAA;AAC3B,MAAA,OAAO,EAAC,CAAA;AAAA,KACV;AAGA,IAAA,MAAM,eAAe,IAAK,CAAA,KAAA,CAAM,QAAQ,MAAO,CAAA,CAAC,MAAM,CAAE,CAAA,GAAA,KAAQ,MAAO,CAAA,GAAG,EAAE,MAAO,CAAA,CAAA,EAAA,GAAA,IAAA,CAAK,MAAM,WAAX,KAAA,IAAA,GAAA,EAAA,GAA0B,EAAE,CAAA,CAAA;AAE/G,IAAA,MAAM,SAAY,GAAA,UAAA,CAAW,YAAa,CAAA,IAAI,EAAE,KAAM,CAAA,KAAA,CAAA;AACtD,IAAA,MAAM,UAAU,IAAK,CAAA,KAAA,CAAM,4BAA+B,GAAA,sBAAA,CAAuB,IAAI,CAAI,GAAA,KAAA,CAAA,CAAA;AAEzF,IAAA,IAAI,MAAS,GAAA,MAAM,EAAG,CAAA,YAAA,CAAa,EAAE,GAAA,EAAK,MAAO,CAAA,GAAA,EAAK,OAAS,EAAA,YAAA,EAAc,SAAW,EAAA,OAAA,EAAS,CAAA,CAAA;AAEjG,IAAA,IAAI,QAAU,EAAA;AACZ,MAAS,MAAA,GAAA,MAAA,CAAO,MAAO,CAAA,QAAA,CAAS,MAAM,CAAA,CAAA;AAAA,KACxC;AAEA,IAAO,OAAA,MAAA,CAAO,IAAI,iBAAiB,CAAA,CAAA;AAAA,GACrC;AAAA,EAEO,OAAU,GAAA;AACf,IAAA,IAAA,CAAK,QAAS,CAAA;AAAA,MACZ,IAAM,EAAA,EAAE,GAAK,EAAA,EAAA,EAAI,QAAU,EAAA,EAAA,EAAI,KAAO,EAAA,EAAA,EAAI,UAAY,EAAA,EAAA,EAAI,QAAU,EAAA,GAAA,EAAK,WAAW,EAAG,EAAA;AAAA,KACxF,CAAA,CAAA;AAAA,GACH;AAAA,EAEO,aAAgB,GAAA;AACrB,IAAO,OAAA,CAAC,GAAK,EAAA,IAAA,EAAM,GAAK,EAAA,GAAA,EAAK,MAAM,IAAI,CAAA,CAAE,GAA6B,CAAA,CAAC,KAAW,MAAA;AAAA,MAChF,KAAO,EAAA,KAAA;AAAA,MACP,KAAA;AAAA,KACA,CAAA,CAAA,CAAA;AAAA,GACJ;AACF,CAAA;AAvKa,oBAAA,CAIJ,SAAY,GAAA,4BAAA,CAAA;AAqKrB,SAAS,gBAAA,CACP,SACA,OACA,EAAA;AACA,EAAA,OAAA,CAAQ,OAAW,IAAA,IAAA,GAAA,OAAA,GAAA,4BAAA,EAA8B,OAAW,IAAA,IAAA,GAAA,OAAA,GAAA,EAAE,CAAA,CAAA;AAChE,CAAA;AAEgB,SAAA,4BAAA,CAA6B,EAAE,KAAA,EAAoD,EAAA;AACjG,EAAA,MAAM,EAAE,OAAS,EAAA,QAAA,EAAU,mBAAoB,EAAA,GAAI,MAAM,QAAS,EAAA,CAAA;AAClE,EAAM,MAAA,MAAA,GAAS,WAAW,SAAS,CAAA,CAAA;AAEnC,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,IAAI,WAAW,MAAO,CAAA,OAAA;AAAA,GAAA,EACpB,QAAQ,GAAI,CAAA,CAAC,QAAQ,KACpB,qBAAA,KAAA,CAAA,aAAA,CAAC,MAAM,QAAN,EAAA;AAAA,IAAe,GAAK,EAAA,KAAA;AAAA,GAAA,kBAClB,KAAA,CAAA,aAAA,CAAA,mBAAA,EAAA;AAAA,IAAoB,MAAA;AAAA,IAAgB,KAAA;AAAA,GAAc,CACrD,CACD,CAEA,EAAA,CAAC,4BAAa,KAAA,CAAA,aAAA,CAAA,kBAAA,EAAA;AAAA,IAAmB,KAAA;AAAA,IAAc,GAAI,EAAA,UAAA;AAAA,IAAW,mBAAA;AAAA,GAA0C,CAC3G,CAAA,CAAA;AAEJ,CAAA;AAEA,MAAM,SAAA,GAAY,CAAC,KAA0B,MAAA;AAAA,EAC3C,SAAS,GAAI,CAAA;AAAA,IACX,OAAS,EAAA,MAAA;AAAA,IACT,QAAU,EAAA,MAAA;AAAA,IACV,UAAY,EAAA,UAAA;AAAA,IACZ,SAAA,EAAW,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IAC1B,MAAA,EAAQ,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,GACxB,CAAA;AAAA,EACD,YAAY,GAAI,CAAA;AAAA,IACd,KAAA,EAAO,KAAM,CAAA,MAAA,CAAO,IAAK,CAAA,SAAA;AAAA,IACzB,YAAA,EAAc,KAAM,CAAA,OAAA,CAAQ,GAAG,CAAA;AAAA,GAChC,CAAA;AACH,CAAA,CAAA,CAAA;AAEO,SAAS,iBAAkB,CAAA,EAAE,IAAM,EAAA,KAAA,EAAmD,EAAA;AAC3F,EAAO,OAAA;AAAA,IACL,KAAO,EAAA,IAAA;AAAA,IACP,KAAA,EAAO,MAAO,CAAA,KAAA,IAAA,IAAA,GAAA,KAAA,GAAS,IAAI,CAAA;AAAA,GAC7B,CAAA;AACF;;;;"}
|
|
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 * When querying the datasource for label names and values to determine keys and values \n * for this ad hoc filter, consider the queries in the scene and use them as a filter.\n * This queries filter can be used to ensure that only ad hoc filter options that would\n * impact the current queries are presented to the user.\n */\n useQueriesAsFilterForOptions?: boolean\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 const updatedFilter = { ...f, [prop]: value, [propLabelKey]: label };\n\n // clear value if key has changed\n if (prop === 'key' && filter[prop] !== value) {\n updatedFilter.value = '';\n updatedFilter.valueLabel = '';\n }\n return updatedFilter;\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 = this.state.useQueriesAsFilterForOptions ? getQueriesForVariables(this) : undefined;\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 = this.state.useQueriesAsFilterForOptions ? getQueriesForVariables(this) : undefined;\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 flexWrap: 'wrap',\n alignItems: 'flex-end',\n columnGap: theme.spacing(2),\n rowGap: theme.spacing(1),\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\nexport function isFilterComplete(filter: AdHocFilterWithLabels): boolean {\n return filter.key !== \"\" && filter.operator !== \"\" && filter.value !== \"\";\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { isFilterComplete } from './AdHocFiltersVariable.js';
|
|
2
|
+
|
|
1
3
|
class AdHocFiltersVariableUrlSyncHandler {
|
|
2
4
|
constructor(_variable) {
|
|
3
5
|
this._variable = _variable;
|
|
@@ -13,7 +15,7 @@ class AdHocFiltersVariableUrlSyncHandler {
|
|
|
13
15
|
if (filters.length === 0) {
|
|
14
16
|
return { [this.getKey()]: [""] };
|
|
15
17
|
}
|
|
16
|
-
const value = filters.map((filter) => toArray(filter).map(escapePipeDelimiters).join("|"));
|
|
18
|
+
const value = filters.filter(isFilterComplete).map((filter) => toArray(filter).map(escapePipeDelimiters).join("|"));
|
|
17
19
|
return { [this.getKey()]: value };
|
|
18
20
|
}
|
|
19
21
|
updateFromUrl(values) {
|
|
@@ -1 +1 @@
|
|
|
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":"AAGO,MAAM,kCAAwE,CAAA;AAAA,EAC5E,YAAoB,SAAiC,EAAA;AAAjC,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA,CAAA;AAAA,GAAkC;AAAA,EAErD,MAAiB,GAAA;AACvB,IAAO,OAAA,CAAA,IAAA,EAAO,IAAK,CAAA,SAAA,CAAU,KAAM,CAAA,IAAA,CAAA,CAAA,CAAA;AAAA,GACrC;AAAA,EAEO,OAAoB,GAAA;AACzB,IAAO,OAAA,CAAC,IAAK,CAAA,MAAA,EAAQ,CAAA,CAAA;AAAA,GACvB;AAAA,EAEO,WAAoC,GAAA;AACzC,IAAM,MAAA,OAAA,GAAU,IAAK,CAAA,SAAA,CAAU,KAAM,CAAA,OAAA,CAAA;AAErC,IAAI,IAAA,OAAA,CAAQ,WAAW,CAAG,EAAA;AACxB,MAAA,OAAO,EAAE,CAAC,IAAA,CAAK,QAAW,GAAA,CAAC,EAAE,CAAE,EAAA,CAAA;AAAA,KACjC;AAEA,IAAA,MAAM,
|
|
1
|
+
{"version":3,"file":"AdHocFiltersVariableUrlSyncHandler.js","sources":["../../../../src/variables/adhoc/AdHocFiltersVariableUrlSyncHandler.ts"],"sourcesContent":["import { SceneObjectUrlSyncHandler, SceneObjectUrlValue, SceneObjectUrlValues } from '../../core/types';\nimport { AdHocFiltersVariable, AdHocFilterWithLabels, isFilterComplete } 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.filter(isFilterComplete).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
|
@@ -375,9 +375,11 @@ declare abstract class SceneObjectBase<TState extends SceneObjectState = SceneOb
|
|
|
375
375
|
*/
|
|
376
376
|
private _handleActivationOfChangedStateProps;
|
|
377
377
|
private _handleChangedStateActivation;
|
|
378
|
+
private _handleChangedBehaviors;
|
|
378
379
|
publishEvent(event: BusEvent, bubble?: boolean): void;
|
|
379
380
|
getRoot(): SceneObject;
|
|
380
381
|
private _internalActivate;
|
|
382
|
+
private _activateBehavior;
|
|
381
383
|
/**
|
|
382
384
|
* This is primarily called from SceneComponentWrapper when the SceneObject's Component is mounted.
|
|
383
385
|
* But in some scenarios this can also be called directly from another scene object. When called manually from another scene object
|
|
@@ -1360,7 +1362,6 @@ interface SceneDataTransformerState extends SceneDataState {
|
|
|
1360
1362
|
declare class SceneDataTransformer extends SceneObjectBase<SceneDataTransformerState> implements SceneDataProvider {
|
|
1361
1363
|
private _transformSub?;
|
|
1362
1364
|
private _results;
|
|
1363
|
-
private _prevDataFromSource?;
|
|
1364
1365
|
/**
|
|
1365
1366
|
* Scan transformations for variable usage and re-process transforms when a variable values change
|
|
1366
1367
|
*/
|
|
@@ -1373,8 +1374,6 @@ declare class SceneDataTransformer extends SceneObjectBase<SceneDataTransformerS
|
|
|
1373
1374
|
reprocessTransformations(): void;
|
|
1374
1375
|
cancelQuery(): void;
|
|
1375
1376
|
getResultsStream(): ReplaySubject<SceneDataProviderResult>;
|
|
1376
|
-
clone(withState?: Partial<SceneDataTransformerState>): this;
|
|
1377
|
-
private haveAlreadyTransformedData;
|
|
1378
1377
|
private transform;
|
|
1379
1378
|
}
|
|
1380
1379
|
|
package/dist/index.js
CHANGED
|
@@ -306,6 +306,9 @@ class SceneObjectBase {
|
|
|
306
306
|
if (!this.isActive) {
|
|
307
307
|
return;
|
|
308
308
|
}
|
|
309
|
+
if (prevState.$behaviors !== newState.$behaviors) {
|
|
310
|
+
this._handleChangedBehaviors(prevState.$behaviors, newState.$behaviors);
|
|
311
|
+
}
|
|
309
312
|
if (prevState.$data !== newState.$data) {
|
|
310
313
|
this._handleChangedStateActivation(prevState.$data, newState.$data);
|
|
311
314
|
}
|
|
@@ -328,6 +331,26 @@ class SceneObjectBase {
|
|
|
328
331
|
this._deactivationHandlers.set(newValue, newValue.activate());
|
|
329
332
|
}
|
|
330
333
|
}
|
|
334
|
+
_handleChangedBehaviors(oldValue, newValue) {
|
|
335
|
+
if (oldValue) {
|
|
336
|
+
for (const oldBehavior of oldValue) {
|
|
337
|
+
if (!newValue || !newValue.includes(oldBehavior)) {
|
|
338
|
+
const deactivationHandler = this._deactivationHandlers.get(oldBehavior);
|
|
339
|
+
if (deactivationHandler) {
|
|
340
|
+
deactivationHandler();
|
|
341
|
+
this._deactivationHandlers.delete(oldBehavior);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
if (newValue) {
|
|
347
|
+
for (const newBehavior of newValue) {
|
|
348
|
+
if (!oldValue || !oldValue.includes(newBehavior)) {
|
|
349
|
+
this._activateBehavior(newBehavior);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
331
354
|
publishEvent(event, bubble) {
|
|
332
355
|
this._events.publish(event);
|
|
333
356
|
if (bubble && this.parent) {
|
|
@@ -357,14 +380,17 @@ class SceneObjectBase {
|
|
|
357
380
|
}
|
|
358
381
|
if ($behaviors) {
|
|
359
382
|
for (const behavior of $behaviors) {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
383
|
+
this._activateBehavior(behavior);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
_activateBehavior(behavior) {
|
|
388
|
+
if (behavior instanceof SceneObjectBase) {
|
|
389
|
+
this._deactivationHandlers.set(behavior, behavior.activate());
|
|
390
|
+
} else if (typeof behavior === "function") {
|
|
391
|
+
const deactivate = behavior(this);
|
|
392
|
+
if (deactivate) {
|
|
393
|
+
this._deactivationHandlers.set(behavior, deactivate);
|
|
368
394
|
}
|
|
369
395
|
}
|
|
370
396
|
}
|
|
@@ -2146,10 +2172,15 @@ class VariableValueRecorder {
|
|
|
2146
2172
|
for (const variableName of sceneObject.variableDependency.getNames()) {
|
|
2147
2173
|
const variable = sceneGraph.lookupVariable(variableName, sceneObject);
|
|
2148
2174
|
if (variable) {
|
|
2149
|
-
this._values.set(variable, variable.getValue());
|
|
2175
|
+
this._values.set(variable.state.name, variable.getValue());
|
|
2150
2176
|
}
|
|
2151
2177
|
}
|
|
2152
2178
|
}
|
|
2179
|
+
cloneAndRecordCurrentValuesForSceneObject(sceneObject) {
|
|
2180
|
+
const clone = new VariableValueRecorder();
|
|
2181
|
+
clone.recordCurrentDependencyValuesForSceneObject(sceneObject);
|
|
2182
|
+
return clone;
|
|
2183
|
+
}
|
|
2153
2184
|
clearValues() {
|
|
2154
2185
|
this._values.clear();
|
|
2155
2186
|
}
|
|
@@ -2157,14 +2188,14 @@ class VariableValueRecorder {
|
|
|
2157
2188
|
return !!this._values;
|
|
2158
2189
|
}
|
|
2159
2190
|
recordCurrentValue(variable) {
|
|
2160
|
-
this._values.set(variable, variable.getValue());
|
|
2191
|
+
this._values.set(variable.state.name, variable.getValue());
|
|
2161
2192
|
}
|
|
2162
2193
|
hasRecordedValue(variable) {
|
|
2163
|
-
return this._values.has(variable);
|
|
2194
|
+
return this._values.has(variable.state.name);
|
|
2164
2195
|
}
|
|
2165
2196
|
hasValueChanged(variable) {
|
|
2166
|
-
if (this._values.has(variable)) {
|
|
2167
|
-
const value = this._values.get(variable);
|
|
2197
|
+
if (this._values.has(variable.state.name)) {
|
|
2198
|
+
const value = this._values.get(variable.state.name);
|
|
2168
2199
|
if (!isVariableValueEqual(value, variable.getValue())) {
|
|
2169
2200
|
return true;
|
|
2170
2201
|
}
|
|
@@ -2180,8 +2211,12 @@ class VariableValueRecorder {
|
|
|
2180
2211
|
}
|
|
2181
2212
|
for (const variableName of sceneObject.variableDependency.getNames()) {
|
|
2182
2213
|
const variable = sceneGraph.lookupVariable(variableName, sceneObject);
|
|
2183
|
-
if (variable
|
|
2184
|
-
|
|
2214
|
+
if (!variable) {
|
|
2215
|
+
continue;
|
|
2216
|
+
}
|
|
2217
|
+
const name = variable.state.name;
|
|
2218
|
+
if (variable && this._values.has(name)) {
|
|
2219
|
+
const value = this._values.get(name);
|
|
2185
2220
|
if (!isVariableValueEqual(value, variable.getValue())) {
|
|
2186
2221
|
return true;
|
|
2187
2222
|
}
|
|
@@ -3325,6 +3360,7 @@ function AdHocFilterRenderer({ filter, model }) {
|
|
|
3325
3360
|
const valueValue = keyLabelToOption(filter.value, filter.valueLabel);
|
|
3326
3361
|
const valueSelect = /* @__PURE__ */ React__default["default"].createElement(ui.Select, {
|
|
3327
3362
|
allowCustomValue: true,
|
|
3363
|
+
isValidNewOption: (inputValue) => inputValue.trim().length > 0,
|
|
3328
3364
|
allowCreateWhileLoading: true,
|
|
3329
3365
|
formatCreateLabel: (inputValue) => `Use custom value: ${inputValue}`,
|
|
3330
3366
|
disabled: model.state.readOnly,
|
|
@@ -3493,7 +3529,7 @@ class AdHocFiltersVariableUrlSyncHandler {
|
|
|
3493
3529
|
if (filters.length === 0) {
|
|
3494
3530
|
return { [this.getKey()]: [""] };
|
|
3495
3531
|
}
|
|
3496
|
-
const value = filters.map((filter) => toArray(filter).map(escapePipeDelimiters).join("|"));
|
|
3532
|
+
const value = filters.filter(isFilterComplete).map((filter) => toArray(filter).map(escapePipeDelimiters).join("|"));
|
|
3497
3533
|
return { [this.getKey()]: value };
|
|
3498
3534
|
}
|
|
3499
3535
|
updateFromUrl(values) {
|
|
@@ -3635,7 +3671,12 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
|
3635
3671
|
}
|
|
3636
3672
|
const updatedFilters = this.state.filters.map((f) => {
|
|
3637
3673
|
if (f === filter) {
|
|
3638
|
-
|
|
3674
|
+
const updatedFilter = __spreadProps$l(__spreadValues$x({}, f), { [prop]: value, [propLabelKey]: label });
|
|
3675
|
+
if (prop === "key" && filter[prop] !== value) {
|
|
3676
|
+
updatedFilter.value = "";
|
|
3677
|
+
updatedFilter.valueLabel = "";
|
|
3678
|
+
}
|
|
3679
|
+
return updatedFilter;
|
|
3639
3680
|
}
|
|
3640
3681
|
return f;
|
|
3641
3682
|
});
|
|
@@ -3744,6 +3785,9 @@ function toSelectableValue({ text, value }) {
|
|
|
3744
3785
|
value: String(value != null ? value : text)
|
|
3745
3786
|
};
|
|
3746
3787
|
}
|
|
3788
|
+
function isFilterComplete(filter) {
|
|
3789
|
+
return filter.key !== "" && filter.operator !== "" && filter.value !== "";
|
|
3790
|
+
}
|
|
3747
3791
|
|
|
3748
3792
|
function mergeMultipleDataLayers(layers) {
|
|
3749
3793
|
const resultStreams = layers.map((l) => l.getResultsStream());
|
|
@@ -3823,7 +3867,7 @@ class SceneQueryRunner extends SceneObjectBase {
|
|
|
3823
3867
|
queryCachingTTL: this.state.queryCachingTTL
|
|
3824
3868
|
}, getEnrichedDataRequest(this));
|
|
3825
3869
|
if (this._adhocFiltersVar) {
|
|
3826
|
-
request.filters = this._adhocFiltersVar.state.filters;
|
|
3870
|
+
request.filters = this._adhocFiltersVar.state.filters.filter(isFilterComplete);
|
|
3827
3871
|
}
|
|
3828
3872
|
if (this._groupByVar) {
|
|
3829
3873
|
request.groupByKeys = this._groupByVar.state.value;
|
|
@@ -4119,6 +4163,8 @@ class SceneQueryRunner extends SceneObjectBase {
|
|
|
4119
4163
|
if (this._layerAnnotations) {
|
|
4120
4164
|
clone["_layerAnnotations"] = this._layerAnnotations.map((frame) => __spreadValues$w({}, frame));
|
|
4121
4165
|
}
|
|
4166
|
+
clone["_variableValueRecorder"] = this._variableValueRecorder.cloneAndRecordCurrentValuesForSceneObject(this);
|
|
4167
|
+
clone["_containerWidth"] = this._containerWidth;
|
|
4122
4168
|
clone["_results"].next({ origin: this, data: (_a = this.state.data) != null ? _a : emptyPanelData });
|
|
4123
4169
|
return clone;
|
|
4124
4170
|
}
|
|
@@ -6108,7 +6154,7 @@ class SceneDataTransformer extends SceneObjectBase {
|
|
|
6108
6154
|
return true;
|
|
6109
6155
|
}
|
|
6110
6156
|
reprocessTransformations() {
|
|
6111
|
-
this.transform(this.getSourceData().state.data
|
|
6157
|
+
this.transform(this.getSourceData().state.data);
|
|
6112
6158
|
}
|
|
6113
6159
|
cancelQuery() {
|
|
6114
6160
|
var _a, _b;
|
|
@@ -6117,42 +6163,8 @@ class SceneDataTransformer extends SceneObjectBase {
|
|
|
6117
6163
|
getResultsStream() {
|
|
6118
6164
|
return this._results;
|
|
6119
6165
|
}
|
|
6120
|
-
|
|
6121
|
-
const clone = super.clone(withState);
|
|
6122
|
-
if (this._prevDataFromSource) {
|
|
6123
|
-
clone["_prevDataFromSource"] = this._prevDataFromSource;
|
|
6124
|
-
}
|
|
6125
|
-
return clone;
|
|
6126
|
-
}
|
|
6127
|
-
haveAlreadyTransformedData(data) {
|
|
6128
|
-
if (!this._prevDataFromSource) {
|
|
6129
|
-
return false;
|
|
6130
|
-
}
|
|
6131
|
-
if (data === this._prevDataFromSource) {
|
|
6132
|
-
return true;
|
|
6133
|
-
}
|
|
6134
|
-
const { series, annotations } = this._prevDataFromSource;
|
|
6135
|
-
if (data.series === series && data.annotations === annotations) {
|
|
6136
|
-
if (this.state.data && data.state !== this.state.data.state) {
|
|
6137
|
-
this.setState({ data: __spreadProps$a(__spreadValues$k({}, this.state.data), { state: data.state }) });
|
|
6138
|
-
}
|
|
6139
|
-
return true;
|
|
6140
|
-
}
|
|
6141
|
-
return false;
|
|
6142
|
-
}
|
|
6143
|
-
transform(data$1, force = false) {
|
|
6166
|
+
transform(data$1) {
|
|
6144
6167
|
var _a;
|
|
6145
|
-
if (this.state.transformations.length === 0 || !data$1) {
|
|
6146
|
-
this._prevDataFromSource = data$1;
|
|
6147
|
-
this.setState({ data: data$1 });
|
|
6148
|
-
if (data$1) {
|
|
6149
|
-
this._results.next({ origin: this, data: data$1 });
|
|
6150
|
-
}
|
|
6151
|
-
return;
|
|
6152
|
-
}
|
|
6153
|
-
if (!force && this.haveAlreadyTransformedData(data$1)) {
|
|
6154
|
-
return;
|
|
6155
|
-
}
|
|
6156
6168
|
const seriesTransformations = this.state.transformations.filter((transformation) => {
|
|
6157
6169
|
if ("options" in transformation || "topic" in transformation) {
|
|
6158
6170
|
return transformation.topic == null || transformation.topic === data.DataTopic.Series;
|
|
@@ -6165,6 +6177,13 @@ class SceneDataTransformer extends SceneObjectBase {
|
|
|
6165
6177
|
}
|
|
6166
6178
|
return false;
|
|
6167
6179
|
}).map((transformation) => "operator" in transformation ? transformation.operator : transformation);
|
|
6180
|
+
if (this.state.transformations.length === 0 || !data$1) {
|
|
6181
|
+
this.setState({ data: data$1 });
|
|
6182
|
+
if (data$1) {
|
|
6183
|
+
this._results.next({ origin: this, data: data$1 });
|
|
6184
|
+
}
|
|
6185
|
+
return;
|
|
6186
|
+
}
|
|
6168
6187
|
if (this._transformSub) {
|
|
6169
6188
|
this._transformSub.unsubscribe();
|
|
6170
6189
|
}
|
|
@@ -6199,10 +6218,9 @@ class SceneDataTransformer extends SceneObjectBase {
|
|
|
6199
6218
|
});
|
|
6200
6219
|
return rxjs.of(result);
|
|
6201
6220
|
})
|
|
6202
|
-
).subscribe((
|
|
6203
|
-
this.setState({ data:
|
|
6204
|
-
this._results.next({ origin: this, data:
|
|
6205
|
-
this._prevDataFromSource = data$1;
|
|
6221
|
+
).subscribe((data2) => {
|
|
6222
|
+
this.setState({ data: data2 });
|
|
6223
|
+
this._results.next({ origin: this, data: data2 });
|
|
6206
6224
|
});
|
|
6207
6225
|
}
|
|
6208
6226
|
}
|