diff --git a/app/components/AccessNameCell.tsx b/app/components/AccessNameCell.tsx deleted file mode 100644 index f3d0b920be..0000000000 --- a/app/components/AccessNameCell.tsx +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * Copyright Oxide Computer Company - */ -import type { CellContext } from '@tanstack/react-table' - -import type { IdentityType } from '@oxide/api' - -import { Badge } from '~/ui/lib/Badge' - -/** - * Display the user or group name. If the row is for a group, add a GROUP badge. - */ -export const AccessNameCell = < - RowData extends { name: string; identityType: IdentityType }, ->( - info: CellContext -) => { - const name = info.getValue() - const identityType = info.row.original.identityType - return ( - <> - {name} - {identityType === 'silo_group' ? ( - - Group - - ) : null} - - ) -} diff --git a/app/pages/SiloAccessPage.tsx b/app/pages/SiloAccessPage.tsx index 0ba0d4f014..f331a3d877 100644 --- a/app/pages/SiloAccessPage.tsx +++ b/app/pages/SiloAccessPage.tsx @@ -22,7 +22,6 @@ import { } from '@oxide/api' import { Access24Icon } from '@oxide/design-system/icons/react' -import { AccessNameCell } from '~/components/AccessNameCell' import { HL } from '~/components/HL' import { RoleBadgeCell } from '~/components/RoleBadgeCell' import { @@ -36,6 +35,7 @@ import { Button } from '~/ui/lib/Button' import { EmptyMessage } from '~/ui/lib/EmptyMessage' import { PageHeader, PageTitle } from '~/ui/lib/PageHeader' import { TableActions, TableEmptyBox } from '~/ui/lib/Table' +import { accessTypeLabel } from '~/util/access' import { groupBy, isTruthy } from '~/util/array' const EmptyState = ({ onClick }: { onClick: () => void }) => ( @@ -111,7 +111,11 @@ export function SiloAccessPage() { const columns = useMemo( () => [ - colHelper.accessor('name', { header: 'Name', cell: AccessNameCell }), + colHelper.accessor('name', { header: 'Name' }), + colHelper.accessor('identityType', { + header: 'Type', + cell: (props) => accessTypeLabel(props.getValue()), + }), colHelper.accessor('siloRole', { header: 'Silo role', cell: RoleBadgeCell, diff --git a/app/pages/project/access/ProjectAccessPage.tsx b/app/pages/project/access/ProjectAccessPage.tsx index 08d365b291..e81c245d40 100644 --- a/app/pages/project/access/ProjectAccessPage.tsx +++ b/app/pages/project/access/ProjectAccessPage.tsx @@ -24,7 +24,6 @@ import { } from '@oxide/api' import { Access24Icon } from '@oxide/design-system/icons/react' -import { AccessNameCell } from '~/components/AccessNameCell' import { HL } from '~/components/HL' import { RoleBadgeCell } from '~/components/RoleBadgeCell' import { @@ -39,6 +38,7 @@ import { Button } from '~/ui/lib/Button' import { EmptyMessage } from '~/ui/lib/EmptyMessage' import { PageHeader, PageTitle } from '~/ui/lib/PageHeader' import { TableActions, TableEmptyBox } from '~/ui/lib/Table' +import { accessTypeLabel } from '~/util/access' import { groupBy, isTruthy } from '~/util/array' const EmptyState = ({ onClick }: { onClick: () => void }) => ( @@ -127,7 +127,11 @@ export function ProjectAccessPage() { const columns = useMemo( () => [ - colHelper.accessor('name', { header: 'Name', cell: AccessNameCell }), + colHelper.accessor('name', { header: 'Name' }), + colHelper.accessor('identityType', { + header: 'Type', + cell: (props) => accessTypeLabel(props.getValue()), + }), colHelper.accessor('siloRole', { header: 'Silo role', cell: RoleBadgeCell, diff --git a/app/util/access.spec.tsx b/app/util/access.spec.tsx new file mode 100644 index 0000000000..2f0ed47884 --- /dev/null +++ b/app/util/access.spec.tsx @@ -0,0 +1,15 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * Copyright Oxide Computer Company + */ +import { expect, test } from 'vitest' + +import { accessTypeLabel } from './access' + +test('accessTypeLabel', () => { + expect(accessTypeLabel('silo_group')).toEqual('Group') + expect(accessTypeLabel('silo_user')).toEqual('User') +}) diff --git a/app/util/access.ts b/app/util/access.ts new file mode 100644 index 0000000000..0816af6136 --- /dev/null +++ b/app/util/access.ts @@ -0,0 +1,11 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * Copyright Oxide Computer Company + */ +import type { IdentityType } from '~/api' + +export const accessTypeLabel = (identityType: IdentityType) => + identityType === 'silo_group' ? 'Group' : 'User' diff --git a/test/e2e/project-access.e2e.ts b/test/e2e/project-access.e2e.ts index a6481688bc..cc177ced09 100644 --- a/test/e2e/project-access.e2e.ts +++ b/test/e2e/project-access.e2e.ts @@ -18,22 +18,26 @@ test('Click through project access page', async ({ page }) => { const table = page.locator('table') await expectRowVisible(table, { Name: 'Hannah Arendt', + Type: 'User', 'Silo role': 'admin', 'Project role': '', }) await expectRowVisible(table, { Name: 'Jacob Klein', + Type: 'User', 'Silo role': '', 'Project role': 'collaborator', }) await expectRowVisible(table, { // no space because expectRowVisible uses textContent, not accessible name - Name: 'real-estate-devsGroup', + Name: 'real-estate-devs', + Type: 'Group', 'Silo role': 'collaborator', }) await expectRowVisible(table, { // no space because expectRowVisible uses textContent, not accessible name - Name: 'kernel-devsGroup', + Name: 'kernel-devs', + Type: 'Group', 'Silo role': '', 'Project role': 'viewer', }) diff --git a/test/e2e/silo-access.e2e.ts b/test/e2e/silo-access.e2e.ts index aaf6142c59..ec45ede7b7 100644 --- a/test/e2e/silo-access.e2e.ts +++ b/test/e2e/silo-access.e2e.ts @@ -20,11 +20,13 @@ test('Click through silo access page', async ({ page }) => { await expectVisible(page, ['role=heading[name*="Access & IAM"]']) await expectRowVisible(table, { // no space because expectRowVisible uses textContent, not accessible name - Name: 'real-estate-devsGroup', + Name: 'real-estate-devs', + Type: 'Group', 'Silo role': 'collaborator', }) await expectRowVisible(table, { Name: 'Hannah Arendt', + Type: 'User', 'Silo role': 'admin', }) await expectNotVisible(page, [`role=cell[name="${user4.display_name}"]`])