@gooddata/sdk-ui-dashboard 11.36.0-alpha.3 → 11.36.0-alpha.7
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/NOTICE +74 -162
- package/esm/__version.d.ts +1 -1
- package/esm/__version.js +1 -1
- package/esm/index.d.ts +5 -13
- package/esm/index.js +2 -10
- package/esm/internal.d.ts +1 -1
- package/esm/model/commandHandlers/dashboard/common/filterViews.js +24 -1
- package/esm/model/commandHandlers/dashboard/common/parameterHydration.d.ts +7 -1
- package/esm/model/commandHandlers/dashboard/common/parameterHydration.js +16 -2
- package/esm/model/commandHandlers/dashboard/common/stateInitializers.js +4 -2
- package/esm/model/commandHandlers/drill/resolveDrillToCustomUrl.d.ts +7 -1
- package/esm/model/commandHandlers/drill/resolveDrillToCustomUrl.js +80 -4
- package/esm/model/commandHandlers/filterContext/filterViewHandler.js +10 -0
- package/esm/model/commandHandlers/filterContext/filterViewParameters.d.ts +7 -0
- package/esm/model/commandHandlers/filterContext/filterViewParameters.js +11 -0
- package/esm/model/store/config/configSelectors.d.ts +0 -12
- package/esm/model/store/config/configSelectors.js +2 -18
- package/esm/model/store/tabs/index.d.ts +4 -0
- package/esm/model/store/tabs/parameters/parametersReducers.d.ts +11 -1
- package/esm/model/store/tabs/parameters/parametersReducers.js +16 -8
- package/esm/model/store/tabs/parameters/parametersSelectors.d.ts +7 -0
- package/esm/model/store/tabs/parameters/parametersSelectors.js +17 -0
- package/esm/model/store/widgetDrills/widgetDrillSelectors.js +10 -18
- package/esm/model/types/commonTypes.d.ts +11 -2
- package/esm/model/utils/measureValueFilterUtils.d.ts +14 -0
- package/esm/model/utils/measureValueFilterUtils.js +21 -0
- package/esm/presentation/alerting/DefaultAlertingDialog/{DefaultAlertingDialogNew.d.ts → DefaultAlertingDialog.d.ts} +1 -1
- package/esm/presentation/alerting/DefaultAlertingDialog/{DefaultAlertingDialogNew.js → DefaultAlertingDialog.js} +6 -12
- package/esm/presentation/alerting/DefaultAlertingDialog/components/AlertAttributeSelect.js +43 -9
- package/esm/presentation/alerting/DefaultAlertingDialog/hooks/useSaveAlertToBackend.js +13 -25
- package/esm/presentation/alerting/DefaultAlertingDialog/utils/items.js +5 -2
- package/esm/presentation/alerting/types.d.ts +1 -72
- package/esm/presentation/automationFilters/hooks/useValidateExistingAutomationFilters.d.ts +1 -2
- package/esm/presentation/automationFilters/hooks/useValidateExistingAutomationFilters.js +5 -5
- package/esm/presentation/dashboard/DashboardHeader/AlertingDialogProvider.js +1 -8
- package/esm/presentation/dashboard/DashboardHeader/ScheduledEmailDialogProvider.js +17 -8
- package/esm/presentation/dashboard/DashboardHeader/ShareDialogDashboardHeader.js +5 -2
- package/esm/presentation/dashboard/components/DashboardRenderer.js +2 -2
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditor.js +97 -13
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParameters.d.ts +1 -1
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParameters.js +3 -3
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/DashboardParametersSection.d.ts +3 -2
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/DashboardParametersSection.js +17 -4
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/InsightParametersSection.d.ts +4 -2
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/InsightParametersSection.js +37 -4
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/Parameter.d.ts +4 -3
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/Parameter.js +3 -4
- package/esm/presentation/drill/DrillSelect/DrillSelectDropdown.js +1 -3
- package/esm/presentation/drill/hooks/useDrillSelectDropdownMenuItems.js +1 -5
- package/esm/presentation/export/DefaultDashboardExportVariables.js +5 -2
- package/esm/presentation/export/hooks/useDashboardRelatedFilters.d.ts +2 -1
- package/esm/presentation/export/hooks/useDashboardRelatedFilters.js +9 -0
- package/esm/presentation/export/types.d.ts +2 -1
- package/esm/presentation/export/types.js +1 -1
- package/esm/presentation/export/useExportData.js +4 -0
- package/esm/presentation/filterBar/attributeFilter/DefaultDashboardAttributeFilter.js +4 -1
- package/esm/presentation/filterBar/filterBar/DefaultDashboardFilterGroup.js +4 -1
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.js +4 -10
- package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts +4 -36
- package/esm/presentation/localization/bundles/en-US.localization-bundle.js +4 -36
- package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/es-419.localization-bundle.js +4 -10
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.js +4 -10
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.js +3 -9
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/DefaultScheduledEmailDialog.js +26 -59
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.d.ts +2 -6
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.js +22 -104
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/hooks/useSaveScheduledEmailToBackend.js +12 -33
- package/esm/presentation/scheduledEmail/hooks/useWidgetAutomationFilters.d.ts +3 -0
- package/esm/presentation/scheduledEmail/hooks/useWidgetAutomationFilters.js +46 -0
- package/esm/presentation/scheduledEmail/types.d.ts +1 -7
- package/esm/presentation/scheduledEmail/utils/filters.d.ts +2 -0
- package/esm/presentation/scheduledEmail/utils/filters.js +5 -0
- package/esm/presentation/shareDialog/DefaultShareDialog.d.ts +1 -1
- package/esm/presentation/shareDialog/DefaultShareDialog.js +2 -2
- package/esm/presentation/shareDialog/types.d.ts +5 -1
- package/esm/presentation/widget/insight/configuration/DrillTargets/useInvalidFilteringParametersIdentifiers.d.ts +2 -2
- package/esm/presentation/widget/insight/configuration/DrillTargets/useInvalidFilteringParametersIdentifiers.js +36 -5
- package/esm/presentation/widget/insight/configuration/InsightAlertConfig/EditAlert.js +2 -2
- package/esm/presentation/widget/insight/configuration/InsightAlertConfig/hooks/useInsightWidgetAlerting.js +3 -6
- package/esm/presentation/widget/insight/configuration/InsightAlerts.js +1 -9
- package/esm/presentation/widget/insight/configuration/InsightDrillConfigPanel/useInsightDrillConfigPanel.js +4 -10
- package/esm/sdk-ui-dashboard.d.ts +31 -249
- package/package.json +20 -20
- package/esm/model/react/filtering/shared.d.ts +0 -6
- package/esm/model/react/filtering/shared.js +0 -38
- package/esm/model/react/filtering/useAutomationAvailableDashboardFilters.d.ts +0 -13
- package/esm/model/react/filtering/useAutomationAvailableDashboardFilters.js +0 -54
- package/esm/model/react/filtering/useDashboardScheduledExportFilters.d.ts +0 -19
- package/esm/model/react/filtering/useDashboardScheduledExportFilters.js +0 -18
- package/esm/model/react/filtering/useScheduledExportFilters.d.ts +0 -26
- package/esm/model/react/filtering/useScheduledExportFilters.js +0 -23
- package/esm/model/react/filtering/useWidgetAlertFilters.d.ts +0 -33
- package/esm/model/react/filtering/useWidgetAlertFilters.js +0 -48
- package/esm/model/react/filtering/useWidgetScheduledExportFilters.d.ts +0 -33
- package/esm/model/react/filtering/useWidgetScheduledExportFilters.js +0 -48
- package/esm/model/react/useDashboardAlerting/useEnableAutomationFilterContext.d.ts +0 -4
- package/esm/model/react/useDashboardAlerting/useEnableAutomationFilterContext.js +0 -20
- package/esm/model/react/useDashboardAlertsOld.d.ts +0 -32
- package/esm/model/react/useDashboardAlertsOld.js +0 -141
- package/esm/presentation/alerting/DefaultAlertingDialog/DefaultAlertingDialogOld.d.ts +0 -5
- package/esm/presentation/alerting/DefaultAlertingDialog/DefaultAlertingDialogOld.js +0 -36
- package/esm/presentation/alerting/DefaultAlertingDialog/components/AlertAttributeSelectOld.d.ts +0 -17
- package/esm/presentation/alerting/DefaultAlertingDialog/components/AlertAttributeSelectOld.js +0 -103
- package/esm/presentation/alerting/DefaultAlertingManagementDialog/DefaultAlertingManagementDialogOld.d.ts +0 -5
- package/esm/presentation/alerting/DefaultAlertingManagementDialog/DefaultAlertingManagementDialogOld.js +0 -53
- package/esm/presentation/alerting/DefaultAlertingManagementDialog/components/AlertOld.d.ts +0 -9
- package/esm/presentation/alerting/DefaultAlertingManagementDialog/components/AlertOld.js +0 -84
- package/esm/presentation/alerting/DefaultAlertingManagementDialog/components/AlertsListOld.d.ts +0 -11
- package/esm/presentation/alerting/DefaultAlertingManagementDialog/components/AlertsListOld.js +0 -16
- package/esm/presentation/dashboard/DashboardHeader/AlertingDialogProviderOld.d.ts +0 -1
- package/esm/presentation/dashboard/DashboardHeader/AlertingDialogProviderOld.js +0 -12
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentFilters.d.ts +0 -29
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentFilters.js +0 -61
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentFiltersList.d.ts +0 -6
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentFiltersList.js +0 -12
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentItems.d.ts +0 -17
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentItems.js +0 -68
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentsWrapper.d.ts +0 -4
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentsWrapper.js +0 -6
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/DashboardAttachments.d.ts +0 -15
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/DashboardAttachments.js +0 -42
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/WidgetAttachments.d.ts +0 -18
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/WidgetAttachments.js +0 -25
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/types.d.ts +0 -2
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/types.js +0 -2
- package/esm/presentation/widget/insight/configuration/InsightAlertsOld.d.ts +0 -2
- package/esm/presentation/widget/insight/configuration/InsightAlertsOld.js +0 -43
|
@@ -5,15 +5,16 @@ import { HighlightStyle, StreamLanguage, syntaxHighlighting } from "@codemirror/
|
|
|
5
5
|
import { Tag } from "@lezer/highlight";
|
|
6
6
|
import { compact, uniqBy } from "lodash-es";
|
|
7
7
|
import { FormattedMessage, useIntl } from "react-intl";
|
|
8
|
-
import { filterObjRef, idRef, isArbitraryAttributeFilter, isAttributeFilter, isMatchAttributeFilter, isNegativeAttributeFilter, isPositiveAttributeFilter, isUriRef, objRefToString, serializeObjRef, } from "@gooddata/sdk-model";
|
|
8
|
+
import { filterObjRef, idRef, insightFilters as insightDefinitionFilters, isArbitraryAttributeFilter, isAttributeFilter, isMatchAttributeFilter, isMeasureValueFilter, isNegativeAttributeFilter, isPositiveAttributeFilter, isUriRef, objRefToString, serializeObjRef, } from "@gooddata/sdk-model";
|
|
9
9
|
import { ConfirmDialogBase, FullScreenOverlay, Overlay, OverlayController, OverlayControllerProvider, SyntaxHighlightingInput, useMediaQuery, } from "@gooddata/sdk-ui-kit";
|
|
10
10
|
import { dashboardAttributeFilterItemToAttributeFilter } from "../../../../converters/filterConverters.js";
|
|
11
11
|
import { useDashboardSelector } from "../../../../model/react/DashboardStoreProvider.js";
|
|
12
12
|
import { useWidgetFilters } from "../../../../model/react/useWidgetFilters.js";
|
|
13
|
-
import { selectAllCatalogDisplayFormsMap } from "../../../../model/store/catalog/catalogSelectors.js";
|
|
14
|
-
import { selectIsWhiteLabeled } from "../../../../model/store/config/configSelectors.js";
|
|
13
|
+
import { selectAllCatalogDisplayFormsMap, selectAllCatalogMeasuresMap, } from "../../../../model/store/catalog/catalogSelectors.js";
|
|
14
|
+
import { selectEnableMeasureValueFilterKD, selectIsWhiteLabeled, } from "../../../../model/store/config/configSelectors.js";
|
|
15
|
+
import { selectInsightByWidgetRef } from "../../../../model/store/insights/insightsSelectors.js";
|
|
15
16
|
import { selectAttributeFilterConfigsOverrides } from "../../../../model/store/tabs/attributeFilterConfigs/attributeFilterConfigsSelectors.js";
|
|
16
|
-
import { selectFilterContextAttributeFilterItems } from "../../../../model/store/tabs/filterContext/filterContextSelectors.js";
|
|
17
|
+
import { selectFilterContextAttributeFilterItems, selectFilterContextMeasureValueFilters, } from "../../../../model/store/tabs/filterContext/filterContextSelectors.js";
|
|
17
18
|
import { selectFilterableWidgetByRef } from "../../../../model/store/tabs/layout/layoutSelectors.js";
|
|
18
19
|
import { DASHBOARD_HEADER_OVERLAYS_Z_INDEX } from "../../../constants/zIndex.js";
|
|
19
20
|
import { useInvalidFilteringParametersIdentifiers } from "../../../widget/insight/configuration/DrillTargets/useInvalidFilteringParametersIdentifiers.js";
|
|
@@ -114,6 +115,30 @@ const buildValidDashboardFiltersFormattingRule = (attributeFilters, attributeFil
|
|
|
114
115
|
token: customTags.filter.toString(),
|
|
115
116
|
};
|
|
116
117
|
};
|
|
118
|
+
const buildValidDashboardMvfFormattingRule = (measureIdentifiers) => {
|
|
119
|
+
if (measureIdentifiers.length === 0) {
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
const validDashboardMvfPlaceholders = measureIdentifiers
|
|
123
|
+
.map((id) => `{dash_mvf_condition\\(${id}\\)}`)
|
|
124
|
+
.join("|");
|
|
125
|
+
return {
|
|
126
|
+
regex: new RegExp(`^${validDashboardMvfPlaceholders}`),
|
|
127
|
+
token: customTags.filter.toString(),
|
|
128
|
+
};
|
|
129
|
+
};
|
|
130
|
+
const buildValidInsightMvfFormattingRule = (measureIdentifiers) => {
|
|
131
|
+
if (measureIdentifiers.length === 0) {
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
const validInsightMvfPlaceholders = measureIdentifiers
|
|
135
|
+
.map((id) => `{mvf_condition\\(${id}\\)}`)
|
|
136
|
+
.join("|");
|
|
137
|
+
return {
|
|
138
|
+
regex: new RegExp(`^${validInsightMvfPlaceholders}`),
|
|
139
|
+
token: customTags.filter.toString(),
|
|
140
|
+
};
|
|
141
|
+
};
|
|
117
142
|
const IDENTIFIER_RULE = {
|
|
118
143
|
regex: /^\{workspace_id\}|\{project_id\}|\{visualization_id\}|\{widget_id\}|\{dashboard_id\}|\{client_id\}|\{data_product_id\}/,
|
|
119
144
|
token: customTags.identifier.toString(),
|
|
@@ -127,6 +152,14 @@ const INVALID_DASHBOARD_ATTRIBUTE_FILTER_RULE = {
|
|
|
127
152
|
regex: /^\{dash_attribute_filter_selection\(.*?\)\}/,
|
|
128
153
|
token: customTags.invalidFilter.toString(),
|
|
129
154
|
};
|
|
155
|
+
const INVALID_DASHBOARD_MVF_RULE = {
|
|
156
|
+
regex: /^\{dash_mvf_condition\(.*?\)\}/,
|
|
157
|
+
token: customTags.invalidFilter.toString(),
|
|
158
|
+
};
|
|
159
|
+
const INVALID_INSIGHT_MVF_RULE = {
|
|
160
|
+
regex: /^\{mvf_condition\(.*?\)\}/,
|
|
161
|
+
token: customTags.invalidFilter.toString(),
|
|
162
|
+
};
|
|
130
163
|
const INVALID_INSIGHT_ATTRIBUTE_FILTER_RULE = {
|
|
131
164
|
regex: /^\{attribute_filter_selection\(.*?\)\}/,
|
|
132
165
|
token: customTags.invalidFilter.toString(),
|
|
@@ -134,27 +167,55 @@ const INVALID_INSIGHT_ATTRIBUTE_FILTER_RULE = {
|
|
|
134
167
|
const DEFAULT_RULES = [
|
|
135
168
|
INVALID_DISPLAY_FORMS_RULE,
|
|
136
169
|
INVALID_DASHBOARD_ATTRIBUTE_FILTER_RULE,
|
|
170
|
+
INVALID_DASHBOARD_MVF_RULE,
|
|
171
|
+
INVALID_INSIGHT_MVF_RULE,
|
|
137
172
|
INVALID_INSIGHT_ATTRIBUTE_FILTER_RULE,
|
|
138
173
|
IDENTIFIER_RULE,
|
|
139
174
|
INVALID_IDENTIFIER_RULE,
|
|
140
175
|
];
|
|
141
|
-
const buildFormattingRules = (attributeDisplayForms, dashboardFilters, insightFilters, attributeFilterConfigs) => {
|
|
176
|
+
const buildFormattingRules = (attributeDisplayForms, dashboardFilters, insightFilters, dashboardMeasureIdentifiers, insightMeasureIdentifiers, attributeFilterConfigs) => {
|
|
142
177
|
const validDisplayFormsRule = buildValidDisplayFormsFormattingRule(attributeDisplayForms);
|
|
143
178
|
const validInsightFiltersRule = buildValidInsightFiltersFormattingRule(insightFilters);
|
|
144
179
|
const validDashboardFiltersRule = buildValidDashboardFiltersFormattingRule(dashboardFilters, attributeFilterConfigs);
|
|
180
|
+
const validDashboardMvfRule = buildValidDashboardMvfFormattingRule(dashboardMeasureIdentifiers);
|
|
181
|
+
const validInsightMvfRule = buildValidInsightMvfFormattingRule(insightMeasureIdentifiers);
|
|
145
182
|
return compact([
|
|
146
183
|
validDisplayFormsRule,
|
|
147
184
|
validDashboardFiltersRule,
|
|
185
|
+
validDashboardMvfRule,
|
|
148
186
|
validInsightFiltersRule,
|
|
187
|
+
validInsightMvfRule,
|
|
149
188
|
...DEFAULT_RULES,
|
|
150
189
|
]);
|
|
151
190
|
};
|
|
152
|
-
function UrlInputPanel({ currentUrlValue, onChange, onCursor, documentationLink, attributeDisplayForms, intl, insightFilters, dashboardFilters, attributeFilterConfigs, }) {
|
|
191
|
+
function UrlInputPanel({ currentUrlValue, onChange, onCursor, documentationLink, attributeDisplayForms, intl, insightFilters, dashboardFilters, dashboardMeasureValueFilters, insightMeasureValueFilters, enableInsightMeasureValueFilters, attributeFilterConfigs, }) {
|
|
153
192
|
const isWhiteLabeled = useDashboardSelector(selectIsWhiteLabeled);
|
|
193
|
+
const catalogMeasuresMap = useDashboardSelector(selectAllCatalogMeasuresMap);
|
|
194
|
+
const dashboardMeasureIdentifiers = useMemo(() => {
|
|
195
|
+
return (dashboardMeasureValueFilters ?? []).map((filter) => {
|
|
196
|
+
const measureRef = filter.dashboardMeasureValueFilter.measure;
|
|
197
|
+
return catalogMeasuresMap.get(measureRef)?.measure.id ?? objRefToString(measureRef);
|
|
198
|
+
});
|
|
199
|
+
}, [catalogMeasuresMap, dashboardMeasureValueFilters]);
|
|
200
|
+
const insightMeasureIdentifiers = useMemo(() => enableInsightMeasureValueFilters
|
|
201
|
+
? (insightMeasureValueFilters ?? []).map((filter) => {
|
|
202
|
+
const measureRef = filter.measureValueFilter.measure;
|
|
203
|
+
return objRefToString(measureRef);
|
|
204
|
+
})
|
|
205
|
+
: [], [enableInsightMeasureValueFilters, insightMeasureValueFilters]);
|
|
154
206
|
const syntaxHighlightingRules = useMemo(() => attributeDisplayForms &&
|
|
155
207
|
insightFilters &&
|
|
156
208
|
dashboardFilters &&
|
|
157
|
-
|
|
209
|
+
dashboardMeasureValueFilters &&
|
|
210
|
+
buildFormattingRules(attributeDisplayForms, dashboardFilters, insightFilters, dashboardMeasureIdentifiers, insightMeasureIdentifiers, attributeFilterConfigs), [
|
|
211
|
+
attributeDisplayForms,
|
|
212
|
+
insightFilters,
|
|
213
|
+
dashboardFilters,
|
|
214
|
+
dashboardMeasureValueFilters,
|
|
215
|
+
dashboardMeasureIdentifiers,
|
|
216
|
+
insightMeasureIdentifiers,
|
|
217
|
+
attributeFilterConfigs,
|
|
218
|
+
]);
|
|
158
219
|
return (_jsxs("div", { children: [
|
|
159
220
|
_jsx("label", { className: "gd-label", children: _jsx(FormattedMessage, { id: "configurationPanel.drillIntoUrl.editor.textAreaLabel" }) }), _jsx(UrlInput, { onChange: onChange, onCursor: onCursor, currentUrlValue: currentUrlValue, syntaxHighlightingRules: syntaxHighlightingRules, intl: intl }), !isWhiteLabeled && documentationLink ? _jsx(HelpLink, { link: documentationLink }) : null] }));
|
|
160
221
|
}
|
|
@@ -163,19 +224,33 @@ const initialCursorPosition = {
|
|
|
163
224
|
to: 0,
|
|
164
225
|
};
|
|
165
226
|
const insertPlaceholderAtCursor = (text, placeholder, cursor) => `${text.substring(0, cursor.from)}${placeholder}${text.substring(cursor.to)}`;
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
227
|
+
const URL_START_RULES = [
|
|
228
|
+
/^[A-Za-z0-9.\-+]+:/,
|
|
229
|
+
/^\{attribute_title\(/,
|
|
230
|
+
/^\{attribute_filter_selection\(/,
|
|
231
|
+
/^\{dash_attribute_filter_selection\(/,
|
|
232
|
+
/^\{dash_mvf_condition\(/,
|
|
233
|
+
];
|
|
234
|
+
const INSIGHT_MVF_URL_START_RULE = /^\{mvf_condition\(/;
|
|
235
|
+
const assertValidUrl = (url, enableInsightMeasureValueFilters) => {
|
|
236
|
+
const rules = enableInsightMeasureValueFilters
|
|
237
|
+
? [...URL_START_RULES, INSIGHT_MVF_URL_START_RULE]
|
|
238
|
+
: URL_START_RULES;
|
|
239
|
+
return rules.some((rule) => rule.test(url)) ? url : `https://${url}`;
|
|
240
|
+
};
|
|
169
241
|
const getWarningTextForInvalidParameters = (parameters) => {
|
|
170
242
|
const invalidParameters = parameters.map((parameter) => `"${parameter}"`).join(", ");
|
|
171
243
|
return (_jsx(FormattedMessage, { id: "configurationPanel.drillIntoUrl.editor.invalidAttributeDisplayForms", values: { invalidParameters } }));
|
|
172
244
|
};
|
|
173
245
|
function CustomUrlEditorDialog({ urlDrillTarget, documentationLink, onSelect, onClose, attributeDisplayForms, loadingAttributeDisplayForms = false, invalidAttributeDisplayFormIdentifiers, enableClientIdParameter, enableDataProductIdParameter, enableWidgetIdParameter, widgetRef, }) {
|
|
174
246
|
const intl = useIntl();
|
|
247
|
+
const enableInsightMeasureValueFilters = useDashboardSelector(selectEnableMeasureValueFilterKD);
|
|
175
248
|
const insightFilters = useSanitizedInsightFilters(widgetRef);
|
|
249
|
+
const insightMeasureValueFilters = useInsightMeasureValueFilters(widgetRef, enableInsightMeasureValueFilters);
|
|
176
250
|
const dashboardFilters = useSanitizedDashboardFilters();
|
|
251
|
+
const dashboardMeasureValueFilters = useDashboardSelector(selectFilterContextMeasureValueFilters);
|
|
177
252
|
const attributeFilterConfigs = useDashboardSelector(selectAttributeFilterConfigsOverrides);
|
|
178
|
-
const invalidFilteringParametersIdentifiers = useInvalidFilteringParametersIdentifiers(urlDrillTarget, insightFilters, dashboardFilters, attributeFilterConfigs);
|
|
253
|
+
const invalidFilteringParametersIdentifiers = useInvalidFilteringParametersIdentifiers(urlDrillTarget, insightFilters, dashboardFilters, dashboardMeasureValueFilters, enableInsightMeasureValueFilters ? insightMeasureValueFilters : undefined, enableInsightMeasureValueFilters, attributeFilterConfigs);
|
|
179
254
|
const invalidParameters = useMemo(() => {
|
|
180
255
|
return [...invalidAttributeDisplayFormIdentifiers, ...invalidFilteringParametersIdentifiers];
|
|
181
256
|
}, [invalidAttributeDisplayFormIdentifiers, invalidFilteringParametersIdentifiers]);
|
|
@@ -183,7 +258,7 @@ function CustomUrlEditorDialog({ urlDrillTarget, documentationLink, onSelect, on
|
|
|
183
258
|
? (isDrillToCustomUrlConfig(urlDrillTarget) && urlDrillTarget.customUrl) || ""
|
|
184
259
|
: "";
|
|
185
260
|
const [currentValue, setCurrentValue] = useState(previousValue);
|
|
186
|
-
const apply = () => onSelect(assertValidUrl(currentValue));
|
|
261
|
+
const apply = () => onSelect(assertValidUrl(currentValue, enableInsightMeasureValueFilters));
|
|
187
262
|
const handleOnChange = (value) => setCurrentValue(value);
|
|
188
263
|
const isApplyEnabled = currentValue && currentValue.localeCompare(previousValue) !== 0;
|
|
189
264
|
const [cursorPosition, setCursorPosition] = useState(initialCursorPosition);
|
|
@@ -197,7 +272,7 @@ function CustomUrlEditorDialog({ urlDrillTarget, documentationLink, onSelect, on
|
|
|
197
272
|
}), submitButtonText: intl.formatMessage({
|
|
198
273
|
id: "configurationPanel.drillIntoUrl.editor.applyButtonLabel",
|
|
199
274
|
}), isSubmitDisabled: !isApplyEnabled, submitOnEnterKey: false, onCancel: onClose, onSubmit: apply, warning: editorWarningText, children: [
|
|
200
|
-
_jsx(UrlInputPanel, { onChange: handleOnChange, onCursor: handleCursorPosition, documentationLink: documentationLink, currentUrlValue: currentValue, attributeDisplayForms: attributeDisplayForms, insightFilters: insightFilters, dashboardFilters: dashboardFilters, attributeFilterConfigs: attributeFilterConfigs, intl: intl }), _jsx(ParametersPanel, { insightFilters: insightFilters, dashboardFilters: dashboardFilters, attributeFilterConfigs: attributeFilterConfigs, attributeDisplayForms: attributeDisplayForms, loadingAttributeDisplayForms: loadingAttributeDisplayForms, enableClientIdParameter: enableClientIdParameter, enableDataProductIdParameter: enableDataProductIdParameter, enableWidgetIdParameter: enableWidgetIdParameter, onAdd: handleOnAdd, intl: intl, widgetRef: widgetRef })
|
|
275
|
+
_jsx(UrlInputPanel, { onChange: handleOnChange, onCursor: handleCursorPosition, documentationLink: documentationLink, currentUrlValue: currentValue, attributeDisplayForms: attributeDisplayForms, insightFilters: insightFilters, dashboardFilters: dashboardFilters, dashboardMeasureValueFilters: dashboardMeasureValueFilters, insightMeasureValueFilters: insightMeasureValueFilters, enableInsightMeasureValueFilters: enableInsightMeasureValueFilters, attributeFilterConfigs: attributeFilterConfigs, intl: intl }), _jsx(ParametersPanel, { insightFilters: insightFilters, dashboardFilters: dashboardFilters, dashboardMeasureValueFilters: dashboardMeasureValueFilters, insightMeasureValueFilters: insightMeasureValueFilters, attributeFilterConfigs: attributeFilterConfigs, attributeDisplayForms: attributeDisplayForms, loadingAttributeDisplayForms: loadingAttributeDisplayForms, enableClientIdParameter: enableClientIdParameter, enableDataProductIdParameter: enableDataProductIdParameter, enableWidgetIdParameter: enableWidgetIdParameter, onAdd: handleOnAdd, intl: intl, widgetRef: widgetRef })
|
|
201
276
|
] }));
|
|
202
277
|
}
|
|
203
278
|
const overlayController = OverlayController.getInstance(DASHBOARD_HEADER_OVERLAYS_Z_INDEX);
|
|
@@ -206,6 +281,15 @@ export function CustomUrlEditor(props) {
|
|
|
206
281
|
const SelectedOverlay = isMobileDevice ? FullScreenOverlay : Overlay;
|
|
207
282
|
return (_jsx(OverlayControllerProvider, { overlayController: overlayController, children: _jsx(SelectedOverlay, { onClose: props.onClose, isModal: true, closeOnOutsideClick: false, closeOnEscape: true, positionType: "fixed", className: "gd-modal-overlay", children: _jsx(CustomUrlEditorDialog, { ...props }) }) }));
|
|
208
283
|
}
|
|
284
|
+
function useInsightMeasureValueFilters(widgetRef, enabled) {
|
|
285
|
+
const insight = useDashboardSelector(selectInsightByWidgetRef(widgetRef));
|
|
286
|
+
return useMemo(() => {
|
|
287
|
+
if (!enabled || !insight) {
|
|
288
|
+
return [];
|
|
289
|
+
}
|
|
290
|
+
return insightDefinitionFilters(insight).filter(isMeasureValueFilter);
|
|
291
|
+
}, [enabled, insight]);
|
|
292
|
+
}
|
|
209
293
|
function useSanitizedInsightFilters(widgetRef) {
|
|
210
294
|
const widget = useDashboardSelector(selectFilterableWidgetByRef(widgetRef));
|
|
211
295
|
const widgetFiltersResult = useWidgetFilters(widget);
|
|
@@ -2,5 +2,5 @@ import { type IDashboardParametersSectionProps } from "./CustomUrlEditorParamete
|
|
|
2
2
|
import { type IInsightParametersSectionProps } from "./CustomUrlEditorParametersSections/InsightParametersSection.js";
|
|
3
3
|
import { type IIdentifierParametersSectionProps } from "./types.js";
|
|
4
4
|
type IParametersPanelProps = IInsightParametersSectionProps & IIdentifierParametersSectionProps & IDashboardParametersSectionProps;
|
|
5
|
-
export declare function ParametersPanel({ attributeDisplayForms, loadingAttributeDisplayForms, enableClientIdParameter, enableDataProductIdParameter, enableWidgetIdParameter, onAdd, intl, dashboardFilters, attributeFilterConfigs, insightFilters, widgetRef }: IParametersPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export declare function ParametersPanel({ attributeDisplayForms, loadingAttributeDisplayForms, enableClientIdParameter, enableDataProductIdParameter, enableWidgetIdParameter, onAdd, intl, dashboardFilters, dashboardMeasureValueFilters, insightMeasureValueFilters, attributeFilterConfigs, insightFilters, widgetRef }: IParametersPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
6
6
|
export {};
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
// (C) 2020-
|
|
2
|
+
// (C) 2020-2026 GoodData Corporation
|
|
3
3
|
import { FormattedMessage } from "react-intl";
|
|
4
4
|
import { Bubble, BubbleHoverTrigger } from "@gooddata/sdk-ui-kit";
|
|
5
5
|
import { DashboardParametersSection, } from "./CustomUrlEditorParametersSections/DashboardParametersSection.js";
|
|
6
6
|
import { IdentifierParametersSection } from "./CustomUrlEditorParametersSections/IdentifierParametersSection.js";
|
|
7
7
|
import { InsightParametersSection, } from "./CustomUrlEditorParametersSections/InsightParametersSection.js";
|
|
8
|
-
export function ParametersPanel({ attributeDisplayForms, loadingAttributeDisplayForms, enableClientIdParameter, enableDataProductIdParameter, enableWidgetIdParameter, onAdd, intl, dashboardFilters, attributeFilterConfigs, insightFilters, widgetRef, }) {
|
|
8
|
+
export function ParametersPanel({ attributeDisplayForms, loadingAttributeDisplayForms, enableClientIdParameter, enableDataProductIdParameter, enableWidgetIdParameter, onAdd, intl, dashboardFilters, dashboardMeasureValueFilters, insightMeasureValueFilters, attributeFilterConfigs, insightFilters, widgetRef, }) {
|
|
9
9
|
return (_jsxs("div", { children: [
|
|
10
10
|
_jsxs("label", { className: "gd-label", children: [
|
|
11
11
|
_jsx(FormattedMessage, { id: "configurationPanel.drillIntoUrl.editor.parametersPanelLabel" }), _jsxs(BubbleHoverTrigger, { className: "gd-list-item-tooltip", showDelay: 0, hideDelay: 0, children: [
|
|
12
12
|
_jsx("span", { className: "gd-icon-circle-question gd-list-item-tooltip-icon" }), _jsx(Bubble, { className: "bubble-primary", alignPoints: [{ align: "cr cl" }], children: _jsx(FormattedMessage, { id: "configurationPanel.drillIntoUrl.editor.parametersPanelTooltip" }) })
|
|
13
13
|
] })
|
|
14
14
|
] }), _jsxs("div", { className: "gd-drill-to-url-parameters gd-drill-to-url-list", children: [
|
|
15
|
-
_jsx(InsightParametersSection, { attributeDisplayForms: attributeDisplayForms, loadingAttributeDisplayForms: loadingAttributeDisplayForms, onAdd: onAdd, intl: intl, insightFilters: insightFilters }), _jsx(DashboardParametersSection, { intl: intl, onAdd: onAdd, dashboardFilters: dashboardFilters, attributeFilterConfigs: attributeFilterConfigs }), _jsx(IdentifierParametersSection, { enableClientIdParameter: enableClientIdParameter, enableDataProductIdParameter: enableDataProductIdParameter, enableWidgetIdParameter: enableWidgetIdParameter, onAdd: onAdd, intl: intl, widgetRef: widgetRef })
|
|
15
|
+
_jsx(InsightParametersSection, { attributeDisplayForms: attributeDisplayForms, loadingAttributeDisplayForms: loadingAttributeDisplayForms, onAdd: onAdd, intl: intl, insightFilters: insightFilters, insightMeasureValueFilters: insightMeasureValueFilters, widgetRef: widgetRef }), _jsx(DashboardParametersSection, { intl: intl, onAdd: onAdd, dashboardFilters: dashboardFilters, dashboardMeasureValueFilters: dashboardMeasureValueFilters, attributeFilterConfigs: attributeFilterConfigs }), _jsx(IdentifierParametersSection, { enableClientIdParameter: enableClientIdParameter, enableDataProductIdParameter: enableDataProductIdParameter, enableWidgetIdParameter: enableWidgetIdParameter, onAdd: onAdd, intl: intl, widgetRef: widgetRef })
|
|
16
16
|
] })
|
|
17
17
|
] }));
|
|
18
18
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { type IAttributeFilter, type IDashboardAttributeFilterConfig } from "@gooddata/sdk-model";
|
|
1
|
+
import { type IAttributeFilter, type IDashboardAttributeFilterConfig, type IDashboardMeasureValueFilter } from "@gooddata/sdk-model";
|
|
2
2
|
import { type IParametersPanelSectionsCommonProps } from "../types.js";
|
|
3
3
|
export interface IDashboardParametersSectionProps extends IParametersPanelSectionsCommonProps {
|
|
4
4
|
dashboardFilters?: IAttributeFilter[];
|
|
5
|
+
dashboardMeasureValueFilters?: IDashboardMeasureValueFilter[];
|
|
5
6
|
attributeFilterConfigs?: IDashboardAttributeFilterConfig[];
|
|
6
7
|
}
|
|
7
|
-
export declare function DashboardParametersSection({ dashboardFilters, attributeFilterConfigs, onAdd }: IDashboardParametersSectionProps): import("react/jsx-runtime").JSX.Element | null;
|
|
8
|
+
export declare function DashboardParametersSection({ dashboardFilters, dashboardMeasureValueFilters, attributeFilterConfigs, intl, onAdd }: IDashboardParametersSectionProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -2,14 +2,19 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
2
2
|
// (C) 2020-2026 GoodData Corporation
|
|
3
3
|
import { Fragment } from "react";
|
|
4
4
|
import { FormattedMessage } from "react-intl";
|
|
5
|
-
import { filterLocalIdentifier, filterObjRef, } from "@gooddata/sdk-model";
|
|
5
|
+
import { filterLocalIdentifier, filterObjRef, objRefToString, } from "@gooddata/sdk-model";
|
|
6
|
+
import { MeasureValueFilterDetailsBubble } from "@gooddata/sdk-ui-filters/internal";
|
|
6
7
|
import { useDashboardSelector } from "../../../../../model/react/DashboardStoreProvider.js";
|
|
7
|
-
import { selectAllCatalogDisplayFormsMap } from "../../../../../model/store/catalog/catalogSelectors.js";
|
|
8
|
+
import { selectAllCatalogDisplayFormsMap, selectAllCatalogMeasuresMap, } from "../../../../../model/store/catalog/catalogSelectors.js";
|
|
8
9
|
import { DropdownSectionHeader } from "../DropdownSectionHeader.js";
|
|
9
10
|
import { DisplayFormParam } from "./DisplayFormParam.js";
|
|
10
|
-
|
|
11
|
+
import { Parameter } from "./Parameter.js";
|
|
12
|
+
export function DashboardParametersSection({ dashboardFilters, dashboardMeasureValueFilters, attributeFilterConfigs, intl, onAdd, }) {
|
|
11
13
|
const catalogDisplayFormsMap = useDashboardSelector(selectAllCatalogDisplayFormsMap);
|
|
12
|
-
|
|
14
|
+
const catalogMeasuresMap = useDashboardSelector(selectAllCatalogMeasuresMap);
|
|
15
|
+
const hasAttributeFilters = !!dashboardFilters?.length;
|
|
16
|
+
const hasMeasureValueFilters = !!dashboardMeasureValueFilters?.length;
|
|
17
|
+
return hasAttributeFilters || hasMeasureValueFilters ? (_jsxs(_Fragment, { children: [
|
|
13
18
|
_jsx(DropdownSectionHeader, { children: _jsx(FormattedMessage, { id: "configurationPanel.drillIntoUrl.editor.dashboardParametersSectionLabel" }) }), dashboardFilters?.map((filter, index) => {
|
|
14
19
|
const df = catalogDisplayFormsMap.get(filterObjRef(filter));
|
|
15
20
|
const filterIdentifier = df?.id;
|
|
@@ -24,5 +29,13 @@ export function DashboardParametersSection({ dashboardFilters, attributeFilterCo
|
|
|
24
29
|
}, isFilter: true })) : null, secondaryDf && areDfsDifferent ? (_jsx(DisplayFormParam, { item: secondaryDf, iconClassName: "gd-icon-filter", onAdd: () => {
|
|
25
30
|
onAdd(`{dash_attribute_filter_selection(${filterSecondaryIdentifier})}`);
|
|
26
31
|
}, isFilter: true })) : null] }, index));
|
|
32
|
+
}), dashboardMeasureValueFilters?.map((filter) => {
|
|
33
|
+
const { measure, localIdentifier, title } = filter.dashboardMeasureValueFilter;
|
|
34
|
+
const catalogMeasure = catalogMeasuresMap.get(measure);
|
|
35
|
+
const measureIdentifier = catalogMeasure?.measure.id ?? objRefToString(measure);
|
|
36
|
+
const measureTitle = title ?? catalogMeasure?.measure.title ?? measureIdentifier;
|
|
37
|
+
return (_jsx(Parameter, { name: measureTitle, description: measureIdentifier, detailTrigger: _jsx(MeasureValueFilterDetailsBubble, { title: measureTitle, requestHandler: catalogMeasure ? async () => catalogMeasure.measure : undefined }), iconClassName: "gd-icon-filter", onAdd: () => {
|
|
38
|
+
onAdd(`{dash_mvf_condition(${measureIdentifier})}`);
|
|
39
|
+
}, intl: intl }, localIdentifier));
|
|
27
40
|
})] })) : null;
|
|
28
41
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { type IAttributeFilter } from "@gooddata/sdk-model";
|
|
1
|
+
import { type IAttributeFilter, type IMeasureValueFilter, type ObjRef } from "@gooddata/sdk-model";
|
|
2
2
|
import { type IAttributeWithDisplayForm, type IParametersPanelSectionsCommonProps } from "../types.js";
|
|
3
3
|
export interface IInsightParametersSectionProps extends IParametersPanelSectionsCommonProps {
|
|
4
4
|
attributeDisplayForms?: IAttributeWithDisplayForm[];
|
|
5
5
|
loadingAttributeDisplayForms: boolean;
|
|
6
6
|
insightFilters?: IAttributeFilter[];
|
|
7
|
+
insightMeasureValueFilters?: IMeasureValueFilter[];
|
|
8
|
+
widgetRef: ObjRef;
|
|
7
9
|
}
|
|
8
|
-
export declare function InsightParametersSection({ attributeDisplayForms, loadingAttributeDisplayForms, insightFilters, onAdd }: IInsightParametersSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export declare function InsightParametersSection({ attributeDisplayForms, loadingAttributeDisplayForms, insightFilters, insightMeasureValueFilters, widgetRef, intl, onAdd }: IInsightParametersSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,19 +1,52 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
// (C) 2020-2026 GoodData Corporation
|
|
3
3
|
import { FormattedMessage } from "react-intl";
|
|
4
|
-
import { filterObjRef } from "@gooddata/sdk-model";
|
|
4
|
+
import { areObjRefsEqual, filterObjRef, insightMeasures, isLocalIdRef, measureAlias, measureItem, measureLocalId, measureTitle, objRefToString, } from "@gooddata/sdk-model";
|
|
5
|
+
import { MeasureValueFilterDetailsBubble } from "@gooddata/sdk-ui-filters/internal";
|
|
5
6
|
import { useDashboardSelector } from "../../../../../model/react/DashboardStoreProvider.js";
|
|
6
|
-
import { selectAllCatalogDisplayFormsMap } from "../../../../../model/store/catalog/catalogSelectors.js";
|
|
7
|
+
import { selectAllCatalogDisplayFormsMap, selectAllCatalogMeasuresMap, } from "../../../../../model/store/catalog/catalogSelectors.js";
|
|
8
|
+
import { selectInsightByWidgetRef } from "../../../../../model/store/insights/insightsSelectors.js";
|
|
7
9
|
import { DropdownSectionHeader } from "../DropdownSectionHeader.js";
|
|
8
10
|
import { DisplayFormParam } from "./DisplayFormParam.js";
|
|
9
|
-
|
|
11
|
+
import { Parameter } from "./Parameter.js";
|
|
12
|
+
export function InsightParametersSection({ attributeDisplayForms, loadingAttributeDisplayForms, insightFilters, insightMeasureValueFilters, widgetRef, intl, onAdd, }) {
|
|
10
13
|
const catalogDisplayForms = useDashboardSelector(selectAllCatalogDisplayFormsMap);
|
|
14
|
+
const catalogMeasuresMap = useDashboardSelector(selectAllCatalogMeasuresMap);
|
|
15
|
+
const insight = useDashboardSelector(selectInsightByWidgetRef(widgetRef));
|
|
16
|
+
const measures = insight ? insightMeasures(insight) : [];
|
|
11
17
|
return (_jsx(_Fragment, { children: (attributeDisplayForms && attributeDisplayForms.length > 0) ||
|
|
12
18
|
loadingAttributeDisplayForms ||
|
|
13
|
-
(insightFilters && insightFilters.length > 0)
|
|
19
|
+
(insightFilters && insightFilters.length > 0) ||
|
|
20
|
+
(insightMeasureValueFilters && insightMeasureValueFilters.length > 0) ? (_jsxs(_Fragment, { children: [
|
|
14
21
|
_jsx(DropdownSectionHeader, { children: _jsx(FormattedMessage, { id: "configurationPanel.drillIntoUrl.editor.insightParametersSectionLabel" }) }), loadingAttributeDisplayForms ? (_jsx("div", { className: "gd-drill-to-url-section-loading s-drill-to-custom-url-attr-section-loading", children: _jsx("div", { className: "gd-spinner small" }) })) : (attributeDisplayForms?.map((item) => (_jsx(DisplayFormParam, { item: item.displayForm, onAdd: onAdd }, item.displayForm.id)))), insightFilters?.map((filter, index) => {
|
|
15
22
|
const displayFormRef = filterObjRef(filter);
|
|
16
23
|
const df = catalogDisplayForms.get(displayFormRef);
|
|
17
24
|
return (df && (_jsx(DisplayFormParam, { item: df, onAdd: () => onAdd(`{attribute_filter_selection(${df.id})}`), iconClassName: "gd-icon-filter", isFilter: true }, index)));
|
|
25
|
+
}), insightMeasureValueFilters?.map((filter) => {
|
|
26
|
+
const { measure, localIdentifier } = filter.measureValueFilter;
|
|
27
|
+
const insightMeasure = getInsightMeasure(measure, measures);
|
|
28
|
+
const insightMeasureItem = insightMeasure ? measureItem(insightMeasure) : undefined;
|
|
29
|
+
const catalogMeasure = isLocalIdRef(measure)
|
|
30
|
+
? insightMeasureItem && catalogMeasuresMap.get(insightMeasureItem)
|
|
31
|
+
: catalogMeasuresMap.get(measure);
|
|
32
|
+
const measureIdentifier = objRefToString(measure);
|
|
33
|
+
const resolvedTitle = getInsightMeasureTitle(insightMeasure) ??
|
|
34
|
+
catalogMeasure?.measure.title ??
|
|
35
|
+
measureIdentifier;
|
|
36
|
+
return (_jsx(Parameter, { name: resolvedTitle, description: measureIdentifier, detailTrigger: _jsx(MeasureValueFilterDetailsBubble, { title: resolvedTitle, requestHandler: catalogMeasure ? async () => catalogMeasure.measure : undefined }), iconClassName: "gd-icon-filter", onAdd: () => {
|
|
37
|
+
onAdd(`{mvf_condition(${measureIdentifier})}`);
|
|
38
|
+
}, intl: intl }, localIdentifier ?? measureIdentifier));
|
|
18
39
|
})] })) : null }));
|
|
19
40
|
}
|
|
41
|
+
function getInsightMeasureTitle(measure) {
|
|
42
|
+
return measure ? (measureAlias(measure) ?? measureTitle(measure)) : undefined;
|
|
43
|
+
}
|
|
44
|
+
function getInsightMeasure(measureRef, measures) {
|
|
45
|
+
if (isLocalIdRef(measureRef)) {
|
|
46
|
+
return measures.find((measure) => measureLocalId(measure) === measureRef.localIdentifier);
|
|
47
|
+
}
|
|
48
|
+
return measures.find((measure) => {
|
|
49
|
+
const item = measureItem(measure);
|
|
50
|
+
return item ? areObjRefsEqual(item, measureRef) : false;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { type ReactElement } from "react";
|
|
1
|
+
import { type ReactElement, type ReactNode } from "react";
|
|
2
2
|
import { type IntlShape } from "react-intl";
|
|
3
3
|
interface IParameterProps {
|
|
4
4
|
name: string;
|
|
5
5
|
description?: string;
|
|
6
|
-
detailContent
|
|
6
|
+
detailContent?: ReactElement;
|
|
7
|
+
detailTrigger?: ReactNode;
|
|
7
8
|
iconClassName: string;
|
|
8
9
|
onAdd: () => void;
|
|
9
10
|
intl: IntlShape;
|
|
10
11
|
}
|
|
11
|
-
export declare function Parameter({ name, description, detailContent, iconClassName, onAdd, intl }: IParameterProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export declare function Parameter({ name, description, detailContent, detailTrigger, iconClassName, onAdd, intl }: IParameterProps): import("react/jsx-runtime").JSX.Element;
|
|
12
13
|
export {};
|
|
@@ -5,7 +5,7 @@ import classNames from "classnames";
|
|
|
5
5
|
import { Bubble, Button } from "@gooddata/sdk-ui-kit";
|
|
6
6
|
import { isDarkTheme, useTheme } from "@gooddata/sdk-ui-theme-provider";
|
|
7
7
|
import { simplifyText } from "@gooddata/util";
|
|
8
|
-
export function Parameter({ name, description, detailContent, iconClassName, onAdd, intl }) {
|
|
8
|
+
export function Parameter({ name, description, detailContent, detailTrigger, iconClassName, onAdd, intl, }) {
|
|
9
9
|
const [displayHelp, setDisplayHelp] = useState(false);
|
|
10
10
|
const theme = useTheme();
|
|
11
11
|
const isDark = theme && isDarkTheme(theme);
|
|
@@ -16,7 +16,6 @@ export function Parameter({ name, description, detailContent, iconClassName, onA
|
|
|
16
16
|
id: "configurationPanel.drillIntoUrl.editor.addParameterButtonLabel",
|
|
17
17
|
});
|
|
18
18
|
return (_jsxs("div", { id: id, className: itemClassNames, onClick: () => onAdd(), children: [
|
|
19
|
-
_jsx("span", { className: "gd-parameter-title", children: name }), description ? _jsxs("span", { className: "addon s-parameter-description", children: ["(", description, ")"] }) : null, _jsx(Button, { className: "gd-button gd-button-link s-parameter-add-button", value: addButtonLabel }), _jsxs("div", { className: "gd-list-item-tooltip", children: [
|
|
20
|
-
_jsx("span", { className: "gd-icon-circle-question gd-list-item-tooltip-icon s-parameter-help-icon", onMouseEnter: () => setDisplayHelp(true), onMouseLeave: () => setDisplayHelp(false) }), displayHelp ? (_jsx(Bubble, { className: `themed-bubble ${isDark ? "bubble-primary" : "bubble-light"}`, alignTo: `#${id}`, alignPoints: [{ align: "cr tl" }], children: detailContent })) : null] })
|
|
21
|
-
] }));
|
|
19
|
+
_jsx("span", { className: "gd-parameter-title", children: name }), description ? _jsxs("span", { className: "addon s-parameter-description", children: ["(", description, ")"] }) : null, _jsx(Button, { className: "gd-button gd-button-link s-parameter-add-button", value: addButtonLabel }), detailTrigger ? (_jsx("div", { className: "gd-list-item-tooltip", onClick: (event) => event.stopPropagation(), children: detailTrigger })) : detailContent ? (_jsxs("div", { className: "gd-list-item-tooltip", children: [
|
|
20
|
+
_jsx("span", { className: "gd-icon-circle-question gd-list-item-tooltip-icon s-parameter-help-icon", onMouseEnter: () => setDisplayHelp(true), onMouseLeave: () => setDisplayHelp(false) }), displayHelp ? (_jsx(Bubble, { className: `themed-bubble ${isDark ? "bubble-primary" : "bubble-light"}`, alignTo: `#${id}`, alignPoints: [{ align: "cr tl" }], children: detailContent })) : null] })) : null] }));
|
|
22
21
|
}
|
|
@@ -12,7 +12,6 @@ import { getDrillOriginLocalIdentifier } from "../../../_staging/drills/drilling
|
|
|
12
12
|
import { useDashboardSelector } from "../../../model/react/DashboardStoreProvider.js";
|
|
13
13
|
import { selectAccessibleDashboards } from "../../../model/store/accessibleDashboards/accessibleDashboardsSelectors.js";
|
|
14
14
|
import { selectCatalogAttributeDisplayFormsById } from "../../../model/store/catalog/catalogSelectors.js";
|
|
15
|
-
import { selectEnableImplicitDrillToUrl } from "../../../model/store/config/configSelectors.js";
|
|
16
15
|
import { selectInsightsMap } from "../../../model/store/insights/insightsSelectors.js";
|
|
17
16
|
import { selectDashboardTitle } from "../../../model/store/meta/metaSelectors.js";
|
|
18
17
|
import { selectWidgetByRef } from "../../../model/store/tabs/layout/layoutSelectors.js";
|
|
@@ -32,7 +31,6 @@ export function DrillSelectDropdown({ isOpen, dropDownAnchorClass, onClose, onCl
|
|
|
32
31
|
const insights = useDashboardSelector(selectInsightsMap);
|
|
33
32
|
const widget = useDashboardSelector(selectWidgetByRef(drillEvent.widgetRef));
|
|
34
33
|
const attributeDisplayForms = useDashboardSelector(selectCatalogAttributeDisplayFormsById);
|
|
35
|
-
const enableImplicitDrillToUrl = useDashboardSelector(selectEnableImplicitDrillToUrl);
|
|
36
34
|
const stopPropagation = useCallback((e) => {
|
|
37
35
|
e.stopPropagation();
|
|
38
36
|
}, []);
|
|
@@ -93,7 +91,7 @@ export function DrillSelectDropdown({ isOpen, dropDownAnchorClass, onClose, onCl
|
|
|
93
91
|
if (isDrillDownDefinition(item.drillDefinition)) {
|
|
94
92
|
return "drillDown";
|
|
95
93
|
}
|
|
96
|
-
if (isDrillToUrl(item.drillDefinition)
|
|
94
|
+
if (isDrillToUrl(item.drillDefinition)) {
|
|
97
95
|
return "drillToUrl";
|
|
98
96
|
}
|
|
99
97
|
if (isCrossFiltering(item.drillDefinition)) {
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
// (C) 2025-2026 GoodData Corporation
|
|
2
2
|
import { useMemo } from "react";
|
|
3
3
|
import { defineMessages, useIntl } from "react-intl";
|
|
4
|
-
import { useDashboardSelector } from "../../../model/react/DashboardStoreProvider.js";
|
|
5
|
-
import { selectEnableImplicitDrillToUrl } from "../../../model/store/config/configSelectors.js";
|
|
6
4
|
import { DrillType } from "../DrillSelect/types.js";
|
|
7
5
|
const groupMenuItemMessages = defineMessages({
|
|
8
6
|
drillDown: { id: "drill_modal_picker.drill-down" },
|
|
@@ -13,7 +11,6 @@ const groupMenuItemMessages = defineMessages({
|
|
|
13
11
|
});
|
|
14
12
|
export const useDrillSelectDropdownMenuItems = ({ drillDownItems, drillItems, crossFilteringItems, keyDriverAnalysisItems, drillToUrlItems, onSelect, }) => {
|
|
15
13
|
const { formatMessage } = useIntl();
|
|
16
|
-
const enableImplicitDrillToUrl = useDashboardSelector(selectEnableImplicitDrillToUrl);
|
|
17
14
|
return useMemo(() => {
|
|
18
15
|
const createMenuGroup = (items, groupId, groupTitle) => ({
|
|
19
16
|
type: "group",
|
|
@@ -45,7 +42,7 @@ export const useDrillSelectDropdownMenuItems = ({ drillDownItems, drillItems, cr
|
|
|
45
42
|
const drillDownMenuItems = drillDownItems.length > 0
|
|
46
43
|
? [createMenuGroup(drillDownItems, "drill-down", groupMenuItemMessages.drillDown.id)]
|
|
47
44
|
: [];
|
|
48
|
-
const drillToUrlMenuItems =
|
|
45
|
+
const drillToUrlMenuItems = drillToUrlItems.length > 0
|
|
49
46
|
? [createMenuGroup(drillToUrlItems, "drill-to-url", groupMenuItemMessages.drillToUrl.id)]
|
|
50
47
|
: [];
|
|
51
48
|
const drillMenuItems = drillItems.length > 0
|
|
@@ -74,6 +71,5 @@ export const useDrillSelectDropdownMenuItems = ({ drillDownItems, drillItems, cr
|
|
|
74
71
|
drillToUrlItems,
|
|
75
72
|
formatMessage,
|
|
76
73
|
onSelect,
|
|
77
|
-
enableImplicitDrillToUrl,
|
|
78
74
|
]);
|
|
79
75
|
};
|
|
@@ -19,18 +19,21 @@ export function DefaultDashboardExportVariables({ renderMode }) {
|
|
|
19
19
|
const conf = useDashboardSelector(selectConfig);
|
|
20
20
|
const dashboardId = useDashboardSelector(selectDashboardId);
|
|
21
21
|
const dashboardDescriptor = useDashboardSelector(selectDashboardDescriptor);
|
|
22
|
-
const { dateFilters, attributeFilters, isError, isLoading } = useDashboardRelatedFilters(run);
|
|
22
|
+
const { dateFilters, attributeFilters, measureValueFilters, isError, isLoading } = useDashboardRelatedFilters(run);
|
|
23
23
|
const theme = useTheme();
|
|
24
24
|
if (!run) {
|
|
25
25
|
return null;
|
|
26
26
|
}
|
|
27
27
|
return (_jsxs("div", { className: "gd-dashboard-meta", ...exportData?.root, children: [
|
|
28
|
-
_jsx("div", { ...exportData?.id, children: dashboardId }), dashboardDescriptor.title ? _jsx("div", { ...exportData?.title, children: dashboardDescriptor.title }) : null, dashboardDescriptor.description ? (_jsx("div", { ...exportData?.description, children: dashboardDescriptor.description })) : null, dashboardDescriptor.tags && dashboardDescriptor.tags.length > 0 ? (_jsx("div", { ...exportData?.tags?.root, children: dashboardDescriptor.tags.map((tag, i) => (_jsx("span", { ...exportData?.tags?.tag, children: tag }, i))) })) : null, _jsx("div", { ...exportData?.filters?.root, ...exportData?.filters?.rootData(isLoading, isError), children: dateFilters.length > 0 || attributeFilters.length > 0 ? (_jsxs(_Fragment, { children: [dateFilters.map((filter, i) => (_jsxs("div", { ...exportData?.filters?.dateFilter, ...exportData?.filters?.filter.filterData(filter, isLoading, isError), children: [
|
|
28
|
+
_jsx("div", { ...exportData?.id, children: dashboardId }), dashboardDescriptor.title ? _jsx("div", { ...exportData?.title, children: dashboardDescriptor.title }) : null, dashboardDescriptor.description ? (_jsx("div", { ...exportData?.description, children: dashboardDescriptor.description })) : null, dashboardDescriptor.tags && dashboardDescriptor.tags.length > 0 ? (_jsx("div", { ...exportData?.tags?.root, children: dashboardDescriptor.tags.map((tag, i) => (_jsx("span", { ...exportData?.tags?.tag, children: tag }, i))) })) : null, _jsx("div", { ...exportData?.filters?.root, ...exportData?.filters?.rootData(isLoading, isError), children: dateFilters.length > 0 || attributeFilters.length > 0 || measureValueFilters.length > 0 ? (_jsxs(_Fragment, { children: [dateFilters.map((filter, i) => (_jsxs("div", { ...exportData?.filters?.dateFilter, ...exportData?.filters?.filter.filterData(filter, isLoading, isError), children: [
|
|
29
29
|
_jsx("span", { ...exportData?.filters?.filter.name, children: filter?.title }),
|
|
30
30
|
" -", " ", _jsx("span", { ...exportData?.filters?.filter.value, children: filter?.subtitle })
|
|
31
31
|
] }, i))), attributeFilters.map((filter, i) => (_jsxs("div", { ...exportData?.filters?.attributeFilter, ...exportData?.filters?.filter.filterData(filter, isLoading, isError), children: [
|
|
32
32
|
_jsx("span", { ...exportData?.filters?.filter.name, children: filter?.title }),
|
|
33
33
|
" -", " ", _jsx("span", { ...exportData?.filters?.filter.value, children: filter?.subtitle })
|
|
34
|
+
] }, i))), measureValueFilters.map((filter, i) => (_jsxs("div", { ...exportData?.filters?.measureValueFilter, ...exportData?.filters?.filter.filterData(filter, isLoading, isError), children: [
|
|
35
|
+
_jsx("span", { ...exportData?.filters?.filter.name, children: filter?.title }),
|
|
36
|
+
" -", " ", _jsx("span", { ...exportData?.filters?.filter.value, children: filter?.subtitle })
|
|
34
37
|
] }, i)))] })) : null }), user?.fullName ? _jsx("div", { ...exportData?.user, children: user.fullName }) : null, conf.workspaceDescriptor ? (_jsx("div", { ...exportData?.workspace, children: conf.workspaceDescriptor.title })) : null, _jsx(MetaImage, { image: theme?.images?.logo, type: "logo" }), _jsx(MetaImage, { image: theme?.images?.coverImage, type: "cover-image" }), _jsx(Palette, { data: theme?.palette?.complementary })
|
|
35
38
|
] }));
|
|
36
39
|
}
|
|
@@ -3,7 +3,7 @@ import { type DashboardAttributeFilterConfigMode, type DashboardDateFilterConfig
|
|
|
3
3
|
* @alpha
|
|
4
4
|
*/
|
|
5
5
|
export type DashboardRelatedFilter = {
|
|
6
|
-
type: "attributeFilter" | "dateFilter";
|
|
6
|
+
type: "attributeFilter" | "dateFilter" | "measureValueFilter";
|
|
7
7
|
all: boolean;
|
|
8
8
|
id: string;
|
|
9
9
|
title: string;
|
|
@@ -14,6 +14,7 @@ export type DashboardRelatedFilter = {
|
|
|
14
14
|
export declare function useDashboardRelatedFilters(run: boolean): {
|
|
15
15
|
dateFilters: DashboardRelatedFilter[];
|
|
16
16
|
attributeFilters: DashboardRelatedFilter[];
|
|
17
|
+
measureValueFilters: DashboardRelatedFilter[];
|
|
17
18
|
isLoading: boolean;
|
|
18
19
|
isError: boolean;
|
|
19
20
|
isSuccess: boolean;
|
|
@@ -7,6 +7,7 @@ import { selectAttributeFilterConfigsOverrides } from "../../../model/store/tabs
|
|
|
7
7
|
import { selectDateFilterConfigOverrides } from "../../../model/store/tabs/dateFilterConfig/dateFilterConfigSelectors.js";
|
|
8
8
|
import { selectDateFilterConfigsOverrides } from "../../../model/store/tabs/dateFilterConfigs/dateFilterConfigsSelectors.js";
|
|
9
9
|
import { selectFilterContextFilters } from "../../../model/store/tabs/filterContext/filterContextSelectors.js";
|
|
10
|
+
import { selectMeasureValueFilterConfigsOverrides } from "../../../model/store/tabs/measureValueFilterConfigs/measureValueFilterConfigsSelectors.js";
|
|
10
11
|
export function useDashboardRelatedFilters(run) {
|
|
11
12
|
const backend = useBackendStrict();
|
|
12
13
|
const workspaceId = useWorkspaceStrict();
|
|
@@ -14,6 +15,7 @@ export function useDashboardRelatedFilters(run) {
|
|
|
14
15
|
const dateFilterConfig = useDashboardSelector(selectDateFilterConfigOverrides);
|
|
15
16
|
const dateFiltersConfig = useDashboardSelector(selectDateFilterConfigsOverrides);
|
|
16
17
|
const attributeFiltersConfig = useDashboardSelector(selectAttributeFilterConfigsOverrides);
|
|
18
|
+
const measureValueFiltersConfig = useDashboardSelector(selectMeasureValueFilterConfigsOverrides);
|
|
17
19
|
const { result, status } = useCancelablePromise({
|
|
18
20
|
promise: async () => {
|
|
19
21
|
if (!run) {
|
|
@@ -36,6 +38,12 @@ export function useDashboardRelatedFilters(run) {
|
|
|
36
38
|
mode: dateFiltersConfig.find((c) => areObjRefsEqual(c.dateDataSet, f?.dataSet))?.config?.mode,
|
|
37
39
|
};
|
|
38
40
|
}
|
|
41
|
+
else if (f?.type === "measureValueFilter") {
|
|
42
|
+
return {
|
|
43
|
+
...f,
|
|
44
|
+
mode: measureValueFiltersConfig.find((c) => c.localIdentifier === f?.id)?.mode,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
39
47
|
return {
|
|
40
48
|
...f,
|
|
41
49
|
mode: attributeFiltersConfig.find((c) => c.localIdentifier === f?.id)?.mode,
|
|
@@ -47,6 +55,7 @@ export function useDashboardRelatedFilters(run) {
|
|
|
47
55
|
isSuccess: status === "success",
|
|
48
56
|
dateFilters: all.filter((f) => f?.type === "dateFilter"),
|
|
49
57
|
attributeFilters: all.filter((f) => f?.type === "attributeFilter"),
|
|
58
|
+
measureValueFilters: all.filter((f) => f?.type === "measureValueFilter"),
|
|
50
59
|
};
|
|
51
60
|
}
|
|
52
61
|
async function updateLabelElements(backend, workspaceId, attributeFiltersConfig, dashboardFilter) {
|
|
@@ -28,7 +28,7 @@ export type CommonExportDataAttributes = {
|
|
|
28
28
|
*/
|
|
29
29
|
export type MetaExportDataAttributes = {
|
|
30
30
|
"data-export-meta-type"?: ExportMetaType;
|
|
31
|
-
"data-export-meta-filter-type"?: "date" | "attribute";
|
|
31
|
+
"data-export-meta-filter-type"?: "date" | "attribute" | "measureValue";
|
|
32
32
|
"data-export-meta-filter-mode"?: "readonly" | "hidden" | "active";
|
|
33
33
|
"data-export-meta-filter-status"?: "loading" | "loaded" | "error";
|
|
34
34
|
"data-export-meta-filters-status"?: "loading" | "loaded" | "error";
|
|
@@ -57,6 +57,7 @@ export type MetaExportData = {
|
|
|
57
57
|
rootData: (isLoading: boolean, isError: boolean) => MetaExportDataAttributes;
|
|
58
58
|
dateFilter: MetaExportDataAttributes;
|
|
59
59
|
attributeFilter: MetaExportDataAttributes;
|
|
60
|
+
measureValueFilter: MetaExportDataAttributes;
|
|
60
61
|
filter: {
|
|
61
62
|
name: MetaExportDataAttributes;
|
|
62
63
|
value: MetaExportDataAttributes;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// (C) 2025 GoodData Corporation
|
|
1
|
+
// (C) 2025-2026 GoodData Corporation
|
|
2
2
|
export {};
|
|
@@ -201,6 +201,10 @@ export const useMetaExportData = () => {
|
|
|
201
201
|
"data-export-meta-type": "dashboard-filter",
|
|
202
202
|
"data-export-meta-filter-type": "attribute",
|
|
203
203
|
},
|
|
204
|
+
measureValueFilter: {
|
|
205
|
+
"data-export-meta-type": "dashboard-filter",
|
|
206
|
+
"data-export-meta-filter-type": "measureValue",
|
|
207
|
+
},
|
|
204
208
|
filter: {
|
|
205
209
|
name: {
|
|
206
210
|
"data-export-meta-type": "dashboard-filter-name",
|
|
@@ -145,6 +145,9 @@ function DefaultDashboardAttributeFilterInner(props) {
|
|
|
145
145
|
filterTitle: title,
|
|
146
146
|
strong: (chunks) => _jsx("strong", { children: chunks }),
|
|
147
147
|
});
|
|
148
|
+
const filterDependencyIconAriaLabel = intl.formatMessage({
|
|
149
|
+
id: "filter.dependency.icon.aria.label",
|
|
150
|
+
});
|
|
148
151
|
const CustomTooltipComponent = useMemo(() => {
|
|
149
152
|
// When text filter FFs are enabled, the attribute filter dropdown header
|
|
150
153
|
// has its own help icon (AttributeFilterDetailsBubble), so hide this one.
|
|
@@ -160,7 +163,7 @@ function DefaultDashboardAttributeFilterInner(props) {
|
|
|
160
163
|
return undefined;
|
|
161
164
|
}, [displayAttributeTooltip, defaultAttributeFilterTitle, attributeDataSet, isOpen, title]);
|
|
162
165
|
const shouldExtendTitle = !!capabilities.supportsKeepingDependentFiltersSelection && isAttributeFilterDependent;
|
|
163
|
-
const titleExtension = shouldExtendTitle ? (_jsx(AttributeFilterDependencyTooltip, { tooltipContent: filterDependencyIconTooltip })) : null;
|
|
166
|
+
const titleExtension = shouldExtendTitle ? (_jsx(AttributeFilterDependencyTooltip, { tooltipContent: filterDependencyIconTooltip, ariaLabel: filterDependencyIconAriaLabel })) : null;
|
|
164
167
|
return (_jsx(AttributeFilterDropdownButton, { ...props, isDraggable: isDraggable, TooltipContentComponent: CustomTooltipComponent, titleExtension: titleExtension, className: isVirtualAttributeFilter ? "gd-virtual-attribute-filter-dropdown-button" : undefined }));
|
|
165
168
|
}
|
|
166
169
|
return DropdownButton;
|
|
@@ -120,7 +120,10 @@ export function DefaultDashboardFilterGroup(props) {
|
|
|
120
120
|
filterTitle,
|
|
121
121
|
strong: (chunks) => _jsx("strong", { children: chunks }),
|
|
122
122
|
});
|
|
123
|
-
|
|
123
|
+
const filterDependencyIconAriaLabel = intl.formatMessage({
|
|
124
|
+
id: "filter.dependency.icon.aria.label",
|
|
125
|
+
});
|
|
126
|
+
return (_jsx(AttributeFilterDependencyTooltip, { tooltipContent: filterDependencyIconTooltip, ariaLabel: filterDependencyIconAriaLabel }));
|
|
124
127
|
}, [capabilities.supportsKeepingDependentFiltersSelection, filterDependenciesByLocalId, intl]);
|
|
125
128
|
return (_jsx(FilterGroup, { title: groupItem.groupConfig.title, filters: itemFilters, getFilterIdentifier: getFilterIdentifier, hasSelectedElements: hasSelectedElements, renderFilter: renderFilter, getTitleExtension: getTitleExtension }));
|
|
126
129
|
}
|