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
---

IAM RBAC: User Detail UI fix, add missing tooltips to Linode Storage Action Menu ([#12722](https://github.com/linode/manager/pull/12722))
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const deleteInUseDisk = (diskName: string) => {
});

cy.findByText(
'Your Linode must be fully powered down in order to perform this action'
'Your Linode must be fully powered down in order to perform this action.'
).should('be.visible');
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ describe('UserDetailsPanel', () => {
<UserDetailsPanel assignedRoles={assignedRoles} user={user} />
);

expect(getByText('Username')).toBeVisible();
expect(getByText(/Username/)).toBeVisible();
expect(getByText(user.username)).toBeVisible();

expect(getByText('Email')).toBeVisible();
expect(getByText(/Email/)).toBeVisible();
expect(getByText(user.email)).toBeVisible();
});

Expand All @@ -31,7 +31,7 @@ describe('UserDetailsPanel', () => {
<UserDetailsPanel assignedRoles={assignedRoles} user={user} />
);

expect(getByText('Assigned Roles')).toBeVisible();
expect(getByText(/Assigned Roles/)).toBeVisible();
expect(getAllByText('0')[0]).toBeVisible();
});

Expand Down Expand Up @@ -61,7 +61,7 @@ describe('UserDetailsPanel', () => {
<UserDetailsPanel assignedRoles={assignedRoles} user={user} />
);

expect(getByText('Assigned Roles')).toBeVisible();
expect(getByText(/Assigned Roles/)).toBeVisible();
expect(getByText('7')).toBeVisible();
});

Expand All @@ -82,7 +82,7 @@ describe('UserDetailsPanel', () => {
<UserDetailsPanel assignedRoles={assignedRoles} user={user} />
);

expect(getByText('Assigned Roles')).toBeVisible();
expect(getByText(/Assigned Roles/)).toBeVisible();
expect(getByText('4')).toBeVisible();
});

Expand All @@ -96,7 +96,7 @@ describe('UserDetailsPanel', () => {
<UserDetailsPanel assignedRoles={assignedRoles} user={user} />
);

expect(getByText('Verified Phone Number')).toBeVisible();
expect(getByText(/Verified number/)).toBeVisible();
expect(getByText(user.verified_phone_number!)).toBeVisible();
});

Expand All @@ -108,7 +108,7 @@ describe('UserDetailsPanel', () => {
<UserDetailsPanel assignedRoles={assignedRoles} user={user} />
);

expect(getByText('2FA')).toBeVisible();
expect(getByText(/2FA/)).toBeVisible();
expect(getByText('Enabled')).toBeVisible();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,14 @@ export const UserDetailsPanel = ({ assignedRoles, user }: Props) => {
status={
user.last_login?.status === 'successful' ? 'active' : 'error'
}
sx={{ alignSelf: 'center' }}
/>
)}
</Stack>
),
},
{
label: 'Last Login',
label: 'Last login',
value: user.last_login ? (
<DateTimeDisplay value={user.last_login.login_datetime} />
) : (
Expand All @@ -74,7 +75,7 @@ export const UserDetailsPanel = ({ assignedRoles, user }: Props) => {
),
},
{
label: 'Verified Phone Number',
label: 'Verified number',
value: (
<MaskableText
isToggleable
Expand Down Expand Up @@ -116,6 +117,7 @@ export const UserDetailsPanel = ({ assignedRoles, user }: Props) => {
'& > p:nth-of-type(2)': {
overflow: 'hidden',
textOverflow: 'ellipsis',
alignItems: 'center',
},
}}
>
Expand All @@ -124,7 +126,7 @@ export const UserDetailsPanel = ({ assignedRoles, user }: Props) => {
font: theme.font.bold,
})}
>
{item.label}
{item.label}:
</Typography>
{item.value}
</Stack>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,13 @@ describe('LinodeDiskActionMenu', () => {
});

it('should disable Resize and Delete when the Linode is running', async () => {
queryMocks.userPermissions.mockReturnValue({
data: {
...queryMocks.userPermissions().data,
resize_linode: true,
delete_linode: true,
},
});
const { getAllByLabelText, getByLabelText } = renderWithTheme(
<LinodeDiskActionMenu {...defaultProps} />
);
Expand All @@ -169,7 +176,7 @@ describe('LinodeDiskActionMenu', () => {

expect(
getAllByLabelText(
'Your Linode must be fully powered down in order to perform this action'
'Your Linode must be fully powered down in order to perform this action.'
)
).toHaveLength(2);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,25 +40,31 @@ export const LinodeDiskActionMenu = (props: Props) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

note - My limited iam account has the role linode_viewer for one of my Linodes, and I see this for the disk's action menu - Create Disk Image is also disabled but there's no tooltip:

image

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.

Added tooltip for the Create Disk Image. Thanks!

const poweredOnTooltip =
linodeStatus !== 'offline'
? 'Your Linode must be fully powered down in order to perform this action'
? 'Your Linode must be fully powered down in order to perform this action.'
: undefined;

const swapTooltip =
disk.filesystem == 'swap'
? 'You cannot create images from Swap images.'
: undefined;

const noPermissionTooltip =
'You do not have permission to perform this action.';

const actions: Action[] = [
{
disabled: !permissions.update_linode,
onClick: onRename,
title: 'Rename',
tooltip: !permissions.update_linode ? noPermissionTooltip : undefined,
},
{
disabled: !permissions.resize_linode || linodeStatus !== 'offline',
onClick: onResize,
title: 'Resize',
tooltip: poweredOnTooltip,
tooltip: !permissions.resize_linode
? noPermissionTooltip
: poweredOnTooltip,
},
{
disabled: readOnly || !!swapTooltip,
Expand All @@ -71,7 +77,7 @@ export const LinodeDiskActionMenu = (props: Props) => {
},
}),
title: 'Create Disk Image',
tooltip: swapTooltip,
tooltip: readOnly ? noPermissionTooltip : swapTooltip,
},
{
disabled: !permissions.clone_linode,
Expand All @@ -83,13 +89,16 @@ export const LinodeDiskActionMenu = (props: Props) => {
},
});
},
tooltip: !permissions.clone_linode ? noPermissionTooltip : undefined,
title: 'Clone',
},
{
disabled: !permissions.delete_linode || linodeStatus !== 'offline',
onClick: onDelete,
title: 'Delete',
tooltip: poweredOnTooltip,
tooltip: !permissions.delete_linode
? noPermissionTooltip
: poweredOnTooltip,
},
];

Expand Down