Update CatalogTable actions to support custom URLs

This commit is contained in:
James Turley
2021-02-13 11:37:41 +00:00
parent f30b16b541
commit 0fc2a84352
5 changed files with 99 additions and 10 deletions
@@ -35,7 +35,7 @@ import ExtensionIcon from '@material-ui/icons/Extension';
import GitHubIcon from '@material-ui/icons/GitHub';
import React from 'react';
import { findLocationForEntityMeta } from '../../data/utils';
import { createEditLink, determineUrlType } from '../createEditLink';
import { createEditLink, determineUrlType } from '../actions';
import { AboutContent } from './AboutContent';
const useStyles = makeStyles({
@@ -15,6 +15,7 @@
*/
import { Entity } from '@backstage/catalog-model';
import { act, fireEvent } from '@testing-library/react';
import { renderWithEffects, wrapInTestApp } from '@backstage/test-utils';
import * as React from 'react';
import { CatalogTable } from './CatalogTable';
@@ -38,6 +39,14 @@ const entities: Entity[] = [
];
describe('CatalogTable component', () => {
beforeEach(() => {
window.open = jest.fn();
});
afterEach(() => {
jest.resetAllMocks();
});
it('should render error message when error is passed in props', async () => {
const rendered = await renderWithEffects(
wrapInTestApp(
@@ -70,4 +79,62 @@ describe('CatalogTable component', () => {
expect(rendered.getByText(/component2/)).toBeInTheDocument();
expect(rendered.getByText(/component3/)).toBeInTheDocument();
});
it('should use specified edit URL if in annotation', async () => {
const entity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
name: 'component1',
annotations: { 'backstage.io/browser-edit-url': 'https://other.place' },
},
};
const { getByTitle } = await renderWithEffects(
wrapInTestApp(
<CatalogTable
titlePreamble="Owned"
entities={[entity]}
loading={false}
/>,
),
);
const editButton = getByTitle('Edit');
await act(async () => {
fireEvent.click(editButton);
});
expect(window.open).toHaveBeenCalledWith('https://other.place', '_blank');
});
it('should use specified view URL if in annotation', async () => {
const entity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
name: 'component1',
annotations: { 'backstage.io/browser-view-url': 'https://other.place' },
},
};
const { getByTitle } = await renderWithEffects(
wrapInTestApp(
<CatalogTable
titlePreamble="Owned"
entities={[entity]}
loading={false}
/>,
),
);
const viewButton = getByTitle('View');
await act(async () => {
fireEvent.click(viewButton);
});
expect(window.open).toHaveBeenCalledWith('https://other.place', '_blank');
});
});
@@ -34,13 +34,12 @@ import {
getEntityRelations,
useStarredEntities,
} from '@backstage/plugin-catalog-react';
import { Chip } from '@material-ui/core';
import Edit from '@material-ui/icons/Edit';
import OpenInNew from '@material-ui/icons/OpenInNew';
import React from 'react';
import { findLocationForEntityMeta } from '../../data/utils';
import { createEditLink } from '../createEditLink';
import { findViewUrl, findEditUrl } from '../actions';
import {
favouriteEntityIcon,
favouriteEntityTooltip,
@@ -154,23 +153,25 @@ export const CatalogTable = ({
const actions: TableProps<EntityRow>['actions'] = [
({ entity }) => {
const location = findLocationForEntityMeta(entity.metadata);
const url = findViewUrl(entity, location);
return {
icon: () => <OpenInNew fontSize="small" />,
tooltip: 'View',
onClick: () => {
if (!location) return;
window.open(location.target, '_blank');
if (!url) return;
window.open(url, '_blank');
},
};
},
({ entity }) => {
const location = findLocationForEntityMeta(entity.metadata);
const url = findEditUrl(entity, location);
return {
icon: () => <Edit fontSize="small" />,
tooltip: 'Edit',
onClick: () => {
if (!location) return;
window.open(createEditLink(location), '_blank');
if (!url) return;
window.open(url, '_blank');
},
};
},
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { LocationSpec } from '@backstage/catalog-model';
import { LocationSpec, Entity } from '@backstage/catalog-model';
import parseGitUrl from 'git-url-parse';
/**
@@ -75,3 +75,25 @@ export const determineUrlType = (url: string): string => {
}
return 'url';
};
export const findEditUrl = (
{ metadata }: Entity,
location?: LocationSpec,
): string | undefined => {
const annotations = metadata.annotations || {};
const editUrl = annotations['backstage.io/browser-edit-url'];
if (editUrl) return editUrl;
return location && createEditLink(location);
};
export const findViewUrl = (
{ metadata }: Entity,
location?: LocationSpec,
): string | undefined => {
const annotations = metadata.annotations || {};
return annotations['backstage.io/browser-view-url'] || location?.target;
};