Commit Graph

5 Commits

Author SHA1 Message Date
gorbenko.pavel 63c674ed99 Merge branch 'claude/heuristic-jones-cb2a26' into service-request
Tests / frontend-test (pull_request) Successful in 1m18s
2026-09-01 17:25:21 +05:00
gorbenko.pavel c5a443b5d1 Включить react-hooks/exhaustive-deps и разобрать устаревшие замыкания
Правило было не задано вовсе: плагин eslint-plugin-react-hooks подключает
профиль @microsoft/eslint-config-spfx/lib/profiles/react, но правил из него
не включает. Теперь в .eslintrc.js явно заданы rules-of-hooks (error) и
exhaustive-deps (warn); сборка проходит с нулём предупреждений.

Что реально чинилось, а не затыкалось:

- shared/useStableCallback.ts — обёртка с неизменной ссылкой над колбэком-пропом
  (аналог будущего useEffectEvent). Ссылка стабильна, внутри всегда актуальная
  версия колбэка, поэтому её можно честно класть в зависимости.
- onCodeLoaded во всех forms/*/*View.tsx и *Form.tsx идёт в эффект загрузки
  через эту обёртку: просто дописать проп в зависимости нельзя — заявка
  перезапрашивалась бы на каждый рендер родителя.
- useRequestSubmit: run стабилизирован (useCallback + savingRef вместо чтения
  состояния), возвращаемый объект мемоизирован. Формы берут из него стабильный
  setError и указывают в зависимостях его, а не submit целиком.
- shared/usePersistedQuery.ts (useRoutedQuery) — было устаревшее замыкание:
  эффект навсегда запоминал первую версию onQueryChange, а та замкнута на route
  на момент монтирования, то есть набранный запрос мог уехать в маршрут чужого
  раздела. Теперь зовётся актуальная версия.
- propertyPane/DebugUserField.tsx — то же самое с onResolved.
- Формы: в эффект "новая заявка по умолчанию на себя" дописан context
  (единственный экземпляр на жизнь веб-части, лишних перезапусков не даёт),
  в ReferralForm ещё и мемоизированный approval.
- RequestsTableView: dataKey в зависимости (он и так выводится из view/
  statusFilter/debouncedQuery, которые там уже есть).

Осознанные отступления оставлены с объяснением ПОЧЕМУ: useMatrixEditor (момент
перечитывания матрицы задаёт вызывающий через reloadKey), companiesFieldValue
в RecruitingHire/RecruitingSelection.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 17:11:54 +05:00
gorbenko.pavel 1e265875e2 fix(ServiceRequest): падение просмотра заявки — хук после раннего return
useMemo с attachmentUrls стоял ПОСЛЕ `if (loading) return` — на первом
рендере (загрузка) он не вызывался, на втором вызывался, порядок хуков
менялся, и React ронял компонент с #310 «rendered more hooks than during
the previous render». Карточка заявки на услуги не открывалась вообще.
Перенёс расчёт выше ранних выходов.

Заодно включил `react-hooks/rules-of-hooks` (error) — плагин давно в
зависимостях и в коде есть eslint-disable для exhaustive-deps, то есть
правила подразумевались, но в .eslintrc их забыли объявить. По остальному
коду правило даёт 0 нарушений, так что этот баг был единственным.
`exhaustive-deps` пока оставил выключенным: на текущем коде это 16
предупреждений, их разбор — отдельная задача, а не довесок к фиксу.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 16:49:44 +05:00
gorbenko.pavel 3a71d0df1f Разные фиксы (#8)
Tests / frontend-test (push) Successful in 1m20s
Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz>
Reviewed-on: http://git.tnsu.kz/timur.gorodetskiy/request-portal/pulls/8
2026-08-18 08:45:42 +00:00
Тимур Городецкий bc91c9861d feat: request portal — bespoke forms + approval mechanism 2026-08-03 09:35:14 +05:00