@pagerduty/backstage-plugin 0.12.0-next.8 → 0.12.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-c6abad2a.esm.js → index-b1b65bd2.esm.js} +9 -8
- package/dist/esm/{index-c6abad2a.esm.js.map → index-b1b65bd2.esm.js.map} +1 -1
- package/dist/esm/{index-ac92409f.esm.js → index-b56f9c4b.esm.js} +569 -322
- package/dist/esm/index-b56f9c4b.esm.js.map +1 -0
- package/dist/index.d.ts +17 -8
- package/dist/index.esm.js +8 -7
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -2
- package/dist/esm/index-1d1c7c36.esm.js +0 -231
- package/dist/esm/index-1d1c7c36.esm.js.map +0 -1
- package/dist/esm/index-ac92409f.esm.js.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { createApiRef, createRouteRef, createPlugin, createApiFactory, discoveryApiRef, configApiRef, fetchApiRef,
|
|
1
|
+
import { createApiRef, createRouteRef, createPlugin, createApiFactory, discoveryApiRef, configApiRef, fetchApiRef, createComponentExtension, useApi, alertApiRef, identityApiRef } from '@backstage/core-plugin-api';
|
|
2
2
|
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";
|
|
@@ -184,7 +185,7 @@ class PagerDutyClient {
|
|
|
184
185
|
}
|
|
185
186
|
}
|
|
186
187
|
|
|
187
|
-
|
|
188
|
+
createRouteRef({
|
|
188
189
|
id: "pagerduty"
|
|
189
190
|
});
|
|
190
191
|
const pagerDutyPlugin = createPlugin({
|
|
@@ -201,28 +202,31 @@ const pagerDutyPlugin = createPlugin({
|
|
|
201
202
|
})
|
|
202
203
|
]
|
|
203
204
|
});
|
|
204
|
-
const PagerDutyPage = pagerDutyPlugin.provide(
|
|
205
|
-
createRoutableExtension({
|
|
206
|
-
name: "PagerDutyPage",
|
|
207
|
-
component: () => import('./index-1d1c7c36.esm.js').then((m) => m.AdvancedConfiguration),
|
|
208
|
-
mountPoint: rootRouteRef
|
|
209
|
-
})
|
|
210
|
-
);
|
|
211
205
|
const EntityPagerDutyCard$1 = pagerDutyPlugin.provide(
|
|
212
206
|
createComponentExtension({
|
|
213
207
|
name: "EntityPagerDutyCard",
|
|
214
208
|
component: {
|
|
215
|
-
lazy: () => Promise.resolve().then(function () { return index; }).then(
|
|
209
|
+
lazy: () => Promise.resolve().then(function () { return index$1; }).then(
|
|
216
210
|
(m) => m.EntityPagerDutyCard
|
|
217
211
|
)
|
|
218
212
|
}
|
|
219
213
|
})
|
|
220
214
|
);
|
|
215
|
+
const EntityPagerDutySmallCard$1 = pagerDutyPlugin.provide(
|
|
216
|
+
createComponentExtension({
|
|
217
|
+
name: "EntityPagerDutySmallCard",
|
|
218
|
+
component: {
|
|
219
|
+
lazy: () => Promise.resolve().then(function () { return index; }).then(
|
|
220
|
+
(m) => m.EntityPagerDutySmallCard
|
|
221
|
+
)
|
|
222
|
+
}
|
|
223
|
+
})
|
|
224
|
+
);
|
|
221
225
|
const HomePagePagerDutyCard = pagerDutyPlugin.provide(
|
|
222
226
|
createCardExtension({
|
|
223
227
|
name: "HomePagePagerDutyCard",
|
|
224
228
|
title: "PagerDuty Homepage Card",
|
|
225
|
-
components: () => import('./index-
|
|
229
|
+
components: () => import('./index-b1b65bd2.esm.js'),
|
|
226
230
|
settings: {
|
|
227
231
|
schema: {
|
|
228
232
|
title: "PagerDuty",
|
|
@@ -459,6 +463,17 @@ const useStyles$5 = makeStyles((theme) => ({
|
|
|
459
463
|
textDecoration: "underline"
|
|
460
464
|
}
|
|
461
465
|
},
|
|
466
|
+
userTextButtonStyle: {
|
|
467
|
+
marginLeft: "-11px",
|
|
468
|
+
marginTop: "-10px",
|
|
469
|
+
marginBottom: "-10px",
|
|
470
|
+
fontSize: "15px",
|
|
471
|
+
color: theme.palette.text.primary,
|
|
472
|
+
"&:hover": {
|
|
473
|
+
backgroundColor: "transparent",
|
|
474
|
+
textDecoration: "underline"
|
|
475
|
+
}
|
|
476
|
+
},
|
|
462
477
|
containerStyle: {
|
|
463
478
|
display: "flex",
|
|
464
479
|
alignItems: "center",
|
|
@@ -476,15 +491,30 @@ const useStyles$5 = makeStyles((theme) => ({
|
|
|
476
491
|
marginTop: "-20px"
|
|
477
492
|
}
|
|
478
493
|
}));
|
|
479
|
-
function
|
|
494
|
+
function navigateToUrl(url) {
|
|
480
495
|
window.open(url, "_blank");
|
|
481
496
|
}
|
|
482
497
|
const EscalationUser = ({ user, policyUrl, policyName }) => {
|
|
483
498
|
const classes = useStyles$5();
|
|
484
|
-
return /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(ListItemIcon, null, /* @__PURE__ */ React.createElement(
|
|
499
|
+
return /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(ListItemIcon, null, /* @__PURE__ */ React.createElement(
|
|
500
|
+
Avatar,
|
|
501
|
+
{
|
|
502
|
+
alt: user.name,
|
|
503
|
+
src: user.avatar_url,
|
|
504
|
+
className: classes.avatarStyle
|
|
505
|
+
}
|
|
506
|
+
)), /* @__PURE__ */ React.createElement(
|
|
485
507
|
ListItemText,
|
|
486
508
|
{
|
|
487
|
-
primary: /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
509
|
+
primary: /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Tooltip, { title: "Open user in PagerDuty", placement: "top" }, /* @__PURE__ */ React.createElement(
|
|
510
|
+
IconButton,
|
|
511
|
+
{
|
|
512
|
+
"aria-label": "open-user-in-browser",
|
|
513
|
+
onClick: () => navigateToUrl(user.html_url),
|
|
514
|
+
className: classes.userTextButtonStyle
|
|
515
|
+
},
|
|
516
|
+
/* @__PURE__ */ React.createElement("span", { className: classes.containerStyle }, user.name)
|
|
517
|
+
)), /* @__PURE__ */ React.createElement(
|
|
488
518
|
Typography,
|
|
489
519
|
{
|
|
490
520
|
className: classes.listItemSecondary,
|
|
@@ -495,31 +525,30 @@ const EscalationUser = ({ user, policyUrl, policyName }) => {
|
|
|
495
525
|
secondary: /* @__PURE__ */ React.createElement(
|
|
496
526
|
IconButton,
|
|
497
527
|
{
|
|
498
|
-
"aria-label": "open-
|
|
499
|
-
onClick: () =>
|
|
528
|
+
"aria-label": "open-escalation-policy-in-browser",
|
|
529
|
+
onClick: () => navigateToUrl(policyUrl),
|
|
500
530
|
className: classes.buttonStyle
|
|
501
531
|
},
|
|
502
532
|
/* @__PURE__ */ React.createElement("span", { className: classes.containerStyle }, /* @__PURE__ */ React.createElement(NotificationsIcon, { className: classes.iconStyle }), policyName)
|
|
503
533
|
)
|
|
504
534
|
}
|
|
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
|
-
))));
|
|
535
|
+
));
|
|
515
536
|
};
|
|
516
537
|
|
|
538
|
+
const useStyles$4 = makeStyles(
|
|
539
|
+
() => createStyles({
|
|
540
|
+
listStyle: {
|
|
541
|
+
marginLeft: "-15px"
|
|
542
|
+
}
|
|
543
|
+
})
|
|
544
|
+
);
|
|
517
545
|
const EscalationPolicy = ({
|
|
518
546
|
policyId,
|
|
519
547
|
policyUrl,
|
|
520
548
|
policyName
|
|
521
549
|
}) => {
|
|
522
550
|
const api = useApi(pagerDutyApiRef);
|
|
551
|
+
const classes = useStyles$4();
|
|
523
552
|
const {
|
|
524
553
|
value: users,
|
|
525
554
|
loading,
|
|
@@ -543,8 +572,7 @@ const EscalationPolicy = ({
|
|
|
543
572
|
List,
|
|
544
573
|
{
|
|
545
574
|
dense: true,
|
|
546
|
-
|
|
547
|
-
style: { marginLeft: "-15px" }
|
|
575
|
+
className: classes.listStyle
|
|
548
576
|
},
|
|
549
577
|
users.map((user, index) => /* @__PURE__ */ React.createElement(
|
|
550
578
|
EscalationUser,
|
|
@@ -594,7 +622,7 @@ const ServiceNotFoundError = () => /* @__PURE__ */ React.createElement(
|
|
|
594
622
|
}
|
|
595
623
|
);
|
|
596
624
|
|
|
597
|
-
const useStyles$
|
|
625
|
+
const useStyles$3 = makeStyles((theme) => ({
|
|
598
626
|
denseListIcon: {
|
|
599
627
|
marginRight: 0,
|
|
600
628
|
display: "flex",
|
|
@@ -618,7 +646,7 @@ const useStyles$4 = makeStyles((theme) => ({
|
|
|
618
646
|
}
|
|
619
647
|
}));
|
|
620
648
|
const ChangeEventListItem = ({ changeEvent }) => {
|
|
621
|
-
const classes = useStyles$
|
|
649
|
+
const classes = useStyles$3();
|
|
622
650
|
const duration = (/* @__PURE__ */ new Date()).getTime() - new Date(changeEvent.timestamp).getTime();
|
|
623
651
|
const changedAt = DateTime.local().minus(Duration.fromMillis(duration)).toRelative({ locale: "en" });
|
|
624
652
|
let externalLinkElem;
|
|
@@ -727,166 +755,59 @@ const ForbiddenError = () => /* @__PURE__ */ React.createElement(
|
|
|
727
755
|
}
|
|
728
756
|
);
|
|
729
757
|
|
|
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 })
|
|
758
|
+
function IncidentCounterCard({ count, label, color, compact }) {
|
|
759
|
+
const textColor = color && validateColor(color) ? color : "black";
|
|
760
|
+
const useStyles = makeStyles(() => ({
|
|
761
|
+
cardStyle: {
|
|
762
|
+
marginRight: "10px",
|
|
763
|
+
height: compact !== true ? "120px" : "80px",
|
|
764
|
+
display: "flex",
|
|
765
|
+
alignItems: "center",
|
|
766
|
+
justifyContent: "center",
|
|
767
|
+
backgroundColor: "rgba(0, 0, 0, 0.03)"
|
|
809
768
|
},
|
|
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
|
|
769
|
+
largeTextStyle: {
|
|
770
|
+
color: textColor,
|
|
771
|
+
fontSize: "30px",
|
|
772
|
+
marginTop: "-10px"
|
|
852
773
|
},
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
serviceName: entityName,
|
|
861
|
-
onIncidentCreated: handleRefresh
|
|
774
|
+
smallTextStyle: {
|
|
775
|
+
color: textColor,
|
|
776
|
+
fontWeight: "bold",
|
|
777
|
+
fontSize: "10px",
|
|
778
|
+
marginTop: "-5px",
|
|
779
|
+
textTransform: "uppercase",
|
|
780
|
+
flexWrap: "wrap"
|
|
862
781
|
}
|
|
863
|
-
));
|
|
782
|
+
}));
|
|
783
|
+
const { cardStyle, largeTextStyle, smallTextStyle } = useStyles();
|
|
784
|
+
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
785
|
}
|
|
865
786
|
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
787
|
+
function OpenServiceButton({ serviceUrl, compact }) {
|
|
788
|
+
const useStyles = makeStyles((theme) => ({
|
|
789
|
+
buttonStyle: {
|
|
790
|
+
color: theme.palette.text.primary,
|
|
791
|
+
"&:hover": {
|
|
792
|
+
backgroundColor: "transparent",
|
|
793
|
+
textDecoration: "underline"
|
|
794
|
+
}
|
|
795
|
+
},
|
|
796
|
+
containerStyle: {
|
|
797
|
+
fontSize: compact !== true ? "12px" : "10px",
|
|
798
|
+
width: compact !== true ? "85px" : "70px"
|
|
799
|
+
},
|
|
800
|
+
iconStyle: {
|
|
801
|
+
fontSize: "30px",
|
|
802
|
+
marginBottom: "-10px"
|
|
803
|
+
},
|
|
804
|
+
textStyle: {
|
|
805
|
+
marginBottom: "-10px"
|
|
872
806
|
}
|
|
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();
|
|
807
|
+
}));
|
|
808
|
+
const { buttonStyle, containerStyle, iconStyle, textStyle } = useStyles();
|
|
888
809
|
function navigateToService() {
|
|
889
|
-
window.open(
|
|
810
|
+
window.open(serviceUrl, "_blank");
|
|
890
811
|
}
|
|
891
812
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
892
813
|
IconButton,
|
|
@@ -899,109 +820,18 @@ function OpenServiceButton(props) {
|
|
|
899
820
|
));
|
|
900
821
|
}
|
|
901
822
|
|
|
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;
|
|
823
|
+
function colorFromPercentage(theme, percentage) {
|
|
824
|
+
if (percentage < 0.5) {
|
|
825
|
+
return theme.palette.error.main;
|
|
826
|
+
} else if (percentage < 0.8) {
|
|
827
|
+
return theme.palette.warning.main;
|
|
923
828
|
}
|
|
924
|
-
return
|
|
829
|
+
return theme.palette.success.main;
|
|
925
830
|
}
|
|
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 }) {
|
|
831
|
+
function ServiceStandardsCard({ total, completed, standards, compact }) {
|
|
1002
832
|
const useStyles = makeStyles((theme) => ({
|
|
1003
833
|
cardStyle: {
|
|
1004
|
-
height: "120px",
|
|
834
|
+
height: compact !== true ? "120px" : "80px",
|
|
1005
835
|
display: "grid",
|
|
1006
836
|
gridTemplateRows: "1fr auto auto",
|
|
1007
837
|
backgroundColor: "rgba(0, 0, 0, 0.03)"
|
|
@@ -1009,22 +839,22 @@ function ServiceStandardsCard({ total, completed, standards }) {
|
|
|
1009
839
|
containerStyle: {
|
|
1010
840
|
display: "flex",
|
|
1011
841
|
justifyContent: "center",
|
|
1012
|
-
marginTop: "-100px"
|
|
842
|
+
marginTop: compact !== true ? "-100px" : "-50px"
|
|
1013
843
|
},
|
|
1014
844
|
largeTextStyle: {
|
|
1015
|
-
fontSize: "50px",
|
|
845
|
+
fontSize: compact !== true ? "50px" : "40px",
|
|
1016
846
|
color: completed !== void 0 && total !== void 0 ? colorFromPercentage(theme, completed / total) : colorFromPercentage(theme, 0),
|
|
1017
847
|
alignSelf: "center",
|
|
1018
848
|
justifyContent: "center"
|
|
1019
849
|
},
|
|
1020
850
|
smallTextStyle: {
|
|
1021
851
|
color: theme.palette.textSubtle,
|
|
1022
|
-
fontSize: "14px",
|
|
852
|
+
fontSize: compact !== true ? "14px" : "12px",
|
|
1023
853
|
fontWeight: "bold",
|
|
1024
854
|
alignSelf: "center",
|
|
1025
855
|
justifyContent: "center",
|
|
1026
856
|
marginLeft: "-2px",
|
|
1027
|
-
marginTop: "25px"
|
|
857
|
+
marginTop: compact !== true ? "25px" : "20px"
|
|
1028
858
|
},
|
|
1029
859
|
tooltipContainer: {},
|
|
1030
860
|
tooltipIcon: {
|
|
@@ -1077,42 +907,246 @@ function ServiceStandardsCard({ total, completed, standards }) {
|
|
|
1077
907
|
))) : /* @__PURE__ */ React.createElement("div", { className: containerStyle }, /* @__PURE__ */ React.createElement(Typography, { className: smallTextStyle }, "Unable to retrieve Scores")));
|
|
1078
908
|
}
|
|
1079
909
|
|
|
1080
|
-
function
|
|
1081
|
-
|
|
1082
|
-
|
|
910
|
+
function labelFromStatus(status) {
|
|
911
|
+
let label;
|
|
912
|
+
switch (status) {
|
|
913
|
+
case "active":
|
|
914
|
+
label = "OK";
|
|
915
|
+
break;
|
|
916
|
+
case "warning":
|
|
917
|
+
label = "ACTIVE";
|
|
918
|
+
break;
|
|
919
|
+
case "critical":
|
|
920
|
+
label = "ALARM";
|
|
921
|
+
break;
|
|
922
|
+
case "maintenance":
|
|
923
|
+
label = "MAINTENANCE";
|
|
924
|
+
break;
|
|
925
|
+
case "disabled":
|
|
926
|
+
label = "DISABLED";
|
|
927
|
+
break;
|
|
928
|
+
default:
|
|
929
|
+
label = "OK";
|
|
930
|
+
break;
|
|
931
|
+
}
|
|
932
|
+
return label;
|
|
933
|
+
}
|
|
934
|
+
function colorFromStatus(theme, status) {
|
|
935
|
+
let color;
|
|
936
|
+
switch (status) {
|
|
937
|
+
case "active":
|
|
938
|
+
color = theme.palette.success.main;
|
|
939
|
+
break;
|
|
940
|
+
case "warning":
|
|
941
|
+
color = theme.palette.warningBackground;
|
|
942
|
+
break;
|
|
943
|
+
case "critical":
|
|
944
|
+
color = theme.palette.error.main;
|
|
945
|
+
break;
|
|
946
|
+
case "maintenance":
|
|
947
|
+
color = "#ebdc00";
|
|
948
|
+
break;
|
|
949
|
+
case "disabled":
|
|
950
|
+
color = "#A9A9A9";
|
|
951
|
+
break;
|
|
952
|
+
default:
|
|
953
|
+
color = theme.palette.success.main;
|
|
954
|
+
break;
|
|
955
|
+
}
|
|
956
|
+
return color;
|
|
957
|
+
}
|
|
958
|
+
function StatusCard({ serviceId, refreshStatus, compact }) {
|
|
959
|
+
const api = useApi(pagerDutyApiRef);
|
|
960
|
+
const [{ value: status, loading, error }, getStatus] = useAsyncFn$1(
|
|
961
|
+
async () => {
|
|
962
|
+
const { service: foundService } = await api.getServiceById(serviceId);
|
|
963
|
+
return foundService.status;
|
|
964
|
+
}
|
|
965
|
+
);
|
|
966
|
+
const useStyles = makeStyles$1((theme) => ({
|
|
1083
967
|
cardStyle: {
|
|
1084
|
-
|
|
1085
|
-
height: "120px",
|
|
968
|
+
height: compact !== true ? "120px" : "80px",
|
|
1086
969
|
display: "flex",
|
|
1087
970
|
alignItems: "center",
|
|
1088
971
|
justifyContent: "center",
|
|
1089
|
-
backgroundColor:
|
|
972
|
+
backgroundColor: status !== void 0 ? colorFromStatus(theme, status) : colorFromStatus(theme, "active"),
|
|
973
|
+
marginRight: "10px"
|
|
1090
974
|
},
|
|
1091
975
|
largeTextStyle: {
|
|
1092
|
-
color:
|
|
976
|
+
color: "white",
|
|
977
|
+
fontWeight: "bold",
|
|
978
|
+
fontSize: "20px",
|
|
979
|
+
wordWrap: "break-word"
|
|
980
|
+
}
|
|
981
|
+
}));
|
|
982
|
+
const { cardStyle, largeTextStyle } = useStyles();
|
|
983
|
+
useEffect(() => {
|
|
984
|
+
getStatus();
|
|
985
|
+
}, [refreshStatus, getStatus]);
|
|
986
|
+
if (error) {
|
|
987
|
+
if (error.message.includes("Forbidden")) {
|
|
988
|
+
return /* @__PURE__ */ React.createElement("p", null, "forbidden");
|
|
989
|
+
}
|
|
990
|
+
return /* @__PURE__ */ React.createElement(Alert$1, { severity: "error" }, "Error encountered while fetching information. ", error.message);
|
|
991
|
+
}
|
|
992
|
+
if (loading) {
|
|
993
|
+
return /* @__PURE__ */ React.createElement(Progress, null);
|
|
994
|
+
}
|
|
995
|
+
if (!status) {
|
|
996
|
+
return /* @__PURE__ */ React.createElement("p", null, "not found");
|
|
997
|
+
}
|
|
998
|
+
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"));
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
const TriggerDialog = ({
|
|
1002
|
+
showDialog,
|
|
1003
|
+
handleDialog,
|
|
1004
|
+
onIncidentCreated,
|
|
1005
|
+
serviceName,
|
|
1006
|
+
integrationKey
|
|
1007
|
+
}) => {
|
|
1008
|
+
const alertApi = useApi(alertApiRef);
|
|
1009
|
+
const identityApi = useApi(identityApiRef);
|
|
1010
|
+
const api = useApi(pagerDutyApiRef);
|
|
1011
|
+
const [description, setDescription] = useState("");
|
|
1012
|
+
const [{ value, loading, error }, handleTriggerAlarm] = useAsyncFn(
|
|
1013
|
+
async (descriptions) => {
|
|
1014
|
+
const { userEntityRef } = await identityApi.getBackstageIdentity();
|
|
1015
|
+
const { name: userName } = parseEntityRef(userEntityRef, {
|
|
1016
|
+
defaultKind: "User",
|
|
1017
|
+
defaultNamespace: DEFAULT_NAMESPACE
|
|
1018
|
+
});
|
|
1019
|
+
return await api.triggerAlarm({
|
|
1020
|
+
integrationKey,
|
|
1021
|
+
source: window.location.toString(),
|
|
1022
|
+
description: descriptions,
|
|
1023
|
+
userName
|
|
1024
|
+
});
|
|
1025
|
+
}
|
|
1026
|
+
);
|
|
1027
|
+
const descriptionChanged = (event) => {
|
|
1028
|
+
setDescription(event.target.value);
|
|
1029
|
+
};
|
|
1030
|
+
useEffect(() => {
|
|
1031
|
+
if (value) {
|
|
1032
|
+
(async () => {
|
|
1033
|
+
alertApi.post({
|
|
1034
|
+
message: `Alarm successfully triggered`
|
|
1035
|
+
});
|
|
1036
|
+
handleDialog();
|
|
1037
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
1038
|
+
onIncidentCreated == null ? void 0 : onIncidentCreated();
|
|
1039
|
+
})();
|
|
1040
|
+
}
|
|
1041
|
+
}, [value, alertApi, handleDialog, onIncidentCreated]);
|
|
1042
|
+
if (error) {
|
|
1043
|
+
alertApi.post({
|
|
1044
|
+
message: `Failed to trigger alarm. ${error.message}`,
|
|
1045
|
+
severity: "error"
|
|
1046
|
+
});
|
|
1047
|
+
}
|
|
1048
|
+
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(
|
|
1049
|
+
Typography,
|
|
1050
|
+
{
|
|
1051
|
+
variant: "body1",
|
|
1052
|
+
style: { marginTop: "1em" },
|
|
1053
|
+
gutterBottom: true,
|
|
1054
|
+
align: "justify"
|
|
1055
|
+
},
|
|
1056
|
+
"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."
|
|
1057
|
+
), /* @__PURE__ */ React.createElement(
|
|
1058
|
+
TextField,
|
|
1059
|
+
{
|
|
1060
|
+
inputProps: { "data-testid": "trigger-input" },
|
|
1061
|
+
id: "description",
|
|
1062
|
+
multiline: true,
|
|
1063
|
+
fullWidth: true,
|
|
1064
|
+
minRows: 4,
|
|
1065
|
+
margin: "normal",
|
|
1066
|
+
label: "Problem description",
|
|
1067
|
+
variant: "outlined",
|
|
1068
|
+
onChange: descriptionChanged
|
|
1069
|
+
}
|
|
1070
|
+
)), /* @__PURE__ */ React.createElement(DialogActions, null, /* @__PURE__ */ React.createElement(
|
|
1071
|
+
Button,
|
|
1072
|
+
{
|
|
1073
|
+
"data-testid": "trigger-button",
|
|
1074
|
+
id: "trigger",
|
|
1075
|
+
color: "secondary",
|
|
1076
|
+
disabled: !description || loading,
|
|
1077
|
+
variant: "contained",
|
|
1078
|
+
onClick: () => handleTriggerAlarm(description),
|
|
1079
|
+
endIcon: loading && /* @__PURE__ */ React.createElement(CircularProgress, { size: 16 })
|
|
1080
|
+
},
|
|
1081
|
+
"Trigger Incident"
|
|
1082
|
+
), /* @__PURE__ */ React.createElement(Button, { id: "close", color: "primary", onClick: handleDialog }, "Close")));
|
|
1083
|
+
};
|
|
1084
|
+
|
|
1085
|
+
function TriggerIncidentButton({ integrationKey, entityName, compact, handleRefresh }) {
|
|
1086
|
+
const useStyles = makeStyles((theme) => ({
|
|
1087
|
+
buttonStyle: {
|
|
1088
|
+
color: theme.palette.text.primary,
|
|
1089
|
+
"&:hover": {
|
|
1090
|
+
backgroundColor: "transparent",
|
|
1091
|
+
textDecoration: "underline"
|
|
1092
|
+
}
|
|
1093
|
+
},
|
|
1094
|
+
containerStyle: {
|
|
1095
|
+
fontSize: compact !== true ? "12px" : "10px",
|
|
1096
|
+
width: compact !== true ? "80px" : "60px",
|
|
1097
|
+
marginRight: "-10px"
|
|
1098
|
+
},
|
|
1099
|
+
iconStyle: {
|
|
1093
1100
|
fontSize: "30px",
|
|
1094
|
-
|
|
1101
|
+
marginBottom: "-10px"
|
|
1095
1102
|
},
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
fontWeight: "bold",
|
|
1099
|
-
fontSize: "10px",
|
|
1100
|
-
marginTop: "-5px",
|
|
1101
|
-
textTransform: "uppercase",
|
|
1102
|
-
flexWrap: "wrap"
|
|
1103
|
+
textStyle: {
|
|
1104
|
+
marginBottom: "-10px"
|
|
1103
1105
|
}
|
|
1104
1106
|
}));
|
|
1105
|
-
const {
|
|
1106
|
-
|
|
1107
|
+
const { buttonStyle, containerStyle, iconStyle, textStyle } = useStyles();
|
|
1108
|
+
const [dialogShown, setDialogShown] = useState(false);
|
|
1109
|
+
const showDialog = useCallback(() => {
|
|
1110
|
+
setDialogShown(true);
|
|
1111
|
+
}, [setDialogShown]);
|
|
1112
|
+
const hideDialog = useCallback(() => {
|
|
1113
|
+
setDialogShown(false);
|
|
1114
|
+
}, [setDialogShown]);
|
|
1115
|
+
const disabled = !integrationKey;
|
|
1116
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
1117
|
+
IconButton,
|
|
1118
|
+
{
|
|
1119
|
+
"aria-label": "create-incident",
|
|
1120
|
+
onClick: showDialog,
|
|
1121
|
+
className: disabled ? "" : buttonStyle,
|
|
1122
|
+
disabled
|
|
1123
|
+
},
|
|
1124
|
+
/* @__PURE__ */ React.createElement("div", { className: containerStyle }, /* @__PURE__ */ React.createElement(AddAlert, { className: iconStyle }), /* @__PURE__ */ React.createElement("p", { className: textStyle }, "Create new incident"))
|
|
1125
|
+
), integrationKey && /* @__PURE__ */ React.createElement(
|
|
1126
|
+
TriggerDialog,
|
|
1127
|
+
{
|
|
1128
|
+
showDialog: dialogShown,
|
|
1129
|
+
handleDialog: hideDialog,
|
|
1130
|
+
integrationKey,
|
|
1131
|
+
serviceName: entityName,
|
|
1132
|
+
onIncidentCreated: handleRefresh
|
|
1133
|
+
}
|
|
1134
|
+
));
|
|
1107
1135
|
}
|
|
1108
1136
|
|
|
1109
|
-
const useStyles$
|
|
1110
|
-
(theme) => createStyles({
|
|
1137
|
+
const useStyles$2 = makeStyles$1(
|
|
1138
|
+
(theme) => createStyles$1({
|
|
1111
1139
|
overviewHeaderTextStyle: {
|
|
1112
1140
|
fontSize: "14px",
|
|
1113
1141
|
fontWeight: 500,
|
|
1114
1142
|
color: theme.palette.type === "light" ? "rgba(0, 0, 0, 0.54)" : "rgba(255, 255, 255, 0.7)"
|
|
1115
1143
|
},
|
|
1144
|
+
oncallHeaderTextStyle: {
|
|
1145
|
+
fontSize: "14px",
|
|
1146
|
+
fontWeight: 500,
|
|
1147
|
+
marginTop: "10px",
|
|
1148
|
+
color: theme.palette.type === "light" ? "rgba(0, 0, 0, 0.54)" : "rgba(255, 255, 255, 0.7)"
|
|
1149
|
+
},
|
|
1116
1150
|
headerStyle: {
|
|
1117
1151
|
marginBottom: "0px",
|
|
1118
1152
|
fontSize: "0px"
|
|
@@ -1143,10 +1177,10 @@ const useStyles$1 = makeStyles$1(
|
|
|
1143
1177
|
}
|
|
1144
1178
|
})
|
|
1145
1179
|
);
|
|
1146
|
-
const BasicCard = ({ children }) => /* @__PURE__ */ React.createElement(InfoCard, { title: "PagerDuty" }, children);
|
|
1180
|
+
const BasicCard$1 = ({ children }) => /* @__PURE__ */ React.createElement(InfoCard, { title: "PagerDuty" }, children);
|
|
1147
1181
|
const PagerDutyCard$1 = (props) => {
|
|
1148
1182
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1149
|
-
const classes = useStyles$
|
|
1183
|
+
const classes = useStyles$2();
|
|
1150
1184
|
const theme = useTheme();
|
|
1151
1185
|
const { readOnly, disableChangeEvents, disableOnCall } = props;
|
|
1152
1186
|
const api = useApi(pagerDutyApiRef);
|
|
@@ -1197,10 +1231,10 @@ const PagerDutyCard$1 = (props) => {
|
|
|
1197
1231
|
default:
|
|
1198
1232
|
errorNode = /* @__PURE__ */ React.createElement(ForbiddenError, null);
|
|
1199
1233
|
}
|
|
1200
|
-
return /* @__PURE__ */ React.createElement(BasicCard, null, errorNode);
|
|
1234
|
+
return /* @__PURE__ */ React.createElement(BasicCard$1, null, errorNode);
|
|
1201
1235
|
}
|
|
1202
1236
|
if (loading) {
|
|
1203
|
-
return /* @__PURE__ */ React.createElement(BasicCard, null, /* @__PURE__ */ React.createElement(Progress, null));
|
|
1237
|
+
return /* @__PURE__ */ React.createElement(BasicCard$1, null, /* @__PURE__ */ React.createElement(Progress, null));
|
|
1204
1238
|
}
|
|
1205
1239
|
return /* @__PURE__ */ React.createElement(Card, { "data-testid": "pagerduty-card" }, /* @__PURE__ */ React.createElement(
|
|
1206
1240
|
CardHeader,
|
|
@@ -1258,7 +1292,7 @@ const PagerDutyCard$1 = (props) => {
|
|
|
1258
1292
|
serviceId: service.id,
|
|
1259
1293
|
refreshEvents: refreshChangeEvents
|
|
1260
1294
|
}
|
|
1261
|
-
)) : /* @__PURE__ */ React.createElement(React.Fragment, null)), disableOnCall !== true ? /* @__PURE__ */ React.createElement(
|
|
1295
|
+
)) : /* @__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
1296
|
EscalationPolicy,
|
|
1263
1297
|
{
|
|
1264
1298
|
"data-testid": "oncall-card",
|
|
@@ -1266,10 +1300,10 @@ const PagerDutyCard$1 = (props) => {
|
|
|
1266
1300
|
policyUrl: service.policyLink,
|
|
1267
1301
|
policyName: service.policyName
|
|
1268
1302
|
}
|
|
1269
|
-
) : /* @__PURE__ */ React.createElement(React.Fragment, null)));
|
|
1303
|
+
)) : /* @__PURE__ */ React.createElement(React.Fragment, null)));
|
|
1270
1304
|
};
|
|
1271
1305
|
|
|
1272
|
-
const isPluginApplicableToEntity = (entity) => {
|
|
1306
|
+
const isPluginApplicableToEntity$1 = (entity) => {
|
|
1273
1307
|
var _a, _b;
|
|
1274
1308
|
return Boolean(
|
|
1275
1309
|
((_a = entity.metadata.annotations) == null ? void 0 : _a[PAGERDUTY_INTEGRATION_KEY]) || ((_b = entity.metadata.annotations) == null ? void 0 : _b[PAGERDUTY_SERVICE_ID])
|
|
@@ -1290,10 +1324,223 @@ const EntityPagerDutyCard = (props) => {
|
|
|
1290
1324
|
);
|
|
1291
1325
|
};
|
|
1292
1326
|
|
|
1327
|
+
var index$1 = /*#__PURE__*/Object.freeze({
|
|
1328
|
+
__proto__: null,
|
|
1329
|
+
isPluginApplicableToEntity: isPluginApplicableToEntity$1,
|
|
1330
|
+
EntityPagerDutyCard: EntityPagerDutyCard
|
|
1331
|
+
});
|
|
1332
|
+
|
|
1333
|
+
const useStyles$1 = makeStyles$1(
|
|
1334
|
+
(theme) => createStyles$1({
|
|
1335
|
+
overviewHeaderTextStyle: {
|
|
1336
|
+
fontSize: "14px",
|
|
1337
|
+
fontWeight: 500,
|
|
1338
|
+
color: theme.palette.type === "light" ? "rgba(0, 0, 0, 0.54)" : "rgba(255, 255, 255, 0.7)"
|
|
1339
|
+
},
|
|
1340
|
+
headerStyle: {
|
|
1341
|
+
marginBottom: "0px",
|
|
1342
|
+
fontSize: "0px"
|
|
1343
|
+
},
|
|
1344
|
+
overviewHeaderContainerStyle: {
|
|
1345
|
+
display: "flex",
|
|
1346
|
+
margin: "0px",
|
|
1347
|
+
padding: "15px",
|
|
1348
|
+
marginBottom: "5px"
|
|
1349
|
+
},
|
|
1350
|
+
headerWithSubheaderContainerStyle: {
|
|
1351
|
+
display: "flex",
|
|
1352
|
+
alignItems: "center"
|
|
1353
|
+
},
|
|
1354
|
+
subheaderTextStyle: {
|
|
1355
|
+
fontSize: "10px",
|
|
1356
|
+
marginLeft: "5px"
|
|
1357
|
+
},
|
|
1358
|
+
overviewCardsContainerStyle: {
|
|
1359
|
+
display: "flex",
|
|
1360
|
+
margin: "15px",
|
|
1361
|
+
marginTop: "-15px"
|
|
1362
|
+
},
|
|
1363
|
+
onCallAccordionDetails: {
|
|
1364
|
+
display: "flex",
|
|
1365
|
+
width: "100%",
|
|
1366
|
+
marginTop: "-25px",
|
|
1367
|
+
marginBottom: "-15px"
|
|
1368
|
+
},
|
|
1369
|
+
incidentMetricsContainerStyle: {
|
|
1370
|
+
display: "flex",
|
|
1371
|
+
height: "100%",
|
|
1372
|
+
justifyContent: "center",
|
|
1373
|
+
columnSpan: "all",
|
|
1374
|
+
margin: "15px",
|
|
1375
|
+
marginTop: "-15px"
|
|
1376
|
+
}
|
|
1377
|
+
})
|
|
1378
|
+
);
|
|
1379
|
+
const BasicCard = ({ children }) => /* @__PURE__ */ React.createElement(InfoCard, { title: "PagerDuty" }, children);
|
|
1380
|
+
const PagerDutySmallCard = (props) => {
|
|
1381
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1382
|
+
const classes = useStyles$1();
|
|
1383
|
+
const theme = useTheme();
|
|
1384
|
+
const { readOnly, disableInsights, disableOnCall } = props;
|
|
1385
|
+
const api = useApi(pagerDutyApiRef);
|
|
1386
|
+
const [refreshStatus, setRefreshStatus] = useState(false);
|
|
1387
|
+
const handleRefresh = useCallback(() => {
|
|
1388
|
+
setRefreshStatus((x) => !x);
|
|
1389
|
+
}, []);
|
|
1390
|
+
const {
|
|
1391
|
+
value: service,
|
|
1392
|
+
loading,
|
|
1393
|
+
error
|
|
1394
|
+
} = useAsync(async () => {
|
|
1395
|
+
const { service: foundService } = await api.getServiceByPagerDutyEntity(
|
|
1396
|
+
props
|
|
1397
|
+
);
|
|
1398
|
+
const serviceStandards = await api.getServiceStandardsByServiceId(
|
|
1399
|
+
foundService.id
|
|
1400
|
+
);
|
|
1401
|
+
const serviceMetrics = await api.getServiceMetricsByServiceId(
|
|
1402
|
+
foundService.id
|
|
1403
|
+
);
|
|
1404
|
+
const result = {
|
|
1405
|
+
id: foundService.id,
|
|
1406
|
+
name: foundService.name,
|
|
1407
|
+
url: foundService.html_url,
|
|
1408
|
+
policyId: foundService.escalation_policy.id,
|
|
1409
|
+
policyLink: foundService.escalation_policy.html_url,
|
|
1410
|
+
policyName: foundService.escalation_policy.name,
|
|
1411
|
+
status: foundService.status,
|
|
1412
|
+
standards: serviceStandards !== void 0 ? serviceStandards.standards : void 0,
|
|
1413
|
+
metrics: serviceMetrics !== void 0 ? serviceMetrics.metrics : void 0
|
|
1414
|
+
};
|
|
1415
|
+
return result;
|
|
1416
|
+
}, [props]);
|
|
1417
|
+
if (error) {
|
|
1418
|
+
let errorNode;
|
|
1419
|
+
switch (error.constructor) {
|
|
1420
|
+
case UnauthorizedError:
|
|
1421
|
+
errorNode = /* @__PURE__ */ React.createElement(MissingTokenError, null);
|
|
1422
|
+
break;
|
|
1423
|
+
case NotFoundError:
|
|
1424
|
+
errorNode = /* @__PURE__ */ React.createElement(ServiceNotFoundError, null);
|
|
1425
|
+
break;
|
|
1426
|
+
default:
|
|
1427
|
+
errorNode = /* @__PURE__ */ React.createElement(ForbiddenError, null);
|
|
1428
|
+
}
|
|
1429
|
+
return /* @__PURE__ */ React.createElement(BasicCard, null, errorNode);
|
|
1430
|
+
}
|
|
1431
|
+
if (loading) {
|
|
1432
|
+
return /* @__PURE__ */ React.createElement(BasicCard, null, /* @__PURE__ */ React.createElement(Progress, null));
|
|
1433
|
+
}
|
|
1434
|
+
return /* @__PURE__ */ React.createElement(Card, { "data-testid": "pagerduty-card" }, /* @__PURE__ */ React.createElement(
|
|
1435
|
+
CardHeader,
|
|
1436
|
+
{
|
|
1437
|
+
className: classes.headerStyle,
|
|
1438
|
+
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" }),
|
|
1439
|
+
action: !readOnly && props.integrationKey ? /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(
|
|
1440
|
+
TriggerIncidentButton,
|
|
1441
|
+
{
|
|
1442
|
+
compact: true,
|
|
1443
|
+
"data-testid": "trigger-incident-button",
|
|
1444
|
+
integrationKey: props.integrationKey,
|
|
1445
|
+
entityName: props.name,
|
|
1446
|
+
handleRefresh
|
|
1447
|
+
}
|
|
1448
|
+
), /* @__PURE__ */ React.createElement(OpenServiceButton, { compact: true, serviceUrl: service.url })) : /* @__PURE__ */ React.createElement(OpenServiceButton, { compact: true, serviceUrl: service.url })
|
|
1449
|
+
}
|
|
1450
|
+
), /* @__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(
|
|
1451
|
+
ServiceStandardsCard,
|
|
1452
|
+
{
|
|
1453
|
+
compact: true,
|
|
1454
|
+
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,
|
|
1455
|
+
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,
|
|
1456
|
+
standards: (service == null ? void 0 : service.standards) !== void 0 ? (_g = service == null ? void 0 : service.standards) == null ? void 0 : _g.standards : void 0
|
|
1457
|
+
}
|
|
1458
|
+
))), disableInsights !== true ? /* @__PURE__ */ React.createElement(Accordion, null, /* @__PURE__ */ React.createElement(
|
|
1459
|
+
AccordionSummary,
|
|
1460
|
+
{
|
|
1461
|
+
expandIcon: /* @__PURE__ */ React.createElement(ExpandMoreIcon, null),
|
|
1462
|
+
"aria-controls": "panel1a-content",
|
|
1463
|
+
id: "panel1a-header"
|
|
1464
|
+
},
|
|
1465
|
+
/* @__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)"))
|
|
1466
|
+
), /* @__PURE__ */ React.createElement(AccordionDetails, null, /* @__PURE__ */ React.createElement(
|
|
1467
|
+
Grid,
|
|
1468
|
+
{
|
|
1469
|
+
item: true,
|
|
1470
|
+
md: 12,
|
|
1471
|
+
className: classes.incidentMetricsContainerStyle
|
|
1472
|
+
},
|
|
1473
|
+
/* @__PURE__ */ React.createElement(Grid, { item: true, md: 4 }, /* @__PURE__ */ React.createElement(
|
|
1474
|
+
IncidentCounterCard,
|
|
1475
|
+
{
|
|
1476
|
+
compact: true,
|
|
1477
|
+
count: (service == null ? void 0 : service.metrics) !== void 0 && service.metrics.length > 0 ? service == null ? void 0 : service.metrics[0].total_interruptions : void 0,
|
|
1478
|
+
label: "interruptions",
|
|
1479
|
+
color: theme.palette.textSubtle
|
|
1480
|
+
}
|
|
1481
|
+
)),
|
|
1482
|
+
/* @__PURE__ */ React.createElement(Grid, { item: true, md: 4 }, /* @__PURE__ */ React.createElement(
|
|
1483
|
+
IncidentCounterCard,
|
|
1484
|
+
{
|
|
1485
|
+
compact: true,
|
|
1486
|
+
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,
|
|
1487
|
+
label: "high urgency",
|
|
1488
|
+
color: theme.palette.warning.main
|
|
1489
|
+
}
|
|
1490
|
+
)),
|
|
1491
|
+
/* @__PURE__ */ React.createElement(Grid, { item: true, md: 4 }, /* @__PURE__ */ React.createElement(
|
|
1492
|
+
IncidentCounterCard,
|
|
1493
|
+
{
|
|
1494
|
+
compact: true,
|
|
1495
|
+
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,
|
|
1496
|
+
label: "incidents",
|
|
1497
|
+
color: theme.palette.error.main
|
|
1498
|
+
}
|
|
1499
|
+
))
|
|
1500
|
+
))) : /* @__PURE__ */ React.createElement(React.Fragment, null), disableOnCall !== true ? /* @__PURE__ */ React.createElement(Accordion, null, /* @__PURE__ */ React.createElement(
|
|
1501
|
+
AccordionSummary,
|
|
1502
|
+
{
|
|
1503
|
+
expandIcon: /* @__PURE__ */ React.createElement(ExpandMoreIcon, null),
|
|
1504
|
+
"aria-controls": "panel1a-content",
|
|
1505
|
+
id: "panel1a-header"
|
|
1506
|
+
},
|
|
1507
|
+
/* @__PURE__ */ React.createElement(Typography, { className: classes.overviewHeaderTextStyle }, "ON CALL")
|
|
1508
|
+
), /* @__PURE__ */ React.createElement(AccordionDetails, { className: classes.onCallAccordionDetails }, /* @__PURE__ */ React.createElement(
|
|
1509
|
+
EscalationPolicy,
|
|
1510
|
+
{
|
|
1511
|
+
"data-testid": "oncall-card",
|
|
1512
|
+
policyId: service.policyId,
|
|
1513
|
+
policyUrl: service.policyLink,
|
|
1514
|
+
policyName: service.policyName
|
|
1515
|
+
}
|
|
1516
|
+
))) : /* @__PURE__ */ React.createElement(React.Fragment, null));
|
|
1517
|
+
};
|
|
1518
|
+
|
|
1519
|
+
const isPluginApplicableToEntity = (entity) => {
|
|
1520
|
+
var _a, _b;
|
|
1521
|
+
return Boolean(
|
|
1522
|
+
((_a = entity.metadata.annotations) == null ? void 0 : _a[PAGERDUTY_INTEGRATION_KEY]) || ((_b = entity.metadata.annotations) == null ? void 0 : _b[PAGERDUTY_SERVICE_ID])
|
|
1523
|
+
);
|
|
1524
|
+
};
|
|
1525
|
+
const EntityPagerDutySmallCard = (props) => {
|
|
1526
|
+
const { readOnly, disableInsights, disableOnCall } = props;
|
|
1527
|
+
const { entity } = useEntity();
|
|
1528
|
+
const pagerDutyEntity = getPagerDutyEntity(entity);
|
|
1529
|
+
return /* @__PURE__ */ React.createElement(
|
|
1530
|
+
PagerDutySmallCard,
|
|
1531
|
+
{
|
|
1532
|
+
...pagerDutyEntity,
|
|
1533
|
+
readOnly,
|
|
1534
|
+
disableInsights,
|
|
1535
|
+
disableOnCall
|
|
1536
|
+
}
|
|
1537
|
+
);
|
|
1538
|
+
};
|
|
1539
|
+
|
|
1293
1540
|
var index = /*#__PURE__*/Object.freeze({
|
|
1294
1541
|
__proto__: null,
|
|
1295
1542
|
isPluginApplicableToEntity: isPluginApplicableToEntity,
|
|
1296
|
-
|
|
1543
|
+
EntityPagerDutySmallCard: EntityPagerDutySmallCard
|
|
1297
1544
|
});
|
|
1298
1545
|
|
|
1299
1546
|
function usePagerdutyEntity() {
|
|
@@ -1344,5 +1591,5 @@ function TriggerButton(props) {
|
|
|
1344
1591
|
|
|
1345
1592
|
const PagerDutyCard = EntityPagerDutyCard;
|
|
1346
1593
|
|
|
1347
|
-
export { EntityPagerDutyCard$1 as E, HomePagePagerDutyCard as H, PagerDutyCard$1 as P, TriggerButton as T, UnauthorizedError as U,
|
|
1348
|
-
//# sourceMappingURL=index-
|
|
1594
|
+
export { EntityPagerDutyCard$1 as E, HomePagePagerDutyCard as H, PagerDutyCard$1 as P, TriggerButton as T, UnauthorizedError as U, EntityPagerDutySmallCard$1 as a, isPluginApplicableToEntity as b, PagerDutyClient as c, pagerDutyApiRef as d, PagerDutyCard as e, isPluginApplicableToEntity$1 as i, pagerDutyPlugin as p };
|
|
1595
|
+
//# sourceMappingURL=index-b56f9c4b.esm.js.map
|