Merge branch 'master' into camilaibs/migrate-catalog-graph-to-new-frontend-system
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-azure-devops': patch
|
||||
---
|
||||
|
||||
Added alpha support for the New Frontend System (Declarative Integration)
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/repo-tools': patch
|
||||
---
|
||||
|
||||
Resolved an issue with generate-catalog-info where it was replacing upper case characters with -.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-common': patch
|
||||
---
|
||||
|
||||
`FetchUrlReader#readUrl()` now supports passing an optional `token` to authenticate requests.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-user-settings': patch
|
||||
---
|
||||
|
||||
conditionally rendering the user name and email in user settings page
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-explore': patch
|
||||
---
|
||||
|
||||
Use the EntityDisplayName component for rendering Group nodes
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-azure-sites-backend': patch
|
||||
---
|
||||
|
||||
Added `permissionIntegrationRouter` for azure-sites-backend routes
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-common': patch
|
||||
---
|
||||
|
||||
Add a config declaration for `workingDirectory`
|
||||
@@ -1,4 +1 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
yarn lint-staged
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Umami Analytics
|
||||
author: AxisCommunications
|
||||
authorUrl: https://github.com/AxisCommunications
|
||||
category: Monitoring
|
||||
description: Track usage of your Backstage instance using Umami Analytics.
|
||||
documentation: https://github.com/AxisCommunications/backstage-plugins/blob/main/plugins/analytics-module-umami/README.md
|
||||
iconUrl: /img/umami-logo.svg
|
||||
npmPackageName: '@axis-backstage/plugin-analytics-module-umami'
|
||||
addedDate: '2024-02-05'
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 428 389.11"><circle cx="214.15" cy="181" r="171" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="20"/><path d="M413 134.11H15.29a15 15 0 0 0-15 15v15.3C.12 168 0 171.52 0 175.11c0 118.19 95.81 214 214 214 116.4 0 211.1-92.94 213.93-208.67 0-.44.07-.88.07-1.33v-30a15 15 0 0 0-15-15Z"/></svg>
|
||||
|
After Width: | Height: | Size: 390 B |
+3
-3
@@ -40,8 +40,8 @@
|
||||
"build-storybook": "yarn ./storybook run build-storybook",
|
||||
"techdocs-cli": "node scripts/techdocs-cli.js",
|
||||
"techdocs-cli:dev": "cross-env TECHDOCS_CLI_DEV_MODE=true node scripts/techdocs-cli.js",
|
||||
"prepare": "husky install",
|
||||
"postinstall": "husky install || true"
|
||||
"prepare": "husky",
|
||||
"postinstall": "husky || true"
|
||||
},
|
||||
"workspaces": {
|
||||
"packages": [
|
||||
@@ -85,7 +85,7 @@
|
||||
"eslint-plugin-react": "^7.28.0",
|
||||
"eslint-plugin-testing-library": "^6.0.0",
|
||||
"fs-extra": "10.1.0",
|
||||
"husky": "^8.0.0",
|
||||
"husky": "^9.0.0",
|
||||
"lint-staged": "^15.0.0",
|
||||
"minimist": "^1.2.5",
|
||||
"node-gyp": "^10.0.0",
|
||||
|
||||
@@ -19,8 +19,12 @@ app:
|
||||
- entity-card:catalog-graph/relations:
|
||||
config:
|
||||
height: 300
|
||||
- entity-card:azure-devops/readme
|
||||
# Entity page content
|
||||
- entity-content:techdocs
|
||||
- entity-content:azure-devops/pipelines
|
||||
- entity-content:azure-devops/pull-requests
|
||||
- entity-content:azure-devops/git-tags
|
||||
|
||||
# scmAuthExtension: >-
|
||||
# createScmAuthExtension({
|
||||
|
||||
Vendored
+16
@@ -67,6 +67,22 @@ export interface Config {
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* An absolute path to a directory that can be used as a working dir, for
|
||||
* example as scratch space for large operations.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* Note that this must be an absolute path.
|
||||
*
|
||||
* If not set, the operating system's designated temporary directory is
|
||||
* commonly used, but that is implementation defined per plugin.
|
||||
*
|
||||
* Plugins are encouraged to heed this config setting if present, to allow
|
||||
* deployment in severely locked-down or limited environments.
|
||||
*/
|
||||
workingDirectory?: string;
|
||||
|
||||
/** Database connection configuration, select base database type using the `client` field */
|
||||
database: {
|
||||
/** Default database client to use */
|
||||
|
||||
@@ -223,6 +223,27 @@ describe('FetchUrlReader', () => {
|
||||
).rejects.toThrow(NotModifiedError);
|
||||
});
|
||||
|
||||
it('should send Authorization header if token is provided', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
worker.use(
|
||||
rest.get(
|
||||
'https://backstage.io/requires-authentication',
|
||||
(req, res, ctx) => {
|
||||
expect(req.headers.get('authorization')).toBe('Bearer mytoken');
|
||||
return res(ctx.status(200));
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
await fetchUrlReader.readUrl(
|
||||
'https://backstage.io/requires-authentication',
|
||||
{
|
||||
token: 'mytoken',
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it('should return etag from the response', async () => {
|
||||
const response = await fetchUrlReader.readUrl(
|
||||
'https://backstage.io/some-resource',
|
||||
|
||||
@@ -131,6 +131,7 @@ export class FetchUrlReader implements UrlReader {
|
||||
...(options?.lastModifiedAfter && {
|
||||
'If-Modified-Since': options.lastModifiedAfter.toUTCString(),
|
||||
}),
|
||||
...(options?.token && { Authorization: `Bearer ${options.token}` }),
|
||||
},
|
||||
// TODO(freben): The signal cast is there because pre-3.x versions of
|
||||
// node-fetch have a very slightly deviating AbortSignal type signature.
|
||||
|
||||
@@ -12,6 +12,11 @@
|
||||
"backstage": {
|
||||
"role": "web-library"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/backstage/backstage",
|
||||
"directory": "packages/core-compat-api"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"start": "backstage-cli package start",
|
||||
|
||||
@@ -12,6 +12,11 @@
|
||||
"backstage": {
|
||||
"role": "web-library"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/backstage/backstage",
|
||||
"directory": "packages/frontend-plugin-api"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"start": "backstage-cli package start",
|
||||
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
isFulfilled,
|
||||
readFile,
|
||||
writeFile,
|
||||
safeEntityName,
|
||||
} from './utils';
|
||||
import { CodeOwnersEntry } from 'codeowners-utils';
|
||||
|
||||
@@ -164,9 +165,7 @@ async function fixCatalogInfoYaml(options: FixOptions) {
|
||||
codeowners,
|
||||
relativePath('.', yamlPath),
|
||||
);
|
||||
const safeName = packageJson.name
|
||||
.replace(/[^a-z0-9_\-\.]+/g, '-')
|
||||
.replace(/^[^a-z0-9]|[^a-z0-9]$/g, '');
|
||||
const safeName = safeEntityName(packageJson.name);
|
||||
let yamlJson: BackstagePackageEntity;
|
||||
|
||||
try {
|
||||
@@ -240,9 +239,7 @@ function createOrMergeEntity(
|
||||
owner: string,
|
||||
existingEntity: BackstagePackageEntity | Record<string, any> = {},
|
||||
): BackstagePackageEntity {
|
||||
const safeEntityName = packageJson.name
|
||||
.replace(/[^a-z0-9_\-\.]+/g, '-')
|
||||
.replace(/^[^a-z0-9]|[^a-z0-9]$/g, '');
|
||||
const entityName = safeEntityName(packageJson.name);
|
||||
|
||||
return {
|
||||
...existingEntity,
|
||||
@@ -251,7 +248,7 @@ function createOrMergeEntity(
|
||||
metadata: {
|
||||
...existingEntity.metadata,
|
||||
// Provide default name/title/description values.
|
||||
name: safeEntityName,
|
||||
name: entityName,
|
||||
title: packageJson.name,
|
||||
...(packageJson.description && !existingEntity.metadata?.description
|
||||
? { description: packageJson.description }
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2024 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 { safeEntityName } from './utils';
|
||||
|
||||
describe('utils', () => {
|
||||
describe('safeEntityName', () => {
|
||||
it('should remove non-alphanumeric characters at the start and end', () => {
|
||||
const result = safeEntityName('%entityname$');
|
||||
expect(result).toBe('entityname');
|
||||
});
|
||||
|
||||
it('should replace non-alphanumeric characters, except - and _, with -', () => {
|
||||
const result = safeEntityName('entity@#name$');
|
||||
expect(result).toBe('entity-name');
|
||||
});
|
||||
|
||||
it('should replace capital letters with - followed by the same letter in lowercase', () => {
|
||||
const result = safeEntityName('EntityName');
|
||||
expect(result).toBe('entity-name');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -48,3 +48,20 @@ export const isRejected = (
|
||||
export const isFulfilled = <T>(
|
||||
input: PromiseSettledResult<T>,
|
||||
): input is PromiseFulfilledResult<T> => input.status === 'fulfilled';
|
||||
|
||||
/**
|
||||
* Generates a suitable entity name from a package name by slugifying the given package name.
|
||||
*
|
||||
* @param packageName - The package name to generate an entity name from.
|
||||
* @returns The generated entity name, a slugified version of the package name.
|
||||
*/
|
||||
export const safeEntityName = (packageName: string): string => {
|
||||
return packageName
|
||||
.replace(/^[^\w\s]|[^a-z0-9]$/g, '')
|
||||
.replace(/[^A-Za-z0-9_\-.]+/g, '-')
|
||||
.replace(
|
||||
/([a-z])([A-Z])/g,
|
||||
(_, a, b) => `${a}-${b.toLocaleLowerCase('en-US')}`,
|
||||
)
|
||||
.replace(/^(.)/, (_, a) => a.toLocaleLowerCase('en-US'));
|
||||
};
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
## API Report File for "@backstage/plugin-azure-devops"
|
||||
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { BackstagePlugin } from '@backstage/frontend-plugin-api';
|
||||
|
||||
// @alpha (undocumented)
|
||||
const _default: BackstagePlugin<{}, {}>;
|
||||
export default _default;
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
```
|
||||
@@ -5,9 +5,22 @@
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"main": "dist/index.esm.js",
|
||||
"types": "dist/index.d.ts"
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./alpha": "./src/alpha.ts",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"alpha": [
|
||||
"src/alpha.ts"
|
||||
],
|
||||
"package.json": [
|
||||
"package.json"
|
||||
]
|
||||
}
|
||||
},
|
||||
"backstage": {
|
||||
"role": "frontend-plugin"
|
||||
@@ -30,9 +43,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/catalog-model": "workspace:^",
|
||||
"@backstage/core-compat-api": "workspace:^",
|
||||
"@backstage/core-components": "workspace:^",
|
||||
"@backstage/core-plugin-api": "workspace:^",
|
||||
"@backstage/errors": "workspace:^",
|
||||
"@backstage/frontend-plugin-api": "workspace:^",
|
||||
"@backstage/plugin-azure-devops-common": "workspace:^",
|
||||
"@backstage/plugin-catalog-react": "workspace:^",
|
||||
"@material-ui/core": "^4.12.2",
|
||||
|
||||
@@ -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 * from './alpha/index';
|
||||
export { default } from './alpha/index';
|
||||
@@ -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 { default } from './plugin';
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {
|
||||
createApiExtension,
|
||||
createApiFactory,
|
||||
createPageExtension,
|
||||
createPlugin,
|
||||
discoveryApiRef,
|
||||
identityApiRef,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { azureDevOpsApiRef, AzureDevOpsClient } from '../api';
|
||||
import {
|
||||
compatWrapper,
|
||||
convertLegacyRouteRef,
|
||||
} from '@backstage/core-compat-api';
|
||||
import {
|
||||
createEntityCardExtension,
|
||||
createEntityContentExtension,
|
||||
} from '@backstage/plugin-catalog-react/alpha';
|
||||
import { azurePullRequestDashboardRouteRef } from '../routes';
|
||||
|
||||
/** @alpha */
|
||||
export const azureDevOpsApi = createApiExtension({
|
||||
factory: createApiFactory({
|
||||
api: azureDevOpsApiRef,
|
||||
deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef },
|
||||
factory: ({ discoveryApi, identityApi }) =>
|
||||
new AzureDevOpsClient({ discoveryApi, identityApi }),
|
||||
}),
|
||||
});
|
||||
|
||||
/** @alpha */
|
||||
export const azureDevOpsPullRequestPage = createPageExtension({
|
||||
defaultPath: '/azure-pull-requests',
|
||||
routeRef: convertLegacyRouteRef(azurePullRequestDashboardRouteRef),
|
||||
loader: () =>
|
||||
import('../components/PullRequestsPage').then(m =>
|
||||
compatWrapper(<m.PullRequestsPage />),
|
||||
),
|
||||
});
|
||||
|
||||
/** @alpha */
|
||||
export const azureDevOpsPipelinesEntityContent = createEntityContentExtension({
|
||||
name: 'pipelines',
|
||||
defaultPath: '/pipelines',
|
||||
defaultTitle: 'Pipelines',
|
||||
loader: () =>
|
||||
import('../components/EntityPageAzurePipelines').then(m =>
|
||||
compatWrapper(<m.EntityPageAzurePipelines />),
|
||||
),
|
||||
});
|
||||
|
||||
/** @alpha */
|
||||
export const azureDevOpsGitTagsEntityContent = createEntityContentExtension({
|
||||
name: 'git-tags',
|
||||
defaultPath: '/git-tags',
|
||||
defaultTitle: 'Git Tags',
|
||||
loader: () =>
|
||||
import('../components/EntityPageAzureGitTags').then(m =>
|
||||
compatWrapper(<m.EntityPageAzureGitTags />),
|
||||
),
|
||||
});
|
||||
|
||||
/** @alpha */
|
||||
export const azureDevOpsPullRequestsEntityContent =
|
||||
createEntityContentExtension({
|
||||
name: 'pull-requests',
|
||||
defaultPath: '/pull-requests',
|
||||
defaultTitle: 'Pull Requests',
|
||||
loader: () =>
|
||||
import('../components/EntityPageAzurePullRequests').then(m =>
|
||||
compatWrapper(<m.EntityPageAzurePullRequests />),
|
||||
),
|
||||
});
|
||||
|
||||
/** @alpha */
|
||||
export const azureDevOpsReadmeEntityCard = createEntityCardExtension({
|
||||
name: 'readme',
|
||||
loader: async () =>
|
||||
import('../components/ReadmeCard').then(m =>
|
||||
compatWrapper(<m.ReadmeCard />),
|
||||
),
|
||||
});
|
||||
|
||||
/** @alpha */
|
||||
export default createPlugin({
|
||||
id: 'azure-devops',
|
||||
extensions: [
|
||||
azureDevOpsApi,
|
||||
azureDevOpsReadmeEntityCard,
|
||||
azureDevOpsPipelinesEntityContent,
|
||||
azureDevOpsGitTagsEntityContent,
|
||||
azureDevOpsPullRequestsEntityContent,
|
||||
azureDevOpsPullRequestPage,
|
||||
],
|
||||
});
|
||||
@@ -27,8 +27,10 @@ import {
|
||||
} from '@backstage/plugin-permission-common';
|
||||
import {
|
||||
azureSitesActionPermission,
|
||||
azureSitesPermissions,
|
||||
AZURE_WEB_SITE_NAME_ANNOTATION,
|
||||
} from '@backstage/plugin-azure-sites-common';
|
||||
import { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
|
||||
import { AzureSitesApi } from '../api';
|
||||
@@ -47,8 +49,13 @@ export async function createRouter(
|
||||
): Promise<express.Router> {
|
||||
const { logger, azureSitesApi, permissions, catalogApi } = options;
|
||||
|
||||
const permissionIntegrationRouter = createPermissionIntegrationRouter({
|
||||
permissions: azureSitesPermissions,
|
||||
});
|
||||
|
||||
const router = Router();
|
||||
router.use(express.json());
|
||||
router.use(permissionIntegrationRouter);
|
||||
|
||||
router.get('/health', (_, response) => {
|
||||
logger.info('PONG!');
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
|
||||
import { screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { GroupsDiagram } from './GroupsDiagram';
|
||||
|
||||
@@ -55,7 +56,7 @@ describe('<GroupsDiagram />', () => {
|
||||
}),
|
||||
};
|
||||
|
||||
const { getByText } = await renderInTestApp(
|
||||
await renderInTestApp(
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
|
||||
<GroupsDiagram />
|
||||
</TestApiProvider>,
|
||||
@@ -65,6 +66,9 @@ describe('<GroupsDiagram />', () => {
|
||||
},
|
||||
},
|
||||
);
|
||||
expect(getByText('Group A', { selector: 'div' })).toBeInTheDocument();
|
||||
|
||||
expect(
|
||||
screen.getByRole('link', { name: 'group:my-namespace/group-a' }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
GroupEntity,
|
||||
parseEntityRef,
|
||||
RELATION_CHILD_OF,
|
||||
stringifyEntityRef,
|
||||
@@ -31,8 +30,8 @@ import { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api';
|
||||
import {
|
||||
catalogApiRef,
|
||||
entityRouteRef,
|
||||
humanizeEntityRef,
|
||||
getEntityRelations,
|
||||
EntityDisplayName,
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
import { makeStyles, Typography, useTheme } from '@material-ui/core';
|
||||
import ZoomOutMap from '@material-ui/icons/ZoomOutMap';
|
||||
@@ -140,7 +139,9 @@ function RenderNode(props: DependencyGraphTypes.RenderNodeProps<any>) {
|
||||
rx={theme.shape.borderRadius}
|
||||
className={classes.groupNode}
|
||||
/>
|
||||
<title>{props.node.name}</title>
|
||||
<title>
|
||||
<EntityDisplayName entityRef={props.node.id} hideIcon disableTooltip />
|
||||
</title>
|
||||
|
||||
<Link
|
||||
to={catalogEntityRoute({
|
||||
@@ -152,7 +153,7 @@ function RenderNode(props: DependencyGraphTypes.RenderNodeProps<any>) {
|
||||
<foreignObject width={nodeWidth} height={nodeHeight}>
|
||||
<div className={classes.centeredContent}>
|
||||
<div className={classNames(classes.textWrapper, classes.textGroup)}>
|
||||
{props.node.name}
|
||||
<EntityDisplayName entityRef={props.node.id} hideIcon />
|
||||
</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
@@ -210,9 +211,7 @@ export function GroupsDiagram(props: {
|
||||
nodes.push({
|
||||
id: stringifyEntityRef(catalogItem),
|
||||
kind: catalogItem.kind,
|
||||
name:
|
||||
(catalogItem as GroupEntity).spec?.profile?.displayName ||
|
||||
humanizeEntityRef(catalogItem, { defaultKind: 'Group' }),
|
||||
name: '',
|
||||
});
|
||||
|
||||
// Edge to parent
|
||||
|
||||
+12
-10
@@ -17,7 +17,7 @@
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react';
|
||||
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
|
||||
import { waitFor } from '@testing-library/react';
|
||||
import { waitFor, screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { GroupsExplorerContent } from '../GroupsExplorerContent';
|
||||
|
||||
@@ -73,24 +73,24 @@ describe('<GroupsExplorerContent />', () => {
|
||||
];
|
||||
catalogApi.getEntities.mockResolvedValue({ items: entities });
|
||||
|
||||
const { getByText } = await renderInTestApp(
|
||||
await renderInTestApp(
|
||||
<Wrapper>
|
||||
<GroupsExplorerContent />
|
||||
</Wrapper>,
|
||||
mountedRoutes,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
await waitFor(() =>
|
||||
expect(
|
||||
getByText('my-namespace/group-a', { selector: 'div' }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
screen.getByRole('link', { name: 'group:my-namespace/group-a' }),
|
||||
).toBeInTheDocument(),
|
||||
);
|
||||
});
|
||||
|
||||
it('renders a custom title', async () => {
|
||||
catalogApi.getEntities.mockResolvedValue({ items: [] });
|
||||
|
||||
const { getByText } = await renderInTestApp(
|
||||
await renderInTestApp(
|
||||
<Wrapper>
|
||||
<GroupsExplorerContent title="Our Teams" />
|
||||
</Wrapper>,
|
||||
@@ -98,7 +98,9 @@ describe('<GroupsExplorerContent />', () => {
|
||||
);
|
||||
|
||||
await waitFor(() =>
|
||||
expect(getByText('Our Teams', { selector: 'h2' })).toBeInTheDocument(),
|
||||
expect(
|
||||
screen.getByText('Our Teams', { selector: 'h2' }),
|
||||
).toBeInTheDocument(),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -106,7 +108,7 @@ describe('<GroupsExplorerContent />', () => {
|
||||
const catalogError = new Error('Network timeout');
|
||||
catalogApi.getEntities.mockRejectedValueOnce(catalogError);
|
||||
|
||||
const { getAllByText } = await renderInTestApp(
|
||||
await renderInTestApp(
|
||||
<Wrapper>
|
||||
<GroupsExplorerContent />
|
||||
</Wrapper>,
|
||||
@@ -114,7 +116,7 @@ describe('<GroupsExplorerContent />', () => {
|
||||
);
|
||||
|
||||
await waitFor(() =>
|
||||
expect(getAllByText(/Error: Network timeout/).length).not.toBe(0),
|
||||
expect(screen.getAllByText(/Error: Network timeout/).length).not.toBe(0),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -358,12 +358,11 @@ describe('TemplateCard', () => {
|
||||
},
|
||||
);
|
||||
|
||||
expect(
|
||||
getByRole('link', { name: 'group:default/my-test-user' }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
getByRole('link', { name: 'group:default/my-test-user' }),
|
||||
).toHaveAttribute('href', '/catalog/group/default/my-test-user');
|
||||
expect(getByRole('link', { name: /.*my-test-user$/ })).toBeInTheDocument();
|
||||
expect(getByRole('link', { name: /.*my-test-user$/ })).toHaveAttribute(
|
||||
'href',
|
||||
'/catalog/group/default/my-test-user',
|
||||
);
|
||||
});
|
||||
|
||||
it('should call the onSelected handler when clicking the choose button', async () => {
|
||||
|
||||
@@ -101,16 +101,20 @@ export const ProviderSettingsItem = (props: {
|
||||
<Grid item xs={12} sm container>
|
||||
<Grid item xs container direction="column" spacing={2}>
|
||||
<Grid item xs>
|
||||
<Typography
|
||||
variant="subtitle1"
|
||||
color="textPrimary"
|
||||
gutterBottom
|
||||
>
|
||||
{profile.displayName}
|
||||
</Typography>
|
||||
<Typography variant="body2" color="textSecondary">
|
||||
{profile.email}
|
||||
</Typography>
|
||||
{profile.displayName && (
|
||||
<Typography
|
||||
variant="subtitle1"
|
||||
color="textPrimary"
|
||||
gutterBottom
|
||||
>
|
||||
{profile.displayName}
|
||||
</Typography>
|
||||
)}
|
||||
{profile.email && (
|
||||
<Typography variant="body2" color="textSecondary">
|
||||
{profile.email}
|
||||
</Typography>
|
||||
)}
|
||||
<Typography variant="body2" color="textSecondary">
|
||||
{description}
|
||||
</Typography>
|
||||
|
||||
@@ -5052,10 +5052,12 @@ __metadata:
|
||||
dependencies:
|
||||
"@backstage/catalog-model": "workspace:^"
|
||||
"@backstage/cli": "workspace:^"
|
||||
"@backstage/core-compat-api": "workspace:^"
|
||||
"@backstage/core-components": "workspace:^"
|
||||
"@backstage/core-plugin-api": "workspace:^"
|
||||
"@backstage/dev-utils": "workspace:^"
|
||||
"@backstage/errors": "workspace:^"
|
||||
"@backstage/frontend-plugin-api": "workspace:^"
|
||||
"@backstage/plugin-azure-devops-common": "workspace:^"
|
||||
"@backstage/plugin-catalog-react": "workspace:^"
|
||||
"@backstage/test-utils": "workspace:^"
|
||||
@@ -29841,12 +29843,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"husky@npm:^8.0.0":
|
||||
version: 8.0.3
|
||||
resolution: "husky@npm:8.0.3"
|
||||
"husky@npm:^9.0.0":
|
||||
version: 9.0.10
|
||||
resolution: "husky@npm:9.0.10"
|
||||
bin:
|
||||
husky: lib/bin.js
|
||||
checksum: 837bc7e4413e58c1f2946d38fb050f5d7324c6f16b0fd66411ffce5703b294bd21429e8ba58711cd331951ee86ed529c5be4f76805959ff668a337dbfa82a1b0
|
||||
husky: bin.mjs
|
||||
checksum: 55f4b6db6706ff0bc181607d6a64f55310cbb18b4d7db2a5b85608c87a80abafc14ac3a8c4d0b44d6272f4a62d4c2d3d5491d6a13e2cc7ac4895309e5e5f0ec2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -40405,7 +40407,7 @@ __metadata:
|
||||
eslint-plugin-react: ^7.28.0
|
||||
eslint-plugin-testing-library: ^6.0.0
|
||||
fs-extra: 10.1.0
|
||||
husky: ^8.0.0
|
||||
husky: ^9.0.0
|
||||
lint-staged: ^15.0.0
|
||||
minimist: ^1.2.5
|
||||
node-gyp: ^10.0.0
|
||||
|
||||
Reference in New Issue
Block a user