Moved shared TechDocs utilities from plugin-techdocs to plugin-techdocs-react
Co-authored-by: Eric Peterson <iamEAP@users.noreply.github.com> Co-authored-by: Anders Näsman <realandersn@users.noreply.github.com> Signed-off-by: Otto Sichert <git@ottosichert.de>
This commit is contained in:
@@ -3,15 +3,25 @@
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { AsyncState } from 'react-use/lib/useAsync';
|
||||
import { ComponentType } from 'react';
|
||||
import { CompoundEntityRef } from '@backstage/catalog-model';
|
||||
import { Context } from 'react';
|
||||
import { Dispatch } from 'react';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { Extension } from '@backstage/core-plugin-api';
|
||||
import { default as React_2 } from 'react';
|
||||
import { SetStateAction } from 'react';
|
||||
import { VersionedValue } from '@backstage/version-bridge';
|
||||
|
||||
// @alpha
|
||||
export function createTechDocsAddon<TComponentProps>(
|
||||
options: TechDocsAddonOptions<TComponentProps>,
|
||||
): Extension<ComponentType<TComponentProps>>;
|
||||
|
||||
// @alpha (undocumented)
|
||||
export const defaultTechDocsReaderPageValue: TechDocsReaderPageValue;
|
||||
|
||||
// @alpha
|
||||
export const TECHDOCS_ADDONS_WRAPPER_KEY = 'techdocs.addons.wrapper.v1';
|
||||
|
||||
@@ -34,6 +44,55 @@ export type TechDocsAddonOptions<TAddonProps = {}> = {
|
||||
// @alpha
|
||||
export const TechDocsAddons: React_2.ComponentType;
|
||||
|
||||
// @public
|
||||
export type TechDocsEntityMetadata = Entity & {
|
||||
locationMetadata?: {
|
||||
type: string;
|
||||
target: string;
|
||||
};
|
||||
};
|
||||
|
||||
// @public
|
||||
export type TechDocsMetadata = {
|
||||
site_name: string;
|
||||
site_description: string;
|
||||
};
|
||||
|
||||
// @alpha (undocumented)
|
||||
export const TechDocsReaderPageContext: Context<
|
||||
| VersionedValue<{
|
||||
1: TechDocsReaderPageValue;
|
||||
}>
|
||||
| undefined
|
||||
>;
|
||||
|
||||
// @alpha
|
||||
export type TechDocsReaderPageValue = {
|
||||
metadata: AsyncState<TechDocsMetadata>;
|
||||
entityName: CompoundEntityRef;
|
||||
entityMetadata: AsyncState<TechDocsEntityMetadata>;
|
||||
shadowRoot?: ShadowRoot;
|
||||
setShadowRoot: Dispatch<SetStateAction<ShadowRoot | undefined>>;
|
||||
title: string;
|
||||
setTitle: Dispatch<SetStateAction<string>>;
|
||||
subtitle: string;
|
||||
setSubtitle: Dispatch<SetStateAction<string>>;
|
||||
onReady?: () => void;
|
||||
};
|
||||
|
||||
// @public
|
||||
export const useShadowRoot: () => ShadowRoot | undefined;
|
||||
|
||||
// @public
|
||||
export const useShadowRootElements: <
|
||||
TReturnedElement extends HTMLElement = HTMLElement,
|
||||
>(
|
||||
selectors: string[],
|
||||
) => TReturnedElement[];
|
||||
|
||||
// @public
|
||||
export const useShadowRootSelection: (wait?: number) => Selection | null;
|
||||
|
||||
// @alpha
|
||||
export const useTechDocsAddons: () => {
|
||||
renderComponentByName: (name: string) => React_2.ReactElement<
|
||||
@@ -51,4 +110,7 @@ export const useTechDocsAddons: () => {
|
||||
> | null)[]
|
||||
| null;
|
||||
};
|
||||
|
||||
// @alpha
|
||||
export const useTechDocsReaderPage: () => TechDocsReaderPageValue;
|
||||
```
|
||||
|
||||
@@ -37,20 +37,26 @@
|
||||
"@backstage/catalog-model": "^1.0.1-next.1",
|
||||
"@backstage/core-components": "^0.9.3-next.1",
|
||||
"@backstage/core-plugin-api": "^1.0.0",
|
||||
"@backstage/version-bridge": "^1.0.0",
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/lab": "4.0.0-alpha.57",
|
||||
"@material-ui/styles": "^4.11.0",
|
||||
"jss": "~10.8.2",
|
||||
"lodash": "^4.17.21",
|
||||
"react-helmet": "6.1.0",
|
||||
"react-router-dom": "6.0.0-beta.0"
|
||||
"react-router-dom": "6.0.0-beta.0",
|
||||
"react-use": "^17.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.13.1 || ^17.0.0",
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/react": "^13.0.0",
|
||||
"@testing-library/react-hooks": "^7.0.2",
|
||||
"@backstage/test-utils": "^1.0.1-next.1"
|
||||
"@backstage/plugin-techdocs": "^1.0.1-next.2",
|
||||
"@backstage/test-utils": "^1.0.1-next.1",
|
||||
"@backstage/theme": "^0.2.15"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { renderHook, act } from '@testing-library/react-hooks';
|
||||
|
||||
import { ThemeProvider } from '@material-ui/core';
|
||||
|
||||
import { lightTheme } from '@backstage/theme';
|
||||
import { TestApiProvider } from '@backstage/test-utils';
|
||||
import { Entity, CompoundEntityRef } from '@backstage/catalog-model';
|
||||
import {
|
||||
techdocsApiRef,
|
||||
TechDocsReaderPageProvider,
|
||||
} from '@backstage/plugin-techdocs';
|
||||
|
||||
import { useTechDocsReaderPage } from './context';
|
||||
import { TechDocsMetadata } from './types';
|
||||
|
||||
const mockShadowRoot = () => {
|
||||
const div = document.createElement('div');
|
||||
const shadowRoot = div.attachShadow({ mode: 'open' });
|
||||
shadowRoot.innerHTML = '<h1>Shadow DOM Mock</h1>';
|
||||
return shadowRoot;
|
||||
};
|
||||
|
||||
const mockEntityMetadata: Entity = {
|
||||
apiVersion: 'v1',
|
||||
kind: 'Component',
|
||||
metadata: {
|
||||
name: 'test',
|
||||
namespace: 'default',
|
||||
},
|
||||
spec: {
|
||||
owner: 'test',
|
||||
},
|
||||
};
|
||||
|
||||
const mockTechDocsMetadata: TechDocsMetadata = {
|
||||
site_name: 'test-componnet',
|
||||
site_description: 'this is a test component',
|
||||
};
|
||||
|
||||
const techdocsApiMock = {
|
||||
getEntityMetadata: jest.fn().mockResolvedValue(mockEntityMetadata),
|
||||
getTechDocsMetadata: jest.fn().mockResolvedValue(mockTechDocsMetadata),
|
||||
};
|
||||
|
||||
const wrapper = ({
|
||||
entityName = {
|
||||
kind: mockEntityMetadata.kind,
|
||||
name: mockEntityMetadata.metadata.name,
|
||||
namespace: mockEntityMetadata.metadata.namespace!!,
|
||||
},
|
||||
children,
|
||||
}: {
|
||||
entityName?: CompoundEntityRef;
|
||||
children: React.ReactNode;
|
||||
}) => (
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<TestApiProvider apis={[[techdocsApiRef, techdocsApiMock]]}>
|
||||
<TechDocsReaderPageProvider entityName={entityName}>
|
||||
{children}
|
||||
</TechDocsReaderPageProvider>
|
||||
</TestApiProvider>
|
||||
</ThemeProvider>
|
||||
);
|
||||
|
||||
describe('useTechDocsReaderPage', () => {
|
||||
it('should set title', async () => {
|
||||
const { result, waitForNextUpdate } = renderHook(
|
||||
() => useTechDocsReaderPage(),
|
||||
{ wrapper },
|
||||
);
|
||||
|
||||
expect(result.current.title).toBe('');
|
||||
|
||||
act(() => result.current.setTitle('test site title'));
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(result.current.title).toBe('test site title');
|
||||
});
|
||||
|
||||
it('should set subtitle', async () => {
|
||||
const { result, waitForNextUpdate } = renderHook(
|
||||
() => useTechDocsReaderPage(),
|
||||
{ wrapper },
|
||||
);
|
||||
|
||||
expect(result.current.subtitle).toBe('');
|
||||
|
||||
act(() => result.current.setSubtitle('test site subtitle'));
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(result.current.subtitle).toBe('test site subtitle');
|
||||
});
|
||||
|
||||
it('should set shadow root', async () => {
|
||||
const { result, waitForNextUpdate } = renderHook(
|
||||
() => useTechDocsReaderPage(),
|
||||
{ wrapper },
|
||||
);
|
||||
|
||||
// mock shadowroot
|
||||
const shadowRoot = mockShadowRoot();
|
||||
|
||||
act(() => result.current.setShadowRoot(shadowRoot));
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(result.current.shadowRoot?.innerHTML).toBe(
|
||||
'<h1>Shadow DOM Mock</h1>',
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Dispatch, SetStateAction, useContext } from 'react';
|
||||
import { AsyncState } from 'react-use/lib/useAsync';
|
||||
|
||||
import { CompoundEntityRef } from '@backstage/catalog-model';
|
||||
import { createVersionedContext } from '@backstage/version-bridge';
|
||||
|
||||
import { TechDocsEntityMetadata, TechDocsMetadata } from './types';
|
||||
|
||||
/**
|
||||
* @alpha type for the value of the TechDocsReaderPageContext
|
||||
*/
|
||||
export type TechDocsReaderPageValue = {
|
||||
metadata: AsyncState<TechDocsMetadata>;
|
||||
entityName: CompoundEntityRef;
|
||||
entityMetadata: AsyncState<TechDocsEntityMetadata>;
|
||||
shadowRoot?: ShadowRoot;
|
||||
setShadowRoot: Dispatch<SetStateAction<ShadowRoot | undefined>>;
|
||||
title: string;
|
||||
setTitle: Dispatch<SetStateAction<string>>;
|
||||
subtitle: string;
|
||||
setSubtitle: Dispatch<SetStateAction<string>>;
|
||||
/**
|
||||
* @deprecated property can be passed down directly to the `TechDocsReaderPageContent` instead.
|
||||
*/
|
||||
onReady?: () => void;
|
||||
};
|
||||
|
||||
/**
|
||||
* @alpha
|
||||
*/
|
||||
export const defaultTechDocsReaderPageValue: TechDocsReaderPageValue = {
|
||||
title: '',
|
||||
subtitle: '',
|
||||
setTitle: () => {},
|
||||
setSubtitle: () => {},
|
||||
setShadowRoot: () => {},
|
||||
metadata: { loading: true },
|
||||
entityMetadata: { loading: true },
|
||||
entityName: { kind: '', name: '', namespace: '' },
|
||||
};
|
||||
|
||||
/**
|
||||
* @alpha
|
||||
*/
|
||||
export const TechDocsReaderPageContext = createVersionedContext<{
|
||||
1: TechDocsReaderPageValue;
|
||||
}>('techdocs-reader-page-context');
|
||||
/**
|
||||
* Hook used to get access to shared state between reader page components.
|
||||
* @alpha
|
||||
*/
|
||||
export const useTechDocsReaderPage = () => {
|
||||
const versionedContext = useContext(TechDocsReaderPageContext);
|
||||
|
||||
if (versionedContext === undefined) {
|
||||
return defaultTechDocsReaderPageValue;
|
||||
}
|
||||
|
||||
const context = versionedContext.atVersion(1);
|
||||
if (context === undefined) {
|
||||
throw new Error('No context found for version 1.');
|
||||
}
|
||||
|
||||
return context;
|
||||
};
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Package encapsulating the TechDocs Addon framework.
|
||||
* Package encapsulating utilities to be shared by frontend TechDocs plugins.
|
||||
*
|
||||
* @packageDocumentation
|
||||
*/
|
||||
@@ -26,5 +26,20 @@ export {
|
||||
TechDocsAddons,
|
||||
TECHDOCS_ADDONS_WRAPPER_KEY,
|
||||
} from './addons';
|
||||
export {
|
||||
defaultTechDocsReaderPageValue,
|
||||
TechDocsReaderPageContext,
|
||||
useTechDocsReaderPage,
|
||||
} from './context';
|
||||
export type { TechDocsReaderPageValue } from './context';
|
||||
export {
|
||||
useShadowRoot,
|
||||
useShadowRootElements,
|
||||
useShadowRootSelection,
|
||||
} from './hooks';
|
||||
export { TechDocsAddonLocations } from './types';
|
||||
export type { TechDocsAddonOptions } from './types';
|
||||
export type {
|
||||
TechDocsEntityMetadata,
|
||||
TechDocsMetadata,
|
||||
TechDocsAddonOptions,
|
||||
} from './types';
|
||||
|
||||
@@ -15,6 +15,26 @@
|
||||
*/
|
||||
|
||||
import { ComponentType } from 'react';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
|
||||
/**
|
||||
* Metadata for TechDocs page
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type TechDocsMetadata = {
|
||||
site_name: string;
|
||||
site_description: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Metadata for TechDocs Entity
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type TechDocsEntityMetadata = Entity & {
|
||||
locationMetadata?: { type: string; target: string };
|
||||
};
|
||||
|
||||
/**
|
||||
* Locations for which TechDocs addons may be declared and rendered.
|
||||
|
||||
@@ -6,14 +6,13 @@
|
||||
/// <reference types="react" />
|
||||
|
||||
import { ApiRef } from '@backstage/core-plugin-api';
|
||||
import { AsyncState } from 'react-use/lib/useAsync';
|
||||
import { AsyncState } from 'react-use/lib/useAsyncFn';
|
||||
import { BackstagePlugin } from '@backstage/core-plugin-api';
|
||||
import { CommonProps } from '@material-ui/core/OverridableComponent';
|
||||
import { CompoundEntityRef } from '@backstage/catalog-model';
|
||||
import { Config } from '@backstage/config';
|
||||
import { CSSProperties } from '@material-ui/styles';
|
||||
import { DiscoveryApi } from '@backstage/core-plugin-api';
|
||||
import { Dispatch } from 'react';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { FetchApi } from '@backstage/core-plugin-api';
|
||||
import { IdentityApi } from '@backstage/core-plugin-api';
|
||||
@@ -21,10 +20,12 @@ import { PropsWithChildren } from 'react';
|
||||
import { default as React_2 } from 'react';
|
||||
import { ReactNode } from 'react';
|
||||
import { RouteRef } from '@backstage/core-plugin-api';
|
||||
import { SetStateAction } from 'react';
|
||||
import { StyledComponentProps } from '@material-ui/core';
|
||||
import { TableColumn } from '@backstage/core-components';
|
||||
import { TableProps } from '@backstage/core-components';
|
||||
import { TechDocsEntityMetadata } from '@backstage/plugin-techdocs-react';
|
||||
import { TechDocsMetadata } from '@backstage/plugin-techdocs-react';
|
||||
import { TechDocsReaderPageValue } from '@backstage/plugin-techdocs-react';
|
||||
import { ToolbarTypeMap } from '@material-ui/core';
|
||||
import { UserListFilterKind } from '@backstage/plugin-catalog-react';
|
||||
|
||||
@@ -252,23 +253,9 @@ export type TechDocsCustomHomeProps = {
|
||||
tabsConfig: TabsConfig;
|
||||
};
|
||||
|
||||
// @public
|
||||
export type TechDocsEntityMetadata = Entity & {
|
||||
locationMetadata?: {
|
||||
type: string;
|
||||
target: string;
|
||||
};
|
||||
};
|
||||
|
||||
// @public
|
||||
export const TechDocsIndexPage: () => JSX.Element;
|
||||
|
||||
// @public
|
||||
export type TechDocsMetadata = {
|
||||
site_name: string;
|
||||
site_description: string;
|
||||
};
|
||||
|
||||
// @public
|
||||
export const TechdocsPage: () => JSX.Element;
|
||||
|
||||
@@ -916,20 +903,6 @@ export const TechDocsReaderPageSubheader: React_2.ComponentType<
|
||||
StyledComponentProps<'root'>
|
||||
>;
|
||||
|
||||
// @public
|
||||
export type TechDocsReaderPageValue = {
|
||||
metadata: AsyncState<TechDocsMetadata>;
|
||||
entityName: CompoundEntityRef;
|
||||
entityMetadata: AsyncState<TechDocsEntityMetadata>;
|
||||
shadowRoot?: ShadowRoot;
|
||||
setShadowRoot: Dispatch<SetStateAction<ShadowRoot | undefined>>;
|
||||
title: string;
|
||||
setTitle: Dispatch<SetStateAction<string>>;
|
||||
subtitle: string;
|
||||
setSubtitle: Dispatch<SetStateAction<string>>;
|
||||
onReady?: () => void;
|
||||
};
|
||||
|
||||
// @public
|
||||
export const TechDocsReaderProvider: ({
|
||||
children,
|
||||
@@ -1030,19 +1003,6 @@ export class TechDocsStorageClient implements TechDocsStorageApi {
|
||||
// @public
|
||||
export const useEntityMetadata: () => AsyncState<TechDocsEntityMetadata>;
|
||||
|
||||
// @public
|
||||
export const useShadowRoot: () => ShadowRoot | undefined;
|
||||
|
||||
// @public
|
||||
export const useShadowRootElements: <
|
||||
TReturnedElement extends HTMLElement = HTMLElement,
|
||||
>(
|
||||
selectors: string[],
|
||||
) => TReturnedElement[];
|
||||
|
||||
// @public
|
||||
export const useTechDocsMetadata: () => AsyncState<TechDocsMetadata>;
|
||||
|
||||
// @public
|
||||
export const useTechDocsReaderPage: () => TechDocsReaderPageValue;
|
||||
```
|
||||
|
||||
@@ -47,8 +47,8 @@
|
||||
"@backstage/plugin-catalog": "^1.1.0-next.2",
|
||||
"@backstage/plugin-search": "^0.7.5-next.0",
|
||||
"@backstage/plugin-techdocs-react": "^0.0.0",
|
||||
"@backstage/version-bridge": "^1.0.0",
|
||||
"@backstage/theme": "^0.2.15",
|
||||
"@backstage/version-bridge": "^1.0.0",
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "4.0.0-alpha.57",
|
||||
|
||||
@@ -15,7 +15,10 @@
|
||||
*/
|
||||
|
||||
import { CompoundEntityRef } from '@backstage/catalog-model';
|
||||
import { TechDocsEntityMetadata, TechDocsMetadata } from './types';
|
||||
import {
|
||||
TechDocsEntityMetadata,
|
||||
TechDocsMetadata,
|
||||
} from '@backstage/plugin-techdocs-react';
|
||||
import { createApiRef } from '@backstage/core-plugin-api';
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,9 +22,12 @@ import {
|
||||
IdentityApi,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { NotFoundError, ResponseError } from '@backstage/errors';
|
||||
import {
|
||||
TechDocsEntityMetadata,
|
||||
TechDocsMetadata,
|
||||
} from '@backstage/plugin-techdocs-react';
|
||||
import { EventSourcePolyfill } from 'event-source-polyfill';
|
||||
import { SyncResult, TechDocsApi, TechDocsStorageApi } from './api';
|
||||
import { TechDocsEntityMetadata, TechDocsMetadata } from './types';
|
||||
|
||||
/**
|
||||
* API to talk to `techdocs-backend`.
|
||||
|
||||
@@ -15,21 +15,20 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { renderHook, act } from '@testing-library/react-hooks';
|
||||
import { renderHook } from '@testing-library/react-hooks';
|
||||
|
||||
import { ThemeProvider } from '@material-ui/core';
|
||||
|
||||
import { lightTheme } from '@backstage/theme';
|
||||
import { TestApiProvider } from '@backstage/test-utils';
|
||||
import { Entity, CompoundEntityRef } from '@backstage/catalog-model';
|
||||
import { TechDocsMetadata } from '@backstage/plugin-techdocs-react';
|
||||
|
||||
import { techdocsApiRef } from '../../../api';
|
||||
import { TechDocsMetadata } from '../../../types';
|
||||
|
||||
import {
|
||||
useEntityMetadata,
|
||||
useTechDocsMetadata,
|
||||
useTechDocsReaderPage,
|
||||
TechDocsReaderPageProvider,
|
||||
} from './context';
|
||||
|
||||
@@ -50,13 +49,6 @@ const mockTechDocsMetadata: TechDocsMetadata = {
|
||||
site_description: 'this is a test component',
|
||||
};
|
||||
|
||||
const mockShadowRoot = () => {
|
||||
const div = document.createElement('div');
|
||||
const shadowRoot = div.attachShadow({ mode: 'open' });
|
||||
shadowRoot.innerHTML = '<h1>Shadow DOM Mock</h1>';
|
||||
return shadowRoot;
|
||||
};
|
||||
|
||||
const techdocsApiMock = {
|
||||
getEntityMetadata: jest.fn().mockResolvedValue(mockEntityMetadata),
|
||||
getTechDocsMetadata: jest.fn().mockResolvedValue(mockTechDocsMetadata),
|
||||
@@ -128,54 +120,4 @@ describe('context', () => {
|
||||
expect(result.current.value).toMatchObject(mockTechDocsMetadata);
|
||||
});
|
||||
});
|
||||
|
||||
describe('useTechDocsReaderPage', () => {
|
||||
it('should set title', async () => {
|
||||
const { result, waitForNextUpdate } = renderHook(
|
||||
() => useTechDocsReaderPage(),
|
||||
{ wrapper },
|
||||
);
|
||||
|
||||
expect(result.current.title).toBe('');
|
||||
|
||||
act(() => result.current.setTitle('test site title'));
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(result.current.title).toBe('test site title');
|
||||
});
|
||||
|
||||
it('should set subtitle', async () => {
|
||||
const { result, waitForNextUpdate } = renderHook(
|
||||
() => useTechDocsReaderPage(),
|
||||
{ wrapper },
|
||||
);
|
||||
|
||||
expect(result.current.subtitle).toBe('');
|
||||
|
||||
act(() => result.current.setSubtitle('test site subtitle'));
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(result.current.subtitle).toBe('test site subtitle');
|
||||
});
|
||||
|
||||
it('should set shadow root', async () => {
|
||||
const { result, waitForNextUpdate } = renderHook(
|
||||
() => useTechDocsReaderPage(),
|
||||
{ wrapper },
|
||||
);
|
||||
|
||||
// mock shadowroot
|
||||
const shadowRoot = mockShadowRoot();
|
||||
|
||||
act(() => result.current.setShadowRoot(shadowRoot));
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(result.current.shadowRoot?.innerHTML).toBe(
|
||||
'<h1>Shadow DOM Mock</h1>',
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,25 +14,20 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, {
|
||||
ReactNode,
|
||||
memo,
|
||||
Dispatch,
|
||||
SetStateAction,
|
||||
useContext,
|
||||
useState,
|
||||
} from 'react';
|
||||
import useAsync, { AsyncState } from 'react-use/lib/useAsync';
|
||||
import React, { ReactNode, memo, useState } from 'react';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
import { CompoundEntityRef } from '@backstage/catalog-model';
|
||||
import {
|
||||
createVersionedContext,
|
||||
createVersionedValueMap,
|
||||
} from '@backstage/version-bridge';
|
||||
TechDocsReaderPageValue,
|
||||
defaultTechDocsReaderPageValue,
|
||||
TechDocsReaderPageContext,
|
||||
useTechDocsReaderPage,
|
||||
} from '@backstage/plugin-techdocs-react';
|
||||
import { createVersionedValueMap } from '@backstage/version-bridge';
|
||||
|
||||
import { techdocsApiRef } from '../../../api';
|
||||
import { TechDocsEntityMetadata, TechDocsMetadata } from '../../../types';
|
||||
|
||||
const areEntityNamesEqual = (
|
||||
prevEntityName: CompoundEntityRef,
|
||||
@@ -50,59 +45,6 @@ const areEntityNamesEqual = (
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @public type for the value of the TechDocsReaderPageContext
|
||||
*/
|
||||
|
||||
export type TechDocsReaderPageValue = {
|
||||
metadata: AsyncState<TechDocsMetadata>;
|
||||
entityName: CompoundEntityRef;
|
||||
entityMetadata: AsyncState<TechDocsEntityMetadata>;
|
||||
shadowRoot?: ShadowRoot;
|
||||
setShadowRoot: Dispatch<SetStateAction<ShadowRoot | undefined>>;
|
||||
title: string;
|
||||
setTitle: Dispatch<SetStateAction<string>>;
|
||||
subtitle: string;
|
||||
setSubtitle: Dispatch<SetStateAction<string>>;
|
||||
/**
|
||||
* @deprecated property can be passed down directly to the `TechDocsReaderPageContent` instead.
|
||||
*/
|
||||
onReady?: () => void;
|
||||
};
|
||||
|
||||
export const defaultTechDocsReaderPageValue: TechDocsReaderPageValue = {
|
||||
title: '',
|
||||
subtitle: '',
|
||||
setTitle: () => {},
|
||||
setSubtitle: () => {},
|
||||
setShadowRoot: () => {},
|
||||
metadata: { loading: true },
|
||||
entityMetadata: { loading: true },
|
||||
entityName: { kind: '', name: '', namespace: '' },
|
||||
};
|
||||
|
||||
export const TechDocsReaderPageContext = createVersionedContext<{
|
||||
1: TechDocsReaderPageValue;
|
||||
}>('techdocs-reader-page-context');
|
||||
/**
|
||||
* Hook used to get access to shared state between reader page components.
|
||||
* @public
|
||||
*/
|
||||
export const useTechDocsReaderPage = () => {
|
||||
const versionedContext = useContext(TechDocsReaderPageContext);
|
||||
|
||||
if (versionedContext === undefined) {
|
||||
return defaultTechDocsReaderPageValue;
|
||||
}
|
||||
|
||||
const context = versionedContext.atVersion(1);
|
||||
if (context === undefined) {
|
||||
throw new Error('No context found for version 1.');
|
||||
}
|
||||
|
||||
return context;
|
||||
};
|
||||
|
||||
/**
|
||||
* render function for {@link TechDocsReaderPageProvider}
|
||||
*
|
||||
|
||||
@@ -20,4 +20,3 @@ export type {
|
||||
TechDocsReaderLayoutProps,
|
||||
} from './TechDocsReaderPage';
|
||||
export * from './context';
|
||||
export * from './hooks';
|
||||
|
||||
+2
-2
@@ -23,12 +23,12 @@ import { StylesProvider, jssPreset } from '@material-ui/styles';
|
||||
import {
|
||||
useTechDocsAddons,
|
||||
TechDocsAddonLocations as locations,
|
||||
useTechDocsReaderPage,
|
||||
} from '@backstage/plugin-techdocs-react';
|
||||
import { CompoundEntityRef } from '@backstage/catalog-model';
|
||||
import { Content, Progress } from '@backstage/core-components';
|
||||
|
||||
import { TechDocsSearch } from '../../../search';
|
||||
import { useTechDocsReaderPage } from '../TechDocsReaderPage';
|
||||
import { TechDocsStateIndicator } from '../TechDocsStateIndicator';
|
||||
|
||||
import { useTechDocsReaderDom } from './dom';
|
||||
@@ -50,7 +50,7 @@ const useStyles = makeStyles({
|
||||
*/
|
||||
export type TechDocsReaderPageContentProps = {
|
||||
/**
|
||||
* @deprecated No need to pass down entityRef as property anymore. Consumes the entityName from `TechDocsReaderPageContext`. Use the {@link useTechDocsReaderPage} hook for custom reader page content.
|
||||
* @deprecated No need to pass down entityRef as property anymore. Consumes the entityName from `TechDocsReaderPageContext`. Use the {@link @backstage/plugin-techdocs-react#useTechDocsReaderPage} hook for custom reader page content.
|
||||
*/
|
||||
entityRef?: CompoundEntityRef;
|
||||
/**
|
||||
|
||||
@@ -21,9 +21,9 @@ import React, {
|
||||
ReactNode,
|
||||
} from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useTechDocsReaderPage } from '@backstage/plugin-techdocs-react';
|
||||
|
||||
import { useReaderState, ReaderState } from '../useReaderState';
|
||||
import { useTechDocsReaderPage } from '../TechDocsReaderPage';
|
||||
|
||||
const TechDocsReaderContext = createContext<ReaderState>({} as ReaderState);
|
||||
|
||||
|
||||
+4
-4
@@ -23,6 +23,9 @@ import CodeIcon from '@material-ui/icons/Code';
|
||||
import {
|
||||
TechDocsAddonLocations as locations,
|
||||
useTechDocsAddons,
|
||||
useTechDocsReaderPage,
|
||||
TechDocsEntityMetadata,
|
||||
TechDocsMetadata,
|
||||
} from '@backstage/plugin-techdocs-react';
|
||||
import {
|
||||
EntityRefLink,
|
||||
@@ -33,10 +36,7 @@ import { RELATION_OWNED_BY, CompoundEntityRef } from '@backstage/catalog-model';
|
||||
import { Header, HeaderLabel } from '@backstage/core-components';
|
||||
import { useRouteRef, configApiRef, useApi } from '@backstage/core-plugin-api';
|
||||
|
||||
import { useTechDocsReaderPage } from '../TechDocsReaderPage';
|
||||
|
||||
import { rootRouteRef } from '../../../routes';
|
||||
import { TechDocsEntityMetadata, TechDocsMetadata } from '../../../types';
|
||||
|
||||
const skeleton = <Skeleton animation="wave" variant="text" height={40} />;
|
||||
|
||||
@@ -44,7 +44,7 @@ const skeleton = <Skeleton animation="wave" variant="text" height={40} />;
|
||||
* Props for {@link TechDocsReaderPageHeader}
|
||||
*
|
||||
* @public
|
||||
* @deprecated No need to pass down properties anymore. The component consumes data from `TechDocsReaderPageContext` instead. Use the {@link useTechDocsReaderPage} hook for custom header.
|
||||
* @deprecated No need to pass down properties anymore. The component consumes data from `TechDocsReaderPageContext` instead. Use the {@link @backstage/plugin-techdocs-react#useTechDocsReaderPage} hook for custom header.
|
||||
*/
|
||||
export type TechDocsReaderPageHeaderProps = PropsWithChildren<{
|
||||
entityRef?: CompoundEntityRef;
|
||||
|
||||
@@ -17,16 +17,12 @@
|
||||
export type {
|
||||
TechDocsReaderPageProps,
|
||||
TechDocsReaderLayoutProps,
|
||||
TechDocsReaderPageValue,
|
||||
TechDocsReaderPageProviderProps,
|
||||
TechDocsReaderPageProviderRenderFunction,
|
||||
} from './TechDocsReaderPage';
|
||||
export {
|
||||
useShadowRoot,
|
||||
useShadowRootElements,
|
||||
useEntityMetadata,
|
||||
useTechDocsMetadata,
|
||||
useTechDocsReaderPage,
|
||||
TechDocsReaderLayout,
|
||||
TechDocsReaderPageProvider,
|
||||
} from './TechDocsReaderPage';
|
||||
|
||||
@@ -14,7 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Entity, CompoundEntityRef } from '@backstage/catalog-model';
|
||||
import { CompoundEntityRef } from '@backstage/catalog-model';
|
||||
import {
|
||||
TechDocsEntityMetadata,
|
||||
TechDocsMetadata,
|
||||
} from '@backstage/plugin-techdocs-react';
|
||||
|
||||
/**
|
||||
* Helper function that gives the children of {@link TechDocsReaderPage} access to techdocs and entity metadata
|
||||
@@ -34,22 +38,3 @@ export type TechDocsReaderPageRenderFunction = ({
|
||||
*/
|
||||
onReady?: () => void;
|
||||
}) => JSX.Element;
|
||||
|
||||
/**
|
||||
* Metadata for TechDocs page
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type TechDocsMetadata = {
|
||||
site_name: string;
|
||||
site_description: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Metadata for TechDocs Entity
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type TechDocsEntityMetadata = Entity & {
|
||||
locationMetadata?: { type: string; target: string };
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user