@pagerduty/backstage-plugin 0.15.9 → 0.15.10-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -0
- package/package.json +32 -19
- package/assets/PD-Green.svg +0 -21
- package/assets/PD-Icon.svg +0 -13
- package/assets/PD-White.svg +0 -21
- package/assets/emptystate.svg +0 -6
- package/assets/forbiddenstate.svg +0 -25
- package/dist/api/client.esm.js +0 -225
- package/dist/api/client.esm.js.map +0 -1
- package/dist/assets/PD-Green.svg +0 -21
- package/dist/assets/PD-Icon.svg +0 -13
- package/dist/assets/PD-White.svg +0 -21
- package/dist/assets/emptystate.svg +0 -6
- package/dist/assets/forbiddenstate.svg +0 -25
- package/dist/components/ChangeEvents/ChangeEventEmptyState.esm.js +0 -29
- package/dist/components/ChangeEvents/ChangeEventEmptyState.esm.js.map +0 -1
- package/dist/components/ChangeEvents/ChangeEventForbiddenState.esm.js +0 -29
- package/dist/components/ChangeEvents/ChangeEventForbiddenState.esm.js.map +0 -1
- package/dist/components/ChangeEvents/ChangeEventListItem.esm.js +0 -82
- package/dist/components/ChangeEvents/ChangeEventListItem.esm.js.map +0 -1
- package/dist/components/ChangeEvents/ChangeEvents.esm.js +0 -52
- package/dist/components/ChangeEvents/ChangeEvents.esm.js.map +0 -1
- package/dist/components/EntityPagerDutyCard/index.esm.js +0 -26
- package/dist/components/EntityPagerDutyCard/index.esm.js.map +0 -1
- package/dist/components/EntityPagerDutySmallCard/index.esm.js +0 -26
- package/dist/components/EntityPagerDutySmallCard/index.esm.js.map +0 -1
- package/dist/components/Errors/ForbiddenError.esm.js +0 -24
- package/dist/components/Errors/ForbiddenError.esm.js.map +0 -1
- package/dist/components/Errors/MissingTokenError.esm.js +0 -24
- package/dist/components/Errors/MissingTokenError.esm.js.map +0 -1
- package/dist/components/Errors/ServiceNotFoundError.esm.js +0 -24
- package/dist/components/Errors/ServiceNotFoundError.esm.js.map +0 -1
- package/dist/components/Escalation/EscalationPolicy.esm.js +0 -61
- package/dist/components/Escalation/EscalationPolicy.esm.js.map +0 -1
- package/dist/components/Escalation/EscalationUser.esm.js +0 -107
- package/dist/components/Escalation/EscalationUser.esm.js.map +0 -1
- package/dist/components/Escalation/EscalationUsersEmptyState.esm.js +0 -23
- package/dist/components/Escalation/EscalationUsersEmptyState.esm.js.map +0 -1
- package/dist/components/Escalation/EscalationUsersForbiddenState.esm.js +0 -23
- package/dist/components/Escalation/EscalationUsersForbiddenState.esm.js.map +0 -1
- package/dist/components/HomePagePagerDutyCard/Content.esm.js +0 -9
- package/dist/components/HomePagePagerDutyCard/Content.esm.js.map +0 -1
- package/dist/components/HomePagePagerDutyCard/index.esm.js +0 -2
- package/dist/components/HomePagePagerDutyCard/index.esm.js.map +0 -1
- package/dist/components/Icons/index.esm.js +0 -9
- package/dist/components/Icons/index.esm.js.map +0 -1
- package/dist/components/Incident/IncidentEmptyState.esm.js +0 -29
- package/dist/components/Incident/IncidentEmptyState.esm.js.map +0 -1
- package/dist/components/Incident/IncidentForbiddenState.esm.js +0 -29
- package/dist/components/Incident/IncidentForbiddenState.esm.js.map +0 -1
- package/dist/components/Incident/IncidentListItem.esm.js +0 -126
- package/dist/components/Incident/IncidentListItem.esm.js.map +0 -1
- package/dist/components/Incident/Incidents.esm.js +0 -46
- package/dist/components/Incident/Incidents.esm.js.map +0 -1
- package/dist/components/PagerDutyCard/index.esm.js +0 -239
- package/dist/components/PagerDutyCard/index.esm.js.map +0 -1
- package/dist/components/PagerDutyCardCommon/InsightsCard.esm.js +0 -41
- package/dist/components/PagerDutyCardCommon/InsightsCard.esm.js.map +0 -1
- package/dist/components/PagerDutyCardCommon/OpenServiceButton.esm.js +0 -48
- package/dist/components/PagerDutyCardCommon/OpenServiceButton.esm.js.map +0 -1
- package/dist/components/PagerDutyCardCommon/ServiceStandardsCard.esm.js +0 -113
- package/dist/components/PagerDutyCardCommon/ServiceStandardsCard.esm.js.map +0 -1
- package/dist/components/PagerDutyCardCommon/StatusCard.esm.js +0 -109
- package/dist/components/PagerDutyCardCommon/StatusCard.esm.js.map +0 -1
- package/dist/components/PagerDutyCardCommon/TriggerIncidentButton.esm.js +0 -71
- package/dist/components/PagerDutyCardCommon/TriggerIncidentButton.esm.js.map +0 -1
- package/dist/components/PagerDutyPage/MappingTable.esm.js +0 -271
- package/dist/components/PagerDutyPage/MappingTable.esm.js.map +0 -1
- package/dist/components/PagerDutyPage/ServiceMappingComponent.esm.js +0 -50
- package/dist/components/PagerDutyPage/ServiceMappingComponent.esm.js.map +0 -1
- package/dist/components/PagerDutyPage/index.esm.js +0 -152
- package/dist/components/PagerDutyPage/index.esm.js.map +0 -1
- package/dist/components/PagerDutySmallCard/index.esm.js +0 -247
- package/dist/components/PagerDutySmallCard/index.esm.js.map +0 -1
- package/dist/components/TriggerButton/index.esm.js +0 -51
- package/dist/components/TriggerButton/index.esm.js.map +0 -1
- package/dist/components/TriggerDialog/TriggerDialog.esm.js +0 -116
- package/dist/components/TriggerDialog/TriggerDialog.esm.js.map +0 -1
- package/dist/components/constants.esm.js +0 -6
- package/dist/components/constants.esm.js.map +0 -1
- package/dist/components/pagerDutyEntity.esm.js +0 -14
- package/dist/components/pagerDutyEntity.esm.js.map +0 -1
- package/dist/deprecated.esm.js +0 -10
- package/dist/deprecated.esm.js.map +0 -1
- package/dist/hooks/index.esm.js +0 -10
- package/dist/hooks/index.esm.js.map +0 -1
- package/dist/index.d.ts +0 -182
- package/dist/index.esm.js +0 -8
- package/dist/index.esm.js.map +0 -1
- package/dist/plugin.esm.js +0 -78
- package/dist/plugin.esm.js.map +0 -1
|
@@ -1,271 +0,0 @@
|
|
|
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, Tooltip, IconButton, DialogTitle, DialogContent, DialogActions } from '@material-ui/core';
|
|
5
|
-
import { QueryClient, QueryClientProvider, useMutation } from '@tanstack/react-query';
|
|
6
|
-
import { Edit, OpenInBrowser } from '@mui/icons-material';
|
|
7
|
-
import { useApi } from '@backstage/core-plugin-api';
|
|
8
|
-
import { pagerDutyApiRef } from '../../api/client.esm.js';
|
|
9
|
-
|
|
10
|
-
function getColorFromStatus(status) {
|
|
11
|
-
switch (status) {
|
|
12
|
-
case "InSync":
|
|
13
|
-
return "green";
|
|
14
|
-
case "OutOfSync":
|
|
15
|
-
return "red";
|
|
16
|
-
case "NotMapped":
|
|
17
|
-
return "orange";
|
|
18
|
-
default:
|
|
19
|
-
return "gray";
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
function makeReadable(status) {
|
|
23
|
-
switch (status) {
|
|
24
|
-
case "InSync":
|
|
25
|
-
return "In Sync";
|
|
26
|
-
case "OutOfSync":
|
|
27
|
-
return "Out of Sync";
|
|
28
|
-
case "NotMapped":
|
|
29
|
-
return "Not Mapped";
|
|
30
|
-
default:
|
|
31
|
-
return "Refresh to Update";
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
const MappingTable = ({
|
|
35
|
-
mappings,
|
|
36
|
-
catalogEntities
|
|
37
|
-
}) => {
|
|
38
|
-
const DenseTable = () => {
|
|
39
|
-
const [validationErrors, setValidationErrors] = useState({});
|
|
40
|
-
const [entityOptions, setEntityOptions] = useState(
|
|
41
|
-
[]
|
|
42
|
-
);
|
|
43
|
-
const pagerDutyApi = useApi(pagerDutyApiRef);
|
|
44
|
-
useEffect(() => {
|
|
45
|
-
getEntityOptions();
|
|
46
|
-
}, []);
|
|
47
|
-
const columns = useMemo(
|
|
48
|
-
() => [
|
|
49
|
-
{
|
|
50
|
-
id: "serviceId",
|
|
51
|
-
accessorKey: "serviceId",
|
|
52
|
-
header: "Service ID",
|
|
53
|
-
visibleInShowHideMenu: false,
|
|
54
|
-
enableEditing: false,
|
|
55
|
-
Edit: () => null,
|
|
56
|
-
Cell: ({ cell }) => /* @__PURE__ */ jsx(Typography, { variant: "body1", style: { fontWeight: 600 }, children: cell.getValue() })
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
id: "integrationKey",
|
|
60
|
-
accessorKey: "integrationKey",
|
|
61
|
-
header: "Integration Key",
|
|
62
|
-
visibleInShowHideMenu: false,
|
|
63
|
-
enableEditing: false,
|
|
64
|
-
Edit: () => null
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
id: "serviceName",
|
|
68
|
-
accessorKey: "serviceName",
|
|
69
|
-
header: "PagerDuty Service",
|
|
70
|
-
enableEditing: false
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
id: "account",
|
|
74
|
-
accessorKey: "account",
|
|
75
|
-
header: "Account",
|
|
76
|
-
enableEditing: false,
|
|
77
|
-
Edit: () => null
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
id: "team",
|
|
81
|
-
accessorKey: "team",
|
|
82
|
-
header: "Team",
|
|
83
|
-
enableEditing: false
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
id: "escalationPolicy",
|
|
87
|
-
accessorKey: "escalationPolicy",
|
|
88
|
-
header: "Escalation Policy",
|
|
89
|
-
enableEditing: false
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
id: "entityRef",
|
|
93
|
-
accessorKey: "entityRef",
|
|
94
|
-
header: "Mapping",
|
|
95
|
-
visibleInShowHideMenu: false,
|
|
96
|
-
editVariant: "select",
|
|
97
|
-
editSelectOptions: entityOptions,
|
|
98
|
-
muiEditTextFieldProps: {
|
|
99
|
-
select: true,
|
|
100
|
-
error: !!validationErrors?.state,
|
|
101
|
-
helperText: validationErrors?.state,
|
|
102
|
-
multiline: true,
|
|
103
|
-
type: "range"
|
|
104
|
-
}
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
id: "entityName",
|
|
108
|
-
accessorKey: "entityName",
|
|
109
|
-
header: "Mapped Entity Name",
|
|
110
|
-
enableEditing: false,
|
|
111
|
-
Edit: () => null
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
id: "status",
|
|
115
|
-
accessorKey: "status",
|
|
116
|
-
header: "Status",
|
|
117
|
-
enableEditing: false,
|
|
118
|
-
Edit: () => null,
|
|
119
|
-
Cell: ({ cell }) => /* @__PURE__ */ jsx(
|
|
120
|
-
Box,
|
|
121
|
-
{
|
|
122
|
-
component: "span",
|
|
123
|
-
bgcolor: getColorFromStatus(cell.getValue()),
|
|
124
|
-
borderRadius: "0.25rem",
|
|
125
|
-
color: "white",
|
|
126
|
-
p: "0.25rem",
|
|
127
|
-
children: makeReadable(cell.getValue())
|
|
128
|
-
}
|
|
129
|
-
)
|
|
130
|
-
},
|
|
131
|
-
{
|
|
132
|
-
id: "serviceUrl",
|
|
133
|
-
accessorKey: "serviceUrl",
|
|
134
|
-
header: "Service URL",
|
|
135
|
-
visibleInShowHideMenu: false,
|
|
136
|
-
enableEditing: false,
|
|
137
|
-
Edit: () => null
|
|
138
|
-
}
|
|
139
|
-
],
|
|
140
|
-
[validationErrors, entityOptions]
|
|
141
|
-
);
|
|
142
|
-
function useUpdateMapping() {
|
|
143
|
-
return useMutation({
|
|
144
|
-
mutationFn: async (mapping) => {
|
|
145
|
-
return await pagerDutyApi.storeServiceMapping(
|
|
146
|
-
mapping.serviceId,
|
|
147
|
-
mapping.integrationKey ?? "",
|
|
148
|
-
mapping.entityRef,
|
|
149
|
-
mapping.account ?? ""
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
const { mutateAsync: updateMapping, isPending: isUpdatingMapping } = useUpdateMapping();
|
|
155
|
-
const handleSaveMapping = async ({ values, table }) => {
|
|
156
|
-
setValidationErrors({});
|
|
157
|
-
values.entityName = catalogEntities.find(
|
|
158
|
-
(entity) => `${entity.type}:${entity.namespace}/${entity.name}`.toLowerCase() === values.entityRef
|
|
159
|
-
)?.name ?? "";
|
|
160
|
-
values.status = "RefreshToUpdate";
|
|
161
|
-
await updateMapping(values);
|
|
162
|
-
const existingMapping = mappings.find(
|
|
163
|
-
(item) => item.serviceId === values.serviceId
|
|
164
|
-
);
|
|
165
|
-
if (existingMapping) {
|
|
166
|
-
existingMapping.entityRef = values.entityRef;
|
|
167
|
-
existingMapping.entityName = values.entityName;
|
|
168
|
-
}
|
|
169
|
-
table.setEditingRow(null);
|
|
170
|
-
};
|
|
171
|
-
const openInBrowser = (url) => {
|
|
172
|
-
window.open(url, "_blank", "noreferrer");
|
|
173
|
-
};
|
|
174
|
-
const dataTable = useMaterialReactTable({
|
|
175
|
-
columns,
|
|
176
|
-
data: mappings,
|
|
177
|
-
editDisplayMode: "modal",
|
|
178
|
-
enableEditing: true,
|
|
179
|
-
positionActionsColumn: "last",
|
|
180
|
-
enableStickyHeader: true,
|
|
181
|
-
enableFilters: true,
|
|
182
|
-
getRowId: (row) => row.serviceId,
|
|
183
|
-
muiToolbarAlertBannerProps: mappings === void 0 ? {
|
|
184
|
-
color: "error",
|
|
185
|
-
children: "Error loading data"
|
|
186
|
-
} : void 0,
|
|
187
|
-
muiTableContainerProps: {
|
|
188
|
-
sx: {
|
|
189
|
-
minHeight: "500px"
|
|
190
|
-
}
|
|
191
|
-
},
|
|
192
|
-
onEditingRowCancel: () => setValidationErrors({}),
|
|
193
|
-
onEditingRowSave: handleSaveMapping,
|
|
194
|
-
renderEditRowDialogContent: ({ table, row, internalEditComponents }) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
195
|
-
/* @__PURE__ */ jsx(DialogTitle, { children: "Update Entity Mapping" }),
|
|
196
|
-
/* @__PURE__ */ jsx(
|
|
197
|
-
DialogContent,
|
|
198
|
-
{
|
|
199
|
-
style: { display: "flex", flexDirection: "column", gap: "1rem" },
|
|
200
|
-
children: internalEditComponents
|
|
201
|
-
}
|
|
202
|
-
),
|
|
203
|
-
/* @__PURE__ */ jsx(DialogActions, { children: /* @__PURE__ */ jsx(MRT_EditActionButtons, { variant: "text", table, row }) })
|
|
204
|
-
] }),
|
|
205
|
-
renderRowActions: ({ row, table }) => /* @__PURE__ */ jsxs(Box, { sx: { display: "flex" }, children: [
|
|
206
|
-
/* @__PURE__ */ jsx(Tooltip, { title: "Edit", children: /* @__PURE__ */ jsx(
|
|
207
|
-
IconButton,
|
|
208
|
-
{
|
|
209
|
-
onClick: () => {
|
|
210
|
-
getEntityOptions();
|
|
211
|
-
table.setEditingRow(row);
|
|
212
|
-
},
|
|
213
|
-
children: /* @__PURE__ */ jsx(Edit, {})
|
|
214
|
-
}
|
|
215
|
-
) }),
|
|
216
|
-
/* @__PURE__ */ jsx(Tooltip, { title: "Open in PagerDuty", children: /* @__PURE__ */ jsx(
|
|
217
|
-
IconButton,
|
|
218
|
-
{
|
|
219
|
-
onClick: () => openInBrowser(row.getValue("serviceUrl")),
|
|
220
|
-
children: /* @__PURE__ */ jsx(OpenInBrowser, {})
|
|
221
|
-
}
|
|
222
|
-
) })
|
|
223
|
-
] }),
|
|
224
|
-
state: {
|
|
225
|
-
isLoading: mappings.length === 0 || catalogEntities.length === 0,
|
|
226
|
-
isSaving: isUpdatingMapping,
|
|
227
|
-
showAlertBanner: mappings === void 0 || catalogEntities === void 0,
|
|
228
|
-
showProgressBars: mappings.length === 0 || catalogEntities.length === 0
|
|
229
|
-
},
|
|
230
|
-
initialState: {
|
|
231
|
-
columnVisibility: {
|
|
232
|
-
serviceId: false,
|
|
233
|
-
entityRef: false,
|
|
234
|
-
serviceUrl: false,
|
|
235
|
-
integrationKey: false
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
});
|
|
239
|
-
function getEntityOptions() {
|
|
240
|
-
const options = [];
|
|
241
|
-
options.push({ value: "", label: "None" });
|
|
242
|
-
catalogEntities.forEach((entity) => {
|
|
243
|
-
const foundServiceAnnotation = entity.annotations["pagerduty.com/service-id"];
|
|
244
|
-
const foundIntegrationKeyAnnotation = entity.annotations["pagerduty.com/integration-key"];
|
|
245
|
-
let foundServiceMapping;
|
|
246
|
-
if (foundServiceAnnotation || foundIntegrationKeyAnnotation) {
|
|
247
|
-
foundServiceMapping = mappings.find(
|
|
248
|
-
(item) => item.serviceId === foundServiceAnnotation || item.integrationKey === foundIntegrationKeyAnnotation
|
|
249
|
-
);
|
|
250
|
-
}
|
|
251
|
-
const entityRef = `${entity.type}:${entity.namespace}/${entity.name}`.toLowerCase();
|
|
252
|
-
const foundEntityMapping = mappings.find(
|
|
253
|
-
(item) => item.entityRef === entityRef
|
|
254
|
-
);
|
|
255
|
-
if (!foundEntityMapping && (!foundServiceAnnotation || !foundIntegrationKeyAnnotation) || (foundServiceAnnotation || foundIntegrationKeyAnnotation) && foundServiceMapping && !foundEntityMapping) {
|
|
256
|
-
options.push({
|
|
257
|
-
value: entityRef,
|
|
258
|
-
label: entity.name
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
});
|
|
262
|
-
setEntityOptions(options);
|
|
263
|
-
}
|
|
264
|
-
return /* @__PURE__ */ jsx(MaterialReactTable, { table: dataTable });
|
|
265
|
-
};
|
|
266
|
-
const queryClient = new QueryClient();
|
|
267
|
-
return /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx(DenseTable, {}) });
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
export { MappingTable };
|
|
271
|
-
//# sourceMappingURL=MappingTable.esm.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"MappingTable.esm.js","sources":["../../../src/components/PagerDutyPage/MappingTable.tsx"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react';\nimport { PagerDutyEntityMapping } from '@pagerduty/backstage-plugin-common';\nimport {\n MRT_ColumnDef,\n MRT_EditActionButtons,\n MRT_TableOptions,\n MaterialReactTable,\n useMaterialReactTable,\n} from 'material-react-table';\nimport {\n Box,\n DialogActions,\n DialogContent,\n DialogTitle,\n IconButton,\n Tooltip,\n Typography,\n} from '@material-ui/core';\nimport {\n QueryClient,\n QueryClientProvider,\n useMutation,\n} from '@tanstack/react-query';\nimport { Edit, OpenInBrowser } from '@mui/icons-material';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { pagerDutyApiRef } from '../../api';\n\ntype BackstageEntity = {\n id: string;\n name: string;\n namespace: string;\n type: string;\n system: string;\n owner: string;\n lifecycle: string;\n annotations: Annotations;\n};\n\nexport type Annotations = {\n 'pagerduty.com/integration-key': string;\n 'pagerduty.com/service-id': string;\n};\n\nfunction getColorFromStatus(status?: string) {\n switch (status) {\n case 'InSync':\n return 'green';\n case 'OutOfSync':\n return 'red';\n case 'NotMapped':\n return 'orange';\n default:\n return 'gray';\n }\n}\n\nfunction makeReadable(status?: string) {\n switch (status) {\n case 'InSync':\n return 'In Sync';\n case 'OutOfSync':\n return 'Out of Sync';\n case 'NotMapped':\n return 'Not Mapped';\n default:\n return 'Refresh to Update';\n }\n}\n\ntype CatalogEntityOptions = {\n value: string;\n label: string;\n};\n\ntype MappingTableProps = {\n mappings: PagerDutyEntityMapping[];\n catalogEntities: BackstageEntity[];\n};\n\nexport const MappingTable = ({\n mappings,\n catalogEntities,\n}: MappingTableProps) => {\n const DenseTable = () => {\n const [validationErrors, setValidationErrors] = useState<\n Record<string, string | undefined>\n >({});\n const [entityOptions, setEntityOptions] = useState<CatalogEntityOptions[]>(\n [],\n );\n const pagerDutyApi = useApi(pagerDutyApiRef);\n\n useEffect(() => {\n getEntityOptions();\n }, []);\n\n const columns = useMemo<MRT_ColumnDef<PagerDutyEntityMapping>[]>(\n () => [\n {\n id: 'serviceId',\n accessorKey: 'serviceId',\n header: 'Service ID',\n visibleInShowHideMenu: false,\n enableEditing: false,\n Edit: () => null,\n Cell: ({ cell }) => (\n <Typography variant=\"body1\" style={{ fontWeight: 600 }}>\n {cell.getValue<string>()}\n </Typography>\n ),\n },\n {\n id: 'integrationKey',\n accessorKey: 'integrationKey',\n header: 'Integration Key',\n visibleInShowHideMenu: false,\n enableEditing: false,\n Edit: () => null,\n },\n {\n id: 'serviceName',\n accessorKey: 'serviceName',\n header: 'PagerDuty Service',\n enableEditing: false,\n },\n {\n id: 'account',\n accessorKey: 'account',\n header: 'Account',\n enableEditing: false,\n Edit: () => null,\n },\n {\n id: 'team',\n accessorKey: 'team',\n header: 'Team',\n enableEditing: false,\n },\n {\n id: 'escalationPolicy',\n accessorKey: 'escalationPolicy',\n header: 'Escalation Policy',\n enableEditing: false,\n },\n {\n id: 'entityRef',\n accessorKey: 'entityRef',\n header: 'Mapping',\n visibleInShowHideMenu: false,\n editVariant: 'select',\n editSelectOptions: entityOptions,\n muiEditTextFieldProps: {\n select: true,\n error: !!validationErrors?.state,\n helperText: validationErrors?.state,\n multiline: true,\n type: 'range',\n },\n },\n {\n id: 'entityName',\n accessorKey: 'entityName',\n header: 'Mapped Entity Name',\n enableEditing: false,\n Edit: () => null,\n },\n {\n id: 'status',\n accessorKey: 'status',\n header: 'Status',\n enableEditing: false,\n Edit: () => null,\n Cell: ({ cell }) => (\n <Box\n component=\"span\"\n bgcolor={getColorFromStatus(cell.getValue<string>())}\n borderRadius=\"0.25rem\"\n color=\"white\"\n p=\"0.25rem\"\n >\n {makeReadable(cell.getValue<string>())}\n </Box>\n ),\n },\n {\n id: 'serviceUrl',\n accessorKey: 'serviceUrl',\n header: 'Service URL',\n visibleInShowHideMenu: false,\n enableEditing: false,\n Edit: () => null,\n },\n ],\n [validationErrors, entityOptions],\n );\n\n // UPDATE hook (put mapping in api)\n function useUpdateMapping() {\n return useMutation({\n mutationFn: async (mapping: PagerDutyEntityMapping) => {\n return await pagerDutyApi.storeServiceMapping(\n mapping.serviceId,\n mapping.integrationKey ?? '',\n mapping.entityRef,\n mapping.account ?? '',\n );\n },\n });\n }\n\n // call UPDATE hook\n const { mutateAsync: updateMapping, isPending: isUpdatingMapping } =\n useUpdateMapping();\n\n // UPDATE action\n const handleSaveMapping: MRT_TableOptions<PagerDutyEntityMapping>['onEditingRowSave'] =\n async ({ values, table }) => {\n setValidationErrors({});\n\n values.entityName =\n catalogEntities.find(\n entity =>\n `${entity.type}:${entity.namespace}/${entity.name}`.toLowerCase() ===\n values.entityRef,\n )?.name ?? '';\n values.status = 'RefreshToUpdate';\n\n await updateMapping(values);\n\n // find corresponding mapping in mappings array\n // and update it with new values\n const existingMapping = mappings.find(\n item => item.serviceId === values.serviceId,\n );\n if (existingMapping) {\n existingMapping.entityRef = values.entityRef;\n existingMapping.entityName = values.entityName;\n }\n\n table.setEditingRow(null); // exit editing mode\n };\n\n const openInBrowser = (url: string) => {\n window.open(url, '_blank', 'noreferrer');\n };\n\n const dataTable = useMaterialReactTable({\n columns,\n data: mappings,\n editDisplayMode: 'modal',\n enableEditing: true,\n positionActionsColumn: 'last',\n enableStickyHeader: true,\n enableFilters: true,\n getRowId: row => row.serviceId,\n muiToolbarAlertBannerProps:\n mappings === undefined\n ? {\n color: 'error',\n children: 'Error loading data',\n }\n : undefined,\n muiTableContainerProps: {\n sx: {\n minHeight: '500px',\n },\n },\n onEditingRowCancel: () => setValidationErrors({}),\n onEditingRowSave: handleSaveMapping,\n renderEditRowDialogContent: ({ table, row, internalEditComponents }) => (\n <>\n <DialogTitle>Update Entity Mapping</DialogTitle>\n <DialogContent\n style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}\n >\n {internalEditComponents}\n </DialogContent>\n <DialogActions>\n <MRT_EditActionButtons variant=\"text\" table={table} row={row} />\n </DialogActions>\n </>\n ),\n renderRowActions: ({ row, table }) => (\n <Box sx={{ display: 'flex' }}>\n <Tooltip title=\"Edit\">\n <IconButton\n onClick={() => {\n getEntityOptions();\n table.setEditingRow(row);\n }}\n >\n <Edit />\n </IconButton>\n </Tooltip>\n <Tooltip title=\"Open in PagerDuty\">\n <IconButton\n onClick={() => openInBrowser(row.getValue('serviceUrl'))}\n >\n <OpenInBrowser />\n </IconButton>\n </Tooltip>\n </Box>\n ),\n state: {\n isLoading: mappings.length === 0 || catalogEntities.length === 0,\n isSaving: isUpdatingMapping,\n showAlertBanner:\n mappings === undefined || catalogEntities === undefined,\n showProgressBars: mappings.length === 0 || catalogEntities.length === 0,\n },\n initialState: {\n columnVisibility: {\n serviceId: false,\n entityRef: false,\n serviceUrl: false,\n integrationKey: false,\n },\n },\n });\n\n function getEntityOptions() {\n const options: CatalogEntityOptions[] = [];\n // initialize with empty object\n options.push({ value: '', label: 'None' });\n\n catalogEntities.forEach(entity => {\n // find service-id annotation in entity\n const foundServiceAnnotation =\n entity.annotations['pagerduty.com/service-id'];\n\n // find integration-key annotation in entity\n const foundIntegrationKeyAnnotation =\n entity.annotations['pagerduty.com/integration-key'];\n\n // find entity with service-id in mappings array if service-id is found in entity\n let foundServiceMapping: PagerDutyEntityMapping | undefined;\n if (foundServiceAnnotation || foundIntegrationKeyAnnotation) {\n foundServiceMapping = mappings.find(\n item =>\n item.serviceId === foundServiceAnnotation ||\n item.integrationKey === foundIntegrationKeyAnnotation,\n );\n }\n\n const entityRef =\n `${entity.type}:${entity.namespace}/${entity.name}`.toLowerCase();\n // find entity with entity.id in entityMappings array\n const foundEntityMapping = mappings.find(\n item => item.entityRef === entityRef,\n );\n\n if (\n (!foundEntityMapping &&\n (!foundServiceAnnotation || !foundIntegrationKeyAnnotation)) ||\n ((foundServiceAnnotation || foundIntegrationKeyAnnotation) &&\n foundServiceMapping &&\n !foundEntityMapping)\n ) {\n options.push({\n value: entityRef,\n label: entity.name,\n });\n }\n });\n\n setEntityOptions(options);\n }\n\n return <MaterialReactTable table={dataTable} />;\n };\n\n const queryClient = new QueryClient();\n\n return (\n <QueryClientProvider client={queryClient}>\n <DenseTable />\n </QueryClientProvider>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { useState, useEffect } from 'react';
|
|
3
|
-
import { useApi } from '@backstage/core-plugin-api';
|
|
4
|
-
import { pagerDutyApiRef } from '../../api/client.esm.js';
|
|
5
|
-
import { catalogApiRef } from '@backstage/plugin-catalog-react';
|
|
6
|
-
import { MappingTable } from './MappingTable.esm.js';
|
|
7
|
-
|
|
8
|
-
const ServiceMappingComponent = () => {
|
|
9
|
-
const [entityMappings, setEntityMappings] = useState([]);
|
|
10
|
-
const [catalogEntities, setCatalogEntities] = useState([]);
|
|
11
|
-
const pagerDutyApi = useApi(pagerDutyApiRef);
|
|
12
|
-
const catalogApi = useApi(catalogApiRef);
|
|
13
|
-
useEffect(() => {
|
|
14
|
-
function fetchMappings() {
|
|
15
|
-
pagerDutyApi.getEntityMappings().then((result) => {
|
|
16
|
-
setEntityMappings(result.mappings);
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
function fetchCatalogEntities() {
|
|
20
|
-
catalogApi.getEntities({
|
|
21
|
-
filter: { kind: "Component" }
|
|
22
|
-
}).then((result) => {
|
|
23
|
-
const entities = [];
|
|
24
|
-
result.items.forEach((entity) => {
|
|
25
|
-
const annotations = {
|
|
26
|
-
"pagerduty.com/integration-key": entity.metadata?.annotations?.["pagerduty.com/integration-key"] ?? "",
|
|
27
|
-
"pagerduty.com/service-id": entity.metadata?.annotations?.["pagerduty.com/service-id"] ?? ""
|
|
28
|
-
};
|
|
29
|
-
entities.push({
|
|
30
|
-
name: entity.metadata?.name,
|
|
31
|
-
id: entity.metadata?.uid ?? "",
|
|
32
|
-
namespace: entity.metadata?.namespace ?? "",
|
|
33
|
-
type: entity.kind ?? "",
|
|
34
|
-
system: entity.spec?.system ? JSON.stringify(entity.spec?.system) : "",
|
|
35
|
-
owner: entity.spec?.owner ? JSON.stringify(entity.spec?.owner) : "",
|
|
36
|
-
lifecycle: entity.spec?.lifecycle ? JSON.stringify(entity.spec?.lifecycle) : "",
|
|
37
|
-
annotations
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
setCatalogEntities(entities);
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
fetchMappings();
|
|
44
|
-
fetchCatalogEntities();
|
|
45
|
-
}, [catalogApi, pagerDutyApi]);
|
|
46
|
-
return /* @__PURE__ */ jsx(MappingTable, { mappings: entityMappings, catalogEntities });
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
export { ServiceMappingComponent };
|
|
50
|
-
//# sourceMappingURL=ServiceMappingComponent.esm.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ServiceMappingComponent.esm.js","sources":["../../../src/components/PagerDutyPage/ServiceMappingComponent.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport { PagerDutyEntityMapping } from '@pagerduty/backstage-plugin-common';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { pagerDutyApiRef } from '../../api';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport { MappingTable } from './MappingTable';\nimport { BackstageEntity, Annotations } from '../types';\n\nexport const ServiceMappingComponent = () => {\n const [entityMappings, setEntityMappings] = useState<\n PagerDutyEntityMapping[]\n >([]);\n const [catalogEntities, setCatalogEntities] = useState<BackstageEntity[]>([]);\n\n const pagerDutyApi = useApi(pagerDutyApiRef);\n const catalogApi = useApi(catalogApiRef);\n\n // call fetchMappings() and fetchCatalogEntities() on useEffect hook\n useEffect(() => {\n function fetchMappings() {\n pagerDutyApi.getEntityMappings().then(result => {\n setEntityMappings(result.mappings);\n });\n }\n\n function fetchCatalogEntities() {\n catalogApi\n .getEntities({\n filter: { kind: 'Component' },\n })\n .then(result => {\n const entities: BackstageEntity[] = [];\n result.items.forEach(entity => {\n const annotations: Annotations = {\n 'pagerduty.com/integration-key':\n entity.metadata?.annotations?.[\n 'pagerduty.com/integration-key'\n ] ?? '',\n 'pagerduty.com/service-id':\n entity.metadata?.annotations?.['pagerduty.com/service-id'] ??\n '',\n };\n\n entities.push({\n name: entity.metadata?.name,\n id: entity.metadata?.uid ?? '',\n namespace: entity.metadata?.namespace ?? '',\n type: entity.kind ?? '',\n system: entity.spec?.system\n ? JSON.stringify(entity.spec?.system)\n : '',\n owner: entity.spec?.owner\n ? JSON.stringify(entity.spec?.owner)\n : '',\n lifecycle: entity.spec?.lifecycle\n ? JSON.stringify(entity.spec?.lifecycle)\n : '',\n annotations: annotations,\n });\n });\n\n setCatalogEntities(entities);\n });\n }\n\n fetchMappings();\n fetchCatalogEntities();\n }, [catalogApi, pagerDutyApi]);\n\n return (\n <MappingTable mappings={entityMappings} catalogEntities={catalogEntities} />\n );\n};\n"],"names":[],"mappings":";;;;;;;AAQO,MAAM,0BAA0B,MAAM;AAC3C,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAI,QAAA,CAE1C,EAAE,CAAA;AACJ,EAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,CAAA,GAAI,QAAA,CAA4B,EAAE,CAAA;AAE5E,EAAA,MAAM,YAAA,GAAe,OAAO,eAAe,CAAA;AAC3C,EAAA,MAAM,UAAA,GAAa,OAAO,aAAa,CAAA;AAGvC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,SAAS,aAAA,GAAgB;AACvB,MAAA,YAAA,CAAa,iBAAA,EAAkB,CAAE,IAAA,CAAK,CAAA,MAAA,KAAU;AAC9C,QAAA,iBAAA,CAAkB,OAAO,QAAQ,CAAA;AAAA,MACnC,CAAC,CAAA;AAAA,IACH;AAEA,IAAA,SAAS,oBAAA,GAAuB;AAC9B,MAAA,UAAA,CACG,WAAA,CAAY;AAAA,QACX,MAAA,EAAQ,EAAE,IAAA,EAAM,WAAA;AAAY,OAC7B,CAAA,CACA,IAAA,CAAK,CAAA,MAAA,KAAU;AACd,QAAA,MAAM,WAA8B,EAAC;AACrC,QAAA,MAAA,CAAO,KAAA,CAAM,QAAQ,CAAA,MAAA,KAAU;AAC7B,UAAA,MAAM,WAAA,GAA2B;AAAA,YAC/B,+BAAA,EACE,MAAA,CAAO,QAAA,EAAU,WAAA,GACf,+BACF,CAAA,IAAK,EAAA;AAAA,YACP,0BAAA,EACE,MAAA,CAAO,QAAA,EAAU,WAAA,GAAc,0BAA0B,CAAA,IACzD;AAAA,WACJ;AAEA,UAAA,QAAA,CAAS,IAAA,CAAK;AAAA,YACZ,IAAA,EAAM,OAAO,QAAA,EAAU,IAAA;AAAA,YACvB,EAAA,EAAI,MAAA,CAAO,QAAA,EAAU,GAAA,IAAO,EAAA;AAAA,YAC5B,SAAA,EAAW,MAAA,CAAO,QAAA,EAAU,SAAA,IAAa,EAAA;AAAA,YACzC,IAAA,EAAM,OAAO,IAAA,IAAQ,EAAA;AAAA,YACrB,MAAA,EAAQ,OAAO,IAAA,EAAM,MAAA,GACjB,KAAK,SAAA,CAAU,MAAA,CAAO,IAAA,EAAM,MAAM,CAAA,GAClC,EAAA;AAAA,YACJ,KAAA,EAAO,OAAO,IAAA,EAAM,KAAA,GAChB,KAAK,SAAA,CAAU,MAAA,CAAO,IAAA,EAAM,KAAK,CAAA,GACjC,EAAA;AAAA,YACJ,SAAA,EAAW,OAAO,IAAA,EAAM,SAAA,GACpB,KAAK,SAAA,CAAU,MAAA,CAAO,IAAA,EAAM,SAAS,CAAA,GACrC,EAAA;AAAA,YACJ;AAAA,WACD,CAAA;AAAA,QACH,CAAC,CAAA;AAED,QAAA,kBAAA,CAAmB,QAAQ,CAAA;AAAA,MAC7B,CAAC,CAAA;AAAA,IACL;AAEA,IAAA,aAAA,EAAc;AACd,IAAA,oBAAA,EAAqB;AAAA,EACvB,CAAA,EAAG,CAAC,UAAA,EAAY,YAAY,CAAC,CAAA;AAE7B,EAAA,uBACE,GAAA,CAAC,YAAA,EAAA,EAAa,QAAA,EAAU,cAAA,EAAgB,eAAA,EAAkC,CAAA;AAE9E;;;;"}
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { useState, useEffect } from 'react';
|
|
3
|
-
import { Grid, Typography, Card, RadioGroup, FormControlLabel, Radio } from '@material-ui/core';
|
|
4
|
-
import { Page, Header, Content, TabbedLayout } from '@backstage/core-components';
|
|
5
|
-
import { ServiceMappingComponent } from './ServiceMappingComponent.esm.js';
|
|
6
|
-
import { useApi } from '@backstage/core-plugin-api';
|
|
7
|
-
import { pagerDutyApiRef } from '../../api/client.esm.js';
|
|
8
|
-
import { NotFoundError } from '@backstage/errors';
|
|
9
|
-
|
|
10
|
-
const SERVICE_DEPENDENCY_SYNC_STRATEGY = "settings::service-dependency-sync-strategy";
|
|
11
|
-
const PagerDutyPage = () => {
|
|
12
|
-
const pagerDutyApi = useApi(pagerDutyApiRef);
|
|
13
|
-
const [
|
|
14
|
-
selectedServiceDependencyStrategy,
|
|
15
|
-
setSelectedServiceDependencyStrategy
|
|
16
|
-
] = useState("disabled");
|
|
17
|
-
useEffect(() => {
|
|
18
|
-
function fetchSetting() {
|
|
19
|
-
pagerDutyApi.getSetting(SERVICE_DEPENDENCY_SYNC_STRATEGY).then((result) => {
|
|
20
|
-
if (result !== void 0) {
|
|
21
|
-
setSelectedServiceDependencyStrategy(result.value);
|
|
22
|
-
}
|
|
23
|
-
}).catch((error) => {
|
|
24
|
-
if (error instanceof NotFoundError) {
|
|
25
|
-
setSelectedServiceDependencyStrategy("disabled");
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
fetchSetting();
|
|
30
|
-
}, [pagerDutyApi]);
|
|
31
|
-
const handleChange = (event) => {
|
|
32
|
-
const value = getSelectedValue(event.target.value);
|
|
33
|
-
setSelectedServiceDependencyStrategy(value);
|
|
34
|
-
pagerDutyApi.storeSettings([
|
|
35
|
-
{
|
|
36
|
-
id: SERVICE_DEPENDENCY_SYNC_STRATEGY,
|
|
37
|
-
value
|
|
38
|
-
}
|
|
39
|
-
]);
|
|
40
|
-
};
|
|
41
|
-
function getSelectedValue(value) {
|
|
42
|
-
switch (value) {
|
|
43
|
-
case "backstage":
|
|
44
|
-
return "backstage";
|
|
45
|
-
case "pagerduty":
|
|
46
|
-
return "pagerduty";
|
|
47
|
-
case "both":
|
|
48
|
-
return "both";
|
|
49
|
-
default:
|
|
50
|
-
return "disabled";
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
return /* @__PURE__ */ jsxs(Page, { themeId: "home", children: [
|
|
54
|
-
/* @__PURE__ */ jsx(Header, { title: "PagerDuty", subtitle: "Advanced configurations" }),
|
|
55
|
-
/* @__PURE__ */ jsx(Content, { children: /* @__PURE__ */ jsxs(TabbedLayout, { children: [
|
|
56
|
-
/* @__PURE__ */ jsx(TabbedLayout.Route, { path: "/service-mapping", title: "Service Mapping", children: /* @__PURE__ */ jsxs(Grid, { container: true, spacing: 3, direction: "column", children: [
|
|
57
|
-
/* @__PURE__ */ jsxs(Grid, { item: true, children: [
|
|
58
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body1", children: "Easily map your existing PagerDuty services to entities in Backstage without the need to add anotations to all your projects." }),
|
|
59
|
-
/* @__PURE__ */ jsxs(Typography, { variant: "body1", children: [
|
|
60
|
-
/* @__PURE__ */ jsx("b", { children: "Warning: " }),
|
|
61
|
-
"Only 1:1 mapping is allowed at this time."
|
|
62
|
-
] })
|
|
63
|
-
] }),
|
|
64
|
-
/* @__PURE__ */ jsx(Grid, { item: true, children: /* @__PURE__ */ jsx(ServiceMappingComponent, {}) })
|
|
65
|
-
] }) }),
|
|
66
|
-
/* @__PURE__ */ jsx(TabbedLayout.Route, { path: "/settings", title: "Configuration", children: /* @__PURE__ */ jsxs(Grid, { container: true, spacing: 3, direction: "column", children: [
|
|
67
|
-
/* @__PURE__ */ jsxs(Grid, { item: true, children: [
|
|
68
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", children: "Plugin configuration" }),
|
|
69
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body1", children: "Configure your PagerDuty plugin configuration here" })
|
|
70
|
-
] }),
|
|
71
|
-
/* @__PURE__ */ jsxs(
|
|
72
|
-
Card,
|
|
73
|
-
{
|
|
74
|
-
title: "Service dependency synchronization preferences",
|
|
75
|
-
style: { padding: "10px", paddingLeft: "15px", width: "50%" },
|
|
76
|
-
children: [
|
|
77
|
-
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
78
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h6", children: "Service dependency synchronization strategy" }),
|
|
79
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body1", children: "Select the main source of truth for your service dependencies" }),
|
|
80
|
-
/* @__PURE__ */ jsxs(
|
|
81
|
-
RadioGroup,
|
|
82
|
-
{
|
|
83
|
-
value: selectedServiceDependencyStrategy,
|
|
84
|
-
onChange: handleChange,
|
|
85
|
-
children: [
|
|
86
|
-
/* @__PURE__ */ jsx(
|
|
87
|
-
FormControlLabel,
|
|
88
|
-
{
|
|
89
|
-
value: "backstage",
|
|
90
|
-
control: /* @__PURE__ */ jsx(Radio, {}),
|
|
91
|
-
label: "Backstage"
|
|
92
|
-
}
|
|
93
|
-
),
|
|
94
|
-
/* @__PURE__ */ jsx(
|
|
95
|
-
FormControlLabel,
|
|
96
|
-
{
|
|
97
|
-
value: "pagerduty",
|
|
98
|
-
control: /* @__PURE__ */ jsx(Radio, {}),
|
|
99
|
-
label: "PagerDuty"
|
|
100
|
-
}
|
|
101
|
-
),
|
|
102
|
-
/* @__PURE__ */ jsx(
|
|
103
|
-
FormControlLabel,
|
|
104
|
-
{
|
|
105
|
-
value: "both",
|
|
106
|
-
control: /* @__PURE__ */ jsx(Radio, {}),
|
|
107
|
-
label: "Both"
|
|
108
|
-
}
|
|
109
|
-
),
|
|
110
|
-
/* @__PURE__ */ jsx(
|
|
111
|
-
FormControlLabel,
|
|
112
|
-
{
|
|
113
|
-
value: "disabled",
|
|
114
|
-
control: /* @__PURE__ */ jsx(Radio, {}),
|
|
115
|
-
label: "Disabled"
|
|
116
|
-
}
|
|
117
|
-
)
|
|
118
|
-
]
|
|
119
|
-
}
|
|
120
|
-
)
|
|
121
|
-
] }),
|
|
122
|
-
/* @__PURE__ */ jsx("br", {}),
|
|
123
|
-
/* @__PURE__ */ jsx("br", {}),
|
|
124
|
-
/* @__PURE__ */ jsxs(Typography, { variant: "body1", children: [
|
|
125
|
-
/* @__PURE__ */ jsx("b", { children: "Warning: " }),
|
|
126
|
-
"Changing this setting will affect how your service dependencies are synchronized and may cause data loss. Check the",
|
|
127
|
-
" ",
|
|
128
|
-
/* @__PURE__ */ jsxs(
|
|
129
|
-
"a",
|
|
130
|
-
{
|
|
131
|
-
style: { color: "cadetblue" },
|
|
132
|
-
href: "https://pagerduty.github.io/backstage-plugin-docs/index.html",
|
|
133
|
-
children: [
|
|
134
|
-
" ",
|
|
135
|
-
"documentation",
|
|
136
|
-
" "
|
|
137
|
-
]
|
|
138
|
-
}
|
|
139
|
-
),
|
|
140
|
-
" ",
|
|
141
|
-
"for more information."
|
|
142
|
-
] })
|
|
143
|
-
]
|
|
144
|
-
}
|
|
145
|
-
)
|
|
146
|
-
] }) })
|
|
147
|
-
] }) })
|
|
148
|
-
] });
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
export { PagerDutyPage };
|
|
152
|
-
//# sourceMappingURL=index.esm.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":["../../../src/components/PagerDutyPage/index.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport {\n Card,\n FormControlLabel,\n Grid,\n Radio,\n RadioGroup,\n Typography,\n} from '@material-ui/core';\nimport {\n Header,\n Page,\n Content,\n TabbedLayout,\n} from '@backstage/core-components';\nimport { ServiceMappingComponent } from './ServiceMappingComponent';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { pagerDutyApiRef } from '../../api';\nimport { NotFoundError } from '@backstage/errors';\n\nconst SERVICE_DEPENDENCY_SYNC_STRATEGY =\n 'settings::service-dependency-sync-strategy';\n\n/** @public */\nexport const PagerDutyPage = () => {\n const pagerDutyApi = useApi(pagerDutyApiRef);\n const [\n selectedServiceDependencyStrategy,\n setSelectedServiceDependencyStrategy,\n ] = useState('disabled');\n\n useEffect(() => {\n function fetchSetting() {\n pagerDutyApi\n .getSetting(SERVICE_DEPENDENCY_SYNC_STRATEGY)\n .then(result => {\n if (result !== undefined) {\n setSelectedServiceDependencyStrategy(result.value);\n }\n })\n .catch(error => {\n if (error instanceof NotFoundError) {\n // If the setting is not found, set the default value to \"disabled\"\n setSelectedServiceDependencyStrategy('disabled');\n }\n });\n }\n\n fetchSetting();\n }, [pagerDutyApi]);\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const value = getSelectedValue((event.target as HTMLInputElement).value);\n\n setSelectedServiceDependencyStrategy(value);\n\n pagerDutyApi.storeSettings([\n {\n id: SERVICE_DEPENDENCY_SYNC_STRATEGY,\n value,\n },\n ]);\n };\n\n function getSelectedValue(\n value: string,\n ): 'backstage' | 'pagerduty' | 'both' | 'disabled' {\n switch (value) {\n case 'backstage':\n return 'backstage';\n case 'pagerduty':\n return 'pagerduty';\n case 'both':\n return 'both';\n default:\n return 'disabled';\n }\n }\n\n return (\n <Page themeId=\"home\">\n <Header title=\"PagerDuty\" subtitle=\"Advanced configurations\" />\n <Content>\n <TabbedLayout>\n <TabbedLayout.Route path=\"/service-mapping\" title=\"Service Mapping\">\n <Grid container spacing={3} direction=\"column\">\n <Grid item>\n {/* <Typography variant=\"h4\">Service to Entity mapping</Typography> */}\n <Typography variant=\"body1\">\n Easily map your existing PagerDuty services to entities in\n Backstage without the need to add anotations to all your\n projects.\n </Typography>\n <Typography variant=\"body1\">\n <b>Warning: </b>Only 1:1 mapping is allowed at this time.\n </Typography>\n </Grid>\n <Grid item>\n <ServiceMappingComponent />\n </Grid>\n </Grid>\n </TabbedLayout.Route>\n <TabbedLayout.Route path=\"/settings\" title=\"Configuration\">\n <Grid container spacing={3} direction=\"column\">\n <Grid item>\n <Typography variant=\"h4\">Plugin configuration</Typography>\n <Typography variant=\"body1\">\n Configure your PagerDuty plugin configuration here\n </Typography>\n </Grid>\n <Card\n title=\"Service dependency synchronization preferences\"\n style={{ padding: '10px', paddingLeft: '15px', width: '50%' }}\n >\n <>\n <Typography variant=\"h6\">\n Service dependency synchronization strategy\n </Typography>\n <Typography variant=\"body1\">\n Select the main source of truth for your service\n dependencies\n </Typography>\n <RadioGroup\n value={selectedServiceDependencyStrategy}\n onChange={handleChange}\n >\n <FormControlLabel\n value=\"backstage\"\n control={<Radio />}\n label=\"Backstage\"\n />\n <FormControlLabel\n value=\"pagerduty\"\n control={<Radio />}\n label=\"PagerDuty\"\n />\n <FormControlLabel\n value=\"both\"\n control={<Radio />}\n label=\"Both\"\n />\n <FormControlLabel\n value=\"disabled\"\n control={<Radio />}\n label=\"Disabled\"\n />\n </RadioGroup>\n </>\n\n <br />\n <br />\n <Typography variant=\"body1\">\n <b>Warning: </b>Changing this setting will affect how your\n service dependencies are synchronized and may cause data loss.\n Check the{' '}\n <a\n style={{ color: 'cadetblue' }}\n href=\"https://pagerduty.github.io/backstage-plugin-docs/index.html\"\n >\n {' '}\n documentation{' '}\n </a>{' '}\n for more information.\n </Typography>\n </Card>\n </Grid>\n </TabbedLayout.Route>\n </TabbedLayout>\n </Content>\n </Page>\n );\n};\n"],"names":[],"mappings":"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"}
|