From a3672c67df09ab71ab922ccd6080a4cddc42005e Mon Sep 17 00:00:00 2001 From: Boris Serdiuk Date: Fri, 25 Oct 2024 00:03:24 +0200 Subject: [PATCH] fix: Support previous breadcrumbs versions in deduplication --- .../__tests__/global-breadcrumbs.test.tsx | 31 +++++++++++++++++++ .../visual-refresh-toolbar/toolbar/index.tsx | 8 +++-- .../toolbar/styles.scss | 5 +++ .../plugins/controllers/breadcrumbs.ts | 15 +++++---- .../plugins/helpers/use-global-breadcrumbs.ts | 4 ++- 5 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/app-layout/__tests__/global-breadcrumbs.test.tsx b/src/app-layout/__tests__/global-breadcrumbs.test.tsx index 2018b19507..d0ac1044a0 100644 --- a/src/app-layout/__tests__/global-breadcrumbs.test.tsx +++ b/src/app-layout/__tests__/global-breadcrumbs.test.tsx @@ -258,6 +258,37 @@ describeEachAppLayout({ themes: ['refresh-toolbar'], sizes: ['desktop'] }, () => }); }); + test('renders breadcrumbs locally again after app layout de-registers', async () => { + function DestructibleLayout() { + const [mounted, setMounted] = useState(true); + return mounted ? ( + setMounted(false)}> + Unmount + + } + /> + ) : null; + } + + await renderAsync( + <> +
+ +
+ + + + ); + expect(wrapper.find('[data-testid="local-breadcrumbs"]')!.getElement()).toBeEmptyDOMElement(); + + wrapper.find('[data-testid="unmount"]')!.click(); + await waitFor(() => { + expect(wrapper.find('[data-testid="local-breadcrumbs"]')!.getElement()).not.toBeEmptyDOMElement(); + }); + }); + test('allows opt-out from this behavior', async () => { render( - {breadcrumbs || - (discoveredBreadcrumbs && ( +
{breadcrumbs}
+ {discoveredBreadcrumbs && ( +
- ))} +
+ )}
)} diff --git a/src/app-layout/visual-refresh-toolbar/toolbar/styles.scss b/src/app-layout/visual-refresh-toolbar/toolbar/styles.scss index 4f58a8ca66..bb8e04eb8f 100644 --- a/src/app-layout/visual-refresh-toolbar/toolbar/styles.scss +++ b/src/app-layout/visual-refresh-toolbar/toolbar/styles.scss @@ -99,6 +99,11 @@ } } +// backward compatibility before this commit: 7a4b7b3e3b1d50830383805a8f4ab6cd93c9701f +.breadcrumbs-own:not(:empty) + .breadcrumbs-discovered { + display: none; +} + .block-body-scroll { overflow: hidden; } diff --git a/src/internal/plugins/controllers/breadcrumbs.ts b/src/internal/plugins/controllers/breadcrumbs.ts index 38b5d4f1b7..6567b494c6 100644 --- a/src/internal/plugins/controllers/breadcrumbs.ts +++ b/src/internal/plugins/controllers/breadcrumbs.ts @@ -3,6 +3,7 @@ import debounce from '../../debounce'; type ChangeCallback = (props: T | null) => void; +type RegistrationCallback = (isRegistered: boolean) => void; export interface BreadcrumbsGlobalRegistration { update(props: T): void; @@ -11,18 +12,18 @@ export interface BreadcrumbsGlobalRegistration { export interface BreadcrumbsApiInternal { registerAppLayout: (changeCallback: ChangeCallback) => (() => void) | void; - registerBreadcrumbs: (props: T, onRegistered: () => void) => BreadcrumbsGlobalRegistration; + registerBreadcrumbs: (props: T, onRegistered: RegistrationCallback) => BreadcrumbsGlobalRegistration; getStateForTesting: () => { appLayoutUpdateCallback: ChangeCallback | null; breadcrumbInstances: Array<{ props: T }>; - breadcrumbRegistrations: Array<() => void>; + breadcrumbRegistrations: Array; }; } export class BreadcrumbsController { #appLayoutUpdateCallback: ChangeCallback | null = null; #breadcrumbInstances: Array<{ props: T }> = []; - #breadcrumbRegistrations: Array<() => void> = []; + #breadcrumbRegistrations: Array = []; #notifyAppLayout = debounce(() => { if (!this.#appLayoutUpdateCallback) { @@ -33,10 +34,7 @@ export class BreadcrumbsController { }, 0); #notifyBreadcrumbs = debounce(() => { - if (!this.#appLayoutUpdateCallback) { - return; - } - this.#breadcrumbRegistrations.forEach(listener => listener()); + this.#breadcrumbRegistrations.forEach(listener => listener(!!this.#appLayoutUpdateCallback)); }, 0); registerAppLayout = (changeCallback: ChangeCallback) => { @@ -47,10 +45,11 @@ export class BreadcrumbsController { this.#notifyBreadcrumbs(); return () => { this.#appLayoutUpdateCallback = null; + this.#notifyBreadcrumbs(); }; }; - registerBreadcrumbs = (props: T, onRegistered: () => void): BreadcrumbsGlobalRegistration => { + registerBreadcrumbs = (props: T, onRegistered: RegistrationCallback): BreadcrumbsGlobalRegistration => { const instance = { props: props }; this.#breadcrumbInstances.push(instance); this.#breadcrumbRegistrations.push(onRegistered); diff --git a/src/internal/plugins/helpers/use-global-breadcrumbs.ts b/src/internal/plugins/helpers/use-global-breadcrumbs.ts index a45e357866..a863b03a0f 100644 --- a/src/internal/plugins/helpers/use-global-breadcrumbs.ts +++ b/src/internal/plugins/helpers/use-global-breadcrumbs.ts @@ -20,7 +20,9 @@ function useSetGlobalBreadcrumbsImplementation({ if (isInToolbar || __disableGlobalization) { return; } - const registration = awsuiPluginsInternal.breadcrumbs.registerBreadcrumbs(props, () => setRegistered(true)); + const registration = awsuiPluginsInternal.breadcrumbs.registerBreadcrumbs(props, isRegistered => + setRegistered(isRegistered ?? true) + ); registrationRef.current = registration; return () => {