Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Upcoming Features
---

Empty message for `SwitchAccountDrawer` child accounts table ([#13412](https://github.com/linode/manager/pull/13412))
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ export const SwitchAccountDrawer = (props: Props) => {
? currentParentTokenWithBearer
: currentTokenWithBearer
}
filter={filter}
isLoading={isLoading}
isSwitchingChildAccounts={isSwitchingChildAccounts}
onClose={onClose}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import { Box, CircleProgress, LinkButton, Notice, Stack } from '@linode/ui';
import React from 'react';
import { Waypoint } from 'react-waypoint';

import { useIsIAMDelegationEnabled } from 'src/features/IAM/hooks/useIsIAMEnabled';

import type { ChildAccount, Filter, UserType } from '@linode/api-v4';

export interface ChildAccountListProps {
Expand Down Expand Up @@ -43,8 +41,6 @@ export const ChildAccountList = React.memo(
fetchNextPage,
isFetchingNextPage,
}: ChildAccountListProps) => {
const { isIAMDelegationEnabled } = useIsIAMDelegationEnabled();

if (isLoading) {
return (
<Box display="flex" justifyContent="center">
Expand All @@ -53,11 +49,7 @@ export const ChildAccountList = React.memo(
);
}

if (
!isIAMDelegationEnabled &&
childAccounts &&
childAccounts.length === 0
) {
if (childAccounts && childAccounts.length === 0) {
return (
<Notice variant="info">
There are no child accounts
Expand All @@ -69,21 +61,6 @@ export const ChildAccountList = React.memo(
);
}

if (
isIAMDelegationEnabled &&
childAccounts &&
childAccounts.length === 0 &&
!Object.prototype.hasOwnProperty.call(filter, 'company')
) {
return (
<Notice variant="info">
You don&apos;t have access to other accounts. You must be added to a
delegation by your account administrator to have access to other
accounts.
</Notice>
);
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not belong in there since this component is only rendered if isIAMDelegationEnabled is false


const renderChildAccounts = childAccounts?.map((childAccount, idx) => {
const euuid = childAccount.euuid;
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import React from 'react';

import { accountFactory } from 'src/factories';
import { renderWithTheme } from 'src/utilities/testHelpers';

import { ChildAccountsTable } from './ChildAccountsTable';

import type { ChildAccountsTableProps } from './ChildAccountsTable';

const childAccounts = accountFactory.buildList(5).map((account, i) => ({
...account,
company: `Child Account ${i}`,
}));

const childAccountsWithMoreThan25 = accountFactory
.buildList(30)
.map((account, i) => ({
...account,
company: `Child Account ${i}`,
}));

const props: ChildAccountsTableProps = {
childAccounts,
currentTokenWithBearer: 'Bearer 123',
onSwitchAccount: vi.fn(),
page: 1,
pageSize: 25,
setIsSwitchingChildAccounts: vi.fn(),
totalResults: 0,
userType: undefined,

Check warning on line 30 in packages/manager/src/features/Account/SwitchAccounts/ChildAccountsTable.test.tsx

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Use null instead. Raw Output: {"ruleId":"sonarjs/no-undefined-assignment","severity":1,"message":"Use null instead.","line":30,"column":13,"nodeType":"Identifier","messageId":"useNull","endLine":30,"endColumn":22}
filter: {},
isLoading: false,
isSwitchingChildAccounts: false,
onClose: vi.fn(),
onPageChange: vi.fn(),
onPageSizeChange: vi.fn(),
};

describe('ChildAccountsTable', () => {
it('should display a list of child accounts', async () => {
const { getByTestId, getAllByText } = renderWithTheme(
<ChildAccountsTable {...props} />
);

expect(getByTestId('child-accounts-table')).toHaveAttribute(
'aria-label',
'List of Child Accounts'
);

childAccounts.forEach((account) => {
expect(getAllByText(account.company)).toHaveLength(1);
});
});

it('should display pagination when there are more than 25 child accounts', async () => {
const firstPageAccounts = childAccountsWithMoreThan25.slice(0, 25);

const { getByTestId } = renderWithTheme(
<ChildAccountsTable
{...props}
childAccounts={firstPageAccounts}
totalResults={childAccountsWithMoreThan25.length}
/>
);

expect(getByTestId('child-accounts-table-pagination')).toBeVisible();
});

it('should display an empty state when no child accounts are found', async () => {
const { getByText } = renderWithTheme(
<ChildAccountsTable {...props} childAccounts={[]} />
);

expect(
getByText(

Check warning on line 75 in packages/manager/src/features/Account/SwitchAccounts/ChildAccountsTable.test.tsx

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Don't wrap `getBy*` query with `expect` & presence matchers like `toBeInTheDocument` or `not.toBeNull` as `getBy*` queries fail implicitly when element is not found Raw Output: {"ruleId":"testing-library/prefer-implicit-assert","severity":1,"message":"Don't wrap `getBy*` query with `expect` & presence matchers like `toBeInTheDocument` or `not.toBeNull` as `getBy*` queries fail implicitly when element is not found","line":75,"column":7,"nodeType":"Identifier","messageId":"preferImplicitAssert","endLine":75,"endColumn":16}
/You don't have access to other accounts. You must be added to a delegation by an account administrator to have access to other accounts./
)
).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, CircleProgress, LinkButton, useTheme } from '@linode/ui';
import { Box, CircleProgress, LinkButton, Notice, useTheme } from '@linode/ui';
import { Pagination } from 'akamai-cds-react-components/Pagination';
import {
Table,
Expand All @@ -10,11 +10,12 @@ import React from 'react';

import { MIN_PAGE_SIZE } from 'src/components/PaginationFooter/PaginationFooter.constants';

import type { Account, UserType } from '@linode/api-v4';
import type { Account, Filter, UserType } from '@linode/api-v4';

interface ChildAccountsTableProps {
export interface ChildAccountsTableProps {
childAccounts?: Account[];
currentTokenWithBearer?: string;
filter: Filter;
isLoading: boolean;
isSwitchingChildAccounts: boolean;
onClose: () => void;
Expand Down Expand Up @@ -42,6 +43,7 @@ interface ChildAccountsTableProps {

export const ChildAccountsTable = (props: ChildAccountsTableProps) => {
const {
filter,
childAccounts,
currentTokenWithBearer,
isLoading,
Expand Down Expand Up @@ -74,9 +76,25 @@ export const ChildAccountsTable = (props: ChildAccountsTableProps) => {
);
}

if (
childAccounts &&
childAccounts.length === 0 &&
!Object.prototype.hasOwnProperty.call(filter, 'company')
) {
return (
<Notice variant="info">
You don&apos;t have access to other accounts. You must be added to a
delegation by an account administrator to have access to other accounts.
</Notice>
);
}

return (
<>
<Table aria-label="List of Child Accounts">
<Table
aria-label="List of Child Accounts"
data-testid="child-accounts-table"
>
<TableBody>
{childAccounts?.map((childAccount, idx) => (
<TableRow key={childAccount.euuid}>
Expand Down Expand Up @@ -111,6 +129,7 @@ export const ChildAccountsTable = (props: ChildAccountsTableProps) => {
{totalResults > MIN_PAGE_SIZE && (
<Pagination
count={totalResults}
data-testid="child-accounts-table-pagination"
itemsLabel="Accounts: "
onPageChange={(e: CustomEvent<number>) =>
handlePageChange(Number(e.detail))
Expand Down