Merge branch 'master' into feat/BCKSTG-93-paragraphs
Signed-off-by: Carlos Esteban Lopez Jaramillo <luchillo17@gmail.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-rails': patch
|
||||
---
|
||||
|
||||
handle skipActiveRecord rails new argument
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-app-api': patch
|
||||
---
|
||||
|
||||
Fixed a bug in the default token manager factory where it created multiple incompatible instances.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-defaults': patch
|
||||
---
|
||||
|
||||
Added factory for the new core identity service to the set of default service factories.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-app-api': patch
|
||||
---
|
||||
|
||||
Added service factory for the new core identity service.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-plugin-api': patch
|
||||
---
|
||||
|
||||
Added new core identity service.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-sentry': minor
|
||||
---
|
||||
|
||||
Add Sentry "Create Project" Scaffolder as new package
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
'@backstage/plugin-adr': patch
|
||||
'@backstage/plugin-api-docs': patch
|
||||
'@backstage/plugin-azure-devops': patch
|
||||
'@backstage/plugin-azure-sites': patch
|
||||
'@backstage/plugin-bazaar': patch
|
||||
'@backstage/plugin-cicd-statistics': patch
|
||||
'@backstage/plugin-cost-insights': patch
|
||||
'@backstage/plugin-firehydrant': patch
|
||||
'@backstage/plugin-fossa': patch
|
||||
'@backstage/plugin-gcp-projects': patch
|
||||
'@backstage/plugin-git-release-manager': patch
|
||||
'@backstage/plugin-home': patch
|
||||
'@backstage/plugin-lighthouse': patch
|
||||
'@backstage/plugin-search': patch
|
||||
'@backstage/plugin-search-react': patch
|
||||
'@backstage/plugin-sonarqube': patch
|
||||
'@backstage/plugin-tech-radar': patch
|
||||
'@backstage/plugin-techdocs': patch
|
||||
'@backstage/plugin-user-settings': patch
|
||||
---
|
||||
|
||||
Small updates to some components to ensure theme typography properties are inherited correctly.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
---
|
||||
|
||||
Remove usage of raw span
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog': patch
|
||||
---
|
||||
|
||||
There is now tooltip in the entity context menu
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch
|
||||
---
|
||||
|
||||
Fixed issue with sometimes trying to commit an empty array of references
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-app-api': patch
|
||||
---
|
||||
|
||||
Internal folder structure refactor.
|
||||
@@ -248,6 +248,10 @@ module.exports = {
|
||||
forbid: [
|
||||
{ element: 'button', message: 'use MUI <Button> instead' },
|
||||
{ element: 'p', message: 'use MUI <Typography> instead' },
|
||||
{
|
||||
element: 'span',
|
||||
message: 'use a MUI <Typography> variant instead',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "4.0.0-alpha.57",
|
||||
"@octokit/rest": "^19.0.3",
|
||||
"@oriflame/backstage-plugin-score-card": "^0.5.1",
|
||||
"@oriflame/backstage-plugin-score-card": "^0.6.0",
|
||||
"@roadiehq/backstage-plugin-buildkite": "^2.0.8",
|
||||
"@roadiehq/backstage-plugin-github-insights": "^2.0.5",
|
||||
"@roadiehq/backstage-plugin-github-pull-requests": "^2.2.7",
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
Paper,
|
||||
useTheme,
|
||||
} from '@material-ui/core';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import BuildIcon from '@material-ui/icons/Build';
|
||||
import LaunchIcon from '@material-ui/icons/Launch';
|
||||
import {
|
||||
@@ -178,9 +179,12 @@ export const SearchModal = ({ toggleModal }: { toggleModal: () => void }) => {
|
||||
}}
|
||||
to={`${getSearchLink()}?query=${term}`}
|
||||
>
|
||||
<span className={classes.viewResultsLink}>
|
||||
<Typography
|
||||
component="span"
|
||||
className={classes.viewResultsLink}
|
||||
>
|
||||
View Full Results
|
||||
</span>
|
||||
</Typography>
|
||||
<LaunchIcon color="primary" />
|
||||
</Link>
|
||||
</Grid>
|
||||
|
||||
@@ -15,6 +15,7 @@ import { ExtensionPoint } from '@backstage/backend-plugin-api';
|
||||
import { HelmetOptions } from 'helmet';
|
||||
import * as http from 'http';
|
||||
import { HttpRouterService } from '@backstage/backend-plugin-api';
|
||||
import { IdentityService } from '@backstage/backend-plugin-api';
|
||||
import { LifecycleService } from '@backstage/backend-plugin-api';
|
||||
import { LoggerService } from '@backstage/backend-plugin-api';
|
||||
import { PermissionsService } from '@backstage/backend-plugin-api';
|
||||
@@ -126,6 +127,17 @@ export type HttpServerOptions = {
|
||||
};
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export const identityFactory: (
|
||||
options?: IdentityFactoryOptions | undefined,
|
||||
) => ServiceFactory<IdentityService>;
|
||||
|
||||
// @public
|
||||
export type IdentityFactoryOptions = {
|
||||
issuer?: string;
|
||||
algorithms?: string[];
|
||||
};
|
||||
|
||||
// @public
|
||||
export const lifecycleFactory: (
|
||||
options?: undefined,
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"@backstage/backend-tasks": "workspace:^",
|
||||
"@backstage/config": "workspace:^",
|
||||
"@backstage/errors": "workspace:^",
|
||||
"@backstage/plugin-auth-node": "workspace:^",
|
||||
"@backstage/plugin-permission-node": "workspace:^",
|
||||
"@types/cors": "^2.8.6",
|
||||
"@types/express": "^4.17.6",
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { cacheFactory } from './cacheFactory';
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { configFactory } from './configFactory';
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { databaseFactory } from './databaseFactory';
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { discoveryFactory } from './discoveryFactory';
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
coreServices,
|
||||
createServiceFactory,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { DefaultIdentityClient } from '@backstage/plugin-auth-node';
|
||||
|
||||
/**
|
||||
* An identity client options object which allows extra configurations
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type IdentityFactoryOptions = {
|
||||
issuer?: string;
|
||||
|
||||
/** JWS "alg" (Algorithm) Header Parameter values. Defaults to an array containing just ES256.
|
||||
* More info on supported algorithms: https://github.com/panva/jose */
|
||||
algorithms?: string[];
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export const identityFactory = createServiceFactory({
|
||||
service: coreServices.identity,
|
||||
deps: {
|
||||
config: coreServices.config,
|
||||
discovery: coreServices.discovery,
|
||||
tokenManager: coreServices.tokenManager,
|
||||
},
|
||||
|
||||
async factory({}, options?: IdentityFactoryOptions) {
|
||||
return async ({ discovery }) => {
|
||||
return DefaultIdentityClient.create({ discovery, ...options });
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { identityFactory } from './identityFactory';
|
||||
export type { IdentityFactoryOptions } from './identityFactory';
|
||||
@@ -14,18 +14,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './cache';
|
||||
export * from './config';
|
||||
export * from './database';
|
||||
export * from './discovery';
|
||||
export * from './httpRouter';
|
||||
export * from './identity';
|
||||
export * from './lifecycle';
|
||||
export * from './logger';
|
||||
export * from './permissions';
|
||||
export * from './rootHttpRouter';
|
||||
|
||||
export { cacheFactory } from './cacheService';
|
||||
export { configFactory } from './configService';
|
||||
export { databaseFactory } from './databaseService';
|
||||
export { discoveryFactory } from './discoveryService';
|
||||
export { loggerFactory } from './loggerService';
|
||||
export { rootLoggerFactory } from './rootLoggerService';
|
||||
export { permissionsFactory } from './permissionsService';
|
||||
export { schedulerFactory } from './schedulerService';
|
||||
export { tokenManagerFactory } from './tokenManagerService';
|
||||
export { urlReaderFactory } from './urlReaderService';
|
||||
export { lifecycleFactory } from './lifecycleService';
|
||||
export { rootLifecycleFactory } from './rootLifecycleService';
|
||||
export * from './rootLifecycle';
|
||||
export * from './rootLogger';
|
||||
export * from './scheduler';
|
||||
export * from './tokenManager';
|
||||
export * from './urlReader';
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { lifecycleFactory } from './lifecycleFactory';
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { loggerFactory } from './loggerFactory';
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { permissionsFactory } from './permissionsFactory';
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { rootLifecycleFactory } from './rootLifecycleFactory';
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import { getVoidLogger } from '@backstage/backend-common';
|
||||
import { BackendLifecycleImpl } from './rootLifecycleService';
|
||||
import { BackendLifecycleImpl } from './rootLifecycleFactory';
|
||||
|
||||
describe('lifecycleService', () => {
|
||||
it('should execute registered shutdown hook', async () => {
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { rootLoggerFactory } from './rootLoggerFactory';
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { schedulerFactory } from './schedulerFactory';
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { tokenManagerFactory } from './tokenManagerFactory';
|
||||
+7
-11
@@ -18,23 +18,19 @@ import {
|
||||
coreServices,
|
||||
createServiceFactory,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import {
|
||||
loggerToWinstonLogger,
|
||||
ServerTokenManager,
|
||||
} from '@backstage/backend-common';
|
||||
import { ServerTokenManager } from '@backstage/backend-common';
|
||||
|
||||
/** @public */
|
||||
export const tokenManagerFactory = createServiceFactory({
|
||||
service: coreServices.tokenManager,
|
||||
deps: {
|
||||
config: coreServices.config,
|
||||
logger: coreServices.logger,
|
||||
logger: coreServices.rootLogger,
|
||||
},
|
||||
async factory() {
|
||||
return async ({ config, logger }) => {
|
||||
return ServerTokenManager.fromConfig(config, {
|
||||
logger: loggerToWinstonLogger(logger),
|
||||
});
|
||||
};
|
||||
async factory({ config, logger }) {
|
||||
const tokenManager = ServerTokenManager.fromConfig(config, {
|
||||
logger,
|
||||
});
|
||||
return async () => tokenManager;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { urlReaderFactory } from './urlReaderFactory';
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
coreServices,
|
||||
ServiceRef,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { BackendLifecycleImpl } from '../services/implementations/rootLifecycleService';
|
||||
import { BackendLifecycleImpl } from '../services/implementations/rootLifecycle/rootLifecycleFactory';
|
||||
import {
|
||||
BackendRegisterInit,
|
||||
EnumerableServiceHolder,
|
||||
|
||||
@@ -31,6 +31,7 @@ import {
|
||||
schedulerFactory,
|
||||
tokenManagerFactory,
|
||||
urlReaderFactory,
|
||||
identityFactory,
|
||||
} from '@backstage/backend-app-api';
|
||||
import { ServiceFactoryOrFunction } from '@backstage/backend-plugin-api';
|
||||
|
||||
@@ -39,16 +40,17 @@ export const defaultServiceFactories = [
|
||||
configFactory(),
|
||||
databaseFactory(),
|
||||
discoveryFactory(),
|
||||
httpRouterFactory(),
|
||||
identityFactory(),
|
||||
lifecycleFactory(),
|
||||
loggerFactory(),
|
||||
rootLoggerFactory(),
|
||||
permissionsFactory(),
|
||||
rootHttpRouterFactory(),
|
||||
rootLifecycleFactory(),
|
||||
rootLoggerFactory(),
|
||||
schedulerFactory(),
|
||||
tokenManagerFactory(),
|
||||
urlReaderFactory(),
|
||||
httpRouterFactory(),
|
||||
rootHttpRouterFactory(),
|
||||
lifecycleFactory(),
|
||||
rootLifecycleFactory(),
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
import { Config } from '@backstage/config';
|
||||
import { Handler } from 'express';
|
||||
import { IdentityApi } from '@backstage/plugin-auth-node';
|
||||
import { JsonValue } from '@backstage/types';
|
||||
import { Knex } from 'knex';
|
||||
import { PermissionEvaluator } from '@backstage/plugin-permission-common';
|
||||
@@ -108,6 +109,7 @@ export namespace coreServices {
|
||||
const scheduler: ServiceRef<SchedulerService, 'plugin'>;
|
||||
const tokenManager: ServiceRef<TokenManagerService, 'plugin'>;
|
||||
const urlReader: ServiceRef<UrlReaderService, 'plugin'>;
|
||||
const identity: ServiceRef<IdentityService, 'plugin'>;
|
||||
}
|
||||
|
||||
// @public
|
||||
@@ -182,6 +184,9 @@ export interface HttpRouterService {
|
||||
use(handler: Handler): void;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface IdentityService extends IdentityApi {}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface LifecycleService {
|
||||
addShutdownHook(options: LifecycleServiceShutdownHook): void;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
"dependencies": {
|
||||
"@backstage/backend-tasks": "workspace:^",
|
||||
"@backstage/config": "workspace:^",
|
||||
"@backstage/plugin-auth-node": "workspace:^",
|
||||
"@backstage/plugin-permission-common": "workspace:^",
|
||||
"@backstage/types": "workspace:^",
|
||||
"@types/express": "^4.17.6",
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { IdentityApi } from '@backstage/plugin-auth-node';
|
||||
|
||||
/** @public */
|
||||
export interface IdentityService extends IdentityApi {}
|
||||
@@ -156,4 +156,13 @@ export namespace coreServices {
|
||||
export const urlReader = createServiceRef<
|
||||
import('./UrlReaderService').UrlReaderService
|
||||
>({ id: 'core.urlReader' });
|
||||
|
||||
/**
|
||||
* The service reference for the plugin scoped {@link IdentityService}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const identity = createServiceRef<
|
||||
import('./IdentityService').IdentityService
|
||||
>({ id: 'core.identity' });
|
||||
}
|
||||
|
||||
@@ -49,3 +49,4 @@ export type {
|
||||
SearchResponseFile,
|
||||
UrlReaderService,
|
||||
} from './UrlReaderService';
|
||||
export type { IdentityService } from './IdentityService';
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
import React, { useMemo } from 'react';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { AnsiChunk, AnsiLine, ChunkModifiers } from './AnsiProcessor';
|
||||
import startCase from 'lodash/startCase';
|
||||
import classnames from 'classnames';
|
||||
@@ -158,7 +159,8 @@ export function LogLine({
|
||||
const elements = useMemo(
|
||||
() =>
|
||||
chunks.map(({ text, modifiers, highlight }, index) => (
|
||||
<span
|
||||
<Typography
|
||||
component="span"
|
||||
key={index}
|
||||
className={classnames(
|
||||
getModifierClasses(classes, modifiers),
|
||||
@@ -169,7 +171,7 @@ export function LogLine({
|
||||
)}
|
||||
>
|
||||
{text}
|
||||
</span>
|
||||
</Typography>
|
||||
)),
|
||||
[chunks, highlightResultIndex, classes],
|
||||
);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Tabs from '@material-ui/core/Tabs';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
|
||||
interface StyledTabsProps {
|
||||
@@ -53,7 +54,7 @@ export const StyledTabs = (props: PropsWithChildren<StyledTabsProps>) => {
|
||||
<Tabs
|
||||
classes={classes}
|
||||
{...props}
|
||||
TabIndicatorProps={{ children: <span /> }}
|
||||
TabIndicatorProps={{ children: <Typography component="span" /> }}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -106,7 +106,7 @@ export const OutsideOfHeader = () => {
|
||||
<Link to="/">General Page</Link>
|
||||
<Link to="/" onClick={handleClick}>
|
||||
<Box display="flex" alignItems="center">
|
||||
<span>Second Page</span>
|
||||
<Typography component="span">Second Page</Typography>
|
||||
{open ? <ExpandLessIcon /> : <ExpandMoreIcon />}
|
||||
</Box>
|
||||
</Link>
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
import Grid from '@material-ui/core/Grid';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import React, { PropsWithChildren, useState } from 'react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { CardTab, TabbedCard } from './TabbedCard';
|
||||
@@ -89,7 +90,7 @@ export const WithControlledTabValue = () => {
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<span>Selected tab is {selectedTab}</span>
|
||||
<Typography component="span">Selected tab is {selectedTab}</Typography>
|
||||
|
||||
<TabbedCard
|
||||
value={selectedTab}
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
ListItemText,
|
||||
makeStyles,
|
||||
} from '@material-ui/core';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { parseEntityRef } from '@backstage/catalog-model';
|
||||
import { Link } from '@backstage/core-components';
|
||||
import { useAnalytics } from '@backstage/core-plugin-api';
|
||||
@@ -83,7 +84,8 @@ export function AdrSearchResultListItem(props: {
|
||||
</Link>
|
||||
}
|
||||
secondary={
|
||||
<span
|
||||
<Typography
|
||||
component="span"
|
||||
style={{
|
||||
display: '-webkit-box',
|
||||
WebkitBoxOrient: 'vertical',
|
||||
@@ -100,7 +102,7 @@ export function AdrSearchResultListItem(props: {
|
||||
) : (
|
||||
result.text
|
||||
)}
|
||||
</span>
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
<Box>
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
import { ApiEntity } from '@backstage/catalog-model';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import React from 'react';
|
||||
import { apiDocsConfigRef } from '../../config';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
@@ -28,5 +29,5 @@ export const ApiTypeTitle = (props: { apiEntity: ApiEntity }) => {
|
||||
const definition = config.getApiDefinitionWidget(apiEntity);
|
||||
const type = definition ? definition.title : apiEntity.spec.type;
|
||||
|
||||
return <span>{type}</span>;
|
||||
return <Typography component="span">{type}</Typography>;
|
||||
};
|
||||
|
||||
@@ -42,34 +42,34 @@ export const getBuildResultComponent = (result: number | undefined) => {
|
||||
switch (result) {
|
||||
case BuildResult.Succeeded:
|
||||
return (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
<StatusOK /> Succeeded
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
case BuildResult.PartiallySucceeded:
|
||||
return (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
<StatusWarning /> Partially Succeeded
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
case BuildResult.Failed:
|
||||
return (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
<StatusError /> Failed
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
case BuildResult.Canceled:
|
||||
return (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
<StatusAborted /> Canceled
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
case BuildResult.None:
|
||||
default:
|
||||
return (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
<StatusWarning /> Unknown
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -81,36 +81,36 @@ export const getBuildStateComponent = (
|
||||
switch (status) {
|
||||
case BuildStatus.InProgress:
|
||||
return (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
<StatusRunning /> In Progress
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
case BuildStatus.Completed:
|
||||
return getBuildResultComponent(result);
|
||||
case BuildStatus.Cancelling:
|
||||
return (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
<StatusAborted /> Cancelling
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
case BuildStatus.Postponed:
|
||||
return (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
<StatusPending /> Postponed
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
case BuildStatus.NotStarted:
|
||||
return (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
<StatusAborted /> Not Started
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
case BuildStatus.None:
|
||||
default:
|
||||
return (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
<StatusWarning /> Unknown
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
+3
-2
@@ -16,6 +16,7 @@
|
||||
|
||||
import { Avatar, Link } from '@backstage/core-components';
|
||||
import { Card, CardContent, CardHeader } from '@material-ui/core';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
|
||||
import { AutoCompleteIcon } from '../AutoCompleteIcon';
|
||||
import { DashboardPullRequest } from '@backstage/plugin-azure-devops-common';
|
||||
@@ -78,9 +79,9 @@ export const PullRequestCard = ({
|
||||
: undefined;
|
||||
|
||||
const subheader = (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
{repoLink} · {creationDate}
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
|
||||
const avatar = (
|
||||
|
||||
+3
-1
@@ -20,6 +20,7 @@ import {
|
||||
PolicyType,
|
||||
} from '@backstage/plugin-azure-devops-common';
|
||||
import { styled, withStyles } from '@material-ui/core/styles';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
|
||||
import CancelIcon from '@material-ui/icons/Cancel';
|
||||
import GroupWorkIcon from '@material-ui/icons/GroupWork';
|
||||
@@ -91,6 +92,7 @@ export const PullRequestCardPolicy = ({
|
||||
policy,
|
||||
}: PullRequestCardPolicyProps) => (
|
||||
<PullRequestCardPolicyContainer>
|
||||
{getPolicyIcon(policy)} <span>{policy.text}</span>
|
||||
{getPolicyIcon(policy)}{' '}
|
||||
<Typography component="span">{policy.text}</Typography>
|
||||
</PullRequestCardPolicyContainer>
|
||||
);
|
||||
|
||||
+3
-1
@@ -33,6 +33,7 @@ import PublicIcon from '@material-ui/icons/Public';
|
||||
import MoreVertIcon from '@material-ui/icons/MoreVert';
|
||||
import StartIcon from '@material-ui/icons/PlayArrow';
|
||||
import StopIcon from '@material-ui/icons/Stop';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import OpenInNewIcon from '@material-ui/icons/OpenInNew';
|
||||
import { DateTime } from 'luxon';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
@@ -51,7 +52,8 @@ const State = ({ value }: { value: States }) => {
|
||||
};
|
||||
return (
|
||||
<Box display="flex" alignItems="center">
|
||||
<span
|
||||
<Typography
|
||||
component="span"
|
||||
style={{
|
||||
display: 'block',
|
||||
width: '8px',
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { Autocomplete } from '@material-ui/lab';
|
||||
import { TextField, makeStyles } from '@material-ui/core';
|
||||
|
||||
@@ -49,7 +50,9 @@ export const ProjectSelector = ({
|
||||
defaultValue={defaultValue}
|
||||
options={catalogEntities}
|
||||
getOptionLabel={option => option?.metadata?.name}
|
||||
renderOption={option => <span>{option?.metadata?.name}</span>}
|
||||
renderOption={option => (
|
||||
<Typography component="span">{option?.metadata?.name}</Typography>
|
||||
)}
|
||||
renderInput={params => <TextField {...params} label={label} />}
|
||||
onChange={(_, data) => {
|
||||
onChange(data!);
|
||||
|
||||
+9
-7
@@ -577,13 +577,15 @@ export class IncrementalIngestionDatabaseManager {
|
||||
.update('ingestion_mark_id', markId)
|
||||
.whereIn('ref', existingRefsArray);
|
||||
|
||||
await tx('ingestion_mark_entities').insert(
|
||||
newRefs.map(ref => ({
|
||||
id: v4(),
|
||||
ingestion_mark_id: markId,
|
||||
ref,
|
||||
})),
|
||||
);
|
||||
if (newRefs.length > 0) {
|
||||
await tx('ingestion_mark_entities').insert(
|
||||
newRefs.map(ref => ({
|
||||
id: v4(),
|
||||
ingestion_mark_id: markId,
|
||||
ref,
|
||||
})),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+8
-4
@@ -125,11 +125,15 @@ export const EntityPeekAheadPopover = (props: EntityPeekAheadPopoverProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<span onMouseEnter={debouncedHandleMouseEnter}>
|
||||
<span data-testid="trigger" {...bindHover(popupState)}>
|
||||
<Typography component="span" onMouseEnter={debouncedHandleMouseEnter}>
|
||||
<Typography
|
||||
component="span"
|
||||
data-testid="trigger"
|
||||
{...bindHover(popupState)}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
</span>
|
||||
</Typography>
|
||||
</Typography>
|
||||
{isHovered && (
|
||||
<HoverPopover
|
||||
PaperProps={{
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
MenuItem,
|
||||
MenuList,
|
||||
Popover,
|
||||
Tooltip,
|
||||
} from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import BugReportIcon from '@material-ui/icons/BugReport';
|
||||
@@ -114,19 +115,21 @@ export function EntityContextMenu(props: EntityContextMenuProps) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<IconButton
|
||||
aria-label="more"
|
||||
aria-controls="long-menu"
|
||||
aria-haspopup="true"
|
||||
aria-expanded={!!anchorEl}
|
||||
role="button"
|
||||
onClick={onOpen}
|
||||
data-testid="menu-button"
|
||||
className={classes.button}
|
||||
id="long-menu"
|
||||
>
|
||||
<MoreVert />
|
||||
</IconButton>
|
||||
<Tooltip title="More" arrow>
|
||||
<IconButton
|
||||
aria-label="more"
|
||||
aria-controls="long-menu"
|
||||
aria-haspopup="true"
|
||||
aria-expanded={!!anchorEl}
|
||||
role="button"
|
||||
onClick={onOpen}
|
||||
data-testid="menu-button"
|
||||
className={classes.button}
|
||||
id="long-menu"
|
||||
>
|
||||
<MoreVert />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Popover
|
||||
open={Boolean(anchorEl)}
|
||||
onClose={onClose}
|
||||
|
||||
@@ -118,9 +118,9 @@ export function StatusChart(props: StatusChartProps) {
|
||||
: percentOrCount;
|
||||
|
||||
return [
|
||||
<span>
|
||||
<Typography component="span">
|
||||
{label}: {valueText}
|
||||
</span>,
|
||||
</Typography>,
|
||||
null,
|
||||
];
|
||||
};
|
||||
|
||||
@@ -18,6 +18,7 @@ import React, { CSSProperties } from 'react';
|
||||
import { DateTime, Duration } from 'luxon';
|
||||
import humanizeDuration from 'humanize-duration';
|
||||
import { capitalize } from 'lodash';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
|
||||
const infoText: CSSProperties = { color: 'InfoText' };
|
||||
|
||||
@@ -60,11 +61,19 @@ function formatDateTimeShort(milliseconds: number) {
|
||||
}
|
||||
|
||||
export function labelFormatter(epoch: number) {
|
||||
return <span style={infoText}>{formatDateTimeShort(epoch)}</span>;
|
||||
return (
|
||||
<Typography component="span" style={infoText}>
|
||||
{formatDateTimeShort(epoch)}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
export function labelFormatterWithoutTime(epoch: number) {
|
||||
return <span style={infoText}>{formatDateShort(epoch)}</span>;
|
||||
return (
|
||||
<Typography component="span" style={infoText}>
|
||||
{formatDateShort(epoch)}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
export function tickFormatterX(epoch: number) {
|
||||
@@ -88,12 +97,12 @@ export function tickFormatterY(duration: number) {
|
||||
|
||||
export function tooltipValueFormatter(durationOrCount: number, name: string) {
|
||||
return [
|
||||
<span style={infoText}>
|
||||
<Typography component="span" style={infoText}>
|
||||
{capitalize(name)}:{' '}
|
||||
{name.endsWith(' count')
|
||||
? durationOrCount
|
||||
: formatDuration(durationOrCount)}
|
||||
</span>,
|
||||
</Typography>,
|
||||
null,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -36,9 +36,9 @@ export const AlertInsightsHeader = ({
|
||||
<ScrollAnchor id={DefaultNavigation.AlertInsightsHeader} />
|
||||
<Typography variant="h4" align="center">
|
||||
{title}{' '}
|
||||
<span role="img" aria-label="direct-hit">
|
||||
<Typography component="span" role="img" aria-label="direct-hit">
|
||||
🎯
|
||||
</span>
|
||||
</Typography>
|
||||
</Typography>
|
||||
<Typography className={classes.h6Subtle} align="center" gutterBottom>
|
||||
{subtitle}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { CurrencyType, Duration, GrowthType } from '../../types';
|
||||
import { ChangeStatistic } from '@backstage/plugin-cost-insights-common';
|
||||
import { rateOf } from '../../utils/currency';
|
||||
@@ -59,48 +60,52 @@ export const CostGrowth = (props: CostGrowthProps) => {
|
||||
});
|
||||
|
||||
if (engineers < engineerThreshold) {
|
||||
return <span className={classes}>Negligible</span>;
|
||||
return (
|
||||
<Typography component="span" className={classes}>
|
||||
Negligible
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
if (currency.kind === CurrencyType.USD) {
|
||||
// Do not display percentage if ratio cannot be calculated
|
||||
if (isNaN(ratio)) {
|
||||
return (
|
||||
<span className={classes}>
|
||||
<Typography component="span" className={classes}>
|
||||
~{currency.prefix}
|
||||
{formatCurrency(converted)}
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<span className={classes}>
|
||||
<Typography component="span" className={classes}>
|
||||
{formatPercent(ratio)} or ~{currency.prefix}
|
||||
{formatCurrency(converted)}
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
if (amount < 1) {
|
||||
return (
|
||||
<span className={classes}>
|
||||
<Typography component="span" className={classes}>
|
||||
less than {indefiniteArticleOf(['a', 'an'], currency.unit)}
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
// Do not display percentage if ratio cannot be calculated
|
||||
if (isNaN(ratio)) {
|
||||
return (
|
||||
<span className={classes}>
|
||||
<Typography component="span" className={classes}>
|
||||
~{formatCurrency(converted, currency.unit)}
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<span className={classes}>
|
||||
<Typography component="span" className={classes}>
|
||||
{formatPercent(ratio)} or ~{formatCurrency(converted, currency.unit)}
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -46,9 +46,9 @@ const CostInsightsHeaderNoData = ({
|
||||
return (
|
||||
<>
|
||||
<Typography variant="h4" align="center" gutterBottom>
|
||||
<span role="img" aria-label="flushed-face">
|
||||
<Typography component="span" role="img" aria-label="flushed-face">
|
||||
😳
|
||||
</span>{' '}
|
||||
</Typography>{' '}
|
||||
Well this is awkward
|
||||
</Typography>
|
||||
<Typography className={classes.h6Subtle} align="center" gutterBottom>
|
||||
@@ -76,9 +76,9 @@ const CostInsightsHeaderAlerts = ({
|
||||
return (
|
||||
<>
|
||||
<Typography variant="h4" align="center" gutterBottom>
|
||||
<span role="img" aria-label="magnifying-glass">
|
||||
<Typography component="span" role="img" aria-label="magnifying-glass">
|
||||
🔎
|
||||
</span>{' '}
|
||||
</Typography>{' '}
|
||||
You have {alerts} thing{alerts > 1 && 's'} to look into
|
||||
</Typography>
|
||||
<Typography className={classes.h6Subtle} align="center" gutterBottom>
|
||||
@@ -101,9 +101,9 @@ const CostInsightsHeaderNoAlerts = ({
|
||||
return (
|
||||
<>
|
||||
<Typography variant="h4" gutterBottom align="center">
|
||||
<span role="img" aria-label="thumbs-up">
|
||||
<Typography component="span" role="img" aria-label="thumbs-up">
|
||||
👍
|
||||
</span>{' '}
|
||||
</Typography>{' '}
|
||||
Your team is doing great
|
||||
</Typography>
|
||||
<Typography className={classes.h6Subtle} align="center" gutterBottom>
|
||||
@@ -120,9 +120,9 @@ export const CostInsightsHeaderNoGroups = () => {
|
||||
return (
|
||||
<>
|
||||
<Typography variant="h4" align="center" gutterBottom>
|
||||
<span role="img" aria-label="flushed-face">
|
||||
<Typography component="span" role="img" aria-label="flushed-face">
|
||||
😳
|
||||
</span>{' '}
|
||||
</Typography>{' '}
|
||||
Well this is awkward
|
||||
</Typography>
|
||||
<Typography className={classes.h6Subtle} align="center" gutterBottom>
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
Select,
|
||||
SelectProps,
|
||||
} from '@material-ui/core';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { Currency, CurrencyType } from '../../types';
|
||||
import { findAlways } from '../../utils/assert';
|
||||
import { useSelectStyles as useStyles } from '../../utils/styles';
|
||||
@@ -73,9 +74,9 @@ export const CurrencySelect = ({
|
||||
key={c.kind || NULL_VALUE}
|
||||
value={c.kind || NULL_VALUE}
|
||||
>
|
||||
<span role="img" aria-label={c.label}>
|
||||
<Typography component="span" role="img" aria-label={c.label}>
|
||||
{c.label}
|
||||
</span>
|
||||
</Typography>
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
|
||||
@@ -59,9 +59,14 @@ export const LegendItem = (props: PropsWithChildren<LegendItemProps>) => {
|
||||
}
|
||||
placement="top-start"
|
||||
>
|
||||
<span role="img" aria-label="help" className={classes.helpIcon}>
|
||||
<Typography
|
||||
component="span"
|
||||
role="img"
|
||||
aria-label="help"
|
||||
className={classes.helpIcon}
|
||||
>
|
||||
<HelpOutlineOutlinedIcon fontSize="small" />
|
||||
</span>
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
@@ -30,9 +30,9 @@ export const WhyCostsMatter = () => {
|
||||
<Grid item>
|
||||
<Typography variant="h6">
|
||||
Sustainability{' '}
|
||||
<span role="img" aria-label="globe">
|
||||
<Typography component="span" role="img" aria-label="globe">
|
||||
🌎
|
||||
</span>
|
||||
</Typography>
|
||||
</Typography>
|
||||
<Typography>
|
||||
Reducing cloud usage improves our carbon footprint.
|
||||
@@ -44,9 +44,13 @@ export const WhyCostsMatter = () => {
|
||||
<Grid item>
|
||||
<Typography variant="h6">
|
||||
Revenue{' '}
|
||||
<span role="img" aria-label="money-with-wings">
|
||||
<Typography
|
||||
component="span"
|
||||
role="img"
|
||||
aria-label="money-with-wings"
|
||||
>
|
||||
💸
|
||||
</span>
|
||||
</Typography>
|
||||
</Typography>
|
||||
<Typography>
|
||||
Keeping cloud costs well-tuned prevents infrastructure from eating
|
||||
@@ -59,9 +63,9 @@ export const WhyCostsMatter = () => {
|
||||
<Grid item>
|
||||
<Typography variant="h6">
|
||||
Innovation{' '}
|
||||
<span role="img" aria-label="medal">
|
||||
<Typography component="span" role="img" aria-label="medal">
|
||||
🥇
|
||||
</span>
|
||||
</Typography>
|
||||
</Typography>
|
||||
<Typography>
|
||||
The more we save, the more we can reinvest in speed and
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import pluralize from 'pluralize';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { KubernetesMigrationAlertCard } from '../components';
|
||||
import { CostInsightsApi } from '../../api';
|
||||
import {
|
||||
@@ -91,11 +92,11 @@ export class KubernetesMigrationAlert implements KubernetesMigrationApi {
|
||||
|
||||
get title() {
|
||||
return (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
Consider migrating{' '}
|
||||
{pluralize('service', this.data.services.length, true)} to Kubernetes{' '}
|
||||
<Lifecycle shorthand />
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -192,7 +192,10 @@ export const ServiceDetailsCard = () => {
|
||||
{!showServiceDetails && !loading && (
|
||||
<div className={classes.warning}>
|
||||
<WarningIcon />
|
||||
<span>This service does not exist in FireHydrant.</span>
|
||||
|
||||
<Typography component="span">
|
||||
This service does not exist in FireHydrant.
|
||||
</Typography>
|
||||
</div>
|
||||
)}
|
||||
{showServiceDetails && (
|
||||
@@ -251,7 +254,7 @@ export const ServiceDetailsCard = () => {
|
||||
<AddIcon className={classes.icon} />
|
||||
</Box>
|
||||
<Box>
|
||||
<span>Declare an incident</span>
|
||||
<Typography component="span">Declare an incident</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</MaterialButton>
|
||||
@@ -267,7 +270,7 @@ export const ServiceDetailsCard = () => {
|
||||
<WhatshotIcon className={classes.icon} />
|
||||
</Box>
|
||||
<Box>
|
||||
<span>View all incidents</span>
|
||||
<Typography component="span">View all incidents</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</MaterialButton>
|
||||
@@ -284,7 +287,7 @@ export const ServiceDetailsCard = () => {
|
||||
<NotesIcon className={classes.icon} />
|
||||
</Box>
|
||||
<Box>
|
||||
<span>View Service Details</span>
|
||||
<Typography component="span">View Service Details</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</MaterialButton>
|
||||
|
||||
@@ -18,6 +18,7 @@ import { useEntity } from '@backstage/plugin-catalog-react';
|
||||
import { Grid, Tooltip } from '@material-ui/core';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { DateTime } from 'luxon';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
@@ -199,7 +200,9 @@ export const FossaCard = (props: { variant?: InfoCardVariants }) => {
|
||||
<Grid item className={classes.lastAnalyzed}>
|
||||
Based on {value.dependencyCount} Dependencies on branch{' '}
|
||||
<Tooltip title="The default branch can be changed by a FOSSA admin.">
|
||||
<span className={classes.branch}>{value.projectDefaultBranch}</span>
|
||||
<Typography className={classes.branch}>
|
||||
{value.projectDefaultBranch}
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
.
|
||||
</Grid>
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
getEntityRelations,
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
import { Tooltip } from '@material-ui/core';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { Skeleton } from '@material-ui/lab';
|
||||
import { DateTime } from 'luxon';
|
||||
import * as React from 'react';
|
||||
@@ -140,11 +141,11 @@ const columns: TableColumn<FossaRow>[] = [
|
||||
DateTime.DATETIME_MED,
|
||||
)}
|
||||
>
|
||||
<span>
|
||||
<Typography component="span">
|
||||
{DateTime.fromISO(details.timestamp).toRelative({
|
||||
locale: 'en',
|
||||
})}
|
||||
</span>
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
)
|
||||
);
|
||||
|
||||
@@ -39,11 +39,17 @@ import { Link as RouterLink } from 'react-router-dom';
|
||||
|
||||
const LongText = ({ text, max }: { text: string; max: number }) => {
|
||||
if (text.length < max) {
|
||||
return <span>{text}</span>;
|
||||
return (
|
||||
<Typography color="primary" component="span">
|
||||
{text}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Tooltip title={text}>
|
||||
<span>{text.slice(0, max)}...</span>
|
||||
<Typography color="primary" component="span">
|
||||
{text.slice(0, max)}...
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import React, { ReactNode } from 'react';
|
||||
import { grey } from '@material-ui/core/colors';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import CallSplitIcon from '@material-ui/icons/CallSplit';
|
||||
import ChatIcon from '@material-ui/icons/Chat';
|
||||
import DynamicFeedIcon from '@material-ui/icons/DynamicFeed';
|
||||
@@ -35,29 +36,31 @@ export const Differ = ({ current, next, icon }: DifferProps) => {
|
||||
return (
|
||||
<>
|
||||
{icon && (
|
||||
<span>
|
||||
<Typography component="span">
|
||||
<Icon icon={icon} />{' '}
|
||||
</span>
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
{!!current && (
|
||||
<span
|
||||
<Typography
|
||||
component="span"
|
||||
data-testid={TEST_IDS.components.differ.current}
|
||||
style={{ color: grey[700] }}
|
||||
>
|
||||
{current ?? 'None'}
|
||||
</span>
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
{current && next && <span>{' → '}</span>}
|
||||
{current && next && <Typography component="span">{' → '}</Typography>}
|
||||
|
||||
{next && (
|
||||
<span
|
||||
<Typography
|
||||
component="span"
|
||||
data-testid={TEST_IDS.components.differ.next}
|
||||
style={{ fontWeight: 'bold' }}
|
||||
>
|
||||
{next}
|
||||
</span>
|
||||
</Typography>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
+3
-2
@@ -50,8 +50,9 @@ export function LinearProgressWithLabel(props: {
|
||||
|
||||
const CompletionEmoji = () => {
|
||||
if (status === STATUSES.ONGOING) return null;
|
||||
if (status === STATUSES.FAILURE) return <span>{` ${ICONS.FAILURE} `}</span>;
|
||||
return <span>{` ${ICONS.SUCCESS} `}</span>;
|
||||
if (status === STATUSES.FAILURE)
|
||||
return <Typography component="span">{` ${ICONS.FAILURE} `}</Typography>;
|
||||
return <Typography component="span">{` ${ICONS.SUCCESS} `}</Typography>;
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -42,6 +42,7 @@ describe('Info', () => {
|
||||
|
||||
expect(await findByText(mockReleaseBranch.name)).toMatchInlineSnapshot(`
|
||||
<span
|
||||
class="MuiTypography-root MuiTypography-body1"
|
||||
data-testid="grm--differ-next"
|
||||
style="font-weight: bold;"
|
||||
>
|
||||
@@ -53,6 +54,7 @@ describe('Info', () => {
|
||||
await findByText(`${mockCalverProject.owner}/${mockCalverProject.repo}`),
|
||||
).toMatchInlineSnapshot(`
|
||||
<span
|
||||
class="MuiTypography-root MuiTypography-body1"
|
||||
data-testid="grm--differ-next"
|
||||
style="font-weight: bold;"
|
||||
>
|
||||
@@ -63,6 +65,7 @@ describe('Info', () => {
|
||||
expect(await findByText(mockCalverProject.versioningStrategy))
|
||||
.toMatchInlineSnapshot(`
|
||||
<span
|
||||
class="MuiTypography-root MuiTypography-body1"
|
||||
data-testid="grm--differ-next"
|
||||
style="font-weight: bold;"
|
||||
>
|
||||
@@ -73,6 +76,7 @@ describe('Info', () => {
|
||||
expect(await findByText(mockReleaseCandidateCalver.tagName))
|
||||
.toMatchInlineSnapshot(`
|
||||
<span
|
||||
class="MuiTypography-root MuiTypography-body1"
|
||||
data-testid="grm--differ-next"
|
||||
style="font-weight: bold;"
|
||||
>
|
||||
|
||||
@@ -75,12 +75,13 @@ describe('useResponseSteps', () => {
|
||||
"message": <b>
|
||||
Something went wrong
|
||||
|
||||
<span
|
||||
<WithStyles(ForwardRef(Typography))
|
||||
aria-label="fire"
|
||||
component="span"
|
||||
role="img"
|
||||
>
|
||||
🔥
|
||||
</span>
|
||||
</WithStyles(ForwardRef(Typography))>
|
||||
</b>,
|
||||
"secondaryMessage": "Error message: :(",
|
||||
},
|
||||
@@ -108,12 +109,13 @@ describe('useResponseSteps', () => {
|
||||
"message": <b>
|
||||
Something went wrong
|
||||
|
||||
<span
|
||||
<WithStyles(ForwardRef(Typography))
|
||||
aria-label="fire"
|
||||
component="span"
|
||||
role="img"
|
||||
>
|
||||
🔥
|
||||
</span>
|
||||
</WithStyles(ForwardRef(Typography))>
|
||||
</b>,
|
||||
"secondaryMessage": "Error message: unknown",
|
||||
},
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { ResponseStep } from '../types/types';
|
||||
@@ -30,9 +31,9 @@ export function useResponseSteps() {
|
||||
message: (
|
||||
<b>
|
||||
Something went wrong{' '}
|
||||
<span role="img" aria-label="fire">
|
||||
<Typography component="span" role="img" aria-label="fire">
|
||||
🔥
|
||||
</span>
|
||||
</Typography>
|
||||
</b>
|
||||
),
|
||||
secondaryMessage: `Error message: ${
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
useApi,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { Tooltip } from '@material-ui/core';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
import { getTimeBasedGreeting } from './timeUtil';
|
||||
@@ -43,9 +44,9 @@ export const WelcomeTitle = () => {
|
||||
|
||||
return (
|
||||
<Tooltip title={greeting.language}>
|
||||
<span>{`${greeting.greeting}${
|
||||
<Typography component="span">{`${greeting.greeting}${
|
||||
profile?.displayName ? `, ${profile?.displayName}` : ''
|
||||
}!`}</span>
|
||||
}!`}</Typography>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { Website, lighthouseApiRef } from '../../api';
|
||||
import useInterval from 'react-use/lib/useInterval';
|
||||
import {
|
||||
@@ -112,7 +113,9 @@ export const AuditListTable = ({ items }: { items: Website[] }) => {
|
||||
lastReport: (
|
||||
<>
|
||||
<AuditStatusIcon audit={website.lastAudit} />{' '}
|
||||
<span>{website.lastAudit.status.toLocaleUpperCase('en-US')}</span>
|
||||
<Typography component="span">
|
||||
{website.lastAudit.status.toLocaleUpperCase('en-US')}
|
||||
</Typography>
|
||||
</>
|
||||
),
|
||||
lastAuditTriggered: formatTime(website.lastAudit.timeCreated),
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { Audit, AuditCompleted, LighthouseCategoryId } from '../../api';
|
||||
import { useWebsiteForEntity } from '../../hooks/useWebsiteForEntity';
|
||||
import AuditStatusIcon from '../AuditStatusIcon';
|
||||
@@ -52,7 +53,7 @@ const LighthouseCategoryScoreStatus = (props: { score: number }) => {
|
||||
</>
|
||||
);
|
||||
default:
|
||||
return <span>N/A</span>;
|
||||
return <Typography component="span">N/A</Typography>;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -128,6 +128,12 @@ export function createFetchRailsAction(options: {
|
||||
description: 'Skip Action Text gem',
|
||||
type: 'boolean',
|
||||
},
|
||||
skipActiveRecord: {
|
||||
title: 'skipActiveRecord',
|
||||
description: 'Skip Active Record files',
|
||||
type: 'boolean',
|
||||
},
|
||||
|
||||
force: {
|
||||
title: 'force',
|
||||
description: 'Overwrite files that already exist',
|
||||
|
||||
+1
@@ -33,6 +33,7 @@ describe('railsArgumentResolver', () => {
|
||||
[{ skipActionMailbox: true }, ['--skip-action-mailbox']],
|
||||
[{ skipActiveStorage: true }, ['--skip-active-storage']],
|
||||
[{ skipActionText: true }, ['--skip-action-text']],
|
||||
[{ skipActiveRecord: true }, ['--skip-active-record']],
|
||||
[{ force: true }, ['--force']],
|
||||
[{ webpacker: 'vue' }, ['--webpack', 'vue']],
|
||||
[{ database: 'postgresql' }, ['--database', 'postgresql']],
|
||||
|
||||
+5
@@ -57,6 +57,7 @@ export type RailsRunOptions = {
|
||||
skipBundle?: boolean;
|
||||
skipTest?: boolean;
|
||||
skipWebpackInstall?: boolean;
|
||||
skipActiveRecord?: boolean;
|
||||
template?: string;
|
||||
webpacker?: Webpacker;
|
||||
};
|
||||
@@ -84,6 +85,10 @@ export const railsArgumentResolver = (
|
||||
argumentsToRun.push('--skip-webpack-install');
|
||||
}
|
||||
|
||||
if (options?.skipActiveRecord) {
|
||||
argumentsToRun.push('--skip-active-record');
|
||||
}
|
||||
|
||||
if (options?.skipTest) {
|
||||
argumentsToRun.push('--skip-test');
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
|
||||
@@ -0,0 +1,160 @@
|
||||
# scaffolder-backend-module-sentry
|
||||
|
||||
Welcome to the Sentry Module for Scaffolder.
|
||||
|
||||
Here you can find all Sentry related features to improve your scaffolder:
|
||||
|
||||
## Getting started
|
||||
|
||||
You need to configure the action in your backend:
|
||||
|
||||
## From your Backstage root directory
|
||||
|
||||
```bash
|
||||
# From your Backstage root directory
|
||||
yarn add --cwd packages/backend @backstage/plugin-scaffolder-backend-module-sentry
|
||||
```
|
||||
|
||||
Configure the action (you can check
|
||||
the [docs](https://backstage.io/docs/features/software-templates/writing-custom-actions#registering-custom-actions) to
|
||||
see all options):
|
||||
|
||||
```typescript
|
||||
const actions = [
|
||||
createSentryCreateProjectAction({
|
||||
integrations,
|
||||
reader: env.reader,
|
||||
containerRunner,
|
||||
}),
|
||||
];
|
||||
|
||||
return await createRouter({
|
||||
containerRunner,
|
||||
catalogClient,
|
||||
actions,
|
||||
logger: env.logger,
|
||||
config: env.config,
|
||||
database: env.database,
|
||||
reader: env.reader,
|
||||
});
|
||||
```
|
||||
|
||||
You need to define your Sentry API Token in your `app-config.yaml`:
|
||||
|
||||
```yaml
|
||||
scaffolder:
|
||||
sentry:
|
||||
token: ${SENTRY_TOKEN}
|
||||
```
|
||||
|
||||
After that you can use the action in your template:
|
||||
|
||||
```yaml
|
||||
apiVersion: scaffolder.backstage.io/v1beta3
|
||||
kind: Template
|
||||
metadata:
|
||||
name: sentry-demo
|
||||
title: Sentry template
|
||||
description: scaffolder sentry app
|
||||
spec:
|
||||
owner: backstage/techdocs-core
|
||||
type: service
|
||||
|
||||
parameters:
|
||||
- title: Fill in some steps
|
||||
required:
|
||||
- name
|
||||
- owner
|
||||
properties:
|
||||
name:
|
||||
title: Name
|
||||
type: string
|
||||
description: Unique name of the component
|
||||
ui:autofocus: true
|
||||
ui:options:
|
||||
rows: 5
|
||||
owner:
|
||||
title: Owner
|
||||
type: string
|
||||
description: Owner of the component
|
||||
ui:field: OwnerPicker
|
||||
ui:options:
|
||||
catalogFilter:
|
||||
kind: Group
|
||||
system:
|
||||
title: System
|
||||
type: string
|
||||
description: System of the component
|
||||
ui:field: EntityPicker
|
||||
ui:options:
|
||||
catalogFilter:
|
||||
kind: System
|
||||
defaultKind: System
|
||||
|
||||
- title: Choose a location
|
||||
required:
|
||||
- repoUrl
|
||||
- dryRun
|
||||
properties:
|
||||
repoUrl:
|
||||
title: Repository Location
|
||||
type: string
|
||||
ui:field: RepoUrlPicker
|
||||
ui:options:
|
||||
allowedHosts:
|
||||
- github.com
|
||||
dryRun:
|
||||
title: Only perform a dry run, don't publish anything
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
steps:
|
||||
- id: fetch
|
||||
name: Fetch
|
||||
action: fetch:template
|
||||
input:
|
||||
url: https://github.com/TEMPLATE
|
||||
values:
|
||||
name: ${{ parameters.name }}
|
||||
|
||||
- id: create-sentry-project
|
||||
if: ${{ parameters.dryRun !== true }}
|
||||
name: Create Sentry Project
|
||||
action: sentry:create-project
|
||||
input:
|
||||
organizationSlug: ORG-SLUG
|
||||
teamSlug: TEAM-SLUG
|
||||
name: ${{ parameters.name }}
|
||||
|
||||
- id: publish
|
||||
if: ${{ parameters.dryRun !== true }}
|
||||
name: Publish
|
||||
action: publish:github
|
||||
input:
|
||||
allowedHosts:
|
||||
- github.com
|
||||
description: This is ${{ parameters.name }}
|
||||
repoUrl: ${{ parameters.repoUrl }}
|
||||
|
||||
- id: register
|
||||
if: ${{ parameters.dryRun !== true }}
|
||||
name: Register
|
||||
action: catalog:register
|
||||
input:
|
||||
repoContentsUrl: ${{ steps['publish'].output.repoContentsUrl }}
|
||||
catalogInfoPath: '/catalog-info.yaml'
|
||||
|
||||
- name: Results
|
||||
if: ${{ parameters.dryRun }}
|
||||
action: debug:log
|
||||
input:
|
||||
listWorkspace: true
|
||||
|
||||
output:
|
||||
links:
|
||||
- title: Repository
|
||||
url: ${{ steps['publish'].output.remoteUrl }}
|
||||
- title: Open in catalog
|
||||
icon: catalog
|
||||
entityRef: ${{ steps['register'].output.entityRef }}
|
||||
```
|
||||
@@ -0,0 +1,21 @@
|
||||
## API Report File for "@backstage/plugin-scaffolder-backend-module-sentry"
|
||||
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { Config } from '@backstage/config';
|
||||
import { TemplateAction } from '@backstage/plugin-scaffolder-backend';
|
||||
|
||||
// @public
|
||||
export function createSentryCreateProjectAction(options: {
|
||||
config: Config;
|
||||
}): TemplateAction<{
|
||||
organizationSlug: string;
|
||||
teamSlug: string;
|
||||
name: string;
|
||||
slug?: string | undefined;
|
||||
authToken?: string | undefined;
|
||||
}>;
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
```
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "@backstage/plugin-scaffolder-backend-module-sentry",
|
||||
"version": "0.0.0",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"main": "dist/index.esm.js",
|
||||
"types": "dist/index.d.ts"
|
||||
},
|
||||
"backstage": {
|
||||
"role": "frontend-plugin"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "backstage-cli package start",
|
||||
"build": "backstage-cli package build",
|
||||
"lint": "backstage-cli package lint",
|
||||
"test": "backstage-cli package test",
|
||||
"clean": "backstage-cli package clean",
|
||||
"prepack": "backstage-cli package prepack",
|
||||
"postpack": "backstage-cli package postpack"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/config": "workspace:^",
|
||||
"@backstage/errors": "workspace:^",
|
||||
"@backstage/integration": "workspace:^",
|
||||
"@backstage/plugin-scaffolder-backend": "workspace:^"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "workspace:^",
|
||||
"@backstage/core-app-api": "workspace:^",
|
||||
"@backstage/dev-utils": "workspace:^",
|
||||
"@backstage/test-utils": "workspace:^",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^12.1.3",
|
||||
"@testing-library/user-event": "^14.0.0",
|
||||
"@types/node": "*",
|
||||
"cross-fetch": "^3.1.5",
|
||||
"msw": "^0.49.0"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createTemplateAction } from '@backstage/plugin-scaffolder-backend';
|
||||
import { InputError } from '@backstage/errors';
|
||||
import { Config } from '@backstage/config';
|
||||
|
||||
/**
|
||||
* Creates the `sentry:craete-project` Scaffolder action.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* See {@link https://backstage.io/docs/features/software-templates/writing-custom-actions}.
|
||||
*
|
||||
* @param options - Configuration of the Sentry API.
|
||||
* @public
|
||||
*/
|
||||
export function createSentryCreateProjectAction(options: { config: Config }) {
|
||||
const { config } = options;
|
||||
|
||||
return createTemplateAction<{
|
||||
organizationSlug: string;
|
||||
teamSlug: string;
|
||||
name: string;
|
||||
slug?: string;
|
||||
authToken?: string;
|
||||
}>({
|
||||
id: 'sentry:project:create',
|
||||
schema: {
|
||||
input: {
|
||||
required: ['organizationSlug', 'teamSlug', 'name'],
|
||||
type: 'object',
|
||||
properties: {
|
||||
organizationSlug: {
|
||||
title: 'The slug of the organization the team belongs to',
|
||||
type: 'string',
|
||||
},
|
||||
teamSlug: {
|
||||
title: 'The slug of the team to create a new project for',
|
||||
type: 'string',
|
||||
},
|
||||
name: {
|
||||
title: 'The name for the new project',
|
||||
type: 'string',
|
||||
},
|
||||
slug: {
|
||||
title:
|
||||
'Optional slug for the new project. If not provided a slug is generated from the name',
|
||||
type: 'string',
|
||||
},
|
||||
authToken: {
|
||||
title:
|
||||
'authenticate via bearer auth token. Requires scope: project:write',
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
async handler(ctx) {
|
||||
const { organizationSlug, teamSlug, name, slug, authToken } = ctx.input;
|
||||
|
||||
const body: any = {
|
||||
name: name,
|
||||
};
|
||||
|
||||
if (slug) {
|
||||
body.slug = slug;
|
||||
}
|
||||
|
||||
const token = authToken
|
||||
? authToken
|
||||
: config.getOptionalString('scaffolder.sentry.token');
|
||||
|
||||
if (!token) {
|
||||
throw new InputError(`No valid sentry token given`);
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
`https://sentry.io/api/0/teams/${organizationSlug}/${teamSlug}/projects/`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(body),
|
||||
},
|
||||
);
|
||||
|
||||
const contentType = response.headers.get('content-type');
|
||||
|
||||
if (contentType !== 'application/json') {
|
||||
throw new InputError(
|
||||
`Unexpected Sentry Response Type: ${await response.text()}`,
|
||||
);
|
||||
}
|
||||
|
||||
const code = response.status;
|
||||
const result = await response.json();
|
||||
|
||||
if (code !== 201) {
|
||||
throw new InputError(`Sentry Response was: ${await result.detail}`);
|
||||
}
|
||||
|
||||
ctx.output('id', result.id);
|
||||
ctx.output('result', result);
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { createSentryCreateProjectAction } from './actions/createProject';
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
Box,
|
||||
Divider,
|
||||
} from '@material-ui/core';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { Link } from '@backstage/core-components';
|
||||
|
||||
/**
|
||||
@@ -85,7 +86,8 @@ export const DefaultResultListItemComponent = ({
|
||||
</Link>
|
||||
}
|
||||
secondary={
|
||||
<span
|
||||
<Typography
|
||||
component="span"
|
||||
style={{
|
||||
display: '-webkit-box',
|
||||
WebkitBoxOrient: 'vertical',
|
||||
@@ -102,7 +104,7 @@ export const DefaultResultListItemComponent = ({
|
||||
) : (
|
||||
result.text
|
||||
)}
|
||||
</span>
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
{secondaryAction && <Box alignItems="flex-end">{secondaryAction}</Box>}
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
Paper,
|
||||
useTheme,
|
||||
} from '@material-ui/core';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import LaunchIcon from '@material-ui/icons/Launch';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import {
|
||||
@@ -131,7 +132,9 @@ export const Modal = ({ toggleModal }: SearchModalProps) => {
|
||||
}}
|
||||
to={`${getSearchLink()}?query=${term}`}
|
||||
>
|
||||
<span className={classes.viewResultsLink}>View Full Results</span>
|
||||
<Typography component="span" className={classes.viewResultsLink}>
|
||||
View Full Results
|
||||
</Typography>
|
||||
<LaunchIcon color="primary" />
|
||||
</Link>
|
||||
</Grid>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import React from 'react';
|
||||
|
||||
const useStyles = makeStyles((theme: BackstageTheme) => {
|
||||
@@ -29,5 +30,9 @@ const useStyles = makeStyles((theme: BackstageTheme) => {
|
||||
|
||||
export const Value = (props: { value?: string }) => {
|
||||
const classes = useStyles();
|
||||
return <span className={classes.value}>{props.value}</span>;
|
||||
return (
|
||||
<Typography component="span" className={classes.value}>
|
||||
{props.value}
|
||||
</Typography>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ClassNameMap } from '@material-ui/core/styles/withStyles';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import React from 'react';
|
||||
import { WithLink } from '../../utils/components';
|
||||
import { RadarDescription } from '../RadarDescription';
|
||||
@@ -50,17 +51,21 @@ export const RadarLegendLink = ({
|
||||
if (description) {
|
||||
return (
|
||||
<>
|
||||
<span
|
||||
<Typography
|
||||
component="span"
|
||||
className={classes.entryLink}
|
||||
onClick={handleClickOpen}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onKeyPress={toggle}
|
||||
>
|
||||
<span className={active ? classes.activeEntry : classes.entry}>
|
||||
<Typography
|
||||
component="span"
|
||||
className={active ? classes.activeEntry : classes.entry}
|
||||
>
|
||||
{title}
|
||||
</span>
|
||||
</span>
|
||||
</Typography>
|
||||
</Typography>
|
||||
{open && (
|
||||
<RadarDescription
|
||||
open={open}
|
||||
@@ -75,9 +80,12 @@ export const RadarLegendLink = ({
|
||||
}
|
||||
return (
|
||||
<WithLink url={url} className={classes.entryLink}>
|
||||
<span className={active ? classes.activeEntry : classes.entry}>
|
||||
<Typography
|
||||
component="span"
|
||||
className={active ? classes.activeEntry : classes.entry}
|
||||
>
|
||||
{title}
|
||||
</span>
|
||||
</Typography>
|
||||
</WithLink>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
ListItemText,
|
||||
makeStyles,
|
||||
} from '@material-ui/core';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { Link } from '@backstage/core-components';
|
||||
import { useAnalytics } from '@backstage/core-plugin-api';
|
||||
import { ResultHighlight } from '@backstage/plugin-search-common';
|
||||
@@ -137,7 +138,8 @@ export const TechDocsSearchResultListItem = (
|
||||
</LinkWrapper>
|
||||
}
|
||||
secondary={
|
||||
<span
|
||||
<Typography
|
||||
component="span"
|
||||
style={{
|
||||
display: '-webkit-box',
|
||||
WebkitBoxOrient: 'vertical',
|
||||
@@ -154,7 +156,7 @@ export const TechDocsSearchResultListItem = (
|
||||
) : (
|
||||
result.text
|
||||
)}
|
||||
</span>
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user