fix(techdocs): avoid rerender current page when navigating to another (#26944)

Signed-off-by: Thomas Cardonne <thomas.cardonne@adevinta.com>
This commit is contained in:
Thomas Cardonne
2024-10-17 14:04:39 +02:00
committed by GitHub
parent f92f09c36e
commit 4a2f73a302
6 changed files with 60 additions and 33 deletions
@@ -34,9 +34,11 @@ jest.mock('../useReaderState', () => ({
...jest.requireActual('../useReaderState'),
useReaderState: (...args: any[]) => useReaderState(...args),
}));
const useShadowDomStylesLoading = jest.fn().mockReturnValue(false);
jest.mock('@backstage/plugin-techdocs-react', () => ({
...jest.requireActual('@backstage/plugin-techdocs-react'),
useShadowDomStylesLoading: jest.fn().mockReturnValue(false),
useShadowDomStylesLoading: (...args: any[]) =>
useShadowDomStylesLoading(...args),
useShadowRootElements: jest.fn(),
}));
@@ -220,4 +222,39 @@ describe('<TechDocsReaderPageContent />', () => {
window.location.hash = '';
});
it('should render progress bar when content is loading', async () => {
getEntityMetadata.mockResolvedValue(mockEntityMetadata);
getTechDocsMetadata.mockResolvedValue(mockTechDocsMetadata);
useTechDocsReaderDom.mockReturnValue(document.createElement('html'));
useReaderState.mockReturnValue({ state: 'CHECKING' });
const rendered = await renderInTestApp(
<Wrapper>
<TechDocsReaderPageContent withSearch={false} />
</Wrapper>,
);
await waitFor(() => {
expect(rendered.queryByRole('progressbar')).toBeInTheDocument();
});
});
it('should render progress bar when styles are loading', async () => {
getEntityMetadata.mockResolvedValue(mockEntityMetadata);
getTechDocsMetadata.mockResolvedValue(mockTechDocsMetadata);
useTechDocsReaderDom.mockReturnValue(document.createElement('html'));
useReaderState.mockReturnValue({ state: 'cached' });
useShadowDomStylesLoading.mockReturnValue(true);
const rendered = await renderInTestApp(
<Wrapper>
<TechDocsReaderPageContent withSearch={false} />
</Wrapper>,
);
await waitFor(() => {
expect(rendered.queryByRole('progressbar')).toBeInTheDocument();
});
});
});
@@ -26,13 +26,16 @@ import {
useTechDocsReaderPage,
} from '@backstage/plugin-techdocs-react';
import { CompoundEntityRef } from '@backstage/catalog-model';
import { Content, ErrorPage } from '@backstage/core-components';
import { Content, ErrorPage, Progress } from '@backstage/core-components';
import { TechDocsSearch } from '../../../search';
import { TechDocsStateIndicator } from '../TechDocsStateIndicator';
import { useTechDocsReaderDom } from './dom';
import { withTechDocsReaderProvider } from '../TechDocsReaderProvider';
import {
useTechDocsReader,
withTechDocsReaderProvider,
} from '../TechDocsReaderProvider';
import { TechDocsReaderPageContentAddons } from './TechDocsReaderPageContentAddons';
const useStyles = makeStyles({
@@ -81,6 +84,7 @@ export const TechDocsReaderPageContent = withTechDocsReaderProvider(
entityRef,
setShadowRoot,
} = useTechDocsReaderPage();
const { state } = useTechDocsReader();
const dom = useTechDocsReaderDom(entityRef);
const path = window.location.pathname;
const hash = window.location.hash;
@@ -143,6 +147,8 @@ export const TechDocsReaderPageContent = withTechDocsReaderProvider(
)}
<Grid xs={12} item>
{/* Centers the styles loaded event to avoid having multiple locations setting the opacity style in Shadow Dom causing the screen to flash multiple times */}
{(state === 'CHECKING' || isStyleLoading) && <Progress />}
<TechDocsShadowDom element={dom} onAppend={handleAppend}>
<TechDocsReaderPageContentAddons />
</TechDocsShadowDom>
@@ -276,6 +276,12 @@ export const useTechDocsReaderDom = (
return;
}
// Skip this update if the location's path has changed but the state
// contains a page for another page that isn't loaded yet.
if (!window.location.pathname.endsWith(path)) {
return;
}
// Scroll to top after render
window.scroll({ top: 0 });
@@ -283,6 +289,7 @@ export const useTechDocsReaderDom = (
const postTransformedDomElement = await postRender(
preTransformedDomElement,
);
setDom(postTransformedDomElement as HTMLElement);
});