diff --git a/CHANGELOG.md b/CHANGELOG.md index e1a093e..7eef56b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.8.5 + +- Исправлена адаптивная компоновка фильтров справочника и скрытие skip-link до клавиатурного фокуса. + ## 0.8.4 - Подключены к конфигурации ограничения массового автоматического увольнения, используемые плановым обходом. diff --git a/README.md b/README.md index 7f6c51f..75caaa6 100644 --- a/README.md +++ b/README.md @@ -135,4 +135,4 @@ node --check app/static/admin.js Тесты с данными используют временную SQLite; отдельные API smoke-тесты запускают приложение с его текущей конфигурацией. Браузерная проверка: `pip install playwright`, `python -m playwright install chromium`, затем `python tests/browser_admin.py`. Она проверяет реальный рендеринг страниц, клавиатуру, диалог, фильтры и восстановление прогресса после ошибки. Скриншоты сохраняются во временную папку; путь выводится в конце. -Версия сервиса: `0.8.4`. Админка всегда показывает версии backend и frontend в footer. +Версия сервиса: `0.8.5`. Админка всегда показывает версии backend и frontend в footer. diff --git a/app/static/admin.css b/app/static/admin.css index b7a045e..efdbed8 100644 --- a/app/static/admin.css +++ b/app/static/admin.css @@ -8,20 +8,19 @@ font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; } -.admin__skip-link { - position: absolute; - top: 8px; - left: 8px; - z-index: 100; - padding: 8px 12px; - color: #ffffff; - background: #0f766e; - transform: translateY(-150%); -} - -.admin__skip-link:focus { - transform: translateY(0); -} +.admin__skip-link { + position: absolute; + top: 8px; + left: -999px; + z-index: 100; + padding: 8px 12px; + color: #ffffff; + background: #0f766e; +} + +.admin__skip-link:focus-visible { + left: 8px; +} .admin__header { display: flex; @@ -544,9 +543,9 @@ color: #6b7280; } -.directory__filters { - display: grid; - grid-template-columns: repeat(4, minmax(0, 1fr)); +.directory__filters { + display: grid; + grid-template-columns: minmax(0, 1.1fr) minmax(0, 2fr) minmax(0, 1.25fr) minmax(0, 2fr); gap: 10px; padding: 16px; background: #ffffff; @@ -554,8 +553,8 @@ border-radius: 8px; } -.directory__filter-group { - display: grid; +.directory__filter-group { + display: grid; grid-template-columns: 1fr; align-content: start; gap: 8px; @@ -586,7 +585,9 @@ font-weight: 700; } -.directory__input { +.directory__input { + box-sizing: border-box; + width: 100%; font: inherit; font-size: 16px; font-weight: 400; @@ -804,13 +805,13 @@ grid-template-columns: 1fr; } - .directory__filter-group, - .directory__filter-group--search, - .directory__filter-actions { - grid-column: 1; - } - - .directory__field { + .directory__filter-group, + .directory__filter-group--search, + .directory__filter-actions { + grid-column: 1; + } + + .directory__field { font-size: 13px; } } diff --git a/app/version.py b/app/version.py index 6b6757f..1b0ac8a 100644 --- a/app/version.py +++ b/app/version.py @@ -1,3 +1,3 @@ -APP_VERSION = "0.8.4" -FRONTEND_VERSION = "0.8.4" -BACKEND_VERSION = "0.8.4" +APP_VERSION = "0.8.5" +FRONTEND_VERSION = "0.8.5" +BACKEND_VERSION = "0.8.5" diff --git a/pyproject.toml b/pyproject.toml index 90feafa..6586745 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "miem-workers" -version = "0.8.4" +version = "0.8.5" description = "MIEM employees parser, admin API, and web admin" requires-python = ">=3.11" dependencies = [ diff --git a/tests/browser_admin.py b/tests/browser_admin.py index 15e6d73..eb7972c 100644 --- a/tests/browser_admin.py +++ b/tests/browser_admin.py @@ -67,6 +67,23 @@ def main(): expect(page.get_by_role("status")).to_have_text("Показаны 26–30 из 30") assert page.locator("th:visible").count() == 5 assert page.locator(".directory__table-wrap").evaluate("e => e.scrollWidth <= e.clientWidth") + skip_link = page.get_by_role("link", name="Перейти к содержимому") + assert skip_link.evaluate("e => getComputedStyle(e).left === '-999px'") + page.keyboard.press("Tab") + expect(skip_link).to_be_focused() + assert skip_link.evaluate("e => getComputedStyle(e).left === '8px'") + page.keyboard.press("Tab") + assert skip_link.evaluate("e => getComputedStyle(e).left === '-999px'") + + for width in (1440, 1024, 921, 920, 768, 621, 620, 390, 320): + page.set_viewport_size({"width": width, "height": 844}) + assert page.locator(".directory__filters").evaluate("e => e.scrollWidth <= e.clientWidth") + assert page.locator(".directory__input").evaluate_all("""controls => controls.every(control => { + const field = control.closest('.directory__field').getBoundingClientRect(); + const rect = control.getBoundingClientRect(); + return rect.left >= field.left - 1 && rect.right <= field.right + 1; + })""") + page.set_viewport_size({"width": 1440, "height": 1000}) page.get_by_label("ФИО или ссылка").fill("Сотрудник 00") page.get_by_role("button", name="Применить фильтры").click() expect(page.get_by_role("status")).to_have_text("Показаны 1–1 из 1") diff --git a/tests/test_api.py b/tests/test_api.py index 6e5d1b9..2b5fb1e 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -18,7 +18,7 @@ def test_health_returns_versions(): response = TestClient(app).get("/api/health") assert response.status_code == 200 - assert response.json()["backend_version"] == "0.8.4" + assert response.json()["backend_version"] == "0.8.5" def test_api_employees_and_stats_require_admin_session():