@grafana/scenes 7.3.0 → 7.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersComboboxRenderer.js +2 -1
- package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersComboboxRenderer.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFiltersRecommendations.js +142 -17
- package/dist/esm/variables/adhoc/AdHocFiltersRecommendations.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFiltersVariable.js +9 -6
- package/dist/esm/variables/adhoc/AdHocFiltersVariable.js.map +1 -1
- package/dist/esm/variables/components/DrilldownRecommendations.js +1 -1
- package/dist/esm/variables/components/DrilldownRecommendations.js.map +1 -1
- package/dist/index.d.ts +14 -2
- package/dist/index.js +834 -706
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -7820,806 +7820,931 @@ const getStyles$d = (theme) => ({
|
|
|
7820
7820
|
})
|
|
7821
7821
|
});
|
|
7822
7822
|
|
|
7823
|
-
|
|
7824
|
-
const MAX_VISIBLE_FILTERS_WITH_GROUP_BY = 2;
|
|
7825
|
-
const MAX_VISIBLE_GROUP_BY = 2;
|
|
7826
|
-
const AdHocFiltersComboboxRenderer = React.memo(function AdHocFiltersComboboxRenderer2({ controller }) {
|
|
7827
|
-
var _a;
|
|
7828
|
-
const { originFilters, filters, readOnly, collapsible, valueRecommendations, enableGroupBy, groupByRestorable } = controller.useState();
|
|
7823
|
+
function DrilldownRecommendations({ recentDrilldowns, recommendedDrilldowns, showRecommended = false }) {
|
|
7829
7824
|
const styles = ui.useStyles2(getStyles$c);
|
|
7830
|
-
const
|
|
7831
|
-
const
|
|
7832
|
-
const
|
|
7833
|
-
|
|
7834
|
-
var _a2;
|
|
7835
|
-
(_a2 = controller.clearAll) == null ? void 0 : _a2.call(controller);
|
|
7836
|
-
};
|
|
7837
|
-
const focusOnWipInputRef = React.useRef();
|
|
7838
|
-
const focusOnGroupByWipInputRef = React.useRef();
|
|
7839
|
-
const singleLineThreshold = theme.spacing.gridSize * 5;
|
|
7840
|
-
const isMultiLine = collapsible && wrapperHeight > singleLineThreshold;
|
|
7841
|
-
const handleCollapseToggle = (event) => {
|
|
7842
|
-
event.stopPropagation();
|
|
7843
|
-
if (collapsible) {
|
|
7844
|
-
setCollapsed(true);
|
|
7845
|
-
}
|
|
7825
|
+
const [isPopoverVisible, setPopoverVisible] = React.useState(false);
|
|
7826
|
+
const ref = React.useRef(null);
|
|
7827
|
+
const openPopover = () => {
|
|
7828
|
+
setPopoverVisible(true);
|
|
7846
7829
|
};
|
|
7847
|
-
const
|
|
7848
|
-
|
|
7849
|
-
|
|
7850
|
-
}
|
|
7830
|
+
const onClickAction = (action) => {
|
|
7831
|
+
action();
|
|
7832
|
+
setPopoverVisible(false);
|
|
7851
7833
|
};
|
|
7852
|
-
const
|
|
7853
|
-
const visibleFilters = filters.filter((f) => !f.hidden);
|
|
7854
|
-
const allFilters = [...visibleOriginFilters, ...visibleFilters];
|
|
7855
|
-
const totalFiltersCount = allFilters.length;
|
|
7856
|
-
const adhocFilters = allFilters.filter((f) => !isGroupByFilter(f));
|
|
7857
|
-
const groupByFilters = allFilters.filter(isGroupByFilter);
|
|
7858
|
-
const shouldCollapse = collapsible && collapsed && totalFiltersCount > 0;
|
|
7859
|
-
const maxVisibleAdhocFilters = enableGroupBy ? MAX_VISIBLE_FILTERS_WITH_GROUP_BY : MAX_VISIBLE_FILTERS_DEFAULT;
|
|
7860
|
-
const adhocFiltersToRender = shouldCollapse ? adhocFilters.slice(0, maxVisibleAdhocFilters) : adhocFilters;
|
|
7861
|
-
const adhocHiddenCount = shouldCollapse ? Math.max(0, adhocFilters.length - maxVisibleAdhocFilters) : 0;
|
|
7862
|
-
const groupByFiltersToRender = shouldCollapse ? groupByFilters.slice(0, MAX_VISIBLE_GROUP_BY) : groupByFilters;
|
|
7863
|
-
const groupByHiddenCount = shouldCollapse ? Math.max(0, groupByFilters.length - MAX_VISIBLE_GROUP_BY) : 0;
|
|
7864
|
-
React.useEffect(() => {
|
|
7865
|
-
if (collapsible && totalFiltersCount === 0 && collapsed) {
|
|
7866
|
-
setCollapsed(false);
|
|
7867
|
-
}
|
|
7868
|
-
}, [collapsible, totalFiltersCount, collapsed]);
|
|
7869
|
-
const showCollapseButton = collapsible && isMultiLine && !collapsed;
|
|
7870
|
-
const showExpandButton = shouldCollapse && (adhocHiddenCount > 0 || groupByHiddenCount > 0);
|
|
7871
|
-
return /* @__PURE__ */ React__default.default.createElement(
|
|
7834
|
+
const content = /* @__PURE__ */ React__default.default.createElement(ui.ClickOutsideWrapper, { onClick: () => setPopoverVisible(false), useCapture: true }, /* @__PURE__ */ React__default.default.createElement("div", { className: styles.menuContainer, onClick: (ev) => ev.stopPropagation() }, /* @__PURE__ */ React__default.default.createElement(ui.Stack, { direction: "column" }, /* @__PURE__ */ React__default.default.createElement(ui.Text, { weight: "bold", variant: "bodySmall", color: "secondary" }, /* @__PURE__ */ React__default.default.createElement(i18n.Trans, { i18nKey: "grafana-scenes.components.drilldown-recommendations.recent" }, "Recent")), recentDrilldowns && recentDrilldowns.length > 0 ? recentDrilldowns.map((drilldown) => /* @__PURE__ */ React__default.default.createElement(
|
|
7872
7835
|
"div",
|
|
7873
7836
|
{
|
|
7874
|
-
|
|
7875
|
-
className: css.cx(styles.
|
|
7876
|
-
|
|
7877
|
-
[styles.collapsed]: shouldCollapse
|
|
7878
|
-
})
|
|
7837
|
+
key: drilldown.label,
|
|
7838
|
+
className: css.cx(styles.combinedFilterPill),
|
|
7839
|
+
onClick: () => onClickAction(drilldown.onClick)
|
|
7879
7840
|
},
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
|
|
7884
|
-
|
|
7885
|
-
|
|
7886
|
-
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
|
|
7899
|
-
|
|
7900
|
-
{ count: adhocHiddenCount }
|
|
7901
|
-
),
|
|
7902
|
-
onClick: (e) => {
|
|
7903
|
-
e.stopPropagation();
|
|
7904
|
-
handleExpand();
|
|
7905
|
-
setTimeout(() => {
|
|
7906
|
-
var _a2;
|
|
7907
|
-
return (_a2 = focusOnWipInputRef.current) == null ? void 0 : _a2.call(focusOnWipInputRef);
|
|
7908
|
-
});
|
|
7909
|
-
}
|
|
7910
|
-
},
|
|
7911
|
-
"+",
|
|
7912
|
-
adhocHiddenCount
|
|
7913
|
-
),
|
|
7914
|
-
!readOnly && /* @__PURE__ */ React__default.default.createElement(AdHocFiltersAlwaysWipCombobox, { ref: focusOnWipInputRef, controller, onInputClick: handleExpand }),
|
|
7915
|
-
enableGroupBy && /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, /* @__PURE__ */ React__default.default.createElement("div", { className: styles.sectionDivider }), /* @__PURE__ */ React__default.default.createElement("span", { className: styles.groupByLabel }, i18n.t("grafana-scenes.variables.adhoc-filters-combobox-renderer.group-by-label", "Group by:")), groupByFiltersToRender.map((filter, index) => /* @__PURE__ */ React__default.default.createElement(
|
|
7916
|
-
GroupByPill,
|
|
7917
|
-
{
|
|
7918
|
-
key: `groupby-${index}-${filter.key}`,
|
|
7919
|
-
filter,
|
|
7920
|
-
controller,
|
|
7921
|
-
readOnly: readOnly || filter.readOnly,
|
|
7922
|
-
focusOnWipInputRef: focusOnGroupByWipInputRef.current
|
|
7923
|
-
}
|
|
7924
|
-
)), shouldCollapse && groupByHiddenCount > 0 && /* @__PURE__ */ React__default.default.createElement(
|
|
7925
|
-
ui.Button,
|
|
7926
|
-
{
|
|
7927
|
-
className: styles.moreIndicator,
|
|
7928
|
-
fill: "text",
|
|
7929
|
-
size: "sm",
|
|
7930
|
-
"aria-label": i18n.t(
|
|
7931
|
-
"grafana-scenes.variables.adhoc-filters-combobox-renderer.show-more-group-by",
|
|
7932
|
-
"Show {{count}} more group by",
|
|
7933
|
-
{ count: groupByHiddenCount }
|
|
7934
|
-
),
|
|
7935
|
-
onClick: (e) => {
|
|
7936
|
-
e.stopPropagation();
|
|
7937
|
-
handleExpand();
|
|
7938
|
-
setTimeout(() => {
|
|
7939
|
-
var _a2;
|
|
7940
|
-
return (_a2 = focusOnGroupByWipInputRef.current) == null ? void 0 : _a2.call(focusOnGroupByWipInputRef);
|
|
7941
|
-
});
|
|
7942
|
-
}
|
|
7943
|
-
},
|
|
7944
|
-
"+",
|
|
7945
|
-
groupByHiddenCount
|
|
7946
|
-
), !readOnly && /* @__PURE__ */ React__default.default.createElement(
|
|
7947
|
-
AdHocFiltersAlwaysWipCombobox,
|
|
7948
|
-
{
|
|
7949
|
-
ref: focusOnGroupByWipInputRef,
|
|
7950
|
-
controller,
|
|
7951
|
-
onInputClick: handleExpand,
|
|
7952
|
-
isGroupBy: true
|
|
7841
|
+
drilldown.label
|
|
7842
|
+
)) : /* @__PURE__ */ React__default.default.createElement("div", { className: styles.emptyMessage }, /* @__PURE__ */ React__default.default.createElement(i18n.Trans, { i18nKey: "grafana-scenes.components.drilldown-recommendations.recent-empty" }, "No recent values")), showRecommended && /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, /* @__PURE__ */ React__default.default.createElement(ui.Text, { weight: "bold", variant: "bodySmall", color: "secondary" }, /* @__PURE__ */ React__default.default.createElement(i18n.Trans, { i18nKey: "grafana-scenes.components.drilldown-recommendations.recommended" }, "Recommended")), recommendedDrilldowns && recommendedDrilldowns.length > 0 ? recommendedDrilldowns.map((drilldown) => /* @__PURE__ */ React__default.default.createElement(
|
|
7843
|
+
"div",
|
|
7844
|
+
{
|
|
7845
|
+
key: drilldown.label,
|
|
7846
|
+
className: css.cx(styles.combinedFilterPill),
|
|
7847
|
+
onClick: () => onClickAction(drilldown.onClick)
|
|
7848
|
+
},
|
|
7849
|
+
drilldown.label
|
|
7850
|
+
)) : /* @__PURE__ */ React__default.default.createElement("div", { className: styles.emptyMessage }, /* @__PURE__ */ React__default.default.createElement(i18n.Trans, { i18nKey: "grafana-scenes.components.drilldown-recommendations.recommended-empty" }, "No recommended values"))))));
|
|
7851
|
+
return /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, /* @__PURE__ */ React__default.default.createElement(
|
|
7852
|
+
ui.IconButton,
|
|
7853
|
+
{
|
|
7854
|
+
name: "bars-clock",
|
|
7855
|
+
tooltip: i18n.t("grafana-scenes.components.drilldown-recommendations.tooltip", "Show recommendations"),
|
|
7856
|
+
ref,
|
|
7857
|
+
className: css.cx(isPopoverVisible && styles.iconActive),
|
|
7858
|
+
onClick: (ev) => {
|
|
7859
|
+
openPopover();
|
|
7860
|
+
ev.stopPropagation();
|
|
7953
7861
|
}
|
|
7954
|
-
|
|
7955
|
-
|
|
7956
|
-
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
|
|
7960
|
-
|
|
7961
|
-
|
|
7962
|
-
"Restore groupby set by this dashboard."
|
|
7963
|
-
),
|
|
7964
|
-
onClick: () => {
|
|
7965
|
-
var _a2;
|
|
7966
|
-
return (_a2 = controller.restoreOriginalGroupBy) == null ? void 0 : _a2.call(controller);
|
|
7862
|
+
}
|
|
7863
|
+
), isPopoverVisible && ref.current && /* @__PURE__ */ React__default.default.createElement(
|
|
7864
|
+
ui.Popover,
|
|
7865
|
+
{
|
|
7866
|
+
content,
|
|
7867
|
+
onKeyDown: (event) => {
|
|
7868
|
+
if (event.key === " ") {
|
|
7869
|
+
event.stopPropagation();
|
|
7967
7870
|
}
|
|
7968
|
-
}
|
|
7969
|
-
)),
|
|
7970
|
-
(showCollapseButton || showExpandButton || !readOnly) && /* @__PURE__ */ React__default.default.createElement("div", { className: styles.rightControls }, /* @__PURE__ */ React__default.default.createElement("div", { className: styles.sectionDivider }), showCollapseButton && /* @__PURE__ */ React__default.default.createElement(
|
|
7971
|
-
ui.Button,
|
|
7972
|
-
{
|
|
7973
|
-
className: styles.collapseButton,
|
|
7974
|
-
fill: "text",
|
|
7975
|
-
size: "sm",
|
|
7976
|
-
onClick: handleCollapseToggle,
|
|
7977
|
-
"aria-label": i18n.t(
|
|
7978
|
-
"grafana-scenes.variables.adhoc-filters-combobox-renderer.collapse-filters",
|
|
7979
|
-
"Collapse filters"
|
|
7980
|
-
),
|
|
7981
|
-
"aria-expanded": !collapsed
|
|
7982
7871
|
},
|
|
7983
|
-
|
|
7984
|
-
|
|
7985
|
-
|
|
7986
|
-
|
|
7987
|
-
|
|
7988
|
-
|
|
7989
|
-
size: "md",
|
|
7990
|
-
className: styles.dropdownIndicator,
|
|
7991
|
-
tooltip: i18n.t("grafana-scenes.variables.adhoc-filters-combobox-renderer.expand-filters", "Expand filters"),
|
|
7992
|
-
onClick: (e) => {
|
|
7993
|
-
e.stopPropagation();
|
|
7994
|
-
handleExpand();
|
|
7995
|
-
}
|
|
7996
|
-
}
|
|
7997
|
-
), !readOnly && /* @__PURE__ */ React__default.default.createElement(
|
|
7998
|
-
ui.IconButton,
|
|
7999
|
-
{
|
|
8000
|
-
name: "times",
|
|
8001
|
-
size: "md",
|
|
8002
|
-
className: styles.controlButton,
|
|
8003
|
-
tooltip: i18n.t("grafana-scenes.variables.adhoc-filters-combobox-renderer.clear-all", "Clear all"),
|
|
8004
|
-
onClick: clearAll
|
|
8005
|
-
}
|
|
8006
|
-
))
|
|
8007
|
-
);
|
|
8008
|
-
});
|
|
7872
|
+
placement: "bottom-start",
|
|
7873
|
+
referenceElement: ref.current,
|
|
7874
|
+
show: true
|
|
7875
|
+
}
|
|
7876
|
+
));
|
|
7877
|
+
}
|
|
8009
7878
|
const getStyles$c = (theme) => ({
|
|
8010
|
-
|
|
7879
|
+
menuContainer: css.css({
|
|
8011
7880
|
display: "flex",
|
|
8012
|
-
|
|
8013
|
-
|
|
8014
|
-
|
|
8015
|
-
rowGap: theme.spacing(0.5),
|
|
8016
|
-
minHeight: theme.spacing(4),
|
|
8017
|
-
backgroundColor: theme.components.input.background,
|
|
8018
|
-
border: `1px solid ${theme.colors.border.strong}`,
|
|
7881
|
+
flexDirection: "column",
|
|
7882
|
+
background: theme.colors.background.elevated,
|
|
7883
|
+
border: `1px solid ${theme.colors.border.weak}`,
|
|
8019
7884
|
borderRadius: theme.shape.radius.default,
|
|
8020
|
-
|
|
8021
|
-
|
|
8022
|
-
flexGrow: 1,
|
|
8023
|
-
width: "100%"
|
|
8024
|
-
}),
|
|
8025
|
-
comboboxFocusOutline: css.css({
|
|
8026
|
-
"&:focus-within": {
|
|
8027
|
-
outline: "2px dotted transparent",
|
|
8028
|
-
outlineOffset: "2px",
|
|
8029
|
-
boxShadow: `0 0 0 2px ${theme.colors.background.canvas}, 0 0 0px 4px ${theme.colors.primary.main}`,
|
|
8030
|
-
transitionTimingFunction: `cubic-bezier(0.19, 1, 0.22, 1)`,
|
|
8031
|
-
transitionDuration: "0.2s",
|
|
8032
|
-
transitionProperty: "outline, outline-offset, box-shadow",
|
|
8033
|
-
zIndex: 2
|
|
8034
|
-
}
|
|
8035
|
-
}),
|
|
8036
|
-
collapsed: css.css({
|
|
8037
|
-
flexWrap: "nowrap",
|
|
8038
|
-
overflow: "hidden"
|
|
7885
|
+
boxShadow: theme.shadows.z3,
|
|
7886
|
+
padding: theme.spacing(2)
|
|
8039
7887
|
}),
|
|
8040
|
-
|
|
8041
|
-
display: "flex",
|
|
7888
|
+
combinedFilterPill: css.css({
|
|
8042
7889
|
alignItems: "center",
|
|
8043
|
-
marginLeft: "auto",
|
|
8044
|
-
flexShrink: 0,
|
|
8045
|
-
gap: theme.spacing(1.5)
|
|
8046
|
-
}),
|
|
8047
|
-
moreIndicator: css.css({
|
|
8048
|
-
color: theme.colors.text.primary,
|
|
8049
7890
|
background: theme.colors.action.selected,
|
|
8050
|
-
|
|
8051
|
-
|
|
8052
|
-
|
|
7891
|
+
borderRadius: theme.shape.radius.default,
|
|
7892
|
+
border: `1px solid ${theme.colors.border.weak}`,
|
|
7893
|
+
padding: theme.spacing(0.2, 1),
|
|
7894
|
+
color: theme.colors.text.primary,
|
|
7895
|
+
overflow: "hidden",
|
|
7896
|
+
whiteSpace: "nowrap",
|
|
7897
|
+
minHeight: theme.spacing(2.75),
|
|
7898
|
+
...theme.typography.bodySmall,
|
|
7899
|
+
fontWeight: theme.typography.fontWeightBold,
|
|
7900
|
+
cursor: "pointer",
|
|
8053
7901
|
"&:hover": {
|
|
8054
7902
|
background: theme.colors.action.hover
|
|
8055
7903
|
}
|
|
8056
7904
|
}),
|
|
8057
|
-
|
|
8058
|
-
|
|
8059
|
-
|
|
8060
|
-
|
|
8061
|
-
collapseButton: css.css({
|
|
8062
|
-
color: theme.colors.text.secondary,
|
|
8063
|
-
padding: 0,
|
|
8064
|
-
height: "auto",
|
|
8065
|
-
lineHeight: "normal",
|
|
8066
|
-
"&:hover": {
|
|
8067
|
-
background: "transparent",
|
|
8068
|
-
color: theme.colors.text.primary
|
|
7905
|
+
iconActive: css.css({
|
|
7906
|
+
"&:before": {
|
|
7907
|
+
backgroundColor: theme.colors.action.hover,
|
|
7908
|
+
opacity: 1
|
|
8069
7909
|
}
|
|
8070
7910
|
}),
|
|
8071
|
-
|
|
8072
|
-
|
|
8073
|
-
|
|
8074
|
-
|
|
8075
|
-
|
|
8076
|
-
|
|
8077
|
-
|
|
8078
|
-
|
|
8079
|
-
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
|
|
8084
|
-
|
|
8085
|
-
|
|
8086
|
-
|
|
8087
|
-
|
|
8088
|
-
|
|
8089
|
-
|
|
8090
|
-
|
|
8091
|
-
|
|
8092
|
-
|
|
8093
|
-
|
|
8094
|
-
var __accessCheck$3 = (obj, member, msg) => member.has(obj) || __typeError$3("Cannot " + msg);
|
|
8095
|
-
var __privateGet$3 = (obj, member, getter) => (__accessCheck$3(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
8096
|
-
var __privateAdd$3 = (obj, member, value) => member.has(obj) ? __typeError$3("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
8097
|
-
var __privateSet$3 = (obj, member, value, setter) => (__accessCheck$3(obj, member, "write to private field"), member.set(obj, value), value);
|
|
8098
|
-
var _value;
|
|
8099
|
-
class SafeSerializableSceneObject {
|
|
8100
|
-
constructor(value) {
|
|
8101
|
-
__privateAdd$3(this, _value);
|
|
8102
|
-
this.text = "__sceneObject";
|
|
8103
|
-
this.valueOf = () => {
|
|
8104
|
-
return __privateGet$3(this, _value);
|
|
8105
|
-
};
|
|
8106
|
-
__privateSet$3(this, _value, value);
|
|
8107
|
-
}
|
|
8108
|
-
toString() {
|
|
8109
|
-
return void 0;
|
|
8110
|
-
}
|
|
8111
|
-
get value() {
|
|
8112
|
-
return this;
|
|
8113
|
-
}
|
|
8114
|
-
}
|
|
8115
|
-
_value = new WeakMap();
|
|
8116
|
-
|
|
8117
|
-
function shouldWrapInSafeSerializableSceneObject(grafanaVersion) {
|
|
8118
|
-
const pattern = /^(\d+)\.(\d+)\.(\d+)/;
|
|
8119
|
-
const match = grafanaVersion.match(pattern);
|
|
8120
|
-
if (!match) {
|
|
8121
|
-
return false;
|
|
8122
|
-
}
|
|
8123
|
-
const major = parseInt(match[1], 10);
|
|
8124
|
-
const minor = parseInt(match[2], 10);
|
|
8125
|
-
const patch = parseInt(match[3], 10);
|
|
8126
|
-
if (major === 11) {
|
|
8127
|
-
return minor === 0 && patch >= 4 || minor === 1 && patch >= 2 || minor > 1;
|
|
8128
|
-
}
|
|
8129
|
-
if (major === 10) {
|
|
8130
|
-
return minor === 4 && patch >= 8 || minor >= 5;
|
|
8131
|
-
}
|
|
8132
|
-
return major > 11;
|
|
8133
|
-
}
|
|
8134
|
-
function wrapInSafeSerializableSceneObject(sceneObject) {
|
|
8135
|
-
const version = runtime.config.buildInfo.version;
|
|
8136
|
-
if (shouldWrapInSafeSerializableSceneObject(version)) {
|
|
8137
|
-
return new SafeSerializableSceneObject(sceneObject);
|
|
8138
|
-
}
|
|
8139
|
-
return { value: sceneObject, text: "__sceneObject" };
|
|
8140
|
-
}
|
|
8141
|
-
|
|
8142
|
-
const reverseScopeFilterOperatorMap = Object.fromEntries(
|
|
8143
|
-
Object.entries(data.scopeFilterOperatorMap).map(([symbol, operator]) => [operator, symbol])
|
|
8144
|
-
);
|
|
8145
|
-
function isEqualityOrMultiOperator(value) {
|
|
8146
|
-
const operators = /* @__PURE__ */ new Set(["equals", "not-equals", "one-of", "not-one-of"]);
|
|
8147
|
-
return operators.has(value);
|
|
8148
|
-
}
|
|
8149
|
-
function isRegexOperator(value) {
|
|
8150
|
-
const operators = /* @__PURE__ */ new Set(["regex-match", "regex-not-match"]);
|
|
8151
|
-
return operators.has(value);
|
|
8152
|
-
}
|
|
8153
|
-
function getAdHocFiltersFromScopes(scopes) {
|
|
8154
|
-
const formattedFilters = /* @__PURE__ */ new Map();
|
|
8155
|
-
const duplicatedFilters = [];
|
|
8156
|
-
const allFilters = scopes.flatMap((scope) => scope.spec.filters);
|
|
8157
|
-
for (const filter of allFilters) {
|
|
8158
|
-
processFilter(formattedFilters, duplicatedFilters, filter);
|
|
8159
|
-
}
|
|
8160
|
-
return [...formattedFilters.values(), ...duplicatedFilters];
|
|
8161
|
-
}
|
|
8162
|
-
function processFilter(formattedFilters, duplicatedFilters, filter) {
|
|
8163
|
-
var _a, _b;
|
|
8164
|
-
if (!filter) {
|
|
8165
|
-
return;
|
|
8166
|
-
}
|
|
8167
|
-
const existingFilter = formattedFilters.get(filter.key);
|
|
8168
|
-
if (existingFilter && isEqualityValue(existingFilter.operator, filter.operator)) {
|
|
8169
|
-
mergeFilterValues(existingFilter, filter);
|
|
8170
|
-
} else if (existingFilter && isRegexValue(existingFilter.operator, filter.operator)) {
|
|
8171
|
-
existingFilter.value += `|${filter.value}`;
|
|
8172
|
-
existingFilter.values = [existingFilter.value];
|
|
8173
|
-
} else if (!existingFilter) {
|
|
8174
|
-
formattedFilters.set(filter.key, {
|
|
8175
|
-
key: filter.key,
|
|
8176
|
-
operator: reverseScopeFilterOperatorMap[filter.operator],
|
|
8177
|
-
value: filter.value,
|
|
8178
|
-
values: (_a = filter.values) != null ? _a : [filter.value],
|
|
8179
|
-
origin: "scope"
|
|
8180
|
-
});
|
|
8181
|
-
} else {
|
|
8182
|
-
duplicatedFilters.push({
|
|
8183
|
-
key: filter.key,
|
|
8184
|
-
operator: reverseScopeFilterOperatorMap[filter.operator],
|
|
8185
|
-
value: filter.value,
|
|
8186
|
-
values: (_b = filter.values) != null ? _b : [filter.value],
|
|
8187
|
-
origin: "scope"
|
|
8188
|
-
});
|
|
8189
|
-
}
|
|
8190
|
-
}
|
|
8191
|
-
function mergeFilterValues(adHocFilter, filter) {
|
|
8192
|
-
var _a, _b, _c, _d;
|
|
8193
|
-
const values = (_a = filter.values) != null ? _a : [filter.value];
|
|
8194
|
-
for (const value of values) {
|
|
8195
|
-
if (!((_b = adHocFilter.values) == null ? void 0 : _b.includes(value))) {
|
|
8196
|
-
(_c = adHocFilter.values) == null ? void 0 : _c.push(value);
|
|
8197
|
-
}
|
|
7911
|
+
emptyMessage: css.css({
|
|
7912
|
+
padding: theme.spacing(0.5, 0),
|
|
7913
|
+
color: theme.colors.text.secondary,
|
|
7914
|
+
...theme.typography.bodySmall
|
|
7915
|
+
})
|
|
7916
|
+
});
|
|
7917
|
+
|
|
7918
|
+
var __typeError$3 = (msg) => {
|
|
7919
|
+
throw TypeError(msg);
|
|
7920
|
+
};
|
|
7921
|
+
var __accessCheck$3 = (obj, member, msg) => member.has(obj) || __typeError$3("Cannot " + msg);
|
|
7922
|
+
var __privateGet$3 = (obj, member, getter) => (__accessCheck$3(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
7923
|
+
var __privateAdd$3 = (obj, member, value) => member.has(obj) ? __typeError$3("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
7924
|
+
var __privateSet$3 = (obj, member, value, setter) => (__accessCheck$3(obj, member, "write to private field"), member.set(obj, value), value);
|
|
7925
|
+
var _value;
|
|
7926
|
+
class SafeSerializableSceneObject {
|
|
7927
|
+
constructor(value) {
|
|
7928
|
+
__privateAdd$3(this, _value);
|
|
7929
|
+
this.text = "__sceneObject";
|
|
7930
|
+
this.valueOf = () => {
|
|
7931
|
+
return __privateGet$3(this, _value);
|
|
7932
|
+
};
|
|
7933
|
+
__privateSet$3(this, _value, value);
|
|
8198
7934
|
}
|
|
8199
|
-
|
|
8200
|
-
return;
|
|
7935
|
+
toString() {
|
|
7936
|
+
return void 0;
|
|
8201
7937
|
}
|
|
8202
|
-
|
|
8203
|
-
|
|
8204
|
-
} else if (filter.operator === "not-equals" && adHocFilter.operator === reverseScopeFilterOperatorMap["not-equals"]) {
|
|
8205
|
-
adHocFilter.operator = reverseScopeFilterOperatorMap["not-one-of"];
|
|
7938
|
+
get value() {
|
|
7939
|
+
return this;
|
|
8206
7940
|
}
|
|
8207
7941
|
}
|
|
8208
|
-
|
|
8209
|
-
|
|
8210
|
-
|
|
7942
|
+
_value = new WeakMap();
|
|
7943
|
+
|
|
7944
|
+
function shouldWrapInSafeSerializableSceneObject(grafanaVersion) {
|
|
7945
|
+
const pattern = /^(\d+)\.(\d+)\.(\d+)/;
|
|
7946
|
+
const match = grafanaVersion.match(pattern);
|
|
7947
|
+
if (!match) {
|
|
8211
7948
|
return false;
|
|
8212
7949
|
}
|
|
8213
|
-
|
|
8214
|
-
|
|
8215
|
-
|
|
8216
|
-
|
|
8217
|
-
|
|
8218
|
-
return false;
|
|
7950
|
+
const major = parseInt(match[1], 10);
|
|
7951
|
+
const minor = parseInt(match[2], 10);
|
|
7952
|
+
const patch = parseInt(match[3], 10);
|
|
7953
|
+
if (major === 11) {
|
|
7954
|
+
return minor === 0 && patch >= 4 || minor === 1 && patch >= 2 || minor > 1;
|
|
8219
7955
|
}
|
|
8220
|
-
|
|
7956
|
+
if (major === 10) {
|
|
7957
|
+
return minor === 4 && patch >= 8 || minor >= 5;
|
|
7958
|
+
}
|
|
7959
|
+
return major > 11;
|
|
8221
7960
|
}
|
|
8222
|
-
function
|
|
8223
|
-
|
|
8224
|
-
|
|
7961
|
+
function wrapInSafeSerializableSceneObject(sceneObject) {
|
|
7962
|
+
const version = runtime.config.buildInfo.version;
|
|
7963
|
+
if (shouldWrapInSafeSerializableSceneObject(version)) {
|
|
7964
|
+
return new SafeSerializableSceneObject(sceneObject);
|
|
8225
7965
|
}
|
|
8226
|
-
return
|
|
7966
|
+
return { value: sceneObject, text: "__sceneObject" };
|
|
8227
7967
|
}
|
|
8228
7968
|
|
|
8229
|
-
|
|
8230
|
-
|
|
7969
|
+
const getRecentFiltersKey = (datasourceUid) => `grafana.filters.recent.${datasourceUid != null ? datasourceUid : "default"}`;
|
|
7970
|
+
const getRecentGroupingKey$1 = (datasourceUid) => `grafana.grouping.recent.${datasourceUid != null ? datasourceUid : "default"}`;
|
|
7971
|
+
function getFilterIdentity(filter) {
|
|
7972
|
+
return `${filter.key}|${filter.operator}|${filter.value}`;
|
|
8231
7973
|
}
|
|
8232
|
-
|
|
8233
|
-
|
|
8234
|
-
|
|
8235
|
-
|
|
8236
|
-
|
|
8237
|
-
|
|
8238
|
-
this.renderProfiler = renderProfiler;
|
|
8239
|
-
this.renderProfiler.setInteractionCompleteHandler(state.onInteractionComplete);
|
|
7974
|
+
function deduplicateFilters(filters) {
|
|
7975
|
+
const filterMap = /* @__PURE__ */ new Map();
|
|
7976
|
+
for (const filter of filters) {
|
|
7977
|
+
const identity = getFilterIdentity(filter);
|
|
7978
|
+
if (filterMap.has(identity)) {
|
|
7979
|
+
filterMap.delete(identity);
|
|
8240
7980
|
}
|
|
7981
|
+
filterMap.set(identity, filter);
|
|
8241
7982
|
}
|
|
8242
|
-
|
|
8243
|
-
|
|
8244
|
-
|
|
8245
|
-
|
|
7983
|
+
return Array.from(filterMap.values());
|
|
7984
|
+
}
|
|
7985
|
+
function deduplicateGroupings(groupings) {
|
|
7986
|
+
const seen = /* @__PURE__ */ new Map();
|
|
7987
|
+
for (const g of groupings) {
|
|
7988
|
+
const key = String(g.value);
|
|
7989
|
+
if (seen.has(key)) {
|
|
7990
|
+
seen.delete(key);
|
|
8246
7991
|
}
|
|
8247
|
-
(
|
|
8248
|
-
}
|
|
8249
|
-
stopInteraction() {
|
|
8250
|
-
var _a;
|
|
8251
|
-
(_a = this.renderProfiler) == null ? void 0 : _a.stopInteraction();
|
|
7992
|
+
seen.set(key, g);
|
|
8252
7993
|
}
|
|
7994
|
+
return Array.from(seen.values());
|
|
8253
7995
|
}
|
|
8254
|
-
|
|
8255
|
-
|
|
8256
|
-
|
|
8257
|
-
|
|
8258
|
-
|
|
8259
|
-
|
|
8260
|
-
|
|
8261
|
-
|
|
7996
|
+
class AdHocFiltersRecommendations extends SceneObjectBase {
|
|
7997
|
+
constructor(state = {}) {
|
|
7998
|
+
super(state);
|
|
7999
|
+
this._activationHandler = () => {
|
|
8000
|
+
const filterJson = data.store.get(this._getFiltersStorageKey());
|
|
8001
|
+
const storedFilters = filterJson ? JSON.parse(filterJson) : [];
|
|
8002
|
+
if (storedFilters.length > 0) {
|
|
8003
|
+
this._verifyRecentFiltersApplicability(storedFilters);
|
|
8004
|
+
} else {
|
|
8005
|
+
this.setState({ recentFilters: [] });
|
|
8006
|
+
}
|
|
8007
|
+
if (this._isGroupByEnabled) {
|
|
8008
|
+
const groupingJson = data.store.get(this._getGroupingStorageKey());
|
|
8009
|
+
const storedGroupings = groupingJson ? JSON.parse(groupingJson) : [];
|
|
8010
|
+
if (storedGroupings.length > 0) {
|
|
8011
|
+
this._verifyRecentGroupingsApplicability(storedGroupings);
|
|
8012
|
+
} else {
|
|
8013
|
+
this.setState({ recentGrouping: [] });
|
|
8262
8014
|
}
|
|
8263
8015
|
}
|
|
8264
|
-
|
|
8265
|
-
|
|
8266
|
-
|
|
8267
|
-
|
|
8268
|
-
|
|
8269
|
-
|
|
8270
|
-
|
|
8271
|
-
|
|
8272
|
-
|
|
8273
|
-
|
|
8274
|
-
|
|
8275
|
-
|
|
8276
|
-
|
|
8277
|
-
|
|
8278
|
-
|
|
8279
|
-
|
|
8280
|
-
|
|
8281
|
-
|
|
8282
|
-
|
|
8283
|
-
|
|
8284
|
-
|
|
8285
|
-
|
|
8286
|
-
|
|
8287
|
-
|
|
8288
|
-
|
|
8289
|
-
|
|
8290
|
-
|
|
8016
|
+
this._fetchRecommendedDrilldowns();
|
|
8017
|
+
const scopesVariable = sceneGraph.lookupVariable(SCOPES_VARIABLE_NAME, this._adHocFilter);
|
|
8018
|
+
let scopesSubscription;
|
|
8019
|
+
let adHocSubscription;
|
|
8020
|
+
if (scopesVariable instanceof ScopesVariable) {
|
|
8021
|
+
this._subs.add(
|
|
8022
|
+
scopesSubscription = scopesVariable.subscribeToState((newState, prevState) => {
|
|
8023
|
+
if (newState.scopes !== prevState.scopes) {
|
|
8024
|
+
this._reloadStoredFilters();
|
|
8025
|
+
if (this._isGroupByEnabled) {
|
|
8026
|
+
this._reloadStoredGroupings();
|
|
8027
|
+
}
|
|
8028
|
+
this._fetchRecommendedDrilldowns();
|
|
8029
|
+
}
|
|
8030
|
+
})
|
|
8031
|
+
);
|
|
8032
|
+
}
|
|
8033
|
+
this._subs.add(
|
|
8034
|
+
adHocSubscription = this._adHocFilter.subscribeToState((newState, prevState) => {
|
|
8035
|
+
if (newState.filters !== prevState.filters) {
|
|
8036
|
+
this._reloadStoredFilters();
|
|
8037
|
+
if (this._isGroupByEnabled) {
|
|
8038
|
+
this._reloadStoredGroupings();
|
|
8039
|
+
}
|
|
8040
|
+
this._fetchRecommendedDrilldowns();
|
|
8041
|
+
}
|
|
8042
|
+
})
|
|
8043
|
+
);
|
|
8044
|
+
return () => {
|
|
8045
|
+
scopesSubscription == null ? void 0 : scopesSubscription.unsubscribe();
|
|
8046
|
+
adHocSubscription == null ? void 0 : adHocSubscription.unsubscribe();
|
|
8047
|
+
};
|
|
8291
8048
|
};
|
|
8049
|
+
this.addActivationHandler(this._activationHandler);
|
|
8292
8050
|
}
|
|
8293
|
-
|
|
8294
|
-
|
|
8295
|
-
|
|
8296
|
-
|
|
8297
|
-
return this.
|
|
8298
|
-
}
|
|
8299
|
-
async getValuesFor(filter) {
|
|
8300
|
-
return this.model._getValuesFor(filter);
|
|
8301
|
-
}
|
|
8302
|
-
getOperators() {
|
|
8303
|
-
return this.model._getOperators();
|
|
8304
|
-
}
|
|
8305
|
-
updateFilter(filter, update) {
|
|
8306
|
-
this.model._updateFilter(filter, update);
|
|
8051
|
+
get _adHocFilter() {
|
|
8052
|
+
if (!(this.parent instanceof AdHocFiltersVariable)) {
|
|
8053
|
+
throw new Error("AdHocFiltersRecommendations must be a child of AdHocFiltersVariable");
|
|
8054
|
+
}
|
|
8055
|
+
return this.parent;
|
|
8307
8056
|
}
|
|
8308
|
-
|
|
8309
|
-
this.
|
|
8057
|
+
get _scopedVars() {
|
|
8058
|
+
return { __sceneObject: wrapInSafeSerializableSceneObject(this._adHocFilter) };
|
|
8310
8059
|
}
|
|
8311
|
-
|
|
8312
|
-
this.
|
|
8060
|
+
get _isGroupByEnabled() {
|
|
8061
|
+
return this._adHocFilter.state.enableGroupBy === true;
|
|
8313
8062
|
}
|
|
8314
|
-
|
|
8315
|
-
|
|
8063
|
+
_reloadStoredFilters() {
|
|
8064
|
+
const json = data.store.get(this._getFiltersStorageKey());
|
|
8065
|
+
const storedFilters = json ? JSON.parse(json) : [];
|
|
8066
|
+
if (storedFilters.length > 0) {
|
|
8067
|
+
this._verifyRecentFiltersApplicability(storedFilters);
|
|
8068
|
+
}
|
|
8316
8069
|
}
|
|
8317
|
-
|
|
8318
|
-
|
|
8070
|
+
_reloadStoredGroupings() {
|
|
8071
|
+
const json = data.store.get(this._getGroupingStorageKey());
|
|
8072
|
+
const storedGroupings = json ? JSON.parse(json) : [];
|
|
8073
|
+
if (storedGroupings.length > 0) {
|
|
8074
|
+
this._verifyRecentGroupingsApplicability(storedGroupings);
|
|
8075
|
+
}
|
|
8319
8076
|
}
|
|
8320
|
-
|
|
8321
|
-
|
|
8077
|
+
_getFiltersStorageKey() {
|
|
8078
|
+
var _a;
|
|
8079
|
+
return getRecentFiltersKey((_a = this._adHocFilter.state.datasource) == null ? void 0 : _a.uid);
|
|
8322
8080
|
}
|
|
8323
|
-
|
|
8324
|
-
|
|
8081
|
+
_getGroupingStorageKey() {
|
|
8082
|
+
var _a;
|
|
8083
|
+
return getRecentGroupingKey$1((_a = this._adHocFilter.state.datasource) == null ? void 0 : _a.uid);
|
|
8325
8084
|
}
|
|
8326
|
-
|
|
8327
|
-
|
|
8085
|
+
async _fetchRecommendedDrilldowns() {
|
|
8086
|
+
var _a;
|
|
8087
|
+
const adhoc = this._adHocFilter;
|
|
8088
|
+
const ds = await getDataSource(adhoc.state.datasource, this._scopedVars);
|
|
8089
|
+
if (!ds || !ds.getRecommendedDrilldowns) {
|
|
8090
|
+
this.setState({ datasourceSupportsRecommendations: false });
|
|
8091
|
+
return;
|
|
8092
|
+
}
|
|
8093
|
+
this.setState({ datasourceSupportsRecommendations: true });
|
|
8094
|
+
const queries = adhoc.state.useQueriesAsFilterForOptions ? getQueriesForVariables(adhoc) : void 0;
|
|
8095
|
+
const timeRange = sceneGraph.getTimeRange(adhoc).state.value;
|
|
8096
|
+
const scopes = sceneGraph.getScopes(adhoc);
|
|
8097
|
+
const allFilters = [...(_a = adhoc.state.originFilters) != null ? _a : [], ...adhoc.state.filters];
|
|
8098
|
+
const filters = allFilters.filter((f) => !isGroupByFilter(f));
|
|
8099
|
+
const groupByKeys = this._isGroupByEnabled ? allFilters.filter((f) => isGroupByFilter(f)).map((f) => f.key) : void 0;
|
|
8100
|
+
const enrichedRequest = getEnrichedDataRequest(adhoc);
|
|
8101
|
+
const dashboardUid = enrichedRequest == null ? void 0 : enrichedRequest.dashboardUID;
|
|
8102
|
+
try {
|
|
8103
|
+
const recommendedDrilldowns = await ds.getRecommendedDrilldowns({
|
|
8104
|
+
timeRange,
|
|
8105
|
+
dashboardUid,
|
|
8106
|
+
queries: queries != null ? queries : [],
|
|
8107
|
+
filters,
|
|
8108
|
+
...groupByKeys ? { groupByKeys } : {},
|
|
8109
|
+
scopes
|
|
8110
|
+
});
|
|
8111
|
+
const stateUpdate = {};
|
|
8112
|
+
if (recommendedDrilldowns == null ? void 0 : recommendedDrilldowns.filters) {
|
|
8113
|
+
stateUpdate.recommendedFilters = recommendedDrilldowns.filters;
|
|
8114
|
+
}
|
|
8115
|
+
if (this._isGroupByEnabled && (recommendedDrilldowns == null ? void 0 : recommendedDrilldowns.groupByKeys)) {
|
|
8116
|
+
stateUpdate.recommendedGrouping = recommendedDrilldowns.groupByKeys.map((key) => ({
|
|
8117
|
+
value: key,
|
|
8118
|
+
text: key
|
|
8119
|
+
}));
|
|
8120
|
+
}
|
|
8121
|
+
this.setState(stateUpdate);
|
|
8122
|
+
} catch (error) {
|
|
8123
|
+
console.error("Failed to fetch recommended drilldowns:", error);
|
|
8124
|
+
}
|
|
8328
8125
|
}
|
|
8329
|
-
|
|
8330
|
-
this.
|
|
8126
|
+
async _verifyRecentFiltersApplicability(storedFilters) {
|
|
8127
|
+
const adhoc = this._adHocFilter;
|
|
8128
|
+
const queries = adhoc.state.useQueriesAsFilterForOptions ? getQueriesForVariables(adhoc) : void 0;
|
|
8129
|
+
const response = await adhoc.getFiltersApplicabilityForQueries(storedFilters, queries != null ? queries : []);
|
|
8130
|
+
if (!response) {
|
|
8131
|
+
const deduped = deduplicateFilters(storedFilters);
|
|
8132
|
+
this.setState({ recentFilters: deduped.slice(-3) });
|
|
8133
|
+
return;
|
|
8134
|
+
}
|
|
8135
|
+
const applicabilityMap = /* @__PURE__ */ new Map();
|
|
8136
|
+
response.forEach((item) => {
|
|
8137
|
+
applicabilityMap.set(item.key, item.applicable !== false);
|
|
8138
|
+
});
|
|
8139
|
+
const applicableFilters = storedFilters.filter((f) => {
|
|
8140
|
+
const isApplicable = applicabilityMap.get(f.key);
|
|
8141
|
+
return isApplicable === void 0 || isApplicable === true;
|
|
8142
|
+
});
|
|
8143
|
+
const recentFilters = deduplicateFilters(applicableFilters).slice(-3);
|
|
8144
|
+
this.setState({ recentFilters });
|
|
8331
8145
|
}
|
|
8332
|
-
|
|
8333
|
-
this.
|
|
8146
|
+
async _verifyRecentGroupingsApplicability(storedGroupings) {
|
|
8147
|
+
const adhoc = this._adHocFilter;
|
|
8148
|
+
const queries = adhoc.state.useQueriesAsFilterForOptions ? getQueriesForVariables(adhoc) : void 0;
|
|
8149
|
+
const groupByFilters = storedGroupings.map((g) => ({
|
|
8150
|
+
key: String(g.value),
|
|
8151
|
+
operator: GROUP_BY_OPERATOR,
|
|
8152
|
+
value: "",
|
|
8153
|
+
condition: ""
|
|
8154
|
+
}));
|
|
8155
|
+
const response = await adhoc.getFiltersApplicabilityForQueries(groupByFilters, queries != null ? queries : []);
|
|
8156
|
+
if (!response) {
|
|
8157
|
+
this.setState({ recentGrouping: deduplicateGroupings(storedGroupings).slice(-3) });
|
|
8158
|
+
return;
|
|
8159
|
+
}
|
|
8160
|
+
const applicabilityMap = /* @__PURE__ */ new Map();
|
|
8161
|
+
response.forEach((item) => {
|
|
8162
|
+
applicabilityMap.set(item.key, item.applicable !== false);
|
|
8163
|
+
});
|
|
8164
|
+
const applicableGroupings = deduplicateGroupings(storedGroupings).filter((g) => {
|
|
8165
|
+
const isApplicable = applicabilityMap.get(String(g.value));
|
|
8166
|
+
return isApplicable === void 0 || isApplicable === true;
|
|
8167
|
+
}).slice(-3);
|
|
8168
|
+
this.setState({ recentGrouping: applicableGroupings });
|
|
8334
8169
|
}
|
|
8335
|
-
|
|
8336
|
-
|
|
8170
|
+
/**
|
|
8171
|
+
* Stores a recent filter in localStorage and updates state.
|
|
8172
|
+
*/
|
|
8173
|
+
storeRecentFilter(filter) {
|
|
8174
|
+
const key = this._getFiltersStorageKey();
|
|
8175
|
+
const storedFilters = data.store.get(key);
|
|
8176
|
+
const allRecentFilters = storedFilters ? JSON.parse(storedFilters) : [];
|
|
8177
|
+
const updatedStoredFilters = deduplicateFilters([...allRecentFilters, filter]).slice(-10);
|
|
8178
|
+
data.store.set(key, JSON.stringify(updatedStoredFilters));
|
|
8179
|
+
const adhoc = this._adHocFilter;
|
|
8180
|
+
const existingFilter = adhoc.state.filters.find((f) => f.key === filter.key && !Boolean(f.nonApplicable));
|
|
8181
|
+
if (existingFilter && !Boolean(existingFilter.nonApplicable)) {
|
|
8182
|
+
this.setState({ recentFilters: updatedStoredFilters.slice(-3) });
|
|
8183
|
+
}
|
|
8337
8184
|
}
|
|
8338
|
-
|
|
8339
|
-
|
|
8340
|
-
|
|
8185
|
+
/**
|
|
8186
|
+
* Stores a recent grouping key in localStorage and updates state.
|
|
8187
|
+
* No-op when enableGroupBy is false.
|
|
8188
|
+
*/
|
|
8189
|
+
storeRecentGrouping(groupByKey) {
|
|
8190
|
+
if (!this._isGroupByEnabled) {
|
|
8191
|
+
return;
|
|
8192
|
+
}
|
|
8193
|
+
const storageKey = this._getGroupingStorageKey();
|
|
8194
|
+
const storedGroupings = data.store.get(storageKey);
|
|
8195
|
+
const allRecentGroupings = storedGroupings ? JSON.parse(storedGroupings) : [];
|
|
8196
|
+
const withoutDuplicate = allRecentGroupings.filter((g) => String(g.value) !== groupByKey);
|
|
8197
|
+
const updated = [...withoutDuplicate, { value: groupByKey, text: groupByKey }];
|
|
8198
|
+
const limited = updated.slice(-10);
|
|
8199
|
+
data.store.set(storageKey, JSON.stringify(limited));
|
|
8200
|
+
this.setState({ recentGrouping: limited.slice(-3) });
|
|
8341
8201
|
}
|
|
8342
|
-
|
|
8343
|
-
|
|
8344
|
-
interactionTracker == null ? void 0 : interactionTracker.startInteraction(name);
|
|
8202
|
+
addFilterToParent(filter) {
|
|
8203
|
+
this._adHocFilter.updateFilters([...this._adHocFilter.state.filters, filter]);
|
|
8345
8204
|
}
|
|
8346
|
-
|
|
8347
|
-
|
|
8348
|
-
|
|
8205
|
+
addGroupByToParent(key) {
|
|
8206
|
+
if (!this._isGroupByEnabled) {
|
|
8207
|
+
return;
|
|
8208
|
+
}
|
|
8209
|
+
const adhoc = this._adHocFilter;
|
|
8210
|
+
const exists = adhoc.state.filters.some((f) => isGroupByFilter(f) && f.key === key);
|
|
8211
|
+
if (exists) {
|
|
8212
|
+
return;
|
|
8213
|
+
}
|
|
8214
|
+
adhoc._addGroupByFilter({ value: key, label: key });
|
|
8349
8215
|
}
|
|
8350
8216
|
}
|
|
8217
|
+
AdHocFiltersRecommendations.Component = AdHocFiltersRecommendationsRenderer;
|
|
8218
|
+
function AdHocFiltersRecommendationsRenderer({ model }) {
|
|
8219
|
+
const { recentFilters, recommendedFilters, datasourceSupportsRecommendations } = model.useState();
|
|
8220
|
+
const { filters } = model._adHocFilter.useState();
|
|
8221
|
+
const recentDrilldowns = recentFilters == null ? void 0 : recentFilters.map((filter) => ({
|
|
8222
|
+
label: `${filter.key} ${filter.operator} ${filter.value}`,
|
|
8223
|
+
onClick: () => {
|
|
8224
|
+
const exists = filters.some((f) => f.key === filter.key && f.value === filter.value);
|
|
8225
|
+
if (!exists) {
|
|
8226
|
+
model.addFilterToParent(filter);
|
|
8227
|
+
}
|
|
8228
|
+
}
|
|
8229
|
+
}));
|
|
8230
|
+
const recommendedDrilldowns = recommendedFilters == null ? void 0 : recommendedFilters.map((filter) => ({
|
|
8231
|
+
label: `${filter.key} ${filter.operator} ${filter.value}`,
|
|
8232
|
+
onClick: () => {
|
|
8233
|
+
const exists = filters.some((f) => f.key === filter.key && f.value === filter.value);
|
|
8234
|
+
if (!exists) {
|
|
8235
|
+
model.addFilterToParent(filter);
|
|
8236
|
+
}
|
|
8237
|
+
}
|
|
8238
|
+
}));
|
|
8239
|
+
return /* @__PURE__ */ React__default.default.createElement(
|
|
8240
|
+
DrilldownRecommendations,
|
|
8241
|
+
{
|
|
8242
|
+
recentDrilldowns,
|
|
8243
|
+
recommendedDrilldowns,
|
|
8244
|
+
showRecommended: datasourceSupportsRecommendations
|
|
8245
|
+
}
|
|
8246
|
+
);
|
|
8247
|
+
}
|
|
8248
|
+
function AdHocGroupByRecommendationsRenderer({ model }) {
|
|
8249
|
+
const { recentGrouping, recommendedGrouping, datasourceSupportsRecommendations } = model.useState();
|
|
8250
|
+
const recentDrilldowns = recentGrouping == null ? void 0 : recentGrouping.map((groupBy) => ({
|
|
8251
|
+
label: `${groupBy.value}`,
|
|
8252
|
+
onClick: () => {
|
|
8253
|
+
model.addGroupByToParent(String(groupBy.value));
|
|
8254
|
+
}
|
|
8255
|
+
}));
|
|
8256
|
+
const recommendedDrilldowns = recommendedGrouping == null ? void 0 : recommendedGrouping.map((groupBy) => ({
|
|
8257
|
+
label: `${groupBy.value}`,
|
|
8258
|
+
onClick: () => {
|
|
8259
|
+
model.addGroupByToParent(String(groupBy.value));
|
|
8260
|
+
}
|
|
8261
|
+
}));
|
|
8262
|
+
return /* @__PURE__ */ React__default.default.createElement(
|
|
8263
|
+
DrilldownRecommendations,
|
|
8264
|
+
{
|
|
8265
|
+
recentDrilldowns,
|
|
8266
|
+
recommendedDrilldowns,
|
|
8267
|
+
showRecommended: datasourceSupportsRecommendations
|
|
8268
|
+
}
|
|
8269
|
+
);
|
|
8270
|
+
}
|
|
8351
8271
|
|
|
8352
|
-
|
|
8272
|
+
const MAX_VISIBLE_FILTERS_DEFAULT = 4;
|
|
8273
|
+
const MAX_VISIBLE_FILTERS_WITH_GROUP_BY = 2;
|
|
8274
|
+
const MAX_VISIBLE_GROUP_BY = 2;
|
|
8275
|
+
const AdHocFiltersComboboxRenderer = React.memo(function AdHocFiltersComboboxRenderer2({ controller }) {
|
|
8276
|
+
var _a;
|
|
8277
|
+
const { originFilters, filters, readOnly, collapsible, valueRecommendations, enableGroupBy, groupByRestorable } = controller.useState();
|
|
8353
8278
|
const styles = ui.useStyles2(getStyles$b);
|
|
8354
|
-
const
|
|
8355
|
-
const
|
|
8356
|
-
const
|
|
8357
|
-
|
|
8279
|
+
const theme = ui.useTheme2();
|
|
8280
|
+
const [collapsed, setCollapsed] = React.useState(true);
|
|
8281
|
+
const [wrapperRef, { height: wrapperHeight }] = reactUse.useMeasure();
|
|
8282
|
+
const clearAll = () => {
|
|
8283
|
+
var _a2;
|
|
8284
|
+
(_a2 = controller.clearAll) == null ? void 0 : _a2.call(controller);
|
|
8358
8285
|
};
|
|
8359
|
-
const
|
|
8360
|
-
|
|
8361
|
-
|
|
8286
|
+
const focusOnWipInputRef = React.useRef();
|
|
8287
|
+
const focusOnGroupByWipInputRef = React.useRef();
|
|
8288
|
+
const singleLineThreshold = theme.spacing.gridSize * 5;
|
|
8289
|
+
const isMultiLine = collapsible && wrapperHeight > singleLineThreshold;
|
|
8290
|
+
const handleCollapseToggle = (event) => {
|
|
8291
|
+
event.stopPropagation();
|
|
8292
|
+
if (collapsible) {
|
|
8293
|
+
setCollapsed(true);
|
|
8294
|
+
}
|
|
8362
8295
|
};
|
|
8363
|
-
const
|
|
8364
|
-
|
|
8365
|
-
|
|
8366
|
-
|
|
8367
|
-
|
|
8368
|
-
|
|
8369
|
-
|
|
8370
|
-
|
|
8371
|
-
|
|
8296
|
+
const handleExpand = () => {
|
|
8297
|
+
if (collapsible && collapsed) {
|
|
8298
|
+
setCollapsed(false);
|
|
8299
|
+
}
|
|
8300
|
+
};
|
|
8301
|
+
const visibleOriginFilters = (_a = originFilters == null ? void 0 : originFilters.filter((f) => f.origin && !f.hidden && !f.dismissedGroupBy)) != null ? _a : [];
|
|
8302
|
+
const visibleFilters = filters.filter((f) => !f.hidden);
|
|
8303
|
+
const allFilters = [...visibleOriginFilters, ...visibleFilters];
|
|
8304
|
+
const totalFiltersCount = allFilters.length;
|
|
8305
|
+
const adhocFilters = allFilters.filter((f) => !isGroupByFilter(f));
|
|
8306
|
+
const groupByFilters = allFilters.filter(isGroupByFilter);
|
|
8307
|
+
const shouldCollapse = collapsible && collapsed && totalFiltersCount > 0;
|
|
8308
|
+
const maxVisibleAdhocFilters = enableGroupBy ? MAX_VISIBLE_FILTERS_WITH_GROUP_BY : MAX_VISIBLE_FILTERS_DEFAULT;
|
|
8309
|
+
const adhocFiltersToRender = shouldCollapse ? adhocFilters.slice(0, maxVisibleAdhocFilters) : adhocFilters;
|
|
8310
|
+
const adhocHiddenCount = shouldCollapse ? Math.max(0, adhocFilters.length - maxVisibleAdhocFilters) : 0;
|
|
8311
|
+
const groupByFiltersToRender = shouldCollapse ? groupByFilters.slice(0, MAX_VISIBLE_GROUP_BY) : groupByFilters;
|
|
8312
|
+
const groupByHiddenCount = shouldCollapse ? Math.max(0, groupByFilters.length - MAX_VISIBLE_GROUP_BY) : 0;
|
|
8313
|
+
React.useEffect(() => {
|
|
8314
|
+
if (collapsible && totalFiltersCount === 0 && collapsed) {
|
|
8315
|
+
setCollapsed(false);
|
|
8316
|
+
}
|
|
8317
|
+
}, [collapsible, totalFiltersCount, collapsed]);
|
|
8318
|
+
const showCollapseButton = collapsible && isMultiLine && !collapsed;
|
|
8319
|
+
const showExpandButton = shouldCollapse && (adhocHiddenCount > 0 || groupByHiddenCount > 0);
|
|
8320
|
+
return /* @__PURE__ */ React__default.default.createElement(
|
|
8372
8321
|
"div",
|
|
8373
8322
|
{
|
|
8374
|
-
|
|
8375
|
-
className: css.cx(styles.
|
|
8376
|
-
|
|
8323
|
+
ref: wrapperRef,
|
|
8324
|
+
className: css.cx(styles.comboboxWrapper, {
|
|
8325
|
+
[styles.comboboxFocusOutline]: !readOnly,
|
|
8326
|
+
[styles.collapsed]: shouldCollapse
|
|
8327
|
+
})
|
|
8377
8328
|
},
|
|
8378
|
-
|
|
8379
|
-
|
|
8380
|
-
|
|
8381
|
-
|
|
8382
|
-
|
|
8383
|
-
|
|
8384
|
-
|
|
8385
|
-
|
|
8386
|
-
|
|
8387
|
-
|
|
8388
|
-
|
|
8389
|
-
|
|
8329
|
+
!readOnly && valueRecommendations && /* @__PURE__ */ React__default.default.createElement(valueRecommendations.Component, { model: valueRecommendations }),
|
|
8330
|
+
adhocFiltersToRender.map((filter, index) => /* @__PURE__ */ React__default.default.createElement(
|
|
8331
|
+
AdHocFilterPill,
|
|
8332
|
+
{
|
|
8333
|
+
key: `${filter.origin ? "origin-" : ""}${index}-${filter.key}`,
|
|
8334
|
+
filter,
|
|
8335
|
+
controller,
|
|
8336
|
+
readOnly: readOnly || filter.readOnly,
|
|
8337
|
+
focusOnWipInputRef: focusOnWipInputRef.current
|
|
8338
|
+
}
|
|
8339
|
+
)),
|
|
8340
|
+
shouldCollapse && adhocHiddenCount > 0 && /* @__PURE__ */ React__default.default.createElement(
|
|
8341
|
+
ui.Button,
|
|
8342
|
+
{
|
|
8343
|
+
className: styles.moreIndicator,
|
|
8344
|
+
fill: "text",
|
|
8345
|
+
size: "sm",
|
|
8346
|
+
"aria-label": i18n.t(
|
|
8347
|
+
"grafana-scenes.variables.adhoc-filters-combobox-renderer.show-more-filters",
|
|
8348
|
+
"Show {{count}} more filters",
|
|
8349
|
+
{ count: adhocHiddenCount }
|
|
8350
|
+
),
|
|
8351
|
+
onClick: (e) => {
|
|
8352
|
+
e.stopPropagation();
|
|
8353
|
+
handleExpand();
|
|
8354
|
+
setTimeout(() => {
|
|
8355
|
+
var _a2;
|
|
8356
|
+
return (_a2 = focusOnWipInputRef.current) == null ? void 0 : _a2.call(focusOnWipInputRef);
|
|
8357
|
+
});
|
|
8358
|
+
}
|
|
8359
|
+
},
|
|
8360
|
+
"+",
|
|
8361
|
+
adhocHiddenCount
|
|
8362
|
+
),
|
|
8363
|
+
!readOnly && /* @__PURE__ */ React__default.default.createElement(AdHocFiltersAlwaysWipCombobox, { ref: focusOnWipInputRef, controller, onInputClick: handleExpand }),
|
|
8364
|
+
enableGroupBy && /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, /* @__PURE__ */ React__default.default.createElement("div", { className: styles.sectionDivider }), /* @__PURE__ */ React__default.default.createElement("span", { className: styles.groupByLabel }, i18n.t("grafana-scenes.variables.adhoc-filters-combobox-renderer.group-by-label", "Group by:")), !readOnly && valueRecommendations && /* @__PURE__ */ React__default.default.createElement(AdHocGroupByRecommendationsRenderer, { model: valueRecommendations }), groupByFiltersToRender.map((filter, index) => /* @__PURE__ */ React__default.default.createElement(
|
|
8365
|
+
GroupByPill,
|
|
8366
|
+
{
|
|
8367
|
+
key: `groupby-${index}-${filter.key}`,
|
|
8368
|
+
filter,
|
|
8369
|
+
controller,
|
|
8370
|
+
readOnly: readOnly || filter.readOnly,
|
|
8371
|
+
focusOnWipInputRef: focusOnGroupByWipInputRef.current
|
|
8372
|
+
}
|
|
8373
|
+
)), shouldCollapse && groupByHiddenCount > 0 && /* @__PURE__ */ React__default.default.createElement(
|
|
8374
|
+
ui.Button,
|
|
8375
|
+
{
|
|
8376
|
+
className: styles.moreIndicator,
|
|
8377
|
+
fill: "text",
|
|
8378
|
+
size: "sm",
|
|
8379
|
+
"aria-label": i18n.t(
|
|
8380
|
+
"grafana-scenes.variables.adhoc-filters-combobox-renderer.show-more-group-by",
|
|
8381
|
+
"Show {{count}} more group by",
|
|
8382
|
+
{ count: groupByHiddenCount }
|
|
8383
|
+
),
|
|
8384
|
+
onClick: (e) => {
|
|
8385
|
+
e.stopPropagation();
|
|
8386
|
+
handleExpand();
|
|
8387
|
+
setTimeout(() => {
|
|
8388
|
+
var _a2;
|
|
8389
|
+
return (_a2 = focusOnGroupByWipInputRef.current) == null ? void 0 : _a2.call(focusOnGroupByWipInputRef);
|
|
8390
|
+
});
|
|
8391
|
+
}
|
|
8392
|
+
},
|
|
8393
|
+
"+",
|
|
8394
|
+
groupByHiddenCount
|
|
8395
|
+
), !readOnly && /* @__PURE__ */ React__default.default.createElement(
|
|
8396
|
+
AdHocFiltersAlwaysWipCombobox,
|
|
8397
|
+
{
|
|
8398
|
+
ref: focusOnGroupByWipInputRef,
|
|
8399
|
+
controller,
|
|
8400
|
+
onInputClick: handleExpand,
|
|
8401
|
+
isGroupBy: true
|
|
8390
8402
|
}
|
|
8391
|
-
|
|
8392
|
-
|
|
8393
|
-
|
|
8394
|
-
|
|
8395
|
-
|
|
8396
|
-
|
|
8397
|
-
|
|
8398
|
-
|
|
8403
|
+
), groupByRestorable && /* @__PURE__ */ React__default.default.createElement(
|
|
8404
|
+
ui.IconButton,
|
|
8405
|
+
{
|
|
8406
|
+
name: "history",
|
|
8407
|
+
size: "md",
|
|
8408
|
+
className: styles.controlButton,
|
|
8409
|
+
tooltip: i18n.t(
|
|
8410
|
+
"grafana-scenes.variables.adhoc-filters-combobox-renderer.restore-default-group-by",
|
|
8411
|
+
"Restore groupby set by this dashboard."
|
|
8412
|
+
),
|
|
8413
|
+
onClick: () => {
|
|
8414
|
+
var _a2;
|
|
8415
|
+
return (_a2 = controller.restoreOriginalGroupBy) == null ? void 0 : _a2.call(controller);
|
|
8399
8416
|
}
|
|
8417
|
+
}
|
|
8418
|
+
)),
|
|
8419
|
+
(showCollapseButton || showExpandButton || !readOnly) && /* @__PURE__ */ React__default.default.createElement("div", { className: styles.rightControls }, /* @__PURE__ */ React__default.default.createElement("div", { className: styles.sectionDivider }), showCollapseButton && /* @__PURE__ */ React__default.default.createElement(
|
|
8420
|
+
ui.Button,
|
|
8421
|
+
{
|
|
8422
|
+
className: styles.collapseButton,
|
|
8423
|
+
fill: "text",
|
|
8424
|
+
size: "sm",
|
|
8425
|
+
onClick: handleCollapseToggle,
|
|
8426
|
+
"aria-label": i18n.t(
|
|
8427
|
+
"grafana-scenes.variables.adhoc-filters-combobox-renderer.collapse-filters",
|
|
8428
|
+
"Collapse filters"
|
|
8429
|
+
),
|
|
8430
|
+
"aria-expanded": !collapsed
|
|
8400
8431
|
},
|
|
8401
|
-
|
|
8402
|
-
|
|
8403
|
-
|
|
8404
|
-
|
|
8405
|
-
|
|
8406
|
-
|
|
8432
|
+
i18n.t("grafana-scenes.variables.adhoc-filters-combobox-renderer.collapse", "Collapse"),
|
|
8433
|
+
/* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "angle-up", size: "md" })
|
|
8434
|
+
), showExpandButton && /* @__PURE__ */ React__default.default.createElement(
|
|
8435
|
+
ui.IconButton,
|
|
8436
|
+
{
|
|
8437
|
+
name: "angle-down",
|
|
8438
|
+
size: "md",
|
|
8439
|
+
className: styles.dropdownIndicator,
|
|
8440
|
+
tooltip: i18n.t("grafana-scenes.variables.adhoc-filters-combobox-renderer.expand-filters", "Expand filters"),
|
|
8441
|
+
onClick: (e) => {
|
|
8442
|
+
e.stopPropagation();
|
|
8443
|
+
handleExpand();
|
|
8444
|
+
}
|
|
8445
|
+
}
|
|
8446
|
+
), !readOnly && /* @__PURE__ */ React__default.default.createElement(
|
|
8447
|
+
ui.IconButton,
|
|
8448
|
+
{
|
|
8449
|
+
name: "times",
|
|
8450
|
+
size: "md",
|
|
8451
|
+
className: styles.controlButton,
|
|
8452
|
+
tooltip: i18n.t("grafana-scenes.variables.adhoc-filters-combobox-renderer.clear-all", "Clear all"),
|
|
8453
|
+
onClick: clearAll
|
|
8454
|
+
}
|
|
8455
|
+
))
|
|
8456
|
+
);
|
|
8457
|
+
});
|
|
8407
8458
|
const getStyles$b = (theme) => ({
|
|
8408
|
-
|
|
8459
|
+
comboboxWrapper: css.css({
|
|
8409
8460
|
display: "flex",
|
|
8410
|
-
|
|
8411
|
-
|
|
8412
|
-
|
|
8461
|
+
flexWrap: "wrap",
|
|
8462
|
+
alignItems: "center",
|
|
8463
|
+
columnGap: theme.spacing(1),
|
|
8464
|
+
rowGap: theme.spacing(0.5),
|
|
8465
|
+
minHeight: theme.spacing(4),
|
|
8466
|
+
backgroundColor: theme.components.input.background,
|
|
8467
|
+
border: `1px solid ${theme.colors.border.strong}`,
|
|
8413
8468
|
borderRadius: theme.shape.radius.default,
|
|
8414
|
-
|
|
8415
|
-
|
|
8469
|
+
paddingInline: theme.spacing(1),
|
|
8470
|
+
paddingBlock: theme.spacing(0.5),
|
|
8471
|
+
flexGrow: 1,
|
|
8472
|
+
width: "100%"
|
|
8416
8473
|
}),
|
|
8417
|
-
|
|
8474
|
+
comboboxFocusOutline: css.css({
|
|
8475
|
+
"&:focus-within": {
|
|
8476
|
+
outline: "2px dotted transparent",
|
|
8477
|
+
outlineOffset: "2px",
|
|
8478
|
+
boxShadow: `0 0 0 2px ${theme.colors.background.canvas}, 0 0 0px 4px ${theme.colors.primary.main}`,
|
|
8479
|
+
transitionTimingFunction: `cubic-bezier(0.19, 1, 0.22, 1)`,
|
|
8480
|
+
transitionDuration: "0.2s",
|
|
8481
|
+
transitionProperty: "outline, outline-offset, box-shadow",
|
|
8482
|
+
zIndex: 2
|
|
8483
|
+
}
|
|
8484
|
+
}),
|
|
8485
|
+
collapsed: css.css({
|
|
8486
|
+
flexWrap: "nowrap",
|
|
8487
|
+
overflow: "hidden"
|
|
8488
|
+
}),
|
|
8489
|
+
rightControls: css.css({
|
|
8490
|
+
display: "flex",
|
|
8418
8491
|
alignItems: "center",
|
|
8419
|
-
|
|
8420
|
-
|
|
8421
|
-
|
|
8422
|
-
|
|
8492
|
+
marginLeft: "auto",
|
|
8493
|
+
flexShrink: 0,
|
|
8494
|
+
gap: theme.spacing(1.5)
|
|
8495
|
+
}),
|
|
8496
|
+
moreIndicator: css.css({
|
|
8423
8497
|
color: theme.colors.text.primary,
|
|
8424
|
-
|
|
8425
|
-
|
|
8426
|
-
|
|
8427
|
-
|
|
8428
|
-
fontWeight: theme.typography.fontWeightBold,
|
|
8429
|
-
cursor: "pointer",
|
|
8498
|
+
background: theme.colors.action.selected,
|
|
8499
|
+
height: "auto",
|
|
8500
|
+
lineHeight: "normal",
|
|
8501
|
+
alignSelf: "stretch",
|
|
8430
8502
|
"&:hover": {
|
|
8431
8503
|
background: theme.colors.action.hover
|
|
8432
8504
|
}
|
|
8433
8505
|
}),
|
|
8434
|
-
|
|
8435
|
-
|
|
8436
|
-
|
|
8437
|
-
|
|
8506
|
+
dropdownIndicator: css.css({
|
|
8507
|
+
color: theme.colors.text.secondary,
|
|
8508
|
+
flexShrink: 0
|
|
8509
|
+
}),
|
|
8510
|
+
collapseButton: css.css({
|
|
8511
|
+
color: theme.colors.text.secondary,
|
|
8512
|
+
padding: 0,
|
|
8513
|
+
height: "auto",
|
|
8514
|
+
lineHeight: "normal",
|
|
8515
|
+
"&:hover": {
|
|
8516
|
+
background: "transparent",
|
|
8517
|
+
color: theme.colors.text.primary
|
|
8438
8518
|
}
|
|
8439
8519
|
}),
|
|
8440
|
-
|
|
8441
|
-
|
|
8520
|
+
sectionDivider: css.css({
|
|
8521
|
+
width: "1px",
|
|
8522
|
+
alignSelf: "stretch",
|
|
8523
|
+
backgroundColor: theme.colors.border.weak,
|
|
8524
|
+
flexShrink: 0
|
|
8525
|
+
}),
|
|
8526
|
+
groupByLabel: css.css({
|
|
8527
|
+
...theme.typography.bodySmall,
|
|
8528
|
+
fontWeight: theme.typography.fontWeightBold,
|
|
8529
|
+
color: theme.colors.text.primary,
|
|
8530
|
+
whiteSpace: "nowrap"
|
|
8531
|
+
}),
|
|
8532
|
+
controlButton: css.css({
|
|
8442
8533
|
color: theme.colors.text.secondary,
|
|
8443
|
-
|
|
8534
|
+
"&:hover": {
|
|
8535
|
+
color: theme.colors.text.primary
|
|
8536
|
+
}
|
|
8444
8537
|
})
|
|
8445
8538
|
});
|
|
8446
8539
|
|
|
8447
|
-
const
|
|
8448
|
-
|
|
8449
|
-
|
|
8540
|
+
const reverseScopeFilterOperatorMap = Object.fromEntries(
|
|
8541
|
+
Object.entries(data.scopeFilterOperatorMap).map(([symbol, operator]) => [operator, symbol])
|
|
8542
|
+
);
|
|
8543
|
+
function isEqualityOrMultiOperator(value) {
|
|
8544
|
+
const operators = /* @__PURE__ */ new Set(["equals", "not-equals", "one-of", "not-one-of"]);
|
|
8545
|
+
return operators.has(value);
|
|
8450
8546
|
}
|
|
8451
|
-
function
|
|
8452
|
-
const
|
|
8453
|
-
|
|
8454
|
-
|
|
8455
|
-
|
|
8456
|
-
|
|
8457
|
-
|
|
8458
|
-
|
|
8547
|
+
function isRegexOperator(value) {
|
|
8548
|
+
const operators = /* @__PURE__ */ new Set(["regex-match", "regex-not-match"]);
|
|
8549
|
+
return operators.has(value);
|
|
8550
|
+
}
|
|
8551
|
+
function getAdHocFiltersFromScopes(scopes) {
|
|
8552
|
+
const formattedFilters = /* @__PURE__ */ new Map();
|
|
8553
|
+
const duplicatedFilters = [];
|
|
8554
|
+
const allFilters = scopes.flatMap((scope) => scope.spec.filters);
|
|
8555
|
+
for (const filter of allFilters) {
|
|
8556
|
+
processFilter(formattedFilters, duplicatedFilters, filter);
|
|
8459
8557
|
}
|
|
8460
|
-
return
|
|
8558
|
+
return [...formattedFilters.values(), ...duplicatedFilters];
|
|
8461
8559
|
}
|
|
8462
|
-
|
|
8463
|
-
|
|
8464
|
-
|
|
8465
|
-
|
|
8466
|
-
|
|
8467
|
-
|
|
8468
|
-
|
|
8469
|
-
|
|
8470
|
-
|
|
8471
|
-
|
|
8472
|
-
|
|
8473
|
-
|
|
8474
|
-
|
|
8475
|
-
|
|
8476
|
-
|
|
8477
|
-
|
|
8478
|
-
|
|
8479
|
-
|
|
8480
|
-
|
|
8481
|
-
|
|
8482
|
-
|
|
8483
|
-
|
|
8484
|
-
|
|
8485
|
-
|
|
8486
|
-
|
|
8487
|
-
|
|
8488
|
-
|
|
8489
|
-
);
|
|
8490
|
-
}
|
|
8491
|
-
this._subs.add(
|
|
8492
|
-
adHocSubscription = this._adHocFilter.subscribeToState((newState, prevState) => {
|
|
8493
|
-
if (newState.filters !== prevState.filters) {
|
|
8494
|
-
const json2 = data.store.get(this._getStorageKey());
|
|
8495
|
-
const storedFilters2 = json2 ? JSON.parse(json2) : [];
|
|
8496
|
-
if (storedFilters2.length > 0) {
|
|
8497
|
-
this._verifyRecentFiltersApplicability(storedFilters2);
|
|
8498
|
-
}
|
|
8499
|
-
this._fetchRecommendedDrilldowns();
|
|
8500
|
-
}
|
|
8501
|
-
})
|
|
8502
|
-
);
|
|
8503
|
-
return () => {
|
|
8504
|
-
scopesSubscription == null ? void 0 : scopesSubscription.unsubscribe();
|
|
8505
|
-
adHocSubscription == null ? void 0 : adHocSubscription.unsubscribe();
|
|
8506
|
-
};
|
|
8507
|
-
};
|
|
8508
|
-
this.addActivationHandler(this._activationHandler);
|
|
8560
|
+
function processFilter(formattedFilters, duplicatedFilters, filter) {
|
|
8561
|
+
var _a, _b;
|
|
8562
|
+
if (!filter) {
|
|
8563
|
+
return;
|
|
8564
|
+
}
|
|
8565
|
+
const existingFilter = formattedFilters.get(filter.key);
|
|
8566
|
+
if (existingFilter && isEqualityValue(existingFilter.operator, filter.operator)) {
|
|
8567
|
+
mergeFilterValues(existingFilter, filter);
|
|
8568
|
+
} else if (existingFilter && isRegexValue(existingFilter.operator, filter.operator)) {
|
|
8569
|
+
existingFilter.value += `|${filter.value}`;
|
|
8570
|
+
existingFilter.values = [existingFilter.value];
|
|
8571
|
+
} else if (!existingFilter) {
|
|
8572
|
+
formattedFilters.set(filter.key, {
|
|
8573
|
+
key: filter.key,
|
|
8574
|
+
operator: reverseScopeFilterOperatorMap[filter.operator],
|
|
8575
|
+
value: filter.value,
|
|
8576
|
+
values: (_a = filter.values) != null ? _a : [filter.value],
|
|
8577
|
+
origin: "scope"
|
|
8578
|
+
});
|
|
8579
|
+
} else {
|
|
8580
|
+
duplicatedFilters.push({
|
|
8581
|
+
key: filter.key,
|
|
8582
|
+
operator: reverseScopeFilterOperatorMap[filter.operator],
|
|
8583
|
+
value: filter.value,
|
|
8584
|
+
values: (_b = filter.values) != null ? _b : [filter.value],
|
|
8585
|
+
origin: "scope"
|
|
8586
|
+
});
|
|
8509
8587
|
}
|
|
8510
|
-
|
|
8511
|
-
|
|
8512
|
-
|
|
8588
|
+
}
|
|
8589
|
+
function mergeFilterValues(adHocFilter, filter) {
|
|
8590
|
+
var _a, _b, _c, _d;
|
|
8591
|
+
const values = (_a = filter.values) != null ? _a : [filter.value];
|
|
8592
|
+
for (const value of values) {
|
|
8593
|
+
if (!((_b = adHocFilter.values) == null ? void 0 : _b.includes(value))) {
|
|
8594
|
+
(_c = adHocFilter.values) == null ? void 0 : _c.push(value);
|
|
8513
8595
|
}
|
|
8514
|
-
return this.parent;
|
|
8515
8596
|
}
|
|
8516
|
-
|
|
8517
|
-
return
|
|
8597
|
+
if (((_d = adHocFilter.values) == null ? void 0 : _d.length) === 1) {
|
|
8598
|
+
return;
|
|
8518
8599
|
}
|
|
8519
|
-
|
|
8520
|
-
|
|
8521
|
-
|
|
8600
|
+
if (filter.operator === "equals" && adHocFilter.operator === reverseScopeFilterOperatorMap["equals"]) {
|
|
8601
|
+
adHocFilter.operator = reverseScopeFilterOperatorMap["one-of"];
|
|
8602
|
+
} else if (filter.operator === "not-equals" && adHocFilter.operator === reverseScopeFilterOperatorMap["not-equals"]) {
|
|
8603
|
+
adHocFilter.operator = reverseScopeFilterOperatorMap["not-one-of"];
|
|
8522
8604
|
}
|
|
8523
|
-
|
|
8524
|
-
|
|
8525
|
-
|
|
8526
|
-
|
|
8527
|
-
|
|
8528
|
-
this.setState({ datasourceSupportsRecommendations: false });
|
|
8529
|
-
return;
|
|
8530
|
-
}
|
|
8531
|
-
this.setState({ datasourceSupportsRecommendations: true });
|
|
8532
|
-
const queries = adhoc.state.useQueriesAsFilterForOptions ? getQueriesForVariables(adhoc) : void 0;
|
|
8533
|
-
const timeRange = sceneGraph.getTimeRange(adhoc).state.value;
|
|
8534
|
-
const scopes = sceneGraph.getScopes(adhoc);
|
|
8535
|
-
const filters = [...(_a = adhoc.state.originFilters) != null ? _a : [], ...adhoc.state.filters].filter((f) => !isGroupByFilter(f));
|
|
8536
|
-
const enrichedRequest = getEnrichedDataRequest(adhoc);
|
|
8537
|
-
const dashboardUid = enrichedRequest == null ? void 0 : enrichedRequest.dashboardUID;
|
|
8538
|
-
try {
|
|
8539
|
-
const recommendedDrilldowns = await ds.getRecommendedDrilldowns({
|
|
8540
|
-
timeRange,
|
|
8541
|
-
dashboardUid,
|
|
8542
|
-
queries: queries != null ? queries : [],
|
|
8543
|
-
filters,
|
|
8544
|
-
scopes
|
|
8545
|
-
});
|
|
8546
|
-
if (recommendedDrilldowns == null ? void 0 : recommendedDrilldowns.filters) {
|
|
8547
|
-
this.setState({ recommendedFilters: recommendedDrilldowns.filters });
|
|
8548
|
-
}
|
|
8549
|
-
} catch (error) {
|
|
8550
|
-
console.error("Failed to fetch recommended drilldowns:", error);
|
|
8551
|
-
}
|
|
8605
|
+
}
|
|
8606
|
+
function isRegexValue(adHocFilterOperator, filterOperator) {
|
|
8607
|
+
const scopeConvertedOperator = data.scopeFilterOperatorMap[adHocFilterOperator];
|
|
8608
|
+
if (!isRegexOperator(scopeConvertedOperator) || !isRegexOperator(filterOperator)) {
|
|
8609
|
+
return false;
|
|
8552
8610
|
}
|
|
8553
|
-
|
|
8554
|
-
|
|
8555
|
-
|
|
8556
|
-
|
|
8557
|
-
|
|
8558
|
-
|
|
8559
|
-
|
|
8560
|
-
|
|
8611
|
+
return hasSameOperators(scopeConvertedOperator, filterOperator);
|
|
8612
|
+
}
|
|
8613
|
+
function isEqualityValue(adHocFilterOperator, filterOperator) {
|
|
8614
|
+
const scopeConvertedOperator = data.scopeFilterOperatorMap[adHocFilterOperator];
|
|
8615
|
+
if (!isEqualityOrMultiOperator(scopeConvertedOperator) || !isEqualityOrMultiOperator(filterOperator)) {
|
|
8616
|
+
return false;
|
|
8617
|
+
}
|
|
8618
|
+
return hasSameOperators(scopeConvertedOperator, filterOperator);
|
|
8619
|
+
}
|
|
8620
|
+
function hasSameOperators(scopeConvertedOperator, filterOperator) {
|
|
8621
|
+
if (scopeConvertedOperator.includes("not") && !filterOperator.includes("not") || !scopeConvertedOperator.includes("not") && filterOperator.includes("not")) {
|
|
8622
|
+
return false;
|
|
8623
|
+
}
|
|
8624
|
+
return true;
|
|
8625
|
+
}
|
|
8626
|
+
|
|
8627
|
+
function isInteractionTracker(s) {
|
|
8628
|
+
return "isInteractionTracker" in s;
|
|
8629
|
+
}
|
|
8630
|
+
class SceneInteractionTracker extends SceneObjectBase {
|
|
8631
|
+
constructor(state = {}, renderProfiler) {
|
|
8632
|
+
super(state);
|
|
8633
|
+
this.renderProfiler = renderProfiler;
|
|
8634
|
+
this.isInteractionTracker = true;
|
|
8635
|
+
if (renderProfiler) {
|
|
8636
|
+
this.renderProfiler = renderProfiler;
|
|
8637
|
+
this.renderProfiler.setInteractionCompleteHandler(state.onInteractionComplete);
|
|
8561
8638
|
}
|
|
8562
|
-
const applicabilityMap = /* @__PURE__ */ new Map();
|
|
8563
|
-
response.forEach((item) => {
|
|
8564
|
-
applicabilityMap.set(item.key, item.applicable !== false);
|
|
8565
|
-
});
|
|
8566
|
-
const applicableFilters = storedFilters.filter((f) => {
|
|
8567
|
-
const isApplicable = applicabilityMap.get(f.key);
|
|
8568
|
-
return isApplicable === void 0 || isApplicable === true;
|
|
8569
|
-
});
|
|
8570
|
-
const recentFilters = deduplicateFilters(applicableFilters).slice(-3);
|
|
8571
|
-
this.setState({ recentFilters });
|
|
8572
8639
|
}
|
|
8573
|
-
|
|
8574
|
-
|
|
8575
|
-
|
|
8576
|
-
|
|
8577
|
-
storeRecentFilter(filter) {
|
|
8578
|
-
const key = this._getStorageKey();
|
|
8579
|
-
const storedFilters = data.store.get(key);
|
|
8580
|
-
const allRecentFilters = storedFilters ? JSON.parse(storedFilters) : [];
|
|
8581
|
-
const updatedStoredFilters = deduplicateFilters([...allRecentFilters, filter]).slice(-10);
|
|
8582
|
-
data.store.set(key, JSON.stringify(updatedStoredFilters));
|
|
8583
|
-
const adhoc = this._adHocFilter;
|
|
8584
|
-
const existingFilter = adhoc.state.filters.find((f) => f.key === filter.key && !Boolean(f.nonApplicable));
|
|
8585
|
-
if (existingFilter && !Boolean(existingFilter.nonApplicable)) {
|
|
8586
|
-
this.setState({ recentFilters: updatedStoredFilters.slice(-3) });
|
|
8640
|
+
startInteraction(name) {
|
|
8641
|
+
var _a;
|
|
8642
|
+
if (!this.state.enableInteractionTracking) {
|
|
8643
|
+
return;
|
|
8587
8644
|
}
|
|
8645
|
+
(_a = this.renderProfiler) == null ? void 0 : _a.startInteraction(name);
|
|
8588
8646
|
}
|
|
8589
|
-
|
|
8590
|
-
|
|
8647
|
+
stopInteraction() {
|
|
8648
|
+
var _a;
|
|
8649
|
+
(_a = this.renderProfiler) == null ? void 0 : _a.stopInteraction();
|
|
8591
8650
|
}
|
|
8592
8651
|
}
|
|
8593
|
-
|
|
8594
|
-
function
|
|
8595
|
-
|
|
8596
|
-
|
|
8597
|
-
|
|
8598
|
-
|
|
8599
|
-
|
|
8600
|
-
|
|
8601
|
-
|
|
8602
|
-
model.addFilterToParent(filter);
|
|
8603
|
-
}
|
|
8604
|
-
}
|
|
8605
|
-
}));
|
|
8606
|
-
const recommendedDrilldowns = recommendedFilters == null ? void 0 : recommendedFilters.map((filter) => ({
|
|
8607
|
-
label: `${filter.key} ${filter.operator} ${filter.value}`,
|
|
8608
|
-
onClick: () => {
|
|
8609
|
-
const exists = filters.some((f) => f.key === filter.key && f.value === filter.value);
|
|
8610
|
-
if (!exists) {
|
|
8611
|
-
model.addFilterToParent(filter);
|
|
8652
|
+
|
|
8653
|
+
function getInteractionTracker(sceneObject) {
|
|
8654
|
+
let parent = sceneObject;
|
|
8655
|
+
while (parent) {
|
|
8656
|
+
if (parent.state.$behaviors) {
|
|
8657
|
+
for (const behavior of parent.state.$behaviors) {
|
|
8658
|
+
if (isInteractionTracker(behavior)) {
|
|
8659
|
+
return behavior;
|
|
8660
|
+
}
|
|
8612
8661
|
}
|
|
8613
8662
|
}
|
|
8614
|
-
|
|
8615
|
-
|
|
8616
|
-
|
|
8617
|
-
|
|
8618
|
-
|
|
8619
|
-
|
|
8620
|
-
|
|
8621
|
-
|
|
8622
|
-
|
|
8663
|
+
parent = parent.parent;
|
|
8664
|
+
}
|
|
8665
|
+
return void 0;
|
|
8666
|
+
}
|
|
8667
|
+
|
|
8668
|
+
class AdHocFiltersVariableController {
|
|
8669
|
+
constructor(model) {
|
|
8670
|
+
this.model = model;
|
|
8671
|
+
}
|
|
8672
|
+
useState() {
|
|
8673
|
+
const state = this.model.useState();
|
|
8674
|
+
return {
|
|
8675
|
+
filters: state.filters,
|
|
8676
|
+
originFilters: state.originFilters,
|
|
8677
|
+
readOnly: state.readOnly,
|
|
8678
|
+
allowCustomValue: state.allowCustomValue,
|
|
8679
|
+
supportsMultiValueOperators: state.supportsMultiValueOperators,
|
|
8680
|
+
onAddCustomValue: state.onAddCustomValue,
|
|
8681
|
+
wip: state._wip,
|
|
8682
|
+
inputPlaceholder: state.inputPlaceholder,
|
|
8683
|
+
groupByInputPlaceholder: state.groupByInputPlaceholder,
|
|
8684
|
+
collapsible: state.collapsible,
|
|
8685
|
+
valueRecommendations: this.model.getRecommendations(),
|
|
8686
|
+
drilldownRecommendationsEnabled: state.drilldownRecommendationsEnabled,
|
|
8687
|
+
enableGroupBy: state.enableGroupBy,
|
|
8688
|
+
groupByRestorable: this.model.isGroupByRestorable()
|
|
8689
|
+
};
|
|
8690
|
+
}
|
|
8691
|
+
async getKeys(currentKey) {
|
|
8692
|
+
return this.model._getKeys(currentKey);
|
|
8693
|
+
}
|
|
8694
|
+
async getGroupByKeys(currentKey) {
|
|
8695
|
+
return this.model._getGroupByKeys(currentKey);
|
|
8696
|
+
}
|
|
8697
|
+
async getValuesFor(filter) {
|
|
8698
|
+
return this.model._getValuesFor(filter);
|
|
8699
|
+
}
|
|
8700
|
+
getOperators() {
|
|
8701
|
+
return this.model._getOperators();
|
|
8702
|
+
}
|
|
8703
|
+
updateFilter(filter, update) {
|
|
8704
|
+
this.model._updateFilter(filter, update);
|
|
8705
|
+
}
|
|
8706
|
+
updateFilters(filters, options) {
|
|
8707
|
+
this.model.updateFilters(filters, options);
|
|
8708
|
+
}
|
|
8709
|
+
updateToMatchAll(filter) {
|
|
8710
|
+
this.model.updateToMatchAll(filter);
|
|
8711
|
+
}
|
|
8712
|
+
removeFilter(filter) {
|
|
8713
|
+
this.model._removeFilter(filter);
|
|
8714
|
+
}
|
|
8715
|
+
removeLastFilter() {
|
|
8716
|
+
this.model._removeLastFilter();
|
|
8717
|
+
}
|
|
8718
|
+
handleComboboxBackspace(filter) {
|
|
8719
|
+
this.model._handleComboboxBackspace(filter);
|
|
8720
|
+
}
|
|
8721
|
+
addWip() {
|
|
8722
|
+
this.model._addWip();
|
|
8723
|
+
}
|
|
8724
|
+
addGroupByFilter(item) {
|
|
8725
|
+
this.model._addGroupByFilter(item);
|
|
8726
|
+
}
|
|
8727
|
+
restoreOriginalFilter(filter) {
|
|
8728
|
+
this.model.restoreOriginalFilter(filter);
|
|
8729
|
+
}
|
|
8730
|
+
restoreOriginalGroupBy() {
|
|
8731
|
+
this.model.restoreOriginalGroupBy();
|
|
8732
|
+
}
|
|
8733
|
+
clearAll() {
|
|
8734
|
+
this.model.clearAll();
|
|
8735
|
+
}
|
|
8736
|
+
startProfile(name) {
|
|
8737
|
+
const queryController = getQueryController(this.model);
|
|
8738
|
+
queryController == null ? void 0 : queryController.startProfile(name);
|
|
8739
|
+
}
|
|
8740
|
+
startInteraction(name) {
|
|
8741
|
+
const interactionTracker = getInteractionTracker(this.model);
|
|
8742
|
+
interactionTracker == null ? void 0 : interactionTracker.startInteraction(name);
|
|
8743
|
+
}
|
|
8744
|
+
stopInteraction() {
|
|
8745
|
+
const interactionTracker = getInteractionTracker(this.model);
|
|
8746
|
+
interactionTracker == null ? void 0 : interactionTracker.stopInteraction();
|
|
8747
|
+
}
|
|
8623
8748
|
}
|
|
8624
8749
|
|
|
8625
8750
|
const ORIGIN_FILTERS_KEY = "originFilters";
|
|
@@ -8858,7 +8983,7 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
|
8858
8983
|
* No-op when enableGroupBy is false.
|
|
8859
8984
|
*/
|
|
8860
8985
|
_addGroupByFilter(item) {
|
|
8861
|
-
var _a, _b;
|
|
8986
|
+
var _a, _b, _c;
|
|
8862
8987
|
if (!this.state.enableGroupBy) {
|
|
8863
8988
|
return;
|
|
8864
8989
|
}
|
|
@@ -8871,6 +8996,7 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
|
8871
8996
|
value: "",
|
|
8872
8997
|
condition: ""
|
|
8873
8998
|
};
|
|
8999
|
+
(_c = this._recommendations) == null ? void 0 : _c.storeRecentGrouping(key);
|
|
8874
9000
|
this.updateFilters([...this.state.filters, newFilter]);
|
|
8875
9001
|
}
|
|
8876
9002
|
restoreOriginalFilter(filter) {
|
|
@@ -9004,7 +9130,7 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
|
9004
9130
|
return this.state.filterExpression;
|
|
9005
9131
|
}
|
|
9006
9132
|
_updateFilter(filter, update) {
|
|
9007
|
-
var _a, _b, _c, _d, _e;
|
|
9133
|
+
var _a, _b, _c, _d, _e, _f;
|
|
9008
9134
|
const { originFilters, filters, _wip } = this.state;
|
|
9009
9135
|
if ("value" in update && !("values" in update)) {
|
|
9010
9136
|
update = { ...update, values: void 0 };
|
|
@@ -9074,10 +9200,12 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
|
9074
9200
|
return f === filter ? { ...f, ...update } : f;
|
|
9075
9201
|
});
|
|
9076
9202
|
this.setState({ filters: updatedFilters });
|
|
9077
|
-
|
|
9078
|
-
|
|
9079
|
-
|
|
9080
|
-
}
|
|
9203
|
+
const merged = { ...filter, ...update };
|
|
9204
|
+
if (isGroupByFilter(merged)) {
|
|
9205
|
+
(_e = this._recommendations) == null ? void 0 : _e.storeRecentGrouping(merged.key);
|
|
9206
|
+
} else {
|
|
9207
|
+
(_f = this._recommendations) == null ? void 0 : _f.storeRecentFilter(merged);
|
|
9208
|
+
}
|
|
9081
9209
|
}
|
|
9082
9210
|
updateToMatchAll(filter) {
|
|
9083
9211
|
var _a;
|