@pagerduty/backstage-plugin 0.12.1-next.2 → 0.12.1-next.20
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-3dd8801b.esm.js → index-9f07e393.esm.js} +24 -5
- package/dist/esm/index-9f07e393.esm.js.map +1 -0
- package/dist/esm/{index-c99fd03f.esm.js → index-c6210841.esm.js} +2 -2
- package/dist/esm/{index-c99fd03f.esm.js.map → index-c6210841.esm.js.map} +1 -1
- package/dist/esm/{index-38e122bb.esm.js → index-d3c80abd.esm.js} +74 -69
- package/dist/esm/index-d3c80abd.esm.js.map +1 -0
- package/dist/index.d.ts +10 -4
- package/dist/index.esm.js +1 -1
- package/package.json +3 -3
- package/dist/esm/index-38e122bb.esm.js.map +0 -1
- package/dist/esm/index-3dd8801b.esm.js.map +0 -1
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
1
|
+
import React, { useState, useEffect } from 'react';
|
|
2
2
|
import { Typography, FormControl, InputLabel, Select, MenuItem, Button, Grid } from '@material-ui/core';
|
|
3
3
|
import { Table, Page, Header, Content } from '@backstage/core-components';
|
|
4
4
|
import { useApi } from '@backstage/core-plugin-api';
|
|
5
|
-
import { p as pagerDutyApiRef } from './index-
|
|
6
|
-
import { useAsync } from 'react-use';
|
|
5
|
+
import { p as pagerDutyApiRef } from './index-9f07e393.esm.js';
|
|
7
6
|
import { catalogApiRef } from '@backstage/plugin-catalog-react';
|
|
8
7
|
import '@backstage/errors';
|
|
9
8
|
import '@backstage/plugin-home-react';
|
|
@@ -24,28 +23,29 @@ import '@material-ui/icons/Info';
|
|
|
24
23
|
import '@material-ui/icons/CheckCircle';
|
|
25
24
|
import '@material-ui/icons/RadioButtonUnchecked';
|
|
26
25
|
import '@material-ui/core/styles';
|
|
26
|
+
import 'react-use';
|
|
27
27
|
import '@material-ui/lab/Alert/Alert';
|
|
28
28
|
import '@backstage/catalog-model';
|
|
29
29
|
import '@material-ui/icons/AddAlert';
|
|
30
30
|
import '@material-ui/icons/ExpandMore';
|
|
31
31
|
|
|
32
|
-
function getMappingStatus(serviceName) {
|
|
33
|
-
if (serviceName === "Ads") {
|
|
34
|
-
return "In Sync" /* InSync */;
|
|
35
|
-
}
|
|
36
|
-
return "Out Of Sync" /* OutOfSync */;
|
|
37
|
-
}
|
|
38
32
|
function getColorFromStatus(status) {
|
|
39
33
|
switch (status) {
|
|
40
|
-
case "
|
|
34
|
+
case "InSync":
|
|
41
35
|
return "green";
|
|
42
|
-
case "
|
|
36
|
+
case "OutOfSync":
|
|
43
37
|
return "red";
|
|
44
|
-
|
|
38
|
+
case "NotMapped":
|
|
45
39
|
return "orange";
|
|
40
|
+
default:
|
|
41
|
+
return "gray";
|
|
46
42
|
}
|
|
47
43
|
}
|
|
48
|
-
const DenseTable = ({
|
|
44
|
+
const DenseTable = ({
|
|
45
|
+
BackstageServices,
|
|
46
|
+
ServiceMappings
|
|
47
|
+
}) => {
|
|
48
|
+
const pagerDutyApi = useApi(pagerDutyApiRef);
|
|
49
49
|
const columns = [
|
|
50
50
|
{ title: "PagerDuty Service", field: "name" },
|
|
51
51
|
{ title: "Team", field: "team" },
|
|
@@ -54,55 +54,55 @@ const DenseTable = ({ BackstageServices, PagerDutyServices }) => {
|
|
|
54
54
|
{ title: "Status", field: "mappingStatus", width: "10%" },
|
|
55
55
|
{ title: "Actions", field: "actions" }
|
|
56
56
|
];
|
|
57
|
-
const data =
|
|
58
|
-
var _a, _b;
|
|
59
|
-
const status = getMappingStatus(service.name);
|
|
57
|
+
const data = ServiceMappings.map((service) => {
|
|
60
58
|
return {
|
|
61
|
-
name: service.
|
|
62
|
-
team:
|
|
63
|
-
escalationPolicy: service.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
status
|
|
75
|
-
)
|
|
59
|
+
name: service.serviceName,
|
|
60
|
+
team: service.team,
|
|
61
|
+
escalationPolicy: service.escalationPolicy,
|
|
62
|
+
// status of mapping
|
|
63
|
+
mappingStatus: /* @__PURE__ */ React.createElement(
|
|
64
|
+
Typography,
|
|
65
|
+
{
|
|
66
|
+
variant: "body2",
|
|
67
|
+
style: {
|
|
68
|
+
color: getColorFromStatus(service.status)
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
service.status
|
|
76
72
|
),
|
|
77
73
|
mapping: (
|
|
78
74
|
// dropdown menu with static options. If service.mapping is defined select that option
|
|
79
|
-
/* @__PURE__ */ React.createElement(FormControl,
|
|
75
|
+
/* @__PURE__ */ React.createElement(FormControl, { variant: "standard" }, /* @__PURE__ */ React.createElement(InputLabel, { id: "demo-simple-select-helper-label" }, "Service"), /* @__PURE__ */ React.createElement(
|
|
80
76
|
Select,
|
|
81
77
|
{
|
|
82
78
|
labelId: "demo-simple-select-helper-label",
|
|
83
|
-
id: "demo-simple-select-helper"
|
|
79
|
+
id: "demo-simple-select-helper",
|
|
80
|
+
onChange: async (selection) => {
|
|
81
|
+
await pagerDutyApi.storeServiceMapping(service.service_id, selection.target.value);
|
|
82
|
+
},
|
|
83
|
+
value: service.entity_ref
|
|
84
84
|
},
|
|
85
85
|
/* @__PURE__ */ React.createElement(MenuItem, { value: "" }, /* @__PURE__ */ React.createElement("em", null, "None")),
|
|
86
86
|
BackstageServices.map((backstageService) => {
|
|
87
87
|
return /* @__PURE__ */ React.createElement(
|
|
88
88
|
MenuItem,
|
|
89
89
|
{
|
|
90
|
-
key: backstageService.
|
|
91
|
-
value: backstageService.
|
|
90
|
+
key: backstageService.id,
|
|
91
|
+
value: backstageService.id
|
|
92
92
|
},
|
|
93
93
|
backstageService.name
|
|
94
94
|
);
|
|
95
95
|
})
|
|
96
96
|
))
|
|
97
97
|
),
|
|
98
|
-
actions: /* @__PURE__ */ React.createElement(Button, { variant: "contained", color: "primary", href: service.
|
|
98
|
+
actions: /* @__PURE__ */ React.createElement(Button, { variant: "contained", color: "primary", href: service.serviceUrl }, "Open in PagerDuty")
|
|
99
99
|
};
|
|
100
100
|
});
|
|
101
101
|
return /* @__PURE__ */ React.createElement(
|
|
102
102
|
Table,
|
|
103
103
|
{
|
|
104
104
|
title: "PagerDuty Service Import",
|
|
105
|
-
subtitle: "Use this page to import services from PagerDuty and map them to existing Backstage services ",
|
|
105
|
+
subtitle: "Use this page to import services from PagerDuty and map them to existing Backstage services. Only 1:1 mapping is allowed.",
|
|
106
106
|
options: {
|
|
107
107
|
search: true,
|
|
108
108
|
paging: true,
|
|
@@ -124,41 +124,46 @@ const DenseTable = ({ BackstageServices, PagerDutyServices }) => {
|
|
|
124
124
|
);
|
|
125
125
|
};
|
|
126
126
|
const ServiceMappingComponent = () => {
|
|
127
|
-
const backstageServices = [];
|
|
128
127
|
const [catalogEntities, setCatalogEntities] = useState([]);
|
|
128
|
+
const [serviceMappings, setServiceMappings] = useState([]);
|
|
129
129
|
const pagerDutyApi = useApi(pagerDutyApiRef);
|
|
130
130
|
const catalogApi = useApi(catalogApiRef);
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
131
|
+
useEffect(() => {
|
|
132
|
+
async function fetchEntities() {
|
|
133
|
+
const { items } = await catalogApi.getEntities({
|
|
134
|
+
filter: { kind: "Component" }
|
|
135
|
+
});
|
|
136
|
+
const backstageServices = [];
|
|
137
|
+
items.forEach((entity) => {
|
|
138
|
+
var _a, _b, _c, _d, _e, _f;
|
|
139
|
+
backstageServices.push({
|
|
140
|
+
name: (_a = entity.metadata) == null ? void 0 : _a.name,
|
|
141
|
+
id: (_c = (_b = entity.metadata) == null ? void 0 : _b.uid) != null ? _c : "",
|
|
142
|
+
system: JSON.stringify((_d = entity.spec) == null ? void 0 : _d.system) || "",
|
|
143
|
+
owner: JSON.stringify((_e = entity.spec) == null ? void 0 : _e.owner) || "",
|
|
144
|
+
lifecycle: JSON.stringify((_f = entity.spec) == null ? void 0 : _f.lifecycle) || ""
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
return backstageServices;
|
|
148
|
+
}
|
|
149
|
+
async function fetchServices() {
|
|
150
|
+
const { mappings: foundServices } = await pagerDutyApi.getEntityMappings();
|
|
151
|
+
return foundServices;
|
|
152
|
+
}
|
|
153
|
+
Promise.all([fetchEntities(), fetchServices()]).then(
|
|
154
|
+
([entities, mappings]) => {
|
|
155
|
+
setCatalogEntities(entities);
|
|
156
|
+
setServiceMappings(mappings);
|
|
140
157
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
151
|
-
catalogEntities == null ? void 0 : catalogEntities.forEach((entity) => {
|
|
152
|
-
var _a, _b, _c, _d;
|
|
153
|
-
backstageServices.push({
|
|
154
|
-
name: entity.metadata.name,
|
|
155
|
-
id: (_a = entity.metadata.uid) != null ? _a : "",
|
|
156
|
-
system: JSON.stringify((_b = entity.spec) == null ? void 0 : _b.system) || "",
|
|
157
|
-
owner: JSON.stringify((_c = entity.spec) == null ? void 0 : _c.owner) || "",
|
|
158
|
-
lifecycle: JSON.stringify((_d = entity.spec) == null ? void 0 : _d.lifecycle) || ""
|
|
159
|
-
});
|
|
160
|
-
});
|
|
161
|
-
return /* @__PURE__ */ React.createElement(DenseTable, { BackstageServices: backstageServices || [], PagerDutyServices: pagerDutyServices != null ? pagerDutyServices : [] });
|
|
158
|
+
);
|
|
159
|
+
}, [catalogApi, pagerDutyApi]);
|
|
160
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, catalogEntities.length > 0 ? /* @__PURE__ */ React.createElement(
|
|
161
|
+
DenseTable,
|
|
162
|
+
{
|
|
163
|
+
BackstageServices: catalogEntities,
|
|
164
|
+
ServiceMappings: serviceMappings != null ? serviceMappings : []
|
|
165
|
+
}
|
|
166
|
+
) : /* @__PURE__ */ React.createElement("div", null, "Loading..."));
|
|
162
167
|
};
|
|
163
168
|
|
|
164
169
|
const PagerDutyPage = () => {
|
|
@@ -166,4 +171,4 @@ const PagerDutyPage = () => {
|
|
|
166
171
|
};
|
|
167
172
|
|
|
168
173
|
export { PagerDutyPage };
|
|
169
|
-
//# sourceMappingURL=index-
|
|
174
|
+
//# sourceMappingURL=index-d3c80abd.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-d3c80abd.esm.js","sources":["../../src/components/PagerDutyPage/ServiceMappingComponent.tsx","../../src/components/PagerDutyPage/index.tsx"],"sourcesContent":["import React, { useEffect, useState } from \"react\";\nimport { Table, TableColumn } from \"@backstage/core-components\";\nimport {\n Button,\n FormControl,\n InputLabel,\n MenuItem,\n Select,\n Typography,\n} from \"@material-ui/core\";\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 { 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\ntype DenseTableProps = {\n BackstageServices: Service[];\n ServiceMappings: PagerDutyEntityMapping[];\n};\n\n// function getMappingStatus(serviceName: string): MappingStatus {\n// if (serviceName === \"Ads\") {\n// return MappingStatus.InSync;\n// }\n\n// return MappingStatus.OutOfSync;\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\nexport const DenseTable = ({\n BackstageServices,\n ServiceMappings,\n}: DenseTableProps) => {\n // const classes = useStyles();\n\n const pagerDutyApi = useApi(pagerDutyApiRef);\n\n const columns: TableColumn[] = [\n { title: \"PagerDuty Service\", field: \"name\" },\n { title: \"Team\", field: \"team\" },\n { title: \"Escalation Policy\", field: \"escalationPolicy\" },\n { title: \"Mapping\", field: \"mapping\" },\n { title: \"Status\", field: \"mappingStatus\", width: \"10%\" },\n { title: \"Actions\", field: \"actions\" },\n ];\n\n const data = ServiceMappings.map((service) => {\n // const status = getMappingStatus(service.serviceName!);\n\n return {\n name: service.serviceName,\n team: service.team,\n escalationPolicy: service.escalationPolicy,\n // status of mapping\n mappingStatus: (\n <Typography\n variant=\"body2\"\n style={{\n color: getColorFromStatus(service.status),\n }}\n >\n {service.status}\n </Typography>\n ),\n mapping: (\n // dropdown menu with static options. If service.mapping is defined select that option\n <FormControl variant=\"standard\">\n <InputLabel id=\"demo-simple-select-helper-label\">Service</InputLabel>\n <Select\n labelId=\"demo-simple-select-helper-label\"\n id=\"demo-simple-select-helper\"\n onChange={async (selection) => {\n await pagerDutyApi.storeServiceMapping(service.service_id, selection.target.value as string)\n \n }}\n value={service.entity_ref}\n >\n <MenuItem value=\"\">\n <em>None</em>\n </MenuItem>\n {BackstageServices.map((backstageService) => {\n return (\n <MenuItem\n key={backstageService.id}\n value={backstageService.id}\n >\n {backstageService.name}\n </MenuItem>\n );\n })}\n </Select>\n </FormControl>\n // <select title=\"Mapping\" value={service.mapping}>\n // <option aria-label=\"None\" value=\"\" />\n // <option value=\"Ads\">Ads</option>\n // <option value=\"Cache\">Cache</option>\n // <option value=\"Catalog\">Catalog</option>\n // <option value=\"Checkout\">Checkout</option>\n // </select>\n ),\n actions: (\n <Button variant=\"contained\" color=\"primary\" href={service.serviceUrl}>\n Open in PagerDuty\n </Button>\n ),\n };\n });\n\n return (\n <Table\n title=\"PagerDuty Service Import\"\n subtitle=\"Use this page to import services from PagerDuty and map them to existing Backstage services. Only 1:1 mapping is allowed.\"\n options={{\n search: true,\n paging: true,\n pageSize: 10,\n pageSizeOptions: [10, 25, 50],\n sorting: true,\n emptyRowsWhenPaging: false,\n showFirstLastPageButtons: true,\n columnResizable: true,\n columnsButton: true,\n rowStyle: {\n height: \"10px\",\n },\n padding: \"dense\",\n }}\n columns={columns}\n data={data}\n />\n );\n};\n\nexport const ServiceMappingComponent = () => {\n \n const [catalogEntities, setCatalogEntities] = useState<Service[]>([]);\n const [serviceMappings, setServiceMappings] = useState<PagerDutyEntityMapping[]>([]);\n const pagerDutyApi = useApi(pagerDutyApiRef);\n const catalogApi = useApi(catalogApiRef);\n\n useEffect(() => {\n async function fetchEntities(): Promise<Service[]> {\n const { items } = await catalogApi.getEntities({\n filter: { kind: \"Component\" },\n });\n\n const backstageServices: Service[] = [];\n items.forEach((entity: Entity) => {\n backstageServices.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 return backstageServices;\n }\n\n async function fetchServices(): Promise<PagerDutyEntityMapping[]> {\n const { mappings: foundServices } = await pagerDutyApi.getEntityMappings();\n\n return foundServices;\n }\n\n Promise.all([fetchEntities(), fetchServices()]).then(\n ([entities, mappings]) => {\n setCatalogEntities(entities);\n setServiceMappings(mappings);\n }\n );\n }, [catalogApi, pagerDutyApi]);\n\n return (\n <>\n {catalogEntities.length > 0 ? (\n <DenseTable\n BackstageServices={catalogEntities}\n ServiceMappings={serviceMappings ?? []}\n />\n ) : (\n <div>Loading...</div>\n )}\n </>\n );\n};\n","import React from \"react\";\nimport { Grid } from \"@material-ui/core\";\nimport { Header, Page, Content } from \"@backstage/core-components\";\nimport { ServiceMappingComponent } from \"./ServiceMappingComponent\";\n\n/** @public */\nexport const PagerDutyPage = () => {\n // const [toggleImport, setToggleImport] = useState(false);\n // const [toggleSave, setToggleSave] = useState(false);\n\n // const handleImport = () => {\n // setToggleImport(!toggleImport);\n // };\n\n // const handleSave = () => {\n // setToggleSave(!toggleSave);\n // }\n\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 alignContent=\"flex-end\">\n <Button variant=\"contained\" color=\"primary\" onClick={() => {handleImport()}}>\n Import\n </Button>\n <Button variant=\"outlined\" color=\"primary\" onClick={() => {handleSave()}}>\n Save\n </Button>\n </Grid>\n </Grid> */}\n <Grid container spacing={3} direction=\"column\">\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.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import * as react from 'react';
|
|
|
5
5
|
import react__default, { ReactNode } from 'react';
|
|
6
6
|
import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
|
|
7
7
|
import { DiscoveryApi, FetchApi, ConfigApi } from '@backstage/core-plugin-api';
|
|
8
|
-
import {
|
|
8
|
+
import { PagerDutyEntityMappingResponse, PagerDutyServiceResponse, PagerDutyIncidentsResponse, PagerDutyChangeEventsResponse, PagerDutyServiceStandardsResponse, PagerDutyServiceMetricsResponse, PagerDutyUser } from '@pagerduty/backstage-plugin-common';
|
|
9
9
|
|
|
10
10
|
/** @public */
|
|
11
11
|
declare const isPluginApplicableToEntity$1: (entity: Entity) => boolean;
|
|
@@ -63,10 +63,15 @@ type PagerDutyTriggerAlarmRequest = {
|
|
|
63
63
|
/** @public */
|
|
64
64
|
interface PagerDutyApi {
|
|
65
65
|
/**
|
|
66
|
-
* Fetches all
|
|
66
|
+
* Fetches all entity mappings.
|
|
67
67
|
*
|
|
68
68
|
*/
|
|
69
|
-
|
|
69
|
+
getEntityMappings(): Promise<PagerDutyEntityMappingResponse>;
|
|
70
|
+
/**
|
|
71
|
+
* Stores the service mapping in the database.
|
|
72
|
+
*
|
|
73
|
+
*/
|
|
74
|
+
storeServiceMapping(serviceId: string, policyId: string): Promise<Response>;
|
|
70
75
|
/**
|
|
71
76
|
* Fetches the service for the provided pager duty Entity.
|
|
72
77
|
*
|
|
@@ -133,7 +138,8 @@ declare class PagerDutyClient implements PagerDutyApi {
|
|
|
133
138
|
static fromConfig(configApi: ConfigApi, dependencies: PagerDutyClientApiDependencies): PagerDutyClient;
|
|
134
139
|
constructor(config: PagerDutyClientApiConfig);
|
|
135
140
|
getServiceByPagerDutyEntity(pagerDutyEntity: PagerDutyEntity): Promise<PagerDutyServiceResponse>;
|
|
136
|
-
|
|
141
|
+
getEntityMappings(): Promise<PagerDutyEntityMappingResponse>;
|
|
142
|
+
storeServiceMapping(serviceId: string, backstageEntityId: string): Promise<Response>;
|
|
137
143
|
getServiceByEntity(entity: Entity): Promise<PagerDutyServiceResponse>;
|
|
138
144
|
getServiceById(serviceId: string): Promise<PagerDutyServiceResponse>;
|
|
139
145
|
getIncidentsByServiceId(serviceId: string): Promise<PagerDutyIncidentsResponse>;
|
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-9f07e393.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,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pagerduty/backstage-plugin",
|
|
3
3
|
"description": "A Backstage plugin that integrates towards PagerDuty",
|
|
4
|
-
"version": "0.12.1-next.
|
|
4
|
+
"version": "0.12.1-next.20",
|
|
5
5
|
"main": "dist/index.esm.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"license": "Apache-2.0",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"validate-color": "^2.2.4"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
|
-
"@pagerduty/backstage-plugin-common": "^0.1.
|
|
53
|
+
"@pagerduty/backstage-plugin-common": "^0.1.5-next.3",
|
|
54
54
|
"react": "^18.0.0 || ^20.0.0",
|
|
55
55
|
"react-dom": "^18.0.0 || ^20.0.0",
|
|
56
56
|
"react-router-dom": "^6.3.0"
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"@backstage/test-utils": "^1.5.1",
|
|
63
63
|
"@commitlint/cli": "^17.7.1",
|
|
64
64
|
"@commitlint/config-conventional": "^17.7.0",
|
|
65
|
-
"@pagerduty/backstage-plugin-common": "^0.1.
|
|
65
|
+
"@pagerduty/backstage-plugin-common": "^0.1.5-next.3",
|
|
66
66
|
"@testing-library/dom": "^8.0.0",
|
|
67
67
|
"@testing-library/jest-dom": "^5.10.1",
|
|
68
68
|
"@testing-library/react": "^12.1.3",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-38e122bb.esm.js","sources":["../../src/components/PagerDutyPage/ServiceMappingComponent.tsx","../../src/components/PagerDutyPage/index.tsx"],"sourcesContent":["import React, { useState } from \"react\";\nimport {\n Table,\n TableColumn,\n} from \"@backstage/core-components\";\nimport { Button, FormControl, InputLabel, MenuItem, Select, Typography } from \"@material-ui/core\";\nimport { PagerDutyService } from \"@pagerduty/backstage-plugin-common\";\nimport { Entity } from \"@backstage/catalog-model\";\nimport { useApi } from \"@backstage/core-plugin-api\";\nimport { pagerDutyApiRef } from \"../../api\";\nimport { useAsync } from \"react-use\";\nimport { catalogApiRef } from \"@backstage/plugin-catalog-react\";\nimport { GetEntitiesResponse } from \"@backstage/catalog-client\";\n\nenum MappingStatus { \n InSync = \"In Sync\", \n OutOfSync = \"Out Of Sync\", \n NotMapped = \"Not Mapped\"};\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\ntype DenseTableProps = {\n BackstageServices: Service[];\n PagerDutyServices: PagerDutyService[];\n};\n\nfunction getMappingStatus(serviceName: string) : MappingStatus {\n \n if(serviceName === \"Ads\") {\n return MappingStatus.InSync;\n } \n \n return MappingStatus.OutOfSync;\n}\n\nfunction getColorFromStatus(status: MappingStatus) {\n switch (status) {\n case MappingStatus.InSync:\n return \"green\";\n case MappingStatus.OutOfSync:\n return \"red\";\n default:\n return \"orange\";\n }\n}\n\nexport const DenseTable = ({ BackstageServices, PagerDutyServices }: DenseTableProps) => {\n// const classes = useStyles();\n\n const columns: TableColumn[] = [\n { title: \"PagerDuty Service\", field: \"name\" },\n { title: \"Team\", field: \"team\" },\n { title: \"Escalation Policy\", field: \"escalationPolicy\" },\n { title: \"Mapping\", field: \"mapping\" },\n { title: \"Status\", field: \"mappingStatus\", width: \"10%\" },\n { title: \"Actions\", field: \"actions\" },\n ];\n\n const data = PagerDutyServices.map((service) => {\n\n const status = getMappingStatus(service.name);\n\n return {\n name: service.name,\n team: service.teams?.at(0)?.summary,\n escalationPolicy: service.escalation_policy.name,\n mappingStatus:\n ( // status of mapping\n <Typography\n variant=\"body2\"\n style={{\n color: getColorFromStatus(status),\n }}\n >\n {status}\n </Typography>\n ),\n mapping: (\n // dropdown menu with static options. If service.mapping is defined select that option\n <FormControl>\n <InputLabel id=\"demo-simple-select-helper-label\">Service</InputLabel>\n <Select\n labelId=\"demo-simple-select-helper-label\"\n id=\"demo-simple-select-helper\"\n // onChange={handleChange}\n >\n <MenuItem value=\"\">\n <em>None</em>\n </MenuItem>\n {BackstageServices.map((backstageService) => {\n return (\n <MenuItem\n key={backstageService.name}\n value={backstageService.name}\n >\n {backstageService.name}\n </MenuItem>\n );\n })}\n </Select>\n </FormControl>\n // <select title=\"Mapping\" value={service.mapping}>\n // <option aria-label=\"None\" value=\"\" />\n // <option value=\"Ads\">Ads</option>\n // <option value=\"Cache\">Cache</option>\n // <option value=\"Catalog\">Catalog</option>\n // <option value=\"Checkout\">Checkout</option>\n // </select>\n ),\n actions: (\n <Button variant=\"contained\" color=\"primary\" href={service.html_url}>\n Open in PagerDuty\n </Button>\n ),\n };\n });\n\n return (\n <Table\n title=\"PagerDuty Service Import\"\n subtitle=\"Use this page to import services from PagerDuty and map them to existing Backstage services \"\n options={{\n search: true,\n paging: true,\n pageSize: 10,\n pageSizeOptions: [10, 25, 50],\n sorting: true,\n emptyRowsWhenPaging: false,\n showFirstLastPageButtons: true,\n columnResizable: true,\n columnsButton: true,\n rowStyle: {\n height: \"10px\",\n },\n padding: \"dense\",\n }}\n columns={columns}\n data={data}\n />\n );\n};\n\nexport const ServiceMappingComponent = () => {\n const backstageServices: Service[] = [];\n const [catalogEntities, setCatalogEntities] = useState<Entity[]>([]);\n const pagerDutyApi = useApi(pagerDutyApiRef);\n const catalogApi = useApi(catalogApiRef);\n\n const {\n value: pagerDutyServices,\n loading,\n error,\n } = useAsync(async () => {\n const { services: foundServices } = await pagerDutyApi.getAllServices();\n\n const response : GetEntitiesResponse = await catalogApi.getEntities({\n filter: {\n kind: \"Component\",\n },\n });\n\n setCatalogEntities(response.items);\n\n return foundServices;\n }, []);\n\n if (error) {\n return <p>Error: {error.message}</p>;\n }\n\n if(loading) {\n return <p>Loading...</p>;\n }\n\n catalogEntities?.forEach((entity) => {\n backstageServices.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 return <DenseTable BackstageServices={backstageServices || []} PagerDutyServices={pagerDutyServices ?? []} />;\n};\n","import React from \"react\";\nimport { Grid } from \"@material-ui/core\";\nimport { Header, Page, Content } from \"@backstage/core-components\";\nimport { ServiceMappingComponent } from \"./ServiceMappingComponent\";\n\n/** @public */\nexport const PagerDutyPage = () => {\n // const [toggleImport, setToggleImport] = useState(false);\n // const [toggleSave, setToggleSave] = useState(false);\n\n // const handleImport = () => {\n // setToggleImport(!toggleImport);\n // };\n\n // const handleSave = () => {\n // setToggleSave(!toggleSave);\n // }\n\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 alignContent=\"flex-end\">\n <Button variant=\"contained\" color=\"primary\" onClick={() => {handleImport()}}>\n Import\n </Button>\n <Button variant=\"outlined\" color=\"primary\" onClick={() => {handleSave()}}>\n Save\n </Button>\n </Grid>\n </Grid> */}\n <Grid container spacing={3} direction=\"column\">\n <Grid item>\n <ServiceMappingComponent />\n </Grid>\n </Grid>\n </Content>\n </Page>\n );\n};\n"],"names":[],"mappings":"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"}
|