@grafana/scenes 6.50.0--canary.1312.20243507649.0 → 6.50.0--canary.1316.20252812955.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/packages/scenes/src/index.js +1 -1
- package/dist/esm/packages/scenes/src/index.js.map +1 -1
- package/dist/esm/packages/scenes/src/locales/en-US/grafana-scenes.json.js +6 -7
- package/dist/esm/packages/scenes/src/locales/en-US/grafana-scenes.json.js.map +1 -1
- package/dist/esm/packages/scenes/src/variables/DrilldownDependenciesManager.js.map +1 -1
- package/dist/esm/packages/scenes/src/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersAlwaysWipCombobox.js +2 -2
- package/dist/esm/packages/scenes/src/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersAlwaysWipCombobox.js.map +1 -1
- package/dist/esm/packages/scenes/src/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersCombobox.js +3 -1
- package/dist/esm/packages/scenes/src/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersCombobox.js.map +1 -1
- package/dist/esm/packages/scenes/src/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersComboboxRenderer.js +110 -23
- package/dist/esm/packages/scenes/src/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersComboboxRenderer.js.map +1 -1
- package/dist/esm/packages/scenes/src/variables/adhoc/AdHocFiltersCombobox/utils.js +3 -0
- package/dist/esm/packages/scenes/src/variables/adhoc/AdHocFiltersCombobox/utils.js.map +1 -1
- package/dist/esm/packages/scenes/src/variables/adhoc/AdHocFiltersVariable.js +15 -26
- package/dist/esm/packages/scenes/src/variables/adhoc/AdHocFiltersVariable.js.map +1 -1
- package/dist/esm/packages/scenes/src/variables/adhoc/controller/AdHocFiltersVariableController.js +4 -5
- package/dist/esm/packages/scenes/src/variables/adhoc/controller/AdHocFiltersVariableController.js.map +1 -1
- package/dist/esm/packages/scenes/src/variables/groupby/GroupByVariable.js +7 -59
- package/dist/esm/packages/scenes/src/variables/groupby/GroupByVariable.js.map +1 -1
- package/dist/{grafana-scenes-C9F_2hih.js → grafana-scenes-CwGWCTcQ.js} +7 -8
- package/dist/{grafana-scenes-C9F_2hih.js.map → grafana-scenes-CwGWCTcQ.js.map} +1 -1
- package/dist/index.d.ts +18 -127
- package/dist/index.js +225 -624
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/esm/packages/scenes/src/variables/adhoc/AdHocFiltersRecommendations.js +0 -174
- package/dist/esm/packages/scenes/src/variables/adhoc/AdHocFiltersRecommendations.js.map +0 -1
- package/dist/esm/packages/scenes/src/variables/components/DrilldownRecommendations.js +0 -102
- package/dist/esm/packages/scenes/src/variables/components/DrilldownRecommendations.js.map +0 -1
- package/dist/esm/packages/scenes/src/variables/groupby/GroupByRecommendations.js +0 -192
- package/dist/esm/packages/scenes/src/variables/groupby/GroupByRecommendations.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -3458,7 +3458,7 @@ function wrapInSafeSerializableSceneObject(sceneObject) {
|
|
|
3458
3458
|
function DefaultGroupByCustomIndicatorContainer(props) {
|
|
3459
3459
|
const { model } = props;
|
|
3460
3460
|
const theme = ui.useTheme2();
|
|
3461
|
-
const styles = getStyles$
|
|
3461
|
+
const styles = getStyles$j(theme);
|
|
3462
3462
|
const inputStyles = ui.getInputStyles({ theme, invalid: false });
|
|
3463
3463
|
const value = lodash.isArray(model.state.value) ? model.state.value : model.state.value ? [model.state.value] : [];
|
|
3464
3464
|
let buttons = [];
|
|
@@ -3540,7 +3540,7 @@ function DefaultGroupByCustomIndicatorContainer(props) {
|
|
|
3540
3540
|
buttons
|
|
3541
3541
|
);
|
|
3542
3542
|
}
|
|
3543
|
-
const getStyles$
|
|
3543
|
+
const getStyles$j = (theme) => ({
|
|
3544
3544
|
clearIcon: css.css({
|
|
3545
3545
|
color: theme.colors.action.disabledText,
|
|
3546
3546
|
cursor: "pointer",
|
|
@@ -3614,518 +3614,6 @@ function getInteractionTracker(sceneObject) {
|
|
|
3614
3614
|
return void 0;
|
|
3615
3615
|
}
|
|
3616
3616
|
|
|
3617
|
-
function DrilldownRecommendations({ recentDrilldowns, recommendedDrilldowns }) {
|
|
3618
|
-
const styles = ui.useStyles2(getStyles$k);
|
|
3619
|
-
const [isPopoverVisible, setPopoverVisible] = React.useState(false);
|
|
3620
|
-
const ref = React.useRef(null);
|
|
3621
|
-
const openPopover = () => {
|
|
3622
|
-
setPopoverVisible(true);
|
|
3623
|
-
};
|
|
3624
|
-
const onClickAction = (action) => {
|
|
3625
|
-
action();
|
|
3626
|
-
setPopoverVisible(false);
|
|
3627
|
-
};
|
|
3628
|
-
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(
|
|
3629
|
-
"div",
|
|
3630
|
-
{
|
|
3631
|
-
key: drilldown.label,
|
|
3632
|
-
className: css.cx(styles.combinedFilterPill),
|
|
3633
|
-
onClick: () => onClickAction(drilldown.onClick)
|
|
3634
|
-
},
|
|
3635
|
-
drilldown.label
|
|
3636
|
-
)) : /* @__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")), /* @__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(
|
|
3637
|
-
"div",
|
|
3638
|
-
{
|
|
3639
|
-
key: drilldown.label,
|
|
3640
|
-
className: css.cx(styles.combinedFilterPill),
|
|
3641
|
-
onClick: () => onClickAction(drilldown.onClick)
|
|
3642
|
-
},
|
|
3643
|
-
drilldown.label
|
|
3644
|
-
)) : /* @__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")))));
|
|
3645
|
-
return /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, /* @__PURE__ */ React__default.default.createElement(
|
|
3646
|
-
ui.IconButton,
|
|
3647
|
-
{
|
|
3648
|
-
name: "plus",
|
|
3649
|
-
tooltip: i18n.t("grafana-scenes.components.drilldown-recommendations.tooltip", "Show recommendations"),
|
|
3650
|
-
ref,
|
|
3651
|
-
className: css.cx(isPopoverVisible && styles.iconActive),
|
|
3652
|
-
onClick: (ev) => {
|
|
3653
|
-
openPopover();
|
|
3654
|
-
ev.stopPropagation();
|
|
3655
|
-
}
|
|
3656
|
-
}
|
|
3657
|
-
), isPopoverVisible && ref.current && /* @__PURE__ */ React__default.default.createElement(
|
|
3658
|
-
ui.Popover,
|
|
3659
|
-
{
|
|
3660
|
-
content,
|
|
3661
|
-
onKeyDown: (event) => {
|
|
3662
|
-
if (event.key === " ") {
|
|
3663
|
-
event.stopPropagation();
|
|
3664
|
-
}
|
|
3665
|
-
},
|
|
3666
|
-
placement: "bottom-start",
|
|
3667
|
-
referenceElement: ref.current,
|
|
3668
|
-
show: true
|
|
3669
|
-
}
|
|
3670
|
-
));
|
|
3671
|
-
}
|
|
3672
|
-
const getStyles$k = (theme) => ({
|
|
3673
|
-
menuContainer: css.css({
|
|
3674
|
-
display: "flex",
|
|
3675
|
-
flexDirection: "column",
|
|
3676
|
-
background: theme.colors.background.elevated,
|
|
3677
|
-
border: `1px solid ${theme.colors.border.weak}`,
|
|
3678
|
-
borderRadius: theme.shape.radius.default,
|
|
3679
|
-
boxShadow: theme.shadows.z3,
|
|
3680
|
-
padding: theme.spacing(2)
|
|
3681
|
-
}),
|
|
3682
|
-
combinedFilterPill: css.css({
|
|
3683
|
-
alignItems: "center",
|
|
3684
|
-
background: theme.colors.action.selected,
|
|
3685
|
-
borderRadius: theme.shape.radius.default,
|
|
3686
|
-
border: `1px solid ${theme.colors.border.weak}`,
|
|
3687
|
-
padding: theme.spacing(0.2, 1),
|
|
3688
|
-
color: theme.colors.text.primary,
|
|
3689
|
-
overflow: "hidden",
|
|
3690
|
-
whiteSpace: "nowrap",
|
|
3691
|
-
minHeight: theme.spacing(2.75),
|
|
3692
|
-
...theme.typography.bodySmall,
|
|
3693
|
-
fontWeight: theme.typography.fontWeightBold,
|
|
3694
|
-
cursor: "pointer",
|
|
3695
|
-
"&:hover": {
|
|
3696
|
-
background: theme.colors.action.hover
|
|
3697
|
-
}
|
|
3698
|
-
}),
|
|
3699
|
-
iconActive: css.css({
|
|
3700
|
-
"&:before": {
|
|
3701
|
-
backgroundColor: theme.colors.action.hover,
|
|
3702
|
-
opacity: 1
|
|
3703
|
-
}
|
|
3704
|
-
}),
|
|
3705
|
-
emptyMessage: css.css({
|
|
3706
|
-
padding: theme.spacing(0.5, 0),
|
|
3707
|
-
color: theme.colors.text.secondary,
|
|
3708
|
-
...theme.typography.bodySmall
|
|
3709
|
-
})
|
|
3710
|
-
});
|
|
3711
|
-
|
|
3712
|
-
class ScopesVariable extends SceneObjectBase {
|
|
3713
|
-
constructor(state) {
|
|
3714
|
-
super({
|
|
3715
|
-
skipUrlSync: true,
|
|
3716
|
-
loading: true,
|
|
3717
|
-
scopes: [],
|
|
3718
|
-
...state,
|
|
3719
|
-
type: "system",
|
|
3720
|
-
name: SCOPES_VARIABLE_NAME,
|
|
3721
|
-
hide: schema.VariableHide.hideVariable
|
|
3722
|
-
});
|
|
3723
|
-
this._renderBeforeActivation = true;
|
|
3724
|
-
// Special options that enables variables to be hidden but still render to access react contexts
|
|
3725
|
-
this.UNSAFE_renderAsHidden = true;
|
|
3726
|
-
}
|
|
3727
|
-
/**
|
|
3728
|
-
* Temporary simple implementation to stringify the scopes.
|
|
3729
|
-
*/
|
|
3730
|
-
getValue() {
|
|
3731
|
-
var _a;
|
|
3732
|
-
const scopes = (_a = this.state.scopes) != null ? _a : [];
|
|
3733
|
-
return new ScopesVariableFormatter(scopes.map((scope) => scope.metadata.name));
|
|
3734
|
-
}
|
|
3735
|
-
getScopes() {
|
|
3736
|
-
return this.state.scopes;
|
|
3737
|
-
}
|
|
3738
|
-
/**
|
|
3739
|
-
* This method is used to keep the context up to date with the scopes context received from React
|
|
3740
|
-
* 1) Subscribes to ScopesContext state changes and synchronizes it with the variable state
|
|
3741
|
-
* 2) Handles enable / disabling of scopes based on variable enable option.
|
|
3742
|
-
*/
|
|
3743
|
-
setContext(context) {
|
|
3744
|
-
if (!context) {
|
|
3745
|
-
return;
|
|
3746
|
-
}
|
|
3747
|
-
this._context = context;
|
|
3748
|
-
const oldState = context.state;
|
|
3749
|
-
if (this.state.enable != null) {
|
|
3750
|
-
context.setEnabled(this.state.enable);
|
|
3751
|
-
}
|
|
3752
|
-
const sub = context.stateObservable.subscribe((state) => {
|
|
3753
|
-
this.updateStateFromContext(state);
|
|
3754
|
-
});
|
|
3755
|
-
return () => {
|
|
3756
|
-
sub.unsubscribe();
|
|
3757
|
-
if (this.state.enable != null) {
|
|
3758
|
-
context.setEnabled(oldState.enabled);
|
|
3759
|
-
}
|
|
3760
|
-
};
|
|
3761
|
-
}
|
|
3762
|
-
updateStateFromContext(state) {
|
|
3763
|
-
const loading = state.value.length === 0 ? false : state.loading;
|
|
3764
|
-
const oldScopes = this.state.scopes.map((scope) => scope.metadata.name);
|
|
3765
|
-
const newScopes = state.value.map((scope) => scope.metadata.name);
|
|
3766
|
-
const scopesHaveChanged = !lodash.isEqual(oldScopes, newScopes);
|
|
3767
|
-
if (!loading && (scopesHaveChanged || newScopes.length === 0)) {
|
|
3768
|
-
const queryController = getQueryController(this);
|
|
3769
|
-
queryController == null ? void 0 : queryController.startProfile(SCOPES_CHANGED_INTERACTION);
|
|
3770
|
-
this.setState({ scopes: state.value, loading });
|
|
3771
|
-
this.publishEvent(new SceneVariableValueChangedEvent(this), true);
|
|
3772
|
-
} else {
|
|
3773
|
-
this.setState({ loading });
|
|
3774
|
-
}
|
|
3775
|
-
}
|
|
3776
|
-
}
|
|
3777
|
-
ScopesVariable.Component = ScopesVariableRenderer;
|
|
3778
|
-
function ScopesVariableRenderer({ model }) {
|
|
3779
|
-
const context = React.useContext(runtime.ScopesContext);
|
|
3780
|
-
React.useEffect(() => {
|
|
3781
|
-
return model.setContext(context);
|
|
3782
|
-
}, [context, model]);
|
|
3783
|
-
return null;
|
|
3784
|
-
}
|
|
3785
|
-
class ScopesVariableFormatter {
|
|
3786
|
-
constructor(_value) {
|
|
3787
|
-
this._value = _value;
|
|
3788
|
-
}
|
|
3789
|
-
formatter(formatNameOrFn) {
|
|
3790
|
-
if (formatNameOrFn === schema.VariableFormatID.QueryParam) {
|
|
3791
|
-
return this._value.map((scope) => `scope=${encodeURIComponent(scope)}`).join("&");
|
|
3792
|
-
}
|
|
3793
|
-
return this._value.join(", ");
|
|
3794
|
-
}
|
|
3795
|
-
}
|
|
3796
|
-
|
|
3797
|
-
const getRecentFiltersKey = (datasourceUid) => `grafana.filters.recent.${datasourceUid != null ? datasourceUid : "default"}`;
|
|
3798
|
-
class AdHocFiltersRecommendations extends SceneObjectBase {
|
|
3799
|
-
constructor(parent) {
|
|
3800
|
-
super({});
|
|
3801
|
-
this._scopedVars = { __sceneObject: wrapInSafeSerializableSceneObject(this) };
|
|
3802
|
-
this._activationHandler = () => {
|
|
3803
|
-
const json = data.store.get(this._getStorageKey());
|
|
3804
|
-
const storedFilters = json ? JSON.parse(json) : [];
|
|
3805
|
-
if (storedFilters.length > 0) {
|
|
3806
|
-
this._verifyRecentFiltersApplicability(storedFilters);
|
|
3807
|
-
} else {
|
|
3808
|
-
this.setState({ recentFilters: [] });
|
|
3809
|
-
}
|
|
3810
|
-
this._fetchRecommendedDrilldowns();
|
|
3811
|
-
const scopesVariable = sceneGraph.lookupVariable(SCOPES_VARIABLE_NAME, this);
|
|
3812
|
-
let scopesSubscription;
|
|
3813
|
-
if (scopesVariable instanceof ScopesVariable) {
|
|
3814
|
-
scopesSubscription = scopesVariable.subscribeToState((newState, prevState) => {
|
|
3815
|
-
if (newState.scopes !== prevState.scopes) {
|
|
3816
|
-
const json2 = data.store.get(this._getStorageKey());
|
|
3817
|
-
const storedFilters2 = json2 ? JSON.parse(json2) : [];
|
|
3818
|
-
if (storedFilters2.length > 0) {
|
|
3819
|
-
this._verifyRecentFiltersApplicability(storedFilters2);
|
|
3820
|
-
}
|
|
3821
|
-
}
|
|
3822
|
-
});
|
|
3823
|
-
}
|
|
3824
|
-
return () => {
|
|
3825
|
-
scopesSubscription == null ? void 0 : scopesSubscription.unsubscribe();
|
|
3826
|
-
};
|
|
3827
|
-
};
|
|
3828
|
-
this._parentVariable = parent;
|
|
3829
|
-
this.addActivationHandler(this._activationHandler);
|
|
3830
|
-
}
|
|
3831
|
-
/**
|
|
3832
|
-
* Get the parent variable
|
|
3833
|
-
*/
|
|
3834
|
-
get parent() {
|
|
3835
|
-
return this._parentVariable;
|
|
3836
|
-
}
|
|
3837
|
-
_getStorageKey() {
|
|
3838
|
-
var _a;
|
|
3839
|
-
return getRecentFiltersKey((_a = this._parentVariable.state.datasource) == null ? void 0 : _a.uid);
|
|
3840
|
-
}
|
|
3841
|
-
async _fetchRecommendedDrilldowns() {
|
|
3842
|
-
var _a;
|
|
3843
|
-
const parent = this._parentVariable;
|
|
3844
|
-
const ds = await getDataSource(parent.state.datasource, this._scopedVars);
|
|
3845
|
-
if (!ds || !ds.getRecommendedDrilldowns) {
|
|
3846
|
-
return;
|
|
3847
|
-
}
|
|
3848
|
-
const queries = parent.state.useQueriesAsFilterForOptions ? getQueriesForVariables(parent) : void 0;
|
|
3849
|
-
const timeRange = sceneGraph.getTimeRange(this).state.value;
|
|
3850
|
-
const scopes = sceneGraph.getScopes(this);
|
|
3851
|
-
const filters = [...(_a = parent.state.originFilters) != null ? _a : [], ...parent.state.filters];
|
|
3852
|
-
const enrichedRequest = getEnrichedDataRequest(this);
|
|
3853
|
-
const dashboardUid = enrichedRequest == null ? void 0 : enrichedRequest.dashboardUID;
|
|
3854
|
-
try {
|
|
3855
|
-
const recommendedDrilldowns = await ds.getRecommendedDrilldowns({
|
|
3856
|
-
timeRange,
|
|
3857
|
-
dashboardUid,
|
|
3858
|
-
queries: queries != null ? queries : [],
|
|
3859
|
-
filters,
|
|
3860
|
-
scopes,
|
|
3861
|
-
userId: runtime.config.bootData.user.id
|
|
3862
|
-
});
|
|
3863
|
-
if (recommendedDrilldowns == null ? void 0 : recommendedDrilldowns.filters) {
|
|
3864
|
-
this.setState({ recommendedFilters: recommendedDrilldowns.filters });
|
|
3865
|
-
}
|
|
3866
|
-
} catch (error) {
|
|
3867
|
-
console.error("Failed to fetch recommended drilldowns:", error);
|
|
3868
|
-
}
|
|
3869
|
-
}
|
|
3870
|
-
async _verifyRecentFiltersApplicability(storedFilters) {
|
|
3871
|
-
const parent = this._parentVariable;
|
|
3872
|
-
const queries = parent.state.useQueriesAsFilterForOptions ? getQueriesForVariables(parent) : void 0;
|
|
3873
|
-
const response = await this._getFiltersApplicabilityForQueries(storedFilters, queries != null ? queries : []);
|
|
3874
|
-
if (!response) {
|
|
3875
|
-
this.setState({ recentFilters: storedFilters.slice(-3) });
|
|
3876
|
-
return;
|
|
3877
|
-
}
|
|
3878
|
-
const applicabilityMap = /* @__PURE__ */ new Map();
|
|
3879
|
-
response.forEach((item) => {
|
|
3880
|
-
applicabilityMap.set(item.key, item.applicable !== false);
|
|
3881
|
-
});
|
|
3882
|
-
const applicableFilters = storedFilters.filter((f) => {
|
|
3883
|
-
const isApplicable = applicabilityMap.get(f.key);
|
|
3884
|
-
return isApplicable === void 0 || isApplicable === true;
|
|
3885
|
-
}).slice(-3);
|
|
3886
|
-
this.setState({ recentFilters: applicableFilters });
|
|
3887
|
-
}
|
|
3888
|
-
async _getFiltersApplicabilityForQueries(filters, queries) {
|
|
3889
|
-
const parent = this._parentVariable;
|
|
3890
|
-
const ds = await getDataSource(parent.state.datasource, this._scopedVars);
|
|
3891
|
-
if (!ds || !ds.getDrilldownsApplicability) {
|
|
3892
|
-
return;
|
|
3893
|
-
}
|
|
3894
|
-
const timeRange = sceneGraph.getTimeRange(this).state.value;
|
|
3895
|
-
return await ds.getDrilldownsApplicability({
|
|
3896
|
-
filters,
|
|
3897
|
-
queries,
|
|
3898
|
-
timeRange,
|
|
3899
|
-
scopes: sceneGraph.getScopes(this),
|
|
3900
|
-
...getEnrichedFiltersRequest(this)
|
|
3901
|
-
});
|
|
3902
|
-
}
|
|
3903
|
-
/**
|
|
3904
|
-
* Stores a recent filter in localStorage and updates state.
|
|
3905
|
-
* Should be called by the parent variable when a filter is added/updated.
|
|
3906
|
-
*/
|
|
3907
|
-
storeRecentFilter(filter) {
|
|
3908
|
-
const key = this._getStorageKey();
|
|
3909
|
-
const storedFilters = data.store.get(key);
|
|
3910
|
-
const allRecentFilters = storedFilters ? JSON.parse(storedFilters) : [];
|
|
3911
|
-
const updatedStoredFilters = [...allRecentFilters, filter].slice(-10);
|
|
3912
|
-
data.store.set(key, JSON.stringify(updatedStoredFilters));
|
|
3913
|
-
const parent = this._parentVariable;
|
|
3914
|
-
const existingFilter = parent.state.filters.find((f) => f.key === filter.key && !Boolean(f.nonApplicable));
|
|
3915
|
-
if (existingFilter && !Boolean(existingFilter.nonApplicable)) {
|
|
3916
|
-
this.setState({ recentFilters: updatedStoredFilters.slice(-3) });
|
|
3917
|
-
}
|
|
3918
|
-
}
|
|
3919
|
-
/**
|
|
3920
|
-
* Get the current filters from the parent variable
|
|
3921
|
-
*/
|
|
3922
|
-
getParentFilters() {
|
|
3923
|
-
return this._parentVariable.state.filters;
|
|
3924
|
-
}
|
|
3925
|
-
/**
|
|
3926
|
-
* Add a filter to the parent variable
|
|
3927
|
-
*/
|
|
3928
|
-
addFilterToParent(filter) {
|
|
3929
|
-
const parent = this._parentVariable;
|
|
3930
|
-
parent.updateFilters([...parent.state.filters, filter]);
|
|
3931
|
-
}
|
|
3932
|
-
}
|
|
3933
|
-
AdHocFiltersRecommendations.Component = AdHocFiltersRecommendationsRenderer;
|
|
3934
|
-
function AdHocFiltersRecommendationsRenderer({ model }) {
|
|
3935
|
-
const { recentFilters, recommendedFilters } = model.useState();
|
|
3936
|
-
const { filters } = model.parent.useState();
|
|
3937
|
-
const recentDrilldowns = recentFilters == null ? void 0 : recentFilters.map((filter) => ({
|
|
3938
|
-
label: `${filter.key} ${filter.operator} ${filter.value}`,
|
|
3939
|
-
onClick: () => {
|
|
3940
|
-
model.addFilterToParent(filter);
|
|
3941
|
-
}
|
|
3942
|
-
}));
|
|
3943
|
-
const recommendedDrilldowns = recommendedFilters == null ? void 0 : recommendedFilters.map((filter) => ({
|
|
3944
|
-
label: `${filter.key} ${filter.operator} ${filter.value}`,
|
|
3945
|
-
onClick: () => {
|
|
3946
|
-
const exists = filters.some((f) => f.key === filter.key && f.value === filter.value);
|
|
3947
|
-
if (!exists) {
|
|
3948
|
-
model.addFilterToParent(filter);
|
|
3949
|
-
}
|
|
3950
|
-
}
|
|
3951
|
-
}));
|
|
3952
|
-
return /* @__PURE__ */ React__default.default.createElement(DrilldownRecommendations, { recentDrilldowns, recommendedDrilldowns });
|
|
3953
|
-
}
|
|
3954
|
-
|
|
3955
|
-
const getRecentGroupingKey = (datasourceUid) => `grafana.grouping.recent.${datasourceUid != null ? datasourceUid : "default"}`;
|
|
3956
|
-
class GroupByRecommendations extends SceneObjectBase {
|
|
3957
|
-
constructor(parent) {
|
|
3958
|
-
super({});
|
|
3959
|
-
this._scopedVars = { __sceneObject: wrapInSafeSerializableSceneObject(this) };
|
|
3960
|
-
this._activationHandler = () => {
|
|
3961
|
-
const json = data.store.get(this._getStorageKey());
|
|
3962
|
-
const storedGroupings = json ? JSON.parse(json) : [];
|
|
3963
|
-
if (storedGroupings.length > 0) {
|
|
3964
|
-
this._verifyRecentGroupingsApplicability(storedGroupings);
|
|
3965
|
-
} else {
|
|
3966
|
-
this.setState({ recentGrouping: [] });
|
|
3967
|
-
}
|
|
3968
|
-
this._fetchRecommendedDrilldowns();
|
|
3969
|
-
const scopesVariable = sceneGraph.lookupVariable(SCOPES_VARIABLE_NAME, this);
|
|
3970
|
-
let scopesSubscription;
|
|
3971
|
-
if (scopesVariable instanceof ScopesVariable) {
|
|
3972
|
-
scopesSubscription = scopesVariable.subscribeToState((newState, prevState) => {
|
|
3973
|
-
if (newState.scopes !== prevState.scopes) {
|
|
3974
|
-
const json2 = data.store.get(this._getStorageKey());
|
|
3975
|
-
const storedGroupings2 = json2 ? JSON.parse(json2) : [];
|
|
3976
|
-
if (storedGroupings2.length > 0) {
|
|
3977
|
-
this._verifyRecentGroupingsApplicability(storedGroupings2);
|
|
3978
|
-
}
|
|
3979
|
-
}
|
|
3980
|
-
});
|
|
3981
|
-
}
|
|
3982
|
-
return () => {
|
|
3983
|
-
scopesSubscription == null ? void 0 : scopesSubscription.unsubscribe();
|
|
3984
|
-
};
|
|
3985
|
-
};
|
|
3986
|
-
this._parentVariable = parent;
|
|
3987
|
-
this.addActivationHandler(this._activationHandler);
|
|
3988
|
-
}
|
|
3989
|
-
/**
|
|
3990
|
-
* Get the parent variable
|
|
3991
|
-
*/
|
|
3992
|
-
get parent() {
|
|
3993
|
-
return this._parentVariable;
|
|
3994
|
-
}
|
|
3995
|
-
_getStorageKey() {
|
|
3996
|
-
var _a;
|
|
3997
|
-
return getRecentGroupingKey((_a = this._parentVariable.state.datasource) == null ? void 0 : _a.uid);
|
|
3998
|
-
}
|
|
3999
|
-
async _fetchRecommendedDrilldowns() {
|
|
4000
|
-
const parent = this._parentVariable;
|
|
4001
|
-
const ds = await getDataSource(parent.state.datasource, this._scopedVars);
|
|
4002
|
-
if (!ds || !ds.getRecommendedDrilldowns) {
|
|
4003
|
-
return;
|
|
4004
|
-
}
|
|
4005
|
-
const queries = getQueriesForVariables(parent);
|
|
4006
|
-
const timeRange = sceneGraph.getTimeRange(this).state.value;
|
|
4007
|
-
const scopes = sceneGraph.getScopes(this);
|
|
4008
|
-
const groupByKeys = Array.isArray(parent.state.value) ? parent.state.value.map((v) => String(v)) : parent.state.value ? [String(parent.state.value)] : [];
|
|
4009
|
-
const enrichedRequest = getEnrichedDataRequest(this);
|
|
4010
|
-
const dashboardUid = enrichedRequest == null ? void 0 : enrichedRequest.dashboardUID;
|
|
4011
|
-
try {
|
|
4012
|
-
const recommendedDrilldowns = await ds.getRecommendedDrilldowns({
|
|
4013
|
-
timeRange,
|
|
4014
|
-
dashboardUid,
|
|
4015
|
-
queries,
|
|
4016
|
-
groupByKeys,
|
|
4017
|
-
scopes,
|
|
4018
|
-
userId: runtime.config.bootData.user.id
|
|
4019
|
-
});
|
|
4020
|
-
if (recommendedDrilldowns == null ? void 0 : recommendedDrilldowns.groupByKeys) {
|
|
4021
|
-
this.setState({
|
|
4022
|
-
recommendedGrouping: recommendedDrilldowns.groupByKeys.map((key) => ({ value: key, text: key }))
|
|
4023
|
-
});
|
|
4024
|
-
}
|
|
4025
|
-
} catch (error) {
|
|
4026
|
-
console.error("Failed to fetch recommended drilldowns:", error);
|
|
4027
|
-
}
|
|
4028
|
-
}
|
|
4029
|
-
async _verifyRecentGroupingsApplicability(storedGroupings) {
|
|
4030
|
-
const queries = getQueriesForVariables(this._parentVariable);
|
|
4031
|
-
const keys = storedGroupings.map((g) => String(g.value));
|
|
4032
|
-
const response = await this._getGroupByApplicabilityForQueries(keys, queries);
|
|
4033
|
-
if (!response) {
|
|
4034
|
-
this.setState({ recentGrouping: storedGroupings.slice(-3) });
|
|
4035
|
-
return;
|
|
4036
|
-
}
|
|
4037
|
-
const applicabilityMap = /* @__PURE__ */ new Map();
|
|
4038
|
-
response.forEach((item) => {
|
|
4039
|
-
applicabilityMap.set(item.key, item.applicable !== false);
|
|
4040
|
-
});
|
|
4041
|
-
const applicableGroupings = storedGroupings.filter((g) => {
|
|
4042
|
-
const isApplicable = applicabilityMap.get(String(g.value));
|
|
4043
|
-
return isApplicable === void 0 || isApplicable === true;
|
|
4044
|
-
}).slice(-3);
|
|
4045
|
-
this.setState({ recentGrouping: applicableGroupings });
|
|
4046
|
-
}
|
|
4047
|
-
async _getGroupByApplicabilityForQueries(value, queries) {
|
|
4048
|
-
const parent = this._parentVariable;
|
|
4049
|
-
const ds = await getDataSource(parent.state.datasource, this._scopedVars);
|
|
4050
|
-
if (!ds || !ds.getDrilldownsApplicability) {
|
|
4051
|
-
return;
|
|
4052
|
-
}
|
|
4053
|
-
const timeRange = sceneGraph.getTimeRange(this).state.value;
|
|
4054
|
-
return await ds.getDrilldownsApplicability({
|
|
4055
|
-
groupByKeys: Array.isArray(value) ? value.map((v) => String(v)) : value ? [String(value)] : [],
|
|
4056
|
-
queries,
|
|
4057
|
-
timeRange,
|
|
4058
|
-
scopes: sceneGraph.getScopes(this),
|
|
4059
|
-
...getEnrichedFiltersRequest(this)
|
|
4060
|
-
});
|
|
4061
|
-
}
|
|
4062
|
-
/**
|
|
4063
|
-
* Stores recent groupings in localStorage and updates state.
|
|
4064
|
-
* Should be called by the parent variable when a grouping is added/updated.
|
|
4065
|
-
*/
|
|
4066
|
-
storeRecentGrouping(applicableValues) {
|
|
4067
|
-
if (applicableValues.length === 0) {
|
|
4068
|
-
return;
|
|
4069
|
-
}
|
|
4070
|
-
const key = this._getStorageKey();
|
|
4071
|
-
const storedGroupings = data.store.get(key);
|
|
4072
|
-
const allRecentGroupings = storedGroupings ? JSON.parse(storedGroupings) : [];
|
|
4073
|
-
const existingWithoutApplicableValues = allRecentGroupings.filter(
|
|
4074
|
-
(grouping) => !applicableValues.includes(String(grouping.value))
|
|
4075
|
-
);
|
|
4076
|
-
const updatedStoredGroupings = [
|
|
4077
|
-
...existingWithoutApplicableValues,
|
|
4078
|
-
...applicableValues.map((value) => ({ value, text: value }))
|
|
4079
|
-
];
|
|
4080
|
-
const limitedStoredGroupings = updatedStoredGroupings.slice(-10);
|
|
4081
|
-
data.store.set(key, JSON.stringify(limitedStoredGroupings));
|
|
4082
|
-
this.setState({ recentGrouping: limitedStoredGroupings.slice(-3) });
|
|
4083
|
-
}
|
|
4084
|
-
/**
|
|
4085
|
-
* Get the current values from the parent variable
|
|
4086
|
-
*/
|
|
4087
|
-
getParentValues() {
|
|
4088
|
-
const parent = this._parentVariable;
|
|
4089
|
-
const value = lodash.isArray(parent.state.value) ? parent.state.value : [parent.state.value];
|
|
4090
|
-
const text = lodash.isArray(parent.state.text) ? parent.state.text.map(String) : [String(parent.state.text)];
|
|
4091
|
-
return { value, text };
|
|
4092
|
-
}
|
|
4093
|
-
/**
|
|
4094
|
-
* Add a grouping value to the parent variable
|
|
4095
|
-
*/
|
|
4096
|
-
addValueToParent(newValue, newText) {
|
|
4097
|
-
const parent = this._parentVariable;
|
|
4098
|
-
const { value, text } = this.getParentValues();
|
|
4099
|
-
if (value.includes(newValue)) {
|
|
4100
|
-
return;
|
|
4101
|
-
}
|
|
4102
|
-
parent.changeValueTo(
|
|
4103
|
-
[...value.filter((v) => v !== ""), newValue],
|
|
4104
|
-
[...text.filter((t) => t !== ""), newText != null ? newText : String(newValue)],
|
|
4105
|
-
true
|
|
4106
|
-
);
|
|
4107
|
-
}
|
|
4108
|
-
}
|
|
4109
|
-
GroupByRecommendations.Component = GroupByRecommendationsRenderer;
|
|
4110
|
-
function GroupByRecommendationsRenderer({ model }) {
|
|
4111
|
-
const { recentGrouping, recommendedGrouping } = model.useState();
|
|
4112
|
-
const recentDrilldowns = recentGrouping == null ? void 0 : recentGrouping.map((groupBy) => ({
|
|
4113
|
-
label: `${groupBy.value}`,
|
|
4114
|
-
onClick: () => {
|
|
4115
|
-
var _a;
|
|
4116
|
-
model.addValueToParent(groupBy.value, (_a = groupBy.text) != null ? _a : String(groupBy.value));
|
|
4117
|
-
}
|
|
4118
|
-
}));
|
|
4119
|
-
const recommendedDrilldowns = recommendedGrouping == null ? void 0 : recommendedGrouping.map((groupBy) => ({
|
|
4120
|
-
label: `${groupBy.value}`,
|
|
4121
|
-
onClick: () => {
|
|
4122
|
-
var _a;
|
|
4123
|
-
model.addValueToParent(groupBy.value, (_a = groupBy.text) != null ? _a : String(groupBy.value));
|
|
4124
|
-
}
|
|
4125
|
-
}));
|
|
4126
|
-
return /* @__PURE__ */ React__default.default.createElement(DrilldownRecommendations, { recentDrilldowns, recommendedDrilldowns });
|
|
4127
|
-
}
|
|
4128
|
-
|
|
4129
3617
|
class GroupByVariable extends MultiValueVariable {
|
|
4130
3618
|
constructor(initialState) {
|
|
4131
3619
|
super({
|
|
@@ -4151,11 +3639,6 @@ class GroupByVariable extends MultiValueVariable {
|
|
|
4151
3639
|
this.setState({ restorable: true });
|
|
4152
3640
|
}
|
|
4153
3641
|
}
|
|
4154
|
-
if (this.state.drilldownRecommendationsEnabled && !this.state._valueRecommendations) {
|
|
4155
|
-
const valueRecommendations = new GroupByRecommendations(this);
|
|
4156
|
-
this.setState({ _valueRecommendations: valueRecommendations });
|
|
4157
|
-
valueRecommendations.activate();
|
|
4158
|
-
}
|
|
4159
3642
|
return () => {
|
|
4160
3643
|
if (this.state.defaultValue) {
|
|
4161
3644
|
this.restoreDefaultValues();
|
|
@@ -4271,7 +3754,7 @@ class GroupByVariable extends MultiValueVariable {
|
|
|
4271
3754
|
}
|
|
4272
3755
|
getApplicableKeys() {
|
|
4273
3756
|
const { value, keysApplicability } = this.state;
|
|
4274
|
-
const valueArray = lodash.isArray(value) ? value
|
|
3757
|
+
const valueArray = lodash.isArray(value) ? value : value ? [value] : [];
|
|
4275
3758
|
if (!keysApplicability || keysApplicability.length === 0) {
|
|
4276
3759
|
return valueArray;
|
|
4277
3760
|
}
|
|
@@ -4330,17 +3813,6 @@ class GroupByVariable extends MultiValueVariable {
|
|
|
4330
3813
|
}
|
|
4331
3814
|
this.changeValueTo(this.state.defaultValue.value, this.state.defaultValue.text, true);
|
|
4332
3815
|
}
|
|
4333
|
-
async _verifyApplicabilityAndStoreRecentGrouping() {
|
|
4334
|
-
await this._verifyApplicability();
|
|
4335
|
-
if (!this.state.drilldownRecommendationsEnabled || !this.state._valueRecommendations) {
|
|
4336
|
-
return;
|
|
4337
|
-
}
|
|
4338
|
-
const applicableValues = this.getApplicableKeys();
|
|
4339
|
-
if (applicableValues.length === 0) {
|
|
4340
|
-
return;
|
|
4341
|
-
}
|
|
4342
|
-
this.state._valueRecommendations.storeRecentGrouping(applicableValues);
|
|
4343
|
-
}
|
|
4344
3816
|
/**
|
|
4345
3817
|
* Allows clearing the value of the variable to an empty value. Overrides default behavior of a MultiValueVariable
|
|
4346
3818
|
*/
|
|
@@ -4361,11 +3833,8 @@ function GroupByVariableRenderer({ model }) {
|
|
|
4361
3833
|
includeAll,
|
|
4362
3834
|
allowCustomValue = true,
|
|
4363
3835
|
defaultValue,
|
|
4364
|
-
keysApplicability
|
|
4365
|
-
_valueRecommendations,
|
|
4366
|
-
drilldownRecommendationsEnabled
|
|
3836
|
+
keysApplicability
|
|
4367
3837
|
} = model.useState();
|
|
4368
|
-
const styles = ui.useStyles2(getStyles$j);
|
|
4369
3838
|
const values = React.useMemo(() => {
|
|
4370
3839
|
const arrayValue = lodash.isArray(value) ? value : [value];
|
|
4371
3840
|
const arrayText = lodash.isArray(text) ? text : [text];
|
|
@@ -4404,7 +3873,7 @@ function GroupByVariableRenderer({ model }) {
|
|
|
4404
3873
|
() => handleOptionGroups(optionSearcher(inputValue).map(toSelectableValue$1)),
|
|
4405
3874
|
[optionSearcher, inputValue]
|
|
4406
3875
|
);
|
|
4407
|
-
|
|
3876
|
+
return isMulti ? /* @__PURE__ */ React__default.default.createElement(
|
|
4408
3877
|
ui.MultiSelect,
|
|
4409
3878
|
{
|
|
4410
3879
|
"aria-label": i18n.t(
|
|
@@ -4418,7 +3887,6 @@ function GroupByVariableRenderer({ model }) {
|
|
|
4418
3887
|
"Group by label"
|
|
4419
3888
|
),
|
|
4420
3889
|
width: "auto",
|
|
4421
|
-
className: css.cx(drilldownRecommendationsEnabled && styles.selectStylesInWrapper),
|
|
4422
3890
|
allowCustomValue,
|
|
4423
3891
|
inputValue,
|
|
4424
3892
|
value: uncommittedValue,
|
|
@@ -4452,7 +3920,7 @@ function GroupByVariableRenderer({ model }) {
|
|
|
4452
3920
|
if (restorable !== model.state.restorable) {
|
|
4453
3921
|
model.setState({ restorable });
|
|
4454
3922
|
}
|
|
4455
|
-
model.
|
|
3923
|
+
model._verifyApplicability();
|
|
4456
3924
|
},
|
|
4457
3925
|
onChange: (newValue, action) => {
|
|
4458
3926
|
if (action.action === "clear" && noValueOnClear) {
|
|
@@ -4488,7 +3956,6 @@ function GroupByVariableRenderer({ model }) {
|
|
|
4488
3956
|
"Group by label"
|
|
4489
3957
|
),
|
|
4490
3958
|
width: "auto",
|
|
4491
|
-
className: css.cx(drilldownRecommendationsEnabled && styles.selectStylesInWrapper),
|
|
4492
3959
|
inputValue,
|
|
4493
3960
|
value: uncommittedValue && uncommittedValue.length > 0 ? uncommittedValue : null,
|
|
4494
3961
|
allowCustomValue,
|
|
@@ -4533,10 +4000,6 @@ function GroupByVariableRenderer({ model }) {
|
|
|
4533
4000
|
}
|
|
4534
4001
|
}
|
|
4535
4002
|
);
|
|
4536
|
-
if (!drilldownRecommendationsEnabled || !_valueRecommendations) {
|
|
4537
|
-
return select;
|
|
4538
|
-
}
|
|
4539
|
-
return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.wrapper }, /* @__PURE__ */ React__default.default.createElement("div", { className: styles.recommendations }, /* @__PURE__ */ React__default.default.createElement(_valueRecommendations.Component, { model: _valueRecommendations })), select);
|
|
4540
4003
|
}
|
|
4541
4004
|
const filterNoOp$1 = () => true;
|
|
4542
4005
|
function WideMenu(props) {
|
|
@@ -4553,31 +4016,6 @@ function toSelectableValue$1(input) {
|
|
|
4553
4016
|
}
|
|
4554
4017
|
return result;
|
|
4555
4018
|
}
|
|
4556
|
-
const getStyles$j = (theme) => ({
|
|
4557
|
-
wrapper: css.css({
|
|
4558
|
-
display: "flex"
|
|
4559
|
-
}),
|
|
4560
|
-
selectStylesInWrapper: css.css({
|
|
4561
|
-
borderTopLeftRadius: 0,
|
|
4562
|
-
borderBottomLeftRadius: 0,
|
|
4563
|
-
border: `1px solid ${theme.colors.border.strong}`,
|
|
4564
|
-
borderLeft: "none"
|
|
4565
|
-
}),
|
|
4566
|
-
recommendations: css.css({
|
|
4567
|
-
display: "flex",
|
|
4568
|
-
alignItems: "center",
|
|
4569
|
-
paddingInline: theme.spacing(0.5),
|
|
4570
|
-
borderTop: `1px solid ${theme.colors.border.strong}`,
|
|
4571
|
-
borderBottom: `1px solid ${theme.colors.border.strong}`,
|
|
4572
|
-
backgroundColor: theme.components.input.background,
|
|
4573
|
-
"& button": {
|
|
4574
|
-
borderRadius: 0,
|
|
4575
|
-
height: "100%",
|
|
4576
|
-
margin: 0,
|
|
4577
|
-
paddingInline: theme.spacing(0.5)
|
|
4578
|
-
}
|
|
4579
|
-
})
|
|
4580
|
-
});
|
|
4581
4019
|
|
|
4582
4020
|
function VizPanelSeriesLimit({ data, showAll, seriesLimit, onShowAllSeries }) {
|
|
4583
4021
|
const styles = ui.useStyles2(getStyles$i);
|
|
@@ -7223,6 +6661,9 @@ const generatePlaceholder = (filter, filterInputType, isMultiValueEdit, isAlways
|
|
|
7223
6661
|
}
|
|
7224
6662
|
return ((_a = filter.valueLabels) == null ? void 0 : _a[0]) || "";
|
|
7225
6663
|
}
|
|
6664
|
+
if (isAlwaysWip && filterInputType === "operator") {
|
|
6665
|
+
return "";
|
|
6666
|
+
}
|
|
7226
6667
|
return filter[filterInputType] && !isAlwaysWip ? `${filter[filterInputType]}` : inputPlaceholder || INPUT_PLACEHOLDER_DEFAULT;
|
|
7227
6668
|
};
|
|
7228
6669
|
const populateInputValueOnInputTypeSwitch = ({
|
|
@@ -7411,7 +6852,8 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({
|
|
|
7411
6852
|
isAlwaysWip,
|
|
7412
6853
|
handleChangeViewMode,
|
|
7413
6854
|
focusOnWipInputRef,
|
|
7414
|
-
populateInputOnEdit
|
|
6855
|
+
populateInputOnEdit,
|
|
6856
|
+
onInputClick
|
|
7415
6857
|
}, parentRef) {
|
|
7416
6858
|
var _a, _b, _c;
|
|
7417
6859
|
const [open, setOpen] = React.useState(false);
|
|
@@ -7894,6 +7336,7 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({
|
|
|
7894
7336
|
className: css.cx(styles.inputStyle, { [styles.loadingInputPadding]: !optionsLoading }),
|
|
7895
7337
|
onClick: (event) => {
|
|
7896
7338
|
event.stopPropagation();
|
|
7339
|
+
onInputClick == null ? void 0 : onInputClick();
|
|
7897
7340
|
setOpen(true);
|
|
7898
7341
|
},
|
|
7899
7342
|
onFocus: () => {
|
|
@@ -8352,53 +7795,102 @@ const getStyles$a = (theme) => ({
|
|
|
8352
7795
|
...getNonApplicablePillStyles(theme)
|
|
8353
7796
|
});
|
|
8354
7797
|
|
|
8355
|
-
const AdHocFiltersAlwaysWipCombobox = React.forwardRef(function AdHocFiltersAlwaysWipCombobox2({ controller }, parentRef) {
|
|
7798
|
+
const AdHocFiltersAlwaysWipCombobox = React.forwardRef(function AdHocFiltersAlwaysWipCombobox2({ controller, onInputClick }, parentRef) {
|
|
8356
7799
|
const { wip } = controller.useState();
|
|
8357
7800
|
React.useLayoutEffect(() => {
|
|
8358
7801
|
if (!wip) {
|
|
8359
7802
|
controller.addWip();
|
|
8360
7803
|
}
|
|
8361
7804
|
}, [wip]);
|
|
8362
|
-
return /* @__PURE__ */ React__default.default.createElement(AdHocCombobox, { controller, filter: wip, isAlwaysWip: true, ref: parentRef });
|
|
7805
|
+
return /* @__PURE__ */ React__default.default.createElement(AdHocCombobox, { controller, filter: wip, isAlwaysWip: true, ref: parentRef, onInputClick });
|
|
8363
7806
|
});
|
|
8364
7807
|
|
|
7808
|
+
const MAX_VISIBLE_FILTERS = 4;
|
|
8365
7809
|
const AdHocFiltersComboboxRenderer = React.memo(function AdHocFiltersComboboxRenderer2({ controller }) {
|
|
8366
|
-
|
|
7810
|
+
var _a;
|
|
7811
|
+
const { originFilters, filters, readOnly, collapsible } = controller.useState();
|
|
8367
7812
|
const styles = ui.useStyles2(getStyles$9);
|
|
7813
|
+
const theme = ui.useTheme2();
|
|
7814
|
+
const [collapsed, setCollapsed] = React.useState(true);
|
|
7815
|
+
const [wrapperRef, { height: wrapperHeight }] = reactUse.useMeasure();
|
|
7816
|
+
const clearAll = () => {
|
|
7817
|
+
controller.clearAll();
|
|
7818
|
+
};
|
|
8368
7819
|
const focusOnWipInputRef = React.useRef();
|
|
7820
|
+
const singleLineThreshold = theme.spacing.gridSize * 5;
|
|
7821
|
+
const isMultiLine = collapsible && wrapperHeight > singleLineThreshold;
|
|
7822
|
+
const handleCollapseToggle = (event) => {
|
|
7823
|
+
event.stopPropagation();
|
|
7824
|
+
if (collapsible) {
|
|
7825
|
+
setCollapsed(true);
|
|
7826
|
+
}
|
|
7827
|
+
};
|
|
7828
|
+
const handleExpand = () => {
|
|
7829
|
+
var _a2, _b;
|
|
7830
|
+
if (!collapsible) {
|
|
7831
|
+
(_a2 = focusOnWipInputRef.current) == null ? void 0 : _a2.call(focusOnWipInputRef);
|
|
7832
|
+
return;
|
|
7833
|
+
}
|
|
7834
|
+
if (collapsed) {
|
|
7835
|
+
setCollapsed(false);
|
|
7836
|
+
} else {
|
|
7837
|
+
(_b = focusOnWipInputRef.current) == null ? void 0 : _b.call(focusOnWipInputRef);
|
|
7838
|
+
}
|
|
7839
|
+
};
|
|
7840
|
+
const visibleOriginFilters = (_a = originFilters == null ? void 0 : originFilters.filter((f) => f.origin)) != null ? _a : [];
|
|
7841
|
+
const visibleFilters = filters.filter((f) => !f.hidden);
|
|
7842
|
+
const allFilters = [...visibleOriginFilters, ...visibleFilters];
|
|
7843
|
+
const totalFiltersCount = allFilters.length;
|
|
7844
|
+
const shouldCollapse = collapsible && collapsed && totalFiltersCount > 0;
|
|
7845
|
+
const filtersToRender = shouldCollapse ? allFilters.slice(0, MAX_VISIBLE_FILTERS) : allFilters;
|
|
7846
|
+
React.useEffect(() => {
|
|
7847
|
+
if (collapsible && totalFiltersCount === 0 && collapsed) {
|
|
7848
|
+
setCollapsed(false);
|
|
7849
|
+
}
|
|
7850
|
+
}, [collapsible, totalFiltersCount, collapsed]);
|
|
7851
|
+
const showCollapseButton = collapsible && isMultiLine && !collapsed;
|
|
8369
7852
|
return /* @__PURE__ */ React__default.default.createElement(
|
|
8370
7853
|
"div",
|
|
8371
7854
|
{
|
|
8372
|
-
|
|
8373
|
-
|
|
8374
|
-
|
|
8375
|
-
|
|
8376
|
-
|
|
7855
|
+
ref: wrapperRef,
|
|
7856
|
+
className: css.cx(styles.comboboxWrapper, {
|
|
7857
|
+
[styles.comboboxFocusOutline]: !readOnly,
|
|
7858
|
+
[styles.collapsed]: shouldCollapse,
|
|
7859
|
+
[styles.clickableCollapsed]: shouldCollapse
|
|
7860
|
+
}),
|
|
7861
|
+
onClick: handleExpand
|
|
8377
7862
|
},
|
|
8378
7863
|
/* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "filter", className: styles.filterIcon, size: "lg" }),
|
|
8379
|
-
|
|
8380
|
-
originFilters == null ? void 0 : originFilters.map(
|
|
8381
|
-
(filter, index) => filter.origin ? /* @__PURE__ */ React__default.default.createElement(
|
|
8382
|
-
AdHocFilterPill,
|
|
8383
|
-
{
|
|
8384
|
-
key: `${index}-${filter.key}`,
|
|
8385
|
-
filter,
|
|
8386
|
-
controller,
|
|
8387
|
-
focusOnWipInputRef: focusOnWipInputRef.current
|
|
8388
|
-
}
|
|
8389
|
-
) : null
|
|
8390
|
-
),
|
|
8391
|
-
filters.filter((filter) => !filter.hidden).map((filter, index) => /* @__PURE__ */ React__default.default.createElement(
|
|
7864
|
+
filtersToRender.map((filter, index) => /* @__PURE__ */ React__default.default.createElement(
|
|
8392
7865
|
AdHocFilterPill,
|
|
8393
7866
|
{
|
|
8394
|
-
key: `${index}-${filter.key}`,
|
|
7867
|
+
key: `${filter.origin ? "origin-" : ""}${index}-${filter.key}`,
|
|
8395
7868
|
filter,
|
|
8396
7869
|
controller,
|
|
8397
7870
|
readOnly: readOnly || filter.readOnly,
|
|
8398
7871
|
focusOnWipInputRef: focusOnWipInputRef.current
|
|
8399
7872
|
}
|
|
8400
7873
|
)),
|
|
8401
|
-
|
|
7874
|
+
shouldCollapse && totalFiltersCount > MAX_VISIBLE_FILTERS && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.moreIndicator }, i18n.t("grafana-scenes.variables.adhoc-filters-combobox-renderer.more-filters", "+{{count}} more", {
|
|
7875
|
+
count: totalFiltersCount - MAX_VISIBLE_FILTERS
|
|
7876
|
+
})),
|
|
7877
|
+
!readOnly && !shouldCollapse ? /* @__PURE__ */ React__default.default.createElement(AdHocFiltersAlwaysWipCombobox, { controller, ref: focusOnWipInputRef }) : null,
|
|
7878
|
+
showCollapseButton && /* @__PURE__ */ React__default.default.createElement(
|
|
7879
|
+
ui.Button,
|
|
7880
|
+
{
|
|
7881
|
+
className: styles.collapseButton,
|
|
7882
|
+
fill: "text",
|
|
7883
|
+
onClick: handleCollapseToggle,
|
|
7884
|
+
"aria-label": i18n.t(
|
|
7885
|
+
"grafana-scenes.variables.adhoc-filters-combobox-renderer.collapse-filters",
|
|
7886
|
+
"Collapse filters"
|
|
7887
|
+
),
|
|
7888
|
+
"aria-expanded": !collapsed
|
|
7889
|
+
},
|
|
7890
|
+
i18n.t("grafana-scenes.variables.adhoc-filters-combobox-renderer.collapse", "Collapse"),
|
|
7891
|
+
/* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "angle-up", size: "md" })
|
|
7892
|
+
),
|
|
7893
|
+
/* @__PURE__ */ React__default.default.createElement("div", { className: styles.clearAllButton }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "times", size: "md", onClick: clearAll }))
|
|
8402
7894
|
);
|
|
8403
7895
|
});
|
|
8404
7896
|
const getStyles$9 = (theme) => ({
|
|
@@ -8430,6 +7922,42 @@ const getStyles$9 = (theme) => ({
|
|
|
8430
7922
|
filterIcon: css.css({
|
|
8431
7923
|
color: theme.colors.text.secondary,
|
|
8432
7924
|
alignSelf: "center"
|
|
7925
|
+
}),
|
|
7926
|
+
collapsed: css.css({
|
|
7927
|
+
flexWrap: "nowrap",
|
|
7928
|
+
overflow: "hidden"
|
|
7929
|
+
}),
|
|
7930
|
+
clickableCollapsed: css.css({
|
|
7931
|
+
cursor: "pointer",
|
|
7932
|
+
"&:hover": {
|
|
7933
|
+
borderColor: theme.colors.border.medium
|
|
7934
|
+
}
|
|
7935
|
+
}),
|
|
7936
|
+
moreIndicator: css.css({
|
|
7937
|
+
color: theme.colors.text.secondary,
|
|
7938
|
+
whiteSpace: "nowrap",
|
|
7939
|
+
...theme.typography.bodySmall,
|
|
7940
|
+
fontStyle: "italic",
|
|
7941
|
+
marginLeft: theme.spacing(0.5)
|
|
7942
|
+
}),
|
|
7943
|
+
collapseButton: css.css({
|
|
7944
|
+
marginLeft: "auto",
|
|
7945
|
+
color: theme.colors.text.secondary,
|
|
7946
|
+
padding: 0,
|
|
7947
|
+
fontSize: theme.typography.bodySmall.fontSize,
|
|
7948
|
+
border: "none",
|
|
7949
|
+
"&:hover": {
|
|
7950
|
+
background: "transparent",
|
|
7951
|
+
color: theme.colors.text.primary
|
|
7952
|
+
}
|
|
7953
|
+
}),
|
|
7954
|
+
clearAllButton: css.css({
|
|
7955
|
+
fontSize: theme.typography.bodySmall.fontSize,
|
|
7956
|
+
cursor: "pointer",
|
|
7957
|
+
color: theme.colors.text.secondary,
|
|
7958
|
+
"&:hover": {
|
|
7959
|
+
color: theme.colors.text.primary
|
|
7960
|
+
}
|
|
8433
7961
|
})
|
|
8434
7962
|
});
|
|
8435
7963
|
|
|
@@ -8534,8 +8062,7 @@ class AdHocFiltersVariableController {
|
|
|
8534
8062
|
supportsMultiValueOperators: state.supportsMultiValueOperators,
|
|
8535
8063
|
onAddCustomValue: state.onAddCustomValue,
|
|
8536
8064
|
wip: state._wip,
|
|
8537
|
-
|
|
8538
|
-
drilldownRecommendationsEnabled: state.drilldownRecommendationsEnabled
|
|
8065
|
+
collapsible: state.collapsible
|
|
8539
8066
|
};
|
|
8540
8067
|
}
|
|
8541
8068
|
async getKeys(currentKey) {
|
|
@@ -8550,9 +8077,6 @@ class AdHocFiltersVariableController {
|
|
|
8550
8077
|
updateFilter(filter, update) {
|
|
8551
8078
|
this.model._updateFilter(filter, update);
|
|
8552
8079
|
}
|
|
8553
|
-
updateFilters(filters, options) {
|
|
8554
|
-
this.model.updateFilters(filters, options);
|
|
8555
|
-
}
|
|
8556
8080
|
updateToMatchAll(filter) {
|
|
8557
8081
|
this.model.updateToMatchAll(filter);
|
|
8558
8082
|
}
|
|
@@ -8571,6 +8095,9 @@ class AdHocFiltersVariableController {
|
|
|
8571
8095
|
restoreOriginalFilter(filter) {
|
|
8572
8096
|
this.model.restoreOriginalFilter(filter);
|
|
8573
8097
|
}
|
|
8098
|
+
clearAll() {
|
|
8099
|
+
this.model.clearAll();
|
|
8100
|
+
}
|
|
8574
8101
|
startProfile(name) {
|
|
8575
8102
|
const queryController = getQueryController(this.model);
|
|
8576
8103
|
queryController == null ? void 0 : queryController.startProfile(name);
|
|
@@ -8660,11 +8187,6 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
|
8660
8187
|
this._debouncedVerifyApplicability = lodash.debounce(this._verifyApplicability, 100);
|
|
8661
8188
|
this._activationHandler = () => {
|
|
8662
8189
|
this._debouncedVerifyApplicability();
|
|
8663
|
-
if (this.state.drilldownRecommendationsEnabled && !this.state._valueRecommendations) {
|
|
8664
|
-
const valueRecommendations = new AdHocFiltersRecommendations(this);
|
|
8665
|
-
this.setState({ _valueRecommendations: valueRecommendations });
|
|
8666
|
-
valueRecommendations.activate();
|
|
8667
|
-
}
|
|
8668
8190
|
return () => {
|
|
8669
8191
|
var _a;
|
|
8670
8192
|
(_a = this.state.originFilters) == null ? void 0 : _a.forEach((filter) => {
|
|
@@ -8734,13 +8256,6 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
|
8734
8256
|
this._prevScopes = scopes;
|
|
8735
8257
|
this._debouncedVerifyApplicability();
|
|
8736
8258
|
}
|
|
8737
|
-
async verifyApplicabilityAndStoreRecentFilter(update) {
|
|
8738
|
-
await this._verifyApplicability();
|
|
8739
|
-
if (!this.state.drilldownRecommendationsEnabled || !this.state._valueRecommendations) {
|
|
8740
|
-
return;
|
|
8741
|
-
}
|
|
8742
|
-
this.state._valueRecommendations.storeRecentFilter(update);
|
|
8743
|
-
}
|
|
8744
8259
|
setState(update) {
|
|
8745
8260
|
var _a, _b;
|
|
8746
8261
|
let filterExpressionChanged = false;
|
|
@@ -8799,6 +8314,18 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
|
8799
8314
|
this._updateFilter(filter, original);
|
|
8800
8315
|
}
|
|
8801
8316
|
}
|
|
8317
|
+
/**
|
|
8318
|
+
* Clear all user-added filters and restore origin filters to their original values.
|
|
8319
|
+
*/
|
|
8320
|
+
clearAll() {
|
|
8321
|
+
var _a;
|
|
8322
|
+
(_a = this.state.originFilters) == null ? void 0 : _a.forEach((filter) => {
|
|
8323
|
+
if (filter.restorable) {
|
|
8324
|
+
this.restoreOriginalFilter(filter);
|
|
8325
|
+
}
|
|
8326
|
+
});
|
|
8327
|
+
this.setState({ filters: [] });
|
|
8328
|
+
}
|
|
8802
8329
|
getValue(fieldPath) {
|
|
8803
8330
|
if (fieldPath === ORIGIN_FILTERS_KEY) {
|
|
8804
8331
|
const originFilters = this.state.originFilters;
|
|
@@ -8832,11 +8359,8 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
|
8832
8359
|
}
|
|
8833
8360
|
if (filter === _wip) {
|
|
8834
8361
|
if ("value" in update && update["value"] !== "") {
|
|
8835
|
-
this.setState({
|
|
8836
|
-
|
|
8837
|
-
_wip: void 0
|
|
8838
|
-
});
|
|
8839
|
-
this.verifyApplicabilityAndStoreRecentFilter({ ..._wip, ...update });
|
|
8362
|
+
this.setState({ filters: [...filters, { ..._wip, ...update }], _wip: void 0 });
|
|
8363
|
+
this._debouncedVerifyApplicability();
|
|
8840
8364
|
} else {
|
|
8841
8365
|
this.setState({ _wip: { ...filter, ...update } });
|
|
8842
8366
|
}
|
|
@@ -8846,12 +8370,6 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
|
8846
8370
|
return f === filter ? { ...f, ...update } : f;
|
|
8847
8371
|
});
|
|
8848
8372
|
this.setState({ filters: updatedFilters });
|
|
8849
|
-
if (this.state.drilldownRecommendationsEnabled && this.state._valueRecommendations) {
|
|
8850
|
-
this.state._valueRecommendations.storeRecentFilter({
|
|
8851
|
-
...filter,
|
|
8852
|
-
...update
|
|
8853
|
-
});
|
|
8854
|
-
}
|
|
8855
8373
|
}
|
|
8856
8374
|
updateToMatchAll(filter) {
|
|
8857
8375
|
this._updateFilter(filter, {
|
|
@@ -9042,12 +8560,11 @@ class AdHocFiltersVariable extends SceneObjectBase {
|
|
|
9042
8560
|
let scopes = sceneGraph.getScopes(this);
|
|
9043
8561
|
if (filter.origin === "scope") {
|
|
9044
8562
|
scopes = scopes == null ? void 0 : scopes.map((scope) => {
|
|
9045
|
-
var _a2;
|
|
9046
8563
|
return {
|
|
9047
8564
|
...scope,
|
|
9048
8565
|
spec: {
|
|
9049
8566
|
...scope.spec,
|
|
9050
|
-
filters:
|
|
8567
|
+
filters: scope.spec.filters.filter((f) => f.key !== filter.key)
|
|
9051
8568
|
}
|
|
9052
8569
|
};
|
|
9053
8570
|
});
|
|
@@ -10536,6 +10053,91 @@ function containsSearchFilter(query) {
|
|
|
10536
10053
|
return str.indexOf(SEARCH_FILTER_VARIABLE) > -1;
|
|
10537
10054
|
}
|
|
10538
10055
|
|
|
10056
|
+
class ScopesVariable extends SceneObjectBase {
|
|
10057
|
+
constructor(state) {
|
|
10058
|
+
super({
|
|
10059
|
+
skipUrlSync: true,
|
|
10060
|
+
loading: true,
|
|
10061
|
+
scopes: [],
|
|
10062
|
+
...state,
|
|
10063
|
+
type: "system",
|
|
10064
|
+
name: SCOPES_VARIABLE_NAME,
|
|
10065
|
+
hide: schema.VariableHide.hideVariable
|
|
10066
|
+
});
|
|
10067
|
+
this._renderBeforeActivation = true;
|
|
10068
|
+
// Special options that enables variables to be hidden but still render to access react contexts
|
|
10069
|
+
this.UNSAFE_renderAsHidden = true;
|
|
10070
|
+
}
|
|
10071
|
+
/**
|
|
10072
|
+
* Temporary simple implementation to stringify the scopes.
|
|
10073
|
+
*/
|
|
10074
|
+
getValue() {
|
|
10075
|
+
var _a;
|
|
10076
|
+
const scopes = (_a = this.state.scopes) != null ? _a : [];
|
|
10077
|
+
return new ScopesVariableFormatter(scopes.map((scope) => scope.metadata.name));
|
|
10078
|
+
}
|
|
10079
|
+
getScopes() {
|
|
10080
|
+
return this.state.scopes;
|
|
10081
|
+
}
|
|
10082
|
+
/**
|
|
10083
|
+
* This method is used to keep the context up to date with the scopes context received from React
|
|
10084
|
+
* 1) Subscribes to ScopesContext state changes and synchronizes it with the variable state
|
|
10085
|
+
* 2) Handles enable / disabling of scopes based on variable enable option.
|
|
10086
|
+
*/
|
|
10087
|
+
setContext(context) {
|
|
10088
|
+
if (!context) {
|
|
10089
|
+
return;
|
|
10090
|
+
}
|
|
10091
|
+
this._context = context;
|
|
10092
|
+
const oldState = context.state;
|
|
10093
|
+
if (this.state.enable != null) {
|
|
10094
|
+
context.setEnabled(this.state.enable);
|
|
10095
|
+
}
|
|
10096
|
+
const sub = context.stateObservable.subscribe((state) => {
|
|
10097
|
+
this.updateStateFromContext(state);
|
|
10098
|
+
});
|
|
10099
|
+
return () => {
|
|
10100
|
+
sub.unsubscribe();
|
|
10101
|
+
if (this.state.enable != null) {
|
|
10102
|
+
context.setEnabled(oldState.enabled);
|
|
10103
|
+
}
|
|
10104
|
+
};
|
|
10105
|
+
}
|
|
10106
|
+
updateStateFromContext(state) {
|
|
10107
|
+
const loading = state.value.length === 0 ? false : state.loading;
|
|
10108
|
+
const oldScopes = this.state.scopes.map((scope) => scope.metadata.name);
|
|
10109
|
+
const newScopes = state.value.map((scope) => scope.metadata.name);
|
|
10110
|
+
const scopesHaveChanged = !lodash.isEqual(oldScopes, newScopes);
|
|
10111
|
+
if (!loading && (scopesHaveChanged || newScopes.length === 0)) {
|
|
10112
|
+
const queryController = getQueryController(this);
|
|
10113
|
+
queryController == null ? void 0 : queryController.startProfile(SCOPES_CHANGED_INTERACTION);
|
|
10114
|
+
this.setState({ scopes: state.value, loading });
|
|
10115
|
+
this.publishEvent(new SceneVariableValueChangedEvent(this), true);
|
|
10116
|
+
} else {
|
|
10117
|
+
this.setState({ loading });
|
|
10118
|
+
}
|
|
10119
|
+
}
|
|
10120
|
+
}
|
|
10121
|
+
ScopesVariable.Component = ScopesVariableRenderer;
|
|
10122
|
+
function ScopesVariableRenderer({ model }) {
|
|
10123
|
+
const context = React.useContext(runtime.ScopesContext);
|
|
10124
|
+
React.useEffect(() => {
|
|
10125
|
+
return model.setContext(context);
|
|
10126
|
+
}, [context, model]);
|
|
10127
|
+
return null;
|
|
10128
|
+
}
|
|
10129
|
+
class ScopesVariableFormatter {
|
|
10130
|
+
constructor(_value) {
|
|
10131
|
+
this._value = _value;
|
|
10132
|
+
}
|
|
10133
|
+
formatter(formatNameOrFn) {
|
|
10134
|
+
if (formatNameOrFn === schema.VariableFormatID.QueryParam) {
|
|
10135
|
+
return this._value.map((scope) => `scope=${encodeURIComponent(scope)}`).join("&");
|
|
10136
|
+
}
|
|
10137
|
+
return this._value.join(", ");
|
|
10138
|
+
}
|
|
10139
|
+
}
|
|
10140
|
+
|
|
10539
10141
|
function getVariables(sceneObject) {
|
|
10540
10142
|
var _a;
|
|
10541
10143
|
return (_a = getClosest(sceneObject, (s) => s.state.$variables)) != null ? _a : EmptyVariableSet;
|
|
@@ -16852,7 +16454,7 @@ function __variableDynamicImportRuntime0__(path) {
|
|
|
16852
16454
|
switch (path) {
|
|
16853
16455
|
case '../locales/cs-CZ/grafana-scenes.json': return Promise.resolve().then(function () { return require('./grafana-scenes-DPdlSPjz.js'); });
|
|
16854
16456
|
case '../locales/de-DE/grafana-scenes.json': return Promise.resolve().then(function () { return require('./grafana-scenes-BHIE4ld0.js'); });
|
|
16855
|
-
case '../locales/en-US/grafana-scenes.json': return Promise.resolve().then(function () { return require('./grafana-scenes-
|
|
16457
|
+
case '../locales/en-US/grafana-scenes.json': return Promise.resolve().then(function () { return require('./grafana-scenes-CwGWCTcQ.js'); });
|
|
16856
16458
|
case '../locales/es-ES/grafana-scenes.json': return Promise.resolve().then(function () { return require('./grafana-scenes-D4tq59Dc.js'); });
|
|
16857
16459
|
case '../locales/fr-FR/grafana-scenes.json': return Promise.resolve().then(function () { return require('./grafana-scenes-Ce77KCbO.js'); });
|
|
16858
16460
|
case '../locales/hu-HU/grafana-scenes.json': return Promise.resolve().then(function () { return require('./grafana-scenes-DMYCnFop.js'); });
|
|
@@ -16997,7 +16599,6 @@ exports.dataLayers = index;
|
|
|
16997
16599
|
exports.escapeUrlPipeDelimiters = escapeUrlPipeDelimiters;
|
|
16998
16600
|
exports.formatRegistry = formatRegistry;
|
|
16999
16601
|
exports.getExploreURL = getExploreURL;
|
|
17000
|
-
exports.getQueriesForVariables = getQueriesForVariables;
|
|
17001
16602
|
exports.isCustomVariableValue = isCustomVariableValue;
|
|
17002
16603
|
exports.isDataLayer = isDataLayer;
|
|
17003
16604
|
exports.isDataRequestEnricher = isDataRequestEnricher;
|