@gooddata/sdk-ui-dashboard 11.65.0-alpha.0 → 11.65.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/__version.d.ts +1 -1
- package/esm/__version.js +1 -1
- package/esm/model/queryServices/queryAttributeElements.js +1 -0
- package/esm/model/types/attributeFilterTypes.d.ts +5 -0
- package/esm/model/types/attributeFilterTypes.d.ts.map +1 -1
- package/esm/model/types/attributeFilterTypes.js +1 -1
- package/esm/presentation/automations/alerting/hooks/useAttributeValuesFromExecResults.d.ts +33 -2
- package/esm/presentation/automations/alerting/hooks/useAttributeValuesFromExecResults.d.ts.map +1 -1
- package/esm/presentation/automations/alerting/hooks/useAttributeValuesFromExecResults.js +29 -13
- package/esm/presentation/automations/alerting/state/useAlertSupportedMetrics.d.ts.map +1 -1
- package/esm/presentation/automations/alerting/state/useAlertSupportedMetrics.js +3 -2
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/Attachments/DashboardAttachments.d.ts.map +1 -1
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/Attachments/DashboardAttachments.js +3 -3
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/Attachments/WidgetAttachments.d.ts.map +1 -1
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/Attachments/WidgetAttachments.js +5 -4
- package/esm/presentation/dashboard/components/DashboardScreenSizeContext.d.ts.map +1 -1
- package/esm/presentation/dashboard/components/DashboardScreenSizeContext.js +10 -7
- package/esm/presentation/dashboard/components/ToastMessages.d.ts.map +1 -1
- package/esm/presentation/dashboard/components/ToastMessages.js +6 -3
- package/esm/presentation/dashboard/components/useEditModeLayoutNoteMessages.d.ts +6 -0
- package/esm/presentation/dashboard/components/useEditModeLayoutNoteMessages.d.ts.map +1 -0
- package/esm/presentation/dashboard/components/useEditModeLayoutNoteMessages.js +48 -0
- package/esm/presentation/drill/utils/drillDownUtils.d.ts.map +1 -1
- package/esm/presentation/drill/utils/drillDownUtils.js +3 -2
- package/esm/presentation/export/hooks/useDashboardRelatedFilters.d.ts +8 -1
- package/esm/presentation/export/hooks/useDashboardRelatedFilters.d.ts.map +1 -1
- package/esm/presentation/export/hooks/useDashboardRelatedFilters.js +21 -5
- package/esm/presentation/filterBar/attributeFilter/DefaultDashboardAttributeFilter.d.ts.map +1 -1
- package/esm/presentation/filterBar/attributeFilter/DefaultDashboardAttributeFilter.js +3 -2
- package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/attributeListItemTooltip/AttributeListItemTooltip.d.ts.map +1 -1
- package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/attributeListItemTooltip/AttributeListItemTooltip.js +4 -1
- package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/attributeListItemTooltip/AttributeListItemTooltipContent.d.ts +6 -2
- package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/attributeListItemTooltip/AttributeListItemTooltipContent.d.ts.map +1 -1
- package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/attributeListItemTooltip/AttributeListItemTooltipContent.js +8 -4
- package/esm/presentation/filterBar/filterBar/filterViews/FilterViewDeleteConfirm.d.ts +2 -1
- package/esm/presentation/filterBar/filterBar/filterViews/FilterViewDeleteConfirm.d.ts.map +1 -1
- package/esm/presentation/filterBar/filterBar/filterViews/FilterViewDeleteConfirm.js +2 -2
- package/esm/presentation/filterBar/filterBar/filterViews/FilterViewsList.d.ts.map +1 -1
- package/esm/presentation/filterBar/filterBar/filterViews/FilterViewsList.js +11 -5
- package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts +8 -0
- package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/en-US.localization-bundle.js +8 -0
- package/esm/presentation/topBar/buttonBar/button/editButton/DefaultEditButton.d.ts.map +1 -1
- package/esm/presentation/topBar/buttonBar/button/editButton/DefaultEditButton.js +2 -4
- package/esm/sdk-ui-dashboard.d.ts +5 -0
- package/package.json +21 -21
- package/styles/css/dashboard.css +9 -0
- package/styles/css/dashboard.css.map +1 -1
- package/styles/css/main.css +9 -0
- package/styles/css/main.css.map +1 -1
- package/styles/scss/dashboard.scss +11 -0
package/esm/__version.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const LIB_VERSION = "11.65.0-alpha.
|
|
1
|
+
export declare const LIB_VERSION = "11.65.0-alpha.1";
|
|
2
2
|
export declare const LIB_DESCRIPTION = "GoodData SDK - Dashboard Component";
|
|
3
3
|
export declare const LIB_NAME = "@gooddata/sdk-ui-dashboard";
|
|
4
4
|
//# sourceMappingURL=__version.d.ts.map
|
package/esm/__version.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// (C) 2021 GoodData Corporation
|
|
2
2
|
// DO NOT CHANGE THIS FILE, IT IS RE-GENERATED ON EVERY BUILD
|
|
3
|
-
export const LIB_VERSION = "11.65.0-alpha.
|
|
3
|
+
export const LIB_VERSION = "11.65.0-alpha.1";
|
|
4
4
|
export const LIB_DESCRIPTION = "GoodData SDK - Dashboard Component";
|
|
5
5
|
export const LIB_NAME = "@gooddata/sdk-ui-dashboard";
|
|
@@ -43,5 +43,10 @@ export interface IParentWithConnectingAttributes {
|
|
|
43
43
|
export interface IUseAttributeElements {
|
|
44
44
|
elements: IAttributeElement[];
|
|
45
45
|
totalCount: number;
|
|
46
|
+
/**
|
|
47
|
+
* Number format of the element values, see
|
|
48
|
+
* {@link @gooddata/sdk-backend-spi#IElementsQueryResult.numberFormat}; the element titles stay raw.
|
|
49
|
+
*/
|
|
50
|
+
numberFormat?: string;
|
|
46
51
|
}
|
|
47
52
|
//# sourceMappingURL=attributeFilterTypes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attributeFilterTypes.d.ts","sourceRoot":"","sources":["../../../src/model/types/attributeFilterTypes.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,KAAK,mCAAmC,EACxC,KAAK,iBAAiB,EACtB,KAAK,MAAM,EACd,MAAM,qBAAqB,CAAC;AAE7B;;GAEG;AACH,MAAM,WAAW,mCAAmC;IAChD,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,2BAA2B,EAAE,MAAM,GAAG,SAAS,CAAC;CACnD;AAED;;GAEG;AACH,MAAM,WAAW,qCAAqC;IAClD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,qBAAqB,EAAE,mCAAmC,EAAE,CAAC;CAChE;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,+BAA+B;IAC5C;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,oBAAoB,EAAE,oBAAoB,EAAE,CAAC;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IAClC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"attributeFilterTypes.d.ts","sourceRoot":"","sources":["../../../src/model/types/attributeFilterTypes.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,KAAK,mCAAmC,EACxC,KAAK,iBAAiB,EACtB,KAAK,MAAM,EACd,MAAM,qBAAqB,CAAC;AAE7B;;GAEG;AACH,MAAM,WAAW,mCAAmC;IAChD,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,2BAA2B,EAAE,MAAM,GAAG,SAAS,CAAC;CACnD;AAED;;GAEG;AACH,MAAM,WAAW,qCAAqC;IAClD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,qBAAqB,EAAE,mCAAmC,EAAE,CAAC;CAChE;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,+BAA+B;IAC5C;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,oBAAoB,EAAE,oBAAoB,EAAE,CAAC;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IAClC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// (C) 2022-
|
|
1
|
+
// (C) 2022-2026 GoodData Corporation
|
|
2
2
|
export {};
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import type { IExecutionResult } from "@gooddata/sdk-backend-spi";
|
|
2
|
-
import { type IAttribute, type IMeasure } from "@gooddata/sdk-model";
|
|
2
|
+
import { type IAttribute, type IMeasure, type ISeparators } from "@gooddata/sdk-model";
|
|
3
|
+
import { DataViewFacade, type IDataSeries } from "@gooddata/sdk-ui";
|
|
4
|
+
/**
|
|
5
|
+
* Formatting applied to attribute element values read from the execution result.
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export interface IAttributeValuesFormatting {
|
|
10
|
+
separators?: ISeparators;
|
|
11
|
+
}
|
|
3
12
|
type IExecutionResultEnvelope = {
|
|
4
13
|
isLoading?: boolean;
|
|
5
14
|
executionResult?: IExecutionResult;
|
|
@@ -29,10 +38,32 @@ export type AttributeValue = {
|
|
|
29
38
|
*
|
|
30
39
|
* @internal
|
|
31
40
|
*/
|
|
32
|
-
export declare function useAttributeValuesFromExecResults(execResult: IExecutionResultEnvelope | undefined): {
|
|
41
|
+
export declare function useAttributeValuesFromExecResults(execResult: IExecutionResultEnvelope | undefined, formatting?: IAttributeValuesFormatting): {
|
|
33
42
|
isResultLoading: boolean;
|
|
34
43
|
getAttributeValues: (attr: IAttribute) => AttributeValue[];
|
|
35
44
|
getMetricValue: (measure?: IMeasure, attr?: IAttribute, value?: string | null) => number | undefined;
|
|
36
45
|
};
|
|
46
|
+
/**
|
|
47
|
+
* Sums the measure values of the series scoped by the given raw attribute values.
|
|
48
|
+
*
|
|
49
|
+
* @remarks
|
|
50
|
+
* Matching works on raw element names: `scopeTitles()` return raw names, so the values passed in must be
|
|
51
|
+
* raw too, never the formatted titles shown in the UI.
|
|
52
|
+
*
|
|
53
|
+
* @internal exported for tests
|
|
54
|
+
*/
|
|
55
|
+
export declare function calculatePredictedValue(data: IDataSeries[], values?: string[] | null): number;
|
|
56
|
+
/**
|
|
57
|
+
* Raw names of the attribute elements to predict the value for: the element the filter value names, or
|
|
58
|
+
* every element when there is none.
|
|
59
|
+
*
|
|
60
|
+
* @remarks
|
|
61
|
+
* The filter value is a raw element value, so it is matched against the raw name and uri, not against the
|
|
62
|
+
* formatted title (dates, numeric computed attributes) shown in the UI; the raw names are returned to match
|
|
63
|
+
* the raw scope titles in {@link calculatePredictedValue}.
|
|
64
|
+
*
|
|
65
|
+
* @internal exported for tests
|
|
66
|
+
*/
|
|
67
|
+
export declare function calculateValues(dataView: DataViewFacade | null, indexes: [number, number], value?: string | null): string[];
|
|
37
68
|
export {};
|
|
38
69
|
//# sourceMappingURL=useAttributeValuesFromExecResults.d.ts.map
|
package/esm/presentation/automations/alerting/hooks/useAttributeValuesFromExecResults.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAttributeValuesFromExecResults.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/automations/alerting/hooks/useAttributeValuesFromExecResults.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EACH,KAAK,UAAU,EAEf,KAAK,QAAQ,
|
|
1
|
+
{"version":3,"file":"useAttributeValuesFromExecResults.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/automations/alerting/hooks/useAttributeValuesFromExecResults.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EACH,KAAK,UAAU,EAEf,KAAK,QAAQ,EACb,KAAK,WAAW,EAGnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACH,cAAc,EACd,KAAK,WAAW,EAGnB,MAAM,kBAAkB,CAAC;AAE1B;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IACvC,UAAU,CAAC,EAAE,WAAW,CAAC;CAC5B;AAED,KAAK,wBAAwB,GAAG;IAAE,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,eAAe,CAAC,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAE5F;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG;IACzB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,iCAAiC,CAC7C,UAAU,EAAE,wBAAwB,GAAG,SAAS,EAChD,UAAU,CAAC,EAAE,0BAA0B;;+BA6C5B,UAAU,KAAG,cAAc,EAAE;+BASzB,QAAQ,SAAS,UAAU,UAAU,MAAM,GAAG,IAAI;EAyBpE;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,UAkBpF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC3B,QAAQ,EAAE,cAAc,GAAG,IAAI,EAC/B,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EACzB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,MAAM,EAAE,CAIV"}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
// (C) 2019-2026 GoodData Corporation
|
|
2
2
|
import { useCallback, useEffect, useState } from "react";
|
|
3
3
|
import { areObjRefsEqual, isResultAttributeHeader, } from "@gooddata/sdk-model";
|
|
4
|
-
import { DataViewFacade } from "@gooddata/sdk-ui";
|
|
4
|
+
import { DataViewFacade, createNumberFormatter, formatAttributeHeaderValues, } from "@gooddata/sdk-ui";
|
|
5
5
|
/**
|
|
6
6
|
* Reads the widget's execution result and exposes the attribute values and measure values in it.
|
|
7
7
|
*
|
|
8
8
|
* @internal
|
|
9
9
|
*/
|
|
10
|
-
export function useAttributeValuesFromExecResults(execResult) {
|
|
10
|
+
export function useAttributeValuesFromExecResults(execResult, formatting) {
|
|
11
|
+
const separators = formatting?.separators;
|
|
11
12
|
// Derive loading from the envelope's own isLoading flag, not from the
|
|
12
13
|
// presence of executionResult: an errored execution has no executionResult
|
|
13
14
|
// but is no longer loading, and there is no readAll() promise to clear the
|
|
@@ -23,7 +24,7 @@ export function useAttributeValuesFromExecResults(execResult) {
|
|
|
23
24
|
.readAll()
|
|
24
25
|
.then((data) => {
|
|
25
26
|
if (!cancelled) {
|
|
26
|
-
setDataView(DataViewFacade.for(data));
|
|
27
|
+
setDataView(DataViewFacade.for(formatAttributeHeaderValues(data, createNumberFormatter(separators))));
|
|
27
28
|
setIsResultLoading(false);
|
|
28
29
|
}
|
|
29
30
|
})
|
|
@@ -43,7 +44,7 @@ export function useAttributeValuesFromExecResults(execResult) {
|
|
|
43
44
|
return () => {
|
|
44
45
|
cancelled = true;
|
|
45
46
|
};
|
|
46
|
-
}, [execResult]);
|
|
47
|
+
}, [execResult, separators]);
|
|
47
48
|
const getAttributeValues = useCallback((attr) => {
|
|
48
49
|
const header = findAttributeHeader(dataView, attr);
|
|
49
50
|
const indexes = findDimIndexes(dataView, header);
|
|
@@ -69,7 +70,16 @@ export function useAttributeValuesFromExecResults(execResult) {
|
|
|
69
70
|
getMetricValue,
|
|
70
71
|
};
|
|
71
72
|
}
|
|
72
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Sums the measure values of the series scoped by the given raw attribute values.
|
|
75
|
+
*
|
|
76
|
+
* @remarks
|
|
77
|
+
* Matching works on raw element names: `scopeTitles()` return raw names, so the values passed in must be
|
|
78
|
+
* raw too, never the formatted titles shown in the UI.
|
|
79
|
+
*
|
|
80
|
+
* @internal exported for tests
|
|
81
|
+
*/
|
|
82
|
+
export function calculatePredictedValue(data, values) {
|
|
73
83
|
return data.reduce((total, series) => {
|
|
74
84
|
return (total +
|
|
75
85
|
Array.from(series).reduce((acc, item) => {
|
|
@@ -84,15 +94,21 @@ function calculatePredictedValue(data, values) {
|
|
|
84
94
|
}, 0));
|
|
85
95
|
}, 0);
|
|
86
96
|
}
|
|
87
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Raw names of the attribute elements to predict the value for: the element the filter value names, or
|
|
99
|
+
* every element when there is none.
|
|
100
|
+
*
|
|
101
|
+
* @remarks
|
|
102
|
+
* The filter value is a raw element value, so it is matched against the raw name and uri, not against the
|
|
103
|
+
* formatted title (dates, numeric computed attributes) shown in the UI; the raw names are returned to match
|
|
104
|
+
* the raw scope titles in {@link calculatePredictedValue}.
|
|
105
|
+
*
|
|
106
|
+
* @internal exported for tests
|
|
107
|
+
*/
|
|
108
|
+
export function calculateValues(dataView, indexes, value) {
|
|
88
109
|
return findAttributeValues(dataView, indexes)
|
|
89
|
-
.
|
|
90
|
-
.
|
|
91
|
-
if (value) {
|
|
92
|
-
return v === value;
|
|
93
|
-
}
|
|
94
|
-
return true;
|
|
95
|
-
});
|
|
110
|
+
.filter((v) => !value || v.name === value || v.value === value)
|
|
111
|
+
.map((v) => v.name);
|
|
96
112
|
}
|
|
97
113
|
// By display form, not catalog attribute: two display forms of one attribute are two descriptors.
|
|
98
114
|
function findAttributeHeader(dataView, attr) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAlertSupportedMetrics.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/automations/alerting/state/useAlertSupportedMetrics.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,yBAAyB,EAAE,KAAK,QAAQ,EAAE,KAAK,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAYlG,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEzD,MAAM,WAAW,8BAA8B;IAC3C,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,yBAAyB,CAAC;CAC3C;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,EACrC,OAAO,EACP,MAAM,EACN,WAAW,GACd,EAAE,8BAA8B,GAAG,sBAAsB,
|
|
1
|
+
{"version":3,"file":"useAlertSupportedMetrics.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/automations/alerting/state/useAlertSupportedMetrics.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,yBAAyB,EAAE,KAAK,QAAQ,EAAE,KAAK,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAYlG,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEzD,MAAM,WAAW,8BAA8B;IAC3C,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,yBAAyB,CAAC;CAC3C;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,EACrC,OAAO,EACP,MAAM,EACN,WAAW,GACd,EAAE,8BAA8B,GAAG,sBAAsB,CAiDzD"}
|
|
@@ -17,7 +17,7 @@ import { getSupportedInsightAttributesByInsight, getSupportedInsightMeasuresByIn
|
|
|
17
17
|
* @internal
|
|
18
18
|
*/
|
|
19
19
|
export function useAlertSupportedMetrics({ insight, widget, alertToEdit, }) {
|
|
20
|
-
const { locale, catalogDateDatasets, catalogAttributes } = useAutomationsContext();
|
|
20
|
+
const { locale, separators, catalogDateDatasets, catalogAttributes } = useAutomationsContext();
|
|
21
21
|
const { executionResultByRef } = useAlertingDialogContext();
|
|
22
22
|
const execResult = executionResultByRef(widget?.ref);
|
|
23
23
|
const [effectiveInsight, setEffectiveInsight] = useState(insight);
|
|
@@ -31,7 +31,8 @@ export function useAlertSupportedMetrics({ insight, widget, alertToEdit, }) {
|
|
|
31
31
|
}, [execResult?.executionResult]);
|
|
32
32
|
const supportedMeasures = useMemo(() => getSupportedInsightMeasuresByInsight(effectiveInsight, catalogDateDatasets, alertToEdit), [effectiveInsight, catalogDateDatasets, alertToEdit]);
|
|
33
33
|
const supportedAttributes = useMemo(() => getSupportedInsightAttributesByInsight(insight, catalogAttributes, catalogDateDatasets, alertToEdit), [insight, catalogDateDatasets, catalogAttributes, alertToEdit]);
|
|
34
|
-
|
|
34
|
+
// element values of numeric computed attributes are offered formatted, as the widget shows them
|
|
35
|
+
const { isResultLoading, getAttributeValues, getMetricValue } = useAttributeValuesFromExecResults(execResult, { separators });
|
|
35
36
|
return {
|
|
36
37
|
measureFormatMap,
|
|
37
38
|
supportedMeasures,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DashboardAttachments.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/Attachments/DashboardAttachments.tsx"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,8CAA8C,EAAE,MAAM,mBAAmB,CAAC;AAUxF,wBAAgB,oBAAoB,CAAC,EACjC,gBAAgB,EAChB,gBAAgB,EAChB,4BAA4B,EAC5B,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,EACpB,qBAAqB,EACrB,eAAe,EACf,iBAAiB,EACjB,wBAAwB,GAC3B,EAAE,8CAA8C,
|
|
1
|
+
{"version":3,"file":"DashboardAttachments.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/Attachments/DashboardAttachments.tsx"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,8CAA8C,EAAE,MAAM,mBAAmB,CAAC;AAUxF,wBAAgB,oBAAoB,CAAC,EACjC,gBAAgB,EAChB,gBAAgB,EAChB,4BAA4B,EAC5B,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,EACpB,qBAAqB,EACrB,eAAe,EACf,iBAAiB,EACjB,wBAAwB,GAC3B,EAAE,8CAA8C,2CAqIhD"}
|
|
@@ -44,8 +44,8 @@ export function DashboardAttachments({ dashboardFilters, isCrossFiltering, onDas
|
|
|
44
44
|
setTimeout(() => {
|
|
45
45
|
setAnnouncement(intl.formatMessage({ id: "dialogs.schedule.management.attachments.removed" }, { format: attachment }));
|
|
46
46
|
});
|
|
47
|
-
//
|
|
48
|
-
if (
|
|
47
|
+
// Hidden formats are preserved, but only visible chips can receive focus.
|
|
48
|
+
if (visibleSelectedAttachments.some((att) => att !== attachment)) {
|
|
49
49
|
focusAttachmentGroup();
|
|
50
50
|
}
|
|
51
51
|
else {
|
|
@@ -74,7 +74,7 @@ export function DashboardAttachments({ dashboardFilters, isCrossFiltering, onDas
|
|
|
74
74
|
selected: selectedAttachments.includes(format),
|
|
75
75
|
})), onChange: handleChange, mode: "dashboard", onAddButtonRef: (ref) => {
|
|
76
76
|
addButtonRef.current = ref;
|
|
77
|
-
} }), isCrossFiltering && selectedAttachments.length > 0 ? (_jsx(Message, { type: "progress", className: "gd-attachment-list-message", children: _jsx(FormattedMessage, { id: "dialogs.schedule.management.attachments.message", values: {
|
|
77
|
+
} }), visibleSelectedAttachments.length === 0 && selectedAttachments.length > 0 ? (_jsx(Message, { type: "progress", className: "gd-attachment-list-message", accessibilityConfig: { role: "status" }, children: _jsx(FormattedMessage, { id: "scheduledEmail.attachments.noVisibleAttachments" }) })) : null, isCrossFiltering && selectedAttachments.length > 0 ? (_jsx(Message, { type: "progress", className: "gd-attachment-list-message", children: _jsx(FormattedMessage, { id: "dialogs.schedule.management.attachments.message", values: {
|
|
78
78
|
strong: (chunks) => _jsx("strong", { children: chunks }),
|
|
79
79
|
} }) })) : null] }) }, selectedAttachments.join()), _jsx("div", { className: "sr-only", "aria-live": "polite", "aria-atomic": "true", role: "status", children: announcement })] }));
|
|
80
80
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WidgetAttachments.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/Attachments/WidgetAttachments.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"WidgetAttachments.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/Attachments/WidgetAttachments.tsx"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,2CAA2C,EAAE,MAAM,mBAAmB,CAAC;AAmBrF,wBAAgB,iBAAiB,CAAC,EAC9B,mBAAmB,EACnB,yBAAyB,EACzB,YAAY,EACZ,oBAAoB,EACpB,WAAW,EACX,mBAAmB,EACnB,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,sBAAsB,EACtB,qBAAqB,EACrB,0BAA0B,EAC1B,eAAe,EACf,iBAAiB,EACjB,wBAAwB,GAC3B,EAAE,2CAA2C,2CAqI7C"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
// (C) 2019-2026 GoodData Corporation
|
|
3
3
|
import { useCallback, useRef, useState } from "react";
|
|
4
|
-
import { useIntl } from "react-intl";
|
|
4
|
+
import { FormattedMessage, useIntl } from "react-intl";
|
|
5
|
+
import { Message } from "@gooddata/sdk-ui-kit";
|
|
5
6
|
import { AUTOMATION_ATTACHMENTS_GROUP_LABEL_ID } from "../../../../../constants/automations.js";
|
|
6
7
|
import { partitionAttachments } from "./attachmentFormats.js";
|
|
7
8
|
import { AttachmentsList } from "./AttachmentsList.js";
|
|
@@ -55,8 +56,8 @@ export function WidgetAttachments({ selectedAttachments, onWidgetAttachmentsChan
|
|
|
55
56
|
setTimeout(() => {
|
|
56
57
|
setAnnouncement(intl.formatMessage({ id: "dialogs.schedule.management.attachments.removed" }, { format: attachment }));
|
|
57
58
|
});
|
|
58
|
-
//
|
|
59
|
-
if (
|
|
59
|
+
// Hidden formats are preserved, but only visible chips can receive focus.
|
|
60
|
+
if (visibleSelectedAttachments.some((att) => att !== attachment)) {
|
|
60
61
|
focusAttachmentGroup();
|
|
61
62
|
}
|
|
62
63
|
else {
|
|
@@ -86,5 +87,5 @@ export function WidgetAttachments({ selectedAttachments, onWidgetAttachmentsChan
|
|
|
86
87
|
selected: selectedAttachments.includes(format),
|
|
87
88
|
})), onChange: handleChange, mode: "widget", onAddButtonRef: (ref) => {
|
|
88
89
|
addButtonRef.current = ref;
|
|
89
|
-
} })] }) }, selectedAttachments.join()), _jsx("div", { className: "sr-only", "aria-live": "polite", "aria-atomic": "true", role: "status", children: announcement })] }));
|
|
90
|
+
} }), visibleSelectedAttachments.length === 0 && selectedAttachments.length > 0 ? (_jsx(Message, { type: "progress", className: "gd-attachment-list-message", accessibilityConfig: { role: "status" }, children: _jsx(FormattedMessage, { id: "scheduledEmail.attachments.noVisibleAttachments" }) })) : null] }) }, selectedAttachments.join()), _jsx("div", { className: "sr-only", "aria-live": "polite", "aria-atomic": "true", role: "status", children: announcement })] }));
|
|
90
91
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DashboardScreenSizeContext.d.ts","sourceRoot":"","sources":["../../../../src/presentation/dashboard/components/DashboardScreenSizeContext.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEH,KAAK,SAAS,EAMjB,MAAM,OAAO,CAAC;AAIf,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"DashboardScreenSizeContext.d.ts","sourceRoot":"","sources":["../../../../src/presentation/dashboard/components/DashboardScreenSizeContext.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEH,KAAK,SAAS,EAMjB,MAAM,OAAO,CAAC;AAIf,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAiDtD,MAAM,WAAW,0BAA0B;IACvC,QAAQ,EAAE,SAAS,CAAC;CACvB;AAKD,wBAAgB,2BAA2B,CAAC,EAAE,QAAQ,EAAE,EAAE,0BAA0B,2CA4BnF;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,QAAO,UAGhC,CAAC"}
|
|
@@ -3,9 +3,10 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { createContext, useContext, useEffect, useState, } from "react";
|
|
4
4
|
import { setScreenSize as setScreenSizeAction } from "../../../model/commands/layout.js";
|
|
5
5
|
import { useDashboardDispatch, useDashboardSelector } from "../../../model/react/DashboardStoreProvider.js";
|
|
6
|
+
import { selectIsInEditMode } from "../../../model/store/renderMode/renderModeSelectors.js";
|
|
6
7
|
import { selectScreen } from "../../../model/store/tabs/layout/layoutSelectors.js";
|
|
7
8
|
import { DASHBOARD_LAYOUT_BREAK_POINTS } from "../../constants/layout.js";
|
|
8
|
-
const getCurrentScreenSize = () => {
|
|
9
|
+
const getCurrentScreenSize = (isEditMode) => {
|
|
9
10
|
let viewportWidth = 0;
|
|
10
11
|
if (window?.innerWidth) {
|
|
11
12
|
viewportWidth = window.innerWidth;
|
|
@@ -16,7 +17,8 @@ const getCurrentScreenSize = () => {
|
|
|
16
17
|
if (viewportWidth >= DASHBOARD_LAYOUT_BREAK_POINTS[3]) {
|
|
17
18
|
return "xl";
|
|
18
19
|
}
|
|
19
|
-
|
|
20
|
+
// Only xl sizes are saved, so edit mode keeps the desktop grid instead of reflowing it.
|
|
21
|
+
if (isEditMode || viewportWidth >= DASHBOARD_LAYOUT_BREAK_POINTS[2]) {
|
|
20
22
|
return "lg";
|
|
21
23
|
}
|
|
22
24
|
if (viewportWidth >= DASHBOARD_LAYOUT_BREAK_POINTS[1]) {
|
|
@@ -27,8 +29,8 @@ const getCurrentScreenSize = () => {
|
|
|
27
29
|
}
|
|
28
30
|
return "xs";
|
|
29
31
|
};
|
|
30
|
-
function setNewSize(prevSize, setScreenSize, dispatch) {
|
|
31
|
-
const newSize = getCurrentScreenSize();
|
|
32
|
+
function setNewSize(prevSize, isEditMode, setScreenSize, dispatch) {
|
|
33
|
+
const newSize = getCurrentScreenSize(isEditMode);
|
|
32
34
|
if (newSize && newSize !== prevSize) {
|
|
33
35
|
// prevent unnecessary re-renders
|
|
34
36
|
setScreenSize(newSize);
|
|
@@ -41,18 +43,19 @@ export function DashboardScreenSizeProvider({ children }) {
|
|
|
41
43
|
const [screenSize, setScreenSize] = useState();
|
|
42
44
|
const dispatch = useDashboardDispatch();
|
|
43
45
|
const appStateScreenSize = useDashboardSelector(selectScreen);
|
|
46
|
+
const isEditMode = useDashboardSelector(selectIsInEditMode);
|
|
44
47
|
useEffect(() => {
|
|
45
48
|
// set initial screen size to app state for usage in sagas
|
|
46
|
-
setNewSize(screenSize, setScreenSize, dispatch);
|
|
49
|
+
setNewSize(screenSize, isEditMode, setScreenSize, dispatch);
|
|
47
50
|
// register event listener for window resize
|
|
48
51
|
const handleWindowResized = () => {
|
|
49
|
-
setNewSize(screenSize, setScreenSize, dispatch);
|
|
52
|
+
setNewSize(screenSize, isEditMode, setScreenSize, dispatch);
|
|
50
53
|
};
|
|
51
54
|
window.addEventListener("resize", handleWindowResized, false);
|
|
52
55
|
return () => {
|
|
53
56
|
window.removeEventListener("resize", handleWindowResized, false);
|
|
54
57
|
};
|
|
55
|
-
}, [screenSize, dispatch]);
|
|
58
|
+
}, [screenSize, isEditMode, dispatch]);
|
|
56
59
|
return (_jsx("div", { className: "s-screen-size-container", children: _jsx(DashboardScreenSizeContext.Provider, { value: screenSize, children: appStateScreenSize ? children : null }) }));
|
|
57
60
|
}
|
|
58
61
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToastMessages.d.ts","sourceRoot":"","sources":["../../../../src/presentation/dashboard/components/ToastMessages.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ToastMessages.d.ts","sourceRoot":"","sources":["../../../../src/presentation/dashboard/components/ToastMessages.tsx"],"names":[],"mappings":"AAaA;;GAEG;AACH,wBAAgB,aAAa,4CA2B5B"}
|
|
@@ -5,6 +5,7 @@ import { NonContextToastsInterop } from "@gooddata/sdk-ui-kit";
|
|
|
5
5
|
import { useParameterToastMessages } from "../../filterBar/parameterFilter/useParameterToastMessages.js";
|
|
6
6
|
import { useCrossFilteringMessages } from "./useCrossFilteringMessages.js";
|
|
7
7
|
import { useDrillValidationMessages } from "./useDrillValidationMessages.js";
|
|
8
|
+
import { useEditModeLayoutNoteMessages } from "./useEditModeLayoutNoteMessages.js";
|
|
8
9
|
import { useFilterContextValidationMessages } from "./useFilterContextValidationMessages.js";
|
|
9
10
|
/**
|
|
10
11
|
* @internal
|
|
@@ -12,14 +13,16 @@ import { useFilterContextValidationMessages } from "./useFilterContextValidation
|
|
|
12
13
|
export function ToastMessages() {
|
|
13
14
|
const { messages: drillValidationMessages, removeMessage: removeDrillValidationMessage } = useDrillValidationMessages();
|
|
14
15
|
const { messages: filterContextValidationMessages, removeMessage: removeFilterContextValidationMessage } = useFilterContextValidationMessages();
|
|
16
|
+
const { messages: editModeLayoutNoteMessages, removeMessage: removeEditModeLayoutNoteMessage } = useEditModeLayoutNoteMessages();
|
|
15
17
|
useCrossFilteringMessages();
|
|
16
18
|
useParameterToastMessages();
|
|
17
|
-
const messages = useMemo(() => [...drillValidationMessages, ...filterContextValidationMessages], [drillValidationMessages, filterContextValidationMessages]);
|
|
19
|
+
const messages = useMemo(() => [...drillValidationMessages, ...filterContextValidationMessages, ...editModeLayoutNoteMessages], [drillValidationMessages, filterContextValidationMessages, editModeLayoutNoteMessages]);
|
|
18
20
|
const removeMessage = useCallback(
|
|
19
|
-
// try removing the id from
|
|
21
|
+
// try removing the id from all collections
|
|
20
22
|
(id) => {
|
|
21
23
|
removeDrillValidationMessage(id);
|
|
22
24
|
removeFilterContextValidationMessage(id);
|
|
23
|
-
|
|
25
|
+
removeEditModeLayoutNoteMessage(id);
|
|
26
|
+
}, [removeDrillValidationMessage, removeFilterContextValidationMessage, removeEditModeLayoutNoteMessage]);
|
|
24
27
|
return _jsx(NonContextToastsInterop, { messages: messages, onDismissMessage: removeMessage });
|
|
25
28
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useEditModeLayoutNoteMessages.d.ts","sourceRoot":"","sources":["../../../../src/presentation/dashboard/components/useEditModeLayoutNoteMessages.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,QAAQ,EAAiB,MAAM,sBAAsB,CAAC;AAkBpE,wBAAgB,6BAA6B;;wBA0BhC,MAAM;EAalB"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// (C) 2026 GoodData Corporation
|
|
3
|
+
import { useCallback, useMemo, useState } from "react";
|
|
4
|
+
import { defineMessages, useIntl } from "react-intl";
|
|
5
|
+
import { useMediaQuery } from "@gooddata/sdk-ui-kit";
|
|
6
|
+
import { useDashboardSelector } from "../../../model/react/DashboardStoreProvider.js";
|
|
7
|
+
import { selectIsInEditMode } from "../../../model/store/renderMode/renderModeSelectors.js";
|
|
8
|
+
const localizationMessages = defineMessages({
|
|
9
|
+
editModeLayoutNote: { id: "messages.dashboard.editModeDesktopLayout.note" },
|
|
10
|
+
});
|
|
11
|
+
const replacements = {
|
|
12
|
+
b: (chunks) => _jsx("b", { children: chunks }),
|
|
13
|
+
};
|
|
14
|
+
const EDIT_MODE_LAYOUT_NOTE_MESSAGE_ID = "edit_mode_desktop_layout_note";
|
|
15
|
+
// Dismissal lasts until the page reloads and is deliberately never persisted.
|
|
16
|
+
let isDismissedInSession = false;
|
|
17
|
+
export function useEditModeLayoutNoteMessages() {
|
|
18
|
+
const intl = useIntl();
|
|
19
|
+
const isEditMode = useDashboardSelector(selectIsInEditMode);
|
|
20
|
+
const isNarrowerThanEditModeMinWidth = useMediaQuery("<=lg");
|
|
21
|
+
const [isDismissed, setIsDismissed] = useState(isDismissedInSession);
|
|
22
|
+
const isVisible = isEditMode && isNarrowerThanEditModeMinWidth && !isDismissed;
|
|
23
|
+
const messages = useMemo(() => {
|
|
24
|
+
if (!isVisible) {
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
return [
|
|
28
|
+
{
|
|
29
|
+
id: EDIT_MODE_LAYOUT_NOTE_MESSAGE_ID,
|
|
30
|
+
type: "progress",
|
|
31
|
+
node: intl.formatMessage(localizationMessages.editModeLayoutNote, replacements),
|
|
32
|
+
createdAt: new Date().getTime(),
|
|
33
|
+
duration: Infinity,
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
}, [isVisible, intl]);
|
|
37
|
+
// The toasts interop also reports removals caused by the note no longer applying; only a visible note can be dismissed.
|
|
38
|
+
const removeMessage = useCallback((id) => {
|
|
39
|
+
if (id === EDIT_MODE_LAYOUT_NOTE_MESSAGE_ID && isVisible) {
|
|
40
|
+
isDismissedInSession = true;
|
|
41
|
+
setIsDismissed(true);
|
|
42
|
+
}
|
|
43
|
+
}, [isVisible]);
|
|
44
|
+
return {
|
|
45
|
+
messages,
|
|
46
|
+
removeMessage,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drillDownUtils.d.ts","sourceRoot":"","sources":["../../../../src/presentation/drill/utils/drillDownUtils.ts"],"names":[],"mappings":"AAIA,OAAO,EACH,KAAK,mCAAmC,EACxC,KAAK,uCAAuC,EAG/C,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,KAAK,WAAW,EAAoC,MAAM,kBAAkB,CAAC;AAOtF,OAAO,EAAE,KAAK,wBAAwB,EAAE,KAAK,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAG7F;;GAEG;AACH,wBAAgB,iBAAiB,CAC7B,eAAe,EAAE,oBAAoB,EACrC,UAAU,EAAE,WAAW,EACvB,sCAAsC,CAAC,EAAE,uCAAuC,EAAE,EAClF,sBAAsB,CAAC,EAAE,mCAAmC,GAC7D,MAAM,GAAG,IAAI,CAoBf;AAED;;GAEG;AACH,wBAAgB,mCAAmC,CAC/C,kBAAkB,EAAE,MAAM,EAC1B,UAAU,EAAE,WAAW,GACxB,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"drillDownUtils.d.ts","sourceRoot":"","sources":["../../../../src/presentation/drill/utils/drillDownUtils.ts"],"names":[],"mappings":"AAIA,OAAO,EACH,KAAK,mCAAmC,EACxC,KAAK,uCAAuC,EAG/C,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,KAAK,WAAW,EAAoC,MAAM,kBAAkB,CAAC;AAOtF,OAAO,EAAE,KAAK,wBAAwB,EAAE,KAAK,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAG7F;;GAEG;AACH,wBAAgB,iBAAiB,CAC7B,eAAe,EAAE,oBAAoB,EACrC,UAAU,EAAE,WAAW,EACvB,sCAAsC,CAAC,EAAE,uCAAuC,EAAE,EAClF,sBAAsB,CAAC,EAAE,mCAAmC,GAC7D,MAAM,GAAG,IAAI,CAoBf;AAED;;GAEG;AACH,wBAAgB,mCAAmC,CAC/C,kBAAkB,EAAE,MAAM,EAC1B,UAAU,EAAE,WAAW,GACxB,MAAM,GAAG,IAAI,CAaf;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,eAAe,EAAE,wBAAwB,EAAE,GAAG,MAAM,CAE3F;AAED;;;;;GAKG;AACH,wBAAgB,kCAAkC,CAC9C,gBAAgB,EAAE,wBAAwB,EAAE,EAC5C,gBAAgB,GAAE,wBAAwB,EAAO,GAClD,wBAAwB,EAAE,CA0B5B"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// (C) 2020-
|
|
1
|
+
// (C) 2020-2026 GoodData Corporation
|
|
2
2
|
import { compact, isEqual, uniqWith } from "lodash-es";
|
|
3
3
|
import { isCrossFiltering, isDrillToLegacyDashboard, } from "@gooddata/sdk-model";
|
|
4
4
|
import { isDrillIntersectionAttributeItem } from "@gooddata/sdk-ui";
|
|
@@ -28,7 +28,8 @@ export function getDrillOriginAttributeElementTitle(drillOriginLocalId, drillEve
|
|
|
28
28
|
.map((intersectionElement) => intersectionElement.header)
|
|
29
29
|
.filter(isDrillIntersectionAttributeItem)
|
|
30
30
|
.filter((intersectionAttributeItem) => intersectionAttributeItem.attributeHeader.localIdentifier === drillOriginLocalId)
|
|
31
|
-
.map((intersectionAttributeItem) => intersectionAttributeItem.attributeHeaderItem.
|
|
31
|
+
.map((intersectionAttributeItem) => intersectionAttributeItem.attributeHeaderItem.formattedName ??
|
|
32
|
+
intersectionAttributeItem.attributeHeaderItem.name)[0];
|
|
32
33
|
}
|
|
33
34
|
/**
|
|
34
35
|
* Get total number of IDrillToUrl
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type DashboardAttributeFilterConfigMode, type DashboardDateFilterConfigMode } from "@gooddata/sdk-model";
|
|
1
|
+
import { type DashboardAttributeFilterConfigMode, type DashboardDateFilterConfigMode, type IAttributeElement, type ISeparators } from "@gooddata/sdk-model";
|
|
2
2
|
/**
|
|
3
3
|
* @alpha
|
|
4
4
|
*/
|
|
@@ -19,4 +19,11 @@ export declare function useDashboardRelatedFilters(run: boolean): {
|
|
|
19
19
|
isError: boolean;
|
|
20
20
|
isSuccess: boolean;
|
|
21
21
|
};
|
|
22
|
+
/**
|
|
23
|
+
* Titles to display for the elements: the raw titles, with the values of a numeric computed attribute
|
|
24
|
+
* formatted by the number format of the elements query result.
|
|
25
|
+
*
|
|
26
|
+
* @internal exported for tests
|
|
27
|
+
*/
|
|
28
|
+
export declare function elementsDisplayTitles(elements: IAttributeElement[], numberFormat: string | undefined, separators: ISeparators | undefined): Array<string | null>;
|
|
22
29
|
//# sourceMappingURL=useDashboardRelatedFilters.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDashboardRelatedFilters.d.ts","sourceRoot":"","sources":["../../../../src/presentation/export/hooks/useDashboardRelatedFilters.ts"],"names":[],"mappings":"AAGA,OAAO,EACH,KAAK,kCAAkC,EACvC,KAAK,6BAA6B,
|
|
1
|
+
{"version":3,"file":"useDashboardRelatedFilters.d.ts","sourceRoot":"","sources":["../../../../src/presentation/export/hooks/useDashboardRelatedFilters.ts"],"names":[],"mappings":"AAGA,OAAO,EACH,KAAK,kCAAkC,EACvC,KAAK,6BAA6B,EAElC,KAAK,iBAAiB,EAEtB,KAAK,WAAW,EAInB,MAAM,qBAAqB,CAAC;AAkB7B;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACjC,IAAI,EAAE,iBAAiB,GAAG,YAAY,GAAG,oBAAoB,CAAC;IAC9D,GAAG,EAAE,OAAO,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,6BAA6B,GAAG,kCAAkC,CAAC;CAC5E,CAAC;AAEF,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,OAAO,GAAG;IACtD,WAAW,EAAE,sBAAsB,EAAE,CAAC;IACtC,gBAAgB,EAAE,sBAAsB,EAAE,CAAC;IAC3C,mBAAmB,EAAE,sBAAsB,EAAE,CAAC;IAC9C,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;CACtB,CA4DA;AA4CD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACjC,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,UAAU,EAAE,WAAW,GAAG,SAAS,GACpC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAQtB"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// (C) 2022-2026 GoodData Corporation
|
|
2
2
|
import { areObjRefsEqual, getAttributeElementsItems, isDashboardAttributeFilter, } from "@gooddata/sdk-model";
|
|
3
|
-
import { useBackendStrict, useCancelablePromise, useWorkspaceStrict } from "@gooddata/sdk-ui";
|
|
3
|
+
import { createNumberFormatter, formatAttributeValue, useBackendStrict, useCancelablePromise, useWorkspaceStrict, } from "@gooddata/sdk-ui";
|
|
4
4
|
import { useFiltersNamings } from "../../../_staging/sharedHooks/useFiltersNamings.js";
|
|
5
5
|
import { useDashboardSelector } from "../../../model/react/DashboardStoreProvider.js";
|
|
6
|
+
import { selectSeparators } from "../../../model/store/config/configSelectors.js";
|
|
6
7
|
import { selectExecutableDashboardFilters } from "../../../model/store/filtering/dashboardFilterSelectors.js";
|
|
7
8
|
import { selectAttributeFilterConfigsOverrides } from "../../../model/store/tabs/attributeFilterConfigs/attributeFilterConfigsSelectors.js";
|
|
8
9
|
import { selectDateFilterConfigOverrides } from "../../../model/store/tabs/dateFilterConfig/dateFilterConfigSelectors.js";
|
|
@@ -16,14 +17,15 @@ export function useDashboardRelatedFilters(run) {
|
|
|
16
17
|
const dateFiltersConfig = useDashboardSelector(selectDateFilterConfigsOverrides);
|
|
17
18
|
const attributeFiltersConfig = useDashboardSelector(selectAttributeFilterConfigsOverrides);
|
|
18
19
|
const measureValueFiltersConfig = useDashboardSelector(selectMeasureValueFilterConfigsOverrides);
|
|
20
|
+
const separators = useDashboardSelector(selectSeparators);
|
|
19
21
|
const { result, status } = useCancelablePromise({
|
|
20
22
|
promise: async () => {
|
|
21
23
|
if (!run) {
|
|
22
24
|
return dashboardFilters;
|
|
23
25
|
}
|
|
24
|
-
return Promise.all(dashboardFilters.map((f) => updateLabelElements(backend, workspaceId, attributeFiltersConfig, f)));
|
|
26
|
+
return Promise.all(dashboardFilters.map((f) => updateLabelElements(backend, workspaceId, attributeFiltersConfig, separators, f)));
|
|
25
27
|
},
|
|
26
|
-
}, [run, dashboardFilters]);
|
|
28
|
+
}, [run, dashboardFilters, separators]);
|
|
27
29
|
const filters = useFiltersNamings(result ?? []);
|
|
28
30
|
const all = filters.filter((f) => f && !f.all).map((f) => {
|
|
29
31
|
if (f?.common) {
|
|
@@ -58,7 +60,7 @@ export function useDashboardRelatedFilters(run) {
|
|
|
58
60
|
measureValueFilters: all.filter((f) => f?.type === "measureValueFilter"),
|
|
59
61
|
};
|
|
60
62
|
}
|
|
61
|
-
async function updateLabelElements(backend, workspaceId, attributeFiltersConfig, dashboardFilter) {
|
|
63
|
+
async function updateLabelElements(backend, workspaceId, attributeFiltersConfig, separators, dashboardFilter) {
|
|
62
64
|
// Skip filters that are not attribute filters
|
|
63
65
|
if (isDashboardAttributeFilter(dashboardFilter)) {
|
|
64
66
|
const config = attributeFiltersConfig.find((c) => c.localIdentifier === dashboardFilter.attributeFilter.localIdentifier);
|
|
@@ -76,15 +78,29 @@ async function updateLabelElements(backend, workspaceId, attributeFiltersConfig,
|
|
|
76
78
|
});
|
|
77
79
|
const data = await query.query();
|
|
78
80
|
const all = await data.all();
|
|
81
|
+
// the filter is only described to the user from here on, so it carries the titles to display
|
|
79
82
|
return {
|
|
80
83
|
...dashboardFilter,
|
|
81
84
|
attributeFilter: {
|
|
82
85
|
...dashboardFilter.attributeFilter,
|
|
83
86
|
attributeElements: {
|
|
84
|
-
values: all.
|
|
87
|
+
values: elementsDisplayTitles(all, data.numberFormat, separators),
|
|
85
88
|
},
|
|
86
89
|
},
|
|
87
90
|
};
|
|
88
91
|
}
|
|
89
92
|
return dashboardFilter;
|
|
90
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Titles to display for the elements: the raw titles, with the values of a numeric computed attribute
|
|
96
|
+
* formatted by the number format of the elements query result.
|
|
97
|
+
*
|
|
98
|
+
* @internal exported for tests
|
|
99
|
+
*/
|
|
100
|
+
export function elementsDisplayTitles(elements, numberFormat, separators) {
|
|
101
|
+
if (!numberFormat) {
|
|
102
|
+
return elements.map((element) => element.title);
|
|
103
|
+
}
|
|
104
|
+
const formatter = createNumberFormatter(separators);
|
|
105
|
+
return elements.map((element) => formatAttributeValue(element.title, numberFormat, formatter));
|
|
106
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefaultDashboardAttributeFilter.d.ts","sourceRoot":"","sources":["../../../../src/presentation/filterBar/attributeFilter/DefaultDashboardAttributeFilter.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAkD,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"DefaultDashboardAttributeFilter.d.ts","sourceRoot":"","sources":["../../../../src/presentation/filterBar/attributeFilter/DefaultDashboardAttributeFilter.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAkD,MAAM,OAAO,CAAC;AAyE1F,OAAO,EAAE,KAAK,8BAA8B,EAAE,MAAM,YAAY,CAAC;AAKjE;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,8BAA8B,GAAG,YAAY,GAAG,IAAI,CAa1G;AAED;;GAEG;AACH,wBAAgB,kCAAkC,CAC9C,KAAK,EAAE,8BAA8B,GACtC,YAAY,GAAG,IAAI,CAErB"}
|
|
@@ -9,7 +9,7 @@ import { useAttributes } from "../../../_staging/sharedHooks/useAttributes.js";
|
|
|
9
9
|
import { useDashboardSelector } from "../../../model/react/DashboardStoreProvider.js";
|
|
10
10
|
import { useDashboardUserInteraction } from "../../../model/react/useDashboardUserInteraction.js";
|
|
11
11
|
import { selectBackendCapabilities } from "../../../model/store/backendCapabilities/backendCapabilitiesSelectors.js";
|
|
12
|
-
import { selectAvailableAttributeFilterSelectionTypes, selectEnableImmediateAttributeFilterDisplayAsLabelMigration, selectIsApplyFiltersAllAtOnceEnabledAndSet, selectLocale, } from "../../../model/store/config/configSelectors.js";
|
|
12
|
+
import { selectAvailableAttributeFilterSelectionTypes, selectEnableImmediateAttributeFilterDisplayAsLabelMigration, selectIsApplyFiltersAllAtOnceEnabledAndSet, selectLocale, selectSeparators, } from "../../../model/store/config/configSelectors.js";
|
|
13
13
|
import { selectIsFilterFromCrossFilteringByLocalIdentifier } from "../../../model/store/drill/drillSelectors.js";
|
|
14
14
|
import { selectIsInEditMode } from "../../../model/store/renderMode/renderModeSelectors.js";
|
|
15
15
|
import { selectAttributeFilterConfigsModeMap, selectAttributeFilterConfigsModeMapByTab, selectAttributeFilterConfigsSelectionTypeMap, selectAttributeFilterConfigsSelectionTypeMapByTab, } from "../../../model/store/tabs/attributeFilterConfigs/attributeFilterConfigsSelectors.js";
|
|
@@ -54,6 +54,7 @@ function DefaultDashboardAttributeFilterInner(props) {
|
|
|
54
54
|
const locale = useDashboardSelector(selectLocale);
|
|
55
55
|
const isEditMode = useDashboardSelector(selectIsInEditMode);
|
|
56
56
|
const capabilities = useDashboardSelector(selectBackendCapabilities);
|
|
57
|
+
const separators = useDashboardSelector(selectSeparators);
|
|
57
58
|
// Extract common properties using wide utilities; narrow props only for standard filters
|
|
58
59
|
const filterLocalId = dashboardAttributeFilterItemLocalIdentifier(filter);
|
|
59
60
|
const filterTitle = dashboardAttributeFilterItemTitle(filter);
|
|
@@ -325,7 +326,7 @@ function DefaultDashboardAttributeFilterInner(props) {
|
|
|
325
326
|
isApplyAllAtOnceEnabledAndSet,
|
|
326
327
|
]);
|
|
327
328
|
const AttributeFilterComponent = props.AttributeFilterComponent ?? AttributeFilterButton;
|
|
328
|
-
const filterContent = (_jsx(AttributeFilterComponent, { title: filterTitle, resetOnParentFilterChange: false, filter: isApplyAllAtOnceEnabledAndSet ? workingAttributeFilter : attributeFilter, displayAsLabel: displayAsLabel, overlayPositionType: overlayPositionType, onApply: (newFilter, isInverted, selectionMode, selectionTitles, displayAsLabel, isResultOfMigration, additionalProps) => {
|
|
329
|
+
const filterContent = (_jsx(AttributeFilterComponent, { title: filterTitle, separators: separators, resetOnParentFilterChange: false, filter: isApplyAllAtOnceEnabledAndSet ? workingAttributeFilter : attributeFilter, displayAsLabel: displayAsLabel, overlayPositionType: overlayPositionType, onApply: (newFilter, isInverted, selectionMode, selectionTitles, displayAsLabel, isResultOfMigration, additionalProps) => {
|
|
329
330
|
const isSelectionInvalid = additionalProps?.isSelectionInvalid ?? false;
|
|
330
331
|
const applyToWorkingOnly = additionalProps?.applyToWorkingOnly ?? false;
|
|
331
332
|
// Convert the SDK-level filter to a dashboard filter item.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AttributeListItemTooltip.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/filterBar/attributeFilter/addAttributeFilter/attributeListItemTooltip/AttributeListItemTooltip.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAY,MAAM,OAAO,CAAC;AAEjD,OAAO,EAAE,KAAK,iBAAiB,EAA0B,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"AttributeListItemTooltip.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/filterBar/attributeFilter/addAttributeFilter/attributeListItemTooltip/AttributeListItemTooltip.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAY,MAAM,OAAO,CAAC;AAEjD,OAAO,EAAE,KAAK,iBAAiB,EAA0B,MAAM,qBAAqB,CAAC;AAkBrF,UAAU,8BAA8B;IACpC,IAAI,EAAE,iBAAiB,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,EAAE,IAAI,EAAE,EAAE,8BAA8B,GAAG,SAAS,CAoD5F"}
|