Skip to content

Commit

Permalink
fix: [PDI-3099] - Enable Create Token button if all visible permiss…
Browse files Browse the repository at this point in the history
…ions selected (#11453)

* fix: Enable `Create Token` button if all visible perms selected

* Added changeset: `Create Token` button becomes disabled when all permissions are selected individually (without using 'select all') and child-account is hidden

* Update the in-line doc
  • Loading branch information
ChihweiLHBird authored Jan 7, 2025
1 parent 2562a2f commit f818d0b
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 10 deletions.
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-11453-fixed-1734765509208.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Fixed
---

`Create Token` button becomes disabled when all permissions are selected individually (without using 'select all') and child-account is hidden ([#11453](https://github.com/linode/manager/pull/11453))
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
allScopesAreTheSame,
basePermNameMap,
hasAccessBeenSelectedForAllScopes,
levelMap,
permTuplesToScopeString,
scopeStringToPermTuples,
} from './utils';
Expand Down Expand Up @@ -178,8 +179,8 @@ export const CreateAPITokenDrawer = (props: Props) => {
// Permission scopes with a different default when Selecting All for the specified access level.
const excludedScopesFromSelectAll: ExcludedScope[] = [
{
defaultAccessLevel: 0,
invalidAccessLevels: [1],
defaultAccessLevel: levelMap.none,
invalidAccessLevels: [levelMap.read_only],
name: 'vpc',
},
];
Expand Down Expand Up @@ -383,7 +384,10 @@ export const CreateAPITokenDrawer = (props: Props) => {
<ActionsPanel
primaryButtonProps={{
'data-testid': 'create-button',
disabled: !hasAccessBeenSelectedForAllScopes(form.values.scopes),
disabled: !hasAccessBeenSelectedForAllScopes(
form.values.scopes,
hideChildAccountAccessScope ? ['child_account'] : []
),
label: 'Create Token',
loading: isPending,
onClick: () => form.handleSubmit(),
Expand Down
12 changes: 12 additions & 0 deletions packages/manager/src/features/Profile/APITokens/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,11 @@ describe('hasAccessBeenSelectedForAllScopes', () => {
['vpc', 0],
];

const allExceptChildAccountSelectedScopes: Permission[] = [
...allSelectedScopes,
['child_account', -1],
];

it('should return false if scopes are all set to a default of no selection', () => {
expect(hasAccessBeenSelectedForAllScopes(defaultScopes)).toBe(false);
});
Expand All @@ -447,4 +452,11 @@ describe('hasAccessBeenSelectedForAllScopes', () => {
it('should return true if all scopes have a valid selection', () => {
expect(hasAccessBeenSelectedForAllScopes(allSelectedScopes)).toBe(true);
});
it('should return true if all scopes except those excluded have a valid selection', () => {
expect(
hasAccessBeenSelectedForAllScopes(allExceptChildAccountSelectedScopes, [
'child_account',
])
).toBe(true);
});
});
20 changes: 13 additions & 7 deletions packages/manager/src/features/Profile/APITokens/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ import { DateTime } from 'luxon';

import { isPast } from 'src/utilities/isPast';

import { ExcludedScope } from './CreateAPITokenDrawer';

export type Permission = [keyof typeof basePermNameMap, number];
import type { ExcludedScope } from './CreateAPITokenDrawer';

export const basePerms = [
'account',
Expand Down Expand Up @@ -46,6 +44,10 @@ export const basePermNameMap = {
vpc: 'VPCs',
} as const;

type PermissionKey = keyof typeof basePermNameMap;

export type Permission = [PermissionKey, number];

export const inverseLevelMap = ['none', 'read_only', 'read_write'];

export const levelMap = {
Expand Down Expand Up @@ -177,7 +179,7 @@ export const permTuplesToScopeString = (scopeTups: Permission[]): string => {
}
const joinedTups = scopeTups.reduce((acc, [key, value]) => {
const level = inverseLevelMap[value];
if (level !== 'none') {
if (level && level !== 'none') {
return [...acc, [key, level].join(':')];
}
return [...acc];
Expand Down Expand Up @@ -257,17 +259,21 @@ Omit<typeof basePermNameMap, T[number]['name']> => {
* Determines whether a selection has been made for every scope, since by default, the scope permissions are set to null.
*
* @param scopeTuples - The array of scope tuples.
* @param excludedPerms - The permission keys to be excluded from this check.
* @returns {boolean} True if all scopes have permissions set to none/read_only/read_write, false otherwise.
*/
export const hasAccessBeenSelectedForAllScopes = (
scopeTuples: Permission[]
scopeTuples: Permission[],
excludedPerms?: PermissionKey[]
): boolean => {
const validAccessLevels = [
levelMap['none'],
levelMap['read_only'],
levelMap['read_write'],
];
return scopeTuples.every((scopeTuple) =>
validAccessLevels.includes(scopeTuple[1])
return scopeTuples.every(
(scopeTuple) =>
validAccessLevels.includes(scopeTuple[1]) ||
excludedPerms?.includes(scopeTuple[0])
);
};

0 comments on commit f818d0b

Please sign in to comment.