[CL-REACT-DOCTOR-MAILCMP] refactor(MailCompose): чистим 16 react-doctor warnings + smoke-test (100% closure) #116

Merged
andrei merged 1 commit from feature/claude-mail-compose-warnings-cleanup into master 2026-05-21 15:36:27 +00:00
Owner

Что сделано

  • Tailwind 4 size-shorthand на 4 иконках — rule design-no-redundant-size-axes
  • Functional setState pattern для 5 input onChange — rule rerender-functional-setstate
  • Helper splitRecipients(input) с flatMap заменяет 3 inline .map().filter() — rule js-flatmap-filter
  • a11y backdrop: role="button" tabIndex={0} aria-label onKeyDown (Escape close) — rules click-events-have-key-events + no-static-element-interactions
  • a11y modal panel: role="presentation" onKeyDown — те же 2 rules
  • Новый i18n ключ admin.mail.closeBackdrop на 14 локалей
  • Новый smoke test (7 кейсов)

Зачем

Phase 2 react-doctor hygiene #5. 100% closure второй раз подряд (после PR #115). GitNexus impact: LOW risk, 0 upstream callers.

До После
16 warnings 0 warnings
0 errors 0 errors
0 tests 7/7 PASS

План тестирования

  • tsc + eslint + i18n-usage clean
  • vitest 7/7 PASS
  • react-doctor: 16 → 0, app errors=0
  • CI 8/8 expected

Где могу ошибаться

  • splitRecipients поведенчески idempotent (тест проверяет split-trim)
  • Allowance comment для inline handlers verbatim
  • AI переводы non-EN low priority (screen reader only)
  • Backdrop onKeyDown только на Escape — Enter не пробрасывает (consistent UX)
## Что сделано - Tailwind 4 size-shorthand на 4 иконках — rule `design-no-redundant-size-axes` - Functional setState pattern для 5 input onChange — rule `rerender-functional-setstate` - Helper `splitRecipients(input)` с `flatMap` заменяет 3 inline `.map().filter()` — rule `js-flatmap-filter` - a11y backdrop: `role="button" tabIndex={0} aria-label onKeyDown` (Escape close) — rules `click-events-have-key-events` + `no-static-element-interactions` - a11y modal panel: `role="presentation" onKeyDown` — те же 2 rules - Новый i18n ключ `admin.mail.closeBackdrop` на 14 локалей - Новый smoke test (7 кейсов) ## Зачем Phase 2 react-doctor hygiene #5. **100% closure** второй раз подряд (после PR #115). GitNexus impact: **LOW** risk, 0 upstream callers. | До | После | |---|---| | 16 warnings | **0 warnings** | | 0 errors | 0 errors | | 0 tests | 7/7 PASS | ## План тестирования - tsc + eslint + i18n-usage clean - vitest 7/7 PASS - react-doctor: 16 → 0, app errors=0 - CI 8/8 expected ## Где могу ошибаться - `splitRecipients` поведенчески idempotent (тест проверяет split-trim) - Allowance comment для inline handlers verbatim - AI переводы non-EN low priority (screen reader only) - Backdrop onKeyDown только на Escape — Enter не пробрасывает (consistent UX)
[CL-REACT-DOCTOR-MAILCMP] refactor(MailCompose): чистим 16 react-doctor warnings + smoke-test (100% closure)
Some checks failed
React Doctor / React Doctor / App (pull_request) Failing after 622h5m47s
CI / Prisma Migrate Gate (pull_request) Failing after 622h6m38s
CI / Secrets Scan (pull_request) Failing after 622h6m47s
CI / Python SDK (pull_request) Failing after 622h7m15s
CI / Telegram Mini App (pull_request) Failing after 622h7m55s
CI / Contracts (pull_request) Failing after 622h9m22s
CI / App (pull_request) Failing after 622h12m43s
CI / API (pull_request) Failing after 622h15m32s
c8456e2ff6
## Что сделано
- Tailwind 4 size-shorthand на 4 иконках (Send/X header + RefreshCw/Send footer): `w-X h-X` → `size-X` (`design-no-redundant-size-axes`)
- Functional setState pattern для 5 input onChange (`setForm((prev) => ({ ...prev, field: e.target.value }))` вместо `setForm({ ...form, field: ... })`) — rule `rerender-functional-setstate`
- Извлечён helper `splitRecipients(input)` с `flatMap(trim → [trimmed]|[])` pattern, заменяет 3 inline `.split().map(trim).filter(Boolean)` цепочки — rule `js-flatmap-filter`
- a11y backdrop: добавлены `role="button" tabIndex={0} aria-label onKeyDown` (closes на Escape) — rules `click-events-have-key-events` + `no-static-element-interactions` ×2 на L77
- a11y modal panel: добавлены `role="presentation" onKeyDown` (stop propagation) — те же 2 rules на L82
- Новый i18n ключ `admin.mail.closeBackdrop` на 14 локалей
- Новый smoke test `app/src/pages/admin/__tests__/MailCompose.test.tsx` (7 кейсов): render title, close X, backdrop role+aria, size-X invariant, error на empty form, functional setState, sendEmail recipient split

## Зачем
Phase 2 react-doctor hygiene #5. **100% closure** второй раз подряд. GitNexus impact: **LOW** risk, 0 upstream callers.

| До | После |
|---|---|
| 16 warnings | **0 warnings** |
| 0 errors | 0 errors |
| 0 tests | 7/7 PASS |

## План тестирования
- `cd app && npx tsc --noEmit` — clean
- `cd app && npx vitest run src/pages/admin/__tests__/MailCompose.test.tsx` — **7/7 PASS**
- `cd app && npm run test:i18n-usage` — Missing: 0
- `cd app && npx react-doctor . --offline --lint -y --json` → MailCompose 16 → **0**, app errors=0

## Где могу ошибаться
- `splitRecipients` ничего не меняет в behavioral (тест на split-by-comma-semicolon-trim покрывает)
- Allowance comment для inline JSX handlers оставлен (verbatim из original, hygiene scope)
- 14 locale переводов сгенерированы AI — non-EN может потребовать native review (low priority — screen reader only)
- Backdrop onKeyDown реагирует только на Escape — Enter не пробрасывает (consistent с modal UX)
andrei merged commit fe0c37c768 into master 2026-05-21 15:36:27 +00:00
andrei deleted branch feature/claude-mail-compose-warnings-cleanup 2026-05-21 15:36:28 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
europa-tech-srl/europatech!116
No description provided.