Update CatalogTable actions to support custom URLs
This commit is contained in:
@@ -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');
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
+23
-1
@@ -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;
|
||||
};
|
||||
@@ -1874,7 +1874,6 @@
|
||||
"@backstage/catalog-model" "^0.7.1"
|
||||
"@backstage/core" "^0.6.2"
|
||||
"@backstage/plugin-catalog-react" "^0.0.4"
|
||||
"@backstage/plugin-scaffolder" "^0.5.1"
|
||||
"@backstage/theme" "^0.2.3"
|
||||
"@material-ui/core" "^4.11.0"
|
||||
"@material-ui/icons" "^4.9.1"
|
||||
@@ -18238,7 +18237,7 @@ modify-values@^1.0.0:
|
||||
resolved "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022"
|
||||
integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==
|
||||
|
||||
moment@^2.19.3, moment@^2.25.3, moment@^2.26.0, moment@^2.27.0:
|
||||
moment@^2.19.3, moment@^2.25.3, moment@^2.27.0:
|
||||
version "2.29.1"
|
||||
resolved "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
|
||||
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
|
||||
|
||||
Reference in New Issue
Block a user