feat: add link buttons to bottom of template card
Signed-off-by: Christian Marker / Intility AS <christian.marker@intility.no>
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
import {
|
||||
Entity,
|
||||
EntityLink,
|
||||
parseEntityRef,
|
||||
RELATION_OWNED_BY,
|
||||
stringifyEntityRef,
|
||||
@@ -46,6 +47,7 @@ import {
|
||||
useTheme,
|
||||
} from '@material-ui/core';
|
||||
import WarningIcon from '@material-ui/icons/Warning';
|
||||
import LanguageIcon from '@material-ui/icons/Language';
|
||||
import React from 'react';
|
||||
import { selectedTemplateRouteRef } from '../../routes';
|
||||
|
||||
@@ -54,7 +56,12 @@ import {
|
||||
ItemCardHeader,
|
||||
MarkdownContent,
|
||||
} from '@backstage/core-components';
|
||||
import { useApi, useRouteRef } from '@backstage/core-plugin-api';
|
||||
import {
|
||||
IconComponent,
|
||||
useApi,
|
||||
useApp,
|
||||
useRouteRef,
|
||||
} from '@backstage/core-plugin-api';
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
cardHeader: {
|
||||
@@ -69,7 +76,6 @@ const useStyles = makeStyles(theme => ({
|
||||
display: '-webkit-box',
|
||||
'-webkit-line-clamp': 10,
|
||||
'-webkit-box-orient': 'vertical',
|
||||
paddingBottom: '0.8em',
|
||||
},
|
||||
label: {
|
||||
color: theme.palette.text.secondary,
|
||||
@@ -80,6 +86,14 @@ const useStyles = makeStyles(theme => ({
|
||||
lineHeight: 1,
|
||||
paddingBottom: '0.2rem',
|
||||
},
|
||||
linksLabel: {
|
||||
padding: '0 16px',
|
||||
},
|
||||
description: {
|
||||
'& p': {
|
||||
margin: '0px',
|
||||
},
|
||||
},
|
||||
leftButton: {
|
||||
marginRight: 'auto',
|
||||
},
|
||||
@@ -92,6 +106,8 @@ const useStyles = makeStyles(theme => ({
|
||||
},
|
||||
}));
|
||||
|
||||
const MuiIcon = ({ icon: Icon }: { icon: IconComponent }) => <Icon />;
|
||||
|
||||
const useDeprecationStyles = makeStyles(theme => ({
|
||||
deprecationIcon: {
|
||||
position: 'absolute',
|
||||
@@ -115,6 +131,7 @@ type TemplateProps = {
|
||||
title: string;
|
||||
type: string;
|
||||
name: string;
|
||||
links: EntityLink[];
|
||||
};
|
||||
|
||||
const getTemplateCardProps = (
|
||||
@@ -127,6 +144,7 @@ const getTemplateCardProps = (
|
||||
type: template.spec.type ?? '',
|
||||
description: template.metadata.description ?? '-',
|
||||
tags: (template.metadata?.tags as string[]) ?? [],
|
||||
links: template.metadata.links ?? [],
|
||||
};
|
||||
};
|
||||
|
||||
@@ -155,6 +173,7 @@ const DeprecationWarning = () => {
|
||||
};
|
||||
|
||||
export const TemplateCard = ({ template, deprecated }: TemplateCardProps) => {
|
||||
const app = useApp();
|
||||
const backstageTheme = useTheme<BackstageTheme>();
|
||||
const templateRoute = useRouteRef(selectedTemplateRouteRef);
|
||||
const templateProps = getTemplateCardProps(template);
|
||||
@@ -170,6 +189,9 @@ export const TemplateCard = ({ template, deprecated }: TemplateCardProps) => {
|
||||
const { name, namespace } = parseEntityRef(stringifyEntityRef(template));
|
||||
const href = templateRoute({ templateName: name, namespace });
|
||||
|
||||
const iconResolver = (key?: string): IconComponent =>
|
||||
key ? app.getSystemIcon(key) ?? LanguageIcon : LanguageIcon;
|
||||
|
||||
const scmIntegrationsApi = useApi(scmIntegrationsApiRef);
|
||||
const sourceLocation = getEntitySourceLocation(template, scmIntegrationsApi);
|
||||
|
||||
@@ -184,12 +206,17 @@ export const TemplateCard = ({ template, deprecated }: TemplateCardProps) => {
|
||||
classes={{ root: classes.title }}
|
||||
/>
|
||||
</CardMedia>
|
||||
<CardContent style={{ display: 'grid' }}>
|
||||
<CardContent
|
||||
style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}
|
||||
>
|
||||
<Box className={classes.box}>
|
||||
<Typography variant="body2" className={classes.label}>
|
||||
Description
|
||||
</Typography>
|
||||
<MarkdownContent content={templateProps.description} />
|
||||
<MarkdownContent
|
||||
className={classes.description}
|
||||
content={templateProps.description}
|
||||
/>
|
||||
</Box>
|
||||
<Box className={classes.box}>
|
||||
<Typography variant="body2" className={classes.label}>
|
||||
@@ -198,7 +225,11 @@ export const TemplateCard = ({ template, deprecated }: TemplateCardProps) => {
|
||||
<EntityRefLinks entityRefs={ownedByRelations} defaultKind="Group" />
|
||||
</Box>
|
||||
<Box>
|
||||
<Typography variant="body2" className={classes.label}>
|
||||
<Typography
|
||||
style={{ marginBottom: '4px' }}
|
||||
variant="body2"
|
||||
className={classes.label}
|
||||
>
|
||||
Tags
|
||||
</Typography>
|
||||
{templateProps.tags?.map(tag => (
|
||||
@@ -206,15 +237,37 @@ export const TemplateCard = ({ template, deprecated }: TemplateCardProps) => {
|
||||
))}
|
||||
</Box>
|
||||
</CardContent>
|
||||
<Typography
|
||||
variant="body2"
|
||||
className={[classes.label, classes.linksLabel].join(' ')}
|
||||
>
|
||||
Links
|
||||
</Typography>
|
||||
<CardActions>
|
||||
{sourceLocation && (
|
||||
<IconButton
|
||||
className={classes.leftButton}
|
||||
href={sourceLocation.locationTargetUrl}
|
||||
>
|
||||
<ScmIntegrationIcon type={sourceLocation.integrationType} />
|
||||
</IconButton>
|
||||
)}
|
||||
<div className={classes.leftButton}>
|
||||
{sourceLocation && (
|
||||
<Tooltip
|
||||
title={
|
||||
sourceLocation.integrationType ||
|
||||
sourceLocation.locationTargetUrl
|
||||
}
|
||||
>
|
||||
<IconButton
|
||||
className={classes.leftButton}
|
||||
href={sourceLocation.locationTargetUrl}
|
||||
>
|
||||
<ScmIntegrationIcon type={sourceLocation.integrationType} />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
{templateProps.links?.map((link, i) => (
|
||||
<Tooltip key={`${link.url}_${i}`} title={link.title || link.url}>
|
||||
<IconButton size="medium" href={link.url}>
|
||||
<MuiIcon icon={iconResolver(link.icon)} />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
))}
|
||||
</div>
|
||||
<Button
|
||||
color="primary"
|
||||
to={href}
|
||||
|
||||
Reference in New Issue
Block a user