import React, { FormEvent, useCallback, useEffect, useState } from 'react'; import { ClickOutsideWrapper, HorizontalGroup, Spinner } from '@grafana/ui'; import { Role, OrgRole } from 'app/types'; import { RolePickerInput } from './RolePickerInput'; import { RolePickerMenu } from './RolePickerMenu'; export interface Props { builtInRole?: OrgRole; appliedRoles: Role[]; roleOptions: Role[]; builtInRoles?: Record; isLoading?: boolean; disabled?: boolean; builtinRolesDisabled?: boolean; showBuiltInRole?: boolean; onRolesChange: (newRoles: string[]) => void; onBuiltinRoleChange?: (newRole: OrgRole) => void; } export const RolePicker = ({ builtInRole, appliedRoles, roleOptions, builtInRoles, disabled, isLoading, builtinRolesDisabled, showBuiltInRole, onRolesChange, onBuiltinRoleChange, }: Props): JSX.Element | null => { const [isOpen, setOpen] = useState(false); const [selectedRoles, setSelectedRoles] = useState(appliedRoles); const [selectedBuiltInRole, setSelectedBuiltInRole] = useState(builtInRole); const [query, setQuery] = useState(''); useEffect(() => { setSelectedRoles(appliedRoles); }, [appliedRoles]); const onOpen = useCallback( (event: FormEvent) => { if (!disabled) { event.preventDefault(); event.stopPropagation(); setOpen(true); } }, [setOpen, disabled] ); const onClose = useCallback(() => { setOpen(false); setQuery(''); setSelectedRoles(appliedRoles); setSelectedBuiltInRole(builtInRole); }, [appliedRoles, builtInRole]); // Only call onClose if menu is open. Prevent unnecessary calls for multiple pickers on the page. const onClickOutside = () => isOpen && onClose(); const onInputChange = (query?: string) => { if (query) { setQuery(query); } else { setQuery(''); } }; const onSelect = (roles: Role[]) => { setSelectedRoles(roles); }; const onBuiltInRoleSelect = (role: OrgRole) => { setSelectedBuiltInRole(role); }; const onUpdate = (newRoles: string[], newBuiltInRole?: OrgRole) => { if (onBuiltinRoleChange && newBuiltInRole) { onBuiltinRoleChange(newBuiltInRole); } onRolesChange(newRoles); setOpen(false); setQuery(''); }; const getOptions = () => { if (query && query.trim() !== '') { return roleOptions.filter((option) => option.name?.toLowerCase().includes(query.toLowerCase())); } return roleOptions; }; if (isLoading) { return ( Loading... ); } return (
{isOpen && ( )}
); };