From 4b8e2c25096c69c37af19b36a0664d4fcbc20e83 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 20 Feb 2025 16:15:27 +0100 Subject: [PATCH] catalog-react: rename EntityCardLayout to EntityContentLayout Signed-off-by: Patrik Oldsberg --- .changeset/ninety-teachers-tease.md | 14 +- packages/app-next/app-config.yaml | 2 +- packages/app-next/src/EntityPages.tsx | 8 +- plugins/catalog-react/report-alpha.api.md | 134 +++++++++--------- ...t.tsx => EntityContentLayoutBlueprint.tsx} | 12 +- .../src/alpha/blueprints/index.ts | 6 +- plugins/catalog/report-alpha.api.md | 6 +- .../catalog/src/alpha/entityContents.test.tsx | 4 +- plugins/catalog/src/alpha/entityContents.tsx | 22 +-- 9 files changed, 106 insertions(+), 102 deletions(-) rename plugins/catalog-react/src/alpha/blueprints/{EntityCardLauyoutBlueprint.tsx => EntityContentLayoutBlueprint.tsx} (87%) diff --git a/.changeset/ninety-teachers-tease.md b/.changeset/ninety-teachers-tease.md index 5cc34b6503..73d6dbba8a 100644 --- a/.changeset/ninety-teachers-tease.md +++ b/.changeset/ninety-teachers-tease.md @@ -2,7 +2,7 @@ '@backstage/plugin-catalog-react': minor --- -Introduces a new `EntityCardLayoutBlueprint` that creates custom entity content layouts. +Introduces a new `EntityContentLayoutBlueprint` that creates custom entity content layouts. The layout components receive card elements and can render them as they see fit. Cards is an array of objects with the following properties: @@ -15,12 +15,12 @@ Creating a custom overview tab layout: ```tsx import { - EntityCardLayoutProps, - EntityCardLayoutBlueprint, + EntityContentLayoutProps, + EntityContentLayoutBlueprint, } from '@backstage/plugin-catalog-react/alpha'; // ... -function StickyEntityContentOverviewLayout(props: EntityCardLayoutProps) { +function StickyEntityContentOverviewLayout(props: EntityContentLayoutProps) { const { cards } = props; const classes = useStyles(); return ( @@ -66,7 +66,7 @@ function StickyEntityContentOverviewLayout(props: EntityCardLayoutProps) { export const customEntityContentOverviewStickyLayoutModule = createFrontendModule({ pluginId: 'app', extensions: [ - EntityCardLayoutBlueprint.make({ + EntityContentLayoutBlueprint.make({ name: 'sticky', params: { // (optional) defaults the `() => false` filter function @@ -83,7 +83,7 @@ Disabling the custom layout: # app-config.yaml app: extensions: - - entity-card-layout:app/sticky: false + - entity-content-layout:app/sticky: false ``` Overriding the custom layout filter: @@ -92,7 +92,7 @@ Overriding the custom layout filter: # app-config.yaml app: extensions: - - entity-card-layout:app/sticky: + - entity-content-layout:app/sticky: config: # This layout will be used only with component entities filter: 'kind:component' diff --git a/packages/app-next/app-config.yaml b/packages/app-next/app-config.yaml index c814d8b8a7..d3da847c6a 100644 --- a/packages/app-next/app-config.yaml +++ b/packages/app-next/app-config.yaml @@ -71,7 +71,7 @@ app: # - entity-content:azure-devops/pull-requests # - entity-content:azure-devops/git-tags - - entity-card-layout:app/sticky: + - entity-content-layout:app/sticky: config: # this layout will apply to entities of kind component filter: 'kind:component' diff --git a/packages/app-next/src/EntityPages.tsx b/packages/app-next/src/EntityPages.tsx index 13c6895187..45e67e2e1d 100644 --- a/packages/app-next/src/EntityPages.tsx +++ b/packages/app-next/src/EntityPages.tsx @@ -18,8 +18,8 @@ import React from 'react'; import Grid from '@material-ui/core/Grid'; import { createFrontendModule } from '@backstage/frontend-plugin-api'; import { - EntityCardLayoutBlueprint, - EntityCardLayoutProps, + EntityContentLayoutBlueprint, + EntityContentLayoutProps, } from '@backstage/plugin-catalog-react/alpha'; import { makeStyles } from '@material-ui/core/styles'; @@ -38,7 +38,7 @@ const useStyles = makeStyles(theme => ({ }, })); -function StickyEntityContentOverviewLayout(props: EntityCardLayoutProps) { +function StickyEntityContentOverviewLayout(props: EntityContentLayoutProps) { const { cards } = props; const classes = useStyles(); return ( @@ -89,7 +89,7 @@ function StickyEntityContentOverviewLayout(props: EntityCardLayoutProps) { export const customEntityContentOverviewLayoutModule = createFrontendModule({ pluginId: 'app', extensions: [ - EntityCardLayoutBlueprint.make({ + EntityContentLayoutBlueprint.make({ name: 'sticky', params: { loader: async () => StickyEntityContentOverviewLayout, diff --git a/plugins/catalog-react/report-alpha.api.md b/plugins/catalog-react/report-alpha.api.md index e23d518c1f..d44dbae7c0 100644 --- a/plugins/catalog-react/report-alpha.api.md +++ b/plugins/catalog-react/report-alpha.api.md @@ -170,73 +170,6 @@ export const EntityCardBlueprint: ExtensionBlueprint<{ }; }>; -// @alpha (undocumented) -export const EntityCardLayoutBlueprint: ExtensionBlueprint<{ - kind: 'entity-card-layout'; - name: undefined; - params: { - filter?: string | ((entity: Entity) => boolean) | undefined; - loader: () => Promise< - (props: EntityCardLayoutProps) => React_2.JSX.Element - >; - }; - output: - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - (props: EntityCardLayoutProps) => React_2.JSX.Element, - 'catalog.entity-card-layout.component', - {} - >; - inputs: {}; - config: { - area: string | undefined; - filter: string | undefined; - }; - configInput: { - filter?: string | undefined; - area?: string | undefined; - }; - dataRefs: { - filterFunction: ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - {} - >; - filterExpression: ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - {} - >; - component: ConfigurableExtensionDataRef< - (props: EntityCardLayoutProps) => React_2.JSX.Element, - 'catalog.entity-card-layout.component', - {} - >; - }; -}>; - -// @alpha (undocumented) -export interface EntityCardLayoutProps { - // (undocumented) - cards: Array<{ - area?: (typeof defaultEntityCardAreas)[number]; - element: React_2.JSX.Element; - }>; -} - // @alpha export const EntityContentBlueprint: ExtensionBlueprint<{ kind: 'entity-content'; @@ -324,6 +257,73 @@ export const EntityContentBlueprint: ExtensionBlueprint<{ }; }>; +// @alpha (undocumented) +export const EntityContentLayoutBlueprint: ExtensionBlueprint<{ + kind: 'entity-content-layout'; + name: undefined; + params: { + filter?: string | ((entity: Entity) => boolean) | undefined; + loader: () => Promise< + (props: EntityContentLayoutProps) => React_2.JSX.Element + >; + }; + output: + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + (props: EntityContentLayoutProps) => React_2.JSX.Element, + 'catalog.entity-content-layout.component', + {} + >; + inputs: {}; + config: { + area: string | undefined; + filter: string | undefined; + }; + configInput: { + filter?: string | undefined; + area?: string | undefined; + }; + dataRefs: { + filterFunction: ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + {} + >; + filterExpression: ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + {} + >; + component: ConfigurableExtensionDataRef< + (props: EntityContentLayoutProps) => React_2.JSX.Element, + 'catalog.entity-content-layout.component', + {} + >; + }; +}>; + +// @alpha (undocumented) +export interface EntityContentLayoutProps { + // (undocumented) + cards: Array<{ + area?: (typeof defaultEntityCardAreas)[number]; + element: React_2.JSX.Element; + }>; +} + // @alpha export function isOwnerOf(owner: Entity, entity: Entity): boolean; diff --git a/plugins/catalog-react/src/alpha/blueprints/EntityCardLauyoutBlueprint.tsx b/plugins/catalog-react/src/alpha/blueprints/EntityContentLayoutBlueprint.tsx similarity index 87% rename from plugins/catalog-react/src/alpha/blueprints/EntityCardLauyoutBlueprint.tsx rename to plugins/catalog-react/src/alpha/blueprints/EntityContentLayoutBlueprint.tsx index 5c5a3b5ac4..6b5f84e0dd 100644 --- a/plugins/catalog-react/src/alpha/blueprints/EntityCardLauyoutBlueprint.tsx +++ b/plugins/catalog-react/src/alpha/blueprints/EntityContentLayoutBlueprint.tsx @@ -27,7 +27,7 @@ import { import React from 'react'; /** @alpha */ -export interface EntityCardLayoutProps { +export interface EntityContentLayoutProps { cards: Array<{ area?: (typeof defaultEntityCardAreas)[number]; element: React.JSX.Element; @@ -35,14 +35,14 @@ export interface EntityCardLayoutProps { } const entityCardLayoutComponentDataRef = createExtensionDataRef< - (props: EntityCardLayoutProps) => React.JSX.Element + (props: EntityContentLayoutProps) => React.JSX.Element >().with({ - id: 'catalog.entity-card-layout.component', + id: 'catalog.entity-content-layout.component', }); /** @alpha */ -export const EntityCardLayoutBlueprint = createExtensionBlueprint({ - kind: 'entity-card-layout', +export const EntityContentLayoutBlueprint = createExtensionBlueprint({ + kind: 'entity-content-layout', attachTo: { id: 'entity-content:catalog/overview', input: 'layouts' }, output: [ entityFilterFunctionDataRef.optional(), @@ -69,7 +69,7 @@ export const EntityCardLayoutBlueprint = createExtensionBlueprint({ | typeof entityFilterFunctionDataRef.T | typeof entityFilterExpressionDataRef.T; loader: () => Promise< - (props: EntityCardLayoutProps) => React.JSX.Element + (props: EntityContentLayoutProps) => React.JSX.Element >; }, { node, config }, diff --git a/plugins/catalog-react/src/alpha/blueprints/index.ts b/plugins/catalog-react/src/alpha/blueprints/index.ts index bda94c8d04..a9d00123c4 100644 --- a/plugins/catalog-react/src/alpha/blueprints/index.ts +++ b/plugins/catalog-react/src/alpha/blueprints/index.ts @@ -16,9 +16,9 @@ export { EntityCardBlueprint } from './EntityCardBlueprint'; export { EntityContentBlueprint } from './EntityContentBlueprint'; export { - EntityCardLayoutBlueprint, - type EntityCardLayoutProps, -} from './EntityCardLauyoutBlueprint'; + EntityContentLayoutBlueprint, + type EntityContentLayoutProps, +} from './EntityContentLayoutBlueprint'; export { defaultEntityContentGroups, defaultEntityCardAreas, diff --git a/plugins/catalog/report-alpha.api.md b/plugins/catalog/report-alpha.api.md index a00d508bcc..498702e035 100644 --- a/plugins/catalog/report-alpha.api.md +++ b/plugins/catalog/report-alpha.api.md @@ -10,7 +10,7 @@ import { AnyExtensionDataRef } from '@backstage/frontend-plugin-api'; import { AnyRouteRefParams } from '@backstage/frontend-plugin-api'; import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { Entity } from '@backstage/catalog-model'; -import { EntityCardLayoutProps } from '@backstage/plugin-catalog-react/alpha'; +import { EntityContentLayoutProps } from '@backstage/plugin-catalog-react/alpha'; import { ExtensionBlueprint } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { ExtensionInput } from '@backstage/frontend-plugin-api'; @@ -689,8 +689,8 @@ const _default: FrontendPlugin< } > | ConfigurableExtensionDataRef< - (props: EntityCardLayoutProps) => JSX_2.Element, - 'catalog.entity-card-layout.component', + (props: EntityContentLayoutProps) => JSX_2.Element, + 'catalog.entity-content-layout.component', {} >, { diff --git a/plugins/catalog/src/alpha/entityContents.test.tsx b/plugins/catalog/src/alpha/entityContents.test.tsx index 5dfdca9d73..4821cc0179 100644 --- a/plugins/catalog/src/alpha/entityContents.test.tsx +++ b/plugins/catalog/src/alpha/entityContents.test.tsx @@ -25,7 +25,7 @@ import { import { catalogOverviewEntityContent } from './entityContents'; import { EntityCardBlueprint, - EntityCardLayoutBlueprint, + EntityContentLayoutBlueprint, } from '@backstage/plugin-catalog-react/alpha'; import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils'; import { @@ -125,7 +125,7 @@ describe('Overview content', () => { }, }); - const customLayout = EntityCardLayoutBlueprint.make({ + const customLayout = EntityContentLayoutBlueprint.make({ name: 'custom-layout', params: { loader: diff --git a/plugins/catalog/src/alpha/entityContents.tsx b/plugins/catalog/src/alpha/entityContents.tsx index 7ad209ec39..1f4a670e2b 100644 --- a/plugins/catalog/src/alpha/entityContents.tsx +++ b/plugins/catalog/src/alpha/entityContents.tsx @@ -23,8 +23,8 @@ import { import { EntityCardBlueprint, EntityContentBlueprint, - EntityCardLayoutBlueprint, - EntityCardLayoutProps, + EntityContentLayoutBlueprint, + EntityContentLayoutProps, } from '@backstage/plugin-catalog-react/alpha'; import { buildFilterFn } from './filter/FilterWrapper'; import { useEntity } from '@backstage/plugin-catalog-react'; @@ -34,9 +34,9 @@ export const catalogOverviewEntityContent = name: 'overview', inputs: { layouts: createExtensionInput([ - EntityCardLayoutBlueprint.dataRefs.filterFunction.optional(), - EntityCardLayoutBlueprint.dataRefs.filterExpression.optional(), - EntityCardLayoutBlueprint.dataRefs.component, + EntityContentLayoutBlueprint.dataRefs.filterFunction.optional(), + EntityContentLayoutBlueprint.dataRefs.filterExpression.optional(), + EntityContentLayoutBlueprint.dataRefs.component, ]), cards: createExtensionInput([ coreExtensionData.reactElement, @@ -56,7 +56,7 @@ export const catalogOverviewEntityContent = })), ); - const DefaultLayoutComponent = (props: EntityCardLayoutProps) => { + const DefaultLayoutComponent = (props: EntityContentLayoutProps) => { return ( @@ -67,11 +67,15 @@ export const catalogOverviewEntityContent = const layouts = [ ...inputs.layouts.map(layout => ({ filter: buildFilterFn( - layout.get(EntityCardLayoutBlueprint.dataRefs.filterFunction), - layout.get(EntityCardLayoutBlueprint.dataRefs.filterExpression), + layout.get( + EntityContentLayoutBlueprint.dataRefs.filterFunction, + ), + layout.get( + EntityContentLayoutBlueprint.dataRefs.filterExpression, + ), ), Component: layout.get( - EntityCardLayoutBlueprint.dataRefs.component, + EntityContentLayoutBlueprint.dataRefs.component, ), })), {