@pagerduty/backstage-plugin 0.12.1-next.93 → 0.12.1-next.95
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/dist/esm/{index-e498f073.esm.js → index-018702f6.esm.js} +2 -2
- package/dist/esm/{index-e498f073.esm.js.map → index-018702f6.esm.js.map} +1 -1
- package/dist/esm/{index-ef6e3ba1.esm.js → index-780abd98.esm.js} +3 -3
- package/dist/esm/{index-ef6e3ba1.esm.js.map → index-780abd98.esm.js.map} +1 -1
- package/dist/esm/{index-5433d1fd.esm.js → index-7d939558.esm.js} +92 -90
- package/dist/esm/index-7d939558.esm.js.map +1 -0
- package/dist/index.esm.js +1 -1
- package/package.json +1 -1
- package/dist/esm/index-5433d1fd.esm.js.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import React, { useState, useMemo } from 'react';
|
|
2
|
-
import { Typography, Box, DialogTitle, DialogContent,
|
|
2
|
+
import { Typography, Box, DialogTitle, DialogContent, DialogActions, Tooltip, IconButton, Grid } from '@material-ui/core';
|
|
3
3
|
import { Page, Header, Content } from '@backstage/core-components';
|
|
4
4
|
import EditIcon from '@mui/icons-material/Edit';
|
|
5
5
|
import { useApi } from '@backstage/core-plugin-api';
|
|
6
|
-
import { p as pagerDutyApiRef } from './index-
|
|
7
|
-
import { QueryClient, QueryClientProvider, useQuery,
|
|
6
|
+
import { p as pagerDutyApiRef } from './index-780abd98.esm.js';
|
|
7
|
+
import { QueryClient, QueryClientProvider, useQuery, useMutation } from '@tanstack/react-query';
|
|
8
8
|
import { useMaterialReactTable, MRT_EditActionButtons, MaterialReactTable } from 'material-react-table';
|
|
9
9
|
import { catalogApiRef } from '@backstage/plugin-catalog-react';
|
|
10
10
|
import { OpenInBrowser } from '@material-ui/icons';
|
|
@@ -58,80 +58,23 @@ function makeReadable(status) {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
const ServiceMappingComponent = () => {
|
|
61
|
+
const [entityMappings, setEntityMappings] = useState([]);
|
|
61
62
|
const [catalogEntities, setCatalogEntities] = useState([]);
|
|
62
|
-
const [entityOptions, setEntityOptions] = useState([]);
|
|
63
63
|
const pagerDutyApi = useApi(pagerDutyApiRef);
|
|
64
64
|
const catalogApi = useApi(catalogApiRef);
|
|
65
|
-
function useGetMappings() {
|
|
66
|
-
return useQuery({
|
|
67
|
-
queryKey: ["mappings"],
|
|
68
|
-
queryFn: async () => {
|
|
69
|
-
const { mappings: foundMappings } = await pagerDutyApi.getEntityMappings();
|
|
70
|
-
return foundMappings;
|
|
71
|
-
},
|
|
72
|
-
refetchOnWindowFocus: false
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
function useUpdateMapping() {
|
|
76
|
-
const queryClient2 = useQueryClient();
|
|
77
|
-
return useMutation({
|
|
78
|
-
mutationFn: async (mapping) => {
|
|
79
|
-
return await pagerDutyApi.storeServiceMapping(
|
|
80
|
-
mapping.serviceId,
|
|
81
|
-
mapping.entityRef
|
|
82
|
-
);
|
|
83
|
-
},
|
|
84
|
-
// client side optimistic update
|
|
85
|
-
onMutate: (newMappingInfo) => {
|
|
86
|
-
queryClient2.setQueryData(
|
|
87
|
-
["updateMappings"],
|
|
88
|
-
(prevMappings) => prevMappings == null ? void 0 : prevMappings.map(
|
|
89
|
-
(prevMapping) => {
|
|
90
|
-
var _a;
|
|
91
|
-
if (prevMapping.serviceId === newMappingInfo.serviceId) {
|
|
92
|
-
newMappingInfo.entityName = ((_a = catalogEntities.find((entity) => entity.id === newMappingInfo.entityRef)) == null ? void 0 : _a.name) || "";
|
|
93
|
-
return newMappingInfo;
|
|
94
|
-
}
|
|
95
|
-
return prevMapping;
|
|
96
|
-
}
|
|
97
|
-
)
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
function fetchCatalogEntities() {
|
|
103
|
-
catalogApi.getEntities({
|
|
104
|
-
filter: { kind: "Component" }
|
|
105
|
-
}).then(({ items }) => {
|
|
106
|
-
const entities = [];
|
|
107
|
-
items.forEach((entity) => {
|
|
108
|
-
var _a, _b, _c, _d, _e, _f;
|
|
109
|
-
entities.push({
|
|
110
|
-
name: (_a = entity.metadata) == null ? void 0 : _a.name,
|
|
111
|
-
id: (_c = (_b = entity.metadata) == null ? void 0 : _b.uid) != null ? _c : "",
|
|
112
|
-
system: JSON.stringify((_d = entity.spec) == null ? void 0 : _d.system) || "",
|
|
113
|
-
owner: JSON.stringify((_e = entity.spec) == null ? void 0 : _e.owner) || "",
|
|
114
|
-
lifecycle: JSON.stringify((_f = entity.spec) == null ? void 0 : _f.lifecycle) || ""
|
|
115
|
-
});
|
|
116
|
-
});
|
|
117
|
-
setCatalogEntities(entities);
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
65
|
function getCatalogEntityOptions() {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
catalogEntities.forEach((entity) => {
|
|
66
|
+
const options = [];
|
|
67
|
+
options.push({ value: "", label: "None" });
|
|
68
|
+
catalogEntities.forEach((entity) => {
|
|
69
|
+
const foundEntity = entityMappings.find((item) => item.entityRef === entity.id);
|
|
70
|
+
if (!foundEntity) {
|
|
127
71
|
options.push({
|
|
128
72
|
value: entity.id,
|
|
129
73
|
label: entity.name
|
|
130
74
|
});
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
return entityOptions;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
return options;
|
|
135
78
|
}
|
|
136
79
|
const DenseTable = () => {
|
|
137
80
|
const [validationErrors, setValidationErrors] = useState({});
|
|
@@ -142,6 +85,7 @@ const ServiceMappingComponent = () => {
|
|
|
142
85
|
header: "Service ID",
|
|
143
86
|
visibleInShowHideMenu: false,
|
|
144
87
|
enableEditing: false,
|
|
88
|
+
Edit: () => null,
|
|
145
89
|
Cell: ({ cell }) => /* @__PURE__ */ React.createElement(Typography, { variant: "body1", style: { fontWeight: 600 } }, cell.getValue())
|
|
146
90
|
},
|
|
147
91
|
{
|
|
@@ -163,8 +107,8 @@ const ServiceMappingComponent = () => {
|
|
|
163
107
|
accessorKey: "entityRef",
|
|
164
108
|
header: "Mapping",
|
|
165
109
|
visibleInShowHideMenu: false,
|
|
166
|
-
|
|
167
|
-
|
|
110
|
+
editVariant: "select",
|
|
111
|
+
editSelectOptions: getCatalogEntityOptions(),
|
|
168
112
|
muiEditTextFieldProps: {
|
|
169
113
|
select: true,
|
|
170
114
|
error: !!(validationErrors == null ? void 0 : validationErrors.state),
|
|
@@ -174,12 +118,14 @@ const ServiceMappingComponent = () => {
|
|
|
174
118
|
{
|
|
175
119
|
accessorKey: "entityName",
|
|
176
120
|
header: "Mapped Entity Name",
|
|
177
|
-
enableEditing: false
|
|
121
|
+
enableEditing: false,
|
|
122
|
+
Edit: () => null
|
|
178
123
|
},
|
|
179
124
|
{
|
|
180
125
|
accessorKey: "status",
|
|
181
126
|
header: "Status",
|
|
182
127
|
enableEditing: false,
|
|
128
|
+
Edit: () => null,
|
|
183
129
|
Cell: ({ cell }) => /* @__PURE__ */ React.createElement(
|
|
184
130
|
Box,
|
|
185
131
|
{
|
|
@@ -196,7 +142,8 @@ const ServiceMappingComponent = () => {
|
|
|
196
142
|
accessorKey: "serviceUrl",
|
|
197
143
|
header: "Service URL",
|
|
198
144
|
visibleInShowHideMenu: false,
|
|
199
|
-
enableEditing: false
|
|
145
|
+
enableEditing: false,
|
|
146
|
+
Edit: () => null
|
|
200
147
|
}
|
|
201
148
|
],
|
|
202
149
|
[validationErrors]
|
|
@@ -207,11 +154,17 @@ const ServiceMappingComponent = () => {
|
|
|
207
154
|
isFetching: isFetchingMappings,
|
|
208
155
|
isLoading: isLoadingMappings
|
|
209
156
|
} = useGetMappings();
|
|
157
|
+
const {
|
|
158
|
+
data: fetchedCatalogEntities = [],
|
|
159
|
+
isError: isLoadingCatalogEntitiesError,
|
|
160
|
+
isFetching: isFetchingCatalogEntities,
|
|
161
|
+
isLoading: isLoadingCatalogEntities
|
|
162
|
+
} = useGetCatalogEntities();
|
|
210
163
|
const { mutateAsync: updateMapping, isPending: isUpdatingMapping } = useUpdateMapping();
|
|
211
164
|
const handleSaveMapping = async ({ values, table }) => {
|
|
212
165
|
var _a;
|
|
213
166
|
setValidationErrors({});
|
|
214
|
-
values.entityName = ((_a =
|
|
167
|
+
values.entityName = ((_a = fetchedCatalogEntities.find((entity) => entity.id === values.entityRef)) == null ? void 0 : _a.name) || "";
|
|
215
168
|
values.status = "RefreshToUpdate";
|
|
216
169
|
await updateMapping(values);
|
|
217
170
|
table.setEditingRow(null);
|
|
@@ -219,7 +172,6 @@ const ServiceMappingComponent = () => {
|
|
|
219
172
|
const openInBrowser = (url) => {
|
|
220
173
|
window.open(url, "_blank", "noreferrer");
|
|
221
174
|
};
|
|
222
|
-
getCatalogEntityOptions();
|
|
223
175
|
const dataTable = useMaterialReactTable({
|
|
224
176
|
columns,
|
|
225
177
|
data: fetchedMappings,
|
|
@@ -242,17 +194,7 @@ const ServiceMappingComponent = () => {
|
|
|
242
194
|
onEditingRowCancel: () => setValidationErrors({}),
|
|
243
195
|
onEditingRowSave: handleSaveMapping,
|
|
244
196
|
// optionally customize modal content
|
|
245
|
-
renderEditRowDialogContent: ({ table, row }) => /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(DialogTitle, null, "Edit Mapping"), /* @__PURE__ */ React.createElement(DialogContent, null,
|
|
246
|
-
Select,
|
|
247
|
-
{
|
|
248
|
-
value: row.getValue("entityRef"),
|
|
249
|
-
displayEmpty: true,
|
|
250
|
-
onChange: (e) => {
|
|
251
|
-
e.persist();
|
|
252
|
-
}
|
|
253
|
-
},
|
|
254
|
-
entityOptions.map((option) => /* @__PURE__ */ React.createElement(MenuItem, { key: option.label, value: option.value }, option.label))
|
|
255
|
-
)))), /* @__PURE__ */ React.createElement(DialogActions, null, /* @__PURE__ */ React.createElement(MRT_EditActionButtons, { variant: "text", table, row }))),
|
|
197
|
+
renderEditRowDialogContent: ({ table, row, internalEditComponents }) => /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(DialogTitle, null, "Edit Mapping"), /* @__PURE__ */ React.createElement(DialogContent, null, internalEditComponents, " "), /* @__PURE__ */ React.createElement(DialogActions, null, /* @__PURE__ */ React.createElement(MRT_EditActionButtons, { variant: "text", table, row }))),
|
|
256
198
|
renderRowActions: ({ row, table }) => /* @__PURE__ */ React.createElement(Box, { sx: { display: "flex" } }, /* @__PURE__ */ React.createElement(Tooltip, { title: "Edit" }, /* @__PURE__ */ React.createElement(IconButton, { onClick: () => table.setEditingRow(row) }, /* @__PURE__ */ React.createElement(EditIcon, null))), /* @__PURE__ */ React.createElement(Tooltip, { title: "Open in PagerDuty" }, /* @__PURE__ */ React.createElement(
|
|
257
199
|
IconButton,
|
|
258
200
|
{
|
|
@@ -261,10 +203,10 @@ const ServiceMappingComponent = () => {
|
|
|
261
203
|
/* @__PURE__ */ React.createElement(OpenInBrowser, null)
|
|
262
204
|
))),
|
|
263
205
|
state: {
|
|
264
|
-
isLoading: isLoadingMappings,
|
|
206
|
+
isLoading: isLoadingMappings || isLoadingCatalogEntities,
|
|
265
207
|
isSaving: isUpdatingMapping,
|
|
266
|
-
showAlertBanner: isLoadingMappingsError,
|
|
267
|
-
showProgressBars: isFetchingMappings,
|
|
208
|
+
showAlertBanner: isLoadingMappingsError || isLoadingCatalogEntitiesError,
|
|
209
|
+
showProgressBars: isFetchingMappings || isFetchingCatalogEntities,
|
|
268
210
|
columnVisibility: {
|
|
269
211
|
serviceId: false,
|
|
270
212
|
entityRef: false,
|
|
@@ -274,6 +216,66 @@ const ServiceMappingComponent = () => {
|
|
|
274
216
|
});
|
|
275
217
|
return /* @__PURE__ */ React.createElement(MaterialReactTable, { table: dataTable });
|
|
276
218
|
};
|
|
219
|
+
function useGetMappings() {
|
|
220
|
+
return useQuery({
|
|
221
|
+
queryKey: ["mappings"],
|
|
222
|
+
queryFn: async () => {
|
|
223
|
+
const { mappings: foundMappings } = await pagerDutyApi.getEntityMappings();
|
|
224
|
+
setEntityMappings(foundMappings);
|
|
225
|
+
return foundMappings;
|
|
226
|
+
},
|
|
227
|
+
refetchOnWindowFocus: false
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
function useGetCatalogEntities() {
|
|
231
|
+
return useQuery({
|
|
232
|
+
queryKey: ["catalogEntities"],
|
|
233
|
+
queryFn: async () => {
|
|
234
|
+
const result = await catalogApi.getEntities({
|
|
235
|
+
filter: { kind: "Component" }
|
|
236
|
+
});
|
|
237
|
+
const entities = [];
|
|
238
|
+
result.items.forEach((entity) => {
|
|
239
|
+
var _a, _b, _c, _d, _e, _f;
|
|
240
|
+
entities.push({
|
|
241
|
+
name: (_a = entity.metadata) == null ? void 0 : _a.name,
|
|
242
|
+
id: (_c = (_b = entity.metadata) == null ? void 0 : _b.uid) != null ? _c : "",
|
|
243
|
+
system: JSON.stringify((_d = entity.spec) == null ? void 0 : _d.system) || "",
|
|
244
|
+
owner: JSON.stringify((_e = entity.spec) == null ? void 0 : _e.owner) || "",
|
|
245
|
+
lifecycle: JSON.stringify((_f = entity.spec) == null ? void 0 : _f.lifecycle) || ""
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
setCatalogEntities(entities);
|
|
249
|
+
return entities;
|
|
250
|
+
},
|
|
251
|
+
refetchOnWindowFocus: false
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
function useUpdateMapping() {
|
|
255
|
+
return useMutation({
|
|
256
|
+
mutationFn: async (mapping) => {
|
|
257
|
+
return await pagerDutyApi.storeServiceMapping(
|
|
258
|
+
mapping.serviceId,
|
|
259
|
+
mapping.entityRef
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
// client side optimistic update
|
|
263
|
+
// onMutate: (newMappingInfo: PagerDutyEntityMapping) => {
|
|
264
|
+
// queryClient.setQueryData(["updateMappings"], (prevMappings: any) =>
|
|
265
|
+
// prevMappings?.map((prevMapping: PagerDutyEntityMapping) => {
|
|
266
|
+
// if (prevMapping.serviceId === newMappingInfo.serviceId) {
|
|
267
|
+
// newMappingInfo.entityName =
|
|
268
|
+
// fetchedCatalogEntities.find(
|
|
269
|
+
// (entity) => entity.id === newMappingInfo.entityRef
|
|
270
|
+
// )?.name || "";
|
|
271
|
+
// return newMappingInfo;
|
|
272
|
+
// }
|
|
273
|
+
// return prevMapping;
|
|
274
|
+
// })
|
|
275
|
+
// );
|
|
276
|
+
// },
|
|
277
|
+
});
|
|
278
|
+
}
|
|
277
279
|
const queryClient = new QueryClient();
|
|
278
280
|
return /* @__PURE__ */ React.createElement(QueryClientProvider, { client: queryClient }, /* @__PURE__ */ React.createElement(DenseTable, null));
|
|
279
281
|
};
|
|
@@ -283,4 +285,4 @@ const PagerDutyPage = () => {
|
|
|
283
285
|
};
|
|
284
286
|
|
|
285
287
|
export { PagerDutyPage };
|
|
286
|
-
//# sourceMappingURL=index-
|
|
288
|
+
//# sourceMappingURL=index-7d939558.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-7d939558.esm.js","sources":["../../src/components/PagerDutyPage/ServiceMappingComponent.tsx","../../src/components/PagerDutyPage/index.tsx"],"sourcesContent":["import React, { useMemo, useState } from \"react\";\nimport {\n Box,\n DialogActions,\n DialogContent,\n DialogTitle,\n IconButton,\n Tooltip,\n Typography,\n} from \"@material-ui/core\";\nimport EditIcon from \"@mui/icons-material/Edit\";\nimport { PagerDutyEntityMapping } from \"@pagerduty/backstage-plugin-common\";\nimport { useApi } from \"@backstage/core-plugin-api\";\nimport { pagerDutyApiRef } from \"../../api\";\nimport {\n QueryClient,\n QueryClientProvider,\n useMutation,\n useQuery,\n} from \"@tanstack/react-query\";\nimport {\n MRT_ColumnDef,\n MRT_EditActionButtons,\n MRT_TableOptions,\n MaterialReactTable,\n useMaterialReactTable,\n} from \"material-react-table\";\nimport { catalogApiRef } from \"@backstage/plugin-catalog-react\";\nimport { OpenInBrowser } from \"@material-ui/icons\";\n\ntype Service = {\n name: string; // \"Ads\"\n id: string; // \"QWe1j283n12j132\"\n system: string; // \"Production\"\n owner: string; // \"Mapped\"\n lifecycle: string; // \"Ads\"\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\nexport const ServiceMappingComponent = () => {\n const [entityMappings, setEntityMappings] = useState <PagerDutyEntityMapping[]>([]);\n const [catalogEntities, setCatalogEntities] = useState<Service[]>([]);\n // const [entityOptions, setEntityOptions] = useState<CatalogEntityOptions[]>([]);\n\n const pagerDutyApi = useApi(pagerDutyApiRef);\n const catalogApi = useApi(catalogApiRef);\n\n // function fetchCatalogEntities() {\n // catalogApi\n // .getEntities({\n // filter: { kind: \"Component\" },\n // })\n // .then((result) => {\n // const entities: Service[] = [];\n // result.items.forEach((entity: any) => {\n // entities.push({\n // name: entity.metadata?.name,\n // id: entity.metadata?.uid ?? \"\",\n // system: JSON.stringify(entity.spec?.system) || \"\",\n // owner: JSON.stringify(entity.spec?.owner) || \"\",\n // lifecycle: JSON.stringify(entity.spec?.lifecycle) || \"\",\n // });\n // });\n\n // setCatalogEntities(entities);\n // });\n // }\n\n type CatalogEntityOptions = {\n value: string;\n label: string;\n };\n\n function getCatalogEntityOptions(): CatalogEntityOptions[] {\n const options: CatalogEntityOptions[] = [];\n // if (entityOptions.length === 0) {\n // initialize with empty object\n options.push({ value: \"\", label: \"None\" });\n // }\n\n catalogEntities.forEach((entity) => {\n // find entity with entity.id in entityMappings array\n const foundEntity = entityMappings.find((item) => item.entityRef === entity.id);\n\n if(!foundEntity){\n options.push({\n value: entity.id,\n label: entity.name,\n });\n }\n });\n\n // setEntityOptions(options);\n\n return options;\n }\n\n const DenseTable = () => {\n const [validationErrors, setValidationErrors] = useState<\n Record<string, string | undefined>\n >({});\n\n const columns = useMemo<MRT_ColumnDef<PagerDutyEntityMapping>[]>(\n () => [\n {\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 accessorKey: \"serviceName\",\n header: \"PagerDuty Service\",\n enableEditing: false,\n },\n {\n accessorKey: \"team\",\n header: \"Team\",\n enableEditing: false,\n },\n {\n accessorKey: \"escalationPolicy\",\n header: \"Escalation Policy\",\n enableEditing: false,\n },\n {\n accessorKey: \"entityRef\",\n header: \"Mapping\",\n visibleInShowHideMenu: false,\n editVariant: \"select\",\n editSelectOptions: getCatalogEntityOptions(),\n muiEditTextFieldProps: {\n select: true,\n error: !!validationErrors?.state,\n helperText: validationErrors?.state,\n },\n },\n {\n accessorKey: \"entityName\",\n header: \"Mapped Entity Name\",\n enableEditing: false,\n Edit: () => null,\n },\n {\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 accessorKey: \"serviceUrl\",\n header: \"Service URL\",\n visibleInShowHideMenu: false,\n enableEditing: false,\n Edit: () => null,\n },\n ],\n [validationErrors]\n );\n\n // call READ hook\n const {\n data: fetchedMappings = [],\n isError: isLoadingMappingsError,\n isFetching: isFetchingMappings,\n isLoading: isLoadingMappings,\n } = useGetMappings();\n\n // call READ hook\n const {\n data: fetchedCatalogEntities = [],\n isError: isLoadingCatalogEntitiesError,\n isFetching: isFetchingCatalogEntities,\n isLoading: isLoadingCatalogEntities,\n } = useGetCatalogEntities();\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 values.entityName =\n fetchedCatalogEntities.find((entity) => entity.id === values.entityRef)\n ?.name || \"\";\n values.status = \"RefreshToUpdate\";\n await updateMapping(values);\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: fetchedMappings,\n editDisplayMode: \"modal\", // default ('row', 'cell', 'table', and 'custom' are also available)\n enableEditing: true,\n positionActionsColumn: \"last\",\n enableStickyHeader: true,\n enableFilters: true,\n getRowId: (row) => row.serviceId,\n muiToolbarAlertBannerProps: isLoadingMappingsError\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 // optionally customize modal content\n renderEditRowDialogContent: ({ table, row, internalEditComponents }) => (\n <>\n <DialogTitle>Edit Mapping</DialogTitle>\n <DialogContent>{internalEditComponents} </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 onClick={() => table.setEditingRow(row)}>\n <EditIcon />\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: isLoadingMappings || isLoadingCatalogEntities,\n isSaving: isUpdatingMapping,\n showAlertBanner:\n isLoadingMappingsError || isLoadingCatalogEntitiesError,\n showProgressBars: isFetchingMappings || isFetchingCatalogEntities,\n columnVisibility: {\n serviceId: false,\n entityRef: false,\n serviceUrl: false,\n },\n },\n });\n\n return <MaterialReactTable table={dataTable} />;\n };\n\n // READ hook (get mappings from api)\n function useGetMappings() {\n return useQuery<PagerDutyEntityMapping[]>({\n queryKey: [\"mappings\"],\n queryFn: async () => {\n // send api request here\n const { mappings: foundMappings } =\n await pagerDutyApi.getEntityMappings();\n\n setEntityMappings(foundMappings);\n\n return foundMappings;\n },\n refetchOnWindowFocus: false,\n });\n }\n\n // READ hook (get catalog entities from api)\n function useGetCatalogEntities() {\n return useQuery<Service[]>({\n queryKey: [\"catalogEntities\"],\n queryFn: async () => {\n // send api request here\n const result = await catalogApi.getEntities({\n filter: { kind: \"Component\" },\n });\n\n const entities: Service[] = [];\n result.items.forEach((entity: any) => {\n entities.push({\n name: entity.metadata?.name,\n id: entity.metadata?.uid ?? \"\",\n system: JSON.stringify(entity.spec?.system) || \"\",\n owner: JSON.stringify(entity.spec?.owner) || \"\",\n lifecycle: JSON.stringify(entity.spec?.lifecycle) || \"\",\n });\n });\n\n setCatalogEntities(entities);\n\n return entities;\n },\n refetchOnWindowFocus: false,\n });\n }\n\n // UPDATE hook (put mapping in api)\n function useUpdateMapping() {\n // const queryClient = useQueryClient();\n return useMutation({\n mutationFn: async (mapping: PagerDutyEntityMapping) => {\n return await pagerDutyApi.storeServiceMapping(\n mapping.serviceId,\n mapping.entityRef\n );\n },\n // client side optimistic update\n // onMutate: (newMappingInfo: PagerDutyEntityMapping) => {\n // queryClient.setQueryData([\"updateMappings\"], (prevMappings: any) =>\n // prevMappings?.map((prevMapping: PagerDutyEntityMapping) => {\n // if (prevMapping.serviceId === newMappingInfo.serviceId) {\n // newMappingInfo.entityName =\n // fetchedCatalogEntities.find(\n // (entity) => entity.id === newMappingInfo.entityRef\n // )?.name || \"\";\n\n // return newMappingInfo;\n // }\n // return prevMapping;\n // })\n // );\n // },\n });\n }\n\n const queryClient = new QueryClient();\n\n return (\n <QueryClientProvider client={queryClient}>\n <DenseTable />\n </QueryClientProvider>\n );\n};\n","import React from \"react\";\nimport { Grid, Typography } from \"@material-ui/core\";\nimport { Header, Page, Content } from \"@backstage/core-components\";\nimport { ServiceMappingComponent } from \"./ServiceMappingComponent\";\n\n/** @public */\nexport const PagerDutyPage = () => {\n return (\n <Page themeId=\"home\">\n <Header title=\"PagerDuty\" subtitle=\"Advanced configurations\" />\n <Content>\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 services to entities in Backstage without the need to add anotations to all your 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 </Content>\n </Page>\n );\n};\n"],"names":[],"mappings":"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"}
|
package/dist/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { E as EntityPagerDutyCard, c as EntityPagerDutySmallCard, H as HomePagePagerDutyCard, f as PagerDutyCard, e as PagerDutyClient, b as PagerDutyPage, T as TriggerButton, U as UnauthorizedError, i as isPagerDutyAvailable, d as isPagerDutySmallCardAvailable, i as isPluginApplicableToEntity, p as pagerDutyApiRef, a as pagerDutyPlugin, a as plugin } from './esm/index-
|
|
1
|
+
export { E as EntityPagerDutyCard, c as EntityPagerDutySmallCard, H as HomePagePagerDutyCard, f as PagerDutyCard, e as PagerDutyClient, b as PagerDutyPage, T as TriggerButton, U as UnauthorizedError, i as isPagerDutyAvailable, d as isPagerDutySmallCardAvailable, i as isPluginApplicableToEntity, p as pagerDutyApiRef, a as pagerDutyPlugin, a as plugin } from './esm/index-780abd98.esm.js';
|
|
2
2
|
import '@backstage/core-plugin-api';
|
|
3
3
|
import '@backstage/errors';
|
|
4
4
|
import '@backstage/plugin-home-react';
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-5433d1fd.esm.js","sources":["../../src/components/PagerDutyPage/ServiceMappingComponent.tsx","../../src/components/PagerDutyPage/index.tsx"],"sourcesContent":["import React, { useMemo, useState } from \"react\";\nimport {\n Box,\n DialogActions,\n DialogContent,\n DialogTitle,\n FormControl,\n Grid,\n IconButton,\n MenuItem,\n Select,\n Tooltip,\n Typography,\n} from \"@material-ui/core\";\nimport EditIcon from \"@mui/icons-material/Edit\";\nimport { PagerDutyEntityMapping } from \"@pagerduty/backstage-plugin-common\";\nimport { useApi } from \"@backstage/core-plugin-api\";\nimport { pagerDutyApiRef } from \"../../api\";\nimport {\n QueryClient,\n QueryClientProvider,\n useMutation,\n useQuery,\n useQueryClient,\n} from \"@tanstack/react-query\";\nimport {\n MRT_ColumnDef,\n MRT_EditActionButtons, \n MRT_TableOptions,\n MaterialReactTable,\n useMaterialReactTable,\n} from \"material-react-table\";\nimport { catalogApiRef } from \"@backstage/plugin-catalog-react\";\nimport { OpenInBrowser } from \"@material-ui/icons\";\n// import { catalogApiRef } from \"@backstage/plugin-catalog-react\";\n// import { Entity } from \"@backstage/catalog-model\";\n\ntype Service = {\n name: string; // \"Ads\"\n id: string; // \"QWe1j283n12j132\"\n system: string; // \"Production\"\n owner: string; // \"Mapped\"\n lifecycle: string; // \"Ads\"\n};\n\n// type TableItem = {\n// name: string | undefined;\n// team: string | undefined;\n// escalationPolicy: string | undefined;\n// mappingStatus: JSX.Element;\n// mapping: JSX.Element;\n// actions: JSX.Element;\n// };\n\n// type DenseTableProps = {\n// items: TableItem[];\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\nexport const ServiceMappingComponent = () => {\n\n const [catalogEntities, setCatalogEntities] = useState<Service[]>([]);\n const [entityOptions, setEntityOptions] = useState<CatalogEntityOptions[]>([]);\n\n const pagerDutyApi = useApi(pagerDutyApiRef);\n const catalogApi = useApi(catalogApiRef);\n\n // READ hook (get mappings from api)\n function useGetMappings() {\n return useQuery<PagerDutyEntityMapping[]>({\n queryKey: [\"mappings\"],\n queryFn: async () => {\n // send api request here\n const { mappings: foundMappings } =\n await pagerDutyApi.getEntityMappings();\n\n return foundMappings;\n },\n refetchOnWindowFocus: false,\n });\n }\n\n // UPDATE hook (put mapping in api)\n function useUpdateMapping() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: async (mapping: PagerDutyEntityMapping) => {\n return await pagerDutyApi.storeServiceMapping(\n mapping.serviceId,\n mapping.entityRef\n );\n },\n // client side optimistic update\n onMutate: (newMappingInfo: PagerDutyEntityMapping) => {\n queryClient.setQueryData([\"updateMappings\"], (prevMappings: any) =>\n prevMappings?.map((prevMapping: PagerDutyEntityMapping) => {\n if (prevMapping.serviceId === newMappingInfo.serviceId) {\n newMappingInfo.entityName = catalogEntities.find((entity) => entity.id === newMappingInfo.entityRef)?.name || \"\";\n\n return newMappingInfo;\n }\n return prevMapping; \n }\n )\n );\n },\n });\n }\n\n function fetchCatalogEntities() {\n catalogApi\n .getEntities({\n filter: { kind: \"Component\" },\n })\n .then(({ items }) => {\n const entities: Service[] = [];\n items.forEach((entity: any) => {\n entities.push({\n name: entity.metadata?.name,\n id: entity.metadata?.uid ?? \"\",\n system: JSON.stringify(entity.spec?.system) || \"\",\n owner: JSON.stringify(entity.spec?.owner) || \"\",\n lifecycle: JSON.stringify(entity.spec?.lifecycle) || \"\",\n });\n });\n setCatalogEntities(entities);\n });\n }\n\n type CatalogEntityOptions = {\n value: string;\n label: string;\n };\n\n function getCatalogEntityOptions() : CatalogEntityOptions[] {\n // fetch entities if not already fetched\n if (catalogEntities.length === 0) {\n fetchCatalogEntities();\n }\n\n if(entityOptions.length === 0) {\n // initialize with empty object\n const options: CatalogEntityOptions[] = [{value: \"\", label: \"None\"}];\n // Add empty object\n // options.push({ value: \"\", label: \"None\" });\n\n catalogEntities.forEach((entity) => {\n options.push({\n value: entity.id,\n label: entity.name,\n });\n setEntityOptions(options);\n });\n }\n\n return entityOptions;\n }\n\n const DenseTable = () => {\n const [validationErrors, setValidationErrors] = useState<\n Record<string, string | undefined>\n >({});\n\n const columns = useMemo<MRT_ColumnDef<PagerDutyEntityMapping>[]>(\n () => [\n {\n accessorKey: \"serviceId\",\n header: \"Service ID\",\n visibleInShowHideMenu: false,\n enableEditing: false,\n Cell: ({ cell }) => (\n <Typography variant=\"body1\" style={{fontWeight: 600}}>\n {cell.getValue<string>()}\n </Typography> \n ),\n },\n {\n accessorKey: \"serviceName\",\n header: \"PagerDuty Service\",\n enableEditing: false,\n },\n {\n accessorKey: \"team\",\n header: \"Team\",\n enableEditing: false,\n },\n {\n accessorKey: \"escalationPolicy\",\n header: \"Escalation Policy\",\n enableEditing: false,\n },\n {\n accessorKey: \"entityRef\",\n header: \"Mapping\",\n visibleInShowHideMenu: false,\n // editVariant: \"select\",\n // editSelectOptions: getCatalogEntityOptions(),\n muiEditTextFieldProps: {\n select: true,\n error: !!validationErrors?.state,\n helperText: validationErrors?.state,\n },\n },\n {\n accessorKey: \"entityName\",\n header: \"Mapped Entity Name\",\n enableEditing: false,\n },\n {\n accessorKey: \"status\",\n header: \"Status\",\n enableEditing: false,\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 accessorKey: \"serviceUrl\",\n header: \"Service URL\",\n visibleInShowHideMenu: false,\n enableEditing: false,\n },\n ],\n [validationErrors]\n );\n\n // call READ hook\n const {\n data: fetchedMappings = [],\n isError: isLoadingMappingsError,\n isFetching: isFetchingMappings,\n isLoading: isLoadingMappings,\n } = useGetMappings();\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 values.entityName = catalogEntities.find((entity) => entity.id === values.entityRef)?.name || \"\";\n values.status = \"RefreshToUpdate\";\n await updateMapping(values);\n table.setEditingRow(null); // exit editing mode\n };\n\n const openInBrowser = (url: string) => {\n window.open(url, \"_blank\", \"noreferrer\");\n };\n\n getCatalogEntityOptions();\n const dataTable = useMaterialReactTable({\n columns,\n data: fetchedMappings,\n editDisplayMode: \"modal\", // default ('row', 'cell', 'table', and 'custom' are also available)\n enableEditing: true,\n positionActionsColumn: \"last\",\n enableStickyHeader: true,\n enableFilters: true,\n getRowId: (row) => row.serviceId,\n muiToolbarAlertBannerProps: isLoadingMappingsError\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 // optionally customize modal content\n renderEditRowDialogContent: ({ table, row }) => (\n <>\n <DialogTitle>Edit Mapping</DialogTitle>\n <DialogContent>\n <Grid>\n <Typography variant=\"overline\">\n <b>PagerDuty Service</b>\n </Typography>\n <Typography variant=\"body2\">\n {row.getValue(\"serviceName\")}\n </Typography>\n <Typography variant=\"overline\">\n <b>Team</b>\n </Typography>\n <Typography variant=\"body2\">{row.getValue(\"team\")}</Typography>\n <Typography variant=\"overline\">\n <b>Escalation Policy</b>\n </Typography>\n <Typography variant=\"body2\">\n {row.getValue(\"escalationPolicy\")}\n </Typography>\n <Typography variant=\"overline\">\n <b>Mapping</b>\n </Typography>\n\n <FormControl>\n <Select\n value={row.getValue(\"entityRef\")}\n displayEmpty\n onChange={(e) => {\n e.persist();\n // row .setValue(\"entityRef\", e.target.value as string);\n }}\n >\n {\n entityOptions.map((option) => (\n <MenuItem key={option.label} value={option.value}>\n {option.label}\n </MenuItem>\n ))\n }\n </Select>\n </FormControl>\n {/* <Typography variant=\"body2\">\n {row.getValue(\"entityRef\")}\n </Typography> */}\n </Grid>\n {/* {internalEditComponents}{\" \"} */}\n {/* or render custom edit components here */}\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 onClick={() => table.setEditingRow(row)}>\n <EditIcon />\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: isLoadingMappings,\n isSaving: isUpdatingMapping,\n showAlertBanner: isLoadingMappingsError,\n showProgressBars: isFetchingMappings,\n columnVisibility: {\n serviceId: false,\n entityRef: false,\n serviceUrl: false,\n },\n },\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","import React from \"react\";\nimport { Grid, Typography } from \"@material-ui/core\";\nimport { Header, Page, Content } from \"@backstage/core-components\";\nimport { ServiceMappingComponent } from \"./ServiceMappingComponent\";\n\n/** @public */\nexport const PagerDutyPage = () => {\n return (\n <Page themeId=\"home\">\n <Header title=\"PagerDuty\" subtitle=\"Advanced configurations\" />\n <Content>\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 services to entities in Backstage without the need to add anotations to all your 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 </Content>\n </Page>\n );\n};\n"],"names":["queryClient"],"mappings":"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"}
|