diff --git a/plugins/explore/api-report.md b/plugins/explore/api-report.md index d7bafb7ee0..27748aa8c5 100644 --- a/plugins/explore/api-report.md +++ b/plugins/explore/api-report.md @@ -9,6 +9,7 @@ import { ApiRef } from '@backstage/core-plugin-api'; import { BackstagePlugin } from '@backstage/core-plugin-api'; import { default as default_2 } from 'react'; import { DiscoveryApi } from '@backstage/core-plugin-api'; +import { DomainEntity } from '@backstage/catalog-model'; import { ExploreToolsConfig } from '@backstage/plugin-explore-react'; import { ExternalRouteRef } from '@backstage/core-plugin-api'; import { FetchApi } from '@backstage/core-plugin-api'; @@ -32,14 +33,17 @@ export const catalogEntityRouteRef: ExternalRouteRef< >; // @public (undocumented) -export const DomainExplorerContent: (props: { - title?: string | undefined; +export const CatalogKindExploreContent: (props: { + tabTitle?: string; + kind: string; }) => JSX.Element; // @public (undocumented) -export const EntityExplorerContent: (props: { - tabTitle?: string; - kind: string; +export const DomainCard: (props: { entity: DomainEntity }) => JSX.Element; + +// @public (undocumented) +export const DomainExplorerContent: (props: { + title?: string | undefined; }) => JSX.Element; // @public diff --git a/plugins/explore/package.json b/plugins/explore/package.json index d14a276ecc..2f5cad2244 100644 --- a/plugins/explore/package.json +++ b/plugins/explore/package.json @@ -46,7 +46,8 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", "classnames": "^2.2.6", - "react-use": "^17.2.4" + "react-use": "^17.2.4", + "pluralize": "^8.0.0" }, "peerDependencies": { "@types/react": "^16.13.1 || ^17.0.0", diff --git a/plugins/explore/src/components/CatalogKindExploreContent/CatalogKindExploreContent.test.tsx b/plugins/explore/src/components/CatalogKindExploreContent/CatalogKindExploreContent.test.tsx index 4670a10855..6075561ff1 100644 --- a/plugins/explore/src/components/CatalogKindExploreContent/CatalogKindExploreContent.test.tsx +++ b/plugins/explore/src/components/CatalogKindExploreContent/CatalogKindExploreContent.test.tsx @@ -19,9 +19,9 @@ import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react'; import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; import { waitFor } from '@testing-library/react'; import React from 'react'; -import { EntityExplorerContent } from './EntityExplorerContent'; +import { CatalogKindExploreContent } from './CatalogKindExploreContent'; -describe('', () => { +describe('', () => { const catalogApi = { addLocation: jest.fn(), getEntities: jest.fn(), @@ -79,7 +79,7 @@ describe('', () => { const { getByText } = await renderInTestApp( - + , mountedRoutes, ); @@ -95,7 +95,7 @@ describe('', () => { const { getByText } = await renderInTestApp( - + , mountedRoutes, ); @@ -108,7 +108,7 @@ describe('', () => { const { getByText } = await renderInTestApp( - + , mountedRoutes, ); @@ -124,7 +124,7 @@ describe('', () => { const { getByText } = await renderInTestApp( - + , mountedRoutes, ); diff --git a/plugins/explore/src/components/CatalogKindExploreContent/CatalogKindExploreContent.tsx b/plugins/explore/src/components/CatalogKindExploreContent/CatalogKindExploreContent.tsx index 55ef13d98e..f3f4ccd103 100644 --- a/plugins/explore/src/components/CatalogKindExploreContent/CatalogKindExploreContent.tsx +++ b/plugins/explore/src/components/CatalogKindExploreContent/CatalogKindExploreContent.tsx @@ -30,10 +30,11 @@ import { WarningPanel, } from '@backstage/core-components'; import { useApi } from '@backstage/core-plugin-api'; +import pluralize from 'pluralize'; const Body = (props: { kind: string }) => { const { kind } = props; - const kindPlural = `${kind}s`; + const kindPlural = pluralize(kind); const catalogApi = useApi(catalogApiRef); const { value: entities, @@ -44,7 +45,7 @@ const Body = (props: { kind: string }) => { filter: { kind }, }); return response.items as Entity[]; - }, [catalogApi]); + }, [kind]); if (loading) { return ; @@ -87,23 +88,21 @@ const Body = (props: { kind: string }) => { }; /** @public */ -export const EntityExplorerContent = (props: { +export const CatalogKindExploreContent = (props: { tabTitle?: string; kind: string; }) => { const { kind, tabTitle } = props; + const kindLowercase = kind.toLocaleLowerCase(); + const kindCapitalized = `${kind[0].toLocaleUpperCase()}${kind.substring(1)}`; return ( - + - Discover the {kind.toLocaleLowerCase()}s in your ecosystem. + Discover the {pluralize(kindLowercase)} in your ecosystem. - + ); }; diff --git a/plugins/explore/src/components/CatalogKindExploreContent/index.ts b/plugins/explore/src/components/CatalogKindExploreContent/index.ts index ab06193939..af4cafae62 100644 --- a/plugins/explore/src/components/CatalogKindExploreContent/index.ts +++ b/plugins/explore/src/components/CatalogKindExploreContent/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export { EntityExplorerContent } from './EntityExplorerContent'; +export { CatalogKindExploreContent } from './CatalogKindExploreContent'; diff --git a/plugins/explore/src/components/DefaultExplorePage/DefaultExplorePage.tsx b/plugins/explore/src/components/DefaultExplorePage/DefaultExplorePage.tsx index 49a79f5143..689da217fe 100644 --- a/plugins/explore/src/components/DefaultExplorePage/DefaultExplorePage.tsx +++ b/plugins/explore/src/components/DefaultExplorePage/DefaultExplorePage.tsx @@ -19,7 +19,7 @@ import { ExploreLayout } from '../ExploreLayout'; import { GroupsExplorerContent } from '../GroupsExplorerContent'; import { ToolExplorerContent } from '../ToolExplorerContent'; import { configApiRef, useApi } from '@backstage/core-plugin-api'; -import { EntityExplorerContent } from '../EntityExplorerContent'; +import { CatalogKindExploreContent } from '../CatalogKindExploreContent'; export const DefaultExplorePage = () => { const configApi = useApi(configApiRef); @@ -32,10 +32,10 @@ export const DefaultExplorePage = () => { subtitle="Discover solutions available in your ecosystem" > - + - + diff --git a/plugins/explore/src/components/DomainCard/DomainCard.test.tsx b/plugins/explore/src/components/DomainCard/DomainCard.test.tsx index eb2f165350..1e4b9b30f1 100644 --- a/plugins/explore/src/components/DomainCard/DomainCard.test.tsx +++ b/plugins/explore/src/components/DomainCard/DomainCard.test.tsx @@ -1,3 +1,57 @@ +/* + * 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 { DomainEntity } from '@backstage/catalog-model'; +import { entityRouteRef } from '@backstage/plugin-catalog-react'; +import { renderInTestApp } from '@backstage/test-utils'; +import React from 'react'; +import { DomainCard } from './DomainCard'; + +describe('', () => { + it('renders a domain card', async () => { + const entity: DomainEntity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Domain', + metadata: { + name: 'artists', + description: 'Everything about artists', + tags: ['a-tag'], + }, + spec: { + owner: 'guest', + }, + }; + const { getByText } = await renderInTestApp( + , + { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, + }, + ); + + expect(getByText('artists')).toBeInTheDocument(); + expect(getByText('Everything about artists')).toBeInTheDocument(); + expect(getByText('a-tag')).toBeInTheDocument(); + expect(getByText('Explore').parentElement).toHaveAttribute( + 'href', + '/catalog/default/domain/artists', + ); + }); +}); /* * Copyright 2023 The Backstage Authors * diff --git a/plugins/explore/src/components/DomainCard/DomainCard.tsx b/plugins/explore/src/components/DomainCard/DomainCard.tsx index eb2f165350..867109f03c 100644 --- a/plugins/explore/src/components/DomainCard/DomainCard.tsx +++ b/plugins/explore/src/components/DomainCard/DomainCard.tsx @@ -1,3 +1,78 @@ +/* + * 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 { DomainEntity, RELATION_OWNED_BY } from '@backstage/catalog-model'; +import { + EntityRefLinks, + entityRouteParams, + getEntityRelations, + entityRouteRef, +} from '@backstage/plugin-catalog-react'; +import { + Box, + Card, + CardActions, + CardContent, + CardMedia, + Chip, +} from '@material-ui/core'; +import React from 'react'; + +import { LinkButton, ItemCardHeader } from '@backstage/core-components'; +import { useRouteRef } from '@backstage/core-plugin-api'; + +/** @public */ +export const DomainCard = (props: { entity: DomainEntity }) => { + const { entity } = props; + + const catalogEntityRoute = useRouteRef(entityRouteRef); + const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY); + const url = catalogEntityRoute(entityRouteParams(entity)); + + const owner = ( + + ); + + return ( + + + + + + {entity.metadata.tags?.length ? ( + + {entity.metadata.tags.map(tag => ( + + ))} + + ) : null} + {entity.metadata.description} + + + + Explore + + + + ); +}; /* * Copyright 2023 The Backstage Authors * diff --git a/plugins/explore/src/components/DomainCard/index.ts b/plugins/explore/src/components/DomainCard/index.ts index eb2f165350..47870e5645 100644 --- a/plugins/explore/src/components/DomainCard/index.ts +++ b/plugins/explore/src/components/DomainCard/index.ts @@ -1,3 +1,20 @@ +/* + * 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 { DomainCard } from './DomainCard'; /* * Copyright 2023 The Backstage Authors * diff --git a/plugins/explore/src/components/EntityCard/EntityCard.test.tsx b/plugins/explore/src/components/EntityCard/EntityCard.test.tsx index ccf5deb875..4b006e347f 100644 --- a/plugins/explore/src/components/EntityCard/EntityCard.test.tsx +++ b/plugins/explore/src/components/EntityCard/EntityCard.test.tsx @@ -14,15 +14,15 @@ * limitations under the License. */ -import { DomainEntity } from '@backstage/catalog-model'; +import { Entity } from '@backstage/catalog-model'; import { entityRouteRef } from '@backstage/plugin-catalog-react'; import { renderInTestApp } from '@backstage/test-utils'; import React from 'react'; import { EntityCard } from './EntityCard'; describe('', () => { - it('renders a domain card', async () => { - const entity: DomainEntity = { + it('renders an entity card', async () => { + const entity: Entity = { apiVersion: 'backstage.io/v1alpha1', kind: 'Domain', metadata: { diff --git a/plugins/explore/src/components/index.ts b/plugins/explore/src/components/index.ts index e2f7810216..b3aa82bc79 100644 --- a/plugins/explore/src/components/index.ts +++ b/plugins/explore/src/components/index.ts @@ -14,5 +14,6 @@ * limitations under the License. */ -export * from './EntityExplorerContent'; +export * from './CatalogKindExploreContent'; export * from './ExploreLayout'; +export * from './DomainCard';