@backstage-community/plugin-newrelic-dashboard 0.3.10
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/CHANGELOG.md +1325 -0
- package/README.md +79 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.esm.js +447 -0
- package/dist/index.esm.js.map +1 -0
- package/package.json +64 -0
package/README.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# New Relic Dashboard Plugin
|
|
2
|
+
|
|
3
|
+
Welcome to the newrelic-dashboard plugin!
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Adds New Relic Dashboard Pages Links to Overview section of the catalog
|
|
8
|
+
- Shows Snapshots of dashboards in New Relic
|
|
9
|
+
|
|
10
|
+
## Getting started
|
|
11
|
+
|
|
12
|
+
This plugin uses the Backstage proxy to securely communicate with New Relic's APIs. We use NerdGraph (New Relic's GraphQL API)
|
|
13
|
+
|
|
14
|
+
To generate a New Relic API Key , you can visit this [link](https://one.newrelic.com/launcher/api-keys-ui.api-keys-launcher)
|
|
15
|
+
|
|
16
|
+
1. Add the following to your app-config.yaml to enable this configuration:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
// app-config.yaml
|
|
20
|
+
proxy:
|
|
21
|
+
'/newrelic/api':
|
|
22
|
+
target: https://api.newrelic.com
|
|
23
|
+
headers:
|
|
24
|
+
X-Api-Key: ${NEW_RELIC_USER_KEY}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
2. Add the following to `EntityPage.tsx` to display New Relic Dashboard Tab
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
// In packages/app/src/components/catalog/EntityPage.tsx
|
|
31
|
+
import {
|
|
32
|
+
isNewRelicDashboardAvailable,
|
|
33
|
+
EntityNewRelicDashboardContent,
|
|
34
|
+
EntityNewRelicDashboardCard,
|
|
35
|
+
} from '@backstage-community/plugin-newrelic-dashboard';
|
|
36
|
+
|
|
37
|
+
const serviceEntityPage = (
|
|
38
|
+
<EntityLayout>
|
|
39
|
+
{/* other tabs... */}
|
|
40
|
+
<EntityLayout.Route
|
|
41
|
+
if={isNewRelicDashboardAvailable}
|
|
42
|
+
path="/newrelic-dashboard"
|
|
43
|
+
title="New Relic Dashboard"
|
|
44
|
+
>
|
|
45
|
+
<EntityNewRelicDashboardContent />
|
|
46
|
+
</EntityLayout.Route>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
3. Add the following in `EntityPage.tsx` to display dashboard links in overview page
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
const overviewContent = (
|
|
53
|
+
{/* other tabs... */}
|
|
54
|
+
<EntitySwitch>
|
|
55
|
+
<EntitySwitch.Case if={isNewRelicDashboardAvailable}>
|
|
56
|
+
<Grid item md={6} xs={12}>
|
|
57
|
+
<EntityNewRelicDashboardCard />
|
|
58
|
+
</Grid>
|
|
59
|
+
</EntitySwitch.Case>
|
|
60
|
+
</EntitySwitch>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
4. Add `newrelic.com/dashboard-guid` annotation in catalog descriptor file
|
|
64
|
+
|
|
65
|
+
To Obtain the dashboard's GUID: Click the info icon by the dashboard's name to access the See metadata and manage tags modal and see the dashboard's GUID.
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
// catalog-info.yaml
|
|
69
|
+
apiVersion: backstage.io/v1alpha1
|
|
70
|
+
kind: Component
|
|
71
|
+
metadata:
|
|
72
|
+
# ...
|
|
73
|
+
annotations:
|
|
74
|
+
newrelic.com/dashboard-guid: <dashboard_guid>
|
|
75
|
+
spec:
|
|
76
|
+
type: service
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
All set , you will be able to see the plugin in action!
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import * as react from 'react';
|
|
3
|
+
import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
|
|
4
|
+
import { Entity } from '@backstage/catalog-model';
|
|
5
|
+
|
|
6
|
+
/** @public */
|
|
7
|
+
declare const newRelicDashboardPlugin: _backstage_core_plugin_api.BackstagePlugin<{
|
|
8
|
+
root: _backstage_core_plugin_api.RouteRef<undefined>;
|
|
9
|
+
}, {}, {}>;
|
|
10
|
+
/** @public */
|
|
11
|
+
declare const EntityNewRelicDashboardContent: () => react.JSX.Element;
|
|
12
|
+
/** @public */
|
|
13
|
+
declare const EntityNewRelicDashboardCard: () => react.JSX.Element;
|
|
14
|
+
/**
|
|
15
|
+
* Render dashboard snapshots from Newrelic in backstage. Use dashboards which have the tag `isDashboardPage: true`
|
|
16
|
+
*
|
|
17
|
+
* @remarks
|
|
18
|
+
* This can be helpful for rendering dashboards outside of Entity Catalog.
|
|
19
|
+
*
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
declare const DashboardSnapshot: (props: {
|
|
23
|
+
guid: string;
|
|
24
|
+
name: string;
|
|
25
|
+
permalink: string;
|
|
26
|
+
}) => react.JSX.Element;
|
|
27
|
+
/**
|
|
28
|
+
* Render dashboard snapshots from Newrelic in backstage. Use dashboards which have the tag `isDashboardPage: true`
|
|
29
|
+
*
|
|
30
|
+
* @deprecated
|
|
31
|
+
* Use DashboardSnapshot export name instead
|
|
32
|
+
*
|
|
33
|
+
* @public
|
|
34
|
+
*/
|
|
35
|
+
declare const DashboardSnapshotComponent: (props: {
|
|
36
|
+
guid: string;
|
|
37
|
+
name: string;
|
|
38
|
+
permalink: string;
|
|
39
|
+
}) => react.JSX.Element;
|
|
40
|
+
/**
|
|
41
|
+
* Render a dashboard snapshots list from Newrelic in backstage. Use dashboards which have the tag `isDashboardPage: true`
|
|
42
|
+
*
|
|
43
|
+
* @remarks
|
|
44
|
+
* This can be helpful for rendering dashboards outside of Entity Catalog.
|
|
45
|
+
*
|
|
46
|
+
* @public
|
|
47
|
+
*/
|
|
48
|
+
declare const DashboardSnapshotList: (props: {
|
|
49
|
+
guid: string;
|
|
50
|
+
}) => react.JSX.Element;
|
|
51
|
+
|
|
52
|
+
/** @public */
|
|
53
|
+
declare const isNewRelicDashboardAvailable: (entity: Entity) => boolean;
|
|
54
|
+
|
|
55
|
+
export { DashboardSnapshot, DashboardSnapshotComponent, DashboardSnapshotList, EntityNewRelicDashboardCard, EntityNewRelicDashboardContent, isNewRelicDashboardAvailable, newRelicDashboardPlugin };
|
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
import { createApiRef, createRouteRef, createPlugin, createApiFactory, configApiRef, discoveryApiRef, fetchApiRef, createComponentExtension, useApi, storageApiRef } from '@backstage/core-plugin-api';
|
|
2
|
+
import { ResponseError } from '@backstage/errors';
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
|
+
import Button from '@material-ui/core/Button';
|
|
5
|
+
import Grid from '@material-ui/core/Grid';
|
|
6
|
+
import { Progress, ErrorPanel, InfoCard, Link, Page, Content } from '@backstage/core-components';
|
|
7
|
+
import Box from '@material-ui/core/Box';
|
|
8
|
+
import makeStyles from '@material-ui/core/styles/makeStyles';
|
|
9
|
+
import Typography from '@material-ui/core/Typography';
|
|
10
|
+
import useAsync from 'react-use/esm/useAsync';
|
|
11
|
+
import DesktopMac from '@material-ui/icons/DesktopMac';
|
|
12
|
+
import { useEntity, MissingAnnotationEmptyState } from '@backstage/plugin-catalog-react';
|
|
13
|
+
import MenuItem from '@material-ui/core/MenuItem';
|
|
14
|
+
import Select from '@material-ui/core/Select';
|
|
15
|
+
import useObservable from 'react-use/esm/useObservable';
|
|
16
|
+
import Tab from '@material-ui/core/Tab';
|
|
17
|
+
import Tabs from '@material-ui/core/Tabs';
|
|
18
|
+
|
|
19
|
+
const newRelicDashboardApiRef = createApiRef({
|
|
20
|
+
id: "plugin.newrelicdashboard.service"
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const getDashboardParentGuidQuery = "query ($query: String) {\n actor {\n entitySearch(query: $query) {\n results {\n entities {\n name\n ... on DashboardEntityOutline {\n name\n dashboardParentGuid\n guid\n }\n permalink\n }\n }\n }\n }\n}\n";
|
|
24
|
+
|
|
25
|
+
const getDashboardSnapshotQuery = "mutation($guid: EntityGuid! , ,$duration: Milliseconds) {\n dashboardCreateSnapshotUrl(guid: $guid , params: {timeWindow: {duration: $duration}})\n}";
|
|
26
|
+
|
|
27
|
+
var __defProp = Object.defineProperty;
|
|
28
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
29
|
+
var __publicField = (obj, key, value) => {
|
|
30
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
31
|
+
return value;
|
|
32
|
+
};
|
|
33
|
+
class NewRelicDashboardClient {
|
|
34
|
+
constructor({
|
|
35
|
+
discoveryApi,
|
|
36
|
+
fetchApi
|
|
37
|
+
}) {
|
|
38
|
+
__publicField(this, "discoveryApi");
|
|
39
|
+
__publicField(this, "fetchApi");
|
|
40
|
+
this.discoveryApi = discoveryApi;
|
|
41
|
+
this.fetchApi = fetchApi;
|
|
42
|
+
}
|
|
43
|
+
async callApi(query, variables) {
|
|
44
|
+
const myHeaders = new Headers();
|
|
45
|
+
myHeaders.append("Content-Type", "application/json");
|
|
46
|
+
const graphql = JSON.stringify({
|
|
47
|
+
query,
|
|
48
|
+
variables
|
|
49
|
+
});
|
|
50
|
+
const requestOptions = {
|
|
51
|
+
method: "POST",
|
|
52
|
+
headers: myHeaders,
|
|
53
|
+
body: graphql,
|
|
54
|
+
redirect: "follow"
|
|
55
|
+
};
|
|
56
|
+
const apiUrl = `${await this.discoveryApi.getBaseUrl(
|
|
57
|
+
"proxy"
|
|
58
|
+
)}/newrelic/api/graphql`;
|
|
59
|
+
const response = await this.fetchApi.fetch(apiUrl, requestOptions);
|
|
60
|
+
if (response.status === 200) {
|
|
61
|
+
return await response.json();
|
|
62
|
+
}
|
|
63
|
+
if (!response.ok) {
|
|
64
|
+
throw await ResponseError.fromResponse(response);
|
|
65
|
+
} else {
|
|
66
|
+
return void 0;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async getDashboardEntity(guid) {
|
|
70
|
+
var _a, _b;
|
|
71
|
+
const DashboardEntityList = await this.callApi(
|
|
72
|
+
getDashboardParentGuidQuery,
|
|
73
|
+
{
|
|
74
|
+
query: `id ='${guid}' OR parentId ='${guid}'`
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
if (DashboardEntityList && ((_b = (_a = DashboardEntityList == null ? void 0 : DashboardEntityList.data) == null ? void 0 : _a.actor.entitySearch.results.entities) == null ? void 0 : _b.length) > 1) {
|
|
78
|
+
DashboardEntityList.data.actor.entitySearch.results.entities = DashboardEntityList == null ? void 0 : DashboardEntityList.data.actor.entitySearch.results.entities.filter(
|
|
79
|
+
(entity) => (entity == null ? void 0 : entity.dashboardParentGuid) !== null
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
getDashboardEntity: DashboardEntityList
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
async getDashboardSnapshot(guid, duration) {
|
|
87
|
+
const DashboardSnapshotValue = await this.callApi(
|
|
88
|
+
getDashboardSnapshotQuery,
|
|
89
|
+
{
|
|
90
|
+
guid,
|
|
91
|
+
duration
|
|
92
|
+
}
|
|
93
|
+
);
|
|
94
|
+
return {
|
|
95
|
+
getDashboardSnapshot: DashboardSnapshotValue
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const rootRouteRef = createRouteRef({
|
|
101
|
+
id: "new-relic-dashboard"
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const newRelicDashboardPlugin = createPlugin({
|
|
105
|
+
id: "new-relic-dashboard",
|
|
106
|
+
routes: {
|
|
107
|
+
root: rootRouteRef
|
|
108
|
+
},
|
|
109
|
+
apis: [
|
|
110
|
+
createApiFactory({
|
|
111
|
+
api: newRelicDashboardApiRef,
|
|
112
|
+
deps: {
|
|
113
|
+
configApi: configApiRef,
|
|
114
|
+
discoveryApi: discoveryApiRef,
|
|
115
|
+
fetchApi: fetchApiRef
|
|
116
|
+
},
|
|
117
|
+
factory: ({ configApi, discoveryApi, fetchApi }) => new NewRelicDashboardClient({
|
|
118
|
+
discoveryApi,
|
|
119
|
+
fetchApi,
|
|
120
|
+
baseUrl: configApi.getOptionalString("newrelicdashboard.baseUrl")
|
|
121
|
+
})
|
|
122
|
+
})
|
|
123
|
+
]
|
|
124
|
+
});
|
|
125
|
+
const EntityNewRelicDashboardContent = newRelicDashboardPlugin.provide(
|
|
126
|
+
createComponentExtension({
|
|
127
|
+
name: "EntityNewRelicDashboardContent",
|
|
128
|
+
component: {
|
|
129
|
+
lazy: () => Promise.resolve().then(function () { return Router$1; }).then((m) => m.Router)
|
|
130
|
+
}
|
|
131
|
+
})
|
|
132
|
+
);
|
|
133
|
+
const EntityNewRelicDashboardCard = newRelicDashboardPlugin.provide(
|
|
134
|
+
createComponentExtension({
|
|
135
|
+
name: "EntityNewRelicDashboardCard",
|
|
136
|
+
component: {
|
|
137
|
+
lazy: () => Promise.resolve().then(function () { return DashboardEntityList$1; }).then(
|
|
138
|
+
(m) => m.DashboardEntityList
|
|
139
|
+
)
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
);
|
|
143
|
+
const DashboardSnapshot$2 = newRelicDashboardPlugin.provide(
|
|
144
|
+
createComponentExtension({
|
|
145
|
+
name: "DashboardSnapshot",
|
|
146
|
+
component: {
|
|
147
|
+
lazy: () => Promise.resolve().then(function () { return DashboardSnapshot$1; }).then((m) => m.DashboardSnapshot)
|
|
148
|
+
}
|
|
149
|
+
})
|
|
150
|
+
);
|
|
151
|
+
const DashboardSnapshotComponent = DashboardSnapshot$2;
|
|
152
|
+
const DashboardSnapshotList$2 = newRelicDashboardPlugin.provide(
|
|
153
|
+
createComponentExtension({
|
|
154
|
+
name: "DashboardSnapshotList",
|
|
155
|
+
component: {
|
|
156
|
+
lazy: () => Promise.resolve().then(function () { return DashboardSnapshotList$1; }).then((m) => m.DashboardSnapshotList)
|
|
157
|
+
}
|
|
158
|
+
})
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
const NEWRELIC_GUID_ANNOTATION = "newrelic.com/dashboard-guid";
|
|
162
|
+
|
|
163
|
+
const useStyles$2 = makeStyles({
|
|
164
|
+
svgIcon: {
|
|
165
|
+
display: "inline-block",
|
|
166
|
+
"& svg": {
|
|
167
|
+
display: "inline-block",
|
|
168
|
+
fontSize: "inherit",
|
|
169
|
+
verticalAlign: "baseline"
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
const DashboardEntityList = () => {
|
|
174
|
+
var _a, _b, _c, _d, _e, _f;
|
|
175
|
+
const { entity } = useEntity();
|
|
176
|
+
const classes = useStyles$2();
|
|
177
|
+
const newRelicDashboardAPI = useApi(newRelicDashboardApiRef);
|
|
178
|
+
const { value, loading, error } = useAsync(async () => {
|
|
179
|
+
var _a2;
|
|
180
|
+
const dashboardObject = newRelicDashboardAPI.getDashboardEntity(
|
|
181
|
+
String((_a2 = entity.metadata.annotations) == null ? void 0 : _a2[NEWRELIC_GUID_ANNOTATION])
|
|
182
|
+
);
|
|
183
|
+
return dashboardObject;
|
|
184
|
+
}, [(_a = entity.metadata.annotations) == null ? void 0 : _a[NEWRELIC_GUID_ANNOTATION]]);
|
|
185
|
+
if (loading) {
|
|
186
|
+
return /* @__PURE__ */ React.createElement(Progress, null);
|
|
187
|
+
}
|
|
188
|
+
if (error) {
|
|
189
|
+
return /* @__PURE__ */ React.createElement(ErrorPanel, { title: error.name, defaultExpanded: true, error });
|
|
190
|
+
}
|
|
191
|
+
return /* @__PURE__ */ React.createElement(InfoCard, { title: "New Relic Dashboard Pages", variant: "gridItem" }, (value == null ? void 0 : value.getDashboardEntity) === void 0 && "Unauthorized Request , please check API Key", (value == null ? void 0 : value.getDashboardEntity) !== void 0 && ((_d = (_c = (_b = value == null ? void 0 : value.getDashboardEntity) == null ? void 0 : _b.data.actor.entitySearch.results) == null ? void 0 : _c.entities) == null ? void 0 : _d.length) <= 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, "No Dashboard Pages found with the specified Dashboard GUID"), (_f = (_e = value == null ? void 0 : value.getDashboardEntity) == null ? void 0 : _e.data.actor.entitySearch.results.entities) == null ? void 0 : _f.map(
|
|
192
|
+
(entityResult, index) => {
|
|
193
|
+
return /* @__PURE__ */ React.createElement(Box, { style: { margin: "10px" }, display: "flex", key: index }, /* @__PURE__ */ React.createElement(Box, { mr: 1, className: classes.svgIcon }, /* @__PURE__ */ React.createElement(Typography, { component: "div" }, /* @__PURE__ */ React.createElement(DesktopMac, null))), /* @__PURE__ */ React.createElement(Box, { flexGrow: "1" }, /* @__PURE__ */ React.createElement(Link, { to: entityResult.permalink }, entityResult.name)));
|
|
194
|
+
}
|
|
195
|
+
));
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
var DashboardEntityList$1 = /*#__PURE__*/Object.freeze({
|
|
199
|
+
__proto__: null,
|
|
200
|
+
DashboardEntityList: DashboardEntityList
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
const useStyles$1 = makeStyles(
|
|
204
|
+
(theme) => ({
|
|
205
|
+
cardSelect: {
|
|
206
|
+
margin: theme.spacing(2, 1, 0, 0)
|
|
207
|
+
},
|
|
208
|
+
img: {
|
|
209
|
+
width: "100%",
|
|
210
|
+
height: "auto",
|
|
211
|
+
border: `solid 1px ${theme.palette.common.black}`
|
|
212
|
+
}
|
|
213
|
+
}),
|
|
214
|
+
{ name: "BackstageNewRelicDashboardSnapshot" }
|
|
215
|
+
);
|
|
216
|
+
const DashboardSnapshot = (props) => {
|
|
217
|
+
var _a, _b, _c;
|
|
218
|
+
const classes = useStyles$1();
|
|
219
|
+
const { guid, name, permalink } = props;
|
|
220
|
+
const newRelicDashboardAPI = useApi(newRelicDashboardApiRef);
|
|
221
|
+
const storageApi = useApi(storageApiRef).forBucket("newrelic-dashboard");
|
|
222
|
+
const setStorageValue = (value2) => {
|
|
223
|
+
storageApi.set(guid, value2);
|
|
224
|
+
};
|
|
225
|
+
const storageSnapshot = useObservable(
|
|
226
|
+
storageApi.observe$(guid),
|
|
227
|
+
storageApi.snapshot(guid)
|
|
228
|
+
);
|
|
229
|
+
const { value, loading, error } = useAsync(async () => {
|
|
230
|
+
const dashboardObject = newRelicDashboardAPI.getDashboardSnapshot(
|
|
231
|
+
guid,
|
|
232
|
+
storageSnapshot.value || 2592e6
|
|
233
|
+
);
|
|
234
|
+
return dashboardObject;
|
|
235
|
+
}, [guid, storageSnapshot.value]);
|
|
236
|
+
if (loading) {
|
|
237
|
+
return /* @__PURE__ */ React.createElement(Progress, null);
|
|
238
|
+
}
|
|
239
|
+
if (error) {
|
|
240
|
+
return /* @__PURE__ */ React.createElement(ErrorPanel, { title: error.name, defaultExpanded: true, error });
|
|
241
|
+
}
|
|
242
|
+
const url = (_c = (_b = (_a = value == null ? void 0 : value.getDashboardSnapshot) == null ? void 0 : _a.data) == null ? void 0 : _b.dashboardCreateSnapshotUrl) == null ? void 0 : _c.replace(
|
|
243
|
+
/\pdf$/i,
|
|
244
|
+
"png"
|
|
245
|
+
);
|
|
246
|
+
return /* @__PURE__ */ React.createElement(
|
|
247
|
+
InfoCard,
|
|
248
|
+
{
|
|
249
|
+
variant: "gridItem",
|
|
250
|
+
title: name,
|
|
251
|
+
action: /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(
|
|
252
|
+
Select,
|
|
253
|
+
{
|
|
254
|
+
className: classes.cardSelect,
|
|
255
|
+
defaultValue: 2592e6,
|
|
256
|
+
value: storageSnapshot.value,
|
|
257
|
+
onChange: (event) => {
|
|
258
|
+
setStorageValue(Number(event.target.value));
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
/* @__PURE__ */ React.createElement(MenuItem, { value: 36e5 }, "1 Hour"),
|
|
262
|
+
/* @__PURE__ */ React.createElement(MenuItem, { value: 432e5 }, "12 Hours"),
|
|
263
|
+
/* @__PURE__ */ React.createElement(MenuItem, { value: 864e5 }, "1 Day"),
|
|
264
|
+
/* @__PURE__ */ React.createElement(MenuItem, { value: 2592e5 }, "3 Days"),
|
|
265
|
+
/* @__PURE__ */ React.createElement(MenuItem, { value: 6048e5 }, "1 Week"),
|
|
266
|
+
/* @__PURE__ */ React.createElement(MenuItem, { value: 2592e6 }, "1 Month")
|
|
267
|
+
))
|
|
268
|
+
},
|
|
269
|
+
/* @__PURE__ */ React.createElement(Box, { display: "flex" }, /* @__PURE__ */ React.createElement(Box, { flexGrow: "1" }, /* @__PURE__ */ React.createElement(Link, { to: permalink }, url ? /* @__PURE__ */ React.createElement(
|
|
270
|
+
"img",
|
|
271
|
+
{
|
|
272
|
+
alt: `${name} Dashboard`,
|
|
273
|
+
className: classes.img,
|
|
274
|
+
src: url
|
|
275
|
+
}
|
|
276
|
+
) : "Dashboard loading... , click here to open if it did not render correctly")))
|
|
277
|
+
);
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
var DashboardSnapshot$1 = /*#__PURE__*/Object.freeze({
|
|
281
|
+
__proto__: null,
|
|
282
|
+
DashboardSnapshot: DashboardSnapshot
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
const tabPanelStyles = makeStyles(
|
|
286
|
+
(theme) => ({
|
|
287
|
+
tabPanel: {
|
|
288
|
+
marginTop: theme.spacing(0.5)
|
|
289
|
+
}
|
|
290
|
+
}),
|
|
291
|
+
{ name: "BackstageNewRelicDashboardTabPanel" }
|
|
292
|
+
);
|
|
293
|
+
function TabPanel(props) {
|
|
294
|
+
const { children, value1, index, ...other } = props;
|
|
295
|
+
const classes = tabPanelStyles(tabPanelStyles);
|
|
296
|
+
return /* @__PURE__ */ React.createElement(
|
|
297
|
+
"div",
|
|
298
|
+
{
|
|
299
|
+
className: classes.tabPanel,
|
|
300
|
+
role: "tabpanel",
|
|
301
|
+
hidden: value1 !== index,
|
|
302
|
+
id: `simple-tabpanel-${index}`,
|
|
303
|
+
"aria-labelledby": `simple-tab-${index}`,
|
|
304
|
+
...other
|
|
305
|
+
},
|
|
306
|
+
children
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
function a11yProps(index) {
|
|
310
|
+
return {
|
|
311
|
+
id: `simple-tab-${index}`,
|
|
312
|
+
"aria-controls": `simple-tabpanel-${index}`
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
const useStyles = makeStyles(
|
|
316
|
+
(theme) => ({
|
|
317
|
+
tabsWrapper: {
|
|
318
|
+
gridArea: "pageSubheader",
|
|
319
|
+
backgroundColor: theme.palette.background.paper,
|
|
320
|
+
paddingLeft: theme.spacing(3)
|
|
321
|
+
},
|
|
322
|
+
defaultTab: {
|
|
323
|
+
padding: theme.spacing(3, 3),
|
|
324
|
+
...theme.typography.caption,
|
|
325
|
+
textTransform: "uppercase",
|
|
326
|
+
fontWeight: "bold",
|
|
327
|
+
color: theme.palette.text.secondary
|
|
328
|
+
},
|
|
329
|
+
selected: {
|
|
330
|
+
color: theme.palette.text.primary
|
|
331
|
+
},
|
|
332
|
+
tabRoot: {
|
|
333
|
+
"&:hover": {
|
|
334
|
+
backgroundColor: theme.palette.background.default,
|
|
335
|
+
color: theme.palette.text.primary
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}),
|
|
339
|
+
{ name: "DashboardHeaderTabs" }
|
|
340
|
+
);
|
|
341
|
+
const DashboardSnapshotList = (props) => {
|
|
342
|
+
var _a, _b, _c, _d, _e, _f;
|
|
343
|
+
const { guid } = props;
|
|
344
|
+
const styles = useStyles();
|
|
345
|
+
const newRelicDashboardAPI = useApi(newRelicDashboardApiRef);
|
|
346
|
+
const { value, loading, error } = useAsync(async () => {
|
|
347
|
+
const dashboardObject = newRelicDashboardAPI.getDashboardEntity(guid);
|
|
348
|
+
return dashboardObject;
|
|
349
|
+
}, [guid]);
|
|
350
|
+
const [value1, setValue1] = useState(0);
|
|
351
|
+
const handleChange = ({}, newValue) => {
|
|
352
|
+
setValue1(newValue);
|
|
353
|
+
};
|
|
354
|
+
if (loading) {
|
|
355
|
+
return /* @__PURE__ */ React.createElement(Progress, null);
|
|
356
|
+
}
|
|
357
|
+
if (error) {
|
|
358
|
+
return /* @__PURE__ */ React.createElement(ErrorPanel, { title: error.name, defaultExpanded: true, error });
|
|
359
|
+
}
|
|
360
|
+
return /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(
|
|
361
|
+
Tabs,
|
|
362
|
+
{
|
|
363
|
+
selectionFollowsFocus: true,
|
|
364
|
+
indicatorColor: "primary",
|
|
365
|
+
textColor: "inherit",
|
|
366
|
+
variant: "scrollable",
|
|
367
|
+
scrollButtons: "auto",
|
|
368
|
+
"aria-label": "scrollable auto tabs example",
|
|
369
|
+
onChange: handleChange,
|
|
370
|
+
value: value1
|
|
371
|
+
},
|
|
372
|
+
(_c = (_b = (_a = value == null ? void 0 : value.getDashboardEntity) == null ? void 0 : _a.data) == null ? void 0 : _b.actor.entitySearch.results.entities) == null ? void 0 : _c.map(
|
|
373
|
+
(Entity, index) => {
|
|
374
|
+
return /* @__PURE__ */ React.createElement(
|
|
375
|
+
Tab,
|
|
376
|
+
{
|
|
377
|
+
label: Entity.name,
|
|
378
|
+
className: styles.defaultTab,
|
|
379
|
+
classes: {
|
|
380
|
+
selected: styles.selected,
|
|
381
|
+
root: styles.tabRoot
|
|
382
|
+
},
|
|
383
|
+
...a11yProps(index)
|
|
384
|
+
}
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
)
|
|
388
|
+
), (_f = (_e = (_d = value == null ? void 0 : value.getDashboardEntity) == null ? void 0 : _d.data) == null ? void 0 : _e.actor.entitySearch.results.entities) == null ? void 0 : _f.map(
|
|
389
|
+
(Entity, index) => {
|
|
390
|
+
return /* @__PURE__ */ React.createElement(TabPanel, { value1, index }, /* @__PURE__ */ React.createElement(
|
|
391
|
+
DashboardSnapshot,
|
|
392
|
+
{
|
|
393
|
+
name: Entity.name,
|
|
394
|
+
permalink: Entity.permalink,
|
|
395
|
+
guid: Entity.guid
|
|
396
|
+
}
|
|
397
|
+
));
|
|
398
|
+
}
|
|
399
|
+
));
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
var DashboardSnapshotList$1 = /*#__PURE__*/Object.freeze({
|
|
403
|
+
__proto__: null,
|
|
404
|
+
DashboardSnapshotList: DashboardSnapshotList
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
const NewRelicDashboard = () => {
|
|
408
|
+
var _a;
|
|
409
|
+
const { entity } = useEntity();
|
|
410
|
+
return /* @__PURE__ */ React.createElement(Page, { themeId: "home" }, /* @__PURE__ */ React.createElement(Content, null, /* @__PURE__ */ React.createElement(Grid, { container: true, spacing: 6, direction: "row", alignItems: "stretch" }, /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(DashboardEntityList, null)), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(
|
|
411
|
+
DashboardSnapshotList,
|
|
412
|
+
{
|
|
413
|
+
guid: String(
|
|
414
|
+
(_a = entity.metadata.annotations) == null ? void 0 : _a[NEWRELIC_GUID_ANNOTATION]
|
|
415
|
+
)
|
|
416
|
+
}
|
|
417
|
+
)))));
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
const isNewRelicDashboardAvailable = (entity) => {
|
|
421
|
+
var _a, _b;
|
|
422
|
+
return Boolean((_b = (_a = entity == null ? void 0 : entity.metadata) == null ? void 0 : _a.annotations) == null ? void 0 : _b[NEWRELIC_GUID_ANNOTATION]);
|
|
423
|
+
};
|
|
424
|
+
const Router = () => {
|
|
425
|
+
const { entity } = useEntity();
|
|
426
|
+
if (isNewRelicDashboardAvailable(entity)) {
|
|
427
|
+
return /* @__PURE__ */ React.createElement(NewRelicDashboard, null);
|
|
428
|
+
}
|
|
429
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(MissingAnnotationEmptyState, { annotation: NEWRELIC_GUID_ANNOTATION }), /* @__PURE__ */ React.createElement(
|
|
430
|
+
Button,
|
|
431
|
+
{
|
|
432
|
+
variant: "contained",
|
|
433
|
+
color: "primary",
|
|
434
|
+
href: "https://github.com/backstage/backstage/tree/master/plugins/newrelic-dashboard"
|
|
435
|
+
},
|
|
436
|
+
"Read New Relic Dashboard Plugin Docs"
|
|
437
|
+
));
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
var Router$1 = /*#__PURE__*/Object.freeze({
|
|
441
|
+
__proto__: null,
|
|
442
|
+
Router: Router,
|
|
443
|
+
isNewRelicDashboardAvailable: isNewRelicDashboardAvailable
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
export { DashboardSnapshot$2 as DashboardSnapshot, DashboardSnapshotComponent, DashboardSnapshotList$2 as DashboardSnapshotList, EntityNewRelicDashboardCard, EntityNewRelicDashboardContent, isNewRelicDashboardAvailable, newRelicDashboardPlugin };
|
|
447
|
+
//# sourceMappingURL=index.esm.js.map
|