@gooddata/sdk-ui-dashboard 11.65.0-alpha.0 → 11.65.0-alpha.2

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.
Files changed (64) hide show
  1. package/esm/__version.d.ts +1 -1
  2. package/esm/__version.js +1 -1
  3. package/esm/model/queryServices/queryAttributeElements.js +1 -0
  4. package/esm/model/types/attributeFilterTypes.d.ts +5 -0
  5. package/esm/model/types/attributeFilterTypes.d.ts.map +1 -1
  6. package/esm/model/types/attributeFilterTypes.js +1 -1
  7. package/esm/presentation/automations/alerting/hooks/useAttributeValuesFromExecResults.d.ts +33 -2
  8. package/esm/presentation/automations/alerting/hooks/useAttributeValuesFromExecResults.d.ts.map +1 -1
  9. package/esm/presentation/automations/alerting/hooks/useAttributeValuesFromExecResults.js +29 -13
  10. package/esm/presentation/automations/alerting/state/useAlertSupportedMetrics.d.ts.map +1 -1
  11. package/esm/presentation/automations/alerting/state/useAlertSupportedMetrics.js +3 -2
  12. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/Attachments/DashboardAttachments.d.ts.map +1 -1
  13. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/Attachments/DashboardAttachments.js +3 -3
  14. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/Attachments/WidgetAttachments.d.ts.map +1 -1
  15. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/Attachments/WidgetAttachments.js +5 -4
  16. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/RecipientsSelect/LiveRegionLastSelectContainer.d.ts +9 -0
  17. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/RecipientsSelect/LiveRegionLastSelectContainer.d.ts.map +1 -0
  18. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/RecipientsSelect/LiveRegionLastSelectContainer.js +12 -0
  19. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/RecipientsSelect/RecipientsSelect.d.ts.map +1 -1
  20. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/RecipientsSelect/RecipientsSelect.js +3 -3
  21. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/RecipientsSelect/RecipientsSelectRenderer.d.ts.map +1 -1
  22. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/RecipientsSelect/RecipientsSelectRenderer.js +14 -7
  23. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/RecipientsSelect/RecipientsSelectionDescription.d.ts +12 -0
  24. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/RecipientsSelect/RecipientsSelectionDescription.d.ts.map +1 -0
  25. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/RecipientsSelect/RecipientsSelectionDescription.js +30 -0
  26. package/esm/presentation/automations/scheduledEmail/utils/users.d.ts +1 -0
  27. package/esm/presentation/automations/scheduledEmail/utils/users.d.ts.map +1 -1
  28. package/esm/presentation/automations/scheduledEmail/utils/users.js +3 -0
  29. package/esm/presentation/dashboard/components/DashboardScreenSizeContext.d.ts.map +1 -1
  30. package/esm/presentation/dashboard/components/DashboardScreenSizeContext.js +10 -7
  31. package/esm/presentation/dashboard/components/ToastMessages.d.ts.map +1 -1
  32. package/esm/presentation/dashboard/components/ToastMessages.js +6 -3
  33. package/esm/presentation/dashboard/components/useEditModeLayoutNoteMessages.d.ts +6 -0
  34. package/esm/presentation/dashboard/components/useEditModeLayoutNoteMessages.d.ts.map +1 -0
  35. package/esm/presentation/dashboard/components/useEditModeLayoutNoteMessages.js +48 -0
  36. package/esm/presentation/drill/utils/drillDownUtils.d.ts.map +1 -1
  37. package/esm/presentation/drill/utils/drillDownUtils.js +3 -2
  38. package/esm/presentation/export/hooks/useDashboardRelatedFilters.d.ts +8 -1
  39. package/esm/presentation/export/hooks/useDashboardRelatedFilters.d.ts.map +1 -1
  40. package/esm/presentation/export/hooks/useDashboardRelatedFilters.js +21 -5
  41. package/esm/presentation/filterBar/attributeFilter/DefaultDashboardAttributeFilter.d.ts.map +1 -1
  42. package/esm/presentation/filterBar/attributeFilter/DefaultDashboardAttributeFilter.js +3 -2
  43. package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/attributeListItemTooltip/AttributeListItemTooltip.d.ts.map +1 -1
  44. package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/attributeListItemTooltip/AttributeListItemTooltip.js +4 -1
  45. package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/attributeListItemTooltip/AttributeListItemTooltipContent.d.ts +6 -2
  46. package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/attributeListItemTooltip/AttributeListItemTooltipContent.d.ts.map +1 -1
  47. package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/attributeListItemTooltip/AttributeListItemTooltipContent.js +8 -4
  48. package/esm/presentation/filterBar/filterBar/filterViews/FilterViewDeleteConfirm.d.ts +2 -1
  49. package/esm/presentation/filterBar/filterBar/filterViews/FilterViewDeleteConfirm.d.ts.map +1 -1
  50. package/esm/presentation/filterBar/filterBar/filterViews/FilterViewDeleteConfirm.js +2 -2
  51. package/esm/presentation/filterBar/filterBar/filterViews/FilterViewsList.d.ts.map +1 -1
  52. package/esm/presentation/filterBar/filterBar/filterViews/FilterViewsList.js +11 -5
  53. package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts +24 -0
  54. package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts.map +1 -1
  55. package/esm/presentation/localization/bundles/en-US.localization-bundle.js +24 -0
  56. package/esm/presentation/topBar/buttonBar/button/editButton/DefaultEditButton.d.ts.map +1 -1
  57. package/esm/presentation/topBar/buttonBar/button/editButton/DefaultEditButton.js +2 -4
  58. package/esm/sdk-ui-dashboard.d.ts +5 -0
  59. package/package.json +21 -21
  60. package/styles/css/dashboard.css +9 -0
  61. package/styles/css/dashboard.css.map +1 -1
  62. package/styles/css/main.css +9 -0
  63. package/styles/css/main.css.map +1 -1
  64. package/styles/scss/dashboard.scss +11 -0
@@ -1,4 +1,4 @@
1
- export declare const LIB_VERSION = "11.65.0-alpha.0";
1
+ export declare const LIB_VERSION = "11.65.0-alpha.2";
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.0";
3
+ export const LIB_VERSION = "11.65.0-alpha.2";
4
4
  export const LIB_DESCRIPTION = "GoodData SDK - Dashboard Component";
5
5
  export const LIB_NAME = "@gooddata/sdk-ui-dashboard";
@@ -24,5 +24,6 @@ function* queryService(ctx, query) {
24
24
  return {
25
25
  elements: attributeElements.items,
26
26
  totalCount: attributeElements.totalCount,
27
+ numberFormat: attributeElements.numberFormat,
27
28
  };
28
29
  }
@@ -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;CACtB"}
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-2023 GoodData Corporation
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
@@ -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,EAGhB,MAAM,qBAAqB,CAAC;AAG7B,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,CAAC,UAAU,EAAE,wBAAwB,GAAG,SAAS;;+BAuCnF,UAAU,KAAG,cAAc,EAAE;+BASzB,QAAQ,SAAS,UAAU,UAAU,MAAM,GAAG,IAAI;EAyBpE"}
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
- function calculatePredictedValue(data, values) {
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
- function calculateValues(dataView, indexes, value) {
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
- .map((v) => v.title)
90
- .filter((v) => {
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,CA8CzD"}
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
- const { isResultLoading, getAttributeValues, getMetricValue } = useAttributeValuesFromExecResults(execResult);
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,2CA4HhD"}
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
- // Focus management: if items remain, focus the group; otherwise focus add button
48
- if (newAttachments.length > 0) {
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":"AASA,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,2CA4H7C"}
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
- // Focus management: if items remain, focus the group; otherwise focus add button
59
- if (newAttachments.length > 0) {
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
  }
@@ -0,0 +1,9 @@
1
+ import { type ReactElement } from "react";
2
+ import { type ContainerProps } from "react-select";
3
+ import { type IAutomationRecipient } from "@gooddata/sdk-model";
4
+ /**
5
+ * React-select 5.x renders its hidden live region as the first child; rendering it last keeps screen readers
6
+ * from stopping on it between the field label and the recipients. Guarded by RecipientsSelect.test.tsx.
7
+ */
8
+ export declare function LiveRegionLastSelectContainer(props: ContainerProps<IAutomationRecipient, boolean>): ReactElement;
9
+ //# sourceMappingURL=LiveRegionLastSelectContainer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LiveRegionLastSelectContainer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/RecipientsSelect/LiveRegionLastSelectContainer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAEpD,OAAO,EAAE,KAAK,cAAc,EAAc,MAAM,cAAc,CAAC;AAE/D,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEhE;;;GAGG;AACH,wBAAgB,6BAA6B,CACzC,KAAK,EAAE,cAAc,CAAC,oBAAoB,EAAE,OAAO,CAAC,GACrD,YAAY,CASd"}
@@ -0,0 +1,12 @@
1
+ import { jsxs as _jsxs } from "react/jsx-runtime";
2
+ // (C) 2026 GoodData Corporation
3
+ import { Children } from "react";
4
+ import { components } from "react-select";
5
+ /**
6
+ * React-select 5.x renders its hidden live region as the first child; rendering it last keeps screen readers
7
+ * from stopping on it between the field label and the recipients. Guarded by RecipientsSelect.test.tsx.
8
+ */
9
+ export function LiveRegionLastSelectContainer(props) {
10
+ const [liveRegion, ...rest] = Children.toArray(props.children);
11
+ return (_jsxs(components.SelectContainer, { ...props, children: [rest, liveRegion] }));
12
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"RecipientsSelect.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/RecipientsSelect/RecipientsSelect.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAW,MAAM,OAAO,CAAC;AAIpD,OAAO,EACH,KAAK,oBAAoB,EACzB,KAAK,8BAA8B,EACnC,KAAK,kCAAkC,EAC1C,MAAM,qBAAqB,CAAC;AAU7B,UAAU,sBAAsB;IAC5B;;OAEG;IACH,KAAK,EAAE,oBAAoB,EAAE,CAAC;IAE9B;;OAEG;IACH,QAAQ,EAAE,CAAC,eAAe,EAAE,oBAAoB,EAAE,KAAK,IAAI,CAAC;IAE5D;;OAEG;IACH,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAElC;;OAEG;IACH,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC;;OAEG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;OAEG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAElC;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,oBAAoB,CAAC,EAAE,8BAA8B,EAAE,GAAG,kCAAkC,EAAE,CAAC;IAE/F;;OAEG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,eAAe,CAAC,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,CAAC;IAE7C;;OAEG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,wBAAgB,gBAAgB,CAAC,EAC7B,EAAE,EACF,KAAK,EACL,QAAQ,EACR,UAAU,EACV,mBAAmB,EACnB,uBAAuB,EACvB,6BAA6B,EAC7B,aAAa,EACb,SAAS,EACT,oBAAoB,EACpB,qBAAqB,EACrB,SAAgB,EAChB,eAAe,EACf,yBAAyB,GAC5B,EAAE,sBAAsB,2CAuExB"}
1
+ {"version":3,"file":"RecipientsSelect.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/RecipientsSelect/RecipientsSelect.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAW,MAAM,OAAO,CAAC;AAIpD,OAAO,EACH,KAAK,oBAAoB,EACzB,KAAK,8BAA8B,EACnC,KAAK,kCAAkC,EAC1C,MAAM,qBAAqB,CAAC;AAU7B,UAAU,sBAAsB;IAC5B;;OAEG;IACH,KAAK,EAAE,oBAAoB,EAAE,CAAC;IAE9B;;OAEG;IACH,QAAQ,EAAE,CAAC,eAAe,EAAE,oBAAoB,EAAE,KAAK,IAAI,CAAC;IAE5D;;OAEG;IACH,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAElC;;OAEG;IACH,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC;;OAEG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;OAEG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAElC;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,oBAAoB,CAAC,EAAE,8BAA8B,EAAE,GAAG,kCAAkC,EAAE,CAAC;IAE/F;;OAEG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,eAAe,CAAC,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,CAAC;IAE7C;;OAEG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,wBAAgB,gBAAgB,CAAC,EAC7B,EAAE,EACF,KAAK,EACL,QAAQ,EACR,UAAU,EACV,mBAAmB,EACnB,uBAAuB,EACvB,6BAA6B,EAC7B,aAAa,EACb,SAAS,EACT,oBAAoB,EACpB,qBAAqB,EACrB,SAAgB,EAChB,eAAe,EACf,yBAAyB,GAC5B,EAAE,sBAAsB,2CAwExB"}
@@ -5,7 +5,7 @@ import { sortBy } from "lodash-es";
5
5
  import { DETAILED_ANNOUNCEMENT_THRESHOLD, UiSearchResultsAnnouncement } from "@gooddata/sdk-ui-kit";
6
6
  import { useWorkspaceUsersSearch } from "../../../../shared/hooks/useWorkspaceUsersSearch.js";
7
7
  import { convertUserToAutomationRecipient } from "../../../../shared/utils/automationUtils.js";
8
- import { createUser, matchRecipient } from "../../../utils/users.js";
8
+ import { createUser, getRecipientLabel, matchRecipient } from "../../../utils/users.js";
9
9
  import { isEmail } from "../../../utils/validate.js";
10
10
  import { RecipientsSelectRenderer } from "./RecipientsSelectRenderer.js";
11
11
  export function RecipientsSelect({ id, value, onChange, loggedUser, allowEmptySelection, allowExternalRecipients, allowOnlyLoggedUserRecipients, maxRecipients, className, notificationChannels, notificationChannelId, showLabel = true, onKeyDownSubmit, externalRecipientOverride, }) {
@@ -37,6 +37,6 @@ export function RecipientsSelect({ id, value, onChange, loggedUser, allowEmptySe
37
37
  externalRecipientOverride,
38
38
  ]);
39
39
  const hasSettledResults = !isLoading && (isServerSearch ? users !== undefined : Boolean(search));
40
- const announcedResultValues = useMemo(() => options.slice(0, DETAILED_ANNOUNCEMENT_THRESHOLD).map((option) => option.name ?? option.id), [options]);
41
- return (_jsxs(_Fragment, { children: [_jsx(UiSearchResultsAnnouncement, { totalResults: hasSettledResults ? options.length : undefined, resultValues: announcedResultValues }), _jsx(RecipientsSelectRenderer, { id: id, canListUsersInProject: true, isMulti: true, options: options, value: value, onChange: onChange, onSearch: onSearch, onActivate: onActivate, isLoading: isLoading, loggedUser: loggedUser, allowOnlyLoggedUserRecipients: allowOnlyLoggedUserRecipients, allowEmptySelection: allowEmptySelection, allowExternalRecipients: allowExternalRecipients, maxRecipients: maxRecipients, className: className, notificationChannel: notificationChannel, usersError: usersError, showLabel: showLabel, onKeyDownSubmit: onKeyDownSubmit, externalRecipientOverride: externalRecipientOverride })] }));
40
+ const announcedResultValues = useMemo(() => options.slice(0, DETAILED_ANNOUNCEMENT_THRESHOLD).map(getRecipientLabel), [options]);
41
+ return (_jsxs(_Fragment, { children: [_jsx(RecipientsSelectRenderer, { id: id, canListUsersInProject: true, isMulti: true, options: options, value: value, onChange: onChange, onSearch: onSearch, onActivate: onActivate, isLoading: isLoading, loggedUser: loggedUser, allowOnlyLoggedUserRecipients: allowOnlyLoggedUserRecipients, allowEmptySelection: allowEmptySelection, allowExternalRecipients: allowExternalRecipients, maxRecipients: maxRecipients, className: className, notificationChannel: notificationChannel, usersError: usersError, showLabel: showLabel, onKeyDownSubmit: onKeyDownSubmit, externalRecipientOverride: externalRecipientOverride }), _jsx(UiSearchResultsAnnouncement, { totalResults: hasSettledResults ? options.length : undefined, resultValues: announcedResultValues })] }));
42
42
  }
@@ -1 +1 @@
1
- {"version":3,"file":"RecipientsSelectRenderer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/RecipientsSelect/RecipientsSelectRenderer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAqE,MAAM,OAAO,CAAC;AAiB9G,OAAO,EACH,KAAK,oBAAoB,EACzB,KAAK,8BAA8B,EACnC,KAAK,kCAAkC,EAE1C,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACH,KAAK,gBAAgB,EAKxB,MAAM,kBAAkB,CAAC;AA8F1B,MAAM,WAAW,8BAA8B;IAC3C;;OAEG;IACH,KAAK,EAAE,oBAAoB,EAAE,CAAC;IAE9B;;OAEG;IACH,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAEhC;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,aAAa,EAAE,oBAAoB,EAAE,KAAK,IAAI,CAAC;IAE3D;;OAEG;IACH,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAEnC;;OAEG;IACH,UAAU,EAAE,MAAM,IAAI,CAAC;IAEvB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAE9B;;OAEG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC;;OAEG;IACH,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAElC;;OAEG;IACH,6BAA6B,CAAC,EAAE,OAAO,CAAC;IAExC;;OAEG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;OAEG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAElC;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,mBAAmB,CAAC,EAAE,8BAA8B,GAAG,kCAAkC,CAAC;IAE1F;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,eAAe,CAAC,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,CAAC;IAE7C;;OAEG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACtC;AAQD,eAAO,MAAM,wBAAwB,8CAC1B,8BAA8B,6CA8vBvC,CAAC"}
1
+ {"version":3,"file":"RecipientsSelectRenderer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/RecipientsSelect/RecipientsSelectRenderer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAqE,MAAM,OAAO,CAAC;AAiB9G,OAAO,EACH,KAAK,oBAAoB,EACzB,KAAK,8BAA8B,EACnC,KAAK,kCAAkC,EAE1C,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACH,KAAK,gBAAgB,EAKxB,MAAM,kBAAkB,CAAC;AAkG1B,MAAM,WAAW,8BAA8B;IAC3C;;OAEG;IACH,KAAK,EAAE,oBAAoB,EAAE,CAAC;IAE9B;;OAEG;IACH,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAEhC;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,aAAa,EAAE,oBAAoB,EAAE,KAAK,IAAI,CAAC;IAE3D;;OAEG;IACH,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAEnC;;OAEG;IACH,UAAU,EAAE,MAAM,IAAI,CAAC;IAEvB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAE9B;;OAEG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC;;OAEG;IACH,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAElC;;OAEG;IACH,6BAA6B,CAAC,EAAE,OAAO,CAAC;IAExC;;OAEG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;OAEG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAElC;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,mBAAmB,CAAC,EAAE,8BAA8B,GAAG,kCAAkC,CAAC;IAE1F;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,eAAe,CAAC,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,CAAC;IAE7C;;OAEG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACtC;AAQD,eAAO,MAAM,wBAAwB,8CAC1B,8BAA8B,6CAmwBvC,CAAC"}
@@ -9,7 +9,10 @@ import { isAutomationUserRecipient, } from "@gooddata/sdk-model";
9
9
  import { ValidationContextStore, createInvalidDatapoint, createInvalidNode, useValidationContextValue, } from "@gooddata/sdk-ui";
10
10
  import { LoadingMask, Message, Overlay, OverlayController, OverlayControllerProvider, UiIcon, UiTooltip, isEscapeKey, makeKeyboardNavigation, } from "@gooddata/sdk-ui-kit";
11
11
  import { DASHBOARD_DIALOG_OVERS_Z_INDEX } from "../../../../../constants/zIndex.js";
12
+ import { getRecipientLabel } from "../../../utils/users.js";
12
13
  import { isEmail } from "../../../utils/validate.js";
14
+ import { LiveRegionLastSelectContainer } from "./LiveRegionLastSelectContainer.js";
15
+ import { RecipientsSelectionDescription } from "./RecipientsSelectionDescription.js";
13
16
  const MAXIMUM_RECIPIENTS_RECEIVE = 60;
14
17
  const PADDING = 16;
15
18
  const LOADING_MENU_HEIGHT = 50;
@@ -113,12 +116,12 @@ export const RecipientsSelectRenderer = memo(function RecipientsSelectRenderer(p
113
116
  const invalidUnknownRecipients = value.filter((v) => v.type === "unknownUser");
114
117
  const invalidUnknownError = !!invalidUnknownRecipients.length;
115
118
  const invalidRecipientsValues = [...invalidExternalRecipients, ...invalidUnknownRecipients]
116
- .map((v) => v.name || v.id)
119
+ .map(getRecipientLabel)
117
120
  .join(", ");
118
121
  const authorOnlyError = allowOnlyLoggedUserRecipients &&
119
122
  ((value.length === 1 && value[0].id !== loggedUser?.id) || value.length > 1);
120
123
  const missingEmailRecipients = value.filter((v) => !getHasEmail(v));
121
- const missingEmailRecipientsValues = missingEmailRecipients.map((v) => v.name || v.id).join(", ");
124
+ const missingEmailRecipientsValues = missingEmailRecipients.map(getRecipientLabel).join(", ");
122
125
  const missingEmailError = !!missingEmailRecipients.length;
123
126
  return {
124
127
  maxRecipientsError,
@@ -229,7 +232,7 @@ export const RecipientsSelectRenderer = memo(function RecipientsSelectRenderer(p
229
232
  const { data, children } = multiValueProps;
230
233
  // MultiValueRemove component from react-select
231
234
  const removeIcon = children[1];
232
- const name = data.name || data.id;
235
+ const name = getRecipientLabel(data);
233
236
  const hasEmail = getHasEmail(data);
234
237
  const noExternal = data.type === "externalUser" && !allowExternalRecipients;
235
238
  const invalidExternal = data.type === "unknownUser";
@@ -260,13 +263,16 @@ export const RecipientsSelectRenderer = memo(function RecipientsSelectRenderer(p
260
263
  return renderEmptyContainer();
261
264
  }, [renderEmptyContainer]);
262
265
  const renderOptionLabel = useCallback((recipient) => {
263
- const displayName = recipient.name || recipient.id;
266
+ const displayName = getRecipientLabel(recipient);
264
267
  const email = isAutomationUserRecipient(recipient) ? (recipient.email ?? "") : "";
265
268
  const renderValue = renderRecipientValue(recipient);
266
269
  return (_jsx(UiTooltip, { anchor: _jsxs("div", { className: "gd-recipient-option-item s-gd-recipient-option-item", children: [_jsx("span", { className: "gd-recipient-option-label-item s-gd-recipient-option-label-item", children: displayName }), allowExternalRecipients && recipient.type === "externalUser" ? (_jsxs("span", { className: "gd-recipient-quest", children: ["\u00A0", _jsx(FormattedMessage, { id: "dialogs.schedule.email.user.guest" })] })) : (renderValue), !externalRecipientOverride &&
267
270
  allowExternalRecipients &&
268
271
  recipient.type === "externalUser" ? (_jsx("div", { className: "gd-recipient-option-label-external-warning", children: _jsx(Message, { type: "warning", children: _jsx(FormattedMessage, { id: "dialogs.schedule.email.user.warning.external", values: { email: displayName } }) }) })) : null] }), content: isEmail(email) ? `${displayName} (${email})` : displayName, variant: "default", arrowPlacement: "right", triggerBy: ["hover", "focus"] }));
269
272
  }, [allowExternalRecipients, externalRecipientOverride, renderRecipientValue]);
273
+ const descriptionId = `${id}-description`;
274
+ const errorId = `${id}-error`;
275
+ const ariaDescribedBy = isValid ? descriptionId : `${descriptionId} ${errorId}`;
270
276
  const renderInputContainer = useCallback((inputProps) => {
271
277
  if (!isMulti) {
272
278
  return renderEmptyContainer();
@@ -287,8 +293,8 @@ export const RecipientsSelectRenderer = memo(function RecipientsSelectRenderer(p
287
293
  inputProps.innerRef(ref);
288
294
  }
289
295
  }, autoComplete: "new-password" // common hack for Safari to not autocomplete
290
- , "aria-invalid": !isValid, "aria-describedby": isValid ? undefined : "gd-recipients-field-error" }) }));
291
- }, [isMulti, id, isValid, renderEmptyContainer]);
296
+ , "aria-invalid": !isValid, "aria-describedby": ariaDescribedBy }) }));
297
+ }, [isMulti, id, isValid, ariaDescribedBy, renderEmptyContainer]);
292
298
  const handleKeyboardRecipientRemove = useCallback((index) => {
293
299
  if (index < 0 || index >= value.length) {
294
300
  return;
@@ -437,6 +443,7 @@ export const RecipientsSelectRenderer = memo(function RecipientsSelectRenderer(p
437
443
  }, [canListUsersInProject, onActivate]);
438
444
  const creatableSelectComponent = {
439
445
  ...ReactSelectComponents,
446
+ SelectContainer: LiveRegionLastSelectContainer,
440
447
  IndicatorsContainer: renderEmptyContainer,
441
448
  Input: renderInputContainer,
442
449
  MultiValueContainer: renderMultiValueContainer,
@@ -496,5 +503,5 @@ export const RecipientsSelectRenderer = memo(function RecipientsSelectRenderer(p
496
503
  // Options arrive pre-filtered (server search, or the owner's options memo).
497
504
  filterOption: null, isClearable: false, isDisabled: !isMulti, isMulti: isMulti, onChange:
498
505
  // using as any as it would be too tricky to type properly
499
- handleOnChange, onInputChange: handleSearchChange, onMenuOpen: onMenuOpen, onMenuClose: () => setState((prev) => ({ ...prev, menuOpen: false })), onKeyDown: handleKeyDown, options: options, onBlur: onBlur, value: value, getOptionValue: (o) => o.id, getOptionLabel: (o) => o.name || o.id, "aria-describedby": isValid ? undefined : "gd-recipients-field-error", "aria-invalid": !isValid }), isValid ? (renderExternalRecipientsNote ? (_jsx("div", { className: "gd-recipients-field-note", children: _jsx(FormattedMessage, { id: "dialogs.schedule.email.recipients.note" }) })) : allowOnlyLoggedUserRecipients ? (_jsx("div", { className: "gd-recipients-field-note", children: _jsx(FormattedMessage, { id: "dialogs.schedule.email.destinationWarning" }) })) : null) : (_jsx("div", { id: "gd-recipients-field-error", className: "gd-recipients-field-error", children: getInvalidDatapoints().map((invalidDatapoint) => (_jsx("div", { id: invalidDatapoint.id, className: "gd-recipients-field-error-item", children: invalidDatapoint.message }, invalidDatapoint.id))) }))] })] }) }));
506
+ handleOnChange, onInputChange: handleSearchChange, onMenuOpen: onMenuOpen, onMenuClose: () => setState((prev) => ({ ...prev, menuOpen: false })), onKeyDown: handleKeyDown, options: options, onBlur: onBlur, value: value, getOptionValue: (o) => o.id, getOptionLabel: getRecipientLabel, "aria-invalid": !isValid }), _jsx(RecipientsSelectionDescription, { id: descriptionId, recipients: value }), isValid ? (renderExternalRecipientsNote ? (_jsx("div", { className: "gd-recipients-field-note", children: _jsx(FormattedMessage, { id: "dialogs.schedule.email.recipients.note" }) })) : allowOnlyLoggedUserRecipients ? (_jsx("div", { className: "gd-recipients-field-note", children: _jsx(FormattedMessage, { id: "dialogs.schedule.email.destinationWarning" }) })) : null) : (_jsx("div", { id: errorId, className: "gd-recipients-field-error", children: getInvalidDatapoints().map((invalidDatapoint) => (_jsx("div", { id: invalidDatapoint.id, className: "gd-recipients-field-error-item", children: invalidDatapoint.message }, invalidDatapoint.id))) }))] })] }) }));
500
507
  });
@@ -0,0 +1,12 @@
1
+ import { type ReactElement } from "react";
2
+ import { type IAutomationRecipient } from "@gooddata/sdk-model";
3
+ interface IRecipientsSelectionDescriptionProps {
4
+ id: string;
5
+ recipients: readonly IAutomationRecipient[];
6
+ }
7
+ /**
8
+ * Hidden screen reader description of the selected recipients, referenced by the recipients input.
9
+ */
10
+ export declare function RecipientsSelectionDescription({ id, recipients, }: IRecipientsSelectionDescriptionProps): ReactElement;
11
+ export {};
12
+ //# sourceMappingURL=RecipientsSelectionDescription.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecipientsSelectionDescription.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/RecipientsSelect/RecipientsSelectionDescription.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAI1C,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AA8BhE,UAAU,oCAAoC;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,SAAS,oBAAoB,EAAE,CAAC;CAC/C;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAAC,EAC3C,EAAE,EACF,UAAU,GACb,EAAE,oCAAoC,GAAG,YAAY,CAQrD"}
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { defineMessages, useIntl } from "react-intl";
3
+ import { DETAILED_ANNOUNCEMENT_THRESHOLD } from "@gooddata/sdk-ui-kit";
4
+ import { getRecipientLabel } from "../../../utils/users.js";
5
+ const messages = defineMessages({
6
+ selectedNone: { id: "dialogs.schedule.email.recipients.selected.none" },
7
+ selectedFew: { id: "dialogs.schedule.email.recipients.selected.few" },
8
+ selectedMany: { id: "dialogs.schedule.email.recipients.selected.many" },
9
+ navigationHint: { id: "dialogs.schedule.email.recipients.navigationHint" },
10
+ });
11
+ function describeRecipients(intl, recipients) {
12
+ const count = recipients.length;
13
+ if (count === 0) {
14
+ return intl.formatMessage(messages.selectedNone);
15
+ }
16
+ const selection = count <= DETAILED_ANNOUNCEMENT_THRESHOLD
17
+ ? intl.formatMessage(messages.selectedFew, {
18
+ count,
19
+ names: intl.formatList(recipients.map(getRecipientLabel), { type: "unit" }),
20
+ })
21
+ : intl.formatMessage(messages.selectedMany, { count });
22
+ return `${selection} ${intl.formatMessage(messages.navigationHint)}`;
23
+ }
24
+ /**
25
+ * Hidden screen reader description of the selected recipients, referenced by the recipients input.
26
+ */
27
+ export function RecipientsSelectionDescription({ id, recipients, }) {
28
+ const intl = useIntl();
29
+ return (_jsx("span", { id: id, hidden: true, children: describeRecipients(intl, recipients) }));
30
+ }
@@ -1,4 +1,5 @@
1
1
  import { type IAutomationRecipient } from "@gooddata/sdk-model";
2
2
  export declare function matchRecipient(user: IAutomationRecipient, search: string): boolean;
3
+ export declare function getRecipientLabel(recipient: IAutomationRecipient): string;
3
4
  export declare function createUser(search: string): IAutomationRecipient;
4
5
  //# sourceMappingURL=users.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/automations/scheduledEmail/utils/users.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,oBAAoB,EAAkC,MAAM,qBAAqB,CAAC;AAIhG,wBAAgB,cAAc,CAAC,IAAI,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,WAexE;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,oBAAoB,CAQ/D"}
1
+ {"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/automations/scheduledEmail/utils/users.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,oBAAoB,EAAkC,MAAM,qBAAqB,CAAC;AAIhG,wBAAgB,cAAc,CAAC,IAAI,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,WAexE;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,oBAAoB,GAAG,MAAM,CAEzE;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,oBAAoB,CAQ/D"}
@@ -14,6 +14,9 @@ export function matchRecipient(user, search) {
14
14
  lowerCaseId?.includes(lowerCaseSearch)) ??
15
15
  false);
16
16
  }
17
+ export function getRecipientLabel(recipient) {
18
+ return recipient.name || recipient.id;
19
+ }
17
20
  export function createUser(search) {
18
21
  const hasEmail = isEmail(search);
19
22
  return {
@@ -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;AA8CtD,MAAM,WAAW,0BAA0B;IACvC,QAAQ,EAAE,SAAS,CAAC;CACvB;AAKD,wBAAgB,2BAA2B,CAAC,EAAE,QAAQ,EAAE,EAAE,0BAA0B,2CA2BnF;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,QAAO,UAGhC,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
- if (viewportWidth >= DASHBOARD_LAYOUT_BREAK_POINTS[2]) {
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":"AAYA;;GAEG;AACH,wBAAgB,aAAa,4CAwB5B"}
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 both collections
21
+ // try removing the id from all collections
20
22
  (id) => {
21
23
  removeDrillValidationMessage(id);
22
24
  removeFilterContextValidationMessage(id);
23
- }, [removeDrillValidationMessage, removeFilterContextValidationMessage]);
25
+ removeEditModeLayoutNoteMessage(id);
26
+ }, [removeDrillValidationMessage, removeFilterContextValidationMessage, removeEditModeLayoutNoteMessage]);
24
27
  return _jsx(NonContextToastsInterop, { messages: messages, onDismissMessage: removeMessage });
25
28
  }