@pagerduty/backstage-plugin 0.12.1-next.97 → 0.12.1-next.99

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.
Files changed (78) hide show
  1. package/dist/api/client.esm.js +151 -0
  2. package/dist/api/client.esm.js.map +1 -0
  3. package/dist/components/ChangeEvents/ChangeEventEmptyState.esm.js +17 -0
  4. package/dist/components/ChangeEvents/ChangeEventEmptyState.esm.js.map +1 -0
  5. package/dist/components/ChangeEvents/ChangeEventForbiddenState.esm.js +17 -0
  6. package/dist/components/ChangeEvents/ChangeEventForbiddenState.esm.js.map +1 -0
  7. package/dist/components/ChangeEvents/ChangeEventListItem.esm.js +70 -0
  8. package/dist/components/ChangeEvents/ChangeEventListItem.esm.js.map +1 -0
  9. package/dist/components/ChangeEvents/ChangeEvents.esm.js +45 -0
  10. package/dist/components/ChangeEvents/ChangeEvents.esm.js.map +1 -0
  11. package/dist/components/EntityPagerDutyCard/index.esm.js +29 -0
  12. package/dist/components/EntityPagerDutyCard/index.esm.js.map +1 -0
  13. package/dist/components/EntityPagerDutySmallCard/index.esm.js +29 -0
  14. package/dist/components/EntityPagerDutySmallCard/index.esm.js.map +1 -0
  15. package/dist/components/Errors/ForbiddenError.esm.js +24 -0
  16. package/dist/components/Errors/ForbiddenError.esm.js.map +1 -0
  17. package/dist/components/Errors/MissingTokenError.esm.js +24 -0
  18. package/dist/components/Errors/MissingTokenError.esm.js.map +1 -0
  19. package/dist/components/Errors/ServiceNotFoundError.esm.js +24 -0
  20. package/dist/components/Errors/ServiceNotFoundError.esm.js.map +1 -0
  21. package/dist/components/Escalation/EscalationPolicy.esm.js +64 -0
  22. package/dist/components/Escalation/EscalationPolicy.esm.js.map +1 -0
  23. package/dist/components/Escalation/EscalationUser.esm.js +98 -0
  24. package/dist/components/Escalation/EscalationUser.esm.js.map +1 -0
  25. package/dist/components/Escalation/EscalationUsersEmptyState.esm.js +20 -0
  26. package/dist/components/Escalation/EscalationUsersEmptyState.esm.js.map +1 -0
  27. package/dist/components/Escalation/EscalationUsersForbiddenState.esm.js +20 -0
  28. package/dist/components/Escalation/EscalationUsersForbiddenState.esm.js.map +1 -0
  29. package/dist/components/HomePagePagerDutyCard/Content.esm.js +9 -0
  30. package/dist/components/HomePagePagerDutyCard/Content.esm.js.map +1 -0
  31. package/dist/components/HomePagePagerDutyCard/index.esm.js +2 -0
  32. package/dist/components/HomePagePagerDutyCard/index.esm.js.map +1 -0
  33. package/dist/components/Incident/IncidentEmptyState.esm.js +27 -0
  34. package/dist/components/Incident/IncidentEmptyState.esm.js.map +1 -0
  35. package/dist/components/Incident/IncidentForbiddenState.esm.js +17 -0
  36. package/dist/components/Incident/IncidentForbiddenState.esm.js.map +1 -0
  37. package/dist/components/Incident/IncidentListItem.esm.js +114 -0
  38. package/dist/components/Incident/IncidentListItem.esm.js.map +1 -0
  39. package/dist/components/Incident/Incidents.esm.js +41 -0
  40. package/dist/components/Incident/Incidents.esm.js.map +1 -0
  41. package/dist/components/PagerDutyCard/index.esm.js +193 -0
  42. package/dist/components/PagerDutyCard/index.esm.js.map +1 -0
  43. package/dist/components/PagerDutyCardCommon/InsightsCard.esm.js +35 -0
  44. package/dist/components/PagerDutyCardCommon/InsightsCard.esm.js.map +1 -0
  45. package/dist/components/PagerDutyCardCommon/OpenServiceButton.esm.js +42 -0
  46. package/dist/components/PagerDutyCardCommon/OpenServiceButton.esm.js.map +1 -0
  47. package/dist/components/PagerDutyCardCommon/ServiceStandardsCard.esm.js +95 -0
  48. package/dist/components/PagerDutyCardCommon/ServiceStandardsCard.esm.js.map +1 -0
  49. package/dist/components/PagerDutyCardCommon/StatusCard.esm.js +102 -0
  50. package/dist/components/PagerDutyCardCommon/StatusCard.esm.js.map +1 -0
  51. package/dist/components/PagerDutyCardCommon/TriggerIncidentButton.esm.js +59 -0
  52. package/dist/components/PagerDutyCardCommon/TriggerIncidentButton.esm.js.map +1 -0
  53. package/dist/components/PagerDutySmallCard/index.esm.js +209 -0
  54. package/dist/components/PagerDutySmallCard/index.esm.js.map +1 -0
  55. package/dist/components/TriggerButton/index.esm.js +48 -0
  56. package/dist/components/TriggerButton/index.esm.js.map +1 -0
  57. package/dist/components/TriggerDialog/TriggerDialog.esm.js +94 -0
  58. package/dist/components/TriggerDialog/TriggerDialog.esm.js.map +1 -0
  59. package/dist/components/constants.esm.js +5 -0
  60. package/dist/components/constants.esm.js.map +1 -0
  61. package/dist/components/pagerDutyEntity.esm.js +13 -0
  62. package/dist/components/pagerDutyEntity.esm.js.map +1 -0
  63. package/dist/deprecated.esm.js +10 -0
  64. package/dist/deprecated.esm.js.map +1 -0
  65. package/dist/hooks/index.esm.js +10 -0
  66. package/dist/hooks/index.esm.js.map +1 -0
  67. package/dist/index.d.ts +9 -24
  68. package/dist/index.esm.js +6 -30
  69. package/dist/index.esm.js.map +1 -1
  70. package/dist/plugin.esm.js +71 -0
  71. package/dist/plugin.esm.js.map +1 -0
  72. package/package.json +19 -24
  73. package/dist/esm/index-84a03966.esm.js +0 -1626
  74. package/dist/esm/index-84a03966.esm.js.map +0 -1
  75. package/dist/esm/index-be994860.esm.js +0 -37
  76. package/dist/esm/index-be994860.esm.js.map +0 -1
  77. package/dist/esm/index-df69ef10.esm.js +0 -292
  78. package/dist/esm/index-df69ef10.esm.js.map +0 -1
@@ -1,1626 +0,0 @@
1
- import { createApiRef, createRouteRef, createPlugin, createApiFactory, discoveryApiRef, configApiRef, fetchApiRef, createRoutableExtension, createComponentExtension, useApi, alertApiRef, identityApiRef } from '@backstage/core-plugin-api';
2
- import { NotFoundError } from '@backstage/errors';
3
- import { createCardExtension } from '@backstage/plugin-home-react';
4
- import React, { useEffect, useState, useCallback } from 'react';
5
- import { useEntity } from '@backstage/plugin-catalog-react';
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
- import { DateTime, Duration } from 'luxon';
8
- import OpenInBrowserIcon from '@material-ui/icons/OpenInBrowser';
9
- import { Link, Progress, StatusWarning, StatusError, EmptyState, TabbedCard, CardTab, InfoCard } from '@backstage/core-components';
10
- import EmptyStateImage from '../assets/emptystate.svg';
11
- import useAsyncFn from 'react-use/lib/useAsyncFn';
12
- import { Alert } from '@material-ui/lab';
13
- import ForbiddenStateImage from '../assets/forbiddenstate.svg';
14
- import Avatar from '@material-ui/core/Avatar';
15
- import NotificationsIcon from '@material-ui/icons/Notifications';
16
- import useAsync from 'react-use/lib/useAsync';
17
- import LinkIcon from '@material-ui/icons/Link';
18
- import PDGreenImage from '../assets/PD-Green.svg';
19
- import PDWhiteImage from '../assets/PD-White.svg';
20
- import validateColor from 'validate-color';
21
- import InfoIcon from '@material-ui/icons/Info';
22
- import CheckCircle from '@material-ui/icons/CheckCircle';
23
- import RadioButtonUncheckedIcon from '@material-ui/icons/RadioButtonUnchecked';
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';
30
-
31
- const PAGERDUTY_INTEGRATION_KEY = "pagerduty.com/integration-key";
32
- const PAGERDUTY_SERVICE_ID = "pagerduty.com/service-id";
33
-
34
- function getPagerDutyEntity(entity) {
35
- const {
36
- [PAGERDUTY_INTEGRATION_KEY]: integrationKey,
37
- [PAGERDUTY_SERVICE_ID]: serviceId
38
- } = entity.metadata.annotations || {};
39
- const name = entity.metadata.name;
40
- return { integrationKey, serviceId, name };
41
- }
42
-
43
- class UnauthorizedError extends Error {
44
- }
45
- class ForbiddenError$1 extends Error {
46
- }
47
- const pagerDutyApiRef = createApiRef({
48
- id: "plugin.pagerduty.api"
49
- });
50
- class PagerDutyClient {
51
- constructor(config) {
52
- this.config = config;
53
- }
54
- static fromConfig(configApi, dependencies) {
55
- var _a;
56
- const { discoveryApi, fetchApi } = dependencies;
57
- const eventsBaseUrl = (_a = configApi.getOptionalString("pagerDuty.eventsBaseUrl")) != null ? _a : "https://events.pagerduty.com/v2";
58
- return new PagerDutyClient({
59
- eventsBaseUrl,
60
- discoveryApi,
61
- fetchApi
62
- });
63
- }
64
- async getServiceByPagerDutyEntity(pagerDutyEntity) {
65
- const { integrationKey, serviceId } = pagerDutyEntity;
66
- let response;
67
- let url;
68
- if (integrationKey) {
69
- url = `${await this.config.discoveryApi.getBaseUrl(
70
- "pagerduty"
71
- )}/services?integration_key=${integrationKey}`;
72
- const serviceResponse = await this.findByUrl(url);
73
- if (serviceResponse.service === void 0)
74
- throw new NotFoundError();
75
- response = serviceResponse;
76
- } else if (serviceId) {
77
- url = `${await this.config.discoveryApi.getBaseUrl(
78
- "pagerduty"
79
- )}/services/${serviceId}`;
80
- response = await this.findByUrl(url);
81
- } else {
82
- throw new NotFoundError();
83
- }
84
- return response;
85
- }
86
- async getEntityMappings() {
87
- const url = `${await this.config.discoveryApi.getBaseUrl(
88
- "pagerduty"
89
- )}/mapping/entity`;
90
- return await this.findByUrl(url);
91
- }
92
- async storeServiceMapping(serviceId, backstageEntityId) {
93
- const body = JSON.stringify({
94
- entityRef: backstageEntityId,
95
- serviceId
96
- });
97
- const options = {
98
- method: "POST",
99
- headers: {
100
- "Content-Type": "application/json; charset=UTF-8",
101
- Accept: "application/json, text/plain, */*"
102
- },
103
- body
104
- };
105
- const url = `${await this.config.discoveryApi.getBaseUrl(
106
- "pagerduty"
107
- )}/mapping/entity`;
108
- return this.request(url, options);
109
- }
110
- async getServiceByEntity(entity) {
111
- return await this.getServiceByPagerDutyEntity(getPagerDutyEntity(entity));
112
- }
113
- async getServiceById(serviceId) {
114
- const url = `${await this.config.discoveryApi.getBaseUrl(
115
- "pagerduty"
116
- )}/services/${serviceId}`;
117
- return await this.findByUrl(url);
118
- }
119
- async getIncidentsByServiceId(serviceId) {
120
- const url = `${await this.config.discoveryApi.getBaseUrl(
121
- "pagerduty"
122
- )}/services/${serviceId}/incidents`;
123
- return await this.findByUrl(url);
124
- }
125
- async getChangeEventsByServiceId(serviceId) {
126
- const url = `${await this.config.discoveryApi.getBaseUrl(
127
- "pagerduty"
128
- )}/services/${serviceId}/change-events`;
129
- return await this.findByUrl(url);
130
- }
131
- async getServiceStandardsByServiceId(serviceId) {
132
- const url = `${await this.config.discoveryApi.getBaseUrl(
133
- "pagerduty"
134
- )}/services/${serviceId}/standards`;
135
- return await this.findByUrl(url);
136
- }
137
- async getServiceMetricsByServiceId(serviceId) {
138
- const url = `${await this.config.discoveryApi.getBaseUrl(
139
- "pagerduty"
140
- )}/services/${serviceId}/metrics`;
141
- return await this.findByUrl(url);
142
- }
143
- async getOnCallByPolicyId(policyId) {
144
- const params = `escalation_policy_ids[]=${policyId}`;
145
- const url = `${await this.config.discoveryApi.getBaseUrl(
146
- "pagerduty"
147
- )}/oncall-users?${params}`;
148
- const response = await this.findByUrl(url);
149
- return response.users;
150
- }
151
- triggerAlarm(request) {
152
- var _a;
153
- const { integrationKey, source, description, userName } = request;
154
- const body = JSON.stringify({
155
- event_action: "trigger",
156
- routing_key: integrationKey,
157
- client: "Backstage",
158
- client_url: source,
159
- payload: {
160
- summary: description,
161
- source,
162
- severity: "error",
163
- class: "manual trigger",
164
- custom_details: {
165
- user: userName
166
- }
167
- }
168
- });
169
- const options = {
170
- method: "POST",
171
- headers: {
172
- "Content-Type": "application/json; charset=UTF-8",
173
- Accept: "application/json, text/plain, */*"
174
- },
175
- body
176
- };
177
- const url = (_a = this.config.eventsBaseUrl) != null ? _a : "https://events.pagerduty.com/v2";
178
- return this.request(`${url}/enqueue`, options);
179
- }
180
- async findByUrl(url) {
181
- const options = {
182
- method: "GET",
183
- headers: {
184
- Accept: "application/vnd.pagerduty+json;version=2",
185
- "Content-Type": "application/json"
186
- }
187
- };
188
- const response = await this.request(url, options);
189
- return response.json();
190
- }
191
- async request(url, options) {
192
- const response = await this.config.fetchApi.fetch(url, options);
193
- if (response.status === 401) {
194
- throw new UnauthorizedError("Unauthorized: You don't have access to this resource");
195
- }
196
- if (response.status === 403) {
197
- throw new ForbiddenError$1("Forbidden: You are not allowed to perform this action");
198
- }
199
- if (response.status === 404) {
200
- throw new NotFoundError("Not Found: Resource not found");
201
- }
202
- if (!response.ok) {
203
- const payload = await response.json();
204
- const errors = payload.errors.map((error) => error).join(" ");
205
- const message = `Request failed with ${response.status}, ${errors}`;
206
- throw new Error(message);
207
- }
208
- return response;
209
- }
210
- }
211
-
212
- const rootRouteRef = createRouteRef({
213
- id: "pagerduty"
214
- });
215
- const pagerDutyPlugin = createPlugin({
216
- id: "pagerduty",
217
- apis: [
218
- createApiFactory({
219
- api: pagerDutyApiRef,
220
- deps: {
221
- discoveryApi: discoveryApiRef,
222
- configApi: configApiRef,
223
- fetchApi: fetchApiRef
224
- },
225
- factory: ({ configApi, discoveryApi, fetchApi }) => PagerDutyClient.fromConfig(configApi, { discoveryApi, fetchApi })
226
- })
227
- ]
228
- });
229
- const PagerDutyPage = pagerDutyPlugin.provide(
230
- createRoutableExtension({
231
- name: "PagerDutyPage",
232
- component: () => import('./index-df69ef10.esm.js').then((m) => m.PagerDutyPage),
233
- mountPoint: rootRouteRef
234
- })
235
- );
236
- const EntityPagerDutyCard$1 = pagerDutyPlugin.provide(
237
- createComponentExtension({
238
- name: "EntityPagerDutyCard",
239
- component: {
240
- lazy: () => Promise.resolve().then(function () { return index$1; }).then(
241
- (m) => m.EntityPagerDutyCard
242
- )
243
- }
244
- })
245
- );
246
- const EntityPagerDutySmallCard$1 = pagerDutyPlugin.provide(
247
- createComponentExtension({
248
- name: "EntityPagerDutySmallCard",
249
- component: {
250
- lazy: () => Promise.resolve().then(function () { return index; }).then(
251
- (m) => m.EntityPagerDutySmallCard
252
- )
253
- }
254
- })
255
- );
256
- const HomePagePagerDutyCard = pagerDutyPlugin.provide(
257
- createCardExtension({
258
- name: "HomePagePagerDutyCard",
259
- title: "PagerDuty Homepage Card",
260
- components: () => import('./index-be994860.esm.js'),
261
- settings: {
262
- schema: {
263
- title: "PagerDuty",
264
- type: "object",
265
- properties: {
266
- integrationKey: {
267
- title: "PagerDuty integration key",
268
- type: "string"
269
- },
270
- serviceId: {
271
- title: "PagerDuty service id",
272
- type: "string"
273
- },
274
- name: {
275
- title: "PagerDuty service name",
276
- type: "string"
277
- }
278
- }
279
- }
280
- }
281
- })
282
- );
283
-
284
- const useStyles$8 = makeStyles((theme) => ({
285
- denseListIcon: {
286
- marginRight: 0,
287
- display: "flex",
288
- flexDirection: "column",
289
- alignItems: "center",
290
- justifyContent: "center"
291
- },
292
- listItemPrimary: {
293
- fontWeight: "bold"
294
- },
295
- warning: {
296
- borderColor: theme.palette.warning.main,
297
- color: "#fff",
298
- backgroundColor: theme.palette.warning.main,
299
- boxShadow: "0 4px 4px 0 rgba(0,0,0,0.2)",
300
- textTransform: "uppercase",
301
- "& *": {
302
- color: "#fff"
303
- }
304
- },
305
- error: {
306
- borderColor: theme.palette.error.main,
307
- color: "#fff",
308
- backgroundColor: theme.palette.error.main,
309
- boxShadow: "0 4px 4px 0 rgba(0,0,0,0.2)",
310
- textTransform: "uppercase",
311
- "& *": {
312
- color: "#fff"
313
- }
314
- },
315
- lowUrgency: {
316
- borderColor: theme.palette.warning.main,
317
- color: theme.palette.warning.main,
318
- backgroundColor: "#fff",
319
- boxShadow: "0 4px 4px 0 rgba(0,0,0,0.2)",
320
- textTransform: "uppercase",
321
- "& *": {
322
- color: theme.palette.warning.main
323
- }
324
- },
325
- highUrgency: {
326
- borderColor: theme.palette.error.main,
327
- color: theme.palette.error.main,
328
- backgroundColor: "#fff",
329
- boxShadow: "0 4px 4px 0 rgba(0,0,0,0.2)",
330
- textTransform: "uppercase",
331
- "& *": {
332
- color: theme.palette.error.main
333
- }
334
- },
335
- textContainer: {
336
- display: "flex",
337
- alignItems: "baseline"
338
- },
339
- smallIconStyle: {
340
- color: theme.palette.text.primary,
341
- marginRight: "-20px"
342
- }
343
- }));
344
- const IncidentListItem = ({ incident }) => {
345
- var _a, _b, _c;
346
- const classes = useStyles$8();
347
- const duration = (/* @__PURE__ */ new Date()).getTime() - new Date(incident.created_at).getTime();
348
- const createdAt = DateTime.local().minus(Duration.fromMillis(duration)).toRelative({ locale: "en" });
349
- const user = (_a = incident.assignments[0]) == null ? void 0 : _a.assignee;
350
- return /* @__PURE__ */ React.createElement(ListItem, { dense: true, key: incident.id }, /* @__PURE__ */ React.createElement(
351
- ListItemText,
352
- {
353
- primary: /* @__PURE__ */ React.createElement("div", { className: classes.textContainer }, /* @__PURE__ */ React.createElement(
354
- Chip,
355
- {
356
- "data-testid": `chip-${incident.status}`,
357
- label: incident.status,
358
- size: "small",
359
- variant: "outlined",
360
- className: incident.status === "triggered" ? classes.error : classes.warning
361
- }
362
- ), /* @__PURE__ */ React.createElement(
363
- Chip,
364
- {
365
- "data-testid": `chip-${incident.urgency}`,
366
- label: `${incident.urgency} urgency`,
367
- size: "small",
368
- variant: "outlined",
369
- className: incident.urgency === "high" ? classes.highUrgency : classes.lowUrgency
370
- }
371
- ), incident.title),
372
- primaryTypographyProps: {
373
- variant: "body1",
374
- className: classes.listItemPrimary
375
- },
376
- secondary: /* @__PURE__ */ React.createElement(Typography, { noWrap: true, variant: "body2", color: "textSecondary" }, "Created ", createdAt, " and assigned to", " ", /* @__PURE__ */ React.createElement(Link, { to: (_b = user == null ? void 0 : user.html_url) != null ? _b : "#" }, (_c = user == null ? void 0 : user.summary) != null ? _c : "nobody"))
377
- }
378
- ), /* @__PURE__ */ React.createElement(ListItemSecondaryAction, null, /* @__PURE__ */ React.createElement(Tooltip, { title: "View in PagerDuty", placement: "top" }, /* @__PURE__ */ React.createElement(
379
- IconButton,
380
- {
381
- href: incident.html_url,
382
- target: "_blank",
383
- rel: "noopener noreferrer",
384
- className: classes.smallIconStyle
385
- },
386
- /* @__PURE__ */ React.createElement(OpenInBrowserIcon, null)
387
- ))));
388
- };
389
-
390
- const IncidentsEmptyState = () => {
391
- return /* @__PURE__ */ React.createElement(
392
- Grid,
393
- {
394
- container: true,
395
- justifyContent: "center",
396
- direction: "column",
397
- alignItems: "center"
398
- },
399
- /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(Typography, { variant: "h5" }, "Nice! No incidents found!")),
400
- /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(
401
- "img",
402
- {
403
- src: EmptyStateImage,
404
- alt: "EmptyState",
405
- "data-testid": "emptyStateImg"
406
- }
407
- ))
408
- );
409
- };
410
-
411
- const IncidentForbiddenState = () => {
412
- return /* @__PURE__ */ React.createElement(Grid, { container: true, justifyContent: "center", direction: "column", alignItems: "center" }, /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(Typography, { variant: "h5" }, "Feature not available with your account or token.")), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(
413
- "img",
414
- {
415
- src: ForbiddenStateImage,
416
- alt: "ForbiddenState",
417
- "data-testid": "forbiddenStateImg"
418
- }
419
- )));
420
- };
421
-
422
- const Incidents = ({ serviceId, refreshIncidents }) => {
423
- const api = useApi(pagerDutyApiRef);
424
- const [{ value: incidents, loading, error }, getIncidents] = useAsyncFn(
425
- async () => {
426
- const { incidents: foundIncidents } = await api.getIncidentsByServiceId(
427
- serviceId
428
- );
429
- return foundIncidents;
430
- }
431
- );
432
- useEffect(() => {
433
- getIncidents();
434
- }, [refreshIncidents, getIncidents]);
435
- if (error) {
436
- if (error.message.includes("Forbidden")) {
437
- return /* @__PURE__ */ React.createElement(IncidentForbiddenState, null);
438
- }
439
- return /* @__PURE__ */ React.createElement(Alert, { severity: "error" }, "Error encountered while fetching information. ", error.message);
440
- }
441
- if (loading) {
442
- return /* @__PURE__ */ React.createElement(Progress, null);
443
- }
444
- if (!(incidents == null ? void 0 : incidents.length)) {
445
- return /* @__PURE__ */ React.createElement(IncidentsEmptyState, null);
446
- }
447
- return /* @__PURE__ */ React.createElement(List, { dense: true }, incidents.map((incident, index) => /* @__PURE__ */ React.createElement(IncidentListItem, { key: incident.id + index, incident })));
448
- };
449
-
450
- const useStyles$7 = makeStyles({
451
- denseListIcon: {
452
- marginRight: 0,
453
- display: "flex",
454
- flexDirection: "column",
455
- alignItems: "center",
456
- justifyContent: "center"
457
- }
458
- });
459
- const EscalationUsersEmptyState = () => {
460
- const classes = useStyles$7();
461
- 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." }));
462
- };
463
-
464
- const useStyles$6 = makeStyles({
465
- denseListIcon: {
466
- marginRight: 0,
467
- display: "flex",
468
- flexDirection: "column",
469
- alignItems: "center",
470
- justifyContent: "center"
471
- }
472
- });
473
- const EscalationUsersForbiddenState = () => {
474
- const classes = useStyles$6();
475
- 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." }));
476
- };
477
-
478
- const useStyles$5 = makeStyles((theme) => ({
479
- listItemPrimary: {
480
- fontWeight: "bold"
481
- },
482
- listItemSecondary: {
483
- fontWeight: "normal",
484
- textDecoration: "underline",
485
- marginTop: "-5px"
486
- },
487
- buttonStyle: {
488
- marginLeft: "-11px",
489
- marginTop: "-10px",
490
- fontSize: "15px",
491
- color: theme.palette.text.primary,
492
- "&:hover": {
493
- backgroundColor: "transparent",
494
- textDecoration: "underline"
495
- }
496
- },
497
- userTextButtonStyle: {
498
- marginLeft: "-11px",
499
- marginTop: "-10px",
500
- marginBottom: "-10px",
501
- fontSize: "15px",
502
- color: theme.palette.text.primary,
503
- "&:hover": {
504
- backgroundColor: "transparent",
505
- textDecoration: "underline"
506
- }
507
- },
508
- containerStyle: {
509
- display: "flex",
510
- alignItems: "center",
511
- fontWeight: "bold"
512
- },
513
- iconStyle: {
514
- fontSize: "25px",
515
- marginLeft: "-4px",
516
- color: theme.palette.text.primary
517
- },
518
- smallIconStyle: {
519
- color: theme.palette.text.primary
520
- },
521
- avatarStyle: {
522
- marginTop: "-20px"
523
- }
524
- }));
525
- function navigateToUrl(url) {
526
- window.open(url, "_blank");
527
- }
528
- const EscalationUser = ({ user, policyUrl, policyName }) => {
529
- const classes = useStyles$5();
530
- return /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(ListItemIcon, null, /* @__PURE__ */ React.createElement(
531
- Avatar,
532
- {
533
- alt: user.name,
534
- src: user.avatar_url,
535
- className: classes.avatarStyle
536
- }
537
- )), /* @__PURE__ */ React.createElement(
538
- ListItemText,
539
- {
540
- primary: /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Tooltip, { title: "Open user in PagerDuty", placement: "top" }, /* @__PURE__ */ React.createElement(
541
- IconButton,
542
- {
543
- "aria-label": "open-user-in-browser",
544
- onClick: () => navigateToUrl(user.html_url),
545
- className: classes.userTextButtonStyle
546
- },
547
- /* @__PURE__ */ React.createElement("span", { className: classes.containerStyle }, user.name)
548
- )), /* @__PURE__ */ React.createElement(
549
- Typography,
550
- {
551
- className: classes.listItemSecondary,
552
- color: "textSecondary"
553
- },
554
- user.email
555
- )),
556
- secondary: /* @__PURE__ */ React.createElement(
557
- IconButton,
558
- {
559
- "aria-label": "open-escalation-policy-in-browser",
560
- onClick: () => navigateToUrl(policyUrl),
561
- className: classes.buttonStyle
562
- },
563
- /* @__PURE__ */ React.createElement("span", { className: classes.containerStyle }, /* @__PURE__ */ React.createElement(NotificationsIcon, { className: classes.iconStyle }), policyName)
564
- )
565
- }
566
- ));
567
- };
568
-
569
- const useStyles$4 = makeStyles(
570
- () => createStyles({
571
- listStyle: {
572
- marginLeft: "-15px"
573
- }
574
- })
575
- );
576
- const EscalationPolicy = ({
577
- policyId,
578
- policyUrl,
579
- policyName
580
- }) => {
581
- const api = useApi(pagerDutyApiRef);
582
- const classes = useStyles$4();
583
- const {
584
- value: users,
585
- loading,
586
- error
587
- } = useAsync(async () => {
588
- return await api.getOnCallByPolicyId(policyId);
589
- });
590
- if (error) {
591
- if (error.message.includes("Forbidden")) {
592
- return /* @__PURE__ */ React.createElement(List, { dense: true, subheader: /* @__PURE__ */ React.createElement(ListSubheader, null, "ON CALL") }, /* @__PURE__ */ React.createElement(EscalationUsersForbiddenState, null));
593
- }
594
- return /* @__PURE__ */ React.createElement(Alert, { severity: "error" }, "Error encountered while fetching information. ", error.message);
595
- }
596
- if (loading) {
597
- return /* @__PURE__ */ React.createElement(Progress, null);
598
- }
599
- if (!(users == null ? void 0 : users.length)) {
600
- return /* @__PURE__ */ React.createElement(EscalationUsersEmptyState, null);
601
- }
602
- return /* @__PURE__ */ React.createElement(
603
- List,
604
- {
605
- dense: true,
606
- className: classes.listStyle
607
- },
608
- users.map((user, index) => /* @__PURE__ */ React.createElement(
609
- EscalationUser,
610
- {
611
- key: index,
612
- user,
613
- policyUrl,
614
- policyName
615
- }
616
- ))
617
- );
618
- };
619
-
620
- const MissingTokenError = () => /* @__PURE__ */ React.createElement(
621
- EmptyState,
622
- {
623
- missing: "info",
624
- title: "Missing or invalid PagerDuty Token",
625
- description: "The request to fetch data needs a valid token. See README for more details.",
626
- action: /* @__PURE__ */ React.createElement(
627
- Button,
628
- {
629
- color: "primary",
630
- variant: "contained",
631
- href: "https://pagerduty.github.io/backstage-plugin-docs/getting-started/pagerduty/"
632
- },
633
- "Read More"
634
- )
635
- }
636
- );
637
-
638
- const ServiceNotFoundError = () => /* @__PURE__ */ React.createElement(
639
- EmptyState,
640
- {
641
- missing: "data",
642
- title: "PagerDuty Service Not Found",
643
- description: "A service could not be found within PagerDuty based on the provided service id. Please verify your configuration.",
644
- action: /* @__PURE__ */ React.createElement(
645
- Button,
646
- {
647
- color: "primary",
648
- variant: "contained",
649
- href: "https://pagerduty.github.io/backstage-plugin-docs/getting-started/pagerduty/"
650
- },
651
- "Read More"
652
- )
653
- }
654
- );
655
-
656
- const useStyles$3 = makeStyles((theme) => ({
657
- denseListIcon: {
658
- marginRight: 0,
659
- display: "flex",
660
- flexDirection: "column",
661
- alignItems: "center",
662
- justifyContent: "center"
663
- },
664
- listItemPrimary: {
665
- fontWeight: "bold"
666
- },
667
- smallExternalLinkIconStyle: {
668
- color: theme.palette.text.primary
669
- },
670
- smallExternalLinkWithoutMarginIconStyle: {
671
- color: theme.palette.text.primary,
672
- marginRight: "-20px"
673
- },
674
- smallIconStyle: {
675
- color: theme.palette.text.primary,
676
- marginRight: "-20px"
677
- }
678
- }));
679
- const ChangeEventListItem = ({ changeEvent }) => {
680
- const classes = useStyles$3();
681
- const duration = (/* @__PURE__ */ new Date()).getTime() - new Date(changeEvent.timestamp).getTime();
682
- const changedAt = DateTime.local().minus(Duration.fromMillis(duration)).toRelative({ locale: "en" });
683
- let externalLinkElem;
684
- if (changeEvent.links.length > 0) {
685
- const text = changeEvent.links[0].text;
686
- externalLinkElem = /* @__PURE__ */ React.createElement(Tooltip, { title: text, placement: "top" }, /* @__PURE__ */ React.createElement(
687
- IconButton,
688
- {
689
- component: Link,
690
- to: changeEvent.links[0].href,
691
- className: changeEvent.html_url === void 0 ? classes.smallExternalLinkWithoutMarginIconStyle : classes.smallExternalLinkIconStyle
692
- },
693
- /* @__PURE__ */ React.createElement(LinkIcon, null)
694
- ));
695
- }
696
- return /* @__PURE__ */ React.createElement(ListItem, { dense: true, key: changeEvent.id }, /* @__PURE__ */ React.createElement(
697
- ListItemText,
698
- {
699
- primary: /* @__PURE__ */ React.createElement(React.Fragment, null, changeEvent.summary),
700
- primaryTypographyProps: {
701
- variant: "body1",
702
- className: classes.listItemPrimary
703
- },
704
- secondary: /* @__PURE__ */ React.createElement(Typography, { variant: "body2", color: "textSecondary" }, "Triggered from ", changeEvent.source, " ", changedAt, ".")
705
- }
706
- ), /* @__PURE__ */ React.createElement(ListItemSecondaryAction, null, externalLinkElem, changeEvent.html_url === void 0 ? null : /* @__PURE__ */ React.createElement(Tooltip, { title: "View in PagerDuty", placement: "top" }, /* @__PURE__ */ React.createElement(
707
- IconButton,
708
- {
709
- component: Link,
710
- to: changeEvent.html_url,
711
- className: classes.smallIconStyle
712
- },
713
- /* @__PURE__ */ React.createElement(OpenInBrowserIcon, null)
714
- ))));
715
- };
716
-
717
- const ChangeEventEmptyState = () => {
718
- return /* @__PURE__ */ React.createElement(Grid, { container: true, justifyContent: "center", direction: "column", alignItems: "center" }, /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(Typography, { variant: "h5" }, "No change events to display yet.")), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(
719
- "img",
720
- {
721
- src: EmptyStateImage,
722
- alt: "EmptyState",
723
- "data-testid": "emptyStateImg"
724
- }
725
- )));
726
- };
727
-
728
- const ChangeEventForbiddenState = () => {
729
- return /* @__PURE__ */ React.createElement(Grid, { container: true, justifyContent: "center", direction: "column", alignItems: "center" }, /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(Typography, { variant: "h5" }, "Feature not available with your account or token.")), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(
730
- "img",
731
- {
732
- src: ForbiddenStateImage,
733
- alt: "ForbiddenState",
734
- "data-testid": "forbiddenStateImg"
735
- }
736
- )));
737
- };
738
-
739
- const ChangeEvents = ({ serviceId, refreshEvents }) => {
740
- const api = useApi(pagerDutyApiRef);
741
- const [{ value: changeEvents, loading, error }, getChangeEvents] = useAsyncFn(
742
- async () => {
743
- const { change_events } = await api.getChangeEventsByServiceId(serviceId);
744
- return change_events;
745
- }
746
- );
747
- useEffect(() => {
748
- getChangeEvents();
749
- }, [refreshEvents, getChangeEvents]);
750
- if (error) {
751
- if (error.message.includes("Forbidden")) {
752
- return /* @__PURE__ */ React.createElement(ChangeEventForbiddenState, null);
753
- }
754
- return /* @__PURE__ */ React.createElement(Alert, { severity: "error" }, "Error encountered while fetching information. ", error.message);
755
- }
756
- if (loading) {
757
- return /* @__PURE__ */ React.createElement(Progress, null);
758
- }
759
- if (!(changeEvents == null ? void 0 : changeEvents.length)) {
760
- return /* @__PURE__ */ React.createElement(ChangeEventEmptyState, null);
761
- }
762
- return /* @__PURE__ */ React.createElement(List, { dense: true }, changeEvents.map((changeEvent, index) => /* @__PURE__ */ React.createElement(
763
- ChangeEventListItem,
764
- {
765
- key: changeEvent.id + index,
766
- changeEvent
767
- }
768
- )));
769
- };
770
-
771
- const ForbiddenError = () => /* @__PURE__ */ React.createElement(
772
- EmptyState,
773
- {
774
- missing: "info",
775
- title: "Unauthorized",
776
- description: "You don't have the required permissions to perform this action. See README for more details.",
777
- action: /* @__PURE__ */ React.createElement(
778
- Button,
779
- {
780
- color: "primary",
781
- variant: "contained",
782
- href: "https://pagerduty.github.io/backstage-plugin-docs/getting-started/pagerduty/"
783
- },
784
- "Read More"
785
- )
786
- }
787
- );
788
-
789
- function IncidentCounterCard({ count, label, color, compact }) {
790
- const textColor = color && validateColor(color) ? color : "black";
791
- const useStyles = makeStyles(() => ({
792
- cardStyle: {
793
- marginRight: "10px",
794
- height: compact !== true ? "120px" : "80px",
795
- display: "flex",
796
- alignItems: "center",
797
- justifyContent: "center",
798
- backgroundColor: "rgba(0, 0, 0, 0.03)"
799
- },
800
- largeTextStyle: {
801
- color: textColor,
802
- fontSize: "30px",
803
- marginTop: "-10px"
804
- },
805
- smallTextStyle: {
806
- color: textColor,
807
- fontWeight: "bold",
808
- fontSize: "10px",
809
- marginTop: "-5px",
810
- textTransform: "uppercase",
811
- flexWrap: "wrap"
812
- }
813
- }));
814
- const { cardStyle, largeTextStyle, smallTextStyle } = useStyles();
815
- 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)));
816
- }
817
-
818
- function OpenServiceButton({ serviceUrl, compact }) {
819
- const useStyles = makeStyles((theme) => ({
820
- buttonStyle: {
821
- color: theme.palette.text.primary,
822
- "&:hover": {
823
- backgroundColor: "transparent",
824
- textDecoration: "underline"
825
- }
826
- },
827
- containerStyle: {
828
- fontSize: compact !== true ? "12px" : "10px",
829
- width: compact !== true ? "85px" : "70px"
830
- },
831
- iconStyle: {
832
- fontSize: "30px",
833
- marginBottom: "-10px"
834
- },
835
- textStyle: {
836
- marginBottom: "-10px"
837
- }
838
- }));
839
- const { buttonStyle, containerStyle, iconStyle, textStyle } = useStyles();
840
- function navigateToService() {
841
- window.open(serviceUrl, "_blank");
842
- }
843
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
844
- IconButton,
845
- {
846
- "aria-label": "open-service-in-browser",
847
- onClick: navigateToService,
848
- className: buttonStyle
849
- },
850
- /* @__PURE__ */ React.createElement("div", { className: containerStyle }, /* @__PURE__ */ React.createElement(OpenInBrowserIcon, { className: iconStyle }), /* @__PURE__ */ React.createElement("p", { className: textStyle }, "Open service in PagerDuty"))
851
- ));
852
- }
853
-
854
- function colorFromPercentage(theme, percentage) {
855
- if (percentage < 0.5) {
856
- return theme.palette.error.main;
857
- } else if (percentage < 0.8) {
858
- return theme.palette.warning.main;
859
- }
860
- return theme.palette.success.main;
861
- }
862
- function ServiceStandardsCard({ total, completed, standards, compact }) {
863
- const useStyles = makeStyles((theme) => ({
864
- cardStyle: {
865
- height: compact !== true ? "120px" : "80px",
866
- display: "grid",
867
- gridTemplateRows: "1fr auto auto",
868
- backgroundColor: "rgba(0, 0, 0, 0.03)"
869
- },
870
- containerStyle: {
871
- display: "flex",
872
- justifyContent: "center",
873
- marginTop: compact !== true ? "-100px" : "-50px"
874
- },
875
- largeTextStyle: {
876
- fontSize: compact !== true ? "50px" : "40px",
877
- color: completed !== void 0 && total !== void 0 ? colorFromPercentage(theme, completed / total) : colorFromPercentage(theme, 0),
878
- alignSelf: "center",
879
- justifyContent: "center"
880
- },
881
- smallTextStyle: {
882
- color: theme.palette.textSubtle,
883
- fontSize: compact !== true ? "14px" : "12px",
884
- fontWeight: "bold",
885
- alignSelf: "center",
886
- justifyContent: "center",
887
- marginLeft: "-2px",
888
- marginTop: compact !== true ? "25px" : "20px"
889
- },
890
- tooltipContainer: {},
891
- tooltipIcon: {
892
- marginRight: "5px"
893
- },
894
- standardItem: {
895
- display: "flex",
896
- alignItems: "center"
897
- }
898
- }));
899
- const BorderLinearProgress = withStyles((theme) => ({
900
- root: {
901
- height: 10,
902
- borderRadius: 5,
903
- margin: 5
904
- },
905
- colorPrimary: {
906
- backgroundColor: theme.palette.grey[theme.palette.type === "light" ? 200 : 700]
907
- },
908
- bar: {
909
- borderRadius: 5,
910
- backgroundColor: completed !== void 0 && total !== void 0 ? colorFromPercentage(theme, completed / total) : colorFromPercentage(theme, 0)
911
- }
912
- }))(LinearProgress);
913
- const {
914
- cardStyle,
915
- containerStyle,
916
- largeTextStyle,
917
- smallTextStyle,
918
- tooltipContainer,
919
- tooltipIcon,
920
- standardItem
921
- } = useStyles();
922
- if (standards === void 0 || completed === void 0 || total === void 0) {
923
- return /* @__PURE__ */ React.createElement(Card, { className: cardStyle }, /* @__PURE__ */ React.createElement("div", { className: containerStyle }, /* @__PURE__ */ React.createElement(Typography, { className: smallTextStyle }, "Unable to retrieve Scores")));
924
- }
925
- return /* @__PURE__ */ React.createElement(Card, { className: cardStyle }, completed !== void 0 && total !== void 0 ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: tooltipContainer }, /* @__PURE__ */ React.createElement(IconButton, null, /* @__PURE__ */ React.createElement(
926
- Tooltip,
927
- {
928
- interactive: true,
929
- title: /* @__PURE__ */ React.createElement(React.Fragment, null, standards == null ? void 0 : standards.map((standard, key) => /* @__PURE__ */ React.createElement("p", { key }, standard.pass ? /* @__PURE__ */ React.createElement("span", { className: standardItem }, /* @__PURE__ */ React.createElement(CheckCircle, { className: tooltipIcon }), " ", standard.name) : /* @__PURE__ */ React.createElement("span", { className: standardItem }, /* @__PURE__ */ React.createElement(RadioButtonUncheckedIcon, { className: tooltipIcon }), " ", standard.name))))
930
- },
931
- /* @__PURE__ */ React.createElement(InfoIcon, null)
932
- ))), /* @__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(
933
- BorderLinearProgress,
934
- {
935
- variant: "determinate",
936
- value: completed / total * 100
937
- }
938
- ))) : /* @__PURE__ */ React.createElement("div", { className: containerStyle }, /* @__PURE__ */ React.createElement(Typography, { className: smallTextStyle }, "Unable to retrieve Scores")));
939
- }
940
-
941
- function labelFromStatus(status) {
942
- let label;
943
- switch (status) {
944
- case "active":
945
- label = "OK";
946
- break;
947
- case "warning":
948
- label = "ACTIVE";
949
- break;
950
- case "critical":
951
- label = "ALARM";
952
- break;
953
- case "maintenance":
954
- label = "MAINTENANCE";
955
- break;
956
- case "disabled":
957
- label = "DISABLED";
958
- break;
959
- default:
960
- label = "OK";
961
- break;
962
- }
963
- return label;
964
- }
965
- function colorFromStatus(theme, status) {
966
- let color;
967
- switch (status) {
968
- case "active":
969
- color = theme.palette.success.main;
970
- break;
971
- case "warning":
972
- color = theme.palette.warningBackground;
973
- break;
974
- case "critical":
975
- color = theme.palette.error.main;
976
- break;
977
- case "maintenance":
978
- color = "#ebdc00";
979
- break;
980
- case "disabled":
981
- color = "#A9A9A9";
982
- break;
983
- default:
984
- color = theme.palette.success.main;
985
- break;
986
- }
987
- return color;
988
- }
989
- function StatusCard({ serviceId, refreshStatus, compact }) {
990
- const api = useApi(pagerDutyApiRef);
991
- const [{ value: status, loading, error }, getStatus] = useAsyncFn$1(
992
- async () => {
993
- const { service: foundService } = await api.getServiceById(serviceId);
994
- return foundService.status;
995
- }
996
- );
997
- const useStyles = makeStyles$1((theme) => ({
998
- cardStyle: {
999
- height: compact !== true ? "120px" : "80px",
1000
- display: "flex",
1001
- alignItems: "center",
1002
- justifyContent: "center",
1003
- backgroundColor: status !== void 0 ? colorFromStatus(theme, status) : colorFromStatus(theme, "active"),
1004
- marginRight: "10px"
1005
- },
1006
- largeTextStyle: {
1007
- color: "white",
1008
- fontWeight: "bold",
1009
- fontSize: "20px",
1010
- wordWrap: "break-word"
1011
- }
1012
- }));
1013
- const { cardStyle, largeTextStyle } = useStyles();
1014
- useEffect(() => {
1015
- getStatus();
1016
- }, [refreshStatus, getStatus]);
1017
- if (error) {
1018
- if (error.message.includes("Forbidden")) {
1019
- return /* @__PURE__ */ React.createElement("p", null, "forbidden");
1020
- }
1021
- return /* @__PURE__ */ React.createElement(Alert$1, { severity: "error" }, "Error encountered while fetching information. ", error.message);
1022
- }
1023
- if (loading) {
1024
- return /* @__PURE__ */ React.createElement(Progress, null);
1025
- }
1026
- if (!status) {
1027
- return /* @__PURE__ */ React.createElement("p", null, "not found");
1028
- }
1029
- 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"));
1030
- }
1031
-
1032
- const TriggerDialog = ({
1033
- showDialog,
1034
- handleDialog,
1035
- onIncidentCreated,
1036
- serviceName,
1037
- integrationKey
1038
- }) => {
1039
- const alertApi = useApi(alertApiRef);
1040
- const identityApi = useApi(identityApiRef);
1041
- const api = useApi(pagerDutyApiRef);
1042
- const [description, setDescription] = useState("");
1043
- const [{ value, loading, error }, handleTriggerAlarm] = useAsyncFn(
1044
- async (descriptions) => {
1045
- const { userEntityRef } = await identityApi.getBackstageIdentity();
1046
- const { name: userName } = parseEntityRef(userEntityRef, {
1047
- defaultKind: "User",
1048
- defaultNamespace: DEFAULT_NAMESPACE
1049
- });
1050
- return await api.triggerAlarm({
1051
- integrationKey,
1052
- source: window.location.toString(),
1053
- description: descriptions,
1054
- userName
1055
- });
1056
- }
1057
- );
1058
- const descriptionChanged = (event) => {
1059
- setDescription(event.target.value);
1060
- };
1061
- useEffect(() => {
1062
- if (value) {
1063
- (async () => {
1064
- alertApi.post({
1065
- message: `Alarm successfully triggered`
1066
- });
1067
- handleDialog();
1068
- await new Promise((resolve) => setTimeout(resolve, 1e3));
1069
- onIncidentCreated == null ? void 0 : onIncidentCreated();
1070
- })();
1071
- }
1072
- }, [value, alertApi, handleDialog, onIncidentCreated]);
1073
- if (error) {
1074
- alertApi.post({
1075
- message: `Failed to trigger alarm. ${error.message}`,
1076
- severity: "error"
1077
- });
1078
- }
1079
- 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(
1080
- Typography,
1081
- {
1082
- variant: "body1",
1083
- style: { marginTop: "1em" },
1084
- gutterBottom: true,
1085
- align: "justify"
1086
- },
1087
- "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."
1088
- ), /* @__PURE__ */ React.createElement(
1089
- TextField,
1090
- {
1091
- inputProps: { "data-testid": "trigger-input" },
1092
- id: "description",
1093
- multiline: true,
1094
- fullWidth: true,
1095
- minRows: 4,
1096
- margin: "normal",
1097
- label: "Problem description",
1098
- variant: "outlined",
1099
- onChange: descriptionChanged
1100
- }
1101
- )), /* @__PURE__ */ React.createElement(DialogActions, null, /* @__PURE__ */ React.createElement(
1102
- Button,
1103
- {
1104
- "data-testid": "trigger-button",
1105
- id: "trigger",
1106
- color: "secondary",
1107
- disabled: !description || loading,
1108
- variant: "contained",
1109
- onClick: () => handleTriggerAlarm(description),
1110
- endIcon: loading && /* @__PURE__ */ React.createElement(CircularProgress, { size: 16 })
1111
- },
1112
- "Trigger Incident"
1113
- ), /* @__PURE__ */ React.createElement(Button, { id: "close", color: "primary", onClick: handleDialog }, "Close")));
1114
- };
1115
-
1116
- function TriggerIncidentButton({ integrationKey, entityName, compact, handleRefresh }) {
1117
- const useStyles = makeStyles((theme) => ({
1118
- buttonStyle: {
1119
- color: theme.palette.text.primary,
1120
- "&:hover": {
1121
- backgroundColor: "transparent",
1122
- textDecoration: "underline"
1123
- }
1124
- },
1125
- containerStyle: {
1126
- fontSize: compact !== true ? "12px" : "10px",
1127
- width: compact !== true ? "80px" : "60px",
1128
- marginRight: "-10px"
1129
- },
1130
- iconStyle: {
1131
- fontSize: "30px",
1132
- marginBottom: "-10px"
1133
- },
1134
- textStyle: {
1135
- marginBottom: "-10px"
1136
- }
1137
- }));
1138
- const { buttonStyle, containerStyle, iconStyle, textStyle } = useStyles();
1139
- const [dialogShown, setDialogShown] = useState(false);
1140
- const showDialog = useCallback(() => {
1141
- setDialogShown(true);
1142
- }, [setDialogShown]);
1143
- const hideDialog = useCallback(() => {
1144
- setDialogShown(false);
1145
- }, [setDialogShown]);
1146
- const disabled = !integrationKey;
1147
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
1148
- IconButton,
1149
- {
1150
- "aria-label": "create-incident",
1151
- onClick: showDialog,
1152
- className: disabled ? "" : buttonStyle,
1153
- disabled
1154
- },
1155
- /* @__PURE__ */ React.createElement("div", { className: containerStyle }, /* @__PURE__ */ React.createElement(AddAlert, { className: iconStyle }), /* @__PURE__ */ React.createElement("p", { className: textStyle }, "Create new incident"))
1156
- ), integrationKey && /* @__PURE__ */ React.createElement(
1157
- TriggerDialog,
1158
- {
1159
- showDialog: dialogShown,
1160
- handleDialog: hideDialog,
1161
- integrationKey,
1162
- serviceName: entityName,
1163
- onIncidentCreated: handleRefresh
1164
- }
1165
- ));
1166
- }
1167
-
1168
- const useStyles$2 = makeStyles$1(
1169
- (theme) => createStyles$1({
1170
- overviewHeaderTextStyle: {
1171
- fontSize: "14px",
1172
- fontWeight: 500,
1173
- color: theme.palette.type === "light" ? "rgba(0, 0, 0, 0.54)" : "rgba(255, 255, 255, 0.7)"
1174
- },
1175
- oncallHeaderTextStyle: {
1176
- fontSize: "14px",
1177
- fontWeight: 500,
1178
- marginTop: "10px",
1179
- color: theme.palette.type === "light" ? "rgba(0, 0, 0, 0.54)" : "rgba(255, 255, 255, 0.7)"
1180
- },
1181
- headerStyle: {
1182
- marginBottom: "0px",
1183
- fontSize: "0px"
1184
- },
1185
- overviewHeaderContainerStyle: {
1186
- display: "flex",
1187
- margin: "15px",
1188
- marginBottom: "20px"
1189
- },
1190
- headerWithSubheaderContainerStyle: {
1191
- display: "flex",
1192
- alignItems: "center"
1193
- },
1194
- subheaderTextStyle: {
1195
- fontSize: "10px",
1196
- marginLeft: "5px"
1197
- },
1198
- overviewCardsContainerStyle: {
1199
- display: "flex",
1200
- margin: "15px",
1201
- marginTop: "-15px"
1202
- },
1203
- incidentMetricsContainerStyle: {
1204
- display: "flex",
1205
- height: "100%",
1206
- justifyContent: "center",
1207
- columnSpan: "all"
1208
- }
1209
- })
1210
- );
1211
- const BasicCard$1 = ({ children }) => /* @__PURE__ */ React.createElement(InfoCard, { title: "PagerDuty" }, children);
1212
- const PagerDutyCard$1 = (props) => {
1213
- var _a, _b, _c, _d, _e, _f, _g, _h;
1214
- const classes = useStyles$2();
1215
- const theme = useTheme();
1216
- const { readOnly, disableChangeEvents, disableOnCall } = props;
1217
- const api = useApi(pagerDutyApiRef);
1218
- const [refreshIncidents, setRefreshIncidents] = useState(false);
1219
- const [refreshChangeEvents, setRefreshChangeEvents] = useState(false);
1220
- const [refreshStatus, setRefreshStatus] = useState(false);
1221
- const handleRefresh = useCallback(() => {
1222
- setRefreshIncidents((x) => !x);
1223
- setRefreshChangeEvents((x) => !x);
1224
- setRefreshStatus((x) => !x);
1225
- }, []);
1226
- const {
1227
- value: service,
1228
- loading,
1229
- error
1230
- } = useAsync(async () => {
1231
- const { service: foundService } = await api.getServiceByPagerDutyEntity(
1232
- props
1233
- );
1234
- const serviceStandards = await api.getServiceStandardsByServiceId(
1235
- foundService.id
1236
- );
1237
- const serviceMetrics = await api.getServiceMetricsByServiceId(
1238
- foundService.id
1239
- );
1240
- const result = {
1241
- id: foundService.id,
1242
- name: foundService.name,
1243
- url: foundService.html_url,
1244
- policyId: foundService.escalation_policy.id,
1245
- policyLink: foundService.escalation_policy.html_url,
1246
- policyName: foundService.escalation_policy.name,
1247
- status: foundService.status,
1248
- standards: serviceStandards !== void 0 ? serviceStandards.standards : void 0,
1249
- metrics: serviceMetrics !== void 0 ? serviceMetrics.metrics : void 0
1250
- };
1251
- return result;
1252
- }, [props]);
1253
- if (error) {
1254
- let errorNode;
1255
- switch (error.constructor) {
1256
- case UnauthorizedError:
1257
- errorNode = /* @__PURE__ */ React.createElement(MissingTokenError, null);
1258
- break;
1259
- case NotFoundError:
1260
- errorNode = /* @__PURE__ */ React.createElement(ServiceNotFoundError, null);
1261
- break;
1262
- default:
1263
- errorNode = /* @__PURE__ */ React.createElement(ForbiddenError, null);
1264
- }
1265
- return /* @__PURE__ */ React.createElement(BasicCard$1, null, errorNode);
1266
- }
1267
- if (loading) {
1268
- return /* @__PURE__ */ React.createElement(BasicCard$1, null, /* @__PURE__ */ React.createElement(Progress, null));
1269
- }
1270
- return /* @__PURE__ */ React.createElement(Card, { "data-testid": "pagerduty-card" }, /* @__PURE__ */ React.createElement(
1271
- CardHeader,
1272
- {
1273
- className: classes.headerStyle,
1274
- 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" }),
1275
- action: !readOnly && props.integrationKey ? /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(
1276
- TriggerIncidentButton,
1277
- {
1278
- "data-testid": "trigger-incident-button",
1279
- integrationKey: props.integrationKey,
1280
- entityName: props.name,
1281
- handleRefresh
1282
- }
1283
- ), /* @__PURE__ */ React.createElement(OpenServiceButton, { serviceUrl: service.url })) : /* @__PURE__ */ React.createElement(OpenServiceButton, { serviceUrl: service.url })
1284
- }
1285
- ), /* @__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("span", { className: classes.headerWithSubheaderContainerStyle }, /* @__PURE__ */ React.createElement(Typography, { className: classes.overviewHeaderTextStyle }, "INSIGHTS"), /* @__PURE__ */ React.createElement(Typography, { className: classes.subheaderTextStyle }, "(last 30 days)"))), /* @__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, { item: true, md: 4 }, /* @__PURE__ */ React.createElement(
1286
- IncidentCounterCard,
1287
- {
1288
- count: (service == null ? void 0 : service.metrics) !== void 0 && service.metrics.length > 0 ? service == null ? void 0 : service.metrics[0].total_interruptions : void 0,
1289
- label: "interruptions",
1290
- color: theme.palette.textSubtle
1291
- }
1292
- )), /* @__PURE__ */ React.createElement(Grid, { item: true, md: 4 }, /* @__PURE__ */ React.createElement(
1293
- IncidentCounterCard,
1294
- {
1295
- 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,
1296
- label: "high urgency",
1297
- color: theme.palette.warning.main
1298
- }
1299
- )), /* @__PURE__ */ React.createElement(Grid, { item: true, md: 4 }, /* @__PURE__ */ React.createElement(
1300
- IncidentCounterCard,
1301
- {
1302
- count: (service == null ? void 0 : service.metrics) !== void 0 && ((_a = service == null ? void 0 : service.metrics) == null ? void 0 : _a.length) > 0 ? service == null ? void 0 : service.metrics[0].total_incident_count : void 0,
1303
- label: "incidents",
1304
- color: theme.palette.error.main
1305
- }
1306
- ))), /* @__PURE__ */ React.createElement(Grid, { item: true, md: 3 }, /* @__PURE__ */ React.createElement(
1307
- ServiceStandardsCard,
1308
- {
1309
- total: ((_b = service == null ? void 0 : service.standards) == null ? void 0 : _b.score) !== void 0 ? (_d = (_c = service == null ? void 0 : service.standards) == null ? void 0 : _c.score) == null ? void 0 : _d.total : void 0,
1310
- completed: ((_e = service == null ? void 0 : service.standards) == null ? void 0 : _e.score) !== void 0 ? (_g = (_f = service == null ? void 0 : service.standards) == null ? void 0 : _f.score) == null ? void 0 : _g.passing : void 0,
1311
- standards: (service == null ? void 0 : service.standards) !== void 0 ? (_h = service == null ? void 0 : service.standards) == null ? void 0 : _h.standards : void 0
1312
- }
1313
- ))), /* @__PURE__ */ React.createElement(Divider, null), /* @__PURE__ */ React.createElement(CardContent, null, /* @__PURE__ */ React.createElement(TabbedCard, null, /* @__PURE__ */ React.createElement(CardTab, { label: "Incidents" }, /* @__PURE__ */ React.createElement(
1314
- Incidents,
1315
- {
1316
- serviceId: service.id,
1317
- refreshIncidents
1318
- }
1319
- )), disableChangeEvents !== true ? /* @__PURE__ */ React.createElement(CardTab, { label: "Change Events" }, /* @__PURE__ */ React.createElement(
1320
- ChangeEvents,
1321
- {
1322
- "data-testid": "change-events",
1323
- serviceId: service.id,
1324
- refreshEvents: refreshChangeEvents
1325
- }
1326
- )) : /* @__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(
1327
- EscalationPolicy,
1328
- {
1329
- "data-testid": "oncall-card",
1330
- policyId: service.policyId,
1331
- policyUrl: service.policyLink,
1332
- policyName: service.policyName
1333
- }
1334
- )) : /* @__PURE__ */ React.createElement(React.Fragment, null)));
1335
- };
1336
-
1337
- const isPluginApplicableToEntity$1 = (entity) => {
1338
- var _a, _b;
1339
- return Boolean(
1340
- ((_a = entity.metadata.annotations) == null ? void 0 : _a[PAGERDUTY_INTEGRATION_KEY]) || ((_b = entity.metadata.annotations) == null ? void 0 : _b[PAGERDUTY_SERVICE_ID])
1341
- );
1342
- };
1343
- const EntityPagerDutyCard = (props) => {
1344
- const { readOnly, disableChangeEvents, disableOnCall } = props;
1345
- const { entity } = useEntity();
1346
- const pagerDutyEntity = getPagerDutyEntity(entity);
1347
- return /* @__PURE__ */ React.createElement(
1348
- PagerDutyCard$1,
1349
- {
1350
- ...pagerDutyEntity,
1351
- readOnly,
1352
- disableChangeEvents,
1353
- disableOnCall
1354
- }
1355
- );
1356
- };
1357
-
1358
- var index$1 = /*#__PURE__*/Object.freeze({
1359
- __proto__: null,
1360
- isPluginApplicableToEntity: isPluginApplicableToEntity$1,
1361
- EntityPagerDutyCard: EntityPagerDutyCard
1362
- });
1363
-
1364
- const useStyles$1 = makeStyles$1(
1365
- (theme) => createStyles$1({
1366
- overviewHeaderTextStyle: {
1367
- fontSize: "14px",
1368
- fontWeight: 500,
1369
- color: theme.palette.type === "light" ? "rgba(0, 0, 0, 0.54)" : "rgba(255, 255, 255, 0.7)"
1370
- },
1371
- headerStyle: {
1372
- marginBottom: "0px",
1373
- fontSize: "0px"
1374
- },
1375
- overviewHeaderContainerStyle: {
1376
- display: "flex",
1377
- margin: "0px",
1378
- padding: "15px",
1379
- marginBottom: "5px"
1380
- },
1381
- headerWithSubheaderContainerStyle: {
1382
- display: "flex",
1383
- alignItems: "center"
1384
- },
1385
- subheaderTextStyle: {
1386
- fontSize: "10px",
1387
- marginLeft: "5px"
1388
- },
1389
- overviewCardsContainerStyle: {
1390
- display: "flex",
1391
- margin: "15px",
1392
- marginTop: "-15px"
1393
- },
1394
- onCallAccordionDetails: {
1395
- display: "flex",
1396
- width: "100%",
1397
- marginTop: "-25px",
1398
- marginBottom: "-15px"
1399
- },
1400
- incidentMetricsContainerStyle: {
1401
- display: "flex",
1402
- height: "100%",
1403
- justifyContent: "center",
1404
- columnSpan: "all",
1405
- margin: "15px",
1406
- marginTop: "-15px"
1407
- }
1408
- })
1409
- );
1410
- const BasicCard = ({ children }) => /* @__PURE__ */ React.createElement(InfoCard, { title: "PagerDuty" }, children);
1411
- const PagerDutySmallCard = (props) => {
1412
- var _a, _b, _c, _d, _e, _f, _g, _h;
1413
- const classes = useStyles$1();
1414
- const theme = useTheme();
1415
- const { readOnly, disableInsights, disableOnCall } = props;
1416
- const api = useApi(pagerDutyApiRef);
1417
- const [refreshStatus, setRefreshStatus] = useState(false);
1418
- const handleRefresh = useCallback(() => {
1419
- setRefreshStatus((x) => !x);
1420
- }, []);
1421
- const {
1422
- value: service,
1423
- loading,
1424
- error
1425
- } = useAsync(async () => {
1426
- const { service: foundService } = await api.getServiceByPagerDutyEntity(
1427
- props
1428
- );
1429
- const serviceStandards = await api.getServiceStandardsByServiceId(
1430
- foundService.id
1431
- );
1432
- const serviceMetrics = await api.getServiceMetricsByServiceId(
1433
- foundService.id
1434
- );
1435
- const result = {
1436
- id: foundService.id,
1437
- name: foundService.name,
1438
- url: foundService.html_url,
1439
- policyId: foundService.escalation_policy.id,
1440
- policyLink: foundService.escalation_policy.html_url,
1441
- policyName: foundService.escalation_policy.name,
1442
- status: foundService.status,
1443
- standards: serviceStandards !== void 0 ? serviceStandards.standards : void 0,
1444
- metrics: serviceMetrics !== void 0 ? serviceMetrics.metrics : void 0
1445
- };
1446
- return result;
1447
- }, [props]);
1448
- if (error) {
1449
- let errorNode;
1450
- switch (error.constructor) {
1451
- case UnauthorizedError:
1452
- errorNode = /* @__PURE__ */ React.createElement(MissingTokenError, null);
1453
- break;
1454
- case NotFoundError:
1455
- errorNode = /* @__PURE__ */ React.createElement(ServiceNotFoundError, null);
1456
- break;
1457
- default:
1458
- errorNode = /* @__PURE__ */ React.createElement(ForbiddenError, null);
1459
- }
1460
- return /* @__PURE__ */ React.createElement(BasicCard, null, errorNode);
1461
- }
1462
- if (loading) {
1463
- return /* @__PURE__ */ React.createElement(BasicCard, null, /* @__PURE__ */ React.createElement(Progress, null));
1464
- }
1465
- return /* @__PURE__ */ React.createElement(Card, { "data-testid": "pagerduty-card" }, /* @__PURE__ */ React.createElement(
1466
- CardHeader,
1467
- {
1468
- className: classes.headerStyle,
1469
- 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" }),
1470
- action: !readOnly && props.integrationKey ? /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(
1471
- TriggerIncidentButton,
1472
- {
1473
- compact: true,
1474
- "data-testid": "trigger-incident-button",
1475
- integrationKey: props.integrationKey,
1476
- entityName: props.name,
1477
- handleRefresh
1478
- }
1479
- ), /* @__PURE__ */ React.createElement(OpenServiceButton, { compact: true, serviceUrl: service.url })) : /* @__PURE__ */ React.createElement(OpenServiceButton, { compact: true, serviceUrl: service.url })
1480
- }
1481
- ), /* @__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(
1482
- ServiceStandardsCard,
1483
- {
1484
- compact: true,
1485
- 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,
1486
- 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,
1487
- standards: (service == null ? void 0 : service.standards) !== void 0 ? (_g = service == null ? void 0 : service.standards) == null ? void 0 : _g.standards : void 0
1488
- }
1489
- ))), disableInsights !== true ? /* @__PURE__ */ React.createElement(Accordion, null, /* @__PURE__ */ React.createElement(
1490
- AccordionSummary,
1491
- {
1492
- expandIcon: /* @__PURE__ */ React.createElement(ExpandMoreIcon, null),
1493
- "aria-controls": "panel1a-content",
1494
- id: "panel1a-header"
1495
- },
1496
- /* @__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)"))
1497
- ), /* @__PURE__ */ React.createElement(AccordionDetails, null, /* @__PURE__ */ React.createElement(
1498
- Grid,
1499
- {
1500
- item: true,
1501
- md: 12,
1502
- className: classes.incidentMetricsContainerStyle
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 && service.metrics.length > 0 ? service == null ? void 0 : service.metrics[0].total_interruptions : void 0,
1509
- label: "interruptions",
1510
- color: theme.palette.textSubtle
1511
- }
1512
- )),
1513
- /* @__PURE__ */ React.createElement(Grid, { item: true, md: 4 }, /* @__PURE__ */ React.createElement(
1514
- IncidentCounterCard,
1515
- {
1516
- compact: true,
1517
- 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,
1518
- label: "high urgency",
1519
- color: theme.palette.warning.main
1520
- }
1521
- )),
1522
- /* @__PURE__ */ React.createElement(Grid, { item: true, md: 4 }, /* @__PURE__ */ React.createElement(
1523
- IncidentCounterCard,
1524
- {
1525
- compact: true,
1526
- 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,
1527
- label: "incidents",
1528
- color: theme.palette.error.main
1529
- }
1530
- ))
1531
- ))) : /* @__PURE__ */ React.createElement(React.Fragment, null), disableOnCall !== true ? /* @__PURE__ */ React.createElement(Accordion, null, /* @__PURE__ */ React.createElement(
1532
- AccordionSummary,
1533
- {
1534
- expandIcon: /* @__PURE__ */ React.createElement(ExpandMoreIcon, null),
1535
- "aria-controls": "panel1a-content",
1536
- id: "panel1a-header"
1537
- },
1538
- /* @__PURE__ */ React.createElement(Typography, { className: classes.overviewHeaderTextStyle }, "ON CALL")
1539
- ), /* @__PURE__ */ React.createElement(AccordionDetails, { className: classes.onCallAccordionDetails }, /* @__PURE__ */ React.createElement(
1540
- EscalationPolicy,
1541
- {
1542
- "data-testid": "oncall-card",
1543
- policyId: service.policyId,
1544
- policyUrl: service.policyLink,
1545
- policyName: service.policyName
1546
- }
1547
- ))) : /* @__PURE__ */ React.createElement(React.Fragment, null));
1548
- };
1549
-
1550
- const isPluginApplicableToEntity = (entity) => {
1551
- var _a, _b;
1552
- return Boolean(
1553
- ((_a = entity.metadata.annotations) == null ? void 0 : _a[PAGERDUTY_INTEGRATION_KEY]) || ((_b = entity.metadata.annotations) == null ? void 0 : _b[PAGERDUTY_SERVICE_ID])
1554
- );
1555
- };
1556
- const EntityPagerDutySmallCard = (props) => {
1557
- const { readOnly, disableInsights, disableOnCall } = props;
1558
- const { entity } = useEntity();
1559
- const pagerDutyEntity = getPagerDutyEntity(entity);
1560
- return /* @__PURE__ */ React.createElement(
1561
- PagerDutySmallCard,
1562
- {
1563
- ...pagerDutyEntity,
1564
- readOnly,
1565
- disableInsights,
1566
- disableOnCall
1567
- }
1568
- );
1569
- };
1570
-
1571
- var index = /*#__PURE__*/Object.freeze({
1572
- __proto__: null,
1573
- isPluginApplicableToEntity: isPluginApplicableToEntity,
1574
- EntityPagerDutySmallCard: EntityPagerDutySmallCard
1575
- });
1576
-
1577
- function usePagerdutyEntity() {
1578
- const { entity } = useEntity();
1579
- return getPagerDutyEntity(entity);
1580
- }
1581
-
1582
- const useStyles = makeStyles((theme) => ({
1583
- buttonStyle: {
1584
- backgroundColor: theme.palette.error.main,
1585
- color: theme.palette.error.contrastText,
1586
- "&:hover": {
1587
- backgroundColor: theme.palette.error.dark
1588
- }
1589
- }
1590
- }));
1591
- function TriggerButton(props) {
1592
- var _a;
1593
- const { buttonStyle } = useStyles();
1594
- const { integrationKey, name } = usePagerdutyEntity();
1595
- const [dialogShown, setDialogShown] = useState(false);
1596
- const showDialog = useCallback(() => {
1597
- setDialogShown(true);
1598
- }, [setDialogShown]);
1599
- const hideDialog = useCallback(() => {
1600
- setDialogShown(false);
1601
- }, [setDialogShown]);
1602
- const disabled = !integrationKey;
1603
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
1604
- Button,
1605
- {
1606
- onClick: showDialog,
1607
- variant: "contained",
1608
- className: disabled ? "" : buttonStyle,
1609
- disabled
1610
- },
1611
- integrationKey ? (_a = props.children) != null ? _a : "Create new incident" : "Missing integration key"
1612
- ), integrationKey && /* @__PURE__ */ React.createElement(
1613
- TriggerDialog,
1614
- {
1615
- showDialog: dialogShown,
1616
- handleDialog: hideDialog,
1617
- integrationKey,
1618
- serviceName: name
1619
- }
1620
- ));
1621
- }
1622
-
1623
- const PagerDutyCard = EntityPagerDutyCard;
1624
-
1625
- export { EntityPagerDutyCard$1 as E, HomePagePagerDutyCard as H, PagerDutyCard$1 as P, TriggerButton as T, UnauthorizedError as U, pagerDutyPlugin as a, PagerDutyPage as b, EntityPagerDutySmallCard$1 as c, isPluginApplicableToEntity as d, PagerDutyClient as e, PagerDutyCard as f, isPluginApplicableToEntity$1 as i, pagerDutyApiRef as p };
1626
- //# sourceMappingURL=index-84a03966.esm.js.map