diff --git a/CHANGELOG.md b/CHANGELOG.md
index 20ae9a414d..9f9235172b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,11 @@ If you encounter issues while upgrading to a newer version, don't hesitate to re
> Collect changes for the next release below
+- Material-UI: Bumped to 4.11.0, which is the version that create-app will
+ resolve to, because we wanted to get the renaming of ExpansionPanel to
+ Accordion into place. This gets rid of a lot of console deprecation warnings
+ in newly scaffolded apps.
+
- The backend plugin
[service builder](https://github.com/spotify/backstage/blob/master/packages/backend-common/src/service/lib/ServiceBuilderImpl.ts)
no longer adds `express.json()` automatically to all routes. While convenient
diff --git a/docs/api/utility-apis.md b/docs/api/utility-apis.md
index 0e09da3f83..37cde87262 100644
--- a/docs/api/utility-apis.md
+++ b/docs/api/utility-apis.md
@@ -17,7 +17,7 @@ Utility APIs. While the `createPlugin` API is focused on the initialization
plugins and the app, the Utility APIs provide ways for plugins to communicate
during their entire life cycle.
-## Usage
+## Consuming APIs
Each Utility API is tied to an `ApiRef` instance, which is a global singleton
object without any additional state or functionality, its only purpose is to
@@ -55,51 +55,112 @@ from any component inside Backstage, including the ones in `@backstage/core`.
The only requirement is that they are beneath the `AppProvider` in the react
tree.
-## Registering Utility API Implementations
+## Supplying APIs
-The Backstage App is responsible for providing implementations for all Utility
-APIs required by plugins. The example app in this repo registers its APIs inside
-[src/apis.ts](/packages/app/src/apis.ts). Here's an example of how to wire up
-the `ErrorApi` inside an app:
+### API Factories
+
+APIs are registered in the form of `ApiFactories`, which encapsulate the process
+of instantiating an API. It is a collection of three things: the `ApiRef` of the
+API to instantiate, a list of all required dependencies, and a factory function
+that returns a new API instance.
+
+For example, this is the default `ApiFactory` for the `ErrorApi`:
```ts
-import {
- ApiRegistry,
- createApp,
- alertApiRef,
- errorApiRef,
- AlertApiForwarder,
- ErrorApiForwarder,
- ErrorAlerter,
- ConfigApi,
-} from '@backstage/core';
-
-const apis = (config: ConfigApi) => {
- const builder = ApiRegistry.builder();
-
- // The alert API is a self-contained implementation that shows alerts to the user.
- const alertApi = builder.add(alertApiRef, new AlertApiForwarder());
-
- // The error API uses the alert API to send error notifications to the user.
- builder.add(errorApiRef, new ErrorAlerter(alertApi, new ErrorApiForwarder()));
- return builder.build();
-};
-
-const app = createApp({
- apis,
- // ... other config
+createApiFactory({
+ api: errorApiRef,
+ deps: { alertApi: alertApiRef },
+ factory: ({ alertApi }) =>
+ new ErrorAlerter(alertApi, new ErrorApiForwarder()),
});
```
-The `ApiRegistry` is used to register all Utility APIs in the app and associate
-them with `ApiRef`s. It implements the `ApiHolder` interface, which enables it
-to provide an API implementation given an `ApiRef`.
+In this example the `errorApiRef` is our API, which encapsulates the `ErrorApi`
+type. The `alertApiRef` is our single dependency, which we give the name
+`alertApi`, and is then passed on to the factory function, which returns an
+implementation of the `ErrorApi`.
-Note that our `ErrorApi` implementation depends on another Utility API, the
-`AlertApi`. This is the method with which APIs can depend on other APIs, using
-manual dependency injection at the initialization of the app. In general, if you
-want to depend on another Utility API in an implementation of an API, you import
-the type for that API and make it a constructor parameter.
+The `createApiFactory` function is a thin wrapper that enables TypeScript type
+inference. You may notice that there are no type annotations in the above
+example, and that is because we're able to infer all types from the `ApiRef`s.
+TypeScript will make sure that the return value of the `factory` function
+matches the type embedded in `api`'s `ApiRef`, in this case the `ErrorApi`. It
+will also match the types between the `deps` and the parameters of the `factory`
+function, again using the type embedded within the `ApiRef`s.
+
+## Registering API Factories
+
+The responsibility for adding Utility APIs to a Backstage app lies in three
+different locations: the Backstage core library, each plugin included in the
+app, and the app itself.
+
+### Core APIs
+
+Starting with the Backstage core library, it provides implementation for all of
+the core APIs. The core APIs are the ones exported by `@backstage/core`, such as
+the `errorApiRef` and `configApiRef`. You can find a full list of them
+[here](../reference/utility-apis/README.md).
+
+The core APIs are loaded for any app created with `createApp` from
+`@backstage/core`, which means that there is no step that needs to be taken to
+include these APIs in an app.
+
+### Plugin APIs
+
+In addition to the core APIs, plugins can define and export their own APIs.
+While doing so they should usually also provide default implementations of their
+own APIs, for example, the `catalog` plugin exports `catalogApiRef`, and also
+supplies a default `ApiFactory` of that API using the `CatalogClient`. There is
+one restriction to plugin-provided API Factories: plugins may not supply
+factories for core APIs, trying to do so will cause the app to crash.
+
+Plugins supply their APIs through the `apis` option of `createPlugin`, for
+example:
+
+```ts
+export const plugin = createPlugin({
+ id: 'techdocs',
+ apis: [
+ createApiFactory({
+ api: techdocsStorageApiRef,
+ deps: { configApi: configApiRef },
+ factory({ configApi }) {
+ return new TechDocsStorageApi({
+ apiOrigin: configApi.getString('techdocs.storageUrl'),
+ });
+ },
+ }),
+ ],
+});
+```
+
+### App APIs
+
+Lastly, the app itself is the final point where APIs can be added, and what has
+the final say in what APIs will be loaded at runtime. The app may override the
+factories for any of the core or plugin APIs, with the exception of the config,
+app theme, and identity APIs. These are static APIs that are tied into the
+`createApp` implementation, and therefore not possible to override.
+
+Overriding APIs is useful for apps that want to switch out behavior to tailor it
+to their environment. In some cases plugins may also export multiple
+implementations of the same API, where they each have their own different
+requirements on for example backend storage and surrounding environment.
+
+Supplying APIs to the app works just like for plugins:
+
+```ts
+const app = createApp({
+ apis: [
+ /* ApiFactories */
+ ],
+ // ... other options
+});
+```
+
+A common pattern is to export a list of all APIs from `apis.ts`, next to
+`App.tsx`. See the [example app in this repo](../../packages/app/src/apis.ts)
+for an example.
## Custom implementations of Utility APIs
@@ -127,19 +188,33 @@ implement the `ErrorApi`, as it is checked by the type embedded in the
## Defining custom Utility APIs
-The pattern for plugins defining their own Utility APIs is not fully established
-yet. The current way is for the plugin to export its own `ApiRef` and type for
-the API, along with one or more implementations. It is then up to the app to
-import, and register those APIs. See for example the
-[lighthouse](/plugins/lighthouse/src/api.ts) or
-[graphiql](/plugins/graphiql/src/lib/api/types.ts) plugins for examples of this.
+Plugins are free to define their own Utility APIs. Simply define the TypeScript
+interface for the API, and create an `ApiRef` using `createApiRef` exported from
+`@backstage/core`. Also be sure to provide at least one implementation of the
+API, and to declare a default factory for the API in `createPlugin`.
-The goal is to make this process a bit smoother, but that requires work in other
-parts of Backstage, like configuration management. So it remains as a TODO. If
-you have more questions regarding this, or have an idea for an API that you want
-to share outside your plugin, hit us up in
-[GitHub issues](https://github.com/spotify/backstage/issues/new/choose) or the
-[Backstage Discord server](https://discord.gg/EBHEGzX).
+Custom Utility APIs can be either public or private, which it is up to the
+plugin to choose. Private APIs do not expose an external API surface, and it's
+therefore possible to make breaking changes to the API without affecting other
+users of the plugin. If an API is made public however, it opens up for other
+plugins to make use of the API, and it also makes it possible for users for your
+plugin to override the API in the app. It is however important to maintain
+backwards compatibility of public APIs, as you may otherwise break apps that are
+using your plugin.
+
+To make an API public, simply export the `ApiRef` of the API, and any associated
+types. To make an API private, just avoid exporting the `ApiRef`, but still be
+sure to supply a default factory to `createPlugin`.
+
+Private APIs are useful for plugins that want to depend on other APIs outside of
+React components, but not have to expose an entire API surface to maintain. When
+using private APIs, it is fine to use the `typeof` of an implementing class as
+the type parameter passed to `createApiRef`, while public APIs should always
+define a separate TypeScript interface type.
+
+Plugins may depend on APIs from other plugins, both in React components and as
+dependencies to API factories. Do however be sure to not cause circular
+dependencies between plugins.
## Architecture
diff --git a/docs/architecture-decisions/index.md b/docs/architecture-decisions/index.md
index 91d2c668d7..0e9ff21812 100644
--- a/docs/architecture-decisions/index.md
+++ b/docs/architecture-decisions/index.md
@@ -4,7 +4,7 @@ title: Architecture Decision Records (ADR)
sidebar_label: Overview
---
-The substantial architecture decisions made in the Backstage project lives here.
+The substantial architecture decisions made in the Backstage project live here.
For more information about ADRs, when to write them, and why, please see
[this blog post](https://engineering.atspotify.com/2020/04/14/when-should-i-write-an-architecture-decision-record/).
diff --git a/docs/assets/getting-started/create-app_output.png b/docs/assets/getting-started/create-app_output.png
index 52dcc13097..caa39ec6d2 100644
Binary files a/docs/assets/getting-started/create-app_output.png and b/docs/assets/getting-started/create-app_output.png differ
diff --git a/docs/getting-started/create-an-app.md b/docs/getting-started/create-an-app.md
index fe22935002..95641f20d1 100644
--- a/docs/getting-started/create-an-app.md
+++ b/docs/getting-started/create-an-app.md
@@ -15,7 +15,13 @@ To create a Backstage app, you will need to have
[NodeJS](https://nodejs.org/en/download/) Active LTS Release installed
(currently v12).
-With `npx`:
+Backstage provides a utility for creating new apps. It guides you through the
+initial setup of selecting the name of the app and a database for the backend.
+The database options are either SQLite or PostgreSQL, where the latter requires
+you to set up a separate database instance. If in doubt, choose SQLite, but
+don't worry about the choice, it's easy to change later!
+
+The easiest way to run the create app package is with `npx`:
```bash
npx @backstage/create-app
@@ -25,7 +31,7 @@ This will create a new Backstage App inside the current folder. The name of the
app-folder is the name that was provided when prompted.
-
+
Inside that directory, it will generate all the files and folder structure
@@ -80,3 +86,12 @@ yarn start
_When `yarn start` is ready it should open up a browser window displaying your
app, if not you can navigate to `http://localhost:3000`._
+
+In most cases you will want to start the backend as well, as it is required for
+the catalog to work, along with many other plugins.
+
+To start the backend, open a separate terminal session and run the following:
+
+```bash
+yarn --cwd packages/backend start
+```
diff --git a/microsite/blog/2020-09-08-announcing-tech-docs.md b/microsite/blog/2020-09-08-announcing-tech-docs.md
index c30f47e8be..624b80842a 100644
--- a/microsite/blog/2020-09-08-announcing-tech-docs.md
+++ b/microsite/blog/2020-09-08-announcing-tech-docs.md
@@ -6,6 +6,9 @@ authorURL: https://github.com/garyniemen
Since we [open sourced Backstage](https://backstage.io/blog/2020/03/16/announcing-backstage), one of the most requested features has been for a technical documentation plugin. Well, good news. The first open source version of TechDocs is here. Now let’s start collaborating and making it better, together.
+
+
Internally, we call it TechDocs. It’s the most used plugin at Spotify by far — accounting for about 20% of our Backstage traffic (even though it is just one of 130+ plugins). Its popularity is evidence of something simple: We made documentation so easy to create, find, and use — people actually use it.
diff --git a/microsite/data/plugins/graphiql.yaml b/microsite/data/plugins/graphiql.yaml
index 6c95d1b175..e997360b04 100644
--- a/microsite/data/plugins/graphiql.yaml
+++ b/microsite/data/plugins/graphiql.yaml
@@ -3,12 +3,10 @@ title: GraphiQL
author: Spotify
authorUrl: https://github.com/spotify
category: Debugging
-description: Integrates GraphiQL as a tool to browse GraphiQL endpoints inside Backstage.
-documentation: https://github.com/spotify/backstage/tree/master/plugins/lighthouse
+description: Integrates GraphiQL as a tool to browse GraphQL API endpoints inside Backstage.
+documentation: https://github.com/spotify/backstage/tree/master/plugins/graphiql
iconUrl: https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/GraphQL_Logo.svg/1024px-GraphQL_Logo.svg.png
npmPackageName: '@backstage/plugin-graphiql'
tags:
- graphql
- - github
- - gitlab
- - api
+ - graphiql
diff --git a/microsite/pages/en/demos.js b/microsite/pages/en/demos.js
index 0cb200892c..d891e05613 100644
--- a/microsite/pages/en/demos.js
+++ b/microsite/pages/en/demos.js
@@ -81,7 +81,9 @@ const Background = props => {
- Make documentation easy
+
+ Make documentation easy
+
Documentation! Everyone needs it, no one wants to create it, and
no one can ever find it. Backstage follows a “docs like code”
diff --git a/mkdocs.yml b/mkdocs.yml
index b12c8f81c7..eb8fa1bf84 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -34,6 +34,7 @@ nav:
- API: 'features/software-catalog/api.md'
- Software creation templates:
- Overview: 'features/software-templates/index.md'
+ - Installation: 'features/software-templates/installation.md'
- Adding templates: 'features/software-templates/adding-templates.md'
- Extending the Scaffolder:
- Overview: 'features/software-templates/extending/index.md'
diff --git a/packages/app/package.json b/packages/app/package.json
index 77f5ab4432..bf0f340a40 100644
--- a/packages/app/package.json
+++ b/packages/app/package.json
@@ -27,7 +27,7 @@
"@backstage/plugin-welcome": "^0.1.1-alpha.21",
"@backstage/test-utils": "^0.1.1-alpha.21",
"@backstage/theme": "^0.1.1-alpha.21",
- "@material-ui/core": "^4.9.1",
+ "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@octokit/rest": "^18.0.0",
"@roadiehq/backstage-plugin-github-pull-requests": "0.3.0",
diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx
index 1139337556..667b14366f 100644
--- a/packages/app/src/App.tsx
+++ b/packages/app/src/App.tsx
@@ -19,6 +19,7 @@ import {
AlertDisplay,
OAuthRequestDialog,
SignInPage,
+ createRouteRef,
} from '@backstage/core';
import React, { FC } from 'react';
import Root from './components/Root';
@@ -31,6 +32,7 @@ import { Router as DocsRouter } from '@backstage/plugin-techdocs';
import { Router as GraphiQLRouter } from '@backstage/plugin-graphiql';
import { Router as TechRadarRouter } from '@backstage/plugin-tech-radar';
import { Router as LighthouseRouter } from '@backstage/plugin-lighthouse';
+import { Router as RegisterComponentRouter } from '@backstage/plugin-register-component';
import { Route, Routes, Navigate } from 'react-router';
import { EntityPage } from './components/catalog/EntityPage';
@@ -56,11 +58,16 @@ const AppProvider = app.getProvider();
const AppRouter = app.getRouter();
const deprecatedAppRoutes = app.getRoutes();
+const catalogRouteRef = createRouteRef({
+ path: '/catalog',
+ title: 'Service Catalog',
+});
+
const AppRoutes = () => (
}
/>
} />
@@ -70,6 +77,10 @@ const AppRoutes = () => (
/>
} />
} />
+ }
+ />
{...deprecatedAppRoutes}
);
diff --git a/packages/cli/templates/default-plugin/package.json.hbs b/packages/cli/templates/default-plugin/package.json.hbs
index 38d4e41b5b..dbfb639b16 100644
--- a/packages/cli/templates/default-plugin/package.json.hbs
+++ b/packages/cli/templates/default-plugin/package.json.hbs
@@ -23,7 +23,7 @@
"dependencies": {
"@backstage/core": "^{{backstageVersion}}",
"@backstage/theme": "^{{backstageVersion}}",
- "@material-ui/core": "^4.9.1",
+ "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
"react": "^16.13.1",
diff --git a/packages/core-api/package.json b/packages/core-api/package.json
index a5e23796cd..191394e536 100644
--- a/packages/core-api/package.json
+++ b/packages/core-api/package.json
@@ -31,7 +31,7 @@
"dependencies": {
"@backstage/config": "^0.1.1-alpha.21",
"@backstage/theme": "^0.1.1-alpha.21",
- "@material-ui/core": "^4.9.1",
+ "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@types/react": "^16.9",
"prop-types": "^15.7.2",
diff --git a/packages/core/package.json b/packages/core/package.json
index d6731aca9a..7e9932bdc1 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -32,7 +32,7 @@
"@backstage/config": "^0.1.1-alpha.21",
"@backstage/core-api": "^0.1.1-alpha.21",
"@backstage/theme": "^0.1.1-alpha.21",
- "@material-ui/core": "^4.9.1",
+ "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
"@types/react": "^16.9",
diff --git a/packages/create-app/templates/default-app/packages/app/package.json.hbs b/packages/create-app/templates/default-app/packages/app/package.json.hbs
index a52810b31c..a057826ba4 100644
--- a/packages/create-app/templates/default-app/packages/app/package.json.hbs
+++ b/packages/create-app/templates/default-app/packages/app/package.json.hbs
@@ -4,7 +4,7 @@
"private": true,
"bundled": true,
"dependencies": {
- "@material-ui/core": "^4.9.1",
+ "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@backstage/cli": "^{{version}}",
"@backstage/core": "^{{version}}",
diff --git a/packages/create-app/templates/default-app/packages/app/src/App.tsx b/packages/create-app/templates/default-app/packages/app/src/App.tsx
index 42eaeccc51..9449ac68a1 100644
--- a/packages/create-app/templates/default-app/packages/app/src/App.tsx
+++ b/packages/create-app/templates/default-app/packages/app/src/App.tsx
@@ -4,6 +4,7 @@ import {
AlertDisplay,
OAuthRequestDialog,
SidebarPage,
+ createRouteRef,
} from '@backstage/core';
import { apis } from './apis';
import * as plugins from './plugins';
@@ -11,8 +12,9 @@ import { AppSidebar } from './sidebar';
import { Route, Routes, Navigate } from 'react-router';
import { Router as CatalogRouter } from '@backstage/plugin-catalog';
import { Router as DocsRouter } from '@backstage/plugin-techdocs';
-
+import { Router as RegisterComponentRouter } from '@backstage/plugin-register-component';
import { Router as TechRadarRouter } from '@backstage/plugin-tech-radar';
+
import { EntityPage } from './components/catalog/EntityPage';
const app = createApp({
@@ -24,6 +26,12 @@ const AppProvider = app.getProvider();
const AppRouter = app.getRouter();
const deprecatedAppRoutes = app.getRoutes();
+const catalogRouteRef = createRouteRef({
+ path: '/catalog',
+ title: 'Service Catalog',
+});
+
+
const App: FC<{}> = () => (
@@ -42,6 +50,10 @@ const App: FC<{}> = () => (
path="/tech-radar"
element={}
/>
+ }
+ />
{deprecatedAppRoutes}
diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json
index c917130cbd..fe7272bf04 100644
--- a/packages/dev-utils/package.json
+++ b/packages/dev-utils/package.json
@@ -33,7 +33,7 @@
"@backstage/core": "^0.1.1-alpha.21",
"@backstage/test-utils": "^0.1.1-alpha.21",
"@backstage/theme": "^0.1.1-alpha.21",
- "@material-ui/core": "^4.9.1",
+ "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json
index d28b66a9ed..8567af8c14 100644
--- a/packages/test-utils/package.json
+++ b/packages/test-utils/package.json
@@ -33,7 +33,7 @@
"@backstage/core-api": "^0.1.1-alpha.21",
"@backstage/test-utils-core": "^0.1.1-alpha.21",
"@backstage/theme": "^0.1.1-alpha.21",
- "@material-ui/core": "^4.9.1",
+ "@material-ui/core": "^4.11.0",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
diff --git a/packages/theme/package.json b/packages/theme/package.json
index e946482f32..436455633b 100644
--- a/packages/theme/package.json
+++ b/packages/theme/package.json
@@ -28,7 +28,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@material-ui/core": "^4.9.1"
+ "@material-ui/core": "^4.11.0"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.21"
diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json
index b22cb6fd63..a913316925 100644
--- a/plugins/api-docs/package.json
+++ b/plugins/api-docs/package.json
@@ -26,7 +26,7 @@
"@backstage/theme": "^0.1.1-alpha.21",
"@kyma-project/asyncapi-react": "^0.11.0",
"@material-icons/font": "^1.0.2",
- "@material-ui/core": "^4.9.1",
+ "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
"react": "^16.13.1",
diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json
index 5f17fc2a80..d32033d4fc 100644
--- a/plugins/catalog/package.json
+++ b/plugins/catalog/package.json
@@ -29,7 +29,7 @@
"@backstage/plugin-sentry": "^0.1.1-alpha.21",
"@backstage/plugin-techdocs": "^0.1.1-alpha.21",
"@backstage/theme": "^0.1.1-alpha.21",
- "@material-ui/core": "^4.9.1",
+ "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
"moment": "^2.26.0",
diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json
index f86563ea7a..7c8f36d370 100644
--- a/plugins/circleci/package.json
+++ b/plugins/circleci/package.json
@@ -25,7 +25,7 @@
"@backstage/catalog-model": "^0.1.1-alpha.21",
"@backstage/plugin-catalog": "^0.1.1-alpha.21",
"@backstage/theme": "^0.1.1-alpha.21",
- "@material-ui/core": "^4.9.1",
+ "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
"circleci-api": "^4.0.0",
diff --git a/plugins/circleci/src/components/BuildWithStepsPage/lib/ActionOutput/ActionOutput.tsx b/plugins/circleci/src/components/BuildWithStepsPage/lib/ActionOutput/ActionOutput.tsx
index dd526c1b5f..2a059f7e02 100644
--- a/plugins/circleci/src/components/BuildWithStepsPage/lib/ActionOutput/ActionOutput.tsx
+++ b/plugins/circleci/src/components/BuildWithStepsPage/lib/ActionOutput/ActionOutput.tsx
@@ -13,18 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import React, { useEffect, useState, FC, Suspense } from 'react';
+
import {
- ExpansionPanel,
- ExpansionPanelSummary,
- Typography,
- ExpansionPanelDetails,
+ Accordion,
+ AccordionDetails,
+ AccordionSummary,
LinearProgress,
+ Typography,
} from '@material-ui/core';
-import moment from 'moment';
-import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import { makeStyles } from '@material-ui/core/styles';
+import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import { BuildStepAction } from 'circleci-api';
+import moment from 'moment';
+import React, { FC, Suspense, useEffect, useState } from 'react';
const LazyLog = React.lazy(() => import('react-lazylog/build/LazyLog'));
moment.relativeTimeThreshold('ss', 0);
@@ -66,11 +67,8 @@ export const ActionOutput: FC<{
)
.humanize();
return (
-
-
+ }
aria-controls={`panel-${name}-content`}
id={`panel-${name}-header`}
@@ -81,8 +79,8 @@ export const ActionOutput: FC<{
{name} ({timeElapsed})
-
-
+
+
{messages.length === 0 ? (
'Nothing here...'
) : (
@@ -92,7 +90,7 @@ export const ActionOutput: FC<{
)}
-
-
+
+
);
};
diff --git a/plugins/explore/package.json b/plugins/explore/package.json
index 1a4a44b9cd..f302f4080c 100644
--- a/plugins/explore/package.json
+++ b/plugins/explore/package.json
@@ -23,7 +23,7 @@
"dependencies": {
"@backstage/core": "^0.1.1-alpha.21",
"@backstage/theme": "^0.1.1-alpha.21",
- "@material-ui/core": "^4.9.1",
+ "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
"classnames": "^2.2.6",
diff --git a/plugins/gcp-projects/package.json b/plugins/gcp-projects/package.json
index 55ed362876..cdc4bb507d 100644
--- a/plugins/gcp-projects/package.json
+++ b/plugins/gcp-projects/package.json
@@ -23,7 +23,7 @@
"dependencies": {
"@backstage/core": "^0.1.1-alpha.21",
"@backstage/theme": "^0.1.1-alpha.21",
- "@material-ui/core": "^4.9.1",
+ "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
"react": "^16.13.1",
diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json
index e4f09976eb..e55a195f6e 100644
--- a/plugins/github-actions/package.json
+++ b/plugins/github-actions/package.json
@@ -27,11 +27,11 @@
"@backstage/core-api": "^0.1.1-alpha.21",
"@backstage/plugin-catalog": "^0.1.1-alpha.21",
"@backstage/theme": "^0.1.1-alpha.21",
- "@material-ui/core": "^4.9.1",
+ "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
"@octokit/rest": "^18.0.0",
- "@octokit/types": "^5.0.1",
+ "@octokit/types": "^5.4.1",
"moment": "^2.27.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
diff --git a/plugins/github-actions/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx b/plugins/github-actions/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx
index d8e3b02524..a8ceb717da 100644
--- a/plugins/github-actions/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx
+++ b/plugins/github-actions/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx
@@ -13,37 +13,38 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import React from 'react';
-import { useWorkflowRunsDetails } from './useWorkflowRunsDetails';
-import { useWorkflowRunJobs } from './useWorkflowRunJobs';
-import { useProjectName } from '../useProjectName';
-import {
- makeStyles,
- Box,
- TableRow,
- TableCell,
- ListItemText,
- ExpansionPanel,
- ExpansionPanelSummary,
- Typography,
- ExpansionPanelDetails,
- TableContainer,
- Table,
- Paper,
- TableBody,
- LinearProgress,
- CircularProgress,
- Theme,
- Breadcrumbs,
- Link as MaterialLink,
-} from '@material-ui/core';
-import { Jobs, Job, Step } from '../../api';
-import moment from 'moment';
-import { WorkflowRunStatus } from '../WorkflowRunStatus';
-import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
-import ExternalLinkIcon from '@material-ui/icons/Launch';
+
import { Entity } from '@backstage/catalog-model';
import { Link } from '@backstage/core';
+import {
+ Accordion,
+ AccordionDetails,
+ AccordionSummary,
+ Box,
+ Breadcrumbs,
+ CircularProgress,
+ LinearProgress,
+ Link as MaterialLink,
+ ListItemText,
+ makeStyles,
+ Paper,
+ Table,
+ TableBody,
+ TableCell,
+ TableContainer,
+ TableRow,
+ Theme,
+ Typography,
+} from '@material-ui/core';
+import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
+import ExternalLinkIcon from '@material-ui/icons/Launch';
+import moment from 'moment';
+import React from 'react';
+import { Job, Jobs, Step } from '../../api';
+import { useProjectName } from '../useProjectName';
+import { WorkflowRunStatus } from '../WorkflowRunStatus';
+import { useWorkflowRunJobs } from './useWorkflowRunJobs';
+import { useWorkflowRunsDetails } from './useWorkflowRunsDetails';
const useStyles = makeStyles(theme => ({
root: {
@@ -113,11 +114,8 @@ const StepView = ({ step }: { step: Step }) => {
const JobListItem = ({ job, className }: { job: Job; className: string }) => {
const classes = useStyles();
return (
-
-
+ }
aria-controls={`panel-${name}-content`}
id={`panel-${name}-header`}
@@ -128,8 +126,8 @@ const JobListItem = ({ job, className }: { job: Job; className: string }) => {
{job.name} ({getElapsedTime(job.started_at, job.completed_at)})
-
-
+
+