Merge branch 'backstage:master' into awanlin/azure-devops-frontend-plugin
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-api-docs': patch
|
||||
---
|
||||
|
||||
Bump `swagger-ui-react` to `^4.0.0-rc.3`.
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@backstage/core-app-api': patch
|
||||
'@backstage/core-components': patch
|
||||
'@backstage/theme': patch
|
||||
---
|
||||
|
||||
Internal refactor to avoid importing all of `@material-ui/core`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog': patch
|
||||
---
|
||||
|
||||
Support `material-ui` overrides in SystemDiagramCard and EmptityLinksEmptyState components
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
'@backstage/plugin-home': patch
|
||||
---
|
||||
|
||||
Adds a `<WelcomeTitle>` component that shows a playful greeting on the home page.
|
||||
To use it, pass it to the home page header:
|
||||
|
||||
```typescript
|
||||
<Page themeId="home">
|
||||
<Header title={<WelcomeTitle />} pageTitleOverride="Home">
|
||||
<HomepageTimer />
|
||||
</Header>
|
||||
…
|
||||
</Page>
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
---
|
||||
|
||||
Fix search in Firefox. When the search was performed by pressing enter, the query parameter was first set but then reverted back.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-components': minor
|
||||
---
|
||||
|
||||
The syntax highlighting library used by the `CodeSnippet` component is now lazy loaded. This most likely has no effect on existing code, but may break tests as the content of the `CodeSnippet` is now rendered asynchronously.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend': patch
|
||||
---
|
||||
|
||||
This change refactors the internal package structure to remove the `next` catalog folder that was used during the implementation and testing phase of the new catalog engine. The implementation is now the default and is therefore restructured to no longer be packaged under `next/`. This refactor does not change catalog imports from other parts of the project.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Update default backend ESLint configuration to allow usage of `__dirname` in tests.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-azure-devops-backend': patch
|
||||
---
|
||||
|
||||
Expands the Azure DevOps backend plugin to provide pull request data to be used by the front end plugin
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-home': patch
|
||||
---
|
||||
|
||||
Fix `<ComponentTabs>` to display only the selected tab, not the other way around.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
---
|
||||
|
||||
Support `material-ui` overrides in plugin-catalog-react components
|
||||
@@ -55,3 +55,4 @@
|
||||
| [Santagostino](https://santagostino.it) | [@santagostino](https://github.com/santagostino) | Developer portal, gateway to our infrastructure, documentation, service catalog and internal tooling. |
|
||||
| [Peak](https://peak.ai) | [Luke Beamish](https://github.com/lukebeamish-peak) | Developer portal for all internal engineers to access documentation and tooling. |
|
||||
| [Gelato](https://gelato.com/) | [Dmitry Makarenko](https://github.com/dmitry-makarenko-gelato) | Developer portal: documentation, service templates, org structure, service catalog, plugins for integration with internal and third-party systems🚀. |
|
||||
| [GoCardless](https://gocardless.com/) | [James Turley](https://github.com/tragiclifestories) | Developer portal: documentation, service templates, org structure, service catalog, plugins for integration with internal systems. |
|
||||
+4
-3
@@ -129,9 +129,10 @@ In general, changesets are not needed for the documentation, build utilities, co
|
||||
1. Run `yarn changeset`
|
||||
2. Select which packages you want to include a changeset for
|
||||
3. Select impact of change that you're introducing, using `minor` for breaking changes and `patch` otherwise. We do not use `major` changes while packages are at version `0.x`.
|
||||
4. Add generated changeset to Git
|
||||
5. Push the commit with your changeset to the branch associated with your PR
|
||||
6. Accept our gratitude for making the release process easier on the maintainers
|
||||
4. Explain your changes in the generated changeset. See [examples of well written changesets](https://backstage.io/docs/getting-started/contributors#writing-changesets).
|
||||
5. Add generated changeset to Git
|
||||
6. Push the commit with your changeset to the branch associated with your PR
|
||||
7. Accept our gratitude for making the release process easier on the maintainers
|
||||
|
||||
For more information, checkout [adding a changeset](https://github.com/atlassian/changesets/blob/master/docs/adding-a-changeset.md) documentation in the changesets repository.
|
||||
|
||||
|
||||
@@ -139,3 +139,92 @@ default app configs.
|
||||
|
||||
You can learn more about the local configuration in
|
||||
[Static Configuration in Backstage](../conf/) section.
|
||||
|
||||
## Writing changesets
|
||||
|
||||
Changesets are an important part of the development process. They are used to
|
||||
generate Changelog entries for all changes to the project. Ultimately they are
|
||||
read by the end users to learn about important changes and fixes to the project.
|
||||
Some of these fixes might require manual intervention from users so it's
|
||||
important to write changesets that users understand and can take action on.
|
||||
|
||||
Here are some important do's and don'ts when writing changesets:
|
||||
|
||||
### Changeset should give a clear description to what has changed
|
||||
|
||||
#### Bad
|
||||
|
||||
```
|
||||
---
|
||||
'@backstage/catalog': patch
|
||||
---
|
||||
Fixed table layout
|
||||
```
|
||||
|
||||
#### Good
|
||||
|
||||
```
|
||||
---
|
||||
'@backstage/catalog': patch
|
||||
---
|
||||
|
||||
Fixed bug in EntityTable component where table layout did not readjust properly below 1080x768 pixels.
|
||||
```
|
||||
|
||||
### Breaking changes not caught by the type checker should be clearly marked with bold **BREAKING** text
|
||||
|
||||
#### Bad
|
||||
|
||||
```
|
||||
---
|
||||
'@backstage/catalog': minor
|
||||
---
|
||||
|
||||
getEntity is now a function that returns a Promise.
|
||||
```
|
||||
|
||||
#### Good
|
||||
|
||||
```
|
||||
---
|
||||
'@backstage/catalog': minor
|
||||
---
|
||||
|
||||
**BREAKING** The getEntity function now returns a Promise and **must** be awaited from now on.
|
||||
```
|
||||
|
||||
### Changes to code should include a diff of the files that need updating
|
||||
|
||||
#### Bad
|
||||
|
||||
```
|
||||
---
|
||||
'@backstage/catalog': patch
|
||||
---
|
||||
|
||||
**BREAKING** The catalogEngine now requires a flux capacitor to be passed.
|
||||
```
|
||||
|
||||
#### Good
|
||||
|
||||
---
|
||||
'@backstage/catalog': patch
|
||||
---
|
||||
|
||||
**BREAKING** The catalog createRouter now requires that a `FluxCapacitor` is
|
||||
passed to the router.
|
||||
|
||||
These changes are **required** to `packages/backend/src/plugins/catalog.ts`
|
||||
|
||||
```diff
|
||||
+ import { FluxCapacitor } from '@backstage/time';
|
||||
+ const fluxCapacitor = new FluxCapacitor();
|
||||
return await createRouter({
|
||||
entitiesCatalog,
|
||||
locationAnalyzer,
|
||||
locationService,
|
||||
+ fluxCapacitor,
|
||||
logger: env.logger,
|
||||
config: env.config,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
---
|
||||
id: installation
|
||||
title: Google Analytics Installation
|
||||
sidebar_label: Installation
|
||||
# prettier-ignore
|
||||
description: Adding Google Analytics to Your App
|
||||
---
|
||||
|
||||
There is a basic
|
||||
[Google Analytics](https://marketingplatform.google.com/about/analytics/)
|
||||
integration built into Backstage. You can enable it by adding the following to
|
||||
your app configuration:
|
||||
|
||||
```yaml
|
||||
app:
|
||||
googleAnalyticsTrackingId: UA-000000-0
|
||||
```
|
||||
|
||||
Replace the tracking ID with the one generated for you after signing up for the
|
||||
Google Analytics service.
|
||||
|
||||
The default behavior is only to send a pageview hit. To record more, review the
|
||||
[Google Analytics developer documentation](https://developers.google.com/analytics/devguides/collection/gtagjs).
|
||||
@@ -0,0 +1,298 @@
|
||||
---
|
||||
id: analytics
|
||||
title: Plugin Analytics
|
||||
description: Measuring usage of your Backstage instance.
|
||||
---
|
||||
|
||||
Setting up, maintaining, and iterating on an instance of Backstage can be a
|
||||
large investment. To help measure return on this investment, Backstage comes
|
||||
with an event-based Analytics API that grants app integrators the flexibility to
|
||||
collect and analyze Backstage usage in the analytics tool of their choice, while
|
||||
providing plugin developers a standard interface for instrumenting key user
|
||||
interactions.
|
||||
|
||||
## Concepts
|
||||
|
||||
- **Events** consist of, at a minimum, an `action` (like `click`) and a
|
||||
`subject` (like `thing that was clicked on`).
|
||||
- **Attributes** represent additional dimensional data (in the form of key/value
|
||||
pairs) that may be provided on an event-by-event basis. To continue the above
|
||||
example, the URL a user clicked to might look like `{ "to": "/a/page" }`.
|
||||
- **Context** represents the broader context in which an event took place. By
|
||||
default, information like `pluginId`, `extension`, and `routeRef` are
|
||||
provided.
|
||||
|
||||
This composition of events aims to allow analysis at different levels of detail,
|
||||
enabling very granular questions (like "what is the most clicked on thing on a
|
||||
particular route") as well as very high-level questions (like "what is the most
|
||||
used plugin in my Backstage instance") to be answered.
|
||||
|
||||
## Supported Analytics Tools
|
||||
|
||||
While all that's needed to consume and forward these events to an analytics tool
|
||||
is a concrete implementation of [AnalyticsApi][analytics-api-type], common
|
||||
integrations are packaged and provided as plugins. Find your analytics tool of
|
||||
choice below.
|
||||
|
||||
| Analytics Tool | Support Status |
|
||||
| ---------------------- | -------------- |
|
||||
| [Google Analytics][ga] | Yes ✅ |
|
||||
|
||||
To suggest an integration, please [open an issue][add-tool] for the analytics
|
||||
tool your organization uses. Or jump to [Writing Integrations][int-howto] to
|
||||
learn how to contribute the integration yourself!
|
||||
|
||||
[ga]:
|
||||
https://github.com/backstage/backstage/blob/master/plugins/analytics-module-ga/README.md
|
||||
[add-tool]:
|
||||
https://github.com/backstage/backstage/issues/new?assignees=&labels=plugin&template=plugin_template.md&title=%5BAnalytics+Module%5D+THE+ANALYTICS+TOOL+TO+INTEGRATE
|
||||
[int-howto]: #writing-integrations
|
||||
[analytics-api-type]:
|
||||
https://backstage.io/docs/reference/core-plugin-api.analyticsapi
|
||||
|
||||
## Key Events
|
||||
|
||||
The following table summarizes events that, depending on the plugins you have
|
||||
installed, may be captured.
|
||||
|
||||
| Action | Provided By | Subject |
|
||||
| ---------- | -------------- | ----------------------------------------- |
|
||||
| `navigate` | Backstage Core | The URL of the page that was navigated to |
|
||||
| `click` | Backstage Core | The text of the link that was clicked on |
|
||||
|
||||
If there is an event you'd like to see captured, please [open an
|
||||
issue][add-event] describing the event you want to see and the questions it
|
||||
would help you answer. Or jump to [Capturing Events][event-howto] to learn how
|
||||
to contribute the instrumentation yourself!
|
||||
|
||||
_OSS plugin maintainers: feel free to document your events in the table above._
|
||||
|
||||
[add-event]:
|
||||
https://github.com/backstage/backstage/issues/new?assignees=&labels=enhancement&template=feature_template.md&title=[Analytics%20Event]:%20THE+EVENT+TO+CAPTURE
|
||||
[event-howto]: #capturing-events
|
||||
|
||||
## Writing Integrations
|
||||
|
||||
Analytics event forwarding is implemented as a Backstage utility API. Just as
|
||||
you might provide a custom API implementation for errors or SCM Authentication,
|
||||
you can provide one for analytics.
|
||||
|
||||
The provided API need only provide a single method `captureEvent`, which takes
|
||||
an `AnalyticsEvent` object.
|
||||
|
||||
```ts
|
||||
import {
|
||||
analyticsApiRef,
|
||||
AnalyticsEvent,
|
||||
AnyApiFactory,
|
||||
createApiFactory,
|
||||
} from '@backstage/core-plugin-api';
|
||||
|
||||
export const apis: AnyApiFactory[] = [
|
||||
createApiFactory(analyticsApiRef, {
|
||||
captureEvent: (event: AnalyticsEvent) => {
|
||||
window._AcmeAnalyticsQ.push(event);
|
||||
},
|
||||
}),
|
||||
];
|
||||
```
|
||||
|
||||
In reality, you would likely want to encapsulate instantiation logic and pull
|
||||
some details from configuration. A more complete example might look like:
|
||||
|
||||
```ts
|
||||
import {
|
||||
AnalyticsApi,
|
||||
analyticsApiRef,
|
||||
AnalyticsEvent,
|
||||
AnyApiFactory,
|
||||
configApiRef,
|
||||
createApiFactory,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { AcmeAnalytics } from 'acme-analytics';
|
||||
|
||||
class AcmeAnalytics implements AnalyticsApi {
|
||||
private constructor(accountId: number) {
|
||||
AcmeAnalytics.init(accountId);
|
||||
}
|
||||
|
||||
static fromConfig(config) {
|
||||
const accountId = config.getString('app.analytics.acme.id');
|
||||
return new AcmeAnalytics(accountId);
|
||||
}
|
||||
|
||||
captureEvent(event: AnalyticsEvent) {
|
||||
const { action, ...rest } = event;
|
||||
AcmeAnalytics.send(action, rest);
|
||||
}
|
||||
}
|
||||
|
||||
export const apis: AnyApiFactory[] = [
|
||||
createApiFactory({
|
||||
api: analyticsApiRef,
|
||||
deps: { configApi: configApiRef },
|
||||
factory: ({ configApi }) => AcmeAnalytics.fromConfig(configApi),
|
||||
}),
|
||||
];
|
||||
```
|
||||
|
||||
If you are integrating with an analytics service (as opposed to an internal
|
||||
tool), consider contributing your API implementation as a plugin!
|
||||
|
||||
By convention, such packages should be named
|
||||
`@backstage/analytics-module-[name]`, and any configuration should be keyed
|
||||
under `app.analytics.[name]`.
|
||||
|
||||
## Capturing Events
|
||||
|
||||
To instrument an event in a component, start by retrieving an analytics tracker
|
||||
using the `useAnalytics()` hook provided by `@backstage/core-plugin-api`. The
|
||||
tracker includes a `captureEvent` method which takes an `action` and a `subject`
|
||||
as arguments.
|
||||
|
||||
```ts
|
||||
import { useAnalytics } from '@backstage/core-plugin-api';
|
||||
|
||||
const analytics = useAnalytics();
|
||||
analytics.captureEvent('deploy', serviceName);
|
||||
```
|
||||
|
||||
### Providing Extra Attributes
|
||||
|
||||
Additional dimensional `attributes` as well as a numeric `value` can be provided
|
||||
on a third `options` argument if/when relevant for the event:
|
||||
|
||||
```ts
|
||||
analytics.captureEvent('merge', pullRequestName, {
|
||||
value: pullRequestAgeInMinutes,
|
||||
attributes: {
|
||||
org,
|
||||
repo,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
In the above example, an event resembling the following object would be
|
||||
captured:
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "merge",
|
||||
"subject": "Name of Pull Request",
|
||||
"value": 60,
|
||||
"attributes": {
|
||||
"org": "some-org",
|
||||
"repo": "some-repo"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Providing Context for Events
|
||||
|
||||
The `attributes` option is good for capturing details available to you within
|
||||
the component that you're instrumenting. For capturing metadata only available
|
||||
further up the react tree, or to help app integrators aggregate distinct events
|
||||
by some common value, use an `<AnalyticsContext>`.
|
||||
|
||||
```tsx
|
||||
import { AnalyticsContext, useAnalytics } from '@backstage/core-plugin-api';
|
||||
|
||||
const MyComponent = ({ value }) => {
|
||||
const analytics = useAnalytics();
|
||||
const handleClick = () => analytics.captureEvent('check', value);
|
||||
return <SomeThing value={value} onClick={handleClick} />;
|
||||
};
|
||||
|
||||
const MyWrapper = () => {
|
||||
return (
|
||||
<AnalyticsContext attributes={{ segment: 'xyz' }}>
|
||||
<MyComponent value={'Some Value'} />
|
||||
</AnalyticsContext>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
In the above example, clicking on `<SomeThing />` would result in an analytics
|
||||
event resembling:
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "check",
|
||||
"subject": "Some Value",
|
||||
"context": {
|
||||
"segment": "xyz"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note that, for brevity in the example above, the context keys provided by
|
||||
Backstage core (`pluginId`, `extension`, and `routeRef`) have been omitted. In
|
||||
reality, those details would be included alongside any additional context
|
||||
provided by you.
|
||||
|
||||
Analytics contexts can be nested; their values are merged down the react tree,
|
||||
allowing keys to be overwritten.
|
||||
|
||||
### Event Naming Considerations
|
||||
|
||||
An event is split into its constituent parts to enable analysis at various
|
||||
levels of granularity. In order to maintain this flexibility at analysis-time,
|
||||
it's important to keep each of these levels of detail disaggregated.
|
||||
|
||||
- Avoid providing an overly specific `action`. For example, instead of
|
||||
`filterEntityTable`, consider just using `filter` as the action, and allowing
|
||||
`EntityTable` to be specified as part of the event's `context` (most likely
|
||||
automatically as part of the `extension` in which the `filter` event was
|
||||
captured).
|
||||
|
||||
- On the flip side, when adding `attributes` to an event, look at existing
|
||||
events and see if the data you are capturing matches the intention, type, or
|
||||
even the content of _their_ `attributes`. For instance, it may be common for
|
||||
events that involve the Catalog to add details like entity `name`, `kind`,
|
||||
and/or `namespace` as `attributes`. Using the same keys in your event will
|
||||
ensure that events instrumented across plugins can easily be aggregated.
|
||||
|
||||
### Unit Testing Event Capture
|
||||
|
||||
The `@backstage/test-utils` package includes a `MockAnalyticsApi` implementation
|
||||
that you can use in your unit tests to spy on and make assertions about any
|
||||
analytics events captured.
|
||||
|
||||
Use it like this:
|
||||
|
||||
```tsx
|
||||
import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
|
||||
import { analyticsApiRef } from '@backstage/core-plugin-api';
|
||||
import { MockAnalyticsApi, wrapInTestApp } from '@backstage/test-utils';
|
||||
import { render, fireEvent, waitFor } from '@testing-library/react';
|
||||
|
||||
describe('SomeComponent', () => {
|
||||
it('should capture event on click', () => {
|
||||
// Use the Mock Analytics API to spy on event captures.
|
||||
const apiSpy = new MockAnalyticsApi();
|
||||
|
||||
// Render the component being tested
|
||||
const { getByText } = render(
|
||||
wrapInTestApp(
|
||||
<ApiProvider apis={ApiRegistry.from([[analyticsApiRef, apiSpy]])}>
|
||||
<SomeComponentUnderTest />
|
||||
</ApiProvider>,
|
||||
),
|
||||
);
|
||||
|
||||
// Fire the event that triggers event capture.
|
||||
fireEvent.click(getByText('some component text'));
|
||||
|
||||
// Assert that the event was captured with the expected data.
|
||||
await waitFor(() => {
|
||||
expect(apiSpy.getEvents()[0]).toMatchObject({
|
||||
action: 'expected action',
|
||||
subject: 'expected subject'',
|
||||
attributes: {
|
||||
foo: 'bar',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
@@ -60,7 +60,7 @@ The YAML file must include the following information. Please note that the
|
||||
indentation for the `privateKey` is required.
|
||||
|
||||
```yaml
|
||||
appId: 1
|
||||
appId: app id
|
||||
clientId: client id
|
||||
clientSecret: client secret
|
||||
webhookSecret: webhook secret
|
||||
@@ -95,7 +95,7 @@ If you want to limit the GitHub app installations visible to backstage you may
|
||||
optionally include the `allowedInstallationOwners` option.
|
||||
|
||||
```yaml
|
||||
appId: 1
|
||||
appId: app id
|
||||
allowedInstallationOwners: ['GlobexCorp']
|
||||
clientId: client id
|
||||
clientSecret: client secret
|
||||
|
||||
@@ -8,11 +8,6 @@ description: Adding Observability to Your Plugin
|
||||
This article briefly describes the observability options that are available to a
|
||||
Backstage integrator.
|
||||
|
||||
## Google Analytics
|
||||
|
||||
See how to install Google Analytics in your app
|
||||
[here](../integrations/google-analytics/installation.md)
|
||||
|
||||
## Datadog RUM Events
|
||||
|
||||
See how to install Datadog Events in your app
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: 'Analytics Module: Google Analytics'
|
||||
author: Spotify
|
||||
authorUrl: https://github.com/spotify
|
||||
category: Analytics
|
||||
description: Track usage of your Backstage instance using Google Analytics.
|
||||
documentation: https://github.com/backstage/backstage/blob/master/plugins/analytics-module-ga/README.md
|
||||
iconUrl: img/ga-icon.png
|
||||
npmPackageName: '@backstage/plugin-analytics-module-ga'
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
title: Grafana
|
||||
author: K-Phoen
|
||||
authorUrl: https://github.com/K-Phoen
|
||||
category: Monitoring
|
||||
description: Associate alerts and dashboards to components.
|
||||
documentation: https://github.com/K-Phoen/backstage-plugin-grafana/
|
||||
iconUrl: https://avatars.githubusercontent.com/u/7195757?s=200&v=4
|
||||
npmPackageName: '@k-phoen/backstage-plugin-grafana'
|
||||
tags:
|
||||
- dashboards
|
||||
- monitoring
|
||||
- alerting
|
||||
@@ -154,11 +154,6 @@
|
||||
"label": "GitLab",
|
||||
"ids": ["integrations/gitlab/locations"]
|
||||
},
|
||||
{
|
||||
"type": "subcategory",
|
||||
"label": "Google Analytics",
|
||||
"ids": ["integrations/google-analytics/installation"]
|
||||
},
|
||||
{
|
||||
"type": "subcategory",
|
||||
"label": "Google GCS",
|
||||
@@ -178,6 +173,7 @@
|
||||
"plugins/structure-of-a-plugin",
|
||||
"plugins/integrating-plugin-into-software-catalog",
|
||||
"plugins/composability",
|
||||
"plugins/analytics",
|
||||
{
|
||||
"type": "subcategory",
|
||||
"label": "Backends and APIs",
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
+1
-2
@@ -100,8 +100,6 @@ nav:
|
||||
- Org Data: 'integrations/github/org.md'
|
||||
- GitLab:
|
||||
- Locations: 'integrations/gitlab/locations.md'
|
||||
- Google Analytics:
|
||||
- Installation: 'integrations/google-analytics/installation.md'
|
||||
- Google GCS:
|
||||
- Locations: 'integrations/google-cloud-storage/locations.md'
|
||||
- LDAP:
|
||||
@@ -115,6 +113,7 @@ nav:
|
||||
- Plugin Development: 'plugins/plugin-development.md'
|
||||
- Integrate into the Software Catalog: 'plugins/integrating-plugin-into-software-catalog.md'
|
||||
- Composability System: 'plugins/composability.md'
|
||||
- Plugin Analytics: 'plugins/analytics.md'
|
||||
- Backends and APIs:
|
||||
- Proxying: 'plugins/proxying.md'
|
||||
- Backend plugin: 'plugins/backend-plugin.md'
|
||||
|
||||
@@ -61,7 +61,6 @@
|
||||
"devDependencies": {
|
||||
"@types/webpack": "^5.28.0",
|
||||
"@changesets/cli": "^2.14.0",
|
||||
"@octokit/openapi-types": "^2.2.0",
|
||||
"@spotify/prettier-config": "^11.0.0",
|
||||
"command-exists": "^1.2.9",
|
||||
"concurrently": "^6.0.0",
|
||||
@@ -71,7 +70,6 @@
|
||||
"lerna": "^4.0.0",
|
||||
"lint-staged": "^11.1.2",
|
||||
"prettier": "^2.2.1",
|
||||
"recursive-readdir": "^2.2.2",
|
||||
"shx": "^0.3.2",
|
||||
"yarn-lock-check": "^1.0.5"
|
||||
},
|
||||
|
||||
@@ -14,25 +14,26 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import Grid from '@material-ui/core/Grid';
|
||||
import {
|
||||
HomePageRandomJoke,
|
||||
ComponentAccordion,
|
||||
ComponentTabs,
|
||||
ComponentTab,
|
||||
} from '@backstage/plugin-home';
|
||||
import {
|
||||
Content,
|
||||
Header,
|
||||
Page,
|
||||
HomepageTimer,
|
||||
Page,
|
||||
} from '@backstage/core-components';
|
||||
import {
|
||||
ComponentAccordion,
|
||||
ComponentTab,
|
||||
ComponentTabs,
|
||||
HomePageRandomJoke,
|
||||
WelcomeTitle,
|
||||
} from '@backstage/plugin-home';
|
||||
import { HomePageSearchBar } from '@backstage/plugin-search';
|
||||
import Grid from '@material-ui/core/Grid';
|
||||
import React from 'react';
|
||||
|
||||
export const HomePage = () => (
|
||||
<Page themeId="home">
|
||||
<Header title="Home">
|
||||
<Header title={<WelcomeTitle />} pageTitleOverride="Home">
|
||||
<HomepageTimer />
|
||||
</Header>
|
||||
<Content>
|
||||
|
||||
@@ -135,13 +135,7 @@ describe('AwsS3UrlReader', () => {
|
||||
'getObject',
|
||||
Buffer.from(
|
||||
require('fs').readFileSync(
|
||||
path.resolve(
|
||||
'src',
|
||||
'reading',
|
||||
'__fixtures__',
|
||||
'awsS3',
|
||||
'awsS3-mock-object.yaml',
|
||||
),
|
||||
path.resolve(__dirname, '__fixtures__/awsS3/awsS3-mock-object.yaml'),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -187,13 +181,7 @@ describe('AwsS3UrlReader', () => {
|
||||
'getObject',
|
||||
Buffer.from(
|
||||
require('fs').readFileSync(
|
||||
path.resolve(
|
||||
'src',
|
||||
'reading',
|
||||
'__fixtures__',
|
||||
'awsS3',
|
||||
'awsS3-mock-object.yaml',
|
||||
),
|
||||
path.resolve(__dirname, '__fixtures__/awsS3/awsS3-mock-object.yaml'),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -249,13 +237,7 @@ describe('AwsS3UrlReader', () => {
|
||||
'getObject',
|
||||
Buffer.from(
|
||||
require('fs').readFileSync(
|
||||
path.resolve(
|
||||
'src',
|
||||
'reading',
|
||||
'__fixtures__',
|
||||
'awsS3',
|
||||
'awsS3-mock-object.yaml',
|
||||
),
|
||||
path.resolve(__dirname, '__fixtures__/awsS3/awsS3-mock-object.yaml'),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -152,7 +152,7 @@ describe('AzureUrlReader', () => {
|
||||
|
||||
describe('readTree', () => {
|
||||
const repoBuffer = fs.readFileSync(
|
||||
path.resolve('src', 'reading', '__fixtures__', 'mock-main.zip'),
|
||||
path.resolve(__dirname, '__fixtures__/mock-main.zip'),
|
||||
);
|
||||
|
||||
const processor = new AzureUrlReader(
|
||||
@@ -264,7 +264,7 @@ describe('AzureUrlReader', () => {
|
||||
|
||||
describe('search', () => {
|
||||
const repoBuffer = fs.readFileSync(
|
||||
path.resolve('src', 'reading', '__fixtures__', 'mock-main.zip'),
|
||||
path.resolve(__dirname, '__fixtures__/mock-main.zip'),
|
||||
);
|
||||
|
||||
const processor = new AzureUrlReader(
|
||||
|
||||
@@ -104,20 +104,13 @@ describe('BitbucketUrlReader', () => {
|
||||
describe('readTree', () => {
|
||||
const repoBuffer = fs.readFileSync(
|
||||
path.resolve(
|
||||
'src',
|
||||
'reading',
|
||||
'__fixtures__',
|
||||
'bitbucket-repo-with-commit-hash.tar.gz',
|
||||
__dirname,
|
||||
'__fixtures__/bitbucket-repo-with-commit-hash.tar.gz',
|
||||
),
|
||||
);
|
||||
|
||||
const privateBitbucketRepoBuffer = fs.readFileSync(
|
||||
path.resolve(
|
||||
'src',
|
||||
'reading',
|
||||
'__fixtures__',
|
||||
'bitbucket-server-repo.tar.gz',
|
||||
),
|
||||
path.resolve(__dirname, '__fixtures__/bitbucket-server-repo.tar.gz'),
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -298,10 +291,8 @@ describe('BitbucketUrlReader', () => {
|
||||
describe('search hosted', () => {
|
||||
const repoBuffer = fs.readFileSync(
|
||||
path.resolve(
|
||||
'src',
|
||||
'reading',
|
||||
'__fixtures__',
|
||||
'bitbucket-repo-with-commit-hash.tar.gz',
|
||||
__dirname,
|
||||
'__fixtures__/bitbucket-repo-with-commit-hash.tar.gz',
|
||||
),
|
||||
);
|
||||
|
||||
@@ -386,12 +377,7 @@ describe('BitbucketUrlReader', () => {
|
||||
|
||||
describe('search private', () => {
|
||||
const privateBitbucketRepoBuffer = fs.readFileSync(
|
||||
path.resolve(
|
||||
'src',
|
||||
'reading',
|
||||
'__fixtures__',
|
||||
'bitbucket-server-repo.tar.gz',
|
||||
),
|
||||
path.resolve(__dirname, '__fixtures__/bitbucket-server-repo.tar.gz'),
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -254,12 +254,7 @@ describe('GithubUrlReader', () => {
|
||||
|
||||
describe('readTree', () => {
|
||||
const repoBuffer = fs.readFileSync(
|
||||
path.resolve(
|
||||
'src',
|
||||
'reading',
|
||||
'__fixtures__',
|
||||
'backstage-mock-etag123.tar.gz',
|
||||
),
|
||||
path.resolve(__dirname, '__fixtures__/backstage-mock-etag123.tar.gz'),
|
||||
);
|
||||
|
||||
const reposGithubApiResponse = {
|
||||
@@ -540,12 +535,7 @@ describe('GithubUrlReader', () => {
|
||||
|
||||
describe('search', () => {
|
||||
const repoBuffer = fs.readFileSync(
|
||||
path.resolve(
|
||||
'src',
|
||||
'reading',
|
||||
'__fixtures__',
|
||||
'backstage-mock-etag123.tar.gz',
|
||||
),
|
||||
path.resolve(__dirname, '__fixtures__/backstage-mock-etag123.tar.gz'),
|
||||
);
|
||||
|
||||
const githubTreeContents: GhTreeResponse['tree'] = [
|
||||
|
||||
@@ -223,7 +223,7 @@ describe('GitlabUrlReader', () => {
|
||||
|
||||
describe('readTree', () => {
|
||||
const archiveBuffer = fs.readFileSync(
|
||||
path.resolve('src', 'reading', '__fixtures__', 'gitlab-archive.tar.gz'),
|
||||
path.resolve(__dirname, '__fixtures__/gitlab-archive.tar.gz'),
|
||||
);
|
||||
|
||||
const projectGitlabApiResponse = {
|
||||
@@ -495,7 +495,7 @@ describe('GitlabUrlReader', () => {
|
||||
|
||||
describe('search', () => {
|
||||
const archiveBuffer = fs.readFileSync(
|
||||
path.resolve('src', 'reading', '__fixtures__', 'gitlab-archive.tar.gz'),
|
||||
path.resolve(__dirname, '__fixtures__/gitlab-archive.tar.gz'),
|
||||
);
|
||||
|
||||
const projectGitlabApiResponse = {
|
||||
|
||||
@@ -46,6 +46,8 @@ describe('paths', () => {
|
||||
const dir = resolvePath(__dirname, '..');
|
||||
const root = resolvePath(__dirname, '../../..');
|
||||
|
||||
jest.spyOn(process, 'cwd').mockReturnValue(dir);
|
||||
|
||||
const paths = findPaths(__dirname);
|
||||
|
||||
expect(paths.ownDir).toBe(dir);
|
||||
|
||||
@@ -14,6 +14,15 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const globalRestrictedSyntax = [
|
||||
{
|
||||
message:
|
||||
'Default import from winston is not allowed, import `* as winston` instead.',
|
||||
selector:
|
||||
'ImportDeclaration[source.value="winston"] ImportDefaultSpecifier',
|
||||
},
|
||||
];
|
||||
|
||||
module.exports = {
|
||||
extends: [
|
||||
'@spotify/eslint-config-base',
|
||||
@@ -69,17 +78,12 @@ module.exports = {
|
||||
// Avoid default import from winston as it breaks at runtime
|
||||
'no-restricted-syntax': [
|
||||
'error',
|
||||
{
|
||||
message:
|
||||
'Default import from winston is not allowed, import `* as winston` instead.',
|
||||
selector:
|
||||
'ImportDeclaration[source.value="winston"] ImportDefaultSpecifier',
|
||||
},
|
||||
{
|
||||
message:
|
||||
"`__dirname` doesn't refer to the same dir in production builds, try `resolvePackagePath()` from `@backstage/backend-common` instead.",
|
||||
selector: 'Identifier[name="__dirname"]',
|
||||
},
|
||||
...globalRestrictedSyntax,
|
||||
],
|
||||
},
|
||||
overrides: [
|
||||
@@ -103,6 +107,7 @@ module.exports = {
|
||||
bundledDependencies: true,
|
||||
},
|
||||
],
|
||||
'no-restricted-syntax': ['error', ...globalRestrictedSyntax],
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -18,7 +18,7 @@ const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const glob = require('util').promisify(require('glob'));
|
||||
|
||||
async function getProjectConfig(targetPath) {
|
||||
async function getProjectConfig(targetPath, displayName) {
|
||||
const configJsPath = path.resolve(targetPath, 'jest.config.js');
|
||||
const configTsPath = path.resolve(targetPath, 'jest.config.ts');
|
||||
// If the package has it's own jest config, we use that instead.
|
||||
@@ -73,6 +73,7 @@ async function getProjectConfig(targetPath) {
|
||||
const transformModulePattern = transformModules && `(?!${transformModules})`;
|
||||
|
||||
const options = {
|
||||
displayName,
|
||||
rootDir: path.resolve(targetPath, 'src'),
|
||||
coverageDirectory: path.resolve(targetPath, 'coverage'),
|
||||
collectCoverageFrom: ['**/*.{js,jsx,ts,tsx}', '!**/*.d.ts'],
|
||||
@@ -143,7 +144,7 @@ async function getRootConfig() {
|
||||
const packageData = await fs.readJson(packagePath);
|
||||
const testScript = packageData.scripts && packageData.scripts.test;
|
||||
if (testScript && testScript.includes('backstage-cli test')) {
|
||||
return await getProjectConfig(projectPath);
|
||||
return await getProjectConfig(projectPath, packageData.name);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
*/
|
||||
|
||||
import React, { useMemo, useEffect, useState, PropsWithChildren } from 'react';
|
||||
import { ThemeProvider, CssBaseline } from '@material-ui/core';
|
||||
import { ThemeProvider } from '@material-ui/core/styles';
|
||||
import CssBaseline from '@material-ui/core/CssBaseline';
|
||||
import { useApi, appThemeApiRef, AppTheme } from '@backstage/core-plugin-api';
|
||||
import { useObservable } from 'react-use';
|
||||
|
||||
|
||||
@@ -1,8 +1,25 @@
|
||||
const base = require('@backstage/cli/config/eslint');
|
||||
const [, baseRestrictedImports] = base.rules['no-restricted-imports'];
|
||||
|
||||
module.exports = {
|
||||
extends: [require.resolve('@backstage/cli/config/eslint')],
|
||||
rules: {
|
||||
// TODO: add prop types to JS and remove
|
||||
'react/prop-types': 0,
|
||||
'jest/expect-expect': 0,
|
||||
'no-restricted-imports': [
|
||||
2,
|
||||
{
|
||||
...baseRestrictedImports,
|
||||
paths: [
|
||||
{
|
||||
// Importing the entire MUI icons packages kills build performance as the list of icons is huge.
|
||||
name: '@material-ui/core',
|
||||
message: "Please import '@material-ui/core/...' instead.",
|
||||
},
|
||||
...baseRestrictedImports.paths,
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
@@ -8,9 +8,8 @@
|
||||
import { ApiRef } from '@backstage/core-plugin-api';
|
||||
import { BackstageIdentityApi } from '@backstage/core-plugin-api';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import { Breadcrumbs as Breadcrumbs_2 } from '@material-ui/core';
|
||||
import { ButtonProps as ButtonProps_2 } from '@material-ui/core';
|
||||
import { CardHeaderProps } from '@material-ui/core';
|
||||
import { ButtonProps as ButtonProps_2 } from '@material-ui/core/Button';
|
||||
import { CardHeaderProps } from '@material-ui/core/CardHeader';
|
||||
import { Column } from '@material-table/core';
|
||||
import { ComponentClass } from 'react';
|
||||
import { ComponentProps } from 'react';
|
||||
@@ -20,9 +19,10 @@ import { CSSProperties } from 'react';
|
||||
import { ElementType } from 'react';
|
||||
import { ErrorInfo } from 'react';
|
||||
import { IconComponent } from '@backstage/core-plugin-api';
|
||||
import { LinearProgressProps } from '@material-ui/core';
|
||||
import { LinkProps as LinkProps_2 } from '@material-ui/core';
|
||||
import { LinearProgressProps } from '@material-ui/core/LinearProgress';
|
||||
import { LinkProps as LinkProps_2 } from '@material-ui/core/Link';
|
||||
import { LinkProps as LinkProps_3 } from 'react-router-dom';
|
||||
import MaterialBreadcrumbs from '@material-ui/core/Breadcrumbs';
|
||||
import { MaterialTableProps } from '@material-table/core';
|
||||
import { NavLinkProps } from 'react-router-dom';
|
||||
import { Overrides } from '@material-ui/core/styles/overrides';
|
||||
@@ -36,14 +36,14 @@ import { SessionApi } from '@backstage/core-plugin-api';
|
||||
import { SignInPageProps } from '@backstage/core-plugin-api';
|
||||
import { SparklinesLineProps } from 'react-sparklines';
|
||||
import { SparklinesProps } from 'react-sparklines';
|
||||
import { StyledComponentProps } from '@material-ui/core';
|
||||
import { StyledComponentProps } from '@material-ui/core/styles';
|
||||
import { StyleRules } from '@material-ui/styles';
|
||||
import { StyleRules as StyleRules_2 } from '@material-ui/core/styles/withStyles';
|
||||
import { TabProps } from '@material-ui/core';
|
||||
import { TabProps } from '@material-ui/core/Tab';
|
||||
import { TextTruncateProps } from 'react-text-truncate';
|
||||
import { Theme } from '@material-ui/core';
|
||||
import { TooltipProps } from '@material-ui/core';
|
||||
import { WithStyles } from '@material-ui/core';
|
||||
import { Theme } from '@material-ui/core/styles';
|
||||
import { TooltipProps } from '@material-ui/core/Tooltip';
|
||||
import { WithStyles } from '@material-ui/core/styles';
|
||||
|
||||
// Warning: (ae-missing-release-tag) "AlertDisplay" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
*/
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Snackbar, IconButton } from '@material-ui/core';
|
||||
import Snackbar from '@material-ui/core/Snackbar';
|
||||
import IconButton from '@material-ui/core/IconButton';
|
||||
import CloseIcon from '@material-ui/icons/Close';
|
||||
import { Alert } from '@material-ui/lab';
|
||||
import { AlertMessage, useApi, alertApiRef } from '@backstage/core-plugin-api';
|
||||
|
||||
@@ -14,12 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React, { CSSProperties } from 'react';
|
||||
import {
|
||||
Avatar as MaterialAvatar,
|
||||
createStyles,
|
||||
makeStyles,
|
||||
Theme,
|
||||
} from '@material-ui/core';
|
||||
import { createStyles, makeStyles, Theme } from '@material-ui/core/styles';
|
||||
import MaterialAvatar from '@material-ui/core/Avatar';
|
||||
import { extractInitials, stringToColor } from './utils';
|
||||
|
||||
export type AvatarClassKey = 'avatar';
|
||||
|
||||
@@ -17,15 +17,13 @@ import React, { ComponentType } from 'react';
|
||||
import { Button } from './Button';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { createRouteRef, useRouteRef } from '@backstage/core-plugin-api';
|
||||
import {
|
||||
Divider,
|
||||
Link,
|
||||
List,
|
||||
ListItem,
|
||||
ListItemText,
|
||||
Typography,
|
||||
Button as MaterialButton,
|
||||
} from '@material-ui/core';
|
||||
import Divider from '@material-ui/core/Divider';
|
||||
import Link from '@material-ui/core/Link';
|
||||
import List from '@material-ui/core/List';
|
||||
import ListItem from '@material-ui/core/ListItem';
|
||||
import ListItemText from '@material-ui/core/ListItemText';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import MaterialButton from '@material-ui/core/Button';
|
||||
import { wrapInTestApp } from '@backstage/test-utils';
|
||||
|
||||
const routeRef = createRouteRef({
|
||||
|
||||
@@ -14,10 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
Button as MaterialButton,
|
||||
import MaterialButton, {
|
||||
ButtonProps as MaterialButtonProps,
|
||||
} from '@material-ui/core';
|
||||
} from '@material-ui/core/Button';
|
||||
import React from 'react';
|
||||
import { Link, LinkProps } from '../Link';
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Chip } from '@material-ui/core';
|
||||
import Chip from '@material-ui/core/Chip';
|
||||
|
||||
export default {
|
||||
title: 'Data Display/Chip',
|
||||
|
||||
@@ -14,12 +14,56 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import SyntaxHighlighter from 'react-syntax-highlighter';
|
||||
import { docco, dark } from 'react-syntax-highlighter/dist/cjs/styles/hljs';
|
||||
import { useTheme } from '@material-ui/core';
|
||||
import React, { lazy, Suspense } from 'react';
|
||||
import { useTheme } from '@material-ui/core/styles';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import { CopyTextButton } from '../CopyTextButton';
|
||||
import { Progress } from '../Progress';
|
||||
|
||||
const LazySyntaxHighlighter = lazy(async () => {
|
||||
const [{ default: SyntaxHighlighter }, { docco, dark }] = await Promise.all([
|
||||
import('react-syntax-highlighter'),
|
||||
import('react-syntax-highlighter/dist/cjs/styles/hljs'),
|
||||
]);
|
||||
|
||||
function LazyHighlighter(props: CodeSnippetProps) {
|
||||
const {
|
||||
text,
|
||||
language,
|
||||
showLineNumbers = false,
|
||||
highlightedNumbers,
|
||||
customStyle,
|
||||
} = props;
|
||||
const theme = useTheme<BackstageTheme>();
|
||||
const mode = theme.palette.type === 'dark' ? dark : docco;
|
||||
const highlightColor =
|
||||
theme.palette.type === 'dark' ? '#256bf3' : '#e6ffed';
|
||||
|
||||
return (
|
||||
<SyntaxHighlighter
|
||||
customStyle={customStyle}
|
||||
language={language}
|
||||
style={mode}
|
||||
showLineNumbers={showLineNumbers}
|
||||
wrapLines
|
||||
lineNumberStyle={{ color: theme.palette.textVerySubtle }}
|
||||
lineProps={(lineNumber: number) =>
|
||||
highlightedNumbers?.includes(lineNumber)
|
||||
? {
|
||||
style: {
|
||||
backgroundColor: highlightColor,
|
||||
},
|
||||
}
|
||||
: {}
|
||||
}
|
||||
>
|
||||
{text}
|
||||
</SyntaxHighlighter>
|
||||
);
|
||||
}
|
||||
|
||||
return { default: LazyHighlighter };
|
||||
});
|
||||
|
||||
/**
|
||||
* Properties for {@link CodeSnippet}
|
||||
@@ -68,38 +112,12 @@ export interface CodeSnippetProps {
|
||||
* providing consistent theming and copy code button
|
||||
*/
|
||||
export function CodeSnippet(props: CodeSnippetProps) {
|
||||
const {
|
||||
text,
|
||||
language,
|
||||
showLineNumbers = false,
|
||||
showCopyCodeButton = false,
|
||||
highlightedNumbers,
|
||||
customStyle,
|
||||
} = props;
|
||||
const theme = useTheme<BackstageTheme>();
|
||||
const mode = theme.palette.type === 'dark' ? dark : docco;
|
||||
const highlightColor = theme.palette.type === 'dark' ? '#256bf3' : '#e6ffed';
|
||||
const { text, showCopyCodeButton = false } = props;
|
||||
return (
|
||||
<div style={{ position: 'relative' }}>
|
||||
<SyntaxHighlighter
|
||||
customStyle={customStyle}
|
||||
language={language}
|
||||
style={mode}
|
||||
showLineNumbers={showLineNumbers}
|
||||
wrapLines
|
||||
lineNumberStyle={{ color: theme.palette.textVerySubtle }}
|
||||
lineProps={(lineNumber: number) =>
|
||||
highlightedNumbers?.includes(lineNumber)
|
||||
? {
|
||||
style: {
|
||||
backgroundColor: highlightColor,
|
||||
},
|
||||
}
|
||||
: {}
|
||||
}
|
||||
>
|
||||
{text}
|
||||
</SyntaxHighlighter>
|
||||
<Suspense fallback={<Progress />}>
|
||||
<LazySyntaxHighlighter {...props} />
|
||||
</Suspense>
|
||||
{showCopyCodeButton && (
|
||||
<div style={{ position: 'absolute', top: 0, right: 0 }}>
|
||||
<CopyTextButton text={text} />
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
*/
|
||||
|
||||
import { errorApiRef, useApi } from '@backstage/core-plugin-api';
|
||||
import { IconButton, Tooltip } from '@material-ui/core';
|
||||
import IconButton from '@material-ui/core/IconButton';
|
||||
import Tooltip from '@material-ui/core/Tooltip';
|
||||
import CopyIcon from '@material-ui/icons/FileCopy';
|
||||
import React, { MouseEventHandler, useEffect, useState } from 'react';
|
||||
import { useCopyToClipboard } from 'react-use';
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import { Button, IconButton, useMediaQuery } from '@material-ui/core';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import IconButton from '@material-ui/core/IconButton';
|
||||
import useMediaQuery from '@material-ui/core/useMediaQuery';
|
||||
import React from 'react';
|
||||
import { Link as RouterLink, LinkProps } from 'react-router-dom';
|
||||
import AddCircleOutline from '@material-ui/icons/AddCircleOutline';
|
||||
|
||||
@@ -14,15 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
IconButton,
|
||||
Typography,
|
||||
} from '@material-ui/core';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import Dialog from '@material-ui/core/Dialog';
|
||||
import DialogActions from '@material-ui/core/DialogActions';
|
||||
import DialogContent from '@material-ui/core/DialogContent';
|
||||
import DialogTitle from '@material-ui/core/DialogTitle';
|
||||
import IconButton from '@material-ui/core/IconButton';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { makeStyles, createStyles, Theme } from '@material-ui/core/styles';
|
||||
import CloseIcon from '@material-ui/icons/Close';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
+2
-1
@@ -16,7 +16,8 @@
|
||||
|
||||
import React from 'react';
|
||||
import { DismissableBanner } from './DismissableBanner';
|
||||
import { Link, Typography } from '@material-ui/core';
|
||||
import Link from '@material-ui/core/Link';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { ApiProvider, ApiRegistry, WebStorage } from '@backstage/core-app-api';
|
||||
import {
|
||||
ErrorApi,
|
||||
|
||||
@@ -18,7 +18,7 @@ import React, { ReactNode, useState, useEffect } from 'react';
|
||||
import { useApi, storageApiRef } from '@backstage/core-plugin-api';
|
||||
import { useObservable } from 'react-use';
|
||||
import classNames from 'classnames';
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import Snackbar from '@material-ui/core/Snackbar';
|
||||
import SnackbarContent from '@material-ui/core/SnackbarContent';
|
||||
|
||||
@@ -15,15 +15,11 @@
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
Drawer,
|
||||
Button,
|
||||
Typography,
|
||||
makeStyles,
|
||||
IconButton,
|
||||
createStyles,
|
||||
Theme,
|
||||
} from '@material-ui/core';
|
||||
import { makeStyles, createStyles, Theme } from '@material-ui/core/styles';
|
||||
import Drawer from '@material-ui/core/Drawer';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import IconButton from '@material-ui/core/IconButton';
|
||||
import Close from '@material-ui/icons/Close';
|
||||
|
||||
export default {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import { EmptyState } from './EmptyState';
|
||||
import { Button } from '@material-ui/core';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import { MissingAnnotationEmptyState } from './MissingAnnotationEmptyState';
|
||||
|
||||
export default {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import React from 'react';
|
||||
import { EmptyState } from './EmptyState';
|
||||
import { renderWithEffects, wrapInTestApp } from '@backstage/test-utils';
|
||||
import { Button } from '@material-ui/core';
|
||||
import Button from '@material-ui/core/Button';
|
||||
|
||||
describe('<EmptyState />', () => {
|
||||
it('render EmptyState component with type annotaion is missing', async () => {
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { makeStyles, Typography, Grid } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import Grid from '@material-ui/core/Grid';
|
||||
import { EmptyStateImage } from './EmptyStateImage';
|
||||
|
||||
export type EmptyStateClassKey = 'root' | 'action' | 'imageContainer';
|
||||
|
||||
@@ -19,7 +19,7 @@ import missingAnnotation from './assets/missingAnnotation.svg';
|
||||
import noInformation from './assets/noInformation.svg';
|
||||
import createComponent from './assets/createComponent.svg';
|
||||
import noBuild from './assets/noBuild.svg';
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
|
||||
type Props = {
|
||||
missing: 'field' | 'info' | 'content' | 'data';
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Button, makeStyles, Typography } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import { Link } from '../Link';
|
||||
import { EmptyState } from './EmptyState';
|
||||
|
||||
@@ -14,7 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { List, ListItem, ListItemText, makeStyles } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import List from '@material-ui/core/List';
|
||||
import ListItem from '@material-ui/core/ListItem';
|
||||
import ListItemText from '@material-ui/core/ListItemText';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import { CopyTextButton } from '../CopyTextButton';
|
||||
import { WarningPanel } from '../WarningPanel';
|
||||
|
||||
@@ -14,7 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ClickAwayListener, makeStyles, Typography } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import ClickAwayListener from '@material-ui/core/ClickAwayListener';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import React, {
|
||||
PropsWithChildren,
|
||||
useCallback,
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
import React from 'react';
|
||||
import { IconLinkVertical, IconLinkVerticalProps } from './IconLinkVertical';
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
|
||||
export type HeaderIconLinkRowClassKey = 'links';
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
*/
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { makeStyles, Link } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Link from '@material-ui/core/Link';
|
||||
import LinkIcon from '@material-ui/icons/Link';
|
||||
import { Link as RouterLink } from '../Link';
|
||||
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ import React from 'react';
|
||||
import { fireEvent } from '@testing-library/react';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
import { HorizontalScrollGrid } from './HorizontalScrollGrid';
|
||||
import { Grid } from '@material-ui/core';
|
||||
import Grid from '@material-ui/core/Grid';
|
||||
|
||||
describe('<HorizontalScrollGrid />', () => {
|
||||
beforeEach(() => {
|
||||
|
||||
+3
-1
@@ -18,7 +18,9 @@ import React, { PropsWithChildren } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import ChevronLeftIcon from '@material-ui/icons/ChevronLeft';
|
||||
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
|
||||
import { Grid, IconButton, makeStyles, Theme } from '@material-ui/core';
|
||||
import { makeStyles, Theme } from '@material-ui/core/styles';
|
||||
import Grid from '@material-ui/core/Grid';
|
||||
import IconButton from '@material-ui/core/IconButton';
|
||||
|
||||
const generateGradientStops = (themeType: 'dark' | 'light') => {
|
||||
// 97% corresponds to the theme.palette.background.default for the light theme
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import CSS from 'csstype';
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
|
||||
type Props = CSS.Properties & {
|
||||
shorthand?: boolean;
|
||||
|
||||
@@ -15,10 +15,9 @@
|
||||
*/
|
||||
|
||||
import { useAnalytics } from '@backstage/core-plugin-api';
|
||||
import {
|
||||
Link as MaterialLink,
|
||||
import MaterialLink, {
|
||||
LinkProps as MaterialLinkProps,
|
||||
} from '@material-ui/core';
|
||||
} from '@material-ui/core/Link';
|
||||
import React, { ElementType } from 'react';
|
||||
import {
|
||||
Link as RouterLink,
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import gfm from 'remark-gfm';
|
||||
import React from 'react';
|
||||
|
||||
@@ -14,15 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
ListItem,
|
||||
ListItemAvatar,
|
||||
ListItemText,
|
||||
makeStyles,
|
||||
Typography,
|
||||
Theme,
|
||||
Button,
|
||||
} from '@material-ui/core';
|
||||
import { makeStyles, Theme } from '@material-ui/core/styles';
|
||||
import ListItem from '@material-ui/core/ListItem';
|
||||
import ListItemAvatar from '@material-ui/core/ListItemAvatar';
|
||||
import ListItemText from '@material-ui/core/ListItemText';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import React, { useState } from 'react';
|
||||
import { PendingAuthRequest } from '@backstage/core-plugin-api';
|
||||
|
||||
|
||||
@@ -14,16 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
List,
|
||||
makeStyles,
|
||||
Theme,
|
||||
Button,
|
||||
} from '@material-ui/core';
|
||||
import { makeStyles, Theme } from '@material-ui/core/styles';
|
||||
import Dialog from '@material-ui/core/Dialog';
|
||||
import DialogActions from '@material-ui/core/DialogActions';
|
||||
import DialogContent from '@material-ui/core/DialogContent';
|
||||
import DialogTitle from '@material-ui/core/DialogTitle';
|
||||
import List from '@material-ui/core/List';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { useObservable } from 'react-use';
|
||||
import LoginRequestListItem from './LoginRequestListItem';
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { Box } from '@material-ui/core';
|
||||
import Box from '@material-ui/core/Box';
|
||||
import React from 'react';
|
||||
import { OverflowTooltip } from './OverflowTooltip';
|
||||
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { makeStyles, Tooltip, TooltipProps } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Tooltip, { TooltipProps } from '@material-ui/core/Tooltip';
|
||||
import React, { useState } from 'react';
|
||||
import TextTruncate, { TextTruncateProps } from 'react-text-truncate';
|
||||
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
|
||||
import React, { useState, useEffect, PropsWithChildren } from 'react';
|
||||
import { LinearProgress, LinearProgressProps } from '@material-ui/core';
|
||||
import LinearProgress, {
|
||||
LinearProgressProps,
|
||||
} from '@material-ui/core/LinearProgress';
|
||||
|
||||
export function Progress(props: PropsWithChildren<LinearProgressProps>) {
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { makeStyles, useTheme } from '@material-ui/core';
|
||||
import { makeStyles, useTheme } from '@material-ui/core/styles';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import { Circle } from 'rc-progress';
|
||||
import React from 'react';
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import { GaugeCard } from './GaugeCard';
|
||||
import { Grid } from '@material-ui/core';
|
||||
import Grid from '@material-ui/core/Grid';
|
||||
import { MemoryRouter } from 'react-router';
|
||||
|
||||
const linkInfo = { title: 'Go to XYZ Location', link: '#' };
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import { InfoCard, InfoCardVariants } from '../../layout/InfoCard';
|
||||
import { BottomLinkProps } from '../../layout/BottomLink';
|
||||
import { Gauge } from './Gauge';
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Tooltip, useTheme } from '@material-ui/core';
|
||||
import { useTheme } from '@material-ui/core/styles';
|
||||
import Tooltip from '@material-ui/core/Tooltip';
|
||||
// @ts-ignore
|
||||
import { Line } from 'rc-progress';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
|
||||
@@ -15,7 +15,10 @@
|
||||
*/
|
||||
|
||||
import { ResponseError } from '@backstage/errors';
|
||||
import { Divider, ListItem, ListItemText, makeStyles } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Divider from '@material-ui/core/Divider';
|
||||
import ListItem from '@material-ui/core/ListItem';
|
||||
import ListItemText from '@material-ui/core/ListItemText';
|
||||
import React from 'react';
|
||||
import { CodeSnippet } from '../CodeSnippet';
|
||||
import { CopyTextButton } from '../CopyTextButton';
|
||||
|
||||
@@ -14,16 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
Checkbox,
|
||||
Chip,
|
||||
ClickAwayListener,
|
||||
FormControl,
|
||||
InputBase,
|
||||
MenuItem,
|
||||
Select,
|
||||
Typography,
|
||||
} from '@material-ui/core';
|
||||
import Checkbox from '@material-ui/core/Checkbox';
|
||||
import Chip from '@material-ui/core/Chip';
|
||||
import ClickAwayListener from '@material-ui/core/ClickAwayListener';
|
||||
import FormControl from '@material-ui/core/FormControl';
|
||||
import InputBase from '@material-ui/core/InputBase';
|
||||
import MenuItem from '@material-ui/core/MenuItem';
|
||||
import Select from '@material-ui/core/Select';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import {
|
||||
createStyles,
|
||||
makeStyles,
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { SvgIcon, makeStyles, createStyles } from '@material-ui/core';
|
||||
import { makeStyles, createStyles } from '@material-ui/core/styles';
|
||||
import SvgIcon from '@material-ui/core/SvgIcon';
|
||||
|
||||
export type ClosedDropdownClassKey = 'icon';
|
||||
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { SvgIcon, makeStyles, createStyles } from '@material-ui/core';
|
||||
import { makeStyles, createStyles } from '@material-ui/core/styles';
|
||||
import SvgIcon from '@material-ui/core/SvgIcon';
|
||||
|
||||
export type OpenedDropdownClassKey = 'icon';
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { TextField } from '@material-ui/core';
|
||||
import TextField from '@material-ui/core/TextField';
|
||||
import React, { useState } from 'react';
|
||||
import { SimpleStepper } from './SimpleStepper';
|
||||
import { SimpleStepperStep } from './SimpleStepperStep';
|
||||
|
||||
@@ -20,7 +20,7 @@ import React, {
|
||||
useEffect,
|
||||
PropsWithChildren,
|
||||
} from 'react';
|
||||
import { Stepper as MuiStepper } from '@material-ui/core';
|
||||
import MuiStepper from '@material-ui/core/Stepper';
|
||||
|
||||
type InternalState = {
|
||||
stepperLength: number;
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React, { useContext, ReactNode, PropsWithChildren } from 'react';
|
||||
import { Button, makeStyles } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import { StepActions } from './types';
|
||||
import { VerticalStepperContext } from './SimpleStepper';
|
||||
|
||||
|
||||
@@ -14,13 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import {
|
||||
Step as MuiStep,
|
||||
StepContent,
|
||||
StepLabel,
|
||||
Typography,
|
||||
makeStyles,
|
||||
} from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import MuiStep from '@material-ui/core/Step';
|
||||
import StepContent from '@material-ui/core/StepContent';
|
||||
import StepLabel from '@material-ui/core/StepLabel';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { SimpleStepperFooter } from './SimpleStepperFooter';
|
||||
import { StepProps } from './types';
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import classNames from 'classnames';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
|
||||
@@ -16,15 +16,15 @@
|
||||
|
||||
import React from 'react';
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableRow,
|
||||
withStyles,
|
||||
createStyles,
|
||||
WithStyles,
|
||||
Theme,
|
||||
} from '@material-ui/core';
|
||||
} from '@material-ui/core/styles';
|
||||
import Table from '@material-ui/core/Table';
|
||||
import TableBody from '@material-ui/core/TableBody';
|
||||
import TableCell from '@material-ui/core/TableCell';
|
||||
import TableRow from '@material-ui/core/TableRow';
|
||||
|
||||
export type MetadataTableTitleCellClassKey = 'root';
|
||||
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import { InfoCard } from '../../layout/InfoCard';
|
||||
import { Grid } from '@material-ui/core';
|
||||
import Grid from '@material-ui/core/Grid';
|
||||
import { StructuredMetadataTable } from './StructuredMetadataTable';
|
||||
|
||||
const cardContentStyle = { heightX: 200, width: 500 };
|
||||
|
||||
+6
-1
@@ -15,7 +15,12 @@
|
||||
*/
|
||||
|
||||
import React, { Fragment, ReactElement } from 'react';
|
||||
import { withStyles, createStyles, WithStyles, Theme } from '@material-ui/core';
|
||||
import {
|
||||
withStyles,
|
||||
createStyles,
|
||||
WithStyles,
|
||||
Theme,
|
||||
} from '@material-ui/core/styles';
|
||||
import startCase from 'lodash/startCase';
|
||||
|
||||
import {
|
||||
|
||||
@@ -16,20 +16,18 @@
|
||||
|
||||
import { useApp } from '@backstage/core-plugin-api';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
DialogActions,
|
||||
IconButton,
|
||||
List,
|
||||
ListItem,
|
||||
ListItemIcon,
|
||||
ListItemText,
|
||||
makeStyles,
|
||||
Popover,
|
||||
Typography,
|
||||
useMediaQuery,
|
||||
} from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import useMediaQuery from '@material-ui/core/useMediaQuery';
|
||||
import Box from '@material-ui/core/Box';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import DialogActions from '@material-ui/core/DialogActions';
|
||||
import IconButton from '@material-ui/core/IconButton';
|
||||
import List from '@material-ui/core/List';
|
||||
import ListItem from '@material-ui/core/ListItem';
|
||||
import ListItemIcon from '@material-ui/core/ListItemIcon';
|
||||
import ListItemText from '@material-ui/core/ListItemText';
|
||||
import Popover from '@material-ui/core/Popover';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import React, { MouseEventHandler, useState } from 'react';
|
||||
import { SupportItem, SupportItemLink, useSupportConfig } from '../../hooks';
|
||||
import { HelpIcon } from '../../icons';
|
||||
|
||||
@@ -23,7 +23,7 @@ import React, {
|
||||
ReactNode,
|
||||
} from 'react';
|
||||
import { RoutedTabs } from './RoutedTabs';
|
||||
import { TabProps } from '@material-ui/core';
|
||||
import { TabProps } from '@material-ui/core/Tab';
|
||||
|
||||
type SubRoute = {
|
||||
path: string;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { TabProps } from '@material-ui/core';
|
||||
import { TabProps } from '@material-ui/core/Tab';
|
||||
import * as React from 'react';
|
||||
|
||||
export type SubRoute = {
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import { Button, makeStyles } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import { Select } from '../Select';
|
||||
import { SelectProps } from '../Select/Select';
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
|
||||
export type SubvalueCellClassKey = 'value' | 'subvalue';
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import React from 'react';
|
||||
import { Link } from '../Link';
|
||||
import { SubvalueCell, Table, TableColumn } from '.';
|
||||
|
||||
@@ -15,13 +15,9 @@
|
||||
*/
|
||||
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import {
|
||||
IconButton,
|
||||
makeStyles,
|
||||
Typography,
|
||||
useTheme,
|
||||
withStyles,
|
||||
} from '@material-ui/core';
|
||||
import { makeStyles, useTheme, withStyles } from '@material-ui/core/styles';
|
||||
import IconButton from '@material-ui/core/IconButton';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
// Material-table is not using the standard icons available in in material-ui. https://github.com/mbrn/material-table/issues/51
|
||||
import AddBox from '@material-ui/icons/AddBox';
|
||||
import ArrowUpward from '@material-ui/icons/ArrowUpward';
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Tab, makeStyles } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Tab from '@material-ui/core/Tab';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
|
||||
interface StyledTabProps {
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
*/
|
||||
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import { Tabs, makeStyles } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Tabs from '@material-ui/core/Tabs';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
|
||||
interface StyledTabsProps {
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { IconButton, makeStyles } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import IconButton from '@material-ui/core/IconButton';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
|
||||
interface StyledIconProps {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import React, { useRef, useEffect, MutableRefObject, useState } from 'react';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import { AppBar } from '@material-ui/core';
|
||||
import AppBar from '@material-ui/core/AppBar';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import NavigateBeforeIcon from '@material-ui/icons/NavigateBefore';
|
||||
import NavigateNextIcon from '@material-ui/icons/NavigateNext';
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
SparklinesLineProps,
|
||||
SparklinesProps,
|
||||
} from 'react-sparklines';
|
||||
import { useTheme } from '@material-ui/core';
|
||||
import { useTheme } from '@material-ui/core/styles';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
|
||||
function color(data: number[], theme: BackstageTheme): string | undefined {
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
|
||||
import React from 'react';
|
||||
import { WarningPanel } from './WarningPanel';
|
||||
import { Button, Link, Typography } from '@material-ui/core';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import Link from '@material-ui/core/Link';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
|
||||
export default {
|
||||
title: 'Feedback/Warning Panel',
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import React from 'react';
|
||||
import { fireEvent, screen } from '@testing-library/react';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
import { Typography } from '@material-ui/core';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
|
||||
import { WarningPanel, WarningProps } from './WarningPanel';
|
||||
|
||||
|
||||
@@ -14,16 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import {
|
||||
Accordion,
|
||||
AccordionSummary,
|
||||
AccordionDetails,
|
||||
Grid,
|
||||
makeStyles,
|
||||
Typography,
|
||||
darken,
|
||||
lighten,
|
||||
} from '@material-ui/core';
|
||||
import { makeStyles, darken, lighten } from '@material-ui/core/styles';
|
||||
import Accordion from '@material-ui/core/Accordion';
|
||||
import AccordionSummary from '@material-ui/core/AccordionSummary';
|
||||
import AccordionDetails from '@material-ui/core/AccordionDetails';
|
||||
import Grid from '@material-ui/core/Grid';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import ErrorOutline from '@material-ui/icons/ErrorOutline';
|
||||
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
|
||||
import React from 'react';
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Divider, Typography, makeStyles } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Divider from '@material-ui/core/Divider';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import ArrowIcon from '@material-ui/icons/ArrowForward';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import Box from '@material-ui/core/Box';
|
||||
|
||||
@@ -13,7 +13,12 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { Box, List, ListItem, Popover, Typography } from '@material-ui/core';
|
||||
|
||||
import Box from '@material-ui/core/Box';
|
||||
import List from '@material-ui/core/List';
|
||||
import ListItem from '@material-ui/core/ListItem';
|
||||
import Popover from '@material-ui/core/Popover';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import ExpandLessIcon from '@material-ui/icons/ExpandLess';
|
||||
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
|
||||
import React, { Fragment } from 'react';
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user