Merge branch 'fix/user-picker-hooks-order' into 'main'
fix(admin-ui): UserPicker — порядок хуков (rules-of-hooks) See merge request 2-6/2-6-4/terravault/ordinis!265
This commit is contained in:
@@ -46,11 +46,23 @@ export function UserPicker({ value, onChange, label, placeholder, disabled }: Us
|
|||||||
const fallbackToTextInput =
|
const fallbackToTextInput =
|
||||||
!usersQ.isLoading && !usersQ.isError && usersList.length === 0
|
!usersQ.isLoading && !usersQ.isError && usersList.length === 0
|
||||||
|
|
||||||
|
// Все хуки ДО любого early-return — иначе rules-of-hooks нарушится при
|
||||||
|
// переходе loading→empty (loading rendered ВСЕ хуки → empty возвращает
|
||||||
|
// TextInput минуя последующие useMemo). React в production падает на
|
||||||
|
// "rendered fewer hooks than expected" → error boundary → "Что-то пошло
|
||||||
|
// не так". Reproduce: loading=true первый рендер, loading=false data=[]
|
||||||
|
// второй.
|
||||||
const usersBySub = useMemo(() => {
|
const usersBySub = useMemo(() => {
|
||||||
const m = new Map<string, UserListItem>()
|
const m = new Map<string, UserListItem>()
|
||||||
for (const u of usersList) m.set(u.sub, u)
|
for (const u of usersList) m.set(u.sub, u)
|
||||||
return m
|
return m
|
||||||
}, [usersList])
|
}, [usersList])
|
||||||
|
const selected = value ? usersBySub.get(value) : undefined
|
||||||
|
const triggerLabel = useMemo(() => {
|
||||||
|
if (!value) return placeholder ?? 'Любой'
|
||||||
|
if (selected) return labelFor(selected)
|
||||||
|
return `${value.slice(0, 8)}…`
|
||||||
|
}, [value, selected, placeholder])
|
||||||
|
|
||||||
if (fallbackToTextInput) {
|
if (fallbackToTextInput) {
|
||||||
return (
|
return (
|
||||||
@@ -65,14 +77,6 @@ export function UserPicker({ value, onChange, label, placeholder, disabled }: Us
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const selected = value ? usersBySub.get(value) : undefined
|
|
||||||
const triggerLabel = useMemo(() => {
|
|
||||||
if (!value) return placeholder ?? 'Любой'
|
|
||||||
if (selected) return labelFor(selected)
|
|
||||||
// Value есть, но юзера нет в кеше — показываем UUID prefix.
|
|
||||||
return `${value.slice(0, 8)}…`
|
|
||||||
}, [value, selected, placeholder])
|
|
||||||
|
|
||||||
// Поиск: substring по preferredUsername / name / email / sub. cmdk
|
// Поиск: substring по preferredUsername / name / email / sub. cmdk
|
||||||
// делает client-side фильтрацию по value атрибуту CommandItem'а;
|
// делает client-side фильтрацию по value атрибуту CommandItem'а;
|
||||||
// концатенируем все поля в один searchable string.
|
// концатенируем все поля в один searchable string.
|
||||||
|
|||||||
Reference in New Issue
Block a user