'use client'; import { AsyncCombobox, usePaginatedLookup } from '@/components/async-combobox'; import type { AsyncComboboxOption } from '@/components/async-combobox'; import { roleService } from '@/services/api'; import type { Role } from '@/types'; import { roleKeys } from '@/app/(modules)/roles/queries/roleKeys'; import type { RoleComboboxProps } from './RoleCombobox.types'; const ROLE_PAGE_SIZE = 20; function parseRoleId(value: string) { const roleId = Number(value); return Number.isFinite(roleId) ? roleId : null; } function mapRoleOption(role: Role): AsyncComboboxOption { return { value: String(role.id), label: role.display_name || role.name, }; } export function RoleCombobox({ value, onValueChange, enabled = true, disabled = false, portalContainer, }: RoleComboboxProps) { const lookup = usePaginatedLookup({ enabled, selectedValue: value, pageSize: ROLE_PAGE_SIZE, queryKey: (searchTerm) => [ ...roleKeys.lists(), 'async-lookup', searchTerm, ROLE_PAGE_SIZE, ] as const, queryFn: ({ searchTerm, skip, limit }) => roleService.getRoles({ search_term: searchTerm || undefined, skip, limit, effective_status: true, sort_by: 'display_name', sort_order: 'asc', }), mapOption: mapRoleOption, resolveSelected: (roleId) => { const numericRoleId = parseRoleId(roleId); return numericRoleId ? roleService.getRoleById(numericRoleId) : Promise.resolve(null); }, resolveSelectedQueryKey: (roleId) => { const numericRoleId = parseRoleId(roleId); return numericRoleId ? roleKeys.detail(numericRoleId) : [...roleKeys.details(), 'invalid', roleId]; }, }); return ( ); }