1212import { create } from '@bufbuild/protobuf' ;
1313import { DataTable , SearchField } from '@redpanda-data/ui' ;
1414import { Link } from '@tanstack/react-router' ;
15- import { TrashIcon } from 'components/icons' ;
15+ import { InfoIcon , TrashIcon } from 'components/icons' ;
1616import { parseAsString } from 'nuqs' ;
1717import {
1818 ACL_Operation ,
@@ -48,29 +48,11 @@ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../
4848import { type PrincipalEntry , usePrincipalList } from '../hooks/use-principal-list' ;
4949import { useSecurityBreadcrumbs } from '../hooks/use-security-breadcrumbs' ;
5050import { AlertDeleteFailed } from '../shared/alert-delete-failed' ;
51+ import { getCreateUserButtonProps } from '../shared/create-user-button-props' ;
5152import { DeleteUserConfirmModal } from '../shared/delete-user-confirm-modal' ;
5253import { filterByName } from '../shared/filter-by-name' ;
5354import { UserRoleTags } from '../shared/user-role-tags' ;
5455
55- const getCreateUserButtonProps = (
56- isAdminApiConfigured : boolean ,
57- featureCreateUser : boolean ,
58- canManageUsers : boolean | undefined
59- ) => {
60- const hasRBAC = canManageUsers !== undefined ;
61-
62- return {
63- disabled : ! ( isAdminApiConfigured && featureCreateUser ) || ( hasRBAC && canManageUsers === false ) ,
64- tooltip : [
65- ! isAdminApiConfigured && 'The Redpanda Admin API is not configured.' ,
66- ! featureCreateUser && "Your cluster doesn't support this feature." ,
67- hasRBAC && canManageUsers === false && 'You need RedpandaCapability.MANAGE_REDPANDA_USERS permission.' ,
68- ]
69- . filter ( Boolean )
70- . join ( ' ' ) ,
71- } ;
72- } ;
73-
7456const PermissionsListActions = ( {
7557 entry,
7658 canDeleteUser,
@@ -221,12 +203,27 @@ export const PermissionsListTab: FC = () => {
221203
222204 return (
223205 < div className = "flex flex-col gap-4" >
224- < div >
206+ < p >
225207 This page provides a detailed overview of all effective permissions for each principal, including those derived
226208 from assigned roles. While the ACLs tab shows permissions directly granted to principals, this tab also
227209 incorporates roles that may assign additional permissions to a principal. This gives you a complete picture of
228210 what each principal can do within your cluster.
229- </ div >
211+ </ p >
212+ < Alert icon = { < InfoIcon /> } variant = "info" >
213+ < AlertDescription >
214+ < p >
215+ To grant permissions, use the{ ' ' }
216+ < Link className = "font-medium underline" to = "/security/acls" >
217+ ACLs
218+ </ Link > { ' ' }
219+ or{ ' ' }
220+ < Link className = "font-medium underline" to = "/security/roles" >
221+ Roles
222+ </ Link > { ' ' }
223+ tabs.
224+ </ p >
225+ </ AlertDescription >
226+ </ Alert >
230227
231228 < SearchField
232229 placeholderText = "Filter by name"
@@ -296,6 +293,7 @@ export const PermissionsListTab: FC = () => {
296293 ] }
297294 data = { usersFiltered }
298295 emptyAction = { ( ( ) => {
296+ if ( searchQuery ) return ;
299297 const { disabled, tooltip } = getCreateUserButtonProps (
300298 isAdminApiConfigured ,
301299 featureCreateUser ,
@@ -313,12 +311,12 @@ export const PermissionsListTab: FC = () => {
313311 Create user
314312 </ Button >
315313 </ TooltipTrigger >
316- { tooltip && < TooltipContent > { tooltip } </ TooltipContent > }
314+ { Boolean ( tooltip ) && < TooltipContent > { tooltip } </ TooltipContent > }
317315 </ Tooltip >
318316 </ TooltipProvider >
319317 ) ;
320318 } ) ( ) }
321- emptyText = " No principals yet"
319+ emptyText = { searchQuery ? ' No principals match your search' : 'No principals yet' }
322320 pagination
323321 sorting
324322 />
0 commit comments