@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.
@@ -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, Card, withStyles, LinearProgress, CardHeader, Divider, CardContent } from '@material-ui/core';
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 { parseEntityRef, DEFAULT_NAMESPACE } from '@backstage/catalog-model';
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 validateColor from 'validate-color';
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-d9f825b5.esm.js').then((m) => m.AdvancedConfiguration),
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-a26fa046.esm.js'),
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 navigateToEscalationPolicy(url) {
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(Avatar, { alt: user.name, src: user.avatar_url, className: classes.avatarStyle })), /* @__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(Typography, { className: classes.listItemPrimary }, user.name), /* @__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-service-in-browser",
499
- onClick: () => navigateToEscalationPolicy(policyUrl),
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
- ), /* @__PURE__ */ React.createElement(ListItemSecondaryAction, null, /* @__PURE__ */ React.createElement(Tooltip, { title: "Open user in PagerDuty", placement: "top" }, /* @__PURE__ */ React.createElement(
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
- subheader: /* @__PURE__ */ React.createElement(ListSubheader, null, "ON CALL"),
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$4 = makeStyles((theme) => ({
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$4();
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
- const TriggerDialog = ({
731
- showDialog,
732
- handleDialog,
733
- onIncidentCreated,
734
- serviceName,
735
- integrationKey
736
- }) => {
737
- const alertApi = useApi(alertApiRef);
738
- const identityApi = useApi(identityApiRef);
739
- const api = useApi(pagerDutyApiRef);
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
- "Trigger Incident"
811
- ), /* @__PURE__ */ React.createElement(Button, { id: "close", color: "primary", onClick: handleDialog }, "Close")));
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
- /* @__PURE__ */ React.createElement("div", { className: containerStyle }, /* @__PURE__ */ React.createElement(AddAlert, { className: iconStyle }), /* @__PURE__ */ React.createElement("p", { className: textStyle }, "Create new incident"))
854
- ), integrationKey && /* @__PURE__ */ React.createElement(
855
- TriggerDialog,
856
- {
857
- showDialog: dialogShown,
858
- handleDialog: hideDialog,
859
- integrationKey,
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
- const useStyles$2 = makeStyles((theme) => ({
867
- buttonStyle: {
868
- color: theme.palette.text.primary,
869
- "&:hover": {
870
- backgroundColor: "transparent",
871
- textDecoration: "underline"
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(props.serviceUrl, "_blank");
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 labelFromStatus(status) {
903
- let label;
904
- switch (status) {
905
- case "active":
906
- label = "OK";
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 label;
842
+ return theme.palette.success.main;
925
843
  }
926
- function colorFromStatus(theme, status) {
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 IncidentCounterCard({ count, label, color }) {
1081
- const textColor = color && validateColor(color) ? color : "black";
1082
- const useStyles = makeStyles(() => ({
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
- marginRight: "10px",
1085
- height: "120px",
981
+ height: compact !== true ? "120px" : "80px",
1086
982
  display: "flex",
1087
983
  alignItems: "center",
1088
984
  justifyContent: "center",
1089
- backgroundColor: "rgba(0, 0, 0, 0.03)"
985
+ backgroundColor: status !== void 0 ? colorFromStatus(theme, status) : colorFromStatus(theme, "active"),
986
+ marginRight: "10px"
1090
987
  },
1091
988
  largeTextStyle: {
1092
- color: textColor,
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
- marginTop: "-10px"
1114
+ marginBottom: "-10px"
1095
1115
  },
1096
- smallTextStyle: {
1097
- color: textColor,
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 { cardStyle, largeTextStyle, smallTextStyle } = useStyles();
1106
- 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)));
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$1 = makeStyles$1(
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$1();
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
- EntityPagerDutyCard: EntityPagerDutyCard
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, PagerDutyClient as b, pagerDutyApiRef as c, PagerDutyCard as d, isPluginApplicableToEntity as i, pagerDutyPlugin as p };
1348
- //# sourceMappingURL=index-b957ec97.esm.js.map
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