@pagerduty/backstage-plugin 0.15.10-next.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/assets/PD-Green.svg +21 -0
  2. package/assets/PD-Icon.svg +13 -0
  3. package/assets/PD-White.svg +21 -0
  4. package/assets/emptystate.svg +6 -0
  5. package/assets/forbiddenstate.svg +25 -0
  6. package/dist/alpha/api.esm.js +22 -0
  7. package/dist/alpha/api.esm.js.map +1 -0
  8. package/dist/alpha/entity-cards.esm.js +69 -0
  9. package/dist/alpha/entity-cards.esm.js.map +1 -0
  10. package/dist/alpha/nav-items.esm.js +21 -0
  11. package/dist/alpha/nav-items.esm.js.map +1 -0
  12. package/dist/alpha/pages.esm.js +15 -0
  13. package/dist/alpha/pages.esm.js.map +1 -0
  14. package/dist/alpha/plugin.esm.js +26 -0
  15. package/dist/alpha/plugin.esm.js.map +1 -0
  16. package/dist/alpha.d.ts +139 -0
  17. package/dist/alpha.esm.js +2 -0
  18. package/dist/alpha.esm.js.map +1 -0
  19. package/dist/api/client.esm.js +225 -0
  20. package/dist/api/client.esm.js.map +1 -0
  21. package/dist/assets/PD-Green.svg +21 -0
  22. package/dist/assets/PD-Icon.svg +13 -0
  23. package/dist/assets/PD-White.svg +21 -0
  24. package/dist/assets/emptystate.svg +6 -0
  25. package/dist/assets/forbiddenstate.svg +25 -0
  26. package/dist/components/ChangeEvents/ChangeEventEmptyState.esm.js +29 -0
  27. package/dist/components/ChangeEvents/ChangeEventEmptyState.esm.js.map +1 -0
  28. package/dist/components/ChangeEvents/ChangeEventForbiddenState.esm.js +29 -0
  29. package/dist/components/ChangeEvents/ChangeEventForbiddenState.esm.js.map +1 -0
  30. package/dist/components/ChangeEvents/ChangeEventListItem.esm.js +85 -0
  31. package/dist/components/ChangeEvents/ChangeEventListItem.esm.js.map +1 -0
  32. package/dist/components/ChangeEvents/ChangeEvents.esm.js +60 -0
  33. package/dist/components/ChangeEvents/ChangeEvents.esm.js.map +1 -0
  34. package/dist/components/EntityPagerDutyCard/index.esm.js +29 -0
  35. package/dist/components/EntityPagerDutyCard/index.esm.js.map +1 -0
  36. package/dist/components/EntityPagerDutySmallCard/index.esm.js +29 -0
  37. package/dist/components/EntityPagerDutySmallCard/index.esm.js.map +1 -0
  38. package/dist/components/Errors/ForbiddenError.esm.js +24 -0
  39. package/dist/components/Errors/ForbiddenError.esm.js.map +1 -0
  40. package/dist/components/Errors/MissingTokenError.esm.js +24 -0
  41. package/dist/components/Errors/MissingTokenError.esm.js.map +1 -0
  42. package/dist/components/Errors/ServiceNotFoundError.esm.js +24 -0
  43. package/dist/components/Errors/ServiceNotFoundError.esm.js.map +1 -0
  44. package/dist/components/Escalation/EscalationPolicy.esm.js +53 -0
  45. package/dist/components/Escalation/EscalationPolicy.esm.js.map +1 -0
  46. package/dist/components/Escalation/EscalationUser.esm.js +97 -0
  47. package/dist/components/Escalation/EscalationUser.esm.js.map +1 -0
  48. package/dist/components/Escalation/EscalationUsersEmptyState.esm.js +23 -0
  49. package/dist/components/Escalation/EscalationUsersEmptyState.esm.js.map +1 -0
  50. package/dist/components/Escalation/EscalationUsersForbiddenState.esm.js +23 -0
  51. package/dist/components/Escalation/EscalationUsersForbiddenState.esm.js.map +1 -0
  52. package/dist/components/HomePagePagerDutyCard/Content.esm.js +9 -0
  53. package/dist/components/HomePagePagerDutyCard/Content.esm.js.map +1 -0
  54. package/dist/components/HomePagePagerDutyCard/index.esm.js +2 -0
  55. package/dist/components/HomePagePagerDutyCard/index.esm.js.map +1 -0
  56. package/dist/components/Icons/index.esm.js +9 -0
  57. package/dist/components/Icons/index.esm.js.map +1 -0
  58. package/dist/components/Incident/IncidentEmptyState.esm.js +29 -0
  59. package/dist/components/Incident/IncidentEmptyState.esm.js.map +1 -0
  60. package/dist/components/Incident/IncidentForbiddenState.esm.js +29 -0
  61. package/dist/components/Incident/IncidentForbiddenState.esm.js.map +1 -0
  62. package/dist/components/Incident/IncidentListItem.esm.js +128 -0
  63. package/dist/components/Incident/IncidentListItem.esm.js.map +1 -0
  64. package/dist/components/Incident/Incidents.esm.js +54 -0
  65. package/dist/components/Incident/Incidents.esm.js.map +1 -0
  66. package/dist/components/PagerDutyCard/index.esm.js +231 -0
  67. package/dist/components/PagerDutyCard/index.esm.js.map +1 -0
  68. package/dist/components/PagerDutyCardCommon/InsightsCard.esm.js +42 -0
  69. package/dist/components/PagerDutyCardCommon/InsightsCard.esm.js.map +1 -0
  70. package/dist/components/PagerDutyCardCommon/OpenServiceButton.esm.js +43 -0
  71. package/dist/components/PagerDutyCardCommon/OpenServiceButton.esm.js.map +1 -0
  72. package/dist/components/PagerDutyCardCommon/ServiceStandardsCard.esm.js +134 -0
  73. package/dist/components/PagerDutyCardCommon/ServiceStandardsCard.esm.js.map +1 -0
  74. package/dist/components/PagerDutyCardCommon/StatusCard.esm.js +109 -0
  75. package/dist/components/PagerDutyCardCommon/StatusCard.esm.js.map +1 -0
  76. package/dist/components/PagerDutyCardCommon/TriggerIncidentButton.esm.js +66 -0
  77. package/dist/components/PagerDutyCardCommon/TriggerIncidentButton.esm.js.map +1 -0
  78. package/dist/components/PagerDutyPage/MappingTable.esm.js +282 -0
  79. package/dist/components/PagerDutyPage/MappingTable.esm.js.map +1 -0
  80. package/dist/components/PagerDutyPage/ServiceMappingComponent.esm.js +50 -0
  81. package/dist/components/PagerDutyPage/ServiceMappingComponent.esm.js.map +1 -0
  82. package/dist/components/PagerDutyPage/index.esm.js +117 -0
  83. package/dist/components/PagerDutyPage/index.esm.js.map +1 -0
  84. package/dist/components/PagerDutySmallCard/index.esm.js +227 -0
  85. package/dist/components/PagerDutySmallCard/index.esm.js.map +1 -0
  86. package/dist/components/TriggerButton/index.esm.js +51 -0
  87. package/dist/components/TriggerButton/index.esm.js.map +1 -0
  88. package/dist/components/TriggerDialog/TriggerDialog.esm.js +120 -0
  89. package/dist/components/TriggerDialog/TriggerDialog.esm.js.map +1 -0
  90. package/dist/components/constants.esm.js +6 -0
  91. package/dist/components/constants.esm.js.map +1 -0
  92. package/dist/components/pagerDutyEntity.esm.js +14 -0
  93. package/dist/components/pagerDutyEntity.esm.js.map +1 -0
  94. package/dist/deprecated.esm.js +10 -0
  95. package/dist/deprecated.esm.js.map +1 -0
  96. package/dist/hooks/index.esm.js +10 -0
  97. package/dist/hooks/index.esm.js.map +1 -0
  98. package/dist/index.d.ts +182 -0
  99. package/dist/index.esm.js +8 -0
  100. package/dist/index.esm.js.map +1 -0
  101. package/dist/package.json.esm.js +133 -0
  102. package/dist/package.json.esm.js.map +1 -0
  103. package/dist/plugin.esm.js +76 -0
  104. package/dist/plugin.esm.js.map +1 -0
  105. package/dist/routes.esm.js +6 -0
  106. package/dist/routes.esm.js.map +1 -0
  107. package/package.json +19 -7
@@ -0,0 +1,134 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { makeStyles, withStyles, LinearProgress, Typography } from '@material-ui/core';
3
+ import InfoIcon from '@material-ui/icons/Info';
4
+ import CheckCircle from '@material-ui/icons/CheckCircle';
5
+ import RadioButtonUncheckedIcon from '@material-ui/icons/RadioButtonUnchecked';
6
+ import { Card, Flex, TooltipTrigger, ButtonIcon, Tooltip } from '@backstage/ui';
7
+
8
+ function colorFromPercentage(theme, percentage) {
9
+ if (percentage < 0.5) {
10
+ return theme.palette.error.main;
11
+ } else if (percentage < 0.8) {
12
+ return theme.palette.warning.main;
13
+ }
14
+ return theme.palette.success.main;
15
+ }
16
+ function ServiceStandardsCard({ total, completed, standards, compact }) {
17
+ const useStyles = makeStyles((theme) => ({
18
+ cardStyle: {
19
+ height: compact !== true ? "120px" : "80px",
20
+ padding: 0,
21
+ position: "relative",
22
+ backgroundColor: "rgba(0, 0, 0, 0.03)"
23
+ },
24
+ largeTextStyle: {
25
+ fontSize: compact !== true ? "50px" : "40px",
26
+ color: completed !== void 0 && total !== void 0 ? colorFromPercentage(theme, completed / total) : colorFromPercentage(theme, 0),
27
+ alignSelf: "center",
28
+ justifyContent: "center"
29
+ },
30
+ smallTextStyle: {
31
+ color: theme.palette.textSubtle,
32
+ fontSize: compact !== true ? "14px" : "12px",
33
+ fontWeight: "bold",
34
+ alignSelf: "center",
35
+ marginLeft: "-17px",
36
+ marginBottom: "-26px"
37
+ },
38
+ tooltipIcon: {
39
+ marginRight: "5px"
40
+ },
41
+ infoIcon: {
42
+ color: "gray",
43
+ "&:hover": {
44
+ backgroundColor: "transparent"
45
+ }
46
+ },
47
+ standardItem: {
48
+ display: "flex",
49
+ alignItems: "center"
50
+ },
51
+ linearProgressContainer: {
52
+ left: 0,
53
+ position: "absolute",
54
+ bottom: 0,
55
+ width: "100%",
56
+ padding: "0px"
57
+ },
58
+ textContainerStyle: {
59
+ position: "absolute",
60
+ top: compact ? "5px" : "20px",
61
+ width: "100%"
62
+ },
63
+ tooltipTriggerStyles: {
64
+ position: "relative",
65
+ zIndex: 1
66
+ }
67
+ }));
68
+ const BorderLinearProgress = withStyles((theme) => ({
69
+ root: {
70
+ height: 10,
71
+ borderRadius: 5,
72
+ margin: 5
73
+ },
74
+ colorPrimary: {
75
+ backgroundColor: theme.palette.grey[theme.palette.type === "light" ? 200 : 700]
76
+ },
77
+ bar: {
78
+ borderRadius: 5,
79
+ backgroundColor: completed !== void 0 && total !== void 0 ? colorFromPercentage(theme, completed / total) : colorFromPercentage(theme, 0)
80
+ }
81
+ }))(LinearProgress);
82
+ const {
83
+ cardStyle,
84
+ largeTextStyle,
85
+ smallTextStyle,
86
+ linearProgressContainer,
87
+ tooltipIcon,
88
+ textContainerStyle,
89
+ infoIcon,
90
+ standardItem,
91
+ tooltipTriggerStyles
92
+ } = useStyles();
93
+ if (standards === void 0 || completed === void 0 || total === void 0) {
94
+ return /* @__PURE__ */ jsx(Card, { className: cardStyle, children: /* @__PURE__ */ jsx(Flex, { justify: "center", children: /* @__PURE__ */ jsx(Typography, { className: smallTextStyle, children: "Unable to retrieve Scores" }) }) });
95
+ }
96
+ return /* @__PURE__ */ jsx(Card, { className: cardStyle, children: /* @__PURE__ */ jsxs(Flex, { direction: "column", children: [
97
+ /* @__PURE__ */ jsxs(TooltipTrigger, { children: [
98
+ /* @__PURE__ */ jsx(
99
+ ButtonIcon,
100
+ {
101
+ className: tooltipTriggerStyles,
102
+ icon: /* @__PURE__ */ jsx(InfoIcon, { className: infoIcon }),
103
+ variant: "tertiary"
104
+ }
105
+ ),
106
+ /* @__PURE__ */ jsx(Tooltip, { children: standards?.map((standard, key) => /* @__PURE__ */ jsx(Typography, { children: standard.pass ? /* @__PURE__ */ jsxs(Typography, { className: standardItem, children: [
107
+ /* @__PURE__ */ jsx(CheckCircle, { className: tooltipIcon }),
108
+ " ",
109
+ standard.name
110
+ ] }) : /* @__PURE__ */ jsxs(Typography, { className: standardItem, children: [
111
+ /* @__PURE__ */ jsx(RadioButtonUncheckedIcon, { className: tooltipIcon }),
112
+ " ",
113
+ standard.name
114
+ ] }) }, key)) })
115
+ ] }),
116
+ /* @__PURE__ */ jsxs(Flex, { justify: "center", className: textContainerStyle, children: [
117
+ /* @__PURE__ */ jsx(Typography, { className: largeTextStyle, children: completed }),
118
+ /* @__PURE__ */ jsxs(Typography, { className: smallTextStyle, children: [
119
+ "/",
120
+ total
121
+ ] })
122
+ ] }),
123
+ /* @__PURE__ */ jsx("div", { className: linearProgressContainer, children: /* @__PURE__ */ jsx(
124
+ BorderLinearProgress,
125
+ {
126
+ variant: "determinate",
127
+ value: completed / total * 100
128
+ }
129
+ ) })
130
+ ] }) });
131
+ }
132
+
133
+ export { colorFromPercentage, ServiceStandardsCard as default };
134
+ //# sourceMappingURL=ServiceStandardsCard.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ServiceStandardsCard.esm.js","sources":["../../../src/components/PagerDutyCardCommon/ServiceStandardsCard.tsx"],"sourcesContent":["import { BackstageTheme } from '@backstage/theme';\nimport {\n LinearProgress,\n Theme,\n Typography,\n makeStyles,\n withStyles,\n} from '@material-ui/core';\nimport InfoIcon from '@material-ui/icons/Info';\nimport { PagerDutyServiceStandard } from '@pagerduty/backstage-plugin-common';\nimport CheckCircle from '@material-ui/icons/CheckCircle';\nimport RadioButtonUncheckedIcon from '@material-ui/icons/RadioButtonUnchecked';\nimport { ButtonIcon, Card, Flex, Tooltip, TooltipTrigger } from '@backstage/ui';\n\ntype Props = {\n total: number | undefined;\n completed: number | undefined;\n standards: PagerDutyServiceStandard[] | undefined;\n compact?: boolean;\n};\n\nexport function colorFromPercentage(theme: Theme, percentage: number) {\n if (percentage < 0.5) {\n return theme.palette.error.main;\n } else if (percentage < 0.8) {\n return theme.palette.warning.main;\n }\n return theme.palette.success.main;\n}\n\nfunction ServiceStandardsCard({ total, completed, standards, compact }: Props) {\n const useStyles = makeStyles<BackstageTheme>(theme => ({\n cardStyle: {\n height: compact !== true ? '120px' : '80px',\n padding: 0,\n position: 'relative',\n backgroundColor: 'rgba(0, 0, 0, 0.03)',\n },\n largeTextStyle: {\n fontSize: compact !== true ? '50px' : '40px',\n color:\n completed !== undefined && total !== undefined\n ? colorFromPercentage(theme, completed / total)\n : colorFromPercentage(theme, 0),\n alignSelf: 'center',\n justifyContent: 'center',\n },\n smallTextStyle: {\n color: theme.palette.textSubtle,\n fontSize: compact !== true ? '14px' : '12px',\n fontWeight: 'bold',\n alignSelf: 'center',\n marginLeft: '-17px',\n marginBottom: '-26px',\n },\n tooltipIcon: {\n marginRight: '5px',\n },\n infoIcon: {\n color: 'gray',\n '&:hover': {\n backgroundColor: 'transparent',\n },\n },\n standardItem: {\n display: 'flex',\n alignItems: 'center',\n },\n linearProgressContainer: {\n left: 0,\n position: 'absolute',\n bottom: 0,\n width: '100%',\n padding: '0px',\n },\n textContainerStyle: {\n position: 'absolute',\n top: compact ? '5px' : '20px',\n width: '100%',\n },\n tooltipTriggerStyles: {\n position: 'relative',\n zIndex: 1,\n },\n }));\n\n const BorderLinearProgress = withStyles(theme => ({\n root: {\n height: 10,\n borderRadius: 5,\n margin: 5,\n },\n colorPrimary: {\n backgroundColor:\n theme.palette.grey[theme.palette.type === 'light' ? 200 : 700],\n },\n bar: {\n borderRadius: 5,\n backgroundColor:\n completed !== undefined && total !== undefined\n ? colorFromPercentage(theme, completed / total)\n : colorFromPercentage(theme, 0),\n },\n }))(LinearProgress);\n\n const {\n cardStyle,\n largeTextStyle,\n smallTextStyle,\n linearProgressContainer,\n tooltipIcon,\n textContainerStyle,\n infoIcon,\n standardItem,\n tooltipTriggerStyles,\n } = useStyles();\n\n if (\n standards === undefined ||\n completed === undefined ||\n total === undefined\n ) {\n return (\n <Card className={cardStyle}>\n <Flex justify=\"center\">\n <Typography className={smallTextStyle}>\n Unable to retrieve Scores\n </Typography>\n </Flex>\n </Card>\n );\n }\n\n return (\n <Card className={cardStyle}>\n <Flex direction=\"column\">\n <TooltipTrigger>\n <ButtonIcon\n className={tooltipTriggerStyles}\n icon={<InfoIcon className={infoIcon} />}\n variant=\"tertiary\"\n />\n <Tooltip>\n {standards?.map((standard, key) => (\n <Typography key={key}>\n {standard.pass ? (\n <Typography className={standardItem}>\n <CheckCircle className={tooltipIcon} /> {standard.name}\n </Typography>\n ) : (\n <Typography className={standardItem}>\n <RadioButtonUncheckedIcon className={tooltipIcon} />{' '}\n {standard.name}\n </Typography>\n )}\n </Typography>\n ))}\n </Tooltip>\n </TooltipTrigger>\n <Flex justify=\"center\" className={textContainerStyle}>\n <Typography className={largeTextStyle}>{completed}</Typography>\n <Typography className={smallTextStyle}>/{total}</Typography>\n </Flex>\n <div className={linearProgressContainer}>\n <BorderLinearProgress\n variant=\"determinate\"\n value={(completed! / total!) * 100}\n />\n </div>\n </Flex>\n </Card>\n );\n}\n\nexport default ServiceStandardsCard;\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,109 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { useEffect } from 'react';
3
+ import { makeStyles } from '@material-ui/core/styles';
4
+ import { useApi } from '@backstage/core-plugin-api';
5
+ import { pagerDutyApiRef } from '../../api/client.esm.js';
6
+ import { useAsyncFn } from 'react-use';
7
+ import Alert from '@material-ui/lab/Alert/Alert';
8
+ import { Progress } from '@backstage/core-components';
9
+ import { Card } from '@backstage/ui';
10
+ import { Typography } from '@material-ui/core';
11
+
12
+ function labelFromStatus(status) {
13
+ let label;
14
+ switch (status) {
15
+ case "active":
16
+ label = "OK";
17
+ break;
18
+ case "warning":
19
+ label = "ACTIVE";
20
+ break;
21
+ case "critical":
22
+ label = "ALARM";
23
+ break;
24
+ case "maintenance":
25
+ label = "MAINTENANCE";
26
+ break;
27
+ case "disabled":
28
+ label = "DISABLED";
29
+ break;
30
+ default:
31
+ label = "OK";
32
+ break;
33
+ }
34
+ return label;
35
+ }
36
+ function colorFromStatus(theme, status) {
37
+ let color;
38
+ switch (status) {
39
+ case "active":
40
+ color = theme.palette.success.main;
41
+ break;
42
+ case "warning":
43
+ color = theme.palette.warningBackground;
44
+ break;
45
+ case "critical":
46
+ color = theme.palette.error.main;
47
+ break;
48
+ case "maintenance":
49
+ color = "#ebdc00";
50
+ break;
51
+ case "disabled":
52
+ color = "#A9A9A9";
53
+ break;
54
+ default:
55
+ color = theme.palette.success.main;
56
+ break;
57
+ }
58
+ return color;
59
+ }
60
+ function StatusCard({ serviceId, refreshStatus, account, compact }) {
61
+ const api = useApi(pagerDutyApiRef);
62
+ const [{ value: status, loading, error }, getStatus] = useAsyncFn(
63
+ async () => {
64
+ const { service: foundService } = await api.getServiceById(
65
+ serviceId,
66
+ account
67
+ );
68
+ return foundService.status;
69
+ }
70
+ );
71
+ const useStyles = makeStyles((theme) => ({
72
+ cardStyle: {
73
+ height: compact !== true ? "120px" : "80px",
74
+ display: "flex",
75
+ alignItems: "center",
76
+ justifyContent: "center",
77
+ backgroundColor: status !== void 0 ? colorFromStatus(theme, status) : colorFromStatus(theme, "active")
78
+ },
79
+ largeTextStyle: {
80
+ color: "white",
81
+ fontWeight: "bold",
82
+ fontSize: "20px",
83
+ wordWrap: "break-word"
84
+ }
85
+ }));
86
+ const { cardStyle, largeTextStyle } = useStyles();
87
+ useEffect(() => {
88
+ getStatus();
89
+ }, [refreshStatus, getStatus]);
90
+ if (error) {
91
+ if (error.message.includes("Forbidden")) {
92
+ return /* @__PURE__ */ jsx(Typography, { children: "forbidden" });
93
+ }
94
+ return /* @__PURE__ */ jsxs(Alert, { severity: "error", children: [
95
+ "Error encountered while fetching information. ",
96
+ error.message
97
+ ] });
98
+ }
99
+ if (loading) {
100
+ return /* @__PURE__ */ jsx(Progress, {});
101
+ }
102
+ if (!status) {
103
+ return /* @__PURE__ */ jsx(Typography, { children: "not found" });
104
+ }
105
+ return /* @__PURE__ */ jsx(Card, { className: cardStyle, children: status !== void 0 ? /* @__PURE__ */ jsx(Typography, { className: largeTextStyle, children: labelFromStatus(status) }) : /* @__PURE__ */ jsx(Typography, { className: largeTextStyle, children: "Unable to get status" }) });
106
+ }
107
+
108
+ export { StatusCard as default };
109
+ //# sourceMappingURL=StatusCard.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusCard.esm.js","sources":["../../../src/components/PagerDutyCardCommon/StatusCard.tsx"],"sourcesContent":["import { useEffect } from 'react';\nimport { Theme, makeStyles } from '@material-ui/core/styles';\nimport { BackstageTheme } from '@backstage/theme';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { pagerDutyApiRef } from '../../api';\nimport { useAsyncFn } from 'react-use';\nimport Alert from '@material-ui/lab/Alert/Alert';\nimport { Progress } from '@backstage/core-components';\nimport { Card } from '@backstage/ui';\nimport { Typography } from '@material-ui/core';\n\ntype Props = {\n serviceId: string;\n refreshStatus: boolean;\n account?: string;\n compact?: boolean;\n};\n\nfunction labelFromStatus(status: string) {\n let label;\n switch (status) {\n case 'active':\n label = 'OK';\n break;\n case 'warning':\n label = 'ACTIVE';\n break;\n case 'critical':\n label = 'ALARM';\n break;\n case 'maintenance':\n label = 'MAINTENANCE';\n break;\n case 'disabled':\n label = 'DISABLED';\n break;\n default:\n label = 'OK';\n break;\n }\n\n return label;\n}\n\nfunction colorFromStatus(theme: Theme, status: string) {\n let color;\n switch (status) {\n case 'active':\n color = theme.palette.success.main;\n break;\n case 'warning':\n color = theme.palette.warningBackground;\n break;\n case 'critical':\n color = theme.palette.error.main;\n break;\n case 'maintenance':\n color = '#ebdc00';\n break;\n case 'disabled':\n color = '#A9A9A9';\n break;\n default:\n color = theme.palette.success.main;\n break;\n }\n\n return color;\n}\n\nfunction StatusCard({ serviceId, refreshStatus, account, compact }: Props) {\n const api = useApi(pagerDutyApiRef);\n const [{ value: status, loading, error }, getStatus] = useAsyncFn(\n async () => {\n const { service: foundService } = await api.getServiceById(\n serviceId,\n account,\n );\n return foundService.status;\n },\n );\n\n const useStyles = makeStyles<BackstageTheme>(theme => ({\n cardStyle: {\n height: compact !== true ? '120px' : '80px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor:\n status !== undefined\n ? colorFromStatus(theme, status)\n : colorFromStatus(theme, 'active'),\n },\n largeTextStyle: {\n color: 'white',\n fontWeight: 'bold',\n fontSize: '20px',\n wordWrap: 'break-word',\n },\n }));\n\n const { cardStyle, largeTextStyle } = useStyles();\n\n useEffect(() => {\n getStatus();\n }, [refreshStatus, getStatus]);\n\n if (error) {\n if (error.message.includes('Forbidden')) {\n return <Typography>forbidden</Typography>;\n }\n\n return (\n <Alert severity=\"error\">\n Error encountered while fetching information. {error.message}\n </Alert>\n );\n }\n\n if (loading) {\n return <Progress />;\n }\n\n if (!status) {\n return <Typography>not found</Typography>;\n }\n\n return (\n <Card className={cardStyle}>\n {status !== undefined ? (\n <Typography className={largeTextStyle}>\n {labelFromStatus(status)}\n </Typography>\n ) : (\n <Typography className={largeTextStyle}>Unable to get status</Typography>\n )}\n </Card>\n );\n}\n\nexport default StatusCard;\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
+ import { useState, useCallback } from 'react';
3
+ import { makeStyles, Typography } from '@material-ui/core';
4
+ import { TriggerDialog } from '../TriggerDialog/TriggerDialog.esm.js';
5
+ import AddAlert from '@material-ui/icons/AddAlert';
6
+ import { ButtonIcon } from '@backstage/ui';
7
+
8
+ function TriggerIncidentButton({
9
+ integrationKey,
10
+ entityName,
11
+ compact,
12
+ handleRefresh
13
+ }) {
14
+ const useStyles = makeStyles(() => ({
15
+ containerStyle: {
16
+ fontSize: compact !== true ? "12px" : "10px",
17
+ width: compact !== true ? "80px" : "60px",
18
+ display: "flex",
19
+ flexDirection: "column",
20
+ alignItems: "center"
21
+ },
22
+ textStyle: {
23
+ textAlign: "center",
24
+ fontSize: "12px",
25
+ minWidth: "30px"
26
+ }
27
+ }));
28
+ const { containerStyle, textStyle } = useStyles();
29
+ const [dialogShown, setDialogShown] = useState(false);
30
+ const showDialog = useCallback(() => {
31
+ setDialogShown(true);
32
+ }, [setDialogShown]);
33
+ const hideDialog = useCallback(() => {
34
+ setDialogShown(false);
35
+ }, [setDialogShown]);
36
+ const disabled = !integrationKey;
37
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
38
+ /* @__PURE__ */ jsxs("div", { className: containerStyle, children: [
39
+ /* @__PURE__ */ jsx(
40
+ ButtonIcon,
41
+ {
42
+ variant: "tertiary",
43
+ size: "medium",
44
+ "aria-label": "create-incident",
45
+ onClick: showDialog,
46
+ isDisabled: disabled,
47
+ icon: /* @__PURE__ */ jsx(AddAlert, {})
48
+ }
49
+ ),
50
+ /* @__PURE__ */ jsx(Typography, { className: textStyle, children: "Create new incident" })
51
+ ] }),
52
+ integrationKey && /* @__PURE__ */ jsx(
53
+ TriggerDialog,
54
+ {
55
+ showDialog: dialogShown,
56
+ handleDialog: hideDialog,
57
+ integrationKey,
58
+ serviceName: entityName,
59
+ onIncidentCreated: handleRefresh
60
+ }
61
+ )
62
+ ] });
63
+ }
64
+
65
+ export { TriggerIncidentButton };
66
+ //# sourceMappingURL=TriggerIncidentButton.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TriggerIncidentButton.esm.js","sources":["../../../src/components/PagerDutyCardCommon/TriggerIncidentButton.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// eslint-disable-next-line @backstage/no-undeclared-imports\nimport { useCallback, useState } from 'react';\nimport { makeStyles, Typography } from '@material-ui/core';\nimport { BackstageTheme } from '@backstage/theme';\n\nimport { TriggerDialog } from '../TriggerDialog';\nimport AddAlert from '@material-ui/icons/AddAlert';\nimport { ButtonIcon } from '@backstage/ui';\n\n/** @public */\nexport type TriggerIncidentButtonProps = {\n integrationKey: string | undefined;\n entityName: string;\n compact?: boolean;\n handleRefresh: () => void;\n};\n\n/** @public */\nexport function TriggerIncidentButton({\n integrationKey,\n entityName,\n compact,\n handleRefresh,\n}: TriggerIncidentButtonProps) {\n const useStyles = makeStyles<BackstageTheme>(() => ({\n containerStyle: {\n fontSize: compact !== true ? '12px' : '10px',\n width: compact !== true ? '80px' : '60px',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n },\n textStyle: {\n textAlign: 'center',\n fontSize: '12px',\n minWidth: '30px',\n },\n }));\n\n const { containerStyle, textStyle } = useStyles();\n const [dialogShown, setDialogShown] = useState<boolean>(false);\n\n const showDialog = useCallback(() => {\n setDialogShown(true);\n }, [setDialogShown]);\n const hideDialog = useCallback(() => {\n setDialogShown(false);\n }, [setDialogShown]);\n\n const disabled = !integrationKey;\n\n return (\n <>\n <div className={containerStyle}>\n <ButtonIcon\n variant=\"tertiary\"\n size=\"medium\"\n aria-label=\"create-incident\"\n onClick={showDialog}\n isDisabled={disabled}\n icon={<AddAlert />}\n />\n\n <Typography className={textStyle}>Create new incident</Typography>\n </div>\n {integrationKey && (\n <TriggerDialog\n showDialog={dialogShown}\n handleDialog={hideDialog}\n integrationKey={integrationKey}\n serviceName={entityName}\n onIncidentCreated={handleRefresh}\n />\n )}\n </>\n );\n}\n"],"names":[],"mappings":";;;;;;;AAkCO,SAAS,qBAAA,CAAsB;AAAA,EACpC,cAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,EAA+B;AAC7B,EAAA,MAAM,SAAA,GAAY,WAA2B,OAAO;AAAA,IAClD,cAAA,EAAgB;AAAA,MACd,QAAA,EAAU,OAAA,KAAY,IAAA,GAAO,MAAA,GAAS,MAAA;AAAA,MACtC,KAAA,EAAO,OAAA,KAAY,IAAA,GAAO,MAAA,GAAS,MAAA;AAAA,MACnC,OAAA,EAAS,MAAA;AAAA,MACT,aAAA,EAAe,QAAA;AAAA,MACf,UAAA,EAAY;AAAA,KACd;AAAA,IACA,SAAA,EAAW;AAAA,MACT,SAAA,EAAW,QAAA;AAAA,MACX,QAAA,EAAU,MAAA;AAAA,MACV,QAAA,EAAU;AAAA;AACZ,GACF,CAAE,CAAA;AAEF,EAAA,MAAM,EAAE,cAAA,EAAgB,SAAA,EAAU,GAAI,SAAA,EAAU;AAChD,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAkB,KAAK,CAAA;AAE7D,EAAA,MAAM,UAAA,GAAa,YAAY,MAAM;AACnC,IAAA,cAAA,CAAe,IAAI,CAAA;AAAA,EACrB,CAAA,EAAG,CAAC,cAAc,CAAC,CAAA;AACnB,EAAA,MAAM,UAAA,GAAa,YAAY,MAAM;AACnC,IAAA,cAAA,CAAe,KAAK,CAAA;AAAA,EACtB,CAAA,EAAG,CAAC,cAAc,CAAC,CAAA;AAEnB,EAAA,MAAM,WAAW,CAAC,cAAA;AAElB,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAW,cAAA,EACd,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,OAAA,EAAQ,UAAA;AAAA,UACR,IAAA,EAAK,QAAA;AAAA,UACL,YAAA,EAAW,iBAAA;AAAA,UACX,OAAA,EAAS,UAAA;AAAA,UACT,UAAA,EAAY,QAAA;AAAA,UACZ,IAAA,sBAAO,QAAA,EAAA,EAAS;AAAA;AAAA,OAClB;AAAA,sBAEA,GAAA,CAAC,UAAA,EAAA,EAAW,SAAA,EAAW,SAAA,EAAW,QAAA,EAAA,qBAAA,EAAmB;AAAA,KAAA,EACvD,CAAA;AAAA,IACC,cAAA,oBACC,GAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACC,UAAA,EAAY,WAAA;AAAA,QACZ,YAAA,EAAc,UAAA;AAAA,QACd,cAAA;AAAA,QACA,WAAA,EAAa,UAAA;AAAA,QACb,iBAAA,EAAmB;AAAA;AAAA;AACrB,GAAA,EAEJ,CAAA;AAEJ;;;;"}
@@ -0,0 +1,282 @@
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { useState, useEffect, useMemo } from 'react';
3
+ import { useMaterialReactTable, MRT_EditActionButtons, MaterialReactTable } from 'material-react-table';
4
+ import { Typography, Box, DialogTitle, DialogContent, DialogActions } from '@material-ui/core';
5
+ import { Flex, TooltipTrigger, ButtonIcon, Tooltip } from '@backstage/ui';
6
+ import { QueryClient, QueryClientProvider, useMutation } from '@tanstack/react-query';
7
+ import { Edit, OpenInBrowser } from '@mui/icons-material';
8
+ import { useApi } from '@backstage/core-plugin-api';
9
+ import { pagerDutyApiRef } from '../../api/client.esm.js';
10
+
11
+ function getColorFromStatus(status) {
12
+ switch (status) {
13
+ case "InSync":
14
+ return "green";
15
+ case "OutOfSync":
16
+ return "red";
17
+ case "NotMapped":
18
+ return "orange";
19
+ default:
20
+ return "gray";
21
+ }
22
+ }
23
+ function makeReadable(status) {
24
+ switch (status) {
25
+ case "InSync":
26
+ return "In Sync";
27
+ case "OutOfSync":
28
+ return "Out of Sync";
29
+ case "NotMapped":
30
+ return "Not Mapped";
31
+ default:
32
+ return "Refresh to Update";
33
+ }
34
+ }
35
+ const MappingTable = ({
36
+ mappings,
37
+ catalogEntities
38
+ }) => {
39
+ const DenseTable = () => {
40
+ const [validationErrors, setValidationErrors] = useState({});
41
+ const [entityOptions, setEntityOptions] = useState(
42
+ []
43
+ );
44
+ const pagerDutyApi = useApi(pagerDutyApiRef);
45
+ useEffect(() => {
46
+ getEntityOptions();
47
+ }, []);
48
+ const columns = useMemo(
49
+ () => [
50
+ {
51
+ id: "serviceId",
52
+ accessorKey: "serviceId",
53
+ header: "Service ID",
54
+ visibleInShowHideMenu: false,
55
+ enableEditing: false,
56
+ Edit: () => null,
57
+ Cell: ({ cell }) => /* @__PURE__ */ jsx(Typography, { variant: "body1", style: { fontWeight: 600 }, children: cell.getValue() })
58
+ },
59
+ {
60
+ id: "integrationKey",
61
+ accessorKey: "integrationKey",
62
+ header: "Integration Key",
63
+ visibleInShowHideMenu: false,
64
+ enableEditing: false,
65
+ Edit: () => null
66
+ },
67
+ {
68
+ id: "serviceName",
69
+ accessorKey: "serviceName",
70
+ header: "PagerDuty Service",
71
+ enableEditing: false
72
+ },
73
+ {
74
+ id: "account",
75
+ accessorKey: "account",
76
+ header: "Account",
77
+ enableEditing: false,
78
+ Edit: () => null
79
+ },
80
+ {
81
+ id: "team",
82
+ accessorKey: "team",
83
+ header: "Team",
84
+ enableEditing: false
85
+ },
86
+ {
87
+ id: "escalationPolicy",
88
+ accessorKey: "escalationPolicy",
89
+ header: "Escalation Policy",
90
+ enableEditing: false
91
+ },
92
+ {
93
+ id: "entityRef",
94
+ accessorKey: "entityRef",
95
+ header: "Mapping",
96
+ visibleInShowHideMenu: false,
97
+ editVariant: "select",
98
+ editSelectOptions: entityOptions,
99
+ muiEditTextFieldProps: {
100
+ select: true,
101
+ error: !!validationErrors?.state,
102
+ helperText: validationErrors?.state,
103
+ multiline: true,
104
+ type: "range"
105
+ }
106
+ },
107
+ {
108
+ id: "entityName",
109
+ accessorKey: "entityName",
110
+ header: "Mapped Entity Name",
111
+ enableEditing: false,
112
+ Edit: () => null
113
+ },
114
+ {
115
+ id: "status",
116
+ accessorKey: "status",
117
+ header: "Status",
118
+ enableEditing: false,
119
+ Edit: () => null,
120
+ Cell: ({ cell }) => /* @__PURE__ */ jsx(
121
+ Box,
122
+ {
123
+ component: "span",
124
+ bgcolor: getColorFromStatus(cell.getValue()),
125
+ borderRadius: "0.25rem",
126
+ color: "white",
127
+ p: "0.25rem",
128
+ children: makeReadable(cell.getValue())
129
+ }
130
+ )
131
+ },
132
+ {
133
+ id: "serviceUrl",
134
+ accessorKey: "serviceUrl",
135
+ header: "Service URL",
136
+ visibleInShowHideMenu: false,
137
+ enableEditing: false,
138
+ Edit: () => null
139
+ }
140
+ ],
141
+ [validationErrors, entityOptions]
142
+ );
143
+ function useUpdateMapping() {
144
+ return useMutation({
145
+ mutationFn: async (mapping) => {
146
+ return await pagerDutyApi.storeServiceMapping(
147
+ mapping.serviceId,
148
+ mapping.integrationKey ?? "",
149
+ mapping.entityRef,
150
+ mapping.account ?? ""
151
+ );
152
+ }
153
+ });
154
+ }
155
+ const { mutateAsync: updateMapping, isPending: isUpdatingMapping } = useUpdateMapping();
156
+ const handleSaveMapping = async ({ values, table }) => {
157
+ setValidationErrors({});
158
+ values.entityName = catalogEntities.find(
159
+ (entity) => `${entity.type}:${entity.namespace}/${entity.name}`.toLowerCase() === values.entityRef
160
+ )?.name ?? "";
161
+ values.status = "RefreshToUpdate";
162
+ await updateMapping(values);
163
+ const existingMapping = mappings.find(
164
+ (item) => item.serviceId === values.serviceId
165
+ );
166
+ if (existingMapping) {
167
+ existingMapping.entityRef = values.entityRef;
168
+ existingMapping.entityName = values.entityName;
169
+ }
170
+ table.setEditingRow(null);
171
+ };
172
+ const openInBrowser = (url) => {
173
+ window.open(url, "_blank", "noreferrer");
174
+ };
175
+ const dataTable = useMaterialReactTable({
176
+ columns,
177
+ data: mappings,
178
+ editDisplayMode: "modal",
179
+ enableEditing: true,
180
+ positionActionsColumn: "last",
181
+ enableStickyHeader: true,
182
+ enableFilters: true,
183
+ getRowId: (row) => row.serviceId,
184
+ muiToolbarAlertBannerProps: mappings === void 0 ? {
185
+ color: "error",
186
+ children: "Error loading data"
187
+ } : void 0,
188
+ muiTableContainerProps: {
189
+ sx: {
190
+ minHeight: "500px"
191
+ }
192
+ },
193
+ onEditingRowCancel: () => setValidationErrors({}),
194
+ onEditingRowSave: handleSaveMapping,
195
+ renderEditRowDialogContent: ({ table, row, internalEditComponents }) => /* @__PURE__ */ jsxs(Fragment, { children: [
196
+ /* @__PURE__ */ jsx(DialogTitle, { children: "Update Entity Mapping" }),
197
+ /* @__PURE__ */ jsx(
198
+ DialogContent,
199
+ {
200
+ style: { display: "flex", flexDirection: "column", gap: "1rem" },
201
+ children: internalEditComponents
202
+ }
203
+ ),
204
+ /* @__PURE__ */ jsx(DialogActions, { children: /* @__PURE__ */ jsx(MRT_EditActionButtons, { variant: "text", table, row }) })
205
+ ] }),
206
+ renderRowActions: ({ row, table }) => /* @__PURE__ */ jsxs(Flex, { children: [
207
+ /* @__PURE__ */ jsxs(TooltipTrigger, { children: [
208
+ /* @__PURE__ */ jsx(
209
+ ButtonIcon,
210
+ {
211
+ "aria-label": "Edit",
212
+ variant: "tertiary",
213
+ onClick: () => {
214
+ getEntityOptions();
215
+ table.setEditingRow(row);
216
+ },
217
+ icon: /* @__PURE__ */ jsx(Edit, {})
218
+ }
219
+ ),
220
+ /* @__PURE__ */ jsx(Tooltip, { children: "Edit" })
221
+ ] }),
222
+ /* @__PURE__ */ jsxs(TooltipTrigger, { children: [
223
+ /* @__PURE__ */ jsx(
224
+ ButtonIcon,
225
+ {
226
+ "aria-label": "Open in PagerDuty",
227
+ variant: "tertiary",
228
+ onClick: () => openInBrowser(row.getValue("serviceUrl")),
229
+ icon: /* @__PURE__ */ jsx(OpenInBrowser, {})
230
+ }
231
+ ),
232
+ /* @__PURE__ */ jsx(Tooltip, { children: " Open in PagerDuty" })
233
+ ] })
234
+ ] }),
235
+ state: {
236
+ isLoading: mappings.length === 0 || catalogEntities.length === 0,
237
+ isSaving: isUpdatingMapping,
238
+ showAlertBanner: mappings === void 0 || catalogEntities === void 0,
239
+ showProgressBars: mappings.length === 0 || catalogEntities.length === 0
240
+ },
241
+ initialState: {
242
+ columnVisibility: {
243
+ serviceId: false,
244
+ entityRef: false,
245
+ serviceUrl: false,
246
+ integrationKey: false
247
+ }
248
+ }
249
+ });
250
+ function getEntityOptions() {
251
+ const options = [];
252
+ options.push({ value: "", label: "None" });
253
+ catalogEntities.forEach((entity) => {
254
+ const foundServiceAnnotation = entity.annotations["pagerduty.com/service-id"];
255
+ const foundIntegrationKeyAnnotation = entity.annotations["pagerduty.com/integration-key"];
256
+ let foundServiceMapping;
257
+ if (foundServiceAnnotation || foundIntegrationKeyAnnotation) {
258
+ foundServiceMapping = mappings.find(
259
+ (item) => item.serviceId === foundServiceAnnotation || item.integrationKey === foundIntegrationKeyAnnotation
260
+ );
261
+ }
262
+ const entityRef = `${entity.type}:${entity.namespace}/${entity.name}`.toLowerCase();
263
+ const foundEntityMapping = mappings.find(
264
+ (item) => item.entityRef === entityRef
265
+ );
266
+ if (!foundEntityMapping && (!foundServiceAnnotation || !foundIntegrationKeyAnnotation) || (foundServiceAnnotation || foundIntegrationKeyAnnotation) && foundServiceMapping && !foundEntityMapping) {
267
+ options.push({
268
+ value: entityRef,
269
+ label: entity.name
270
+ });
271
+ }
272
+ });
273
+ setEntityOptions(options);
274
+ }
275
+ return /* @__PURE__ */ jsx(MaterialReactTable, { table: dataTable });
276
+ };
277
+ const queryClient = new QueryClient();
278
+ return /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx(DenseTable, {}) });
279
+ };
280
+
281
+ export { MappingTable };
282
+ //# sourceMappingURL=MappingTable.esm.js.map