@pagerduty/backstage-plugin 0.9.4-next.1 → 0.9.4-next.10

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,9 +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, CardHeader, Divider, CardContent } from '@material-ui/core';
7
- import Done from '@material-ui/icons/Done';
8
- import Warning from '@material-ui/icons/Warning';
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';
9
7
  import { DateTime, Duration } from 'luxon';
10
8
  import OpenInBrowserIcon from '@material-ui/icons/OpenInBrowser';
11
9
  import { Link, Progress, StatusWarning, StatusError, EmptyState, TabbedCard, CardTab, InfoCard } from '@backstage/core-components';
@@ -15,14 +13,16 @@ import { Alert } from '@material-ui/lab';
15
13
  import ForbiddenStateImage from '../assets/forbiddenstate.svg';
16
14
  import Avatar from '@material-ui/core/Avatar';
17
15
  import NotificationsIcon from '@material-ui/icons/Notifications';
18
- import MailOutline from '@material-ui/icons/MailOutline';
19
16
  import useAsync from 'react-use/lib/useAsync';
20
- import { parseEntityRef, DEFAULT_NAMESPACE } from '@backstage/catalog-model';
17
+ import LinkIcon from '@material-ui/icons/Link';
21
18
  import PDGreenImage from '../assets/PD-Green.svg';
22
19
  import PDWhiteImage from '../assets/PD-White.svg';
20
+ import { parseEntityRef, DEFAULT_NAMESPACE } from '@backstage/catalog-model';
23
21
  import AddAlert from '@material-ui/icons/AddAlert';
24
- import { useTheme } from '@material-ui/core/styles';
25
- import LinearProgress from '@material-ui/core/LinearProgress';
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';
25
+ import validateColor from 'validate-color';
26
26
 
27
27
  const PAGERDUTY_INTEGRATION_KEY = "pagerduty.com/integration-key";
28
28
  const PAGERDUTY_SERVICE_ID = "pagerduty.com/service-id";
@@ -82,6 +82,12 @@ class PagerDutyClient {
82
82
  async getServiceByEntity(entity) {
83
83
  return await this.getServiceByPagerDutyEntity(getPagerDutyEntity(entity));
84
84
  }
85
+ async getServiceById(serviceId) {
86
+ const url = `${await this.config.discoveryApi.getBaseUrl(
87
+ "pagerduty"
88
+ )}/services/${serviceId}`;
89
+ return await this.findByUrl(url);
90
+ }
85
91
  async getIncidentsByServiceId(serviceId) {
86
92
  const url = `${await this.config.discoveryApi.getBaseUrl(
87
93
  "pagerduty"
@@ -94,6 +100,12 @@ class PagerDutyClient {
94
100
  )}/services/${serviceId}/change-events`;
95
101
  return await this.findByUrl(url);
96
102
  }
103
+ async getServiceStandardsByServiceId(serviceId) {
104
+ const url = `${await this.config.discoveryApi.getBaseUrl(
105
+ "pagerduty"
106
+ )}/services/${serviceId}/standards`;
107
+ return await this.findByUrl(url);
108
+ }
97
109
  async getOnCallByPolicyId(policyId) {
98
110
  const params = `escalation_policy_ids[]=${policyId}`;
99
111
  const url = `${await this.config.discoveryApi.getBaseUrl(
@@ -194,7 +206,7 @@ const HomePagePagerDutyCard = pagerDutyPlugin.provide(
194
206
  createCardExtension({
195
207
  name: "HomePagePagerDutyCard",
196
208
  title: "PagerDuty Homepage Card",
197
- components: () => import('./index-b2ba10a3.esm.js'),
209
+ components: () => import('./index-7306b2fe.esm.js'),
198
210
  settings: {
199
211
  schema: {
200
212
  title: "PagerDuty",
@@ -218,7 +230,7 @@ const HomePagePagerDutyCard = pagerDutyPlugin.provide(
218
230
  })
219
231
  );
220
232
 
221
- const useStyles$7 = makeStyles((theme) => ({
233
+ const useStyles$8 = makeStyles((theme) => ({
222
234
  denseListIcon: {
223
235
  marginRight: 0,
224
236
  display: "flex",
@@ -230,39 +242,81 @@ const useStyles$7 = makeStyles((theme) => ({
230
242
  fontWeight: "bold"
231
243
  },
232
244
  warning: {
233
- borderColor: theme.palette.status.warning,
234
- color: theme.palette.status.warning,
245
+ borderColor: theme.palette.warning.main,
246
+ color: "#fff",
247
+ backgroundColor: theme.palette.warning.main,
248
+ boxShadow: "0 4px 4px 0 rgba(0,0,0,0.2)",
249
+ textTransform: "uppercase",
235
250
  "& *": {
236
- color: theme.palette.status.warning
251
+ color: "#fff"
237
252
  }
238
253
  },
239
254
  error: {
240
- borderColor: theme.palette.status.error,
241
- color: theme.palette.status.error,
255
+ borderColor: theme.palette.error.main,
256
+ color: "#fff",
257
+ backgroundColor: theme.palette.error.main,
258
+ boxShadow: "0 4px 4px 0 rgba(0,0,0,0.2)",
259
+ textTransform: "uppercase",
242
260
  "& *": {
243
- color: theme.palette.status.error
261
+ color: "#fff"
244
262
  }
263
+ },
264
+ lowUrgency: {
265
+ borderColor: theme.palette.warning.main,
266
+ color: theme.palette.warning.main,
267
+ backgroundColor: "#fff",
268
+ boxShadow: "0 4px 4px 0 rgba(0,0,0,0.2)",
269
+ textTransform: "uppercase",
270
+ "& *": {
271
+ color: theme.palette.warning.main
272
+ }
273
+ },
274
+ highUrgency: {
275
+ borderColor: theme.palette.error.main,
276
+ color: theme.palette.error.main,
277
+ backgroundColor: "#fff",
278
+ boxShadow: "0 4px 4px 0 rgba(0,0,0,0.2)",
279
+ textTransform: "uppercase",
280
+ "& *": {
281
+ color: theme.palette.error.main
282
+ }
283
+ },
284
+ textContainer: {
285
+ display: "flex",
286
+ alignItems: "baseline"
287
+ },
288
+ smallIconStyle: {
289
+ color: theme.palette.text.primary,
290
+ marginRight: "-20px"
245
291
  }
246
292
  }));
247
293
  const IncidentListItem = ({ incident }) => {
248
294
  var _a, _b, _c;
249
- const classes = useStyles$7();
295
+ const classes = useStyles$8();
250
296
  const duration = (/* @__PURE__ */ new Date()).getTime() - new Date(incident.created_at).getTime();
251
297
  const createdAt = DateTime.local().minus(Duration.fromMillis(duration)).toRelative({ locale: "en" });
252
298
  const user = (_a = incident.assignments[0]) == null ? void 0 : _a.assignee;
253
299
  return /* @__PURE__ */ React.createElement(ListItem, { dense: true, key: incident.id }, /* @__PURE__ */ React.createElement(
254
300
  ListItemText,
255
301
  {
256
- primary: /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
302
+ primary: /* @__PURE__ */ React.createElement("div", { className: classes.textContainer }, /* @__PURE__ */ React.createElement(
257
303
  Chip,
258
304
  {
259
305
  "data-testid": `chip-${incident.status}`,
260
306
  label: incident.status,
261
307
  size: "small",
262
308
  variant: "outlined",
263
- icon: incident.status === "acknowledged" ? /* @__PURE__ */ React.createElement(Done, null) : /* @__PURE__ */ React.createElement(Warning, null),
264
309
  className: incident.status === "triggered" ? classes.error : classes.warning
265
310
  }
311
+ ), /* @__PURE__ */ React.createElement(
312
+ Chip,
313
+ {
314
+ "data-testid": `chip-${incident.urgency}`,
315
+ label: `${incident.urgency} urgency`,
316
+ size: "small",
317
+ variant: "outlined",
318
+ className: incident.urgency === "high" ? classes.highUrgency : classes.lowUrgency
319
+ }
266
320
  ), incident.title),
267
321
  primaryTypographyProps: {
268
322
  variant: "body1",
@@ -276,7 +330,7 @@ const IncidentListItem = ({ incident }) => {
276
330
  href: incident.html_url,
277
331
  target: "_blank",
278
332
  rel: "noopener noreferrer",
279
- color: "primary"
333
+ className: classes.smallIconStyle
280
334
  },
281
335
  /* @__PURE__ */ React.createElement(OpenInBrowserIcon, null)
282
336
  ))));
@@ -342,7 +396,7 @@ const Incidents = ({ serviceId, refreshIncidents }) => {
342
396
  return /* @__PURE__ */ React.createElement(List, { dense: true }, incidents.map((incident, index) => /* @__PURE__ */ React.createElement(IncidentListItem, { key: incident.id + index, incident })));
343
397
  };
344
398
 
345
- const useStyles$6 = makeStyles({
399
+ const useStyles$7 = makeStyles({
346
400
  denseListIcon: {
347
401
  marginRight: 0,
348
402
  display: "flex",
@@ -352,11 +406,11 @@ const useStyles$6 = makeStyles({
352
406
  }
353
407
  });
354
408
  const EscalationUsersEmptyState = () => {
355
- const classes = useStyles$6();
409
+ const classes = useStyles$7();
356
410
  return /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(ListItemIcon, null, /* @__PURE__ */ React.createElement("div", { className: classes.denseListIcon }, /* @__PURE__ */ React.createElement(StatusWarning, null))), /* @__PURE__ */ React.createElement(ListItemText, { primary: "No one is on-call. Update the escalation policy." }));
357
411
  };
358
412
 
359
- const useStyles$5 = makeStyles({
413
+ const useStyles$6 = makeStyles({
360
414
  denseListIcon: {
361
415
  marginRight: 0,
362
416
  display: "flex",
@@ -366,11 +420,11 @@ const useStyles$5 = makeStyles({
366
420
  }
367
421
  });
368
422
  const EscalationUsersForbiddenState = () => {
369
- const classes = useStyles$5();
423
+ const classes = useStyles$6();
370
424
  return /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(ListItemIcon, null, /* @__PURE__ */ React.createElement("div", { className: classes.denseListIcon }, /* @__PURE__ */ React.createElement(StatusError, null))), /* @__PURE__ */ React.createElement(ListItemText, { primary: "You don't permissions to list on-calls. Check your OAuth token permissions." }));
371
425
  };
372
426
 
373
- const useStyles$4 = makeStyles((theme) => ({
427
+ const useStyles$5 = makeStyles((theme) => ({
374
428
  listItemPrimary: {
375
429
  fontWeight: "bold"
376
430
  },
@@ -401,11 +455,17 @@ const useStyles$4 = makeStyles((theme) => ({
401
455
  },
402
456
  smallIconStyle: {
403
457
  color: theme.palette.text.primary
458
+ },
459
+ avatarStyle: {
460
+ marginTop: "-20px"
404
461
  }
405
462
  }));
406
- const EscalationUser = ({ user }) => {
407
- const classes = useStyles$4();
408
- return /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(ListItemIcon, null, /* @__PURE__ */ React.createElement(Avatar, { alt: user.name, src: user.avatar_url })), /* @__PURE__ */ React.createElement(
463
+ function navigateToEscalationPolicy(url) {
464
+ window.open(url, "_blank");
465
+ }
466
+ const EscalationUser = ({ user, policyUrl, policyName }) => {
467
+ const classes = useStyles$5();
468
+ 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(
409
469
  ListItemText,
410
470
  {
411
471
  primary: /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Typography, { className: classes.listItemPrimary }, user.name), /* @__PURE__ */ React.createElement(
@@ -420,12 +480,13 @@ const EscalationUser = ({ user }) => {
420
480
  IconButton,
421
481
  {
422
482
  "aria-label": "open-service-in-browser",
483
+ onClick: () => navigateToEscalationPolicy(policyUrl),
423
484
  className: classes.buttonStyle
424
485
  },
425
- /* @__PURE__ */ React.createElement("span", { className: classes.containerStyle }, /* @__PURE__ */ React.createElement(NotificationsIcon, { className: classes.iconStyle }), "Web Team")
486
+ /* @__PURE__ */ React.createElement("span", { className: classes.containerStyle }, /* @__PURE__ */ React.createElement(NotificationsIcon, { className: classes.iconStyle }), policyName)
426
487
  )
427
488
  }
428
- ), /* @__PURE__ */ React.createElement(ListItemSecondaryAction, null, /* @__PURE__ */ React.createElement(Tooltip, { title: "Send e-mail to user", placement: "top" }, /* @__PURE__ */ React.createElement(IconButton, { href: `mailto:${user.email}` }, /* @__PURE__ */ React.createElement(MailOutline, { className: classes.smallIconStyle }))), /* @__PURE__ */ React.createElement(Tooltip, { title: "View in PagerDuty", placement: "top" }, /* @__PURE__ */ React.createElement(
489
+ ), /* @__PURE__ */ React.createElement(ListItemSecondaryAction, null, /* @__PURE__ */ React.createElement(Tooltip, { title: "Open user in PagerDuty", placement: "top" }, /* @__PURE__ */ React.createElement(
429
490
  IconButton,
430
491
  {
431
492
  href: user.html_url,
@@ -437,7 +498,7 @@ const EscalationUser = ({ user }) => {
437
498
  ))));
438
499
  };
439
500
 
440
- const EscalationPolicy = ({ policyId }) => {
501
+ const EscalationPolicy = ({ policyId, policyUrl, policyName }) => {
441
502
  const api = useApi(pagerDutyApiRef);
442
503
  const {
443
504
  value: users,
@@ -458,7 +519,7 @@ const EscalationPolicy = ({ policyId }) => {
458
519
  if (!(users == null ? void 0 : users.length)) {
459
520
  return /* @__PURE__ */ React.createElement(EscalationUsersEmptyState, null);
460
521
  }
461
- return /* @__PURE__ */ React.createElement(List, { dense: true, subheader: /* @__PURE__ */ React.createElement(ListSubheader, null, "ON CALL") }, users.map((user, index) => /* @__PURE__ */ React.createElement(EscalationUser, { key: index, user })));
522
+ return /* @__PURE__ */ React.createElement(List, { dense: true, subheader: /* @__PURE__ */ React.createElement(ListSubheader, null, "ON CALL"), style: { marginLeft: "-15px" } }, users.map((user, index) => /* @__PURE__ */ React.createElement(EscalationUser, { key: index, user, policyUrl, policyName })));
462
523
  };
463
524
 
464
525
  const MissingTokenError = () => /* @__PURE__ */ React.createElement(
@@ -497,91 +558,7 @@ const ServiceNotFoundError = () => /* @__PURE__ */ React.createElement(
497
558
  }
498
559
  );
499
560
 
500
- const TriggerDialog = ({
501
- showDialog,
502
- handleDialog,
503
- onIncidentCreated,
504
- name,
505
- integrationKey
506
- }) => {
507
- const alertApi = useApi(alertApiRef);
508
- const identityApi = useApi(identityApiRef);
509
- const api = useApi(pagerDutyApiRef);
510
- const [description, setDescription] = useState("");
511
- const [{ value, loading, error }, handleTriggerAlarm] = useAsyncFn(
512
- async (descriptions) => {
513
- const { userEntityRef } = await identityApi.getBackstageIdentity();
514
- const { name: userName } = parseEntityRef(userEntityRef, {
515
- defaultKind: "User",
516
- defaultNamespace: DEFAULT_NAMESPACE
517
- });
518
- return await api.triggerAlarm({
519
- integrationKey,
520
- source: window.location.toString(),
521
- description: descriptions,
522
- userName
523
- });
524
- }
525
- );
526
- const descriptionChanged = (event) => {
527
- setDescription(event.target.value);
528
- };
529
- useEffect(() => {
530
- if (value) {
531
- (async () => {
532
- alertApi.post({
533
- message: `Alarm successfully triggered`
534
- });
535
- handleDialog();
536
- await new Promise((resolve) => setTimeout(resolve, 1e3));
537
- onIncidentCreated == null ? void 0 : onIncidentCreated();
538
- })();
539
- }
540
- }, [value, alertApi, handleDialog, onIncidentCreated]);
541
- if (error) {
542
- alertApi.post({
543
- message: `Failed to trigger alarm. ${error.message}`,
544
- severity: "error"
545
- });
546
- }
547
- 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, '"', name, '"'), "."), /* @__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(
548
- Typography,
549
- {
550
- variant: "body1",
551
- style: { marginTop: "1em" },
552
- gutterBottom: true,
553
- align: "justify"
554
- },
555
- "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."
556
- ), /* @__PURE__ */ React.createElement(
557
- TextField,
558
- {
559
- inputProps: { "data-testid": "trigger-input" },
560
- id: "description",
561
- multiline: true,
562
- fullWidth: true,
563
- rows: "4",
564
- margin: "normal",
565
- label: "Problem description",
566
- variant: "outlined",
567
- onChange: descriptionChanged
568
- }
569
- )), /* @__PURE__ */ React.createElement(DialogActions, null, /* @__PURE__ */ React.createElement(
570
- Button,
571
- {
572
- "data-testid": "trigger-button",
573
- id: "trigger",
574
- color: "secondary",
575
- disabled: !description || loading,
576
- variant: "contained",
577
- onClick: () => handleTriggerAlarm(description),
578
- endIcon: loading && /* @__PURE__ */ React.createElement(CircularProgress, { size: 16 })
579
- },
580
- "Trigger Incident"
581
- ), /* @__PURE__ */ React.createElement(Button, { id: "close", color: "primary", onClick: handleDialog }, "Close")));
582
- };
583
-
584
- const useStyles$3 = makeStyles({
561
+ const useStyles$4 = makeStyles((theme) => ({
585
562
  denseListIcon: {
586
563
  marginRight: 0,
587
564
  display: "flex",
@@ -591,10 +568,17 @@ const useStyles$3 = makeStyles({
591
568
  },
592
569
  listItemPrimary: {
593
570
  fontWeight: "bold"
571
+ },
572
+ smallExternalLinkIconStyle: {
573
+ color: theme.palette.text.primary
574
+ },
575
+ smallIconStyle: {
576
+ color: theme.palette.text.primary,
577
+ marginRight: "-20px"
594
578
  }
595
- });
579
+ }));
596
580
  const ChangeEventListItem = ({ changeEvent }) => {
597
- const classes = useStyles$3();
581
+ const classes = useStyles$4();
598
582
  const duration = (/* @__PURE__ */ new Date()).getTime() - new Date(changeEvent.timestamp).getTime();
599
583
  const changedAt = DateTime.local().minus(Duration.fromMillis(duration)).toRelative({ locale: "en" });
600
584
  let externalLinkElem;
@@ -605,9 +589,9 @@ const ChangeEventListItem = ({ changeEvent }) => {
605
589
  {
606
590
  component: Link,
607
591
  to: changeEvent.links[0].href,
608
- color: "primary"
592
+ className: classes.smallExternalLinkIconStyle
609
593
  },
610
- /* @__PURE__ */ React.createElement(OpenInBrowserIcon, null)
594
+ /* @__PURE__ */ React.createElement(LinkIcon, null)
611
595
  ));
612
596
  }
613
597
  return /* @__PURE__ */ React.createElement(ListItem, { dense: true, key: changeEvent.id }, /* @__PURE__ */ React.createElement(
@@ -625,7 +609,7 @@ const ChangeEventListItem = ({ changeEvent }) => {
625
609
  {
626
610
  component: Link,
627
611
  to: changeEvent.html_url,
628
- color: "primary"
612
+ className: classes.smallIconStyle
629
613
  },
630
614
  /* @__PURE__ */ React.createElement(OpenInBrowserIcon, null)
631
615
  ))));
@@ -708,7 +692,91 @@ function usePagerdutyEntity() {
708
692
  return getPagerDutyEntity(entity);
709
693
  }
710
694
 
711
- const useStyles$2 = makeStyles((theme) => ({
695
+ const TriggerDialog = ({
696
+ showDialog,
697
+ handleDialog,
698
+ onIncidentCreated,
699
+ name,
700
+ integrationKey
701
+ }) => {
702
+ const alertApi = useApi(alertApiRef);
703
+ const identityApi = useApi(identityApiRef);
704
+ const api = useApi(pagerDutyApiRef);
705
+ const [description, setDescription] = useState("");
706
+ const [{ value, loading, error }, handleTriggerAlarm] = useAsyncFn(
707
+ async (descriptions) => {
708
+ const { userEntityRef } = await identityApi.getBackstageIdentity();
709
+ const { name: userName } = parseEntityRef(userEntityRef, {
710
+ defaultKind: "User",
711
+ defaultNamespace: DEFAULT_NAMESPACE
712
+ });
713
+ return await api.triggerAlarm({
714
+ integrationKey,
715
+ source: window.location.toString(),
716
+ description: descriptions,
717
+ userName
718
+ });
719
+ }
720
+ );
721
+ const descriptionChanged = (event) => {
722
+ setDescription(event.target.value);
723
+ };
724
+ useEffect(() => {
725
+ if (value) {
726
+ (async () => {
727
+ alertApi.post({
728
+ message: `Alarm successfully triggered`
729
+ });
730
+ handleDialog();
731
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
732
+ onIncidentCreated == null ? void 0 : onIncidentCreated();
733
+ })();
734
+ }
735
+ }, [value, alertApi, handleDialog, onIncidentCreated]);
736
+ if (error) {
737
+ alertApi.post({
738
+ message: `Failed to trigger alarm. ${error.message}`,
739
+ severity: "error"
740
+ });
741
+ }
742
+ 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, '"', name, '"'), "."), /* @__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(
743
+ Typography,
744
+ {
745
+ variant: "body1",
746
+ style: { marginTop: "1em" },
747
+ gutterBottom: true,
748
+ align: "justify"
749
+ },
750
+ "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."
751
+ ), /* @__PURE__ */ React.createElement(
752
+ TextField,
753
+ {
754
+ inputProps: { "data-testid": "trigger-input" },
755
+ id: "description",
756
+ multiline: true,
757
+ fullWidth: true,
758
+ rows: "4",
759
+ margin: "normal",
760
+ label: "Problem description",
761
+ variant: "outlined",
762
+ onChange: descriptionChanged
763
+ }
764
+ )), /* @__PURE__ */ React.createElement(DialogActions, null, /* @__PURE__ */ React.createElement(
765
+ Button,
766
+ {
767
+ "data-testid": "trigger-button",
768
+ id: "trigger",
769
+ color: "secondary",
770
+ disabled: !description || loading,
771
+ variant: "contained",
772
+ onClick: () => handleTriggerAlarm(description),
773
+ endIcon: loading && /* @__PURE__ */ React.createElement(CircularProgress, { size: 16 })
774
+ },
775
+ "Trigger Incident"
776
+ ), /* @__PURE__ */ React.createElement(Button, { id: "close", color: "primary", onClick: handleDialog }, "Close")));
777
+ };
778
+
779
+ const useStyles$3 = makeStyles((theme) => ({
712
780
  buttonStyle: {
713
781
  color: theme.palette.text.primary,
714
782
  "&:hover": {
@@ -727,8 +795,8 @@ const useStyles$2 = makeStyles((theme) => ({
727
795
  marginBottom: "-10px"
728
796
  }
729
797
  }));
730
- function TriggerIncidentButton() {
731
- const { buttonStyle, containerStyle, iconStyle } = useStyles$2();
798
+ function TriggerIncidentButton({ handleRefresh }) {
799
+ const { buttonStyle, containerStyle, iconStyle } = useStyles$3();
732
800
  const { integrationKey, name } = usePagerdutyEntity();
733
801
  const [dialogShown, setDialogShown] = useState(false);
734
802
  const showDialog = useCallback(() => {
@@ -746,19 +814,20 @@ function TriggerIncidentButton() {
746
814
  className: disabled ? "" : buttonStyle,
747
815
  disabled
748
816
  },
749
- /* @__PURE__ */ React.createElement("div", { className: containerStyle }, /* @__PURE__ */ React.createElement(AddAlert, { className: iconStyle }), /* @__PURE__ */ React.createElement("p", null, "Create New Incident"))
817
+ /* @__PURE__ */ React.createElement("div", { className: containerStyle }, /* @__PURE__ */ React.createElement(AddAlert, { className: iconStyle }), /* @__PURE__ */ React.createElement("p", null, "Create new incident"))
750
818
  ), integrationKey && /* @__PURE__ */ React.createElement(
751
819
  TriggerDialog,
752
820
  {
753
821
  showDialog: dialogShown,
754
822
  handleDialog: hideDialog,
755
823
  integrationKey,
756
- name
824
+ name,
825
+ onIncidentCreated: handleRefresh
757
826
  }
758
827
  ));
759
828
  }
760
829
 
761
- const useStyles$1 = makeStyles((theme) => ({
830
+ const useStyles$2 = makeStyles((theme) => ({
762
831
  buttonStyle: {
763
832
  color: theme.palette.text.primary,
764
833
  "&:hover": {
@@ -778,7 +847,7 @@ const useStyles$1 = makeStyles((theme) => ({
778
847
  }
779
848
  }));
780
849
  function OpenServiceButton(props) {
781
- const { buttonStyle, containerStyle, iconStyle } = useStyles$1();
850
+ const { buttonStyle, containerStyle, iconStyle } = useStyles$2();
782
851
  function navigateToService() {
783
852
  window.open(props.serviceUrl, "_blank");
784
853
  }
@@ -793,20 +862,228 @@ function OpenServiceButton(props) {
793
862
  ));
794
863
  }
795
864
 
865
+ function labelFromStatus(status) {
866
+ let label;
867
+ switch (status) {
868
+ case "active":
869
+ label = "OK";
870
+ break;
871
+ case "warning":
872
+ label = "ACTIVE";
873
+ break;
874
+ case "critical":
875
+ label = "ALARM";
876
+ break;
877
+ case "maintenance":
878
+ label = "MAINTENANCE";
879
+ break;
880
+ case "disabled":
881
+ label = "DISABLED";
882
+ break;
883
+ default:
884
+ label = "OK";
885
+ break;
886
+ }
887
+ return label;
888
+ }
889
+ function colorFromStatus(theme, status) {
890
+ let color;
891
+ switch (status) {
892
+ case "active":
893
+ color = theme.palette.success.main;
894
+ break;
895
+ case "warning":
896
+ color = theme.palette.warningBackground;
897
+ break;
898
+ case "critical":
899
+ color = theme.palette.error.main;
900
+ break;
901
+ case "maintenance":
902
+ color = "#ebdc00";
903
+ break;
904
+ case "disabled":
905
+ color = "#A9A9A9";
906
+ break;
907
+ default:
908
+ color = theme.palette.success.main;
909
+ break;
910
+ }
911
+ return color;
912
+ }
913
+ function StatusCard({ serviceId, refreshStatus }) {
914
+ const api = useApi(pagerDutyApiRef);
915
+ const [{ value: status, loading, error }, getStatus] = useAsyncFn$1(
916
+ async () => {
917
+ const { service: foundService } = await api.getServiceById(serviceId);
918
+ return foundService.status;
919
+ }
920
+ );
921
+ const useStyles = makeStyles$1((theme) => ({
922
+ cardStyle: {
923
+ height: "120px",
924
+ display: "flex",
925
+ alignItems: "center",
926
+ justifyContent: "center",
927
+ backgroundColor: status !== void 0 ? colorFromStatus(theme, status) : colorFromStatus(theme, "active"),
928
+ marginRight: "10px"
929
+ },
930
+ largeTextStyle: {
931
+ color: "white",
932
+ fontWeight: "bold",
933
+ fontSize: "20px",
934
+ wordWrap: "break-word"
935
+ }
936
+ }));
937
+ const { cardStyle, largeTextStyle } = useStyles();
938
+ useEffect(() => {
939
+ getStatus();
940
+ }, [refreshStatus, getStatus]);
941
+ if (error) {
942
+ if (error.message.includes("Forbidden")) {
943
+ return /* @__PURE__ */ React.createElement("p", null, "forbidden");
944
+ }
945
+ return /* @__PURE__ */ React.createElement(Alert$1, { severity: "error" }, "Error encountered while fetching information. ", error.message);
946
+ }
947
+ if (loading) {
948
+ return /* @__PURE__ */ React.createElement(Progress, null);
949
+ }
950
+ if (!status) {
951
+ return /* @__PURE__ */ React.createElement("p", null, "not found");
952
+ }
953
+ 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"));
954
+ }
955
+
956
+ function colorFromPercentage(theme, percentage) {
957
+ if (percentage < 0.5) {
958
+ return theme.palette.error.main;
959
+ } else if (percentage < 0.8) {
960
+ return theme.palette.warning.main;
961
+ }
962
+ return theme.palette.success.main;
963
+ }
964
+ function ServiceStandardsCard({ total, completed }) {
965
+ const useStyles = makeStyles((theme) => ({
966
+ cardStyle: {
967
+ height: "120px",
968
+ display: "grid",
969
+ gridTemplateRows: "1fr auto auto",
970
+ backgroundColor: "rgba(0, 0, 0, 0.03)"
971
+ },
972
+ containerStyle: {
973
+ display: "flex",
974
+ justifyContent: "center"
975
+ },
976
+ largeTextStyle: {
977
+ fontSize: "50px",
978
+ color: completed !== void 0 && total !== void 0 ? colorFromPercentage(theme, completed / total) : colorFromPercentage(theme, 0),
979
+ alignSelf: "center",
980
+ justifyContent: "center"
981
+ },
982
+ smallTextStyle: {
983
+ color: theme.palette.textSubtle,
984
+ fontSize: "14px",
985
+ fontWeight: "bold",
986
+ alignSelf: "center",
987
+ justifyContent: "center",
988
+ marginLeft: "-2px",
989
+ marginTop: "25px"
990
+ }
991
+ }));
992
+ const BorderLinearProgress = withStyles((theme) => ({
993
+ root: {
994
+ height: 10,
995
+ borderRadius: 5,
996
+ margin: 5
997
+ },
998
+ colorPrimary: {
999
+ backgroundColor: theme.palette.grey[theme.palette.type === "light" ? 200 : 700]
1000
+ },
1001
+ bar: {
1002
+ borderRadius: 5,
1003
+ backgroundColor: completed !== void 0 && total !== void 0 ? colorFromPercentage(theme, completed / total) : colorFromPercentage(theme, 0)
1004
+ }
1005
+ }))(LinearProgress);
1006
+ const { cardStyle, containerStyle, largeTextStyle, smallTextStyle } = useStyles();
1007
+ return /* @__PURE__ */ React.createElement(Card, { className: cardStyle }, completed !== void 0 && total !== void 0 ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: containerStyle }, /* @__PURE__ */ React.createElement(Typography, { className: largeTextStyle }, completed), /* @__PURE__ */ React.createElement(Typography, { className: smallTextStyle }, "/", total)), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(
1008
+ BorderLinearProgress,
1009
+ {
1010
+ variant: "determinate",
1011
+ value: completed / total * 100
1012
+ }
1013
+ ))) : /* @__PURE__ */ React.createElement("div", { className: containerStyle }, /* @__PURE__ */ React.createElement(Typography, { className: largeTextStyle }, "Unable to retrieve Scores")));
1014
+ }
1015
+
1016
+ function IncidentCounterCard({ count, label, color }) {
1017
+ const textColor = color && validateColor(color) ? color : "black";
1018
+ const useStyles = makeStyles(() => ({
1019
+ cardStyle: {
1020
+ marginRight: "10px",
1021
+ height: "120px",
1022
+ display: "flex",
1023
+ alignItems: "center",
1024
+ justifyContent: "center",
1025
+ backgroundColor: "rgba(0, 0, 0, 0.03)"
1026
+ },
1027
+ largeTextStyle: {
1028
+ color: textColor,
1029
+ fontSize: "30px",
1030
+ marginTop: "-10px"
1031
+ },
1032
+ smallTextStyle: {
1033
+ color: textColor,
1034
+ fontWeight: "bold",
1035
+ fontSize: "10px",
1036
+ marginTop: "-5px",
1037
+ textTransform: "uppercase",
1038
+ flexWrap: "wrap"
1039
+ }
1040
+ }));
1041
+ const { cardStyle, largeTextStyle, smallTextStyle } = useStyles();
1042
+ return /* @__PURE__ */ React.createElement(Card, { className: cardStyle }, /* @__PURE__ */ React.createElement(Typography, { className: largeTextStyle }, count), /* @__PURE__ */ React.createElement(Typography, { className: smallTextStyle }, label));
1043
+ }
1044
+
1045
+ const useStyles$1 = makeStyles$1(
1046
+ (theme) => createStyles({
1047
+ overviewHeaderTextStyle: {
1048
+ fontSize: "14px",
1049
+ fontWeight: 500,
1050
+ color: theme.palette.type === "light" ? "rgba(0, 0, 0, 0.54)" : "rgba(255, 255, 255, 0.7)"
1051
+ },
1052
+ headerStyle: {
1053
+ marginRight: "1em"
1054
+ },
1055
+ overviewHeaderContainerStyle: {
1056
+ display: "flex",
1057
+ margin: "15px",
1058
+ marginBottom: "20px"
1059
+ },
1060
+ overviewCardsContainerStyle: {
1061
+ display: "flex",
1062
+ margin: "15px",
1063
+ marginTop: "-15px"
1064
+ },
1065
+ incidentMetricsContainerStyle: {
1066
+ display: "flex",
1067
+ height: "100%",
1068
+ justifyContent: "center",
1069
+ columnSpan: "all"
1070
+ }
1071
+ })
1072
+ );
796
1073
  const BasicCard = ({ children }) => /* @__PURE__ */ React.createElement(InfoCard, { title: "PagerDuty" }, children);
797
1074
  const PagerDutyCard$1 = (props) => {
1075
+ var _a, _b;
1076
+ const classes = useStyles$1();
798
1077
  const theme = useTheme();
799
- const { readOnly, disableChangeEvents, integrationKey, name } = props;
1078
+ const { readOnly, disableChangeEvents } = props;
800
1079
  const api = useApi(pagerDutyApiRef);
801
1080
  const [refreshIncidents, setRefreshIncidents] = useState(false);
802
1081
  const [refreshChangeEvents, setRefreshChangeEvents] = useState(false);
803
- const [dialogShown, setDialogShown] = useState(false);
804
- const hideDialog = useCallback(() => {
805
- setDialogShown(false);
806
- }, [setDialogShown]);
1082
+ const [refreshStatus, setRefreshStatus] = useState(false);
807
1083
  const handleRefresh = useCallback(() => {
808
1084
  setRefreshIncidents((x) => !x);
809
1085
  setRefreshChangeEvents((x) => !x);
1086
+ setRefreshStatus((x) => !x);
810
1087
  }, []);
811
1088
  const {
812
1089
  value: service,
@@ -816,13 +1093,18 @@ const PagerDutyCard$1 = (props) => {
816
1093
  const { service: foundService } = await api.getServiceByPagerDutyEntity(
817
1094
  props
818
1095
  );
819
- return {
1096
+ const { standards: serviceStandards } = await api.getServiceStandardsByServiceId(foundService.id);
1097
+ const result = {
820
1098
  id: foundService.id,
821
1099
  name: foundService.name,
822
1100
  url: foundService.html_url,
823
1101
  policyId: foundService.escalation_policy.id,
824
- policyLink: foundService.escalation_policy.html_url
1102
+ policyLink: foundService.escalation_policy.html_url,
1103
+ policyName: foundService.escalation_policy.name,
1104
+ status: foundService.status,
1105
+ standardsScore: serviceStandards.score
825
1106
  };
1107
+ return result;
826
1108
  }, [props]);
827
1109
  if (error) {
828
1110
  let errorNode;
@@ -841,250 +1123,41 @@ const PagerDutyCard$1 = (props) => {
841
1123
  if (loading) {
842
1124
  return /* @__PURE__ */ React.createElement(BasicCard, null, /* @__PURE__ */ React.createElement(Progress, null));
843
1125
  }
844
- const createIncidentDisabled = !integrationKey;
845
1126
  return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Card, { "data-testid": "pagerduty-card" }, /* @__PURE__ */ React.createElement(
846
1127
  CardHeader,
847
1128
  {
848
- style: { marginRight: "1em" },
1129
+ className: classes.headerStyle,
849
1130
  title: theme.palette.type === "dark" ? /* @__PURE__ */ React.createElement("img", { src: PDWhiteImage, alt: "PagerDuty", height: "35" }) : /* @__PURE__ */ React.createElement("img", { src: PDGreenImage, alt: "PagerDuty", height: "35" }),
850
- action: !readOnly ? /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(TriggerIncidentButton, null), /* @__PURE__ */ React.createElement(OpenServiceButton, { serviceUrl: service.url })) : /* @__PURE__ */ React.createElement(OpenServiceButton, { serviceUrl: service.url })
1131
+ action: !readOnly ? /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(TriggerIncidentButton, { handleRefresh }), /* @__PURE__ */ React.createElement(OpenServiceButton, { serviceUrl: service.url })) : /* @__PURE__ */ React.createElement(OpenServiceButton, { serviceUrl: service.url })
851
1132
  }
852
- ), /* @__PURE__ */ React.createElement(Grid, { item: true, md: 12, style: { display: "flex", margin: "15px" } }, /* @__PURE__ */ React.createElement(Grid, { item: true, md: 3 }, /* @__PURE__ */ React.createElement(Typography, { style: { fontSize: "16px", fontWeight: "bold" } }, "STATUS")), /* @__PURE__ */ React.createElement(Grid, { item: true, md: 6 }, /* @__PURE__ */ React.createElement(Typography, { style: { fontSize: "16px", fontWeight: "bold" } }, "INCIDENT HISTORY")), /* @__PURE__ */ React.createElement(Grid, { item: true, md: 3 }, /* @__PURE__ */ React.createElement(
853
- Typography,
1133
+ ), /* @__PURE__ */ React.createElement(Grid, { item: true, md: 12, className: classes.overviewHeaderContainerStyle }, /* @__PURE__ */ React.createElement(Grid, { item: true, md: 3 }, /* @__PURE__ */ React.createElement(Typography, { className: classes.overviewHeaderTextStyle }, "STATUS")), /* @__PURE__ */ React.createElement(Grid, { item: true, md: 6 }, /* @__PURE__ */ React.createElement(Typography, { className: classes.overviewHeaderTextStyle }, "INSIGHTS")), /* @__PURE__ */ React.createElement(Grid, { item: true, md: 3 }, /* @__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: 3 }, /* @__PURE__ */ React.createElement(StatusCard, { serviceId: service.id, refreshStatus })), /* @__PURE__ */ React.createElement(Grid, { item: true, md: 6, className: classes.incidentMetricsContainerStyle }, /* @__PURE__ */ React.createElement(Grid, { md: 4 }, /* @__PURE__ */ React.createElement(
1134
+ IncidentCounterCard,
854
1135
  {
855
- style: {
856
- fontSize: "16px",
857
- fontWeight: "bold",
858
- marginLeft: "10px"
859
- }
860
- },
861
- "SERVICE STANDARDS"
862
- ))), /* @__PURE__ */ React.createElement(
863
- Grid,
1136
+ count: 29,
1137
+ label: "interruptions",
1138
+ color: theme.palette.textSubtle
1139
+ }
1140
+ )), /* @__PURE__ */ React.createElement(Grid, { md: 4 }, /* @__PURE__ */ React.createElement(
1141
+ IncidentCounterCard,
864
1142
  {
865
- item: true,
866
- md: 12,
867
- style: { display: "flex", margin: "15px", marginTop: "-15px" }
868
- },
869
- /* @__PURE__ */ React.createElement(Grid, { item: true, md: 3 }, /* @__PURE__ */ React.createElement(
870
- Card,
871
- {
872
- style: {
873
- background: "darkRed",
874
- marginRight: "20px",
875
- height: "150px",
876
- display: "flex",
877
- alignItems: "center",
878
- justifyContent: "center"
879
- }
880
- },
881
- /* @__PURE__ */ React.createElement(
882
- Typography,
883
- {
884
- variant: "h3",
885
- style: { color: "white", fontWeight: "bold" }
886
- },
887
- "ALARM"
888
- ),
889
- /* @__PURE__ */ React.createElement(
890
- Typography,
891
- {
892
- style: {
893
- alignSelf: "start",
894
- position: "absolute",
895
- verticalAlign: "bottom",
896
- marginTop: "120px",
897
- marginLeft: "10px",
898
- color: "white"
899
- }
900
- },
901
- "Last triggered 8 minutes ago"
902
- )
903
- )),
904
- /* @__PURE__ */ React.createElement(
905
- Grid,
906
- {
907
- item: true,
908
- md: 6,
909
- style: {
910
- display: "flex",
911
- height: "100%",
912
- justifyContent: "center",
913
- columnSpan: "all"
914
- }
915
- },
916
- /* @__PURE__ */ React.createElement(Grid, { md: 4, style: { height: "100%" } }, /* @__PURE__ */ React.createElement(
917
- Card,
918
- {
919
- style: {
920
- marginRight: "10px",
921
- height: "150px",
922
- display: "flex",
923
- alignItems: "center",
924
- justifyContent: "center"
925
- }
926
- },
927
- /* @__PURE__ */ React.createElement(
928
- Typography,
929
- {
930
- style: {
931
- color: "red",
932
- fontSize: "50px"
933
- }
934
- },
935
- "1"
936
- ),
937
- /* @__PURE__ */ React.createElement(
938
- Typography,
939
- {
940
- style: {
941
- color: "red",
942
- fontWeight: "bold",
943
- fontSize: "10px"
944
- }
945
- },
946
- "TRIGGERED"
947
- )
948
- )),
949
- /* @__PURE__ */ React.createElement(Grid, { md: 4 }, /* @__PURE__ */ React.createElement(
950
- Card,
951
- {
952
- style: {
953
- marginRight: "10px",
954
- height: "150px",
955
- display: "flex",
956
- alignItems: "center",
957
- justifyContent: "center"
958
- }
959
- },
960
- /* @__PURE__ */ React.createElement(
961
- Typography,
962
- {
963
- style: {
964
- color: "orange",
965
- fontSize: "50px"
966
- }
967
- },
968
- "1"
969
- ),
970
- /* @__PURE__ */ React.createElement(
971
- Typography,
972
- {
973
- style: {
974
- color: "orange",
975
- fontWeight: "bold",
976
- fontSize: "10px"
977
- }
978
- },
979
- "ACKNOWLEDGED"
980
- )
981
- )),
982
- /* @__PURE__ */ React.createElement(Grid, { md: 4 }, /* @__PURE__ */ React.createElement(
983
- Card,
984
- {
985
- style: {
986
- marginRight: "10px",
987
- height: "150px",
988
- display: "flex",
989
- alignItems: "center",
990
- justifyContent: "center"
991
- }
992
- },
993
- /* @__PURE__ */ React.createElement(
994
- Typography,
995
- {
996
- style: {
997
- color: "green",
998
- fontSize: "50px"
999
- }
1000
- },
1001
- "43"
1002
- ),
1003
- /* @__PURE__ */ React.createElement(
1004
- Typography,
1005
- {
1006
- style: {
1007
- color: "green",
1008
- fontWeight: "bold",
1009
- fontSize: "10px"
1010
- }
1011
- },
1012
- "RESOLVED"
1013
- )
1014
- ))
1015
- ),
1016
- /* @__PURE__ */ React.createElement(Grid, { item: true, md: 3 }, /* @__PURE__ */ React.createElement(
1017
- Card,
1018
- {
1019
- style: {
1020
- height: "150px",
1021
- display: "grid",
1022
- gridTemplateRows: "1fr auto auto"
1023
- }
1024
- },
1025
- /* @__PURE__ */ React.createElement(
1026
- "div",
1027
- {
1028
- style: {
1029
- display: "flex",
1030
- justifyContent: "center",
1031
- marginTop: "30px"
1032
- }
1033
- },
1034
- /* @__PURE__ */ React.createElement(
1035
- Typography,
1036
- {
1037
- style: {
1038
- fontSize: "50px",
1039
- color: "black",
1040
- fontWeight: "bold",
1041
- alignSelf: "center",
1042
- justifyContent: "center"
1043
- }
1044
- },
1045
- "4"
1046
- ),
1047
- /* @__PURE__ */ React.createElement(
1048
- Typography,
1049
- {
1050
- variant: "body1",
1051
- style: {
1052
- color: "black",
1053
- alignSelf: "center",
1054
- justifyContent: "center",
1055
- marginLeft: "1px",
1056
- marginTop: "20px"
1057
- }
1058
- },
1059
- "/5"
1060
- )
1061
- ),
1062
- /* @__PURE__ */ React.createElement("div", { style: { display: "flex", flexDirection: "row-reverse" } }, /* @__PURE__ */ React.createElement(
1063
- Typography,
1064
- {
1065
- style: {
1066
- justifyContent: "end",
1067
- color: "gray",
1068
- textDecoration: "underline",
1069
- marginRight: "5px"
1070
- }
1071
- },
1072
- "See service standards"
1073
- )),
1074
- /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(
1075
- LinearProgress,
1076
- {
1077
- variant: "determinate",
1078
- value: 80,
1079
- style: {
1080
- margin: "5px",
1081
- borderRadius: "10px",
1082
- height: "10px"
1083
- }
1084
- }
1085
- ))
1086
- ))
1087
- ), /* @__PURE__ */ React.createElement(Divider, null), /* @__PURE__ */ React.createElement(CardContent, null, /* @__PURE__ */ React.createElement(TabbedCard, null, /* @__PURE__ */ React.createElement(CardTab, { label: "Incidents" }, /* @__PURE__ */ React.createElement(
1143
+ count: 29,
1144
+ label: "high urgency",
1145
+ color: theme.palette.warning.main
1146
+ }
1147
+ )), /* @__PURE__ */ React.createElement(Grid, { md: 4 }, /* @__PURE__ */ React.createElement(
1148
+ IncidentCounterCard,
1149
+ {
1150
+ count: 32,
1151
+ label: "incidents",
1152
+ color: theme.palette.error.main
1153
+ }
1154
+ ))), /* @__PURE__ */ React.createElement(Grid, { item: true, md: 3 }, /* @__PURE__ */ React.createElement(
1155
+ ServiceStandardsCard,
1156
+ {
1157
+ total: (_a = service == null ? void 0 : service.standardsScore) == null ? void 0 : _a.total,
1158
+ completed: (_b = service == null ? void 0 : service.standardsScore) == null ? void 0 : _b.passing
1159
+ }
1160
+ ))), /* @__PURE__ */ React.createElement(Divider, null), /* @__PURE__ */ React.createElement(CardContent, null, /* @__PURE__ */ React.createElement(TabbedCard, null, /* @__PURE__ */ React.createElement(CardTab, { label: "Incidents" }, /* @__PURE__ */ React.createElement(
1088
1161
  Incidents,
1089
1162
  {
1090
1163
  serviceId: service.id,
@@ -1096,17 +1169,14 @@ const PagerDutyCard$1 = (props) => {
1096
1169
  serviceId: service.id,
1097
1170
  refreshEvents: refreshChangeEvents
1098
1171
  }
1099
- )) : /* @__PURE__ */ React.createElement(React.Fragment, null)), /* @__PURE__ */ React.createElement(EscalationPolicy, { policyId: service.policyId }))), !createIncidentDisabled && /* @__PURE__ */ React.createElement(
1100
- TriggerDialog,
1172
+ )) : /* @__PURE__ */ React.createElement(React.Fragment, null)), /* @__PURE__ */ React.createElement(
1173
+ EscalationPolicy,
1101
1174
  {
1102
- "data-testid": "trigger-dialog",
1103
- showDialog: dialogShown,
1104
- handleDialog: hideDialog,
1105
- onIncidentCreated: handleRefresh,
1106
- name,
1107
- integrationKey
1175
+ policyId: service.policyId,
1176
+ policyUrl: service.policyLink,
1177
+ policyName: service.policyName
1108
1178
  }
1109
- ));
1179
+ ))));
1110
1180
  };
1111
1181
 
1112
1182
  const isPluginApplicableToEntity = (entity) => {
@@ -1164,7 +1234,7 @@ function TriggerButton(props) {
1164
1234
  className: disabled ? "" : buttonStyle,
1165
1235
  disabled
1166
1236
  },
1167
- integrationKey ? (_a = props.children) != null ? _a : "Create Incident" : "Missing integration key"
1237
+ integrationKey ? (_a = props.children) != null ? _a : "Create new incident" : "Missing integration key"
1168
1238
  ), integrationKey && /* @__PURE__ */ React.createElement(
1169
1239
  TriggerDialog,
1170
1240
  {
@@ -1179,4 +1249,4 @@ function TriggerButton(props) {
1179
1249
  const PagerDutyCard = EntityPagerDutyCard;
1180
1250
 
1181
1251
  export { EntityPagerDutyCard$1 as E, HomePagePagerDutyCard as H, PagerDutyCard$1 as P, TriggerButton as T, UnauthorizedError as U, PagerDutyClient as a, pagerDutyApiRef as b, PagerDutyCard as c, isPluginApplicableToEntity as i, pagerDutyPlugin as p };
1182
- //# sourceMappingURL=index-46807363.esm.js.map
1252
+ //# sourceMappingURL=index-05ed342b.esm.js.map