diff --git a/packages/app/package.json b/packages/app/package.json
index 2c8b10ffb3..a85c26f7f3 100644
--- a/packages/app/package.json
+++ b/packages/app/package.json
@@ -21,6 +21,7 @@
"@backstage/cli": "^0.1.1-alpha.4",
"@backstage/core": "^0.1.1-alpha.4",
"@backstage/plugin-home-page": "^0.1.1-alpha.4",
+ "@backstage/plugin-inventory": "^0.1.1-alpha.4",
"@backstage/plugin-lighthouse": "^0.1.1-alpha.4",
"@backstage/plugin-welcome": "^0.1.1-alpha.4",
"@backstage/theme": "^0.1.1-alpha.4",
diff --git a/packages/app/src/components/Root/Root.tsx b/packages/app/src/components/Root/Root.tsx
index d4fead2dd9..61adbe9ddc 100644
--- a/packages/app/src/components/Root/Root.tsx
+++ b/packages/app/src/components/Root/Root.tsx
@@ -19,6 +19,7 @@ import PropTypes from 'prop-types';
import { Link, makeStyles, Typography } from '@material-ui/core';
import HomeIcon from '@material-ui/icons/Home';
import AccountCircle from '@material-ui/icons/AccountCircle';
+import AccountTreeIcon from '@material-ui/icons/AccountTree';
import {
Sidebar,
SidebarPage,
@@ -79,6 +80,7 @@ const Root: FC<{}> = ({ children }) => (
+
diff --git a/packages/app/src/plugins.ts b/packages/app/src/plugins.ts
index 919ea0666b..c1cc2cce1a 100644
--- a/packages/app/src/plugins.ts
+++ b/packages/app/src/plugins.ts
@@ -13,6 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
export { plugin as HomePagePlugin } from '@backstage/plugin-home-page';
export { plugin as WelcomePlugin } from '@backstage/plugin-welcome';
export { plugin as LighthousePlugin } from '@backstage/plugin-lighthouse';
+export { plugin as InventoryPlugin } from '@backstage/plugin-inventory';
diff --git a/packages/backend/package.json b/packages/backend/package.json
index c880f59893..0530f04452 100644
--- a/packages/backend/package.json
+++ b/packages/backend/package.json
@@ -9,18 +9,21 @@
},
"scripts": {
"build": "tsc",
- "start": "tsc-watch --onFirstSuccess nodemon",
+ "start": "backstage-cli watch-deps --build -- tsc-watch --onFirstSuccess nodemon",
"lint": "backstage-cli lint",
"test": "backstage-cli test",
"clean": "backstage-cli clean"
},
"dependencies": {
+ "@backstage/plugin-inventory-backend": "0.1.1-alpha.4",
+ "compression": "^1.7.4",
"cors": "^2.8.5",
"express": "^4.17.1",
"helmet": "^3.22.0"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.4",
+ "@types/compression": "^1.7.0",
"@types/cors": "^2.8.6",
"@types/express": "^4.17.6",
"@types/express-serve-static-core": "^4.17.5",
diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts
index 307bd04be7..fd8015c328 100644
--- a/packages/backend/src/index.ts
+++ b/packages/backend/src/index.ts
@@ -25,15 +25,21 @@
import express from 'express';
import cors from 'cors';
import helmet from 'helmet';
+import compression from 'compression';
import { testRouter } from './test';
+import { router as inventoryRouter } from '@backstage/plugin-inventory-backend';
-const PORT = parseInt(process.env.PORT ?? '', 10) || 7000;
+const DEFAULT_PORT = 7000;
+
+const PORT = parseInt(process.env.PORT ?? '', 10) || DEFAULT_PORT;
const app = express();
app.use(helmet());
app.use(cors());
+app.use(compression());
app.use(express.json());
app.use('/test', testRouter);
+app.use('/inventory', inventoryRouter);
app.listen(PORT, () => {
console.log(`Listening on port ${PORT}`);
diff --git a/packages/backend/tsconfig.json b/packages/backend/tsconfig.json
index 6a071b2b50..b463ac102f 100644
--- a/packages/backend/tsconfig.json
+++ b/packages/backend/tsconfig.json
@@ -5,6 +5,7 @@
"outDir": "dist",
"incremental": true,
"sourceMap": true,
+ "declaration": true,
"strict": true,
"target": "es5",
"module": "commonjs",
diff --git a/plugins/inventory-backend/.eslintrc.js b/plugins/inventory-backend/.eslintrc.js
new file mode 100644
index 0000000000..f400a039e7
--- /dev/null
+++ b/plugins/inventory-backend/.eslintrc.js
@@ -0,0 +1,6 @@
+module.exports = {
+ rules: {
+ 'no-console': 0, // Permitted in console programs
+ 'new-cap': ['error', { capIsNew: false }], // Because Express constructs things e.g. like 'const r = express.Router()'
+ },
+};
diff --git a/plugins/inventory-backend/README.md b/plugins/inventory-backend/README.md
new file mode 100644
index 0000000000..bc224ee42e
--- /dev/null
+++ b/plugins/inventory-backend/README.md
@@ -0,0 +1,13 @@
+# Inventory Backend
+
+WORK IN PROGRESS
+
+This is the backend part of the default inventory plugin.
+
+It responds to requests from the frontend part, and fulfills them by delegating
+to your existing inventory related services.
+
+## Links
+
+- (Frontend part of the plugin)[https://github.com/spotify/backstage/tree/master/plugins/inventory]
+- (The Backstage homepage)[https://backstage.io]
diff --git a/plugins/inventory-backend/package.json b/plugins/inventory-backend/package.json
new file mode 100644
index 0000000000..37f3f27e78
--- /dev/null
+++ b/plugins/inventory-backend/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "@backstage/plugin-inventory-backend",
+ "version": "0.1.1-alpha.4",
+ "main": "dist",
+ "license": "Apache-2.0",
+ "private": true,
+ "scripts": {
+ "build": "tsc",
+ "lint": "backstage-cli lint",
+ "test": "backstage-cli test",
+ "clean": "backstage-cli clean"
+ },
+ "devDependencies": {
+ "@backstage/cli": "^0.1.1-alpha.4"
+ },
+ "dependencies": {
+ "express": "^4.17.1"
+ },
+ "files": [
+ "dist"
+ ]
+}
diff --git a/plugins/inventory-backend/src/index.ts b/plugins/inventory-backend/src/index.ts
new file mode 100644
index 0000000000..92c9090376
--- /dev/null
+++ b/plugins/inventory-backend/src/index.ts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2020 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export { router } from './plugin';
diff --git a/plugins/inventory-backend/src/plugin.test.ts b/plugins/inventory-backend/src/plugin.test.ts
new file mode 100644
index 0000000000..b3e2f19771
--- /dev/null
+++ b/plugins/inventory-backend/src/plugin.test.ts
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+describe('test', () => {
+ it('unbreaks the test runner', () => {
+ expect(true).toBeTruthy();
+ });
+});
diff --git a/plugins/inventory-backend/src/plugin.ts b/plugins/inventory-backend/src/plugin.ts
new file mode 100644
index 0000000000..88299a5c0f
--- /dev/null
+++ b/plugins/inventory-backend/src/plugin.ts
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2020 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import express from 'express';
+
+export const router = express.Router();
+
+router.get('/', async (_, res) => {
+ res
+ .status(200)
+ .send([
+ { id: 'component1' },
+ { id: 'component2' },
+ { id: 'component3' },
+ { id: 'component4' },
+ ]);
+});
diff --git a/plugins/inventory-backend/src/setupTests.ts b/plugins/inventory-backend/src/setupTests.ts
new file mode 100644
index 0000000000..f3b69cc361
--- /dev/null
+++ b/plugins/inventory-backend/src/setupTests.ts
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2020 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
diff --git a/plugins/inventory-backend/tsconfig.json b/plugins/inventory-backend/tsconfig.json
new file mode 100644
index 0000000000..b463ac102f
--- /dev/null
+++ b/plugins/inventory-backend/tsconfig.json
@@ -0,0 +1,15 @@
+{
+ "include": ["src"],
+ "compilerOptions": {
+ "baseUrl": "src",
+ "outDir": "dist",
+ "incremental": true,
+ "sourceMap": true,
+ "declaration": true,
+ "strict": true,
+ "target": "es5",
+ "module": "commonjs",
+ "esModuleInterop": true,
+ "types": ["node", "jest"]
+ }
+}
diff --git a/plugins/inventory/.eslintrc.js b/plugins/inventory/.eslintrc.js
new file mode 100644
index 0000000000..13573efa9c
--- /dev/null
+++ b/plugins/inventory/.eslintrc.js
@@ -0,0 +1,3 @@
+module.exports = {
+ extends: [require.resolve('@backstage/cli/config/eslint')],
+};
diff --git a/plugins/inventory/README.md b/plugins/inventory/README.md
new file mode 100644
index 0000000000..e77a77148f
--- /dev/null
+++ b/plugins/inventory/README.md
@@ -0,0 +1,13 @@
+# Inventory Frontend
+
+WORK IN PROGRESS
+
+This is the frontend part of the default inventory plugin.
+
+It will implement the core API for handling your inventory of software, and
+supply the base views to show and manage them.
+
+## Links
+
+- (Backend part of the plugin)[https://github.com/spotify/backstage/tree/master/plugins/inventory-backend]
+- (The Backstage homepage)[https://backstage.io]
diff --git a/plugins/inventory/package.json b/plugins/inventory/package.json
new file mode 100644
index 0000000000..8a260d2778
--- /dev/null
+++ b/plugins/inventory/package.json
@@ -0,0 +1,38 @@
+{
+ "name": "@backstage/plugin-inventory",
+ "version": "0.1.1-alpha.4",
+ "main": "dist/index.cjs.js",
+ "types": "dist/index.d.ts",
+ "license": "Apache-2.0",
+ "private": true,
+ "scripts": {
+ "build": "backstage-cli plugin:build",
+ "start": "backstage-cli plugin:serve",
+ "lint": "backstage-cli lint",
+ "test": "backstage-cli test",
+ "clean": "backstage-cli clean"
+ },
+ "devDependencies": {
+ "@backstage/cli": "^0.1.1-alpha.4",
+ "@testing-library/jest-dom": "^4.2.4",
+ "@testing-library/react": "^9.3.2",
+ "@testing-library/user-event": "^7.1.2",
+ "@types/jest": "^24.0.0",
+ "@types/node": "^12.0.0",
+ "@types/testing-library__jest-dom": "5.0.2",
+ "jest-fetch-mock": "^3.0.3"
+ },
+ "dependencies": {
+ "@backstage/core": "^0.1.1-alpha.4",
+ "@backstage/theme": "^0.1.1-alpha.4",
+ "@material-ui/core": "^4.9.1",
+ "@material-ui/icons": "^4.9.1",
+ "@material-ui/lab": "4.0.0-alpha.45",
+ "react": "16.13.1",
+ "react-dom": "16.13.1",
+ "react-use": "^13.0.0"
+ },
+ "files": [
+ "dist"
+ ]
+}
diff --git a/plugins/inventory/src/components/InventoryPage/InventoryPage.test.tsx b/plugins/inventory/src/components/InventoryPage/InventoryPage.test.tsx
new file mode 100644
index 0000000000..fe17da308c
--- /dev/null
+++ b/plugins/inventory/src/components/InventoryPage/InventoryPage.test.tsx
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2020 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import { render } from '@testing-library/react';
+import mockFetch from 'jest-fetch-mock';
+import InventoryPage from './InventoryPage';
+import { ThemeProvider } from '@material-ui/core';
+import { lightTheme } from '@backstage/theme';
+
+describe('InventoryPage', () => {
+ it('should render', async () => {
+ mockFetch.mockResponse(() => new Promise(() => {}));
+ const rendered = render(
+
+
+ ,
+ );
+ expect(await rendered.findByText('backstage-backend')).toBeInTheDocument();
+ });
+});
diff --git a/plugins/inventory/src/components/InventoryPage/InventoryPage.tsx b/plugins/inventory/src/components/InventoryPage/InventoryPage.tsx
new file mode 100644
index 0000000000..0b837d840c
--- /dev/null
+++ b/plugins/inventory/src/components/InventoryPage/InventoryPage.tsx
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2020 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React, { FC } from 'react';
+import { Typography } from '@material-ui/core';
+import { Content, InfoCard, Header, Page, pageTheme } from '@backstage/core';
+import Table from '@material-ui/core/Table';
+import TableBody from '@material-ui/core/TableBody';
+import TableCell from '@material-ui/core/TableCell';
+import TableContainer from '@material-ui/core/TableContainer';
+import TableHead from '@material-ui/core/TableHead';
+import TableRow from '@material-ui/core/TableRow';
+
+// TODO(freben): Connect to backend
+const STATIC_DATA = [
+ { id: 'backstage-frontend', kind: 'website' },
+ { id: 'backstage-backend', kind: 'service' },
+ { id: 'backstage-microsite', kind: 'website' },
+];
+
+const InventoryPage: FC<{}> = () => {
+ return (
+
+
+
+ All of it
+
+
+
+
+
+ ID
+ Kind
+
+
+
+ {STATIC_DATA.map(d => (
+
+ {d.id}
+ {d.kind}
+
+ ))}
+
+
+
+
+
+
+ );
+};
+
+export default InventoryPage;
diff --git a/plugins/inventory/src/components/InventoryPage/index.ts b/plugins/inventory/src/components/InventoryPage/index.ts
new file mode 100644
index 0000000000..7a11d39f10
--- /dev/null
+++ b/plugins/inventory/src/components/InventoryPage/index.ts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2020 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export { default } from './InventoryPage';
diff --git a/plugins/inventory/src/index.ts b/plugins/inventory/src/index.ts
new file mode 100644
index 0000000000..3a0a0fe2d3
--- /dev/null
+++ b/plugins/inventory/src/index.ts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2020 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export { plugin } from './plugin';
diff --git a/plugins/inventory/src/plugin.test.ts b/plugins/inventory/src/plugin.test.ts
new file mode 100644
index 0000000000..4fac72593f
--- /dev/null
+++ b/plugins/inventory/src/plugin.test.ts
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2020 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { plugin } from './plugin';
+
+describe('inventory', () => {
+ it('should export plugin', () => {
+ expect(plugin).toBeDefined();
+ });
+});
diff --git a/plugins/inventory/src/plugin.ts b/plugins/inventory/src/plugin.ts
new file mode 100644
index 0000000000..197dd3cd38
--- /dev/null
+++ b/plugins/inventory/src/plugin.ts
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2020 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { createPlugin } from '@backstage/core';
+import InventoryPage from './components/InventoryPage';
+
+export const plugin = createPlugin({
+ id: 'inventory',
+ register({ router }) {
+ router.registerRoute('/inventory', InventoryPage);
+ },
+});
diff --git a/plugins/inventory/src/setupTests.ts b/plugins/inventory/src/setupTests.ts
new file mode 100644
index 0000000000..1a907ab8e6
--- /dev/null
+++ b/plugins/inventory/src/setupTests.ts
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2020 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import '@testing-library/jest-dom/extend-expect';
+require('jest-fetch-mock').enableMocks();
diff --git a/plugins/inventory/tsconfig.json b/plugins/inventory/tsconfig.json
new file mode 100644
index 0000000000..7b73db2f0f
--- /dev/null
+++ b/plugins/inventory/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "extends": "../../tsconfig.json",
+ "include": ["src"],
+ "compilerOptions": {
+ "baseUrl": "src"
+ }
+}
diff --git a/yarn.lock b/yarn.lock
index 5126cfa721..12946641f3 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3821,6 +3821,13 @@
resolved "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
+"@types/compression@^1.7.0":
+ version "1.7.0"
+ resolved "https://registry.npmjs.org/@types/compression/-/compression-1.7.0.tgz#8dc2a56604873cf0dd4e746d9ae4d31ae77b2390"
+ integrity sha512-3LzWUM+3k3XdWOUk/RO+uSjv7YWOatYq2QADJntK1pjkk4DfVP0KrIEPDnXRJxAAGKe0VpIPRmlINLDuCedZWw==
+ dependencies:
+ "@types/express" "*"
+
"@types/connect-history-api-fallback@*":
version "1.3.3"
resolved "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.3.tgz#4772b79b8b53185f0f4c9deab09236baf76ee3b4"