Testbed to help iterate on addons + correct dependency graph

Signed-off-by: Eric Peterson <ericpeterson@spotify.com>
This commit is contained in:
Eric Peterson
2022-03-21 12:26:03 +01:00
committed by Emma Indal
parent 0b67af3485
commit 10a7736ced
13 changed files with 280 additions and 109 deletions
@@ -17,14 +17,17 @@
import React, { useCallback, useState } from 'react';
import { useOutlet } from 'react-router';
import { useParams } from 'react-router-dom';
import useAsync from 'react-use/lib/useAsync';
import { Reader } from './Reader';
import { TechDocsReaderPageHeader } from './TechDocsReaderPageHeader';
import useAsync, { AsyncState } from 'react-use/lib/useAsync';
import { techdocsApiRef } from '../../api';
import { TechDocsEntityMetadata, TechDocsMetadata } from '../../types';
import { CompoundEntityRef } from '@backstage/catalog-model';
import { useApi, useApp } from '@backstage/core-plugin-api';
import { Page, Content } from '@backstage/core-components';
import { getComponentData, useApi, useApp } from '@backstage/core-plugin-api';
import { Page } from '@backstage/core-components';
import {
TechDocsReaderPage as AddonAwareReaderPage,
TECHDOCS_ADDONS_WRAPPER_KEY,
} from '@backstage/plugin-techdocs-addons';
import { useTechDocsReaderDom, withTechDocsReaderProvider } from './Reader';
/**
* Helper function that gives the children of {@link TechDocsReaderPage} access to techdocs and entity metadata
@@ -42,6 +45,24 @@ export type TechDocsReaderPageRenderFunction = ({
onReady: () => void;
}) => JSX.Element;
type SpecialReaderPageProps = {
entityName: CompoundEntityRef;
asyncEntityMetadata: AsyncState<any>;
asyncTechDocsMetadata: AsyncState<any>;
};
const SpecialReaderPage = (props: SpecialReaderPageProps) => {
const dom = useTechDocsReaderDom(props.entityName);
return (
<AddonAwareReaderPage
asyncEntityMetadata={props.asyncEntityMetadata}
asyncTechDocsMetadata={props.asyncTechDocsMetadata}
dom={dom}
/>
);
};
/**
* Props for {@link TechDocsReaderPage}
*
@@ -61,7 +82,7 @@ export const TechDocsReaderPage = (props: TechDocsReaderPageProps) => {
const techdocsApi = useApi(techdocsApiRef);
const { value: techdocsMetadataValue } = useAsync(() => {
const asyncTechDocsMetadata = useAsync(() => {
if (documentReady) {
return techdocsApi.getTechDocsMetadata({ kind, namespace, name });
}
@@ -69,50 +90,47 @@ export const TechDocsReaderPage = (props: TechDocsReaderPageProps) => {
return Promise.resolve(undefined);
}, [kind, namespace, name, techdocsApi, documentReady]);
const { value: entityMetadataValue, error: entityMetadataError } =
useAsync(() => {
return techdocsApi.getEntityMetadata({ kind, namespace, name });
}, [kind, namespace, name, techdocsApi]);
const asyncEntityMetadata = useAsync(() => {
return techdocsApi.getEntityMetadata({ kind, namespace, name });
}, [kind, namespace, name, techdocsApi]);
const onReady = useCallback(() => {
setDocumentReady(true);
}, [setDocumentReady]);
if (entityMetadataError) return <NotFoundErrorPage />;
if (asyncEntityMetadata.error) return <NotFoundErrorPage />;
if (!children)
return (
outlet || (
<Page themeId="documentation">
<TechDocsReaderPageHeader
techDocsMetadata={techdocsMetadataValue}
entityMetadata={entityMetadataValue}
entityRef={{
kind,
namespace,
name,
}}
if (!children) {
if (outlet) {
// If the outlet is a single child and that child is an instance of the
// TechDocsAddons registry, then render it a certain way.
if (
getComponentData(outlet.props.children, TECHDOCS_ADDONS_WRAPPER_KEY)
) {
const Component = withTechDocsReaderProvider(SpecialReaderPage, {
kind,
namespace,
name,
});
return (
<Component
entityName={{ kind, namespace, name }}
asyncEntityMetadata={asyncEntityMetadata}
asyncTechDocsMetadata={asyncTechDocsMetadata}
/>
<Content data-testid="techdocs-content">
<Reader
onReady={onReady}
entityRef={{
kind,
namespace,
name,
}}
/>
</Content>
</Page>
)
);
);
}
// Otherwise, just return the outlet (legacy-style composability).
return outlet;
}
}
return (
<Page themeId="documentation">
{children instanceof Function
? children({
techdocsMetadataValue,
entityMetadataValue,
techdocsMetadataValue: asyncTechDocsMetadata.value,
entityMetadataValue: asyncEntityMetadata.value,
entityRef: { kind, namespace, name },
onReady,
})