From 8341f989405b3d3617fffe210793e390fa5b5d3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Sat, 18 Apr 2026 22:32:54 +0200 Subject: [PATCH 1/3] Simplify OwnerEntityColumn to use EntityRefLink directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the catalog API lookup and manual title resolution. The EntityRefLink already uses the entity presentation API to resolve display names, so the component only needs the entity ref string. This removes unused imports of useApi, useAsync, catalogApiRef, parseEntityRef, and UserEntity. Signed-off-by: Fredrik Adelöw Made-with: Cursor --- .../columns/OwnerEntityColumn.test.tsx | 62 +++++++------------ .../columns/OwnerEntityColumn.tsx | 30 +-------- 2 files changed, 24 insertions(+), 68 deletions(-) diff --git a/plugins/scaffolder/src/components/ListTasksPage/columns/OwnerEntityColumn.test.tsx b/plugins/scaffolder/src/components/ListTasksPage/columns/OwnerEntityColumn.test.tsx index 2cc069af5d..5720bfd5b4 100644 --- a/plugins/scaffolder/src/components/ListTasksPage/columns/OwnerEntityColumn.test.tsx +++ b/plugins/scaffolder/src/components/ListTasksPage/columns/OwnerEntityColumn.test.tsx @@ -14,48 +14,15 @@ * limitations under the License. */ -import { Entity } from '@backstage/catalog-model'; -import { - renderInTestApp, - TestApiProvider, - mockApis, -} from '@backstage/test-utils'; -import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react'; -import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils'; +import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; +import { entityRouteRef } from '@backstage/plugin-catalog-react'; import { OwnerEntityColumn } from './OwnerEntityColumn'; -import { identityApiRef } from '@backstage/core-plugin-api'; describe('', () => { - const catalogApi = catalogApiMock.mock(); - const identityApi = mockApis.identity(); - - it('should render the column with the user', async () => { - const props = { - entityRef: 'user:default/foo', - }; - - const entity: Entity = { - apiVersion: 'v1', - kind: 'User', - metadata: { - name: 'test', - }, - spec: { - profile: { - displayName: 'BackUser', - }, - }, - }; - catalogApi.getEntityByRef.mockResolvedValue(entity); - - const { getByText, getByRole } = await renderInTestApp( - - + it('should render a link to the user entity', async () => { + const { getByRole } = await renderInTestApp( + + , { mountedRoutes: { @@ -68,7 +35,20 @@ describe('', () => { 'href', '/catalog/default/user/foo', ); - const text = getByText('BackUser'); - expect(text).toBeDefined(); + }); + + it('should render Unknown when entityRef is missing', async () => { + const { getByText } = await renderInTestApp( + + + , + { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, + }, + ); + + expect(getByText('Unknown')).toBeInTheDocument(); }); }); diff --git a/plugins/scaffolder/src/components/ListTasksPage/columns/OwnerEntityColumn.tsx b/plugins/scaffolder/src/components/ListTasksPage/columns/OwnerEntityColumn.tsx index a6d53d2ea1..6c1ca0bde9 100644 --- a/plugins/scaffolder/src/components/ListTasksPage/columns/OwnerEntityColumn.tsx +++ b/plugins/scaffolder/src/components/ListTasksPage/columns/OwnerEntityColumn.tsx @@ -13,37 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { useApi } from '@backstage/core-plugin-api'; - -import useAsync from 'react-use/esm/useAsync'; - -import { catalogApiRef, EntityRefLink } from '@backstage/plugin-catalog-react'; -import { parseEntityRef, UserEntity } from '@backstage/catalog-model'; +import { EntityRefLink } from '@backstage/plugin-catalog-react'; import Typography from '@material-ui/core/Typography'; export const OwnerEntityColumn = ({ entityRef }: { entityRef?: string }) => { - const catalogApi = useApi(catalogApiRef); - - const { value, loading, error } = useAsync( - () => catalogApi.getEntityByRef(entityRef || ''), - [catalogApi, entityRef], - ); - if (!entityRef) { - return Unknown; + return Unknown; } - if (loading || error) { - return null; - } - - return ( - - ); + return ; }; From 415e30b489cfd52c01dfbf8b503884e10ee04418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Sat, 18 Apr 2026 22:33:41 +0200 Subject: [PATCH 2/3] Add changeset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw Made-with: Cursor --- .changeset/owner-column-cleanup.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/owner-column-cleanup.md diff --git a/.changeset/owner-column-cleanup.md b/.changeset/owner-column-cleanup.md new file mode 100644 index 0000000000..709f74f781 --- /dev/null +++ b/.changeset/owner-column-cleanup.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Simplified the `OwnerEntityColumn` in the task list to rely on `EntityRefLink` and the entity presentation API instead of manually fetching entities from the catalog. From 83ac69be864848c5b4b6210497ecceefe5fe5b48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Sat, 18 Apr 2026 22:50:30 +0200 Subject: [PATCH 3/3] Fix ListTaskPage test to match simplified OwnerEntityColumn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update assertions to expect the entity presentation short ref (e.g. 'foo') instead of the old catalog-resolved display name (e.g. 'BackUser'), and remove now-unused entity fixtures and catalog API mocking. Signed-off-by: Fredrik Adelöw Made-with: Cursor --- .../ListTasksPage/ListTaskPage.test.tsx | 56 +------------------ 1 file changed, 2 insertions(+), 54 deletions(-) diff --git a/plugins/scaffolder/src/components/ListTasksPage/ListTaskPage.test.tsx b/plugins/scaffolder/src/components/ListTasksPage/ListTaskPage.test.tsx index 9843ebb5ee..ec144f4b51 100644 --- a/plugins/scaffolder/src/components/ListTasksPage/ListTaskPage.test.tsx +++ b/plugins/scaffolder/src/components/ListTasksPage/ListTaskPage.test.tsx @@ -14,7 +14,6 @@ * limitations under the License. */ -import { Entity } from '@backstage/catalog-model'; import { renderInTestApp, TestApiProvider, @@ -46,20 +45,6 @@ describe('', () => { const mockPermissionApi = { authorize: jest.fn() }; it('should render the page', async () => { - const entity: Entity = { - apiVersion: 'v1', - kind: 'service', - metadata: { - name: 'test', - }, - spec: { - profile: { - displayName: 'BackUser', - }, - }, - }; - catalogApi.getEntityByRef.mockResolvedValue(entity); - scaffolderApiMock.listTasks.mockResolvedValue({ tasks: [], totalTasks: 0 }); const { getByText } = await renderInTestApp( @@ -87,19 +72,6 @@ describe('', () => { }); it('should render the task I am owner', async () => { - const entity: Entity = { - apiVersion: 'v1', - kind: 'User', - metadata: { - name: 'foo', - }, - spec: { - profile: { - displayName: 'BackUser', - }, - }, - }; - catalogApi.getEntityByRef.mockResolvedValue(entity); scaffolderApiMock.listTasks.mockResolvedValue({ tasks: [ { @@ -151,34 +123,10 @@ describe('', () => { expect(getByText('All tasks that have been started')).toBeInTheDocument(); expect(getByText('Tasks')).toBeInTheDocument(); expect(await findByText('One Template')).toBeInTheDocument(); - expect(await findByText('BackUser')).toBeInTheDocument(); + expect(await findByText('foo')).toBeInTheDocument(); }); it('should render all tasks', async () => { - const entity: Entity = { - apiVersion: 'v1', - kind: 'User', - metadata: { - name: 'foo', - }, - spec: { - profile: { - displayName: 'BackUser', - }, - }, - }; - catalogApi.getEntityByRef - .mockResolvedValue(entity) - .mockResolvedValue(entity) - .mockResolvedValue({ - ...entity, - spec: { - profile: { - displayName: 'OtherUser', - }, - }, - }); - scaffolderApiMock.listTasks .mockResolvedValue({ tasks: [ @@ -252,6 +200,6 @@ describe('', () => { offset: 0, }); expect(await findByText('One Template')).toBeInTheDocument(); - expect(await findByText('OtherUser')).toBeInTheDocument(); + expect(await findByText('boo')).toBeInTheDocument(); }); });