@gooddata/sdk-ui-pluggable-host 11.41.0-alpha.4 → 11.41.0

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 (130) hide show
  1. package/esm/components/FullScreenLoader.d.ts +1 -0
  2. package/esm/components/FullScreenLoader.d.ts.map +1 -0
  3. package/esm/components/HostUiContainer.d.ts +1 -0
  4. package/esm/components/HostUiContainer.d.ts.map +1 -0
  5. package/esm/components/HostUiContainer.js +16 -2
  6. package/esm/components/Root.d.ts +1 -0
  7. package/esm/components/Root.d.ts.map +1 -0
  8. package/esm/components/lib/translations.d.ts +1 -0
  9. package/esm/components/lib/translations.d.ts.map +1 -0
  10. package/esm/components/useRedirectNavigation.d.ts +1 -0
  11. package/esm/components/useRedirectNavigation.d.ts.map +1 -0
  12. package/esm/components/useRedirectTarget.d.ts +1 -0
  13. package/esm/components/useRedirectTarget.d.ts.map +1 -0
  14. package/esm/debug.d.ts +1 -0
  15. package/esm/debug.d.ts.map +1 -0
  16. package/esm/index.d.ts +1 -0
  17. package/esm/index.d.ts.map +1 -0
  18. package/esm/lib/chunkReloadGuard.d.ts +1 -0
  19. package/esm/lib/chunkReloadGuard.d.ts.map +1 -0
  20. package/esm/lib/hostNotifications.d.ts +1 -0
  21. package/esm/lib/hostNotifications.d.ts.map +1 -0
  22. package/esm/lib/isProduction.d.ts +1 -0
  23. package/esm/lib/isProduction.d.ts.map +1 -0
  24. package/esm/loader/appSecurityValidation.d.ts +57 -0
  25. package/esm/loader/appSecurityValidation.d.ts.map +1 -0
  26. package/esm/loader/appSecurityValidation.js +102 -0
  27. package/esm/loader/lastVisitedApp.d.ts +1 -0
  28. package/esm/loader/lastVisitedApp.d.ts.map +1 -0
  29. package/esm/loader/localLoader.d.ts +1 -0
  30. package/esm/loader/localLoader.d.ts.map +1 -0
  31. package/esm/loader/pluggableApplicationsLoader.d.ts +1 -0
  32. package/esm/loader/pluggableApplicationsLoader.d.ts.map +1 -0
  33. package/esm/loader/redirectLogic.d.ts +1 -0
  34. package/esm/loader/redirectLogic.d.ts.map +1 -0
  35. package/esm/loader/remoteLoader.d.ts +1 -0
  36. package/esm/loader/remoteLoader.d.ts.map +1 -0
  37. package/esm/loader/remoteUrlSecurity.d.ts +1 -0
  38. package/esm/loader/remoteUrlSecurity.d.ts.map +1 -0
  39. package/esm/loader/routing.d.ts +1 -0
  40. package/esm/loader/routing.d.ts.map +1 -0
  41. package/esm/platformContext/backend.d.ts +1 -0
  42. package/esm/platformContext/backend.d.ts.map +1 -0
  43. package/esm/platformContext/bootstrap.d.ts +1 -0
  44. package/esm/platformContext/bootstrap.d.ts.map +1 -0
  45. package/esm/platformContext/loadPlatformContext.d.ts +1 -0
  46. package/esm/platformContext/loadPlatformContext.d.ts.map +1 -0
  47. package/esm/platformContext/tigerNotAuthenticatedHandler.d.ts +1 -0
  48. package/esm/platformContext/tigerNotAuthenticatedHandler.d.ts.map +1 -0
  49. package/esm/platformContext/types.d.ts +1 -0
  50. package/esm/platformContext/types.d.ts.map +1 -0
  51. package/esm/platformContext/useLoadPlatformContext.d.ts +1 -0
  52. package/esm/platformContext/useLoadPlatformContext.d.ts.map +1 -0
  53. package/esm/platformContext/useWorkspaceColorPalette.d.ts +1 -0
  54. package/esm/platformContext/useWorkspaceColorPalette.d.ts.map +1 -0
  55. package/esm/platformContext/useWorkspacePermissions.d.ts +1 -0
  56. package/esm/platformContext/useWorkspacePermissions.d.ts.map +1 -0
  57. package/esm/platformContext/useWorkspaceSettings.d.ts +1 -0
  58. package/esm/platformContext/useWorkspaceSettings.d.ts.map +1 -0
  59. package/esm/platformContext/useWorkspaceTheme.d.ts +1 -0
  60. package/esm/platformContext/useWorkspaceTheme.d.ts.map +1 -0
  61. package/esm/platformContext/waitForInjectedApiToken.d.ts +1 -0
  62. package/esm/platformContext/waitForInjectedApiToken.d.ts.map +1 -0
  63. package/esm/registry/pluggableApplicationsRegistry.d.ts +1 -0
  64. package/esm/registry/pluggableApplicationsRegistry.d.ts.map +1 -0
  65. package/esm/translations/de-DE.json +4 -1
  66. package/esm/translations/en-AU.json +4 -1
  67. package/esm/translations/en-GB.json +4 -1
  68. package/esm/translations/en-US.json +52 -0
  69. package/esm/translations/es-419.json +4 -1
  70. package/esm/translations/es-ES.json +4 -1
  71. package/esm/translations/fi-FI.json +4 -1
  72. package/esm/translations/fr-CA.json +4 -1
  73. package/esm/translations/fr-FR.json +4 -1
  74. package/esm/translations/id-ID.json +4 -1
  75. package/esm/translations/it-IT.json +4 -1
  76. package/esm/translations/ja-JP.json +4 -1
  77. package/esm/translations/ko-KR.json +4 -1
  78. package/esm/translations/nl-NL.json +4 -1
  79. package/esm/translations/pl-PL.json +4 -1
  80. package/esm/translations/pt-BR.json +4 -1
  81. package/esm/translations/pt-PT.json +4 -1
  82. package/esm/translations/ru-RU.json +4 -1
  83. package/esm/translations/sl-SI.json +4 -1
  84. package/esm/translations/th-TH.json +4 -1
  85. package/esm/translations/tr-TR.json +4 -1
  86. package/esm/translations/uk-UA.json +4 -1
  87. package/esm/translations/vi-VN.json +4 -1
  88. package/esm/translations/zh-HK.json +4 -1
  89. package/esm/translations/zh-Hans.json +4 -1
  90. package/esm/translations/zh-Hant.json +4 -1
  91. package/esm/types/lifecycle.d.ts +1 -0
  92. package/esm/types/lifecycle.d.ts.map +1 -0
  93. package/esm/ui/DefaultHostUi.d.ts +1 -0
  94. package/esm/ui/DefaultHostUi.d.ts.map +1 -0
  95. package/esm/ui/DefaultHostUi.js +10 -3
  96. package/esm/ui/GenAIChat.d.ts +1 -0
  97. package/esm/ui/GenAIChat.d.ts.map +1 -0
  98. package/esm/ui/HostChrome.d.ts +7 -1
  99. package/esm/ui/HostChrome.d.ts.map +1 -0
  100. package/esm/ui/HostChrome.js +37 -14
  101. package/esm/ui/HostIntlProvider.d.ts +1 -0
  102. package/esm/ui/HostIntlProvider.d.ts.map +1 -0
  103. package/esm/ui/HostNotificationDispatcher.d.ts +1 -0
  104. package/esm/ui/HostNotificationDispatcher.d.ts.map +1 -0
  105. package/esm/ui/PluggableApplicationRenderer.d.ts +3 -1
  106. package/esm/ui/PluggableApplicationRenderer.d.ts.map +1 -0
  107. package/esm/ui/PluggableApplicationRenderer.js +70 -10
  108. package/esm/ui/PluggableApplicationRenderer.scss +31 -1
  109. package/esm/ui/SemanticSearch.d.ts +1 -0
  110. package/esm/ui/SemanticSearch.d.ts.map +1 -0
  111. package/esm/ui/WorkspacePicker.d.ts +1 -0
  112. package/esm/ui/WorkspacePicker.d.ts.map +1 -0
  113. package/esm/ui/appMenuItems.d.ts +2 -0
  114. package/esm/ui/appMenuItems.d.ts.map +1 -0
  115. package/esm/ui/appMenuItems.js +1 -1
  116. package/esm/ui/chromeHelpers.d.ts +1 -0
  117. package/esm/ui/chromeHelpers.d.ts.map +1 -0
  118. package/esm/ui/hostChromeBem.d.ts +1 -0
  119. package/esm/ui/hostChromeBem.d.ts.map +1 -0
  120. package/esm/ui/resolveHostUiModule.d.ts +1 -0
  121. package/esm/ui/resolveHostUiModule.d.ts.map +1 -0
  122. package/esm/ui/useHostChromeChat.d.ts +1 -0
  123. package/esm/ui/useHostChromeChat.d.ts.map +1 -0
  124. package/esm/ui/useHostChromePricing.d.ts +1 -0
  125. package/esm/ui/useHostChromePricing.d.ts.map +1 -0
  126. package/esm/ui/useHostChromeSearch.d.ts +1 -0
  127. package/esm/ui/useHostChromeSearch.d.ts.map +1 -0
  128. package/esm/ui/useHostChromeWorkspaceFeatures.d.ts +1 -0
  129. package/esm/ui/useHostChromeWorkspaceFeatures.d.ts.map +1 -0
  130. package/package.json +17 -17
@@ -1,21 +1,36 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  // (C) 2026 GoodData Corporation
3
3
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
4
- import { FormattedMessage } from "react-intl";
5
- import { isReloadPlatformContextRequestedEvent, } from "@gooddata/sdk-pluggable-application-model";
4
+ import { FormattedMessage, defineMessage, useIntl } from "react-intl";
5
+ import { isDocumentTitleChangedEvent, isReloadPlatformContextRequestedEvent, } from "@gooddata/sdk-pluggable-application-model";
6
6
  import { LoadingComponent, useAutoupdateRef } from "@gooddata/sdk-ui";
7
7
  import { bemFactory } from "@gooddata/sdk-ui-kit";
8
8
  import { now } from "../debug.js";
9
+ import { getSecuredRemoteAppValidUntil, validateAppSecurity, } from "../loader/appSecurityValidation.js";
9
10
  import { getAppLifecycleCallbacks, loadPluggableApplication } from "../loader/pluggableApplicationsLoader.js";
10
11
  import { getApplicationHref } from "../loader/routing.js";
11
12
  import { BackendPlatformContextProvider } from "../platformContext/useLoadPlatformContext.js";
12
13
  import "./PluggableApplicationRenderer.scss";
13
14
  const { b, e } = bemFactory("gd-pluggable-application-renderer");
14
- export function PluggableApplicationRenderer({ app, ctx, pathname, onHeaderChange, }) {
15
+ // Use `defineMessage` for each id so the intl extractor and validator can statically
16
+ // match them against the locale JSON files. A plain `{ id }` literal passed to
17
+ // `intl.formatMessage` is opaque to the tooling.
18
+ const SECURITY_FAILURE_MESSAGES = {
19
+ "organization-not-allowed": defineMessage({ id: "gs.host.error.appNotAllowedForOrganization" }),
20
+ "build-expired": defineMessage({ id: "gs.host.error.appBuildExpired" }),
21
+ "metadata-missing": defineMessage({ id: "gs.host.error.appSecurityMetadataMissing" }),
22
+ };
23
+ export function PluggableApplicationRenderer({ app, ctx, pathname, onHeaderChange, onDocumentTitleChange, }) {
24
+ const intl = useIntl();
25
+ const intlRef = useAutoupdateRef(intl);
15
26
  const ctxRef = useAutoupdateRef(ctx);
16
27
  const onHeaderChangeRef = useAutoupdateRef(onHeaderChange);
28
+ const onDocumentTitleChangeRef = useAutoupdateRef(onDocumentTitleChange);
17
29
  const containerRef = useRef(null);
18
30
  const mountHandleRef = useRef(undefined);
31
+ // The app/module pair currently mounted. Held so the context-change effect can
32
+ // re-run the security check against the live organization without reloading.
33
+ const mountedAppRef = useRef(undefined);
19
34
  const [viewState, setViewState] = useState({ state: "loading" });
20
35
  const baseHref = getApplicationHref(app, ctx, pathname);
21
36
  const appBasePath = ctx.embeddingMode === "iframe" ? `/embedded${baseHref}` : baseHref;
@@ -24,17 +39,23 @@ export function PluggableApplicationRenderer({ app, ctx, pathname, onHeaderChang
24
39
  // onEvent is intentionally stable (empty deps) — pluggable apps capture it at mount time
25
40
  // and do not update it when the host re-renders. Do not make this callback depend on
26
41
  // any value that can change after mount, or the mounted app will silently call a stale closure.
42
+ // Values that change after mount are read through refs (e.g. onDocumentTitleChangeRef).
27
43
  const onEvent = useCallback((event) => {
28
44
  if (isReloadPlatformContextRequestedEvent(event)) {
29
45
  void BackendPlatformContextProvider.load();
46
+ return;
30
47
  }
31
- }, []);
48
+ if (isDocumentTitleChangedEvent(event)) {
49
+ onDocumentTitleChangeRef.current?.(app.id, event.payload.pageTitle);
50
+ }
51
+ }, [app.id, onDocumentTitleChangeRef]);
32
52
  useEffect(() => {
33
53
  let cancelled = false;
34
54
  const mountId = `${app.id}:${Date.now()}`;
35
55
  const totalStart = now();
36
56
  const prevHandle = mountHandleRef.current;
37
57
  mountHandleRef.current = undefined;
58
+ mountedAppRef.current = undefined;
38
59
  setViewState({ state: "loading" });
39
60
  // Defer unmount of the previous app to avoid synchronously unmounting
40
61
  // a React root while React is already rendering (race in strict mode).
@@ -48,6 +69,17 @@ export function PluggableApplicationRenderer({ app, ctx, pathname, onHeaderChang
48
69
  if (cancelled) {
49
70
  return;
50
71
  }
72
+ const securityFailure = validateAppSecurity(app, loadedApp, ctxRef.current);
73
+ if (securityFailure) {
74
+ const message = intlRef.current.formatMessage(SECURITY_FAILURE_MESSAGES[securityFailure.kind]);
75
+ console.error(`[host-runtime/renderer] Refusing to mount app "${app.id}": ${securityFailure.kind}.`, securityFailure);
76
+ lifecycle?.onLoadFailed?.(app.id, securityFailure.kind);
77
+ setViewState({ state: "error", message });
78
+ return;
79
+ }
80
+ // Report load success only after the security check passes, so a rejected
81
+ // app never produces both an onLoadCompleted and an onLoadFailed for the
82
+ // same attempt.
51
83
  lifecycle?.onLoadCompleted?.(app.id, now() - loadStart);
52
84
  const container = containerRef.current;
53
85
  if (!container) {
@@ -63,9 +95,10 @@ export function PluggableApplicationRenderer({ app, ctx, pathname, onHeaderChang
63
95
  onTelemetryEvent,
64
96
  onHeaderChange: (header) => onHeaderChangeRef.current?.(app.id, header),
65
97
  });
98
+ mountedAppRef.current = { app, loadedApp };
66
99
  lifecycle?.onMountCompleted?.(app.id, now() - mountStart);
67
100
  lifecycle?.onRendered?.(app.id, now() - totalStart);
68
- setViewState({ state: "ready" });
101
+ setViewState({ state: "ready", validUntil: getSecuredRemoteAppValidUntil(app, loadedApp) });
69
102
  })
70
103
  .catch((mountError) => {
71
104
  if (cancelled) {
@@ -84,18 +117,45 @@ export function PluggableApplicationRenderer({ app, ctx, pathname, onHeaderChang
84
117
  const handle = mountHandleRef.current;
85
118
  if (handle) {
86
119
  mountHandleRef.current = undefined;
120
+ mountedAppRef.current = undefined;
87
121
  queueMicrotask(() => {
88
122
  handle.unmount();
89
123
  lifecycle?.onUnmounted?.(app.id);
90
124
  });
91
125
  }
92
126
  };
93
- }, [app, appBasePath, ctxRef, onHeaderChangeRef, onTelemetryEvent, lifecycle, onEvent]);
127
+ }, [app, appBasePath, ctxRef, intlRef, onHeaderChangeRef, onTelemetryEvent, lifecycle, onEvent]);
94
128
  useEffect(() => {
95
- mountHandleRef.current?.updateContext?.(ctx);
96
- }, [ctx]);
129
+ const mounted = mountedAppRef.current;
130
+ const handle = mountHandleRef.current;
131
+ if (!mounted || !handle) {
132
+ return;
133
+ }
134
+ // Re-run the security check against the new context. The app's base path does not
135
+ // encode the organization id, so an organization change does not re-run the mount
136
+ // effect — without this an app could stay mounted under an organization that is no
137
+ // longer in its allowlist (or with a now-expired build).
138
+ const securityFailure = validateAppSecurity(mounted.app, mounted.loadedApp, ctx);
139
+ if (securityFailure) {
140
+ const message = intlRef.current.formatMessage(SECURITY_FAILURE_MESSAGES[securityFailure.kind]);
141
+ console.error(`[host-runtime/renderer] Unmounting app "${mounted.app.id}" after context change: ${securityFailure.kind}.`, securityFailure);
142
+ mountHandleRef.current = undefined;
143
+ mountedAppRef.current = undefined;
144
+ handle.unmount();
145
+ lifecycle?.onUnmounted?.(mounted.app.id);
146
+ lifecycle?.onLoadFailed?.(mounted.app.id, securityFailure.kind);
147
+ setViewState({ state: "error", message });
148
+ return;
149
+ }
150
+ handle.updateContext?.(ctx);
151
+ }, [ctx, intlRef, lifecycle]);
97
152
  return (_jsxs("section", { className: b(), children: [viewState.state === "loading" ? (_jsx("div", { className: e("loading"), children: _jsx(LoadingComponent, { height: 40 }) })) : null, viewState.state === "error" ? (_jsxs("div", { className: e("error"), children: [
98
153
  _jsx("h2", { children: _jsx(FormattedMessage, { id: "gs.host.error.applicationFailedToLoad" }) }), _jsx("p", { children: viewState.message })
99
- ] })) : null, _jsx("div", { ref: containerRef, className: e("container", { visible: viewState.state === "ready" }) })
100
- ] }));
154
+ ] })) : null, _jsx("div", { ref: containerRef, className: e("container", { visible: viewState.state === "ready" }) }), viewState.state === "ready" && viewState.validUntil !== undefined ? (_jsx("div", { className: e("demoBadge"), role: "status", children: _jsx(FormattedMessage, { id: "gs.host.demoApp.validUntil", values: {
155
+ date: intl.formatDate(viewState.validUntil, {
156
+ year: "numeric",
157
+ month: "long",
158
+ day: "numeric",
159
+ }),
160
+ } }) })) : null] }));
101
161
  }
@@ -12,10 +12,20 @@
12
12
 
13
13
  &__error {
14
14
  min-height: 240px;
15
+ height: 100%;
15
16
  display: flex;
16
17
  flex-direction: column;
17
- justify-content: center;
18
+ align-items: center;
19
+ text-align: center;
18
20
  gap: 8px;
21
+
22
+ // Push the error block to roughly one third from the top. The spacer's
23
+ // flex-basis is a percentage of this column's height (resolves against
24
+ // the 100% height above), so it stays proportional as the area resizes.
25
+ &::before {
26
+ content: "";
27
+ flex: 0 0 33%;
28
+ }
19
29
  }
20
30
 
21
31
  &__container {
@@ -26,4 +36,24 @@
26
36
  display: block;
27
37
  height: 100%;
28
38
  }
39
+
40
+ // Small semi-transparent floating badge pinned to the bottom-right of the
41
+ // page, shown only for validated demo-bucket apps. Non-interactive so it
42
+ // never intercepts clicks meant for the app beneath it.
43
+ &__demoBadge {
44
+ position: fixed;
45
+ right: 16px;
46
+ bottom: 16px;
47
+ z-index: 100;
48
+ padding: 6px 12px;
49
+ border-radius: 6px;
50
+ font-size: 12px;
51
+ line-height: 1.4;
52
+ color: #fff;
53
+ background: rgba(20, 35, 49, 0.16);
54
+ backdrop-filter: blur(4px);
55
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
56
+ pointer-events: none;
57
+ user-select: none;
58
+ }
29
59
  }
@@ -23,3 +23,4 @@ export interface ISemanticSearchProps {
23
23
  onEvent?: (event: SemanticSearchEvent) => void;
24
24
  }
25
25
  export declare function SemanticSearch({ backend, workspaceId, metadataTimeZone, canManage, canAnalyze, canFullControl, isTrial, enableUseGenAIChat, useHostedMetricEditor, useHostedAnalyticalDesigner, useHostedLdmModeler, onAskAiAssistant, onEvent }: ISemanticSearchProps): import("react/jsx-runtime").JSX.Element;
26
+ //# sourceMappingURL=SemanticSearch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SemanticSearch.d.ts","sourceRoot":"","sources":["../../src/ui/SemanticSearch.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,OAAO,EAEH,KAAK,cAAc,EAItB,MAAM,2CAA2C,CAAC;AAInD;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,CAAC;AAExF,MAAM,WAAW,oBAAoB;IACjC,OAAO,EAAE,kBAAkB,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;CAClD;AAED,wBAAgB,cAAc,CAAC,EAC3B,OAAO,EACP,WAAW,EACX,gBAAgB,EAChB,SAAiB,EACjB,UAAkB,EAClB,cAAsB,EACtB,OAAe,EACf,kBAA0B,EAC1B,qBAA6B,EAC7B,2BAAmC,EACnC,mBAA2B,EAC3B,gBAAgB,EAChB,OAAO,EACV,EAAE,oBAAoB,2CA6EtB"}
@@ -7,3 +7,4 @@ export interface IAppHeaderWorkspacePickerProps {
7
7
  onWorkspaceSelect: (workspace: IHeaderWorkspace) => void;
8
8
  }
9
9
  export declare function AppHeaderWorkspacePicker({ backend, userId, workspaceId, onWorkspaceSelect }: IAppHeaderWorkspacePickerProps): import("react/jsx-runtime").JSX.Element;
10
+ //# sourceMappingURL=WorkspacePicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkspacePicker.d.ts","sourceRoot":"","sources":["../../src/ui/WorkspacePicker.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAGpE,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,MAAM,WAAW,8BAA8B;IAC3C,OAAO,EAAE,kBAAkB,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,CAAC,SAAS,EAAE,gBAAgB,KAAK,IAAI,CAAC;CAC5D;AA8BD,wBAAgB,wBAAwB,CAAC,EACrC,OAAO,EACP,MAAM,EACN,WAAW,EACX,iBAAiB,EACpB,EAAE,8BAA8B,2CAWhC"}
@@ -1,6 +1,7 @@
1
1
  import { type ILocale, type PluggableApplicationRegistryItem } from "@gooddata/sdk-model";
2
2
  import { type IPlatformContext } from "@gooddata/sdk-pluggable-application-model";
3
3
  import { type IHeaderMenuItem } from "@gooddata/sdk-ui-kit";
4
+ export declare function getLocalizedTitle(app: PluggableApplicationRegistryItem, locale: ILocale | undefined): string;
4
5
  export interface IAppMenuResult {
5
6
  menuItemsGroups: IHeaderMenuItem[][];
6
7
  messages: Record<string, string>;
@@ -15,3 +16,4 @@ export interface IAppMenuResult {
15
16
  * workspace/organization-scoped URLs and active state detection.
16
17
  */
17
18
  export declare function buildAppMenu(apps: PluggableApplicationRegistryItem[], ctx: IPlatformContext, pathname: string, locale: ILocale | undefined): IAppMenuResult;
19
+ //# sourceMappingURL=appMenuItems.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appMenuItems.d.ts","sourceRoot":"","sources":["../../src/ui/appMenuItems.ts"],"names":[],"mappings":"AAIA,OAAO,EACH,KAAK,OAAO,EACZ,KAAK,gCAAgC,EAExC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAwB,KAAK,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AACxG,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAkC5D,wBAAgB,iBAAiB,CAC7B,GAAG,EAAE,gCAAgC,EACrC,MAAM,EAAE,OAAO,GAAG,SAAS,GAC5B,MAAM,CAQR;AAED,MAAM,WAAW,cAAc;IAC3B,eAAe,EAAE,eAAe,EAAE,EAAE,CAAC;IACrC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAeD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CACxB,IAAI,EAAE,gCAAgC,EAAE,EACxC,GAAG,EAAE,gBAAgB,EACrB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,GAAG,SAAS,GAC5B,cAAc,CA4BhB"}
@@ -27,7 +27,7 @@ const NAV_MSG_PREFIX = "shellApplication.menuItem.";
27
27
  function navMessageKey(appId) {
28
28
  return `${NAV_MSG_PREFIX}${appId}`;
29
29
  }
30
- function getLocalizedTitle(app, locale) {
30
+ export function getLocalizedTitle(app, locale) {
31
31
  if (locale && app.localizedTitle) {
32
32
  const localizedTitle = app.localizedTitle[locale];
33
33
  if (localizedTitle) {
@@ -15,3 +15,4 @@ export declare function getUserDisplayName(user: IUser): string;
15
15
  * an organization-scoped route).
16
16
  */
17
17
  export declare function swapWorkspaceInPath(pathname: string, newWorkspaceId: string): string;
18
+ //# sourceMappingURL=chromeHelpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chromeHelpers.d.ts","sourceRoot":"","sources":["../../src/ui/chromeHelpers.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAEjD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,CAStD;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAGpF"}
@@ -1 +1,2 @@
1
1
  export declare const b: (props?: import("@gooddata/sdk-ui-kit").StyleProps | undefined) => string, e: (element: string, props?: import("@gooddata/sdk-ui-kit").StyleProps | undefined) => string;
2
+ //# sourceMappingURL=hostChromeBem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hostChromeBem.d.ts","sourceRoot":"","sources":["../../src/ui/hostChromeBem.ts"],"names":[],"mappings":"AAIA,eAAO,MAAQ,CAAC,6EAAE,CAAC,4FAAiC,CAAC"}
@@ -6,3 +6,4 @@ import { type IPlatformContext, type IHostUiModule } from "@gooddata/sdk-pluggab
6
6
  * via module federation. Otherwise, the built-in default host UI is used.
7
7
  */
8
8
  export declare function resolveHostUiModule(ctx: IPlatformContext): Promise<IHostUiModule>;
9
+ //# sourceMappingURL=resolveHostUiModule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveHostUiModule.d.ts","sourceRoot":"","sources":["../../src/ui/resolveHostUiModule.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAOtG;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,aAAa,CAAC,CAevF"}
@@ -27,3 +27,4 @@ export interface IUseHostChromeChatArgs {
27
27
  * events to the host telemetry callbacks.
28
28
  */
29
29
  export declare function useHostChromeChat({ features, ctx, telemetry }: IUseHostChromeChatArgs): IHostChromeChat;
30
+ //# sourceMappingURL=useHostChromeChat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useHostChromeChat.d.ts","sourceRoot":"","sources":["../../src/ui/useHostChromeChat.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAyB,MAAM,OAAO,CAAC;AAE9D,OAAO,EACH,KAAK,gBAAgB,EACrB,KAAK,+BAA+B,EACvC,MAAM,2CAA2C,CAAC;AAMnD,OAAO,EAAE,KAAK,4BAA4B,EAAE,MAAM,qCAAqC,CAAC;AAExF,MAAM,WAAW,eAAe;IAC5B,4EAA4E;IAC5E,OAAO,EAAE,SAAS,CAAC;IACnB;;;OAGG;IACH,YAAY,EAAE,OAAO,CAAC;IACtB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,4DAA4D;IAC5D,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAED,MAAM,WAAW,sBAAsB;IACnC,QAAQ,EAAE,4BAA4B,CAAC;IACvC,GAAG,EAAE,gBAAgB,CAAC;IACtB,SAAS,EAAE,+BAA+B,GAAG,SAAS,CAAC;CAC1D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,sBAAsB,GAAG,eAAe,CAqDvG"}
@@ -50,3 +50,4 @@ export declare function setHostPricingExtension(extension: UseHostPricingExtensi
50
50
  * back to a no-op shape when no pricing extension is registered.
51
51
  */
52
52
  export declare function useHostChromePricing(ctx: IPlatformContext, locale: string): IHostChromePricing;
53
+ //# sourceMappingURL=useHostChromePricing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useHostChromePricing.d.ts","sourceRoot":"","sources":["../../src/ui/useHostChromePricing.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAElF;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IAC/B,oEAAoE;IACpE,OAAO,EAAE,SAAS,CAAC;IACnB,2FAA2F;IAC3F,OAAO,EAAE,OAAO,CAAC;IACjB,gFAAgF;IAChF,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,mBAAmB,EAAE,MAAM,IAAI,CAAC;CACnC;AAED;;;;;;GAMG;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,GAAG,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,KAAK,kBAAkB,CAAC;AAIpG;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,uBAAuB,GAAG,SAAS,GAAG,IAAI,CAE5F;AASD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,kBAAkB,CAE9F"}
@@ -18,3 +18,4 @@ export interface IUseHostChromeSearchArgs {
18
18
  * footer button so it can hand the user's question to the chat hook.
19
19
  */
20
20
  export declare function useHostChromeSearch({ features, isTrial, onAskAiAssistant, telemetry }: IUseHostChromeSearchArgs): IHostChromeSearch;
21
+ //# sourceMappingURL=useHostChromeSearch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useHostChromeSearch.d.ts","sourceRoot":"","sources":["../../src/ui/useHostChromeSearch.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAe,MAAM,OAAO,CAAC;AAEpD,OAAO,EAAE,KAAK,+BAA+B,EAAE,MAAM,2CAA2C,CAAC;AAKjG,OAAO,EAAE,KAAK,4BAA4B,EAAE,MAAM,qCAAqC,CAAC;AAExF,MAAM,WAAW,iBAAiB;IAC9B,uFAAuF;IACvF,OAAO,EAAE,SAAS,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACrC,QAAQ,EAAE,4BAA4B,CAAC;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,gBAAgB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,SAAS,EAAE,+BAA+B,GAAG,SAAS,CAAC;CAC1D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAChC,QAAQ,EACR,OAAO,EACP,gBAAgB,EAChB,SAAS,EACZ,EAAE,wBAAwB,GAAG,iBAAiB,CA8B9C"}
@@ -17,3 +17,4 @@ export interface IHostChromeWorkspaceFeatures {
17
17
  * chrome needs to decide whether to render search, chat, etc.
18
18
  */
19
19
  export declare function useHostChromeWorkspaceFeatures(resolvedApplications: PluggableApplicationRegistryItem[], ctx: IPlatformContext, pathname: string): IHostChromeWorkspaceFeatures;
20
+ //# sourceMappingURL=useHostChromeWorkspaceFeatures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useHostChromeWorkspaceFeatures.d.ts","sourceRoot":"","sources":["../../src/ui/useHostChromeWorkspaceFeatures.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,gCAAgC,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAI3G,MAAM,WAAW,4BAA4B;IACzC,cAAc,EAAE,OAAO,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,sBAAsB,EAAE,OAAO,CAAC;IAChC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAC1C,oBAAoB,EAAE,gCAAgC,EAAE,EACxD,GAAG,EAAE,gBAAgB,EACrB,QAAQ,EAAE,MAAM,GACjB,4BAA4B,CAmC9B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gooddata/sdk-ui-pluggable-host",
3
- "version": "11.41.0-alpha.4",
3
+ "version": "11.41.0",
4
4
  "description": "GoodData SDK runtime for hosting pluggable applications — registry, loader, routing, platform context, default UI chrome",
5
5
  "license": "MIT",
6
6
  "author": "GoodData Corporation",
@@ -29,20 +29,20 @@
29
29
  "dependencies": {
30
30
  "@module-federation/runtime": "2.3.1",
31
31
  "lodash-es": "^4.17.23",
32
- "@gooddata/sdk-backend-base": "11.41.0-alpha.4",
33
- "@gooddata/sdk-backend-spi": "11.41.0-alpha.4",
34
- "@gooddata/sdk-embedding": "11.41.0-alpha.4",
35
- "@gooddata/sdk-backend-tiger": "11.41.0-alpha.4",
36
- "@gooddata/sdk-model": "11.41.0-alpha.4",
37
- "@gooddata/sdk-pluggable-application-model": "11.41.0-alpha.4",
38
- "@gooddata/sdk-ui-application-header": "11.41.0-alpha.4",
39
- "@gooddata/sdk-ui-ext": "11.41.0-alpha.4",
40
- "@gooddata/sdk-ui-gen-ai": "11.41.0-alpha.4",
41
- "@gooddata/sdk-ui": "11.41.0-alpha.4",
42
- "@gooddata/sdk-ui-kit": "11.41.0-alpha.4",
43
- "@gooddata/sdk-ui-semantic-search": "11.41.0-alpha.4",
44
- "@gooddata/util": "11.41.0-alpha.4",
45
- "@gooddata/sdk-ui-theme-provider": "11.41.0-alpha.4"
32
+ "@gooddata/sdk-backend-spi": "11.41.0",
33
+ "@gooddata/sdk-backend-tiger": "11.41.0",
34
+ "@gooddata/sdk-backend-base": "11.41.0",
35
+ "@gooddata/sdk-embedding": "11.41.0",
36
+ "@gooddata/sdk-model": "11.41.0",
37
+ "@gooddata/sdk-pluggable-application-model": "11.41.0",
38
+ "@gooddata/sdk-ui-ext": "11.41.0",
39
+ "@gooddata/sdk-ui-application-header": "11.41.0",
40
+ "@gooddata/sdk-ui": "11.41.0",
41
+ "@gooddata/sdk-ui-kit": "11.41.0",
42
+ "@gooddata/sdk-ui-theme-provider": "11.41.0",
43
+ "@gooddata/sdk-ui-semantic-search": "11.41.0",
44
+ "@gooddata/util": "11.41.0",
45
+ "@gooddata/sdk-ui-gen-ai": "11.41.0"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@microsoft/api-documenter": "^7.17.0",
@@ -85,8 +85,8 @@
85
85
  "vite": "8.0.16",
86
86
  "vitest": "4.1.8",
87
87
  "vitest-dom": "0.1.1",
88
- "@gooddata/oxlint-config": "11.41.0-alpha.4",
89
- "@gooddata/eslint-config": "11.41.0-alpha.4"
88
+ "@gooddata/oxlint-config": "11.41.0",
89
+ "@gooddata/eslint-config": "11.41.0"
90
90
  },
91
91
  "peerDependencies": {
92
92
  "react": ">=18.3.1",