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
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-12037-fixed-1744750096750.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Fixed
---

Missing warning message for restricted users on Volumes page ([#12037](https://github.com/linode/manager/pull/12037))
24 changes: 21 additions & 3 deletions packages/manager/src/features/Account/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export type ActionType =
| 'view';

interface GetRestrictedResourceText {
action?: ActionType;
action?: ActionType | ActionType[];
includeContactInfo?: boolean;
isChildUser?: boolean;
isSingular?: boolean;
Expand All @@ -46,7 +46,7 @@ export type RestrictedGlobalGrantType =
| NonAccountAccessGrant;

/**
* Get a resource restricted message based on action and resource type.
* Get a resource restricted message based on action(s) and resource type.
*/
export const getRestrictedResourceText = ({
action = 'edit',
Expand All @@ -61,7 +61,9 @@ export const getRestrictedResourceText = ({

const contactPerson = isChildUser ? PARENT_USER : ADMINISTRATOR;

let message = `You don't have permissions to ${action} ${resource}.`;
const actionText = formatAction(action);

let message = `You don't have permissions to ${actionText} ${resource}.`;

if (includeContactInfo) {
message += ` Please contact your ${contactPerson} to request the necessary permissions.`;
Expand Down Expand Up @@ -89,3 +91,19 @@ export const useIsTaxIdEnabled = (): {

return { isTaxIdEnabled };
};

/**
* Formats one or more actions into a readable string
* @param action - A single action or array of actions
*
* @returns A formatted string representing the action(s)
*/
function formatAction(action: ActionType | ActionType[]): string {
if (!Array.isArray(action)) return action;

const len = action.length;
if (len === 1) return action[0];
if (len === 2) return `${action[0]} or ${action[1]}`;

return `${action.slice(0, -1).join(', ')}, or ${action[action.length - 1]}`;
}
27 changes: 23 additions & 4 deletions packages/manager/src/features/Volumes/VolumesLanding.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
ErrorState,
IconButton,
InputAdornment,
Notice,
TextField,
} from '@linode/ui';
import CloseIcon from '@mui/icons-material/Close';
Expand All @@ -23,6 +24,7 @@ import { TableRow } from 'src/components/TableRow';
import { TableRowEmpty } from 'src/components/TableRowEmpty/TableRowEmpty';
import { TableSortCell } from 'src/components/TableSortCell';
import { getRestrictedResourceText } from 'src/features/Account/utils';
import { useAccountManagement } from 'src/hooks/useAccountManagement';
import { useDialogData } from 'src/hooks/useDialogData';
import { useOrderV2 } from 'src/hooks/useOrderV2';
import { usePaginationV2 } from 'src/hooks/usePaginationV2';
Expand Down Expand Up @@ -71,6 +73,8 @@ export const VolumesLanding = () => {
});
const { query } = search;

const { _isRestrictedUser } = useAccountManagement();

const { handleOrderChange, order, orderBy } = useOrderV2({
initialRoute: {
defaultOrder: {
Expand All @@ -90,17 +94,21 @@ export const VolumesLanding = () => {
}),
};

const { data: volumes, error, isFetching, isLoading } = useVolumesQuery(
const {
data: volumes,
error,
isFetching,
isLoading,
} = useVolumesQuery(
{
page: pagination.page,
page_size: pagination.pageSize,
},
filter
);

const {
isBlockStorageEncryptionFeatureEnabled,
} = useIsBlockStorageEncryptionFeatureEnabled();
const { isBlockStorageEncryptionFeatureEnabled } =
useIsBlockStorageEncryptionFeatureEnabled();

const { data: selectedVolume, isFetching: isFetchingVolume } = useDialogData({
enabled: !!params.volumeId,
Expand Down Expand Up @@ -166,6 +174,17 @@ export const VolumesLanding = () => {
return (
<>
<DocumentTitleSegment segment="Volumes" />
{_isRestrictedUser && (
<Notice
important
text={getRestrictedResourceText({
action: ['create', 'edit'],
resourceType: 'Volumes',
isSingular: false,
})}
variant="warning"
/>
)}
<LandingHeader
breadcrumbProps={{
pathname: 'Volumes',
Expand Down