@backstage/plugin-devtools 0.0.0-nightly-20230509022028
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 +18 -0
- package/README.md +375 -0
- package/dist/esm/index-3bbd2c6b.esm.js +25 -0
- package/dist/esm/index-3bbd2c6b.esm.js.map +1 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.esm.js +345 -0
- package/dist/index.esm.js.map +1 -0
- package/package.json +65 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# @backstage/plugin-devtools
|
|
2
|
+
|
|
3
|
+
## 0.0.0-nightly-20230509022028
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 347aeca204c: Introduced the DevTools plugin, checkout the plugin's [`README.md`](https://github.com/backstage/backstage/tree/master/plugins/devtools) for more details!
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
- @backstage/plugin-devtools-common@0.0.0-nightly-20230509022028
|
|
13
|
+
- @backstage/core-components@0.0.0-nightly-20230509022028
|
|
14
|
+
- @backstage/core-plugin-api@1.5.1
|
|
15
|
+
- @backstage/plugin-permission-react@0.4.12
|
|
16
|
+
- @backstage/errors@1.1.5
|
|
17
|
+
- @backstage/theme@0.2.19
|
|
18
|
+
- @backstage/types@1.0.2
|
package/README.md
ADDED
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
# DevTools
|
|
2
|
+
|
|
3
|
+
Welcome to the DevTools plugin! This plugin helps elevate useful information about a Backstage instance through the frontend, which can be helpful for an integrator for troubleshooting, reviewing, and understanding their installation.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
The DevTools plugin comes with two tabs out of the box.
|
|
8
|
+
|
|
9
|
+
### Info
|
|
10
|
+
|
|
11
|
+
Lists helpful information about your current running Backstage instance such as: OS, NodeJS version, Backstage version, and package versions.
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
### Config
|
|
16
|
+
|
|
17
|
+
Lists the configuration being used by your current running Backstage instance.
|
|
18
|
+
|
|
19
|
+

|
|
20
|
+
|
|
21
|
+
## Optional Features
|
|
22
|
+
|
|
23
|
+
The DevTools plugin can be setup with other tabs with additional helpful features.
|
|
24
|
+
|
|
25
|
+
### External Dependencies
|
|
26
|
+
|
|
27
|
+
Lists the status of configured External Dependencies based on your current running Backstage instance's ability to reach them.
|
|
28
|
+
|
|
29
|
+

|
|
30
|
+
|
|
31
|
+
## Setup
|
|
32
|
+
|
|
33
|
+
The following sections will help you get the DevTools plugin setup and running.
|
|
34
|
+
|
|
35
|
+
### Backend
|
|
36
|
+
|
|
37
|
+
You need to setup the [DevTools backend plugin](../devtools-backend/README.md) before you move forward with any of the following steps if you haven't already.
|
|
38
|
+
|
|
39
|
+
### Frontend
|
|
40
|
+
|
|
41
|
+
To setup the DevTools frontend you'll need to do the following steps:
|
|
42
|
+
|
|
43
|
+
1. First we need to add the `@backstage/plugin-devtools` package to your frontend app:
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
# From your Backstage root directory
|
|
47
|
+
yarn add --cwd packages/app @backstage/plugin-devtools
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
2. Now open the `packages/app/src/App.tsx` file
|
|
51
|
+
3. Then after all the import statements add the following line:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { DevToolsPage } from '@backstage/plugin-devtools';
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
4. In this same file just before the closing `</ FlatRoutes>`, this will be near the bottom of the file, add this line:
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
<Route path="/devtools" element={<DevToolsPage />} />
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
5. Next open the `packages/app/src/components/Root/Root.tsx` file
|
|
64
|
+
6. We want to add this icon import after all the existing import statements:
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
import BuildIcon from '@material-ui/icons/Build';
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
7. Then add this line just after the `<SidebarSettings />` line:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
<SidebarItem icon={BuildIcon} to="devtools" text="DevTools" />
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
8. Now run `yarn dev` from the root of your project and you should see the DevTools option show up just below Settings in your sidebar and clicking on it will get you to the [Info tab](#info)
|
|
77
|
+
|
|
78
|
+
## Customizing
|
|
79
|
+
|
|
80
|
+
The DevTools plugin has been designed so that you can customize the tabs to suite your needs. You may only want some or none of the out of the box tabs or you may want to add your own. The following sections explains how to do that (assuming you've already done the [setup steps](#setup)). As part of this example we'll also be showing how you can add the optional [External Dependencies](#external-dependencies) tab.
|
|
81
|
+
|
|
82
|
+
1. In the `packages/app/src/components` folder create a new sub-folder called `devtools`
|
|
83
|
+
2. Then in this new `devtools` folder add a file called `CustomDevToolsPage.tsx`
|
|
84
|
+
3. In the `CustomDevToolsPage.tsx` file add the following content:
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
import {
|
|
88
|
+
ConfigContent,
|
|
89
|
+
ExternalDependenciesContent,
|
|
90
|
+
InfoContent,
|
|
91
|
+
} from '@backstage/plugin-devtools';
|
|
92
|
+
import { DevToolsLayout } from '@backstage/plugin-devtools';
|
|
93
|
+
import React from 'react';
|
|
94
|
+
|
|
95
|
+
export const DevToolsPage = () => {
|
|
96
|
+
return (
|
|
97
|
+
<DevToolsLayout>
|
|
98
|
+
<DevToolsLayout.Route path="info" title="Info">
|
|
99
|
+
<InfoContent />
|
|
100
|
+
</DevToolsLayout.Route>
|
|
101
|
+
<DevToolsLayout.Route path="config" title="Config">
|
|
102
|
+
<ConfigContent />
|
|
103
|
+
</DevToolsLayout.Route>
|
|
104
|
+
<DevToolsLayout.Route
|
|
105
|
+
path="external-dependencies"
|
|
106
|
+
title="External Dependencies"
|
|
107
|
+
>
|
|
108
|
+
<ExternalDependenciesContent />
|
|
109
|
+
</DevToolsLayout.Route>
|
|
110
|
+
</DevToolsLayout>
|
|
111
|
+
);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export const customDevToolsPage = <DevToolsPage />;
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
4. Now open the `packages/app/src/App.tsx` file and add the following import after all the existing import statements:
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
import { customDevToolsPage } from './components/devtools/CustomDevToolsPage';
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
5. Then we need to adjust our route as follows
|
|
124
|
+
|
|
125
|
+
```diff
|
|
126
|
+
- <Route path="/devtools" element={<DevToolsPage />} />
|
|
127
|
+
+ <Route path="/devtools" element={<DevToolsPage />} >
|
|
128
|
+
+ {customDevToolsPage}
|
|
129
|
+
+ </Route>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
6. Now run `yarn dev` from the root of your project. When you go to the DevTools you'll now see you have a third tab for [External Dependencies](#external-dependencies)
|
|
133
|
+
|
|
134
|
+
With this setup you can add or remove the tabs as you'd like or add your own simply by editing your `CustomDevToolsPage.tsx` file
|
|
135
|
+
|
|
136
|
+
## Permissions
|
|
137
|
+
|
|
138
|
+
The DevTools plugin supports the [permissions framework](https://backstage.io/docs/permissions/overview), the following sections outline how you can use them with the assumption that you have the permissions framework setup and working.
|
|
139
|
+
|
|
140
|
+
**Note:** These sections are intended as guidance and are completely optional. The DevTools plugin will work with the permission framework off or on without any specific policy setup.
|
|
141
|
+
|
|
142
|
+
### Secure Sidebar Option
|
|
143
|
+
|
|
144
|
+
To use the permission framework to secure the DevTools sidebar option you'll want to do the following:
|
|
145
|
+
|
|
146
|
+
1. First we need to add the `@backstage/plugin-devtools-common` package to your frontend app:
|
|
147
|
+
|
|
148
|
+
```sh
|
|
149
|
+
# From your Backstage root directory
|
|
150
|
+
yarn add --cwd packages/app @backstage/plugin-devtools
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
2. Then open the `packages/app/src/components/Root/Root.tsx` file
|
|
154
|
+
3. The add these imports after all the existing import statements:
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
import { devToolsAdministerPermission } from '@backstage/plugin-devtools-common';
|
|
158
|
+
import { RequirePermission } from '@backstage/plugin-permission-react';
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
4. Then make the following change:
|
|
162
|
+
|
|
163
|
+
```diff
|
|
164
|
+
- <SidebarItem icon={BuildIcon} to="devtools" text="DevTools" />
|
|
165
|
+
+ <RequirePermission
|
|
166
|
+
+ permission={devToolsAdministerPermission}
|
|
167
|
+
+ errorPage={<></>}>
|
|
168
|
+
+ <SidebarItem icon={BuildIcon} to="devtools" text="DevTools" />
|
|
169
|
+
+ </RequirePermission>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Secure the DevTools Route
|
|
173
|
+
|
|
174
|
+
To use the permission framework to secure the DevTools route you'll want to do the following:
|
|
175
|
+
|
|
176
|
+
1. First we need to add the `@backstage/plugin-devtools-common` package to your frontend app (skip this step if you've already done this):
|
|
177
|
+
|
|
178
|
+
```sh
|
|
179
|
+
# From your Backstage root directory
|
|
180
|
+
yarn add --cwd packages/app @backstage/plugin-devtools-common
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
2. Then open the `packages/app/src/App.tsx` file
|
|
184
|
+
3. The add this import after all the existing import statements:
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
import { devToolsAdministerPermission } from '@backstage/plugin-devtools-common';
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
4. Then make the following change:
|
|
191
|
+
|
|
192
|
+
```diff
|
|
193
|
+
- <Route path="/devtools" element={<DevToolsPage />} />
|
|
194
|
+
+ <Route path="/devtools"
|
|
195
|
+
+ element={
|
|
196
|
+
+ <RequirePermission permission={devToolsAdministerPermission}>
|
|
197
|
+
+ <DevToolsPage />
|
|
198
|
+
+ </RequirePermission>
|
|
199
|
+
+ }
|
|
200
|
+
+ />
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Note: if you are using a `customDevToolsPage` as per the [Customizing](#customizing) documentation the changes for Step 4 will be:
|
|
204
|
+
|
|
205
|
+
```diff
|
|
206
|
+
- <Route path="/devtools" element={<DevToolsPage />} />
|
|
207
|
+
+ <Route path="/devtools"
|
|
208
|
+
+ element={
|
|
209
|
+
+ <RequirePermission permission={devToolsAdministerPermission}>
|
|
210
|
+
+ <DevToolsPage />
|
|
211
|
+
+ </RequirePermission>
|
|
212
|
+
+ }
|
|
213
|
+
+ >
|
|
214
|
+
+ {customDevToolsPage}
|
|
215
|
+
+ </Route>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Permission Policy
|
|
219
|
+
|
|
220
|
+
Here is an example permission policy that you might use to secure the DevTools plugin:
|
|
221
|
+
|
|
222
|
+
```ts
|
|
223
|
+
// packages/backend/src/plugins/permission.ts
|
|
224
|
+
|
|
225
|
+
class TestPermissionPolicy implements PermissionPolicy {
|
|
226
|
+
async handle(request: PolicyQuery): Promise<PolicyDecision> {
|
|
227
|
+
if (isPermission(request.permission, devToolsAdministerPermission)) {
|
|
228
|
+
if (
|
|
229
|
+
user?.identity.ownershipEntityRefs.includes(
|
|
230
|
+
'group:default/backstage-admins',
|
|
231
|
+
)
|
|
232
|
+
) {
|
|
233
|
+
return { result: AuthorizeResult.ALLOW };
|
|
234
|
+
}
|
|
235
|
+
return { result: AuthorizeResult.DENY };
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (isPermission(request.permission, devToolsInfoReadPermission)) {
|
|
239
|
+
if (
|
|
240
|
+
user?.identity.ownershipEntityRefs.includes(
|
|
241
|
+
'group:default/backstage-admins',
|
|
242
|
+
)
|
|
243
|
+
) {
|
|
244
|
+
return { result: AuthorizeResult.ALLOW };
|
|
245
|
+
}
|
|
246
|
+
return { result: AuthorizeResult.DENY };
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (isPermission(request.permission, devToolsConfigReadPermission)) {
|
|
250
|
+
if (
|
|
251
|
+
user?.identity.ownershipEntityRefs.includes(
|
|
252
|
+
'group:default/backstage-admins',
|
|
253
|
+
)
|
|
254
|
+
) {
|
|
255
|
+
return { result: AuthorizeResult.ALLOW };
|
|
256
|
+
}
|
|
257
|
+
return { result: AuthorizeResult.DENY };
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (
|
|
261
|
+
isPermission(
|
|
262
|
+
request.permission,
|
|
263
|
+
devToolsExternalDependenciesReadPermission,
|
|
264
|
+
)
|
|
265
|
+
) {
|
|
266
|
+
if (
|
|
267
|
+
user?.identity.ownershipEntityRefs.includes(
|
|
268
|
+
'group:default/backstage-admins',
|
|
269
|
+
)
|
|
270
|
+
) {
|
|
271
|
+
return { result: AuthorizeResult.ALLOW };
|
|
272
|
+
}
|
|
273
|
+
return { result: AuthorizeResult.DENY };
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return { result: AuthorizeResult.ALLOW };
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
To use this policy you'll need to make sure to add the `@backstage/plugin-devtools-common` package to your backend you can do that by running this command:
|
|
282
|
+
|
|
283
|
+
```sh
|
|
284
|
+
# From your Backstage root directory
|
|
285
|
+
yarn add --cwd packages/backend @backstage/plugin-devtools-common
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
You'll also need to add these imports:
|
|
289
|
+
|
|
290
|
+
```ts
|
|
291
|
+
import {
|
|
292
|
+
devToolsAdministerPermission,
|
|
293
|
+
devToolsConfigReadPermission,
|
|
294
|
+
devToolsExternalDependenciesReadPermission,
|
|
295
|
+
devToolsInfoReadPermission,
|
|
296
|
+
} from '@backstage/plugin-devtools-common';
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
**Note:** The group "group:default/backstage-admins" is simply an example and does not exist. You can point this to any group you have in your catalog instead.
|
|
300
|
+
|
|
301
|
+
### Customizing with Permissions
|
|
302
|
+
|
|
303
|
+
If you followed the [Customizing](#customizing) documentation and want to use permission there this is what your `CustomDevToolsPage.tsx` would look like:
|
|
304
|
+
|
|
305
|
+
```tsx
|
|
306
|
+
import {
|
|
307
|
+
ConfigContent,
|
|
308
|
+
ExternalDependenciesContent,
|
|
309
|
+
InfoContent,
|
|
310
|
+
} from '@backstage/plugin-devtools';
|
|
311
|
+
import { DevToolsLayout } from '@backstage/plugin-devtools';
|
|
312
|
+
import {
|
|
313
|
+
devToolsConfigReadPermission,
|
|
314
|
+
devToolsExternalDependenciesReadPermission,
|
|
315
|
+
devToolsInfoReadPermission,
|
|
316
|
+
} from '@backstage/plugin-devtools-common';
|
|
317
|
+
import { RequirePermission } from '@backstage/plugin-permission-react';
|
|
318
|
+
import React from 'react';
|
|
319
|
+
|
|
320
|
+
const DevToolsPage = () => {
|
|
321
|
+
return (
|
|
322
|
+
<DevToolsLayout>
|
|
323
|
+
<DevToolsLayout.Route path="info" title="Info">
|
|
324
|
+
<RequirePermission permission={devToolsInfoReadPermission}>
|
|
325
|
+
<InfoContent />
|
|
326
|
+
</RequirePermission>
|
|
327
|
+
</DevToolsLayout.Route>
|
|
328
|
+
<DevToolsLayout.Route path="config" title="Config">
|
|
329
|
+
<RequirePermission permission={devToolsConfigReadPermission}>
|
|
330
|
+
<ConfigContent />
|
|
331
|
+
</RequirePermission>
|
|
332
|
+
</DevToolsLayout.Route>
|
|
333
|
+
<DevToolsLayout.Route
|
|
334
|
+
path="external-dependencies"
|
|
335
|
+
title="External Dependencies"
|
|
336
|
+
>
|
|
337
|
+
<RequirePermission
|
|
338
|
+
permission={devToolsExternalDependenciesReadPermission}
|
|
339
|
+
>
|
|
340
|
+
<ExternalDependenciesContent />
|
|
341
|
+
</RequirePermission>
|
|
342
|
+
</DevToolsLayout.Route>
|
|
343
|
+
</DevToolsLayout>
|
|
344
|
+
);
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
export const customDevToolsPage = <DevToolsPage />;
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
## Configuration
|
|
351
|
+
|
|
352
|
+
The following sections outline the configuration for the DevTools plugin
|
|
353
|
+
|
|
354
|
+
### External Dependencies Configuration
|
|
355
|
+
|
|
356
|
+
If you decide to use the External Dependencies tab then you'll need to setup the configuration for it in your `app-config.yaml`, if there is no config setup then the tab will be empty. Here's an example:
|
|
357
|
+
|
|
358
|
+
```yaml
|
|
359
|
+
devTools:
|
|
360
|
+
externalDependencies:
|
|
361
|
+
endpoints:
|
|
362
|
+
- name: 'Google'
|
|
363
|
+
type: 'fetch'
|
|
364
|
+
target: 'https://google.ca'
|
|
365
|
+
- name: 'Google Public DNS'
|
|
366
|
+
type: 'ping'
|
|
367
|
+
target: '8.8.8.8'
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
Configuration details:
|
|
371
|
+
|
|
372
|
+
- `endpoints` is an array
|
|
373
|
+
- `name` is the friendly name for your endpoint
|
|
374
|
+
- `type` can be either `ping` or `fetch` and will perform the respective action on the `target`
|
|
375
|
+
- `target` is either a URL or server that you want to trigger a `type` action on
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useOutlet } from 'react-router-dom';
|
|
3
|
+
import { devToolsInfoReadPermission, devToolsConfigReadPermission } from '@backstage/plugin-devtools-common';
|
|
4
|
+
import { DevToolsLayout, InfoContent, ConfigContent } from '../index.esm.js';
|
|
5
|
+
import { RequirePermission } from '@backstage/plugin-permission-react';
|
|
6
|
+
import '@backstage/core-plugin-api';
|
|
7
|
+
import '@backstage/errors';
|
|
8
|
+
import '@backstage/core-components';
|
|
9
|
+
import '@material-ui/core';
|
|
10
|
+
import '@material-ui/lab';
|
|
11
|
+
import 'react-json-view';
|
|
12
|
+
import 'react-use/lib/useAsync';
|
|
13
|
+
import '@material-ui/icons/Description';
|
|
14
|
+
import '@material-ui/icons/DeveloperBoard';
|
|
15
|
+
import '@material-ui/icons/FileCopy';
|
|
16
|
+
|
|
17
|
+
const DefaultDevToolsPage = () => /* @__PURE__ */ React.createElement(DevToolsLayout, null, /* @__PURE__ */ React.createElement(DevToolsLayout.Route, { path: "info", title: "Info" }, /* @__PURE__ */ React.createElement(RequirePermission, { permission: devToolsInfoReadPermission }, /* @__PURE__ */ React.createElement(InfoContent, null))), /* @__PURE__ */ React.createElement(DevToolsLayout.Route, { path: "config", title: "Config" }, /* @__PURE__ */ React.createElement(RequirePermission, { permission: devToolsConfigReadPermission }, /* @__PURE__ */ React.createElement(ConfigContent, null))));
|
|
18
|
+
|
|
19
|
+
const DevToolsPage = () => {
|
|
20
|
+
const outlet = useOutlet();
|
|
21
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, outlet || /* @__PURE__ */ React.createElement(DefaultDevToolsPage, null));
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export { DevToolsPage };
|
|
25
|
+
//# sourceMappingURL=index-3bbd2c6b.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-3bbd2c6b.esm.js","sources":["../../src/components/DefaultDevToolsPage/DefaultDevToolsPage.tsx","../../src/components/DevToolsPage/DevToolsPage.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n devToolsConfigReadPermission,\n devToolsInfoReadPermission,\n} from '@backstage/plugin-devtools-common';\n\nimport { ConfigContent } from '../Content/ConfigContent';\nimport { DevToolsLayout } from '../DevToolsLayout';\nimport { InfoContent } from '../Content/InfoContent';\nimport React from 'react';\nimport { RequirePermission } from '@backstage/plugin-permission-react';\n\n/** @public */\nexport const DefaultDevToolsPage = () => (\n <DevToolsLayout>\n <DevToolsLayout.Route path=\"info\" title=\"Info\">\n <RequirePermission permission={devToolsInfoReadPermission}>\n <InfoContent />\n </RequirePermission>\n </DevToolsLayout.Route>\n <DevToolsLayout.Route path=\"config\" title=\"Config\">\n <RequirePermission permission={devToolsConfigReadPermission}>\n <ConfigContent />\n </RequirePermission>\n </DevToolsLayout.Route>\n </DevToolsLayout>\n);\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport { useOutlet } from 'react-router-dom';\nimport { DefaultDevToolsPage } from '../DefaultDevToolsPage';\n\nexport const DevToolsPage = () => {\n const outlet = useOutlet();\n\n return <>{outlet || <DefaultDevToolsPage />}</>;\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AA4BO,MAAM,sBAAsB,sBACjC,KAAA,CAAA,aAAA,CAAC,cACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,eAAe,KAAf,EAAA,EAAqB,IAAK,EAAA,MAAA,EAAO,OAAM,MACtC,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,iBAAkB,EAAA,EAAA,UAAA,EAAY,8CAC5B,KAAA,CAAA,aAAA,CAAA,WAAA,EAAA,IAAY,CACf,CACF,mBACC,KAAA,CAAA,aAAA,CAAA,cAAA,CAAe,KAAf,EAAA,EAAqB,MAAK,QAAS,EAAA,KAAA,EAAM,QACxC,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,qBAAkB,UAAY,EAAA,4BAAA,EAAA,sCAC5B,aAAc,EAAA,IAAA,CACjB,CACF,CACF,CAAA;;ACpBK,MAAM,eAAe,MAAM;AAChC,EAAA,MAAM,SAAS,SAAU,EAAA,CAAA;AAEzB,EAAA,uBAAU,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,EAAA,MAAA,oBAAW,KAAA,CAAA,aAAA,CAAA,mBAAA,EAAA,IAAoB,CAAG,CAAA,CAAA;AAC9C;;;;"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
|
|
3
|
+
import { TabProps } from '@material-ui/core';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
|
|
6
|
+
/** @public */
|
|
7
|
+
declare const devToolsPlugin: _backstage_core_plugin_api.BackstagePlugin<{
|
|
8
|
+
root: _backstage_core_plugin_api.RouteRef<undefined>;
|
|
9
|
+
}, {}, {}>;
|
|
10
|
+
/** @public */
|
|
11
|
+
declare const DevToolsPage: () => JSX.Element;
|
|
12
|
+
|
|
13
|
+
/** @public */
|
|
14
|
+
declare const ConfigContent: () => JSX.Element;
|
|
15
|
+
|
|
16
|
+
/** @public */
|
|
17
|
+
declare const InfoContent: () => JSX.Element;
|
|
18
|
+
|
|
19
|
+
/** @public */
|
|
20
|
+
declare const ExternalDependenciesContent: () => JSX.Element;
|
|
21
|
+
|
|
22
|
+
/** @public */
|
|
23
|
+
type SubRoute = {
|
|
24
|
+
path: string;
|
|
25
|
+
title: string;
|
|
26
|
+
children: JSX.Element;
|
|
27
|
+
tabProps?: TabProps<React.ElementType, {
|
|
28
|
+
component?: React.ElementType;
|
|
29
|
+
}>;
|
|
30
|
+
};
|
|
31
|
+
/** @public */
|
|
32
|
+
type DevToolsLayoutProps = {
|
|
33
|
+
children?: React.ReactNode;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* DevTools is a compound component, which allows you to define a custom layout
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```jsx
|
|
40
|
+
* <DevToolsLayout>
|
|
41
|
+
* <DevToolsLayout.Route path="/example" title="Example tab">
|
|
42
|
+
* <div>This is rendered under /example/anything-here route</div>
|
|
43
|
+
* </DevToolsLayout.Route>
|
|
44
|
+
* </DevToolsLayout>
|
|
45
|
+
* ```
|
|
46
|
+
* @public
|
|
47
|
+
*/
|
|
48
|
+
declare const DevToolsLayout: {
|
|
49
|
+
({ children }: DevToolsLayoutProps): JSX.Element;
|
|
50
|
+
Route: (props: SubRoute) => null;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export { ConfigContent, DevToolsLayout, DevToolsLayoutProps, DevToolsPage, ExternalDependenciesContent, InfoContent, SubRoute, devToolsPlugin };
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import { createApiRef, createRouteRef, createPlugin, createApiFactory, discoveryApiRef, identityApiRef, createRoutableExtension, useApi, attachComponentData, useElementFilter } from '@backstage/core-plugin-api';
|
|
2
|
+
import { ResponseError } from '@backstage/errors';
|
|
3
|
+
import { Progress, WarningPanel, Table, StatusWarning, StatusError, StatusOK, Page, Header, RoutedTabs } from '@backstage/core-components';
|
|
4
|
+
import { makeStyles, createStyles, useTheme, Box, Paper, Typography, SvgIcon, List, ListItem, ListItemAvatar, Avatar, ListItemText, Divider, Grid } from '@material-ui/core';
|
|
5
|
+
import { Alert } from '@material-ui/lab';
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import ReactJson from 'react-json-view';
|
|
8
|
+
import useAsync from 'react-use/lib/useAsync';
|
|
9
|
+
import DescriptionIcon from '@material-ui/icons/Description';
|
|
10
|
+
import DeveloperBoardIcon from '@material-ui/icons/DeveloperBoard';
|
|
11
|
+
import FileCopyIcon from '@material-ui/icons/FileCopy';
|
|
12
|
+
|
|
13
|
+
const devToolsApiRef = createApiRef({
|
|
14
|
+
id: "plugin.devtools.service"
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
class DevToolsClient {
|
|
18
|
+
constructor(options) {
|
|
19
|
+
this.discoveryApi = options.discoveryApi;
|
|
20
|
+
this.identityApi = options.identityApi;
|
|
21
|
+
}
|
|
22
|
+
async getConfig() {
|
|
23
|
+
const urlSegment = "config";
|
|
24
|
+
const configInfo = await this.get(urlSegment);
|
|
25
|
+
return configInfo;
|
|
26
|
+
}
|
|
27
|
+
async getExternalDependencies() {
|
|
28
|
+
const urlSegment = "external-dependencies";
|
|
29
|
+
const externalDependencies = await this.get(urlSegment);
|
|
30
|
+
return externalDependencies;
|
|
31
|
+
}
|
|
32
|
+
async getInfo() {
|
|
33
|
+
const urlSegment = "info";
|
|
34
|
+
const info = await this.get(urlSegment);
|
|
35
|
+
return info;
|
|
36
|
+
}
|
|
37
|
+
async get(path) {
|
|
38
|
+
const baseUrl = `${await this.discoveryApi.getBaseUrl("devtools")}/`;
|
|
39
|
+
const url = new URL(path, baseUrl);
|
|
40
|
+
const { token } = await this.identityApi.getCredentials();
|
|
41
|
+
const response = await fetch(url.toString(), {
|
|
42
|
+
headers: token ? { Authorization: `Bearer ${token}` } : {}
|
|
43
|
+
});
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
throw await ResponseError.fromResponse(response);
|
|
46
|
+
}
|
|
47
|
+
return response.json();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const rootRouteRef = createRouteRef({
|
|
52
|
+
id: "devtools"
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const devToolsPlugin = createPlugin({
|
|
56
|
+
id: "devtools",
|
|
57
|
+
apis: [
|
|
58
|
+
createApiFactory({
|
|
59
|
+
api: devToolsApiRef,
|
|
60
|
+
deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef },
|
|
61
|
+
factory: ({ discoveryApi, identityApi }) => new DevToolsClient({ discoveryApi, identityApi })
|
|
62
|
+
})
|
|
63
|
+
],
|
|
64
|
+
routes: {
|
|
65
|
+
root: rootRouteRef
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
const DevToolsPage = devToolsPlugin.provide(
|
|
69
|
+
createRoutableExtension({
|
|
70
|
+
name: "DevToolsPage",
|
|
71
|
+
component: () => import('./esm/index-3bbd2c6b.esm.js').then((m) => m.DevToolsPage),
|
|
72
|
+
mountPoint: rootRouteRef
|
|
73
|
+
})
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
function useConfig() {
|
|
77
|
+
const api = useApi(devToolsApiRef);
|
|
78
|
+
const { value, loading, error } = useAsync(() => {
|
|
79
|
+
return api.getConfig();
|
|
80
|
+
}, [api]);
|
|
81
|
+
return {
|
|
82
|
+
configInfo: value,
|
|
83
|
+
loading,
|
|
84
|
+
error
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function useExternalDependencies() {
|
|
89
|
+
const api = useApi(devToolsApiRef);
|
|
90
|
+
const { value, loading, error } = useAsync(() => {
|
|
91
|
+
return api.getExternalDependencies();
|
|
92
|
+
}, [api]);
|
|
93
|
+
return {
|
|
94
|
+
externalDependencies: value,
|
|
95
|
+
loading,
|
|
96
|
+
error
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function useInfo() {
|
|
101
|
+
const api = useApi(devToolsApiRef);
|
|
102
|
+
const { value, loading, error } = useAsync(() => {
|
|
103
|
+
return api.getInfo();
|
|
104
|
+
}, [api]);
|
|
105
|
+
return {
|
|
106
|
+
about: value,
|
|
107
|
+
loading,
|
|
108
|
+
error
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const useStyles$2 = makeStyles(
|
|
113
|
+
(theme) => createStyles({
|
|
114
|
+
warningStyle: {
|
|
115
|
+
paddingBottom: theme.spacing(2)
|
|
116
|
+
},
|
|
117
|
+
paperStyle: {
|
|
118
|
+
padding: theme.spacing(2)
|
|
119
|
+
}
|
|
120
|
+
})
|
|
121
|
+
);
|
|
122
|
+
const WarningContent = ({ error }) => {
|
|
123
|
+
if (!error.messages) {
|
|
124
|
+
return /* @__PURE__ */ React.createElement(Typography, null, error.message);
|
|
125
|
+
}
|
|
126
|
+
const messages = error.messages;
|
|
127
|
+
return /* @__PURE__ */ React.createElement(Box, null, messages.map((message) => /* @__PURE__ */ React.createElement(Typography, null, message)));
|
|
128
|
+
};
|
|
129
|
+
const ConfigContent = () => {
|
|
130
|
+
const classes = useStyles$2();
|
|
131
|
+
const theme = useTheme();
|
|
132
|
+
const { configInfo, loading, error } = useConfig();
|
|
133
|
+
if (loading) {
|
|
134
|
+
return /* @__PURE__ */ React.createElement(Progress, null);
|
|
135
|
+
} else if (error) {
|
|
136
|
+
return /* @__PURE__ */ React.createElement(Alert, { severity: "error" }, error.message);
|
|
137
|
+
}
|
|
138
|
+
if (!configInfo) {
|
|
139
|
+
return /* @__PURE__ */ React.createElement(Alert, { severity: "error" }, "Unable to load config data");
|
|
140
|
+
}
|
|
141
|
+
return /* @__PURE__ */ React.createElement(Box, null, configInfo && configInfo.error && /* @__PURE__ */ React.createElement(Box, { className: classes.warningStyle }, /* @__PURE__ */ React.createElement(WarningPanel, { title: "Config validation failed" }, /* @__PURE__ */ React.createElement(WarningContent, { error: configInfo.error }))), /* @__PURE__ */ React.createElement(Paper, { className: classes.paperStyle }, /* @__PURE__ */ React.createElement(
|
|
142
|
+
ReactJson,
|
|
143
|
+
{
|
|
144
|
+
src: configInfo.config,
|
|
145
|
+
name: "config",
|
|
146
|
+
enableClipboard: false,
|
|
147
|
+
theme: theme.palette.type === "dark" ? "monokai" : "rjv-default"
|
|
148
|
+
}
|
|
149
|
+
)));
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const columns$1 = [
|
|
153
|
+
{
|
|
154
|
+
title: "Name",
|
|
155
|
+
width: "auto",
|
|
156
|
+
field: "name",
|
|
157
|
+
defaultSort: "asc"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
title: "Versions",
|
|
161
|
+
width: "auto",
|
|
162
|
+
field: "versions"
|
|
163
|
+
}
|
|
164
|
+
];
|
|
165
|
+
const InfoDependenciesTable = ({
|
|
166
|
+
infoDependencies
|
|
167
|
+
}) => {
|
|
168
|
+
return /* @__PURE__ */ React.createElement(
|
|
169
|
+
Table,
|
|
170
|
+
{
|
|
171
|
+
title: "Package Dependencies",
|
|
172
|
+
options: {
|
|
173
|
+
paging: true,
|
|
174
|
+
pageSize: 15,
|
|
175
|
+
pageSizeOptions: [15, 30, 100],
|
|
176
|
+
loadingType: "linear",
|
|
177
|
+
padding: "dense"
|
|
178
|
+
},
|
|
179
|
+
columns: columns$1,
|
|
180
|
+
data: infoDependencies || []
|
|
181
|
+
}
|
|
182
|
+
);
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const BackstageLogoIcon = (props) => /* @__PURE__ */ React.createElement(SvgIcon, { ...props, viewBox: "0 0 337.46 428.5" }, /* @__PURE__ */ React.createElement("path", { d: "M303 166.05a80.69 80.69 0 0013.45-10.37c.79-.77 1.55-1.53 2.3-2.3a83.12 83.12 0 007.93-9.38 63.69 63.69 0 006.32-10.77 48.58 48.58 0 004.35-16.4c1.49-19.39-10-38.67-35.62-54.22L198.56 0 78.3 115.23 0 190.25l108.6 65.91a111.59 111.59 0 0057.76 16.41c24.92 0 48.8-8.8 66.42-25.69 19.16-18.36 25.52-42.12 13.7-61.87a49.22 49.22 0 00-6.8-8.87 89.17 89.17 0 0019.32 2.15h.15a85.08 85.08 0 0031-5.79 80.88 80.88 0 0012.85-6.45zm-100.55 59.81c-19.32 18.51-50.4 21.23-75.7 5.9l-75.14-45.61 67.45-64.64 76.41 46.38c27.53 16.69 26.02 39.72 6.98 57.97zm8.93-82.22l-70.65-42.89L205.14 39l69.37 42.1c25.94 15.72 29.31 37 10.55 55a60.69 60.69 0 01-73.68 7.54zm29.86 190c-19.57 18.75-46.17 29.09-74.88 29.09a123.73 123.73 0 01-64.1-18.2L0 282.52v24.67l108.6 65.91a111.6 111.6 0 0057.76 16.42c24.92 0 48.8-8.81 66.42-25.69 12.88-12.34 20-27.13 19.68-41.49v-1.79a87.27 87.27 0 01-11.22 13.13zm0-39c-19.57 18.75-46.17 29.08-74.88 29.08a123.81 123.81 0 01-64.1-18.19L0 243.53v24.68l108.6 65.91a111.6 111.6 0 0057.76 16.42c24.92 0 48.8-8.81 66.42-25.69 12.88-12.34 20-27.13 19.68-41.5v-1.78a87.27 87.27 0 01-11.22 13.13zm0-39c-19.57 18.76-46.17 29.09-74.88 29.09a123.81 123.81 0 01-64.1-18.19L0 204.55v24.68l108.6 65.91a111.59 111.59 0 0057.76 16.41c24.92 0 48.8-8.8 66.42-25.68 12.88-12.35 20-27.13 19.68-41.5v-1.82a86.09 86.09 0 01-11.22 13.16zm83.7 25.74a94.15 94.15 0 01-60.2 25.86V334a81.6 81.6 0 0051.74-22.37c14-13.38 21.14-28.11 21-42.64v-2.19a94.92 94.92 0 01-12.54 14.65zm-83.7 91.21c-19.57 18.76-46.17 29.09-74.88 29.09a123.73 123.73 0 01-64.1-18.2L0 321.5v24.68l108.6 65.9a111.6 111.6 0 0057.76 16.42c24.92 0 48.8-8.8 66.42-25.69 12.88-12.34 20-27.13 19.68-41.49v-1.79a86.29 86.29 0 01-11.22 13.13zM327 162.45c-.68.69-1.35 1.38-2.05 2.06a94.37 94.37 0 01-10.64 8.65 91.35 91.35 0 01-11.6 7 94.53 94.53 0 01-26.24 8.71 97.69 97.69 0 01-14.16 1.57c.5 1.61.9 3.25 1.25 4.9a53.27 53.27 0 011.14 12V217h.05a84.41 84.41 0 0025.35-5.55 81 81 0 0026.39-16.82c.8-.77 1.5-1.56 2.26-2.34a82.08 82.08 0 007.93-9.38 63.76 63.76 0 006.32-10.74 48.55 48.55 0 004.32-16.45c.09-1.23.2-2.47.19-3.7V150q-1.08 1.54-2.25 3.09a96.73 96.73 0 01-8.26 9.36zm0 77.92c-.69.7-1.31 1.41-2 2.1a94.2 94.2 0 01-60.2 25.86V295a81.6 81.6 0 0051.74-22.37 73.51 73.51 0 0016.46-22.5 48.56 48.56 0 004.32-16.44c.09-1.24.2-2.47.19-3.71v-2.19c-.74 1.07-1.46 2.15-2.27 3.21a95.68 95.68 0 01-8.24 9.37zm0-39c-.69.7-1.31 1.41-2 2.1a93.18 93.18 0 01-10.63 8.65 91.63 91.63 0 01-11.63 7 95.47 95.47 0 01-37.94 10.18V256a81.65 81.65 0 0051.74-22.37c.8-.77 1.5-1.56 2.26-2.34a82.08 82.08 0 007.93-9.38 63.76 63.76 0 006.27-10.76 48.56 48.56 0 004.32-16.44c.09-1.24.2-2.48.19-3.71v-2.2c-.74 1.08-1.46 2.16-2.27 3.22a95.68 95.68 0 01-8.24 9.37z" }));
|
|
186
|
+
|
|
187
|
+
const useStyles$1 = makeStyles(
|
|
188
|
+
(theme) => createStyles({
|
|
189
|
+
paperStyle: {
|
|
190
|
+
marginBottom: theme.spacing(2)
|
|
191
|
+
},
|
|
192
|
+
flexContainer: {
|
|
193
|
+
display: "flex",
|
|
194
|
+
flexDirection: "row",
|
|
195
|
+
padding: 0
|
|
196
|
+
},
|
|
197
|
+
copyButton: {
|
|
198
|
+
float: "left",
|
|
199
|
+
margin: theme.spacing(2)
|
|
200
|
+
}
|
|
201
|
+
})
|
|
202
|
+
);
|
|
203
|
+
const copyToClipboard = ({ about }) => {
|
|
204
|
+
if (about) {
|
|
205
|
+
let formatted = `OS: ${about.operatingSystem}
|
|
206
|
+
node: ${about.nodeJsVersion}
|
|
207
|
+
backstage: ${about.backstageVersion}
|
|
208
|
+
Dependencies:
|
|
209
|
+
`;
|
|
210
|
+
const deps = about.dependencies;
|
|
211
|
+
for (const key in deps) {
|
|
212
|
+
if (Object.prototype.hasOwnProperty.call(deps, key)) {
|
|
213
|
+
formatted = `${formatted} ${deps[key].name}: ${deps[key].versions}
|
|
214
|
+
`;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
window.navigator.clipboard.writeText(formatted);
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
const InfoContent = () => {
|
|
221
|
+
const classes = useStyles$1();
|
|
222
|
+
const { about, loading, error } = useInfo();
|
|
223
|
+
if (loading) {
|
|
224
|
+
return /* @__PURE__ */ React.createElement(Progress, null);
|
|
225
|
+
} else if (error) {
|
|
226
|
+
return /* @__PURE__ */ React.createElement(Alert, { severity: "error" }, error.message);
|
|
227
|
+
}
|
|
228
|
+
return /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Paper, { className: classes.paperStyle }, /* @__PURE__ */ React.createElement(List, { className: classes.flexContainer }, /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(ListItemAvatar, null, /* @__PURE__ */ React.createElement(Avatar, null, /* @__PURE__ */ React.createElement(DeveloperBoardIcon, null))), /* @__PURE__ */ React.createElement(
|
|
229
|
+
ListItemText,
|
|
230
|
+
{
|
|
231
|
+
primary: "Operating System",
|
|
232
|
+
secondary: about == null ? void 0 : about.operatingSystem
|
|
233
|
+
}
|
|
234
|
+
)), /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(ListItemAvatar, null, /* @__PURE__ */ React.createElement(Avatar, null, /* @__PURE__ */ React.createElement(DescriptionIcon, null))), /* @__PURE__ */ React.createElement(
|
|
235
|
+
ListItemText,
|
|
236
|
+
{
|
|
237
|
+
primary: "NodeJS Version",
|
|
238
|
+
secondary: about == null ? void 0 : about.nodeJsVersion
|
|
239
|
+
}
|
|
240
|
+
)), /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(ListItemAvatar, null, /* @__PURE__ */ React.createElement(Avatar, null, /* @__PURE__ */ React.createElement(BackstageLogoIcon, null))), /* @__PURE__ */ React.createElement(
|
|
241
|
+
ListItemText,
|
|
242
|
+
{
|
|
243
|
+
primary: "Backstage Version",
|
|
244
|
+
secondary: about == null ? void 0 : about.backstageVersion
|
|
245
|
+
}
|
|
246
|
+
)), /* @__PURE__ */ React.createElement(Divider, { orientation: "vertical", variant: "middle", flexItem: true }), /* @__PURE__ */ React.createElement(
|
|
247
|
+
ListItem,
|
|
248
|
+
{
|
|
249
|
+
button: true,
|
|
250
|
+
onClick: () => {
|
|
251
|
+
copyToClipboard({ about });
|
|
252
|
+
},
|
|
253
|
+
className: classes.copyButton
|
|
254
|
+
},
|
|
255
|
+
/* @__PURE__ */ React.createElement(ListItemAvatar, null, /* @__PURE__ */ React.createElement(Avatar, null, /* @__PURE__ */ React.createElement(FileCopyIcon, null))),
|
|
256
|
+
/* @__PURE__ */ React.createElement(ListItemText, { primary: "Copy Info to Clipboard" })
|
|
257
|
+
))), /* @__PURE__ */ React.createElement(InfoDependenciesTable, { infoDependencies: about == null ? void 0 : about.dependencies }));
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
const useStyles = makeStyles(
|
|
261
|
+
(theme) => createStyles({
|
|
262
|
+
paperStyle: {
|
|
263
|
+
padding: theme.spacing(2)
|
|
264
|
+
}
|
|
265
|
+
})
|
|
266
|
+
);
|
|
267
|
+
const getExternalDependencyStatus = (result) => {
|
|
268
|
+
switch (result == null ? void 0 : result.status) {
|
|
269
|
+
case "Healthy":
|
|
270
|
+
return /* @__PURE__ */ React.createElement(Typography, { component: "span" }, /* @__PURE__ */ React.createElement(StatusOK, null), " ", result.status);
|
|
271
|
+
case "Unhealthy":
|
|
272
|
+
return /* @__PURE__ */ React.createElement(Typography, { component: "span" }, /* @__PURE__ */ React.createElement(StatusError, null), " ", `${result.status}`);
|
|
273
|
+
case void 0:
|
|
274
|
+
default:
|
|
275
|
+
return /* @__PURE__ */ React.createElement(Typography, { component: "span" }, /* @__PURE__ */ React.createElement(StatusWarning, null), " Unknown");
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
const columns = [
|
|
279
|
+
{
|
|
280
|
+
title: "Name",
|
|
281
|
+
width: "auto",
|
|
282
|
+
field: "name"
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
title: "Target",
|
|
286
|
+
width: "auto",
|
|
287
|
+
field: "target"
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
title: "Type",
|
|
291
|
+
width: "auto",
|
|
292
|
+
field: "type"
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
title: "Status",
|
|
296
|
+
width: "auto",
|
|
297
|
+
render: (row) => /* @__PURE__ */ React.createElement(Grid, { container: true, direction: "column" }, /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(Typography, { variant: "button" }, getExternalDependencyStatus(row))), /* @__PURE__ */ React.createElement(Grid, { item: true }, row.error && /* @__PURE__ */ React.createElement(Typography, null, row.error)))
|
|
298
|
+
}
|
|
299
|
+
];
|
|
300
|
+
const ExternalDependenciesContent = () => {
|
|
301
|
+
const classes = useStyles();
|
|
302
|
+
const { externalDependencies, loading, error } = useExternalDependencies();
|
|
303
|
+
if (loading) {
|
|
304
|
+
return /* @__PURE__ */ React.createElement(Progress, null);
|
|
305
|
+
} else if (error) {
|
|
306
|
+
return /* @__PURE__ */ React.createElement(Alert, { severity: "error" }, error.message);
|
|
307
|
+
}
|
|
308
|
+
if (!externalDependencies || externalDependencies.length === 0) {
|
|
309
|
+
return /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Paper, { className: classes.paperStyle }, /* @__PURE__ */ React.createElement(Typography, null, "No external dependencies found")));
|
|
310
|
+
}
|
|
311
|
+
return /* @__PURE__ */ React.createElement(
|
|
312
|
+
Table,
|
|
313
|
+
{
|
|
314
|
+
title: "Status",
|
|
315
|
+
options: {
|
|
316
|
+
paging: true,
|
|
317
|
+
pageSize: 20,
|
|
318
|
+
pageSizeOptions: [20, 50, 100],
|
|
319
|
+
loadingType: "linear",
|
|
320
|
+
showEmptyDataSourceMessage: !loading
|
|
321
|
+
},
|
|
322
|
+
columns,
|
|
323
|
+
data: externalDependencies || []
|
|
324
|
+
}
|
|
325
|
+
);
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
const dataKey = "plugin.devtools.devtoolsLayoutRoute";
|
|
329
|
+
const Route = () => null;
|
|
330
|
+
attachComponentData(Route, dataKey, true);
|
|
331
|
+
attachComponentData(Route, "core.gatherMountPoints", true);
|
|
332
|
+
const DevToolsLayout = ({ children }) => {
|
|
333
|
+
const routes = useElementFilter(
|
|
334
|
+
children,
|
|
335
|
+
(elements) => elements.selectByComponentData({
|
|
336
|
+
key: dataKey,
|
|
337
|
+
withStrictError: "Child of DevToolsLayout must be an DevToolsLayout.Route"
|
|
338
|
+
}).getElements().map((child) => child.props)
|
|
339
|
+
);
|
|
340
|
+
return /* @__PURE__ */ React.createElement(Page, { themeId: "home" }, /* @__PURE__ */ React.createElement(Header, { title: "Backstage DevTools" }), /* @__PURE__ */ React.createElement(RoutedTabs, { routes }));
|
|
341
|
+
};
|
|
342
|
+
DevToolsLayout.Route = Route;
|
|
343
|
+
|
|
344
|
+
export { ConfigContent, DevToolsLayout, DevToolsPage, ExternalDependenciesContent, InfoContent, devToolsPlugin };
|
|
345
|
+
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/api/DevToolsApi.ts","../src/api/DevToolsClient.ts","../src/routes.ts","../src/plugin.ts","../src/hooks/useConfig.ts","../src/hooks/useExternalDependencies.ts","../src/hooks/useInfo.ts","../src/components/Content/ConfigContent/ConfigContent.tsx","../src/components/Content/InfoContent/InfoDependenciesTable.tsx","../src/components/Content/InfoContent/BackstageLogoIcon.tsx","../src/components/Content/InfoContent/InfoContent.tsx","../src/components/Content/ExternalDependenciesContent/ExternalDependenciesContent.tsx","../src/components/DevToolsLayout/DevToolsLayout.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createApiRef } from '@backstage/core-plugin-api';\nimport {\n ConfigInfo,\n DevToolsInfo,\n ExternalDependency,\n} from '@backstage/plugin-devtools-common';\n\nexport const devToolsApiRef = createApiRef<DevToolsApi>({\n id: 'plugin.devtools.service',\n});\n\nexport interface DevToolsApi {\n getConfig(): Promise<ConfigInfo | undefined>;\n getExternalDependencies(): Promise<ExternalDependency[] | undefined>;\n getInfo(): Promise<DevToolsInfo | undefined>;\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api';\nimport {\n ConfigInfo,\n DevToolsInfo,\n ExternalDependency,\n} from '@backstage/plugin-devtools-common';\nimport { ResponseError } from '@backstage/errors';\nimport { DevToolsApi } from './DevToolsApi';\n\nexport class DevToolsClient implements DevToolsApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly identityApi: IdentityApi;\n\n public constructor(options: {\n discoveryApi: DiscoveryApi;\n identityApi: IdentityApi;\n }) {\n this.discoveryApi = options.discoveryApi;\n this.identityApi = options.identityApi;\n }\n\n public async getConfig(): Promise<ConfigInfo | undefined> {\n const urlSegment = 'config';\n\n const configInfo = await this.get<ConfigInfo | undefined>(urlSegment);\n return configInfo;\n }\n\n public async getExternalDependencies(): Promise<\n ExternalDependency[] | undefined\n > {\n const urlSegment = 'external-dependencies';\n\n const externalDependencies = await this.get<\n ExternalDependency[] | undefined\n >(urlSegment);\n return externalDependencies;\n }\n\n public async getInfo(): Promise<DevToolsInfo | undefined> {\n const urlSegment = 'info';\n\n const info = await this.get<DevToolsInfo | undefined>(urlSegment);\n return info;\n }\n\n private async get<T>(path: string): Promise<T> {\n const baseUrl = `${await this.discoveryApi.getBaseUrl('devtools')}/`;\n const url = new URL(path, baseUrl);\n\n const { token } = await this.identityApi.getCredentials();\n const response = await fetch(url.toString(), {\n headers: token ? { Authorization: `Bearer ${token}` } : {},\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json() as Promise<T>;\n }\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createRouteRef } from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'devtools',\n});\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createApiFactory,\n createPlugin,\n createRoutableExtension,\n discoveryApiRef,\n identityApiRef,\n} from '@backstage/core-plugin-api';\nimport { devToolsApiRef, DevToolsClient } from './api';\n\nimport { rootRouteRef } from './routes';\n\n/** @public */\nexport const devToolsPlugin = createPlugin({\n id: 'devtools',\n apis: [\n createApiFactory({\n api: devToolsApiRef,\n deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef },\n factory: ({ discoveryApi, identityApi }) =>\n new DevToolsClient({ discoveryApi, identityApi }),\n }),\n ],\n routes: {\n root: rootRouteRef,\n },\n});\n\n/** @public */\nexport const DevToolsPage = devToolsPlugin.provide(\n createRoutableExtension({\n name: 'DevToolsPage',\n component: () =>\n import('./components/DevToolsPage').then(m => m.DevToolsPage),\n mountPoint: rootRouteRef,\n }),\n);\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { devToolsApiRef } from '../api';\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/lib/useAsync';\nimport { ConfigInfo } from '@backstage/plugin-devtools-common';\n\nexport function useConfig(): {\n configInfo?: ConfigInfo;\n loading: boolean;\n error?: Error;\n} {\n const api = useApi(devToolsApiRef);\n const { value, loading, error } = useAsync(() => {\n return api.getConfig();\n }, [api]);\n\n return {\n configInfo: value,\n loading,\n error,\n };\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { devToolsApiRef } from '../api';\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/lib/useAsync';\nimport { ExternalDependency } from '@backstage/plugin-devtools-common';\n\nexport function useExternalDependencies(): {\n externalDependencies?: ExternalDependency[];\n loading: boolean;\n error?: Error;\n} {\n const api = useApi(devToolsApiRef);\n const { value, loading, error } = useAsync(() => {\n return api.getExternalDependencies();\n }, [api]);\n\n return {\n externalDependencies: value,\n loading,\n error,\n };\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { devToolsApiRef } from '../api';\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/lib/useAsync';\nimport { DevToolsInfo } from '@backstage/plugin-devtools-common';\n\nexport function useInfo(): {\n about?: DevToolsInfo;\n loading: boolean;\n error?: Error;\n} {\n const api = useApi(devToolsApiRef);\n const { value, loading, error } = useAsync(() => {\n return api.getInfo();\n }, [api]);\n\n return {\n about: value,\n loading,\n error,\n };\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Progress, WarningPanel } from '@backstage/core-components';\nimport {\n Box,\n createStyles,\n makeStyles,\n Paper,\n Theme,\n Typography,\n useTheme,\n} from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport React from 'react';\nimport ReactJson from 'react-json-view';\nimport { useConfig } from '../../../hooks';\nimport { ConfigError } from '@backstage/plugin-devtools-common';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n warningStyle: {\n paddingBottom: theme.spacing(2),\n },\n paperStyle: {\n padding: theme.spacing(2),\n },\n }),\n);\n\nexport const WarningContent = ({ error }: { error: ConfigError }) => {\n if (!error.messages) {\n return <Typography>{error.message}</Typography>;\n }\n\n const messages = error.messages as string[];\n\n return (\n <Box>\n {messages.map(message => (\n <Typography>{message}</Typography>\n ))}\n </Box>\n );\n};\n\n/** @public */\nexport const ConfigContent = () => {\n const classes = useStyles();\n const theme = useTheme();\n const { configInfo, loading, error } = useConfig();\n\n if (loading) {\n return <Progress />;\n } else if (error) {\n return <Alert severity=\"error\">{error.message}</Alert>;\n }\n\n if (!configInfo) {\n return <Alert severity=\"error\">Unable to load config data</Alert>;\n }\n\n return (\n <Box>\n {configInfo && configInfo.error && (\n <Box className={classes.warningStyle}>\n <WarningPanel title=\"Config validation failed\">\n <WarningContent error={configInfo.error} />\n </WarningPanel>\n </Box>\n )}\n <Paper className={classes.paperStyle}>\n <ReactJson\n src={configInfo.config as object}\n name=\"config\"\n enableClipboard={false}\n theme={theme.palette.type === 'dark' ? 'monokai' : 'rjv-default'}\n />\n </Paper>\n </Box>\n );\n};\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Table, TableColumn } from '@backstage/core-components';\nimport { PackageDependency } from '@backstage/plugin-devtools-common';\n\nimport React from 'react';\n\nconst columns: TableColumn[] = [\n {\n title: 'Name',\n width: 'auto',\n field: 'name',\n defaultSort: 'asc',\n },\n {\n title: 'Versions',\n width: 'auto',\n field: 'versions',\n },\n];\n\nexport const InfoDependenciesTable = ({\n infoDependencies,\n}: {\n infoDependencies: PackageDependency[] | undefined;\n}) => {\n return (\n <Table\n title=\"Package Dependencies\"\n options={{\n paging: true,\n pageSize: 15,\n pageSizeOptions: [15, 30, 100],\n loadingType: 'linear',\n padding: 'dense',\n }}\n columns={columns}\n data={infoDependencies || []}\n />\n );\n};\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { SvgIcon, SvgIconProps } from '@material-ui/core';\n\nimport React from 'react';\n\nexport const BackstageLogoIcon = (props: SvgIconProps) => (\n <SvgIcon {...props} viewBox=\"0 0 337.46 428.5\">\n <path d=\"M303 166.05a80.69 80.69 0 0013.45-10.37c.79-.77 1.55-1.53 2.3-2.3a83.12 83.12 0 007.93-9.38 63.69 63.69 0 006.32-10.77 48.58 48.58 0 004.35-16.4c1.49-19.39-10-38.67-35.62-54.22L198.56 0 78.3 115.23 0 190.25l108.6 65.91a111.59 111.59 0 0057.76 16.41c24.92 0 48.8-8.8 66.42-25.69 19.16-18.36 25.52-42.12 13.7-61.87a49.22 49.22 0 00-6.8-8.87 89.17 89.17 0 0019.32 2.15h.15a85.08 85.08 0 0031-5.79 80.88 80.88 0 0012.85-6.45zm-100.55 59.81c-19.32 18.51-50.4 21.23-75.7 5.9l-75.14-45.61 67.45-64.64 76.41 46.38c27.53 16.69 26.02 39.72 6.98 57.97zm8.93-82.22l-70.65-42.89L205.14 39l69.37 42.1c25.94 15.72 29.31 37 10.55 55a60.69 60.69 0 01-73.68 7.54zm29.86 190c-19.57 18.75-46.17 29.09-74.88 29.09a123.73 123.73 0 01-64.1-18.2L0 282.52v24.67l108.6 65.91a111.6 111.6 0 0057.76 16.42c24.92 0 48.8-8.81 66.42-25.69 12.88-12.34 20-27.13 19.68-41.49v-1.79a87.27 87.27 0 01-11.22 13.13zm0-39c-19.57 18.75-46.17 29.08-74.88 29.08a123.81 123.81 0 01-64.1-18.19L0 243.53v24.68l108.6 65.91a111.6 111.6 0 0057.76 16.42c24.92 0 48.8-8.81 66.42-25.69 12.88-12.34 20-27.13 19.68-41.5v-1.78a87.27 87.27 0 01-11.22 13.13zm0-39c-19.57 18.76-46.17 29.09-74.88 29.09a123.81 123.81 0 01-64.1-18.19L0 204.55v24.68l108.6 65.91a111.59 111.59 0 0057.76 16.41c24.92 0 48.8-8.8 66.42-25.68 12.88-12.35 20-27.13 19.68-41.5v-1.82a86.09 86.09 0 01-11.22 13.16zm83.7 25.74a94.15 94.15 0 01-60.2 25.86V334a81.6 81.6 0 0051.74-22.37c14-13.38 21.14-28.11 21-42.64v-2.19a94.92 94.92 0 01-12.54 14.65zm-83.7 91.21c-19.57 18.76-46.17 29.09-74.88 29.09a123.73 123.73 0 01-64.1-18.2L0 321.5v24.68l108.6 65.9a111.6 111.6 0 0057.76 16.42c24.92 0 48.8-8.8 66.42-25.69 12.88-12.34 20-27.13 19.68-41.49v-1.79a86.29 86.29 0 01-11.22 13.13zM327 162.45c-.68.69-1.35 1.38-2.05 2.06a94.37 94.37 0 01-10.64 8.65 91.35 91.35 0 01-11.6 7 94.53 94.53 0 01-26.24 8.71 97.69 97.69 0 01-14.16 1.57c.5 1.61.9 3.25 1.25 4.9a53.27 53.27 0 011.14 12V217h.05a84.41 84.41 0 0025.35-5.55 81 81 0 0026.39-16.82c.8-.77 1.5-1.56 2.26-2.34a82.08 82.08 0 007.93-9.38 63.76 63.76 0 006.32-10.74 48.55 48.55 0 004.32-16.45c.09-1.23.2-2.47.19-3.7V150q-1.08 1.54-2.25 3.09a96.73 96.73 0 01-8.26 9.36zm0 77.92c-.69.7-1.31 1.41-2 2.1a94.2 94.2 0 01-60.2 25.86V295a81.6 81.6 0 0051.74-22.37 73.51 73.51 0 0016.46-22.5 48.56 48.56 0 004.32-16.44c.09-1.24.2-2.47.19-3.71v-2.19c-.74 1.07-1.46 2.15-2.27 3.21a95.68 95.68 0 01-8.24 9.37zm0-39c-.69.7-1.31 1.41-2 2.1a93.18 93.18 0 01-10.63 8.65 91.63 91.63 0 01-11.63 7 95.47 95.47 0 01-37.94 10.18V256a81.65 81.65 0 0051.74-22.37c.8-.77 1.5-1.56 2.26-2.34a82.08 82.08 0 007.93-9.38 63.76 63.76 0 006.27-10.76 48.56 48.56 0 004.32-16.44c.09-1.24.2-2.48.19-3.71v-2.2c-.74 1.08-1.46 2.16-2.27 3.22a95.68 95.68 0 01-8.24 9.37z\" />\n </SvgIcon>\n);\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Progress } from '@backstage/core-components';\nimport {\n Avatar,\n Box,\n createStyles,\n Divider,\n List,\n ListItem,\n ListItemAvatar,\n ListItemText,\n makeStyles,\n Paper,\n Theme,\n} from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport React from 'react';\nimport { useInfo } from '../../../hooks';\nimport { InfoDependenciesTable } from './InfoDependenciesTable';\nimport DescriptionIcon from '@material-ui/icons/Description';\nimport DeveloperBoardIcon from '@material-ui/icons/DeveloperBoard';\nimport { BackstageLogoIcon } from './BackstageLogoIcon';\nimport FileCopyIcon from '@material-ui/icons/FileCopy';\nimport { DevToolsInfo } from '@backstage/plugin-devtools-common';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n paperStyle: {\n marginBottom: theme.spacing(2),\n },\n flexContainer: {\n display: 'flex',\n flexDirection: 'row',\n padding: 0,\n },\n copyButton: {\n float: 'left',\n margin: theme.spacing(2),\n },\n }),\n);\n\nconst copyToClipboard = ({ about }: { about: DevToolsInfo | undefined }) => {\n if (about) {\n let formatted = `OS: ${about.operatingSystem}\\nnode: ${about.nodeJsVersion}\\nbackstage: ${about.backstageVersion}\\nDependencies:\\n`;\n const deps = about.dependencies;\n for (const key in deps) {\n if (Object.prototype.hasOwnProperty.call(deps, key)) {\n formatted = `${formatted} ${deps[key].name}: ${deps[key].versions}\\n`;\n }\n }\n window.navigator.clipboard.writeText(formatted);\n }\n};\n\n/** @public */\nexport const InfoContent = () => {\n const classes = useStyles();\n const { about, loading, error } = useInfo();\n\n if (loading) {\n return <Progress />;\n } else if (error) {\n return <Alert severity=\"error\">{error.message}</Alert>;\n }\n return (\n <Box>\n <Paper className={classes.paperStyle}>\n <List className={classes.flexContainer}>\n <ListItem>\n <ListItemAvatar>\n <Avatar>\n <DeveloperBoardIcon />\n </Avatar>\n </ListItemAvatar>\n <ListItemText\n primary=\"Operating System\"\n secondary={about?.operatingSystem}\n />\n </ListItem>\n <ListItem>\n <ListItemAvatar>\n <Avatar>\n <DescriptionIcon />\n </Avatar>\n </ListItemAvatar>\n <ListItemText\n primary=\"NodeJS Version\"\n secondary={about?.nodeJsVersion}\n />\n </ListItem>\n <ListItem>\n <ListItemAvatar>\n <Avatar>\n <BackstageLogoIcon />\n </Avatar>\n </ListItemAvatar>\n <ListItemText\n primary=\"Backstage Version\"\n secondary={about?.backstageVersion}\n />\n </ListItem>\n <Divider orientation=\"vertical\" variant=\"middle\" flexItem />\n <ListItem\n button\n onClick={() => {\n copyToClipboard({ about });\n }}\n className={classes.copyButton}\n >\n <ListItemAvatar>\n <Avatar>\n <FileCopyIcon />\n </Avatar>\n </ListItemAvatar>\n <ListItemText primary=\"Copy Info to Clipboard\" />\n </ListItem>\n </List>\n </Paper>\n <InfoDependenciesTable infoDependencies={about?.dependencies} />\n </Box>\n );\n};\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Progress,\n StatusError,\n StatusOK,\n StatusWarning,\n Table,\n TableColumn,\n} from '@backstage/core-components';\nimport { ExternalDependency } from '@backstage/plugin-devtools-common';\nimport {\n Box,\n createStyles,\n Grid,\n makeStyles,\n Paper,\n Theme,\n Typography,\n} from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport React from 'react';\nimport { useExternalDependencies } from '../../../hooks';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n paperStyle: {\n padding: theme.spacing(2),\n },\n }),\n);\n\nexport const getExternalDependencyStatus = (\n result: Partial<ExternalDependency> | undefined,\n) => {\n switch (result?.status) {\n case 'Healthy':\n return (\n <Typography component=\"span\">\n <StatusOK /> {result.status}\n </Typography>\n );\n case 'Unhealthy':\n return (\n <Typography component=\"span\">\n <StatusError /> {`${result.status}`}\n </Typography>\n );\n case undefined:\n default:\n return (\n <Typography component=\"span\">\n <StatusWarning /> Unknown\n </Typography>\n );\n }\n};\n\nconst columns: TableColumn[] = [\n {\n title: 'Name',\n width: 'auto',\n field: 'name',\n },\n {\n title: 'Target',\n width: 'auto',\n field: 'target',\n },\n {\n title: 'Type',\n width: 'auto',\n field: 'type',\n },\n {\n title: 'Status',\n width: 'auto',\n render: (row: Partial<ExternalDependency>) => (\n <Grid container direction=\"column\">\n <Grid item>\n <Typography variant=\"button\">\n {getExternalDependencyStatus(row)}\n </Typography>\n </Grid>\n <Grid item>{row.error && <Typography>{row.error}</Typography>}</Grid>\n </Grid>\n ),\n },\n];\n\n/** @public */\nexport const ExternalDependenciesContent = () => {\n const classes = useStyles();\n const { externalDependencies, loading, error } = useExternalDependencies();\n\n if (loading) {\n return <Progress />;\n } else if (error) {\n return <Alert severity=\"error\">{error.message}</Alert>;\n }\n\n if (!externalDependencies || externalDependencies.length === 0) {\n return (\n <Box>\n <Paper className={classes.paperStyle}>\n <Typography>No external dependencies found</Typography>\n </Paper>\n </Box>\n );\n }\n\n return (\n <Table\n title=\"Status\"\n options={{\n paging: true,\n pageSize: 20,\n pageSizeOptions: [20, 50, 100],\n loadingType: 'linear',\n showEmptyDataSourceMessage: !loading,\n }}\n columns={columns}\n data={externalDependencies || []}\n />\n );\n};\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Header, Page, RoutedTabs } from '@backstage/core-components';\nimport {\n attachComponentData,\n useElementFilter,\n} from '@backstage/core-plugin-api';\nimport { TabProps } from '@material-ui/core';\nimport { default as React } from 'react';\n\n/** @public */\nexport type SubRoute = {\n path: string;\n title: string;\n children: JSX.Element;\n tabProps?: TabProps<React.ElementType, { component?: React.ElementType }>;\n};\n\nconst dataKey = 'plugin.devtools.devtoolsLayoutRoute';\n\nconst Route: (props: SubRoute) => null = () => null;\nattachComponentData(Route, dataKey, true);\n\n// This causes all mount points that are discovered within this route to use the path of the route itself\nattachComponentData(Route, 'core.gatherMountPoints', true);\n\n/** @public */\nexport type DevToolsLayoutProps = {\n children?: React.ReactNode;\n};\n\n/**\n * DevTools is a compound component, which allows you to define a custom layout\n *\n * @example\n * ```jsx\n * <DevToolsLayout>\n * <DevToolsLayout.Route path=\"/example\" title=\"Example tab\">\n * <div>This is rendered under /example/anything-here route</div>\n * </DevToolsLayout.Route>\n * </DevToolsLayout>\n * ```\n * @public\n */\nexport const DevToolsLayout = ({ children }: DevToolsLayoutProps) => {\n const routes = useElementFilter(children, elements =>\n elements\n .selectByComponentData({\n key: dataKey,\n withStrictError:\n 'Child of DevToolsLayout must be an DevToolsLayout.Route',\n })\n .getElements<SubRoute>()\n .map(child => child.props),\n );\n\n return (\n <Page themeId=\"home\">\n <Header title=\"Backstage DevTools\" />\n <RoutedTabs routes={routes} />\n </Page>\n );\n};\n\nDevToolsLayout.Route = Route;\n"],"names":["useStyles","columns"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@backstage/plugin-devtools",
|
|
3
|
+
"version": "0.0.0-nightly-20230509022028",
|
|
4
|
+
"main": "dist/index.esm.js",
|
|
5
|
+
"types": "dist/index.d.ts",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public",
|
|
9
|
+
"main": "dist/index.esm.js",
|
|
10
|
+
"types": "dist/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"backstage": {
|
|
13
|
+
"role": "frontend-plugin"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://backstage.io",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/backstage/backstage",
|
|
19
|
+
"directory": "plugins/devtools"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"start": "backstage-cli package start",
|
|
23
|
+
"build": "backstage-cli package build",
|
|
24
|
+
"lint": "backstage-cli package lint",
|
|
25
|
+
"test": "backstage-cli package test",
|
|
26
|
+
"clean": "backstage-cli package clean",
|
|
27
|
+
"prepack": "backstage-cli package prepack",
|
|
28
|
+
"postpack": "backstage-cli package postpack"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@backstage/core-components": "^0.0.0-nightly-20230509022028",
|
|
32
|
+
"@backstage/core-plugin-api": "^1.5.1",
|
|
33
|
+
"@backstage/errors": "^1.1.5",
|
|
34
|
+
"@backstage/plugin-devtools-common": "^0.0.0-nightly-20230509022028",
|
|
35
|
+
"@backstage/plugin-permission-react": "^0.4.12",
|
|
36
|
+
"@backstage/theme": "^0.2.19",
|
|
37
|
+
"@backstage/types": "^1.0.2",
|
|
38
|
+
"@material-ui/core": "^4.9.13",
|
|
39
|
+
"@material-ui/icons": "^4.9.1",
|
|
40
|
+
"@material-ui/lab": "^4.0.0-alpha.57",
|
|
41
|
+
"react-json-view": "^1.21.3",
|
|
42
|
+
"react-use": "^17.2.4"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"@types/react": "^16.13.1 || ^17.0.0",
|
|
46
|
+
"react": "^16.13.1 || ^17.0.0",
|
|
47
|
+
"react-router-dom": "6.0.0-beta.0 || ^6.3.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@backstage/cli": "^0.0.0-nightly-20230509022028",
|
|
51
|
+
"@backstage/core-app-api": "^0.0.0-nightly-20230509022028",
|
|
52
|
+
"@backstage/dev-utils": "^0.0.0-nightly-20230509022028",
|
|
53
|
+
"@backstage/test-utils": "^0.0.0-nightly-20230509022028",
|
|
54
|
+
"@testing-library/jest-dom": "^5.10.1",
|
|
55
|
+
"@testing-library/react": "^12.1.3",
|
|
56
|
+
"@testing-library/user-event": "^14.0.0",
|
|
57
|
+
"@types/node": "*",
|
|
58
|
+
"cross-fetch": "^3.1.5",
|
|
59
|
+
"msw": "^0.47.0"
|
|
60
|
+
},
|
|
61
|
+
"files": [
|
|
62
|
+
"dist"
|
|
63
|
+
],
|
|
64
|
+
"module": "./dist/index.esm.js"
|
|
65
|
+
}
|