Skip to content

Commit 2d416b8

Browse files
fix: [M3-8193] - Check account access for disabling add tags button (#10583)
Co-authored-by: Jaalah Ramos <jaalah.ramos@gmail.com>
1 parent 284d3a4 commit 2d416b8

4 files changed

Lines changed: 61 additions & 3 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@linode/manager": Fixed
3+
---
4+
5+
Users must be an unrestricted User in order to add or modify tags on Linodes ([#10583](https://github.com/linode/manager/pull/10583))
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { fireEvent, screen, waitFor } from '@testing-library/react';
2+
import React from 'react';
3+
4+
import { renderWithTheme } from 'src/utilities/testHelpers';
5+
6+
import { TagCell } from './TagCell';
7+
8+
describe('TagCell Component', () => {
9+
const tags = ['tag1', 'tag2'];
10+
const updateTags = vi.fn(() => Promise.resolve());
11+
12+
describe('Disabled States', () => {
13+
it('does not allow adding a new tag when disabled', async () => {
14+
const { getByTestId } = renderWithTheme(
15+
<TagCell disabled tags={tags} updateTags={updateTags} />
16+
);
17+
const disabledButton = getByTestId('Button');
18+
expect(disabledButton).toHaveAttribute('aria-disabled', 'true');
19+
});
20+
21+
it('should display the tooltip if disabled and tooltipText is true', async () => {
22+
const { getByTestId } = renderWithTheme(
23+
<TagCell disabled tags={tags} updateTags={updateTags} />
24+
);
25+
const disabledButton = getByTestId('Button');
26+
expect(disabledButton).toBeInTheDocument();
27+
28+
fireEvent.mouseOver(disabledButton);
29+
30+
await waitFor(() => {
31+
expect(screen.getByRole('tooltip')).toBeInTheDocument();
32+
});
33+
34+
expect(
35+
screen.getByText(
36+
'You must be an unrestricted User in order to add or modify tags on Linodes.'
37+
)
38+
).toBeVisible();
39+
});
40+
});
41+
});

packages/manager/src/components/TagCell/TagCell.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import MoreHoriz from '@mui/icons-material/MoreHoriz';
22
import { styled } from '@mui/material/styles';
33
import Grid from '@mui/material/Unstable_Grid2';
4-
import { SxProps } from '@mui/system';
54
import * as React from 'react';
65

76
import { IconButton } from 'src/components/IconButton';
@@ -13,6 +12,8 @@ import { StyledPlusIcon, StyledTagButton } from '../Button/StyledTagButton';
1312
import { CircleProgress } from '../CircleProgress';
1413
import { AddTag } from './AddTag';
1514

15+
import type { SxProps } from '@mui/system';
16+
1617
export interface TagCellProps {
1718
/**
1819
* Disable adding or deleting tags.
@@ -83,6 +84,11 @@ export const TagCell = (props: TagCellProps) => {
8384

8485
const AddButton = (props: { panel?: boolean }) => (
8586
<StyledTagButton
87+
tooltipText={`${
88+
disabled
89+
? 'You must be an unrestricted User in order to add or modify tags on Linodes.'
90+
: ''
91+
}`}
8692
buttonType="outlined"
8793
disabled={disabled}
8894
endIcon={<StyledPlusIcon disabled={disabled} />}

packages/manager/src/features/Linodes/LinodeEntityDetailFooter.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { useSnackbar } from 'notistack';
44
import * as React from 'react';
55

66
import { TagCell } from 'src/components/TagCell/TagCell';
7+
import { useRestrictedGlobalGrantCheck } from 'src/hooks/useRestrictedGlobalGrantCheck';
78
import { useLinodeUpdateMutation } from 'src/queries/linodes/linodes';
89
import { useProfile } from 'src/queries/profile/profile';
910
import { getAPIErrorOrDefault } from 'src/utilities/errorUtils';
@@ -16,8 +17,8 @@ import {
1617
sxLastListItem,
1718
sxListItemFirstChild,
1819
} from './LinodeEntityDetail.styles';
19-
import { LinodeHandlers } from './LinodesLanding/LinodesLanding';
2020

21+
import type { LinodeHandlers } from './LinodesLanding/LinodesLanding';
2122
import type { Linode } from '@linode/api-v4/lib/linodes/types';
2223
import type { TypographyProps } from 'src/components/Typography';
2324

@@ -59,6 +60,11 @@ export const LinodeEntityDetailFooter = React.memo((props: FooterProps) => {
5960
openTagDrawer,
6061
} = props;
6162

63+
const isReadOnlyAccountAccess = useRestrictedGlobalGrantCheck({
64+
globalGrantType: 'account_access',
65+
permittedGrantLevel: 'read_write',
66+
});
67+
6268
const { mutateAsync: updateLinode } = useLinodeUpdateMutation(linodeId);
6369

6470
const { enqueueSnackbar } = useSnackbar();
@@ -157,7 +163,7 @@ export const LinodeEntityDetailFooter = React.memo((props: FooterProps) => {
157163
sx={{
158164
width: '100%',
159165
}}
160-
disabled={isLinodesGrantReadOnly}
166+
disabled={isLinodesGrantReadOnly || isReadOnlyAccountAccess}
161167
listAllTags={openTagDrawer}
162168
tags={linodeTags}
163169
updateTags={updateTags}

0 commit comments

Comments
 (0)