Add component page with unregister button (#866)
* Add component page with unregister button * Use errorApi and redirect on ComponentPage Co-authored-by: Wojciech Adaszynski <wojciecha@spotify.com>
This commit is contained in:
committed by
GitHub
parent
e7c8369c32
commit
9fc9f972fc
@@ -28,6 +28,7 @@
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.1.1-alpha.5",
|
||||
"@backstage/dev-utils": "^0.1.1-alpha.5",
|
||||
"@backstage/test-utils": "^0.1.1-alpha.5",
|
||||
"@testing-library/jest-dom": "^4.2.4",
|
||||
"@testing-library/react": "^9.3.2",
|
||||
"@testing-library/user-event": "^7.1.2",
|
||||
|
||||
@@ -19,12 +19,19 @@ import { render } from '@testing-library/react';
|
||||
import CatalogPage from './CatalogPage';
|
||||
import { ThemeProvider } from '@material-ui/core';
|
||||
import { lightTheme } from '@backstage/theme';
|
||||
import { ComponentFactory } from '../../data/component';
|
||||
|
||||
const testComponentFactory: ComponentFactory = {
|
||||
getAllComponents: jest.fn(() => Promise.resolve([{ name: 'test' }])),
|
||||
getComponentByName: jest.fn(() => Promise.resolve({ name: 'test' })),
|
||||
removeComponentByName: jest.fn(() => Promise.resolve(true)),
|
||||
};
|
||||
|
||||
describe('CatalogPage', () => {
|
||||
it('should render', async () => {
|
||||
const rendered = render(
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<CatalogPage />
|
||||
<CatalogPage componentFactory={testComponentFactory} />
|
||||
</ThemeProvider>,
|
||||
);
|
||||
expect(await rendered.findByText('Your components')).toBeInTheDocument();
|
||||
|
||||
@@ -18,12 +18,12 @@ import React, { FC } from 'react';
|
||||
import { Content, Header, Page, pageTheme } from '@backstage/core';
|
||||
import { useAsync } from 'react-use';
|
||||
import { ComponentFactory } from '../../data/component';
|
||||
import { MockComponentFactory } from '../../data/mock-factory';
|
||||
import CatalogTable from '../CatalogTable/CatalogTable';
|
||||
|
||||
const componentFactory: ComponentFactory = MockComponentFactory;
|
||||
|
||||
const CatalogPage: FC<{}> = () => {
|
||||
type CatalogPageProps = {
|
||||
componentFactory: ComponentFactory;
|
||||
};
|
||||
const CatalogPage: FC<CatalogPageProps> = ({ componentFactory }) => {
|
||||
const { value, error, loading } = useAsync(componentFactory.getAllComponents);
|
||||
return (
|
||||
<Page theme={pageTheme.home}>
|
||||
|
||||
@@ -16,13 +16,16 @@
|
||||
import React, { FC } from 'react';
|
||||
import { Component } from '../../data/component';
|
||||
import { InfoCard, Progress, Table, TableColumn } from '@backstage/core';
|
||||
import { Typography } from '@material-ui/core';
|
||||
import { Typography, Link } from '@material-ui/core';
|
||||
|
||||
const columns: TableColumn[] = [
|
||||
{
|
||||
title: 'Name',
|
||||
field: 'name',
|
||||
highlight: true,
|
||||
render: (componentData: any) => (
|
||||
<Link href={`/catalog/${componentData.name}`}>{componentData.name}</Link>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* 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 ComponentContextMenu from './ComponentContextMenu';
|
||||
import { render } from '@testing-library/react';
|
||||
import * as React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
|
||||
describe('ComponentContextMenu', () => {
|
||||
it('should call onUnregisterComponent on button click', async () => {
|
||||
await act(async () => {
|
||||
const mockCallback = jest.fn();
|
||||
const menu = await render(
|
||||
<ComponentContextMenu onUnregisterComponent={mockCallback} />,
|
||||
);
|
||||
const button = await menu.findByTestId('menu-button');
|
||||
button.click();
|
||||
const unregister = await menu.findByText('Unregister component');
|
||||
expect(unregister).toBeInTheDOM();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* 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, { FC, useEffect, useRef, useState } from 'react';
|
||||
import {
|
||||
IconButton,
|
||||
ListItemIcon,
|
||||
Menu,
|
||||
MenuItem,
|
||||
Typography,
|
||||
} from '@material-ui/core';
|
||||
import { Cancel, MoreVert, SwapHoriz } from '@material-ui/icons';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
|
||||
const useStyles = makeStyles({
|
||||
menu: {
|
||||
marginTop: 52,
|
||||
},
|
||||
});
|
||||
|
||||
type ComponentContextMenuProps = {
|
||||
onUnregisterComponent: () => void;
|
||||
};
|
||||
|
||||
const ComponentContextMenu: FC<ComponentContextMenuProps> = ({
|
||||
onUnregisterComponent,
|
||||
}) => {
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
const menuAnchor = useRef<HTMLDivElement>(null);
|
||||
const classes = useStyles();
|
||||
|
||||
useEffect(() => {
|
||||
const globalCloseHandler = (event: any) => {
|
||||
const menu = menuAnchor.current;
|
||||
if (menu !== null && !menu.contains(event.target)) {
|
||||
setMenuOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('click', globalCloseHandler);
|
||||
return () => window.removeEventListener('click', globalCloseHandler);
|
||||
}, [menuOpen]);
|
||||
|
||||
return (
|
||||
<div ref={menuAnchor}>
|
||||
<IconButton
|
||||
aria-label="more"
|
||||
aria-controls="long-menu"
|
||||
aria-haspopup="true"
|
||||
onClick={() => setMenuOpen(!menuOpen)}
|
||||
data-testid="menu-button"
|
||||
>
|
||||
<MoreVert />
|
||||
</IconButton>
|
||||
<Menu
|
||||
open={menuOpen}
|
||||
anchorEl={menuAnchor.current}
|
||||
className={classes.menu}
|
||||
>
|
||||
<MenuItem onClick={onUnregisterComponent}>
|
||||
<ListItemIcon>
|
||||
<Cancel fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<Typography variant="inherit">Unregister component</Typography>
|
||||
</MenuItem>
|
||||
<MenuItem>
|
||||
<ListItemIcon>
|
||||
<SwapHoriz fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<Typography variant="inherit">More repository</Typography>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export default ComponentContextMenu;
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* 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 ComponentMetadataCard from './ComponentMetadataCard';
|
||||
import { Component } from '../../data/component';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
describe('ComponentMetadataCard component', () => {
|
||||
it('should display component name if provided', async () => {
|
||||
const testComponent: Component = {
|
||||
name: 'test',
|
||||
};
|
||||
const rendered = await render(
|
||||
<ComponentMetadataCard loading={false} component={testComponent} />,
|
||||
);
|
||||
expect(await rendered.findByText('test')).toBeInTheDOM();
|
||||
});
|
||||
it('should display loader when loading is set to true', async () => {
|
||||
const rendered = await render(
|
||||
<ComponentMetadataCard loading component={undefined} />,
|
||||
);
|
||||
expect(await rendered.findByRole('progressbar')).toBeInTheDOM();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* 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, { FC } from 'react';
|
||||
import { Component } from '../../data/component';
|
||||
import { Progress, InfoCard, StructuredMetadataTable } from '@backstage/core';
|
||||
|
||||
type ComponentMetadataCardProps = {
|
||||
loading: boolean;
|
||||
component: Component | undefined;
|
||||
};
|
||||
const ComponentMetadataCard: FC<ComponentMetadataCardProps> = ({
|
||||
loading,
|
||||
component,
|
||||
}) => {
|
||||
if (loading) {
|
||||
return <Progress />;
|
||||
}
|
||||
if (!component) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<InfoCard title="Metadata">
|
||||
<StructuredMetadataTable metadata={component} />
|
||||
</InfoCard>
|
||||
);
|
||||
};
|
||||
export default ComponentMetadataCard;
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* 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 ComponentPage from './ComponentPage';
|
||||
import { render } from '@testing-library/react';
|
||||
import * as React from 'react';
|
||||
import { wrapInTheme } from '@backstage/test-utils';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { ApiProvider, ApiRegistry, errorApiRef } from '@backstage/core';
|
||||
|
||||
const getTestProps = (componentName: string) => {
|
||||
return {
|
||||
match: {
|
||||
params: {
|
||||
name: componentName,
|
||||
},
|
||||
},
|
||||
history: {
|
||||
push: jest.fn(),
|
||||
},
|
||||
componentFactory: {
|
||||
getAllComponents: jest.fn(() => Promise.resolve([{ name: 'test' }])),
|
||||
getComponentByName: jest.fn(() => Promise.resolve({ name: 'test' })),
|
||||
removeComponentByName: jest.fn(() => Promise.resolve(true)),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const errorApi = { post: () => {} };
|
||||
|
||||
describe('ComponentPage', () => {
|
||||
it('should redirect to component table page when name is not provided', async () => {
|
||||
const props = getTestProps('');
|
||||
await render(
|
||||
wrapInTheme(
|
||||
<ApiProvider apis={ApiRegistry.from([[errorApiRef, errorApi]])}>
|
||||
<ComponentPage {...props} />
|
||||
</ApiProvider>,
|
||||
),
|
||||
);
|
||||
expect(props.history.push).toHaveBeenCalledWith('/catalog');
|
||||
});
|
||||
it('should use factory to fetch component by name and display it', async () => {
|
||||
await act(async () => {
|
||||
const props = getTestProps('test');
|
||||
await render(
|
||||
wrapInTheme(
|
||||
<ApiProvider apis={ApiRegistry.from([[errorApiRef, errorApi]])}>
|
||||
<ComponentPage {...props} />
|
||||
</ApiProvider>,
|
||||
),
|
||||
);
|
||||
expect(props.componentFactory.getComponentByName).toHaveBeenCalledWith(
|
||||
'test',
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* 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, { FC, useEffect, useState } from 'react';
|
||||
import { useAsync } from 'react-use';
|
||||
import { ComponentFactory } from '../../data/component';
|
||||
import ComponentMetadataCard from '../ComponentMetadataCard/ComponentMetadataCard';
|
||||
import {
|
||||
Content,
|
||||
Header,
|
||||
pageTheme,
|
||||
Page,
|
||||
useApi,
|
||||
ErrorApi,
|
||||
errorApiRef,
|
||||
} from '@backstage/core';
|
||||
import ComponentContextMenu from '../ComponentContextMenu/ComponentContextMenu';
|
||||
import ComponentRemovalDialog from '../ComponentRemovalDialog/ComponentRemovalDialog';
|
||||
|
||||
const REDIRECT_DELAY = 1000;
|
||||
|
||||
type ComponentPageProps = {
|
||||
componentFactory: ComponentFactory;
|
||||
match: {
|
||||
params: {
|
||||
name: string;
|
||||
};
|
||||
};
|
||||
history: {
|
||||
push: (url: string) => void;
|
||||
};
|
||||
};
|
||||
|
||||
const ComponentPage: FC<ComponentPageProps> = ({
|
||||
match,
|
||||
history,
|
||||
componentFactory,
|
||||
}) => {
|
||||
const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false);
|
||||
const [removingPending, setRemovingPending] = useState(false);
|
||||
const showRemovalDialog = () => setConfirmationDialogOpen(true);
|
||||
const hideRemovalDialog = () => setConfirmationDialogOpen(false);
|
||||
const componentName = match.params.name;
|
||||
const errorApi = useApi<ErrorApi>(errorApiRef);
|
||||
|
||||
if (componentName === '') {
|
||||
history.push('/catalog');
|
||||
return null;
|
||||
}
|
||||
|
||||
const catalogRequest = useAsync(() =>
|
||||
componentFactory.getComponentByName(match.params.name),
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (catalogRequest.error) {
|
||||
errorApi.post(new Error('Component not found!'));
|
||||
setTimeout(() => {
|
||||
history.push('/catalog');
|
||||
}, REDIRECT_DELAY);
|
||||
}
|
||||
}, [catalogRequest.error]);
|
||||
|
||||
const removeComponent = async () => {
|
||||
setConfirmationDialogOpen(false);
|
||||
setRemovingPending(true);
|
||||
await componentFactory.removeComponentByName(componentName);
|
||||
history.push('/catalog');
|
||||
};
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.home}>
|
||||
<Header title={catalogRequest?.value?.name || 'Catalog'}>
|
||||
<ComponentContextMenu onUnregisterComponent={showRemovalDialog} />
|
||||
</Header>
|
||||
{confirmationDialogOpen && catalogRequest.value && (
|
||||
<ComponentRemovalDialog
|
||||
component={catalogRequest.value}
|
||||
onClose={hideRemovalDialog}
|
||||
onConfirm={removeComponent}
|
||||
onCancel={hideRemovalDialog}
|
||||
/>
|
||||
)}
|
||||
<Content>
|
||||
<ComponentMetadataCard
|
||||
loading={catalogRequest.loading || removingPending}
|
||||
component={catalogRequest.value}
|
||||
/>
|
||||
</Content>
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
export default ComponentPage;
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* 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, { FC } from 'react';
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogContentText,
|
||||
DialogTitle,
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} from '@material-ui/core';
|
||||
import { Component } from '../../data/component';
|
||||
|
||||
type ComponentRemovalDialogProps = {
|
||||
onConfirm: () => any;
|
||||
onCancel: () => any;
|
||||
onClose: () => any;
|
||||
component: Component;
|
||||
};
|
||||
const ComponentRemovalDialog: FC<ComponentRemovalDialogProps> = ({
|
||||
onConfirm,
|
||||
onCancel,
|
||||
onClose,
|
||||
component,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const fullScreen = useMediaQuery(theme.breakpoints.down('sm'));
|
||||
return (
|
||||
<Dialog fullScreen={fullScreen} open onClose={onClose}>
|
||||
<DialogTitle id="responsive-dialog-title">
|
||||
Are you sure you want to unregister this component?
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<DialogContentText>
|
||||
This action will unregister {component.name}. To undo, just
|
||||
re-register the component in Backstage.
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={onCancel} color="primary">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button onClick={onConfirm} color="primary">
|
||||
Unregister
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
export default ComponentRemovalDialog;
|
||||
@@ -20,4 +20,5 @@ export type Component = {
|
||||
export interface ComponentFactory {
|
||||
getAllComponents(): Promise<Component[]>;
|
||||
getComponentByName(name: string): Promise<Component | undefined>;
|
||||
removeComponentByName(name: string): Promise<boolean>;
|
||||
}
|
||||
|
||||
@@ -16,16 +16,33 @@
|
||||
import { Component, ComponentFactory } from './component';
|
||||
import mock from './mock-factory-data.json';
|
||||
|
||||
const ARTIFICIAL_TIMEOUT = 800;
|
||||
let inMemoryStore = [...mock];
|
||||
export const MockComponentFactory: ComponentFactory = {
|
||||
getAllComponents(): Promise<Component[]> {
|
||||
return new Promise((resolve) => setTimeout(() => resolve(mock), 2000));
|
||||
return new Promise((resolve) =>
|
||||
setTimeout(() => resolve(inMemoryStore), ARTIFICIAL_TIMEOUT),
|
||||
);
|
||||
},
|
||||
getComponentByName(name: string): Promise<Component | undefined> {
|
||||
return new Promise((resolve, reject) =>
|
||||
setTimeout(() => {
|
||||
const mockComponent = inMemoryStore.find(
|
||||
(component) => component.name === name,
|
||||
);
|
||||
if (mockComponent) return resolve(mockComponent);
|
||||
return reject({ code: 'Component not found!' });
|
||||
}, ARTIFICIAL_TIMEOUT),
|
||||
);
|
||||
},
|
||||
removeComponentByName(name: string): Promise<boolean> {
|
||||
return new Promise((resolve) =>
|
||||
setTimeout(
|
||||
() => resolve(mock.find((component) => component.name === name)),
|
||||
2000,
|
||||
),
|
||||
setTimeout(() => {
|
||||
inMemoryStore = inMemoryStore.filter(
|
||||
(component) => component.name !== name,
|
||||
);
|
||||
resolve(true);
|
||||
}, ARTIFICIAL_TIMEOUT),
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* 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 * as React from 'react';
|
||||
import { ComponentFactory } from './component';
|
||||
import { MockComponentFactory } from './mock-factory';
|
||||
|
||||
const componentFactory: ComponentFactory = MockComponentFactory;
|
||||
|
||||
export const withMockStore = (Component: React.ElementType) => {
|
||||
return (props: any) => (
|
||||
<Component {...props} componentFactory={componentFactory} />
|
||||
);
|
||||
};
|
||||
@@ -16,10 +16,13 @@
|
||||
|
||||
import { createPlugin } from '@backstage/core';
|
||||
import CatalogPage from './components/CatalogPage';
|
||||
import ComponentPage from './components/ComponentPage/ComponentPage';
|
||||
import { withMockStore } from './data/with-mock-store';
|
||||
|
||||
export const plugin = createPlugin({
|
||||
id: 'catalog',
|
||||
register({ router }) {
|
||||
router.registerRoute('/catalog', CatalogPage);
|
||||
router.registerRoute('/catalog', withMockStore(CatalogPage));
|
||||
router.registerRoute('/catalog/:name/', withMockStore(ComponentPage));
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user