@gooddata/sdk-ui-ext 11.52.0-alpha.5 → 11.52.0-alpha.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/esm/dataLoaders/InsightDataLoader.d.ts +6 -0
  2. package/esm/dataLoaders/InsightDataLoader.d.ts.map +1 -1
  3. package/esm/dataLoaders/InsightDataLoader.js +4 -1
  4. package/esm/dataLoaders/index.d.ts +13 -0
  5. package/esm/dataLoaders/index.d.ts.map +1 -1
  6. package/esm/dataLoaders/index.js +14 -0
  7. package/esm/index.d.ts +1 -1
  8. package/esm/index.d.ts.map +1 -1
  9. package/esm/index.js +1 -1
  10. package/esm/insightView/InsightRenderer.d.ts +3 -6
  11. package/esm/insightView/InsightRenderer.d.ts.map +1 -1
  12. package/esm/insightView/InsightRenderer.js +165 -142
  13. package/esm/internal/components/configurationControls/conditionalFormatting/CfDateValueDropdown.d.ts +3 -4
  14. package/esm/internal/components/configurationControls/conditionalFormatting/CfDateValueDropdown.d.ts.map +1 -1
  15. package/esm/internal/components/configurationControls/conditionalFormatting/CfDateValueDropdown.js +9 -7
  16. package/esm/internal/components/configurationControls/conditionalFormatting/ConditionEditor.d.ts.map +1 -1
  17. package/esm/internal/components/configurationControls/conditionalFormatting/ConditionEditor.js +57 -37
  18. package/esm/internal/components/configurationControls/conditionalFormatting/cfFieldProps.d.ts +12 -0
  19. package/esm/internal/components/configurationControls/conditionalFormatting/cfFieldProps.d.ts.map +1 -0
  20. package/esm/internal/components/configurationControls/conditionalFormatting/cfFieldProps.js +2 -0
  21. package/esm/internal/components/configurationControls/conditionalFormatting/conditionalFormattingModel.d.ts +10 -10
  22. package/esm/internal/components/configurationControls/conditionalFormatting/conditionalFormattingModel.d.ts.map +1 -1
  23. package/esm/internal/components/configurationControls/conditionalFormatting/conditionalFormattingModel.js +11 -11
  24. package/esm/internal/components/configurationPanels/PivotTableConfigurationPanel.d.ts.map +1 -1
  25. package/esm/internal/components/configurationPanels/PivotTableConfigurationPanel.js +2 -1
  26. package/esm/internal/components/pluggableVisualizations/mekko/PluggableMekko.d.ts +6 -1
  27. package/esm/internal/components/pluggableVisualizations/mekko/PluggableMekko.d.ts.map +1 -1
  28. package/esm/internal/components/pluggableVisualizations/mekko/PluggableMekko.js +39 -5
  29. package/esm/internal/components/pluggableVisualizations/pivotTable/PluggablePivotTable.d.ts.map +1 -1
  30. package/esm/internal/components/pluggableVisualizations/pivotTable/PluggablePivotTable.js +0 -1
  31. package/esm/internal/components/pluggableVisualizations/pivotTableNext/PivotTableNextDescriptor.d.ts.map +1 -1
  32. package/esm/internal/components/pluggableVisualizations/pivotTableNext/PivotTableNextDescriptor.js +2 -9
  33. package/esm/internal/components/pluggableVisualizations/pivotTableNext/PluggablePivotTableNext.d.ts.map +1 -1
  34. package/esm/internal/components/pluggableVisualizations/pivotTableNext/PluggablePivotTableNext.js +2 -2
  35. package/esm/internal/components/pluggableVisualizations/pivotTableNext/pivotTableNextConfigFromInsight.d.ts +8 -3
  36. package/esm/internal/components/pluggableVisualizations/pivotTableNext/pivotTableNextConfigFromInsight.d.ts.map +1 -1
  37. package/esm/internal/components/pluggableVisualizations/pivotTableNext/pivotTableNextConfigFromInsight.js +41 -37
  38. package/esm/internal/translations/en-US.localization-bundle.d.ts +12 -0
  39. package/esm/internal/translations/en-US.localization-bundle.d.ts.map +1 -1
  40. package/esm/internal/translations/en-US.localization-bundle.js +12 -0
  41. package/esm/internal/utils/bucketHelper.d.ts.map +1 -1
  42. package/esm/internal/utils/bucketHelper.js +7 -14
  43. package/esm/internal/utils/embeddingCodeGenerator/insightToPropsConverter/convertor.d.ts +2 -2
  44. package/esm/internal/utils/embeddingCodeGenerator/insightToPropsConverter/convertor.d.ts.map +1 -1
  45. package/esm/internal/utils/embeddingCodeGenerator/insightToPropsConverter/convertor.js +4 -2
  46. package/esm/internal/utils/propertiesHelper.d.ts +5 -0
  47. package/esm/internal/utils/propertiesHelper.d.ts.map +1 -1
  48. package/esm/internal/utils/propertiesHelper.js +7 -0
  49. package/esm/locales.d.ts +6 -0
  50. package/esm/locales.d.ts.map +1 -1
  51. package/esm/locales.js +2 -0
  52. package/esm/notificationsPanel/Notification/Notification.d.ts.map +1 -1
  53. package/esm/notificationsPanel/Notification/Notification.js +6 -3
  54. package/esm/notificationsPanel/NotificationFiltersDetail/NotificationFiltersDetail.d.ts +3 -3
  55. package/esm/notificationsPanel/NotificationFiltersDetail/NotificationFiltersDetail.d.ts.map +1 -1
  56. package/esm/notificationsPanel/NotificationFiltersDetail/NotificationFiltersDetail.js +4 -4
  57. package/esm/notificationsPanel/NotificationFiltersDetail/NotificationFiltersDetailDialog.d.ts +9 -3
  58. package/esm/notificationsPanel/NotificationFiltersDetail/NotificationFiltersDetailDialog.d.ts.map +1 -1
  59. package/esm/notificationsPanel/NotificationFiltersDetail/NotificationFiltersDetailDialog.js +4 -4
  60. package/esm/sdk-ui-ext.d.ts +13 -0
  61. package/esm/share/ObjectShareDialog.js +22 -6
  62. package/esm/share/messages.d.ts +7 -0
  63. package/esm/share/messages.d.ts.map +1 -1
  64. package/esm/share/messages.js +5 -0
  65. package/esm/share/objectShareController.helpers.d.ts +117 -17
  66. package/esm/share/objectShareController.helpers.d.ts.map +1 -1
  67. package/esm/share/objectShareController.helpers.js +181 -44
  68. package/esm/share/objectShareController.types.d.ts +34 -10
  69. package/esm/share/objectShareController.types.d.ts.map +1 -1
  70. package/esm/share/useAccessList.d.ts +6 -0
  71. package/esm/share/useAccessList.d.ts.map +1 -1
  72. package/esm/share/useAccessList.js +26 -6
  73. package/esm/share/useLabelScope.d.ts +46 -1
  74. package/esm/share/useLabelScope.d.ts.map +1 -1
  75. package/esm/share/useLabelScope.js +98 -6
  76. package/esm/share/useObjectShareController.d.ts.map +1 -1
  77. package/esm/share/useObjectShareController.js +213 -45
  78. package/esm/share/useObjectShareDialog.d.ts +7 -0
  79. package/esm/share/useObjectShareDialog.d.ts.map +1 -1
  80. package/esm/share/useObjectShareDialog.js +22 -2
  81. package/package.json +21 -21
@@ -10,6 +10,12 @@ export interface IInsightDataLoader {
10
10
  * @param ref - the ref of the insight to obtain
11
11
  */
12
12
  getInsight(backend: IAnalyticalBackend, ref: ObjRef): Promise<IInsight>;
13
+ /**
14
+ * Removes the cached insight for the given ref, so that the next getInsight call
15
+ * fetches it from the backend again.
16
+ * @param ref - the ref of the insight to invalidate
17
+ */
18
+ invalidateInsight(ref: ObjRef): void;
13
19
  }
14
20
  /**
15
21
  * @internal
@@ -1 +1 @@
1
- {"version":3,"file":"InsightDataLoader.d.ts","sourceRoot":"","sources":["../../src/dataLoaders/InsightDataLoader.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAkB,MAAM,qBAAqB,CAAC;AAKjF;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B;;;;OAIG;IACH,UAAU,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC3E;AA4BD;;GAEG;AACH,eAAO,MAAM,wBAAwB,6DAEpC,CAAC"}
1
+ {"version":3,"file":"InsightDataLoader.d.ts","sourceRoot":"","sources":["../../src/dataLoaders/InsightDataLoader.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAkB,MAAM,qBAAqB,CAAC;AAKjF;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B;;;;OAIG;IACH,UAAU,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAExE;;;;OAIG;IACH,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACxC;AAgCD;;GAEG;AACH,eAAO,MAAM,wBAAwB,6DAEpC,CAAC"}
@@ -1,4 +1,4 @@
1
- // (C) 2021-2025 GoodData Corporation
1
+ // (C) 2021-2026 GoodData Corporation
2
2
  import { LRUCache } from "lru-cache";
3
3
  import { objRefToString } from "@gooddata/sdk-model";
4
4
  import { INSIGHT_CACHE_SIZE } from "./constants.js";
@@ -25,6 +25,9 @@ class InsightDataLoader {
25
25
  }
26
26
  return insight;
27
27
  }
28
+ invalidateInsight(ref) {
29
+ this.insightCache.delete(objRefToString(ref));
30
+ }
28
31
  }
29
32
  /**
30
33
  * @internal
@@ -1,7 +1,20 @@
1
+ import { type ObjRef } from "@gooddata/sdk-model";
1
2
  /**
2
3
  * Clears all the caches used by the InsightView components.
3
4
  *
4
5
  * @public
5
6
  */
6
7
  export declare function clearInsightViewCaches(): void;
8
+ /**
9
+ * Clears the cached definition of a single insight used by the InsightView components.
10
+ *
11
+ * @remarks
12
+ * Use this after an insight has been edited, so that the next render fetches the new
13
+ * definition. To clear every cache at once, use {@link clearInsightViewCaches}.
14
+ *
15
+ * @param workspace - the workspace the insight belongs to
16
+ * @param ref - the ref of the insight whose cached definition should be dropped
17
+ * @public
18
+ */
19
+ export declare function clearInsightViewCacheForInsight(workspace: string, ref: ObjRef): void;
7
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dataLoaders/index.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAO7C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dataLoaders/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAOlD;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAO7C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,+BAA+B,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAEpF"}
@@ -15,3 +15,17 @@ export function clearInsightViewCaches() {
15
15
  ];
16
16
  relevantFactories.forEach((factory) => factory.reset());
17
17
  }
18
+ /**
19
+ * Clears the cached definition of a single insight used by the InsightView components.
20
+ *
21
+ * @remarks
22
+ * Use this after an insight has been edited, so that the next render fetches the new
23
+ * definition. To clear every cache at once, use {@link clearInsightViewCaches}.
24
+ *
25
+ * @param workspace - the workspace the insight belongs to
26
+ * @param ref - the ref of the insight whose cached definition should be dropped
27
+ * @public
28
+ */
29
+ export function clearInsightViewCacheForInsight(workspace, ref) {
30
+ insightDataLoaderFactory.forWorkspace(workspace).invalidateInsight(ref);
31
+ }
package/esm/index.d.ts CHANGED
@@ -13,7 +13,7 @@ import { type IInsight, type IInsightDefinition, type ISettings } from "@gooddat
13
13
  import { type IDrillEvent } from "@gooddata/sdk-ui";
14
14
  export type { ChartInlineVisualizationType } from "@gooddata/sdk-ui-charts";
15
15
  import { DASHBOARD_LAYOUT_DEFAULT_VIS_HEIGHT_PX, DASHBOARD_LAYOUT_WIDGET_SIZE_INFO_DEFAULT, EmbedInsightDialog, EmptyAfmSdkError, FluidLayoutDescriptor, type IDrillDownDefinition, type IEmbedInsightDialogProps, type IFluidLayoutDescriptor, type IInsightTitleProps, type IInsightViewProps, type ILayoutDescriptor, INSIGHT_WIDGET_SIZE_INFO_DEFAULT, INSIGHT_WIDGET_SIZE_INFO_NEW_DEFAULT, type ISizeInfo, type ISizeInfoDefault, type IVisualizationDefaultSizeInfo, type IVisualizationMeta, type IVisualizationSizeInfo, KPI_WIDGET_SIZE_INFO_DEFAULT, type LayoutType, MIN_VISUALIZATION_WIDTH, PluggableVisualizationErrorCodes, type PluggableVisualizationErrorType, RICH_TEXT_WIDGET_SIZE_INFO_DEFAULT, RICH_TEXT_WIDGET_SIZE_INFO_NEW_DEFAULT, VISUALIZATION_SWITCHER_WIDGET_SIZE_INFO_DEFAULT, VISUALIZATION_SWITCHER_WIDGET_SIZE_INFO_NEW_DEFAULT, WIDGET_DROPZONE_SIZE_INFO_DEFAULT, addIntersectionFiltersToInsight, fluidLayoutDescriptor, isDrillDownDefinition, isEmptyAfm, isSizeInfo, isSizeInfoDefault, isVisualizationDefaultSizeInfo } from "./internal/index.js";
16
- export { clearInsightViewCaches } from "./dataLoaders/index.js";
16
+ export { clearInsightViewCaches, clearInsightViewCacheForInsight } from "./dataLoaders/index.js";
17
17
  export { InsightView } from "./insightView/InsightView.js";
18
18
  export { InsightError, type IInsightErrorProps } from "./insightView/InsightError.js";
19
19
  export { InsightRenderer, type IInsightRendererProps } from "./insightView/InsightRenderer.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/esm/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // (C) 2007-2026 GoodData Corporation
2
2
  import { DASHBOARD_LAYOUT_DEFAULT_VIS_HEIGHT_PX, DASHBOARD_LAYOUT_WIDGET_SIZE_INFO_DEFAULT, EmbedInsightDialog, EmptyAfmSdkError, FluidLayoutDescriptor, FullVisualizationCatalog, INSIGHT_WIDGET_SIZE_INFO_DEFAULT, INSIGHT_WIDGET_SIZE_INFO_NEW_DEFAULT, KPI_WIDGET_SIZE_INFO_DEFAULT, MIN_VISUALIZATION_WIDTH, PluggableVisualizationErrorCodes, RICH_TEXT_WIDGET_SIZE_INFO_DEFAULT, RICH_TEXT_WIDGET_SIZE_INFO_NEW_DEFAULT, VISUALIZATION_SWITCHER_WIDGET_SIZE_INFO_DEFAULT, VISUALIZATION_SWITCHER_WIDGET_SIZE_INFO_NEW_DEFAULT, WIDGET_DROPZONE_SIZE_INFO_DEFAULT, addIntersectionFiltersToInsight, fluidLayoutDescriptor, isDrillDownDefinition, isEmptyAfm, isSizeInfo, isSizeInfoDefault, isVisualizationDefaultSizeInfo, } from "./internal/index.js";
3
- export { clearInsightViewCaches } from "./dataLoaders/index.js";
3
+ export { clearInsightViewCaches, clearInsightViewCacheForInsight } from "./dataLoaders/index.js";
4
4
  export { InsightView } from "./insightView/InsightView.js";
5
5
  export { InsightError } from "./insightView/InsightError.js";
6
6
  export { InsightRenderer } from "./insightView/InsightRenderer.js";
@@ -1,4 +1,3 @@
1
- import { type WrappedComponentProps } from "react-intl";
2
1
  import { type IUserWorkspaceSettings } from "@gooddata/sdk-backend-spi";
3
2
  import { type IColorPalette, type IInsightDefinition, type IInsightWidget, type ITheme, type IWorkspacePermissions } from "@gooddata/sdk-model";
4
3
  import { type ILocale, type ITranslations, type OnError } from "@gooddata/sdk-ui";
@@ -21,17 +20,15 @@ export interface IInsightRendererProps extends Omit<IInsightViewProps, "insight"
21
20
  */
22
21
  widget?: IInsightWidget;
23
22
  }
24
- export declare const IntlInsightRenderer: import("react").FC<import("react-intl").WithIntlProps<Omit<IInsightRendererProps & WrappedComponentProps & {
23
+ type InsightRendererCoreProps = IInsightRendererProps & {
25
24
  messages: ITranslations;
26
- }, "theme" | "themeIsLoading" | "themeStatus">>> & {
27
- WrappedComponent: import("react").ComponentType<Omit<IInsightRendererProps & WrappedComponentProps & {
28
- messages: ITranslations;
29
- }, "theme" | "themeIsLoading" | "themeStatus">>;
30
25
  };
26
+ export declare const IntlInsightRenderer: import("react").ComponentType<Omit<InsightRendererCoreProps, "theme" | "themeIsLoading" | "themeStatus">>;
31
27
  /**
32
28
  * Renders insight passed as a parameter.
33
29
  *
34
30
  * @internal
35
31
  */
36
32
  export declare function InsightRenderer(props: IInsightRendererProps): import("react/jsx-runtime").JSX.Element | null;
33
+ export {};
37
34
  //# sourceMappingURL=InsightRenderer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"InsightRenderer.d.ts","sourceRoot":"","sources":["../../src/insightView/InsightRenderer.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,qBAAqB,EAAc,MAAM,YAAY,CAAC;AAOpE,OAAO,EAGH,KAAK,sBAAsB,EAC9B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACH,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,MAAM,EACX,KAAK,qBAAqB,EAM7B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAKH,KAAK,OAAO,EACZ,KAAK,aAAa,EAGlB,KAAK,OAAO,EAMf,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAGH,KAAK,iBAAiB,EAIzB,MAAM,sBAAsB,CAAC;AAE9B;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAC/C,iBAAiB,EACjB,SAAS,GAAG,gBAAgB,GAAG,iBAAiB,GAAG,WAAW,CACjE;IACG,OAAO,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACxC,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,sBAAsB,GAAG,SAAS,CAAC;IAC7C,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC,YAAY,EAAE,aAAa,GAAG,SAAS,CAAC;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB;;;OAGG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;CAC3B;AA+RD,eAAO,MAAM,mBAAmB;;;;;;CAA2D,CAAC;AAwB5F;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,qBAAqB,kDAuC3D"}
1
+ {"version":3,"file":"InsightRenderer.d.ts","sourceRoot":"","sources":["../../src/insightView/InsightRenderer.tsx"],"names":[],"mappings":"AAYA,OAAO,EAGH,KAAK,sBAAsB,EAC9B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACH,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,MAAM,EACX,KAAK,qBAAqB,EAM7B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAKH,KAAK,OAAO,EACZ,KAAK,aAAa,EAGlB,KAAK,OAAO,EAMf,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAGH,KAAK,iBAAiB,EAKzB,MAAM,sBAAsB,CAAC;AAE9B;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAC/C,iBAAiB,EACjB,SAAS,GAAG,gBAAgB,GAAG,iBAAiB,GAAG,WAAW,CACjE;IACG,OAAO,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACxC,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,sBAAsB,GAAG,SAAS,CAAC;IAC7C,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC,YAAY,EAAE,aAAa,GAAG,SAAS,CAAC;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB;;;OAGG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED,KAAK,wBAAwB,GAAG,qBAAqB,GAAG;IAAE,QAAQ,EAAE,aAAa,CAAA;CAAE,CAAC;AAuVpF,eAAO,MAAM,mBAAmB,2GAA+C,CAAC;AAwBhF;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,qBAAqB,kDAuC3D"}
@@ -1,9 +1,8 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  // (C) 2020-2026 GoodData Corporation
3
- import { PureComponent, createRef, useCallback, useEffect, useRef } from "react";
3
+ import { memo, useCallback, useEffect, useRef, useState } from "react";
4
4
  import { isEqual } from "lodash-es";
5
5
  import { createRoot } from "react-dom/client";
6
- import { injectIntl } from "react-intl";
7
6
  import { v4 as uuidv4 } from "uuid";
8
7
  import { ExecutionFactoryUpgradingToExecByReference, ExecutionFactoryWithFixedFilters, } from "@gooddata/sdk-backend-base";
9
8
  import { insightProperties, insightSetProperties, insightTitle, insightVisualizationType, insightVisualizationUrl, } from "@gooddata/sdk-model";
@@ -17,58 +16,95 @@ const visualizationUriRootStyle = {
17
16
  flex: "1 1 auto",
18
17
  flexDirection: "column",
19
18
  };
20
- // this needs to be a pure component as it can happen that this might be rendered multiple times
19
+ const noop = () => { };
20
+ const defaultFilters = [];
21
+ const defaultDrillableItems = [];
22
+ /**
23
+ * Applies the defaults on the props. The values used as defaults are referentially stable so that they do not
24
+ * trigger any unnecessary work down the line.
25
+ */
26
+ const resolveProps = (props) => ({
27
+ ...props,
28
+ ErrorComponent: props.ErrorComponent ?? ErrorComponent,
29
+ filters: props.filters ?? defaultFilters,
30
+ drillableItems: props.drillableItems ?? defaultDrillableItems,
31
+ LoadingComponent: props.LoadingComponent ?? LoadingComponent,
32
+ pushData: props.pushData ?? noop,
33
+ locale: props.locale ?? DefaultLocale,
34
+ afterRender: props.afterRender ?? noop,
35
+ });
36
+ // this needs to be a memoized component as it can happen that this might be rendered multiple times
21
37
  // with the same props (referentially) - this might make the rendered visualization behave unpredictably
22
38
  // and is bad for performance so we need to make sure the re-renders are performed only if necessary
23
- class InsightRendererCore extends PureComponent {
24
- elementId = getElementId();
25
- visualization;
26
- containerRef = createRef();
39
+ const InsightRendererCore = memo(function InsightRendererCore(props) {
40
+ const currentProps = resolveProps(props);
41
+ const [elementId] = useState(getElementId);
42
+ const visualizationRef = useRef(undefined);
43
+ const containerRef = useRef(null);
27
44
  /**
28
45
  * The component may render both visualization and config panel. In React18 we therefore need two
29
46
  * roots with their respective render methods. This Map holds the roots for both and provides
30
47
  * render and unmount methods whenever needed.
31
48
  */
32
- reactRootsMap = new Map();
33
- static defaultProps = {
34
- ErrorComponent,
35
- filters: [],
36
- drillableItems: [],
37
- LoadingComponent,
38
- pushData: () => { },
39
- locale: DefaultLocale,
40
- afterRender: () => { },
41
- };
42
- unmountVisualization = () => {
43
- if (this.visualization) {
44
- this.visualization.unmount();
49
+ const reactRootsMapRef = useRef(new Map());
50
+ /**
51
+ * The callbacks and element getters below outlive the render they were created in (the visualization
52
+ * instance only ever gets the ones from the render it was set up in). They therefore read the props from
53
+ * this ref to always see the current values - the very same way `this.props` did before.
54
+ *
55
+ * This effect must stay first so that the ref is up to date before any other effect runs.
56
+ */
57
+ const propsRef = useRef(currentProps);
58
+ useEffect(() => {
59
+ propsRef.current = currentProps;
60
+ });
61
+ const unmountVisualization = useCallback(() => {
62
+ if (visualizationRef.current) {
63
+ visualizationRef.current.unmount();
64
+ }
65
+ visualizationRef.current = undefined;
66
+ }, []);
67
+ const getExecutionFactory = useCallback(() => {
68
+ const { backend, workspace, executeByReference, filters } = propsRef.current;
69
+ const factory = backend.workspace(workspace).execution();
70
+ if (executeByReference) {
71
+ /*
72
+ * When executing by reference, decorate the original execution factory so that it
73
+ * transparently routes `forInsight` to `forInsightByRef` AND adds the filters
74
+ * from InsightView props.
75
+ *
76
+ * Code will pass this factory over to the pluggable visualizations - they will do execution
77
+ * `forInsight` and under the covers things will be routed and done differently without the
78
+ * plug viz knowing.
79
+ */
80
+ return new ExecutionFactoryUpgradingToExecByReference(new ExecutionFactoryWithFixedFilters(factory, filters));
45
81
  }
46
- this.visualization = undefined;
47
- };
48
- updateVisualization = () => {
82
+ return factory;
83
+ }, []);
84
+ const updateVisualization = useCallback(() => {
49
85
  // if the container no longer exists, update was called after unmount -> do nothing
50
- if (!this.visualization || !this.containerRef.current) {
86
+ if (!visualizationRef.current || !containerRef.current) {
51
87
  return;
52
88
  }
89
+ const { insight: insightProp, config = {}, settings, locale, messages, widget, drillableItems, colorPalette, execConfig, theme, } = propsRef.current;
53
90
  // if there is no insight, bail early
54
- if (!this.props.insight) {
91
+ if (!insightProp) {
55
92
  return;
56
93
  }
57
- const { config = {} } = this.props;
58
- const { responsiveUiDateFormat } = this.props.settings ?? {};
94
+ const { responsiveUiDateFormat } = settings ?? {};
59
95
  const visProps = {
60
- locale: this.props.locale,
61
- messages: this.props.messages,
96
+ locale,
97
+ messages,
62
98
  dateFormat: responsiveUiDateFormat,
63
- a11yTitle: this.props.widget?.title,
64
- a11yDescription: this.props.widget?.description,
99
+ a11yTitle: widget?.title,
100
+ a11yDescription: widget?.description,
65
101
  custom: {
66
- drillableItems: this.props.drillableItems,
67
- lastSavedVisClassUrl: insightVisualizationUrl(this.props.insight),
102
+ drillableItems,
103
+ lastSavedVisClassUrl: insightVisualizationUrl(insightProp),
68
104
  },
69
105
  config: {
70
106
  separators: config.separators,
71
- colorPalette: this.props.colorPalette,
107
+ colorPalette,
72
108
  mapboxToken: config.mapboxToken,
73
109
  agGridToken: config.agGridToken,
74
110
  forceDisableDrillOnAxes: config.forceDisableDrillOnAxes,
@@ -76,13 +112,13 @@ class InsightRendererCore extends PureComponent {
76
112
  isExportMode: config.isExportMode,
77
113
  enableExecutionCancelling: config.enableExecutionCancelling,
78
114
  },
79
- executionConfig: this.props.execConfig,
115
+ executionConfig: execConfig,
80
116
  customVisualizationConfig: config,
81
- theme: this.props.theme,
117
+ theme,
82
118
  supportsChartFill: config.supportsChartFill,
83
119
  };
84
- const visClass = insightVisualizationType(this.props.insight);
85
- const filled = fillMissingTitlesWithMessages(this.props.insight, this.props.locale, this.props.messages, undefined);
120
+ const visClass = insightVisualizationType(insightProp);
121
+ const filled = fillMissingTitlesWithMessages(insightProp, locale, messages, undefined);
86
122
  let insight = fillMissingFormats(filled);
87
123
  /**
88
124
  * Ignore titles for simple measures in all visualizations except for repeater.
@@ -95,29 +131,60 @@ class InsightRendererCore extends PureComponent {
95
131
  if (visClass !== "repeater") {
96
132
  insight = ignoreTitlesForSimpleMeasures(insight);
97
133
  }
98
- this.visualization?.update(visProps, insight, {}, this.getExecutionFactory());
99
- };
100
- setupVisualization = () => {
134
+ visualizationRef.current?.update(visProps, insight, {}, getExecutionFactory());
135
+ }, [getExecutionFactory]);
136
+ const reactRenderFunction = useCallback((children, element) => {
137
+ if (!element) {
138
+ return;
139
+ }
140
+ const htmlElement = element;
141
+ if (!reactRootsMapRef.current.get(htmlElement)) {
142
+ reactRootsMapRef.current.set(htmlElement, createRoot(htmlElement));
143
+ }
144
+ reactRootsMapRef.current.get(htmlElement).render(children);
145
+ }, []);
146
+ const reactUnmountFunction = useCallback(() => {
147
+ reactRootsMapRef.current.forEach((root) => root.render(null));
148
+ }, []);
149
+ const onExportReadyDecorator = useCallback((exportFunction) => {
150
+ const { onExportReady } = propsRef.current;
151
+ if (!onExportReady) {
152
+ return;
153
+ }
154
+ const decorator = (exportConfig) => {
155
+ const { insight } = propsRef.current;
156
+ if (exportConfig.title || !insight) {
157
+ return exportFunction(exportConfig);
158
+ }
159
+ return exportFunction({
160
+ ...exportConfig,
161
+ title: insightTitle(insight),
162
+ });
163
+ };
164
+ onExportReady(decorator);
165
+ }, []);
166
+ const setupVisualization = useCallback(() => {
167
+ const { insight, settings, backend, workspace, permissions, locale, messages, pushData, onDrill, onDataView, onLoadingChanged, afterRender, } = propsRef.current;
101
168
  // if there is no insight, bail early
102
- if (!this.props.insight) {
169
+ if (!insight) {
103
170
  return;
104
171
  }
105
172
  // the visualization we may have from earlier is no longer valid -> get rid of it
106
- this.unmountVisualization();
107
- const visualizationFactory = FullVisualizationCatalog.forInsight(this.props.insight, this.props.settings?.enableNewPivotTable ?? true, this.props.settings?.enableNewGeoPushpin ?? false).getFactory();
108
- this.visualization = visualizationFactory({
109
- backend: this.props.backend,
173
+ unmountVisualization();
174
+ const visualizationFactory = FullVisualizationCatalog.forInsight(insight, settings?.enableNewPivotTable ?? true, settings?.enableNewGeoPushpin ?? false).getFactory();
175
+ visualizationRef.current = visualizationFactory({
176
+ backend: backend,
110
177
  callbacks: {
111
178
  onError: (error) => {
112
- this.props.onError?.(error);
113
- this.props.onLoadingChanged?.({ isLoading: false });
179
+ propsRef.current.onError?.(error);
180
+ propsRef.current.onLoadingChanged?.({ isLoading: false });
114
181
  },
115
- onLoadingChanged: this.props.onLoadingChanged,
116
- pushData: this.props.pushData,
117
- onDrill: this.props.onDrill,
118
- onDataView: this.props.onDataView,
119
- onExportReady: this.onExportReadyDecorator,
120
- afterRender: this.props.afterRender,
182
+ onLoadingChanged,
183
+ pushData,
184
+ onDrill,
185
+ onDataView,
186
+ onExportReady: onExportReadyDecorator,
187
+ afterRender,
121
188
  },
122
189
  // This renderer has no configuration panel of its own — it renders read-only insights.
123
190
  // It used to resolve the panel with a document-wide lookup of the well-known
@@ -130,107 +197,63 @@ class InsightRendererCore extends PureComponent {
130
197
  // fix STL-3184
131
198
  configPanelElement: () => null,
132
199
  element: () => {
133
- const rootNode = this.containerRef.current?.getRootNode() ?? document;
134
- return rootNode.querySelector(`#${this.elementId}`);
200
+ const rootNode = containerRef.current?.getRootNode() ?? document;
201
+ return rootNode.querySelector(`#${elementId}`);
135
202
  },
136
203
  environment: "dashboards", // TODO get rid of this
137
- locale: this.props.locale,
138
- messages: this.props.messages,
139
- projectId: this.props.workspace,
140
- visualizationProperties: insightProperties(this.props.insight),
141
- featureFlags: this.props.settings,
142
- permissions: this.props.permissions,
143
- renderFun: this.getReactRenderFunction(),
144
- unmountFun: this.getReactUnmountFunction(),
204
+ locale,
205
+ messages,
206
+ projectId: workspace,
207
+ visualizationProperties: insightProperties(insight),
208
+ featureFlags: settings,
209
+ permissions,
210
+ renderFun: reactRenderFunction,
211
+ unmountFun: reactUnmountFunction,
145
212
  });
146
- };
147
- getReactRenderFunction = () => {
148
- return (children, element) => {
149
- if (!element) {
150
- return;
151
- }
152
- const htmlElement = element;
153
- if (!this.reactRootsMap.get(htmlElement)) {
154
- this.reactRootsMap.set(htmlElement, createRoot(htmlElement));
155
- }
156
- this.reactRootsMap.get(htmlElement).render(children);
157
- };
158
- };
159
- getReactUnmountFunction = () => {
160
- return () => this.reactRootsMap.forEach((root) => root.render(null));
161
- };
162
- onExportReadyDecorator = (exportFunction) => {
163
- if (!this.props.onExportReady) {
213
+ }, [elementId, onExportReadyDecorator, reactRenderFunction, reactUnmountFunction, unmountVisualization]);
214
+ const prevPropsRef = useRef(undefined);
215
+ // componentDidMount & componentDidUpdate: intentionally without dependencies so that it runs after
216
+ // every render of this (memoized) component
217
+ useEffect(() => {
218
+ const prevProps = prevPropsRef.current;
219
+ prevPropsRef.current = currentProps;
220
+ if (!prevProps) {
221
+ setupVisualization();
222
+ updateVisualization();
164
223
  return;
165
224
  }
166
- const decorator = (exportConfig) => {
167
- if (exportConfig.title || !this.props.insight) {
168
- return exportFunction(exportConfig);
169
- }
170
- return exportFunction({
171
- ...exportConfig,
172
- title: insightTitle(this.props.insight),
173
- });
174
- };
175
- this.props.onExportReady(decorator);
176
- };
177
- getExecutionFactory = () => {
178
- const factory = this.props.backend.workspace(this.props.workspace).execution();
179
- if (this.props.executeByReference) {
180
- /*
181
- * When executing by reference, decorate the original execution factory so that it
182
- * transparently routes `forInsight` to `forInsightByRef` AND adds the filters
183
- * from InsightView props.
184
- *
185
- * Code will pass this factory over to the pluggable visualizations - they will do execution
186
- * `forInsight` and under the covers things will be routed and done differently without the
187
- * plug viz knowing.
188
- */
189
- return new ExecutionFactoryUpgradingToExecByReference(new ExecutionFactoryWithFixedFilters(factory, this.props.filters));
190
- }
191
- return factory;
192
- };
193
- componentDidMountInner = () => {
194
- this.setupVisualization();
195
- return this.updateVisualization();
196
- };
197
- componentDidMount() {
198
- this.componentDidMountInner();
199
- }
200
- componentDidUpdateInner = (prevProps) => {
201
225
  /**
202
226
  * Ignore properties when comparing insights to determine if a new setup is needed: changes to properties
203
227
  * only will be handled using the updateVisualization without unnecessary new setup just fine.
204
228
  */
205
229
  const prevInsightForCompare = prevProps.insight && insightSetProperties(prevProps.insight, {});
206
- const newInsightForCompare = this.props.insight && insightSetProperties(this.props.insight, {});
230
+ const newInsightForCompare = currentProps.insight && insightSetProperties(currentProps.insight, {});
207
231
  const needsNewSetup = !isEqual(newInsightForCompare, prevInsightForCompare) ||
208
- !isEqual(this.props.filters, prevProps.filters) ||
209
- !isEqual(this.props.settings, prevProps.settings) ||
210
- this.props.workspace !== prevProps.workspace;
232
+ !isEqual(currentProps.filters, prevProps.filters) ||
233
+ !isEqual(currentProps.settings, prevProps.settings) ||
234
+ currentProps.workspace !== prevProps.workspace;
211
235
  if (needsNewSetup) {
212
- this.setupVisualization();
236
+ setupVisualization();
213
237
  }
214
- return this.updateVisualization();
215
- };
216
- componentDidUpdate(prevProps) {
217
- this.componentDidUpdateInner(prevProps);
218
- }
219
- componentWillUnmount() {
220
- this.unmountVisualization();
221
- // In order to avoid race conditions when mounting and unmounting synchronously,
222
- // we use timeout for React18.
223
- // https://github.com/facebook/react/issues/25675
224
- this.reactRootsMap.forEach((root) => setTimeout(() => root.unmount(), 0));
225
- }
226
- render() {
227
- return (
228
- // never ever dynamically change the props of this div, otherwise bad things will happen
229
- // e.g. visualization being rendered multiple times, etc.
230
- _jsx("div", { className: "visualization-uri-root", id: this.elementId, ref: this.containerRef, style: visualizationUriRootStyle }));
231
- }
232
- }
233
- export const IntlInsightRenderer = injectIntl(withTheme(withContexts(InsightRendererCore)));
238
+ updateVisualization();
239
+ });
240
+ // componentWillUnmount
241
+ useEffect(() => {
242
+ const reactRootsMap = reactRootsMapRef.current;
243
+ return () => {
244
+ unmountVisualization();
245
+ // In order to avoid race conditions when mounting and unmounting synchronously,
246
+ // we use timeout for React18.
247
+ // https://github.com/facebook/react/issues/25675
248
+ reactRootsMap.forEach((root) => setTimeout(() => root.unmount(), 0));
249
+ };
250
+ }, [unmountVisualization]);
251
+ return (
252
+ // never ever dynamically change the props of this div, otherwise bad things will happen
253
+ // e.g. visualization being rendered multiple times, etc.
254
+ _jsx("div", { className: "visualization-uri-root", id: elementId, ref: containerRef, style: visualizationUriRootStyle }));
255
+ });
256
+ export const IntlInsightRenderer = withTheme(withContexts(InsightRendererCore));
234
257
  /**
235
258
  * Updated callback (callback with a different reference) is not properly propagated to the "visualization" instance
236
259
  * (because it only takes the callbacks provided on the first render)
@@ -1,15 +1,14 @@
1
1
  import { type IDateFilterOptionsByType } from "@gooddata/sdk-ui-filters";
2
2
  import { type ConditionalFormattingValue } from "@gooddata/sdk-ui-pivot/next";
3
+ import { type ICfFieldProps } from "./cfFieldProps.js";
3
4
  import { type ICfDateMeta, type ICfDateSettings } from "./conditionalFormattingModel.js";
4
- export interface ICfDateValueDropdownProps {
5
+ export interface ICfDateValueDropdownProps extends ICfFieldProps {
5
6
  value: ConditionalFormattingValue;
6
7
  date: ICfDateMeta;
7
8
  /** Workspace preset catalog (shared with the dashboard date filter); undefined = static only. */
8
9
  catalogOptions?: IDateFilterOptionsByType;
9
10
  /** Workspace date-display settings (format, week start). */
10
11
  dateSettings?: ICfDateSettings;
11
- /** Id of the rendered inline error, associated with the trigger for assistive tech. */
12
- errorId?: string;
13
12
  onChange: (value: ConditionalFormattingValue) => void;
14
13
  }
15
14
  /**
@@ -21,5 +20,5 @@ export interface ICfDateValueDropdownProps {
21
20
  * already-shifted range (no flag), and reopening reconstructs the preset + checked toggle by
22
21
  * matching the stored range against "preset shifted by one".
23
22
  */
24
- export declare function CfDateValueDropdown({ value, date, catalogOptions, dateSettings, errorId, onChange }: ICfDateValueDropdownProps): import("react/jsx-runtime").JSX.Element;
23
+ export declare function CfDateValueDropdown({ value, date, catalogOptions, dateSettings, hasError, errorId, onChange, onVisit }: ICfDateValueDropdownProps): import("react/jsx-runtime").JSX.Element;
25
24
  //# sourceMappingURL=CfDateValueDropdown.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CfDateValueDropdown.d.ts","sourceRoot":"","sources":["../../../../../src/internal/components/configurationControls/conditionalFormatting/CfDateValueDropdown.tsx"],"names":[],"mappings":"AAQA,OAAO,EAKH,KAAK,wBAAwB,EAIhC,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACH,KAAK,0BAA0B,EAKlC,MAAM,6BAA6B,CAAC;AAIrC,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,iCAAiC,CAAC;AA6GzF,MAAM,WAAW,yBAAyB;IACtC,KAAK,EAAE,0BAA0B,CAAC;IAClC,IAAI,EAAE,WAAW,CAAC;IAClB,iGAAiG;IACjG,cAAc,CAAC,EAAE,wBAAwB,CAAC;IAC1C,4DAA4D;IAC5D,YAAY,CAAC,EAAE,eAAe,CAAC;IAC/B,uFAAuF;IACvF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,CAAC,KAAK,EAAE,0BAA0B,KAAK,IAAI,CAAC;CACzD;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,EAChC,KAAK,EACL,IAAI,EACJ,cAAc,EACd,YAAY,EACZ,OAAO,EACP,QAAQ,EACX,EAAE,yBAAyB,2CA4E3B"}
1
+ {"version":3,"file":"CfDateValueDropdown.d.ts","sourceRoot":"","sources":["../../../../../src/internal/components/configurationControls/conditionalFormatting/CfDateValueDropdown.tsx"],"names":[],"mappings":"AAQA,OAAO,EAKH,KAAK,wBAAwB,EAIhC,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACH,KAAK,0BAA0B,EAKlC,MAAM,6BAA6B,CAAC;AAIrC,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,iCAAiC,CAAC;AA4GzF,MAAM,WAAW,yBAA0B,SAAQ,aAAa;IAC5D,KAAK,EAAE,0BAA0B,CAAC;IAClC,IAAI,EAAE,WAAW,CAAC;IAClB,iGAAiG;IACjG,cAAc,CAAC,EAAE,wBAAwB,CAAC;IAC1C,4DAA4D;IAC5D,YAAY,CAAC,EAAE,eAAe,CAAC;IAC/B,QAAQ,EAAE,CAAC,KAAK,EAAE,0BAA0B,KAAK,IAAI,CAAC;CACzD;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,EAChC,KAAK,EACL,IAAI,EACJ,cAAc,EACd,YAAY,EACZ,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,OAAO,EACV,EAAE,yBAAyB,2CA+E3B"}
@@ -65,15 +65,14 @@ function matchStoredValue(value, absoluteForm, filterOptions, granularity) {
65
65
  }
66
66
  return matchDateFilterToDateFilterOptionWithPreference(storedFilter, filterOptions, undefined);
67
67
  }
68
- // DateFilter's button contract is fixed, so the error association travels via context.
68
+ // DateFilter's button contract is fixed, so the error state travels via context.
69
69
  const CfDateButtonA11yContext = createContext({});
70
70
  // Rendered through DateFilter's button slot. Module-level so its identity is stable across renders.
71
71
  // Deliberately NOT wiring props.onClick: DateFilterCore's wrapping span already toggles the dropdown,
72
72
  // so wiring both toggles it twice per click (open → instantly closed).
73
73
  function CfDateButton({ customFilterName, textSubtitle, isOpen, buttonRef, dropdownId, }) {
74
- // describedBy is only set while the value has an inline error — it doubles as the error state.
75
- const { describedBy } = useContext(CfDateButtonA11yContext);
76
- return (_jsx(DropdownButton, { className: cx("gd-cf-date-value", { "gd-cf-date-value--error": describedBy !== undefined }), value: customFilterName ?? textSubtitle, isOpen: isOpen, isFullWidth: true, buttonRef: buttonRef, dropdownId: dropdownId, accessibilityConfig: describedBy ? { ariaDescribedBy: describedBy } : undefined }));
74
+ const { describedBy, hasError } = useContext(CfDateButtonA11yContext);
75
+ return (_jsx(DropdownButton, { className: cx("gd-cf-date-value", { "gd-cf-date-value--error": hasError }), value: customFilterName ?? textSubtitle, isOpen: isOpen, isFullWidth: true, buttonRef: buttonRef, dropdownId: dropdownId, accessibilityConfig: describedBy ? { ariaDescribedBy: describedBy } : undefined }));
77
76
  }
78
77
  /**
79
78
  * The value picker of a date condition: the standard DateFilter embedded with a dialog-styled
@@ -84,7 +83,7 @@ function CfDateButton({ customFilterName, textSubtitle, isOpen, buttonRef, dropd
84
83
  * already-shifted range (no flag), and reopening reconstructs the preset + checked toggle by
85
84
  * matching the stored range against "preset shifted by one".
86
85
  */
87
- export function CfDateValueDropdown({ value, date, catalogOptions, dateSettings, errorId, onChange, }) {
86
+ export function CfDateValueDropdown({ value, date, catalogOptions, dateSettings, hasError, errorId, onChange, onVisit, }) {
88
87
  const intl = useIntl();
89
88
  const stored = value.kind === "absoluteDate" ? { from: value.from, to: value.to } : undefined;
90
89
  // The static form needs bounds to open on; pin the current period at mount (recomputing "now"
@@ -131,10 +130,13 @@ export function CfDateValueDropdown({ value, date, catalogOptions, dateSettings,
131
130
  }
132
131
  // allTime/emptyValues never appear among the options (the All time / Is empty operators cover them).
133
132
  };
134
- return (_jsx(CfDateButtonA11yContext.Provider, { value: { describedBy: errorId }, children: _jsx(DateFilter, { dateFilterMode: "active", filterOptions: filterOptions, availableGranularities: filterOptions.relativeForm ? [...allowedValueGranularities(date.granularity)] : [], selectedFilterOption: matched.dateFilterOption, excludeCurrentPeriod: matched.excludeCurrentPeriod, isTimeForAbsoluteRangeEnabled: usesTimeResolution(date.granularity), dateFormat: dateSettings?.dateFormat,
133
+ return (_jsx(CfDateButtonA11yContext.Provider, { value: { describedBy: errorId, hasError }, children: _jsx(DateFilter, { dateFilterMode: "active", filterOptions: filterOptions, availableGranularities: filterOptions.relativeForm ? [...allowedValueGranularities(date.granularity)] : [], selectedFilterOption: matched.dateFilterOption, excludeCurrentPeriod: matched.excludeCurrentPeriod, isTimeForAbsoluteRangeEnabled: usesTimeResolution(date.granularity), dateFormat: dateSettings?.dateFormat,
135
134
  // Week columns pin Monday: the resolver snaps ISO weeks, and a Sunday-start calendar
136
135
  // would let a selection straddle the snap boundary.
137
- weekStart: date.granularity === "GDC.time.week_us" ? "Monday" : dateSettings?.weekStart, locale: intl.locale, onApply: handleApply, overlayPositionType: "sameAsTarget", ButtonComponent: CfDateButton, customFilterName: value.kind === "none"
136
+ weekStart: date.granularity === "GDC.time.week_us" ? "Monday" : dateSettings?.weekStart, locale: intl.locale, onApply: handleApply,
137
+ // Every close counts as a visit, applied or not. Blur can't serve as that signal: opening
138
+ // the picker moves focus into its own overlay.
139
+ onClose: onVisit, overlayPositionType: "sameAsTarget", ButtonComponent: CfDateButton, customFilterName: value.kind === "none"
138
140
  ? intl.formatMessage(conditionalFormattingMessages.dialogSelectPeriod)
139
141
  : undefined }) }));
140
142
  }