@pagerduty/backstage-plugin 0.12.0-next.9 → 0.12.1-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/dist/esm/index-90403557.esm.js +121 -0
- package/dist/esm/index-90403557.esm.js.map +1 -0
- package/dist/esm/{index-a26fa046.esm.js → index-a4100303.esm.js} +9 -8
- package/dist/esm/{index-a26fa046.esm.js.map → index-a4100303.esm.js.map} +1 -1
- package/dist/esm/{index-b957ec97.esm.js → index-d9b5aaee.esm.js} +574 -314
- package/dist/esm/index-d9b5aaee.esm.js.map +1 -0
- package/dist/index.d.ts +19 -2
- package/dist/index.esm.js +8 -7
- package/dist/index.esm.js.map +1 -1
- package/package.json +5 -5
- package/dist/esm/index-b957ec97.esm.js.map +0 -1
- package/dist/esm/index-d9f825b5.esm.js +0 -231
- package/dist/esm/index-d9f825b5.esm.js.map +0 -1
|
@@ -3,7 +3,7 @@ import { NotFoundError } from '@backstage/errors';
|
|
|
3
3
|
import { createCardExtension } from '@backstage/plugin-home-react';
|
|
4
4
|
import React, { useEffect, useState, useCallback } from 'react';
|
|
5
5
|
import { useEntity } from '@backstage/plugin-catalog-react';
|
|
6
|
-
import { makeStyles, ListItem, ListItemText, Chip, Typography, ListItemSecondaryAction, Tooltip, IconButton, Grid, List, ListItemIcon, ListSubheader, Button, Dialog, DialogTitle, DialogContent, TextField, DialogActions, CircularProgress,
|
|
6
|
+
import { makeStyles, ListItem, ListItemText, Chip, Typography, ListItemSecondaryAction, Tooltip, IconButton, Grid, List, ListItemIcon, createStyles, ListSubheader, Button, Card, withStyles, LinearProgress, Dialog, DialogTitle, DialogContent, TextField, DialogActions, CircularProgress, CardHeader, Divider, CardContent, Accordion, AccordionSummary, AccordionDetails } from '@material-ui/core';
|
|
7
7
|
import { DateTime, Duration } from 'luxon';
|
|
8
8
|
import OpenInBrowserIcon from '@material-ui/icons/OpenInBrowser';
|
|
9
9
|
import { Link, Progress, StatusWarning, StatusError, EmptyState, TabbedCard, CardTab, InfoCard } from '@backstage/core-components';
|
|
@@ -17,15 +17,16 @@ import useAsync from 'react-use/lib/useAsync';
|
|
|
17
17
|
import LinkIcon from '@material-ui/icons/Link';
|
|
18
18
|
import PDGreenImage from '../assets/PD-Green.svg';
|
|
19
19
|
import PDWhiteImage from '../assets/PD-White.svg';
|
|
20
|
-
import
|
|
21
|
-
import AddAlert from '@material-ui/icons/AddAlert';
|
|
22
|
-
import { makeStyles as makeStyles$1, createStyles, useTheme } from '@material-ui/core/styles';
|
|
23
|
-
import { useAsyncFn as useAsyncFn$1 } from 'react-use';
|
|
24
|
-
import Alert$1 from '@material-ui/lab/Alert/Alert';
|
|
20
|
+
import validateColor from 'validate-color';
|
|
25
21
|
import InfoIcon from '@material-ui/icons/Info';
|
|
26
22
|
import CheckCircle from '@material-ui/icons/CheckCircle';
|
|
27
23
|
import RadioButtonUncheckedIcon from '@material-ui/icons/RadioButtonUnchecked';
|
|
28
|
-
import
|
|
24
|
+
import { makeStyles as makeStyles$1, createStyles as createStyles$1, useTheme } from '@material-ui/core/styles';
|
|
25
|
+
import { useAsyncFn as useAsyncFn$1 } from 'react-use';
|
|
26
|
+
import Alert$1 from '@material-ui/lab/Alert/Alert';
|
|
27
|
+
import { parseEntityRef, DEFAULT_NAMESPACE } from '@backstage/catalog-model';
|
|
28
|
+
import AddAlert from '@material-ui/icons/AddAlert';
|
|
29
|
+
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
|
|
29
30
|
|
|
30
31
|
const PAGERDUTY_INTEGRATION_KEY = "pagerduty.com/integration-key";
|
|
31
32
|
const PAGERDUTY_SERVICE_ID = "pagerduty.com/service-id";
|
|
@@ -82,6 +83,12 @@ class PagerDutyClient {
|
|
|
82
83
|
}
|
|
83
84
|
return response;
|
|
84
85
|
}
|
|
86
|
+
async getAllServices() {
|
|
87
|
+
const url = `${await this.config.discoveryApi.getBaseUrl(
|
|
88
|
+
"pagerduty"
|
|
89
|
+
)}/services`;
|
|
90
|
+
return await this.findByUrl(url);
|
|
91
|
+
}
|
|
85
92
|
async getServiceByEntity(entity) {
|
|
86
93
|
return await this.getServiceByPagerDutyEntity(getPagerDutyEntity(entity));
|
|
87
94
|
}
|
|
@@ -204,7 +211,7 @@ const pagerDutyPlugin = createPlugin({
|
|
|
204
211
|
const PagerDutyPage = pagerDutyPlugin.provide(
|
|
205
212
|
createRoutableExtension({
|
|
206
213
|
name: "PagerDutyPage",
|
|
207
|
-
component: () => import('./index-
|
|
214
|
+
component: () => import('./index-90403557.esm.js').then((m) => m.PagerDutyPage),
|
|
208
215
|
mountPoint: rootRouteRef
|
|
209
216
|
})
|
|
210
217
|
);
|
|
@@ -212,17 +219,27 @@ const EntityPagerDutyCard$1 = pagerDutyPlugin.provide(
|
|
|
212
219
|
createComponentExtension({
|
|
213
220
|
name: "EntityPagerDutyCard",
|
|
214
221
|
component: {
|
|
215
|
-
lazy: () => Promise.resolve().then(function () { return index; }).then(
|
|
222
|
+
lazy: () => Promise.resolve().then(function () { return index$1; }).then(
|
|
216
223
|
(m) => m.EntityPagerDutyCard
|
|
217
224
|
)
|
|
218
225
|
}
|
|
219
226
|
})
|
|
220
227
|
);
|
|
228
|
+
const EntityPagerDutySmallCard$1 = pagerDutyPlugin.provide(
|
|
229
|
+
createComponentExtension({
|
|
230
|
+
name: "EntityPagerDutySmallCard",
|
|
231
|
+
component: {
|
|
232
|
+
lazy: () => Promise.resolve().then(function () { return index; }).then(
|
|
233
|
+
(m) => m.EntityPagerDutySmallCard
|
|
234
|
+
)
|
|
235
|
+
}
|
|
236
|
+
})
|
|
237
|
+
);
|
|
221
238
|
const HomePagePagerDutyCard = pagerDutyPlugin.provide(
|
|
222
239
|
createCardExtension({
|
|
223
240
|
name: "HomePagePagerDutyCard",
|
|
224
241
|
title: "PagerDuty Homepage Card",
|
|
225
|
-
components: () => import('./index-
|
|
242
|
+
components: () => import('./index-a4100303.esm.js'),
|
|
226
243
|
settings: {
|
|
227
244
|
schema: {
|
|
228
245
|
title: "PagerDuty",
|
|
@@ -459,6 +476,17 @@ const useStyles$5 = makeStyles((theme) => ({
|
|
|
459
476
|
textDecoration: "underline"
|
|
460
477
|
}
|
|
461
478
|
},
|
|
479
|
+
userTextButtonStyle: {
|
|
480
|
+
marginLeft: "-11px",
|
|
481
|
+
marginTop: "-10px",
|
|
482
|
+
marginBottom: "-10px",
|
|
483
|
+
fontSize: "15px",
|
|
484
|
+
color: theme.palette.text.primary,
|
|
485
|
+
"&:hover": {
|
|
486
|
+
backgroundColor: "transparent",
|
|
487
|
+
textDecoration: "underline"
|
|
488
|
+
}
|
|
489
|
+
},
|
|
462
490
|
containerStyle: {
|
|
463
491
|
display: "flex",
|
|
464
492
|
alignItems: "center",
|
|
@@ -476,15 +504,30 @@ const useStyles$5 = makeStyles((theme) => ({
|
|
|
476
504
|
marginTop: "-20px"
|
|
477
505
|
}
|
|
478
506
|
}));
|
|
479
|
-
function
|
|
507
|
+
function navigateToUrl(url) {
|
|
480
508
|
window.open(url, "_blank");
|
|
481
509
|
}
|
|
482
510
|
const EscalationUser = ({ user, policyUrl, policyName }) => {
|
|
483
511
|
const classes = useStyles$5();
|
|
484
|
-
return /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(ListItemIcon, null, /* @__PURE__ */ React.createElement(
|
|
512
|
+
return /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(ListItemIcon, null, /* @__PURE__ */ React.createElement(
|
|
513
|
+
Avatar,
|
|
514
|
+
{
|
|
515
|
+
alt: user.name,
|
|
516
|
+
src: user.avatar_url,
|
|
517
|
+
className: classes.avatarStyle
|
|
518
|
+
}
|
|
519
|
+
)), /* @__PURE__ */ React.createElement(
|
|
485
520
|
ListItemText,
|
|
486
521
|
{
|
|
487
|
-
primary: /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
522
|
+
primary: /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Tooltip, { title: "Open user in PagerDuty", placement: "top" }, /* @__PURE__ */ React.createElement(
|
|
523
|
+
IconButton,
|
|
524
|
+
{
|
|
525
|
+
"aria-label": "open-user-in-browser",
|
|
526
|
+
onClick: () => navigateToUrl(user.html_url),
|
|
527
|
+
className: classes.userTextButtonStyle
|
|
528
|
+
},
|
|
529
|
+
/* @__PURE__ */ React.createElement("span", { className: classes.containerStyle }, user.name)
|
|
530
|
+
)), /* @__PURE__ */ React.createElement(
|
|
488
531
|
Typography,
|
|
489
532
|
{
|
|
490
533
|
className: classes.listItemSecondary,
|
|
@@ -495,31 +538,30 @@ const EscalationUser = ({ user, policyUrl, policyName }) => {
|
|
|
495
538
|
secondary: /* @__PURE__ */ React.createElement(
|
|
496
539
|
IconButton,
|
|
497
540
|
{
|
|
498
|
-
"aria-label": "open-
|
|
499
|
-
onClick: () =>
|
|
541
|
+
"aria-label": "open-escalation-policy-in-browser",
|
|
542
|
+
onClick: () => navigateToUrl(policyUrl),
|
|
500
543
|
className: classes.buttonStyle
|
|
501
544
|
},
|
|
502
545
|
/* @__PURE__ */ React.createElement("span", { className: classes.containerStyle }, /* @__PURE__ */ React.createElement(NotificationsIcon, { className: classes.iconStyle }), policyName)
|
|
503
546
|
)
|
|
504
547
|
}
|
|
505
|
-
)
|
|
506
|
-
IconButton,
|
|
507
|
-
{
|
|
508
|
-
href: user.html_url,
|
|
509
|
-
target: "_blank",
|
|
510
|
-
rel: "noopener noreferrer",
|
|
511
|
-
className: classes.smallIconStyle
|
|
512
|
-
},
|
|
513
|
-
/* @__PURE__ */ React.createElement(OpenInBrowserIcon, null)
|
|
514
|
-
))));
|
|
548
|
+
));
|
|
515
549
|
};
|
|
516
550
|
|
|
551
|
+
const useStyles$4 = makeStyles(
|
|
552
|
+
() => createStyles({
|
|
553
|
+
listStyle: {
|
|
554
|
+
marginLeft: "-15px"
|
|
555
|
+
}
|
|
556
|
+
})
|
|
557
|
+
);
|
|
517
558
|
const EscalationPolicy = ({
|
|
518
559
|
policyId,
|
|
519
560
|
policyUrl,
|
|
520
561
|
policyName
|
|
521
562
|
}) => {
|
|
522
563
|
const api = useApi(pagerDutyApiRef);
|
|
564
|
+
const classes = useStyles$4();
|
|
523
565
|
const {
|
|
524
566
|
value: users,
|
|
525
567
|
loading,
|
|
@@ -543,8 +585,7 @@ const EscalationPolicy = ({
|
|
|
543
585
|
List,
|
|
544
586
|
{
|
|
545
587
|
dense: true,
|
|
546
|
-
|
|
547
|
-
style: { marginLeft: "-15px" }
|
|
588
|
+
className: classes.listStyle
|
|
548
589
|
},
|
|
549
590
|
users.map((user, index) => /* @__PURE__ */ React.createElement(
|
|
550
591
|
EscalationUser,
|
|
@@ -594,7 +635,7 @@ const ServiceNotFoundError = () => /* @__PURE__ */ React.createElement(
|
|
|
594
635
|
}
|
|
595
636
|
);
|
|
596
637
|
|
|
597
|
-
const useStyles$
|
|
638
|
+
const useStyles$3 = makeStyles((theme) => ({
|
|
598
639
|
denseListIcon: {
|
|
599
640
|
marginRight: 0,
|
|
600
641
|
display: "flex",
|
|
@@ -618,7 +659,7 @@ const useStyles$4 = makeStyles((theme) => ({
|
|
|
618
659
|
}
|
|
619
660
|
}));
|
|
620
661
|
const ChangeEventListItem = ({ changeEvent }) => {
|
|
621
|
-
const classes = useStyles$
|
|
662
|
+
const classes = useStyles$3();
|
|
622
663
|
const duration = (/* @__PURE__ */ new Date()).getTime() - new Date(changeEvent.timestamp).getTime();
|
|
623
664
|
const changedAt = DateTime.local().minus(Duration.fromMillis(duration)).toRelative({ locale: "en" });
|
|
624
665
|
let externalLinkElem;
|
|
@@ -727,166 +768,59 @@ const ForbiddenError = () => /* @__PURE__ */ React.createElement(
|
|
|
727
768
|
}
|
|
728
769
|
);
|
|
729
770
|
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
const [description, setDescription] = useState("");
|
|
741
|
-
const [{ value, loading, error }, handleTriggerAlarm] = useAsyncFn(
|
|
742
|
-
async (descriptions) => {
|
|
743
|
-
const { userEntityRef } = await identityApi.getBackstageIdentity();
|
|
744
|
-
const { name: userName } = parseEntityRef(userEntityRef, {
|
|
745
|
-
defaultKind: "User",
|
|
746
|
-
defaultNamespace: DEFAULT_NAMESPACE
|
|
747
|
-
});
|
|
748
|
-
return await api.triggerAlarm({
|
|
749
|
-
integrationKey,
|
|
750
|
-
source: window.location.toString(),
|
|
751
|
-
description: descriptions,
|
|
752
|
-
userName
|
|
753
|
-
});
|
|
754
|
-
}
|
|
755
|
-
);
|
|
756
|
-
const descriptionChanged = (event) => {
|
|
757
|
-
setDescription(event.target.value);
|
|
758
|
-
};
|
|
759
|
-
useEffect(() => {
|
|
760
|
-
if (value) {
|
|
761
|
-
(async () => {
|
|
762
|
-
alertApi.post({
|
|
763
|
-
message: `Alarm successfully triggered`
|
|
764
|
-
});
|
|
765
|
-
handleDialog();
|
|
766
|
-
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
767
|
-
onIncidentCreated == null ? void 0 : onIncidentCreated();
|
|
768
|
-
})();
|
|
769
|
-
}
|
|
770
|
-
}, [value, alertApi, handleDialog, onIncidentCreated]);
|
|
771
|
-
if (error) {
|
|
772
|
-
alertApi.post({
|
|
773
|
-
message: `Failed to trigger alarm. ${error.message}`,
|
|
774
|
-
severity: "error"
|
|
775
|
-
});
|
|
776
|
-
}
|
|
777
|
-
return /* @__PURE__ */ React.createElement(Dialog, { maxWidth: "md", open: showDialog, onClose: handleDialog, fullWidth: true }, /* @__PURE__ */ React.createElement(DialogTitle, null, "This action will trigger an incident for ", /* @__PURE__ */ React.createElement("strong", null, '"', serviceName, '"'), "."), /* @__PURE__ */ React.createElement(DialogContent, null, /* @__PURE__ */ React.createElement(Alert, { severity: "info" }, /* @__PURE__ */ React.createElement(Typography, { variant: "body1", align: "justify" }, `If the issue you are seeing does not need urgent attention, please get in touch with the responsible team using their preferred communications channel. You can find information about the owner of this entity in the "About" card. If the issue is urgent, please don't hesitate to trigger the alert.`)), /* @__PURE__ */ React.createElement(
|
|
778
|
-
Typography,
|
|
779
|
-
{
|
|
780
|
-
variant: "body1",
|
|
781
|
-
style: { marginTop: "1em" },
|
|
782
|
-
gutterBottom: true,
|
|
783
|
-
align: "justify"
|
|
784
|
-
},
|
|
785
|
-
"Please describe the problem you want to report. Be as descriptive as possible. Your signed in user and a reference to the current page will automatically be amended to the alarm so that the receiver can reach out to you if necessary."
|
|
786
|
-
), /* @__PURE__ */ React.createElement(
|
|
787
|
-
TextField,
|
|
788
|
-
{
|
|
789
|
-
inputProps: { "data-testid": "trigger-input" },
|
|
790
|
-
id: "description",
|
|
791
|
-
multiline: true,
|
|
792
|
-
fullWidth: true,
|
|
793
|
-
minRows: 4,
|
|
794
|
-
margin: "normal",
|
|
795
|
-
label: "Problem description",
|
|
796
|
-
variant: "outlined",
|
|
797
|
-
onChange: descriptionChanged
|
|
798
|
-
}
|
|
799
|
-
)), /* @__PURE__ */ React.createElement(DialogActions, null, /* @__PURE__ */ React.createElement(
|
|
800
|
-
Button,
|
|
801
|
-
{
|
|
802
|
-
"data-testid": "trigger-button",
|
|
803
|
-
id: "trigger",
|
|
804
|
-
color: "secondary",
|
|
805
|
-
disabled: !description || loading,
|
|
806
|
-
variant: "contained",
|
|
807
|
-
onClick: () => handleTriggerAlarm(description),
|
|
808
|
-
endIcon: loading && /* @__PURE__ */ React.createElement(CircularProgress, { size: 16 })
|
|
771
|
+
function IncidentCounterCard({ count, label, color, compact }) {
|
|
772
|
+
const textColor = color && validateColor(color) ? color : "black";
|
|
773
|
+
const useStyles = makeStyles(() => ({
|
|
774
|
+
cardStyle: {
|
|
775
|
+
marginRight: "10px",
|
|
776
|
+
height: compact !== true ? "120px" : "80px",
|
|
777
|
+
display: "flex",
|
|
778
|
+
alignItems: "center",
|
|
779
|
+
justifyContent: "center",
|
|
780
|
+
backgroundColor: "rgba(0, 0, 0, 0.03)"
|
|
809
781
|
},
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
const useStyles$3 = makeStyles((theme) => ({
|
|
815
|
-
buttonStyle: {
|
|
816
|
-
color: theme.palette.text.primary,
|
|
817
|
-
"&:hover": {
|
|
818
|
-
backgroundColor: "transparent",
|
|
819
|
-
textDecoration: "underline"
|
|
820
|
-
}
|
|
821
|
-
},
|
|
822
|
-
containerStyle: {
|
|
823
|
-
fontSize: "12px",
|
|
824
|
-
width: "80px",
|
|
825
|
-
marginRight: "-10px"
|
|
826
|
-
},
|
|
827
|
-
iconStyle: {
|
|
828
|
-
fontSize: "30px",
|
|
829
|
-
marginBottom: "-10px"
|
|
830
|
-
},
|
|
831
|
-
textStyle: {
|
|
832
|
-
marginBottom: "-10px"
|
|
833
|
-
}
|
|
834
|
-
}));
|
|
835
|
-
function TriggerIncidentButton({ integrationKey, entityName, handleRefresh }) {
|
|
836
|
-
const { buttonStyle, containerStyle, iconStyle, textStyle } = useStyles$3();
|
|
837
|
-
const [dialogShown, setDialogShown] = useState(false);
|
|
838
|
-
const showDialog = useCallback(() => {
|
|
839
|
-
setDialogShown(true);
|
|
840
|
-
}, [setDialogShown]);
|
|
841
|
-
const hideDialog = useCallback(() => {
|
|
842
|
-
setDialogShown(false);
|
|
843
|
-
}, [setDialogShown]);
|
|
844
|
-
const disabled = !integrationKey;
|
|
845
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
846
|
-
IconButton,
|
|
847
|
-
{
|
|
848
|
-
"aria-label": "create-incident",
|
|
849
|
-
onClick: showDialog,
|
|
850
|
-
className: disabled ? "" : buttonStyle,
|
|
851
|
-
disabled
|
|
782
|
+
largeTextStyle: {
|
|
783
|
+
color: textColor,
|
|
784
|
+
fontSize: "30px",
|
|
785
|
+
marginTop: "-10px"
|
|
852
786
|
},
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
serviceName: entityName,
|
|
861
|
-
onIncidentCreated: handleRefresh
|
|
787
|
+
smallTextStyle: {
|
|
788
|
+
color: textColor,
|
|
789
|
+
fontWeight: "bold",
|
|
790
|
+
fontSize: "10px",
|
|
791
|
+
marginTop: "-5px",
|
|
792
|
+
textTransform: "uppercase",
|
|
793
|
+
flexWrap: "wrap"
|
|
862
794
|
}
|
|
863
|
-
));
|
|
795
|
+
}));
|
|
796
|
+
const { cardStyle, largeTextStyle, smallTextStyle } = useStyles();
|
|
797
|
+
return /* @__PURE__ */ React.createElement(Card, { className: cardStyle }, count !== void 0 ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Typography, { className: largeTextStyle }, count), /* @__PURE__ */ React.createElement(Typography, { className: smallTextStyle }, label)) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Typography, { className: largeTextStyle }, "-"), /* @__PURE__ */ React.createElement(Typography, { className: smallTextStyle }, label)));
|
|
864
798
|
}
|
|
865
799
|
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
800
|
+
function OpenServiceButton({ serviceUrl, compact }) {
|
|
801
|
+
const useStyles = makeStyles((theme) => ({
|
|
802
|
+
buttonStyle: {
|
|
803
|
+
color: theme.palette.text.primary,
|
|
804
|
+
"&:hover": {
|
|
805
|
+
backgroundColor: "transparent",
|
|
806
|
+
textDecoration: "underline"
|
|
807
|
+
}
|
|
808
|
+
},
|
|
809
|
+
containerStyle: {
|
|
810
|
+
fontSize: compact !== true ? "12px" : "10px",
|
|
811
|
+
width: compact !== true ? "85px" : "70px"
|
|
812
|
+
},
|
|
813
|
+
iconStyle: {
|
|
814
|
+
fontSize: "30px",
|
|
815
|
+
marginBottom: "-10px"
|
|
816
|
+
},
|
|
817
|
+
textStyle: {
|
|
818
|
+
marginBottom: "-10px"
|
|
872
819
|
}
|
|
873
|
-
}
|
|
874
|
-
containerStyle
|
|
875
|
-
fontSize: "12px",
|
|
876
|
-
width: "85px"
|
|
877
|
-
},
|
|
878
|
-
iconStyle: {
|
|
879
|
-
fontSize: "30px",
|
|
880
|
-
marginBottom: "-10px"
|
|
881
|
-
},
|
|
882
|
-
textStyle: {
|
|
883
|
-
marginBottom: "-10px"
|
|
884
|
-
}
|
|
885
|
-
}));
|
|
886
|
-
function OpenServiceButton(props) {
|
|
887
|
-
const { buttonStyle, containerStyle, iconStyle, textStyle } = useStyles$2();
|
|
820
|
+
}));
|
|
821
|
+
const { buttonStyle, containerStyle, iconStyle, textStyle } = useStyles();
|
|
888
822
|
function navigateToService() {
|
|
889
|
-
window.open(
|
|
823
|
+
window.open(serviceUrl, "_blank");
|
|
890
824
|
}
|
|
891
825
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
892
826
|
IconButton,
|
|
@@ -899,109 +833,18 @@ function OpenServiceButton(props) {
|
|
|
899
833
|
));
|
|
900
834
|
}
|
|
901
835
|
|
|
902
|
-
function
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
break;
|
|
908
|
-
case "warning":
|
|
909
|
-
label = "ACTIVE";
|
|
910
|
-
break;
|
|
911
|
-
case "critical":
|
|
912
|
-
label = "ALARM";
|
|
913
|
-
break;
|
|
914
|
-
case "maintenance":
|
|
915
|
-
label = "MAINTENANCE";
|
|
916
|
-
break;
|
|
917
|
-
case "disabled":
|
|
918
|
-
label = "DISABLED";
|
|
919
|
-
break;
|
|
920
|
-
default:
|
|
921
|
-
label = "OK";
|
|
922
|
-
break;
|
|
836
|
+
function colorFromPercentage(theme, percentage) {
|
|
837
|
+
if (percentage < 0.5) {
|
|
838
|
+
return theme.palette.error.main;
|
|
839
|
+
} else if (percentage < 0.8) {
|
|
840
|
+
return theme.palette.warning.main;
|
|
923
841
|
}
|
|
924
|
-
return
|
|
842
|
+
return theme.palette.success.main;
|
|
925
843
|
}
|
|
926
|
-
function
|
|
927
|
-
let color;
|
|
928
|
-
switch (status) {
|
|
929
|
-
case "active":
|
|
930
|
-
color = theme.palette.success.main;
|
|
931
|
-
break;
|
|
932
|
-
case "warning":
|
|
933
|
-
color = theme.palette.warningBackground;
|
|
934
|
-
break;
|
|
935
|
-
case "critical":
|
|
936
|
-
color = theme.palette.error.main;
|
|
937
|
-
break;
|
|
938
|
-
case "maintenance":
|
|
939
|
-
color = "#ebdc00";
|
|
940
|
-
break;
|
|
941
|
-
case "disabled":
|
|
942
|
-
color = "#A9A9A9";
|
|
943
|
-
break;
|
|
944
|
-
default:
|
|
945
|
-
color = theme.palette.success.main;
|
|
946
|
-
break;
|
|
947
|
-
}
|
|
948
|
-
return color;
|
|
949
|
-
}
|
|
950
|
-
function StatusCard({ serviceId, refreshStatus }) {
|
|
951
|
-
const api = useApi(pagerDutyApiRef);
|
|
952
|
-
const [{ value: status, loading, error }, getStatus] = useAsyncFn$1(
|
|
953
|
-
async () => {
|
|
954
|
-
const { service: foundService } = await api.getServiceById(serviceId);
|
|
955
|
-
return foundService.status;
|
|
956
|
-
}
|
|
957
|
-
);
|
|
958
|
-
const useStyles = makeStyles$1((theme) => ({
|
|
959
|
-
cardStyle: {
|
|
960
|
-
height: "120px",
|
|
961
|
-
display: "flex",
|
|
962
|
-
alignItems: "center",
|
|
963
|
-
justifyContent: "center",
|
|
964
|
-
backgroundColor: status !== void 0 ? colorFromStatus(theme, status) : colorFromStatus(theme, "active"),
|
|
965
|
-
marginRight: "10px"
|
|
966
|
-
},
|
|
967
|
-
largeTextStyle: {
|
|
968
|
-
color: "white",
|
|
969
|
-
fontWeight: "bold",
|
|
970
|
-
fontSize: "20px",
|
|
971
|
-
wordWrap: "break-word"
|
|
972
|
-
}
|
|
973
|
-
}));
|
|
974
|
-
const { cardStyle, largeTextStyle } = useStyles();
|
|
975
|
-
useEffect(() => {
|
|
976
|
-
getStatus();
|
|
977
|
-
}, [refreshStatus, getStatus]);
|
|
978
|
-
if (error) {
|
|
979
|
-
if (error.message.includes("Forbidden")) {
|
|
980
|
-
return /* @__PURE__ */ React.createElement("p", null, "forbidden");
|
|
981
|
-
}
|
|
982
|
-
return /* @__PURE__ */ React.createElement(Alert$1, { severity: "error" }, "Error encountered while fetching information. ", error.message);
|
|
983
|
-
}
|
|
984
|
-
if (loading) {
|
|
985
|
-
return /* @__PURE__ */ React.createElement(Progress, null);
|
|
986
|
-
}
|
|
987
|
-
if (!status) {
|
|
988
|
-
return /* @__PURE__ */ React.createElement("p", null, "not found");
|
|
989
|
-
}
|
|
990
|
-
return /* @__PURE__ */ React.createElement(Card, { className: cardStyle }, status !== void 0 ? /* @__PURE__ */ React.createElement(Typography, { className: largeTextStyle }, labelFromStatus(status)) : /* @__PURE__ */ React.createElement(Typography, { className: largeTextStyle }, "Unable to get status"));
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
function colorFromPercentage(theme, percentage) {
|
|
994
|
-
if (percentage < 0.5) {
|
|
995
|
-
return theme.palette.error.main;
|
|
996
|
-
} else if (percentage < 0.8) {
|
|
997
|
-
return theme.palette.warning.main;
|
|
998
|
-
}
|
|
999
|
-
return theme.palette.success.main;
|
|
1000
|
-
}
|
|
1001
|
-
function ServiceStandardsCard({ total, completed, standards }) {
|
|
844
|
+
function ServiceStandardsCard({ total, completed, standards, compact }) {
|
|
1002
845
|
const useStyles = makeStyles((theme) => ({
|
|
1003
846
|
cardStyle: {
|
|
1004
|
-
height: "120px",
|
|
847
|
+
height: compact !== true ? "120px" : "80px",
|
|
1005
848
|
display: "grid",
|
|
1006
849
|
gridTemplateRows: "1fr auto auto",
|
|
1007
850
|
backgroundColor: "rgba(0, 0, 0, 0.03)"
|
|
@@ -1009,22 +852,22 @@ function ServiceStandardsCard({ total, completed, standards }) {
|
|
|
1009
852
|
containerStyle: {
|
|
1010
853
|
display: "flex",
|
|
1011
854
|
justifyContent: "center",
|
|
1012
|
-
marginTop: "-100px"
|
|
855
|
+
marginTop: compact !== true ? "-100px" : "-50px"
|
|
1013
856
|
},
|
|
1014
857
|
largeTextStyle: {
|
|
1015
|
-
fontSize: "50px",
|
|
858
|
+
fontSize: compact !== true ? "50px" : "40px",
|
|
1016
859
|
color: completed !== void 0 && total !== void 0 ? colorFromPercentage(theme, completed / total) : colorFromPercentage(theme, 0),
|
|
1017
860
|
alignSelf: "center",
|
|
1018
861
|
justifyContent: "center"
|
|
1019
862
|
},
|
|
1020
863
|
smallTextStyle: {
|
|
1021
864
|
color: theme.palette.textSubtle,
|
|
1022
|
-
fontSize: "14px",
|
|
865
|
+
fontSize: compact !== true ? "14px" : "12px",
|
|
1023
866
|
fontWeight: "bold",
|
|
1024
867
|
alignSelf: "center",
|
|
1025
868
|
justifyContent: "center",
|
|
1026
869
|
marginLeft: "-2px",
|
|
1027
|
-
marginTop: "25px"
|
|
870
|
+
marginTop: compact !== true ? "25px" : "20px"
|
|
1028
871
|
},
|
|
1029
872
|
tooltipContainer: {},
|
|
1030
873
|
tooltipIcon: {
|
|
@@ -1077,42 +920,246 @@ function ServiceStandardsCard({ total, completed, standards }) {
|
|
|
1077
920
|
))) : /* @__PURE__ */ React.createElement("div", { className: containerStyle }, /* @__PURE__ */ React.createElement(Typography, { className: smallTextStyle }, "Unable to retrieve Scores")));
|
|
1078
921
|
}
|
|
1079
922
|
|
|
1080
|
-
function
|
|
1081
|
-
|
|
1082
|
-
|
|
923
|
+
function labelFromStatus(status) {
|
|
924
|
+
let label;
|
|
925
|
+
switch (status) {
|
|
926
|
+
case "active":
|
|
927
|
+
label = "OK";
|
|
928
|
+
break;
|
|
929
|
+
case "warning":
|
|
930
|
+
label = "ACTIVE";
|
|
931
|
+
break;
|
|
932
|
+
case "critical":
|
|
933
|
+
label = "ALARM";
|
|
934
|
+
break;
|
|
935
|
+
case "maintenance":
|
|
936
|
+
label = "MAINTENANCE";
|
|
937
|
+
break;
|
|
938
|
+
case "disabled":
|
|
939
|
+
label = "DISABLED";
|
|
940
|
+
break;
|
|
941
|
+
default:
|
|
942
|
+
label = "OK";
|
|
943
|
+
break;
|
|
944
|
+
}
|
|
945
|
+
return label;
|
|
946
|
+
}
|
|
947
|
+
function colorFromStatus(theme, status) {
|
|
948
|
+
let color;
|
|
949
|
+
switch (status) {
|
|
950
|
+
case "active":
|
|
951
|
+
color = theme.palette.success.main;
|
|
952
|
+
break;
|
|
953
|
+
case "warning":
|
|
954
|
+
color = theme.palette.warningBackground;
|
|
955
|
+
break;
|
|
956
|
+
case "critical":
|
|
957
|
+
color = theme.palette.error.main;
|
|
958
|
+
break;
|
|
959
|
+
case "maintenance":
|
|
960
|
+
color = "#ebdc00";
|
|
961
|
+
break;
|
|
962
|
+
case "disabled":
|
|
963
|
+
color = "#A9A9A9";
|
|
964
|
+
break;
|
|
965
|
+
default:
|
|
966
|
+
color = theme.palette.success.main;
|
|
967
|
+
break;
|
|
968
|
+
}
|
|
969
|
+
return color;
|
|
970
|
+
}
|
|
971
|
+
function StatusCard({ serviceId, refreshStatus, compact }) {
|
|
972
|
+
const api = useApi(pagerDutyApiRef);
|
|
973
|
+
const [{ value: status, loading, error }, getStatus] = useAsyncFn$1(
|
|
974
|
+
async () => {
|
|
975
|
+
const { service: foundService } = await api.getServiceById(serviceId);
|
|
976
|
+
return foundService.status;
|
|
977
|
+
}
|
|
978
|
+
);
|
|
979
|
+
const useStyles = makeStyles$1((theme) => ({
|
|
1083
980
|
cardStyle: {
|
|
1084
|
-
|
|
1085
|
-
height: "120px",
|
|
981
|
+
height: compact !== true ? "120px" : "80px",
|
|
1086
982
|
display: "flex",
|
|
1087
983
|
alignItems: "center",
|
|
1088
984
|
justifyContent: "center",
|
|
1089
|
-
backgroundColor:
|
|
985
|
+
backgroundColor: status !== void 0 ? colorFromStatus(theme, status) : colorFromStatus(theme, "active"),
|
|
986
|
+
marginRight: "10px"
|
|
1090
987
|
},
|
|
1091
988
|
largeTextStyle: {
|
|
1092
|
-
color:
|
|
989
|
+
color: "white",
|
|
990
|
+
fontWeight: "bold",
|
|
991
|
+
fontSize: "20px",
|
|
992
|
+
wordWrap: "break-word"
|
|
993
|
+
}
|
|
994
|
+
}));
|
|
995
|
+
const { cardStyle, largeTextStyle } = useStyles();
|
|
996
|
+
useEffect(() => {
|
|
997
|
+
getStatus();
|
|
998
|
+
}, [refreshStatus, getStatus]);
|
|
999
|
+
if (error) {
|
|
1000
|
+
if (error.message.includes("Forbidden")) {
|
|
1001
|
+
return /* @__PURE__ */ React.createElement("p", null, "forbidden");
|
|
1002
|
+
}
|
|
1003
|
+
return /* @__PURE__ */ React.createElement(Alert$1, { severity: "error" }, "Error encountered while fetching information. ", error.message);
|
|
1004
|
+
}
|
|
1005
|
+
if (loading) {
|
|
1006
|
+
return /* @__PURE__ */ React.createElement(Progress, null);
|
|
1007
|
+
}
|
|
1008
|
+
if (!status) {
|
|
1009
|
+
return /* @__PURE__ */ React.createElement("p", null, "not found");
|
|
1010
|
+
}
|
|
1011
|
+
return /* @__PURE__ */ React.createElement(Card, { className: cardStyle }, status !== void 0 ? /* @__PURE__ */ React.createElement(Typography, { className: largeTextStyle }, labelFromStatus(status)) : /* @__PURE__ */ React.createElement(Typography, { className: largeTextStyle }, "Unable to get status"));
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
const TriggerDialog = ({
|
|
1015
|
+
showDialog,
|
|
1016
|
+
handleDialog,
|
|
1017
|
+
onIncidentCreated,
|
|
1018
|
+
serviceName,
|
|
1019
|
+
integrationKey
|
|
1020
|
+
}) => {
|
|
1021
|
+
const alertApi = useApi(alertApiRef);
|
|
1022
|
+
const identityApi = useApi(identityApiRef);
|
|
1023
|
+
const api = useApi(pagerDutyApiRef);
|
|
1024
|
+
const [description, setDescription] = useState("");
|
|
1025
|
+
const [{ value, loading, error }, handleTriggerAlarm] = useAsyncFn(
|
|
1026
|
+
async (descriptions) => {
|
|
1027
|
+
const { userEntityRef } = await identityApi.getBackstageIdentity();
|
|
1028
|
+
const { name: userName } = parseEntityRef(userEntityRef, {
|
|
1029
|
+
defaultKind: "User",
|
|
1030
|
+
defaultNamespace: DEFAULT_NAMESPACE
|
|
1031
|
+
});
|
|
1032
|
+
return await api.triggerAlarm({
|
|
1033
|
+
integrationKey,
|
|
1034
|
+
source: window.location.toString(),
|
|
1035
|
+
description: descriptions,
|
|
1036
|
+
userName
|
|
1037
|
+
});
|
|
1038
|
+
}
|
|
1039
|
+
);
|
|
1040
|
+
const descriptionChanged = (event) => {
|
|
1041
|
+
setDescription(event.target.value);
|
|
1042
|
+
};
|
|
1043
|
+
useEffect(() => {
|
|
1044
|
+
if (value) {
|
|
1045
|
+
(async () => {
|
|
1046
|
+
alertApi.post({
|
|
1047
|
+
message: `Alarm successfully triggered`
|
|
1048
|
+
});
|
|
1049
|
+
handleDialog();
|
|
1050
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
1051
|
+
onIncidentCreated == null ? void 0 : onIncidentCreated();
|
|
1052
|
+
})();
|
|
1053
|
+
}
|
|
1054
|
+
}, [value, alertApi, handleDialog, onIncidentCreated]);
|
|
1055
|
+
if (error) {
|
|
1056
|
+
alertApi.post({
|
|
1057
|
+
message: `Failed to trigger alarm. ${error.message}`,
|
|
1058
|
+
severity: "error"
|
|
1059
|
+
});
|
|
1060
|
+
}
|
|
1061
|
+
return /* @__PURE__ */ React.createElement(Dialog, { maxWidth: "md", open: showDialog, onClose: handleDialog, fullWidth: true }, /* @__PURE__ */ React.createElement(DialogTitle, null, "This action will trigger an incident for ", /* @__PURE__ */ React.createElement("strong", null, '"', serviceName, '"'), "."), /* @__PURE__ */ React.createElement(DialogContent, null, /* @__PURE__ */ React.createElement(Alert, { severity: "info" }, /* @__PURE__ */ React.createElement(Typography, { variant: "body1", align: "justify" }, `If the issue you are seeing does not need urgent attention, please get in touch with the responsible team using their preferred communications channel. You can find information about the owner of this entity in the "About" card. If the issue is urgent, please don't hesitate to trigger the alert.`)), /* @__PURE__ */ React.createElement(
|
|
1062
|
+
Typography,
|
|
1063
|
+
{
|
|
1064
|
+
variant: "body1",
|
|
1065
|
+
style: { marginTop: "1em" },
|
|
1066
|
+
gutterBottom: true,
|
|
1067
|
+
align: "justify"
|
|
1068
|
+
},
|
|
1069
|
+
"Please describe the problem you want to report. Be as descriptive as possible. Your signed in user and a reference to the current page will automatically be amended to the alarm so that the receiver can reach out to you if necessary."
|
|
1070
|
+
), /* @__PURE__ */ React.createElement(
|
|
1071
|
+
TextField,
|
|
1072
|
+
{
|
|
1073
|
+
inputProps: { "data-testid": "trigger-input" },
|
|
1074
|
+
id: "description",
|
|
1075
|
+
multiline: true,
|
|
1076
|
+
fullWidth: true,
|
|
1077
|
+
minRows: 4,
|
|
1078
|
+
margin: "normal",
|
|
1079
|
+
label: "Problem description",
|
|
1080
|
+
variant: "outlined",
|
|
1081
|
+
onChange: descriptionChanged
|
|
1082
|
+
}
|
|
1083
|
+
)), /* @__PURE__ */ React.createElement(DialogActions, null, /* @__PURE__ */ React.createElement(
|
|
1084
|
+
Button,
|
|
1085
|
+
{
|
|
1086
|
+
"data-testid": "trigger-button",
|
|
1087
|
+
id: "trigger",
|
|
1088
|
+
color: "secondary",
|
|
1089
|
+
disabled: !description || loading,
|
|
1090
|
+
variant: "contained",
|
|
1091
|
+
onClick: () => handleTriggerAlarm(description),
|
|
1092
|
+
endIcon: loading && /* @__PURE__ */ React.createElement(CircularProgress, { size: 16 })
|
|
1093
|
+
},
|
|
1094
|
+
"Trigger Incident"
|
|
1095
|
+
), /* @__PURE__ */ React.createElement(Button, { id: "close", color: "primary", onClick: handleDialog }, "Close")));
|
|
1096
|
+
};
|
|
1097
|
+
|
|
1098
|
+
function TriggerIncidentButton({ integrationKey, entityName, compact, handleRefresh }) {
|
|
1099
|
+
const useStyles = makeStyles((theme) => ({
|
|
1100
|
+
buttonStyle: {
|
|
1101
|
+
color: theme.palette.text.primary,
|
|
1102
|
+
"&:hover": {
|
|
1103
|
+
backgroundColor: "transparent",
|
|
1104
|
+
textDecoration: "underline"
|
|
1105
|
+
}
|
|
1106
|
+
},
|
|
1107
|
+
containerStyle: {
|
|
1108
|
+
fontSize: compact !== true ? "12px" : "10px",
|
|
1109
|
+
width: compact !== true ? "80px" : "60px",
|
|
1110
|
+
marginRight: "-10px"
|
|
1111
|
+
},
|
|
1112
|
+
iconStyle: {
|
|
1093
1113
|
fontSize: "30px",
|
|
1094
|
-
|
|
1114
|
+
marginBottom: "-10px"
|
|
1095
1115
|
},
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
fontWeight: "bold",
|
|
1099
|
-
fontSize: "10px",
|
|
1100
|
-
marginTop: "-5px",
|
|
1101
|
-
textTransform: "uppercase",
|
|
1102
|
-
flexWrap: "wrap"
|
|
1116
|
+
textStyle: {
|
|
1117
|
+
marginBottom: "-10px"
|
|
1103
1118
|
}
|
|
1104
1119
|
}));
|
|
1105
|
-
const {
|
|
1106
|
-
|
|
1120
|
+
const { buttonStyle, containerStyle, iconStyle, textStyle } = useStyles();
|
|
1121
|
+
const [dialogShown, setDialogShown] = useState(false);
|
|
1122
|
+
const showDialog = useCallback(() => {
|
|
1123
|
+
setDialogShown(true);
|
|
1124
|
+
}, [setDialogShown]);
|
|
1125
|
+
const hideDialog = useCallback(() => {
|
|
1126
|
+
setDialogShown(false);
|
|
1127
|
+
}, [setDialogShown]);
|
|
1128
|
+
const disabled = !integrationKey;
|
|
1129
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
1130
|
+
IconButton,
|
|
1131
|
+
{
|
|
1132
|
+
"aria-label": "create-incident",
|
|
1133
|
+
onClick: showDialog,
|
|
1134
|
+
className: disabled ? "" : buttonStyle,
|
|
1135
|
+
disabled
|
|
1136
|
+
},
|
|
1137
|
+
/* @__PURE__ */ React.createElement("div", { className: containerStyle }, /* @__PURE__ */ React.createElement(AddAlert, { className: iconStyle }), /* @__PURE__ */ React.createElement("p", { className: textStyle }, "Create new incident"))
|
|
1138
|
+
), integrationKey && /* @__PURE__ */ React.createElement(
|
|
1139
|
+
TriggerDialog,
|
|
1140
|
+
{
|
|
1141
|
+
showDialog: dialogShown,
|
|
1142
|
+
handleDialog: hideDialog,
|
|
1143
|
+
integrationKey,
|
|
1144
|
+
serviceName: entityName,
|
|
1145
|
+
onIncidentCreated: handleRefresh
|
|
1146
|
+
}
|
|
1147
|
+
));
|
|
1107
1148
|
}
|
|
1108
1149
|
|
|
1109
|
-
const useStyles$
|
|
1110
|
-
(theme) => createStyles({
|
|
1150
|
+
const useStyles$2 = makeStyles$1(
|
|
1151
|
+
(theme) => createStyles$1({
|
|
1111
1152
|
overviewHeaderTextStyle: {
|
|
1112
1153
|
fontSize: "14px",
|
|
1113
1154
|
fontWeight: 500,
|
|
1114
1155
|
color: theme.palette.type === "light" ? "rgba(0, 0, 0, 0.54)" : "rgba(255, 255, 255, 0.7)"
|
|
1115
1156
|
},
|
|
1157
|
+
oncallHeaderTextStyle: {
|
|
1158
|
+
fontSize: "14px",
|
|
1159
|
+
fontWeight: 500,
|
|
1160
|
+
marginTop: "10px",
|
|
1161
|
+
color: theme.palette.type === "light" ? "rgba(0, 0, 0, 0.54)" : "rgba(255, 255, 255, 0.7)"
|
|
1162
|
+
},
|
|
1116
1163
|
headerStyle: {
|
|
1117
1164
|
marginBottom: "0px",
|
|
1118
1165
|
fontSize: "0px"
|
|
@@ -1143,10 +1190,10 @@ const useStyles$1 = makeStyles$1(
|
|
|
1143
1190
|
}
|
|
1144
1191
|
})
|
|
1145
1192
|
);
|
|
1146
|
-
const BasicCard = ({ children }) => /* @__PURE__ */ React.createElement(InfoCard, { title: "PagerDuty" }, children);
|
|
1193
|
+
const BasicCard$1 = ({ children }) => /* @__PURE__ */ React.createElement(InfoCard, { title: "PagerDuty" }, children);
|
|
1147
1194
|
const PagerDutyCard$1 = (props) => {
|
|
1148
1195
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1149
|
-
const classes = useStyles$
|
|
1196
|
+
const classes = useStyles$2();
|
|
1150
1197
|
const theme = useTheme();
|
|
1151
1198
|
const { readOnly, disableChangeEvents, disableOnCall } = props;
|
|
1152
1199
|
const api = useApi(pagerDutyApiRef);
|
|
@@ -1197,10 +1244,10 @@ const PagerDutyCard$1 = (props) => {
|
|
|
1197
1244
|
default:
|
|
1198
1245
|
errorNode = /* @__PURE__ */ React.createElement(ForbiddenError, null);
|
|
1199
1246
|
}
|
|
1200
|
-
return /* @__PURE__ */ React.createElement(BasicCard, null, errorNode);
|
|
1247
|
+
return /* @__PURE__ */ React.createElement(BasicCard$1, null, errorNode);
|
|
1201
1248
|
}
|
|
1202
1249
|
if (loading) {
|
|
1203
|
-
return /* @__PURE__ */ React.createElement(BasicCard, null, /* @__PURE__ */ React.createElement(Progress, null));
|
|
1250
|
+
return /* @__PURE__ */ React.createElement(BasicCard$1, null, /* @__PURE__ */ React.createElement(Progress, null));
|
|
1204
1251
|
}
|
|
1205
1252
|
return /* @__PURE__ */ React.createElement(Card, { "data-testid": "pagerduty-card" }, /* @__PURE__ */ React.createElement(
|
|
1206
1253
|
CardHeader,
|
|
@@ -1258,7 +1305,7 @@ const PagerDutyCard$1 = (props) => {
|
|
|
1258
1305
|
serviceId: service.id,
|
|
1259
1306
|
refreshEvents: refreshChangeEvents
|
|
1260
1307
|
}
|
|
1261
|
-
)) : /* @__PURE__ */ React.createElement(React.Fragment, null)), disableOnCall !== true ? /* @__PURE__ */ React.createElement(
|
|
1308
|
+
)) : /* @__PURE__ */ React.createElement(React.Fragment, null)), disableOnCall !== true ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Typography, { className: classes.oncallHeaderTextStyle }, "ON CALL"), /* @__PURE__ */ React.createElement(
|
|
1262
1309
|
EscalationPolicy,
|
|
1263
1310
|
{
|
|
1264
1311
|
"data-testid": "oncall-card",
|
|
@@ -1266,10 +1313,10 @@ const PagerDutyCard$1 = (props) => {
|
|
|
1266
1313
|
policyUrl: service.policyLink,
|
|
1267
1314
|
policyName: service.policyName
|
|
1268
1315
|
}
|
|
1269
|
-
) : /* @__PURE__ */ React.createElement(React.Fragment, null)));
|
|
1316
|
+
)) : /* @__PURE__ */ React.createElement(React.Fragment, null)));
|
|
1270
1317
|
};
|
|
1271
1318
|
|
|
1272
|
-
const isPluginApplicableToEntity = (entity) => {
|
|
1319
|
+
const isPluginApplicableToEntity$1 = (entity) => {
|
|
1273
1320
|
var _a, _b;
|
|
1274
1321
|
return Boolean(
|
|
1275
1322
|
((_a = entity.metadata.annotations) == null ? void 0 : _a[PAGERDUTY_INTEGRATION_KEY]) || ((_b = entity.metadata.annotations) == null ? void 0 : _b[PAGERDUTY_SERVICE_ID])
|
|
@@ -1290,10 +1337,223 @@ const EntityPagerDutyCard = (props) => {
|
|
|
1290
1337
|
);
|
|
1291
1338
|
};
|
|
1292
1339
|
|
|
1340
|
+
var index$1 = /*#__PURE__*/Object.freeze({
|
|
1341
|
+
__proto__: null,
|
|
1342
|
+
isPluginApplicableToEntity: isPluginApplicableToEntity$1,
|
|
1343
|
+
EntityPagerDutyCard: EntityPagerDutyCard
|
|
1344
|
+
});
|
|
1345
|
+
|
|
1346
|
+
const useStyles$1 = makeStyles$1(
|
|
1347
|
+
(theme) => createStyles$1({
|
|
1348
|
+
overviewHeaderTextStyle: {
|
|
1349
|
+
fontSize: "14px",
|
|
1350
|
+
fontWeight: 500,
|
|
1351
|
+
color: theme.palette.type === "light" ? "rgba(0, 0, 0, 0.54)" : "rgba(255, 255, 255, 0.7)"
|
|
1352
|
+
},
|
|
1353
|
+
headerStyle: {
|
|
1354
|
+
marginBottom: "0px",
|
|
1355
|
+
fontSize: "0px"
|
|
1356
|
+
},
|
|
1357
|
+
overviewHeaderContainerStyle: {
|
|
1358
|
+
display: "flex",
|
|
1359
|
+
margin: "0px",
|
|
1360
|
+
padding: "15px",
|
|
1361
|
+
marginBottom: "5px"
|
|
1362
|
+
},
|
|
1363
|
+
headerWithSubheaderContainerStyle: {
|
|
1364
|
+
display: "flex",
|
|
1365
|
+
alignItems: "center"
|
|
1366
|
+
},
|
|
1367
|
+
subheaderTextStyle: {
|
|
1368
|
+
fontSize: "10px",
|
|
1369
|
+
marginLeft: "5px"
|
|
1370
|
+
},
|
|
1371
|
+
overviewCardsContainerStyle: {
|
|
1372
|
+
display: "flex",
|
|
1373
|
+
margin: "15px",
|
|
1374
|
+
marginTop: "-15px"
|
|
1375
|
+
},
|
|
1376
|
+
onCallAccordionDetails: {
|
|
1377
|
+
display: "flex",
|
|
1378
|
+
width: "100%",
|
|
1379
|
+
marginTop: "-25px",
|
|
1380
|
+
marginBottom: "-15px"
|
|
1381
|
+
},
|
|
1382
|
+
incidentMetricsContainerStyle: {
|
|
1383
|
+
display: "flex",
|
|
1384
|
+
height: "100%",
|
|
1385
|
+
justifyContent: "center",
|
|
1386
|
+
columnSpan: "all",
|
|
1387
|
+
margin: "15px",
|
|
1388
|
+
marginTop: "-15px"
|
|
1389
|
+
}
|
|
1390
|
+
})
|
|
1391
|
+
);
|
|
1392
|
+
const BasicCard = ({ children }) => /* @__PURE__ */ React.createElement(InfoCard, { title: "PagerDuty" }, children);
|
|
1393
|
+
const PagerDutySmallCard = (props) => {
|
|
1394
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1395
|
+
const classes = useStyles$1();
|
|
1396
|
+
const theme = useTheme();
|
|
1397
|
+
const { readOnly, disableInsights, disableOnCall } = props;
|
|
1398
|
+
const api = useApi(pagerDutyApiRef);
|
|
1399
|
+
const [refreshStatus, setRefreshStatus] = useState(false);
|
|
1400
|
+
const handleRefresh = useCallback(() => {
|
|
1401
|
+
setRefreshStatus((x) => !x);
|
|
1402
|
+
}, []);
|
|
1403
|
+
const {
|
|
1404
|
+
value: service,
|
|
1405
|
+
loading,
|
|
1406
|
+
error
|
|
1407
|
+
} = useAsync(async () => {
|
|
1408
|
+
const { service: foundService } = await api.getServiceByPagerDutyEntity(
|
|
1409
|
+
props
|
|
1410
|
+
);
|
|
1411
|
+
const serviceStandards = await api.getServiceStandardsByServiceId(
|
|
1412
|
+
foundService.id
|
|
1413
|
+
);
|
|
1414
|
+
const serviceMetrics = await api.getServiceMetricsByServiceId(
|
|
1415
|
+
foundService.id
|
|
1416
|
+
);
|
|
1417
|
+
const result = {
|
|
1418
|
+
id: foundService.id,
|
|
1419
|
+
name: foundService.name,
|
|
1420
|
+
url: foundService.html_url,
|
|
1421
|
+
policyId: foundService.escalation_policy.id,
|
|
1422
|
+
policyLink: foundService.escalation_policy.html_url,
|
|
1423
|
+
policyName: foundService.escalation_policy.name,
|
|
1424
|
+
status: foundService.status,
|
|
1425
|
+
standards: serviceStandards !== void 0 ? serviceStandards.standards : void 0,
|
|
1426
|
+
metrics: serviceMetrics !== void 0 ? serviceMetrics.metrics : void 0
|
|
1427
|
+
};
|
|
1428
|
+
return result;
|
|
1429
|
+
}, [props]);
|
|
1430
|
+
if (error) {
|
|
1431
|
+
let errorNode;
|
|
1432
|
+
switch (error.constructor) {
|
|
1433
|
+
case UnauthorizedError:
|
|
1434
|
+
errorNode = /* @__PURE__ */ React.createElement(MissingTokenError, null);
|
|
1435
|
+
break;
|
|
1436
|
+
case NotFoundError:
|
|
1437
|
+
errorNode = /* @__PURE__ */ React.createElement(ServiceNotFoundError, null);
|
|
1438
|
+
break;
|
|
1439
|
+
default:
|
|
1440
|
+
errorNode = /* @__PURE__ */ React.createElement(ForbiddenError, null);
|
|
1441
|
+
}
|
|
1442
|
+
return /* @__PURE__ */ React.createElement(BasicCard, null, errorNode);
|
|
1443
|
+
}
|
|
1444
|
+
if (loading) {
|
|
1445
|
+
return /* @__PURE__ */ React.createElement(BasicCard, null, /* @__PURE__ */ React.createElement(Progress, null));
|
|
1446
|
+
}
|
|
1447
|
+
return /* @__PURE__ */ React.createElement(Card, { "data-testid": "pagerduty-card" }, /* @__PURE__ */ React.createElement(
|
|
1448
|
+
CardHeader,
|
|
1449
|
+
{
|
|
1450
|
+
className: classes.headerStyle,
|
|
1451
|
+
title: theme.palette.type === "dark" ? /* @__PURE__ */ React.createElement("img", { src: PDWhiteImage, alt: "PagerDuty", height: "25" }) : /* @__PURE__ */ React.createElement("img", { src: PDGreenImage, alt: "PagerDuty", height: "25" }),
|
|
1452
|
+
action: !readOnly && props.integrationKey ? /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(
|
|
1453
|
+
TriggerIncidentButton,
|
|
1454
|
+
{
|
|
1455
|
+
compact: true,
|
|
1456
|
+
"data-testid": "trigger-incident-button",
|
|
1457
|
+
integrationKey: props.integrationKey,
|
|
1458
|
+
entityName: props.name,
|
|
1459
|
+
handleRefresh
|
|
1460
|
+
}
|
|
1461
|
+
), /* @__PURE__ */ React.createElement(OpenServiceButton, { compact: true, serviceUrl: service.url })) : /* @__PURE__ */ React.createElement(OpenServiceButton, { compact: true, serviceUrl: service.url })
|
|
1462
|
+
}
|
|
1463
|
+
), /* @__PURE__ */ React.createElement(Grid, { item: true, md: 12, className: classes.overviewHeaderContainerStyle }, /* @__PURE__ */ React.createElement(Grid, { item: true, md: 6 }, /* @__PURE__ */ React.createElement(Typography, { className: classes.overviewHeaderTextStyle }, "STATUS")), /* @__PURE__ */ React.createElement(Grid, { item: true, md: 6 }, /* @__PURE__ */ React.createElement(Typography, { className: classes.overviewHeaderTextStyle }, "STANDARDS"))), /* @__PURE__ */ React.createElement(Grid, { item: true, md: 12, className: classes.overviewCardsContainerStyle }, /* @__PURE__ */ React.createElement(Grid, { item: true, md: 6 }, /* @__PURE__ */ React.createElement(StatusCard, { compact: true, serviceId: service.id, refreshStatus })), /* @__PURE__ */ React.createElement(Grid, { item: true, md: 6 }, /* @__PURE__ */ React.createElement(
|
|
1464
|
+
ServiceStandardsCard,
|
|
1465
|
+
{
|
|
1466
|
+
compact: true,
|
|
1467
|
+
total: ((_a = service == null ? void 0 : service.standards) == null ? void 0 : _a.score) !== void 0 ? (_c = (_b = service == null ? void 0 : service.standards) == null ? void 0 : _b.score) == null ? void 0 : _c.total : void 0,
|
|
1468
|
+
completed: ((_d = service == null ? void 0 : service.standards) == null ? void 0 : _d.score) !== void 0 ? (_f = (_e = service == null ? void 0 : service.standards) == null ? void 0 : _e.score) == null ? void 0 : _f.passing : void 0,
|
|
1469
|
+
standards: (service == null ? void 0 : service.standards) !== void 0 ? (_g = service == null ? void 0 : service.standards) == null ? void 0 : _g.standards : void 0
|
|
1470
|
+
}
|
|
1471
|
+
))), disableInsights !== true ? /* @__PURE__ */ React.createElement(Accordion, null, /* @__PURE__ */ React.createElement(
|
|
1472
|
+
AccordionSummary,
|
|
1473
|
+
{
|
|
1474
|
+
expandIcon: /* @__PURE__ */ React.createElement(ExpandMoreIcon, null),
|
|
1475
|
+
"aria-controls": "panel1a-content",
|
|
1476
|
+
id: "panel1a-header"
|
|
1477
|
+
},
|
|
1478
|
+
/* @__PURE__ */ React.createElement("span", { className: classes.headerWithSubheaderContainerStyle }, /* @__PURE__ */ React.createElement(Typography, { className: classes.overviewHeaderTextStyle }, "INSIGHTS"), /* @__PURE__ */ React.createElement(Typography, { className: classes.subheaderTextStyle }, "(last 30 days)"))
|
|
1479
|
+
), /* @__PURE__ */ React.createElement(AccordionDetails, null, /* @__PURE__ */ React.createElement(
|
|
1480
|
+
Grid,
|
|
1481
|
+
{
|
|
1482
|
+
item: true,
|
|
1483
|
+
md: 12,
|
|
1484
|
+
className: classes.incidentMetricsContainerStyle
|
|
1485
|
+
},
|
|
1486
|
+
/* @__PURE__ */ React.createElement(Grid, { item: true, md: 4 }, /* @__PURE__ */ React.createElement(
|
|
1487
|
+
IncidentCounterCard,
|
|
1488
|
+
{
|
|
1489
|
+
compact: true,
|
|
1490
|
+
count: (service == null ? void 0 : service.metrics) !== void 0 && service.metrics.length > 0 ? service == null ? void 0 : service.metrics[0].total_interruptions : void 0,
|
|
1491
|
+
label: "interruptions",
|
|
1492
|
+
color: theme.palette.textSubtle
|
|
1493
|
+
}
|
|
1494
|
+
)),
|
|
1495
|
+
/* @__PURE__ */ React.createElement(Grid, { item: true, md: 4 }, /* @__PURE__ */ React.createElement(
|
|
1496
|
+
IncidentCounterCard,
|
|
1497
|
+
{
|
|
1498
|
+
compact: true,
|
|
1499
|
+
count: (service == null ? void 0 : service.metrics) !== void 0 && service.metrics.length > 0 ? service == null ? void 0 : service.metrics[0].total_high_urgency_incidents : void 0,
|
|
1500
|
+
label: "high urgency",
|
|
1501
|
+
color: theme.palette.warning.main
|
|
1502
|
+
}
|
|
1503
|
+
)),
|
|
1504
|
+
/* @__PURE__ */ React.createElement(Grid, { item: true, md: 4 }, /* @__PURE__ */ React.createElement(
|
|
1505
|
+
IncidentCounterCard,
|
|
1506
|
+
{
|
|
1507
|
+
compact: true,
|
|
1508
|
+
count: (service == null ? void 0 : service.metrics) !== void 0 && ((_h = service == null ? void 0 : service.metrics) == null ? void 0 : _h.length) > 0 ? service == null ? void 0 : service.metrics[0].total_incident_count : void 0,
|
|
1509
|
+
label: "incidents",
|
|
1510
|
+
color: theme.palette.error.main
|
|
1511
|
+
}
|
|
1512
|
+
))
|
|
1513
|
+
))) : /* @__PURE__ */ React.createElement(React.Fragment, null), disableOnCall !== true ? /* @__PURE__ */ React.createElement(Accordion, null, /* @__PURE__ */ React.createElement(
|
|
1514
|
+
AccordionSummary,
|
|
1515
|
+
{
|
|
1516
|
+
expandIcon: /* @__PURE__ */ React.createElement(ExpandMoreIcon, null),
|
|
1517
|
+
"aria-controls": "panel1a-content",
|
|
1518
|
+
id: "panel1a-header"
|
|
1519
|
+
},
|
|
1520
|
+
/* @__PURE__ */ React.createElement(Typography, { className: classes.overviewHeaderTextStyle }, "ON CALL")
|
|
1521
|
+
), /* @__PURE__ */ React.createElement(AccordionDetails, { className: classes.onCallAccordionDetails }, /* @__PURE__ */ React.createElement(
|
|
1522
|
+
EscalationPolicy,
|
|
1523
|
+
{
|
|
1524
|
+
"data-testid": "oncall-card",
|
|
1525
|
+
policyId: service.policyId,
|
|
1526
|
+
policyUrl: service.policyLink,
|
|
1527
|
+
policyName: service.policyName
|
|
1528
|
+
}
|
|
1529
|
+
))) : /* @__PURE__ */ React.createElement(React.Fragment, null));
|
|
1530
|
+
};
|
|
1531
|
+
|
|
1532
|
+
const isPluginApplicableToEntity = (entity) => {
|
|
1533
|
+
var _a, _b;
|
|
1534
|
+
return Boolean(
|
|
1535
|
+
((_a = entity.metadata.annotations) == null ? void 0 : _a[PAGERDUTY_INTEGRATION_KEY]) || ((_b = entity.metadata.annotations) == null ? void 0 : _b[PAGERDUTY_SERVICE_ID])
|
|
1536
|
+
);
|
|
1537
|
+
};
|
|
1538
|
+
const EntityPagerDutySmallCard = (props) => {
|
|
1539
|
+
const { readOnly, disableInsights, disableOnCall } = props;
|
|
1540
|
+
const { entity } = useEntity();
|
|
1541
|
+
const pagerDutyEntity = getPagerDutyEntity(entity);
|
|
1542
|
+
return /* @__PURE__ */ React.createElement(
|
|
1543
|
+
PagerDutySmallCard,
|
|
1544
|
+
{
|
|
1545
|
+
...pagerDutyEntity,
|
|
1546
|
+
readOnly,
|
|
1547
|
+
disableInsights,
|
|
1548
|
+
disableOnCall
|
|
1549
|
+
}
|
|
1550
|
+
);
|
|
1551
|
+
};
|
|
1552
|
+
|
|
1293
1553
|
var index = /*#__PURE__*/Object.freeze({
|
|
1294
1554
|
__proto__: null,
|
|
1295
1555
|
isPluginApplicableToEntity: isPluginApplicableToEntity,
|
|
1296
|
-
|
|
1556
|
+
EntityPagerDutySmallCard: EntityPagerDutySmallCard
|
|
1297
1557
|
});
|
|
1298
1558
|
|
|
1299
1559
|
function usePagerdutyEntity() {
|
|
@@ -1344,5 +1604,5 @@ function TriggerButton(props) {
|
|
|
1344
1604
|
|
|
1345
1605
|
const PagerDutyCard = EntityPagerDutyCard;
|
|
1346
1606
|
|
|
1347
|
-
export { EntityPagerDutyCard$1 as E, HomePagePagerDutyCard as H, PagerDutyCard$1 as P, TriggerButton as T, UnauthorizedError as U, PagerDutyPage as a,
|
|
1348
|
-
//# sourceMappingURL=index-
|
|
1607
|
+
export { EntityPagerDutyCard$1 as E, HomePagePagerDutyCard as H, PagerDutyCard$1 as P, TriggerButton as T, UnauthorizedError as U, PagerDutyPage as a, EntityPagerDutySmallCard$1 as b, isPluginApplicableToEntity as c, PagerDutyClient as d, pagerDutyApiRef as e, PagerDutyCard as f, isPluginApplicableToEntity$1 as i, pagerDutyPlugin as p };
|
|
1608
|
+
//# sourceMappingURL=index-d9b5aaee.esm.js.map
|