@gooddata/sdk-ui-pluggable-host 11.62.0-alpha.1 → 11.62.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 (36) hide show
  1. package/esm/components/HostUiContainer.d.ts.map +1 -1
  2. package/esm/components/HostUiContainer.js +9 -4
  3. package/esm/components/Root.scss +12 -0
  4. package/esm/components/useRedirectTarget.d.ts.map +1 -1
  5. package/esm/components/useRedirectTarget.js +9 -0
  6. package/esm/lib/stylesheetRegistry.d.ts +9 -0
  7. package/esm/lib/stylesheetRegistry.d.ts.map +1 -1
  8. package/esm/lib/stylesheetRegistry.js +36 -4
  9. package/esm/loader/federationRuntimePlugin.d.ts +1 -1
  10. package/esm/loader/federationRuntimePlugin.d.ts.map +1 -1
  11. package/esm/loader/federationRuntimePlugin.js +11 -1
  12. package/esm/platformContext/notAuthenticatedGrace.d.ts +24 -0
  13. package/esm/platformContext/notAuthenticatedGrace.d.ts.map +1 -0
  14. package/esm/platformContext/notAuthenticatedGrace.js +39 -0
  15. package/esm/platformContext/tigerNotAuthenticatedHandler.d.ts +2 -1
  16. package/esm/platformContext/tigerNotAuthenticatedHandler.d.ts.map +1 -1
  17. package/esm/platformContext/tigerNotAuthenticatedHandler.js +8 -8
  18. package/esm/platformContext/useLoadPlatformContext.d.ts.map +1 -1
  19. package/esm/platformContext/useLoadPlatformContext.js +13 -2
  20. package/esm/platformContext/useWorkspacePermissions.d.ts.map +1 -1
  21. package/esm/platformContext/useWorkspacePermissions.js +12 -0
  22. package/esm/platformContext/useWorkspaceSettings.d.ts.map +1 -1
  23. package/esm/platformContext/useWorkspaceSettings.js +9 -1
  24. package/esm/ui/GenAIChat.d.ts +4 -2
  25. package/esm/ui/GenAIChat.d.ts.map +1 -1
  26. package/esm/ui/GenAIChat.js +2 -2
  27. package/esm/ui/HostChat.d.ts +4 -2
  28. package/esm/ui/HostChat.d.ts.map +1 -1
  29. package/esm/ui/HostChat.js +2 -1
  30. package/esm/ui/PluggableApplicationRenderer.d.ts +11 -1
  31. package/esm/ui/PluggableApplicationRenderer.d.ts.map +1 -1
  32. package/esm/ui/PluggableApplicationRenderer.js +8 -2
  33. package/esm/ui/useHostChromeChat.d.ts +4 -2
  34. package/esm/ui/useHostChromeChat.d.ts.map +1 -1
  35. package/esm/ui/useHostChromeChat.js +2 -2
  36. package/package.json +20 -20
@@ -1 +1 @@
1
- {"version":3,"file":"HostUiContainer.d.ts","sourceRoot":"","sources":["../../src/components/HostUiContainer.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,EAA0B,KAAK,gCAAgC,EAAE,MAAM,qBAAqB,CAAC;AACpG,OAAO,EAGH,KAAK,gBAAgB,EAExB,MAAM,2CAA2C,CAAC;AAkBnD,OAAO,wBAAwB,CAAC;AAOhC,MAAM,WAAW,qBAAqB;IAClC,GAAG,EAAE,gBAAgB,CAAC;IACtB,IAAI,EAAE,gCAAgC,EAAE,CAAC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,gBAAgB,CAAC;IACjC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,EAAE,qBAAqB,2CAkXtG"}
1
+ {"version":3,"file":"HostUiContainer.d.ts","sourceRoot":"","sources":["../../src/components/HostUiContainer.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,EAA0B,KAAK,gCAAgC,EAAE,MAAM,qBAAqB,CAAC;AACpG,OAAO,EAGH,KAAK,gBAAgB,EAExB,MAAM,2CAA2C,CAAC;AAkBnD,OAAO,wBAAwB,CAAC;AAOhC,MAAM,WAAW,qBAAqB;IAClC,GAAG,EAAE,gBAAgB,CAAC;IACtB,IAAI,EAAE,gCAAgC,EAAE,CAAC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,gBAAgB,CAAC;IACjC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,EAAE,qBAAqB,2CA4XtG"}
@@ -70,10 +70,15 @@ export function HostUiContainer({ ctx, apps, pathname, routerNavigate, onError }
70
70
  const [aiVisibility, setAiVisibility] = useState(null);
71
71
  const [aiContext, setAiContext] = useState(null);
72
72
  const aiVisibilitySeqRef = useRef(0);
73
+ // Publisher document saved event and sequence number.
73
74
  const [aiPublisherDocumentSaved, setAiPublisherDocumentSaved] = useState(undefined);
74
- const aiPublisherDocumentSavedSeqRef = useRef(0);
75
75
  const reportAiAssistantPublisherDocumentSaved = useCallback((saved) => {
76
- setAiPublisherDocumentSaved({ ...saved, seq: ++aiPublisherDocumentSavedSeqRef.current });
76
+ setAiPublisherDocumentSaved({ ...saved, seq: (aiPublisherDocumentSaved?.seq ?? 0) + 1 });
77
+ }, []);
78
+ // Dashboard saved event and sequence number.
79
+ const [aiDashboardSaved, setAiDashboardSaved] = useState(undefined);
80
+ const reportAiAssistantDashboardSaved = useCallback((saved) => {
81
+ setAiDashboardSaved({ ...saved, seq: (aiDashboardSaved?.seq ?? 0) + 1 });
77
82
  }, []);
78
83
  const requestOpenAi = useCallback((question, agentId, userContext, appendToChat, replaceUserContext) => {
79
84
  setAiVisibility({
@@ -254,7 +259,7 @@ export function HostUiContainer({ ctx, apps, pathname, routerNavigate, onError }
254
259
  return;
255
260
  }
256
261
  if (activeInternalApplication) {
257
- appRootRef.current.render(_jsx(HostErrorBoundary, { resetKey: pathname, onError: reportError, locale: resolveLocale(ctx.preferredLocale), children: _jsx(HostIntlProvider, { locale: resolveLocale(ctx.preferredLocale), children: _jsx(PluggableApplicationRenderer, { app: activeInternalApplication, ctx: ctx, pathname: pathname, aiAssistantOpen: aiAssistantOpen, onOpenAiAssistant: requestOpenAi, onCloseAiAssistant: requestCloseAi, onAiAssistantContext: setAiAssistantContext, onAiAssistantPublisherDocumentSaved: reportAiAssistantPublisherDocumentSaved, aiLinkClickHandlerRef: appAiLinkClickRef, navigationRequestRef: appNavigationRequestRef, aiEventReceiveRef: appEventReceiveRef, onHeaderChange: onHeaderChange, onDocumentTitleChange: onDocumentTitleChange }, activeInternalApplication.id) }) }, `${activeInternalApplication.id}:${appContextEpoch}`));
262
+ appRootRef.current.render(_jsx(HostErrorBoundary, { resetKey: pathname, onError: reportError, locale: resolveLocale(ctx.preferredLocale), children: _jsx(HostIntlProvider, { locale: resolveLocale(ctx.preferredLocale), children: _jsx(PluggableApplicationRenderer, { app: activeInternalApplication, ctx: ctx, pathname: pathname, aiAssistantOpen: aiAssistantOpen, onOpenAiAssistant: requestOpenAi, onCloseAiAssistant: requestCloseAi, onAiAssistantContext: setAiAssistantContext, onAiAssistantPublisherDocumentSaved: reportAiAssistantPublisherDocumentSaved, onAiAssistantDashboardSaved: reportAiAssistantDashboardSaved, aiLinkClickHandlerRef: appAiLinkClickRef, navigationRequestRef: appNavigationRequestRef, aiEventReceiveRef: appEventReceiveRef, onHeaderChange: onHeaderChange, onDocumentTitleChange: onDocumentTitleChange }, activeInternalApplication.id) }) }, `${activeInternalApplication.id}:${appContextEpoch}`));
258
263
  }
259
264
  else {
260
265
  appRootRef.current.render(null);
@@ -274,5 +279,5 @@ export function HostUiContainer({ ctx, apps, pathname, routerNavigate, onError }
274
279
  setAiAssistantContext,
275
280
  reportAiAssistantPublisherDocumentSaved,
276
281
  ]);
277
- return (_jsxs(_Fragment, { children: [_jsx("div", { ref: containerRef, className: "gd-host-ui-container" }), hostReady && !ctx.isExportMode ? (_jsx(HostChat, { ctx: ctx, resolvedApplications: apps, pathname: pathname, activeAppId: activeInternalApplication?.id, visibility: aiVisibility, context: aiContext, publisherDocumentSaved: aiPublisherDocumentSaved, onOpenChange: setAiAssistantOpen, onChatStateChange: onChatStateChange, onAppLinkClick: onAppLinkClick, onAppEventReceive: onAppEventReceive })) : null] }));
282
+ return (_jsxs(_Fragment, { children: [_jsx("div", { ref: containerRef, className: "gd-host-ui-container" }), hostReady && !ctx.isExportMode ? (_jsx(HostChat, { ctx: ctx, resolvedApplications: apps, pathname: pathname, activeAppId: activeInternalApplication?.id, visibility: aiVisibility, context: aiContext, publisherDocumentSaved: aiPublisherDocumentSaved, dashboardSaved: aiDashboardSaved, onOpenChange: setAiAssistantOpen, onChatStateChange: onChatStateChange, onAppLinkClick: onAppLinkClick, onAppEventReceive: onAppEventReceive })) : null] }));
278
283
  }
@@ -9,6 +9,18 @@
9
9
  }
10
10
 
11
11
  &__error {
12
+ min-height: 100vh;
13
+ box-sizing: border-box;
14
+ display: flex;
15
+ flex-direction: column;
16
+ align-items: center;
17
+ justify-content: center;
12
18
  padding: 2rem;
19
+ text-align: center;
13
20
  }
14
21
  }
22
+
23
+ // The app slot sits below the host header, so a viewport-high fallback would overflow it.
24
+ .gd-host-chrome__app-container > .gd-host-root__error {
25
+ min-height: 100%;
26
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"useRedirectTarget.d.ts","sourceRoot":"","sources":["../../src/components/useRedirectTarget.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,gCAAgC,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAOlF,MAAM,MAAM,mBAAmB,GACzB;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,GACpB;IAAE,KAAK,EAAE,QAAQ,CAAA;CAAE,GACnB;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,KAAK,EAAE,WAAW,CAAA;CAAE,GACtB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC;;GAEG;AACH,wBAAgB,iBAAiB,CAC7B,IAAI,EAAE,gCAAgC,EAAE,EACxC,GAAG,EAAE,gBAAgB,EACrB,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,GAChB,mBAAmB,CA6DrB"}
1
+ {"version":3,"file":"useRedirectTarget.d.ts","sourceRoot":"","sources":["../../src/components/useRedirectTarget.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,gCAAgC,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAQlF,MAAM,MAAM,mBAAmB,GACzB;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,GACpB;IAAE,KAAK,EAAE,QAAQ,CAAA;CAAE,GACnB;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,KAAK,EAAE,WAAW,CAAA;CAAE,GACtB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC;;GAEG;AACH,wBAAgB,iBAAiB,CAC7B,IAAI,EAAE,gCAAgC,EAAE,EACxC,GAAG,EAAE,gBAAgB,EACrB,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,GAChB,mBAAmB,CAsErB"}
@@ -1,8 +1,10 @@
1
1
  // (C) 2026 GoodData Corporation
2
2
  import { useEffect, useState } from "react";
3
+ import { isNotAuthenticated } from "@gooddata/sdk-backend-spi";
3
4
  import { debugLog } from "../debug.js";
4
5
  import { AppNotFoundError, resolveRedirectTarget } from "../loader/redirectLogic.js";
5
6
  import { getBackend } from "../platformContext/backend.js";
7
+ import { afterNotAuthenticatedGrace } from "../platformContext/notAuthenticatedGrace.js";
6
8
  import { getWorkspaceAccess } from "../platformContext/workspaceAccess.js";
7
9
  /**
8
10
  * Resolves the redirect target for the current URL and permission context.
@@ -11,6 +13,7 @@ export function useRedirectTarget(apps, ctx, pathname, search) {
11
13
  const [redirectState, setRedirectState] = useState({ state: "loading" });
12
14
  useEffect(() => {
13
15
  let cancelled = false;
16
+ let cancelGrace;
14
17
  // Preserve "render" state during re-resolution so that HostUiContainer stays mounted
15
18
  // while the async redirect check runs. Other states (loading, error, not-found) reset to loading.
16
19
  setRedirectState((prev) => (prev.state === "render" ? prev : { state: "loading" }));
@@ -54,11 +57,17 @@ export function useRedirectTarget(apps, ctx, pathname, search) {
54
57
  else {
55
58
  const error = e instanceof Error ? e.message : "Unknown redirect error.";
56
59
  debugLog(`[host-app/redirect] useRedirectTarget: unexpected error → ${error}`);
60
+ // Stay "loading" while the backend redirects to login on a 401.
61
+ if (isNotAuthenticated(e)) {
62
+ cancelGrace = afterNotAuthenticatedGrace(() => setRedirectState({ state: "error", error }));
63
+ return;
64
+ }
57
65
  setRedirectState({ state: "error", error });
58
66
  }
59
67
  });
60
68
  return () => {
61
69
  cancelled = true;
70
+ cancelGrace?.();
62
71
  };
63
72
  }, [apps, pathname, search, ctx]);
64
73
  return redirectState;
@@ -23,6 +23,15 @@ export declare function registerAppStylesheetScope(appId: string, remoteEntryUrl
23
23
  * is resolved before an app renders inside it.
24
24
  */
25
25
  export declare function reserveHostStylesheetScope(remoteEntryUrl: string): void;
26
+ /**
27
+ * Declares that the remote at `remoteEntryUrl` serves its assets from `assetBaseUrl`, so
28
+ * stylesheet links under that base belong to whichever app owns the remote entry URL.
29
+ *
30
+ * Call order relative to `registerAppStylesheetScope` does not matter. Refused with a warning
31
+ * when the base is an origin root or covers the host UI module's scope, because it would then
32
+ * claim host stylesheets.
33
+ */
34
+ export declare function registerRemoteAssetBase(remoteEntryUrl: string, assetBaseUrl: string): void;
26
35
  /**
27
36
  * Re-enables all stylesheets attributed to the app. Safe to call before any of the
28
37
  * app's CSS exists and repeatedly.
@@ -1 +1 @@
1
- {"version":3,"file":"stylesheetRegistry.d.ts","sourceRoot":"","sources":["../../src/lib/stylesheetRegistry.ts"],"names":[],"mappings":"AAkJA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,IAAI,CAiCtF;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAQvE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAM1D;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAM5D;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,CAQ9C"}
1
+ {"version":3,"file":"stylesheetRegistry.d.ts","sourceRoot":"","sources":["../../src/lib/stylesheetRegistry.ts"],"names":[],"mappings":"AA4JA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,IAAI,CAiCtF;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAQvE;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAkB1F;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAM1D;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAM5D;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,CAS9C"}
@@ -1,10 +1,14 @@
1
1
  // (C) 2026 GoodData Corporation
2
2
  const scopePrefixes = new Map();
3
3
  const reservedHostPrefixes = new Set();
4
+ const assetBaseAliases = new Map();
4
5
  const deactivatedApps = new Set();
5
6
  let linkLoadStates = new WeakMap();
6
7
  let retiredLinks = new WeakSet();
7
8
  let observer;
9
+ function withAliases(prefix) {
10
+ return [prefix, ...(assetBaseAliases.get(prefix) ?? [])];
11
+ }
8
12
  function deriveScopePrefix(remoteEntryUrl) {
9
13
  try {
10
14
  const url = new URL(remoteEntryUrl, document.baseURI);
@@ -21,9 +25,11 @@ function findOwnerOfHref(href) {
21
25
  let longestPrefixLength = -1;
22
26
  for (const [appId, prefixes] of scopePrefixes) {
23
27
  for (const prefix of prefixes) {
24
- if (href.startsWith(prefix) && prefix.length > longestPrefixLength) {
25
- owner = appId;
26
- longestPrefixLength = prefix.length;
28
+ for (const candidate of withAliases(prefix)) {
29
+ if (href.startsWith(candidate) && candidate.length > longestPrefixLength) {
30
+ owner = appId;
31
+ longestPrefixLength = candidate.length;
32
+ }
27
33
  }
28
34
  }
29
35
  }
@@ -32,7 +38,7 @@ function findOwnerOfHref(href) {
32
38
  // An app prefix above a reserved host prefix would claim the host's own links.
33
39
  function coversReservedHostScope(prefix) {
34
40
  for (const reserved of reservedHostPrefixes) {
35
- if (reserved.startsWith(prefix)) {
41
+ if (withAliases(reserved).some((candidate) => candidate.startsWith(prefix))) {
36
42
  return true;
37
43
  }
38
44
  }
@@ -171,6 +177,31 @@ export function reserveHostStylesheetScope(remoteEntryUrl) {
171
177
  reservedHostPrefixes.add(prefix);
172
178
  }
173
179
  }
180
+ /**
181
+ * Declares that the remote at `remoteEntryUrl` serves its assets from `assetBaseUrl`, so
182
+ * stylesheet links under that base belong to whichever app owns the remote entry URL.
183
+ *
184
+ * Call order relative to `registerAppStylesheetScope` does not matter. Refused with a warning
185
+ * when the base is an origin root or covers the host UI module's scope, because it would then
186
+ * claim host stylesheets.
187
+ */
188
+ export function registerRemoteAssetBase(remoteEntryUrl, assetBaseUrl) {
189
+ if (typeof document === "undefined") {
190
+ return;
191
+ }
192
+ const prefix = deriveScopePrefix(remoteEntryUrl);
193
+ const alias = deriveScopePrefix(assetBaseUrl.endsWith("/") ? assetBaseUrl : `${assetBaseUrl}/`);
194
+ if (!prefix || !alias || alias === prefix) {
195
+ return;
196
+ }
197
+ if (new URL(alias).pathname === "/" || coversReservedHostScope(alias)) {
198
+ console.warn(`[host-runtime/stylesheet-registry] Not tracking stylesheets under asset base "${assetBaseUrl}" of remote "${remoteEntryUrl}": the base would also cover host stylesheets.`);
199
+ return;
200
+ }
201
+ const aliases = assetBaseAliases.get(prefix) ?? new Set();
202
+ aliases.add(alias);
203
+ assetBaseAliases.set(prefix, aliases);
204
+ }
174
205
  /**
175
206
  * Re-enables all stylesheets attributed to the app. Safe to call before any of the
176
207
  * app's CSS exists and repeatedly.
@@ -199,6 +230,7 @@ export function deactivateAppStylesheets(appId) {
199
230
  export function resetStylesheetRegistry() {
200
231
  scopePrefixes.clear();
201
232
  reservedHostPrefixes.clear();
233
+ assetBaseAliases.clear();
202
234
  deactivatedApps.clear();
203
235
  linkLoadStates = new WeakMap();
204
236
  retiredLinks = new WeakSet();
@@ -42,7 +42,7 @@ export declare function evictRemoteEntryLoadCache(remoteInfo: {
42
42
  }): void;
43
43
  /**
44
44
  * Host-side Module Federation runtime plugin. Registered on the federation instance created
45
- * by the remote loader; both hooks work around behaviour of the MF runtime we cannot
45
+ * by the remote loader; its hooks work around behaviour of the MF runtime we cannot
46
46
  * configure any other way.
47
47
  */
48
48
  export declare function createHostFederationPlugin(): ModuleFederationRuntimePlugin;
@@ -1 +1 @@
1
- {"version":3,"file":"federationRuntimePlugin.d.ts","sourceRoot":"","sources":["../../src/loader/federationRuntimePlugin.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,6BAA6B,EAAE,MAAM,4BAA4B,CAAC;AAEhF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAE9C;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,2BAA2B,oCAAoC,CAAC;AAK7E;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAU3F;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,IAAI,6BAA6B,CAgB1E"}
1
+ {"version":3,"file":"federationRuntimePlugin.d.ts","sourceRoot":"","sources":["../../src/loader/federationRuntimePlugin.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,6BAA6B,EAAE,MAAM,4BAA4B,CAAC;AAIhF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAE9C;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,2BAA2B,oCAAoC,CAAC;AAK7E;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAU3F;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,IAAI,6BAA6B,CA0B1E"}
@@ -1,4 +1,5 @@
1
1
  // (C) 2026 GoodData Corporation
2
+ import { registerRemoteAssetBase } from "../lib/stylesheetRegistry.js";
2
3
  /**
3
4
  * Timeout applied to every `<link rel="preload">` Module Federation creates.
4
5
  *
@@ -46,7 +47,7 @@ export function evictRemoteEntryLoadCache(remoteInfo) {
46
47
  }
47
48
  /**
48
49
  * Host-side Module Federation runtime plugin. Registered on the federation instance created
49
- * by the remote loader; both hooks work around behaviour of the MF runtime we cannot
50
+ * by the remote loader; its hooks work around behaviour of the MF runtime we cannot
50
51
  * configure any other way.
51
52
  */
52
53
  export function createHostFederationPlugin() {
@@ -62,5 +63,14 @@ export function createHostFederationPlugin() {
62
63
  evictRemoteEntryLoadCache(remoteInfo);
63
64
  }
64
65
  },
66
+ // A manifest publicPath (e.g. the CDN base) moves the remote's CSS off its entry URL.
67
+ // The stylesheet registry must know that base to attribute those links to the app.
68
+ loadRemoteSnapshot: async (args) => {
69
+ const { moduleInfo, remoteSnapshot } = args;
70
+ if ("entry" in moduleInfo && "publicPath" in remoteSnapshot && remoteSnapshot.publicPath) {
71
+ registerRemoteAssetBase(moduleInfo.entry, remoteSnapshot.publicPath);
72
+ }
73
+ return args;
74
+ },
65
75
  };
66
76
  }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * How long a 401 is treated as "login redirect in progress" before it is shown as an error.
3
+ *
4
+ * @remarks
5
+ * The backend's not-authenticated handler navigates to the login page on every 401, so the error
6
+ * is normally never seen. The error surfaces only when no navigation happens, e.g. the 401 carries
7
+ * no authentication flow or an embedding host installed a handler that does not redirect.
8
+ *
9
+ * @internal
10
+ */
11
+ export declare const NOT_AUTHENTICATED_GRACE_MS = 10000;
12
+ /**
13
+ * Calls `onExpired` once the grace period passes. Returns a function that cancels the call.
14
+ *
15
+ * @internal
16
+ */
17
+ export declare function afterNotAuthenticatedGrace(onExpired: () => void): () => void;
18
+ /**
19
+ * Resolves once the grace period passes, or immediately when `signal` aborts.
20
+ *
21
+ * @internal
22
+ */
23
+ export declare function waitForNotAuthenticatedGrace(signal: AbortSignal): Promise<void>;
24
+ //# sourceMappingURL=notAuthenticatedGrace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notAuthenticatedGrace.d.ts","sourceRoot":"","sources":["../../src/platformContext/notAuthenticatedGrace.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,eAAO,MAAM,0BAA0B,QAAS,CAAC;AAEjD;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAG5E;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB/E"}
@@ -0,0 +1,39 @@
1
+ // (C) 2026 GoodData Corporation
2
+ /**
3
+ * How long a 401 is treated as "login redirect in progress" before it is shown as an error.
4
+ *
5
+ * @remarks
6
+ * The backend's not-authenticated handler navigates to the login page on every 401, so the error
7
+ * is normally never seen. The error surfaces only when no navigation happens, e.g. the 401 carries
8
+ * no authentication flow or an embedding host installed a handler that does not redirect.
9
+ *
10
+ * @internal
11
+ */
12
+ export const NOT_AUTHENTICATED_GRACE_MS = 10_000;
13
+ /**
14
+ * Calls `onExpired` once the grace period passes. Returns a function that cancels the call.
15
+ *
16
+ * @internal
17
+ */
18
+ export function afterNotAuthenticatedGrace(onExpired) {
19
+ const timer = setTimeout(onExpired, NOT_AUTHENTICATED_GRACE_MS);
20
+ return () => clearTimeout(timer);
21
+ }
22
+ /**
23
+ * Resolves once the grace period passes, or immediately when `signal` aborts.
24
+ *
25
+ * @internal
26
+ */
27
+ export function waitForNotAuthenticatedGrace(signal) {
28
+ return new Promise((resolve) => {
29
+ if (signal.aborted) {
30
+ resolve();
31
+ return;
32
+ }
33
+ const cancel = afterNotAuthenticatedGrace(resolve);
34
+ signal.addEventListener("abort", () => {
35
+ cancel();
36
+ resolve();
37
+ }, { once: true });
38
+ });
39
+ }
@@ -1,4 +1,5 @@
1
1
  import { type IAuthenticationContext, type NotAuthenticated } from "@gooddata/sdk-backend-spi";
2
+ import { type RedirectToTigerAuthenticationHandler } from "@gooddata/sdk-backend-tiger";
2
3
  /** Not authenticated handler will be called every time 401 is returned from Tiger backend. */
3
- export declare function createNotAuthenticatedHandler(externalProviderId?: string): (ctx: IAuthenticationContext, err: NotAuthenticated) => void;
4
+ export declare function createNotAuthenticatedHandler(externalProviderId?: string, redirectHandler?: RedirectToTigerAuthenticationHandler): (ctx: IAuthenticationContext, err: NotAuthenticated) => void;
4
5
  //# sourceMappingURL=tigerNotAuthenticatedHandler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tigerNotAuthenticatedHandler.d.ts","sourceRoot":"","sources":["../../src/platformContext/tigerNotAuthenticatedHandler.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,sBAAsB,EAAE,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAM/F,8FAA8F;AAE9F,wBAAgB,6BAA6B,CACzC,kBAAkB,CAAC,EAAE,MAAM,GAC5B,CAAC,GAAG,EAAE,sBAAsB,EAAE,GAAG,EAAE,gBAAgB,KAAK,IAAI,CAY9D"}
1
+ {"version":3,"file":"tigerNotAuthenticatedHandler.d.ts","sourceRoot":"","sources":["../../src/platformContext/tigerNotAuthenticatedHandler.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,sBAAsB,EAAE,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC/F,OAAO,EACH,KAAK,oCAAoC,EAG5C,MAAM,6BAA6B,CAAC;AAErC,8FAA8F;AAE9F,wBAAgB,6BAA6B,CACzC,kBAAkB,CAAC,EAAE,MAAM,EAC3B,eAAe,GAAE,oCAEkB,GACpC,CAAC,GAAG,EAAE,sBAAsB,EAAE,GAAG,EAAE,gBAAgB,KAAK,IAAI,CAU9D"}
@@ -2,15 +2,15 @@
2
2
  import { throttle } from "lodash-es";
3
3
  import { createRedirectToTigerAuthenticationWithParams, redirectToTigerAuthentication, } from "@gooddata/sdk-backend-tiger";
4
4
  /** Not authenticated handler will be called every time 401 is returned from Tiger backend. */
5
- export function createNotAuthenticatedHandler(externalProviderId) {
6
- const redirectHandler = externalProviderId
7
- ? createRedirectToTigerAuthenticationWithParams({ externalProviderId })
8
- : redirectToTigerAuthentication;
9
- const debouncedRedirectHandler = throttle(redirectHandler, 500, {
10
- leading: false,
11
- trailing: true,
5
+ export function createNotAuthenticatedHandler(externalProviderId, redirectHandler = externalProviderId
6
+ ? createRedirectToTigerAuthenticationWithParams({ externalProviderId })
7
+ : redirectToTigerAuthentication) {
8
+ // Boot fires several requests in parallel. Redirect on the first 401 and ignore the rest.
9
+ const throttledRedirectHandler = throttle(redirectHandler, 500, {
10
+ leading: true,
11
+ trailing: false,
12
12
  });
13
13
  return (ctx, err) => {
14
- debouncedRedirectHandler(ctx, err);
14
+ throttledRedirectHandler(ctx, err);
15
15
  };
16
16
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useLoadPlatformContext.d.ts","sourceRoot":"","sources":["../../src/platformContext/useLoadPlatformContext.ts"],"names":[],"mappings":"AAOA,OAAO,EAA2B,KAAK,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAO3G,OAAO,EACH,KAAK,6BAA6B,EAGrC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACH,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,EAElC,MAAM,YAAY,CAAC;AAYpB;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,IAAI,0BAA0B,CAAC,gBAAgB,CAAC,CA6JrF;AAED;;;;GAIG;AACH,MAAM,WAAW,+BAA+B;IAC5C,YAAY,CAAC,SAAS,EAAE,6BAA6B,GAAG,IAAI,CAAC;IAC7D,SAAS,EAAE,MAAM,QAAQ,CAAC,0BAA0B,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAC/E,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;IAChD,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AAmED;;GAEG;AACH,eAAO,MAAM,8BAA8B,EAAE,+BACA,CAAC;AAE9C;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAAC,SAAS,EAAE,6BAA6B,GAAG,IAAI,CAE/F"}
1
+ {"version":3,"file":"useLoadPlatformContext.d.ts","sourceRoot":"","sources":["../../src/platformContext/useLoadPlatformContext.ts"],"names":[],"mappings":"AAQA,OAAO,EAA2B,KAAK,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAO3G,OAAO,EACH,KAAK,6BAA6B,EAGrC,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACH,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,EAElC,MAAM,YAAY,CAAC;AAYpB;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,IAAI,0BAA0B,CAAC,gBAAgB,CAAC,CA6JrF;AAED;;;;GAIG;AACH,MAAM,WAAW,+BAA+B;IAC5C,YAAY,CAAC,SAAS,EAAE,6BAA6B,GAAG,IAAI,CAAC;IAC7D,SAAS,EAAE,MAAM,QAAQ,CAAC,0BAA0B,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAC/E,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;IAChD,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AA4ED;;GAEG;AACH,eAAO,MAAM,8BAA8B,EAAE,+BACA,CAAC;AAE9C;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAAC,SAAS,EAAE,6BAA6B,GAAG,IAAI,CAE/F"}
@@ -1,12 +1,14 @@
1
1
  // (C) 2026 GoodData Corporation
2
2
  import { useEffect, useMemo, useState, useSyncExternalStore } from "react";
3
3
  import { useLocation } from "react-router";
4
+ import { isNotAuthenticated } from "@gooddata/sdk-backend-spi";
4
5
  import { isLocale } from "@gooddata/sdk-model";
5
6
  import { isProduction } from "../lib/isProduction.js";
6
7
  import { getApplicationScopeFromPath, getWorkspaceIdFromPath } from "../loader/routing.js";
7
8
  import { resolveAvailableWorkspaceApplications } from "../registry/pluggableApplicationsRegistry.js";
8
9
  import { getBackend } from "./backend.js";
9
10
  import { HostApplicationDisabledError, loadPlatformContext, } from "./loadPlatformContext.js";
11
+ import { waitForNotAuthenticatedGrace } from "./notAuthenticatedGrace.js";
10
12
  import { useWorkspaceColorPalette } from "./useWorkspaceColorPalette.js";
11
13
  import { useWorkspacePermissions } from "./useWorkspacePermissions.js";
12
14
  import { useWorkspaceSettings } from "./useWorkspaceSettings.js";
@@ -171,12 +173,13 @@ class BackendPlatformContextProviderClass {
171
173
  this._setResult(this._loadingStateMemo);
172
174
  }
173
175
  this._abortController = new AbortController();
176
+ const signal = this._abortController.signal;
174
177
  try {
175
178
  if (shouldWaitForInjectedApiToken()) {
176
- await waitForInjectedApiToken(this._abortController.signal);
179
+ await waitForInjectedApiToken(signal);
177
180
  }
178
181
  const ctx = await loadPlatformContext({
179
- signal: this._abortController.signal,
182
+ signal,
180
183
  callbacks: this._callbacks,
181
184
  });
182
185
  if (!this._abortController.signal.aborted) {
@@ -191,6 +194,14 @@ class BackendPlatformContextProviderClass {
191
194
  if (e instanceof DOMException && e.name === "AbortError") {
192
195
  return;
193
196
  }
197
+ // The backend redirects to login on a 401. Keep the loader up so the error does not
198
+ // flash before the browser leaves the page.
199
+ if (isNotAuthenticated(e)) {
200
+ await waitForNotAuthenticatedGrace(signal);
201
+ if (signal.aborted) {
202
+ return;
203
+ }
204
+ }
194
205
  console.error("[host-runtime/platform-context] Failed to load platform context.", e);
195
206
  const message = e instanceof Error ? e.message : "Unknown platform context error.";
196
207
  if (!this._abortController.signal.aborted) {
@@ -1 +1 @@
1
- {"version":3,"file":"useWorkspacePermissions.d.ts","sourceRoot":"","sources":["../../src/platformContext/useWorkspacePermissions.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAIjE,KAAK,yBAAyB,GACxB;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,GACpB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,qBAAqB,CAAA;CAAE,GACtD;IAAE,KAAK,EAAE,WAAW,CAAA;CAAE,GACtB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAYxC;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACnC,OAAO,EAAE,kBAAkB,GAAG,SAAS,EACvC,WAAW,EAAE,MAAM,GAAG,SAAS,GAChC,yBAAyB,CA6D3B"}
1
+ {"version":3,"file":"useWorkspacePermissions.d.ts","sourceRoot":"","sources":["../../src/platformContext/useWorkspacePermissions.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,kBAAkB,EAAsB,MAAM,2BAA2B,CAAC;AACxF,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAKjE,KAAK,yBAAyB,GACxB;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,GACpB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,qBAAqB,CAAA;CAAE,GACtD;IAAE,KAAK,EAAE,WAAW,CAAA;CAAE,GACtB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAYxC;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACnC,OAAO,EAAE,kBAAkB,GAAG,SAAS,EACvC,WAAW,EAAE,MAAM,GAAG,SAAS,GAChC,yBAAyB,CAuE3B"}
@@ -1,5 +1,7 @@
1
1
  // (C) 2026 GoodData Corporation
2
2
  import { useEffect, useState } from "react";
3
+ import { isNotAuthenticated } from "@gooddata/sdk-backend-spi";
4
+ import { afterNotAuthenticatedGrace } from "./notAuthenticatedGrace.js";
3
5
  import { classifyWorkspaceAccessError } from "./workspaceAccess.js";
4
6
  const IDLE = { state: "idle" };
5
7
  const LOADING = { state: "loading" };
@@ -26,6 +28,7 @@ export function useWorkspacePermissions(backend, workspaceId) {
26
28
  return;
27
29
  }
28
30
  let cancelled = false;
31
+ let cancelGrace;
29
32
  setSnapshot({ backend, workspaceId, state: LOADING });
30
33
  const update = (state) => {
31
34
  if (!cancelled) {
@@ -49,10 +52,19 @@ export function useWorkspacePermissions(backend, workspaceId) {
49
52
  return;
50
53
  }
51
54
  const error = e instanceof Error ? e.message : "Unknown error loading workspace permissions.";
55
+ // Stay "loading" while the backend redirects to login on a 401.
56
+ if (isNotAuthenticated(e)) {
57
+ if (cancelled) {
58
+ return;
59
+ }
60
+ cancelGrace = afterNotAuthenticatedGrace(() => update({ state: "error", error }));
61
+ return;
62
+ }
52
63
  update({ state: "error", error });
53
64
  });
54
65
  return () => {
55
66
  cancelled = true;
67
+ cancelGrace?.();
56
68
  };
57
69
  }, [backend, workspaceId]);
58
70
  if (!backend || !workspaceId) {
@@ -1 +1 @@
1
- {"version":3,"file":"useWorkspaceSettings.d.ts","sourceRoot":"","sources":["../../src/platformContext/useWorkspaceSettings.ts"],"names":[],"mappings":"AAIA,OAAO,EAEH,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC9B,MAAM,2BAA2B,CAAC;AAEnC,KAAK,sBAAsB,GACrB;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,GACpB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,sBAAsB,CAAA;CAAE,GACpD;IAAE,KAAK,EAAE,WAAW,CAAA;CAAE,GACtB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAChC,OAAO,EAAE,kBAAkB,GAAG,SAAS,EACvC,WAAW,EAAE,MAAM,GAAG,SAAS,GAChC,sBAAsB,CAqCxB"}
1
+ {"version":3,"file":"useWorkspaceSettings.d.ts","sourceRoot":"","sources":["../../src/platformContext/useWorkspaceSettings.ts"],"names":[],"mappings":"AAIA,OAAO,EAEH,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAE9B,MAAM,2BAA2B,CAAC;AAInC,KAAK,sBAAsB,GACrB;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,GACpB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,sBAAsB,CAAA;CAAE,GACpD;IAAE,KAAK,EAAE,WAAW,CAAA;CAAE,GACtB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAChC,OAAO,EAAE,kBAAkB,GAAG,SAAS,EACvC,WAAW,EAAE,MAAM,GAAG,SAAS,GAChC,sBAAsB,CA8CxB"}
@@ -1,6 +1,7 @@
1
1
  // (C) 2026 GoodData Corporation
2
2
  import { useEffect, useState } from "react";
3
- import { UnexpectedResponseError, } from "@gooddata/sdk-backend-spi";
3
+ import { UnexpectedResponseError, isNotAuthenticated, } from "@gooddata/sdk-backend-spi";
4
+ import { afterNotAuthenticatedGrace } from "./notAuthenticatedGrace.js";
4
5
  /**
5
6
  * Loads effective workspace-scoped settings for the current user.
6
7
  *
@@ -18,6 +19,7 @@ export function useWorkspaceSettings(backend, workspaceId) {
18
19
  return;
19
20
  }
20
21
  let cancelled = false;
22
+ let cancelGrace;
21
23
  setSettingsState({ state: "loading" });
22
24
  backend
23
25
  .workspace(workspaceId)
@@ -36,10 +38,16 @@ export function useWorkspaceSettings(backend, workspaceId) {
36
38
  return;
37
39
  }
38
40
  const error = e instanceof Error ? e.message : "Unknown error loading workspace settings.";
41
+ // Stay "loading" while the backend redirects to login on a 401.
42
+ if (isNotAuthenticated(e)) {
43
+ cancelGrace = afterNotAuthenticatedGrace(() => setSettingsState({ state: "error", error }));
44
+ return;
45
+ }
39
46
  setSettingsState({ state: "error", error });
40
47
  });
41
48
  return () => {
42
49
  cancelled = true;
50
+ cancelGrace?.();
43
51
  };
44
52
  }, [backend, workspaceId]);
45
53
  return settingsState;
@@ -1,7 +1,7 @@
1
1
  import { type IUserWorkspaceSettings } from "@gooddata/sdk-backend-spi";
2
2
  import type { IGenAIUserContext } from "@gooddata/sdk-model";
3
3
  import { type ChatDefinitionReceivedEvent, type ChatAssistantMessageEvent, type ChatClosedEvent, type ChatFeedbackEvent, type ChatOpenedEvent, type ChatResetEvent, type ChatUserMessageEvent, type ChatModeChangeEvent } from "@gooddata/sdk-ui-gen-ai";
4
- import { type IPublisherDocumentSaved } from "@gooddata/sdk-ui-gen-ai/internal";
4
+ import { type IDashboardSaved, type IPublisherDocumentSaved } from "@gooddata/sdk-ui-gen-ai/internal";
5
5
  /**
6
6
  * Discriminated union of GenAI chat events that are forwarded to the host
7
7
  * caller via the `onEvent` callback.
@@ -76,6 +76,8 @@ export interface IGenAIChatProps {
76
76
  ambientUserContextLoading?: boolean;
77
77
  /** The latest document of the conversation that the active application saved. */
78
78
  publisherDocumentSaved: IPublisherDocumentSaved | undefined;
79
+ /** The latest dashboard save reported by the active application. */
80
+ dashboardSaved: IDashboardSaved | undefined;
79
81
  /**
80
82
  * Tag identifiers the assistant's object search/autocomplete should be restricted to,
81
83
  * reflecting the active hosted application's current view.
@@ -108,5 +110,5 @@ export interface IGenAIChatProps {
108
110
  * (`@gooddata/sdk-ui-gen-ai/internal`); this adapter only supplies the host's data sources, renders the
109
111
  * host's own save-visualization / copy toasts, and forwards telemetry events through `onEvent`.
110
112
  */
111
- export declare function GenAIChat({ workspaceId, open, disabled, onOpen, onClose, askedQuestion, askSeq, appendToChat, agentId, userContext, replaceUserContext, ambientUserContext, ambientUserContextLoading, publisherDocumentSaved, includeTags, excludeTags, canManageProject, canAnalyzeProject, canFullControl, settings, dialogPosition, embedded, onAppLinkClick, onEvent, }: IGenAIChatProps): import("react/jsx-runtime").JSX.Element;
113
+ export declare function GenAIChat({ workspaceId, open, disabled, onOpen, onClose, askedQuestion, askSeq, appendToChat, agentId, userContext, replaceUserContext, ambientUserContext, ambientUserContextLoading, publisherDocumentSaved, dashboardSaved, includeTags, excludeTags, canManageProject, canAnalyzeProject, canFullControl, settings, dialogPosition, embedded, onAppLinkClick, onEvent, }: IGenAIChatProps): import("react/jsx-runtime").JSX.Element;
112
114
  //# sourceMappingURL=GenAIChat.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GenAIChat.d.ts","sourceRoot":"","sources":["../../src/ui/GenAIChat.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"GenAIChat.d.ts","sourceRoot":"","sources":["../../src/ui/GenAIChat.tsx"],"names":[],"mappings":"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"}
@@ -18,7 +18,7 @@ const EMBEDDED_CHAT_CLASS = "gd-gen-ai-chat-embedded";
18
18
  * (`@gooddata/sdk-ui-gen-ai/internal`); this adapter only supplies the host's data sources, renders the
19
19
  * host's own save-visualization / copy toasts, and forwards telemetry events through `onEvent`.
20
20
  */
21
- export function GenAIChat({ workspaceId, open, disabled, onOpen, onClose, askedQuestion, askSeq, appendToChat, agentId, userContext, replaceUserContext, ambientUserContext, ambientUserContextLoading, publisherDocumentSaved, includeTags, excludeTags, canManageProject, canAnalyzeProject, canFullControl, settings, dialogPosition, embedded, onAppLinkClick, onEvent, }) {
21
+ export function GenAIChat({ workspaceId, open, disabled, onOpen, onClose, askedQuestion, askSeq, appendToChat, agentId, userContext, replaceUserContext, ambientUserContext, ambientUserContextLoading, publisherDocumentSaved, dashboardSaved, includeTags, excludeTags, canManageProject, canAnalyzeProject, canFullControl, settings, dialogPosition, embedded, onAppLinkClick, onEvent, }) {
22
22
  const { addSuccess, addError } = useToastMessage();
23
23
  const intl = useIntl();
24
24
  const backend = useBackendStrict();
@@ -74,5 +74,5 @@ export function GenAIChat({ workspaceId, open, disabled, onOpen, onClose, askedQ
74
74
  }
75
75
  }, [addError, addSuccess, intl, onEvent]);
76
76
  const enableRightPanel = useGenAiRightPanel(settings?.["enableGenAiRightPanel"], embedded);
77
- return (_jsx(GenAIChatDialogConnected, { backend: backend, workspace: workspaceId, locale: intl.locale, isOpen: open, isDisabled: disabled, onOpen: onOpen, onClose: onClose, askedQuestion: askedQuestion, askSeq: askSeq, userContext: userContext, appendToChat: appendToChat, agentId: agentId, replaceUserContext: replaceUserContext, ambientUserContext: ambientUserContext, publisherDocumentSaved: publisherDocumentSaved, ambientUserContextLoading: ambientUserContextLoading, includeTags: includeTags, excludeTags: excludeTags, canManage: canManageProject, canAnalyze: canAnalyzeProject, canFullControl: canFullControl, settings: settings, dialogPosition: dialogPosition, className: embedded ? EMBEDDED_CHAT_CLASS : undefined, allowNativeLinks: false, onLinkClick: onLinkClick, onEvent: handleEvent, displayMode: enableRightPanel ? "inline" : "modal", returnFocusTo: embedded ? EMBEDDED_AI_TRIGGER_ID : HEADER_CHAT_BUTTON_ID }));
77
+ return (_jsx(GenAIChatDialogConnected, { backend: backend, workspace: workspaceId, locale: intl.locale, isOpen: open, isDisabled: disabled, onOpen: onOpen, onClose: onClose, askedQuestion: askedQuestion, askSeq: askSeq, userContext: userContext, appendToChat: appendToChat, agentId: agentId, replaceUserContext: replaceUserContext, ambientUserContext: ambientUserContext, publisherDocumentSaved: publisherDocumentSaved, dashboardSaved: dashboardSaved, ambientUserContextLoading: ambientUserContextLoading, includeTags: includeTags, excludeTags: excludeTags, canManage: canManageProject, canAnalyze: canAnalyzeProject, canFullControl: canFullControl, settings: settings, dialogPosition: dialogPosition, className: embedded ? EMBEDDED_CHAT_CLASS : undefined, allowNativeLinks: false, onLinkClick: onLinkClick, onEvent: handleEvent, displayMode: enableRightPanel ? "inline" : "modal", returnFocusTo: embedded ? EMBEDDED_AI_TRIGGER_ID : HEADER_CHAT_BUTTON_ID }));
78
78
  }
@@ -1,7 +1,7 @@
1
1
  import { type IGenAIUserContext, type PluggableApplicationRegistryItem } from "@gooddata/sdk-model";
2
2
  import { type IPlatformContext } from "@gooddata/sdk-pluggable-application-model";
3
3
  import { GenAIAssistantMode } from "@gooddata/sdk-ui-gen-ai";
4
- import { type IPublisherDocumentSaved } from "@gooddata/sdk-ui-gen-ai/internal";
4
+ import { type IDashboardSaved, type IPublisherDocumentSaved } from "@gooddata/sdk-ui-gen-ai/internal";
5
5
  import { GenAIChatEvent } from "./GenAIChat.js";
6
6
  import "./HostChat.scss";
7
7
  import "@gooddata/sdk-ui-gen-ai/styles/css/main.css";
@@ -71,6 +71,8 @@ export interface IHostChatProps {
71
71
  onAppEventReceive?: (event: GenAIChatEvent) => void;
72
72
  /** The latest document of the conversation that the active application saved. */
73
73
  publisherDocumentSaved: IPublisherDocumentSaved | undefined;
74
+ /** The latest dashboard save reported by the active application. */
75
+ dashboardSaved: IDashboardSaved | undefined;
74
76
  }
75
77
  /**
76
78
  * Owns and renders the host's single GenAI chat, decoupled from the host UI module.
@@ -81,5 +83,5 @@ export interface IHostChatProps {
81
83
  * (embedded/export). The header chat button and app-side controls drive it through the `visibility`
82
84
  * and `context` props; it reports its open-state and button state back via callbacks.
83
85
  */
84
- export declare function HostChat({ ctx, resolvedApplications, pathname, activeAppId, visibility, context, onOpenChange, onChatStateChange, onAppLinkClick, onAppEventReceive, publisherDocumentSaved, }: IHostChatProps): import("react/jsx-runtime").JSX.Element;
86
+ export declare function HostChat({ ctx, resolvedApplications, pathname, activeAppId, visibility, context, onOpenChange, onChatStateChange, onAppLinkClick, onAppEventReceive, publisherDocumentSaved, dashboardSaved, }: IHostChatProps): import("react/jsx-runtime").JSX.Element;
85
87
  //# sourceMappingURL=HostChat.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"HostChat.d.ts","sourceRoot":"","sources":["../../src/ui/HostChat.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,gCAAgC,EAAE,MAAM,qBAAqB,CAAC;AACpG,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAElF,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAMhF,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGhD,OAAO,iBAAiB,CAAC;AACzB,OAAO,6CAA6C,CAAC;AAMrD;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,GAAG,EAAE,MAAM,CAAC;CACf;AAED,+FAA+F;AAC/F,MAAM,WAAW,aAAa;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC7B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,cAAc;IAC3B,GAAG,EAAE,gBAAgB,CAAC;IACtB,oBAAoB,EAAE,gCAAgC,EAAE,CAAC;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,qFAAqF;IACrF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+FAA+F;IAC/F,UAAU,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACxC,oFAAoF;IACpF,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAClC,mFAAmF;IACnF,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,6FAA6F;IAC7F,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,YAAY,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,kBAAkB,CAAA;KAAE,KAAK,IAAI,CAAC;IAC1G;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC;IAClD;;OAEG;IACH,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IACpD,iFAAiF;IACjF,sBAAsB,EAAE,uBAAuB,GAAG,SAAS,CAAC;CAC/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,EACrB,GAAG,EACH,oBAAoB,EACpB,QAAQ,EACR,WAAW,EACX,UAAiB,EACjB,OAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,sBAAsB,GACzB,EAAE,cAAc,2CAmIhB"}
1
+ {"version":3,"file":"HostChat.d.ts","sourceRoot":"","sources":["../../src/ui/HostChat.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,gCAAgC,EAAE,MAAM,qBAAqB,CAAC;AACpG,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAElF,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAMtG,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGhD,OAAO,iBAAiB,CAAC;AACzB,OAAO,6CAA6C,CAAC;AAMrD;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,GAAG,EAAE,MAAM,CAAC;CACf;AAED,+FAA+F;AAC/F,MAAM,WAAW,aAAa;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC7B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,cAAc;IAC3B,GAAG,EAAE,gBAAgB,CAAC;IACtB,oBAAoB,EAAE,gCAAgC,EAAE,CAAC;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,qFAAqF;IACrF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+FAA+F;IAC/F,UAAU,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACxC,oFAAoF;IACpF,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAClC,mFAAmF;IACnF,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,6FAA6F;IAC7F,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,YAAY,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,kBAAkB,CAAA;KAAE,KAAK,IAAI,CAAC;IAC1G;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC;IAClD;;OAEG;IACH,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IACpD,iFAAiF;IACjF,sBAAsB,EAAE,uBAAuB,GAAG,SAAS,CAAC;IAC5D,oEAAoE;IACpE,cAAc,EAAE,eAAe,GAAG,SAAS,CAAC;CAC/C;AAED;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,EACrB,GAAG,EACH,oBAAoB,EACpB,QAAQ,EACR,WAAW,EACX,UAAiB,EACjB,OAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,sBAAsB,EACtB,cAAc,GACjB,EAAE,cAAc,2CAoIhB"}
@@ -21,7 +21,7 @@ import { useHostChromeWorkspaceFeatures } from "./useHostChromeWorkspaceFeatures
21
21
  * (embedded/export). The header chat button and app-side controls drive it through the `visibility`
22
22
  * and `context` props; it reports its open-state and button state back via callbacks.
23
23
  */
24
- export function HostChat({ ctx, resolvedApplications, pathname, activeAppId, visibility = null, context = null, onOpenChange, onChatStateChange, onAppLinkClick, onAppEventReceive, publisherDocumentSaved, }) {
24
+ export function HostChat({ ctx, resolvedApplications, pathname, activeAppId, visibility = null, context = null, onOpenChange, onChatStateChange, onAppLinkClick, onAppEventReceive, publisherDocumentSaved, dashboardSaved, }) {
25
25
  const features = useHostChromeWorkspaceFeatures(resolvedApplications, ctx, pathname);
26
26
  const shellTelemetry = useMemo(() => getAppLifecycleCallbacks()?.createTelemetryCallbacks?.("host-ui"), []);
27
27
  const chat = useHostChromeChat({
@@ -34,6 +34,7 @@ export function HostChat({ ctx, resolvedApplications, pathname, activeAppId, vis
34
34
  onAppLinkClick,
35
35
  onAppEventReceive,
36
36
  publisherDocumentSaved,
37
+ dashboardSaved,
37
38
  });
38
39
  const { askAiAssistant: chatAskAiAssistant, openAiAssistant: chatOpenAiAssistant, open: chatOpen, close: chatClose, toggle: chatToggle, setTags: chatSetTags, setAmbientUserContext: chatSetAmbientUserContext, setAmbientUserContextLoading: chatSetAmbientUserContextLoading, isOpen: chatIsOpen, showChatItem, } = chat;
39
40
  // Report the chat open-state outward so the runtime can forward it to the active pluggable
@@ -30,6 +30,16 @@ export interface IPluggableApplicationRendererProps {
30
30
  documentRef?: string;
31
31
  savedDocumentId: string;
32
32
  }) => void;
33
+ /** Tell the host-owned chat that the active app saved a dashboard the chat had drafted. */
34
+ onAiAssistantDashboardSaved?: (saved: {
35
+ conversationId: string;
36
+ originalDashboardId: string;
37
+ savedDashboardId: string;
38
+ savedInsights: ReadonlyArray<{
39
+ originalInsightId: string;
40
+ savedInsightId: string;
41
+ }>;
42
+ }) => void;
33
43
  /**
34
44
  * Ref the renderer populates with a handler that delegates a host-chat link click to the active
35
45
  * app's mount handle (`onAiAssistantLinkClicked`), so an embedded app can handle it in-app.
@@ -54,5 +64,5 @@ export interface IPluggableApplicationRendererProps {
54
64
  onHeaderChange?: (appId: string, header: IAppHeaderOptions) => void;
55
65
  onDocumentTitleChange?: (appId: string, pageTitle: string | undefined) => void;
56
66
  }
57
- export declare function PluggableApplicationRenderer({ app, ctx, pathname, aiAssistantOpen, onOpenAiAssistant, onCloseAiAssistant, onAiAssistantContext, onAiAssistantPublisherDocumentSaved, aiLinkClickHandlerRef, aiEventReceiveRef, navigationRequestRef, onHeaderChange, onDocumentTitleChange, }: IPluggableApplicationRendererProps): import("react/jsx-runtime").JSX.Element;
67
+ export declare function PluggableApplicationRenderer({ app, ctx, pathname, aiAssistantOpen, onOpenAiAssistant, onCloseAiAssistant, onAiAssistantContext, onAiAssistantPublisherDocumentSaved, onAiAssistantDashboardSaved, aiLinkClickHandlerRef, aiEventReceiveRef, navigationRequestRef, onHeaderChange, onDocumentTitleChange, }: IPluggableApplicationRendererProps): import("react/jsx-runtime").JSX.Element;
58
68
  //# sourceMappingURL=PluggableApplicationRenderer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PluggableApplicationRenderer.d.ts","sourceRoot":"","sources":["../../src/ui/PluggableApplicationRenderer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAsE,MAAM,OAAO,CAAC;AAI3G,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,gCAAgC,EAAE,MAAM,qBAAqB,CAAC;AACpG,OAAO,EACH,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EAUxB,MAAM,2CAA2C,CAAC;AAgBnD,OAAO,qCAAqC,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAkBhD,MAAM,WAAW,kCAAkC;IAC/C,GAAG,EAAE,gCAAgC,CAAC;IACtC,GAAG,EAAE,gBAAgB,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,sFAAsF;IACtF,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,6FAA6F;IAC7F,iBAAiB,CAAC,EAAE,CAChB,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,iBAAiB,EAC/B,YAAY,CAAC,EAAE,OAAO,EACtB,kBAAkB,CAAC,EAAE,OAAO,KAC3B,IAAI,CAAC;IACV,8DAA8D;IAC9D,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,oHAAoH;IACpH,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE;QAC7B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;QACvB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;QACvB,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,WAAW,CAAC,EAAE,iBAAiB,CAAC;QAChC,kBAAkB,CAAC,EAAE,OAAO,CAAC;KAChC,KAAK,IAAI,CAAC;IACX,0FAA0F;IAC1F,mCAAmC,CAAC,EAAE,CAAC,KAAK,EAAE;QAC1C,cAAc,EAAE,MAAM,CAAC;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;KAC3B,KAAK,IAAI,CAAC;IACX;;;OAGG;IACH,qBAAqB,CAAC,EAAE,SAAS,CAC7B,CAAC,CAAC,IAAI,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,GAAG,SAAS,CACtG,CAAC;IACF;;;OAGG;IACH,iBAAiB,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;IAC7E;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,sBAAsB,KAAK,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC;IAC7F,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACpE,qBAAqB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;CAClF;AAED,wBAAgB,4BAA4B,CAAC,EACzC,GAAG,EACH,GAAG,EACH,QAAQ,EACR,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,mCAAmC,EACnC,qBAAqB,EACrB,iBAAiB,EACjB,oBAAoB,EACpB,cAAc,EACd,qBAAqB,GACxB,EAAE,kCAAkC,2CAwUpC"}
1
+ {"version":3,"file":"PluggableApplicationRenderer.d.ts","sourceRoot":"","sources":["../../src/ui/PluggableApplicationRenderer.tsx"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  // (C) 2026 GoodData Corporation
3
3
  import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
4
4
  import { FormattedMessage, defineMessage, useIntl } from "react-intl";
5
- import { isAiAssistantContextChangedEvent, isAiAssistantPublisherDocumentSavedEvent, isCloseAiAssistantRequestedEvent, isDocumentTitleChangedEvent, isOpenAiAssistantRequestedEvent, isReloadPlatformContextRequestedEvent, } from "@gooddata/sdk-pluggable-application-model";
5
+ import { isAiAssistantContextChangedEvent, isAiAssistantDashboardSavedEvent, isAiAssistantPublisherDocumentSavedEvent, isCloseAiAssistantRequestedEvent, isDocumentTitleChangedEvent, isOpenAiAssistantRequestedEvent, 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";
@@ -22,7 +22,7 @@ const SECURITY_FAILURE_MESSAGES = {
22
22
  "build-expired": defineMessage({ id: "gs.host.error.appBuildExpired" }),
23
23
  "metadata-missing": defineMessage({ id: "gs.host.error.appSecurityMetadataMissing" }),
24
24
  };
25
- export function PluggableApplicationRenderer({ app, ctx, pathname, aiAssistantOpen, onOpenAiAssistant, onCloseAiAssistant, onAiAssistantContext, onAiAssistantPublisherDocumentSaved, aiLinkClickHandlerRef, aiEventReceiveRef, navigationRequestRef, onHeaderChange, onDocumentTitleChange, }) {
25
+ export function PluggableApplicationRenderer({ app, ctx, pathname, aiAssistantOpen, onOpenAiAssistant, onCloseAiAssistant, onAiAssistantContext, onAiAssistantPublisherDocumentSaved, onAiAssistantDashboardSaved, aiLinkClickHandlerRef, aiEventReceiveRef, navigationRequestRef, onHeaderChange, onDocumentTitleChange, }) {
26
26
  const intl = useIntl();
27
27
  const intlRef = useAutoupdateRef(intl);
28
28
  const ctxRef = useAutoupdateRef(ctx);
@@ -32,6 +32,7 @@ export function PluggableApplicationRenderer({ app, ctx, pathname, aiAssistantOp
32
32
  const onCloseAiAssistantRef = useAutoupdateRef(onCloseAiAssistant);
33
33
  const onAiAssistantContextRef = useAutoupdateRef(onAiAssistantContext);
34
34
  const onAiAssistantPublisherDocumentSavedRef = useAutoupdateRef(onAiAssistantPublisherDocumentSaved);
35
+ const onAiAssistantDashboardSavedRef = useAutoupdateRef(onAiAssistantDashboardSaved);
35
36
  const containerRef = useRef(null);
36
37
  const mountHandleRef = useRef(undefined);
37
38
  // The app/module pair currently mounted. Held so the context-change effect can
@@ -83,6 +84,10 @@ export function PluggableApplicationRenderer({ app, ctx, pathname, aiAssistantOp
83
84
  });
84
85
  return;
85
86
  }
87
+ if (isAiAssistantDashboardSavedEvent(event)) {
88
+ onAiAssistantDashboardSavedRef.current?.(event.payload);
89
+ return;
90
+ }
86
91
  if (isDocumentTitleChangedEvent(event)) {
87
92
  onDocumentTitleChangeRef.current?.(app.id, event.payload.pageTitle);
88
93
  }
@@ -93,6 +98,7 @@ export function PluggableApplicationRenderer({ app, ctx, pathname, aiAssistantOp
93
98
  onCloseAiAssistantRef,
94
99
  onAiAssistantContextRef,
95
100
  onAiAssistantPublisherDocumentSavedRef,
101
+ onAiAssistantDashboardSavedRef,
96
102
  ]);
97
103
  useEffect(() => {
98
104
  let cancelled = false;
@@ -2,7 +2,7 @@ import { type ReactNode } from "react";
2
2
  import { type IGenAIUserContext } from "@gooddata/sdk-model";
3
3
  import { type IPlatformContext, type IPluggableAppTelemetryCallbacks } from "@gooddata/sdk-pluggable-application-model";
4
4
  import { GenAIAssistantMode } from "@gooddata/sdk-ui-gen-ai";
5
- import { type IPublisherDocumentSaved } from "@gooddata/sdk-ui-gen-ai/internal";
5
+ import { type IDashboardSaved, type IPublisherDocumentSaved } from "@gooddata/sdk-ui-gen-ai/internal";
6
6
  import { type GenAIChatEvent } from "./GenAIChat.js";
7
7
  import { type IHostChromeWorkspaceFeatures } from "./useHostChromeWorkspaceFeatures.js";
8
8
  export interface IHostChromeChat {
@@ -73,6 +73,8 @@ export interface IUseHostChromeChatArgs {
73
73
  onAppEventReceive?: (event: GenAIChatEvent) => void;
74
74
  /** The latest document of the conversation that the active app saved. */
75
75
  publisherDocumentSaved: IPublisherDocumentSaved | undefined;
76
+ /** The latest dashboard save reported by the active application. */
77
+ dashboardSaved: IDashboardSaved | undefined;
76
78
  }
77
79
  /**
78
80
  * Owns the GenAI chat state and renders the `<GenAIChat>` element for the host chrome.
@@ -81,5 +83,5 @@ export interface IUseHostChromeChatArgs {
81
83
  * points, the runtime availability probe (`useGenAiChatAvailability`) and forwarding chat
82
84
  * events to the host telemetry callbacks.
83
85
  */
84
- export declare function useHostChromeChat({ features, ctx, telemetry, dialogPosition, embedded, disabled, onAppLinkClick, onAppEventReceive, publisherDocumentSaved, }: IUseHostChromeChatArgs): IHostChromeChat;
86
+ export declare function useHostChromeChat({ features, ctx, telemetry, dialogPosition, embedded, disabled, onAppLinkClick, onAppEventReceive, publisherDocumentSaved, dashboardSaved, }: IUseHostChromeChatArgs): IHostChromeChat;
85
87
  //# sourceMappingURL=useHostChromeChat.d.ts.map
@@ -1 +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,EAAE,KAAK,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EACH,KAAK,gBAAgB,EACrB,KAAK,+BAA+B,EACvC,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAA4B,MAAM,yBAAyB,CAAC;AACvF,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAIhF,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,KAAK,4BAA4B,EAAE,MAAM,qCAAqC,CAAC;AAExF,MAAM,WAAW,eAAe;IAC5B,4EAA4E;IAC5E,OAAO,EAAE,SAAS,CAAC;IACnB,iDAAiD;IACjD,MAAM,EAAE,OAAO,CAAC;IAChB;;OAEG;IACH,IAAI,EAAE,kBAAkB,CAAC;IACzB;;;OAGG;IACH,YAAY,EAAE,OAAO,CAAC;IACtB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,6BAA6B;IAC7B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,2EAA2E;IAC3E,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB;;;OAGG;IACH,cAAc,EAAE,CACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,iBAAiB,EAC/B,YAAY,CAAC,EAAE,OAAO,EACtB,kBAAkB,CAAC,EAAE,OAAO,KAC3B,IAAI,CAAC;IACV;;;OAGG;IACH,eAAe,EAAE,CACb,WAAW,CAAC,EAAE,iBAAiB,EAC/B,kBAAkB,CAAC,EAAE,OAAO,EAC5B,OAAO,CAAC,EAAE,MAAM,KACf,IAAI,CAAC;IACV;;;OAGG;IACH,OAAO,EAAE,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAClE;;;OAGG;IACH,qBAAqB,EAAE,CAAC,WAAW,CAAC,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACjE;;OAEG;IACH,4BAA4B,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CAC5D;AAED,MAAM,WAAW,sBAAsB;IACnC,QAAQ,EAAE,4BAA4B,CAAC;IACvC,GAAG,EAAE,gBAAgB,CAAC;IACtB,SAAS,EAAE,+BAA+B,GAAG,SAAS,CAAC;IACvD,+FAA+F;IAC/F,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yFAAyF;IACzF,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC;IACvG,wDAAwD;IACxD,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IACpD,yEAAyE;IACzE,sBAAsB,EAAE,uBAAuB,GAAG,SAAS,CAAC;CAC/D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,EAC9B,QAAQ,EACR,GAAG,EACH,SAAS,EACT,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,cAAc,EACd,iBAAiB,EACjB,sBAAsB,GACzB,EAAE,sBAAsB,GAAG,eAAe,CAmI1C"}
1
+ {"version":3,"file":"useHostChromeChat.d.ts","sourceRoot":"","sources":["../../src/ui/useHostChromeChat.tsx"],"names":[],"mappings":"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"}
@@ -11,7 +11,7 @@ import { GenAIChat } from "./GenAIChat.js";
11
11
  * points, the runtime availability probe (`useGenAiChatAvailability`) and forwarding chat
12
12
  * events to the host telemetry callbacks.
13
13
  */
14
- export function useHostChromeChat({ features, ctx, telemetry, dialogPosition, embedded, disabled, onAppLinkClick, onAppEventReceive, publisherDocumentSaved, }) {
14
+ export function useHostChromeChat({ features, ctx, telemetry, dialogPosition, embedded, disabled, onAppLinkClick, onAppEventReceive, publisherDocumentSaved, dashboardSaved, }) {
15
15
  const [isChatOpen, setIsChatOpen] = useState(false);
16
16
  const [askedQuestion, setAskedQuestion] = useState(null);
17
17
  const [appendToChat, setAppendToChat] = useState(false);
@@ -69,7 +69,7 @@ export function useHostChromeChat({ features, ctx, telemetry, dialogPosition, em
69
69
  onAppEventReceive?.(event);
70
70
  }, [telemetry, onAppEventReceive]);
71
71
  const showChatItem = useGenAiChatAvailability(getBackend(), features.workspaceId, features.showChat, features.canManageProject);
72
- const element = features.showChat && features.workspaceId ? (_jsx(GenAIChat, { workspaceId: features.workspaceId, open: isChatOpen, disabled: disabled, onOpen: open, onClose: close, askedQuestion: askedQuestion, appendToChat: appendToChat, agentId: agentId, replaceUserContext: replaceUserContext, askSeq: askSeq, userContext: userContext, ambientUserContext: ambientUserContext, ambientUserContextLoading: ambientUserContextLoading, publisherDocumentSaved: publisherDocumentSaved, includeTags: includeTags, excludeTags: excludeTags, canManageProject: features.canManageProject, canAnalyzeProject: features.canAnalyzeWorkspace, canFullControl: features.canFullControl, settings: ctx.workspaceSettings, dialogPosition: dialogPosition, embedded: embedded, onAppLinkClick: onAppLinkClick, onEvent: handleChatEvent })) : null;
72
+ const element = features.showChat && features.workspaceId ? (_jsx(GenAIChat, { workspaceId: features.workspaceId, open: isChatOpen, disabled: disabled, onOpen: open, onClose: close, askedQuestion: askedQuestion, appendToChat: appendToChat, agentId: agentId, replaceUserContext: replaceUserContext, askSeq: askSeq, userContext: userContext, ambientUserContext: ambientUserContext, ambientUserContextLoading: ambientUserContextLoading, publisherDocumentSaved: publisherDocumentSaved, dashboardSaved: dashboardSaved, includeTags: includeTags, excludeTags: excludeTags, canManageProject: features.canManageProject, canAnalyzeProject: features.canAnalyzeWorkspace, canFullControl: features.canFullControl, settings: ctx.workspaceSettings, dialogPosition: dialogPosition, embedded: embedded, onAppLinkClick: onAppLinkClick, onEvent: handleChatEvent })) : null;
73
73
  return {
74
74
  element,
75
75
  isOpen: isChatOpen,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gooddata/sdk-ui-pluggable-host",
3
- "version": "11.62.0-alpha.1",
3
+ "version": "11.62.0-alpha.3",
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,25 +29,26 @@
29
29
  "dependencies": {
30
30
  "@module-federation/runtime": "2.6.0",
31
31
  "lodash-es": "^4.17.23",
32
- "@gooddata/sdk-backend-base": "11.62.0-alpha.1",
33
- "@gooddata/sdk-backend-tiger": "11.62.0-alpha.1",
34
- "@gooddata/sdk-embedding": "11.62.0-alpha.1",
35
- "@gooddata/sdk-backend-spi": "11.62.0-alpha.1",
36
- "@gooddata/sdk-model": "11.62.0-alpha.1",
37
- "@gooddata/sdk-pluggable-application-model": "11.62.0-alpha.1",
38
- "@gooddata/sdk-ui": "11.62.0-alpha.1",
39
- "@gooddata/sdk-ui-ext": "11.62.0-alpha.1",
40
- "@gooddata/sdk-ui-application-header": "11.62.0-alpha.1",
41
- "@gooddata/sdk-ui-gen-ai": "11.62.0-alpha.1",
42
- "@gooddata/sdk-ui-kit": "11.62.0-alpha.1",
43
- "@gooddata/sdk-ui-semantic-search": "11.62.0-alpha.1",
44
- "@gooddata/sdk-ui-theme-provider": "11.62.0-alpha.1",
45
- "@gooddata/util": "11.62.0-alpha.1"
32
+ "@gooddata/sdk-backend-base": "11.62.0-alpha.3",
33
+ "@gooddata/sdk-embedding": "11.62.0-alpha.3",
34
+ "@gooddata/sdk-backend-spi": "11.62.0-alpha.3",
35
+ "@gooddata/sdk-model": "11.62.0-alpha.3",
36
+ "@gooddata/sdk-backend-tiger": "11.62.0-alpha.3",
37
+ "@gooddata/sdk-pluggable-application-model": "11.62.0-alpha.3",
38
+ "@gooddata/sdk-ui": "11.62.0-alpha.3",
39
+ "@gooddata/sdk-ui-application-header": "11.62.0-alpha.3",
40
+ "@gooddata/sdk-ui-ext": "11.62.0-alpha.3",
41
+ "@gooddata/sdk-ui-gen-ai": "11.62.0-alpha.3",
42
+ "@gooddata/sdk-ui-kit": "11.62.0-alpha.3",
43
+ "@gooddata/sdk-ui-semantic-search": "11.62.0-alpha.3",
44
+ "@gooddata/sdk-ui-theme-provider": "11.62.0-alpha.3",
45
+ "@gooddata/util": "11.62.0-alpha.3"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@microsoft/api-documenter": "7.30.16",
49
49
  "@microsoft/api-extractor": "7.59.2",
50
50
  "@testing-library/dom": "10.4.2",
51
+ "@testing-library/jest-dom": "7.0.1",
51
52
  "@testing-library/react": "16.3.0",
52
53
  "@types/lodash-es": "4.17.12",
53
54
  "@types/node": "24.12.0",
@@ -55,7 +56,7 @@
55
56
  "@types/react-dom": "19.1.7",
56
57
  "@typescript-eslint/eslint-plugin": "8.58.0",
57
58
  "@typescript-eslint/parser": "8.58.0",
58
- "@vitest/coverage-v8": "4.1.11",
59
+ "@vitest/coverage-v8": "5.0.4",
59
60
  "eslint": "^9.39.2",
60
61
  "eslint-plugin-headers": "1.3.3",
61
62
  "eslint-plugin-jsdoc": "62.1.0",
@@ -79,10 +80,9 @@
79
80
  "tslib": "2.8.1",
80
81
  "typescript": "7.0.2",
81
82
  "vite": "8.0.16",
82
- "vitest": "4.1.11",
83
- "vitest-dom": "0.1.1",
84
- "@gooddata/eslint-config": "11.62.0-alpha.1",
85
- "@gooddata/oxlint-config": "11.62.0-alpha.1"
83
+ "vitest": "5.0.4",
84
+ "@gooddata/oxlint-config": "11.62.0-alpha.3",
85
+ "@gooddata/eslint-config": "11.62.0-alpha.3"
86
86
  },
87
87
  "peerDependencies": {
88
88
  "react": ">=18.3.1",