@gooddata/sdk-ui-ext 11.53.0-alpha.1 → 11.53.0-alpha.3

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 (86) hide show
  1. package/NOTICE +6 -6
  2. package/esm/insightView/InsightRenderer.d.ts +3 -6
  3. package/esm/insightView/InsightRenderer.d.ts.map +1 -1
  4. package/esm/insightView/InsightRenderer.js +193 -143
  5. package/esm/internal/components/BaseVisualization.d.ts +6 -33
  6. package/esm/internal/components/BaseVisualization.d.ts.map +1 -1
  7. package/esm/internal/components/BaseVisualization.js +255 -213
  8. package/esm/internal/index.d.ts +1 -1
  9. package/esm/internal/index.d.ts.map +1 -1
  10. package/esm/internal/index.js +1 -1
  11. package/esm/internal/translations/de-DE.localization-bundle.d.ts +4 -0
  12. package/esm/internal/translations/de-DE.localization-bundle.d.ts.map +1 -1
  13. package/esm/internal/translations/de-DE.localization-bundle.js +4 -0
  14. package/esm/internal/translations/en-AU.localization-bundle.d.ts +4 -0
  15. package/esm/internal/translations/en-AU.localization-bundle.d.ts.map +1 -1
  16. package/esm/internal/translations/en-AU.localization-bundle.js +4 -0
  17. package/esm/internal/translations/en-GB.localization-bundle.d.ts +4 -0
  18. package/esm/internal/translations/en-GB.localization-bundle.d.ts.map +1 -1
  19. package/esm/internal/translations/en-GB.localization-bundle.js +4 -0
  20. package/esm/internal/translations/es-419.localization-bundle.d.ts +4 -0
  21. package/esm/internal/translations/es-419.localization-bundle.d.ts.map +1 -1
  22. package/esm/internal/translations/es-419.localization-bundle.js +4 -0
  23. package/esm/internal/translations/es-ES.localization-bundle.d.ts +4 -0
  24. package/esm/internal/translations/es-ES.localization-bundle.d.ts.map +1 -1
  25. package/esm/internal/translations/es-ES.localization-bundle.js +4 -0
  26. package/esm/internal/translations/fi-FI.localization-bundle.d.ts +4 -0
  27. package/esm/internal/translations/fi-FI.localization-bundle.d.ts.map +1 -1
  28. package/esm/internal/translations/fi-FI.localization-bundle.js +4 -0
  29. package/esm/internal/translations/fr-CA.localization-bundle.d.ts +4 -0
  30. package/esm/internal/translations/fr-CA.localization-bundle.d.ts.map +1 -1
  31. package/esm/internal/translations/fr-CA.localization-bundle.js +4 -0
  32. package/esm/internal/translations/fr-FR.localization-bundle.d.ts +4 -0
  33. package/esm/internal/translations/fr-FR.localization-bundle.d.ts.map +1 -1
  34. package/esm/internal/translations/fr-FR.localization-bundle.js +4 -0
  35. package/esm/internal/translations/id-ID.localization-bundle.d.ts +4 -0
  36. package/esm/internal/translations/id-ID.localization-bundle.d.ts.map +1 -1
  37. package/esm/internal/translations/id-ID.localization-bundle.js +4 -0
  38. package/esm/internal/translations/it-IT.localization-bundle.d.ts +4 -0
  39. package/esm/internal/translations/it-IT.localization-bundle.d.ts.map +1 -1
  40. package/esm/internal/translations/it-IT.localization-bundle.js +4 -0
  41. package/esm/internal/translations/ja-JP.localization-bundle.d.ts +4 -0
  42. package/esm/internal/translations/ja-JP.localization-bundle.d.ts.map +1 -1
  43. package/esm/internal/translations/ja-JP.localization-bundle.js +4 -0
  44. package/esm/internal/translations/ko-KR.localization-bundle.d.ts +4 -0
  45. package/esm/internal/translations/ko-KR.localization-bundle.d.ts.map +1 -1
  46. package/esm/internal/translations/ko-KR.localization-bundle.js +4 -0
  47. package/esm/internal/translations/nl-NL.localization-bundle.d.ts +4 -0
  48. package/esm/internal/translations/nl-NL.localization-bundle.d.ts.map +1 -1
  49. package/esm/internal/translations/nl-NL.localization-bundle.js +4 -0
  50. package/esm/internal/translations/pl-PL.localization-bundle.d.ts +4 -0
  51. package/esm/internal/translations/pl-PL.localization-bundle.d.ts.map +1 -1
  52. package/esm/internal/translations/pl-PL.localization-bundle.js +4 -0
  53. package/esm/internal/translations/pt-BR.localization-bundle.d.ts +4 -0
  54. package/esm/internal/translations/pt-BR.localization-bundle.d.ts.map +1 -1
  55. package/esm/internal/translations/pt-BR.localization-bundle.js +4 -0
  56. package/esm/internal/translations/pt-PT.localization-bundle.d.ts +4 -0
  57. package/esm/internal/translations/pt-PT.localization-bundle.d.ts.map +1 -1
  58. package/esm/internal/translations/pt-PT.localization-bundle.js +4 -0
  59. package/esm/internal/translations/ru-RU.localization-bundle.d.ts +4 -0
  60. package/esm/internal/translations/ru-RU.localization-bundle.d.ts.map +1 -1
  61. package/esm/internal/translations/ru-RU.localization-bundle.js +4 -0
  62. package/esm/internal/translations/sl-SI.localization-bundle.d.ts +4 -0
  63. package/esm/internal/translations/sl-SI.localization-bundle.d.ts.map +1 -1
  64. package/esm/internal/translations/sl-SI.localization-bundle.js +4 -0
  65. package/esm/internal/translations/th-TH.localization-bundle.d.ts +4 -0
  66. package/esm/internal/translations/th-TH.localization-bundle.d.ts.map +1 -1
  67. package/esm/internal/translations/th-TH.localization-bundle.js +4 -0
  68. package/esm/internal/translations/tr-TR.localization-bundle.d.ts +4 -0
  69. package/esm/internal/translations/tr-TR.localization-bundle.d.ts.map +1 -1
  70. package/esm/internal/translations/tr-TR.localization-bundle.js +4 -0
  71. package/esm/internal/translations/uk-UA.localization-bundle.d.ts +4 -0
  72. package/esm/internal/translations/uk-UA.localization-bundle.d.ts.map +1 -1
  73. package/esm/internal/translations/uk-UA.localization-bundle.js +4 -0
  74. package/esm/internal/translations/vi-VN.localization-bundle.d.ts +4 -0
  75. package/esm/internal/translations/vi-VN.localization-bundle.d.ts.map +1 -1
  76. package/esm/internal/translations/vi-VN.localization-bundle.js +4 -0
  77. package/esm/internal/translations/zh-HK.localization-bundle.d.ts +4 -0
  78. package/esm/internal/translations/zh-HK.localization-bundle.d.ts.map +1 -1
  79. package/esm/internal/translations/zh-HK.localization-bundle.js +4 -0
  80. package/esm/internal/translations/zh-Hans.localization-bundle.d.ts +4 -0
  81. package/esm/internal/translations/zh-Hans.localization-bundle.d.ts.map +1 -1
  82. package/esm/internal/translations/zh-Hans.localization-bundle.js +4 -0
  83. package/esm/internal/translations/zh-Hant.localization-bundle.d.ts +4 -0
  84. package/esm/internal/translations/zh-Hant.localization-bundle.d.ts.map +1 -1
  85. package/esm/internal/translations/zh-Hant.localization-bundle.js +4 -0
  86. package/package.json +21 -21
package/NOTICE CHANGED
@@ -7,9 +7,9 @@
7
7
 
8
8
  The following 3rd-party software packages may be used by or distributed with gooddata-ui-sdk. Any information relevant to third-party vendors listed below are collected using common, reasonable means.
9
9
 
10
- Date generated: 2026-8-13
10
+ Date generated: 2026-8-17
11
11
 
12
- Revision ID: 03b276147864f291b2ed2694a19ccbfa1d69ce6b
12
+ Revision ID: a87db0e8382a288c7d652219ae8787851fb066a3
13
13
 
14
14
  ================================================================================
15
15
  ================================================================================
@@ -375,7 +375,7 @@ Revision ID: 03b276147864f291b2ed2694a19ccbfa1d69ce6b
375
375
  - balanced-match (2.0.0) [MIT]
376
376
  - balanced-match (4.0.4) [MIT]
377
377
  - base64-js (1.5.1) [MIT]
378
- - baseline-browser-mapping (2.11.13) [Apache-2.0]
378
+ - baseline-browser-mapping (2.11.14) [Apache-2.0]
379
379
  - batch (0.6.1) [MIT]
380
380
  - binary-extensions (2.3.0) [MIT]
381
381
  - bl (4.1.0) [MIT]
@@ -5303,9 +5303,9 @@ MIT
5303
5303
 
5304
5304
 
5305
5305
  --------------------------------------------------------------------------------
5306
- Package Title: baseline-browser-mapping (2.11.13)
5306
+ Package Title: baseline-browser-mapping (2.11.14)
5307
5307
 
5308
- Package Locator: npm+baseline-browser-mapping$2.11.13
5308
+ Package Locator: npm+baseline-browser-mapping$2.11.14
5309
5309
 
5310
5310
  Package Depth: Transitive
5311
5311
  --------------------------------------------------------------------------------
@@ -29407,4 +29407,4 @@ POSSIBILITY OF SUCH DAMAGE.
29407
29407
  --------------------------------------------------------------------------------
29408
29408
  --------------------------------------------------------------------------------
29409
29409
 
29410
- Report Generated by FOSSA on 2026-8-13
29410
+ Report Generated by FOSSA on 2026-8-17
@@ -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<InsightRendererCoreProps>;
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;AAuXpF,eAAO,MAAM,mBAAmB,yDAAoC,CAAC;AAwBrE;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,qBAAqB,kDAuC3D"}
@@ -1,14 +1,13 @@
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, useLayoutEffect, 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";
10
9
  import { DefaultLocale, ErrorComponent, IntlWrapper, LoadingComponent, fillMissingFormats, fillMissingTitlesWithMessages, ignoreTitlesForSimpleMeasures, useResolveMessages, withContexts, } from "@gooddata/sdk-ui";
11
- import { withTheme } from "@gooddata/sdk-ui-theme-provider";
10
+ import { useTheme } from "@gooddata/sdk-ui-theme-provider";
12
11
  import { DEFAULT_MESSAGES, FullVisualizationCatalog, resolveMessages, } from "../internal/index.js";
13
12
  const getElementId = () => `gd-vis-${uuidv4()}`;
14
13
  const visualizationUriRootStyle = {
@@ -17,58 +16,102 @@ 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 theme = useTheme();
41
+ const currentProps = { ...resolveProps(props), theme };
42
+ const [elementId] = useState(getElementId);
43
+ const visualizationRef = useRef(undefined);
44
+ const containerRef = useRef(null);
27
45
  /**
28
46
  * The component may render both visualization and config panel. In React18 we therefore need two
29
47
  * roots with their respective render methods. This Map holds the roots for both and provides
30
48
  * render and unmount methods whenever needed.
31
49
  */
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();
50
+ const reactRootsMapRef = useRef(new Map());
51
+ /**
52
+ * Whether the effects are currently torn down. Used to tell a real unmount apart from a teardown that is
53
+ * immediately followed by a new setup of the same component instance.
54
+ */
55
+ const isUnmountedRef = useRef(false);
56
+ /**
57
+ * The callbacks and element getters below outlive the render they were created in (the visualization
58
+ * instance only ever gets the ones from the render it was set up in). They therefore read the props from
59
+ * this ref to always see the current values - the very same way `this.props` did before.
60
+ *
61
+ * This effect must stay first so that the ref is up to date before any other effect runs. It is a layout
62
+ * effect so that it keeps the pre-paint semantics the class lifecycle methods had.
63
+ */
64
+ const propsRef = useRef(currentProps);
65
+ useLayoutEffect(() => {
66
+ propsRef.current = currentProps;
67
+ });
68
+ const unmountVisualization = useCallback(() => {
69
+ if (visualizationRef.current) {
70
+ visualizationRef.current.unmount();
45
71
  }
46
- this.visualization = undefined;
47
- };
48
- updateVisualization = () => {
72
+ visualizationRef.current = undefined;
73
+ }, []);
74
+ const getExecutionFactory = useCallback(() => {
75
+ const { backend, workspace, executeByReference, filters } = propsRef.current;
76
+ const factory = backend.workspace(workspace).execution();
77
+ if (executeByReference) {
78
+ /*
79
+ * When executing by reference, decorate the original execution factory so that it
80
+ * transparently routes `forInsight` to `forInsightByRef` AND adds the filters
81
+ * from InsightView props.
82
+ *
83
+ * Code will pass this factory over to the pluggable visualizations - they will do execution
84
+ * `forInsight` and under the covers things will be routed and done differently without the
85
+ * plug viz knowing.
86
+ */
87
+ return new ExecutionFactoryUpgradingToExecByReference(new ExecutionFactoryWithFixedFilters(factory, filters));
88
+ }
89
+ return factory;
90
+ }, []);
91
+ const updateVisualization = useCallback(() => {
49
92
  // if the container no longer exists, update was called after unmount -> do nothing
50
- if (!this.visualization || !this.containerRef.current) {
93
+ if (!visualizationRef.current || !containerRef.current) {
51
94
  return;
52
95
  }
96
+ const { insight: insightProp, config = {}, settings, locale, messages, widget, drillableItems, colorPalette, execConfig, theme, } = propsRef.current;
53
97
  // if there is no insight, bail early
54
- if (!this.props.insight) {
98
+ if (!insightProp) {
55
99
  return;
56
100
  }
57
- const { config = {} } = this.props;
58
- const { responsiveUiDateFormat } = this.props.settings ?? {};
101
+ const { responsiveUiDateFormat } = settings ?? {};
59
102
  const visProps = {
60
- locale: this.props.locale,
61
- messages: this.props.messages,
103
+ locale,
104
+ messages,
62
105
  dateFormat: responsiveUiDateFormat,
63
- a11yTitle: this.props.widget?.title,
64
- a11yDescription: this.props.widget?.description,
106
+ a11yTitle: widget?.title,
107
+ a11yDescription: widget?.description,
65
108
  custom: {
66
- drillableItems: this.props.drillableItems,
67
- lastSavedVisClassUrl: insightVisualizationUrl(this.props.insight),
109
+ drillableItems,
110
+ lastSavedVisClassUrl: insightVisualizationUrl(insightProp),
68
111
  },
69
112
  config: {
70
113
  separators: config.separators,
71
- colorPalette: this.props.colorPalette,
114
+ colorPalette,
72
115
  mapboxToken: config.mapboxToken,
73
116
  agGridToken: config.agGridToken,
74
117
  forceDisableDrillOnAxes: config.forceDisableDrillOnAxes,
@@ -76,13 +119,13 @@ class InsightRendererCore extends PureComponent {
76
119
  isExportMode: config.isExportMode,
77
120
  enableExecutionCancelling: config.enableExecutionCancelling,
78
121
  },
79
- executionConfig: this.props.execConfig,
122
+ executionConfig: execConfig,
80
123
  customVisualizationConfig: config,
81
- theme: this.props.theme,
124
+ theme,
82
125
  supportsChartFill: config.supportsChartFill,
83
126
  };
84
- const visClass = insightVisualizationType(this.props.insight);
85
- const filled = fillMissingTitlesWithMessages(this.props.insight, this.props.locale, this.props.messages, undefined);
127
+ const visClass = insightVisualizationType(insightProp);
128
+ const filled = fillMissingTitlesWithMessages(insightProp, locale, messages, undefined);
86
129
  let insight = fillMissingFormats(filled);
87
130
  /**
88
131
  * Ignore titles for simple measures in all visualizations except for repeater.
@@ -95,29 +138,60 @@ class InsightRendererCore extends PureComponent {
95
138
  if (visClass !== "repeater") {
96
139
  insight = ignoreTitlesForSimpleMeasures(insight);
97
140
  }
98
- this.visualization?.update(visProps, insight, {}, this.getExecutionFactory());
99
- };
100
- setupVisualization = () => {
141
+ visualizationRef.current?.update(visProps, insight, {}, getExecutionFactory());
142
+ }, [getExecutionFactory]);
143
+ const reactRenderFunction = useCallback((children, element) => {
144
+ if (!element) {
145
+ return;
146
+ }
147
+ const htmlElement = element;
148
+ if (!reactRootsMapRef.current.get(htmlElement)) {
149
+ reactRootsMapRef.current.set(htmlElement, createRoot(htmlElement));
150
+ }
151
+ reactRootsMapRef.current.get(htmlElement).render(children);
152
+ }, []);
153
+ const reactUnmountFunction = useCallback(() => {
154
+ reactRootsMapRef.current.forEach((root) => root.render(null));
155
+ }, []);
156
+ const onExportReadyDecorator = useCallback((exportFunction) => {
157
+ const { onExportReady } = propsRef.current;
158
+ if (!onExportReady) {
159
+ return;
160
+ }
161
+ const decorator = (exportConfig) => {
162
+ const { insight } = propsRef.current;
163
+ if (exportConfig.title || !insight) {
164
+ return exportFunction(exportConfig);
165
+ }
166
+ return exportFunction({
167
+ ...exportConfig,
168
+ title: insightTitle(insight),
169
+ });
170
+ };
171
+ onExportReady(decorator);
172
+ }, []);
173
+ const setupVisualization = useCallback(() => {
174
+ const { insight, settings, backend, workspace, permissions, locale, messages, pushData, onDrill, onDataView, onLoadingChanged, afterRender, } = propsRef.current;
101
175
  // if there is no insight, bail early
102
- if (!this.props.insight) {
176
+ if (!insight) {
103
177
  return;
104
178
  }
105
179
  // 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,
180
+ unmountVisualization();
181
+ const visualizationFactory = FullVisualizationCatalog.forInsight(insight, settings?.enableNewPivotTable ?? true, settings?.enableNewGeoPushpin ?? false).getFactory();
182
+ visualizationRef.current = visualizationFactory({
183
+ backend: backend,
110
184
  callbacks: {
111
185
  onError: (error) => {
112
- this.props.onError?.(error);
113
- this.props.onLoadingChanged?.({ isLoading: false });
186
+ propsRef.current.onError?.(error);
187
+ propsRef.current.onLoadingChanged?.({ isLoading: false });
114
188
  },
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,
189
+ onLoadingChanged,
190
+ pushData,
191
+ onDrill,
192
+ onDataView,
193
+ onExportReady: onExportReadyDecorator,
194
+ afterRender,
121
195
  },
122
196
  // This renderer has no configuration panel of its own — it renders read-only insights.
123
197
  // It used to resolve the panel with a document-wide lookup of the well-known
@@ -130,107 +204,83 @@ class InsightRendererCore extends PureComponent {
130
204
  // fix STL-3184
131
205
  configPanelElement: () => null,
132
206
  element: () => {
133
- const rootNode = this.containerRef.current?.getRootNode() ?? document;
134
- return rootNode.querySelector(`#${this.elementId}`);
207
+ const rootNode = containerRef.current?.getRootNode() ?? document;
208
+ return rootNode.querySelector(`#${elementId}`);
135
209
  },
136
210
  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(),
211
+ locale,
212
+ messages,
213
+ projectId: workspace,
214
+ visualizationProperties: insightProperties(insight),
215
+ featureFlags: settings,
216
+ permissions,
217
+ renderFun: reactRenderFunction,
218
+ unmountFun: reactUnmountFunction,
145
219
  });
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) {
220
+ }, [elementId, onExportReadyDecorator, reactRenderFunction, reactUnmountFunction, unmountVisualization]);
221
+ const prevPropsRef = useRef(undefined);
222
+ // componentDidMount & componentDidUpdate: intentionally without dependencies so that it runs after
223
+ // every render of this (memoized) component. A layout effect so that it keeps running before paint,
224
+ // the very same way the class lifecycle methods did.
225
+ useLayoutEffect(() => {
226
+ const prevProps = prevPropsRef.current;
227
+ prevPropsRef.current = currentProps;
228
+ if (!prevProps) {
229
+ setupVisualization();
230
+ updateVisualization();
164
231
  return;
165
232
  }
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
233
  /**
202
234
  * Ignore properties when comparing insights to determine if a new setup is needed: changes to properties
203
235
  * only will be handled using the updateVisualization without unnecessary new setup just fine.
204
236
  */
205
237
  const prevInsightForCompare = prevProps.insight && insightSetProperties(prevProps.insight, {});
206
- const newInsightForCompare = this.props.insight && insightSetProperties(this.props.insight, {});
238
+ const newInsightForCompare = currentProps.insight && insightSetProperties(currentProps.insight, {});
207
239
  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;
240
+ !isEqual(currentProps.filters, prevProps.filters) ||
241
+ !isEqual(currentProps.settings, prevProps.settings) ||
242
+ currentProps.workspace !== prevProps.workspace;
211
243
  if (needsNewSetup) {
212
- this.setupVisualization();
244
+ setupVisualization();
213
245
  }
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)));
246
+ updateVisualization();
247
+ });
248
+ // componentWillUnmount
249
+ useEffect(() => {
250
+ const reactRootsMap = reactRootsMapRef.current;
251
+ isUnmountedRef.current = false;
252
+ return () => {
253
+ unmountVisualization();
254
+ /**
255
+ * Unlike componentWillUnmount, this cleanup also runs when the effects of this very component
256
+ * instance are torn down and set up again (StrictMode double-invoke in development, <Activity>
257
+ * hiding, Fast Refresh). The refs survive that, so the setup state has to be reset here -
258
+ * otherwise the next effect pass would see unchanged props, skip setupVisualization and leave
259
+ * an empty container behind.
260
+ */
261
+ prevPropsRef.current = undefined;
262
+ isUnmountedRef.current = true;
263
+ // In order to avoid race conditions when mounting and unmounting synchronously,
264
+ // we use timeout for React18.
265
+ // https://github.com/facebook/react/issues/25675
266
+ setTimeout(() => {
267
+ // the component was mounted again in the meantime, the roots are in use - keep them so
268
+ // that the visualization set up by the new effect pass is not torn down underneath it
269
+ if (!isUnmountedRef.current) {
270
+ return;
271
+ }
272
+ reactRootsMap.forEach((root) => root.unmount());
273
+ // the roots above are gone; drop them so that a later remount creates fresh ones
274
+ reactRootsMap.clear();
275
+ }, 0);
276
+ };
277
+ }, [unmountVisualization]);
278
+ return (
279
+ // never ever dynamically change the props of this div, otherwise bad things will happen
280
+ // e.g. visualization being rendered multiple times, etc.
281
+ _jsx("div", { className: "visualization-uri-root", id: elementId, ref: containerRef, style: visualizationUriRootStyle }));
282
+ });
283
+ export const IntlInsightRenderer = withContexts(InsightRendererCore);
234
284
  /**
235
285
  * Updated callback (callback with a different reference) is not properly propagated to the "visualization" instance
236
286
  * (because it only takes the callbacks provided on the first render)
@@ -1,4 +1,3 @@
1
- import { PureComponent } from "react";
2
1
  import { type IAnalyticalBackend, type IPreparedExecution } from "@gooddata/sdk-backend-spi";
3
2
  import { type IExecutionConfig, type IInsight, type IInsightDefinition, type ISettings, type ITheme, type IVisualizationClass, type IWorkspacePermissions } from "@gooddata/sdk-model";
4
3
  import { type ExplicitDrill, type ILocale, type OnError, type OnExportReady, type OnLoadingChanged, type VisualizationEnvironment } from "@gooddata/sdk-ui";
@@ -46,39 +45,13 @@ export interface IBaseVisualizationProps extends IVisCallbacks {
46
45
  configurationPanelRenderers?: IConfigurationPanelRenderers;
47
46
  supportsChartFill?: boolean;
48
47
  }
49
- export declare class BaseVisualization extends PureComponent<IBaseVisualizationProps> {
50
- static defaultProps: Pick<IBaseVisualizationProps, "visualizationCatalog" | "newDerivedBucketItems" | "referencePoint" | "onExtendedReferencePointChanged" | "onNewDerivedBucketItemsPlaced" | "isMdObjectValid" | "configPanelClassName" | "featureFlags">;
51
- private visElementId;
52
- private visualization;
53
- private executionFactory;
54
- private containerRef;
55
- /**
56
- * The component may render both visualization and config panel. In React18 we therefore need two
57
- * roots with their respective render methods. This Map holds the roots for both and provides
58
- * render and unmount methods whenever needed.
59
- */
60
- private reactRootsMap;
61
- constructor(props: IBaseVisualizationProps);
62
- componentWillUnmount(): void;
63
- UNSAFE_componentWillReceiveProps(nextProps: IBaseVisualizationProps): void;
64
- componentDidMount(): void;
65
- componentDidUpdate(): void;
66
- render(): import("react/jsx-runtime").JSX.Element;
67
- private getVisElementClassName;
68
- private getClassName;
69
- private setupVisualization;
70
- private getReactRenderFunction;
71
- private getReactUnmountFunction;
72
- private updateVisualization;
73
- private triggerPlaceNewDerivedBucketItems;
74
- private triggerExtendedReferencePointChanged;
75
- private triggerPropertiesChanged;
76
- private static bucketReferencePointHasChanged;
77
- private static propertiesControlsHasChanged;
78
- private somePropertiesRelevantForReferencePointChanged;
79
- private getVisualizationProps;
80
- getInsightWithDrillDownApplied(sourceVisualization: IInsight, drillDownContext: IDrillDownContext): IInsight;
48
+ /**
49
+ * Imperative API of the {@link BaseVisualization}, available through its ref.
50
+ */
51
+ export interface IBaseVisualizationApi {
81
52
  getExecution(): IPreparedExecution | null;
82
53
  getExecutions(): IPreparedExecution[] | undefined;
54
+ getInsightWithDrillDownApplied(sourceVisualization: IInsight, drillDownContext: IDrillDownContext): IInsight;
83
55
  }
56
+ export declare const BaseVisualization: import("react").ForwardRefExoticComponent<IBaseVisualizationProps & import("react").RefAttributes<IBaseVisualizationApi>>;
84
57
  //# sourceMappingURL=BaseVisualization.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"BaseVisualization.d.ts","sourceRoot":"","sources":["../../../src/internal/components/BaseVisualization.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BaseVisualization.d.ts","sourceRoot":"","sources":["../../../src/internal/components/BaseVisualization.tsx"],"names":[],"mappings":"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"}