address review comments

Signed-off-by: Brian Fletcher <brian@roadie.io>
This commit is contained in:
Brian Fletcher
2022-12-22 19:28:28 +00:00
parent ad5c714055
commit 3d679f83c1
5 changed files with 136 additions and 115 deletions
@@ -13,9 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Button, Tooltip } from '@material-ui/core';
import { IconButton } from '@material-ui/core';
import EmailIcon from '@material-ui/icons/Email';
import React from 'react';
import { Link } from '@backstage/core-components';
/**
* Email Card action link
@@ -24,10 +25,14 @@ import React from 'react';
*/
export const EmailCardAction = ({ email }: { email: string }) => {
return (
<Tooltip title={`Email ${email}`}>
<Button target="_blank" href={`mailto:${email}`} size="small">
<EmailIcon color="action" />
</Button>
</Tooltip>
<IconButton
component={Link}
aria-label="Email"
title={`Email ${email}`}
to={`mailto:${email}`}
target="_blank"
>
<EmailIcon />
</IconButton>
);
};
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { entityRouteRef } from '../../../routes';
import { Tooltip } from '@material-ui/core';
import { IconButton } from '@material-ui/core';
import InfoIcon from '@material-ui/icons/Info';
import React from 'react';
import { useRouteRef } from '@backstage/core-plugin-api';
@@ -30,19 +30,17 @@ export const EntityCardActions = ({ entity }: { entity: Entity }) => {
const entityRoute = useRouteRef(entityRouteRef);
return (
<>
<Tooltip title="Show details">
<Link
component="button"
to={entityRoute({
name: entity.metadata.name,
namespace: entity.metadata.namespace || 'default',
kind: entity.kind.toLocaleLowerCase('en-US'),
})}
>
<InfoIcon color="action" />
</Link>
</Tooltip>
</>
<IconButton
component={Link}
aria-label="Show"
title="Show details"
to={entityRoute({
name: entity.metadata.name,
namespace: entity.metadata.namespace || 'default',
kind: entity.kind.toLocaleLowerCase('en-US'),
})}
>
<InfoIcon />
</IconButton>
);
};
@@ -1,41 +0,0 @@
/*
* 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 { Card, CardContent } from '@material-ui/core';
import { Alert } from '@material-ui/lab';
import React from 'react';
/**
* Entity not found card
*
* @private
*/
export const EntityNotFoundCard = ({
entityRef,
error,
}: {
entityRef: string;
error?: Error;
}) => {
return (
<Card>
<CardContent>
<Alert severity="warning">
{entityRef} was not found {error?.message}
</Alert>
</CardContent>
</Card>
);
};
@@ -22,9 +22,15 @@ import {
import Button from '@material-ui/core/Button';
import { wrapInTestApp, TestApiProvider } from '@backstage/test-utils';
import { catalogApiRef } from '../../api';
import { CompoundEntityRef } from '@backstage/catalog-model';
import {
CompoundEntityRef,
parseEntityRef,
stringifyEntityRef,
} from '@backstage/catalog-model';
import { entityRouteRef } from '../../routes';
import { CatalogApi } from '@backstage/catalog-client';
import { Table, TableColumn } from '@backstage/core-components';
import { EntityRefLink } from '../EntityRefLink';
const mockCatalogApi = {
getEntityByRef: async (entityRef: CompoundEntityRef) => {
@@ -137,3 +143,55 @@ export const SlowCatalogItem = (args: EntityPeekAheadPopoverProps) => (
SlowCatalogItem.args = {
entityRef: 'component:default/slow.catalog.item',
};
const columns: TableColumn<CompoundEntityRef>[] = [
{
title: 'entity',
render: entityRef => {
return (
<EntityPeekAheadPopover entityRef={stringifyEntityRef(entityRef)}>
<EntityRefLink entityRef={entityRef} />
</EntityPeekAheadPopover>
);
},
},
{
title: 'owner',
render: () => {
return (
<EntityPeekAheadPopover entityRef="user:default/fname.lname">
<EntityRefLink
entityRef={parseEntityRef('user:default/fname.lname')}
/>
</EntityPeekAheadPopover>
);
},
},
{
title: 'name',
render: entityRef => stringifyEntityRef(entityRef),
},
];
export const TableOfItems = (args: { data: CompoundEntityRef[] }) => (
<Table columns={columns} data={args.data} />
);
TableOfItems.args = {
data: [
{
name: 'playback',
kind: 'component',
namespace: 'default',
},
{
name: 'playback',
kind: 'component',
namespace: 'default',
},
{
name: 'playback',
kind: 'component',
namespace: 'default',
},
],
};
@@ -38,13 +38,12 @@ import {
isUserEntity,
parseEntityRef,
} from '@backstage/catalog-model';
import { Progress } from '@backstage/core-components';
import { Progress, ResponseErrorPanel } from '@backstage/core-components';
import {
EntityCardActions,
UserCardActions,
GroupCardActions,
} from './CardActionComponents';
import { EntityNotFoundCard } from './EntityNotFoundCard';
import { debounce } from 'lodash';
/**
@@ -126,11 +125,7 @@ export const EntityPeekAheadPopover = (props: EntityPeekAheadPopoverProps) => {
return (
<>
{' '}
<span
onMouseEnter={debouncedHandleMouseEnter}
onMouseLeave={handleOnMouseLeave}
>
<span onMouseEnter={debouncedHandleMouseEnter}>
<span data-testid="trigger" {...bindHover(popupState)}>
{children}
</span>
@@ -149,56 +144,62 @@ export const EntityPeekAheadPopover = (props: EntityPeekAheadPopoverProps) => {
vertical: 'top',
horizontal: 'center',
}}
onMouseLeave={handleOnMouseLeave}
>
<>
{loading && <Progress />}
{!entity && !loading && (
<EntityNotFoundCard entityRef={entityRef} error={error} />
)}
{entity && (
<Card>
<CardContent>
<Typography color="textSecondary">
{compoundEntityRef.namespace}
</Typography>
<Typography variant="h5" component="div">
{compoundEntityRef.name}
</Typography>
<Typography color="textSecondary">{entity.kind}</Typography>
<Typography
className={classes.descriptionTypography}
paragraph
>
{entity.metadata.description}
</Typography>
<Typography>{entity.spec?.type}</Typography>
<Box marginTop="0.5em">
{(entity.metadata.tags || [])
.slice(0, maxTagChips)
.map(tag => {
return <Chip key={tag} size="small" label={tag} />;
})}
{entity.metadata.tags?.length &&
entity.metadata.tags?.length > maxTagChips && (
<Tooltip title="Drill into the entity to see all of the tags.">
<Chip key="other-tags" size="small" label="..." />
</Tooltip>
)}
</Box>
</CardContent>
<CardActions>
{error && <ResponseErrorPanel error={error} />}
<Card>
{loading && <Progress />}
<CardContent>
{entity && (
<>
{isUserEntity(entity) && (
<UserCardActions entity={entity} />
)}
{isGroupEntity(entity) && (
<GroupCardActions entity={entity} />
)}
<EntityCardActions entity={entity} />
<Typography color="textSecondary">
{compoundEntityRef.namespace}
</Typography>
<Typography variant="h5" component="div">
{compoundEntityRef.name}
</Typography>
<Typography color="textSecondary">{entity.kind}</Typography>
<Typography
className={classes.descriptionTypography}
paragraph
>
{entity.metadata.description}
</Typography>
<Typography>{entity.spec?.type}</Typography>
<Box marginTop="0.5em">
{(entity.metadata.tags || [])
.slice(0, maxTagChips)
.map(tag => {
return <Chip key={tag} size="small" label={tag} />;
})}
{entity.metadata.tags?.length &&
entity.metadata.tags?.length > maxTagChips && (
<Tooltip title="Drill into the entity to see all of the tags.">
<Chip key="other-tags" size="small" label="..." />
</Tooltip>
)}
</Box>
</>
)}
</CardContent>
{!error && (
<CardActions>
{entity && (
<>
{isUserEntity(entity) && (
<UserCardActions entity={entity} />
)}
{isGroupEntity(entity) && (
<GroupCardActions entity={entity} />
)}
<EntityCardActions entity={entity} />
</>
)}
</CardActions>
</Card>
)}
)}
</Card>
</>
</HoverPopover>
)}