change UI bsed on UX

This commit is contained in:
Samira Mokaram
2020-11-11 14:24:40 +01:00
parent f7614ee6fc
commit 2aed296e45
8 changed files with 217 additions and 40 deletions
@@ -29,8 +29,8 @@ import {
import UserIcon from '@material-ui/icons/Person';
import EmailIcon from '@material-ui/icons/Email';
import { StatusWarning } from '@backstage/core';
import Pagerduty from '../assets/pd.svg';
import { Oncall, PagerDutyEscalationPolicy } from './types';
import { Oncall } from './types';
import PagerdutyIcon from './Pd';
const useStyles = makeStyles({
denseListIcon: {
@@ -45,7 +45,7 @@ const useStyles = makeStyles({
},
});
const EscalationUser = ({ user }: PagerDutyEscalationPolicy) => {
const EscalationUser = ({ user }: Oncall) => {
const classes = useStyles();
return (
<ListItem>
@@ -56,7 +56,7 @@ const EscalationUser = ({ user }: PagerDutyEscalationPolicy) => {
<ListItemSecondaryAction>
<Tooltip title="Send e-mail to user" placement="left">
<IconButton href={`mailto:${user.email}`}>
<EmailIcon />
<EmailIcon color="primary" />
</IconButton>
</Tooltip>
<Tooltip title="View in PagerDuty" placement="left">
@@ -64,12 +64,9 @@ const EscalationUser = ({ user }: PagerDutyEscalationPolicy) => {
href={user.html_url}
target="_blank"
rel="noopener noreferrer"
color="primary"
>
<img
src={Pagerduty}
alt="View in PagerDuty"
className={classes.svgButtonImage}
/>
<PagerdutyIcon viewBox="0 0 100 100" />
</IconButton>
</Tooltip>
</ListItemSecondaryAction>
@@ -25,11 +25,12 @@ import {
makeStyles,
IconButton,
ListSubheader,
Link,
} from '@material-ui/core';
import { StatusError, StatusWarning, StatusOK } from '@backstage/core';
import Pagerduty from '../assets/pd.svg';
import moment from 'moment';
import { Incident } from '../components/types';
import PagerdutyIcon from './Pd';
const useStyles = makeStyles({
denseListIcon: {
@@ -64,6 +65,7 @@ type IncidentListItemProps = {
const IncidentListItem = ({ incident }: IncidentListItemProps) => {
const classes = useStyles();
const user = incident.assignments[0].assignee;
return (
<ListItem key={incident.id}>
<ListItemIcon>
@@ -82,8 +84,9 @@ const IncidentListItem = ({ incident }: IncidentListItemProps) => {
secondary={
<span style={{ wordBreak: 'break-all', whiteSpace: 'normal' }}>
Created {moment(incident.created_at).fromNow()}, assigned to{' '}
{(incident?.assignments[0]?.assignee?.summary &&
incident.assignments[0].assignee.summary) ||
{(incident?.assignments[0]?.assignee?.summary && (
<Link href={`mailto:${user.email}`}>{user.summary}</Link>
)) ||
'nobody'}
</span>
}
@@ -91,15 +94,12 @@ const IncidentListItem = ({ incident }: IncidentListItemProps) => {
<ListItemSecondaryAction>
<Tooltip title="View in PagerDuty" placement="left">
<IconButton
href={incident.homepageUrl}
href={user.html_url}
target="_blank"
rel="noopener noreferrer"
color="primary"
>
<img
src={Pagerduty}
alt="View in PagerDuty"
className={classes.svgButtonImage}
/>
<PagerdutyIcon viewBox="0 0 100 100" />
</IconButton>
</Tooltip>
</ListItemSecondaryAction>
@@ -14,15 +14,16 @@
* limitations under the License.
*/
import React from 'react';
import { InfoCard, useApi } from '@backstage/core';
import { useApi } from '@backstage/core';
import { Entity } from '@backstage/catalog-model';
import { Grid, LinearProgress } from '@material-ui/core';
import { LinearProgress } from '@material-ui/core';
import { Incidents } from './Incidents';
import { EscalationPolicy } from './Escalation';
import { TriggerButton } from './TriggerButton';
import { useAsync } from 'react-use';
import { Alert } from '@material-ui/lab';
import { pagerDutyApiRef } from '../api/pagerDutyClient';
import { PagerdutyCard } from './PagerdutyCard';
export const PAGERDUTY_INTEGRATION_KEY = 'pagerduty.com/integration-key';
@@ -71,19 +72,26 @@ export const PagerDutyServiceCard = ({ entity }: Props) => {
return <LinearProgress />;
}
const link = {
const pagerdutyLink = {
title: 'View in PagerDuty',
link: value!.homepageUrl,
href: value!.homepageUrl,
};
const triggerAlarm = {
title: 'Trigger Alarm',
action: <TriggerButton entity={entity} />,
};
return (
<InfoCard title="PagerDuty" deepLink={link}>
<Incidents incidents={value!.incidents} />
<EscalationPolicy escalation={value!.oncalls} />
<Grid container item xs={12} justify="flex-end">
<TriggerButton entity={entity} />
</Grid>
{/* todo show something when we dont have token */}
</InfoCard>
<PagerdutyCard
title="Pagerduty"
subheader={{ ViewPagerduty: pagerdutyLink, TriggerAlarm: triggerAlarm }}
content={
<>
<Incidents incidents={value!.incidents} />
<EscalationPolicy escalation={value!.oncalls} />
</>
}
></PagerdutyCard>
);
};
@@ -0,0 +1,132 @@
import React from 'react';
import {
Card,
CardHeader,
CardContent,
Divider,
Link,
makeStyles,
} from '@material-ui/core';
import LinkIcon from '@material-ui/icons/Link';
import ReportProblemIcon from '@material-ui/icons/ReportProblem';
import classnames from 'classnames';
import Pagerduty from '../assets/pd.svg';
import PagerdutyIcon from './Pd';
// TODO: create a general component to use it in pagerduty and aboutCard
const useStyles = makeStyles(theme => ({
links: {
margin: theme.spacing(2, 0),
display: 'grid',
gridAutoFlow: 'column',
gridAutoColumns: 'min-content',
gridGap: theme.spacing(3),
},
link: {
display: 'grid',
justifyItems: 'center',
gridGap: 4,
textAlign: 'center',
},
label: {
fontSize: '0.7rem',
textTransform: 'uppercase',
fontWeight: 600,
letterSpacing: 1.2,
},
trigger: {
color: theme.palette.secondary.main,
},
svgButtonImage: {
height: '1.5em',
color: theme.palette.primary.main,
},
}));
type SubHeaderProps = {
ViewPagerduty: { title: string; href: string };
TriggerAlarm: { title: string; action: React.ReactNode };
};
type PagerdutyCardProps = {
title: string;
subheader: SubHeaderProps;
content: React.ReactNode;
};
type VerticalIconProps = {
label: string;
href?: string;
action?: React.ReactNode;
icon?: React.ReactNode;
};
const VerticalIcon = ({
label,
href,
icon = <LinkIcon />,
action,
}: VerticalIconProps) => {
const classes = useStyles();
if (action) {
return (
<>
<Link className={classnames(classes.link, classes.trigger)} href={href}>
{icon}
{action}
</Link>
</>
);
}
return (
<>
<Link className={classes.link} href={href}>
{icon}
<span className={classes.label}>{label}</span>
</Link>
</>
);
};
export const PagerdutyCard = ({
title,
subheader,
content,
}: PagerdutyCardProps) => {
const classes = useStyles();
const getSubheader = ({ ViewPagerduty, TriggerAlarm }: SubHeaderProps) => {
return (
<nav className={classes.links}>
<VerticalIcon
label={ViewPagerduty.title}
href={ViewPagerduty.href}
icon={
// <LinkIcon />
// <img
// src={Pagerduty}
// alt="View in PagerDuty"
// className={classes.svgButtonImage}
// />
<PagerdutyIcon viewBox="0 0 100 100" />
}
></VerticalIcon>
<VerticalIcon
label={TriggerAlarm.title}
icon={<ReportProblemIcon />}
action={TriggerAlarm.action}
></VerticalIcon>
</nav>
);
};
return (
<Card>
<CardHeader
title={title}
subheader={getSubheader(subheader)}
></CardHeader>
<Divider />
<CardContent>{content}</CardContent>
</Card>
);
};
+27
View File
@@ -0,0 +1,27 @@
// import React from 'react';
// import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon';
// const SvgPd = (props: SvgIconProps) =>
// React.createElement(
// SvgIcon,
// props,
// <g fill="#7A7A7A" fillRule="nonzero">
// <path d="M10.442 84.98H0V32.57c0-5.381 2.209-8.634 4.056-10.442 4.097-4.016 9.639-4.136 10.562-4.136h16.426c5.863 0 9.237 2.37 11.084 4.377 3.655 3.976 3.695 9.117 3.615 10.482v19.76c0 5.702-2.33 9.075-4.257 10.883-3.976 3.734-9.237 3.815-10.482 3.775H10.442v17.71zm20.963-28.193c.563 0 2.129-.16 2.972-.964.643-.602.964-1.687.964-3.253V32.289c0-.562-.12-2.048-.924-2.892-.763-.803-2.249-.963-3.373-.963H14.538c-4.096 0-4.096 3.092-4.096 4.136v24.217h20.963zM89.236.2h10.442v52.45c0 5.382-2.209 8.635-4.056 10.442-4.097 4.016-9.639 4.136-10.562 4.136H68.634c-5.863 0-9.237-2.369-11.084-4.377-3.655-3.976-3.695-9.116-3.615-10.482V32.65c0-5.702 2.33-9.076 4.257-10.883 3.976-3.735 9.237-3.815 10.482-3.775h20.562V.2zM68.273 28.435c-.563 0-2.129.16-2.972.963-.643.603-.964 1.687-.964 3.253v20.281c0 .563.12 2.049.924 2.892.763.803 2.249.964 3.373.964H85.14c4.137-.04 4.137-3.133 4.137-4.177V28.434H68.273z" />
// </g>,
// );
// export default SvgPd;
import React from 'react';
import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon';
const SvgPd = (props: SvgIconProps) =>
React.createElement(
SvgIcon,
props,
<g fillRule="nonzero">
<path d="M10.442 84.98H0V32.57c0-5.381 2.209-8.634 4.056-10.442 4.097-4.016 9.639-4.136 10.562-4.136h16.426c5.863 0 9.237 2.37 11.084 4.377 3.655 3.976 3.695 9.117 3.615 10.482v19.76c0 5.702-2.33 9.075-4.257 10.883-3.976 3.734-9.237 3.815-10.482 3.775H10.442v17.71zm20.963-28.193c.563 0 2.129-.16 2.972-.964.643-.602.964-1.687.964-3.253V32.289c0-.562-.12-2.048-.924-2.892-.763-.803-2.249-.963-3.373-.963H14.538c-4.096 0-4.096 3.092-4.096 4.136v24.217h20.963zM89.236.2h10.442v52.45c0 5.382-2.209 8.635-4.056 10.442-4.097 4.016-9.639 4.136-10.562 4.136H68.634c-5.863 0-9.237-2.369-11.084-4.377-3.655-3.976-3.695-9.116-3.615-10.482V32.65c0-5.702 2.33-9.076 4.257-10.883 3.976-3.735 9.237-3.815 10.482-3.775h20.562V.2zM68.273 28.435c-.563 0-2.129.16-2.972.963-.643.603-.964 1.687-.964 3.253v20.281c0 .563.12 2.049.924 2.892.763.803 2.249.964 3.373.964H85.14c4.137-.04 4.137-3.133 4.137-4.177V28.434H68.273z" />
</g>,
);
export default SvgPd;
@@ -15,17 +15,34 @@
*/
import React, { useState } from 'react';
import { Button } from '@material-ui/core';
import { Button, makeStyles } from '@material-ui/core';
import { TriggerDialog } from './TriggerDialog';
import { Entity } from '@backstage/catalog-model';
import { PAGERDUTY_INTEGRATION_KEY } from './PagerDutyServiceCard';
const useStyles = makeStyles({
triggerAlarm: {
paddingTop: 0,
paddingBottom: 0,
fontSize: '0.7rem',
textTransform: 'uppercase',
fontWeight: 600,
letterSpacing: 1.2,
lineHeight: 1.1,
'&:hover, &:focus, &.focus': {
backgroundColor: 'transparent',
textDecoration: 'none',
},
},
});
type Props = {
entity: Entity;
};
export const TriggerButton = ({ entity }: Props) => {
const [showDialog, setShowDialog] = useState<boolean>(false);
const classes = useStyles();
const handleDialog = () => {
setShowDialog(!showDialog);
@@ -34,12 +51,11 @@ export const TriggerButton = ({ entity }: Props) => {
return (
<>
<Button
size="small"
variant="contained"
color="secondary"
onClick={handleDialog}
className={classes.triggerAlarm}
>
Trigger alarm
Trigger Alarm
</Button>
{showDialog && (
<TriggerDialog
@@ -103,6 +103,7 @@ export const TriggerDialog = ({ name, integrationKey, onClose }: Props) => {
the issue and reach out to you if necessary.
</p>
<TextField
inputProps={{ 'data-testid': 'trigger-input' }}
id="description"
multiline
fullWidth
@@ -114,6 +115,7 @@ export const TriggerDialog = ({ name, integrationKey, onClose }: Props) => {
</DialogContent>
<DialogActions>
<Button
data-testid="trigger-button"
id="trigger"
color="secondary"
disabled={!description || loading}
+1 -6
View File
@@ -32,7 +32,7 @@ export type Service = {
name: string;
html_url: string;
integrationKey: string;
escalation_policy: PagerDutyEscalationPolicy;
escalation_policy: Oncall;
};
export type ResponseService = {
@@ -69,10 +69,6 @@ export type OncallsResponse = {
oncalls: Oncall[];
};
export type PagerDutyEscalationPolicy = {
user: User;
};
export type User = {
id: string;
summary: string;
@@ -82,6 +78,5 @@ export type User = {
};
export type Oncall = {
escalation_policy: PagerDutyEscalationPolicy;
user: User;
};