@backstage/cli 0.33.1 → 0.34.0-next.1
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 +37 -0
- package/config/nodeTransformHooks.mjs +4 -4
- package/dist/lib/version.cjs.js +20 -14
- package/dist/packages/backend-defaults/package.json.cjs.js +1 -1
- package/dist/packages/backend-plugin-api/package.json.cjs.js +1 -1
- package/dist/packages/backend-test-utils/package.json.cjs.js +1 -1
- package/dist/packages/catalog-client/package.json.cjs.js +1 -1
- package/dist/packages/cli/package.json.cjs.js +1 -1
- package/dist/packages/core-components/package.json.cjs.js +1 -1
- package/dist/packages/dev-utils/package.json.cjs.js +1 -1
- package/dist/packages/frontend-defaults/package.json.cjs.js +6 -0
- package/dist/packages/frontend-plugin-api/package.json.cjs.js +6 -0
- package/dist/packages/frontend-test-utils/package.json.cjs.js +6 -0
- package/dist/packages/test-utils/package.json.cjs.js +1 -1
- package/dist/packages/theme/package.json.cjs.js +1 -1
- package/dist/plugins/auth-backend/package.json.cjs.js +1 -1
- package/dist/plugins/auth-backend-module-guest-provider/package.json.cjs.js +1 -1
- package/dist/plugins/catalog-node/package.json.cjs.js +1 -1
- package/dist/plugins/scaffolder-node/package.json.cjs.js +1 -1
- package/dist/plugins/scaffolder-node-test-utils/package.json.cjs.js +1 -1
- package/package.json +27 -27
- package/templates/new-frontend-plugin/.eslintrc.js.hbs +1 -0
- package/templates/new-frontend-plugin/README.md.hbs +20 -0
- package/templates/new-frontend-plugin/dev/index.tsx +10 -0
- package/templates/new-frontend-plugin/package.json.hbs +49 -0
- package/templates/new-frontend-plugin/portable-template.yaml +5 -0
- package/templates/new-frontend-plugin/src/components/ExampleComponent/ExampleComponent.test.tsx.hbs +28 -0
- package/templates/new-frontend-plugin/src/components/ExampleComponent/ExampleComponent.tsx.hbs +37 -0
- package/templates/new-frontend-plugin/src/components/ExampleComponent/index.ts +1 -0
- package/templates/new-frontend-plugin/src/components/ExampleFetchComponent/ExampleFetchComponent.test.tsx.hbs +19 -0
- package/templates/new-frontend-plugin/src/components/ExampleFetchComponent/ExampleFetchComponent.tsx.hbs +308 -0
- package/templates/new-frontend-plugin/src/components/ExampleFetchComponent/index.ts +1 -0
- package/templates/new-frontend-plugin/src/index.ts.hbs +1 -0
- package/templates/new-frontend-plugin/src/plugin.test.ts.hbs +7 -0
- package/templates/new-frontend-plugin/src/plugin.tsx.hbs +26 -0
- package/templates/new-frontend-plugin/src/routes.ts +3 -0
- package/templates/new-frontend-plugin/src/setupTests.ts +1 -0
- package/templates/new-frontend-plugin-module/.eslintrc.js.hbs +1 -0
- package/templates/new-frontend-plugin-module/README.md.hbs +5 -0
- package/templates/new-frontend-plugin-module/package.json.hbs +35 -0
- package/templates/new-frontend-plugin-module/portable-template.yaml +5 -0
- package/templates/new-frontend-plugin-module/src/index.ts.hbs +1 -0
- package/templates/new-frontend-plugin-module/src/module.tsx.hbs +8 -0
- package/templates/new-frontend-plugin-module/src/setupTests.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# @backstage/cli
|
|
2
2
|
|
|
3
|
+
## 0.34.0-next.1
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 38b4243: Added plugin and module templates for the new frontend system. These templates are not included by default, but can be included by adding `@backstage/cli/templates/new-frontend-plugin` and `@backstage/cli/templates/new-frontend-plugin-module` as [custom templates](https://backstage.io/docs/tooling/cli/templates#installing-custom-templates).
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
- @backstage/catalog-model@1.7.5
|
|
13
|
+
- @backstage/cli-common@0.1.15
|
|
14
|
+
- @backstage/cli-node@0.2.13
|
|
15
|
+
- @backstage/config@1.3.3
|
|
16
|
+
- @backstage/config-loader@1.10.2
|
|
17
|
+
- @backstage/errors@1.2.7
|
|
18
|
+
- @backstage/eslint-plugin@0.1.11
|
|
19
|
+
- @backstage/integration@1.17.1
|
|
20
|
+
- @backstage/release-manifests@0.0.13
|
|
21
|
+
- @backstage/types@1.2.1
|
|
22
|
+
|
|
23
|
+
## 0.33.2-next.0
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- a6af768: Allow js files to be processed by the nodeTransform loader
|
|
28
|
+
- Updated dependencies
|
|
29
|
+
- @backstage/cli-node@0.2.13
|
|
30
|
+
- @backstage/config-loader@1.10.2
|
|
31
|
+
- @backstage/catalog-model@1.7.5
|
|
32
|
+
- @backstage/cli-common@0.1.15
|
|
33
|
+
- @backstage/config@1.3.3
|
|
34
|
+
- @backstage/errors@1.2.7
|
|
35
|
+
- @backstage/eslint-plugin@0.1.11
|
|
36
|
+
- @backstage/integration@1.17.1
|
|
37
|
+
- @backstage/release-manifests@0.0.13
|
|
38
|
+
- @backstage/types@1.2.1
|
|
39
|
+
|
|
3
40
|
## 0.33.1
|
|
4
41
|
|
|
5
42
|
### Patch Changes
|
|
@@ -127,10 +127,10 @@ async function withDetectedModuleType(resolved) {
|
|
|
127
127
|
};
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
//
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
130
|
+
// Under normal circumstances .js files should reliably have a format and so
|
|
131
|
+
// we should only reach this point for .ts files. However, if additional
|
|
132
|
+
// custom loaders are being used the format may not be detected for .js files
|
|
133
|
+
// either. As such we don't restrict the file format at this point.
|
|
134
134
|
|
|
135
135
|
// TODO(Rugvip): Does this need caching? kept it simple for now but worth exploring
|
|
136
136
|
const packageJsonPath = await findPackageJSON(fileURLToPath(resolved.url));
|
package/dist/lib/version.cjs.js
CHANGED
|
@@ -13,13 +13,16 @@ var _package$7 = require('../packages/core-components/package.json.cjs.js');
|
|
|
13
13
|
var _package$8 = require('../packages/core-plugin-api/package.json.cjs.js');
|
|
14
14
|
var _package$9 = require('../packages/dev-utils/package.json.cjs.js');
|
|
15
15
|
var _package$a = require('../packages/errors/package.json.cjs.js');
|
|
16
|
-
var _package$b = require('../packages/
|
|
17
|
-
var _package$
|
|
18
|
-
var _package$
|
|
19
|
-
var _package$
|
|
20
|
-
var _package$g = require('../plugins/
|
|
21
|
-
var _package$h = require('../plugins/
|
|
22
|
-
var _package$
|
|
16
|
+
var _package$b = require('../packages/frontend-defaults/package.json.cjs.js');
|
|
17
|
+
var _package$c = require('../packages/frontend-plugin-api/package.json.cjs.js');
|
|
18
|
+
var _package$d = require('../packages/frontend-test-utils/package.json.cjs.js');
|
|
19
|
+
var _package$e = require('../packages/test-utils/package.json.cjs.js');
|
|
20
|
+
var _package$g = require('../plugins/scaffolder-node/package.json.cjs.js');
|
|
21
|
+
var _package$h = require('../plugins/scaffolder-node-test-utils/package.json.cjs.js');
|
|
22
|
+
var _package$i = require('../plugins/auth-backend/package.json.cjs.js');
|
|
23
|
+
var _package$j = require('../plugins/auth-backend-module-guest-provider/package.json.cjs.js');
|
|
24
|
+
var _package$k = require('../plugins/catalog-node/package.json.cjs.js');
|
|
25
|
+
var _package$f = require('../packages/theme/package.json.cjs.js');
|
|
23
26
|
var _package = require('../packages/backend-defaults/package.json.cjs.js');
|
|
24
27
|
|
|
25
28
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
@@ -39,13 +42,16 @@ const packageVersions = {
|
|
|
39
42
|
"@backstage/core-plugin-api": _package$8.version,
|
|
40
43
|
"@backstage/dev-utils": _package$9.version,
|
|
41
44
|
"@backstage/errors": _package$a.version,
|
|
42
|
-
"@backstage/
|
|
43
|
-
"@backstage/
|
|
44
|
-
"@backstage/
|
|
45
|
-
"@backstage/
|
|
46
|
-
"@backstage/
|
|
47
|
-
"@backstage/plugin-
|
|
48
|
-
"@backstage/plugin-
|
|
45
|
+
"@backstage/frontend-defaults": _package$b.version,
|
|
46
|
+
"@backstage/frontend-plugin-api": _package$c.version,
|
|
47
|
+
"@backstage/frontend-test-utils": _package$d.version,
|
|
48
|
+
"@backstage/test-utils": _package$e.version,
|
|
49
|
+
"@backstage/theme": _package$f.version,
|
|
50
|
+
"@backstage/plugin-scaffolder-node": _package$g.version,
|
|
51
|
+
"@backstage/plugin-scaffolder-node-test-utils": _package$h.version,
|
|
52
|
+
"@backstage/plugin-auth-backend": _package$i.version,
|
|
53
|
+
"@backstage/plugin-auth-backend-module-guest-provider": _package$j.version,
|
|
54
|
+
"@backstage/plugin-catalog-node": _package$k.version
|
|
49
55
|
};
|
|
50
56
|
function findVersion() {
|
|
51
57
|
const pkgContent = fs__default.default.readFileSync(paths.paths.resolveOwn("package.json"), "utf8");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.0-next.1",
|
|
4
4
|
"description": "CLI for developing Backstage plugins and apps",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "cli"
|
|
@@ -47,16 +47,16 @@
|
|
|
47
47
|
]
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@backstage/catalog-model": "
|
|
51
|
-
"@backstage/cli-common": "
|
|
52
|
-
"@backstage/cli-node": "
|
|
53
|
-
"@backstage/config": "
|
|
54
|
-
"@backstage/config-loader": "
|
|
55
|
-
"@backstage/errors": "
|
|
56
|
-
"@backstage/eslint-plugin": "
|
|
57
|
-
"@backstage/integration": "
|
|
58
|
-
"@backstage/release-manifests": "
|
|
59
|
-
"@backstage/types": "
|
|
50
|
+
"@backstage/catalog-model": "1.7.5",
|
|
51
|
+
"@backstage/cli-common": "0.1.15",
|
|
52
|
+
"@backstage/cli-node": "0.2.13",
|
|
53
|
+
"@backstage/config": "1.3.3",
|
|
54
|
+
"@backstage/config-loader": "1.10.2",
|
|
55
|
+
"@backstage/errors": "1.2.7",
|
|
56
|
+
"@backstage/eslint-plugin": "0.1.11",
|
|
57
|
+
"@backstage/integration": "1.17.1",
|
|
58
|
+
"@backstage/release-manifests": "0.0.13",
|
|
59
|
+
"@backstage/types": "1.2.1",
|
|
60
60
|
"@manypkg/get-packages": "^1.1.3",
|
|
61
61
|
"@module-federation/enhanced": "^0.9.0",
|
|
62
62
|
"@octokit/graphql": "^5.0.0",
|
|
@@ -163,22 +163,22 @@
|
|
|
163
163
|
"zod-validation-error": "^3.4.0"
|
|
164
164
|
},
|
|
165
165
|
"devDependencies": {
|
|
166
|
-
"@backstage/backend-plugin-api": "
|
|
167
|
-
"@backstage/backend-test-utils": "
|
|
168
|
-
"@backstage/catalog-client": "
|
|
169
|
-
"@backstage/config": "
|
|
170
|
-
"@backstage/core-app-api": "
|
|
171
|
-
"@backstage/core-components": "
|
|
172
|
-
"@backstage/core-plugin-api": "
|
|
173
|
-
"@backstage/dev-utils": "
|
|
174
|
-
"@backstage/errors": "
|
|
175
|
-
"@backstage/plugin-auth-backend": "
|
|
176
|
-
"@backstage/plugin-auth-backend-module-guest-provider": "
|
|
177
|
-
"@backstage/plugin-catalog-node": "
|
|
178
|
-
"@backstage/plugin-scaffolder-node": "
|
|
179
|
-
"@backstage/plugin-scaffolder-node-test-utils": "
|
|
180
|
-
"@backstage/test-utils": "
|
|
181
|
-
"@backstage/theme": "
|
|
166
|
+
"@backstage/backend-plugin-api": "1.4.2-next.0",
|
|
167
|
+
"@backstage/backend-test-utils": "1.7.1-next.0",
|
|
168
|
+
"@backstage/catalog-client": "1.11.0-next.0",
|
|
169
|
+
"@backstage/config": "1.3.3",
|
|
170
|
+
"@backstage/core-app-api": "1.18.0",
|
|
171
|
+
"@backstage/core-components": "0.17.5-next.1",
|
|
172
|
+
"@backstage/core-plugin-api": "1.10.9",
|
|
173
|
+
"@backstage/dev-utils": "1.1.13-next.1",
|
|
174
|
+
"@backstage/errors": "1.2.7",
|
|
175
|
+
"@backstage/plugin-auth-backend": "0.25.3-next.0",
|
|
176
|
+
"@backstage/plugin-auth-backend-module-guest-provider": "0.2.11-next.0",
|
|
177
|
+
"@backstage/plugin-catalog-node": "1.18.0-next.0",
|
|
178
|
+
"@backstage/plugin-scaffolder-node": "0.11.0-next.0",
|
|
179
|
+
"@backstage/plugin-scaffolder-node-test-utils": "0.3.2-next.0",
|
|
180
|
+
"@backstage/test-utils": "1.7.11-next.0",
|
|
181
|
+
"@backstage/theme": "0.6.8-next.0",
|
|
182
182
|
"@rspack/core": "^1.3.9",
|
|
183
183
|
"@rspack/dev-server": "^1.1.1",
|
|
184
184
|
"@rspack/plugin-react-refresh": "^1.4.2",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# {{pluginId}}
|
|
2
|
+
|
|
3
|
+
Welcome to the {{pluginId}} plugin!
|
|
4
|
+
|
|
5
|
+
_This plugin was created through the Backstage CLI_
|
|
6
|
+
|
|
7
|
+
## Getting started
|
|
8
|
+
|
|
9
|
+
Your plugin has been added to the app in this repository, meaning you'll be able
|
|
10
|
+
to access it by running `yarn start` in the root directory, and then navigating
|
|
11
|
+
to [/{{pluginId}}](http://localhost:3000/{{pluginId}}).
|
|
12
|
+
|
|
13
|
+
This plugin is built with Backstage's [new frontend
|
|
14
|
+
system](https://backstage.io/docs/frontend-system/architecture/index), and you
|
|
15
|
+
can find more information about building plugins in the [plugin builder
|
|
16
|
+
documentation](https://backstage.io/docs/frontend-system/building-plugins/index).
|
|
17
|
+
|
|
18
|
+
You can also serve the plugin in isolation by running `yarn start` in the plugin directory.
|
|
19
|
+
This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads.
|
|
20
|
+
It is only meant for local development, and the setup for it can be found inside the [/dev](./dev) directory.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{packageName}}",
|
|
3
|
+
"main": "src/index.ts",
|
|
4
|
+
"types": "src/index.ts",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public",
|
|
7
|
+
"main": "dist/index.esm.js",
|
|
8
|
+
"types": "dist/index.d.ts"
|
|
9
|
+
},
|
|
10
|
+
"backstage": {
|
|
11
|
+
"role": "frontend-plugin",
|
|
12
|
+
"pluginId": "{{pluginId}}"
|
|
13
|
+
},
|
|
14
|
+
"sideEffects": false,
|
|
15
|
+
"scripts": {
|
|
16
|
+
"start": "backstage-cli package start",
|
|
17
|
+
"build": "backstage-cli package build",
|
|
18
|
+
"lint": "backstage-cli package lint",
|
|
19
|
+
"test": "backstage-cli package test",
|
|
20
|
+
"clean": "backstage-cli package clean",
|
|
21
|
+
"prepack": "backstage-cli package prepack",
|
|
22
|
+
"postpack": "backstage-cli package postpack"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@backstage/core-components": "{{versionQuery '@backstage/core-components'}}",
|
|
26
|
+
"@backstage/frontend-plugin-api": "{{versionQuery '@backstage/frontend-plugin-api'}}",
|
|
27
|
+
"@backstage/theme": "{{versionQuery '@backstage/theme'}}",
|
|
28
|
+
"@material-ui/core": "{{versionQuery '@material-ui/core' '4.12.2'}}",
|
|
29
|
+
"@material-ui/icons": "{{versionQuery '@material-ui/icons' '4.9.1'}}",
|
|
30
|
+
"@material-ui/lab": "{{versionQuery '@material-ui/lab' '4.0.0-alpha.61'}}",
|
|
31
|
+
"react-use": "{{versionQuery 'react-use' '17.2.4'}}"
|
|
32
|
+
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"react": "{{versionQuery 'react' '^16.13.1 || ^17.0.0 || ^18.0.0'}}"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@backstage/cli": "{{versionQuery '@backstage/cli'}}",
|
|
38
|
+
"@backstage/frontend-defaults": "{{versionQuery '@backstage/frontend-defaults'}}",
|
|
39
|
+
"@backstage/frontend-test-utils": "{{versionQuery '@backstage/frontend-test-utils'}}",
|
|
40
|
+
"@testing-library/jest-dom": "{{versionQuery '@testing-library/jest-dom' '6.0.0'}}",
|
|
41
|
+
"@testing-library/react": "{{versionQuery '@testing-library/react' '14.0.0'}}",
|
|
42
|
+
"@testing-library/user-event": "{{versionQuery '@testing-library/user-event' '14.0.0'}}",
|
|
43
|
+
"msw": "{{versionQuery 'msw' '1.0.0'}}",
|
|
44
|
+
"react": "{{versionQuery 'react' '^16.13.1 || ^17.0.0 || ^18.0.0'}}"
|
|
45
|
+
},
|
|
46
|
+
"files": [
|
|
47
|
+
"dist"
|
|
48
|
+
]
|
|
49
|
+
}
|
package/templates/new-frontend-plugin/src/components/ExampleComponent/ExampleComponent.test.tsx.hbs
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ExampleComponent } from './ExampleComponent';
|
|
2
|
+
import { rest } from 'msw';
|
|
3
|
+
import { setupServer } from 'msw/node';
|
|
4
|
+
import { screen } from '@testing-library/react';
|
|
5
|
+
import {
|
|
6
|
+
registerMswTestHooks,
|
|
7
|
+
renderInTestApp,
|
|
8
|
+
} from '@backstage/frontend-test-utils';
|
|
9
|
+
|
|
10
|
+
describe('ExampleComponent', () => {
|
|
11
|
+
const server = setupServer();
|
|
12
|
+
// Enable sane handlers for network requests
|
|
13
|
+
registerMswTestHooks(server);
|
|
14
|
+
|
|
15
|
+
// setup mock response
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
server.use(
|
|
18
|
+
rest.get('/*', (_, res, ctx) => res(ctx.status(200), ctx.json({}))),
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should render', async () => {
|
|
23
|
+
await renderInTestApp(<ExampleComponent />);
|
|
24
|
+
expect(
|
|
25
|
+
screen.getByText('Welcome to {{pluginId}}!'),
|
|
26
|
+
).toBeInTheDocument();
|
|
27
|
+
});
|
|
28
|
+
});
|
package/templates/new-frontend-plugin/src/components/ExampleComponent/ExampleComponent.tsx.hbs
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Typography, Grid } from '@material-ui/core';
|
|
2
|
+
import {
|
|
3
|
+
InfoCard,
|
|
4
|
+
Header,
|
|
5
|
+
Page,
|
|
6
|
+
Content,
|
|
7
|
+
ContentHeader,
|
|
8
|
+
HeaderLabel,
|
|
9
|
+
SupportButton,
|
|
10
|
+
} from '@backstage/core-components';
|
|
11
|
+
import { ExampleFetchComponent } from '../ExampleFetchComponent';
|
|
12
|
+
|
|
13
|
+
export const ExampleComponent = () => (
|
|
14
|
+
<Page themeId="tool">
|
|
15
|
+
<Header title="Welcome to {{pluginId}}!" subtitle="Optional subtitle">
|
|
16
|
+
<HeaderLabel label="Owner" value="Team X" />
|
|
17
|
+
<HeaderLabel label="Lifecycle" value="Alpha" />
|
|
18
|
+
</Header>
|
|
19
|
+
<Content>
|
|
20
|
+
<ContentHeader title="Plugin title">
|
|
21
|
+
<SupportButton>A description of your plugin goes here.</SupportButton>
|
|
22
|
+
</ContentHeader>
|
|
23
|
+
<Grid container spacing={3} direction="column">
|
|
24
|
+
<Grid item>
|
|
25
|
+
<InfoCard title="Information card">
|
|
26
|
+
<Typography variant="body1">
|
|
27
|
+
All content should be wrapped in a card like this.
|
|
28
|
+
</Typography>
|
|
29
|
+
</InfoCard>
|
|
30
|
+
</Grid>
|
|
31
|
+
<Grid item>
|
|
32
|
+
<ExampleFetchComponent />
|
|
33
|
+
</Grid>
|
|
34
|
+
</Grid>
|
|
35
|
+
</Content>
|
|
36
|
+
</Page>
|
|
37
|
+
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ExampleComponent } from './ExampleComponent';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { renderInTestApp } from '@backstage/frontend-test-utils';
|
|
2
|
+
import { ExampleFetchComponent } from './ExampleFetchComponent';
|
|
3
|
+
|
|
4
|
+
describe('ExampleFetchComponent', () => {
|
|
5
|
+
it('renders the user table', async () => {
|
|
6
|
+
const { getAllByText, getByAltText, getByText, findByRole } =
|
|
7
|
+
await renderInTestApp(<ExampleFetchComponent />);
|
|
8
|
+
|
|
9
|
+
// Wait for the table to render
|
|
10
|
+
const table = await findByRole('table');
|
|
11
|
+
const nationality = getAllByText('GB');
|
|
12
|
+
// Assert that the table contains the expected user data
|
|
13
|
+
expect(table).toBeInTheDocument();
|
|
14
|
+
expect(getByAltText('Carolyn')).toBeInTheDocument();
|
|
15
|
+
expect(getByText('Carolyn Moore')).toBeInTheDocument();
|
|
16
|
+
expect(getByText('carolyn.moore@example.com')).toBeInTheDocument();
|
|
17
|
+
expect(nationality[0]).toBeInTheDocument();
|
|
18
|
+
});
|
|
19
|
+
});
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
import { makeStyles } from '@material-ui/core/styles';
|
|
2
|
+
import {
|
|
3
|
+
Table,
|
|
4
|
+
TableColumn,
|
|
5
|
+
Progress,
|
|
6
|
+
ResponseErrorPanel,
|
|
7
|
+
} from '@backstage/core-components';
|
|
8
|
+
import useAsync from 'react-use/lib/useAsync';
|
|
9
|
+
|
|
10
|
+
export const exampleUsers = {
|
|
11
|
+
results: [
|
|
12
|
+
{
|
|
13
|
+
gender: 'female',
|
|
14
|
+
name: {
|
|
15
|
+
title: 'Miss',
|
|
16
|
+
first: 'Carolyn',
|
|
17
|
+
last: 'Moore',
|
|
18
|
+
},
|
|
19
|
+
email: 'carolyn.moore@example.com',
|
|
20
|
+
picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Carolyn',
|
|
21
|
+
nat: 'GB',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
gender: 'female',
|
|
25
|
+
name: {
|
|
26
|
+
title: 'Ms',
|
|
27
|
+
first: 'Esma',
|
|
28
|
+
last: 'Berberoğlu',
|
|
29
|
+
},
|
|
30
|
+
email: 'esma.berberoglu@example.com',
|
|
31
|
+
picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Esma',
|
|
32
|
+
nat: 'TR',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
gender: 'female',
|
|
36
|
+
name: {
|
|
37
|
+
title: 'Ms',
|
|
38
|
+
first: 'Isabella',
|
|
39
|
+
last: 'Rhodes',
|
|
40
|
+
},
|
|
41
|
+
email: 'isabella.rhodes@example.com',
|
|
42
|
+
picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Isabella',
|
|
43
|
+
nat: 'GB',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
gender: 'male',
|
|
47
|
+
name: {
|
|
48
|
+
title: 'Mr',
|
|
49
|
+
first: 'Derrick',
|
|
50
|
+
last: 'Carter',
|
|
51
|
+
},
|
|
52
|
+
email: 'derrick.carter@example.com',
|
|
53
|
+
picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Derrick',
|
|
54
|
+
nat: 'IE',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
gender: 'female',
|
|
58
|
+
name: {
|
|
59
|
+
title: 'Miss',
|
|
60
|
+
first: 'Mattie',
|
|
61
|
+
last: 'Lambert',
|
|
62
|
+
},
|
|
63
|
+
email: 'mattie.lambert@example.com',
|
|
64
|
+
picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Mattie',
|
|
65
|
+
nat: 'AU',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
gender: 'male',
|
|
69
|
+
name: {
|
|
70
|
+
title: 'Mr',
|
|
71
|
+
first: 'Mijat',
|
|
72
|
+
last: 'Rakić',
|
|
73
|
+
},
|
|
74
|
+
email: 'mijat.rakic@example.com',
|
|
75
|
+
picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Mijat',
|
|
76
|
+
nat: 'RS',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
gender: 'male',
|
|
80
|
+
name: {
|
|
81
|
+
title: 'Mr',
|
|
82
|
+
first: 'Javier',
|
|
83
|
+
last: 'Reid',
|
|
84
|
+
},
|
|
85
|
+
email: 'javier.reid@example.com',
|
|
86
|
+
picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Javier',
|
|
87
|
+
nat: 'US',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
gender: 'female',
|
|
91
|
+
name: {
|
|
92
|
+
title: 'Ms',
|
|
93
|
+
first: 'Isabella',
|
|
94
|
+
last: 'Li',
|
|
95
|
+
},
|
|
96
|
+
email: 'isabella.li@example.com',
|
|
97
|
+
picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Isabella',
|
|
98
|
+
nat: 'CA',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
gender: 'female',
|
|
102
|
+
name: {
|
|
103
|
+
title: 'Mrs',
|
|
104
|
+
first: 'Stephanie',
|
|
105
|
+
last: 'Garrett',
|
|
106
|
+
},
|
|
107
|
+
email: 'stephanie.garrett@example.com',
|
|
108
|
+
picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Stephanie',
|
|
109
|
+
nat: 'AU',
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
gender: 'female',
|
|
113
|
+
name: {
|
|
114
|
+
title: 'Ms',
|
|
115
|
+
first: 'Antonia',
|
|
116
|
+
last: 'Núñez',
|
|
117
|
+
},
|
|
118
|
+
email: 'antonia.nunez@example.com',
|
|
119
|
+
picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Antonia',
|
|
120
|
+
nat: 'ES',
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
gender: 'male',
|
|
124
|
+
name: {
|
|
125
|
+
title: 'Mr',
|
|
126
|
+
first: 'Donald',
|
|
127
|
+
last: 'Young',
|
|
128
|
+
},
|
|
129
|
+
email: 'donald.young@example.com',
|
|
130
|
+
picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Donald',
|
|
131
|
+
nat: 'US',
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
gender: 'male',
|
|
135
|
+
name: {
|
|
136
|
+
title: 'Mr',
|
|
137
|
+
first: 'Iegor',
|
|
138
|
+
last: 'Holodovskiy',
|
|
139
|
+
},
|
|
140
|
+
email: 'iegor.holodovskiy@example.com',
|
|
141
|
+
picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Iegor',
|
|
142
|
+
nat: 'UA',
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
gender: 'female',
|
|
146
|
+
name: {
|
|
147
|
+
title: 'Madame',
|
|
148
|
+
first: 'Jessica',
|
|
149
|
+
last: 'David',
|
|
150
|
+
},
|
|
151
|
+
email: 'jessica.david@example.com',
|
|
152
|
+
picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Jessica',
|
|
153
|
+
nat: 'CH',
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
gender: 'female',
|
|
157
|
+
name: {
|
|
158
|
+
title: 'Ms',
|
|
159
|
+
first: 'Eve',
|
|
160
|
+
last: 'Martinez',
|
|
161
|
+
},
|
|
162
|
+
email: 'eve.martinez@example.com',
|
|
163
|
+
picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Eve',
|
|
164
|
+
nat: 'FR',
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
gender: 'male',
|
|
168
|
+
name: {
|
|
169
|
+
title: 'Mr',
|
|
170
|
+
first: 'Caleb',
|
|
171
|
+
last: 'Silva',
|
|
172
|
+
},
|
|
173
|
+
email: 'caleb.silva@example.com',
|
|
174
|
+
picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Caleb',
|
|
175
|
+
nat: 'US',
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
gender: 'female',
|
|
179
|
+
name: {
|
|
180
|
+
title: 'Miss',
|
|
181
|
+
first: 'Marcia',
|
|
182
|
+
last: 'Jenkins',
|
|
183
|
+
},
|
|
184
|
+
email: 'marcia.jenkins@example.com',
|
|
185
|
+
picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Marcia',
|
|
186
|
+
nat: 'US',
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
gender: 'female',
|
|
190
|
+
name: {
|
|
191
|
+
title: 'Mrs',
|
|
192
|
+
first: 'Mackenzie',
|
|
193
|
+
last: 'Jones',
|
|
194
|
+
},
|
|
195
|
+
email: 'mackenzie.jones@example.com',
|
|
196
|
+
picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Mackenzie',
|
|
197
|
+
nat: 'NZ',
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
gender: 'male',
|
|
201
|
+
name: {
|
|
202
|
+
title: 'Mr',
|
|
203
|
+
first: 'Jeremiah',
|
|
204
|
+
last: 'Gutierrez',
|
|
205
|
+
},
|
|
206
|
+
email: 'jeremiah.gutierrez@example.com',
|
|
207
|
+
picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Jeremiah',
|
|
208
|
+
nat: 'AU',
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
gender: 'female',
|
|
212
|
+
name: {
|
|
213
|
+
title: 'Ms',
|
|
214
|
+
first: 'Luciara',
|
|
215
|
+
last: 'Souza',
|
|
216
|
+
},
|
|
217
|
+
email: 'luciara.souza@example.com',
|
|
218
|
+
picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Luciara',
|
|
219
|
+
nat: 'BR',
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
gender: 'male',
|
|
223
|
+
name: {
|
|
224
|
+
title: 'Mr',
|
|
225
|
+
first: 'Valgi',
|
|
226
|
+
last: 'da Cunha',
|
|
227
|
+
},
|
|
228
|
+
email: 'valgi.dacunha@example.com',
|
|
229
|
+
picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Valgi',
|
|
230
|
+
nat: 'BR',
|
|
231
|
+
},
|
|
232
|
+
],
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
const useStyles = makeStyles({
|
|
236
|
+
avatar: {
|
|
237
|
+
height: 32,
|
|
238
|
+
width: 32,
|
|
239
|
+
borderRadius: '50%',
|
|
240
|
+
},
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
type User = {
|
|
244
|
+
gender: string; // "male"
|
|
245
|
+
name: {
|
|
246
|
+
title: string; // "Mr",
|
|
247
|
+
first: string; // "Duane",
|
|
248
|
+
last: string; // "Reed"
|
|
249
|
+
};
|
|
250
|
+
email: string; // "duane.reed@example.com"
|
|
251
|
+
picture: string; // "https://api.dicebear.com/6.x/open-peeps/svg?seed=Duane"
|
|
252
|
+
nat: string; // "AU"
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
type DenseTableProps = {
|
|
256
|
+
users: User[];
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
export const DenseTable = ({ users }: DenseTableProps) => {
|
|
260
|
+
const classes = useStyles();
|
|
261
|
+
|
|
262
|
+
const columns: TableColumn[] = [
|
|
263
|
+
{ title: 'Avatar', field: 'avatar' },
|
|
264
|
+
{ title: 'Name', field: 'name' },
|
|
265
|
+
{ title: 'Email', field: 'email' },
|
|
266
|
+
{ title: 'Nationality', field: 'nationality' },
|
|
267
|
+
];
|
|
268
|
+
|
|
269
|
+
const data = users.map(user => {
|
|
270
|
+
return {
|
|
271
|
+
avatar: (
|
|
272
|
+
<img
|
|
273
|
+
src={user.picture}
|
|
274
|
+
className={classes.avatar}
|
|
275
|
+
alt={user.name.first}
|
|
276
|
+
/>
|
|
277
|
+
),
|
|
278
|
+
name: `${user.name.first} ${user.name.last}`,
|
|
279
|
+
email: user.email,
|
|
280
|
+
nationality: user.nat,
|
|
281
|
+
};
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
return (
|
|
285
|
+
<Table
|
|
286
|
+
title="Example User List"
|
|
287
|
+
options=\{{ search: false, paging: false }}
|
|
288
|
+
columns={columns}
|
|
289
|
+
data={data}
|
|
290
|
+
/>
|
|
291
|
+
);
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
export const ExampleFetchComponent = () => {
|
|
295
|
+
|
|
296
|
+
const { value, loading, error } = useAsync(async (): Promise<User[]> => {
|
|
297
|
+
// Would use fetch in a real world example
|
|
298
|
+
return exampleUsers.results;
|
|
299
|
+
}, []);
|
|
300
|
+
|
|
301
|
+
if (loading) {
|
|
302
|
+
return <Progress />;
|
|
303
|
+
} else if (error) {
|
|
304
|
+
return <ResponseErrorPanel error={error} />;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return <DenseTable users={value || []} />;
|
|
308
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ExampleFetchComponent } from './ExampleFetchComponent';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { {{ pluginVar }} as default } from './plugin';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
createFrontendPlugin,
|
|
4
|
+
PageBlueprint,
|
|
5
|
+
} from '@backstage/frontend-plugin-api';
|
|
6
|
+
|
|
7
|
+
import { rootRouteRef } from './routes';
|
|
8
|
+
|
|
9
|
+
export const page = PageBlueprint.make({
|
|
10
|
+
params: {
|
|
11
|
+
path: '/{{pluginId}}',
|
|
12
|
+
routeRef: rootRouteRef,
|
|
13
|
+
loader: () =>
|
|
14
|
+
import('./components/ExampleComponent').then(m =>
|
|
15
|
+
<m.ExampleComponent />,
|
|
16
|
+
),
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export const {{ pluginVar }} = createFrontendPlugin({
|
|
21
|
+
id: '{{pluginId}}',
|
|
22
|
+
extensions: [page],
|
|
23
|
+
routes: {
|
|
24
|
+
root: rootRouteRef,
|
|
25
|
+
}
|
|
26
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{packageName}}",
|
|
3
|
+
"description": "The {{moduleId}} frontend module for the {{pluginId}} plugin.",
|
|
4
|
+
"main": "src/index.ts",
|
|
5
|
+
"types": "src/index.ts",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public",
|
|
8
|
+
"main": "dist/index.cjs.js",
|
|
9
|
+
"module": "dist/index.esm.js",
|
|
10
|
+
"types": "dist/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"backstage": {
|
|
13
|
+
"role": "frontend-plugin-module",
|
|
14
|
+
"pluginId": "{{pluginId}}"
|
|
15
|
+
},
|
|
16
|
+
"sideEffects": false,
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "backstage-cli package build",
|
|
19
|
+
"lint": "backstage-cli package lint",
|
|
20
|
+
"test": "backstage-cli package test",
|
|
21
|
+
"clean": "backstage-cli package clean",
|
|
22
|
+
"prepack": "backstage-cli package prepack",
|
|
23
|
+
"postpack": "backstage-cli package postpack"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@backstage/frontend-plugin-api": "{{versionQuery '@backstage/frontend-plugin-api'}}"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@backstage/cli": "{{versionQuery '@backstage/cli'}}",
|
|
30
|
+
"@testing-library/jest-dom": "{{versionQuery '@testing-library/jest-dom' '6.0.0'}}"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist"
|
|
34
|
+
]
|
|
35
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { {{ moduleVar }} as default } from './plugin';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|