diff --git a/packages/app/package.json b/packages/app/package.json index 91fe2cf34c..0ab288fcca 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -2,20 +2,6 @@ "name": "example-app", "version": "0.1.1-alpha.4", "private": true, - "devDependencies": { - "@testing-library/cypress": "^6.0.0", - "@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/react-router-dom": "^5.1.3", - "@types/zen-observable": "^0.8.0", - "cross-env": "^7.0.0", - "cypress": "^4.2.0", - "eslint-plugin-cypress": "^2.10.3", - "start-server-and-test": "^1.10.11" - }, "dependencies": { "@backstage/cli": "^0.1.1-alpha.4", "@backstage/core": "^0.1.1-alpha.4", @@ -38,6 +24,21 @@ "react-use": "^13.24.0", "zen-observable": "^0.8.15" }, + "devDependencies": { + "@testing-library/cypress": "^6.0.0", + "@types/jquery": "^3.3.34", + "@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/react-router-dom": "^5.1.3", + "@types/zen-observable": "^0.8.0", + "cross-env": "^7.0.0", + "cypress": "^4.2.0", + "eslint-plugin-cypress": "^2.10.3", + "start-server-and-test": "^1.10.11" + }, "scripts": { "start": "backstage-cli app:serve", "bundle": "backstage-cli app:build", diff --git a/packages/app/src/apis.ts b/packages/app/src/apis.ts index c00aee1f5c..c3380215b3 100644 --- a/packages/app/src/apis.ts +++ b/packages/app/src/apis.ts @@ -30,11 +30,7 @@ import { LighthouseRestApi, } from '@backstage/plugin-lighthouse'; -import { - techRadarApiRef, - TechRadar, - loadSampleData, -} from '@backstage/plugin-tech-radar'; +import { techRadarApiRef, TechRadar } from '@backstage/plugin-tech-radar'; import { CircleCIApi, circleCIApiRef } from '@backstage/plugin-circleci'; @@ -49,6 +45,13 @@ builder.add(circleCIApiRef, new CircleCIApi()); builder.add(featureFlagsApiRef, new FeatureFlags()); builder.add(lighthouseApiRef, new LighthouseRestApi('http://localhost:3003')); -builder.add(techRadarApiRef, new TechRadar(1800, 800, loadSampleData)); + +builder.add( + techRadarApiRef, + new TechRadar({ + width: 1500, + height: 800, + }), +); export default builder.build() as ApiHolder; diff --git a/packages/backend-common/tsconfig.json b/packages/backend-common/tsconfig.json index 6d7ca21afa..ca39bf9964 100644 --- a/packages/backend-common/tsconfig.json +++ b/packages/backend-common/tsconfig.json @@ -1,7 +1,6 @@ { "include": ["src"], "compilerOptions": { - "baseUrl": "src", "outDir": "dist", "incremental": true, "sourceMap": true, diff --git a/packages/backend/tsconfig.json b/packages/backend/tsconfig.json index b463ac102f..0f255b6d2c 100644 --- a/packages/backend/tsconfig.json +++ b/packages/backend/tsconfig.json @@ -1,7 +1,6 @@ { "include": ["src"], "compilerOptions": { - "baseUrl": "src", "outDir": "dist", "incremental": true, "sourceMap": true, diff --git a/packages/cli/bin/backstage-cli b/packages/cli/bin/backstage-cli index ad5cc09749..15b97d7063 100755 --- a/packages/cli/bin/backstage-cli +++ b/packages/cli/bin/backstage-cli @@ -21,68 +21,12 @@ const path = require('path'); const isLocal = require('fs').existsSync(path.resolve(__dirname, '../src')); if (!isLocal || process.env.BACKSTAGE_E2E_CLI_TEST) { - // src-relative imports are a pain to get to work with plain tsc compilation, as the - // transpiled code will maintain the imports as they are in the source. Which means an - // import for `helpers/paths` will start like that in the output, which won't work in NodeJS. - // - // This is a solution for getting src-relative imports to work with typescript/node in - // the published package. We're using `module: "amd"` to ship the entire cli implementation - // in one file, and it also happens to generate correct module definition and import statements. - // Minimal AMD implementation - const moduleFactories = {}; - const moduleCache = {}; - global.define = (name, deps, moduleFunc) => { - moduleFactories[name] = () => { - const exportsObj = {}; - - // require() that first searches for locally defined amd modules - const requireFunc = name => { - let factory = moduleFactories[name]; - if (!factory) { - // Check /index as well, to mirror nodejs resolution - const index = `${name}/index`; - if (!moduleFactories[index]) { - return require(name); - } - name = index; - factory = moduleFactories[name]; - } - if (!moduleCache[name]) { - moduleCache[name] = factory(); - } - return moduleCache[name]; - }; - const impls = deps.slice(2).map(requireFunc); - - moduleFunc(requireFunc, exportsObj, ...impls); - - return exportsObj; - }; - }; require('../dist'); - - // index module is the entrypoint - moduleFactories.index(); } else { - const tsConfigPath = path.resolve(__dirname, '../tsconfig.json'); - const { - baseUrl: relativeBaseUrl, - paths = {}, - } = require(tsConfigPath).compilerOptions; - const baseUrl = path.resolve(__dirname, '..', relativeBaseUrl); - - // Use tsconfig-paths to resolve src-relative paths during development - const cleanupPaths = require('tsconfig-paths').register({ baseUrl, paths }); - require('ts-node').register({ project: path.resolve(__dirname, '../tsconfig.build.json'), - compilerOptions: { - module: 'CommonJS', - }, transpileOnly: true, }); require('../src'); - - cleanupPaths(); } diff --git a/packages/cli/package.json b/packages/cli/package.json index 418e5f9fe2..ee46b09862 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -28,26 +28,6 @@ "bin": { "backstage-cli": "bin/backstage-cli" }, - "devDependencies": { - "@types/diff": "^4.0.2", - "@types/fs-extra": "^8.1.0", - "@types/html-webpack-plugin": "^3.2.2", - "@types/inquirer": "^6.5.0", - "@types/node": "^13.7.2", - "@types/ora": "^3.2.0", - "@types/react-dev-utils": "^9.0.4", - "@types/recursive-readdir": "^2.2.0", - "@types/rollup-plugin-peer-deps-external": "^2.2.0", - "@types/rollup-plugin-postcss": "^2.0.0", - "@types/tar": "^4.0.3", - "@types/webpack": "^4.41.7", - "@types/webpack-dev-server": "^3.10.0", - "del": "^5.1.0", - "nodemon": "^2.0.2", - "ts-node": "^8.6.2", - "tsconfig-paths": "^3.9.0", - "zombie": "^6.1.4" - }, "dependencies": { "@lerna/package-graph": "^3.18.5", "@lerna/project": "^3.18.0", @@ -86,6 +66,25 @@ "webpack": "^4.41.6", "webpack-dev-server": "^3.10.3" }, + "devDependencies": { + "@types/diff": "^4.0.2", + "@types/fs-extra": "^8.1.0", + "@types/html-webpack-plugin": "^3.2.2", + "@types/inquirer": "^6.5.0", + "@types/node": "^13.7.2", + "@types/ora": "^3.2.0", + "@types/react-dev-utils": "^9.0.4", + "@types/recursive-readdir": "^2.2.0", + "@types/rollup-plugin-peer-deps-external": "^2.2.0", + "@types/rollup-plugin-postcss": "^2.0.0", + "@types/tar": "^4.0.3", + "@types/webpack": "^4.41.7", + "@types/webpack-dev-server": "^3.10.0", + "del": "^5.1.0", + "nodemon": "^2.0.2", + "ts-node": "^8.6.2", + "zombie": "^6.1.4" + }, "files": [ "templates", "config", diff --git a/packages/cli/src/commands/app/build.ts b/packages/cli/src/commands/app/build.ts index 601e31a9c1..362f79a7fa 100644 --- a/packages/cli/src/commands/app/build.ts +++ b/packages/cli/src/commands/app/build.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { run } from 'lib/run'; +import { run } from '../../lib/run'; export default async () => { const args = ['build']; diff --git a/packages/cli/src/commands/app/serve.ts b/packages/cli/src/commands/app/serve.ts index 22775242ca..1d0ccfc465 100644 --- a/packages/cli/src/commands/app/serve.ts +++ b/packages/cli/src/commands/app/serve.ts @@ -14,9 +14,9 @@ * limitations under the License. */ -import { run } from 'lib/run'; -import { createLogFunc } from 'lib/logging'; -import { watchDeps } from 'lib/watchDeps'; +import { run } from '../../lib/run'; +import { createLogFunc } from '../../lib/logging'; +import { watchDeps } from '../../lib/watchDeps'; export default async () => { // Start dynamic watch and build of dependencies, then serve the app diff --git a/packages/cli/src/commands/build-cache/index.ts b/packages/cli/src/commands/build-cache/index.ts index e58313c6b2..72199ec42e 100644 --- a/packages/cli/src/commands/build-cache/index.ts +++ b/packages/cli/src/commands/build-cache/index.ts @@ -15,8 +15,8 @@ */ import { Command } from 'commander'; -import { run } from 'lib/run'; -import { withCache, parseOptions } from 'lib/buildCache'; +import { run } from '../../lib/run'; +import { withCache, parseOptions } from '../../lib/buildCache'; /* * The build-cache command is used to make builds a no-op if there are no changes to the package. diff --git a/packages/cli/src/commands/clean/clean.ts b/packages/cli/src/commands/clean/clean.ts index 06998a4ca3..2fa49fcc4a 100644 --- a/packages/cli/src/commands/clean/clean.ts +++ b/packages/cli/src/commands/clean/clean.ts @@ -16,8 +16,8 @@ import fs from 'fs-extra'; import { resolve as resolvePath, relative as relativePath } from 'path'; -import { paths } from 'lib/paths'; -import { getDefaultCacheOptions } from 'lib/buildCache'; +import { paths } from '../../lib/paths'; +import { getDefaultCacheOptions } from '../../lib/buildCache'; export default async function clean() { const cacheOptions = getDefaultCacheOptions(); diff --git a/packages/cli/src/commands/create-app/createApp.ts b/packages/cli/src/commands/create-app/createApp.ts index b5c9ba69eb..2a9f6ff9fd 100644 --- a/packages/cli/src/commands/create-app/createApp.ts +++ b/packages/cli/src/commands/create-app/createApp.ts @@ -21,9 +21,9 @@ import inquirer, { Answers, Question } from 'inquirer'; import { exec as execCb } from 'child_process'; import { resolve as resolvePath } from 'path'; import os from 'os'; -import { Task, templatingTask } from 'lib/tasks'; -import { paths } from 'lib/paths'; -import { version } from 'lib/version'; +import { Task, templatingTask } from '../../lib/tasks'; +import { paths } from '../../lib/paths'; +import { version } from '../../lib/version'; const exec = promisify(execCb); async function checkExists(rootDir: string, name: string) { @@ -63,7 +63,7 @@ async function buildApp(appFolder: string) { await Task.forItem('executing', command, async () => { process.chdir(appFolder); - await exec(command).catch(error => { + await exec(command).catch((error) => { process.stdout.write(error.stderr); process.stdout.write(error.stdout); throw new Error(`Could not execute command ${chalk.cyan(command)}`); @@ -78,7 +78,7 @@ export async function moveApp( id: string, ) { await Task.forItem('moving', id, async () => { - await fs.move(tempDir, destination).catch(error => { + await fs.move(tempDir, destination).catch((error) => { throw new Error( `Failed to move app from ${tempDir} to ${destination}: ${error.message}`, ); @@ -101,7 +101,7 @@ async function addPackageResolutions(appDir: string) { packageFileJson.resolutions[`@backstage/${pkg}`] = `file:${pkgPath}`; const newContents = `${JSON.stringify(packageFileJson, null, 2)}\n`; - await fs.writeFile(pkgJsonPath, newContents, 'utf-8').catch(error => { + await fs.writeFile(pkgJsonPath, newContents, 'utf-8').catch((error) => { throw new Error( `Failed to add resolutions to package.json: ${error.message}`, ); diff --git a/packages/cli/src/commands/create-plugin/createPlugin.ts b/packages/cli/src/commands/create-plugin/createPlugin.ts index 3c92397a3d..b0bf1d85b5 100644 --- a/packages/cli/src/commands/create-plugin/createPlugin.ts +++ b/packages/cli/src/commands/create-plugin/createPlugin.ts @@ -25,10 +25,10 @@ import { parseOwnerIds, addCodeownersEntry, getCodeownersFilePath, -} from 'lib/codeowners'; -import { paths } from 'lib/paths'; -import { version } from 'lib/version'; -import { Task, templatingTask } from 'lib/tasks'; +} from '../../lib/codeowners'; +import { paths } from '../../lib/paths'; +import { version } from '../../lib/version'; +import { Task, templatingTask } from '../../lib/tasks'; const exec = promisify(execCb); async function checkExists(rootDir: string, id: string) { @@ -107,7 +107,7 @@ export async function addPluginDependencyToApp( packageFileJson.dependencies = sortObjectByKeys(dependencies); const newContents = `${JSON.stringify(packageFileJson, null, 2)}\n`; - await fs.writeFile(packageFile, newContents, 'utf-8').catch(error => { + await fs.writeFile(packageFile, newContents, 'utf-8').catch((error) => { throw new Error( `Failed to add plugin as dependency to app: ${packageFile}: ${error.message}`, ); @@ -119,14 +119,14 @@ export async function addPluginToApp(rootDir: string, pluginName: string) { const pluginPackage = `@backstage/plugin-${pluginName}`; const pluginNameCapitalized = pluginName .split('-') - .map(name => capitalize(name)) + .map((name) => capitalize(name)) .join(''); const pluginExport = `export { plugin as ${pluginNameCapitalized} } from '${pluginPackage}';`; const pluginsFilePath = 'packages/app/src/plugins.ts'; const pluginsFile = resolvePath(rootDir, pluginsFilePath); await Task.forItem('processing', pluginsFilePath, async () => { - await addExportStatement(pluginsFile, pluginExport).catch(error => { + await addExportStatement(pluginsFile, pluginExport).catch((error) => { throw new Error( `Failed to import plugin in app: ${pluginsFile}: ${error.message}`, ); @@ -146,7 +146,7 @@ async function buildPlugin(pluginFolder: string) { await Task.forItem('executing', command, async () => { process.chdir(pluginFolder); - await exec(command).catch(error => { + await exec(command).catch((error) => { process.stdout.write(error.stderr); process.stdout.write(error.stdout); throw new Error(`Could not execute command ${chalk.cyan(command)}`); @@ -161,7 +161,7 @@ export async function movePlugin( id: string, ) { await Task.forItem('moving', id, async () => { - await fs.move(tempDir, destination).catch(error => { + await fs.move(tempDir, destination).catch((error) => { throw new Error( `Failed to move plugin from ${tempDir} to ${destination}: ${error.message}`, ); diff --git a/packages/cli/src/commands/lint.ts b/packages/cli/src/commands/lint.ts index 2d74b4122f..07819bacfb 100644 --- a/packages/cli/src/commands/lint.ts +++ b/packages/cli/src/commands/lint.ts @@ -15,7 +15,7 @@ */ import { Command } from 'commander'; -import { run } from 'lib/run'; +import { run } from '../lib/run'; export default async (cmd: Command) => { const args = ['lint', '--max-warnings=0', '--format=codeframe']; diff --git a/packages/cli/src/commands/plugin/build.ts b/packages/cli/src/commands/plugin/build.ts index aedf39e5b4..fcda3f424b 100644 --- a/packages/cli/src/commands/plugin/build.ts +++ b/packages/cli/src/commands/plugin/build.ts @@ -17,8 +17,8 @@ import { rollup, watch, OutputOptions } from 'rollup'; import { Command } from 'commander'; import chalk from 'chalk'; -import { withCache, getDefaultCacheOptions } from 'lib/buildCache'; -import { paths } from 'lib/paths'; +import { withCache, getDefaultCacheOptions } from '../../lib/buildCache'; +import { paths } from '../../lib/paths'; import conf from './rollup.config'; function logError(error: any) { @@ -62,7 +62,7 @@ export default async (cmd: Command) => { // Instead we just wait until the user sends an interrupt signal. await new Promise(() => { const watcher = watch(conf); - watcher.on('event', event => { + watcher.on('event', (event) => { // START — the watcher is (re)starting // BUNDLE_START — building an individual bundle // BUNDLE_END — finished building a bundle diff --git a/packages/cli/src/commands/plugin/diff/handlers.ts b/packages/cli/src/commands/plugin/diff/handlers.ts index df7ca081de..32079415ea 100644 --- a/packages/cli/src/commands/plugin/diff/handlers.ts +++ b/packages/cli/src/commands/plugin/diff/handlers.ts @@ -18,7 +18,7 @@ import fs from 'fs-extra'; import chalk from 'chalk'; import { dirname } from 'path'; import { diffLines } from 'diff'; -import { paths } from 'lib/paths'; +import { paths } from '../../../lib/paths'; import { TemplateFile, PromptFunc, FileHandler } from './types'; export async function writeTargetFile(targetPath: string, contents: string) { @@ -193,8 +193,8 @@ export async function handleAllFiles( ) { for (const file of files) { const { targetPath } = file; - const fileHandler = fileHandlers.find(handler => - handler.patterns.some(pattern => + const fileHandler = fileHandlers.find((handler) => + handler.patterns.some((pattern) => typeof pattern === 'string' ? pattern === targetPath : pattern.test(targetPath), diff --git a/packages/cli/src/commands/plugin/diff/read.ts b/packages/cli/src/commands/plugin/diff/read.ts index ef981a0081..a05d7166e2 100644 --- a/packages/cli/src/commands/plugin/diff/read.ts +++ b/packages/cli/src/commands/plugin/diff/read.ts @@ -18,8 +18,8 @@ import fs from 'fs-extra'; import { relative as relativePath } from 'path'; import handlebars from 'handlebars'; import recursiveReadDir from 'recursive-readdir'; -import { paths } from 'lib/paths'; -import { version } from 'lib/version'; +import { paths } from '../../../lib/paths'; +import { version } from '../../../lib/version'; import { PluginInfo, TemplateFile } from './types'; // Reads info from the existing plugin @@ -64,9 +64,11 @@ export async function readTemplate( templateDir: string, templateVars: any, ): Promise { - const templateFilePaths = await recursiveReadDir(templateDir).catch(error => { - throw new Error(`Failed to read template directory: ${error.message}`); - }); + const templateFilePaths = await recursiveReadDir(templateDir).catch( + (error) => { + throw new Error(`Failed to read template directory: ${error.message}`); + }, + ); const templateFiles = new Array(); for (const templateFile of templateFilePaths) { diff --git a/packages/cli/src/commands/plugin/rollup.config.ts b/packages/cli/src/commands/plugin/rollup.config.ts index 95077e2df3..36b43bf5a7 100644 --- a/packages/cli/src/commands/plugin/rollup.config.ts +++ b/packages/cli/src/commands/plugin/rollup.config.ts @@ -22,7 +22,7 @@ import postcss from 'rollup-plugin-postcss'; import imageFiles from 'rollup-plugin-image-files'; import json from '@rollup/plugin-json'; import { RollupWatchOptions } from 'rollup'; -import { paths } from 'lib/paths'; +import { paths } from '../../lib/paths'; export default { input: 'src/index.ts', diff --git a/packages/cli/src/commands/plugin/serve/index.ts b/packages/cli/src/commands/plugin/serve/index.ts index 00c7728b63..9bdd46dc84 100644 --- a/packages/cli/src/commands/plugin/serve/index.ts +++ b/packages/cli/src/commands/plugin/serve/index.ts @@ -15,7 +15,7 @@ */ import { startDevServer } from './server'; -import { watchDeps } from 'lib/watchDeps'; +import { watchDeps } from '../../../lib/watchDeps'; export default async () => { await watchDeps({ build: true }); diff --git a/packages/cli/src/commands/plugin/serve/paths.ts b/packages/cli/src/commands/plugin/serve/paths.ts index b44a7bff74..56c3f6ffb7 100644 --- a/packages/cli/src/commands/plugin/serve/paths.ts +++ b/packages/cli/src/commands/plugin/serve/paths.ts @@ -15,7 +15,7 @@ */ import { existsSync } from 'fs'; -import { paths } from 'lib/paths'; +import { paths } from '../../../lib/paths'; export function getPaths() { const resolveTargetModule = (path: string) => { diff --git a/packages/cli/src/commands/plugin/testCommand.ts b/packages/cli/src/commands/plugin/testCommand.ts index 333af5494e..df031d8e89 100644 --- a/packages/cli/src/commands/plugin/testCommand.ts +++ b/packages/cli/src/commands/plugin/testCommand.ts @@ -15,7 +15,7 @@ */ import { Command } from 'commander'; -import { run } from 'lib/run'; +import { run } from '../../lib/run'; export default async (cmd: Command) => { const args = ['test']; diff --git a/packages/cli/src/commands/remove-plugin/removePlugin.test.ts b/packages/cli/src/commands/remove-plugin/removePlugin.test.ts index 17962d10b9..465260008d 100644 --- a/packages/cli/src/commands/remove-plugin/removePlugin.test.ts +++ b/packages/cli/src/commands/remove-plugin/removePlugin.test.ts @@ -17,13 +17,13 @@ import fse from 'fs-extra'; import path from 'path'; import os from 'os'; -import { paths } from 'lib/paths'; +import { paths } from '../../lib/paths'; import { addExportStatement, capitalize, createTemporaryPluginFolder, } from '../create-plugin/createPlugin'; -import { addCodeownersEntry } from 'lib/codeowners'; +import { addCodeownersEntry } from '../../lib/codeowners'; import { removeReferencesFromAppPackage, removeReferencesFromPluginsFile, @@ -39,10 +39,7 @@ const testPluginPackage = `${BACKSTAGE}/plugin-${testPluginName}`; const tempDir = path.join(os.tmpdir(), 'remove-plugin-test'); const removeEmptyLines = (file: string): string => - file - .split('\n') - .filter(Boolean) - .join('\n'); + file.split('\n').filter(Boolean).join('\n'); const createTestPackageFile = async ( testFilePath: string, @@ -69,7 +66,7 @@ const createTestPluginFile = async ( fse.copyFileSync(pluginsFilePath, testFilePath); const pluginNameCapitalized = testPluginName .split('-') - .map(name => capitalize(name)) + .map((name) => capitalize(name)) .join(''); const exportStatement = `export { default as ${pluginNameCapitalized}} from @backstage/plugin-${testPluginName}`; addExportStatement(testFilePath, exportStatement); diff --git a/packages/cli/src/commands/remove-plugin/removePlugin.ts b/packages/cli/src/commands/remove-plugin/removePlugin.ts index 1b8447fade..cf4cc73f20 100644 --- a/packages/cli/src/commands/remove-plugin/removePlugin.ts +++ b/packages/cli/src/commands/remove-plugin/removePlugin.ts @@ -17,9 +17,9 @@ import fse from 'fs-extra'; import path from 'path'; import chalk from 'chalk'; import inquirer, { Answers, Question } from 'inquirer'; -import { getCodeownersFilePath } from 'lib/codeowners'; -import { paths } from 'lib/paths'; -import { Task } from 'lib/tasks'; +import { getCodeownersFilePath } from '../../lib/codeowners'; +import { paths } from '../../lib/paths'; +import { Task } from '../../lib/tasks'; // import os from 'os'; const BACKSTAGE = '@backstage'; @@ -85,7 +85,7 @@ const removeAllStatementsContainingID = async (file: string, ID: string) => { const contentAfterRemoval = originalContent .split('\n') .filter(Boolean) // get rid of empty lines - .filter(statement => { + .filter((statement) => { return !statement.includes(`${ID}`); }) // get rid of lines with pluginName .concat(['']) // newline at end of line @@ -105,7 +105,7 @@ export const removeReferencesFromPluginsFile = async ( ) => { const pluginNameCapitalized = pluginName .split('-') - .map(name => capitalize(name)) + .map((name) => capitalize(name)) .join(''); await Task.forItem('removing', 'export references', async () => { diff --git a/packages/cli/src/commands/testCommand.ts b/packages/cli/src/commands/testCommand.ts index 4d567169dc..9969aee3b4 100644 --- a/packages/cli/src/commands/testCommand.ts +++ b/packages/cli/src/commands/testCommand.ts @@ -15,8 +15,8 @@ */ import { Command } from 'commander'; -import { paths } from 'lib/paths'; -import { runCheck } from 'lib/run'; +import { paths } from '../lib/paths'; +import { runCheck } from '../lib/run'; function includesAnyOf(hayStack: string[], ...needles: string[]) { for (const needle of needles) { diff --git a/packages/cli/src/commands/watch-deps/index.ts b/packages/cli/src/commands/watch-deps/index.ts index ec9e4be58f..61f403883c 100644 --- a/packages/cli/src/commands/watch-deps/index.ts +++ b/packages/cli/src/commands/watch-deps/index.ts @@ -15,9 +15,9 @@ */ import { Command } from 'commander'; -import { run } from 'lib/run'; -import { createLogPipe } from 'lib/logging'; -import { watchDeps, Options } from 'lib/watchDeps'; +import { run } from '../../lib/run'; +import { createLogPipe } from '../../lib/logging'; +import { watchDeps, Options } from '../../lib/watchDeps'; /* * The watch-deps command is meant to improve iteration speed while working in a large monorepo diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 6c6aec3776..e20cef2615 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -16,8 +16,8 @@ import program from 'commander'; import chalk from 'chalk'; -import { exitWithError } from 'lib/errors'; -import { version } from 'lib/version'; +import { exitWithError } from './lib/errors'; +import { version } from './lib/version'; const main = (argv: string[]) => { program.name('backstage-cli').version(version); @@ -25,68 +25,68 @@ const main = (argv: string[]) => { program .command('create-app') .description('Creates a new app in a new directory') - .action(actionHandler(() => require('commands/create-app/createApp'))); + .action(actionHandler(() => require('./commands/create-app/createApp'))); program .command('app:build') .description('Build an app for a production release') - .action(actionHandler(() => require('commands/app/build'))); + .action(actionHandler(() => require('./commands/app/build'))); program .command('app:serve') .description('Serve an app for local development') - .action(actionHandler(() => require('commands/app/serve'))); + .action(actionHandler(() => require('./commands/app/serve'))); program .command('create-plugin') .description('Creates a new plugin in the current repository') .action( - actionHandler(() => require('commands/create-plugin/createPlugin')), + actionHandler(() => require('./commands/create-plugin/createPlugin')), ); program .command('remove-plugin') .description('Removes plugin in the current repository') .action( - actionHandler(() => require('commands/remove-plugin/removePlugin')), + actionHandler(() => require('./commands/remove-plugin/removePlugin')), ); program .command('plugin:build') .option('--watch', 'Enable watch mode') .description('Build a plugin') - .action(actionHandler(() => require('commands/plugin/build'))); + .action(actionHandler(() => require('./commands/plugin/build'))); program .command('plugin:serve') .description('Serves the dev/ folder of a plugin') - .action(actionHandler(() => require('commands/plugin/serve'))); + .action(actionHandler(() => require('./commands/plugin/serve'))); program .command('plugin:diff') .option('--check', 'Fail if changes are required') .option('--yes', 'Apply all changes') .description('Diff an existing plugin with the creation template') - .action(actionHandler(() => require('commands/plugin/diff'))); + .action(actionHandler(() => require('./commands/plugin/diff'))); program .command('lint') .option('--fix', 'Attempt to automatically fix violations') .description('Lint a package') - .action(actionHandler(() => require('commands/lint'))); + .action(actionHandler(() => require('./commands/lint'))); program .command('test') .allowUnknownOption(true) // Allows the command to run, but we still need to parse raw args .helpOption(', --backstage-cli-help') // Let Jest handle help .description('Run tests, forwarding args to Jest, defaulting to watch mode') - .action(actionHandler(() => require('commands/testCommand'))); + .action(actionHandler(() => require('./commands/testCommand'))); program .command('watch-deps') .option('--build', 'Build all dependencies on startup') .description('Watch all dependencies while running another command') - .action(actionHandler(() => require('commands/watch-deps'))); + .action(actionHandler(() => require('./commands/watch-deps'))); program .command('build-cache') @@ -103,12 +103,12 @@ const main = (argv: string[]) => { 'Cache dir', '/node_modules/.cache/backstage-builds', ) - .action(actionHandler(() => require('commands/build-cache'))); + .action(actionHandler(() => require('./commands/build-cache'))); program .command('clean') .description('Delete cache directories') - .action(actionHandler(() => require('commands/clean/clean'))); + .action(actionHandler(() => require('./commands/clean/clean'))); program.on('command:*', () => { console.log(); @@ -142,7 +142,7 @@ function actionHandler( }; } -process.on('unhandledRejection', rejection => { +process.on('unhandledRejection', (rejection) => { if (rejection instanceof Error) { exitWithError(rejection); } else { diff --git a/packages/cli/src/lib/buildCache/cache.ts b/packages/cli/src/lib/buildCache/cache.ts index 8ba2d8851d..d49eedaba9 100644 --- a/packages/cli/src/lib/buildCache/cache.ts +++ b/packages/cli/src/lib/buildCache/cache.ts @@ -16,11 +16,11 @@ import fs from 'fs-extra'; import { resolve as resolvePath, relative as relativePath } from 'path'; -import { runPlain, runCheck } from 'lib/run'; +import { runPlain, runCheck } from '../run'; import { Options } from './options'; import { extractArchive, createArchive } from './archive'; -import { paths } from 'lib/paths'; -import { version, isDev } from 'lib/version'; +import { paths } from '../paths'; +import { version, isDev } from '../version'; const INFO_FILE = '.backstage-build-cache'; @@ -127,9 +127,7 @@ export class Cache { await writeCacheInfo(outputDir, { key }); const timestamp = new Date().toISOString().replace(/-|:|\..*/g, ''); - const rand = Math.random() - .toString(36) - .slice(2, 6); + const rand = Math.random().toString(36).slice(2, 6); const archiveName = `cache-${timestamp}-${rand}.tgz`; const archivePath = resolvePath(location, archiveName); @@ -137,7 +135,7 @@ export class Cache { const { entries = [] } = (await readCacheInfo(location)) ?? {}; // Check if there's already aan entry for this key, in that case we just wanna bump it - const entryIndex = entries.findIndex(e => compareKeys(e.key, key)); + const entryIndex = entries.findIndex((e) => compareKeys(e.key, key)); if (entryIndex !== -1) { const [existingEntry] = entries.splice(entryIndex, 1); entries.unshift(existingEntry); @@ -167,7 +165,7 @@ export class Cache { return { hit: true, archive }; } - const matchingEntry = this.entries.find(e => compareKeys(e.key, key)); + const matchingEntry = this.entries.find((e) => compareKeys(e.key, key)); if (!matchingEntry) { return { hit: false, archive }; } diff --git a/packages/cli/src/lib/buildCache/options.ts b/packages/cli/src/lib/buildCache/options.ts index 5edb46e913..9a6a379fce 100644 --- a/packages/cli/src/lib/buildCache/options.ts +++ b/packages/cli/src/lib/buildCache/options.ts @@ -16,7 +16,7 @@ import { resolve as resolvePath } from 'path'; import { Command } from 'commander'; -import { paths } from 'lib/paths'; +import { paths } from '../paths'; const DEFAULT_CACHE_DIR = '/node_modules/.cache/backstage-builds'; const DEFAULT_MAX_ENTRIES = 10; diff --git a/packages/cli/src/lib/watchDeps/compiler.ts b/packages/cli/src/lib/watchDeps/compiler.ts index c8a0eb7d78..5ea8efc3e6 100644 --- a/packages/cli/src/lib/watchDeps/compiler.ts +++ b/packages/cli/src/lib/watchDeps/compiler.ts @@ -15,14 +15,14 @@ */ import { spawn } from 'child_process'; -import { LogPipe } from 'lib/logging'; +import { LogPipe } from '../logging'; import chalk from 'chalk'; import { Package } from './packages'; export function startCompiler(pkg: Package, logPipe: LogPipe) { // First we figure out which yarn script is a available, falling back to "build --watch" const scriptName = ['build:watch', 'watch'].find( - script => script in pkg.scripts, + (script) => script in pkg.scripts, ); const args = scriptName ? [scriptName] : ['build', '--watch']; @@ -40,7 +40,7 @@ export function startCompiler(pkg: Package, logPipe: LogPipe) { watch.stderr.on('data', logErr); const promise = new Promise((resolve, reject) => { - watch.on('error', error => { + watch.on('error', (error) => { reject(error); }); diff --git a/packages/cli/src/lib/watchDeps/logger.ts b/packages/cli/src/lib/watchDeps/logger.ts index 7f3862509a..59eb400301 100644 --- a/packages/cli/src/lib/watchDeps/logger.ts +++ b/packages/cli/src/lib/watchDeps/logger.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { createLogPipe } from 'lib/logging'; +import { createLogPipe } from '../logging'; export type ColorFunc = (msg: string) => string; diff --git a/packages/cli/src/lib/watchDeps/packages.ts b/packages/cli/src/lib/watchDeps/packages.ts index 4eee0f3069..7a45524b45 100644 --- a/packages/cli/src/lib/watchDeps/packages.ts +++ b/packages/cli/src/lib/watchDeps/packages.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { paths } from 'lib/paths'; +import { paths } from '../paths'; const LernaProject = require('@lerna/project'); const PackageGraph = require('@lerna/package-graph'); diff --git a/packages/cli/src/lib/watchDeps/watchDeps.ts b/packages/cli/src/lib/watchDeps/watchDeps.ts index e4b5d1e4b3..c986749d3b 100644 --- a/packages/cli/src/lib/watchDeps/watchDeps.ts +++ b/packages/cli/src/lib/watchDeps/watchDeps.ts @@ -20,8 +20,8 @@ import { createLogPipeFactory } from './logger'; import { findAllDeps } from './packages'; import { startWatcher, startPackageWatcher } from './watcher'; import { startCompiler } from './compiler'; -import { run } from 'lib/run'; -import { paths } from 'lib/paths'; +import { run } from '../run'; +import { paths } from '../paths'; const PACKAGE_BLACKLIST = [ // We never want to watch for changes in the cli, but all packages will depend on it. @@ -66,8 +66,8 @@ export async function watchDeps(options: Options = {}) { } // We lazily watch all our deps, as in we don't start the actual watch compiler until a change is detected - const watcher = await startWatcher(deps, WATCH_LOCATIONS, pkg => { - startCompiler(pkg, createLogPipe(pkg.name)).promise.catch(error => { + const watcher = await startWatcher(deps, WATCH_LOCATIONS, (pkg) => { + startCompiler(pkg, createLogPipe(pkg.name)).promise.catch((error) => { process.stderr.write(`${error}\n`); }); }); diff --git a/packages/cli/src/lib/watchDeps/watcher.ts b/packages/cli/src/lib/watchDeps/watcher.ts index c6c4487d0a..bcfe766b63 100644 --- a/packages/cli/src/lib/watchDeps/watcher.ts +++ b/packages/cli/src/lib/watchDeps/watcher.ts @@ -18,7 +18,7 @@ import { resolve as resolvePath } from 'path'; import chalk from 'chalk'; import chokidar from 'chokidar'; import { Package } from './packages'; -import { createLogFunc } from 'lib/logging'; +import { createLogFunc } from '../logging'; export type Watcher = { update(newPackages: Package[]): Promise; @@ -42,7 +42,7 @@ export async function startWatcher( let signalled = false; watchedPackageLocations.add(pkg.location); - const watchLocations = paths.map(path => resolvePath(pkg.location, path)); + const watchLocations = paths.map((path) => resolvePath(pkg.location, path)); const watcher = chokidar .watch(watchLocations, { cwd: pkg.location, diff --git a/packages/cli/templates/default-app/plugins/welcome/package.json.hbs b/packages/cli/templates/default-app/plugins/welcome/package.json.hbs index d936bb0784..aa454f68e7 100644 --- a/packages/cli/templates/default-app/plugins/welcome/package.json.hbs +++ b/packages/cli/templates/default-app/plugins/welcome/package.json.hbs @@ -9,12 +9,6 @@ "lint": "backstage-cli lint", "test": "backstage-cli test" }, - "devDependencies": { - "@backstage/cli": "^{{version}}", - "@testing-library/jest-dom": "^4.2.4", - "@testing-library/react": "^9.3.2", - "@types/testing-library__jest-dom": "5.0.2" - }, "dependencies": { "@backstage/core": "^{{version}}", "@backstage/theme": "^{{version}}", @@ -24,6 +18,12 @@ "react-dom": "16.13.1", "react-router-dom": "5.1.2" }, + "devDependencies": { + "@backstage/cli": "^{{version}}", + "@testing-library/jest-dom": "^4.2.4", + "@testing-library/react": "^9.3.2", + "@types/testing-library__jest-dom": "5.0.2" + }, "files": [ "dist" ] diff --git a/packages/cli/templates/default-app/plugins/welcome/tsconfig.json b/packages/cli/templates/default-app/plugins/welcome/tsconfig.json index 7b73db2f0f..5a3931ffce 100644 --- a/packages/cli/templates/default-app/plugins/welcome/tsconfig.json +++ b/packages/cli/templates/default-app/plugins/welcome/tsconfig.json @@ -1,7 +1,5 @@ { "extends": "../../tsconfig.json", "include": ["src"], - "compilerOptions": { - "baseUrl": "src" - } + "compilerOptions": {} } diff --git a/packages/cli/templates/default-plugin/package.json.hbs b/packages/cli/templates/default-plugin/package.json.hbs index dad663ce2c..efa07e61d3 100644 --- a/packages/cli/templates/default-plugin/package.json.hbs +++ b/packages/cli/templates/default-plugin/package.json.hbs @@ -11,16 +11,6 @@ "test": "backstage-cli test", "clean": "backstage-cli clean" }, - "devDependencies": { - "@backstage/cli": "^{{version}}", - "@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": "^{{version}}", "@backstage/theme": "^{{version}}", @@ -31,6 +21,16 @@ "react-dom": "16.13.1", "react-use": "^13.0.0" }, + "devDependencies": { + "@backstage/cli": "^{{version}}", + "@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" + }, "files": [ "dist" ] diff --git a/packages/cli/templates/default-plugin/tsconfig.json b/packages/cli/templates/default-plugin/tsconfig.json index 7b73db2f0f..5a3931ffce 100644 --- a/packages/cli/templates/default-plugin/tsconfig.json +++ b/packages/cli/templates/default-plugin/tsconfig.json @@ -1,7 +1,5 @@ { "extends": "../../tsconfig.json", "include": ["src"], - "compilerOptions": { - "baseUrl": "src" - } + "compilerOptions": {} } diff --git a/packages/cli/tsconfig.build.json b/packages/cli/tsconfig.build.json index 116632b612..1ef5cdace5 100644 --- a/packages/cli/tsconfig.build.json +++ b/packages/cli/tsconfig.build.json @@ -2,7 +2,7 @@ "extends": "./tsconfig.json", "exclude": ["**/*.test.*"], "compilerOptions": { - "outFile": "dist/index.js", - "module": "amd" + "outDir": "dist", + "module": "CommonJS" } } diff --git a/packages/cli/tsconfig.json b/packages/cli/tsconfig.json index 7b73db2f0f..5a3931ffce 100644 --- a/packages/cli/tsconfig.json +++ b/packages/cli/tsconfig.json @@ -1,7 +1,5 @@ { "extends": "../../tsconfig.json", "include": ["src"], - "compilerOptions": { - "baseUrl": "src" - } + "compilerOptions": {} } diff --git a/packages/core/package.json b/packages/core/package.json index 107cba0196..5918fd6008 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -24,20 +24,6 @@ "test": "backstage-cli test", "clean": "backstage-cli clean" }, - "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.4", - "@backstage/test-utils": "0.1.1-alpha.4", - "@backstage/test-utils-core": "^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/classnames": "^2.2.9", - "@types/google-protobuf": "^3.7.2", - "@types/jest": "^24.0.0", - "@types/node": "^12.0.0", - "@types/react-helmet": "^5.0.15", - "@types/react-sparklines": "^1.7.0" - }, "dependencies": { "@backstage/theme": "^0.1.1-alpha.4", "@material-ui/core": "^4.9.1", @@ -56,6 +42,20 @@ "react-router-dom": "^5.1.2", "react-sparklines": "^1.7.0" }, + "devDependencies": { + "@backstage/cli": "^0.1.1-alpha.4", + "@backstage/test-utils": "0.1.1-alpha.4", + "@backstage/test-utils-core": "^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/classnames": "^2.2.9", + "@types/google-protobuf": "^3.7.2", + "@types/jest": "^24.0.0", + "@types/node": "^12.0.0", + "@types/react-helmet": "^5.0.15", + "@types/react-sparklines": "^1.7.0" + }, "files": [ "dist" ] diff --git a/packages/core/src/api/apis/definitions/featureFlags.ts b/packages/core/src/api/apis/definitions/featureFlags.ts index 5d6a134f84..926fe091d5 100644 --- a/packages/core/src/api/apis/definitions/featureFlags.ts +++ b/packages/core/src/api/apis/definitions/featureFlags.ts @@ -19,7 +19,7 @@ import { UserFlags, FeatureFlagsRegistry, FeatureFlagsRegistryItem, -} from 'api/app/FeatureFlags'; +} from '../../app/FeatureFlags'; /** * The feature flags API is used to toggle functionality to users across plugins and Backstage. diff --git a/packages/core/src/api/app/AppBuilder.tsx b/packages/core/src/api/app/AppBuilder.tsx index 94d6df1b3d..f65482b996 100644 --- a/packages/core/src/api/app/AppBuilder.tsx +++ b/packages/core/src/api/app/AppBuilder.tsx @@ -18,9 +18,9 @@ import React, { ComponentType } from 'react'; import { Route, Switch, Redirect } from 'react-router-dom'; import { AppContextProvider } from './AppContext'; import { App } from './types'; -import BackstagePlugin from 'api/plugin/Plugin'; +import BackstagePlugin from '../plugin/Plugin'; import { FeatureFlagsRegistryItem } from './FeatureFlags'; -import { featureFlagsApiRef } from 'api/apis/definitions/featureFlags'; +import { featureFlagsApiRef } from '../apis/definitions/featureFlags'; import ErrorPage from '../../layout/ErrorPage'; import { @@ -28,8 +28,8 @@ import { SystemIcons, SystemIconKey, defaultSystemIcons, -} from 'icons'; -import { ApiHolder, ApiProvider } from 'api/apis'; +} from '../../icons'; +import { ApiHolder, ApiProvider } from '../apis'; import LoginPage from './LoginPage'; class AppImpl implements App { diff --git a/packages/core/src/api/app/FeatureFlags.test.tsx b/packages/core/src/api/app/FeatureFlags.test.tsx index 38fe457781..5822d05be8 100644 --- a/packages/core/src/api/app/FeatureFlags.test.tsx +++ b/packages/core/src/api/app/FeatureFlags.test.tsx @@ -18,7 +18,7 @@ import { FeatureFlags as FeatureFlagsImpl } from './FeatureFlags'; import { FeatureFlagState, FeatureFlagsApi, -} from 'api/apis/definitions/featureFlags'; +} from '../apis/definitions/featureFlags'; describe('FeatureFlags', () => { beforeEach(() => { @@ -150,7 +150,7 @@ describe('FeatureFlags', () => { it('should get the correct values', () => { const getByName = (name: string) => - featureFlags.getRegisteredFlags().find(flag => flag.name === name); + featureFlags.getRegisteredFlags().find((flag) => flag.name === name); expect(getByName('registered-flag-0')).toBeUndefined(); expect(getByName('registered-flag-1')).toEqual({ diff --git a/packages/core/src/api/app/FeatureFlags.tsx b/packages/core/src/api/app/FeatureFlags.tsx index fcbefedb3e..63c1b19d88 100644 --- a/packages/core/src/api/app/FeatureFlags.tsx +++ b/packages/core/src/api/app/FeatureFlags.tsx @@ -14,11 +14,11 @@ * limitations under the License. */ -import { FeatureFlagName } from 'api/plugin/types'; +import { FeatureFlagName } from '../plugin/types'; import { FeatureFlagState, FeatureFlagsApi, -} from 'api/apis/definitions/featureFlags'; +} from '../apis/definitions/featureFlags'; /** * Helper method for validating compatibility and flag name. @@ -130,12 +130,12 @@ export interface FeatureFlagsRegistryItem { export class FeatureFlagsRegistry extends Array { static from(entries: FeatureFlagsRegistryItem[]) { - Array.from(entries).forEach(entry => validateFlagName(entry.name)); + Array.from(entries).forEach((entry) => validateFlagName(entry.name)); return new FeatureFlagsRegistry(...entries); } push(...entries: FeatureFlagsRegistryItem[]): number { - Array.from(entries).forEach(entry => validateFlagName(entry.name)); + Array.from(entries).forEach((entry) => validateFlagName(entry.name)); return super.push(...entries); } @@ -146,7 +146,7 @@ export class FeatureFlagsRegistry extends Array { )[] ): FeatureFlagsRegistryItem[] { const _concat = super.concat(...entries); - Array.from(_concat).forEach(entry => validateFlagName(entry.name)); + Array.from(_concat).forEach((entry) => validateFlagName(entry.name)); return _concat; } diff --git a/packages/core/src/api/app/LoginPage/LoginPage.tsx b/packages/core/src/api/app/LoginPage/LoginPage.tsx index 9176c4c522..07160e750c 100644 --- a/packages/core/src/api/app/LoginPage/LoginPage.tsx +++ b/packages/core/src/api/app/LoginPage/LoginPage.tsx @@ -16,10 +16,10 @@ import React, { FC, useState } from 'react'; import { GitHub as GitHubIcon } from '@material-ui/icons'; -import Page from 'layout/Page'; -import Header from 'layout/Header'; -import Content from 'layout/Content/Content'; -import ContentHeader from 'layout/ContentHeader/ContentHeader'; +import Page from '../../../layout/Page'; +import Header from '../../../layout/Header'; +import Content from '../../../layout/Content/Content'; +import ContentHeader from '../../../layout/ContentHeader/ContentHeader'; import { Grid, Typography, @@ -29,7 +29,7 @@ import { ListItem, Link, } from '@material-ui/core'; -import InfoCard from 'layout/InfoCard/InfoCard'; +import InfoCard from '../../../layout/InfoCard/InfoCard'; enum AuthType { GitHub, @@ -72,11 +72,11 @@ const LoginPage: FC<{}> = () => { 'Content-Type': 'application/x-www-form-urlencoded', }), }) - .then(response => { + .then((response) => { if (response.status === 200) return response.json(); throw Error(`${response.status} ${response.statusText}`); }) - .then(data => { + .then((data) => { const info = { username: username, token: token, diff --git a/packages/core/src/api/plugin/Plugin.tsx b/packages/core/src/api/plugin/Plugin.tsx index a8b694ae8d..3d067c66ad 100644 --- a/packages/core/src/api/plugin/Plugin.tsx +++ b/packages/core/src/api/plugin/Plugin.tsx @@ -21,7 +21,7 @@ import { RouteOptions, FeatureFlagName, } from './types'; -import { validateBrowserCompat, validateFlagName } from 'api/app/FeatureFlags'; +import { validateBrowserCompat, validateFlagName } from '../app/FeatureFlags'; export type PluginConfig = { id: string; diff --git a/packages/core/src/components/CopyTextButton/CopyTextButton.stories.tsx b/packages/core/src/components/CopyTextButton/CopyTextButton.stories.tsx index e8e1317e4e..80c11f6b4a 100644 --- a/packages/core/src/components/CopyTextButton/CopyTextButton.stories.tsx +++ b/packages/core/src/components/CopyTextButton/CopyTextButton.stories.tsx @@ -16,7 +16,7 @@ import React from 'react'; import CopyTextButton from '.'; -import { ApiProvider, errorApiRef, ApiRegistry, ErrorApi } from 'api'; +import { ApiProvider, errorApiRef, ApiRegistry, ErrorApi } from '../../api'; export default { title: 'CopyTextButton', diff --git a/packages/core/src/components/CopyTextButton/CopyTextButton.test.tsx b/packages/core/src/components/CopyTextButton/CopyTextButton.test.tsx index 28aaf2f0c0..695a700738 100644 --- a/packages/core/src/components/CopyTextButton/CopyTextButton.test.tsx +++ b/packages/core/src/components/CopyTextButton/CopyTextButton.test.tsx @@ -18,7 +18,7 @@ import React from 'react'; import { render } from '@testing-library/react'; import { wrapInThemedTestApp } from '@backstage/test-utils'; import CopyTextButton from './CopyTextButton'; -import { ApiRegistry, errorApiRef, ApiProvider, ErrorApi } from 'api'; +import { ApiRegistry, errorApiRef, ApiProvider, ErrorApi } from '../../api'; jest.mock('popper.js', () => { const PopperJS = jest.requireActual('popper.js'); diff --git a/packages/core/src/components/CopyTextButton/CopyTextButton.tsx b/packages/core/src/components/CopyTextButton/CopyTextButton.tsx index 62295eb0ce..5af62f4380 100644 --- a/packages/core/src/components/CopyTextButton/CopyTextButton.tsx +++ b/packages/core/src/components/CopyTextButton/CopyTextButton.tsx @@ -19,9 +19,9 @@ import { IconButton, makeStyles, Tooltip } from '@material-ui/core'; import PropTypes from 'prop-types'; import CopyIcon from '@material-ui/icons/FileCopy'; import { BackstageTheme } from '@backstage/theme'; -import { errorApiRef, useApi } from 'api'; +import { errorApiRef, useApi } from '../../api'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles((theme) => ({ button: { '&:hover': { backgroundColor: theme.palette.highlight, @@ -56,7 +56,7 @@ const defaultProps = { tooltipText: 'Text copied to clipboard', }; -const CopyTextButton: FC = props => { +const CopyTextButton: FC = (props) => { const { text, tooltipDelay, tooltipText } = { ...defaultProps, ...props, @@ -66,7 +66,7 @@ const CopyTextButton: FC = props => { const inputRef = useRef(null); const [open, setOpen] = useState(false); - const handleCopyClick: MouseEventHandler = e => { + const handleCopyClick: MouseEventHandler = (e) => { e.stopPropagation(); setOpen(true); diff --git a/packages/core/src/components/ProgressBars/ProgressCard.tsx b/packages/core/src/components/ProgressBars/ProgressCard.tsx index 9b4a0d79e0..66dda771c3 100644 --- a/packages/core/src/components/ProgressBars/ProgressCard.tsx +++ b/packages/core/src/components/ProgressBars/ProgressCard.tsx @@ -16,7 +16,7 @@ import React, { FC } from 'react'; import { makeStyles } from '@material-ui/core'; -import InfoCard from 'layout/InfoCard'; +import InfoCard from '../../layout/InfoCard'; import { Props as BottomLinkProps } from '../../layout/BottomLink'; import CircleProgress from './CircleProgress'; @@ -36,7 +36,7 @@ const useStyles = makeStyles({ }, }); -const ProgressCard: FC = props => { +const ProgressCard: FC = (props) => { const classes = useStyles(props); const { title, subheader, progress, deepLink, variant } = props; diff --git a/packages/core/src/components/SimpleStepper/SimpleStepper.test.tsx b/packages/core/src/components/SimpleStepper/SimpleStepper.test.tsx index f07ceca6ff..3015da3029 100644 --- a/packages/core/src/components/SimpleStepper/SimpleStepper.test.tsx +++ b/packages/core/src/components/SimpleStepper/SimpleStepper.test.tsx @@ -23,6 +23,33 @@ const getTextInSlide = (rendered: any, index: number) => within(rendered.getByTestId(`step${index}`)).getByText; describe('Stepper', () => { + it('Maintains state history', async () => { + const rendered = render( + wrapInTestApp( + + +
step0
+
+ +
step1
+
+ +
step2
+
+
, + ), + ); + + fireEvent.click(getTextInSlide(rendered, 0)('Next') as Node); + expect(rendered.getByText('step1')).toBeInTheDocument(); + + fireEvent.click(getTextInSlide(rendered, 1)('Back') as Node); + expect(rendered.getByText('step0')).toBeInTheDocument(); + + fireEvent.click(getTextInSlide(rendered, 0)('Next') as Node); + expect(rendered.getByText('step1')).toBeInTheDocument(); + }); + it('Handles nextStep property', async () => { const rendered = render( wrapInTestApp( diff --git a/packages/core/src/components/SimpleStepper/SimpleStepper.tsx b/packages/core/src/components/SimpleStepper/SimpleStepper.tsx index a13ad6b5ee..b55d70e9a0 100644 --- a/packages/core/src/components/SimpleStepper/SimpleStepper.tsx +++ b/packages/core/src/components/SimpleStepper/SimpleStepper.tsx @@ -42,7 +42,7 @@ export interface StepperProps { const Stepper: FC = ({ children, elevated, onStepChange }) => { const [stepIndex, setStepIndex] = useState(0); - const [stepHistory, setStepHistory] = useState([]); + const [stepHistory, setStepHistory] = useState([0]); const steps: React.ReactNode[] = []; let endStep; diff --git a/packages/core/src/components/Status/Status.stories.tsx b/packages/core/src/components/Status/Status.stories.tsx index 33a8e51e65..7a6a58caa8 100644 --- a/packages/core/src/components/Status/Status.stories.tsx +++ b/packages/core/src/components/Status/Status.stories.tsx @@ -24,8 +24,8 @@ import { StatusRunning, StatusWarning, } from './Status'; -import Table from 'components/Table'; -import InfoCard from 'layout/InfoCard'; +import Table from '../Table'; +import InfoCard from '../../layout/InfoCard'; export default { title: 'Status', diff --git a/packages/core/src/components/Table/Table.stories.tsx b/packages/core/src/components/Table/Table.stories.tsx index b1a886ddc8..7164f9b730 100644 --- a/packages/core/src/components/Table/Table.stories.tsx +++ b/packages/core/src/components/Table/Table.stories.tsx @@ -22,7 +22,9 @@ export default { component: Table, }; -const generateTestData: (number: number) => Array<{}> = (rows = 20) => { +const containerStyle = { width: 850 }; + +const generateTestData: (number: number) => Array<{}> = (rows = 10) => { const data: Array<{}> = []; while (data.length <= rows) { data.push({ @@ -37,7 +39,7 @@ const generateTestData: (number: number) => Array<{}> = (rows = 20) => { return data; }; -const testData100 = generateTestData(100); +const testData10 = generateTestData(10); export const DefaultTable = () => { const columns: TableColumn[] = [ @@ -63,12 +65,14 @@ export const DefaultTable = () => { ]; return ( - +
+
+ ); }; @@ -96,11 +100,13 @@ export const HiddenSearchTable = () => { ]; return ( -
+
+
+ ); }; @@ -138,6 +144,8 @@ export const SubvalueTable = () => { ]; return ( -
+
+
+ ); }; diff --git a/packages/core/src/components/TrendLine/TrendLine.stories.tsx b/packages/core/src/components/TrendLine/TrendLine.stories.tsx index 562feeff80..506fc4e387 100644 --- a/packages/core/src/components/TrendLine/TrendLine.stories.tsx +++ b/packages/core/src/components/TrendLine/TrendLine.stories.tsx @@ -16,8 +16,8 @@ import React from 'react'; import TrendLine from '.'; -import Table from 'components/Table'; -import InfoCard from 'layout/InfoCard'; +import Table from '../Table'; +import InfoCard from '../../layout/InfoCard'; export default { title: 'TrendLine', diff --git a/packages/core/src/components/WarningPanel/WarningPanel.tsx b/packages/core/src/components/WarningPanel/WarningPanel.tsx index a3e6ed6c78..aa173d2174 100644 --- a/packages/core/src/components/WarningPanel/WarningPanel.tsx +++ b/packages/core/src/components/WarningPanel/WarningPanel.tsx @@ -19,7 +19,7 @@ import { Typography, makeStyles } from '@material-ui/core'; import { BackstageTheme } from '@backstage/theme'; import ErrorOutline from '@material-ui/icons/ErrorOutline'; -const useErrorOutlineStyles = makeStyles(theme => ({ +const useErrorOutlineStyles = makeStyles((theme) => ({ root: { marginRight: theme.spacing(1), fill: theme.palette.warningText, @@ -30,7 +30,7 @@ const ErrorOutlineStyled = () => { return ; }; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles((theme) => ({ message: { display: 'flex', flexDirection: 'column', @@ -62,7 +62,7 @@ type Props = { title?: string; }; -const WarningPanel: FC = props => { +const WarningPanel: FC = (props) => { const classes = useStyles(props); const { title, message, children } = props; return ( @@ -74,7 +74,9 @@ const WarningPanel: FC = props => { {message && ( - {message} + + {message} + )} {children} diff --git a/packages/core/src/icons/icons.tsx b/packages/core/src/icons/icons.tsx index a8debf56b4..ca3ef32859 100644 --- a/packages/core/src/icons/icons.tsx +++ b/packages/core/src/icons/icons.tsx @@ -18,7 +18,7 @@ import { SvgIconProps } from '@material-ui/core'; import PeopleIcon from '@material-ui/icons/People'; import PersonIcon from '@material-ui/icons/Person'; import React, { FC } from 'react'; -import { useApp } from 'api/app/AppContext'; +import { useApp } from '../api/app/AppContext'; import { IconComponent, SystemIconKey, SystemIcons } from './types'; export const defaultSystemIcons: SystemIcons = { @@ -27,7 +27,7 @@ export const defaultSystemIcons: SystemIcons = { }; const overridableSystemIcon = (key: SystemIconKey): IconComponent => { - const Component: FC = props => { + const Component: FC = (props) => { const app = useApp(); const Icon = app.getSystemIcon(key); return ; diff --git a/packages/core/src/layout/Header/Header.tsx b/packages/core/src/layout/Header/Header.tsx index 94de84ad8c..d8e7540349 100644 --- a/packages/core/src/layout/Header/Header.tsx +++ b/packages/core/src/layout/Header/Header.tsx @@ -19,11 +19,11 @@ import Helmet from 'react-helmet'; import { Typography, Tooltip, makeStyles } from '@material-ui/core'; import { BackstageTheme } from '@backstage/theme'; -import { Theme } from 'layout/Page/Page'; +import { Theme } from '../Page/Page'; // import { Link } from 'shared/components'; import Waves from './Waves'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles((theme) => ({ header: { gridArea: 'pageHeader', padding: theme.spacing(3), @@ -175,7 +175,7 @@ export const Header: FC = ({ - {theme => ( + {(theme) => (
diff --git a/packages/core/src/layout/Header/Waves.test.tsx b/packages/core/src/layout/Header/Waves.test.tsx index 02ea8da634..2c7d463052 100644 --- a/packages/core/src/layout/Header/Waves.test.tsx +++ b/packages/core/src/layout/Header/Waves.test.tsx @@ -16,7 +16,7 @@ import React from 'react'; import { render } from '@testing-library/react'; -import { pageTheme } from 'layout/Page/PageThemeProvider'; +import { pageTheme } from '../Page/PageThemeProvider'; import Waves from './Waves'; describe('', () => { diff --git a/packages/core/src/layout/Header/Waves.tsx b/packages/core/src/layout/Header/Waves.tsx index 001f3d61c4..f37ecf7b12 100644 --- a/packages/core/src/layout/Header/Waves.tsx +++ b/packages/core/src/layout/Header/Waves.tsx @@ -16,7 +16,7 @@ import React, { FC } from 'react'; import { makeStyles } from '@material-ui/core'; -import { PageTheme } from 'layout/Page'; +import { PageTheme } from '../Page'; const useStyles = makeStyles({ wave: { diff --git a/packages/core/src/layout/InfoCard/InfoCard.tsx b/packages/core/src/layout/InfoCard/InfoCard.tsx index 42c5401de5..a2585a3006 100644 --- a/packages/core/src/layout/InfoCard/InfoCard.tsx +++ b/packages/core/src/layout/InfoCard/InfoCard.tsx @@ -24,7 +24,7 @@ import { withStyles, makeStyles, } from '@material-ui/core'; -import ErrorBoundary from 'layout/ErrorBoundary/ErrorBoundary'; +import ErrorBoundary from '../ErrorBoundary'; import BottomLink, { Props as BottomLinkProps } from '../BottomLink'; const useStyles = makeStyles((theme) => ({ diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 7b73db2f0f..5a3931ffce 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -1,7 +1,5 @@ { "extends": "../../tsconfig.json", "include": ["src"], - "compilerOptions": { - "baseUrl": "src" - } + "compilerOptions": {} } diff --git a/packages/dev-utils/tsconfig.json b/packages/dev-utils/tsconfig.json index 7b73db2f0f..5a3931ffce 100644 --- a/packages/dev-utils/tsconfig.json +++ b/packages/dev-utils/tsconfig.json @@ -1,7 +1,5 @@ { "extends": "../../tsconfig.json", "include": ["src"], - "compilerOptions": { - "baseUrl": "src" - } + "compilerOptions": {} } diff --git a/packages/storybook/.storybook/main.js b/packages/storybook/.storybook/main.js index 12b9c34435..7243452357 100644 --- a/packages/storybook/.storybook/main.js +++ b/packages/storybook/.storybook/main.js @@ -22,7 +22,6 @@ module.exports = { // Point to dist version of theme and any other packages that might be needed in the future '@backstage/theme': path.resolve(__dirname, '../../theme'), }; - config.resolve.modules.push(coreSrc); // Remove the default babel-loader for js files, we're using ts-loader instead const [jsLoader] = config.module.rules.splice(0, 1); @@ -56,7 +55,7 @@ module.exports = { // Fail storybook build on CI if there are webpack warnings. if (process.env.CI) { - config.plugins.push(new WebpackPluginFailBuildOnWarning()) + config.plugins.push(new WebpackPluginFailBuildOnWarning()); } return config; diff --git a/packages/storybook/package.json b/packages/storybook/package.json index 00e4f82da8..81c2346d14 100644 --- a/packages/storybook/package.json +++ b/packages/storybook/package.json @@ -13,6 +13,9 @@ "@storybook/addons/**" ] }, + "dependencies": { + "@backstage/theme": "0.1.1-alpha.4" + }, "devDependencies": { "@storybook/addon-actions": "^5.3.17", "@storybook/addon-links": "^5.3.17", @@ -20,8 +23,5 @@ "@storybook/addons": "^5.3.17", "@storybook/react": "^5.3.17", "storybook-dark-mode": "^0.4.1" - }, - "dependencies": { - "@backstage/theme": "0.1.1-alpha.4" } } diff --git a/packages/test-utils-core/tsconfig.json b/packages/test-utils-core/tsconfig.json index 7b73db2f0f..5a3931ffce 100644 --- a/packages/test-utils-core/tsconfig.json +++ b/packages/test-utils-core/tsconfig.json @@ -1,7 +1,5 @@ { "extends": "../../tsconfig.json", "include": ["src"], - "compilerOptions": { - "baseUrl": "src" - } + "compilerOptions": {} } diff --git a/packages/test-utils/tsconfig.json b/packages/test-utils/tsconfig.json index 7b73db2f0f..5a3931ffce 100644 --- a/packages/test-utils/tsconfig.json +++ b/packages/test-utils/tsconfig.json @@ -1,7 +1,5 @@ { "extends": "../../tsconfig.json", "include": ["src"], - "compilerOptions": { - "baseUrl": "src" - } + "compilerOptions": {} } diff --git a/packages/theme/package.json b/packages/theme/package.json index c3f7f6c57b..18b4dd7fa2 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -23,12 +23,12 @@ "lint": "backstage-cli lint", "clean": "backstage-cli clean" }, - "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.4" - }, "dependencies": { "@material-ui/core": "^4.9.1" }, + "devDependencies": { + "@backstage/cli": "^0.1.1-alpha.4" + }, "files": [ "dist" ] diff --git a/packages/theme/src/themes.ts b/packages/theme/src/themes.ts index 9e9e2945fa..559b402369 100644 --- a/packages/theme/src/themes.ts +++ b/packages/theme/src/themes.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { createTheme } from 'baseTheme'; +import { createTheme } from './baseTheme'; import { blue, yellow } from '@material-ui/core/colors'; export const lightTheme = createTheme({ diff --git a/packages/theme/tsconfig.json b/packages/theme/tsconfig.json index 7b73db2f0f..5a3931ffce 100644 --- a/packages/theme/tsconfig.json +++ b/packages/theme/tsconfig.json @@ -1,7 +1,5 @@ { "extends": "../../tsconfig.json", "include": ["src"], - "compilerOptions": { - "baseUrl": "src" - } + "compilerOptions": {} } diff --git a/plugins/explore/package.json b/plugins/explore/package.json index fb13381321..731aa6e4ed 100644 --- a/plugins/explore/package.json +++ b/plugins/explore/package.json @@ -11,17 +11,6 @@ "test": "backstage-cli test", "clean": "backstage-cli clean" }, - "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.4", - "@backstage/test-utils": "^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", @@ -33,6 +22,17 @@ "react-dom": "16.13.1", "react-use": "^13.0.0" }, + "devDependencies": { + "@backstage/cli": "^0.1.1-alpha.4", + "@backstage/test-utils": "^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.4", + "jest-fetch-mock": "^3.0.3" + }, "files": [ "dist" ] diff --git a/plugins/explore/tsconfig.json b/plugins/explore/tsconfig.json index 7b73db2f0f..5a3931ffce 100644 --- a/plugins/explore/tsconfig.json +++ b/plugins/explore/tsconfig.json @@ -1,7 +1,5 @@ { "extends": "../../tsconfig.json", "include": ["src"], - "compilerOptions": { - "baseUrl": "src" - } + "compilerOptions": {} } diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json index 086c639bc1..092aa2deea 100644 --- a/plugins/graphiql/package.json +++ b/plugins/graphiql/package.json @@ -25,19 +25,6 @@ "test": "backstage-cli test", "clean": "backstage-cli clean" }, - "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.4", - "@backstage/dev-utils": "^0.1.1-alpha.4", - "@backstage/test-utils": "^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", - "react-router-dom": "^5.1.2" - }, "dependencies": { "@backstage/core": "^0.1.1-alpha.4", "@backstage/theme": "^0.1.1-alpha.4", @@ -50,6 +37,19 @@ "react-dom": "16.13.1", "react-use": "^13.0.0" }, + "devDependencies": { + "@backstage/cli": "^0.1.1-alpha.4", + "@backstage/dev-utils": "^0.1.1-alpha.4", + "@backstage/test-utils": "^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.4", + "jest-fetch-mock": "^3.0.3", + "react-router-dom": "^5.1.2" + }, "files": [ "dist" ] diff --git a/plugins/graphiql/src/components/GraphiQLBrowser/GraphiQLBrowser.tsx b/plugins/graphiql/src/components/GraphiQLBrowser/GraphiQLBrowser.tsx index 5885183b01..b41fc04b9e 100644 --- a/plugins/graphiql/src/components/GraphiQLBrowser/GraphiQLBrowser.tsx +++ b/plugins/graphiql/src/components/GraphiQLBrowser/GraphiQLBrowser.tsx @@ -17,8 +17,8 @@ import React, { FC, useState, Suspense } from 'react'; import { Tabs, Tab, makeStyles, Typography, Divider } from '@material-ui/core'; import 'graphiql/graphiql.css'; -import { StorageBucket } from 'lib/storage'; -import { GraphQLEndpoint } from 'lib/api'; +import { StorageBucket } from '../../lib/storage'; +import { GraphQLEndpoint } from '../../lib/api'; import { Progress } from '@backstage/core'; import { BackstageTheme } from '@backstage/theme'; diff --git a/plugins/graphiql/src/components/GraphiQLPage/GraphiQLPage.test.tsx b/plugins/graphiql/src/components/GraphiQLPage/GraphiQLPage.test.tsx index d19e05524e..d07155d338 100644 --- a/plugins/graphiql/src/components/GraphiQLPage/GraphiQLPage.test.tsx +++ b/plugins/graphiql/src/components/GraphiQLPage/GraphiQLPage.test.tsx @@ -20,7 +20,7 @@ import { ThemeProvider } from '@material-ui/core'; import { lightTheme } from '@backstage/theme'; import { ApiProvider, ApiRegistry } from '@backstage/core'; import { renderWithEffects } from '@backstage/test-utils'; -import { GraphQLBrowseApi, graphQlBrowseApiRef } from 'lib/api'; +import { GraphQLBrowseApi, graphQlBrowseApiRef } from '../../lib/api'; jest.mock('components/GraphiQLBrowser', () => ({ GraphiQLBrowser: () => '', diff --git a/plugins/graphiql/src/components/GraphiQLPage/GraphiQLPage.tsx b/plugins/graphiql/src/components/GraphiQLPage/GraphiQLPage.tsx index 39ee015bed..a16fdf3ee6 100644 --- a/plugins/graphiql/src/components/GraphiQLPage/GraphiQLPage.tsx +++ b/plugins/graphiql/src/components/GraphiQLPage/GraphiQLPage.tsx @@ -26,8 +26,8 @@ import { } from '@backstage/core'; import { useAsync } from 'react-use'; import 'graphiql/graphiql.css'; -import { graphQlBrowseApiRef } from 'lib/api'; -import { GraphiQLBrowser } from 'components'; +import { graphQlBrowseApiRef } from '../../lib/api'; +import { GraphiQLBrowser } from '../GraphiQLBrowser'; import { Typography } from '@material-ui/core'; export const GraphiQLPage: FC<{}> = () => { diff --git a/plugins/graphiql/tsconfig.json b/plugins/graphiql/tsconfig.json index 55fa1e2384..b663b01fa2 100644 --- a/plugins/graphiql/tsconfig.json +++ b/plugins/graphiql/tsconfig.json @@ -1,7 +1,5 @@ { "extends": "../../tsconfig.json", "include": ["src", "dev"], - "compilerOptions": { - "baseUrl": "src" - } + "compilerOptions": {} } diff --git a/plugins/home-page/dev/index.tsx b/plugins/home-page/dev/index.tsx index d97643057b..812a5585d4 100644 --- a/plugins/home-page/dev/index.tsx +++ b/plugins/home-page/dev/index.tsx @@ -17,6 +17,4 @@ import { createDevApp } from '@backstage/dev-utils'; import { plugin } from '../src/plugin'; -createDevApp() - .registerPlugin(plugin) - .render(); +createDevApp().registerPlugin(plugin).render(); diff --git a/plugins/home-page/package.json b/plugins/home-page/package.json index 6bd38a265a..a1f29388a1 100644 --- a/plugins/home-page/package.json +++ b/plugins/home-page/package.json @@ -12,17 +12,6 @@ "test": "backstage-cli test", "clean": "backstage-cli clean" }, - "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.4", - "@backstage/dev-utils": "^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", - "react-router-dom": "^5.1.2" - }, "dependencies": { "@backstage/core": "^0.1.1-alpha.4", "@backstage/theme": "^0.1.1-alpha.4", @@ -32,6 +21,17 @@ "react": "16.13.1", "react-dom": "16.13.1" }, + "devDependencies": { + "@backstage/cli": "^0.1.1-alpha.4", + "@backstage/dev-utils": "^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.4", + "react-router-dom": "^5.1.2" + }, "files": [ "dist" ] diff --git a/plugins/home-page/src/components/HomePage/HomePage.tsx b/plugins/home-page/src/components/HomePage/HomePage.tsx index e9e71c3b0b..60b271892f 100644 --- a/plugins/home-page/src/components/HomePage/HomePage.tsx +++ b/plugins/home-page/src/components/HomePage/HomePage.tsx @@ -16,7 +16,7 @@ import React, { FC } from 'react'; import { Typography, Link, Grid } from '@material-ui/core'; -import HomePageTimer from 'components/HomepageTimer'; +import HomePageTimer from '../HomepageTimer'; import { Content, InfoCard, Header, Page, pageTheme } from '@backstage/core'; import SquadTechHealth from './SquadTechHealth'; import Table from '@material-ui/core/Table'; @@ -68,7 +68,7 @@ const HomePage: FC<{}> = () => { - {data.map(d => ( + {data.map((d) => ( {d.entity} {d.kind} diff --git a/plugins/home-page/src/plugin.ts b/plugins/home-page/src/plugin.ts index 7de760a849..182d43b9b8 100644 --- a/plugins/home-page/src/plugin.ts +++ b/plugins/home-page/src/plugin.ts @@ -15,7 +15,7 @@ */ import { createPlugin } from '@backstage/core'; -import HomePage from 'components/HomePage'; +import HomePage from './components/HomePage'; export const plugin = createPlugin({ id: 'home-page', diff --git a/plugins/home-page/tsconfig.json b/plugins/home-page/tsconfig.json index 55fa1e2384..b663b01fa2 100644 --- a/plugins/home-page/tsconfig.json +++ b/plugins/home-page/tsconfig.json @@ -1,7 +1,5 @@ { "extends": "../../tsconfig.json", "include": ["src", "dev"], - "compilerOptions": { - "baseUrl": "src" - } + "compilerOptions": {} } diff --git a/plugins/inventory-backend/package.json b/plugins/inventory-backend/package.json index 16d510a968..9a72daed5e 100644 --- a/plugins/inventory-backend/package.json +++ b/plugins/inventory-backend/package.json @@ -11,11 +11,6 @@ "test": "backstage-cli test", "clean": "backstage-cli clean" }, - "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.4", - "jest-fetch-mock": "^3.0.3", - "tsc-watch": "^4.2.3" - }, "dependencies": { "@backstage/backend-common": "0.1.1-alpha.4", "compression": "^1.7.4", @@ -26,6 +21,11 @@ "morgan": "^1.10.0", "winston": "^3.2.1" }, + "devDependencies": { + "@backstage/cli": "^0.1.1-alpha.4", + "jest-fetch-mock": "^3.0.3", + "tsc-watch": "^4.2.3" + }, "files": [ "dist" ], diff --git a/plugins/inventory-backend/tsconfig.json b/plugins/inventory-backend/tsconfig.json index 1a3f7ca819..dd13cfe1bc 100644 --- a/plugins/inventory-backend/tsconfig.json +++ b/plugins/inventory-backend/tsconfig.json @@ -1,7 +1,6 @@ { "include": ["src"], "compilerOptions": { - "baseUrl": "src", "outDir": "dist", "incremental": true, "sourceMap": true, diff --git a/plugins/inventory/package.json b/plugins/inventory/package.json index 85ebe7fc34..c3b33d0c12 100644 --- a/plugins/inventory/package.json +++ b/plugins/inventory/package.json @@ -12,16 +12,6 @@ "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", @@ -32,6 +22,16 @@ "react-dom": "16.13.1", "react-use": "^13.0.0" }, + "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.4", + "jest-fetch-mock": "^3.0.3" + }, "files": [ "dist" ] diff --git a/plugins/inventory/src/components/InventoryPage/InventoryPage.tsx b/plugins/inventory/src/components/InventoryPage/InventoryPage.tsx index 0b837d840c..647899eb35 100644 --- a/plugins/inventory/src/components/InventoryPage/InventoryPage.tsx +++ b/plugins/inventory/src/components/InventoryPage/InventoryPage.tsx @@ -47,7 +47,7 @@ const InventoryPage: FC<{}> = () => { - {STATIC_DATA.map(d => ( + {STATIC_DATA.map((d) => ( {d.id} {d.kind} diff --git a/plugins/inventory/tsconfig.json b/plugins/inventory/tsconfig.json index 7b73db2f0f..5a3931ffce 100644 --- a/plugins/inventory/tsconfig.json +++ b/plugins/inventory/tsconfig.json @@ -1,7 +1,5 @@ { "extends": "../../tsconfig.json", "include": ["src"], - "compilerOptions": { - "baseUrl": "src" - } + "compilerOptions": {} } diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json index 852fe0f881..529a4b0374 100644 --- a/plugins/lighthouse/package.json +++ b/plugins/lighthouse/package.json @@ -12,17 +12,6 @@ "test": "backstage-cli test", "clean": "backstage-cli clean" }, - "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.4", - "@backstage/test-utils": "^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", @@ -35,6 +24,17 @@ "react-router-dom": "^5.1.2", "react-use": "^13.24.0" }, + "devDependencies": { + "@backstage/cli": "^0.1.1-alpha.4", + "@backstage/test-utils": "^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.4", + "jest-fetch-mock": "^3.0.3" + }, "files": [ "dist" ] diff --git a/plugins/lighthouse/src/components/AuditView/index.test.tsx b/plugins/lighthouse/src/components/AuditView/index.test.tsx index 31034440d6..000780a1cb 100644 --- a/plugins/lighthouse/src/components/AuditView/index.test.tsx +++ b/plugins/lighthouse/src/components/AuditView/index.test.tsx @@ -46,7 +46,7 @@ describe('AuditView', () => { apis = ApiRegistry.from([ [lighthouseApiRef, new LighthouseRestApi('https://lighthouse')], ]); - id = websiteResponse.audits.find(a => a.status === 'COMPLETED') + id = websiteResponse.audits.find((a) => a.status === 'COMPLETED') ?.id as string; useParams.mockReturnValue({ id }); }); @@ -98,7 +98,7 @@ describe('AuditView', () => { await rendered.findByTestId('audit-sidebar'); - websiteResponse.audits.forEach(a => { + websiteResponse.audits.forEach((a) => { expect( rendered.queryByText(formatTime(a.timeCreated)), ).toBeInTheDocument(); @@ -116,14 +116,14 @@ describe('AuditView', () => { await rendered.findByTestId('audit-sidebar'); - const audit = websiteResponse.audits.find(a => a.id === id) as Audit; + const audit = websiteResponse.audits.find((a) => a.id === id) as Audit; const auditElement = rendered.getByText(formatTime(audit.timeCreated)); expect(auditElement.parentElement?.parentElement?.className).toContain( 'selected', ); const notSelectedAudit = websiteResponse.audits.find( - a => a.id !== id, + (a) => a.id !== id, ) as Audit; const notSelectedAuditElement = rendered.getByText( formatTime(notSelectedAudit.timeCreated), @@ -144,7 +144,7 @@ describe('AuditView', () => { await rendered.findByTestId('audit-sidebar'); - websiteResponse.audits.forEach(a => { + websiteResponse.audits.forEach((a) => { expect( rendered.getByText(formatTime(a.timeCreated)).parentElement ?.parentElement, @@ -183,7 +183,7 @@ describe('AuditView', () => { describe.skip('when a loading audit is accessed', () => { it('shows a loading view', async () => { - id = websiteResponse.audits.find(a => a.status === 'RUNNING') + id = websiteResponse.audits.find((a) => a.status === 'RUNNING') ?.id as string; useParams.mockReturnValueOnce({ id }); @@ -203,7 +203,7 @@ describe('AuditView', () => { describe.skip('when a failed audit is accessed', () => { it('shows an error message', async () => { - id = websiteResponse.audits.find(a => a.status === 'FAILED') + id = websiteResponse.audits.find((a) => a.status === 'FAILED') ?.id as string; useParams.mockReturnValueOnce({ id }); diff --git a/plugins/lighthouse/src/components/AuditView/index.tsx b/plugins/lighthouse/src/components/AuditView/index.tsx index bb766b3997..889c6c53f3 100644 --- a/plugins/lighthouse/src/components/AuditView/index.tsx +++ b/plugins/lighthouse/src/components/AuditView/index.tsx @@ -68,7 +68,7 @@ const AuditLinkList: FC = ({ component="nav" aria-label="lighthouse audit history" > - {audits.map(audit => ( + {audits.map((audit) => ( = () => { - a.id === params.id)} /> + a.id === params.id)} /> ); diff --git a/plugins/lighthouse/src/components/CreateAudit/index.test.tsx b/plugins/lighthouse/src/components/CreateAudit/index.test.tsx index 3ce07dbb02..f15ee19ede 100644 --- a/plugins/lighthouse/src/components/CreateAudit/index.test.tsx +++ b/plugins/lighthouse/src/components/CreateAudit/index.test.tsx @@ -164,7 +164,7 @@ describe('CreateAudit', () => { fireEvent.click(rendered.getByText(/Create Audit/)); await wait(() => expect(rendered.getByLabelText(/URL/)).toBeEnabled()); - await new Promise(r => setTimeout(r, 0)); + await new Promise((r) => setTimeout(r, 0)); expect(errorApi.post).toHaveBeenCalledWith(expect.any(Error)); }); diff --git a/plugins/lighthouse/src/components/CreateAudit/index.tsx b/plugins/lighthouse/src/components/CreateAudit/index.tsx index 19db33791b..55ae99d1db 100644 --- a/plugins/lighthouse/src/components/CreateAudit/index.tsx +++ b/plugins/lighthouse/src/components/CreateAudit/index.tsx @@ -40,7 +40,7 @@ import { lighthouseApiRef } from '../../api'; import { useQuery } from '../../utils'; import LighthouseSupportButton from '../SupportButton'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles((theme) => ({ input: { minWidth: 300, }, @@ -113,7 +113,7 @@ const CreateAudit: FC<{}> = () => {
{ + onSubmit={(ev) => { ev.preventDefault(); triggerAudit(); }} @@ -128,7 +128,7 @@ const CreateAudit: FC<{}> = () => { helperText="The target URL for Lighthouse to use." required disabled={submitting} - onChange={ev => setUrl(ev.target.value)} + onChange={(ev) => setUrl(ev.target.value)} value={url} inputProps={{ 'aria-label': 'URL' }} /> @@ -142,7 +142,7 @@ const CreateAudit: FC<{}> = () => { select required disabled={submitting} - onChange={ev => setEmulatedFormFactor(ev.target.value)} + onChange={(ev) => setEmulatedFormFactor(ev.target.value)} value={emulatedFormFactor} inputProps={{ 'aria-label': 'Emulated form factor' }} > diff --git a/plugins/lighthouse/src/components/Intro/index.tsx b/plugins/lighthouse/src/components/Intro/index.tsx index ee5d5d66af..72847eef42 100644 --- a/plugins/lighthouse/src/components/Intro/index.tsx +++ b/plugins/lighthouse/src/components/Intro/index.tsx @@ -71,7 +71,7 @@ export default builder.build() as ApiHolder; \`\`\` `; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles((theme) => ({ tabs: { marginBottom: -18 }, tab: { minWidth: 72, paddingLeft: 1, paddingRight: 1 }, content: { marginBottom: theme.spacing(2) }, diff --git a/plugins/lighthouse/src/utils.ts b/plugins/lighthouse/src/utils.ts index cc09b52f4f..a243b5f8d1 100644 --- a/plugins/lighthouse/src/utils.ts +++ b/plugins/lighthouse/src/utils.ts @@ -53,13 +53,13 @@ export function buildSparklinesDataForItem( (audit: Audit): audit is AuditCompleted => audit.status === 'COMPLETED', ) .reduce((scores, audit) => { - Object.values(audit.categories).forEach(category => { + Object.values(audit.categories).forEach((category) => { scores[category.id] = scores[category.id] || []; scores[category.id].unshift(category.score); }); // edge case: if only one audit exists, force a "flat" sparkline - Object.values(scores).forEach(arr => { + Object.values(scores).forEach((arr) => { if (arr.length === 1) arr.push(arr[0]); }); diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index ce1161a208..a1a80736de 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -10,12 +10,6 @@ "test": "backstage-cli test", "clean": "backstage-cli clean" }, - "devDependencies": { - "@backstage/cli": "^0.1.1-alpha.4", - "@types/fs-extra": "^8.1.0", - "@types/supertest": "^2.0.8", - "supertest": "^4.0.2" - }, "dependencies": { "@backstage/backend-common": "0.1.1-alpha.4", "dockerode": "^3.2.0", @@ -28,5 +22,11 @@ "helmet": "^3.22.0", "morgan": "^1.10.0", "winston": "^3.2.1" + }, + "devDependencies": { + "@backstage/cli": "^0.1.1-alpha.4", + "@types/fs-extra": "^8.1.0", + "@types/supertest": "^2.0.8", + "supertest": "^4.0.2" } } diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 878b4ddbf2..2b185bc9c3 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -12,16 +12,6 @@ "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", @@ -32,6 +22,16 @@ "react-dom": "16.13.1", "react-use": "^13.0.0" }, + "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.4", + "jest-fetch-mock": "^3.0.3" + }, "files": [ "dist" ] diff --git a/plugins/scaffolder/tsconfig.json b/plugins/scaffolder/tsconfig.json index 7b73db2f0f..5a3931ffce 100644 --- a/plugins/scaffolder/tsconfig.json +++ b/plugins/scaffolder/tsconfig.json @@ -1,7 +1,5 @@ { "extends": "../../tsconfig.json", "include": ["src"], - "compilerOptions": { - "baseUrl": "src" - } + "compilerOptions": {} } diff --git a/plugins/tech-radar/README.md b/plugins/tech-radar/README.md index d48cd969a8..49a5bb3add 100644 --- a/plugins/tech-radar/README.md +++ b/plugins/tech-radar/README.md @@ -1,89 +1,120 @@ # @backstage/plugin-tech-radar -Screenshot of Tech Radar plugin +Screenshot of Tech Radar plugin The Backstage integration for the Tech Radar based on [Zalando's Tech Radar](https://opensource.zalando.com/tech-radar/) open sourced on [GitHub](https://github.com/zalando/tech-radar). This is used at [Spotify](https://spotify.github.io) for visualizing the official guidelines of different areas of software development such as languages, frameworks, infrastructure and processes. ## Purpose -Zalando explains it very well on their website: +Zalando has a fantastic description [on their website](https://opensource.zalando.com/tech-radar/): > The Tech Radar is a tool to inspire and support engineering teams at Zalando to pick the best technologies for new projects; it provides a platform to share knowledge and experience in technologies, to reflect on technology decisions and continuously evolve our technology landscape. Based on the pioneering work of ThoughtWorks, our Tech Radar sets out the changes in technologies that are interesting in software development — changes that we think our engineering teams should pay attention to and consider using in their projects. -It serves well for teams and companies of all sizes that want to have alignment and wish to visualize it. It scales well for companies who have dozens of different technologies in place. +It serves and scales well for teams and companies of all sizes that want to have alignment across dozens of technologies and visualize it in a simple way. ## Getting Started -In your installation, add the dependency to your Backstage installation: +The Tech Radar can be used in two ways: + +- **Simple (Recommended)** - This gives you an out-of-the-box Tech Radar experience. It lives on the `/tech-radar` URL of your Backstage installation, and you can set a variety of configuration directly in your `apis.ts`. +- **Advanced** - This gives you the React UI component directly. It enables you to insert the Radar on your own layout or page for a more customized feel. + +### Install + +For either simple or advanced installations, you'll need to add the dependency using Yarn: ```sh yarn add @backstage/plugin-tech-radar ``` -In your `apis.ts` set up the "out of the box" implementation for Tech Radar: +### Simple Configuration + +In your `apis.ts` set up the simple "out of the box" implementation for Tech Radar: ```ts import { ApiHolder, ApiRegistry } from '@backstage/core'; import { techRadarApiRef, TechRadar, - loadSampleData, } from '@backstage/plugin-tech-radar'; const builder = ApiRegistry.builder(); -builder.add(techRadarApiRef, new TechRadar(1400, 800, loadSampleData)); +builder.add(techRadarApiRef, new TechRadar({ + width: 1400, + height: 800 +)); export default builder.build() as ApiHolder; ``` -It will then be available on your Backstage installation over at +Congrats, you're done! We'll just load it with [example data](src/sampleData.ts) to get you started. Just go to to see it live in action. -## Configuration - -The implementation for the TechRadar class is: +And if you'd like to configure it more, such as providing it with your own data, see the `TechRadarApi` TypeScript interface below for the options: ```ts -export interface TechRadarAdditionalOptions { - title?: string; - subtitle?: string; +export interface TechRadarComponentProps { + width: number; + height: number; + getData?: () => Promise; svgProps?: object; } -export interface TechRadarLoaderResponse { - quadrants: RadarQuadrant[]; - rings: RadarRing[]; - entries: RadarEntry[]; +export interface TechRadarApi extends TechRadarComponentProps { + title?: string; + subtitle?: string; } - -export interface TechRadarApi { - width: number; - height: number; - load: () => Promise; - additionalOpts: TechRadarAdditionalOptions; -} - -// Constructor signature for the `TechRadar` class -// constructor( -// public width: number, -// public height: number, -// public load: () => Promise, -// public additionalOpts: TechRadarAdditionalOptions = {}, -// ) ``` -The source code is available in [api.ts](src/api.ts). +You can see the API directly over at [src/api.ts](./src/api.ts). -## Code Samples +### Advanced Configuration -### Set up Tech Radar with sample data +This way won't expose an `/tech-radar` path. Instead, you'll need to create your own Backstage plugin and use the Tech Radar as any other React UI component. -See example above. +In your Backstage app, run the following command: -### Set up Tech Radar with hard-coded values +```sh +yarn create-plugin +``` + +In your plugin, in any React component you'd like to import the Tech Radar, do the following: + +```tsx +import { TechRadarComponent } from '@backstage/plugin-tech-radar'; + +function MyCustomRadar() { + return ; +} +``` + +If you'd like to configure it more, see the `TechRadarComponentProps` TypeScript interface for options: ```ts -const hardCodedData = () => +export interface TechRadarComponentProps { + width: number; + height: number; + getData?: () => Promise; + svgProps?: object; +} +``` + +You can see the API directly over at [src/api.ts](./src/api.ts). + +## Frequently Asked Questions + +### Who created the Tech Radar? + +[ThoughtWorks](https://thoughtworks.com/radar) created the Tech Radar concept, and [Zalando created the visualization](https://opensource.zalando.com/tech-radar/) that we use at Spotify and in this plugin. + +### How do I load in my own data? + +It's simple. In both the Simple (Backstage plugin) and Advanced (React component) configurations, you can pass through a `getData` prop which expects a `Promise` signature. See more in [src/api.ts](./src/api.ts). + +Here's an example: + +```tsx +const getHardCodedData = () => Promise.resolve({ quadrants: [{ id: 'infrastructure', name: 'Infrastructure' }], rings: [{ id: 'use', name: 'USE', color: '#93c47d' }], @@ -100,48 +131,43 @@ const hardCodedData = () => ], }); -builder.add(techRadarApiRef, new TechRadar(1400, 800, hardCodedData)); +// Simple +builder.add(techRadarApiRef, new TechRadar({ + width: 1400, + height: 800, + getData: getHardCodedData +)); + +// Advanced + ``` -### Set up Tech Radar with an API call - -```ts -const apiRetrievedData = async () => { - const response = await fetch('http://example.com/tech-radar-values.json'); - const json = await response.json(); - return json as TechRadarLoaderResponse; -}; - -builder.add(techRadarApiRef, new TechRadar(1400, 800, apiRetrievedData)); -``` - -### Use a custom title and subtitle +### How do I write tests? + +You can use the `svgProps` option to pass custom React props to the `` element we create for the Tech Radar. This complements well with the `data-testid` attribute and the `@testing-library/react` library we use in Backstage. ```ts +// Simple builder.add( techRadarApiRef, - new TechRadar(1400, 800, loadSampleData, { - title: 'My Company Tech Radar', - subtitle: 'Learn about what technologies we use at My Company.', - }), -); -``` - -### Use custom props - -Great for testing through adding a `data-testid` for being able to test with `@testing-library/react` - -```ts -builder.add( - techRadarApiRef, - new TechRadar(1400, 800, loadSampleData, { + new TechRadar({ + width: 1400, + height: 800, svgProps: { - // for the main tag of the visualization 'data-testid': 'tech-radar-svg', }, }), ); +// Advanced +; + // Then, in your tests... // const { getByTestId } = render(...); // expect(getByTestId('tech-radar-svg')).toBeInTheDocument(); diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index 3d51d2ef8d..df0b9780f0 100644 --- a/plugins/tech-radar/package.json +++ b/plugins/tech-radar/package.json @@ -11,18 +11,6 @@ "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/color": "^3.0.1", - "@types/d3-force": "^1.2.1", - "@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/test-utils-core": "^0.1.1-alpha.4", @@ -36,5 +24,17 @@ "react": "16.13.1", "react-dom": "16.13.1", "react-use": "^13.0.0" + }, + "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/color": "^3.0.1", + "@types/d3-force": "^1.2.1", + "@types/jest": "^24.0.0", + "@types/node": "^12.0.0", + "@types/testing-library__jest-dom": "5.0.4", + "jest-fetch-mock": "^3.0.3" } } diff --git a/plugins/tech-radar/src/api.ts b/plugins/tech-radar/src/api.ts index 78f07bfd4b..4893901342 100644 --- a/plugins/tech-radar/src/api.ts +++ b/plugins/tech-radar/src/api.ts @@ -16,6 +16,10 @@ import { ApiRef } from '@backstage/core'; +/** + * Types related to the Radar's visualization. + */ + export interface RadarRing { id: string; name: string; @@ -37,42 +41,63 @@ export interface RadarEntry { url: string; } +/** + * Types related to data collection for the Radar. + */ + export interface TechRadarLoaderResponse { quadrants: RadarQuadrant[]; rings: RadarRing[]; entries: RadarEntry[]; } -export interface TechRadarAdditionalOptions { - title?: string; - subtitle?: string; +/** + * Set up the Radar as a Backstage component. + */ + +export interface TechRadarComponentProps { + width: number; + height: number; + getData?: () => Promise; svgProps?: object; } -export interface TechRadarApi { - width: number; - height: number; - load: () => Promise; - additionalOpts: TechRadarAdditionalOptions; +/** + * Set up the Radar as a Backstage plugin. + */ + +export interface TechRadarApi extends TechRadarComponentProps { + title?: string; + subtitle?: string; } export const techRadarApiRef = new ApiRef({ id: 'plugin.techradar', - description: 'Used by the Tech Radar to render the diagram', + description: 'Used by the Tech Radar to render the visualization', }); export class TechRadar implements TechRadarApi { - private defaultAdditionalOpts: Partial = { - title: 'Tech Radar', - subtitle: 'Welcome to the Tech Radar!', - }; + // Default columns + public width: TechRadarApi['width']; + public height: TechRadarApi['height']; + public getData: TechRadarApi['getData']; + public svgProps: TechRadarApi['svgProps']; + public title: TechRadarApi['title']; + public subtitle: TechRadarApi['subtitle']; - constructor( - public width: number, - public height: number, - public load: () => Promise, - public additionalOpts: TechRadarAdditionalOptions = {}, - ) { - this.additionalOpts = { ...this.defaultAdditionalOpts, ...additionalOpts }; + constructor(overrideOptions: TechRadarApi) { + const defaultOptions: Partial = { + title: 'Tech Radar', + subtitle: 'Welcome to the Tech Radar!', + }; + + const options = { ...defaultOptions, ...overrideOptions }; + + this.width = options.width; + this.height = options.height; + this.getData = options.getData; + this.svgProps = options.svgProps; + this.title = options.title; + this.subtitle = options.subtitle; } } diff --git a/plugins/tech-radar/src/components/Radar/Radar.js b/plugins/tech-radar/src/components/Radar/Radar.js index e353e44589..ee956bfb89 100644 --- a/plugins/tech-radar/src/components/Radar/Radar.js +++ b/plugins/tech-radar/src/components/Radar/Radar.js @@ -105,14 +105,14 @@ export default class Radar extends React.Component { static adjustEntries(entries, activeEntry, quadrants, rings, radius) { let seed = 42; entries.forEach((entry, idx) => { - const quadrant = quadrants.find(q => { + const quadrant = quadrants.find((q) => { const match = typeof entry.quadrant === 'object' ? entry.quadrant.id : entry.quadrant; return q.id === match; }); - const ring = rings.find(r => { + const ring = rings.find((r) => { const match = typeof entry.ring === 'object' ? entry.ring.id : entry.ring; return r.id === match; @@ -137,21 +137,13 @@ export default class Radar extends React.Component { entry.active = activeEntry ? entry.id === activeEntry.id : false; entry.color = entry.active ? entry.ring.color - : color(entry.ring.color) - .desaturate(0.5) - .lighten(0.1) - .string(); + : color(entry.ring.color).desaturate(0.5).lighten(0.1).string(); }); const simulation = forceSimulation() .nodes(entries) .velocityDecay(0.19) - .force( - 'collision', - forceCollide() - .radius(12) - .strength(0.85), - ) + .force('collision', forceCollide().radius(12).strength(0.85)) .stop(); for ( @@ -198,7 +190,7 @@ export default class Radar extends React.Component { return ( { + ref={(node) => { this.node = node; }} width={width} @@ -213,7 +205,7 @@ export default class Radar extends React.Component { quadrants={quadrants} rings={rings} activeEntry={activeEntry} - onEntryMouseEnter={entry => this._setActiveEntry(entry)} + onEntryMouseEnter={(entry) => this._setActiveEntry(entry)} onEntryMouseLeave={() => this._clearActiveEntry()} /> diff --git a/plugins/tech-radar/src/components/RadarBubble/RadarBubble.js b/plugins/tech-radar/src/components/RadarBubble/RadarBubble.js index 072f80ca20..83487d637e 100644 --- a/plugins/tech-radar/src/components/RadarBubble/RadarBubble.js +++ b/plugins/tech-radar/src/components/RadarBubble/RadarBubble.js @@ -49,16 +49,16 @@ class RadarBubble extends React.PureComponent { this._updatePosition(); } - _setRect = rect => { + _setRect = (rect) => { this.rect = rect; }; - _setNode = node => { + _setNode = (node) => { this.node = node; }; - _setText = text => { + _setText = (text) => { this.text = text; }; - _setPath = path => { + _setPath = (path) => { this.path = path; }; diff --git a/plugins/tech-radar/src/components/RadarComponent.test.tsx b/plugins/tech-radar/src/components/RadarComponent.test.tsx new file mode 100644 index 0000000000..2f3fcff198 --- /dev/null +++ b/plugins/tech-radar/src/components/RadarComponent.test.tsx @@ -0,0 +1,102 @@ +/* + * 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, waitForElement } from '@testing-library/react'; +import { ThemeProvider } from '@material-ui/core'; +import { lightTheme } from '@backstage/theme'; +import { ApiRegistry, ApiProvider, errorApiRef } from '@backstage/core'; +import { withLogCollector } from '@backstage/test-utils-core'; + +import GetBBoxPolyfill from '../utils/polyfills/getBBox'; +import RadarComponent from './RadarComponent'; + +describe('RadarComponent', () => { + beforeAll(() => { + GetBBoxPolyfill.create(0, 0, 1000, 500); + }); + + afterAll(() => { + GetBBoxPolyfill.remove(); + }); + + it('should render a progress bar', async () => { + const errorApi = { post: () => {} }; + + const { getByTestId, queryByTestId } = render( + + + + + , + ); + + expect(getByTestId('progress')).toBeInTheDocument(); + + await waitForElement(() => queryByTestId('tech-radar-svg')); + }); + + it('should call the errorApi if load fails', async () => { + const errorApi = { post: jest.fn() }; + const techRadarLoadFail = () => + Promise.reject(new Error('404 Page Not Found')); + + const { queryByTestId } = render( + + + + + , + ); + + await waitForElement(() => !queryByTestId('progress')); + + expect(errorApi.post).toHaveBeenCalledTimes(1); + expect(errorApi.post).toHaveBeenCalledWith(new Error('404 Page Not Found')); + expect(queryByTestId('tech-radar-svg')).not.toBeInTheDocument(); + }); + + it('should not render without errorApiRef', () => { + expect( + withLogCollector(['error'], () => { + expect(() => { + render( + + + + + , + ); + }).toThrow(); + }).error[0], + ).toMatch( + /^Error: Uncaught \[Error: No implementation available for apiRef{core.error}\]/, + ); + }); +}); diff --git a/plugins/tech-radar/src/components/RadarComponent.tsx b/plugins/tech-radar/src/components/RadarComponent.tsx new file mode 100644 index 0000000000..7a6c4fedaf --- /dev/null +++ b/plugins/tech-radar/src/components/RadarComponent.tsx @@ -0,0 +1,85 @@ +/* + * 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, { useEffect, useState, FC } from 'react'; +import { Progress, useApi, errorApiRef, ErrorApi } from '@backstage/core'; +import Radar from '../components/Radar'; +import { TechRadarComponentProps, TechRadarLoaderResponse } from '../api'; +import getSampleData from '../sampleData'; + +const useTechRadarLoader = (props: TechRadarComponentProps) => { + const [state, setState] = useState<{ + loading: boolean; + error?: Error; + data?: TechRadarLoaderResponse; + }>({ + loading: true, + error: undefined, + data: undefined, + }); + + useEffect(() => { + if (!props.getData) { + return; + } + + props + .getData() + .then((payload: TechRadarLoaderResponse) => { + setState({ loading: false, error: undefined, data: payload }); + }) + .catch((err: Error) => { + setState({ + loading: false, + error: err, + data: undefined, + }); + }); + }, []); + + return state; +}; + +const RadarComponent: FC = (props) => { + const errorApi = useApi(errorApiRef); + const { loading, error, data } = useTechRadarLoader(props); + + useEffect(() => { + if (error) { + errorApi.post(error); + } + }, [error && error.message]); + + return ( + <> + {loading && } + {!loading && !error && ( + + )} + + ); +}; + +RadarComponent.defaultProps = { + getData: getSampleData, +}; + +export default RadarComponent; diff --git a/plugins/tech-radar/src/components/RadarGrid/RadarGrid.js b/plugins/tech-radar/src/components/RadarGrid/RadarGrid.js index ce6c046242..f48a8e9514 100644 --- a/plugins/tech-radar/src/components/RadarGrid/RadarGrid.js +++ b/plugins/tech-radar/src/components/RadarGrid/RadarGrid.js @@ -84,7 +84,7 @@ class RadarGrid extends React.PureComponent { />, ]; - const ringNodes = rings.map(r => r.outerRadius).map(makeRingNode); + const ringNodes = rings.map((r) => r.outerRadius).map(makeRingNode); return axisNodes.concat(ringNodes); } diff --git a/plugins/tech-radar/src/components/RadarLegend/RadarLegend.js b/plugins/tech-radar/src/components/RadarLegend/RadarLegend.js index 674dd34cbb..5fb7b5a1ba 100644 --- a/plugins/tech-radar/src/components/RadarLegend/RadarLegend.js +++ b/plugins/tech-radar/src/components/RadarLegend/RadarLegend.js @@ -88,7 +88,7 @@ class RadarLegend extends React.PureComponent {

{quadrant.name}

- {rings.map(ring => + {rings.map((ring) => RadarLegend._renderRing( ring, RadarLegend._getSegment(segments, quadrant, ring), @@ -117,7 +117,7 @@ class RadarLegend extends React.PureComponent {

(empty)

) : (
    - {entries.map(entry => { + {entries.map((entry) => { let node = {entry.title}; if (entry.url) { @@ -175,7 +175,7 @@ class RadarLegend extends React.PureComponent { return ( - {quadrants.map(quadrant => + {quadrants.map((quadrant) => RadarLegend._renderQuadrant( segments, quadrant, diff --git a/plugins/tech-radar/src/components/RadarPage.test.tsx b/plugins/tech-radar/src/components/RadarPage.test.tsx index 9913895949..5ef71d1693 100644 --- a/plugins/tech-radar/src/components/RadarPage.test.tsx +++ b/plugins/tech-radar/src/components/RadarPage.test.tsx @@ -22,7 +22,7 @@ import { ApiRegistry, ApiProvider, errorApiRef } from '@backstage/core'; import { withLogCollector } from '@backstage/test-utils-core'; import GetBBoxPolyfill from '../utils/polyfills/getBBox'; -import { techRadarApiRef, TechRadar, loadSampleData } from '../index'; +import { techRadarApiRef, TechRadar } from '../index'; import RadarPage from './RadarPage'; describe('RadarPage', () => { @@ -36,7 +36,9 @@ describe('RadarPage', () => { it('should render a progress bar', async () => { const errorApi = { post: () => {} }; - const techRadarApi = new TechRadar(1200, 800, loadSampleData, { + const techRadarApi = new TechRadar({ + width: 1200, + height: 800, svgProps: { 'data-testid': 'tech-radar-svg' }, }); @@ -60,7 +62,9 @@ describe('RadarPage', () => { it('should render a header with a svg', async () => { const errorApi = { post: () => {} }; - const techRadarApi = new TechRadar(1200, 800, loadSampleData, { + const techRadarApi = new TechRadar({ + width: 1200, + height: 800, svgProps: { 'data-testid': 'tech-radar-svg' }, }); @@ -87,7 +91,10 @@ describe('RadarPage', () => { const errorApi = { post: jest.fn() }; const techRadarLoadFail = () => Promise.reject(new Error('404 Page Not Found')); - const techRadarApi = new TechRadar(1200, 800, techRadarLoadFail, { + const techRadarApi = new TechRadar({ + width: 1200, + height: 800, + getData: techRadarLoadFail, svgProps: { 'data-testid': 'tech-radar-svg' }, }); @@ -112,7 +119,10 @@ describe('RadarPage', () => { }); it('should not render without errorApiRef', () => { - const techRadarApi = new TechRadar(1200, 800, loadSampleData); + const techRadarApi = new TechRadar({ + width: 1200, + height: 800, + }); expect( withLogCollector(['error'], () => { diff --git a/plugins/tech-radar/src/components/RadarPage.tsx b/plugins/tech-radar/src/components/RadarPage.tsx index 0ea3d8743a..395939845b 100644 --- a/plugins/tech-radar/src/components/RadarPage.tsx +++ b/plugins/tech-radar/src/components/RadarPage.tsx @@ -14,81 +14,22 @@ * limitations under the License. */ -import React, { useEffect, useState, FC } from 'react'; +import React, { FC } from 'react'; import { Grid } from '@material-ui/core'; -import { - Progress, - Page, - Header, - Content, - pageTheme, - useApi, - errorApiRef, - ErrorApi, -} from '@backstage/core'; -import Radar from '../components/Radar'; -import { techRadarApiRef, TechRadarApi, TechRadarLoaderResponse } from '../api'; - -const useTechRadarLoader = (techRadarApi: TechRadarApi) => { - const [state, setState] = useState<{ - loading: boolean; - error?: Error; - data?: TechRadarLoaderResponse; - }>({ - loading: true, - error: undefined, - data: undefined, - }); - - useEffect(() => { - techRadarApi - .load() - .then((payload: TechRadarLoaderResponse) => { - setState({ loading: false, error: undefined, data: payload }); - }) - .catch((err: Error) => { - setState({ - loading: false, - error: err, - data: undefined, - }); - }); - }, []); - - return state; -}; +import { Page, Header, Content, pageTheme, useApi } from '@backstage/core'; +import RadarComponent from '../components/RadarComponent'; +import { techRadarApiRef, TechRadarApi } from '../api'; const RadarPage: FC<{}> = () => { - const errorApi = useApi(errorApiRef); const techRadarApi = useApi(techRadarApiRef); - const { loading, error, data } = useTechRadarLoader(techRadarApi); - - useEffect(() => { - if (error) { - errorApi.post(error); - } - }, [error && error.message]); return ( -
    +
    - {loading && } - {!loading && !error && ( - - )} + diff --git a/plugins/tech-radar/src/components/RadarPlot/RadarPlot.js b/plugins/tech-radar/src/components/RadarPlot/RadarPlot.js index b93d20cbff..afa4c4cd95 100644 --- a/plugins/tech-radar/src/components/RadarPlot/RadarPlot.js +++ b/plugins/tech-radar/src/components/RadarPlot/RadarPlot.js @@ -46,16 +46,16 @@ export default class RadarPlot extends React.PureComponent { rings={rings} entries={entries} onEntryMouseEnter={ - onEntryMouseEnter && (entry => onEntryMouseEnter(entry)) + onEntryMouseEnter && ((entry) => onEntryMouseEnter(entry)) } onEntryMouseLeave={ - onEntryMouseLeave && (entry => onEntryMouseLeave(entry)) + onEntryMouseLeave && ((entry) => onEntryMouseLeave(entry)) } /> - {entries.map(entry => ( + {entries.map((entry) => ( { +export default function getSampleData(): Promise { return Promise.resolve({ rings, quadrants, diff --git a/plugins/tech-radar/tsconfig.json b/plugins/tech-radar/tsconfig.json index 7b73db2f0f..5a3931ffce 100644 --- a/plugins/tech-radar/tsconfig.json +++ b/plugins/tech-radar/tsconfig.json @@ -1,7 +1,5 @@ { "extends": "../../tsconfig.json", "include": ["src"], - "compilerOptions": { - "baseUrl": "src" - } + "compilerOptions": {} } diff --git a/plugins/welcome/package.json b/plugins/welcome/package.json index 007151e8dc..631305218d 100644 --- a/plugins/welcome/package.json +++ b/plugins/welcome/package.json @@ -11,15 +11,6 @@ "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" - }, "dependencies": { "@backstage/core": "^0.1.1-alpha.4", "@backstage/theme": "^0.1.1-alpha.4", @@ -30,6 +21,15 @@ "react-dom": "16.13.1", "react-router-dom": "5.1.2" }, + "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.4" + }, "files": [ "dist" ] diff --git a/plugins/welcome/src/components/WelcomePage/ErrorButton.test.tsx b/plugins/welcome/src/components/WelcomePage/ErrorButton.test.tsx deleted file mode 100644 index 6a91a6c202..0000000000 --- a/plugins/welcome/src/components/WelcomePage/ErrorButton.test.tsx +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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, fireEvent } from '@testing-library/react'; -import ErrorButton from './ErrorButton'; -import { ApiRegistry, errorApiRef, ApiProvider } from '@backstage/core'; - -describe('ErrorButton', () => { - it('should trigger an error', () => { - const errorApi = { post: jest.fn() }; - - const rendered = render( - - - , - ); - - const button = rendered.getByText('Trigger an error!'); - expect(button).toBeInTheDocument(); - - expect(errorApi.post).not.toHaveBeenCalled(); - fireEvent.click(button); - expect(errorApi.post).toHaveBeenCalledWith( - expect.objectContaining({ message: 'Oh no!' }), - ); - }); -}); diff --git a/plugins/welcome/src/components/WelcomePage/ErrorButton.tsx b/plugins/welcome/src/components/WelcomePage/ErrorButton.tsx deleted file mode 100644 index daaf4c94ac..0000000000 --- a/plugins/welcome/src/components/WelcomePage/ErrorButton.tsx +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 { Button } from '@material-ui/core'; -import { errorApiRef, useApi } from '@backstage/core'; - -const ErrorButton: FC<{}> = () => { - const errorApi = useApi(errorApiRef); - - const handleClick = () => { - errorApi.post(new Error('Oh no!')); - }; - - return ( - - ); -}; - -export default ErrorButton; diff --git a/plugins/welcome/src/components/WelcomePage/ToggleFeatureFlagButton.test.tsx b/plugins/welcome/src/components/WelcomePage/ToggleFeatureFlagButton.test.tsx deleted file mode 100644 index 13d6741cc7..0000000000 --- a/plugins/welcome/src/components/WelcomePage/ToggleFeatureFlagButton.test.tsx +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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, { ReactNode } from 'react'; -import { render, fireEvent } from '@testing-library/react'; -import ToggleFeatureFlagButton from './ToggleFeatureFlagButton'; -import { - ApiRegistry, - featureFlagsApiRef, - ApiProvider, - FeatureFlags, -} from '@backstage/core'; - -function withApiRegistry(component: ReactNode, featureFlags: FeatureFlags) { - return ( - - {component} - - ); -} - -describe('ToggleFeatureFlagButton', () => { - let featureFlags: FeatureFlags; - - beforeEach(() => { - featureFlags = new FeatureFlags(); - window.localStorage.clear(); - }); - - it('should enable the feature flag', () => { - const rendered = render( - withApiRegistry(, featureFlags), - ); - - const button = rendered.getByTestId('button-switch-feature-flag-state'); - expect(button).toBeInTheDocument(); - - expect(window.localStorage.featureFlags).toBeUndefined(); - fireEvent.click(button); - expect(window.localStorage.featureFlags).toBe('{"enable-welcome-box":1}'); - }); - - it('should disable the feature flag', () => { - window.localStorage.setItem('featureFlags', '{"enable-welcome-box":1}'); - - const rendered = render( - withApiRegistry(, featureFlags), - ); - - const button = rendered.getByTestId('button-switch-feature-flag-state'); - expect(button).toBeInTheDocument(); - - expect(window.localStorage.featureFlags).toBe('{"enable-welcome-box":1}'); - fireEvent.click(button); - expect(window.localStorage.featureFlags).toBe('{"enable-welcome-box":0}'); - }); -}); diff --git a/plugins/welcome/src/components/WelcomePage/ToggleFeatureFlagButton.tsx b/plugins/welcome/src/components/WelcomePage/ToggleFeatureFlagButton.tsx deleted file mode 100644 index 3ce66ce1c7..0000000000 --- a/plugins/welcome/src/components/WelcomePage/ToggleFeatureFlagButton.tsx +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 { Button } from '@material-ui/core'; -import { FeatureFlagState, featureFlagsApiRef, useApi } from '@backstage/core'; - -const ToggleFeatureFlagButton: FC<{}> = () => { - const featureFlagsApi = useApi(featureFlagsApiRef); - const flags = featureFlagsApi.getFlags(); - const flagState = flags.get('enable-welcome-box'); - - const handleClick = () => { - const newValue = - flagState === FeatureFlagState.On - ? FeatureFlagState.Off - : FeatureFlagState.On; - flags.set('enable-welcome-box', newValue); - window.location.reload(); - }; - - return ( - - ); -}; - -export default ToggleFeatureFlagButton; diff --git a/plugins/welcome/src/components/WelcomePage/WelcomePage.tsx b/plugins/welcome/src/components/WelcomePage/WelcomePage.tsx index 307369f5fd..1512a22e50 100644 --- a/plugins/welcome/src/components/WelcomePage/WelcomePage.tsx +++ b/plugins/welcome/src/components/WelcomePage/WelcomePage.tsx @@ -24,7 +24,7 @@ import { ListItemText, Link, } from '@material-ui/core'; -import Timer from 'components/Timer'; +import Timer from '../Timer'; import { Content, InfoCard, @@ -33,9 +33,8 @@ import { pageTheme, ContentHeader, SupportButton, + WarningPanel, } from '@backstage/core'; -import ErrorButton from './ErrorButton'; -import ToggleFeatureFlagButton from './ToggleFeatureFlagButton'; const WelcomePage: FC<{}> = () => { const profile = { givenName: '' }; @@ -44,7 +43,7 @@ const WelcomePage: FC<{}> = () => {
    @@ -52,16 +51,37 @@ const WelcomePage: FC<{}> = () => { + + + + We created Backstage about 4 years ago. While Spotify's + internal version of Backstage has had the benefit of time to + mature and evolve, the first iteration of our open source + version is still nascent. We are envisioning three phases of + the project and we have already begun work on various aspects + of these phases. The best way to keep track of the progress is + through the  + + Milestones + + . + + } + /> + - + - You now have a running instance of Backstage! + You now have a running instance of Backstage!  🎉 - Let's make sure you get the most out of this platform by walking - you through the basics. +  Let's make sure you get the most out of this platform by + walking you through the basics. The Setup @@ -85,7 +105,7 @@ const WelcomePage: FC<{}> = () => { - Try It Out + Build Your Plugins We suggest you either check out the documentation for{' '} @@ -94,15 +114,18 @@ const WelcomePage: FC<{}> = () => { {' '} or have a look in the code for the{' '} - Home Page + existing plugins {' '} - in the directory "plugins/home-page/src". + in the directory{' '} + + plugins/ + + . - - Quick Links + backstage.io @@ -112,21 +135,12 @@ const WelcomePage: FC<{}> = () => { Create a plugin + + Plugin gallery + - - - - The button below is an example of how to consume APIs. - -
    - -
    -
    - -
    -
    diff --git a/plugins/welcome/src/plugin.ts b/plugins/welcome/src/plugin.ts index fbc1d14256..9690805c98 100644 --- a/plugins/welcome/src/plugin.ts +++ b/plugins/welcome/src/plugin.ts @@ -15,7 +15,7 @@ */ import { createPlugin } from '@backstage/core'; -import WelcomePage from 'components/WelcomePage'; +import WelcomePage from './components/WelcomePage'; export const plugin = createPlugin({ id: 'welcome', diff --git a/plugins/welcome/tsconfig.json b/plugins/welcome/tsconfig.json index 7b73db2f0f..5a3931ffce 100644 --- a/plugins/welcome/tsconfig.json +++ b/plugins/welcome/tsconfig.json @@ -1,7 +1,5 @@ { "extends": "../../tsconfig.json", "include": ["src"], - "compilerOptions": { - "baseUrl": "src" - } + "compilerOptions": {} } diff --git a/yarn.lock b/yarn.lock index e3244ea127..ddd2b87518 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2965,16 +2965,16 @@ typescript "^3.7.4" "@storybook/addon-actions@^5.3.17": - version "5.3.17" - resolved "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-5.3.17.tgz#ec7ae8fa25ef211c2a3302b6ac1d271a6247f767" - integrity sha512-06HQSBqWFyXcqV418Uv3oMHomNy9g3uCt0FHrqY3BAc7PldY1X0tW65oy//uBueaRaYKdhtRrrjfXRaPQWmDbA== + version "5.3.18" + resolved "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-5.3.18.tgz#e3e3b1475cebc9bdd2d563822fba9ac662b2601a" + integrity sha512-jdBVCcfyWin274Lkwg5cL+1fJ651NCuIWxuJVsmHQtIl2xTjf2MyoMoKQZNdt4xtE+W9w+rS4bYt04elrizThg== dependencies: - "@storybook/addons" "5.3.17" - "@storybook/api" "5.3.17" - "@storybook/client-api" "5.3.17" - "@storybook/components" "5.3.17" - "@storybook/core-events" "5.3.17" - "@storybook/theming" "5.3.17" + "@storybook/addons" "5.3.18" + "@storybook/api" "5.3.18" + "@storybook/client-api" "5.3.18" + "@storybook/components" "5.3.18" + "@storybook/core-events" "5.3.18" + "@storybook/theming" "5.3.18" core-js "^3.0.1" fast-deep-equal "^2.0.1" global "^4.3.2" @@ -3019,7 +3019,7 @@ regenerator-runtime "^0.13.3" util-deprecate "^1.0.2" -"@storybook/addons@5.3.17", "@storybook/addons@^5.3.17": +"@storybook/addons@5.3.17": version "5.3.17" resolved "https://registry.npmjs.org/@storybook/addons/-/addons-5.3.17.tgz#8efab65904040b0b8578eedc9a5772dbcbf6fa83" integrity sha512-zg6O1bmffRsHXJOWAnSD2O3tPnVMoD8Yfu+a5zBVXDiUP1E/TGzgjjjYBUUCU3yQg1Ted5rIn4o6ql/rZNNlgA== @@ -3032,7 +3032,7 @@ global "^4.3.2" util-deprecate "^1.0.2" -"@storybook/addons@5.3.18": +"@storybook/addons@5.3.18", "@storybook/addons@^5.3.17": version "5.3.18" resolved "https://registry.npmjs.org/@storybook/addons/-/addons-5.3.18.tgz#5cbba6407ef7a802041c5ee831473bc3bed61f64" integrity sha512-ZQjDgTUDFRLvAiBg2d8FgPgghfQ+9uFyXQbtiGlTBLinrPCeQd7J86qiUES0fcGoohCCw0wWKtvB0WF2z1XNDg== @@ -3108,6 +3108,17 @@ global "^4.3.2" telejson "^3.2.0" +"@storybook/channel-postmessage@5.3.18": + version "5.3.18" + resolved "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-5.3.18.tgz#93d46740b5cc9b36ddd073f0715b54c4959953bf" + integrity sha512-awxBW/aVfNtY9QvYZgsPaMXgUpC2+W3vEyQcl/w4ce0YVH+7yWx3wt3Ku49lQwxZwDrxP3QoC0U+mkPc9hBJwA== + dependencies: + "@storybook/channels" "5.3.18" + "@storybook/client-logger" "5.3.18" + core-js "^3.0.1" + global "^4.3.2" + telejson "^3.2.0" + "@storybook/channels@5.3.17": version "5.3.17" resolved "https://registry.npmjs.org/@storybook/channels/-/channels-5.3.17.tgz#74eccb10c2395499da6a290bcd0272d6d6c7c5b2" @@ -3145,6 +3156,29 @@ ts-dedent "^1.1.0" util-deprecate "^1.0.2" +"@storybook/client-api@5.3.18": + version "5.3.18" + resolved "https://registry.npmjs.org/@storybook/client-api/-/client-api-5.3.18.tgz#e71041796f95888de0e4524734418e6b120b060a" + integrity sha512-QiXTDUpjdyW19BlocLw07DrkOnEzVaWGJcRze2nSs29IKKuq1Ncv2LOAZt6ySSq0PmIKsjBou3bmS1/aXmDMdw== + dependencies: + "@storybook/addons" "5.3.18" + "@storybook/channel-postmessage" "5.3.18" + "@storybook/channels" "5.3.18" + "@storybook/client-logger" "5.3.18" + "@storybook/core-events" "5.3.18" + "@storybook/csf" "0.0.1" + "@types/webpack-env" "^1.15.0" + core-js "^3.0.1" + eventemitter3 "^4.0.0" + global "^4.3.2" + is-plain-object "^3.0.0" + lodash "^4.17.15" + memoizerific "^1.11.3" + qs "^6.6.0" + stable "^0.1.8" + ts-dedent "^1.1.0" + util-deprecate "^1.0.2" + "@storybook/client-logger@5.3.17": version "5.3.17" resolved "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-5.3.17.tgz#bf9c7ef52da75a5c1f2c5d74724442224deea6e4" @@ -4173,11 +4207,6 @@ resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA== -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= - "@types/lodash@4.14.149": version "4.14.149" resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.149.tgz#1342d63d948c6062838fbf961012f74d4e638440" @@ -4514,10 +4543,10 @@ dependencies: pretty-format "^25.1.0" -"@types/testing-library__jest-dom@5.0.2": - version "5.0.2" - resolved "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.0.2.tgz#89b782e0f187fe1e80d6375133da74182ba02065" - integrity sha512-dZP+/WHndgCSmdaImITy0KhjGAa9c0hlGGkzefbtrPFpnGEPZECDA0zyvfSp8RKhHECJJSKHFExjOwzo0rHyIA== +"@types/testing-library__jest-dom@5.0.4": + version "5.0.4" + resolved "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.0.4.tgz#c7bfbafb920cd1ce40506474e70ee73637f33701" + integrity sha512-Ns69aaNvlxvXkPxIwsqeaWH5vJpwa/pdBIlf8LGkRnbV3tiqUgifs13moLXg1NQ2AM23qRR5CtHarNshvRyEdA== dependencies: "@types/jest" "*" @@ -20480,16 +20509,6 @@ tsc-watch@^4.2.3: string-argv "^0.1.1" strip-ansi "^4.0.0" -tsconfig-paths@^3.9.0: - version "3.9.0" - resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b" - integrity sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.1" - minimist "^1.2.0" - strip-bom "^3.0.0" - tslib@1.10.0: version "1.10.0" resolved "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"