@pagerduty/backstage-plugin
Version:
A Backstage plugin that integrates towards PagerDuty
223 lines (220 loc) • 9.07 kB
JavaScript
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
import { useState, useCallback } from 'react';
import { CardHeader, Accordion, AccordionSummary, AccordionDetails } from '@material-ui/core';
import { Card, Flex, Grid, Text } from '@backstage/ui';
import useAsync from 'react-use/lib/useAsync';
import { pagerDutyApiRef, UnauthorizedError } from '../../api/client.esm.js';
import { MissingTokenError } from '../Errors/MissingTokenError.esm.js';
import { ServiceNotFoundError } from '../Errors/ServiceNotFoundError.esm.js';
import PDGreenImage from '../../assets/PD-Green.svg';
import PDWhiteImage from '../../assets/PD-White.svg';
import { useApi } from '@backstage/core-plugin-api';
import { NotFoundError } from '@backstage/errors';
import { Progress, InfoCard } from '@backstage/core-components';
import { ForbiddenError } from '../Errors/ForbiddenError.esm.js';
import IncidentCounterCard from '../PagerDutyCardCommon/InsightsCard.esm.js';
import { OpenServiceButton } from '../PagerDutyCardCommon/OpenServiceButton.esm.js';
import ServiceStandardsCard from '../PagerDutyCardCommon/ServiceStandardsCard.esm.js';
import StatusCard from '../PagerDutyCardCommon/StatusCard.esm.js';
import { TriggerIncidentButton } from '../PagerDutyCardCommon/TriggerIncidentButton.esm.js';
import { makeStyles, useTheme, createStyles } from '@material-ui/core/styles';
import { EscalationPolicy } from '../Escalation/EscalationPolicy.esm.js';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
const useStyles = makeStyles(
(_) => createStyles({
subheaderTextStyle: {
fontSize: "10px",
paddingLeft: "5px",
paddingTop: "3px"
},
accordionStyle: {
background: "transparent"
},
gridRootStyle: {
width: "100%"
},
cardStyles: {
paddingLeft: "10px",
paddingRight: "10px"
}
})
);
const BasicCard = ({ children }) => /* @__PURE__ */ jsx(InfoCard, { title: "PagerDuty", children });
const PagerDutySmallCard = (props) => {
const classes = useStyles();
const theme = useTheme();
const { readOnly, disableInsights, disableOnCall } = props;
const api = useApi(pagerDutyApiRef);
const [refreshStatus, setRefreshStatus] = useState(false);
const handleRefresh = useCallback(() => {
setRefreshStatus((x) => !x);
}, []);
const {
value: service,
loading,
error
} = useAsync(async () => {
const { service: foundService } = await api.getServiceByPagerDutyEntity(
props
);
const serviceStandards = await api.getServiceStandardsByServiceId(
foundService.id,
props.account
);
const serviceMetrics = await api.getServiceMetricsByServiceId(
foundService.id,
props.account
);
const result = {
id: foundService.id,
name: foundService.name,
account: props.account,
url: foundService.html_url,
policyId: foundService.escalation_policy.id,
policyLink: foundService.escalation_policy.html_url,
policyName: foundService.escalation_policy.name,
status: foundService.status,
standards: serviceStandards !== void 0 ? serviceStandards.standards : void 0,
metrics: serviceMetrics !== void 0 ? serviceMetrics.metrics : void 0
};
return result;
}, [props]);
if (error) {
let errorNode;
switch (error.constructor) {
case UnauthorizedError:
errorNode = /* @__PURE__ */ jsx(MissingTokenError, {});
break;
case NotFoundError:
errorNode = /* @__PURE__ */ jsx(ServiceNotFoundError, {});
break;
default:
errorNode = /* @__PURE__ */ jsx(ForbiddenError, {});
}
return /* @__PURE__ */ jsx(BasicCard, { children: errorNode });
}
if (loading) {
return /* @__PURE__ */ jsx(BasicCard, { children: /* @__PURE__ */ jsx(Progress, {}) });
}
return /* @__PURE__ */ jsxs(Card, { "data-testid": "pagerduty-card", className: classes.cardStyles, children: [
/* @__PURE__ */ jsx(
CardHeader,
{
title: theme.palette.type === "dark" ? /* @__PURE__ */ jsx("img", { src: PDWhiteImage, alt: "PagerDuty", height: "25" }) : /* @__PURE__ */ jsx("img", { src: PDGreenImage, alt: "PagerDuty", height: "25" }),
action: !readOnly && props.integrationKey ? /* @__PURE__ */ jsxs(Flex, { children: [
/* @__PURE__ */ jsx(
TriggerIncidentButton,
{
compact: true,
"data-testid": "trigger-incident-button",
integrationKey: props.integrationKey,
entityName: props.name,
handleRefresh
}
),
/* @__PURE__ */ jsx(OpenServiceButton, { compact: true, serviceUrl: service.url })
] }) : /* @__PURE__ */ jsx(OpenServiceButton, { compact: true, serviceUrl: service.url })
}
),
/* @__PURE__ */ jsxs(Grid.Root, { columns: "2", gap: "1", pl: "1", pr: "1", children: [
/* @__PURE__ */ jsx(Grid.Item, { children: /* @__PURE__ */ jsx(Text, { weight: "bold", color: "secondary", children: "STATUS" }) }),
/* @__PURE__ */ jsx(Grid.Item, { children: /* @__PURE__ */ jsx(Text, { weight: "bold", color: "secondary", children: "STANDARDS" }) })
] }),
/* @__PURE__ */ jsxs(Grid.Root, { columns: "2", gap: "1", pl: "1", pr: "1", children: [
/* @__PURE__ */ jsx(Grid.Item, { children: /* @__PURE__ */ jsx(
StatusCard,
{
compact: true,
serviceId: service.id,
refreshStatus,
account: service.account
}
) }),
/* @__PURE__ */ jsx(Grid.Item, { children: /* @__PURE__ */ jsx(
ServiceStandardsCard,
{
compact: true,
total: service?.standards?.score !== void 0 ? service?.standards?.score?.total : void 0,
completed: service?.standards?.score !== void 0 ? service?.standards?.score?.passing : void 0,
standards: service?.standards !== void 0 ? service?.standards?.standards : void 0
}
) })
] }),
disableInsights !== true ? /* @__PURE__ */ jsxs(Accordion, { className: classes.accordionStyle, children: [
/* @__PURE__ */ jsxs(
AccordionSummary,
{
expandIcon: /* @__PURE__ */ jsx(ExpandMoreIcon, {}),
"aria-controls": "panel1a-content",
id: "panel1a-header",
children: [
/* @__PURE__ */ jsx(Text, { weight: "bold", color: "secondary", children: "INSIGHTS" }),
/* @__PURE__ */ jsx(Text, { weight: "bold", color: "secondary", className: classes.subheaderTextStyle, children: "(last 30 days)" })
]
}
),
/* @__PURE__ */ jsx(AccordionDetails, { children: /* @__PURE__ */ jsxs(
Grid.Root,
{
columns: "3",
gap: "1",
pl: "1",
pr: "1",
className: classes.gridRootStyle,
children: [
/* @__PURE__ */ jsx(Grid.Item, { children: /* @__PURE__ */ jsx(
IncidentCounterCard,
{
compact: true,
count: service?.metrics !== void 0 && service.metrics.length > 0 ? service?.metrics[0].total_interruptions : void 0,
label: "interruptions",
color: theme.palette.textSubtle
}
) }),
/* @__PURE__ */ jsx(Grid.Item, { children: /* @__PURE__ */ jsx(
IncidentCounterCard,
{
compact: true,
count: service?.metrics !== void 0 && service.metrics.length > 0 ? service?.metrics[0].total_high_urgency_incidents : void 0,
label: "high urgency",
color: theme.palette.warning.main
}
) }),
/* @__PURE__ */ jsx(Grid.Item, { children: /* @__PURE__ */ jsx(
IncidentCounterCard,
{
compact: true,
count: service?.metrics !== void 0 && service?.metrics?.length > 0 ? service?.metrics[0].total_incident_count : void 0,
label: "incidents",
color: theme.palette.error.main
}
) })
]
}
) })
] }) : /* @__PURE__ */ jsx(Fragment, {}),
disableOnCall !== true ? /* @__PURE__ */ jsxs(Accordion, { className: classes.accordionStyle, children: [
/* @__PURE__ */ jsx(
AccordionSummary,
{
expandIcon: /* @__PURE__ */ jsx(ExpandMoreIcon, {}),
"aria-controls": "panel1a-content",
id: "panel1a-header",
children: /* @__PURE__ */ jsx(Text, { weight: "bold", color: "secondary", children: "ON CALL" })
}
),
/* @__PURE__ */ jsx(AccordionDetails, { children: /* @__PURE__ */ jsx(
EscalationPolicy,
{
"data-testid": "oncall-card",
policyId: service.policyId,
policyUrl: service.policyLink,
policyName: service.policyName,
account: service.account
}
) })
] }) : /* @__PURE__ */ jsx(Fragment, {})
] });
};
export { PagerDutySmallCard };
//# sourceMappingURL=index.esm.js.map