diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..6c10e4351 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +docs/desktop-regression/screenshots/** linguist-generated=true diff --git a/docs/desktop-regression/PR.md b/docs/desktop-regression/PR.md new file mode 100644 index 000000000..b4955442d --- /dev/null +++ b/docs/desktop-regression/PR.md @@ -0,0 +1,144 @@ + + +## Что изменено + +UI Kit после #401 менял desktop layout, карточки, типографику и расположение действий. При ширине ≥1000 px восстановлена композиция dev до merge #401; mobile/tablet <1000 px сохраняет адаптив и исправления мобильной компоновки, включая светлую нейтральную шапку. + +## Зачем + +Существующий desktop не должен меняться при responsive/UI Kit миграции. Эталон: **5fe4d5c6db435488fffa688d0fa6bd713d6eb7a0**, первый родитель merge #401. Mobile-эталон для этой проверки: **1138fe0cad35a90551be8451b2b2df0d24aacd8f**. + +## Реализация + +- Responsive/UI Kit styles, Card/Field/Form/Filters adapters и общие geometry rules ограничены <1000 px. Desktop Button/Avatar/Icon/PageHeader и consumer styles сохраняют прежние размеры, Mont, отступы и сетки. +- Office, Feed/FeedFilter, проекты/InfoCard, Programs/ProgramCard, Detail профиля/проекта/программы, Members, Vacancies, Courses и оба редактора восстановлены по desktop-эталону. +- DesktopLayoutService управляет presentation-границей. Корни страниц/router outlets, поиск и формы сохраняются при resize; изменяется нужная presentation-разметка. +- Mobile: ровные Detail actions и metadata, компактные карточки, activity над списком, работающие категории, полные навыки и читаемая география программы. +- Pixel comparison gate проверяет **точное RGB совпадение и размеры**; overflow является отдельной проверкой. + +## API + +Не менялся. **Бизнес-логика не изменена**: нет diff в API/domain/infrastructure, DTO, payloads, routes, package/dependencies или backend. Прежние save/autosave/filter services, logout handler, IDs, role conditions, deadlines/status precedence сохранены. + +## UI + +Новый desktop-дизайн не вводился. [Отчёт и воспроизведение](https://github.com/PROCOLLAB-github/procollab/blob/fix/dev-mobile-ui-composition/docs/desktop-regression/README.md), [pixel results](https://github.com/PROCOLLAB-github/procollab/blob/fix/dev-mobile-ui-composition/docs/desktop-regression/comparison-desktop-after.json), [review / AC audit](https://github.com/PROCOLLAB-github/procollab/blob/fix/dev-mobile-ui-composition/docs/desktop-regression/review.md). + +Изменённые shared components: **Button, Icon, Avatar, Loader, Badge, Back, PageHeader, ProfileControlPanel, Tabs**, Card/Field/Form/Filters/Drawer/Dialog/Alert stylesheet adapters; social **Avatar adapter, Bar, Input, Select, Textarea, AutocompleteInput, Search, Checkbox, Dropdown, FileItem, Modal, Switch, Tag, UploadFile**; widgets **Detail, FeedFilter, InfoCard, VacancySkills/Status, ProjectsFilter/VacancyFilter, ProjectInviteDialog, ProjectVacancyCard/VacancyCard, News, RegionSelect, SkillsGroup/SpecializationsGroup, step navigation** и общие style mixins. [Полный список исходных файлов восстановления](https://github.com/PROCOLLAB-github/procollab/blob/fix/dev-mobile-ui-composition/docs/desktop-regression/source-files.json). + +Для прослеживаемости миграции #401 ниже сохранён её исходный список 80 переведённых шаблонов; это список этапа UI Kit, а не число файлов текущего восстановления. + +
+Все 80 переведённых HTML-шаблонов + +1. `projects/social_platform/src/app/ui/pages/auth/email-verification/email-verification.component.html` +2. `projects/social_platform/src/app/ui/pages/auth/login/login.component.html` +3. `projects/social_platform/src/app/ui/pages/auth/register/register.component.html` +4. `projects/social_platform/src/app/ui/pages/auth/reset-password/reset-password.component.html` +5. `projects/social_platform/src/app/ui/pages/auth/set-password/set-password.component.html` +6. `projects/social_platform/src/app/ui/pages/courses/courses.component.html` +7. `projects/social_platform/src/app/ui/pages/courses/lesson/shared/radio-select-task/radio-select-task.component.html` +8. `projects/social_platform/src/app/ui/pages/courses/list/course/course.component.html` +9. `projects/social_platform/src/app/ui/pages/courses/list/list.component.html` +10. `projects/social_platform/src/app/ui/pages/feed/feed.component.html` +11. `projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.html` +12. `projects/social_platform/src/app/ui/pages/members/member-filters-dialog/member-filters-dialog.component.html` +13. `projects/social_platform/src/app/ui/pages/members/members-filters/members-filters.component.html` +14. `projects/social_platform/src/app/ui/pages/members/members.component.html` +15. `projects/social_platform/src/app/ui/pages/office/nav/nav.component.html` +16. `projects/social_platform/src/app/ui/pages/onboarding/stage-zero/stage-zero.component.html` +17. `projects/social_platform/src/app/ui/pages/profile/edit/edit.component.html` +18. `projects/social_platform/src/app/ui/pages/program/detail/analytics/analytics.component.html` +19. `projects/social_platform/src/app/ui/pages/program/detail/analytics/drilldown/analytics-drilldown.component.html` +20. `projects/social_platform/src/app/ui/pages/program/detail/list/list.component.html` +21. `projects/social_platform/src/app/ui/pages/program/detail/list/program-projects-filter/program-projects-filter.component.html` +22. `projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/project-rating/components/boolean-criterion/boolean-criterion.component.html` +23. `projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/project-rating/components/range-criterion-input/range-criterion-input.component.html` +24. `projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/project-rating/project-rating.component.html` +25. `projects/social_platform/src/app/ui/pages/program/detail/main/role-widget/program-role-widget.component.html` +26. `projects/social_platform/src/app/ui/pages/program/detail/register/register.component.html` +27. `projects/social_platform/src/app/ui/pages/program/main/program-card/program-card.component.html` +28. `projects/social_platform/src/app/ui/pages/program/program.component.html` +29. `projects/social_platform/src/app/ui/pages/projects/bar-new/bar.component.html` +30. `projects/social_platform/src/app/ui/pages/projects/detail/info/components/projects-mid-side/projects-mid-side.component.html` +31. `projects/social_platform/src/app/ui/pages/projects/detail/kanban/components/cancel-task-form/cancel-task-form.component.html` +32. `projects/social_platform/src/app/ui/pages/projects/detail/kanban/components/create-board-form/create-board-form.component.html` +33. `projects/social_platform/src/app/ui/pages/projects/detail/kanban/components/create-tag-form/create-tag-form.component.html` +34. `projects/social_platform/src/app/ui/pages/projects/detail/kanban/components/task/detail/task-detail.component.html` +35. `projects/social_platform/src/app/ui/pages/projects/detail/kanban/pages/archive/kanban-archive.component.html` +36. `projects/social_platform/src/app/ui/pages/projects/edit/components/project-achievement-step/project-achievement-step.component.html` +37. `projects/social_platform/src/app/ui/pages/projects/edit/components/project-additional-step/project-additional-step.component.html` +38. `projects/social_platform/src/app/ui/pages/projects/edit/components/project-navigation/project-navigation.component.html` +39. `projects/social_platform/src/app/ui/pages/projects/edit/components/project-team-step/collaborator-card/collaborator-card.component.html` +40. `projects/social_platform/src/app/ui/pages/projects/edit/components/project-team-step/invite-card/invite-card.component.html` +41. `projects/social_platform/src/app/ui/pages/projects/edit/components/project-team-step/project-team-step.component.html` +42. `projects/social_platform/src/app/ui/pages/projects/edit/components/project-vacancy-step/project-vacancy-step.component.html` +43. `projects/social_platform/src/app/ui/pages/projects/edit/edit.component.html` +44. `projects/social_platform/src/app/ui/pages/projects/list/list.component.html` +45. `projects/social_platform/src/app/ui/pages/projects/projects.component.html` +46. `projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancy-responses/vacancy-responses.component.html` +47. `projects/social_platform/src/app/ui/pages/vacancies/detail/info/info.component.html` +48. `projects/social_platform/src/app/ui/pages/vacancies/list/list.component.html` +49. `projects/social_platform/src/app/ui/pages/vacancies/vacancies.component.html` +50. `projects/social_platform/src/app/ui/primitives/bar/bar.component.html` +51. `projects/social_platform/src/app/ui/primitives/checkbox/checkbox.component.html` +52. `projects/social_platform/src/app/ui/primitives/input/input.component.html` +53. `projects/social_platform/src/app/ui/primitives/modal/modal.component.html` +54. `projects/social_platform/src/app/ui/primitives/select/select.component.html` +55. `projects/social_platform/src/app/ui/primitives/upload-file/upload-file.component.html` +56. `projects/social_platform/src/app/ui/widgets/chat-window/chat-window.component.html` +57. `projects/social_platform/src/app/ui/widgets/detail/detail.component.html` +58. `projects/social_platform/src/app/ui/widgets/feed-filter/feed-filter.component.html` +59. `projects/social_platform/src/app/ui/widgets/info-card/info-card.component.html` +60. `projects/social_platform/src/app/ui/widgets/message-input/message-input.component.html` +61. `projects/social_platform/src/app/ui/widgets/news-card/carousel/carousel.component.html` +62. `projects/social_platform/src/app/ui/widgets/news-card/feed-news-modal/feed-news-modal.component.html` +63. `projects/social_platform/src/app/ui/widgets/news-card/feed-news-preview/feed-news-preview.component.html` +64. `projects/social_platform/src/app/ui/widgets/news-form/news-form.component.html` +65. `projects/social_platform/src/app/ui/widgets/project-invite/profile-project-invite-modal.component.html` +66. `projects/social_platform/src/app/ui/widgets/project-invite/project-invite-dialog.component.html` +67. `projects/social_platform/src/app/ui/widgets/project-invite/project-invite-role-input.component.html` +68. `projects/social_platform/src/app/ui/widgets/project-invite/project-member-invite-modal.component.html` +69. `projects/social_platform/src/app/ui/widgets/project-vacancy-card/project-vacancy-card.component.html` +70. `projects/social_platform/src/app/ui/widgets/projects-filter/projects-filter.component.html` +71. `projects/social_platform/src/app/ui/widgets/region-select/region-select.component.html` +72. `projects/social_platform/src/app/ui/widgets/skills-basket/skills-basket.component.html` +73. `projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.html` +74. `projects/social_platform/src/app/ui/widgets/vacancy-created-dialog/vacancy-created-dialog.component.html` +75. `projects/social_platform/src/app/ui/widgets/vacancy-filter/vacancy-filter.component.html` +76. `projects/ui/src/lib/components/primitives/avatar/avatar.component.html` +77. `projects/ui/src/lib/components/primitives/back/back.component.html` +78. `projects/ui/src/lib/components/primitives/button/button.component.html` +79. `projects/ui/src/lib/components/primitives/icon/icon.component.html` +80. `projects/ui/src/lib/components/primitives/loader/loader.component.html` + +
+ +## Permissions + +Не менялись. Existing guards/role conditions/server-owned permissions сохранены; server-side authorization заново не менялась и не аудировалась. + +## Проверки + +- [x] **Checked in browser:** 36 desktop пары (14 экранов + 3 empty states + loading action × 1440/1920), **0 отличающихся RGB-пикселей**. Повтор desktop эталона: 36/36, 0 пикселей. Без masks. +- [x] **Checked in browser:** 42 mobile/tablet пары (14 экранов × 320/390/768), **0 отличающихся RGB-пикселей** относительно mobile-эталона. +- [x] **Checked in browser:** 48 state checks (loading, empty, HTTP 500/retry, disabled, validation), 18 mobile interactions и 6 resize checks через 1000 px. Поиск/filter query/DOM routed roots сохраняются. +- [x] **Checked by tests:** npm run test:ci — 2006 tests / 406 files. Три существующих runner exclusions сохранены. +- [x] **Checked by build:** npm run build:social:prod — успешно, budgets не увеличены. +- [x] **Checked by source/lint:** API/domain/infrastructure/dependencies diff пустой; ESLint 0 errors, 6 существующих warnings; SCSS проверен. + +## Acceptance criteria + +- [x] Desktop ≥1000 сохраняет legacy composition, shared styles не навязывают новую геометрию. +- [x] Ключевые разделы проверены на 1440 и 1920 px **pixel/visual regression**, а не только overflow. +- [x] Mobile/tablet 320/390/768 сохранён, states/interactions повторно проверены. +- [x] API, permissions и бизнес-логика сохранены. + +## Не проверено + +- [ ] Реальные iOS/Android на dev-стенде после merge, перед prod. Доступа к физическим устройствам нет. Найденные проблемы — отдельными PR. +- Полный live backend/role matrix и каждый скрытый scroll section/popup. Снимки фиксируют видимую композицию при viewport height 844 px; внутренний scroll Office не превращается в full-document screenshot. Desktop pixel states включают empty и loading action; остальные состояния проверены mobile state harness. + +## Риски / migration + +Два presentation-каскада сохраняют legacy desktop и responsive mobile, поэтому дальнейшие изменения shared styles требуют обеих pixel matrices. Build содержит Angular/template/CommonJS и component-size warnings, error budgets не увеличены. API/data migration не нужны. PR направлен в dev; production merge/deploy не входят в задачу. **READY TO MERGE INTO DEV** для реализации, device smoke-test остаётся этапом dev acceptance. diff --git a/docs/desktop-regression/README.md b/docs/desktop-regression/README.md new file mode 100644 index 000000000..7267a65b2 --- /dev/null +++ b/docs/desktop-regression/README.md @@ -0,0 +1,113 @@ + + +# Восстановление desktop после #401 + +Desktop ≥1000 px возвращён к визуальному состоянию `dev` до merge #401. +Mobile/tablet <1000 px сохраняет адаптив и исправления мобильной компоновки из #403. +Новый desktop-дизайн в эту задачу не входит. + +- Desktop-эталон: `5fe4d5c6db435488fffa688d0fa6bd713d6eb7a0` — первый родитель merge + `ec57fa7cadb8ca7acef6859380a966a837783495` (#401). +- Mobile-эталон: `1138fe0cad35a90551be8451b2b2df0d24aacd8f` — мобильные исправления #403 до восстановления desktop. +- [Viewer](comparison.html), [desktop JSON](comparison-desktop-after.json), + [mobile JSON](comparison-mobile-after.json), [requirement audit](review.md). + +## Acceptance criteria + +1. Desktop сохраняет прежние layout, композицию, Mont, размеры, отступы и расположение действий. +2. Office, Feed/FeedFilter, проекты/InfoCard, Programs/ProgramCard, Detail профиля/проекта/программы, + Members, Vacancies, Courses, PageHeader и shared Button/Card проверены на 1440 и 1920 px. +3. **Pixel/visual regression — обязательный gate.** Размеры снимков и все RGB-пиксели должны совпадать. + Нет масок и разрешённых исключений. `compare.py --check` возвращает ошибку при любом отличии. + Дополнительная метрика `changedPixels` с допуском 8/255 помогает анализировать diff; + решение PASS использует строгую метрику `exactChangedPixels == 0`. +4. Mobile/tablet сохраняется на 320, 390 и 768 px; проверяются состояния и взаимодействия. +5. API, permissions, payloads, маршруты, бизнес-правила и зависимости сохраняются. + +## Результаты + +| Проверка | Результат | +| -------------------------------------------------------------------- | ------------------------------------------------------------------ | +| Повторный снимок desktop-эталона | 36/36, **0 отличающихся пикселей** | +| Desktop до #401 vs исправление, 1440/1920 | 36/36, **0 отличающихся пикселей** | +| Mobile до восстановления desktop vs исправление, 320/390/768 | 42/42, **0 отличающихся пикселей** | +| Loading, empty, error/retry, disabled, validation и основные разделы | 48 mobile state checks | +| Навигация, фильтры, навыки, карточки, активность и действия Detail | 18 mobile сценариев | +| Переход 390 → 1000 → 768 → 390 | 6 checks: DOM routed roots, поиск и query фильтра сохраняются | +| Unit tests | 2006 tests / 406 files; 3 существующих исключения runner сохранены | +| Production build | Успешно, бюджеты не увеличены | +| TypeScript lint | 0 errors, 6 существующих warnings | + +14 обычных экранов × 2 desktop-ширины + 3 empty-состояния × 2 ширины + loading action × 2 ширины = 36 пар. +Mobile: 14 экранов × 3 ширины = 42 пары. + +Экраны: Feed/Office/FeedFilter, Projects dashboard, My projects, Members, Programs, Program Detail, +Profile Detail, Project Detail, Vacancies, Vacancy Detail, Courses, Course Detail, +Profile editor, Project editor. Desktop states: empty Feed, Vacancies, Courses и loading action урока. +Все пары доступны в [viewer](comparison.html) и каталогах screenshots/desktop-before, +screenshots/desktop-after, screenshots/mobile-before, screenshots/mobile-after. + +## Реализация и shared компоненты + +Новые responsive/UI Kit правила ограничены `<1000px`. Для desktop восстановлены прежние +consumer styles и нужные фрагменты разметки. Общие `.ui-card`, `.ui-form`, `.ui-filters`, +`.ui-field` и остальные адаптеры на desktop не задают новую геометрию. +Нативные кнопки имеют нейтральный reset с нулевой specificity; размеры задают прежние consumers. + +`DesktopLayoutService` задаёт одну presentation-границу. Корни страниц, router outlets, +поиск и формы сохраняются при изменении ширины; переключаются presentation-фрагменты. +Desktop Avatar в social platform использует прежнюю рамку/обёртку, наследуя input API canonical Avatar. +Стили полей сохраняют исходный порядок CSS: отступы модификаторов не перекрываются media-блоком. + +- `@uilib`: Button, Icon, Avatar, Loader, Badge, Back, PageHeader, ProfileControlPanel, Tabs; + DesktopLayoutService. Card/Field/Form/Filters/Drawer/Dialog/Alert adapters — scoped stylesheet. +- Social primitives: Avatar compatibility adapter, Bar, Input, Select, Textarea, AutocompleteInput, + Search, Checkbox, Dropdown, FileItem, Modal, Switch, Tag, UploadFile. +- Shared widgets: Detail, FeedFilter, InfoCard, VacancySkills/Status, ProjectsFilter/VacancyFilter, + ProjectInviteDialog, ProjectVacancyCard/VacancyCard, News components, RegionSelect, + SkillsGroup/SpecializationsGroup; общие typography/feed/vacancy/responsive mixins. +- Step navigation проекта/профиля: прежняя desktop-разметка и мобильный Tabs ниже 1000 px. + +## Воспроизведение + +Нужны те же установленные зависимости, Playwright, Chrome, Python с Pillow и NumPy. +`PLAYWRIGHT_MODULE` и `CHROME_PATH` указывают на установленный модуль и браузер. + +Собрать production из desktop-эталона, mobile-эталона и текущей ветки в отдельных каталогах. +Раздавать их через `node docs/desktop-regression/serve.cjs `: +desktop reference — 4431, mobile reference — 4432, исправление — 4433. +Для state/interaction/resize scripts раздать исправление также на 4360. + +```powershell +node docs/desktop-regression/capture.cjs desktop-before http://localhost:4431 +node docs/desktop-regression/capture.cjs desktop-repeat http://localhost:4431 +node docs/desktop-regression/capture.cjs desktop-after http://localhost:4433 +# Повторить для всех трёх desktop фаз: +node docs/desktop-regression/capture.cjs desktop-before http://localhost:4431 1440,1920 edit +node docs/desktop-regression/capture-states.cjs desktop-before http://localhost:4431 +node docs/desktop-regression/capture-loading.cjs desktop-before http://localhost:4431 +node docs/desktop-regression/capture.cjs mobile-before http://localhost:4432 320,390,768 +node docs/desktop-regression/capture.cjs mobile-after http://localhost:4433 320,390,768 +# Повторить для обеих mobile фаз: +node docs/desktop-regression/capture.cjs mobile-before http://localhost:4432 320,390,768 edit +python docs/desktop-regression/compare.py desktop-before desktop-repeat --check +python docs/desktop-regression/compare.py desktop-before desktop-after --check +python docs/desktop-regression/compare.py mobile-before mobile-after --check +node docs/desktop-regression/states.cjs +node docs/desktop-regression/interactions.cjs +node docs/desktop-regression/resize.cjs +npm run test:ci +npm run build:social:prod +npm run lint:ts +``` + +Синтетические API fixtures одинаковы для каждой пары, clock фиксирован, Mont загружен, +animations/transitions отключены, браузер и device scale одинаковые. API запросы перехватываются; +реальный backend не изменяется. Повтор эталона проверяет детерминизм. + +Снимки показывают видимую композицию при высоте viewport 844 px. Office использует внутренний +scroll; `fullPage` не означает снимок всех скрытых областей scroll-контейнера. Динамический backend, +все роли и все возможные данные этим набором не исчерпываются. + +Реальные iOS/Android на dev-стенде **не проверены**: нет доступа к физическим устройствам. +После merge требуется device smoke-test перед prod; найденные проблемы — отдельными PR. diff --git a/docs/desktop-regression/build.log b/docs/desktop-regression/build.log new file mode 100644 index 000000000..0ce69b396 --- /dev/null +++ b/docs/desktop-regression/build.log @@ -0,0 +1,2454 @@ + +> procollab@0.0.0 build:social:prod +> npm run build:sprite && ng build social_platform --configuration=production + + +> procollab@0.0.0 build:sprite +> svg-sprite -s --dest=projects/social_platform/src/assets/icons "projects/social_platform/src/assets/icons/svg/**/*.svg" + +> Building... +√ Building... +Initial chunk files | Names | Raw size | Estimated transfer size +chunk-3CG57ZN5.js | - | 435.93 kB | 73.95 kB +chunk-EMX2ZQ7G.js | - | 213.04 kB | 60.81 kB +main-O2SWNA4H.js | main | 207.24 kB | 53.23 kB +styles-JB553RZJ.css | styles | 133.36 kB | 12.17 kB +chunk-32JCLU4R.js | - | 111.30 kB | 28.30 kB +chunk-FQQXBL2D.js | - | 83.07 kB | 25.83 kB +chunk-V2IJE6ER.js | - | 72.83 kB | 16.82 kB +chunk-YIH7FSUZ.js | - | 63.35 kB | 12.16 kB +chunk-SEBII2ES.js | - | 42.79 kB | 8.66 kB +chunk-DGTRQFRV.js | - | 29.13 kB | 5.34 kB +chunk-Q6NJS6MG.js | - | 27.24 kB | 7.03 kB +chunk-WYGUCQ2H.js | - | 11.43 kB | 2.59 kB +chunk-DN3CBCVF.js | - | 8.34 kB | 2.56 kB +chunk-JL552RI3.js | - | 4.30 kB | 1.19 kB +chunk-J63M22RD.js | - | 4.04 kB | 1.47 kB +chunk-N7P262YB.js | - | 3.19 kB | 1.27 kB +chunk-GYIMPQDO.js | - | 3.02 kB | 1.14 kB +chunk-JP4HTDU5.js | - | 1.47 kB | 386 bytes +chunk-VOSPIT4N.js | - | 1.22 kB | 521 bytes +chunk-UMKP35NR.js | - | 695 bytes | 695 bytes +chunk-JHUOFMVX.js | - | 483 bytes | 483 bytes +chunk-ZTXJLEZP.js | - | 474 bytes | 474 bytes +chunk-IAS7Y3HI.js | - | 465 bytes | 465 bytes +chunk-4WVOMZ3C.js | - | 352 bytes | 352 bytes +chunk-Y7FCNQPS.js | - | 195 bytes | 195 bytes +chunk-RQDRLMC2.js | - | 180 bytes | 180 bytes +chunk-W2ZPBHP5.js | - | 160 bytes | 160 bytes +chunk-N7PJCV3T.js | - | 128 bytes | 128 bytes +chunk-DKVRXEF2.js | - | 127 bytes | 127 bytes +chunk-PY5GJ2VA.js | - | 51 bytes | 51 bytes +chunk-GDMD5RKS.js | - | 51 bytes | 51 bytes +chunk-NCHAAQO5.js | - | 30 bytes | 30 bytes +chunk-KTRLVWC3.js | - | 30 bytes | 30 bytes +chunk-CRTRRB5R.js | - | 30 bytes | 30 bytes +chunk-PKT6RRYE.js | - | 30 bytes | 30 bytes +chunk-YIJ4Z6S4.js | - | 30 bytes | 30 bytes +chunk-KEPWQ2XV.js | - | 30 bytes | 30 bytes +chunk-FE3JRQRM.js | - | 30 bytes | 30 bytes +chunk-GAELZNYR.js | - | 25 bytes | 25 bytes +chunk-4CQUPGHG.js | - | 25 bytes | 25 bytes +chunk-PPZSTFUD.js | - | 25 bytes | 25 bytes +chunk-UYXSSEQD.js | - | 25 bytes | 25 bytes +chunk-FI4DW6KU.js | - | 25 bytes | 25 bytes +chunk-25HWN6II.js | - | 25 bytes | 25 bytes +chunk-SVFKPVOL.js | - | 25 bytes | 25 bytes +chunk-CRUTENDI.js | - | 0 bytes | 0 bytes +chunk-S7EUWH5W.js | - | 0 bytes | 0 bytes + + | Initial total | 1.46 MB | 319.19 kB + +Lazy chunk files | Names | Raw size | Estimated transfer size +chunk-M3GFW3BB.js | detail-routes | 275.03 kB | 42.16 kB +chunk-6VIOOPBT.js | onboarding-routes | 113.25 kB | 15.06 kB +chunk-DGDJLME2.js | office-routes | 111.68 kB | 19.67 kB +chunk-BEFPGAFR.js | detail-routes | 92.27 kB | 16.92 kB +chunk-ACE7VP46.js | lesson-routes | 85.07 kB | 10.96 kB +chunk-FKCA4C6N.js | - | 83.92 kB | 16.36 kB +chunk-ZOBCXQ4X.js | projects-routes | 79.38 kB | 14.50 kB +chunk-OM7RVM2H.js | - | 72.50 kB | 13.57 kB +chunk-AJJJSWEY.js | index | 72.43 kB | 17.54 kB +chunk-AMVSDNEL.js | auth-routes | 71.06 kB | 9.72 kB +chunk-K5BP25SC.js | feed-routes | 47.71 kB | 7.69 kB +chunk-JDJBBXO4.js | vacancies-detail-routes | 45.38 kB | 8.95 kB +chunk-SXNPXFOC.js | profile-detail-routes | 40.98 kB | 7.75 kB +chunk-BJAXUOYJ.js | course-detail-routes | 40.92 kB | 7.16 kB +chunk-KBPUUHZY.js | project-team-step-component | 40.76 kB | 8.14 kB +...and 88 more lazy chunks files. Use "--verbose" to show all the files. + +Application bundle generation complete. [23.899 seconds] - 2026-10-05T12:33:34.917Z + +▲ [WARNING] 23 repetitive deprecation warnings omitted. +Run in verbose mode to see all warnings. [plugin angular-sass] + + null + + +▲ [WARNING] 1 repetitive deprecation warnings omitted. +Run in verbose mode to see all warnings. [plugin angular-sass] + + null + + +▲ [WARNING] 6 repetitive deprecation warnings omitted. +Run in verbose mode to see all warnings. [plugin angular-sass] + + null + + +▲ [WARNING] 3 repetitive deprecation warnings omitted. +Run in verbose mode to see all warnings. [plugin angular-sass] + + null + + +▲ [WARNING] 32 repetitive deprecation warnings omitted. +Run in verbose mode to see all warnings. [plugin angular-sass] + + null + + +▲ [WARNING] 4 repetitive deprecation warnings omitted. +Run in verbose mode to see all warnings. [plugin angular-sass] + + null + + +▲ [WARNING] 4 repetitive deprecation warnings omitted. +Run in verbose mode to see all warnings. [plugin angular-sass] + + null + + +▲ [WARNING] 3 repetitive deprecation warnings omitted. +Run in verbose mode to see all warnings. [plugin angular-sass] + + null + + +▲ [WARNING] 24 repetitive deprecation warnings omitted. +Run in verbose mode to see all warnings. [plugin angular-sass] + + null + + +▲ [WARNING] 9 repetitive deprecation warnings omitted. +Run in verbose mode to see all warnings. [plugin angular-sass] + + null + + +▲ [WARNING] 3 repetitive deprecation warnings omitted. +Run in verbose mode to see all warnings. [plugin angular-sass] + + null + + +▲ [WARNING] 12 repetitive deprecation warnings omitted. +Run in verbose mode to see all warnings. [plugin angular-sass] + + null + + +▲ [WARNING] 5 repetitive deprecation warnings omitted. +Run in verbose mode to see all warnings. [plugin angular-sass] + + null + + +▲ [WARNING] 2 repetitive deprecation warnings omitted. +Run in verbose mode to see all warnings. [plugin angular-sass] + + null + + +▲ [WARNING] NG8113: BackComponent is not used within the template of CoursesComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/courses/courses.component.ts:19:4: + 19 │ BackComponent, + ╵ ~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.html:9:67: + 9 │ ...card__photo" [url]="member().personal?.avatar || ''" [size]="70" /> + ╵ ~~~~~~ + + Warning occurs in the template of component MemberCardComponent. + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.ts:16:15: + 16 │ templateUrl: "./member-card.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.html:15:66: + 15 │ ...er-card__secondary" [title]="member().personal?.speciality || ''"> + ╵ ~~~~~~~~~~ + + Warning occurs in the template of component MemberCardComponent. + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.ts:16:15: + 16 │ templateUrl: "./member-card.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.html:16:28: + 16 │ {{ member().personal?.speciality }} + ╵ ~~~~~~~~~~ + + Warning occurs in the template of component MemberCardComponent. + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.ts:16:15: + 16 │ templateUrl: "./member-card.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.html:17:30: + 17 │ @if (member().personal?.birthday; as birthday) { + ╵ ~~~~~~~~ + + Warning occurs in the template of component MemberCardComponent. + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.ts:16:15: + 16 │ templateUrl: "./member-card.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.html:18:30: + 18 │ {{ member().personal?.speciality ? " • " : "" }}{{ birth... + ╵ ~~~~~~~~~~ + + Warning occurs in the template of component MemberCardComponent. + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.ts:16:15: + 16 │ templateUrl: "./member-card.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: DialogFooterDirective is not used within the template of MemberFiltersDialogComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/members/member-filters-dialog/member-filters-dialog.component.ts:37:4: + 37 │ DialogFooterDirective, + ╵ ~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: ProfileInfoComponent is not used within the template of NavComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/office/nav/nav.component.ts:82:4: + 82 │ ProfileInfoComponent, + ╵ ~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: AlertDirective is not used within the template of SnackbarComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/office/snackbar/snackbar.component.ts:37:12: + 37 │ imports: [AlertDirective, CommonModule, IconComponent], + ╵ ~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/onboarding/stage-zero/stage-zero.component.html:435:45: + 435 │ ... @if (achievements.at(i)?.get("title"); as title) { + ╵ ~~~ + + Warning occurs in the template of component OnboardingStageZeroComponent. + + projects/social_platform/src/app/ui/pages/onboarding/stage-zero/stage-zero.component.ts:23:15: + 23 │ templateUrl: "./stage-zero.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8102: The left side of this nullish coalescing operation does not include 'null' or 'undefined' in its type, therefore the '??' operator can be safely removed. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-left-side/profile-left-side.component.html:28:15: + 28 │ ... {{ user()!.personal.speciality ?? "не указана" }} + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Warning occurs in the template of component ProfileLeftSideComponent. + + projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-left-side/profile-left-side.component.ts:23:15: + 23 │ templateUrl: "./profile-left-side.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: TruncatePipe is not used within the template of ProfileLeftSideComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-left-side/profile-left-side.component.ts:25:78: + 25 │ ...RouterModule, IconComponent, YearsFromBirthdayPipe, TruncatePipe], + ╵ ~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: TruncatePipe is not used within the template of ProfileRightSideComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-right-side/profile-right-side.component.ts:32:4: + 32 │ TruncatePipe, + ╵ ~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: UploadFileComponent is not used within the template of ProfileMainStepComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/profile/edit/components/profile-main-step/profile-main-step.component.ts:33:4: + 33 │ UploadFileComponent, + ╵ ~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/program/detail/list/list.component.html:95:52: + 95 │ ... [isSubscribed]="profileProjSubsIds()?.includes(listItem.id)" + ╵ ~~~~~~~~ + + Warning occurs in the template of component ProgramListComponent. + + projects/social_platform/src/app/ui/pages/program/detail/list/list.component.ts:40:15: + 40 │ templateUrl: "./list.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/program/detail/list/list.component.html:103:54: + 103 │ ... [isSubscribed]="profileProjSubsIds()?.includes(listItem.id)" + ╵ ~~~~~~~~ + + Warning occurs in the template of component ProgramListComponent. + + projects/social_platform/src/app/ui/pages/program/detail/list/list.component.ts:40:15: + 40 │ templateUrl: "./list.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/program/detail/main/main.component.html:73:64: + 73 │ ...)!.isUserMember && program()!.links?.length && program()!.links) { + ╵ ~~~~~~ + + Warning occurs in the template of component ProgramDetailMainComponent. + + projects/social_platform/src/app/ui/pages/program/detail/main/main.component.ts:38:15: + 38 │ templateUrl: "./main.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/program/detail/main/main.component.html:82:68: + 82 │ ... @if (program()!.isUserMember && program()!.materials?.length) { + ╵ ~~~~~~ + + Warning occurs in the template of component ProgramDetailMainComponent. + + projects/social_platform/src/app/ui/pages/program/detail/main/main.component.ts:38:15: + 38 │ templateUrl: "./main.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: BackComponent is not used within the template of ProgramComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/program/program.component.ts:22:4: + 22 │ BackComponent, + ╵ ~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: MessageInputComponent is not used within the template of ProjectChatComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/detail/chat/chat.component.ts:34:4: + 34 │ MessageInputComponent, + ╵ ~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-achievement-step/project-achievement-step.component.html:10:39: + 10 │ ... @if (achievements.at(i)?.get("title"); as achievementsName) { + ╵ ~~~ + + Warning occurs in the template of component ProjectAchievementStepComponent. + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-achievement-step/project-achievement-step.component.ts:17:15: + 17 │ templateUrl: "./project-achievement-step.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-main-step/project-main-step.component.html:315:32: + 315 │ @if (goals.at(i)?.get("title"); as goalName) { + ╵ ~~~ + + Warning occurs in the template of component ProjectMainStepComponent. + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-main-step/project-main-step.component.ts:39:15: + 39 │ templateUrl: "./project-main-step.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-main-step/project-main-step.component.html:331:32: + 331 │ @if (goals.at(i)?.get("completionDate"); as goalDat... + ╵ ~~~ + + Warning occurs in the template of component ProjectMainStepComponent. + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-main-step/project-main-step.component.ts:39:15: + 39 │ templateUrl: "./project-main-step.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-main-step/project-main-step.component.html:353:32: + 353 │ @if (goals.at(i)?.get("responsible"); as goalLeader) { + ╵ ~~~ + + Warning occurs in the template of component ProjectMainStepComponent. + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-main-step/project-main-step.component.ts:39:15: + 39 │ templateUrl: "./project-main-step.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.html:11:37: + 11 │ @if (partners.at(i)?.get("name"); as name) { + ╵ ~~~ + + Warning occurs in the template of component ProjectPartnerResourcesStepComponent. + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.ts:20:15: + 20 │ templateUrl: "./project-partner-resources-step.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.html:27:37: + 27 │ @if (partners.at(i)?.get("inn"); as inn) { + ╵ ~~~ + + Warning occurs in the template of component ProjectPartnerResourcesStepComponent. + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.ts:20:15: + 20 │ templateUrl: "./project-partner-resources-step.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.html:46:35: + 46 │ ... @if (partners.at(i)?.get("contribution"); as contribut... + ╵ ~~~ + + Warning occurs in the template of component ProjectPartnerResourcesStepComponent. + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.ts:20:15: + 20 │ templateUrl: "./project-partner-resources-step.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.html:63:35: + 63 │ ... @if (partners.at(i)?.get("decisionMaker"); as decision... + ╵ ~~~ + + Warning occurs in the template of component ProjectPartnerResourcesStepComponent. + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.ts:20:15: + 20 │ templateUrl: "./project-partner-resources-step.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.html:116:36: + 116 │ @if (resources.at(i)?.get("type"); as type) { + ╵ ~~~ + + Warning occurs in the template of component ProjectPartnerResourcesStepComponent. + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.ts:20:15: + 20 │ templateUrl: "./project-partner-resources-step.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.html:133:36: + 133 │ ... @if (resources.at(i)?.get("description"); as descripti... + ╵ ~~~ + + Warning occurs in the template of component ProjectPartnerResourcesStepComponent. + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.ts:20:15: + 20 │ templateUrl: "./project-partner-resources-step.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.html:150:36: + 150 │ ... @if (resources.at(i)?.get("partnerCompany"); as partne... + ╵ ~~~ + + Warning occurs in the template of component ProjectPartnerResourcesStepComponent. + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.ts:20:15: + 20 │ templateUrl: "./project-partner-resources-step.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8109: isFilterOpen is a function and should be invoked: isFilterOpen() [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/projects.component.html:118:73: + 118 │ ...="filter page__filter" [class.page__filter--open]="isFilterOpen"> + ╵ ~~~~~~~~~~~~ + + Warning occurs in the template of component ProjectsComponent. + + projects/social_platform/src/app/ui/pages/projects/projects.component.ts:33:15: + 33 │ templateUrl: "./projects.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-left-side/vacancies-left-side.component.html:7:29: + 7 │ @if (item.description?.trim()) { + ╵ ~~~~ + + Warning occurs in the template of component VacanciesLeftSideComponent. + + projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-left-side/vacancies-left-side.component.ts:9:15: + 9 │ templateUrl: "./vacancies-left-side.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-right-side/vacancies-right-side.component.html:57:23: + 57 │ @if (item.project?.links?.length) { + ╵ ~~~~~ + + Warning occurs in the template of component VacanciesRightSideComponent. + + projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-right-side/vacancies-right-side.component.ts:14:15: + 14 │ templateUrl: "./vacancies-right-side.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: BackComponent is not used within the template of VacanciesComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/vacancies/vacancies.component.ts:27:4: + 27 │ BackComponent, + ╵ ~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: CardDirective is not used within the template of NewsCardComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/widgets/news-card/news-card.component.ts:58:4: + 58 │ CardDirective, + ╵ ~~~~~~~~~~~~~ + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/auth/login/login.component.scss:29:4: + 29 │ padding-left: 10px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/courses/list/course/course.component.scss:14:2: + 14 │ position: relative; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/courses/list/course/course.component.scss:15:2: + 15 │ width: 100%; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/courses/list/course/course.component.scss:16:2: + 16 │ max-width: 333px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/courses/list/course/course.component.scss:17:2: + 17 │ overflow: hidden; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/courses/list/course/course.component.scss:18:2: + 18 │ cursor: pointer; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.scss:16:2: + 16 │ position: relative; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.scss:17:2: + 17 │ box-sizing: border-box; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.scss:18:2: + 18 │ display: block; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.scss:19:2: + 19 │ width: 156px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.scss:20:2: + 20 │ height: 248px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/office/nav/nav.component.scss:42:4: + 42 │ max-width: responsive.$container-md; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/office/nav/nav.component.scss:42:4: + 42 │ max-width: responsive.$container-md; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/office/nav/nav.component.scss:42:4: + 42 │ max-width: responsive.$container-md; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/office/nav/nav.component.scss:42:4: + 42 │ max-width: responsive.$container-md; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/office/nav/nav.component.scss:42:4: + 42 │ max-width: responsive.$container-md; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/office/office.component.scss:51:4: + 51 │ align-items: center; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/office/office.component.scss:51:4: + 51 │ align-items: center; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/office/office.component.scss:51:4: + 51 │ align-items: center; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/office/office.component.scss:52:4: + 52 │ justify-content: space-between; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/office/office.component.scss:52:4: + 52 │ justify-content: space-between; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/program/detail/list/list.component.scss:295:2: + 295 │ max-height: calc(100vh - 40px); + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/program/detail/list/list.component.scss:295:2: + 295 │ max-height: calc(100vh - 40px); + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/program/detail/list/list.component.scss:295:2: + 295 │ max-height: calc(100vh - 40px); + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/program/detail/list/list.component.scss:295:2: + 295 │ max-height: calc(100vh - 40px); + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/program/detail/list/list.component.scss:305:2: + 305 │ overflow-y: auto; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/projects/detail/team/team.component.scss:28:6: + 28 │ row-gap: 48px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-additional-step/project-additional-step.component.scss:24:2: + 24 │ position: relative; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/projects/edit/edit.component.scss:153:2: + 153 │ display: flex; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/projects/edit/edit.component.scss:154:2: + 154 │ flex-direction: column; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/projects/edit/edit.component.scss:155:2: + 155 │ align-items: center; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/projects/edit/edit.component.scss:156:2: + 156 │ justify-content: center; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/projects/edit/edit.component.scss:157:2: + 157 │ width: 80%; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-right-side/vacancies-right-side.component.scss:43:4: + 43 │ flex-direction: column; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-right-side/vacancies-right-side.component.scss:43:4: + 43 │ flex-direction: column; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-right-side/vacancies-right-side.component.scss:44:4: + 44 │ margin-top: 20px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-right-side/vacancies-right-side.component.scss:44:4: + 44 │ margin-top: 20px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-right-side/vacancies-right-side.component.scss:73:4: + 73 │ line-height: 20px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancy-responses/vacancy-responses.component.scss:81:2: + 81 │ display: flex; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancy-responses/vacancy-responses.component.scss:81:2: + 81 │ display: flex; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancy-responses/vacancy-responses.component.scss:82:2: + 82 │ flex-direction: column; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancy-responses/vacancy-responses.component.scss:82:2: + 82 │ flex-direction: column; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancy-responses/vacancy-responses.component.scss:83:2: + 83 │ gap: 16px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/vacancies/detail/vacancies-detail.component.scss:21:4: + 21 │ margin-bottom: 20px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/vacancies/detail/vacancies-detail.component.scss:21:4: + 21 │ margin-bottom: 20px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/vacancies/detail/vacancies-detail.component.scss:72:4: + 72 │ line-height: 20px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/vacancies/detail/vacancies-detail.component.scss:72:4: + 72 │ line-height: 20px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/vacancies/list/response-card/response-card.component.scss:53:4: + 53 │ line-height: 20px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/vacancies/list/response-card/response-card.component.scss:53:4: + 53 │ line-height: 20px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/autocomplete-input/autocomplete-input.component.scss:54:8: + 54 │ + &_arrow { + ╵ ^ + + + The selector "+ .field__input-slim:focus_arrow" is invalid CSS. + This will be an error in Dart Sass 2.0.0. + + More info: https://sass-lang.com/d/bogus-combinators + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/autocomplete-input/autocomplete-input.component.scss:57:10: + 57 │ i { + ╵ ^ + + + The selector "+ .field__input-slim:focus_arrow i" is invalid CSS. + This will be an error in Dart Sass 2.0.0. + + More info: https://sass-lang.com/d/bogus-combinators + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/autocomplete-input/autocomplete-input.component.scss:271:8: + 271 │ +&_arrow { + ╵ ^ + + + The selector "+ .field__input-slim:focus_arrow" is invalid CSS. + This will be an error in Dart Sass 2.0.0. + + More info: https://sass-lang.com/d/bogus-combinators + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/autocomplete-input/autocomplete-input.component.scss:274:10: + 274 │ i { + ╵ ^ + + + The selector "+ .field__input-slim:focus_arrow i" is invalid CSS. + This will be an error in Dart Sass 2.0.0. + + More info: https://sass-lang.com/d/bogus-combinators + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/checkbox/checkbox.component.scss:11:2: + 11 │ position: relative; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/checkbox/checkbox.component.scss:12:2: + 12 │ display: flex; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/checkbox/checkbox.component.scss:13:2: + 13 │ align-items: center; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/checkbox/checkbox.component.scss:14:2: + 14 │ justify-content: center; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/checkbox/checkbox.component.scss:15:2: + 15 │ width: 20px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/modal/modal.component.scss:76:4: + 76 │ background: var(--white); + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/modal/modal.component.scss:76:4: + 76 │ background: var(--white); + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/modal/modal.component.scss:76:4: + 76 │ background: var(--white); + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/modal/modal.component.scss:76:4: + 76 │ background: var(--white); + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/modal/modal.component.scss:76:4: + 76 │ background: var(--white); + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/tag/tag.component.scss:11:2: + 11 │ position: relative; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/tag/tag.component.scss:12:2: + 12 │ display: flex; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/tag/tag.component.scss:13:2: + 13 │ align-items: center; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/tag/tag.component.scss:14:2: + 14 │ justify-content: center; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/tag/tag.component.scss:15:2: + 15 │ width: 100%; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/textarea/textarea.component.scss:60:6: + 60 │ border-radius: var(--ui-radius-card); + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/textarea/textarea.component.scss:60:6: + 60 │ border-radius: var(--ui-radius-card); + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/textarea/textarea.component.scss:60:6: + 60 │ border-radius: var(--ui-radius-card); + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/textarea/textarea.component.scss:60:6: + 60 │ border-radius: var(--ui-radius-card); + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/textarea/textarea.component.scss:60:6: + 60 │ border-radius: var(--ui-radius-card); + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/info-card/info-card.component.scss:12:4: + 12 │ position: relative; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/info-card/info-card.component.scss:13:4: + 13 │ display: flex; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/info-card/info-card.component.scss:14:4: + 14 │ flex-direction: column; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/info-card/info-card.component.scss:15:4: + 15 │ width: 156px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/info-card/info-card.component.scss:96:4: + 96 │ width: 100%; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/news-card/feed-news-preview/feed-news-preview.component.scss:16:2: + 16 │ cursor: pointer; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/project-vacancy-card/project-vacancy-card.component.scss:19:2: + 19 │ display: flex; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/project-vacancy-card/project-vacancy-card.component.scss:19:2: + 19 │ display: flex; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/project-vacancy-card/project-vacancy-card.component.scss:19:2: + 19 │ display: flex; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/project-vacancy-card/project-vacancy-card.component.scss:20:2: + 20 │ flex: 1; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/project-vacancy-card/project-vacancy-card.component.scss:20:2: + 20 │ flex: 1; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.scss:17:2: + 17 │ display: flex; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.scss:18:2: + 18 │ flex-direction: column; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.scss:19:2: + 19 │ gap: 16px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.scss:20:2: + 20 │ height: 100%; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/vacancy-created-dialog/vacancy-created-dialog.component.scss:52:4: + 52 │ flex-direction: column; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/vacancy-created-dialog/vacancy-created-dialog.component.scss:52:4: + 52 │ flex-direction: column; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/vacancy-created-dialog/vacancy-created-dialog.component.scss:53:4: + 53 │ margin-top: 20px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/vacancy-created-dialog/vacancy-created-dialog.component.scss:53:4: + 53 │ margin-top: 20px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/vacancy-skills/vacancy-skills.component.scss:33:4: + 33 │ padding: 4px 10px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/vacancy-skills/vacancy-skills.component.scss:33:4: + 33 │ padding: 4px 10px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/vacancy-skills/vacancy-skills.component.scss:34:4: + 34 │ font: inherit; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/vacancy-skills/vacancy-skills.component.scss:34:4: + 34 │ font: inherit; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/vacancy-skills/vacancy-skills.component.scss:44:4: + 44 │ line-height: 18px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/ui/src/lib/components/primitives/button/button.component.scss:44:2: + 44 │ position: relative; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/ui/src/lib/components/primitives/button/button.component.scss:44:2: + 44 │ position: relative; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/styles.scss:9:8: + 9 │ @import "styles/colors.scss"; + ╵ ^ + + + Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0. + + More info and automated migrator: https://sass-lang.com/d/import + + The plugin "angular-sass" was triggered by this import + + angular:styles/global:styles:1:8: + 1 │ @import 'projects/social_platform/src/styles.scss'; + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/styles.scss:10:8: + 10 │ @import "styles/global.scss"; + ╵ ^ + + + Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0. + + More info and automated migrator: https://sass-lang.com/d/import + + The plugin "angular-sass" was triggered by this import + + angular:styles/global:styles:1:8: + 1 │ @import 'projects/social_platform/src/styles.scss'; + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/styles.scss:11:8: + 11 │ @import "styles/responsive.scss"; + ╵ ^ + + + Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0. + + More info and automated migrator: https://sass-lang.com/d/import + + The plugin "angular-sass" was triggered by this import + + angular:styles/global:styles:1:8: + 1 │ @import 'projects/social_platform/src/styles.scss'; + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/styles.scss:12:8: + 12 │ @import "styles/rounded.scss"; + ╵ ^ + + + Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0. + + More info and automated migrator: https://sass-lang.com/d/import + + The plugin "angular-sass" was triggered by this import + + angular:styles/global:styles:1:8: + 1 │ @import 'projects/social_platform/src/styles.scss'; + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/styles.scss:13:8: + 13 │ @import "styles/typography.scss"; + ╵ ^ + + + Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0. + + More info and automated migrator: https://sass-lang.com/d/import + + The plugin "angular-sass" was triggered by this import + + angular:styles/global:styles:1:8: + 1 │ @import 'projects/social_platform/src/styles.scss'; + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] 11 repetitive deprecation warnings omitted. +Run in verbose mode to see all warnings. [plugin angular-sass] + + angular:styles/global:styles:1:8: + 1 │ @import 'projects/social_platform/src/styles.scss'; + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + null + + +▲ [WARNING] bundle initial exceeded maximum budget. Budget 500.00 kB was not met by 960.04 kB with a total of 1.46 MB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/profile/edit/components/profile-achievements-step/profile-achievements-step.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 489 bytes with a total of 2.49 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/profile/edit/components/profile-experience-step/profile-experience-step.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 407 bytes with a total of 2.41 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/news-card/feed-news-modal/feed-news-modal.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 1.48 kB with a total of 3.48 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/feed/new-project/new-project.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.42 kB with a total of 6.42 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/projects-filter/projects-filter.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.71 kB with a total of 5.71 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/news-card/feed-news-preview/feed-news-preview.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 7.66 kB with a total of 9.66 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-left-side/profile-left-side.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 1.42 kB with a total of 3.42 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/onboarding/stage-three/user-type-card/user-type-card.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.66 kB with a total of 4.66 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/program/detail/analytics/drilldown/analytics-drilldown.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 8.95 kB with a total of 10.95 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-right-side/vacancies-right-side.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 305 bytes with a total of 2.31 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/auth/email-verification/email-verification.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.72 kB with a total of 4.72 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/vacancies/detail/info/info.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.49 kB with a total of 6.49 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 5.31 kB with a total of 7.31 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/projects/edit/components/project-navigation/project-navigation.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.52 kB with a total of 5.52 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/primitives/avatar-control/avatar-control.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 262 bytes with a total of 2.26 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/project-direction-card/project-direction-card.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 1.74 kB with a total of 3.74 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/project-rating/project-rating.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.06 kB with a total of 5.06 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/rating-card.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 5.02 kB with a total of 7.02 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/onboarding/stage-two/stage-two.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.88 kB with a total of 6.88 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/office/office.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.10 kB with a total of 4.10 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/projects/edit/components/project-team-step/invite-card/invite-card.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 447 bytes with a total of 2.45 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/vacancies/detail/vacancies-detail.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 192 bytes with a total of 2.19 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/members/members-filters/members-filters.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.85 kB with a total of 4.85 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/primitives/modal/modal.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 609 bytes with a total of 2.61 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/program/detail/list/program-projects-filter/program-projects-filter.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.65 kB with a total of 5.65 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/detail/detail.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 8.91 kB with a total of 10.91 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/info-card/info-card.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 11.76 kB with a total of 13.76 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-right-side/profile-right-side.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 1.91 kB with a total of 3.91 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/courses/detail/course-detail.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.81 kB with a total of 5.81 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/onboarding/stage-one/stage-one.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.88 kB with a total of 5.88 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/vacancy-filter/vacancy-filter.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.21 kB with a total of 6.21 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/feed-filter/feed-filter.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 6.18 kB with a total of 8.18 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/onboarding/stage-zero/stage-zero.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 1.06 kB with a total of 3.06 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/courses/detail/info/course-module-card/circle-progress-bar/circle-progress-bar.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.46 kB with a total of 4.46 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/chat-window/chat-message/chat-message.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.62 kB with a total of 5.62 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/members/members.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 193 bytes with a total of 2.19 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/courses/lesson/shared/exclude-task/exclude-task.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.66 kB with a total of 6.66 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/projects/list/list.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 519 bytes with a total of 2.52 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/projects/edit/components/project-additional-step/project-additional-step.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 5.68 kB with a total of 7.68 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/profile/edit/components/profile-education-step/profile-education-step.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 407 bytes with a total of 2.41 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.42 kB with a total of 4.42 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/vacancies/list/response-card/response-card.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 584 bytes with a total of 2.58 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/courses/lesson/shared/radio-select-task/radio-select-task.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 5.18 kB with a total of 7.18 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/message-input/message-input.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.93 kB with a total of 6.93 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 138 bytes with a total of 2.14 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancy-responses/vacancy-responses.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 1.93 kB with a total of 3.93 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/projects/edit/components/project-team-step/collaborator-card/collaborator-card.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 447 bytes with a total of 2.45 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/program/detail/analytics/analytics.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 12.32 kB with a total of 14.32 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/courses/lesson/lesson.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.67 kB with a total of 5.67 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/feed/open-vacancy/open-vacancy.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.25 kB with a total of 6.25 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/profile/edit/components/profile-main-step/profile-main-step.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 318 bytes with a total of 2.32 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/courses/lesson/shared/write-task/write-task.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 1.07 kB with a total of 3.07 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/courses/courses.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.46 kB with a total of 4.46 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/projects/edit/components/project-vacancy-step/project-vacancy-step.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 5.39 kB with a total of 7.39 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/primitives/search/search.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 1.14 kB with a total of 3.14 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/program/detail/main/role-widget/program-role-widget.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.98 kB with a total of 4.98 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/primitives/tag/tag.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 1.52 kB with a total of 3.52 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/courses/detail/info/info.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.55 kB with a total of 5.55 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/news-card/news-card.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 5.23 kB with a total of 7.23 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/program/detail/main/main.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.66 kB with a total of 6.66 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/primitives/tooltip/tooltip.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.19 kB with a total of 6.19 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/members/member-statistics-card/member-statistics-card.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 63 bytes with a total of 2.06 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/profile/edit/edit.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 7.86 kB with a total of 9.86 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/project-vacancy-card/project-vacancy-card.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 1.64 kB with a total of 3.64 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/project-invite/project-invite-dialog.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 9.88 kB with a total of 11.88 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/profile/edit/components/profile-skills-step/profile-skills-step.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 666 bytes with a total of 2.67 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/courses/lesson/complete/complete.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.66 kB with a total of 4.66 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/projects/edit/edit.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.84 kB with a total of 6.84 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/courses/lesson/shared/file-task/file-task.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 5.28 kB with a total of 7.28 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/office/nav/nav.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 5.51 kB with a total of 7.51 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/onboarding/stage-three/stage-three.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.52 kB with a total of 4.52 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/primitives/autocomplete-input/autocomplete-input.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 9.31 kB with a total of 11.31 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/projects/edit/components/project-main-step/project-main-step.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 5.57 kB with a total of 7.57 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/project-rating/components/range-criterion-input/range-criterion-input.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.78 kB with a total of 4.78 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/primitives/select/select.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 6.82 kB with a total of 8.82 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/program/main/program-card/program-card.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 116 bytes with a total of 2.12 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/projects/edit/components/project-achievement-step/project-achievement-step.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.71 kB with a total of 4.71 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/program/detail/list/list.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 7.12 kB with a total of 9.12 kB. + + +▲ [WARNING] projects/ui/src/lib/components/primitives/button/button.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 8.57 kB with a total of 10.57 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/auth/register/register.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.48 kB with a total of 5.48 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/primitives/textarea/textarea.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 6.40 kB with a total of 8.40 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/auth/login/login.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.93 kB with a total of 5.93 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/news-card/carousel/carousel.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.53 kB with a total of 5.53 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/primitives/input/input.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 9.80 kB with a total of 11.80 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/courses/list/course/course.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.72 kB with a total of 5.72 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/skills-basket/skills-basket.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.40 kB with a total of 5.40 kB. + + +▲ [WARNING] Module 'dayjs' used by 'projects/social_platform/src/app/api/auth/facades/ui/auth-ui-info.service.ts' is not ESM + + CommonJS or AMD dependencies can cause optimization bailouts. + For more information see: https://angular.dev/tools/cli/build#configuring-commonjs-dependencies + + +▲ [WARNING] Module 'snakecase-keys' used by 'projects/core/src/lib/interceptors/camelcase.interceptor.ts' is not ESM + + CommonJS or AMD dependencies can cause optimization bailouts. + For more information see: https://angular.dev/tools/cli/build#configuring-commonjs-dependencies + + +▲ [WARNING] Module 'dayjs/plugin/customParseFormat' used by 'projects/core/src/lib/services/validation/validation.service.ts' is not ESM + + CommonJS or AMD dependencies can cause optimization bailouts. + For more information see: https://angular.dev/tools/cli/build#configuring-commonjs-dependencies + + +▲ [WARNING] Module 'dayjs/plugin/relativeTime' used by 'projects/core/src/lib/services/validation/validation.service.ts' is not ESM + + CommonJS or AMD dependencies can cause optimization bailouts. + For more information see: https://angular.dev/tools/cli/build#configuring-commonjs-dependencies + + +▲ [WARNING] Module 'dayjs/plugin/isToday' used by 'projects/core/src/lib/pipes/formatters/dayjs.pipe.ts' is not ESM + + CommonJS or AMD dependencies can cause optimization bailouts. + For more information see: https://angular.dev/tools/cli/build#configuring-commonjs-dependencies + + +▲ [WARNING] Module 'dayjs/locale/ru' used by 'projects/core/src/lib/pipes/formatters/dayjs.pipe.ts' is not ESM + + CommonJS or AMD dependencies can cause optimization bailouts. + For more information see: https://angular.dev/tools/cli/build#configuring-commonjs-dependencies + + +▲ [WARNING] Module 'file-saver' used by 'projects/social_platform/src/app/utils/export-file.ts' is not ESM + + CommonJS or AMD dependencies can cause optimization bailouts. + For more information see: https://angular.dev/tools/cli/build#configuring-commonjs-dependencies + + +▲ [WARNING] Module 'map-obj' used by 'node_modules/camelcase-keys/index.js' is not ESM + + CommonJS or AMD dependencies can cause optimization bailouts. + For more information see: https://angular.dev/tools/cli/build#configuring-commonjs-dependencies + + +Output location: Z:\Документы\PROCOLLAB-dev\procollab-dev-platform-responsive\dist\social_platform diff --git a/docs/desktop-regression/button-tests.log b/docs/desktop-regression/button-tests.log new file mode 100644 index 000000000..10a6aaed2 --- /dev/null +++ b/docs/desktop-regression/button-tests.log @@ -0,0 +1,13 @@ + +> procollab@0.0.0 test:ci +> vitest run projects/ui/src/lib/components/primitives/button/button-states.spec.ts + + + RUN v3.2.6 Z:/Документы/PROCOLLAB-dev/procollab-dev-platform-responsive + + ✓ projects/ui/src/lib/components/primitives/button/button-states.spec.ts (2 tests) 166ms + + Test Files 1 passed (1) + Tests 2 passed (2) + Start at 15:29:06 + Duration 7.43s (transform 4.20s, setup 3.33s, collect 1.69s, tests 166ms, environment 1.54s, prepare 1.81s) diff --git a/docs/desktop-regression/capture-loading.cjs b/docs/desktop-regression/capture-loading.cjs new file mode 100644 index 000000000..1d7821cc6 --- /dev/null +++ b/docs/desktop-regression/capture-loading.cjs @@ -0,0 +1,71 @@ +/** @format */ + +const fs = require("node:fs"); +const path = require("node:path"); +const assert = require("node:assert/strict"); +const { launch } = require("../responsive/browser-harness.cjs"); +require("../mobile-polish/fixtures.cjs"); +const phase = process.argv[2], + baseUrl = process.argv[3]; +(async () => { + const directory = path.join(__dirname, "screenshots", phase); + fs.mkdirSync(directory, { recursive: true }); + const rows = []; + for (const width of [1440, 1920]) { + const h = await launch(width, { baseUrl }); + let release; + const pending = new Promise(resolve => { + release = resolve; + }); + try { + await h.page.goto(baseUrl + "/office/feed"); + await h.page.waitForLoadState("networkidle"); + await h.page.evaluate(() => { + history.pushState({}, "", "/office/courses/1/lesson/1"); + dispatchEvent(new PopStateEvent("popstate")); + }); + await h.page.locator("app-write-task textarea").fill("Ответ для финальной проверки UI Kit"); + await h.page.waitForLoadState("networkidle"); + await h.page.evaluate(() => { + for (const img of document.images) img.loading = "eager"; + }); + await h.page.waitForLoadState("networkidle"); + await h.page.evaluate(() => document.fonts.ready); + await h.page.waitForFunction(() => [...document.images].every(img => img.complete)); + await h.page.addStyleTag({ + content: + "*,*::before,*::after{animation:none!important;transition:none!important;caret-color:transparent!important;}", + }); + await h.context.route("**/courses/tasks/1/answer/", async route => { + await pending; + await route.fulfill({ json: {} }); + }); + await h.page.getByRole("button", { name: "завершить урок", exact: true }).click(); + await h.page.locator("app-button app-loader").waitFor(); + if (phase === "desktop-after") { + const action = h.page.getByRole("button", { name: "завершить урок", exact: true }); + assert.equal(await action.isDisabled(), true); + assert.equal(await action.getAttribute("aria-busy"), "true"); + } + // Avoid incidental hover; compare the loading presentation itself. + await h.page.mouse.move(0, 0); + assert.deepEqual(h.errors, []); + await h.page.screenshot({ + path: path.join(directory, `loading-action-${width}.png`), + fullPage: true, + }); + rows.push({ name: "loading-action", width, passed: true }); + console.log(`${phase}: loading-action ${width}`); + } finally { + release(); + await h.browser.close(); + } + } + fs.writeFileSync( + path.join(__dirname, phase + "-loading.json"), + JSON.stringify(rows, null, 2) + "\n", + ); +})().catch(error => { + console.error(error); + process.exitCode = 1; +}); diff --git a/docs/desktop-regression/capture-states.cjs b/docs/desktop-regression/capture-states.cjs new file mode 100644 index 000000000..929faffc9 --- /dev/null +++ b/docs/desktop-regression/capture-states.cjs @@ -0,0 +1,81 @@ +/** @format */ + +const fs = require("node:fs"); +const path = require("node:path"); +const assert = require("node:assert/strict"); +const { launch } = require("../responsive/browser-harness.cjs"); +require("../mobile-polish/fixtures.cjs"); +const phase = process.argv[2], + baseUrl = process.argv[3]; +const screens = [ + [ + "empty-feed", + "/office/feed", + /\/feed\/$/, + { + count: 0, + results: [], + counts: { all: 0, project: 0, vacancy: 0, news: 0, partnerprogram: 0, education: 0 }, + }, + ".page__feed--no-items", + ], + [ + "empty-vacancies", + "/office/vacancies/all", + /\/vacancies\/$/, + { count: 0, results: [] }, + ".page__vacancies--no-items", + ], + ["empty-courses", "/office/courses/all", /\/courses\/$/, [], "app-list .courses"], +]; +(async () => { + const directory = path.join(__dirname, "screenshots", phase); + fs.mkdirSync(directory, { recursive: true }); + const rows = []; + for (const width of [1440, 1920]) + for (const [name, route, endpoint, response, selector] of screens) { + const h = await launch(width, { baseUrl }); + try { + await h.context.route( + url => endpoint.test(url.pathname), + async request => { + await request.fulfill({ json: response }); + }, + ); + await h.page.goto(baseUrl + "/office/feed"); + await h.page.waitForLoadState("networkidle"); + if (route !== "/office/feed") + await h.page.evaluate(route => { + history.pushState({}, "", route); + dispatchEvent(new PopStateEvent("popstate")); + }, route); + await h.page.locator(selector).first().waitFor({ state: "attached" }); + await h.page.waitForLoadState("networkidle"); + await h.page.evaluate(() => { + for (const img of document.images) img.loading = "eager"; + }); + await h.page.evaluate(() => document.fonts.ready); + await h.page.waitForFunction(() => [...document.images].every(img => img.complete)); + await h.page.addStyleTag({ + content: + "*,*::before,*::after{animation:none!important;transition:none!important;caret-color:transparent!important;}", + }); + assert.deepEqual(h.errors, []); + await h.page.screenshot({ + path: path.join(directory, `${name}-${width}.png`), + fullPage: true, + }); + rows.push({ name, width, passed: true }); + console.log(`${phase}: ${name} ${width}`); + } finally { + await h.browser.close(); + } + } + fs.writeFileSync( + path.join(__dirname, `${phase}-states.json`), + JSON.stringify(rows, null, 2) + "\n", + ); +})().catch(error => { + console.error(error); + process.exitCode = 1; +}); diff --git a/docs/desktop-regression/capture.cjs b/docs/desktop-regression/capture.cjs new file mode 100644 index 000000000..65dfde86f --- /dev/null +++ b/docs/desktop-regression/capture.cjs @@ -0,0 +1,116 @@ +/** @format */ + +const fs = require("node:fs"); +const path = require("node:path"); +const assert = require("node:assert/strict"); +const { launch, measure } = require("../responsive/browser-harness.cjs"); +require("../mobile-polish/fixtures.cjs"); +const phase = process.argv[2]; +const baseUrl = process.argv[3]; +const widths = (process.argv[4] || "1440,1920").split(",").map(Number); +const editing = process.argv[5] === "edit"; +const screens = editing + ? [ + ["profile-edit", "/office/profile/edit?editingStep=main", "app-profile-main-step"], + [ + "project-edit", + "/office/projects/1/edit?editingStep=main&programLinkId=1", + "app-project-main-step", + ], + ] + : [ + ["feed", "/office/feed", "app-open-vacancy"], + ["projects", "/office/projects/dashboard", "app-info-card"], + ["my-projects", "/office/projects/my", "app-info-card"], + ["members", "/office/members", "app-member-card"], + ["programs", "/office/program/all", "app-program-card"], + ["program", "/office/program/1", "app-program-role-widget"], + ["profile", "/office/profile/1", "app-profile-left-side"], + ["project", "/office/projects/1", "app-projects-left-side"], + ["vacancies", "/office/vacancies/all", "app-project-vacancy-card"], + ["vacancy", "/office/vacancies/1", "app-vacancies-detail"], + ["courses", "/office/courses/all", "app-course"], + ["course", "/office/courses/1", "app-course-detail"], + ]; +(async () => { + const directory = path.join(__dirname, "screenshots", phase); + fs.mkdirSync(directory, { recursive: true }); + const rows = []; + for (const width of widths) { + const h = await launch(width, { baseUrl, isMobile: width < 750, hasTouch: width < 750 }); + try { + // Fixed clock, no animations, no screenshot masks or omitted page sections. + await h.context.addInitScript(() => { + const NativeDate = Date; + class FixedDate extends NativeDate { + constructor(...args) { + super(...(args.length ? args : [1791288000000])); + } + static now() { + return 1791288000000; + } + } + window.Date = FixedDate; + }); + await h.page.goto(baseUrl + "/office/feed"); + await h.page.waitForLoadState("networkidle"); + for (const [name, route, selector] of screens) { + h.errors.length = 0; + if (name === "feed") await h.page.goto(baseUrl + route); + else + await h.page.evaluate(route => { + history.pushState({}, "", route); + dispatchEvent(new PopStateEvent("popstate")); + }, route); + await h.page.waitForURL(baseUrl + route); + await h.page.waitForLoadState("networkidle"); + await h.page + .locator(selector) + .first() + .waitFor({ state: "attached" }) + .catch(async error => { + console.error( + JSON.stringify( + { + url: h.page.url(), + text: await h.page.locator("body").innerText(), + errors: h.errors, + requests: h.requests, + }, + null, + 2, + ), + ); + throw error; + }); + await h.page.evaluate(() => { + for (const img of document.images) img.loading = "eager"; + }); + await h.page.waitForLoadState("networkidle"); + await h.page.evaluate(() => document.fonts.ready); + await h.page.waitForFunction(() => [...document.images].every(img => img.complete)); + await h.page.addStyleTag({ + content: + "*, *::before, *::after { animation: none !important; transition: none !important; caret-color: transparent !important; }", + }); + const measurement = await measure(h.page); + assert.deepEqual(h.errors, [], `${phase} ${name} ${width}`); + await h.page.screenshot({ + path: path.join(directory, `${name}-${width}.png`), + fullPage: true, + }); + rows.push({ name, width, ...measurement }); + console.log(`${phase}: ${name} ${width}`); + } + } finally { + await h.browser.close(); + } + } + fs.writeFileSync( + path.join(__dirname, `${phase}${editing ? "-edit" : ""}.json`), + JSON.stringify(rows, null, 2) + "\n", + ); +})().catch(error => { + console.error(error); + process.exitCode = 1; +}); diff --git a/docs/desktop-regression/compare.py b/docs/desktop-regression/compare.py new file mode 100644 index 000000000..d297180f8 --- /dev/null +++ b/docs/desktop-regression/compare.py @@ -0,0 +1,46 @@ +"""Compare full-page PNGs without masks; fail the visual regression gate.""" +import json +import sys +from pathlib import Path + +import numpy as np +from PIL import Image + +root = Path(__file__).parent +before, after = sys.argv[1:3] +output = root / "screenshots" / f"diff-{after}" +output.mkdir(parents=True, exist_ok=True) +rows = [] +for file in sorted((root / "screenshots" / before).glob("*.png")): + a = Image.open(file).convert("RGB") + b = Image.open(root / "screenshots" / after / file.name).convert("RGB") + same_size = a.size == b.size + w, h = max(a.width, b.width), max(a.height, b.height) + padded = [] + for img in (a, b): + canvas = Image.new("RGB", (w, h), "white") + canvas.paste(img) + padded.append(np.asarray(canvas).astype(np.int16)) + delta = np.max(np.abs(padded[0] - padded[1]), axis=2) + mask = delta > 8 + count = int(np.count_nonzero(mask)) + percent = count / (w * h) * 100 + ys, xs = np.where(mask) + bbox = [int(xs.min()), int(ys.min()), int(xs.max()), int(ys.max())] if count else None + exact_count = int(np.count_nonzero(delta)) + passed = same_size and exact_count == 0 + rows.append({"screen": file.stem, "beforeSize": a.size, "afterSize": b.size, + "changedPixels": count, "changedPercent": round(percent, 6), + "exactChangedPixels": exact_count, + "maxChannelDelta": int(delta.max()), + "bbox": bbox, "passed": passed}) + if count or not same_size: + overlay = (padded[1] * 0.4 + 255 * 0.6).astype(np.uint8) + overlay[mask] = [240, 40, 100] + Image.fromarray(overlay).save(output / file.name) + else: + (output / file.name).unlink(missing_ok=True) + print(f"{'PASS' if passed else 'FAIL'} {file.stem}: exact={exact_count}px; delta>8={percent:.4f}% {a.size} -> {b.size} bbox={bbox}") +(root / f"comparison-{after}.json").write_text(json.dumps(rows, indent=2) + "\n", encoding="utf-8") +if "--check" in sys.argv and (not rows or any(not r["passed"] for r in rows)): + sys.exit(1) diff --git a/docs/desktop-regression/comparison-data.js b/docs/desktop-regression/comparison-data.js new file mode 100644 index 000000000..188145608 --- /dev/null +++ b/docs/desktop-regression/comparison-data.js @@ -0,0 +1,1332 @@ +const pixelComparisons = { + "desktop": [ + { + "screen": "course-1440", + "beforeSize": [ + 1440, + 844 + ], + "afterSize": [ + 1440, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "course-1920", + "beforeSize": [ + 1920, + 844 + ], + "afterSize": [ + 1920, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "courses-1440", + "beforeSize": [ + 1440, + 844 + ], + "afterSize": [ + 1440, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "courses-1920", + "beforeSize": [ + 1920, + 844 + ], + "afterSize": [ + 1920, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "empty-courses-1440", + "beforeSize": [ + 1440, + 844 + ], + "afterSize": [ + 1440, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "empty-courses-1920", + "beforeSize": [ + 1920, + 844 + ], + "afterSize": [ + 1920, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "empty-feed-1440", + "beforeSize": [ + 1440, + 844 + ], + "afterSize": [ + 1440, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "empty-feed-1920", + "beforeSize": [ + 1920, + 844 + ], + "afterSize": [ + 1920, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "empty-vacancies-1440", + "beforeSize": [ + 1440, + 844 + ], + "afterSize": [ + 1440, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "empty-vacancies-1920", + "beforeSize": [ + 1920, + 844 + ], + "afterSize": [ + 1920, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "feed-1440", + "beforeSize": [ + 1440, + 844 + ], + "afterSize": [ + 1440, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "feed-1920", + "beforeSize": [ + 1920, + 844 + ], + "afterSize": [ + 1920, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "loading-action-1440", + "beforeSize": [ + 1440, + 844 + ], + "afterSize": [ + 1440, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "loading-action-1920", + "beforeSize": [ + 1920, + 844 + ], + "afterSize": [ + 1920, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "members-1440", + "beforeSize": [ + 1440, + 844 + ], + "afterSize": [ + 1440, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "members-1920", + "beforeSize": [ + 1920, + 844 + ], + "afterSize": [ + 1920, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "my-projects-1440", + "beforeSize": [ + 1440, + 844 + ], + "afterSize": [ + 1440, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "my-projects-1920", + "beforeSize": [ + 1920, + 844 + ], + "afterSize": [ + 1920, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-1440", + "beforeSize": [ + 1440, + 844 + ], + "afterSize": [ + 1440, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-1920", + "beforeSize": [ + 1920, + 844 + ], + "afterSize": [ + 1920, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-edit-1440", + "beforeSize": [ + 1440, + 844 + ], + "afterSize": [ + 1440, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-edit-1920", + "beforeSize": [ + 1920, + 844 + ], + "afterSize": [ + 1920, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "program-1440", + "beforeSize": [ + 1440, + 844 + ], + "afterSize": [ + 1440, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "program-1920", + "beforeSize": [ + 1920, + 844 + ], + "afterSize": [ + 1920, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "programs-1440", + "beforeSize": [ + 1440, + 844 + ], + "afterSize": [ + 1440, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "programs-1920", + "beforeSize": [ + 1920, + 844 + ], + "afterSize": [ + 1920, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-1440", + "beforeSize": [ + 1440, + 844 + ], + "afterSize": [ + 1440, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-1920", + "beforeSize": [ + 1920, + 844 + ], + "afterSize": [ + 1920, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-edit-1440", + "beforeSize": [ + 1440, + 844 + ], + "afterSize": [ + 1440, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-edit-1920", + "beforeSize": [ + 1920, + 844 + ], + "afterSize": [ + 1920, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "projects-1440", + "beforeSize": [ + 1440, + 844 + ], + "afterSize": [ + 1440, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "projects-1920", + "beforeSize": [ + 1920, + 844 + ], + "afterSize": [ + 1920, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancies-1440", + "beforeSize": [ + 1440, + 844 + ], + "afterSize": [ + 1440, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancies-1920", + "beforeSize": [ + 1920, + 844 + ], + "afterSize": [ + 1920, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancy-1440", + "beforeSize": [ + 1440, + 844 + ], + "afterSize": [ + 1440, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancy-1920", + "beforeSize": [ + 1920, + 844 + ], + "afterSize": [ + 1920, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + } + ], + "mobile": [ + { + "screen": "course-320", + "beforeSize": [ + 320, + 844 + ], + "afterSize": [ + 320, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "course-390", + "beforeSize": [ + 390, + 844 + ], + "afterSize": [ + 390, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "course-768", + "beforeSize": [ + 768, + 844 + ], + "afterSize": [ + 768, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "courses-320", + "beforeSize": [ + 320, + 844 + ], + "afterSize": [ + 320, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "courses-390", + "beforeSize": [ + 390, + 844 + ], + "afterSize": [ + 390, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "courses-768", + "beforeSize": [ + 768, + 844 + ], + "afterSize": [ + 768, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "feed-320", + "beforeSize": [ + 320, + 844 + ], + "afterSize": [ + 320, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "feed-390", + "beforeSize": [ + 390, + 844 + ], + "afterSize": [ + 390, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "feed-768", + "beforeSize": [ + 768, + 844 + ], + "afterSize": [ + 768, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "members-320", + "beforeSize": [ + 320, + 844 + ], + "afterSize": [ + 320, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "members-390", + "beforeSize": [ + 390, + 844 + ], + "afterSize": [ + 390, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "members-768", + "beforeSize": [ + 768, + 844 + ], + "afterSize": [ + 768, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "my-projects-320", + "beforeSize": [ + 320, + 844 + ], + "afterSize": [ + 320, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "my-projects-390", + "beforeSize": [ + 390, + 844 + ], + "afterSize": [ + 390, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "my-projects-768", + "beforeSize": [ + 768, + 844 + ], + "afterSize": [ + 768, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-320", + "beforeSize": [ + 320, + 844 + ], + "afterSize": [ + 320, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-390", + "beforeSize": [ + 390, + 844 + ], + "afterSize": [ + 390, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-768", + "beforeSize": [ + 768, + 844 + ], + "afterSize": [ + 768, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-edit-320", + "beforeSize": [ + 320, + 844 + ], + "afterSize": [ + 320, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-edit-390", + "beforeSize": [ + 390, + 844 + ], + "afterSize": [ + 390, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-edit-768", + "beforeSize": [ + 768, + 844 + ], + "afterSize": [ + 768, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "program-320", + "beforeSize": [ + 320, + 844 + ], + "afterSize": [ + 320, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "program-390", + "beforeSize": [ + 390, + 844 + ], + "afterSize": [ + 390, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "program-768", + "beforeSize": [ + 768, + 844 + ], + "afterSize": [ + 768, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "programs-320", + "beforeSize": [ + 320, + 844 + ], + "afterSize": [ + 320, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "programs-390", + "beforeSize": [ + 390, + 844 + ], + "afterSize": [ + 390, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "programs-768", + "beforeSize": [ + 768, + 844 + ], + "afterSize": [ + 768, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-320", + "beforeSize": [ + 320, + 844 + ], + "afterSize": [ + 320, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-390", + "beforeSize": [ + 390, + 844 + ], + "afterSize": [ + 390, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-768", + "beforeSize": [ + 768, + 844 + ], + "afterSize": [ + 768, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-edit-320", + "beforeSize": [ + 320, + 844 + ], + "afterSize": [ + 320, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-edit-390", + "beforeSize": [ + 390, + 844 + ], + "afterSize": [ + 390, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-edit-768", + "beforeSize": [ + 768, + 844 + ], + "afterSize": [ + 768, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "projects-320", + "beforeSize": [ + 320, + 844 + ], + "afterSize": [ + 320, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "projects-390", + "beforeSize": [ + 390, + 844 + ], + "afterSize": [ + 390, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "projects-768", + "beforeSize": [ + 768, + 844 + ], + "afterSize": [ + 768, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancies-320", + "beforeSize": [ + 320, + 844 + ], + "afterSize": [ + 320, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancies-390", + "beforeSize": [ + 390, + 844 + ], + "afterSize": [ + 390, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancies-768", + "beforeSize": [ + 768, + 844 + ], + "afterSize": [ + 768, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancy-320", + "beforeSize": [ + 320, + 844 + ], + "afterSize": [ + 320, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancy-390", + "beforeSize": [ + 390, + 844 + ], + "afterSize": [ + 390, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancy-768", + "beforeSize": [ + 768, + 844 + ], + "afterSize": [ + 768, + 844 + ], + "changedPixels": 0, + "changedPercent": 0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + } + ] +}; diff --git a/docs/desktop-regression/comparison-desktop-after.json b/docs/desktop-regression/comparison-desktop-after.json new file mode 100644 index 000000000..9a0a12922 --- /dev/null +++ b/docs/desktop-regression/comparison-desktop-after.json @@ -0,0 +1,398 @@ +[ + { + "screen": "course-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "course-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "courses-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "courses-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "empty-courses-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "empty-courses-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "empty-feed-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "empty-feed-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "empty-vacancies-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "empty-vacancies-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "feed-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "feed-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "loading-action-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "loading-action-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "members-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "members-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "my-projects-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "my-projects-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-edit-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-edit-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "program-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "program-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "programs-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "programs-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-edit-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-edit-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "projects-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "projects-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancies-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancies-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancy-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancy-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + } +] diff --git a/docs/desktop-regression/comparison-desktop-repeat.json b/docs/desktop-regression/comparison-desktop-repeat.json new file mode 100644 index 000000000..9a0a12922 --- /dev/null +++ b/docs/desktop-regression/comparison-desktop-repeat.json @@ -0,0 +1,398 @@ +[ + { + "screen": "course-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "course-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "courses-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "courses-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "empty-courses-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "empty-courses-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "empty-feed-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "empty-feed-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "empty-vacancies-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "empty-vacancies-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "feed-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "feed-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "loading-action-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "loading-action-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "members-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "members-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "my-projects-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "my-projects-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-edit-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-edit-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "program-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "program-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "programs-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "programs-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-edit-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-edit-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "projects-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "projects-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancies-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancies-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancy-1440", + "beforeSize": [1440, 844], + "afterSize": [1440, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancy-1920", + "beforeSize": [1920, 844], + "afterSize": [1920, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + } +] diff --git a/docs/desktop-regression/comparison-mobile-after.json b/docs/desktop-regression/comparison-mobile-after.json new file mode 100644 index 000000000..d3c305d21 --- /dev/null +++ b/docs/desktop-regression/comparison-mobile-after.json @@ -0,0 +1,464 @@ +[ + { + "screen": "course-320", + "beforeSize": [320, 844], + "afterSize": [320, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "course-390", + "beforeSize": [390, 844], + "afterSize": [390, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "course-768", + "beforeSize": [768, 844], + "afterSize": [768, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "courses-320", + "beforeSize": [320, 844], + "afterSize": [320, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "courses-390", + "beforeSize": [390, 844], + "afterSize": [390, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "courses-768", + "beforeSize": [768, 844], + "afterSize": [768, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "feed-320", + "beforeSize": [320, 844], + "afterSize": [320, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "feed-390", + "beforeSize": [390, 844], + "afterSize": [390, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "feed-768", + "beforeSize": [768, 844], + "afterSize": [768, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "members-320", + "beforeSize": [320, 844], + "afterSize": [320, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "members-390", + "beforeSize": [390, 844], + "afterSize": [390, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "members-768", + "beforeSize": [768, 844], + "afterSize": [768, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "my-projects-320", + "beforeSize": [320, 844], + "afterSize": [320, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "my-projects-390", + "beforeSize": [390, 844], + "afterSize": [390, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "my-projects-768", + "beforeSize": [768, 844], + "afterSize": [768, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-320", + "beforeSize": [320, 844], + "afterSize": [320, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-390", + "beforeSize": [390, 844], + "afterSize": [390, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-768", + "beforeSize": [768, 844], + "afterSize": [768, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-edit-320", + "beforeSize": [320, 844], + "afterSize": [320, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-edit-390", + "beforeSize": [390, 844], + "afterSize": [390, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "profile-edit-768", + "beforeSize": [768, 844], + "afterSize": [768, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "program-320", + "beforeSize": [320, 844], + "afterSize": [320, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "program-390", + "beforeSize": [390, 844], + "afterSize": [390, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "program-768", + "beforeSize": [768, 844], + "afterSize": [768, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "programs-320", + "beforeSize": [320, 844], + "afterSize": [320, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "programs-390", + "beforeSize": [390, 844], + "afterSize": [390, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "programs-768", + "beforeSize": [768, 844], + "afterSize": [768, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-320", + "beforeSize": [320, 844], + "afterSize": [320, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-390", + "beforeSize": [390, 844], + "afterSize": [390, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-768", + "beforeSize": [768, 844], + "afterSize": [768, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-edit-320", + "beforeSize": [320, 844], + "afterSize": [320, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-edit-390", + "beforeSize": [390, 844], + "afterSize": [390, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "project-edit-768", + "beforeSize": [768, 844], + "afterSize": [768, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "projects-320", + "beforeSize": [320, 844], + "afterSize": [320, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "projects-390", + "beforeSize": [390, 844], + "afterSize": [390, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "projects-768", + "beforeSize": [768, 844], + "afterSize": [768, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancies-320", + "beforeSize": [320, 844], + "afterSize": [320, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancies-390", + "beforeSize": [390, 844], + "afterSize": [390, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancies-768", + "beforeSize": [768, 844], + "afterSize": [768, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancy-320", + "beforeSize": [320, 844], + "afterSize": [320, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancy-390", + "beforeSize": [390, 844], + "afterSize": [390, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + }, + { + "screen": "vacancy-768", + "beforeSize": [768, 844], + "afterSize": [768, 844], + "changedPixels": 0, + "changedPercent": 0.0, + "exactChangedPixels": 0, + "maxChannelDelta": 0, + "bbox": null, + "passed": true + } +] diff --git a/docs/desktop-regression/comparison.html b/docs/desktop-regression/comparison.html new file mode 100644 index 000000000..854ecd74a --- /dev/null +++ b/docs/desktop-regression/comparison.html @@ -0,0 +1,185 @@ + + + + + + + + PROCOLLAB — visual regression + + + +
+

PROCOLLAB · visual regression

+

Desktop: dev до #401 (5fe4d5c6). Mobile: адаптив 1138fe0c.

+
+ + + + + +
+

+

+ Отчёт, команды и ограничения · Высота viewport 844 px, внутренний + scroll Office. Изображения без масок. +

+
+
+
+
Эталон
+
+ ЭталонИсправление для наложения +
+
+
+
После исправления
+
После исправления
+
+
+ + + + diff --git a/docs/desktop-regression/desktop-after-edit.json b/docs/desktop-regression/desktop-after-edit.json new file mode 100644 index 000000000..565a21397 --- /dev/null +++ b/docs/desktop-regression/desktop-after-edit.json @@ -0,0 +1,212 @@ +[ + { + "name": "profile-edit", + "width": 1440, + "actualPath": "/office/profile/edit", + "actualQuery": "?editingStep=main", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-button", + "app-project-navigation", + "app-profile-main-step", + "app-avatar-control", + "app-modal", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-button", + "app-project-navigation", + "app-profile-main-step", + "app-avatar-control", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nредактирование профиля\ncохранить\n\nосновные данные\n\nобразование\n\nработа\n\nдостижения\n\nнавы" + }, + { + "name": "project-edit", + "width": 1440, + "actualPath": "/office/projects/1/edit", + "actualQuery": "?editingStep=main&programLinkId=1", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-edit", + "app-button", + "app-project-navigation", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-modal", + "app-upload-file", + "app-select", + "app-dropdown", + "app-input", + "app-region-select", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-edit", + "app-button", + "app-project-navigation", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-upload-file", + "app-select", + "app-input", + "app-region-select", + "app-textarea" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nредактировать проект\nудалить проект\nсохранить черновик\nотправить заявку\n\nосновные данные" + }, + { + "name": "profile-edit", + "width": 1920, + "actualPath": "/office/profile/edit", + "actualQuery": "?editingStep=main", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-button", + "app-project-navigation", + "app-profile-main-step", + "app-avatar-control", + "app-modal", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-button", + "app-project-navigation", + "app-profile-main-step", + "app-avatar-control", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nредактирование профиля\ncохранить\n\nосновные данные\n\nобразование\n\nработа\n\nдостижения\n\nнавы" + }, + { + "name": "project-edit", + "width": 1920, + "actualPath": "/office/projects/1/edit", + "actualQuery": "?editingStep=main&programLinkId=1", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-edit", + "app-button", + "app-project-navigation", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-modal", + "app-upload-file", + "app-select", + "app-dropdown", + "app-input", + "app-region-select", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-edit", + "app-button", + "app-project-navigation", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-upload-file", + "app-select", + "app-input", + "app-region-select", + "app-textarea" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nредактировать проект\nудалить проект\nсохранить черновик\nотправить заявку\n\nосновные данные" + } +] diff --git a/docs/desktop-regression/desktop-after-loading.json b/docs/desktop-regression/desktop-after-loading.json new file mode 100644 index 000000000..97d812e6c --- /dev/null +++ b/docs/desktop-regression/desktop-after-loading.json @@ -0,0 +1,12 @@ +[ + { + "name": "loading-action", + "width": 1440, + "passed": true + }, + { + "name": "loading-action", + "width": 1920, + "passed": true + } +] diff --git a/docs/desktop-regression/desktop-after-states.json b/docs/desktop-regression/desktop-after-states.json new file mode 100644 index 000000000..02e2050be --- /dev/null +++ b/docs/desktop-regression/desktop-after-states.json @@ -0,0 +1,32 @@ +[ + { + "name": "empty-feed", + "width": 1440, + "passed": true + }, + { + "name": "empty-vacancies", + "width": 1440, + "passed": true + }, + { + "name": "empty-courses", + "width": 1440, + "passed": true + }, + { + "name": "empty-feed", + "width": 1920, + "passed": true + }, + { + "name": "empty-vacancies", + "width": 1920, + "passed": true + }, + { + "name": "empty-courses", + "width": 1920, + "passed": true + } +] diff --git a/docs/desktop-regression/desktop-after.json b/docs/desktop-regression/desktop-after.json new file mode 100644 index 000000000..1d46c5d44 --- /dev/null +++ b/docs/desktop-regression/desktop-after.json @@ -0,0 +1,1168 @@ +[ + { + "name": "feed", + "width": 1440, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости прогр" + }, + { + "name": "projects", + "width": 1440, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-button", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-button", + "app-project-activity-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпроекты\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселер" + }, + { + "name": "my-projects", + "width": 1440, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-bar-new", + "app-list", + "app-info-card", + "app-modal", + "app-button", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-bar-new", + "app-list", + "app-info-card", + "app-button", + "app-project-activity-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпроекты\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПривязан к програм" + }, + { + "name": "members", + "width": 1440, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-search", + "app-member-card", + "app-button", + "app-members-filters", + "app-autocomplete-input", + "app-member-statistics-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-back", + "app-search", + "app-member-card", + "app-button", + "app-members-filters", + "app-autocomplete-input", + "app-member-statistics-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nучастники\n\nПоиск\n\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробело" + }, + { + "name": "programs", + "width": 1440, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026\n\n" + }, + { + "name": "program", + "width": 1440, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nоценка проектов\nаналитика\nпроекты-участники\nучастники\nаналитика\nорганизатор\nУчастники\n1\n" + }, + { + "name": "profile", + "width": 1440, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26" + }, + { + "name": "project", + "width": 1440, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАксе" + }, + { + "name": "vacancies", + "width": 1440, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nвакансии\n\nПоиск\n\nАктивна\n01.10.2026\nДизайнер интерфейсов\nПроект\nОченьДлинноеНазваниеБезП" + }, + { + "name": "vacancy", + "width": 1440, + "actualPath": "/office/vacancies/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-badge", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-badge", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nВакансии\nДизайнер интерфейсов\nАктивна\nПроект: ОченьДлинноеНазваниеБезПробеловОченьДлинно" + }, + { + "name": "courses", + "width": 1440, + "actualPath": "/office/courses/all", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-button", + "app-soon-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-back", + "app-search", + "app-list", + "app-course", + "app-soon-card", + "app-button" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nкурсы\n\nПоиск\n\nдоступно всем пользователям\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНа" + }, + { + "name": "course", + "width": 1440, + "actualPath": "/office/courses/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-detail", + "app-soon-card", + "app-course-module-card", + "app-circle-progress-bar", + "app-course-about", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-detail", + "app-soon-card", + "app-course-module-card", + "app-circle-progress-bar", + "app-course-about" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПро" + }, + { + "name": "feed", + "width": 1920, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости прогр" + }, + { + "name": "projects", + "width": 1920, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-button", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-button", + "app-project-activity-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпроекты\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселер" + }, + { + "name": "my-projects", + "width": 1920, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-bar-new", + "app-list", + "app-info-card", + "app-modal", + "app-button", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-bar-new", + "app-list", + "app-info-card", + "app-button", + "app-project-activity-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпроекты\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПривязан к програм" + }, + { + "name": "members", + "width": 1920, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-search", + "app-member-card", + "app-button", + "app-members-filters", + "app-autocomplete-input", + "app-member-statistics-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-back", + "app-search", + "app-member-card", + "app-button", + "app-members-filters", + "app-autocomplete-input", + "app-member-statistics-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nучастники\n\nПоиск\n\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробело" + }, + { + "name": "programs", + "width": 1920, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026\n\n" + }, + { + "name": "program", + "width": 1920, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nоценка проектов\nаналитика\nпроекты-участники\nучастники\nаналитика\nорганизатор\nУчастники\n1\n" + }, + { + "name": "profile", + "width": 1920, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26" + }, + { + "name": "project", + "width": 1920, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАксе" + }, + { + "name": "vacancies", + "width": 1920, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nвакансии\n\nПоиск\n\nАктивна\n01.10.2026\nДизайнер интерфейсов\nПроект\nОченьДлинноеНазваниеБезП" + }, + { + "name": "vacancy", + "width": 1920, + "actualPath": "/office/vacancies/1", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-badge", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-badge", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nВакансии\nДизайнер интерфейсов\nАктивна\nПроект: ОченьДлинноеНазваниеБезПробеловОченьДлинно" + }, + { + "name": "courses", + "width": 1920, + "actualPath": "/office/courses/all", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-button", + "app-soon-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-back", + "app-search", + "app-list", + "app-course", + "app-soon-card", + "app-button" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nкурсы\n\nПоиск\n\nдоступно всем пользователям\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНа" + }, + { + "name": "course", + "width": 1920, + "actualPath": "/office/courses/1", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-detail", + "app-soon-card", + "app-course-module-card", + "app-circle-progress-bar", + "app-course-about", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-detail", + "app-soon-card", + "app-course-module-card", + "app-circle-progress-bar", + "app-course-about" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПро" + } +] diff --git a/docs/desktop-regression/desktop-before-edit.json b/docs/desktop-regression/desktop-before-edit.json new file mode 100644 index 000000000..565a21397 --- /dev/null +++ b/docs/desktop-regression/desktop-before-edit.json @@ -0,0 +1,212 @@ +[ + { + "name": "profile-edit", + "width": 1440, + "actualPath": "/office/profile/edit", + "actualQuery": "?editingStep=main", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-button", + "app-project-navigation", + "app-profile-main-step", + "app-avatar-control", + "app-modal", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-button", + "app-project-navigation", + "app-profile-main-step", + "app-avatar-control", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nредактирование профиля\ncохранить\n\nосновные данные\n\nобразование\n\nработа\n\nдостижения\n\nнавы" + }, + { + "name": "project-edit", + "width": 1440, + "actualPath": "/office/projects/1/edit", + "actualQuery": "?editingStep=main&programLinkId=1", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-edit", + "app-button", + "app-project-navigation", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-modal", + "app-upload-file", + "app-select", + "app-dropdown", + "app-input", + "app-region-select", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-edit", + "app-button", + "app-project-navigation", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-upload-file", + "app-select", + "app-input", + "app-region-select", + "app-textarea" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nредактировать проект\nудалить проект\nсохранить черновик\nотправить заявку\n\nосновные данные" + }, + { + "name": "profile-edit", + "width": 1920, + "actualPath": "/office/profile/edit", + "actualQuery": "?editingStep=main", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-button", + "app-project-navigation", + "app-profile-main-step", + "app-avatar-control", + "app-modal", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-button", + "app-project-navigation", + "app-profile-main-step", + "app-avatar-control", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nредактирование профиля\ncохранить\n\nосновные данные\n\nобразование\n\nработа\n\nдостижения\n\nнавы" + }, + { + "name": "project-edit", + "width": 1920, + "actualPath": "/office/projects/1/edit", + "actualQuery": "?editingStep=main&programLinkId=1", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-edit", + "app-button", + "app-project-navigation", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-modal", + "app-upload-file", + "app-select", + "app-dropdown", + "app-input", + "app-region-select", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-edit", + "app-button", + "app-project-navigation", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-upload-file", + "app-select", + "app-input", + "app-region-select", + "app-textarea" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nредактировать проект\nудалить проект\nсохранить черновик\nотправить заявку\n\nосновные данные" + } +] diff --git a/docs/desktop-regression/desktop-before-loading.json b/docs/desktop-regression/desktop-before-loading.json new file mode 100644 index 000000000..97d812e6c --- /dev/null +++ b/docs/desktop-regression/desktop-before-loading.json @@ -0,0 +1,12 @@ +[ + { + "name": "loading-action", + "width": 1440, + "passed": true + }, + { + "name": "loading-action", + "width": 1920, + "passed": true + } +] diff --git a/docs/desktop-regression/desktop-before-states.json b/docs/desktop-regression/desktop-before-states.json new file mode 100644 index 000000000..02e2050be --- /dev/null +++ b/docs/desktop-regression/desktop-before-states.json @@ -0,0 +1,32 @@ +[ + { + "name": "empty-feed", + "width": 1440, + "passed": true + }, + { + "name": "empty-vacancies", + "width": 1440, + "passed": true + }, + { + "name": "empty-courses", + "width": 1440, + "passed": true + }, + { + "name": "empty-feed", + "width": 1920, + "passed": true + }, + { + "name": "empty-vacancies", + "width": 1920, + "passed": true + }, + { + "name": "empty-courses", + "width": 1920, + "passed": true + } +] diff --git a/docs/desktop-regression/desktop-before.json b/docs/desktop-regression/desktop-before.json new file mode 100644 index 000000000..5a4c70444 --- /dev/null +++ b/docs/desktop-regression/desktop-before.json @@ -0,0 +1,1152 @@ +[ + { + "name": "feed", + "width": 1440, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости прогр" + }, + { + "name": "projects", + "width": 1440, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-button", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-button", + "app-project-activity-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпроекты\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселер" + }, + { + "name": "my-projects", + "width": 1440, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-bar-new", + "app-list", + "app-info-card", + "app-modal", + "app-button", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-bar-new", + "app-list", + "app-info-card", + "app-button", + "app-project-activity-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпроекты\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПривязан к програм" + }, + { + "name": "members", + "width": 1440, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-back", + "app-search", + "app-member-card", + "app-button", + "app-members-filters", + "app-autocomplete-input", + "app-member-statistics-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-back", + "app-search", + "app-member-card", + "app-button", + "app-members-filters", + "app-autocomplete-input", + "app-member-statistics-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nучастники\n\nПоиск\n\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробело" + }, + { + "name": "programs", + "width": 1440, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026\n\n" + }, + { + "name": "program", + "width": 1440, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nоценка проектов\nаналитика\nпроекты-участники\nучастники\nаналитика\nорганизатор\nУчастники\n1\n" + }, + { + "name": "profile", + "width": 1440, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26" + }, + { + "name": "project", + "width": 1440, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАксе" + }, + { + "name": "vacancies", + "width": 1440, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nвакансии\n\nПоиск\n\nАктивна\n01.10.2026\nДизайнер интерфейсов\nПроект\nОченьДлинноеНазваниеБезП" + }, + { + "name": "vacancy", + "width": 1440, + "actualPath": "/office/vacancies/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nВакансии\nДизайнер интерфейсов\nАктивна\nПроект: ОченьДлинноеНазваниеБезПробеловОченьДлинно" + }, + { + "name": "courses", + "width": 1440, + "actualPath": "/office/courses/all", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-back", + "app-search", + "app-list", + "app-course", + "app-button", + "app-soon-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-back", + "app-search", + "app-list", + "app-course", + "app-soon-card", + "app-button" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nкурсы\n\nПоиск\n\nдоступно всем пользователям\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНа" + }, + { + "name": "course", + "width": 1440, + "actualPath": "/office/courses/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-detail", + "app-soon-card", + "app-course-module-card", + "app-circle-progress-bar", + "app-course-about", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-detail", + "app-soon-card", + "app-course-module-card", + "app-circle-progress-bar", + "app-course-about" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПро" + }, + { + "name": "feed", + "width": 1920, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости прогр" + }, + { + "name": "projects", + "width": 1920, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-button", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-button", + "app-project-activity-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпроекты\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселер" + }, + { + "name": "my-projects", + "width": 1920, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-bar-new", + "app-list", + "app-info-card", + "app-modal", + "app-button", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-bar-new", + "app-list", + "app-info-card", + "app-button", + "app-project-activity-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпроекты\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПривязан к програм" + }, + { + "name": "members", + "width": 1920, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-back", + "app-search", + "app-member-card", + "app-button", + "app-members-filters", + "app-autocomplete-input", + "app-member-statistics-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-back", + "app-search", + "app-member-card", + "app-button", + "app-members-filters", + "app-autocomplete-input", + "app-member-statistics-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nучастники\n\nПоиск\n\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробело" + }, + { + "name": "programs", + "width": 1920, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026\n\n" + }, + { + "name": "program", + "width": 1920, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nоценка проектов\nаналитика\nпроекты-участники\nучастники\nаналитика\nорганизатор\nУчастники\n1\n" + }, + { + "name": "profile", + "width": 1920, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26" + }, + { + "name": "project", + "width": 1920, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАксе" + }, + { + "name": "vacancies", + "width": 1920, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nвакансии\n\nПоиск\n\nАктивна\n01.10.2026\nДизайнер интерфейсов\nПроект\nОченьДлинноеНазваниеБезП" + }, + { + "name": "vacancy", + "width": 1920, + "actualPath": "/office/vacancies/1", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nВакансии\nДизайнер интерфейсов\nАктивна\nПроект: ОченьДлинноеНазваниеБезПробеловОченьДлинно" + }, + { + "name": "courses", + "width": 1920, + "actualPath": "/office/courses/all", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-back", + "app-search", + "app-list", + "app-course", + "app-button", + "app-soon-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-back", + "app-search", + "app-list", + "app-course", + "app-soon-card", + "app-button" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nкурсы\n\nПоиск\n\nдоступно всем пользователям\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНа" + }, + { + "name": "course", + "width": 1920, + "actualPath": "/office/courses/1", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-detail", + "app-soon-card", + "app-course-module-card", + "app-circle-progress-bar", + "app-course-about", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-detail", + "app-soon-card", + "app-course-module-card", + "app-circle-progress-bar", + "app-course-about" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПро" + } +] diff --git a/docs/desktop-regression/desktop-repeat-edit.json b/docs/desktop-regression/desktop-repeat-edit.json new file mode 100644 index 000000000..565a21397 --- /dev/null +++ b/docs/desktop-regression/desktop-repeat-edit.json @@ -0,0 +1,212 @@ +[ + { + "name": "profile-edit", + "width": 1440, + "actualPath": "/office/profile/edit", + "actualQuery": "?editingStep=main", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-button", + "app-project-navigation", + "app-profile-main-step", + "app-avatar-control", + "app-modal", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-button", + "app-project-navigation", + "app-profile-main-step", + "app-avatar-control", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nредактирование профиля\ncохранить\n\nосновные данные\n\nобразование\n\nработа\n\nдостижения\n\nнавы" + }, + { + "name": "project-edit", + "width": 1440, + "actualPath": "/office/projects/1/edit", + "actualQuery": "?editingStep=main&programLinkId=1", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-edit", + "app-button", + "app-project-navigation", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-modal", + "app-upload-file", + "app-select", + "app-dropdown", + "app-input", + "app-region-select", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-edit", + "app-button", + "app-project-navigation", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-upload-file", + "app-select", + "app-input", + "app-region-select", + "app-textarea" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nредактировать проект\nудалить проект\nсохранить черновик\nотправить заявку\n\nосновные данные" + }, + { + "name": "profile-edit", + "width": 1920, + "actualPath": "/office/profile/edit", + "actualQuery": "?editingStep=main", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-button", + "app-project-navigation", + "app-profile-main-step", + "app-avatar-control", + "app-modal", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-button", + "app-project-navigation", + "app-profile-main-step", + "app-avatar-control", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nредактирование профиля\ncохранить\n\nосновные данные\n\nобразование\n\nработа\n\nдостижения\n\nнавы" + }, + { + "name": "project-edit", + "width": 1920, + "actualPath": "/office/projects/1/edit", + "actualQuery": "?editingStep=main&programLinkId=1", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-edit", + "app-button", + "app-project-navigation", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-modal", + "app-upload-file", + "app-select", + "app-dropdown", + "app-input", + "app-region-select", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-edit", + "app-button", + "app-project-navigation", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-upload-file", + "app-select", + "app-input", + "app-region-select", + "app-textarea" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nредактировать проект\nудалить проект\nсохранить черновик\nотправить заявку\n\nосновные данные" + } +] diff --git a/docs/desktop-regression/desktop-repeat-loading.json b/docs/desktop-regression/desktop-repeat-loading.json new file mode 100644 index 000000000..97d812e6c --- /dev/null +++ b/docs/desktop-regression/desktop-repeat-loading.json @@ -0,0 +1,12 @@ +[ + { + "name": "loading-action", + "width": 1440, + "passed": true + }, + { + "name": "loading-action", + "width": 1920, + "passed": true + } +] diff --git a/docs/desktop-regression/desktop-repeat-states.json b/docs/desktop-regression/desktop-repeat-states.json new file mode 100644 index 000000000..02e2050be --- /dev/null +++ b/docs/desktop-regression/desktop-repeat-states.json @@ -0,0 +1,32 @@ +[ + { + "name": "empty-feed", + "width": 1440, + "passed": true + }, + { + "name": "empty-vacancies", + "width": 1440, + "passed": true + }, + { + "name": "empty-courses", + "width": 1440, + "passed": true + }, + { + "name": "empty-feed", + "width": 1920, + "passed": true + }, + { + "name": "empty-vacancies", + "width": 1920, + "passed": true + }, + { + "name": "empty-courses", + "width": 1920, + "passed": true + } +] diff --git a/docs/desktop-regression/desktop-repeat.json b/docs/desktop-regression/desktop-repeat.json new file mode 100644 index 000000000..5a4c70444 --- /dev/null +++ b/docs/desktop-regression/desktop-repeat.json @@ -0,0 +1,1152 @@ +[ + { + "name": "feed", + "width": 1440, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости прогр" + }, + { + "name": "projects", + "width": 1440, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-button", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-button", + "app-project-activity-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпроекты\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселер" + }, + { + "name": "my-projects", + "width": 1440, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-bar-new", + "app-list", + "app-info-card", + "app-modal", + "app-button", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-bar-new", + "app-list", + "app-info-card", + "app-button", + "app-project-activity-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпроекты\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПривязан к програм" + }, + { + "name": "members", + "width": 1440, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-back", + "app-search", + "app-member-card", + "app-button", + "app-members-filters", + "app-autocomplete-input", + "app-member-statistics-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-back", + "app-search", + "app-member-card", + "app-button", + "app-members-filters", + "app-autocomplete-input", + "app-member-statistics-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nучастники\n\nПоиск\n\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробело" + }, + { + "name": "programs", + "width": 1440, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026\n\n" + }, + { + "name": "program", + "width": 1440, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nоценка проектов\nаналитика\nпроекты-участники\nучастники\nаналитика\nорганизатор\nУчастники\n1\n" + }, + { + "name": "profile", + "width": 1440, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26" + }, + { + "name": "project", + "width": 1440, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАксе" + }, + { + "name": "vacancies", + "width": 1440, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nвакансии\n\nПоиск\n\nАктивна\n01.10.2026\nДизайнер интерфейсов\nПроект\nОченьДлинноеНазваниеБезП" + }, + { + "name": "vacancy", + "width": 1440, + "actualPath": "/office/vacancies/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nВакансии\nДизайнер интерфейсов\nАктивна\nПроект: ОченьДлинноеНазваниеБезПробеловОченьДлинно" + }, + { + "name": "courses", + "width": 1440, + "actualPath": "/office/courses/all", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-back", + "app-search", + "app-list", + "app-course", + "app-button", + "app-soon-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-back", + "app-search", + "app-list", + "app-course", + "app-soon-card", + "app-button" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nкурсы\n\nПоиск\n\nдоступно всем пользователям\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНа" + }, + { + "name": "course", + "width": 1440, + "actualPath": "/office/courses/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-detail", + "app-soon-card", + "app-course-module-card", + "app-circle-progress-bar", + "app-course-about", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-detail", + "app-soon-card", + "app-course-module-card", + "app-circle-progress-bar", + "app-course-about" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПро" + }, + { + "name": "feed", + "width": 1920, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости прогр" + }, + { + "name": "projects", + "width": 1920, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-button", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-button", + "app-project-activity-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпроекты\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселер" + }, + { + "name": "my-projects", + "width": 1920, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-bar-new", + "app-list", + "app-info-card", + "app-modal", + "app-button", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-back", + "app-search", + "app-bar-new", + "app-list", + "app-info-card", + "app-button", + "app-project-activity-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпроекты\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПривязан к програм" + }, + { + "name": "members", + "width": 1920, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-back", + "app-search", + "app-member-card", + "app-button", + "app-members-filters", + "app-autocomplete-input", + "app-member-statistics-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-back", + "app-search", + "app-member-card", + "app-button", + "app-members-filters", + "app-autocomplete-input", + "app-member-statistics-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nучастники\n\nПоиск\n\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробело" + }, + { + "name": "programs", + "width": 1920, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026\n\n" + }, + { + "name": "program", + "width": 1920, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nоценка проектов\nаналитика\nпроекты-участники\nучастники\nаналитика\nорганизатор\nУчастники\n1\n" + }, + { + "name": "profile", + "width": 1920, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26" + }, + { + "name": "project", + "width": 1920, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАксе" + }, + { + "name": "vacancies", + "width": 1920, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nвакансии\n\nПоиск\n\nАктивна\n01.10.2026\nДизайнер интерфейсов\nПроект\nОченьДлинноеНазваниеБезП" + }, + { + "name": "vacancy", + "width": 1920, + "actualPath": "/office/vacancies/1", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nВакансии\nДизайнер интерфейсов\nАктивна\nПроект: ОченьДлинноеНазваниеБезПробеловОченьДлинно" + }, + { + "name": "courses", + "width": 1920, + "actualPath": "/office/courses/all", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-back", + "app-search", + "app-list", + "app-course", + "app-button", + "app-soon-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-back", + "app-search", + "app-list", + "app-course", + "app-soon-card", + "app-button" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nкурсы\n\nПоиск\n\nдоступно всем пользователям\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНа" + }, + { + "name": "course", + "width": 1920, + "actualPath": "/office/courses/1", + "actualQuery": "", + "viewport": 1920, + "pageWidth": 1905, + "bodyWidth": 1905, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-detail", + "app-soon-card", + "app-course-module-card", + "app-circle-progress-bar", + "app-course-about", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-detail", + "app-soon-card", + "app-course-module-card", + "app-circle-progress-bar", + "app-course-about" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПро" + } +] diff --git a/docs/desktop-regression/eslint.log b/docs/desktop-regression/eslint.log new file mode 100644 index 000000000..f1179cf5e --- /dev/null +++ b/docs/desktop-regression/eslint.log @@ -0,0 +1,19 @@ + +> procollab@0.0.0 lint:ts +> eslint projects/**/*.ts + + +Z:\Документы\PROCOLLAB-dev\procollab-dev-platform-responsive\projects\core\src\lib\services\logger\logger.service.ts + 47:3 warning Unused eslint-disable directive (no problems were reported from 'no-console') + 61:3 warning Unused eslint-disable directive (no problems were reported from 'no-console') + 73:3 warning Unused eslint-disable directive (no problems were reported from 'no-console') + 85:3 warning Unused eslint-disable directive (no problems were reported from 'no-console') + +Z:\Документы\PROCOLLAB-dev\procollab-dev-platform-responsive\projects\social_platform\src\app\domain\chat\chat-message.model.ts + 22:3 warning Unused eslint-disable directive (no problems were reported from 'no-use-before-define') + +Z:\Документы\PROCOLLAB-dev\procollab-dev-platform-responsive\projects\social_platform\src\app\ui\widgets\message-input\message-input.component.ts + 176:3 warning Unused eslint-disable directive (no problems were reported from 'no-use-before-define') + +✖ 6 problems (0 errors, 6 warnings) + 0 errors and 6 warnings potentially fixable with the `--fix` option. diff --git a/docs/desktop-regression/interactions.cjs b/docs/desktop-regression/interactions.cjs new file mode 100644 index 000000000..eeea72d14 --- /dev/null +++ b/docs/desktop-regression/interactions.cjs @@ -0,0 +1,186 @@ +/** @format */ + +const fs = require("node:fs"); +const path = require("node:path"); +const assert = require("node:assert/strict"); +const { launch, assertViewport } = require("../responsive/browser-harness.cjs"); +const fixtures = require("../mobile-polish/fixtures.cjs"); +const rows = []; +const directory = path.join(__dirname, "screenshots", "interactions"); +fs.mkdirSync(directory, { recursive: true }); + +async function goto(h, route, selector) { + h.errors.length = 0; + await h.page.goto(h.base + route); + await h.page.waitForLoadState("networkidle"); + await h.page.locator(selector).first().waitFor(); +} + +async function check(h, name, width, details = {}) { + const measurement = await assertViewport(h.page); + assert.deepEqual(h.errors, []); + const screenshot = `screenshots/interactions/${name}-${width}.png`; + await h.page.screenshot({ path: path.join(__dirname, screenshot), fullPage: true }); + rows.push({ name, width, passed: true, ...details, ...measurement, screenshot }); + console.log(`${name} ${width}: passed`); +} + +(async () => { + for (const width of [320, 390, 768]) { + const h = await launch(width, { isMobile: width < 750, hasTouch: width < 750 }); + h.page.setDefaultTimeout(10000); + try { + await goto(h, "/office/program/all", "app-program-card"); + const region = h.page.locator(".card__region").first(); + assert.equal((await region.textContent()).trim(), "для всей России"); + assert.ok(await region.evaluate(el => el.scrollWidth <= el.clientWidth + 1)); + await h.page.getByRole("button", { name: "Открыть меню", exact: true }).click(); + assert.equal(await h.page.getByRole("button", { name: "Выйти", exact: true }).count(), 1); + await h.page.locator("#mobile-navigation a[routerLink=feed]").click(); + await h.page.locator("app-open-vacancy").waitFor(); + await h.page.waitForLoadState("networkidle"); + assert.equal((await h.page.locator(".nav-bar__title").textContent()).trim(), "Новости"); + const title = await h.page.locator(".nav-bar__title").boundingBox(); + const header = await h.page.locator(".office__top").boundingBox(); + assert.ok(Math.abs(title.x + title.width / 2 - header.x - header.width / 2) <= 1); + assert.equal( + await h.page.locator(".office__top").evaluate(el => getComputedStyle(el).backgroundImage), + "none", + ); + for (const selector of [ + ".nav-bar__toggle", + "button.control-panel__action", + ".control-panel__profile .user", + ]) { + const box = await h.page.locator(selector).boundingBox(); + assert.ok(box.width >= 44 && box.height >= 44, selector + " target"); + } + assert.equal(await h.page.locator("app-feed-filter .filter__option").count(), 6); + assert.equal(await h.page.locator("app-feed-filter .select").count(), 0); + const notifications = h.page.getByRole("button", { name: "Уведомления", exact: true }); + await notifications.focus(); + await h.page.keyboard.press("Enter"); + await h.page.locator(".control-panel__notifications").waitFor(); + assert.equal(await notifications.getAttribute("aria-expanded"), "true"); + await h.page.locator("app-open-vacancy h3").click(); + await h.page.locator(".control-panel__notifications").waitFor({ state: "detached" }); + const noOverlap = await h.page + .locator("app-feed-filter .filter__option") + .evaluateAll(options => + options.every(option => { + const icon = option.querySelector(".filter__option--icon").getBoundingClientRect(); + const label = option.querySelector(".filter__title").getBoundingClientRect(); + const count = option.querySelector(".filter__count").getBoundingClientRect(); + return ( + icon.right <= label.left && (label.bottom <= count.top || label.right <= count.left) + ); + }), + ); + assert.ok(noOverlap); + const toggle = h.page.locator("app-open-vacancy .skills__toggle"); + await toggle.click(); + await h.page.locator("app-open-vacancy app-tag").nth(3).waitFor(); + assert.equal(await toggle.getAttribute("aria-expanded"), "true"); + assert.equal(await h.page.locator("app-open-vacancy app-tag").count(), 4); + const skillVisible = await h.page.locator("app-open-vacancy app-tag").evaluateAll(tags => + tags.every(tag => { + const el = tag.querySelector("p") || tag; + const s = getComputedStyle(el); + return s.textOverflow !== "ellipsis" && el.scrollWidth <= el.clientWidth + 1; + }), + ); + assert.ok(skillVisible); + const category = h.page.locator(".filter__option").filter({ hasText: "свежие вакансии" }); + await category.click(); + await h.page.waitForURL(/includes=vacancy/); + await h.page.waitForLoadState("networkidle"); + assert.equal(await category.getAttribute("aria-pressed"), "true"); + assert.ok(h.requests.some(r => /\/feed\/$/.test(r.path) && /type=vacancy/.test(r.query))); + const disabled = h.page.getByRole("button", { name: /образование/ }); + assert.equal(await disabled.isDisabled(), true); + const url = h.page.url(); + await disabled.evaluate(el => el.click()); + assert.equal(h.page.url(), url); + await check(h, "navigation-feed-skills", width); + + await goto(h, "/office/projects/dashboard", "app-info-card"); + const activity = await h.page.locator("app-project-activity-card").boundingBox(); + const list = await h.page.locator(".page__outlet").boundingBox(); + const parent = await h.page.locator(".page__info").boundingBox(); + assert.ok(activity.y + activity.height <= list.y + 1); + assert.ok(Math.abs(activity.width - parent.width) <= 1); + assert.equal( + await h.page + .locator(".activity__metrics") + .evaluate(el => getComputedStyle(el).gridTemplateColumns.split(" ").length), + 2, + ); + const card = await h.page.locator("app-info-card .card__body").first().boundingBox(); + assert.ok(card.width <= 261 && card.width < parent.width); + await check(h, "projects-activity", width); + + await goto(h, "/office/members", "app-member-card"); + const member = await h.page.locator("app-member-card .member-card").first().boundingBox(); + assert.ok(member.width <= 261); + await check(h, "members", width); + + for (const [name, route] of [ + ["profile", "/office/profile/1"], + ["project", "/office/projects/1"], + ["program", "/office/program/1"], + ]) { + await goto(h, route, ".info__actions app-button"); + const actions = await h.page.locator(".info__actions").boundingBox(); + const children = await h.page + .locator( + ".info__actions > a, .info__actions > app-button, .info__actions > .info__unavailable", + ) + .all(); + for (const child of children) { + if (!(await child.isVisible())) continue; + const box = await child.boundingBox(); + assert.ok(Math.abs(box.width - (actions.width - 12) / 2) <= 1, `${name} action column`); + const button = child.locator("button").first(); + const buttonBox = await button.boundingBox(); + assert.ok( + buttonBox.height >= 44 && Math.abs(buttonBox.width - box.width) <= 1, + `${name} button target`, + ); + } + assert.equal(await h.page.locator(".info__divider:visible").count(), 0); + assert.ok((await h.page.locator(".info__page-header").textContent()).trim().length > 0); + if (name === "project") { + const metadata = await h.page.locator("app-projects-left-side").boundingBox(); + assert.ok(metadata.width > actions.width - 2, "project metadata full width"); + } + if (name === "program") { + const contacts = h.page.getByRole("button", { name: "Контакты", exact: true }); + assert.equal(await contacts.count(), 1); + assert.equal(await contacts.isDisabled(), true); + } + await check(h, `${name}-actions`, width); + } + await h.page.getByRole("link", { name: "Мой профиль", exact: true }).click(); + await h.page.waitForURL(/\/office\/profile\/1$/); + await h.page.waitForLoadState("networkidle"); + assert.equal((await h.page.locator(".nav-bar__title").textContent()).trim(), "Профиль"); + await h.page.getByRole("button", { name: "Открыть меню", exact: true }).click(); + await h.page.locator("#mobile-navigation").waitFor(); + await h.page.waitForFunction(() => !!document.activeElement?.closest("#mobile-navigation")); + await h.page.keyboard.press("Escape"); + await h.page.locator("#mobile-navigation").waitFor({ state: "detached" }); + assert.equal(await h.page.locator("#mobile-navigation").count(), 0); + assert.equal( + await h.page.locator(".nav-bar__toggle").evaluate(el => document.activeElement === el), + true, + ); + } finally { + await h.browser.close(); + } + } + fs.writeFileSync(path.join(__dirname, "interactions.json"), JSON.stringify(rows, null, 2) + "\n"); + console.log(`${rows.length} interaction screens passed`); +})().catch(error => { + console.error(error); + process.exitCode = 1; +}); diff --git a/docs/desktop-regression/interactions.json b/docs/desktop-regression/interactions.json new file mode 100644 index 000000000..0ab753dd2 --- /dev/null +++ b/docs/desktop-regression/interactions.json @@ -0,0 +1,917 @@ +[ + { + "name": "navigation-feed-skills", + "width": 320, + "passed": true, + "actualPath": "/office/feed", + "actualQuery": "?includes=vacancy", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag" + ], + "text": "Новости\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости программ\n0\nобразование\n0\nНовая вакансия\n29.09.2026\nПроект / компания\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nДизайнер интерф", + "screenshot": "screenshots/interactions/navigation-feed-skills-320.png" + }, + { + "name": "projects-activity", + "width": 320, + "passed": true, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nпоказать раздел\n\nмои подписки\n\nГородские проекты\n\nСервис для студенческих команд\n\nОткрыть\nпок", + "screenshot": "screenshots/interactions/projects-activity-320.png" + }, + { + "name": "members", + "width": 320, + "passed": true, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card" + ], + "text": "Участники\nучастники\nФильтры\nПерейти в профиль\nСтатистика\nВсего участников\n—\nВ проектах\n—\nВ программах\n—\nНе удалось загрузить статистику участников\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nРазработчик • 26 л", + "screenshot": "screenshots/interactions/members-320.png" + }, + { + "name": "profile-actions", + "width": 320, + "passed": true, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Профиль\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nнавыки\n\n0 / 15940\n\n01.10.2026\n\nОченьДлинно", + "screenshot": "screenshots/interactions/profile-actions-320.png" + }, + { + "name": "project-actions", + "width": 320, + "passed": true, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "Профиль проекта\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАкселератор студенческих проектов\nСфера\n\nИнформационные технологии\n\nРегион\n\nРостовская область\n\nTRL\n\n1\n\nСрок реализации\n\n2027-01-01\n\nЛидер\nТестовый ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ", + "screenshot": "screenshots/interactions/project-actions-320.png" + }, + { + "name": "program-actions", + "width": 320, + "passed": true, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "Программы\nКейс-чемпионат студенческих проектов\nоценка проектов\nаналитика\nКонтакты\nпроекты-участники\nучастники\nматериалы\nаналитика\nорганизатор\nУчастники\n1\nПроекты\n1\nСдано\nрешений\n0\nБез проектов\n0\n0,0%\nОткрыть →\nо программе\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНаз", + "screenshot": "screenshots/interactions/program-actions-320.png" + }, + { + "name": "navigation-feed-skills", + "width": 390, + "passed": true, + "actualPath": "/office/feed", + "actualQuery": "?includes=vacancy", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag" + ], + "text": "Новости\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости программ\n0\nобразование\n0\nНовая вакансия\n29.09.2026\nПроект / компания\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nДизайнер интерф", + "screenshot": "screenshots/interactions/navigation-feed-skills-390.png" + }, + { + "name": "projects-activity", + "width": 390, + "passed": true, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nпоказать раздел\n\nмои подписки\n\nГородские проекты\n\nСервис для студенческих команд\n\nОткрыть\nпок", + "screenshot": "screenshots/interactions/projects-activity-390.png" + }, + { + "name": "members", + "width": 390, + "passed": true, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card" + ], + "text": "Участники\nучастники\nФильтры\nПерейти в профиль\nСтатистика\nВсего участников\n—\nВ проектах\n—\nВ программах\n—\nНе удалось загрузить статистику участников\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nРазработчик • 26 л", + "screenshot": "screenshots/interactions/members-390.png" + }, + { + "name": "profile-actions", + "width": 390, + "passed": true, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Профиль\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nнавыки\n\n0 / 15940\n\n01.10.2026\n\nОченьДлинно", + "screenshot": "screenshots/interactions/profile-actions-390.png" + }, + { + "name": "project-actions", + "width": 390, + "passed": true, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "Профиль проекта\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАкселератор студенческих проектов\nСфера\n\nИнформационные технологии\n\nРегион\n\nРостовская область\n\nTRL\n\n1\n\nСрок реализации\n\n2027-01-01\n\nЛидер\nТестовый ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ", + "screenshot": "screenshots/interactions/project-actions-390.png" + }, + { + "name": "program-actions", + "width": 390, + "passed": true, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "Программы\nКейс-чемпионат студенческих проектов\nоценка проектов\nаналитика\nКонтакты\nпроекты-участники\nучастники\nматериалы\nаналитика\nорганизатор\nУчастники\n1\nПроекты\n1\nСдано\nрешений\n0\nБез проектов\n0\n0,0%\nОткрыть →\nо программе\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНаз", + "screenshot": "screenshots/interactions/program-actions-390.png" + }, + { + "name": "navigation-feed-skills", + "width": 768, + "passed": true, + "actualPath": "/office/feed", + "actualQuery": "?includes=vacancy", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag" + ], + "text": "Новости\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости программ\n0\nобразование\n0\nНовая вакансия\n29.09.2026\nПроект / компания\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nДизайнер интерф", + "screenshot": "screenshots/interactions/navigation-feed-skills-768.png" + }, + { + "name": "projects-activity", + "width": 768, + "passed": true, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nпоказать раздел\n\nмои подписки\n\nГородские проекты\n\nСервис для студенческих команд\n\nОткрыть\nпок", + "screenshot": "screenshots/interactions/projects-activity-768.png" + }, + { + "name": "members", + "width": 768, + "passed": true, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card" + ], + "text": "Участники\nучастники\nФильтры\nПерейти в профиль\nСтатистика\nВсего участников\n—\nВ проектах\n—\nВ программах\n—\nНе удалось загрузить статистику участников\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nРазработчик • 26 л", + "screenshot": "screenshots/interactions/members-768.png" + }, + { + "name": "profile-actions", + "width": 768, + "passed": true, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Профиль\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nнавыки\n\n0 / 15940\n\n01.10.2026\n\nОченьДлинно", + "screenshot": "screenshots/interactions/profile-actions-768.png" + }, + { + "name": "project-actions", + "width": 768, + "passed": true, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "Профиль проекта\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАкселератор студенческих проектов\nСфера\n\nИнформационные технологии\n\nРегион\n\nРостовская область\n\nTRL\n\n1\n\nСрок реализации\n\n2027-01-01\n\nЛидер\nТестовый ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ", + "screenshot": "screenshots/interactions/project-actions-768.png" + }, + { + "name": "program-actions", + "width": 768, + "passed": true, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "Программы\nКейс-чемпионат студенческих проектов\nоценка проектов\nаналитика\nКонтакты\nпроекты-участники\nучастники\nматериалы\nаналитика\nорганизатор\nУчастники\n1\nПроекты\n1\nСдано\nрешений\n0\nБез проектов\n0\n0,0%\nОткрыть →\nо программе\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНаз", + "screenshot": "screenshots/interactions/program-actions-768.png" + } +] diff --git a/docs/desktop-regression/mobile-after-edit.json b/docs/desktop-regression/mobile-after-edit.json new file mode 100644 index 000000000..79ec36bc7 --- /dev/null +++ b/docs/desktop-regression/mobile-after-edit.json @@ -0,0 +1,341 @@ +[ + { + "name": "profile-edit", + "width": 320, + "actualPath": "/office/profile/edit", + "actualQuery": "?editingStep=main", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-modal", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea" + ], + "text": "Редактирование профиля\nредактирование профиля\ncохранить\nосновные данные\nобразование\nработа\nдостижения\nнавыки\nдействия\nфото\nимя\nфамилия\nРегион\nдата рождения\nспециальность\nобо мне\n\n124 / 300\n\nуказать личные контакты\nдобавить контакт\nтелефон" + }, + { + "name": "project-edit", + "width": 320, + "actualPath": "/office/projects/1/edit", + "actualQuery": "?editingStep=main&programLinkId=1", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-edit", + "app-button", + "app-project-navigation", + "app-tabs", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-modal", + "app-upload-file", + "app-select", + "app-dropdown", + "app-input", + "app-region-select", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-edit", + "app-button", + "app-project-navigation", + "app-tabs", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-upload-file", + "app-select", + "app-input", + "app-region-select", + "app-textarea" + ], + "text": "Редактирование проекта\nудалить проект\nсохранить черновик\nотправить заявку\nосновные данные\nпартнеры и ресурсы\nдостижения\nвакансии\nкоманда\nданные для конкурсов\nлоготип\nпрезентация\n\nПрезентации формата .PDF\nили .PPTX весом до 50МБ\n\nобложка\n\nСтандартная обложка\n\nЗагрузить файл\n1\nназвание\n\n17 / 256\n\nреги" + }, + { + "name": "profile-edit", + "width": 390, + "actualPath": "/office/profile/edit", + "actualQuery": "?editingStep=main", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-modal", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea" + ], + "text": "Редактирование профиля\nредактирование профиля\ncохранить\nосновные данные\nобразование\nработа\nдостижения\nнавыки\nдействия\nфото\nимя\nфамилия\nРегион\nдата рождения\nспециальность\nобо мне\n\n124 / 300\n\nуказать личные контакты\nдобавить контакт\nтелефон" + }, + { + "name": "project-edit", + "width": 390, + "actualPath": "/office/projects/1/edit", + "actualQuery": "?editingStep=main&programLinkId=1", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-edit", + "app-button", + "app-project-navigation", + "app-tabs", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-modal", + "app-upload-file", + "app-select", + "app-dropdown", + "app-input", + "app-region-select", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-edit", + "app-button", + "app-project-navigation", + "app-tabs", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-upload-file", + "app-select", + "app-input", + "app-region-select", + "app-textarea" + ], + "text": "Редактирование проекта\nудалить проект\nсохранить черновик\nотправить заявку\nосновные данные\nпартнеры и ресурсы\nдостижения\nвакансии\nкоманда\nданные для конкурсов\nлоготип\nпрезентация\n\nПрезентации формата .PDF\nили .PPTX весом до 50МБ\n\nобложка\n\nСтандартная обложка\n\nЗагрузить файл\n1\nназвание\n\n17 / 256\n\nреги" + }, + { + "name": "profile-edit", + "width": 768, + "actualPath": "/office/profile/edit", + "actualQuery": "?editingStep=main", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-modal", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea" + ], + "text": "Редактирование профиля\nредактирование профиля\ncохранить\nосновные данные\nобразование\nработа\nдостижения\nнавыки\nдействия\nфото\nимя\nфамилия\nРегион\nдата рождения\nспециальность\nобо мне\n\n124 / 300\n\nуказать личные контакты\nдобавить контакт\nтелефон" + }, + { + "name": "project-edit", + "width": 768, + "actualPath": "/office/projects/1/edit", + "actualQuery": "?editingStep=main&programLinkId=1", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-edit", + "app-button", + "app-project-navigation", + "app-tabs", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-modal", + "app-upload-file", + "app-select", + "app-dropdown", + "app-input", + "app-region-select", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-edit", + "app-button", + "app-project-navigation", + "app-tabs", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-upload-file", + "app-select", + "app-input", + "app-region-select", + "app-textarea" + ], + "text": "Редактирование проекта\nудалить проект\nсохранить черновик\nотправить заявку\nосновные данные\nпартнеры и ресурсы\nдостижения\nвакансии\nкоманда\nданные для конкурсов\nлоготип\nпрезентация\n\nПрезентации формата .PDF\nили .PPTX весом до 50МБ\n\nобложка\n\nСтандартная обложка\n\nЗагрузить файл\n1\nназвание\n\n17 / 256\n\nреги" + } +] diff --git a/docs/desktop-regression/mobile-after.json b/docs/desktop-regression/mobile-after.json new file mode 100644 index 000000000..b58970f67 --- /dev/null +++ b/docs/desktop-regression/mobile-after.json @@ -0,0 +1,1772 @@ +[ + { + "name": "feed", + "width": 320, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag" + ], + "text": "Новости\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости программ\n0\nобразование\n0\nНовая вакансия\n29.09.2026\nПроект / компания\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nДизайнер интерф" + }, + { + "name": "projects", + "width": 320, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nпоказать раздел\n\nмои подписки\n\nГородские проекты\n\nСервис для студенческих команд\n\nОткрыть\nпок" + }, + { + "name": "my-projects", + "width": 320, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nМоя активность\nПроектов\n1\nЯ лидер\n1\nВ программе\n0\nСд" + }, + { + "name": "members", + "width": 320, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card" + ], + "text": "Участники\nучастники\nФильтры\nПерейти в профиль\nСтатистика\nВсего участников\n—\nВ проектах\n—\nВ программах\n—\nНе удалось загрузить статистику участников\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nРазработчик • 26 л" + }, + { + "name": "programs", + "width": 320, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card" + ], + "text": "Программы\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026 - 01.01.2027\n\nдля всей России" + }, + { + "name": "program", + "width": 320, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "Программы\nКейс-чемпионат студенческих проектов\nоценка проектов\nаналитика\nКонтакты\nпроекты-участники\nучастники\nматериалы\nаналитика\nорганизатор\nУчастники\n1\nПроекты\n1\nСдано\nрешений\n0\nБез проектов\n0\n0,0%\nОткрыть →\nо программе\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНаз" + }, + { + "name": "profile", + "width": 320, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Профиль\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nнавыки\n\n0 / 15940\n\n01.10.2026\n\nОченьДлинно" + }, + { + "name": "project", + "width": 320, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "Профиль проекта\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАкселератор студенческих проектов\nСфера\n\nИнформационные технологии\n\nРегион\n\nРостовская область\n\nTRL\n\n1\n\nСрок реализации\n\n2027-01-01\n\nЛидер\nТестовый ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ" + }, + { + "name": "vacancies", + "width": 320, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter" + ], + "text": "Вакансии\nвакансии\n\nПоиск\n\nАктивна\n01.10.2026\nДизайнер интерфейсов\nПроект\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nИщем: Разработчик\n\n100000 ₽\n\nМотивированность\n\nГлубинное интервью\n\nПроектирование пользовательского о" + }, + { + "name": "vacancy", + "width": 320, + "actualPath": "/office/vacancies/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-badge", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-badge", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button" + ], + "text": "Вакансии\nВакансии\nДизайнер интерфейсов\nАктивна\nПроект: ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nИщем: Разработчик\n\n100 000 ₽\nУдаленная работа\nМосква\nОписание вакансии\nПомогите создавать понятные интерфейсы для студе" + }, + { + "name": "courses", + "width": 320, + "actualPath": "/office/courses/all", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge", + "app-soon-card", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge" + ], + "text": "Курсы\nкурсы\n\nПоиск\n\nдоступно всем пользователям\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазвани...\n\n01.01.2026 — 01.01.2027\n\nпродолжить обучение" + }, + { + "name": "course", + "width": 320, + "actualPath": "/office/courses/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-detail", + "app-course-module-card", + "app-circle-progress-bar", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-course-detail", + "app-button", + "app-detail", + "app-course-module-card", + "app-circle-progress-bar" + ], + "text": "Курсы\nаналитика\nо курсе\nназад\nвернуться в программу\n\nпрогресс по курсу\n\n10%\n\nМодуль 1\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\n1 урок\n\n10%" + }, + { + "name": "feed", + "width": 390, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag" + ], + "text": "Новости\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости программ\n0\nобразование\n0\nНовая вакансия\n29.09.2026\nПроект / компания\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nДизайнер интерф" + }, + { + "name": "projects", + "width": 390, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nпоказать раздел\n\nмои подписки\n\nГородские проекты\n\nСервис для студенческих команд\n\nОткрыть\nпок" + }, + { + "name": "my-projects", + "width": 390, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nМоя активность\nПроектов\n1\nЯ лидер\n1\nВ программе\n0\nСд" + }, + { + "name": "members", + "width": 390, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card" + ], + "text": "Участники\nучастники\nФильтры\nПерейти в профиль\nСтатистика\nВсего участников\n—\nВ проектах\n—\nВ программах\n—\nНе удалось загрузить статистику участников\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nРазработчик • 26 л" + }, + { + "name": "programs", + "width": 390, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card" + ], + "text": "Программы\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026 - 01.01.2027\n\nдля всей России" + }, + { + "name": "program", + "width": 390, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "Программы\nКейс-чемпионат студенческих проектов\nоценка проектов\nаналитика\nКонтакты\nпроекты-участники\nучастники\nматериалы\nаналитика\nорганизатор\nУчастники\n1\nПроекты\n1\nСдано\nрешений\n0\nБез проектов\n0\n0,0%\nОткрыть →\nо программе\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНаз" + }, + { + "name": "profile", + "width": 390, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Профиль\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nнавыки\n\n0 / 15940\n\n01.10.2026\n\nОченьДлинно" + }, + { + "name": "project", + "width": 390, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "Профиль проекта\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАкселератор студенческих проектов\nСфера\n\nИнформационные технологии\n\nРегион\n\nРостовская область\n\nTRL\n\n1\n\nСрок реализации\n\n2027-01-01\n\nЛидер\nТестовый ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ" + }, + { + "name": "vacancies", + "width": 390, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter" + ], + "text": "Вакансии\nвакансии\n\nПоиск\n\nАктивна\n01.10.2026\nДизайнер интерфейсов\nПроект\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nИщем: Разработчик\n\n100000 ₽\n\nМотивированность\n\nГлубинное интервью\n\nПроектирование пользовательского о" + }, + { + "name": "vacancy", + "width": 390, + "actualPath": "/office/vacancies/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-badge", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-badge", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button" + ], + "text": "Вакансии\nВакансии\nДизайнер интерфейсов\nАктивна\nПроект: ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nИщем: Разработчик\n\n100 000 ₽\nУдаленная работа\nМосква\nОписание вакансии\nПомогите создавать понятные интерфейсы для студе" + }, + { + "name": "courses", + "width": 390, + "actualPath": "/office/courses/all", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge", + "app-soon-card", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge" + ], + "text": "Курсы\nкурсы\n\nПоиск\n\nдоступно всем пользователям\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазвани...\n\n01.01.2026 — 01.01.2027\n\nпродолжить обучение" + }, + { + "name": "course", + "width": 390, + "actualPath": "/office/courses/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-detail", + "app-course-module-card", + "app-circle-progress-bar", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-course-detail", + "app-button", + "app-detail", + "app-course-module-card", + "app-circle-progress-bar" + ], + "text": "Курсы\nаналитика\nо курсе\nназад\nвернуться в программу\n\nпрогресс по курсу\n\n10%\n\nМодуль 1\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\n1 урок\n\n10%" + }, + { + "name": "feed", + "width": 768, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag" + ], + "text": "Новости\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости программ\n0\nобразование\n0\nНовая вакансия\n29.09.2026\nПроект / компания\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nДизайнер интерф" + }, + { + "name": "projects", + "width": 768, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nпоказать раздел\n\nмои подписки\n\nГородские проекты\n\nСервис для студенческих команд\n\nОткрыть\nпок" + }, + { + "name": "my-projects", + "width": 768, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nМоя активность\nПроектов\n1\nЯ лидер\n1\nВ программе\n0\nСд" + }, + { + "name": "members", + "width": 768, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card" + ], + "text": "Участники\nучастники\nФильтры\nПерейти в профиль\nСтатистика\nВсего участников\n—\nВ проектах\n—\nВ программах\n—\nНе удалось загрузить статистику участников\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nРазработчик • 26 л" + }, + { + "name": "programs", + "width": 768, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card" + ], + "text": "Программы\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026 - 01.01.2027\n\nдля всей России" + }, + { + "name": "program", + "width": 768, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "Программы\nКейс-чемпионат студенческих проектов\nоценка проектов\nаналитика\nКонтакты\nпроекты-участники\nучастники\nматериалы\nаналитика\nорганизатор\nУчастники\n1\nПроекты\n1\nСдано\nрешений\n0\nБез проектов\n0\n0,0%\nОткрыть →\nо программе\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНаз" + }, + { + "name": "profile", + "width": 768, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Профиль\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nнавыки\n\n0 / 15940\n\n01.10.2026\n\nОченьДлинно" + }, + { + "name": "project", + "width": 768, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "Профиль проекта\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАкселератор студенческих проектов\nСфера\n\nИнформационные технологии\n\nРегион\n\nРостовская область\n\nTRL\n\n1\n\nСрок реализации\n\n2027-01-01\n\nЛидер\nТестовый ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ" + }, + { + "name": "vacancies", + "width": 768, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter" + ], + "text": "Вакансии\nвакансии\n\nПоиск\n\nАктивна\n01.10.2026\nДизайнер интерфейсов\nПроект\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nИщем: Разработчик\n\n100000 ₽\n\nМотивированность\n\nГлубинное интервью\n\nПроектирование пользовательского о" + }, + { + "name": "vacancy", + "width": 768, + "actualPath": "/office/vacancies/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-badge", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-badge", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button" + ], + "text": "Вакансии\nВакансии\nДизайнер интерфейсов\nАктивна\nПроект: ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nИщем: Разработчик\n\n100 000 ₽\nУдаленная работа\nМосква\nОписание вакансии\nПомогите создавать понятные интерфейсы для студе" + }, + { + "name": "courses", + "width": 768, + "actualPath": "/office/courses/all", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge", + "app-soon-card", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge" + ], + "text": "Курсы\nкурсы\n\nПоиск\n\nдоступно всем пользователям\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазвани...\n\n01.01.2026 — 01.01.2027\n\nпродолжить обучение" + }, + { + "name": "course", + "width": 768, + "actualPath": "/office/courses/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-detail", + "app-course-module-card", + "app-circle-progress-bar", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-course-detail", + "app-button", + "app-detail", + "app-course-module-card", + "app-circle-progress-bar" + ], + "text": "Курсы\nаналитика\nо курсе\nназад\nвернуться в программу\n\nпрогресс по курсу\n\n10%\n\nМодуль 1\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\n1 урок\n\n10%" + } +] diff --git a/docs/desktop-regression/mobile-before-edit.json b/docs/desktop-regression/mobile-before-edit.json new file mode 100644 index 000000000..79ec36bc7 --- /dev/null +++ b/docs/desktop-regression/mobile-before-edit.json @@ -0,0 +1,341 @@ +[ + { + "name": "profile-edit", + "width": 320, + "actualPath": "/office/profile/edit", + "actualQuery": "?editingStep=main", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-modal", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea" + ], + "text": "Редактирование профиля\nредактирование профиля\ncохранить\nосновные данные\nобразование\nработа\nдостижения\nнавыки\nдействия\nфото\nимя\nфамилия\nРегион\nдата рождения\nспециальность\nобо мне\n\n124 / 300\n\nуказать личные контакты\nдобавить контакт\nтелефон" + }, + { + "name": "project-edit", + "width": 320, + "actualPath": "/office/projects/1/edit", + "actualQuery": "?editingStep=main&programLinkId=1", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-edit", + "app-button", + "app-project-navigation", + "app-tabs", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-modal", + "app-upload-file", + "app-select", + "app-dropdown", + "app-input", + "app-region-select", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-edit", + "app-button", + "app-project-navigation", + "app-tabs", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-upload-file", + "app-select", + "app-input", + "app-region-select", + "app-textarea" + ], + "text": "Редактирование проекта\nудалить проект\nсохранить черновик\nотправить заявку\nосновные данные\nпартнеры и ресурсы\nдостижения\nвакансии\nкоманда\nданные для конкурсов\nлоготип\nпрезентация\n\nПрезентации формата .PDF\nили .PPTX весом до 50МБ\n\nобложка\n\nСтандартная обложка\n\nЗагрузить файл\n1\nназвание\n\n17 / 256\n\nреги" + }, + { + "name": "profile-edit", + "width": 390, + "actualPath": "/office/profile/edit", + "actualQuery": "?editingStep=main", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-modal", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea" + ], + "text": "Редактирование профиля\nредактирование профиля\ncохранить\nосновные данные\nобразование\nработа\nдостижения\nнавыки\nдействия\nфото\nимя\nфамилия\nРегион\nдата рождения\nспециальность\nобо мне\n\n124 / 300\n\nуказать личные контакты\nдобавить контакт\nтелефон" + }, + { + "name": "project-edit", + "width": 390, + "actualPath": "/office/projects/1/edit", + "actualQuery": "?editingStep=main&programLinkId=1", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-edit", + "app-button", + "app-project-navigation", + "app-tabs", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-modal", + "app-upload-file", + "app-select", + "app-dropdown", + "app-input", + "app-region-select", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-edit", + "app-button", + "app-project-navigation", + "app-tabs", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-upload-file", + "app-select", + "app-input", + "app-region-select", + "app-textarea" + ], + "text": "Редактирование проекта\nудалить проект\nсохранить черновик\nотправить заявку\nосновные данные\nпартнеры и ресурсы\nдостижения\nвакансии\nкоманда\nданные для конкурсов\nлоготип\nпрезентация\n\nПрезентации формата .PDF\nили .PPTX весом до 50МБ\n\nобложка\n\nСтандартная обложка\n\nЗагрузить файл\n1\nназвание\n\n17 / 256\n\nреги" + }, + { + "name": "profile-edit", + "width": 768, + "actualPath": "/office/profile/edit", + "actualQuery": "?editingStep=main", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-modal", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea" + ], + "text": "Редактирование профиля\nредактирование профиля\ncохранить\nосновные данные\nобразование\nработа\nдостижения\nнавыки\nдействия\nфото\nимя\nфамилия\nРегион\nдата рождения\nспециальность\nобо мне\n\n124 / 300\n\nуказать личные контакты\nдобавить контакт\nтелефон" + }, + { + "name": "project-edit", + "width": 768, + "actualPath": "/office/projects/1/edit", + "actualQuery": "?editingStep=main&programLinkId=1", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-edit", + "app-button", + "app-project-navigation", + "app-tabs", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-modal", + "app-upload-file", + "app-select", + "app-dropdown", + "app-input", + "app-region-select", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-edit", + "app-button", + "app-project-navigation", + "app-tabs", + "app-project-main-step", + "app-avatar-control", + "app-tooltip", + "app-upload-file", + "app-select", + "app-input", + "app-region-select", + "app-textarea" + ], + "text": "Редактирование проекта\nудалить проект\nсохранить черновик\nотправить заявку\nосновные данные\nпартнеры и ресурсы\nдостижения\nвакансии\nкоманда\nданные для конкурсов\nлоготип\nпрезентация\n\nПрезентации формата .PDF\nили .PPTX весом до 50МБ\n\nобложка\n\nСтандартная обложка\n\nЗагрузить файл\n1\nназвание\n\n17 / 256\n\nреги" + } +] diff --git a/docs/desktop-regression/mobile-before.json b/docs/desktop-regression/mobile-before.json new file mode 100644 index 000000000..b58970f67 --- /dev/null +++ b/docs/desktop-regression/mobile-before.json @@ -0,0 +1,1772 @@ +[ + { + "name": "feed", + "width": 320, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag" + ], + "text": "Новости\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости программ\n0\nобразование\n0\nНовая вакансия\n29.09.2026\nПроект / компания\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nДизайнер интерф" + }, + { + "name": "projects", + "width": 320, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nпоказать раздел\n\nмои подписки\n\nГородские проекты\n\nСервис для студенческих команд\n\nОткрыть\nпок" + }, + { + "name": "my-projects", + "width": 320, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nМоя активность\nПроектов\n1\nЯ лидер\n1\nВ программе\n0\nСд" + }, + { + "name": "members", + "width": 320, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card" + ], + "text": "Участники\nучастники\nФильтры\nПерейти в профиль\nСтатистика\nВсего участников\n—\nВ проектах\n—\nВ программах\n—\nНе удалось загрузить статистику участников\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nРазработчик • 26 л" + }, + { + "name": "programs", + "width": 320, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card" + ], + "text": "Программы\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026 - 01.01.2027\n\nдля всей России" + }, + { + "name": "program", + "width": 320, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "Программы\nКейс-чемпионат студенческих проектов\nоценка проектов\nаналитика\nКонтакты\nпроекты-участники\nучастники\nматериалы\nаналитика\nорганизатор\nУчастники\n1\nПроекты\n1\nСдано\nрешений\n0\nБез проектов\n0\n0,0%\nОткрыть →\nо программе\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНаз" + }, + { + "name": "profile", + "width": 320, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Профиль\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nнавыки\n\n0 / 15940\n\n01.10.2026\n\nОченьДлинно" + }, + { + "name": "project", + "width": 320, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "Профиль проекта\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАкселератор студенческих проектов\nСфера\n\nИнформационные технологии\n\nРегион\n\nРостовская область\n\nTRL\n\n1\n\nСрок реализации\n\n2027-01-01\n\nЛидер\nТестовый ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ" + }, + { + "name": "vacancies", + "width": 320, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter" + ], + "text": "Вакансии\nвакансии\n\nПоиск\n\nАктивна\n01.10.2026\nДизайнер интерфейсов\nПроект\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nИщем: Разработчик\n\n100000 ₽\n\nМотивированность\n\nГлубинное интервью\n\nПроектирование пользовательского о" + }, + { + "name": "vacancy", + "width": 320, + "actualPath": "/office/vacancies/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-badge", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-badge", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button" + ], + "text": "Вакансии\nВакансии\nДизайнер интерфейсов\nАктивна\nПроект: ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nИщем: Разработчик\n\n100 000 ₽\nУдаленная работа\nМосква\nОписание вакансии\nПомогите создавать понятные интерфейсы для студе" + }, + { + "name": "courses", + "width": 320, + "actualPath": "/office/courses/all", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge", + "app-soon-card", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge" + ], + "text": "Курсы\nкурсы\n\nПоиск\n\nдоступно всем пользователям\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазвани...\n\n01.01.2026 — 01.01.2027\n\nпродолжить обучение" + }, + { + "name": "course", + "width": 320, + "actualPath": "/office/courses/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-detail", + "app-course-module-card", + "app-circle-progress-bar", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-course-detail", + "app-button", + "app-detail", + "app-course-module-card", + "app-circle-progress-bar" + ], + "text": "Курсы\nаналитика\nо курсе\nназад\nвернуться в программу\n\nпрогресс по курсу\n\n10%\n\nМодуль 1\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\n1 урок\n\n10%" + }, + { + "name": "feed", + "width": 390, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag" + ], + "text": "Новости\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости программ\n0\nобразование\n0\nНовая вакансия\n29.09.2026\nПроект / компания\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nДизайнер интерф" + }, + { + "name": "projects", + "width": 390, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nпоказать раздел\n\nмои подписки\n\nГородские проекты\n\nСервис для студенческих команд\n\nОткрыть\nпок" + }, + { + "name": "my-projects", + "width": 390, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nМоя активность\nПроектов\n1\nЯ лидер\n1\nВ программе\n0\nСд" + }, + { + "name": "members", + "width": 390, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card" + ], + "text": "Участники\nучастники\nФильтры\nПерейти в профиль\nСтатистика\nВсего участников\n—\nВ проектах\n—\nВ программах\n—\nНе удалось загрузить статистику участников\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nРазработчик • 26 л" + }, + { + "name": "programs", + "width": 390, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card" + ], + "text": "Программы\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026 - 01.01.2027\n\nдля всей России" + }, + { + "name": "program", + "width": 390, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "Программы\nКейс-чемпионат студенческих проектов\nоценка проектов\nаналитика\nКонтакты\nпроекты-участники\nучастники\nматериалы\nаналитика\nорганизатор\nУчастники\n1\nПроекты\n1\nСдано\nрешений\n0\nБез проектов\n0\n0,0%\nОткрыть →\nо программе\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНаз" + }, + { + "name": "profile", + "width": 390, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Профиль\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nнавыки\n\n0 / 15940\n\n01.10.2026\n\nОченьДлинно" + }, + { + "name": "project", + "width": 390, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "Профиль проекта\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАкселератор студенческих проектов\nСфера\n\nИнформационные технологии\n\nРегион\n\nРостовская область\n\nTRL\n\n1\n\nСрок реализации\n\n2027-01-01\n\nЛидер\nТестовый ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ" + }, + { + "name": "vacancies", + "width": 390, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter" + ], + "text": "Вакансии\nвакансии\n\nПоиск\n\nАктивна\n01.10.2026\nДизайнер интерфейсов\nПроект\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nИщем: Разработчик\n\n100000 ₽\n\nМотивированность\n\nГлубинное интервью\n\nПроектирование пользовательского о" + }, + { + "name": "vacancy", + "width": 390, + "actualPath": "/office/vacancies/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-badge", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-badge", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button" + ], + "text": "Вакансии\nВакансии\nДизайнер интерфейсов\nАктивна\nПроект: ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nИщем: Разработчик\n\n100 000 ₽\nУдаленная работа\nМосква\nОписание вакансии\nПомогите создавать понятные интерфейсы для студе" + }, + { + "name": "courses", + "width": 390, + "actualPath": "/office/courses/all", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge", + "app-soon-card", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge" + ], + "text": "Курсы\nкурсы\n\nПоиск\n\nдоступно всем пользователям\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазвани...\n\n01.01.2026 — 01.01.2027\n\nпродолжить обучение" + }, + { + "name": "course", + "width": 390, + "actualPath": "/office/courses/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-detail", + "app-course-module-card", + "app-circle-progress-bar", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-course-detail", + "app-button", + "app-detail", + "app-course-module-card", + "app-circle-progress-bar" + ], + "text": "Курсы\nаналитика\nо курсе\nназад\nвернуться в программу\n\nпрогресс по курсу\n\n10%\n\nМодуль 1\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\n1 урок\n\n10%" + }, + { + "name": "feed", + "width": 768, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag" + ], + "text": "Новости\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости программ\n0\nобразование\n0\nНовая вакансия\n29.09.2026\nПроект / компания\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nДизайнер интерф" + }, + { + "name": "projects", + "width": 768, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nпоказать раздел\n\nмои подписки\n\nГородские проекты\n\nСервис для студенческих команд\n\nОткрыть\nпок" + }, + { + "name": "my-projects", + "width": 768, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nМоя активность\nПроектов\n1\nЯ лидер\n1\nВ программе\n0\nСд" + }, + { + "name": "members", + "width": 768, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card" + ], + "text": "Участники\nучастники\nФильтры\nПерейти в профиль\nСтатистика\nВсего участников\n—\nВ проектах\n—\nВ программах\n—\nНе удалось загрузить статистику участников\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nРазработчик • 26 л" + }, + { + "name": "programs", + "width": 768, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card" + ], + "text": "Программы\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026 - 01.01.2027\n\nдля всей России" + }, + { + "name": "program", + "width": 768, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "Программы\nКейс-чемпионат студенческих проектов\nоценка проектов\nаналитика\nКонтакты\nпроекты-участники\nучастники\nматериалы\nаналитика\nорганизатор\nУчастники\n1\nПроекты\n1\nСдано\nрешений\n0\nБез проектов\n0\n0,0%\nОткрыть →\nо программе\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНаз" + }, + { + "name": "profile", + "width": 768, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Профиль\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nнавыки\n\n0 / 15940\n\n01.10.2026\n\nОченьДлинно" + }, + { + "name": "project", + "width": 768, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "Профиль проекта\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАкселератор студенческих проектов\nСфера\n\nИнформационные технологии\n\nРегион\n\nРостовская область\n\nTRL\n\n1\n\nСрок реализации\n\n2027-01-01\n\nЛидер\nТестовый ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ" + }, + { + "name": "vacancies", + "width": 768, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter" + ], + "text": "Вакансии\nвакансии\n\nПоиск\n\nАктивна\n01.10.2026\nДизайнер интерфейсов\nПроект\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nИщем: Разработчик\n\n100000 ₽\n\nМотивированность\n\nГлубинное интервью\n\nПроектирование пользовательского о" + }, + { + "name": "vacancy", + "width": 768, + "actualPath": "/office/vacancies/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-badge", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-vacancies-detail", + "app-back", + "app-vacancy-status", + "app-badge", + "app-detail", + "app-vacancies-left-side", + "app-vacancy-skills", + "app-tag", + "app-vacancies-right-side", + "app-button" + ], + "text": "Вакансии\nВакансии\nДизайнер интерфейсов\nАктивна\nПроект: ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nИщем: Разработчик\n\n100 000 ₽\nУдаленная работа\nМосква\nОписание вакансии\nПомогите создавать понятные интерфейсы для студе" + }, + { + "name": "courses", + "width": 768, + "actualPath": "/office/courses/all", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge", + "app-soon-card", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge" + ], + "text": "Курсы\nкурсы\n\nПоиск\n\nдоступно всем пользователям\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазвани...\n\n01.01.2026 — 01.01.2027\n\nпродолжить обучение" + }, + { + "name": "course", + "width": 768, + "actualPath": "/office/courses/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-detail", + "app-course-module-card", + "app-circle-progress-bar", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-course-detail", + "app-button", + "app-detail", + "app-course-module-card", + "app-circle-progress-bar" + ], + "text": "Курсы\nаналитика\nо курсе\nназад\nвернуться в программу\n\nпрогресс по курсу\n\n10%\n\nМодуль 1\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\n1 урок\n\n10%" + } +] diff --git a/docs/desktop-regression/resize.cjs b/docs/desktop-regression/resize.cjs new file mode 100644 index 000000000..49450b566 --- /dev/null +++ b/docs/desktop-regression/resize.cjs @@ -0,0 +1,74 @@ +/** @format */ + +const assert = require("node:assert/strict"); +const fs = require("node:fs"); +const { launch, assertViewport } = require("../responsive/browser-harness.cjs"); +require("../mobile-polish/fixtures.cjs"); +(async () => { + const h = await launch(390); + const rows = []; + try { + await h.page.goto(h.base + "/office/feed"); + await h.page.waitForLoadState("networkidle"); + await h.page.getByRole("button", { name: /свежие вакансии/ }).click(); + await h.page.waitForLoadState("networkidle"); + await h.page.evaluate(() => { + window.qaFeedRoot = document.querySelector("app-feed .page"); + if (!window.qaFeedRoot) throw new Error("Feed root missing"); + }); + const query = new URL(h.page.url()).search; + for (const width of [1000, 768, 390]) { + await h.page.setViewportSize({ width, height: 844 }); + await h.page.waitForFunction(width => innerWidth === width, width); + await h.page.waitForFunction( + width => !!document.querySelector("button.control-panel__action") === width < 1000, + width, + ); + await assertViewport(h.page); + assert.equal(new URL(h.page.url()).search, query); + assert.equal( + await h.page.evaluate(() => window.qaFeedRoot === document.querySelector("app-feed .page")), + true, + ); + rows.push({ screen: "feed", width, preserved: true }); + } + await h.page.evaluate(() => { + history.pushState({}, "", "/office/projects/dashboard"); + dispatchEvent(new PopStateEvent("popstate")); + }); + await h.page.locator("app-dashboard-item").first().waitFor(); + const input = h.page.locator("app-projects app-search input"); + await h.page.locator("app-projects app-search .search").click(); + await input.fill("город"); + await h.page.waitForTimeout(500); // Existing search debounce. + await h.page.evaluate(() => { + window.qaDashboard = document.querySelector("app-dashboard-item").parentElement; + }); + const route = h.page.url(); + for (const width of [1000, 768, 390]) { + await h.page.setViewportSize({ width, height: 844 }); + await h.page.waitForFunction( + width => !!document.querySelector("app-projects app-page-header") === width < 1000, + width, + ); + await assertViewport(h.page); + assert.equal(await input.inputValue(), "город"); + assert.equal(h.page.url(), route); + assert.equal( + await h.page.evaluate( + () => window.qaDashboard === document.querySelector("app-dashboard-item").parentElement, + ), + true, + ); + rows.push({ screen: "projects", width, preserved: true }); + } + assert.deepEqual(h.errors, []); + fs.writeFileSync(__dirname + "/resize.json", JSON.stringify(rows, null, 2) + "\n"); + console.log("6 resize checks passed; routed hosts, search and filters preserved"); + } finally { + await h.browser.close(); + } +})().catch(error => { + console.error(error); + process.exitCode = 1; +}); diff --git a/docs/desktop-regression/resize.json b/docs/desktop-regression/resize.json new file mode 100644 index 000000000..0441fe358 --- /dev/null +++ b/docs/desktop-regression/resize.json @@ -0,0 +1,32 @@ +[ + { + "screen": "feed", + "width": 1000, + "preserved": true + }, + { + "screen": "feed", + "width": 768, + "preserved": true + }, + { + "screen": "feed", + "width": 390, + "preserved": true + }, + { + "screen": "projects", + "width": 1000, + "preserved": true + }, + { + "screen": "projects", + "width": 768, + "preserved": true + }, + { + "screen": "projects", + "width": 390, + "preserved": true + } +] diff --git a/docs/desktop-regression/review.md b/docs/desktop-regression/review.md new file mode 100644 index 000000000..a95092fa9 --- /dev/null +++ b/docs/desktop-regression/review.md @@ -0,0 +1,67 @@ + + +# Requirement audit и review + +Scope: восстановить desktop `dev` до #401 и сохранить адаптив из #403. +Review выполнен в текущей задаче по `procollab-review`, PR preparation — по `procollab-pr`. +Visual reference задан пользователем; новое продуктовое/design решение не вводилось. + +| AC | Реализация / evidence | Verdict | +| ------------------------------------------ | ---------------------------------------------------------------------------------------- | --------------------------------------- | +| Desktop ≥1000 сохраняет прежнюю композицию | Scoped styles и legacy fragments; 36 exact pixel comparisons с `5fe4d5c6` | PASS | +| Приоритетные разделы и shared Button/Card | 14 экранов + 3 empty states + loading action на 1440/1920; [сравнение](README.md) | PASS | +| Pixel regression обязателен | `compare.py --check`: размер + exact RGB; reference repeat и after: 36/36, 0 pixels | PASS | +| Mobile/tablet сохраняется | 42 exact comparisons с `1138fe0c` на 320/390/768; 48 states, 18 interactions | PASS | +| Breakpoint не сбрасывает текущую страницу | 6 resize checks: same DOM roots, search value, route/filter query сохранены | PASS | +| API/permissions/business rules сохранены | Нет diff в API/domain/infrastructure, DTO, routes, dependencies; прежние handlers/guards | PASS by source + unit/integration tests | + +## Checked by source + +- Media boundary `<1000px` и desktop legacy values, canonical Button/Avatar/Icon consumers. +- Presentation service не содержит domain/API решений. Корни router/search/forms не дублируются. +- Имеющиеся role conditions и handlers сохранены в обеих presentation-ветках. +- Forms/CVA, save/autosave services, HTTP contracts, IDs, server-owned permissions и deadlines не менялись. +- `git diff --exit-code origin/dev -- projects/social_platform/src/app/api projects/social_platform/src/app/domain projects/social_platform/src/app/infrastructure package.json package-lock.json angular.json` — пустой diff. +- Дополнительно восстановлена desktop ширина 605 px двух информационных диалогов редактора проекта. + +## Checked by tests / build + +- `npm run test:ci`: 2006 tests, 406 files. Runner по-прежнему исключает + `projects.component.spec.ts`, `program.component.spec.ts`, `editor-submit-button.directive.spec.ts`. +- Placement regression проверяет условия размещения activity через Angular template AST. +- `npm run build:social:prod`: успешная компиляция TypeScript/templates/styles, budgets сохранены. +- `npm run lint:ts`: 0 errors, 6 прежних warnings. SCSS проверен на изменённых файлах. + +## Checked in browser + +- Windows / installed Chrome / одинаковые fixture responses и browser context. +- Desktop reference repeat, before/after, mobile before/after: strict pixel equality, без masks. +- Loading page/action, pending action без повторного запроса, empty, HTTP 500/retry, + disabled controls и validation регистрации/onboarding: [48 checks](states.json). +- Центр мобильной шапки, drawer route transition/Escape/focus return, notifications с клавиатуры, + filter query/request, полные навыки, карточки и Detail actions: [18 checks](interactions.json). +- Поиск/фильтр после resize: [6 checks](resize.json). + +## Findings и устранение + +- MAJOR: общие UI Kit геометрия/типографика меняли desktop consumers. Ограничены mobile, + прежние desktop styles/markup восстановлены; exact comparisons проходят. +- MAJOR: shared Tabs заменили прежнюю desktop step navigation. Legacy desktop markup восстановлен, + оба редактора включены в pixel comparison. +- MINOR: медиа-обёртка изменила CSS cascade полей и их mobile padding. Сохранён исходный + каскад responsive controls, повторные сравнения editor ширин проходят. +- Test harness: Escape отправлялся до появления drawer и захвата фокуса. Теперь проверка ждёт + реальный dialog/focus, затем проверяет закрытие и возврат фокуса; assertions не ослаблены. + +Нерешённых actionable findings в проверенном scope нет. + +## Not checked / limits + +- Реальные iOS/Android на dev и production. Device smoke-test после merge остаётся обязательным. +- Live backend данные и полный role matrix; server permissions не изменялись и заново не аудировались. +- Каждый скрытый scroll section, popup и возможный async state не покрыт pixel screenshots. + Desktop pixel states: empty feed/vacancies/courses и loading action; остальные error/disabled/validation покрыты mobile state checks. +- Onboarding desktop не входит в набор desktop pixel goldens; его прежняя геометрия восстановлена по source. + +Verdict: READY TO MERGE INTO DEV для реализации. Dev acceptance и физический device smoke-test +требуются после merge перед production handoff. diff --git a/docs/desktop-regression/screenshots/desktop-after/course-1440.png b/docs/desktop-regression/screenshots/desktop-after/course-1440.png new file mode 100644 index 000000000..28fc758f0 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/course-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/course-1920.png b/docs/desktop-regression/screenshots/desktop-after/course-1920.png new file mode 100644 index 000000000..a9a068cdb Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/course-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/courses-1440.png b/docs/desktop-regression/screenshots/desktop-after/courses-1440.png new file mode 100644 index 000000000..cbe2f3efa Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/courses-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/courses-1920.png b/docs/desktop-regression/screenshots/desktop-after/courses-1920.png new file mode 100644 index 000000000..97aff998b Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/courses-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/empty-courses-1440.png b/docs/desktop-regression/screenshots/desktop-after/empty-courses-1440.png new file mode 100644 index 000000000..a64d1a410 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/empty-courses-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/empty-courses-1920.png b/docs/desktop-regression/screenshots/desktop-after/empty-courses-1920.png new file mode 100644 index 000000000..f2afde1ca Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/empty-courses-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/empty-feed-1440.png b/docs/desktop-regression/screenshots/desktop-after/empty-feed-1440.png new file mode 100644 index 000000000..390f08614 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/empty-feed-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/empty-feed-1920.png b/docs/desktop-regression/screenshots/desktop-after/empty-feed-1920.png new file mode 100644 index 000000000..8021bdd96 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/empty-feed-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/empty-vacancies-1440.png b/docs/desktop-regression/screenshots/desktop-after/empty-vacancies-1440.png new file mode 100644 index 000000000..25e0d187d Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/empty-vacancies-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/empty-vacancies-1920.png b/docs/desktop-regression/screenshots/desktop-after/empty-vacancies-1920.png new file mode 100644 index 000000000..f0d772dbc Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/empty-vacancies-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/feed-1440.png b/docs/desktop-regression/screenshots/desktop-after/feed-1440.png new file mode 100644 index 000000000..5c1f6b5ba Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/feed-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/feed-1920.png b/docs/desktop-regression/screenshots/desktop-after/feed-1920.png new file mode 100644 index 000000000..dbbc494e2 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/feed-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/loading-action-1440.png b/docs/desktop-regression/screenshots/desktop-after/loading-action-1440.png new file mode 100644 index 000000000..f9a423c68 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/loading-action-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/loading-action-1920.png b/docs/desktop-regression/screenshots/desktop-after/loading-action-1920.png new file mode 100644 index 000000000..ab14093b0 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/loading-action-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/members-1440.png b/docs/desktop-regression/screenshots/desktop-after/members-1440.png new file mode 100644 index 000000000..82ba26d32 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/members-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/members-1920.png b/docs/desktop-regression/screenshots/desktop-after/members-1920.png new file mode 100644 index 000000000..88d9735d1 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/members-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/my-projects-1440.png b/docs/desktop-regression/screenshots/desktop-after/my-projects-1440.png new file mode 100644 index 000000000..b68148c3c Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/my-projects-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/my-projects-1920.png b/docs/desktop-regression/screenshots/desktop-after/my-projects-1920.png new file mode 100644 index 000000000..f35605787 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/my-projects-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/profile-1440.png b/docs/desktop-regression/screenshots/desktop-after/profile-1440.png new file mode 100644 index 000000000..bdf7b8893 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/profile-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/profile-1920.png b/docs/desktop-regression/screenshots/desktop-after/profile-1920.png new file mode 100644 index 000000000..694c06e11 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/profile-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/profile-edit-1440.png b/docs/desktop-regression/screenshots/desktop-after/profile-edit-1440.png new file mode 100644 index 000000000..c476a08d3 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/profile-edit-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/profile-edit-1920.png b/docs/desktop-regression/screenshots/desktop-after/profile-edit-1920.png new file mode 100644 index 000000000..c5375fb79 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/profile-edit-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/program-1440.png b/docs/desktop-regression/screenshots/desktop-after/program-1440.png new file mode 100644 index 000000000..d75134d8d Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/program-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/program-1920.png b/docs/desktop-regression/screenshots/desktop-after/program-1920.png new file mode 100644 index 000000000..a6533d244 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/program-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/programs-1440.png b/docs/desktop-regression/screenshots/desktop-after/programs-1440.png new file mode 100644 index 000000000..bd1e531bd Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/programs-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/programs-1920.png b/docs/desktop-regression/screenshots/desktop-after/programs-1920.png new file mode 100644 index 000000000..2ac2fca15 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/programs-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/project-1440.png b/docs/desktop-regression/screenshots/desktop-after/project-1440.png new file mode 100644 index 000000000..ca9c33f86 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/project-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/project-1920.png b/docs/desktop-regression/screenshots/desktop-after/project-1920.png new file mode 100644 index 000000000..57b237a69 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/project-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/project-edit-1440.png b/docs/desktop-regression/screenshots/desktop-after/project-edit-1440.png new file mode 100644 index 000000000..bd450be9c Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/project-edit-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/project-edit-1920.png b/docs/desktop-regression/screenshots/desktop-after/project-edit-1920.png new file mode 100644 index 000000000..1e66e1a61 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/project-edit-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/projects-1440.png b/docs/desktop-regression/screenshots/desktop-after/projects-1440.png new file mode 100644 index 000000000..80253540a Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/projects-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/projects-1920.png b/docs/desktop-regression/screenshots/desktop-after/projects-1920.png new file mode 100644 index 000000000..ed8ded08e Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/projects-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/vacancies-1440.png b/docs/desktop-regression/screenshots/desktop-after/vacancies-1440.png new file mode 100644 index 000000000..cffaf991b Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/vacancies-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/vacancies-1920.png b/docs/desktop-regression/screenshots/desktop-after/vacancies-1920.png new file mode 100644 index 000000000..da5a70205 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/vacancies-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/vacancy-1440.png b/docs/desktop-regression/screenshots/desktop-after/vacancy-1440.png new file mode 100644 index 000000000..bb61fa169 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/vacancy-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-after/vacancy-1920.png b/docs/desktop-regression/screenshots/desktop-after/vacancy-1920.png new file mode 100644 index 000000000..7b456f551 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-after/vacancy-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/course-1440.png b/docs/desktop-regression/screenshots/desktop-before/course-1440.png new file mode 100644 index 000000000..28fc758f0 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/course-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/course-1920.png b/docs/desktop-regression/screenshots/desktop-before/course-1920.png new file mode 100644 index 000000000..a9a068cdb Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/course-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/courses-1440.png b/docs/desktop-regression/screenshots/desktop-before/courses-1440.png new file mode 100644 index 000000000..cbe2f3efa Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/courses-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/courses-1920.png b/docs/desktop-regression/screenshots/desktop-before/courses-1920.png new file mode 100644 index 000000000..97aff998b Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/courses-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/empty-courses-1440.png b/docs/desktop-regression/screenshots/desktop-before/empty-courses-1440.png new file mode 100644 index 000000000..a64d1a410 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/empty-courses-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/empty-courses-1920.png b/docs/desktop-regression/screenshots/desktop-before/empty-courses-1920.png new file mode 100644 index 000000000..f2afde1ca Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/empty-courses-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/empty-feed-1440.png b/docs/desktop-regression/screenshots/desktop-before/empty-feed-1440.png new file mode 100644 index 000000000..390f08614 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/empty-feed-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/empty-feed-1920.png b/docs/desktop-regression/screenshots/desktop-before/empty-feed-1920.png new file mode 100644 index 000000000..8021bdd96 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/empty-feed-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/empty-vacancies-1440.png b/docs/desktop-regression/screenshots/desktop-before/empty-vacancies-1440.png new file mode 100644 index 000000000..25e0d187d Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/empty-vacancies-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/empty-vacancies-1920.png b/docs/desktop-regression/screenshots/desktop-before/empty-vacancies-1920.png new file mode 100644 index 000000000..f0d772dbc Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/empty-vacancies-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/feed-1440.png b/docs/desktop-regression/screenshots/desktop-before/feed-1440.png new file mode 100644 index 000000000..5c1f6b5ba Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/feed-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/feed-1920.png b/docs/desktop-regression/screenshots/desktop-before/feed-1920.png new file mode 100644 index 000000000..dbbc494e2 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/feed-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/loading-action-1440.png b/docs/desktop-regression/screenshots/desktop-before/loading-action-1440.png new file mode 100644 index 000000000..f9a423c68 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/loading-action-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/loading-action-1920.png b/docs/desktop-regression/screenshots/desktop-before/loading-action-1920.png new file mode 100644 index 000000000..ab14093b0 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/loading-action-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/members-1440.png b/docs/desktop-regression/screenshots/desktop-before/members-1440.png new file mode 100644 index 000000000..82ba26d32 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/members-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/members-1920.png b/docs/desktop-regression/screenshots/desktop-before/members-1920.png new file mode 100644 index 000000000..88d9735d1 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/members-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/my-projects-1440.png b/docs/desktop-regression/screenshots/desktop-before/my-projects-1440.png new file mode 100644 index 000000000..b68148c3c Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/my-projects-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/my-projects-1920.png b/docs/desktop-regression/screenshots/desktop-before/my-projects-1920.png new file mode 100644 index 000000000..f35605787 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/my-projects-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/profile-1440.png b/docs/desktop-regression/screenshots/desktop-before/profile-1440.png new file mode 100644 index 000000000..bdf7b8893 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/profile-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/profile-1920.png b/docs/desktop-regression/screenshots/desktop-before/profile-1920.png new file mode 100644 index 000000000..694c06e11 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/profile-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/profile-edit-1440.png b/docs/desktop-regression/screenshots/desktop-before/profile-edit-1440.png new file mode 100644 index 000000000..c476a08d3 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/profile-edit-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/profile-edit-1920.png b/docs/desktop-regression/screenshots/desktop-before/profile-edit-1920.png new file mode 100644 index 000000000..c5375fb79 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/profile-edit-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/program-1440.png b/docs/desktop-regression/screenshots/desktop-before/program-1440.png new file mode 100644 index 000000000..d75134d8d Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/program-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/program-1920.png b/docs/desktop-regression/screenshots/desktop-before/program-1920.png new file mode 100644 index 000000000..a6533d244 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/program-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/programs-1440.png b/docs/desktop-regression/screenshots/desktop-before/programs-1440.png new file mode 100644 index 000000000..bd1e531bd Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/programs-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/programs-1920.png b/docs/desktop-regression/screenshots/desktop-before/programs-1920.png new file mode 100644 index 000000000..2ac2fca15 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/programs-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/project-1440.png b/docs/desktop-regression/screenshots/desktop-before/project-1440.png new file mode 100644 index 000000000..ca9c33f86 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/project-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/project-1920.png b/docs/desktop-regression/screenshots/desktop-before/project-1920.png new file mode 100644 index 000000000..57b237a69 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/project-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/project-edit-1440.png b/docs/desktop-regression/screenshots/desktop-before/project-edit-1440.png new file mode 100644 index 000000000..bd450be9c Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/project-edit-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/project-edit-1920.png b/docs/desktop-regression/screenshots/desktop-before/project-edit-1920.png new file mode 100644 index 000000000..1e66e1a61 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/project-edit-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/projects-1440.png b/docs/desktop-regression/screenshots/desktop-before/projects-1440.png new file mode 100644 index 000000000..80253540a Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/projects-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/projects-1920.png b/docs/desktop-regression/screenshots/desktop-before/projects-1920.png new file mode 100644 index 000000000..ed8ded08e Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/projects-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/vacancies-1440.png b/docs/desktop-regression/screenshots/desktop-before/vacancies-1440.png new file mode 100644 index 000000000..cffaf991b Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/vacancies-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/vacancies-1920.png b/docs/desktop-regression/screenshots/desktop-before/vacancies-1920.png new file mode 100644 index 000000000..da5a70205 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/vacancies-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/vacancy-1440.png b/docs/desktop-regression/screenshots/desktop-before/vacancy-1440.png new file mode 100644 index 000000000..bb61fa169 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/vacancy-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-before/vacancy-1920.png b/docs/desktop-regression/screenshots/desktop-before/vacancy-1920.png new file mode 100644 index 000000000..7b456f551 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-before/vacancy-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/course-1440.png b/docs/desktop-regression/screenshots/desktop-repeat/course-1440.png new file mode 100644 index 000000000..28fc758f0 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/course-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/course-1920.png b/docs/desktop-regression/screenshots/desktop-repeat/course-1920.png new file mode 100644 index 000000000..a9a068cdb Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/course-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/courses-1440.png b/docs/desktop-regression/screenshots/desktop-repeat/courses-1440.png new file mode 100644 index 000000000..cbe2f3efa Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/courses-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/courses-1920.png b/docs/desktop-regression/screenshots/desktop-repeat/courses-1920.png new file mode 100644 index 000000000..97aff998b Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/courses-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/empty-courses-1440.png b/docs/desktop-regression/screenshots/desktop-repeat/empty-courses-1440.png new file mode 100644 index 000000000..a64d1a410 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/empty-courses-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/empty-courses-1920.png b/docs/desktop-regression/screenshots/desktop-repeat/empty-courses-1920.png new file mode 100644 index 000000000..f2afde1ca Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/empty-courses-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/empty-feed-1440.png b/docs/desktop-regression/screenshots/desktop-repeat/empty-feed-1440.png new file mode 100644 index 000000000..390f08614 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/empty-feed-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/empty-feed-1920.png b/docs/desktop-regression/screenshots/desktop-repeat/empty-feed-1920.png new file mode 100644 index 000000000..8021bdd96 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/empty-feed-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/empty-vacancies-1440.png b/docs/desktop-regression/screenshots/desktop-repeat/empty-vacancies-1440.png new file mode 100644 index 000000000..25e0d187d Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/empty-vacancies-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/empty-vacancies-1920.png b/docs/desktop-regression/screenshots/desktop-repeat/empty-vacancies-1920.png new file mode 100644 index 000000000..f0d772dbc Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/empty-vacancies-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/feed-1440.png b/docs/desktop-regression/screenshots/desktop-repeat/feed-1440.png new file mode 100644 index 000000000..5c1f6b5ba Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/feed-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/feed-1920.png b/docs/desktop-regression/screenshots/desktop-repeat/feed-1920.png new file mode 100644 index 000000000..dbbc494e2 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/feed-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/loading-action-1440.png b/docs/desktop-regression/screenshots/desktop-repeat/loading-action-1440.png new file mode 100644 index 000000000..f9a423c68 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/loading-action-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/loading-action-1920.png b/docs/desktop-regression/screenshots/desktop-repeat/loading-action-1920.png new file mode 100644 index 000000000..ab14093b0 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/loading-action-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/members-1440.png b/docs/desktop-regression/screenshots/desktop-repeat/members-1440.png new file mode 100644 index 000000000..82ba26d32 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/members-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/members-1920.png b/docs/desktop-regression/screenshots/desktop-repeat/members-1920.png new file mode 100644 index 000000000..88d9735d1 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/members-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/my-projects-1440.png b/docs/desktop-regression/screenshots/desktop-repeat/my-projects-1440.png new file mode 100644 index 000000000..b68148c3c Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/my-projects-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/my-projects-1920.png b/docs/desktop-regression/screenshots/desktop-repeat/my-projects-1920.png new file mode 100644 index 000000000..f35605787 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/my-projects-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/profile-1440.png b/docs/desktop-regression/screenshots/desktop-repeat/profile-1440.png new file mode 100644 index 000000000..bdf7b8893 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/profile-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/profile-1920.png b/docs/desktop-regression/screenshots/desktop-repeat/profile-1920.png new file mode 100644 index 000000000..694c06e11 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/profile-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/profile-edit-1440.png b/docs/desktop-regression/screenshots/desktop-repeat/profile-edit-1440.png new file mode 100644 index 000000000..c476a08d3 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/profile-edit-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/profile-edit-1920.png b/docs/desktop-regression/screenshots/desktop-repeat/profile-edit-1920.png new file mode 100644 index 000000000..c5375fb79 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/profile-edit-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/program-1440.png b/docs/desktop-regression/screenshots/desktop-repeat/program-1440.png new file mode 100644 index 000000000..d75134d8d Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/program-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/program-1920.png b/docs/desktop-regression/screenshots/desktop-repeat/program-1920.png new file mode 100644 index 000000000..a6533d244 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/program-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/programs-1440.png b/docs/desktop-regression/screenshots/desktop-repeat/programs-1440.png new file mode 100644 index 000000000..bd1e531bd Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/programs-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/programs-1920.png b/docs/desktop-regression/screenshots/desktop-repeat/programs-1920.png new file mode 100644 index 000000000..2ac2fca15 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/programs-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/project-1440.png b/docs/desktop-regression/screenshots/desktop-repeat/project-1440.png new file mode 100644 index 000000000..ca9c33f86 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/project-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/project-1920.png b/docs/desktop-regression/screenshots/desktop-repeat/project-1920.png new file mode 100644 index 000000000..57b237a69 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/project-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/project-edit-1440.png b/docs/desktop-regression/screenshots/desktop-repeat/project-edit-1440.png new file mode 100644 index 000000000..bd450be9c Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/project-edit-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/project-edit-1920.png b/docs/desktop-regression/screenshots/desktop-repeat/project-edit-1920.png new file mode 100644 index 000000000..1e66e1a61 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/project-edit-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/projects-1440.png b/docs/desktop-regression/screenshots/desktop-repeat/projects-1440.png new file mode 100644 index 000000000..80253540a Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/projects-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/projects-1920.png b/docs/desktop-regression/screenshots/desktop-repeat/projects-1920.png new file mode 100644 index 000000000..ed8ded08e Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/projects-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/vacancies-1440.png b/docs/desktop-regression/screenshots/desktop-repeat/vacancies-1440.png new file mode 100644 index 000000000..cffaf991b Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/vacancies-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/vacancies-1920.png b/docs/desktop-regression/screenshots/desktop-repeat/vacancies-1920.png new file mode 100644 index 000000000..da5a70205 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/vacancies-1920.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/vacancy-1440.png b/docs/desktop-regression/screenshots/desktop-repeat/vacancy-1440.png new file mode 100644 index 000000000..bb61fa169 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/vacancy-1440.png differ diff --git a/docs/desktop-regression/screenshots/desktop-repeat/vacancy-1920.png b/docs/desktop-regression/screenshots/desktop-repeat/vacancy-1920.png new file mode 100644 index 000000000..7b456f551 Binary files /dev/null and b/docs/desktop-regression/screenshots/desktop-repeat/vacancy-1920.png differ diff --git a/docs/desktop-regression/screenshots/interactions/members-320.png b/docs/desktop-regression/screenshots/interactions/members-320.png new file mode 100644 index 000000000..a2d5c15a9 Binary files /dev/null and b/docs/desktop-regression/screenshots/interactions/members-320.png differ diff --git a/docs/desktop-regression/screenshots/interactions/members-390.png b/docs/desktop-regression/screenshots/interactions/members-390.png new file mode 100644 index 000000000..006cc3b44 Binary files /dev/null and b/docs/desktop-regression/screenshots/interactions/members-390.png differ diff --git a/docs/desktop-regression/screenshots/interactions/members-768.png b/docs/desktop-regression/screenshots/interactions/members-768.png new file mode 100644 index 000000000..3f2af2700 Binary files /dev/null and b/docs/desktop-regression/screenshots/interactions/members-768.png differ diff --git a/docs/desktop-regression/screenshots/interactions/navigation-feed-skills-320.png b/docs/desktop-regression/screenshots/interactions/navigation-feed-skills-320.png new file mode 100644 index 000000000..bb3fd309b Binary files /dev/null and b/docs/desktop-regression/screenshots/interactions/navigation-feed-skills-320.png differ diff --git a/docs/desktop-regression/screenshots/interactions/navigation-feed-skills-390.png b/docs/desktop-regression/screenshots/interactions/navigation-feed-skills-390.png new file mode 100644 index 000000000..e9df351e7 Binary files /dev/null and b/docs/desktop-regression/screenshots/interactions/navigation-feed-skills-390.png differ diff --git a/docs/desktop-regression/screenshots/interactions/navigation-feed-skills-768.png b/docs/desktop-regression/screenshots/interactions/navigation-feed-skills-768.png new file mode 100644 index 000000000..27b430248 Binary files /dev/null and b/docs/desktop-regression/screenshots/interactions/navigation-feed-skills-768.png differ diff --git a/docs/desktop-regression/screenshots/interactions/profile-actions-320.png b/docs/desktop-regression/screenshots/interactions/profile-actions-320.png new file mode 100644 index 000000000..6d986bb01 Binary files /dev/null and b/docs/desktop-regression/screenshots/interactions/profile-actions-320.png differ diff --git a/docs/desktop-regression/screenshots/interactions/profile-actions-390.png b/docs/desktop-regression/screenshots/interactions/profile-actions-390.png new file mode 100644 index 000000000..3dc0eef00 Binary files /dev/null and b/docs/desktop-regression/screenshots/interactions/profile-actions-390.png differ diff --git a/docs/desktop-regression/screenshots/interactions/profile-actions-768.png b/docs/desktop-regression/screenshots/interactions/profile-actions-768.png new file mode 100644 index 000000000..2792b9133 Binary files /dev/null and b/docs/desktop-regression/screenshots/interactions/profile-actions-768.png differ diff --git a/docs/desktop-regression/screenshots/interactions/program-actions-320.png b/docs/desktop-regression/screenshots/interactions/program-actions-320.png new file mode 100644 index 000000000..d227b6fc7 Binary files /dev/null and b/docs/desktop-regression/screenshots/interactions/program-actions-320.png differ diff --git a/docs/desktop-regression/screenshots/interactions/program-actions-390.png b/docs/desktop-regression/screenshots/interactions/program-actions-390.png new file mode 100644 index 000000000..ca42ebed2 Binary files /dev/null and b/docs/desktop-regression/screenshots/interactions/program-actions-390.png differ diff --git a/docs/desktop-regression/screenshots/interactions/program-actions-768.png b/docs/desktop-regression/screenshots/interactions/program-actions-768.png new file mode 100644 index 000000000..6eb899bf8 Binary files /dev/null and b/docs/desktop-regression/screenshots/interactions/program-actions-768.png differ diff --git a/docs/desktop-regression/screenshots/interactions/project-actions-320.png b/docs/desktop-regression/screenshots/interactions/project-actions-320.png new file mode 100644 index 000000000..270a2d0b3 Binary files /dev/null and b/docs/desktop-regression/screenshots/interactions/project-actions-320.png differ diff --git a/docs/desktop-regression/screenshots/interactions/project-actions-390.png b/docs/desktop-regression/screenshots/interactions/project-actions-390.png new file mode 100644 index 000000000..28c978850 Binary files /dev/null and b/docs/desktop-regression/screenshots/interactions/project-actions-390.png differ diff --git a/docs/desktop-regression/screenshots/interactions/project-actions-768.png b/docs/desktop-regression/screenshots/interactions/project-actions-768.png new file mode 100644 index 000000000..4b4882ef2 Binary files /dev/null and b/docs/desktop-regression/screenshots/interactions/project-actions-768.png differ diff --git a/docs/desktop-regression/screenshots/interactions/projects-activity-320.png b/docs/desktop-regression/screenshots/interactions/projects-activity-320.png new file mode 100644 index 000000000..2bae40960 Binary files /dev/null and b/docs/desktop-regression/screenshots/interactions/projects-activity-320.png differ diff --git a/docs/desktop-regression/screenshots/interactions/projects-activity-390.png b/docs/desktop-regression/screenshots/interactions/projects-activity-390.png new file mode 100644 index 000000000..e45c85ef0 Binary files /dev/null and b/docs/desktop-regression/screenshots/interactions/projects-activity-390.png differ diff --git a/docs/desktop-regression/screenshots/interactions/projects-activity-768.png b/docs/desktop-regression/screenshots/interactions/projects-activity-768.png new file mode 100644 index 000000000..52815ac85 Binary files /dev/null and b/docs/desktop-regression/screenshots/interactions/projects-activity-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/course-320.png b/docs/desktop-regression/screenshots/mobile-after/course-320.png new file mode 100644 index 000000000..a142af53d Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/course-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/course-390.png b/docs/desktop-regression/screenshots/mobile-after/course-390.png new file mode 100644 index 000000000..febe2a0d9 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/course-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/course-768.png b/docs/desktop-regression/screenshots/mobile-after/course-768.png new file mode 100644 index 000000000..a0d36aba7 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/course-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/courses-320.png b/docs/desktop-regression/screenshots/mobile-after/courses-320.png new file mode 100644 index 000000000..c03bda60e Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/courses-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/courses-390.png b/docs/desktop-regression/screenshots/mobile-after/courses-390.png new file mode 100644 index 000000000..9313fe831 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/courses-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/courses-768.png b/docs/desktop-regression/screenshots/mobile-after/courses-768.png new file mode 100644 index 000000000..afd420a3d Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/courses-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/feed-320.png b/docs/desktop-regression/screenshots/mobile-after/feed-320.png new file mode 100644 index 000000000..c408ae762 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/feed-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/feed-390.png b/docs/desktop-regression/screenshots/mobile-after/feed-390.png new file mode 100644 index 000000000..bc1e6810b Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/feed-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/feed-768.png b/docs/desktop-regression/screenshots/mobile-after/feed-768.png new file mode 100644 index 000000000..ca58289fd Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/feed-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/members-320.png b/docs/desktop-regression/screenshots/mobile-after/members-320.png new file mode 100644 index 000000000..a2d5c15a9 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/members-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/members-390.png b/docs/desktop-regression/screenshots/mobile-after/members-390.png new file mode 100644 index 000000000..006cc3b44 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/members-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/members-768.png b/docs/desktop-regression/screenshots/mobile-after/members-768.png new file mode 100644 index 000000000..3f2af2700 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/members-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/my-projects-320.png b/docs/desktop-regression/screenshots/mobile-after/my-projects-320.png new file mode 100644 index 000000000..0eb539b2f Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/my-projects-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/my-projects-390.png b/docs/desktop-regression/screenshots/mobile-after/my-projects-390.png new file mode 100644 index 000000000..fdf04c57e Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/my-projects-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/my-projects-768.png b/docs/desktop-regression/screenshots/mobile-after/my-projects-768.png new file mode 100644 index 000000000..e8b7c1c01 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/my-projects-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/profile-320.png b/docs/desktop-regression/screenshots/mobile-after/profile-320.png new file mode 100644 index 000000000..6d986bb01 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/profile-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/profile-390.png b/docs/desktop-regression/screenshots/mobile-after/profile-390.png new file mode 100644 index 000000000..3dc0eef00 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/profile-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/profile-768.png b/docs/desktop-regression/screenshots/mobile-after/profile-768.png new file mode 100644 index 000000000..2792b9133 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/profile-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/profile-edit-320.png b/docs/desktop-regression/screenshots/mobile-after/profile-edit-320.png new file mode 100644 index 000000000..30a3add05 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/profile-edit-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/profile-edit-390.png b/docs/desktop-regression/screenshots/mobile-after/profile-edit-390.png new file mode 100644 index 000000000..eb3c0813f Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/profile-edit-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/profile-edit-768.png b/docs/desktop-regression/screenshots/mobile-after/profile-edit-768.png new file mode 100644 index 000000000..ae37f77fb Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/profile-edit-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/program-320.png b/docs/desktop-regression/screenshots/mobile-after/program-320.png new file mode 100644 index 000000000..d227b6fc7 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/program-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/program-390.png b/docs/desktop-regression/screenshots/mobile-after/program-390.png new file mode 100644 index 000000000..ca42ebed2 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/program-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/program-768.png b/docs/desktop-regression/screenshots/mobile-after/program-768.png new file mode 100644 index 000000000..6eb899bf8 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/program-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/programs-320.png b/docs/desktop-regression/screenshots/mobile-after/programs-320.png new file mode 100644 index 000000000..e64443230 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/programs-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/programs-390.png b/docs/desktop-regression/screenshots/mobile-after/programs-390.png new file mode 100644 index 000000000..a5e1daef3 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/programs-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/programs-768.png b/docs/desktop-regression/screenshots/mobile-after/programs-768.png new file mode 100644 index 000000000..d5d7f64fe Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/programs-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/project-320.png b/docs/desktop-regression/screenshots/mobile-after/project-320.png new file mode 100644 index 000000000..270a2d0b3 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/project-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/project-390.png b/docs/desktop-regression/screenshots/mobile-after/project-390.png new file mode 100644 index 000000000..28c978850 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/project-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/project-768.png b/docs/desktop-regression/screenshots/mobile-after/project-768.png new file mode 100644 index 000000000..4b4882ef2 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/project-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/project-edit-320.png b/docs/desktop-regression/screenshots/mobile-after/project-edit-320.png new file mode 100644 index 000000000..0f92f60e7 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/project-edit-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/project-edit-390.png b/docs/desktop-regression/screenshots/mobile-after/project-edit-390.png new file mode 100644 index 000000000..6a9a84a90 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/project-edit-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/project-edit-768.png b/docs/desktop-regression/screenshots/mobile-after/project-edit-768.png new file mode 100644 index 000000000..c0cb8e33e Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/project-edit-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/projects-320.png b/docs/desktop-regression/screenshots/mobile-after/projects-320.png new file mode 100644 index 000000000..2bae40960 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/projects-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/projects-390.png b/docs/desktop-regression/screenshots/mobile-after/projects-390.png new file mode 100644 index 000000000..e45c85ef0 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/projects-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/projects-768.png b/docs/desktop-regression/screenshots/mobile-after/projects-768.png new file mode 100644 index 000000000..52815ac85 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/projects-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/vacancies-320.png b/docs/desktop-regression/screenshots/mobile-after/vacancies-320.png new file mode 100644 index 000000000..fc5f46e06 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/vacancies-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/vacancies-390.png b/docs/desktop-regression/screenshots/mobile-after/vacancies-390.png new file mode 100644 index 000000000..51d9cbf09 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/vacancies-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/vacancies-768.png b/docs/desktop-regression/screenshots/mobile-after/vacancies-768.png new file mode 100644 index 000000000..62a2e140d Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/vacancies-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/vacancy-320.png b/docs/desktop-regression/screenshots/mobile-after/vacancy-320.png new file mode 100644 index 000000000..4a550d06b Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/vacancy-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/vacancy-390.png b/docs/desktop-regression/screenshots/mobile-after/vacancy-390.png new file mode 100644 index 000000000..d3ef7a9fb Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/vacancy-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-after/vacancy-768.png b/docs/desktop-regression/screenshots/mobile-after/vacancy-768.png new file mode 100644 index 000000000..6945268a1 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-after/vacancy-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/course-320.png b/docs/desktop-regression/screenshots/mobile-before/course-320.png new file mode 100644 index 000000000..a142af53d Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/course-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/course-390.png b/docs/desktop-regression/screenshots/mobile-before/course-390.png new file mode 100644 index 000000000..febe2a0d9 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/course-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/course-768.png b/docs/desktop-regression/screenshots/mobile-before/course-768.png new file mode 100644 index 000000000..a0d36aba7 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/course-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/courses-320.png b/docs/desktop-regression/screenshots/mobile-before/courses-320.png new file mode 100644 index 000000000..c03bda60e Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/courses-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/courses-390.png b/docs/desktop-regression/screenshots/mobile-before/courses-390.png new file mode 100644 index 000000000..9313fe831 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/courses-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/courses-768.png b/docs/desktop-regression/screenshots/mobile-before/courses-768.png new file mode 100644 index 000000000..afd420a3d Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/courses-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/feed-320.png b/docs/desktop-regression/screenshots/mobile-before/feed-320.png new file mode 100644 index 000000000..c408ae762 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/feed-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/feed-390.png b/docs/desktop-regression/screenshots/mobile-before/feed-390.png new file mode 100644 index 000000000..bc1e6810b Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/feed-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/feed-768.png b/docs/desktop-regression/screenshots/mobile-before/feed-768.png new file mode 100644 index 000000000..ca58289fd Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/feed-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/members-320.png b/docs/desktop-regression/screenshots/mobile-before/members-320.png new file mode 100644 index 000000000..a2d5c15a9 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/members-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/members-390.png b/docs/desktop-regression/screenshots/mobile-before/members-390.png new file mode 100644 index 000000000..006cc3b44 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/members-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/members-768.png b/docs/desktop-regression/screenshots/mobile-before/members-768.png new file mode 100644 index 000000000..3f2af2700 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/members-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/my-projects-320.png b/docs/desktop-regression/screenshots/mobile-before/my-projects-320.png new file mode 100644 index 000000000..0eb539b2f Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/my-projects-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/my-projects-390.png b/docs/desktop-regression/screenshots/mobile-before/my-projects-390.png new file mode 100644 index 000000000..fdf04c57e Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/my-projects-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/my-projects-768.png b/docs/desktop-regression/screenshots/mobile-before/my-projects-768.png new file mode 100644 index 000000000..e8b7c1c01 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/my-projects-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/profile-320.png b/docs/desktop-regression/screenshots/mobile-before/profile-320.png new file mode 100644 index 000000000..6d986bb01 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/profile-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/profile-390.png b/docs/desktop-regression/screenshots/mobile-before/profile-390.png new file mode 100644 index 000000000..3dc0eef00 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/profile-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/profile-768.png b/docs/desktop-regression/screenshots/mobile-before/profile-768.png new file mode 100644 index 000000000..2792b9133 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/profile-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/profile-edit-320.png b/docs/desktop-regression/screenshots/mobile-before/profile-edit-320.png new file mode 100644 index 000000000..30a3add05 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/profile-edit-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/profile-edit-390.png b/docs/desktop-regression/screenshots/mobile-before/profile-edit-390.png new file mode 100644 index 000000000..eb3c0813f Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/profile-edit-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/profile-edit-768.png b/docs/desktop-regression/screenshots/mobile-before/profile-edit-768.png new file mode 100644 index 000000000..ae37f77fb Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/profile-edit-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/program-320.png b/docs/desktop-regression/screenshots/mobile-before/program-320.png new file mode 100644 index 000000000..d227b6fc7 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/program-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/program-390.png b/docs/desktop-regression/screenshots/mobile-before/program-390.png new file mode 100644 index 000000000..ca42ebed2 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/program-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/program-768.png b/docs/desktop-regression/screenshots/mobile-before/program-768.png new file mode 100644 index 000000000..6eb899bf8 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/program-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/programs-320.png b/docs/desktop-regression/screenshots/mobile-before/programs-320.png new file mode 100644 index 000000000..e64443230 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/programs-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/programs-390.png b/docs/desktop-regression/screenshots/mobile-before/programs-390.png new file mode 100644 index 000000000..a5e1daef3 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/programs-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/programs-768.png b/docs/desktop-regression/screenshots/mobile-before/programs-768.png new file mode 100644 index 000000000..d5d7f64fe Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/programs-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/project-320.png b/docs/desktop-regression/screenshots/mobile-before/project-320.png new file mode 100644 index 000000000..270a2d0b3 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/project-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/project-390.png b/docs/desktop-regression/screenshots/mobile-before/project-390.png new file mode 100644 index 000000000..28c978850 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/project-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/project-768.png b/docs/desktop-regression/screenshots/mobile-before/project-768.png new file mode 100644 index 000000000..4b4882ef2 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/project-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/project-edit-320.png b/docs/desktop-regression/screenshots/mobile-before/project-edit-320.png new file mode 100644 index 000000000..0f92f60e7 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/project-edit-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/project-edit-390.png b/docs/desktop-regression/screenshots/mobile-before/project-edit-390.png new file mode 100644 index 000000000..6a9a84a90 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/project-edit-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/project-edit-768.png b/docs/desktop-regression/screenshots/mobile-before/project-edit-768.png new file mode 100644 index 000000000..c0cb8e33e Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/project-edit-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/projects-320.png b/docs/desktop-regression/screenshots/mobile-before/projects-320.png new file mode 100644 index 000000000..2bae40960 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/projects-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/projects-390.png b/docs/desktop-regression/screenshots/mobile-before/projects-390.png new file mode 100644 index 000000000..e45c85ef0 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/projects-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/projects-768.png b/docs/desktop-regression/screenshots/mobile-before/projects-768.png new file mode 100644 index 000000000..52815ac85 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/projects-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/vacancies-320.png b/docs/desktop-regression/screenshots/mobile-before/vacancies-320.png new file mode 100644 index 000000000..fc5f46e06 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/vacancies-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/vacancies-390.png b/docs/desktop-regression/screenshots/mobile-before/vacancies-390.png new file mode 100644 index 000000000..51d9cbf09 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/vacancies-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/vacancies-768.png b/docs/desktop-regression/screenshots/mobile-before/vacancies-768.png new file mode 100644 index 000000000..62a2e140d Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/vacancies-768.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/vacancy-320.png b/docs/desktop-regression/screenshots/mobile-before/vacancy-320.png new file mode 100644 index 000000000..4a550d06b Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/vacancy-320.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/vacancy-390.png b/docs/desktop-regression/screenshots/mobile-before/vacancy-390.png new file mode 100644 index 000000000..d3ef7a9fb Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/vacancy-390.png differ diff --git a/docs/desktop-regression/screenshots/mobile-before/vacancy-768.png b/docs/desktop-regression/screenshots/mobile-before/vacancy-768.png new file mode 100644 index 000000000..6945268a1 Binary files /dev/null and b/docs/desktop-regression/screenshots/mobile-before/vacancy-768.png differ diff --git a/docs/desktop-regression/screenshots/states/courses-320.png b/docs/desktop-regression/screenshots/states/courses-320.png new file mode 100644 index 000000000..c03bda60e Binary files /dev/null and b/docs/desktop-regression/screenshots/states/courses-320.png differ diff --git a/docs/desktop-regression/screenshots/states/courses-390.png b/docs/desktop-regression/screenshots/states/courses-390.png new file mode 100644 index 000000000..9313fe831 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/courses-390.png differ diff --git a/docs/desktop-regression/screenshots/states/courses-768.png b/docs/desktop-regression/screenshots/states/courses-768.png new file mode 100644 index 000000000..afd420a3d Binary files /dev/null and b/docs/desktop-regression/screenshots/states/courses-768.png differ diff --git a/docs/desktop-regression/screenshots/states/disabled-action-320.png b/docs/desktop-regression/screenshots/states/disabled-action-320.png new file mode 100644 index 000000000..f92508267 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/disabled-action-320.png differ diff --git a/docs/desktop-regression/screenshots/states/disabled-action-390.png b/docs/desktop-regression/screenshots/states/disabled-action-390.png new file mode 100644 index 000000000..4e9054b07 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/disabled-action-390.png differ diff --git a/docs/desktop-regression/screenshots/states/disabled-action-768.png b/docs/desktop-regression/screenshots/states/disabled-action-768.png new file mode 100644 index 000000000..a82eea418 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/disabled-action-768.png differ diff --git a/docs/desktop-regression/screenshots/states/disabled-filter-320.png b/docs/desktop-regression/screenshots/states/disabled-filter-320.png new file mode 100644 index 000000000..9c2c2d7d1 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/disabled-filter-320.png differ diff --git a/docs/desktop-regression/screenshots/states/disabled-filter-390.png b/docs/desktop-regression/screenshots/states/disabled-filter-390.png new file mode 100644 index 000000000..184878e47 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/disabled-filter-390.png differ diff --git a/docs/desktop-regression/screenshots/states/disabled-filter-768.png b/docs/desktop-regression/screenshots/states/disabled-filter-768.png new file mode 100644 index 000000000..567f3eb2e Binary files /dev/null and b/docs/desktop-regression/screenshots/states/disabled-filter-768.png differ diff --git a/docs/desktop-regression/screenshots/states/empty-320.png b/docs/desktop-regression/screenshots/states/empty-320.png new file mode 100644 index 000000000..93d132e62 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/empty-320.png differ diff --git a/docs/desktop-regression/screenshots/states/empty-390.png b/docs/desktop-regression/screenshots/states/empty-390.png new file mode 100644 index 000000000..b593e4018 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/empty-390.png differ diff --git a/docs/desktop-regression/screenshots/states/empty-768.png b/docs/desktop-regression/screenshots/states/empty-768.png new file mode 100644 index 000000000..f0c4cb271 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/empty-768.png differ diff --git a/docs/desktop-regression/screenshots/states/error-320.png b/docs/desktop-regression/screenshots/states/error-320.png new file mode 100644 index 000000000..cdba1f904 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/error-320.png differ diff --git a/docs/desktop-regression/screenshots/states/error-390.png b/docs/desktop-regression/screenshots/states/error-390.png new file mode 100644 index 000000000..052424d60 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/error-390.png differ diff --git a/docs/desktop-regression/screenshots/states/error-768.png b/docs/desktop-regression/screenshots/states/error-768.png new file mode 100644 index 000000000..56b5e3444 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/error-768.png differ diff --git a/docs/desktop-regression/screenshots/states/loading-action-320.png b/docs/desktop-regression/screenshots/states/loading-action-320.png new file mode 100644 index 000000000..9b57305f1 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/loading-action-320.png differ diff --git a/docs/desktop-regression/screenshots/states/loading-action-390.png b/docs/desktop-regression/screenshots/states/loading-action-390.png new file mode 100644 index 000000000..ec4a061d9 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/loading-action-390.png differ diff --git a/docs/desktop-regression/screenshots/states/loading-action-768.png b/docs/desktop-regression/screenshots/states/loading-action-768.png new file mode 100644 index 000000000..6e10d31f9 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/loading-action-768.png differ diff --git a/docs/desktop-regression/screenshots/states/loading-page-320.png b/docs/desktop-regression/screenshots/states/loading-page-320.png new file mode 100644 index 000000000..c386bf550 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/loading-page-320.png differ diff --git a/docs/desktop-regression/screenshots/states/loading-page-390.png b/docs/desktop-regression/screenshots/states/loading-page-390.png new file mode 100644 index 000000000..a77ddf8e8 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/loading-page-390.png differ diff --git a/docs/desktop-regression/screenshots/states/loading-page-768.png b/docs/desktop-regression/screenshots/states/loading-page-768.png new file mode 100644 index 000000000..ae67594c0 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/loading-page-768.png differ diff --git a/docs/desktop-regression/screenshots/states/onboarding-0-320.png b/docs/desktop-regression/screenshots/states/onboarding-0-320.png new file mode 100644 index 000000000..36dd2eeaa Binary files /dev/null and b/docs/desktop-regression/screenshots/states/onboarding-0-320.png differ diff --git a/docs/desktop-regression/screenshots/states/onboarding-0-390.png b/docs/desktop-regression/screenshots/states/onboarding-0-390.png new file mode 100644 index 000000000..3b81d2e46 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/onboarding-0-390.png differ diff --git a/docs/desktop-regression/screenshots/states/onboarding-0-768.png b/docs/desktop-regression/screenshots/states/onboarding-0-768.png new file mode 100644 index 000000000..4418d4954 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/onboarding-0-768.png differ diff --git a/docs/desktop-regression/screenshots/states/onboarding-1-320.png b/docs/desktop-regression/screenshots/states/onboarding-1-320.png new file mode 100644 index 000000000..f0e2ed53a Binary files /dev/null and b/docs/desktop-regression/screenshots/states/onboarding-1-320.png differ diff --git a/docs/desktop-regression/screenshots/states/onboarding-1-390.png b/docs/desktop-regression/screenshots/states/onboarding-1-390.png new file mode 100644 index 000000000..cc03fb3c6 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/onboarding-1-390.png differ diff --git a/docs/desktop-regression/screenshots/states/onboarding-1-768.png b/docs/desktop-regression/screenshots/states/onboarding-1-768.png new file mode 100644 index 000000000..ef3fa50cc Binary files /dev/null and b/docs/desktop-regression/screenshots/states/onboarding-1-768.png differ diff --git a/docs/desktop-regression/screenshots/states/profile-320.png b/docs/desktop-regression/screenshots/states/profile-320.png new file mode 100644 index 000000000..3007d338d Binary files /dev/null and b/docs/desktop-regression/screenshots/states/profile-320.png differ diff --git a/docs/desktop-regression/screenshots/states/profile-390.png b/docs/desktop-regression/screenshots/states/profile-390.png new file mode 100644 index 000000000..23a1958f6 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/profile-390.png differ diff --git a/docs/desktop-regression/screenshots/states/profile-768.png b/docs/desktop-regression/screenshots/states/profile-768.png new file mode 100644 index 000000000..696de1882 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/profile-768.png differ diff --git a/docs/desktop-regression/screenshots/states/profile-edit-320.png b/docs/desktop-regression/screenshots/states/profile-edit-320.png new file mode 100644 index 000000000..3c7c46269 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/profile-edit-320.png differ diff --git a/docs/desktop-regression/screenshots/states/profile-edit-390.png b/docs/desktop-regression/screenshots/states/profile-edit-390.png new file mode 100644 index 000000000..0dde9893b Binary files /dev/null and b/docs/desktop-regression/screenshots/states/profile-edit-390.png differ diff --git a/docs/desktop-regression/screenshots/states/profile-edit-768.png b/docs/desktop-regression/screenshots/states/profile-edit-768.png new file mode 100644 index 000000000..a3fa20e45 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/profile-edit-768.png differ diff --git a/docs/desktop-regression/screenshots/states/programs-320.png b/docs/desktop-regression/screenshots/states/programs-320.png new file mode 100644 index 000000000..d7f61925a Binary files /dev/null and b/docs/desktop-regression/screenshots/states/programs-320.png differ diff --git a/docs/desktop-regression/screenshots/states/programs-390.png b/docs/desktop-regression/screenshots/states/programs-390.png new file mode 100644 index 000000000..d8f937994 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/programs-390.png differ diff --git a/docs/desktop-regression/screenshots/states/programs-768.png b/docs/desktop-regression/screenshots/states/programs-768.png new file mode 100644 index 000000000..64809084b Binary files /dev/null and b/docs/desktop-regression/screenshots/states/programs-768.png differ diff --git a/docs/desktop-regression/screenshots/states/projects-320.png b/docs/desktop-regression/screenshots/states/projects-320.png new file mode 100644 index 000000000..3dcc89602 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/projects-320.png differ diff --git a/docs/desktop-regression/screenshots/states/projects-390.png b/docs/desktop-regression/screenshots/states/projects-390.png new file mode 100644 index 000000000..7dd67c6df Binary files /dev/null and b/docs/desktop-regression/screenshots/states/projects-390.png differ diff --git a/docs/desktop-regression/screenshots/states/projects-768.png b/docs/desktop-regression/screenshots/states/projects-768.png new file mode 100644 index 000000000..bcc45f8d2 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/projects-768.png differ diff --git a/docs/desktop-regression/screenshots/states/vacancies-320.png b/docs/desktop-regression/screenshots/states/vacancies-320.png new file mode 100644 index 000000000..3f179ca86 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/vacancies-320.png differ diff --git a/docs/desktop-regression/screenshots/states/vacancies-390.png b/docs/desktop-regression/screenshots/states/vacancies-390.png new file mode 100644 index 000000000..a5e64f193 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/vacancies-390.png differ diff --git a/docs/desktop-regression/screenshots/states/vacancies-768.png b/docs/desktop-regression/screenshots/states/vacancies-768.png new file mode 100644 index 000000000..5a79d747c Binary files /dev/null and b/docs/desktop-regression/screenshots/states/vacancies-768.png differ diff --git a/docs/desktop-regression/screenshots/states/validation-onboarding-320.png b/docs/desktop-regression/screenshots/states/validation-onboarding-320.png new file mode 100644 index 000000000..9b33f1f33 Binary files /dev/null and b/docs/desktop-regression/screenshots/states/validation-onboarding-320.png differ diff --git a/docs/desktop-regression/screenshots/states/validation-onboarding-390.png b/docs/desktop-regression/screenshots/states/validation-onboarding-390.png new file mode 100644 index 000000000..66bf115ec Binary files /dev/null and b/docs/desktop-regression/screenshots/states/validation-onboarding-390.png differ diff --git a/docs/desktop-regression/screenshots/states/validation-onboarding-768.png b/docs/desktop-regression/screenshots/states/validation-onboarding-768.png new file mode 100644 index 000000000..6a197ba8a Binary files /dev/null and b/docs/desktop-regression/screenshots/states/validation-onboarding-768.png differ diff --git a/docs/desktop-regression/screenshots/states/validation-register-320.png b/docs/desktop-regression/screenshots/states/validation-register-320.png new file mode 100644 index 000000000..9d0beb34b Binary files /dev/null and b/docs/desktop-regression/screenshots/states/validation-register-320.png differ diff --git a/docs/desktop-regression/screenshots/states/validation-register-390.png b/docs/desktop-regression/screenshots/states/validation-register-390.png new file mode 100644 index 000000000..50909334f Binary files /dev/null and b/docs/desktop-regression/screenshots/states/validation-register-390.png differ diff --git a/docs/desktop-regression/screenshots/states/validation-register-768.png b/docs/desktop-regression/screenshots/states/validation-register-768.png new file mode 100644 index 000000000..0d5a78f7c Binary files /dev/null and b/docs/desktop-regression/screenshots/states/validation-register-768.png differ diff --git a/docs/desktop-regression/serve.cjs b/docs/desktop-regression/serve.cjs new file mode 100644 index 000000000..acb32077c --- /dev/null +++ b/docs/desktop-regression/serve.cjs @@ -0,0 +1,37 @@ +/** @format */ + +const http = require("node:http"); +const fs = require("node:fs"); +const path = require("node:path"); +let root = path.resolve(process.argv[2]); +if (fs.existsSync(path.join(root, "browser/index.html"))) root = path.join(root, "browser"); +const port = Number(process.argv[3]); +const types = { + ".html": "text/html", + ".js": "text/javascript", + ".css": "text/css", + ".svg": "image/svg+xml", + ".png": "image/png", + ".jpg": "image/jpeg", + ".woff2": "font/woff2", + ".woff": "font/woff", + ".json": "application/json", + ".md": "text/plain; charset=utf-8", +}; +http + .createServer((request, response) => { + let file = path.resolve( + root, + "." + decodeURIComponent(new URL(request.url, "http://localhost").pathname), + ); + if (!file.startsWith(root + path.sep)) return response.writeHead(403).end(); + if (!fs.existsSync(file) || fs.statSync(file).isDirectory()) + file = path.join(root, "index.html"); + if (!fs.existsSync(file)) return response.writeHead(404).end("Not found"); + response.writeHead(200, { + "Content-Type": types[path.extname(file)] || "application/octet-stream", + "Cache-Control": "no-store", + }); + fs.createReadStream(file).pipe(response); + }) + .listen(port, "127.0.0.1", () => console.log(`Preview ${port}: ${root}`)); diff --git a/docs/desktop-regression/source-files.json b/docs/desktop-regression/source-files.json new file mode 100644 index 000000000..24da40995 --- /dev/null +++ b/docs/desktop-regression/source-files.json @@ -0,0 +1,139 @@ +[ + "projects/social_platform/src/app/ui/pages/auth/auth.component.scss", + "projects/social_platform/src/app/ui/pages/auth/email-verification/email-verification.component.scss", + "projects/social_platform/src/app/ui/pages/auth/login/login.component.scss", + "projects/social_platform/src/app/ui/pages/courses/lesson/shared/exclude-task/exclude-task.component.scss", + "projects/social_platform/src/app/ui/pages/courses/lesson/shared/file-task/file-task.component.scss", + "projects/social_platform/src/app/ui/pages/courses/lesson/shared/radio-select-task/radio-select-task.component.scss", + "projects/social_platform/src/app/ui/pages/courses/lesson/shared/video-task/info-task.component.scss", + "projects/social_platform/src/app/ui/pages/courses/lesson/shared/write-task/write-task.component.scss", + "projects/social_platform/src/app/ui/pages/courses/list/course/course.component.html", + "projects/social_platform/src/app/ui/pages/courses/list/course/course.component.scss", + "projects/social_platform/src/app/ui/pages/courses/list/course/course.component.ts", + "projects/social_platform/src/app/ui/pages/courses/list/list.component.html", + "projects/social_platform/src/app/ui/pages/courses/list/list.component.ts", + "projects/social_platform/src/app/ui/pages/error/error-code/error-code.component.scss", + "projects/social_platform/src/app/ui/pages/feed/feed.component.html", + "projects/social_platform/src/app/ui/pages/feed/feed.component.ts", + "projects/social_platform/src/app/ui/pages/feed/open-vacancy/open-vacancy.component.html", + "projects/social_platform/src/app/ui/pages/feed/open-vacancy/open-vacancy.component.ts", + "projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.scss", + "projects/social_platform/src/app/ui/pages/members/member-filters-dialog/member-filters-dialog.component.scss", + "projects/social_platform/src/app/ui/pages/members/member-statistics-card/member-statistics-card.component.scss", + "projects/social_platform/src/app/ui/pages/members/members-filters/members-filters.component.scss", + "projects/social_platform/src/app/ui/pages/members/members.component.html", + "projects/social_platform/src/app/ui/pages/members/members.component.scss", + "projects/social_platform/src/app/ui/pages/office/nav/nav.component.scss", + "projects/social_platform/src/app/ui/pages/office/office.component.scss", + "projects/social_platform/src/app/ui/pages/office/snackbar/snackbar.component.scss", + "projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-left-side/profile-left-side.component.scss", + "projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-right-side/profile-right-side.component.scss", + "projects/social_platform/src/app/ui/pages/profile/detail/profile-news/profile-news.component.scss", + "projects/social_platform/src/app/ui/pages/profile/edit/components/profile-achievements-step/profile-achievements-step.component.scss", + "projects/social_platform/src/app/ui/pages/profile/edit/components/profile-education-step/profile-education-step.component.scss", + "projects/social_platform/src/app/ui/pages/profile/edit/components/profile-experience-step/profile-experience-step.component.scss", + "projects/social_platform/src/app/ui/pages/profile/edit/components/profile-main-step/profile-main-step.component.scss", + "projects/social_platform/src/app/ui/pages/profile/edit/components/profile-skills-step/profile-skills-step.component.scss", + "projects/social_platform/src/app/ui/pages/profile/edit/edit.component.html", + "projects/social_platform/src/app/ui/pages/profile/edit/edit.component.scss", + "projects/social_platform/src/app/ui/pages/profile/edit/edit.component.ts", + "projects/social_platform/src/app/ui/pages/program/detail/analytics/analytics.component.scss", + "projects/social_platform/src/app/ui/pages/program/detail/analytics/drilldown/analytics-drilldown.component.scss", + "projects/social_platform/src/app/ui/pages/program/detail/list/list.component.scss", + "projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/project-rating/components/boolean-criterion/boolean-criterion.component.scss", + "projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/project-rating/components/range-criterion-input/range-criterion-input.component.scss", + "projects/social_platform/src/app/ui/pages/program/detail/main/role-widget/program-role-widget.component.scss", + "projects/social_platform/src/app/ui/pages/program/main/program-card/program-card.component.html", + "projects/social_platform/src/app/ui/pages/program/main/program-card/program-card.component.scss", + "projects/social_platform/src/app/ui/pages/program/main/program-card/program-card.component.ts", + "projects/social_platform/src/app/ui/pages/projects/bar-new/bar.component.html", + "projects/social_platform/src/app/ui/pages/projects/bar-new/bar.component.scss", + "projects/social_platform/src/app/ui/pages/projects/bar-new/bar.component.ts", + "projects/social_platform/src/app/ui/pages/projects/detail/info/components/projects-left-side/projects-left-side.component.scss", + "projects/social_platform/src/app/ui/pages/projects/detail/news-detail/news-detail.component.scss", + "projects/social_platform/src/app/ui/pages/projects/detail/team/team.component.scss", + "projects/social_platform/src/app/ui/pages/projects/detail/work-section/work-section.component.scss", + "projects/social_platform/src/app/ui/pages/projects/edit/components/project-achievement-step/project-achievement-step.component.scss", + "projects/social_platform/src/app/ui/pages/projects/edit/components/project-additional-step/project-additional-step.component.scss", + "projects/social_platform/src/app/ui/pages/projects/edit/components/project-main-step/project-main-step.component.scss", + "projects/social_platform/src/app/ui/pages/projects/edit/components/project-navigation/project-navigation.component.html", + "projects/social_platform/src/app/ui/pages/projects/edit/components/project-navigation/project-navigation.component.scss", + "projects/social_platform/src/app/ui/pages/projects/edit/components/project-navigation/project-navigation.component.ts", + "projects/social_platform/src/app/ui/pages/projects/edit/components/project-team-step/project-team-step.component.scss", + "projects/social_platform/src/app/ui/pages/projects/edit/components/project-vacancy-step/project-vacancy-step.component.scss", + "projects/social_platform/src/app/ui/pages/projects/edit/edit.component.html", + "projects/social_platform/src/app/ui/pages/projects/edit/edit.component.scss", + "projects/social_platform/src/app/ui/pages/projects/project-activity-card/project-activity-card.component.scss", + "projects/social_platform/src/app/ui/pages/projects/projects-activity-placement.spec.ts", + "projects/social_platform/src/app/ui/pages/projects/projects.component.html", + "projects/social_platform/src/app/ui/pages/projects/projects.component.scss", + "projects/social_platform/src/app/ui/pages/projects/projects.component.ts", + "projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-right-side/vacancies-right-side.component.scss", + "projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancy-responses/vacancy-responses.component.scss", + "projects/social_platform/src/app/ui/pages/vacancies/detail/vacancies-detail.component.scss", + "projects/social_platform/src/app/ui/pages/vacancies/list/list.component.html", + "projects/social_platform/src/app/ui/pages/vacancies/list/list.component.ts", + "projects/social_platform/src/app/ui/pages/vacancies/list/response-card/response-card.component.scss", + "projects/social_platform/src/app/ui/primitives/autocomplete-input/autocomplete-input.component.scss", + "projects/social_platform/src/app/ui/primitives/avatar/avatar.component.html", + "projects/social_platform/src/app/ui/primitives/avatar/avatar.component.scss", + "projects/social_platform/src/app/ui/primitives/avatar/avatar.component.ts", + "projects/social_platform/src/app/ui/primitives/bar/bar.component.html", + "projects/social_platform/src/app/ui/primitives/bar/bar.component.scss", + "projects/social_platform/src/app/ui/primitives/bar/bar.component.ts", + "projects/social_platform/src/app/ui/primitives/checkbox/checkbox.component.scss", + "projects/social_platform/src/app/ui/primitives/dropdown/dropdown.component.scss", + "projects/social_platform/src/app/ui/primitives/file-item/file-item.component.scss", + "projects/social_platform/src/app/ui/primitives/input/input.component.scss", + "projects/social_platform/src/app/ui/primitives/modal/modal.component.scss", + "projects/social_platform/src/app/ui/primitives/search/search.component.scss", + "projects/social_platform/src/app/ui/primitives/select/select.component.scss", + "projects/social_platform/src/app/ui/primitives/switch/switch.component.scss", + "projects/social_platform/src/app/ui/primitives/tag/tag.component.scss", + "projects/social_platform/src/app/ui/primitives/textarea/textarea.component.scss", + "projects/social_platform/src/app/ui/primitives/upload-file/upload-file.component.scss", + "projects/social_platform/src/app/ui/widgets/cookie-consent/cookie-consent.component.scss", + "projects/social_platform/src/app/ui/widgets/detail/detail.component.html", + "projects/social_platform/src/app/ui/widgets/detail/detail.component.scss", + "projects/social_platform/src/app/ui/widgets/feed-filter/feed-filter.component.scss", + "projects/social_platform/src/app/ui/widgets/info-card/info-card.component.scss", + "projects/social_platform/src/app/ui/widgets/news-card/feed-news-modal/feed-news-modal.component.scss", + "projects/social_platform/src/app/ui/widgets/news-card/feed-news-preview/feed-news-preview.component.scss", + "projects/social_platform/src/app/ui/widgets/news-card/news-card.component.scss", + "projects/social_platform/src/app/ui/widgets/news-form/news-form.component.scss", + "projects/social_platform/src/app/ui/widgets/project-invite/project-invite-dialog.component.scss", + "projects/social_platform/src/app/ui/widgets/project-invite/project-invite-role-input.component.scss", + "projects/social_platform/src/app/ui/widgets/project-vacancy-card/project-vacancy-card.component.scss", + "projects/social_platform/src/app/ui/widgets/projects-filter/projects-filter.component.scss", + "projects/social_platform/src/app/ui/widgets/region-select/region-select.component.scss", + "projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.scss", + "projects/social_platform/src/app/ui/widgets/vacancy-created-dialog/vacancy-created-dialog.component.scss", + "projects/social_platform/src/app/ui/widgets/vacancy-filter/vacancy-filter.component.scss", + "projects/social_platform/src/app/ui/widgets/vacancy-skills/vacancy-skills.component.scss", + "projects/social_platform/src/app/ui/widgets/vacancy-status/vacancy-status.component.scss", + "projects/social_platform/src/styles.scss", + "projects/social_platform/src/styles/_course-task.scss", + "projects/social_platform/src/styles/_feed-card.scss", + "projects/social_platform/src/styles/_platform-responsive.scss", + "projects/social_platform/src/styles/_typography.scss", + "projects/social_platform/src/styles/_ui-system.scss", + "projects/social_platform/src/styles/components/_vacancy-ui.scss", + "projects/ui/src/lib/components/layout/page-header/page-header.component.scss", + "projects/ui/src/lib/components/layout/page-header/page-header.component.ts", + "projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.html", + "projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.scss", + "projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.ts", + "projects/ui/src/lib/components/primitives/avatar/avatar.component.scss", + "projects/ui/src/lib/components/primitives/back/back.component.scss", + "projects/ui/src/lib/components/primitives/badge/badge.component.scss", + "projects/ui/src/lib/components/primitives/button/button.component.html", + "projects/ui/src/lib/components/primitives/button/button.component.scss", + "projects/ui/src/lib/components/primitives/button/button.component.ts", + "projects/ui/src/lib/components/primitives/icon/icon.component.html", + "projects/ui/src/lib/components/primitives/icon/icon.component.scss", + "projects/ui/src/lib/components/primitives/icon/icon.component.ts", + "projects/ui/src/lib/components/primitives/loader/loader.component.scss", + "projects/ui/src/lib/components/primitives/tabs/tabs.component.scss", + "projects/ui/src/lib/services/desktop-layout.service.ts", + "projects/ui/src/public-api.ts" +] diff --git a/docs/desktop-regression/states.cjs b/docs/desktop-regression/states.cjs new file mode 100644 index 000000000..a89459400 --- /dev/null +++ b/docs/desktop-regression/states.cjs @@ -0,0 +1,232 @@ +/** @format */ + +const fs = require("node:fs"); +const path = require("node:path"); +const assert = require("node:assert/strict"); +const { launch, assertViewport } = require("../responsive/browser-harness.cjs"); +const fixtures = require("../responsive/fixtures.cjs"); + +const directory = path.join(__dirname, "screenshots", "states"); +fs.mkdirSync(directory, { recursive: true }); +const rows = []; +const widths = [320, 390, 768]; +const sections = [ + ["projects", "/office/projects/all", "app-info-card"], + ["vacancies", "/office/vacancies/all", "app-project-vacancy-card"], + ["programs", "/office/program/all", "app-program-card"], + ["courses", "/office/courses/all", "app-course"], + ["profile", "/office/profile/1", "app-detail"], + ["profile-edit", "/office/profile/edit?editingStep=main", "app-page-header"], + [ + "onboarding-0", + "/office/onboarding/stage-0", + "app-stage-zero .page__form input:not([type=file])", + ], + ["onboarding-1", "/office/onboarding/stage-1", "app-stage-one app-autocomplete-input"], +]; + +async function goto(page, route, settled = true) { + await page.goto("http://127.0.0.1:4360" + route); + if (settled) await page.waitForLoadState("networkidle"); +} + +async function capture(harness, name, width, extra = {}) { + const measurement = await assertViewport(harness.page); + const expectedErrors = extra.injectedHttp500 + ? harness.errors.filter( + message => + /Failed to load resource.*500/.test(message) || + /\[ERROR\] \[HTTP\] GET https:\/\/(?:api|dev)\.procollab\.ru\/programs\/1\/manager-overview\/ 500 /.test( + message, + ), + ) + : []; + assert.deepEqual( + harness.errors.filter(message => !expectedErrors.includes(message)), + [], + ); + const screenshot = `screenshots/states/${name}-${width}.png`; + await harness.page.screenshot({ path: path.join(__dirname, screenshot), fullPage: true }); + rows.push({ name, width, passed: true, ...measurement, screenshot, expectedErrors, ...extra }); + console.log(JSON.stringify({ name, width, passed: true })); +} + +async function state(width, name, action) { + const harness = await launch(width, { isMobile: width < 750, hasTouch: width < 750 }); + harness.page.setDefaultTimeout(8000); + try { + await action(harness); + } finally { + await harness.browser.close(); + } +} + +(async () => { + for (const width of widths) { + const harness = await launch(width, { isMobile: width < 750, hasTouch: width < 750 }); + try { + for (const [name, route, content] of sections) { + harness.errors.length = 0; + await goto(harness.page, route); + await harness.page.locator(content).first().waitFor({ state: "visible" }); + await capture(harness, name, width, { category: "section" }); + } + } finally { + await harness.browser.close(); + } + + await state(width, "loading-page", async h => { + let release; + const pending = new Promise(resolve => { + release = resolve; + }); + await h.context.route("**/programs/1/manager-overview/**", async route => { + await pending; + const url = new URL(route.request().url()); + await route.fulfill({ json: fixtures.response(url.pathname, "GET", url.searchParams) }); + }); + try { + await goto(h.page, "/office/program/1/analytics", false); + await h.page.getByTestId("analytics-loading").waitFor(); + await capture(h, "loading-page", width, { category: "loading" }); + } finally { + release(); + } + await h.page.getByTestId("analytics-loading").waitFor({ state: "hidden" }); + }); + + await state(width, "loading-action", async h => { + await goto(h.page, "/office/courses/1/lesson/1"); + await h.page.locator("app-write-task textarea").fill("Ответ для финальной проверки UI Kit"); + let release; + const pending = new Promise(resolve => { + release = resolve; + }); + let submissions = 0; + await h.context.route("**/courses/tasks/1/answer/", async route => { + submissions++; + await pending; + const url = new URL(route.request().url()); + await route.fulfill({ json: fixtures.response(url.pathname, "POST", url.searchParams) }); + }); + try { + const button = h.page.getByRole("button", { name: "завершить урок", exact: true }); + await button.click(); + await h.page.locator("app-button app-loader").waitFor(); + assert.equal(await button.isDisabled(), true); + assert.equal(await button.getAttribute("aria-busy"), "true"); + await button.evaluate(element => element.click()); + assert.equal(submissions, 1, "Loading must prevent duplicate submission"); + await capture(h, "loading-action", width, { category: "loading", submissions }); + } finally { + release(); + } + await h.page.locator("app-complete").waitFor(); + }); + + await state(width, "empty", async h => { + await h.context.route( + url => /\/vacancies\/$/.test(url.pathname), + route => route.fulfill({ json: { count: 0, results: [], next: null, previous: null } }), + ); + await goto(h.page, "/office/vacancies/all"); + await h.page.locator("app-state").getByText("Вакансии не найдены", { exact: true }).waitFor(); + await capture(h, "empty", width, { category: "empty" }); + }); + + await state(width, "error", async h => { + let failing = true; + let attempts = 0; + await h.context.route("**/programs/1/manager-overview/**", async route => { + attempts++; + if (failing) return route.fulfill({ status: 500, json: { detail: "Injected QA failure" } }); + const url = new URL(route.request().url()); + return route.fulfill({ json: fixtures.response(url.pathname, "GET", url.searchParams) }); + }); + await goto(h.page, "/office/program/1/analytics"); + await h.page.getByTestId("analytics-error").waitFor({ timeout: 60000 }); + assert.equal(await h.page.getByTestId("analytics-error").getAttribute("role"), "alert"); + await capture(h, "error", width, { category: "error", injectedHttp500: true }); + failing = false; + await h.page.getByRole("button", { name: "Повторить", exact: true }).click(); + await h.page.getByTestId("analytics-error").waitFor({ state: "hidden" }); + await h.page.locator(".summary-card").first().waitFor(); + assert.ok(attempts >= 2, "Error retry must reload data"); + await assertViewport(h.page); + rows.at(-1).retryPassed = true; + }); + + await state(width, "disabled-action", async h => { + await goto(h.page, "/office/courses/1/lesson/1"); + const button = h.page.getByRole("button", { name: "завершить урок", exact: true }); + assert.equal(await button.isDisabled(), true); + const before = h.requests.filter(request => request.method !== "GET").length; + await button.evaluate(element => element.click()); + assert.equal(h.requests.filter(request => request.method !== "GET").length, before); + assert.equal( + await button.evaluate(element => { + element.focus(); + return document.activeElement !== element; + }), + true, + ); + await capture(h, "disabled-action", width, { category: "disabled" }); + }); + + await state(width, "disabled-filter", async h => { + await goto(h.page, "/office/feed"); + const button = h.page.getByRole("button", { name: /образование/ }); + assert.equal(await button.isDisabled(), true); + const before = h.page.url(); + await button.evaluate(element => element.click()); + assert.equal(h.page.url(), before); + await capture(h, "disabled-filter", width, { category: "disabled" }); + }); + + await state(width, "validation-register", async h => { + await goto(h.page, "/auth/register"); + if (width >= 1000) { + const register = await h.page.locator(".register").boundingBox(); + assert.ok(register.x >= 199, "Registration must retain the desktop auth gutter"); + } + for (const checkbox of await h.page.locator("app-checkbox .field").all()) + await checkbox.click(); + await h.page.getByRole("button", { name: "зарегистрироваться", exact: true }).click(); + await h.page.locator(".error").first().waitFor(); + assert.equal( + h.requests.some( + request => request.method === "POST" && /\/auth\/users\/$/.test(request.path), + ), + false, + ); + await capture(h, "validation-register", width, { category: "validation" }); + }); + + const avatar = fixtures.user.avatar; + fixtures.user.avatar = null; + try { + await state(width, "validation-onboarding", async h => { + await goto(h.page, "/office/onboarding/stage-0"); + await h.page.getByRole("button", { name: "продолжить", exact: true }).click(); + await h.page.locator(".error").first().waitFor(); + assert.equal(h.page.url().includes("stage-0"), true); + assert.equal( + h.requests.some(request => request.method === "PATCH"), + false, + ); + await capture(h, "validation-onboarding", width, { category: "validation" }); + }); + } finally { + fixtures.user.avatar = avatar; + } + } + assert.equal(rows.length, 48); + fs.writeFileSync( + path.join(__dirname, "states.json"), + JSON.stringify({ widths, rows }, null, 2) + "\n", + ); + console.log(`${rows.length} UI state checks passed`); +})().catch(error => { + console.error(error); + process.exitCode = 1; +}); diff --git a/docs/desktop-regression/states.json b/docs/desktop-regression/states.json new file mode 100644 index 000000000..f994a9249 --- /dev/null +++ b/docs/desktop-regression/states.json @@ -0,0 +1,2330 @@ +{ + "widths": [320, 390, 768], + "rows": [ + { + "name": "projects", + "width": 320, + "passed": true, + "actualPath": "/office/projects/all", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-projects-filter", + "app-select", + "app-dropdown", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-projects-filter", + "app-select" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\nФильтр\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nПроект для проверки адаптива\n\nОткрыть\n\nфильтры\n\nсбросить\nсфера проекта", + "screenshot": "screenshots/states/projects-320.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "vacancies", + "width": 320, + "passed": true, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter" + ], + "text": "Вакансии\nвакансии\n\nПоиск\n\nАктивна\n01.10.2026\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nПроект\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробело", + "screenshot": "screenshots/states/vacancies-320.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "programs", + "width": 320, + "passed": true, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card" + ], + "text": "Программы\nпрограммы\n\nПоиск\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nты уже участвуешь!\n\n01.10.2026 - 01.01.2027\n\nдля всей России", + "screenshot": "screenshots/states/programs-320.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "courses", + "width": 320, + "passed": true, + "actualPath": "/office/courses/all", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge", + "app-soon-card", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge" + ], + "text": "Курсы\nкурсы\n\nПоиск\n\nдоступно всем пользователям\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазвани...\n\n01.01.2026 — 01.01.2027\n\nпродолжить обучение", + "screenshot": "screenshots/states/courses-320.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "profile", + "width": 320, + "passed": true, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Профиль\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов Тестовый\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазвание", + "screenshot": "screenshots/states/profile-320.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "profile-edit", + "width": 320, + "passed": true, + "actualPath": "/office/profile/edit", + "actualQuery": "?editingStep=main", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-modal", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea" + ], + "text": "Редактирование профиля\nредактирование профиля\ncохранить\nосновные данные\nобразование\nработа\nдостижения\nнавыки\nдействия\nфото\nимя\nфамилия\nРегион\nдата рождения\nспециальность\nобо мне\n\n124 / 300\n\nуказать личные контакты\nдобавить контакт\nтелефон", + "screenshot": "screenshots/states/profile-edit-320.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "onboarding-0", + "width": 320, + "passed": true, + "actualPath": "/office/onboarding/stage-0", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-modal", + "app-region-select", + "app-select", + "app-dropdown", + "app-input", + "app-button", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-region-select", + "app-select", + "app-input", + "app-button" + ], + "text": "1\n2\n3\n4\nПривет, ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов Тестовый! ✌️\n\nРасскажите о себе, чтобы ваше резюме было сильным и отражало опыт\n\nФотография профиля*\n\nРегион*\n\nОбразование\n\nУровень образования\nВысшее образова", + "screenshot": "screenshots/states/onboarding-0-320.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "onboarding-1", + "width": 320, + "passed": true, + "actualPath": "/office/onboarding/stage-1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-onboarding", + "app-stage-one", + "app-tooltip", + "app-button", + "app-autocomplete-input", + "app-specializations-group", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-onboarding", + "app-stage-one", + "app-tooltip", + "app-button", + "app-autocomplete-input", + "app-specializations-group" + ], + "text": "1\n2\n3\n4\nКем хотите работать?\nзакончить регистрацию позже\nпродолжить\nпоиск по библиотеке\nбиблиотека\nРазработчик", + "screenshot": "screenshots/states/onboarding-1-320.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "loading-page", + "width": 320, + "passed": true, + "actualPath": "/office/program/1/analytics", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-modal", + "app-program-analytics", + "app-analytics-drilldown", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-program-analytics" + ], + "text": "Программы\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nназад\nКонтакты\n\nУправление программой\n\nАналитика\n\nСводка пути участников от регистрации до экспертной оценки.\n\nЗагружаем аналитику программы…", + "screenshot": "screenshots/states/loading-page-320.png", + "expectedErrors": [], + "category": "loading" + }, + { + "name": "loading-action", + "width": 320, + "passed": true, + "actualPath": "/office/courses/1/lesson/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task", + "app-loader", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task", + "app-loader" + ], + "text": "Курсы\nназад\n\nмодуль 1\n\nурок 1\n\nо курсе\n\n1\n\nзадание 1\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазван...\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nответ\n\n35 / 1000\n\nзавершить урок", + "screenshot": "screenshots/states/loading-action-320.png", + "expectedErrors": [], + "category": "loading", + "submissions": 1 + }, + { + "name": "empty", + "width": 320, + "passed": true, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-state", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-state", + "app-button", + "app-vacancy-filter" + ], + "text": "Вакансии\nвакансии\n\nПоиск\n\nВакансии не найдены\n\nПопробуйте изменить запрос или сбросить фильтры.\n\nСбросить фильтры\nфильтры\nмои отклики", + "screenshot": "screenshots/states/empty-320.png", + "expectedErrors": [], + "category": "empty" + }, + { + "name": "error", + "width": 320, + "passed": true, + "actualPath": "/office/program/1/analytics", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-modal", + "app-program-analytics", + "app-analytics-drilldown", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-program-analytics" + ], + "text": "Программы\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nназад\nКонтакты\n\nУправление программой\n\nАналитика\n\nСводка пути участников от регистрации до экспертной оценки.\n\nАналитика недоступна\n\nНе удалось загрузить аналитику. ", + "screenshot": "screenshots/states/error-320.png", + "expectedErrors": [ + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[15:30:42.177] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 67ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"", + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[15:30:44.192] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 8ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"", + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[15:30:48.202] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 4ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"", + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[15:30:56.209] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 4ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"" + ], + "category": "error", + "injectedHttp500": true, + "retryPassed": true + }, + { + "name": "disabled-action", + "width": 320, + "passed": true, + "actualPath": "/office/courses/1/lesson/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task" + ], + "text": "Курсы\nназад\n\nмодуль 1\n\nурок 1\n\nо курсе\n\n1\n\nзадание 1\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазван...\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nответ\n\n0 / 1000\n\nзавершить урок", + "screenshot": "screenshots/states/disabled-action-320.png", + "expectedErrors": [], + "category": "disabled" + }, + { + "name": "disabled-filter", + "width": 320, + "passed": true, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-state", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-state" + ], + "text": "Новости\nвсе новости\n0\nновости проектов\n0\nсвежие вакансии\n0\nновости сообщества\n0\nновости программ\n0\nобразование\n0\n\nв данном разделе пока нет новостей", + "screenshot": "screenshots/states/disabled-filter-320.png", + "expectedErrors": [], + "category": "disabled" + }, + { + "name": "validation-register", + "width": 320, + "passed": true, + "actualPath": "/auth/register", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-auth", + "app-login", + "app-input", + "app-checkbox", + "app-button", + "app-modal", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-auth", + "app-login", + "app-input", + "app-checkbox", + "app-button" + ], + "text": "имя\nфамилия\nдата рождения\nпочта\nпароль\nповторите пароль\nОбязательное поле\nя прочитал соглашение и даю согласие на обработку персональных данных\nнажимая на кнопку подтверждаете, что вам больше 14 лет\nзарегистрироваться\n\nесли есть аккаунт? - войдите", + "screenshot": "screenshots/states/validation-register-320.png", + "expectedErrors": [], + "category": "validation" + }, + { + "name": "validation-onboarding", + "width": 320, + "passed": true, + "actualPath": "/office/onboarding/stage-0", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-modal", + "app-region-select", + "app-select", + "app-dropdown", + "app-input", + "app-button", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-region-select", + "app-select", + "app-input", + "app-button" + ], + "text": "1\n2\n3\n4\nПривет, ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов Тестовый! ✌️\n\nРасскажите о себе, чтобы ваше резюме было сильным и отражало опыт\n\nФотография профиля*\n\nВыберите фото для профиля\nРегион*\n\nОбразование\n\nУровень о", + "screenshot": "screenshots/states/validation-onboarding-320.png", + "expectedErrors": [], + "category": "validation" + }, + { + "name": "projects", + "width": 390, + "passed": true, + "actualPath": "/office/projects/all", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-projects-filter", + "app-select", + "app-dropdown", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-projects-filter", + "app-select" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\nФильтр\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nПроект для проверки адаптива\n\nОткрыть\n\nфильтры\n\nсбросить\nсфера проекта", + "screenshot": "screenshots/states/projects-390.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "vacancies", + "width": 390, + "passed": true, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter" + ], + "text": "Вакансии\nвакансии\n\nПоиск\n\nАктивна\n01.10.2026\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nПроект\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробело", + "screenshot": "screenshots/states/vacancies-390.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "programs", + "width": 390, + "passed": true, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card" + ], + "text": "Программы\nпрограммы\n\nПоиск\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nты уже участвуешь!\n\n01.10.2026 - 01.01.2027\n\nдля всей России", + "screenshot": "screenshots/states/programs-390.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "courses", + "width": 390, + "passed": true, + "actualPath": "/office/courses/all", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge", + "app-soon-card", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge" + ], + "text": "Курсы\nкурсы\n\nПоиск\n\nдоступно всем пользователям\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазвани...\n\n01.01.2026 — 01.01.2027\n\nпродолжить обучение", + "screenshot": "screenshots/states/courses-390.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "profile", + "width": 390, + "passed": true, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Профиль\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов Тестовый\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазвание", + "screenshot": "screenshots/states/profile-390.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "profile-edit", + "width": 390, + "passed": true, + "actualPath": "/office/profile/edit", + "actualQuery": "?editingStep=main", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-modal", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea" + ], + "text": "Редактирование профиля\nредактирование профиля\ncохранить\nосновные данные\nобразование\nработа\nдостижения\nнавыки\nдействия\nфото\nимя\nфамилия\nРегион\nдата рождения\nспециальность\nобо мне\n\n124 / 300\n\nуказать личные контакты\nдобавить контакт\nтелефон", + "screenshot": "screenshots/states/profile-edit-390.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "onboarding-0", + "width": 390, + "passed": true, + "actualPath": "/office/onboarding/stage-0", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-modal", + "app-region-select", + "app-select", + "app-dropdown", + "app-input", + "app-button", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-region-select", + "app-select", + "app-input", + "app-button" + ], + "text": "1\n2\n3\n4\nПривет, ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов Тестовый! ✌️\n\nРасскажите о себе, чтобы ваше резюме было сильным и отражало опыт\n\nФотография профиля*\n\nРегион*\n\nОбразование\n\nУровень образования\nВысшее образова", + "screenshot": "screenshots/states/onboarding-0-390.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "onboarding-1", + "width": 390, + "passed": true, + "actualPath": "/office/onboarding/stage-1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-onboarding", + "app-stage-one", + "app-tooltip", + "app-button", + "app-autocomplete-input", + "app-specializations-group", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-onboarding", + "app-stage-one", + "app-tooltip", + "app-button", + "app-autocomplete-input", + "app-specializations-group" + ], + "text": "1\n2\n3\n4\nКем хотите работать?\nзакончить регистрацию позже\nпродолжить\nпоиск по библиотеке\nбиблиотека\nРазработчик", + "screenshot": "screenshots/states/onboarding-1-390.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "loading-page", + "width": 390, + "passed": true, + "actualPath": "/office/program/1/analytics", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-modal", + "app-program-analytics", + "app-analytics-drilldown", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-program-analytics" + ], + "text": "Программы\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nназад\nКонтакты\n\nУправление программой\n\nАналитика\n\nСводка пути участников от регистрации до экспертной оценки.\n\nЗагружаем аналитику программы…", + "screenshot": "screenshots/states/loading-page-390.png", + "expectedErrors": [], + "category": "loading" + }, + { + "name": "loading-action", + "width": 390, + "passed": true, + "actualPath": "/office/courses/1/lesson/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task", + "app-loader", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task", + "app-loader" + ], + "text": "Курсы\nназад\n\nмодуль 1\n\nурок 1\n\nо курсе\n\n1\n\nзадание 1\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазван...\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nответ\n\n35 / 1000\n\nзавершить урок", + "screenshot": "screenshots/states/loading-action-390.png", + "expectedErrors": [], + "category": "loading", + "submissions": 1 + }, + { + "name": "empty", + "width": 390, + "passed": true, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-state", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-state", + "app-button", + "app-vacancy-filter" + ], + "text": "Вакансии\nвакансии\n\nПоиск\n\nВакансии не найдены\n\nПопробуйте изменить запрос или сбросить фильтры.\n\nСбросить фильтры\nфильтры\nмои отклики", + "screenshot": "screenshots/states/empty-390.png", + "expectedErrors": [], + "category": "empty" + }, + { + "name": "error", + "width": 390, + "passed": true, + "actualPath": "/office/program/1/analytics", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-modal", + "app-program-analytics", + "app-analytics-drilldown", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-program-analytics" + ], + "text": "Программы\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nназад\nКонтакты\n\nУправление программой\n\nАналитика\n\nСводка пути участников от регистрации до экспертной оценки.\n\nАналитика недоступна\n\nНе удалось загрузить аналитику. ", + "screenshot": "screenshots/states/error-390.png", + "expectedErrors": [ + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[15:31:22.860] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 41ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"", + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[15:31:24.869] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 3ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"", + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[15:31:28.877] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 4ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"", + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[15:31:36.882] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 3ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"" + ], + "category": "error", + "injectedHttp500": true, + "retryPassed": true + }, + { + "name": "disabled-action", + "width": 390, + "passed": true, + "actualPath": "/office/courses/1/lesson/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task" + ], + "text": "Курсы\nназад\n\nмодуль 1\n\nурок 1\n\nо курсе\n\n1\n\nзадание 1\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазван...\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nответ\n\n0 / 1000\n\nзавершить урок", + "screenshot": "screenshots/states/disabled-action-390.png", + "expectedErrors": [], + "category": "disabled" + }, + { + "name": "disabled-filter", + "width": 390, + "passed": true, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-state", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-state" + ], + "text": "Новости\nвсе новости\n0\nновости проектов\n0\nсвежие вакансии\n0\nновости сообщества\n0\nновости программ\n0\nобразование\n0\n\nв данном разделе пока нет новостей", + "screenshot": "screenshots/states/disabled-filter-390.png", + "expectedErrors": [], + "category": "disabled" + }, + { + "name": "validation-register", + "width": 390, + "passed": true, + "actualPath": "/auth/register", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-auth", + "app-login", + "app-input", + "app-checkbox", + "app-button", + "app-modal", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-auth", + "app-login", + "app-input", + "app-checkbox", + "app-button" + ], + "text": "имя\nфамилия\nдата рождения\nпочта\nпароль\nповторите пароль\nОбязательное поле\nя прочитал соглашение и даю согласие на обработку персональных данных\nнажимая на кнопку подтверждаете, что вам больше 14 лет\nзарегистрироваться\n\nесли есть аккаунт? - войдите", + "screenshot": "screenshots/states/validation-register-390.png", + "expectedErrors": [], + "category": "validation" + }, + { + "name": "validation-onboarding", + "width": 390, + "passed": true, + "actualPath": "/office/onboarding/stage-0", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-modal", + "app-region-select", + "app-select", + "app-dropdown", + "app-input", + "app-button", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-region-select", + "app-select", + "app-input", + "app-button" + ], + "text": "1\n2\n3\n4\nПривет, ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов Тестовый! ✌️\n\nРасскажите о себе, чтобы ваше резюме было сильным и отражало опыт\n\nФотография профиля*\n\nВыберите фото для профиля\nРегион*\n\nОбразование\n\nУровень о", + "screenshot": "screenshots/states/validation-onboarding-390.png", + "expectedErrors": [], + "category": "validation" + }, + { + "name": "projects", + "width": 768, + "passed": true, + "actualPath": "/office/projects/all", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-projects-filter", + "app-select", + "app-dropdown", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-projects-filter", + "app-select" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\nФильтр\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nПроект для проверки адаптива\n\nОткрыть\n\nфильтры\n\nсбросить\nсфера проекта", + "screenshot": "screenshots/states/projects-768.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "vacancies", + "width": 768, + "passed": true, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter" + ], + "text": "Вакансии\nвакансии\n\nПоиск\n\nАктивна\n01.10.2026\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nПроект\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробело", + "screenshot": "screenshots/states/vacancies-768.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "programs", + "width": 768, + "passed": true, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card" + ], + "text": "Программы\nпрограммы\n\nПоиск\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nты уже участвуешь!\n\n01.10.2026 - 01.01.2027\n\nдля всей России", + "screenshot": "screenshots/states/programs-768.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "courses", + "width": 768, + "passed": true, + "actualPath": "/office/courses/all", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge", + "app-soon-card", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge" + ], + "text": "Курсы\nкурсы\n\nПоиск\n\nдоступно всем пользователям\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазвани...\n\n01.01.2026 — 01.01.2027\n\nпродолжить обучение", + "screenshot": "screenshots/states/courses-768.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "profile", + "width": 768, + "passed": true, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Профиль\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов Тестовый\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазвание", + "screenshot": "screenshots/states/profile-768.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "profile-edit", + "width": 768, + "passed": true, + "actualPath": "/office/profile/edit", + "actualQuery": "?editingStep=main", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-modal", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea" + ], + "text": "Редактирование профиля\nредактирование профиля\ncохранить\nосновные данные\nобразование\nработа\nдостижения\nнавыки\nдействия\nфото\nимя\nфамилия\nРегион\nдата рождения\nспециальность\nобо мне\n\n124 / 300\n\nуказать личные контакты\nдобавить контакт\nтелефон", + "screenshot": "screenshots/states/profile-edit-768.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "onboarding-0", + "width": 768, + "passed": true, + "actualPath": "/office/onboarding/stage-0", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-modal", + "app-region-select", + "app-select", + "app-dropdown", + "app-input", + "app-button", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-region-select", + "app-select", + "app-input", + "app-button" + ], + "text": "1\n2\n3\n4\nПривет, ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов Тестовый! ✌️\n\nРасскажите о себе, чтобы ваше резюме было сильным и отражало опыт\n\nФотография профиля*\n\nРегион*\n\nОбразование\n\nУровень образования\nВысшее образова", + "screenshot": "screenshots/states/onboarding-0-768.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "onboarding-1", + "width": 768, + "passed": true, + "actualPath": "/office/onboarding/stage-1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-onboarding", + "app-stage-one", + "app-tooltip", + "app-button", + "app-autocomplete-input", + "app-specializations-group", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-onboarding", + "app-stage-one", + "app-tooltip", + "app-button", + "app-autocomplete-input", + "app-specializations-group" + ], + "text": "1\n2\n3\n4\nКем хотите работать?\nзакончить регистрацию позже\nпродолжить\nпоиск по библиотеке\nбиблиотека\nРазработчик", + "screenshot": "screenshots/states/onboarding-1-768.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "loading-page", + "width": 768, + "passed": true, + "actualPath": "/office/program/1/analytics", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-modal", + "app-program-analytics", + "app-analytics-drilldown", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-program-analytics" + ], + "text": "Программы\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nназад\nКонтакты\n\nУправление программой\n\nАналитика\n\nСводка пути участников от регистрации до экспертной оценки.\n\nЗагружаем аналитику программы…", + "screenshot": "screenshots/states/loading-page-768.png", + "expectedErrors": [], + "category": "loading" + }, + { + "name": "loading-action", + "width": 768, + "passed": true, + "actualPath": "/office/courses/1/lesson/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task", + "app-loader", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task", + "app-loader" + ], + "text": "Курсы\nназад\n\nмодуль 1\n\nурок 1\n\nо курсе\n\n1\n\nзадание 1\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазван...\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nответ\n\n35 / 1000\n\nзавершить урок", + "screenshot": "screenshots/states/loading-action-768.png", + "expectedErrors": [], + "category": "loading", + "submissions": 1 + }, + { + "name": "empty", + "width": 768, + "passed": true, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-state", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-state", + "app-button", + "app-vacancy-filter" + ], + "text": "Вакансии\nвакансии\n\nПоиск\n\nВакансии не найдены\n\nПопробуйте изменить запрос или сбросить фильтры.\n\nСбросить фильтры\nфильтры\nмои отклики", + "screenshot": "screenshots/states/empty-768.png", + "expectedErrors": [], + "category": "empty" + }, + { + "name": "error", + "width": 768, + "passed": true, + "actualPath": "/office/program/1/analytics", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-modal", + "app-program-analytics", + "app-analytics-drilldown", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-program-analytics" + ], + "text": "Программы\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nназад\nКонтакты\n\nУправление программой\n\nАналитика\n\nСводка пути участников от регистрации до экспертной оценки.\n\nАналитика недоступна\n\nНе удалось загрузить аналитику. ", + "screenshot": "screenshots/states/error-768.png", + "expectedErrors": [ + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[15:32:02.687] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 49ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"", + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[15:32:04.697] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 3ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"", + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[15:32:08.703] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 2ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"", + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[15:32:16.712] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 4ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"" + ], + "category": "error", + "injectedHttp500": true, + "retryPassed": true + }, + { + "name": "disabled-action", + "width": 768, + "passed": true, + "actualPath": "/office/courses/1/lesson/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task" + ], + "text": "Курсы\nназад\n\nмодуль 1\n\nурок 1\n\nо курсе\n\n1\n\nзадание 1\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазван...\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nответ\n\n0 / 1000\n\nзавершить урок", + "screenshot": "screenshots/states/disabled-action-768.png", + "expectedErrors": [], + "category": "disabled" + }, + { + "name": "disabled-filter", + "width": 768, + "passed": true, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-state", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-state" + ], + "text": "Новости\nвсе новости\n0\nновости проектов\n0\nсвежие вакансии\n0\nновости сообщества\n0\nновости программ\n0\nобразование\n0\n\nв данном разделе пока нет новостей", + "screenshot": "screenshots/states/disabled-filter-768.png", + "expectedErrors": [], + "category": "disabled" + }, + { + "name": "validation-register", + "width": 768, + "passed": true, + "actualPath": "/auth/register", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-auth", + "app-login", + "app-input", + "app-checkbox", + "app-button", + "app-modal", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-auth", + "app-login", + "app-input", + "app-checkbox", + "app-button" + ], + "text": "имя\nфамилия\nдата рождения\nпочта\nпароль\nповторите пароль\nОбязательное поле\nя прочитал соглашение и даю согласие на обработку персональных данных\nнажимая на кнопку подтверждаете, что вам больше 14 лет\nзарегистрироваться\n\nесли есть аккаунт? - войдите", + "screenshot": "screenshots/states/validation-register-768.png", + "expectedErrors": [], + "category": "validation" + }, + { + "name": "validation-onboarding", + "width": 768, + "passed": true, + "actualPath": "/office/onboarding/stage-0", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-modal", + "app-region-select", + "app-select", + "app-dropdown", + "app-input", + "app-button", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-region-select", + "app-select", + "app-input", + "app-button" + ], + "text": "1\n2\n3\n4\nПривет, ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов Тестовый! ✌️\n\nРасскажите о себе, чтобы ваше резюме было сильным и отражало опыт\n\nФотография профиля*\n\nВыберите фото для профиля\nРегион*\n\nОбразование\n\nУровень о", + "screenshot": "screenshots/states/validation-onboarding-768.png", + "expectedErrors": [], + "category": "validation" + } + ] +} diff --git a/docs/desktop-regression/states.log b/docs/desktop-regression/states.log new file mode 100644 index 000000000..3a8b9e447 --- /dev/null +++ b/docs/desktop-regression/states.log @@ -0,0 +1,69 @@ +{"name":"projects","width":320,"passed":true} +{"name":"vacancies","width":320,"passed":true} +{"name":"programs","width":320,"passed":true} +{"name":"courses","width":320,"passed":true} +{"name":"profile","width":320,"passed":true} +{"name":"profile-edit","width":320,"passed":true} +{"name":"onboarding-0","width":320,"passed":true} +{"name":"onboarding-1","width":320,"passed":true} +{"name":"loading-page","width":320,"passed":true} +{"name":"loading-action","width":320,"passed":true} +{"name":"empty","width":320,"passed":true} +{"name":"error","width":320,"passed":true} +{"name":"disabled-action","width":320,"passed":true} +{"name":"disabled-filter","width":320,"passed":true} +{"name":"validation-register","width":320,"passed":true} +{"name":"validation-onboarding","width":320,"passed":true} +{"name":"projects","width":390,"passed":true} +{"name":"vacancies","width":390,"passed":true} +{"name":"programs","width":390,"passed":true} +{"name":"courses","width":390,"passed":true} +{"name":"profile","width":390,"passed":true} +{"name":"profile-edit","width":390,"passed":true} +{"name":"onboarding-0","width":390,"passed":true} +{"name":"onboarding-1","width":390,"passed":true} +{"name":"loading-page","width":390,"passed":true} +{"name":"loading-action","width":390,"passed":true} +{"name":"empty","width":390,"passed":true} +{"name":"error","width":390,"passed":true} +{"name":"disabled-action","width":390,"passed":true} +{"name":"disabled-filter","width":390,"passed":true} +{"name":"validation-register","width":390,"passed":true} +{"name":"validation-onboarding","width":390,"passed":true} +{"name":"projects","width":768,"passed":true} +{"name":"vacancies","width":768,"passed":true} +{"name":"programs","width":768,"passed":true} +{"name":"courses","width":768,"passed":true} +{"name":"profile","width":768,"passed":true} +{"name":"profile-edit","width":768,"passed":true} +{"name":"onboarding-0","width":768,"passed":true} +{"name":"onboarding-1","width":768,"passed":true} +{"name":"loading-page","width":768,"passed":true} +{"name":"loading-action","width":768,"passed":true} +{"name":"empty","width":768,"passed":true} +{"name":"error","width":768,"passed":true} +{"name":"disabled-action","width":768,"passed":true} +{"name":"disabled-filter","width":768,"passed":true} +{"name":"validation-register","width":768,"passed":true} +{"name":"validation-onboarding","width":768,"passed":true} +48 UI state checks passed +navigation-feed-skills 320: passed +projects-activity 320: passed +members 320: passed +profile-actions 320: passed +project-actions 320: passed +program-actions 320: passed +navigation-feed-skills 390: passed +projects-activity 390: passed +members 390: passed +profile-actions 390: passed +project-actions 390: passed +program-actions 390: passed +navigation-feed-skills 768: passed +projects-activity 768: passed +members 768: passed +profile-actions 768: passed +project-actions 768: passed +program-actions 768: passed +18 interaction screens passed +6 resize checks passed; routed hosts, search and filters preserved diff --git a/docs/desktop-regression/unit-tests.log b/docs/desktop-regression/unit-tests.log new file mode 100644 index 000000000..159f84d5e --- /dev/null +++ b/docs/desktop-regression/unit-tests.log @@ -0,0 +1,1158 @@ + +> procollab@0.0.0 test:ci +> vitest run + + + RUN v3.2.6 Z:/Документы/PROCOLLAB-dev/procollab-dev-platform-responsive + + ✓ projects/social_platform/src/app/ui/widgets/project-invite/profile-project-invite-modal.component.spec.ts (21 tests) 2494ms + ✓ Окно выбора проекта > локальный поиск нормализует пробелы и регистр, строка выбирается целиком и выделяется 524ms + ✓ projects/social_platform/src/app/ui/pages/projects/edit/components/project-team-step/project-team-step.component.spec.ts (7 tests) 2736ms + ✓ Окно приглашения из редактора команды > CTA открывает окно с поиском, URL отсутствует, отправка неактивна до выбора и роли 1138ms + ✓ Окно приглашения из редактора команды > показывает public data, причины disabled, выбирает строку и очищает выбор 597ms + ✓ Окно приглашения из редактора команды > ошибка inline сохраняет выбор/роль, повтор защищён, успех закрывает и возвращает фокус 613ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/analytics/drilldown/analytics-drilldown.component.spec.ts (30 tests) 3546ms + ✓ AnalyticsDrilldownComponent: real overlay lifecycle > all: единое оформление списка и правильный заголовок 1036ms + ✓ projects/social_platform/src/app/ui/widgets/info-card/info-card.component.spec.ts (41 tests) 3538ms + ✓ InfoCardComponent: статусы моих проектов > 'draft' / 'Лидер': статус, доступ и единственный корректный маршрут 880ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/analytics/drilldown/analytics-attention.component.spec.ts (19 tests) 3783ms + ✓ Attention views: real overlay > participants: реальные поля, local date, legacy city, fallback, актуальный count 991ms + ✓ projects/social_platform/src/app/ui/pages/projects/list/list.component.spec.ts (9 tests) 2742ms + ✓ ProjectsListComponent: контекст и track > /my: CTA выполняет один переход в detail 1285ms + ✓ projects/social_platform/src/app/ui/widgets/news-card/feed-news-preview/feed-news-preview.component.spec.ts (23 tests) 5236ms + ✓ FeedNewsPreviewComponent > project: нет пустой media-области; thumbnail появляется только с изображением 1471ms + ✓ FeedNewsPreviewComponent > Подробнее определяется обрезанием, обновляется при resize и исчезает когда текст помещается 654ms + ✓ FeedNewsPreviewComponent > card открывает одно окно 333ms + ✓ projects/social_platform/src/app/ui/pages/profile/edit/components/profile-main-step/profile-main-step.component.spec.ts (6 tests) 5475ms + ✓ ProfileMainStepComponent user region > loads canonical city as selected user region without API side effects 3037ms + ✓ ProfileMainStepComponent user region > preserves untouched legacy city Набережные Челны through focus, blur and Escape 534ms + ✓ ProfileMainStepComponent user region > preserves untouched legacy city Мсква through focus, blur and Escape 726ms + ✓ ProfileMainStepComponent user region > preserves untouched legacy city moscow through focus, blur and Escape 529ms + ✓ ProfileMainStepComponent user region > clears legacy on search, ranks Moscow first and commits only an option to city 368ms + ✓ projects/social_platform/src/app/ui/pages/projects/edit/components/project-main-step/project-main-step.component.spec.ts (12 tests) 6653ms + ✓ ProjectMainStepComponent > стандартная обложка предлагает загрузку и не выдаёт системный URL за загруженный файл 3133ms + ✓ ProjectMainStepComponent > пользовательская обложка предлагает только замену с клавиатуры, без кнопки сброса 557ms + ✓ ProjectMainStepComponent > замена стандартной и пользовательской обложки загрузкой не вызывает DELETE 762ms + ✓ ProjectMainStepComponent > пустая обложка показывает zero state, не записывая фиктивный URL в обязательный control 485ms + ✓ projects/social_platform/src/app/ui/pages/profile/edit/edit.component.spec.ts (3 tests) 4495ms + ✓ ProfileEditComponent > should create 3495ms + ✓ ProfileEditComponent > closes the skills library with the explicit close button 664ms + ✓ ProfileEditComponent > closes the skills library through the modal backdrop 313ms +stderr | projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/rating-card.component.spec.ts > RatingCardComponent > keeps unrated CTA active and criteria editable when registration is past but evaluation is future + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + ✓ projects/social_platform/src/app/ui/pages/members/members-mobile.spec.ts (7 tests) 1545ms + ✓ Мобильное представление участников > держит статистику перед мобильным списком, под desktop-фильтрами и не перезагружает её при поиске 628ms +stderr | projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/rating-card.component.spec.ts > RatingCardComponent > allows editing an existing rating until the evaluation deadline, then returns to readonly on success + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + +stderr | projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/rating-card.component.spec.ts > RatingCardComponent > allows editing an existing rating until the evaluation deadline, then returns to readonly on success + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + ✓ projects/social_platform/src/app/ui/pages/program/detail/analytics/drilldown/analytics-case.component.spec.ts (12 tests) 1507ms + ✓ Case drilldown в существующем Overlay > selected: четыре колонки, реальные поля, null presentation и только один modal 671ms +stderr | projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/rating-card.component.spec.ts > RatingCardComponent > keeps expired CTA visible and all criteria readonly (rated=false) + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + +stderr | projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/rating-card.component.spec.ts > RatingCardComponent > keeps expired CTA visible and all criteria readonly (rated=true) + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + ✓ projects/social_platform/src/app/ui/pages/onboarding/stage-zero/stage-zero.component.spec.ts (3 tests) 1369ms + ✓ StageZeroComponent > should create 978ms +stderr | projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/rating-card.component.spec.ts > RatingCardComponent > keeps CTA and criteria available for deadline + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + +stderr | projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/rating-card.component.spec.ts > RatingCardComponent > keeps CTA and criteria available for invalid deadline + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + +stderr | projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/rating-card.component.spec.ts > RatingCardComponent > updates visible CTA and criteria on fresh closed/reopened program responses + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + ✓ projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/rating-card.component.spec.ts (8 tests) 1420ms + ✓ RatingCardComponent > should create 465ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/main/main.roles.spec.ts (4 tests) 1218ms + ✓ Program page: program-scoped news and role visibility > loads and shows both existing and newly created news for manager without member role 964ms + ✓ projects/social_platform/src/app/ui/pages/projects/edit/edit.component.spec.ts (3 tests) 1494ms + ✓ ProjectEditComponent > should create 1272ms +stderr | projects/social_platform/src/app/ui/widgets/info-card/info-card-subscription.spec.ts > InfoCard: асинхронная подписка (base) > не закрашивает закладку при ошибке подписки +[15:23:20.269] [ERROR] Error subscribing to project: {"kind":"add_project_subscription_error","cause":{}} + + ✓ projects/social_platform/src/app/ui/pages/projects/projects-presentation.spec.ts (6 tests) 1611ms + ✓ ProjectsComponent: приглашение и активность на странице > сохраняет размещение активности в разделе dashboard 986ms +stderr | projects/social_platform/src/app/ui/widgets/info-card/info-card-subscription.spec.ts > InfoCard: асинхронная подписка (base) > сохраняет подписку и подтверждение при ошибке, после успешного повтора закрывает +[15:23:20.458] [ERROR] Error unsubscribing from project: {"kind":"delete_project_subscription_error","cause":{}} + + ✓ projects/social_platform/src/app/ui/widgets/news-card/news-card.component.spec.ts (5 tests) 979ms + ✓ NewsCardComponent > should create 639ms + ✓ projects/social_platform/src/app/ui/widgets/news-form/news-form.component.spec.ts (7 tests) 861ms + ✓ NewsFormComponent > should create 406ms + ✓ projects/social_platform/src/app/ui/widgets/detail/detail-cleanup.component.spec.ts (5 tests) 1945ms + ✓ Detail cleanup actions > renders create, open-existing and submitted CTA states without changing submitted disabling 1072ms +stderr | projects/social_platform/src/app/ui/widgets/info-card/info-card-subscription.spec.ts > InfoCard: асинхронная подписка (subs) > не закрашивает закладку при ошибке подписки +[15:23:20.943] [ERROR] Error subscribing to project: {"kind":"add_project_subscription_error","cause":{}} + + ✓ projects/social_platform/src/app/ui/pages/projects/edit/components/project-additional-step/project-additional-step.component.spec.ts (8 tests) 1837ms + ✓ ProjectAdditionalStepComponent canonical form > required indicators follow backend metadata; optional text has no fake required error 896ms + ✓ projects/social_platform/src/app/ui/widgets/info-card/info-card-list-contract.spec.ts (8 tests) 1048ms + ✓ Мои проекты: HTTP list → преобразование контракта → карточка > is_submitted=true, draft=false: lifecycle и доступ независимы 601ms +stderr | projects/social_platform/src/app/ui/widgets/info-card/info-card-subscription.spec.ts > InfoCard: асинхронная подписка (subs) > сохраняет подписку и подтверждение при ошибке, после успешного повтора закрывает +[15:23:21.085] [ERROR] Error unsubscribing from project: {"kind":"delete_project_subscription_error","cause":{}} + + ✓ projects/social_platform/src/app/ui/widgets/info-card/info-card-subscription.spec.ts (8 tests) 1872ms + ✓ InfoCard: асинхронная подписка (base) > закрашивает закладку после отложенного ответа без перезагрузки и второго клика 714ms + ✓ projects/social_platform/src/app/ui/pages/projects/dashboard/dashboard.component.spec.ts (3 tests) 1237ms + ✓ ProjectsDashboard: контексты карточек > передаёт my/subs/base, ID и подписки; показывает нужный контекст каждого раздела 1125ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/analytics/analytics.component.spec.ts (42 tests) 13312ms + ✓ ProgramAnalyticsComponent > cases from manager overview > не показывает общую выгрузку и не запрашивает проекты до открытия кейса 2082ms + ✓ ProgramAnalyticsComponent > cases from manager overview > клик строки 0 передаёт точный scope, включая нулевой кейс 644ms + ✓ ProgramAnalyticsComponent > cases from manager overview > клик строки 2 передаёт точный scope, включая нулевой кейс 420ms + ✓ ProgramAnalyticsComponent > cases from manager overview > клик строки 3 передаёт точный scope, включая нулевой кейс 343ms + ✓ ProgramAnalyticsComponent > cases from manager overview > keeps cases and evaluation as adjacent cards in the same two-column grid row 321ms + ✓ ProgramAnalyticsComponent > cases from manager overview > preserves backend counts/order/zero rows and appends withoutCase without mutations 460ms + ✓ ProgramAnalyticsComponent > cases from manager overview > includes the visible without-case bucket in the common scale 308ms + ✓ ProgramAnalyticsComponent > показывает authoritative summary и реальный разрез регионов 305ms + ✓ ProgramAnalyticsComponent > non-competitive скрывает строку даже с notSubmitted > 0 и не делает detail request 355ms + ✓ ProgramAnalyticsComponent > marks zero attention rows and keeps tooltip controls separate and keyboard accessible 308ms + ✓ projects/social_platform/src/app/ui/pages/feed/feed.component.spec.ts (1 test) 894ms + ✓ FeedComponent: порядок и представление карточек #372 > сохраняет шесть начальных карточек, ключи type:id и append в DOM без перестановки 892ms + ✓ projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-mid-side/profile-mid-side.component.spec.ts (4 tests) 904ms + ✓ ProfileMidSideComponent > показывает центрируемый empty state владельцу пустого профиля 611ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/main/role-widget/program-role-widget.component.spec.ts (11 tests) 970ms + ✓ ProgramRoleWidgetComponent > shows skeleton without bogus zero counters 315ms + ✓ projects/social_platform/src/app/ui/primitives/input/input.component.spec.ts (20 tests) 809ms + ✓ projects/social_platform/src/app/ui/pages/vacancies/detail/info/info.component.spec.ts (3 tests) 911ms + ✓ VacancyInfoComponent PROCOLLAB CV > разрешает прикрепить PROCOLLAB CV при пустом accompanyingFile 656ms + ✓ projects/social_platform/src/app/ui/pages/auth/register/register.component.spec.ts (4 tests) 1383ms + ✓ RegisterComponent > should create 830ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/analytics/drilldown/analytics-attention-route.spec.ts (3 tests) 1217ms + ✓ Attention SPA: observable route → resolver → overview > participants-without-team отменяется до Program(13), без нового auto request 952ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/main/main.component.spec.ts (2 tests) 787ms + ✓ MainComponent > should create 735ms + ✓ projects/social_platform/src/app/ui/pages/onboarding/stage-two/stage-two.component.spec.ts (4 tests) 1260ms + ✓ StageTwoComponent > should create 786ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/list/list.component.spec.ts (2 tests) 1539ms + ✓ ProgramListComponent > should create 1263ms + ✓ projects/social_platform/src/app/ui/pages/auth/login/login.component.spec.ts (4 tests) 753ms + ✓ LoginComponent > should create 516ms + ✓ projects/social_platform/src/app/ui/pages/profile/detail/main/main.component.spec.ts (1 test) 959ms + ✓ MainComponent > should create 956ms +stdout | projects/social_platform/src/app/ui/pages/program/detail/register/register.component.spec.ts > ProgramRegisterComponent > onSubmit > вызывает use-case с programId и значениями формы +[15:23:25.982] [DEBUG] Route changed from ProgramRegisterComponent + +stdout | projects/social_platform/src/app/ui/pages/program/detail/register/register.component.spec.ts > ProgramRegisterComponent > onSubmit > навигирует на детальную страницу программы при успехе use-case +[15:23:26.066] [DEBUG] Route changed from ProgramRegisterComponent + +stdout | projects/social_platform/src/app/ui/pages/program/detail/register/register.component.spec.ts > ProgramRegisterComponent > onSubmit > срабатывает по клику на кнопку submit в DOM +[15:23:26.184] [DEBUG] Route changed from ProgramRegisterComponent + + ✓ projects/social_platform/src/app/ui/pages/program/detail/register/register.component.spec.ts (7 tests) 963ms + ✓ ProgramRegisterComponent > ngOnInit строит форму из schema резолвера > создаёт FormGroup с полем под каждый ключ schema 487ms + ✓ projects/social_platform/src/app/ui/widgets/region-select/region-select.component.spec.ts (12 tests) 761ms + ✓ projects/social_platform/src/app/api/auth/use-cases/register.use-case.spec.ts (5 tests) 70ms + ✓ projects/social_platform/src/app/ui/pages/projects/detail/info/info.component.spec.ts (1 test) 724ms + ✓ ProjectInfoComponent > should create 722ms + ✓ projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancy-responses/vacancy-responses.component.spec.ts (12 tests) 831ms + ✓ VacancyResponsesComponent > показывает два действия только для pending response 495ms + ✓ projects/social_platform/src/app/ui/pages/profile/detail/profile-news/profile-news.component.spec.ts (1 test) 567ms + ✓ ProfileNewsComponent > should create 565ms + ✓ projects/social_platform/src/app/ui/pages/vacancies/vacancies.component.spec.ts (2 tests) 636ms + ✓ VacanciesComponent > should create 513ms + ✓ projects/social_platform/src/app/ui/pages/projects/detail/info/components/projects-mid-side/projects-mid-side.component.spec.ts (4 tests) 1094ms + ✓ ProjectsMidSideComponent > shows the complete project description after expansion 1084ms + ✓ projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.spec.ts (7 tests) 573ms + ✓ Карточка каталога участников > показывает первый навык в исходном порядке и точный +N при 0 навыках 355ms + ✓ projects/social_platform/src/app/ui/pages/members/members.component.spec.ts (1 test) 1400ms + ✓ MembersComponent > should create 1397ms + ✓ projects/social_platform/src/app/ui/widgets/project-vacancy-card/project-vacancy-card.component.spec.ts (10 tests) 962ms + ✓ ProjectVacancyCardComponent > should create 545ms + ✓ projects/social_platform/src/app/ui/pages/office/office.component.spec.ts (3 tests) 1701ms + ✓ OfficeComponent > should create 1509ms + ✓ projects/social_platform/src/app/api/profile/facades/edit/profile-form.service.spec.ts (8 tests) 483ms + ✓ projects/social_platform/src/app/ui/pages/chat/chat-direct/chat-direct.component.spec.ts (1 test) 1246ms + ✓ ChatDirectComponent > should create 1234ms + ✓ projects/social_platform/src/app/ui/pages/vacancies/list/list.component.spec.ts (7 tests) 1520ms + ✓ VacanciesListComponent > должен вызвать vacancyInfoService.init() при инициализации компонента 1102ms + ✓ projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-right-side/profile-right-side.component.spec.ts (2 tests) 538ms + ✓ ProfileRightSideComponent > keeps the complete long project title in the profile project list DOM 472ms + ✓ projects/social_platform/src/app/ui/pages/auth/reset-password/reset-password.component.spec.ts (1 test) 801ms + ✓ ResetPasswordComponent > should create 799ms + ✓ projects/social_platform/src/app/ui/widgets/chat-window/chat-window.component.spec.ts (1 test) 542ms + ✓ ChatWindowComponent > should create 540ms + ✓ projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.spec.ts (5 tests) 421ms + ✓ VacancyCardComponent > should create 322ms +stderr | projects/social_platform/src/app/ui/pages/auth/set-password/set-password.component.spec.ts > SetPasswordComponent > should create +[15:23:34.316] [ERROR] Token is missing + + ✓ projects/social_platform/src/app/ui/pages/auth/set-password/set-password.component.spec.ts (1 test) 455ms + ✓ SetPasswordComponent > should create 452ms + ✓ projects/social_platform/src/app/ui/pages/projects/edit/components/project-team-step/invite-card/invite-card.component.spec.ts (4 tests) 867ms + ✓ InviteCardComponent > should create 627ms + ✓ projects/social_platform/src/app/ui/pages/projects/detail/news-detail/news-detail.component.spec.ts (1 test) 1042ms + ✓ NewsDetailComponent > should create 1035ms + ✓ projects/social_platform/src/app/ui/primitives/tooltip/tooltip.component.spec.ts (4 tests) 708ms + ✓ TooltipComponent overlay mode > should use overlay mode for analytics tooltip 537ms + ✓ projects/social_platform/src/app/ui/pages/vacancies/list/response-card/response-card.component.spec.ts (6 tests) 355ms +stdout | projects/social_platform/src/app/ui/widgets/projects-filter/projects-filter.component.spec.ts > ProjectsFilterComponent > сохраняет справочник отраслей и фильтрацию через query-параметр industry +[15:23:35.977] [DEBUG] Query change from ProjectsComponent + + ✓ projects/social_platform/src/app/ui/widgets/projects-filter/projects-filter.component.spec.ts (2 tests) 648ms + ✓ ProjectsFilterComponent > should create 575ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/list/program-projects-filter/program-projects-filter.component.spec.ts (2 tests) 765ms + ✓ ProjectsFilterComponent > should create 594ms + ✓ projects/social_platform/src/app/ui/primitives/select/select.component.spec.ts (7 tests) 773ms + ✓ SelectComponent > should create 530ms + ✓ projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-left-side/profile-left-side.component.spec.ts (6 tests) 484ms + ✓ ProfileLeftSideComponent > renders programs as compact named rectangular links 341ms + ✓ projects/social_platform/src/app/ui/pages/courses/detail/info/course-module-card/course-module-card.component.spec.ts (7 tests) 561ms + ✓ projects/social_platform/src/app/ui/pages/onboarding/stage-one/stage-one.component.spec.ts (1 test) 487ms + ✓ StageOneComponent > should create 483ms + ✓ projects/social_platform/src/app/ui/primitives/avatar-control/avatar-control.component.spec.ts (1 test) 408ms + ✓ AvatarControlComponent > should create 406ms + ✓ projects/social_platform/src/app/ui/primitives/textarea/textarea.component.spec.ts (6 tests) 553ms + ✓ TextareaComponent > should create 323ms + ✓ projects/social_platform/src/app/ui/widgets/news-card/feed-news-modal/feed-news-modal.component.spec.ts (1 test) 631ms + ✓ FeedNewsModalComponent > показывает полный текст, переносы, ссылку, все файлы и contain-карусель без detail HTTP 628ms + ✓ projects/social_platform/src/app/api/project/use-cases/create-partner.use-case.spec.ts (3 tests) 66ms + ✓ projects/social_platform/src/app/ui/pages/program/main/main.component.spec.ts (1 test) 673ms + ✓ MainComponent > should create 668ms + ✓ projects/social_platform/src/app/ui/pages/projects/project-activity-card/project-activity-card.component.spec.ts (11 tests) 690ms + ✓ ProjectActivityCardComponent > показывает четыре значения authoritative count 396ms + ✓ projects/social_platform/src/app/ui/pages/chat/chat.component.spec.ts (1 test) 558ms + ✓ ChatComponent > should create 552ms + ✓ projects/social_platform/src/app/ui/primitives/upload-file/upload-file.component.spec.ts (15 tests) 523ms + ✓ projects/social_platform/src/app/ui/pages/projects/detail/info/components/projects-left-side/projects-left-side.component.spec.ts (4 tests) 583ms + ✓ ProjectsLeftSideComponent > should show explicit project metadata labels 397ms + ✓ projects/social_platform/src/app/ui/pages/feed/open-vacancy/open-vacancy.component.spec.ts (1 test) 639ms + ✓ OpenVacancyComponent > показывает тип, дату, источник, роль, описание, навыки и CTA 637ms + ✓ projects/social_platform/src/app/api/profile/use-cases/get-profile-news-detail.use-case.spec.ts (3 tests) 100ms + ✓ projects/social_platform/src/app/ui/primitives/modal/modal.component.spec.ts (4 tests) 417ms + ✓ projects/social_platform/src/app/ui/pages/vacancies/detail/vacancies-detail.component.spec.ts (2 tests) 537ms + ✓ VacanciesDetailComponent > should create 411ms + ✓ projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-right-side/vacancies-right-side.component.spec.ts (9 tests) 414ms + ✓ projects/social_platform/src/app/ui/pages/office/delete-confirm/delete-confirm.component.spec.ts (1 test) 334ms + ✓ DeleteConfirmComponent > should create 332ms + ✓ projects/social_platform/src/app/infrastructure/adapters/project/project-goals-http.adapter.spec.ts (4 tests) 78ms + ✓ projects/social_platform/src/app/ui/pages/members/member-statistics-card/member-statistics-card.component.spec.ts (11 tests) 471ms + ✓ projects/social_platform/src/app/utils/export-regions-workbook.spec.ts (1 test) 387ms + ✓ region XLSX workbook integration > generates a ZIP/OOXML workbook with real string and number cells 382ms + ✓ projects/social_platform/src/app/ui/pages/projects/detail/chat/chat.component.spec.ts (1 test) 484ms + ✓ ChatComponent > should create 481ms + ✓ projects/social_platform/src/app/ui/pages/courses/lesson/shared/video-task/info-task.component.spec.ts (1 test) 284ms + ✓ projects/social_platform/src/app/ui/widgets/chat-window/chat-message/chat-message.component.spec.ts (1 test) 454ms + ✓ ChatMessageComponent > should create 451ms + ✓ projects/social_platform/src/app/ui/widgets/specializations-group/specializations-group.component.spec.ts (4 tests) 347ms + ✓ projects/social_platform/src/app/ui/pages/courses/list/course/course.component.spec.ts (1 test) 383ms + ✓ CourseComponent > should create 378ms + ✓ projects/social_platform/src/app/api/project/facades/edit/project-cover-reset.service.spec.ts (11 tests) 300ms + ✓ projects/social_platform/src/app/api/searches/searches.service.spec.ts (5 tests) 75ms + ✓ projects/social_platform/src/app/ui/primitives/autocomplete-input/autocomplete-input.component.spec.ts (3 tests) 425ms + ✓ AutoCompleteInputComponent: последовательные запросы > повторяет тот же поиск после выбора и программной очистки 348ms + ✓ projects/social_platform/src/app/ui/pages/courses/lesson/shared/write-task/write-task.component.spec.ts (1 test) 306ms + ✓ WriteTaskComponent > should create 303ms + ✓ projects/social_platform/src/app/app.component.spec.ts (1 test) 271ms + ✓ projects/social_platform/src/app/ui/primitives/avatar/avatar.component.spec.ts (6 tests) 269ms + ✓ projects/ui/src/lib/components/layout/invite-manage-card/invite-manage-card.component.spec.ts (1 test) 311ms + ✓ InviteManageCardComponent > should create 309ms + ✓ projects/social_platform/src/app/api/project/facades/edit/projects-edit-info.service.spec.ts (22 tests) 373ms + ✓ projects/social_platform/src/app/ui/pages/courses/lesson/complete/complete.component.spec.ts (5 tests) 295ms + ✓ projects/social_platform/src/app/api/invite/use-cases/revoke-invite.use-case.spec.ts (3 tests) 86ms + ✓ projects/social_platform/src/app/ui/widgets/cookie-consent/cookie-consent.component.spec.ts (5 tests) 283ms + ✓ projects/social_platform/src/app/ui/pages/projects/edit/components/project-team-step/collaborator-card/collaborator-card.component.spec.ts (2 tests) 379ms + ✓ CollaboratorCardComponent > should create 313ms +stdout | projects/social_platform/src/app/ui/widgets/feed-filter/feed-filter.component.spec.ts > FeedComponent > показывает счётчики всех шести категорий независимо от фильтра +[15:23:46.215] [DEBUG] Query change from FeedFilterComponent + + ✓ projects/social_platform/src/app/ui/widgets/feed-filter/feed-filter.component.spec.ts (2 tests) 411ms + ✓ projects/social_platform/src/app/ui/widgets/header/header.component.spec.ts (1 test) 362ms + ✓ HeaderComponent > should create 359ms + ✓ projects/social_platform/src/app/ui/pages/members/members-filters/members-filters.component.spec.ts (2 tests) 409ms + ✓ MembersFiltersComponent > should create 359ms + ✓ projects/social_platform/src/app/api/vacancy/use-cases/get-vacancy-responses.use-case.spec.ts (2 tests) 66ms + ✓ projects/social_platform/src/app/api/project/use-cases/remove-project-collaborator.use-case.spec.ts (3 tests) 63ms + ✓ projects/social_platform/src/app/ui/widgets/message-input/message-input.component.spec.ts (1 test) 287ms + ✓ projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-left-side/vacancies-left-side.component.spec.ts (1 test) 312ms + ✓ VacanciesLeftSideComponent > renders vacancy detail skills with the readable tag treatment 310ms + ✓ projects/social_platform/src/app/ui/pages/onboarding/stage-three/stage-three.component.spec.ts (1 test) 380ms + ✓ StageThreeComponent > should create 378ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/project-rating/components/range-criterion-input/range-criterion-input.component.spec.ts (5 tests) 251ms + ✓ projects/social_platform/src/app/ui/primitives/bar/bar.component.spec.ts (1 test) 245ms + ✓ projects/social_platform/src/app/ui/pages/courses/lesson/shared/radio-select-task/radio-select-task.component.spec.ts (1 test) 290ms + ✓ projects/social_platform/src/app/ui/pages/feed/new-project/new-project.component.spec.ts (1 test) 262ms + ✓ projects/social_platform/src/app/api/project/facades/edit/project-additional.service.spec.ts (39 tests) 286ms + ✓ projects/social_platform/src/app/ui/widgets/skills-group/skills-group.component.spec.ts (4 tests) 408ms + ✓ SkillsGroupComponent > should create 300ms + ✓ projects/social_platform/src/app/ui/widgets/project-invite/project-invite-role-input.component.spec.ts (4 tests) 299ms + ✓ projects/social_platform/src/app/ui/widgets/vacancy-filter/vacancy-filter.component.spec.ts (1 test) 342ms + ✓ FeedComponent > should create 340ms + ✓ projects/social_platform/src/app/domain/shared/chat-state.service.spec.ts (1 test) 34ms + ✓ projects/social_platform/src/app/ui/pages/program/main/program-card/program-card.component.spec.ts (1 test) 246ms + ✓ projects/social_platform/src/app/ui/widgets/news-card/carousel/carousel.component.spec.ts (2 tests) 240ms + ✓ projects/social_platform/src/app/api/project/facades/edit/project-form.service.spec.ts (13 tests) 271ms + ✓ projects/social_platform/src/app/api/feed/facades/feed-info.service.spec.ts (3 tests) 148ms + ✓ projects/social_platform/src/app/api/program/facades/detail/program-analytics-attention.service.spec.ts (42 tests) 359ms + ✓ projects/social_platform/src/app/ui/widgets/skills-basket/skills-basket.component.spec.ts (4 tests) 569ms + ✓ SkillsBasketComponent > should create 383ms + ✓ projects/social_platform/src/app/api/vacancy/use-cases/get-vacancies.use-case.spec.ts (3 tests) 102ms + ✓ projects/social_platform/src/app/ui/widgets/vacancy-skills/vacancy-skills.component.spec.ts (2 tests) 547ms + ✓ VacancySkillsComponent > показывает правильное число остальных навыков, раскрывает весь список и сворачивает его 516ms + ✓ projects/social_platform/src/app/ui/primitives/file-upload-item/file-upload-item.component.spec.ts (1 test) 321ms + ✓ FileUploadItemComponent > should create 319ms + ✓ projects/core/src/lib/interceptors/camelcase.interceptor.spec.ts (6 tests) 127ms + ✓ projects/social_platform/src/app/ui/primitives/switch/switch.component.spec.ts (4 tests) 226ms + ✓ projects/social_platform/src/app/ui/pages/projects/bar-new/bar.component.spec.ts (1 test) 332ms + ✓ BarNewComponent > should create 330ms + ✓ projects/ui/src/lib/components/primitives/avatar/avatar.component.spec.ts (6 tests) 421ms + ✓ AvatarComponent > should create 320ms + ✓ projects/social_platform/src/app/ui/pages/office/snackbar/snackbar.component.spec.ts (1 test) 225ms + ✓ projects/ui/src/lib/components/primitives/back/back.component.spec.ts (1 test) 263ms + ✓ projects/social_platform/src/app/api/member/facades/members-info.service.spec.ts (16 tests) 277ms + ✓ projects/social_platform/src/app/ui/pages/auth/email-verification/email-verification.component.spec.ts (1 test) 249ms + ✓ projects/social_platform/src/app/infrastructure/repository/program/program.repository.spec.ts (30 tests) 272ms + ✓ projects/ui/src/lib/components/primitives/icon/icon.component.spec.ts (5 tests) 259ms + ✓ projects/social_platform/src/app/ui/primitives/search/search.component.spec.ts (2 tests) 230ms + ✓ projects/social_platform/src/app/ui/pages/onboarding/onboarding.component.spec.ts (1 test) 208ms + ✓ projects/social_platform/src/app/api/project/facades/edit/project-form-autosave.service.spec.ts (24 tests) 221ms + ✓ projects/social_platform/src/app/ui/pages/error/error-code/error-code.component.spec.ts (1 test) 197ms + ✓ projects/social_platform/src/app/ui/pages/courses/lesson/shared/exclude-task/exclude-task.component.spec.ts (1 test) 278ms + ✓ projects/social_platform/src/app/api/program/facades/detail/program-analytics-info.service.spec.ts (15 tests) 146ms + ✓ projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.spec.ts (13 tests) 217ms + ✓ projects/social_platform/src/app/ui/primitives/loader/loader.component.spec.ts (4 tests) 179ms + ✓ projects/social_platform/src/app/ui/primitives/button/button.component.spec.ts (6 tests) 373ms + ✓ projects/social_platform/src/app/ui/pages/courses/detail/info/course-module-card/circle-progress-bar/circle-progress-bar.component.spec.ts (1 test) 389ms + ✓ CircleProgressBarComponent > should create 383ms + ✓ projects/social_platform/src/app/infrastructure/adapters/project/project-collaborators-http.adapter.spec.ts (3 tests) 63ms + ✓ projects/social_platform/src/app/infrastructure/repository/project/project-goals.repository.spec.ts (4 tests) 86ms + ✓ projects/social_platform/src/app/ui/primitives/img-card/img-card.component.spec.ts (1 test) 203ms + ✓ projects/core/src/lib/services/error/error.service.spec.ts (1 test) 53ms + ✓ projects/social_platform/src/app/api/program/use-cases/get-program-manager-overview.use-case.spec.ts (2 tests) 84ms + ✓ projects/ui/src/lib/components/layout/sidebar/sidebar.component.spec.ts (1 test) 298ms + ✓ projects/social_platform/src/app/ui/primitives/icon/icon.component.spec.ts (5 tests) 352ms + ✓ projects/social_platform/src/app/api/program/facades/detail/program-role-widget.service.spec.ts (11 tests) 194ms + ✓ projects/ui/src/lib/components/primitives/button/button-states.spec.ts (2 tests) 281ms + ✓ projects/social_platform/src/app/api/program/use-cases/get-all-members.use-case.spec.ts (3 tests) 58ms + ✓ projects/social_platform/src/app/api/vacancy/facades/vacancy-detail-info.service.spec.ts (17 tests) 225ms + ✓ projects/social_platform/src/app/infrastructure/repository/auth/auth.repository.spec.ts (17 tests) 209ms + ✓ projects/social_platform/src/app/ui/primitives/checkbox/checkbox.component.spec.ts (5 tests) 298ms + ✓ projects/ui/src/lib/components/layout/profile-info/profile-info.component.spec.ts (1 test) 241ms + ✓ projects/social_platform/src/app/api/project/facades/edit/ui/project-team-ui.service.spec.ts (2 tests) 78ms + ✓ projects/social_platform/src/app/ui/pages/auth/confirm-password-reset/confirm-password-reset.component.spec.ts (1 test) 266ms + ✓ projects/social_platform/src/app/infrastructure/adapters/program/program-http.adapter.spec.ts (22 tests) 188ms + ✓ projects/social_platform/src/app/ui/primitives/tag/tag.component.spec.ts (1 test) 228ms + ✓ projects/social_platform/src/app/ui/pages/onboarding/stage-three/user-type-card/user-type-card.component.spec.ts (1 test) 193ms + ✓ projects/social_platform/src/app/api/chat/use-cases/observe-edit-message.use-case.spec.ts (2 tests) 65ms + ✓ projects/social_platform/src/app/api/kanban/use-cases/get-board.use-case.spec.ts (4 tests) 84ms + ✓ projects/social_platform/src/app/ui/pages/auth/confirm-email/confirm-email.component.spec.ts (1 test) 478ms + ✓ ConfirmEmailComponent > should create 473ms + ✓ projects/social_platform/src/app/ui/pages/error/error.component.spec.ts (1 test) 164ms + ✓ projects/social_platform/src/app/infrastructure/adapters/auth/auth-http.adapter.spec.ts (24 tests) 284ms + ✓ projects/social_platform/src/app/ui/widgets/detail/services/profile/detail-profile-invite.spec.ts (9 tests) 143ms + ✓ projects/social_platform/src/app/api/project/facades/edit/ui/project-vacancy-ui.service.spec.ts (17 tests) 232ms + ✓ projects/social_platform/src/app/api/program/use-cases/get-program-manager-attention.use-case.spec.ts (23 tests) 231ms + ✓ projects/core/src/lib/services/websockets/websocket.service.spec.ts (1 test) 42ms + ✓ projects/social_platform/src/app/infrastructure/repository/project/project.repository.spec.ts (21 tests) 322ms + ✓ projects/social_platform/src/app/ui/primitives/file-item/file-item.component.spec.ts (1 test) 292ms + ✓ projects/social_platform/src/app/api/vacancy/use-cases/send-vacancy-response.use-case.spec.ts (4 tests) 106ms + ✓ projects/social_platform/src/app/api/project/use-cases/get-project.use-case.spec.ts (3 tests) 63ms + ✓ projects/social_platform/src/app/api/project/facades/edit/project-team.service.spec.ts (19 tests) 243ms + ✓ projects/social_platform/src/app/api/chat/use-cases/observe-typing.use-case.spec.ts (2 tests) 42ms + ✓ projects/social_platform/src/app/api/vacancy/use-cases/get-vacancy-detail.use-case.spec.ts (3 tests) 64ms + ✓ projects/social_platform/src/app/ui/pages/error/not-found/error-not-found.component.spec.ts (1 test) 123ms + ✓ projects/social_platform/src/app/api/chat/use-cases/observe-set-online.use-case.spec.ts (2 tests) 83ms + ✓ projects/social_platform/src/app/ui/widgets/detail/services/program/detail-program-info.service.spec.ts (15 tests) 163ms + ✓ projects/social_platform/src/app/api/program/use-cases/get-program-role-widget.use-case.spec.ts (7 tests) 139ms + ✓ projects/social_platform/src/app/api/profile/use-cases/delete-profile-news.use-case.spec.ts (3 tests) 67ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/detail.resolver.spec.ts (10 tests) 104ms + ✓ projects/social_platform/src/app/api/profile/use-cases/fetch-profile-news.use-case.spec.ts (3 tests) 51ms + ✓ projects/social_platform/src/app/api/project/use-cases/get-project-resources.use-case.spec.ts (3 tests) 64ms + ✓ projects/social_platform/src/app/ui/pages/chat/chat-direct/chat-direct.resolver.spec.ts (1 test) 50ms + ✓ projects/social_platform/src/app/api/project/use-cases/add-project-subscription.use-case.spec.ts (3 tests) 84ms + ✓ projects/social_platform/src/app/api/invite/use-cases/reject-invite.use-case.spec.ts (3 tests) 123ms + ✓ projects/social_platform/src/app/infrastructure/repository/invite/invite.repository.spec.ts (9 tests) 218ms + ✓ projects/social_platform/src/app/api/program/use-cases/get-all-projects.use-case.spec.ts (3 tests) 59ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/services/rating-card.service.spec.ts (9 tests) 122ms + ✓ projects/social_platform/src/app/api/profile/facades/edit/profile-edit-info.service.spec.ts (4 tests) 258ms + ✓ projects/social_platform/src/app/infrastructure/repository/vacancy/vacancy.repository.spec.ts (16 tests) 257ms + ✓ projects/social_platform/src/app/api/onboarding/facades/stages/onboarding-stage-zero-info.service.spec.ts (7 tests) 189ms + ✓ projects/social_platform/src/app/infrastructure/repository/skills/skills.repository.spec.ts (2 tests) 86ms + ✓ projects/social_platform/src/app/ui/pages/auth/auth.component.spec.ts (1 test) 144ms + ✓ projects/social_platform/src/app/api/project/facades/edit/project-form.factory.spec.ts (4 tests) 31ms + ✓ projects/social_platform/src/app/api/project/use-cases/reset-project-cover.use-case.spec.ts (13 tests) 130ms + ✓ projects/social_platform/src/app/api/profile/use-cases/save-profile.use-case.spec.ts (3 tests) 207ms + ✓ projects/social_platform/src/app/ui/pages/office/snackbar/animation/animation.service.spec.ts (1 test) 45ms + ✓ projects/social_platform/src/app/api/program/use-cases/program-case-projects.use-case.spec.ts (15 tests) 147ms + ✓ projects/social_platform/src/app/api/project/use-cases/program-link-fields.use-cases.spec.ts (15 tests) 552ms + ✓ projects/social_platform/src/app/api/invite/use-cases/accept-invite.use-case.spec.ts (3 tests) 422ms + ✓ AcceptInviteUseCase > делегирует inviteId в репозиторий и эмитит событие 341ms + ✓ projects/social_platform/src/app/api/program/use-cases/get-programs.use-case.spec.ts (3 tests) 138ms + ✓ projects/social_platform/src/app/api/project/use-cases/create-project.use-case.spec.ts (3 tests) 117ms + ✓ projects/social_platform/src/app/api/invite/mappers/map-invite-send-error.spec.ts (24 tests) 102ms + ✓ projects/social_platform/src/app/api/program/facades/detail/program-case-projects.service.spec.ts (11 tests) 134ms + ✓ projects/social_platform/src/app/api/program/facades/detail/program-analytics-drilldown.service.spec.ts (10 tests) 154ms + ✓ projects/social_platform/src/app/api/project/use-cases/delete-project.use-case.spec.ts (3 tests) 85ms + ✓ projects/social_platform/src/app/infrastructure/adapters/chat/chat-ws.adapter.spec.ts (14 tests) 172ms + ✓ projects/social_platform/src/app/infrastructure/adapters/profile/profile-news-http.adapter.spec.ts (7 tests) 80ms + ✓ projects/social_platform/src/app/api/auth/use-cases/update-profile.use-case.spec.ts (3 tests) 69ms + ✓ projects/social_platform/src/app/infrastructure/adapters/member/member-statistics-contract.spec.ts (6 tests) 102ms + ✓ projects/social_platform/src/app/api/vacancy/use-cases/reject-response.use-case.spec.ts (3 tests) 77ms + ✓ projects/social_platform/src/app/api/program/use-cases/delete-news.use-case.spec.ts (3 tests) 90ms + ✓ projects/social_platform/src/app/api/project/use-cases/submit-competitive-project.use-case.spec.ts (3 tests) 79ms + ✓ projects/social_platform/src/app/api/feed/use-cases/read-feed-news.use-case.spec.ts (4 tests) 162ms + ✓ projects/core/src/lib/services/error/global-error-handler.service.spec.ts (1 test) 220ms + ✓ projects/social_platform/src/app/infrastructure/adapters/chat/chat-http.adapter.spec.ts (4 tests) 86ms + ✓ projects/social_platform/src/app/infrastructure/repository/project/project-collaborators.repository.spec.ts (3 tests) 70ms + ✓ projects/social_platform/src/app/api/auth/auth.service.spec.ts (1 test) 65ms + ✓ projects/social_platform/src/app/infrastructure/adapters/project/project-rating-http.adapter.spec.ts (4 tests) 154ms + ✓ projects/social_platform/src/app/api/member/facades/member-statistics.facade.spec.ts (5 tests) 569ms + ✓ Состояние глобальной статистики участников > остаётся loading до ответа и выполняет только один запрос за жизнь страницы 439ms + ✓ projects/social_platform/src/app/api/project/facades/projects-info.service.spec.ts (3 tests) 421ms + ✓ ProjectsInfoService: загрузка активности > запрашивает count при входе на /office/projects/dashboard 347ms + ✓ projects/social_platform/src/app/infrastructure/repository/project/project-rating.repository.spec.ts (6 tests) 107ms + ✓ projects/social_platform/src/app/infrastructure/adapters/project/project-program-http.adapter.spec.ts (3 tests) 65ms + ✓ projects/social_platform/src/app/api/project/facades/edit/project-contacts.service.spec.ts (3 tests) 111ms + ✓ projects/social_platform/src/app/infrastructure/adapters/program/program-case-http.integration.spec.ts (2 tests) 99ms + ✓ projects/core/src/lib/interceptors/bearer-token.interceptor.spec.ts (1 test) 49ms + ✓ projects/social_platform/src/app/ui/pages/projects/list/my.resolver.spec.ts (1 test) 68ms + ✓ projects/social_platform/src/app/api/project/use-cases/update-form.use-case.spec.ts (3 tests) 302ms + ✓ projects/social_platform/src/app/infrastructure/repository/project/project-news.repository.spec.ts (8 tests) 347ms + ✓ projects/social_platform/src/app/api/vacancy/use-cases/update-vacancy.use-case.spec.ts (3 tests) 73ms + ✓ projects/social_platform/src/app/infrastructure/repository/program/program-news.repository.spec.ts (6 tests) 110ms + ✓ projects/social_platform/src/app/api/project/use-cases/get-project-subscriptions.use-case.spec.ts (3 tests) 75ms + ✓ projects/social_platform/src/app/api/vacancy/use-cases/get-project-responses.use-case.spec.ts (3 tests) 209ms + ✓ projects/social_platform/src/app/ui/pages/chat/chat-groups.resolver.spec.ts (1 test) 32ms + ✓ projects/social_platform/src/app/api/project/use-cases/get-project-goals.use-case.spec.ts (3 tests) 70ms + ✓ projects/social_platform/src/app/api/courses/use-cases/get-course-lesson.use-case.spec.ts (3 tests) 68ms + ✓ projects/social_platform/src/app/api/profile/use-cases/toggle-profile-news-like.use-case.spec.ts (3 tests) 194ms + ✓ projects/social_platform/src/app/api/feed/use-cases/toggle-feed-like.use-case.spec.ts (4 tests) 147ms + ✓ projects/social_platform/src/app/api/invite/use-cases/update-invite.use-case.spec.ts (3 tests) 60ms + ✓ projects/social_platform/src/app/api/invite/use-cases/get-my-invites.use-case.spec.ts (3 tests) 149ms + ✓ projects/social_platform/src/app/infrastructure/repository/profile/profile-news.repository.spec.ts (8 tests) 209ms + ✓ projects/social_platform/src/app/api/program/use-cases/assign-project-program.spec.ts (3 tests) 96ms + ✓ projects/social_platform/src/app/infrastructure/repository/project/project-program.repository.spec.ts (5 tests) 75ms + ✓ projects/social_platform/src/app/infrastructure/repository/specializations/specializations.repository.spec.ts (2 tests) 47ms + ✓ projects/social_platform/src/app/api/profile/use-cases/read-profile-news.use-case.spec.ts (3 tests) 98ms + ✓ projects/social_platform/src/app/api/project/use-cases/create-resource.use-case.spec.ts (3 tests) 149ms + ✓ projects/social_platform/src/app/infrastructure/repository/member/member.repository.spec.ts (1 test) 94ms + ✓ projects/social_platform/src/app/api/project/use-cases/delete-project-subscription.use-case.spec.ts (3 tests) 79ms + ✓ projects/social_platform/src/app/api/project/use-cases/get-my-projects.use-case.spec.ts (3 tests) 180ms + ✓ projects/social_platform/src/app/api/chat/use-cases/observe-set-offline.use-case.spec.ts (2 tests) 45ms + ✓ projects/social_platform/src/app/api/program/program-widget-refresh.spec.ts (8 tests) 112ms + ✓ projects/social_platform/src/app/infrastructure/repository/chat/chat-realtime.repository.spec.ts (3 tests) 127ms + ✓ projects/social_platform/src/app/ui/pages/projects/detail/news-detail/news-detail.resolver.spec.ts (1 test) 77ms + ✓ projects/social_platform/src/app/api/program/use-cases/register-program.use-case.spec.ts (3 tests) 63ms + ✓ projects/social_platform/src/app/api/chat/use-cases/observe-messages.use-case.spec.ts (2 tests) 92ms + ✓ projects/social_platform/src/app/infrastructure/repository/industry/industry.repository.spec.ts (3 tests) 106ms + ✓ projects/social_platform/src/app/api/project/use-cases/get-project-subscribers.use-case.spec.ts (3 tests) 95ms + ✓ projects/social_platform/src/app/api/program/use-cases/get-program-filters.use-case.spec.ts (3 tests) 61ms + ✓ projects/social_platform/src/app/infrastructure/adapters/project/project-news-http.adapter.spec.ts (7 tests) 209ms + ✓ projects/social_platform/src/app/api/program/use-cases/create-program-filters.use-case.spec.ts (3 tests) 113ms + ✓ projects/social_platform/src/app/api/project/use-cases/read-project-news.use-case.spec.ts (3 tests) 96ms + ✓ projects/social_platform/src/app/api/invite/facades/invite-participant-search.facade.spec.ts (4 tests) 104ms + ✓ projects/social_platform/src/app/api/invite/use-cases/send-for-user.use-case.spec.ts (3 tests) 81ms + ✓ projects/social_platform/src/app/api/program/use-cases/participating-program.use-case.spec.ts (3 tests) 94ms + ✓ projects/social_platform/src/app/infrastructure/adapters/program/program-news-http.adapter.spec.ts (6 tests) 149ms + ✓ projects/social_platform/src/app/ui/pages/projects/detail/info/info.resolver.spec.ts (1 test) 54ms + ✓ projects/social_platform/src/app/api/program/facades/detail/ui/program-detail-main-ui-info.service.spec.ts (13 tests) 76ms + ✓ projects/social_platform/src/app/infrastructure/repository/courses/courses.repository.spec.ts (5 tests) 94ms + ✓ projects/social_platform/src/app/infrastructure/adapters/member/member-http.adapter.spec.ts (2 tests) 88ms + ✓ projects/social_platform/src/app/ui/pages/projects/projects-activity-placement.spec.ts (4 tests) 9ms + ✓ projects/social_platform/src/app/infrastructure/adapters/project/project-http.adapter.spec.ts (8 tests) 218ms + ✓ projects/social_platform/src/app/api/project/use-cases/fetch-project-news.use-case.spec.ts (3 tests) 72ms + ✓ projects/social_platform/src/app/api/auth/use-cases/login.use-case.spec.ts (4 tests) 137ms + ✓ projects/social_platform/src/app/api/project/use-cases/create-goals.use-case.spec.ts (3 tests) 67ms + ✓ projects/social_platform/src/app/api/skills/use-cases/search-skills.use-case.spec.ts (3 tests) 111ms + ✓ projects/social_platform/src/app/api/project/use-cases/transfer-project-ownership.use-case.spec.ts (3 tests) 82ms + ✓ projects/social_platform/src/app/api/vacancy/use-cases/post-vacancy.use-case.spec.ts (3 tests) 104ms + ✓ projects/social_platform/src/app/api/vacancy/facades/vacancy-info.service.spec.ts (4 tests) 130ms + ✓ projects/social_platform/src/app/api/chat/use-cases/start-typing.use-case.spec.ts (1 test) 114ms + ✓ projects/social_platform/src/app/api/program/use-cases/get-program-manager-assignments.use-case.spec.ts (6 tests) 295ms + ✓ projects/social_platform/src/app/api/feed/use-cases/fetch-feed.use-case.spec.ts (3 tests) 271ms + ✓ projects/social_platform/src/app/infrastructure/repository/project/project-subscription.repository.spec.ts (4 tests) 87ms + ✓ projects/social_platform/src/app/api/program/use-cases/rate-project.use-case.spec.ts (3 tests) 113ms + ✓ projects/social_platform/src/app/ui/pages/projects/edit/edit.resolver.spec.ts (1 test) 202ms + ✓ projects/social_platform/src/app/infrastructure/adapters/vacancy/vacancy-http.adapter.spec.ts (5 tests) 277ms + ✓ projects/social_platform/src/app/domain/shared/entity-cache.spec.ts (11 tests) 45ms + ✓ projects/social_platform/src/app/api/program/facades/detail/program-detail-main-info.service.spec.ts (3 tests) 141ms + ✓ projects/social_platform/src/app/infrastructure/repository/project/project-partner.repository.spec.ts (4 tests) 447ms + ✓ projects/core/src/consts/lists/russian-regions-list.const.spec.ts (7 tests) 80ms + ✓ projects/social_platform/src/app/api/program/use-cases/filter-project-ratings.use-case.spec.ts (3 tests) 75ms + ✓ projects/social_platform/src/app/ui/widgets/detail/services/detail-info.service.spec.ts (1 test) 83ms + ✓ projects/social_platform/src/app/api/onboarding/facades/stages/ui/onboarding-stage-one-ui-info.service.spec.ts (1 test) 53ms + ✓ projects/social_platform/src/app/api/courses/facades/ui/course-detail-ui-info.service.spec.ts (5 tests) 86ms + ✓ projects/social_platform/src/app/api/chat/use-cases/load-project-files.use-case.spec.ts (3 tests) 56ms + ✓ projects/social_platform/src/app/api/chat/use-cases/connect-chat.use-case.spec.ts (1 test) 98ms + ✓ projects/social_platform/src/app/api/courses/use-cases/get-courses.use-case.spec.ts (3 tests) 66ms + ✓ projects/social_platform/src/app/infrastructure/adapters/feed/feed-http.adapter.spec.ts (1 test) 41ms + ✓ projects/social_platform/src/app/infrastructure/adapters/skills/skills-http.adapter.spec.ts (2 tests) 63ms + ✓ projects/social_platform/src/app/infrastructure/adapters/invite/invite-http.adapter.spec.ts (7 tests) 292ms + ✓ projects/social_platform/src/app/infrastructure/adapters/subscription/subscription-http.adapter.spec.ts (4 tests) 92ms + ✓ projects/social_platform/src/app/infrastructure/adapters/courses/courses-http.adapter.spec.ts (5 tests) 99ms + ✓ projects/social_platform/src/app/api/chat/use-cases/check-unreads.use-case.spec.ts (3 tests) 200ms + ✓ projects/social_platform/src/app/api/project/use-cases/get-project-partners.use-case.spec.ts (3 tests) 80ms + ✓ projects/social_platform/src/app/api/program/use-cases/get-project-ratings.use-case.spec.ts (3 tests) 250ms + ✓ projects/social_platform/src/app/api/auth/use-cases/reset-password.use-case.spec.ts (3 tests) 158ms + ✓ projects/social_platform/src/app/infrastructure/adapters/project/project-count-contract.spec.ts (1 test) 67ms + ✓ projects/core/src/lib/services/validation/validation.service.spec.ts (1 test) 50ms + ✓ projects/social_platform/src/app/api/chat/use-cases/load-messages.use-case.spec.ts (3 tests) 83ms + ✓ projects/social_platform/src/app/api/program/use-cases/toggle-like.use-case.spec.ts (3 tests) 193ms + ✓ projects/social_platform/src/app/ui/pages/chat/chat.resolver.spec.ts (1 test) 50ms + ✓ projects/social_platform/src/app/ui/primitives/modal/modal.service.spec.ts (1 test) 123ms + ✓ projects/social_platform/src/app/infrastructure/adapters/project/project-cover-contract.spec.ts (3 tests) 241ms + ✓ projects/social_platform/src/app/api/profile/use-cases/add-profile-news.use-case.spec.ts (3 tests) 238ms + ✓ projects/social_platform/src/app/api/kanban/use-cases/get-task.use-case.spec.ts (4 tests) 92ms + ✓ projects/social_platform/src/app/api/courses/use-cases/get-course-structure.use-case.spec.ts (3 tests) 87ms + ✓ projects/social_platform/src/app/api/project/use-cases/delete-partner.use-case.spec.ts (3 tests) 146ms + ✓ projects/social_platform/src/app/api/auth/use-cases/download-cv.use-case.spec.ts (3 tests) 71ms + ✓ projects/social_platform/src/app/infrastructure/adapters/project/project-resource-http.adapter.spec.ts (4 tests) 133ms + ✓ projects/social_platform/src/app/infrastructure/repository/project/project-resource.repository.spec.ts (4 tests) 83ms + ✓ projects/social_platform/src/app/api/project/use-cases/delete-project-news.use-case.spec.ts (3 tests) 228ms + ✓ projects/social_platform/src/app/api/program/use-cases/read-news.use-case.spec.ts (3 tests) 94ms + ✓ projects/social_platform/src/app/api/project/use-cases/update-resource.use-case.spec.ts (3 tests) 265ms + ✓ projects/social_platform/src/app/api/project/use-cases/get-project-news-detail.use-case.spec.ts (3 tests) 97ms + ✓ projects/social_platform/src/app/api/courses/use-cases/get-course-detail.use-case.spec.ts (3 tests) 199ms + ✓ projects/core/src/lib/guards/auth/auth-required.guard.spec.ts (1 test) 89ms + ✓ projects/social_platform/src/app/api/invite/use-cases/get-project-invites.use-case.spec.ts (3 tests) 109ms + ✓ projects/core/src/lib/services/tokens/token.service.spec.ts (1 test) 57ms + ✓ projects/social_platform/src/app/infrastructure/repository/chat/chat.repository.spec.ts (3 tests) 104ms + ✓ projects/social_platform/src/app/api/courses/use-cases/submit-task-answer.use-case.spec.ts (3 tests) 95ms + ✓ projects/social_platform/src/app/api/project/use-cases/edit-project-news.use-case.spec.ts (3 tests) 223ms + ✓ projects/social_platform/src/app/ui/pages/projects/detail/chat/chat.resolver.spec.ts (1 test) 130ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/list/program-projects-filter/service/program-projects-filter-info.service.spec.ts (1 test) 62ms + ✓ projects/social_platform/src/app/api/chat/use-cases/send-message.use-case.spec.ts (1 test) 305ms + ✓ projects/social_platform/src/app/api/program/program-widget-presentation.spec.ts (30 tests) 84ms + ✓ projects/social_platform/src/app/infrastructure/repository/feed/feed.repository.spec.ts (1 test) 71ms + ✓ projects/social_platform/src/app/api/vacancy/use-cases/get-my-vacancies.use-case.spec.ts (3 tests) 213ms + ✓ projects/social_platform/src/app/api/auth/use-cases/resend-email.use-case.spec.ts (3 tests) 88ms + ✓ projects/social_platform/src/app/api/project/use-cases/delete-goal.use-case.spec.ts (3 tests) 269ms + ✓ projects/social_platform/src/app/infrastructure/adapters/project/project-partner-http.adapter.spec.ts (4 tests) 117ms + ✓ projects/social_platform/src/app/ui/pages/projects/projects.resolver.spec.ts (2 tests) 419ms + ✓ projects/social_platform/src/app/api/project/use-cases/toggle-project-news-like.use-case.spec.ts (3 tests) 353ms + ✓ projects/social_platform/src/app/api/project/use-cases/delete-resource.use-case.spec.ts (3 tests) 72ms + ✓ projects/social_platform/src/app/api/program/use-cases/get-program-data-schema.use-case.spec.ts (3 tests) 64ms + ✓ projects/social_platform/src/app/api/program/use-cases/edit-news.use-case.spec.ts (3 tests) 74ms + ✓ projects/social_platform/src/app/api/program/use-cases/get-program.use-case.spec.ts (3 tests) 115ms + ✓ projects/social_platform/src/app/api/kanban/use-cases/get-column-tasks.use-case.spec.ts (3 tests) 392ms + ✓ projects/social_platform/src/app/api/member/use-cases/get-members.use-case.spec.ts (4 tests) 469ms + ✓ GetMembersUseCase > делегирует вызов с skip/take/params 437ms + ✓ projects/social_platform/src/app/api/program/use-cases/fetch-news.use-case.spec.ts (3 tests) 209ms + ✓ projects/social_platform/src/app/ui/services/notification/notification.service.spec.ts (1 test) 89ms + ✓ projects/social_platform/src/app/api/project/use-cases/update-goal.use-case.spec.ts (3 tests) 119ms + ✓ projects/social_platform/src/app/api/vacancy/use-cases/accept-response.use-case.spec.ts (3 tests) 362ms + ✓ projects/social_platform/src/app/api/member/member-filters.spec.ts (10 tests) 145ms + ✓ projects/social_platform/src/app/ui/pages/projects/list/all.resolver.spec.ts (1 test) 51ms + ✓ projects/social_platform/src/app/api/program/use-cases/apply-project-to-program.use-case.spec.ts (3 tests) 326ms + ✓ projects/social_platform/src/app/api/auth/use-cases/set-password.use-case.spec.ts (3 tests) 248ms + ✓ projects/social_platform/src/app/api/chat/use-cases/edit-message.use-case.spec.ts (1 test) 215ms + ✓ projects/social_platform/src/app/api/skills/use-cases/get-skills-nested.use-case.spec.ts (3 tests) 158ms + ✓ projects/social_platform/src/app/api/chat/use-cases/observe-read-message.use-case.spec.ts (2 tests) 107ms + ✓ projects/social_platform/src/app/api/program/use-cases/add-news.use-case.spec.ts (3 tests) 82ms + ✓ projects/social_platform/src/app/api/project/use-cases/add-project-news.use-case.spec.ts (3 tests) 116ms + ✓ projects/social_platform/src/app/api/onboarding/onboarding.service.spec.ts (1 test) 42ms + ✓ projects/social_platform/src/app/api/profile/use-cases/edit-profile-news.use-case.spec.ts (3 tests) 228ms + ✓ projects/social_platform/src/app/infrastructure/adapters/specializations/specializations-http.adapter.spec.ts (2 tests) 62ms + ✓ projects/social_platform/src/app/api/project/use-cases/leave-project.use-case.spec.ts (3 tests) 296ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/register/register.resolver.spec.ts (1 test) 39ms + ✓ projects/social_platform/src/app/api/chat/use-cases/delete-message.use-case.spec.ts (1 test) 288ms + ✓ projects/social_platform/src/app/api/project/use-cases/get-all-projects.use-case.spec.ts (3 tests) 343ms + ✓ projects/social_platform/src/app/infrastructure/adapters/industry/industry-http.adapter.spec.ts (1 test) 140ms + ✓ projects/social_platform/src/app/api/chat/use-cases/observe-delete-message.use-case.spec.ts (2 tests) 206ms + ✓ projects/core/src/lib/services/file/file.service.spec.ts (1 test) 182ms + ✓ projects/core/src/lib/services/api/api.service.spec.ts (1 test) 45ms + ✓ projects/social_platform/src/app/api/profile/facades/edit/profile-save-error.utils.spec.ts (5 tests) 17ms + ✓ projects/social_platform/src/app/api/chat/use-cases/read-message.use-case.spec.ts (1 test) 42ms + ✓ projects/social_platform/src/app/api/vacancy/use-cases/delete-vacancy.use-case.spec.ts (3 tests) 229ms + ✓ projects/social_platform/src/app/domain/invite/invite-candidates.spec.ts (2 tests) 23ms + ✓ projects/social_platform/src/app/api/profile/facades/detail/ui/profile-detail-ui-info.service.spec.ts (4 tests) 20ms + ✓ projects/social_platform/src/app/api/feed/facades/ui/feed-ui-info.service.spec.ts (1 test) 16ms + ✓ projects/social_platform/src/app/api/profile/facades/edit/profile-edit-validation.utils.spec.ts (9 tests) 111ms + ✓ projects/social_platform/src/app/infrastructure/adapters/courses/local-storage-seen-modules.adapter.spec.ts (4 tests) 18ms + ✓ projects/core/src/lib/pipes/formatters/parse-breaks.pipe.spec.ts (1 test) 10ms + ✓ projects/core/src/lib/pipes/formatters/years-from-birthday.pipe.spec.ts (1 test) 6ms + ✓ projects/social_platform/src/app/utils/program-case-analytics.spec.ts (14 tests) 54ms + ✓ projects/core/src/lib/pipes/formatters/parse-links.pipe.spec.ts (1 test) 14ms + ✓ projects/social_platform/src/app/api/vacancy/vacancy-response-error.spec.ts (8 tests) 16ms + ✓ projects/core/src/lib/pipes/user/user-role.pipe.spec.ts (1 test) 10ms + ✓ projects/core/src/lib/pipes/controls/control-error.pipe.spec.ts (1 test) 6ms + ✓ projects/core/src/lib/pipes/transformers/link-transform.pipe.spec.ts (1 test) 14ms + ✓ projects/social_platform/src/app/api/project/facades/detail/ui/projects-detail-ui.service.spec.ts (1 test) 8ms + ✓ projects/core/src/lib/pipes/formatters/pluralize.pipe.spec.ts (1 test) 6ms + ✓ projects/social_platform/src/app/utils/program-analytics-assignment.spec.ts (9 tests) 26ms + ✓ projects/core/src/lib/pipes/transformers/salary-trasform.pipe.spec.ts (1 test) 10ms + ✓ projects/core/src/lib/pipes/controls/form-control.pipe.spec.ts (1 test) 10ms + ✓ projects/core/src/lib/pipes/formatters/dayjs.pipe.spec.ts (1 test) 14ms + ✓ projects/core/src/lib/pipes/user/user-links.pipe.spec.ts (1 test) 8ms + ✓ projects/social_platform/src/app/ui/pipes/file-type.pipe.spec.ts (1 test) 7ms + ✓ projects/social_platform/src/app/ui/routes/program/detail.routes.spec.ts (2 tests) 6ms + ✓ projects/social_platform/src/app/utils/export-regions.spec.ts (3 tests) 13ms + + Test Files 406 passed (406) + Tests 2006 passed (2006) + Start at 15:22:42 + Duration 136.04s (transform 45.00s, setup 747.86s, collect 367.88s, tests 170.23s, environment 49.86s, prepare 154.39s) diff --git a/docs/desktop-regression/visual.log b/docs/desktop-regression/visual.log new file mode 100644 index 000000000..5a4118ef6 --- /dev/null +++ b/docs/desktop-regression/visual.log @@ -0,0 +1,230 @@ +desktop-after: feed 1440 +desktop-after: projects 1440 +desktop-after: my-projects 1440 +desktop-after: members 1440 +desktop-after: programs 1440 +desktop-after: program 1440 +desktop-after: profile 1440 +desktop-after: project 1440 +desktop-after: vacancies 1440 +desktop-after: vacancy 1440 +desktop-after: courses 1440 +desktop-after: course 1440 +desktop-after: feed 1920 +desktop-after: projects 1920 +desktop-after: my-projects 1920 +desktop-after: members 1920 +desktop-after: programs 1920 +desktop-after: program 1920 +desktop-after: profile 1920 +desktop-after: project 1920 +desktop-after: vacancies 1920 +desktop-after: vacancy 1920 +desktop-after: courses 1920 +desktop-after: course 1920 +desktop-after: empty-feed 1440 +desktop-after: empty-vacancies 1440 +desktop-after: empty-courses 1440 +desktop-after: empty-feed 1920 +desktop-after: empty-vacancies 1920 +desktop-after: empty-courses 1920 +desktop-after: profile-edit 1440 +desktop-after: project-edit 1440 +desktop-after: profile-edit 1920 +desktop-after: project-edit 1920 +desktop-after: loading-action 1440 +desktop-after: loading-action 1920 +mobile-after: feed 320 +mobile-after: projects 320 +mobile-after: my-projects 320 +mobile-after: members 320 +mobile-after: programs 320 +mobile-after: program 320 +mobile-after: profile 320 +mobile-after: project 320 +mobile-after: vacancies 320 +mobile-after: vacancy 320 +mobile-after: courses 320 +mobile-after: course 320 +mobile-after: feed 390 +mobile-after: projects 390 +mobile-after: my-projects 390 +mobile-after: members 390 +mobile-after: programs 390 +mobile-after: program 390 +mobile-after: profile 390 +mobile-after: project 390 +mobile-after: vacancies 390 +mobile-after: vacancy 390 +mobile-after: courses 390 +mobile-after: course 390 +mobile-after: feed 768 +mobile-after: projects 768 +mobile-after: my-projects 768 +mobile-after: members 768 +mobile-after: programs 768 +mobile-after: program 768 +mobile-after: profile 768 +mobile-after: project 768 +mobile-after: vacancies 768 +mobile-after: vacancy 768 +mobile-after: courses 768 +mobile-after: course 768 +mobile-after: profile-edit 320 +mobile-after: project-edit 320 +mobile-after: profile-edit 390 +mobile-after: project-edit 390 +mobile-after: profile-edit 768 +mobile-after: project-edit 768 +PASS course-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS course-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS courses-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS courses-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS empty-courses-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS empty-courses-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS empty-feed-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS empty-feed-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS empty-vacancies-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS empty-vacancies-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS feed-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS feed-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +FAIL loading-action-1440: exact=1027px; delta>8=0.0812% (1440, 844) -> (1440, 844) bbox=[905, 733, 1237, 758] +FAIL loading-action-1920: exact=1027px; delta>8=0.0609% (1920, 844) -> (1920, 844) bbox=[1443, 733, 1775, 758] +PASS members-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS members-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS my-projects-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS my-projects-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS profile-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS profile-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS profile-edit-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS profile-edit-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS program-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS program-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS programs-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS programs-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS project-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS project-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS project-edit-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS project-edit-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS projects-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS projects-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS vacancies-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS vacancies-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS vacancy-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS vacancy-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +desktop-after: loading-action 1440 +desktop-after: loading-action 1920 +PASS course-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS course-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS courses-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS courses-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS empty-courses-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS empty-courses-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS empty-feed-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS empty-feed-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS empty-vacancies-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS empty-vacancies-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS feed-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS feed-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS loading-action-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS loading-action-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS members-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS members-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS my-projects-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS my-projects-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS profile-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS profile-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS profile-edit-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS profile-edit-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS program-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS program-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS programs-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS programs-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS project-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS project-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS project-edit-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS project-edit-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS projects-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS projects-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS vacancies-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS vacancies-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS vacancy-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS vacancy-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS course-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS course-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS courses-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS courses-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS empty-courses-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS empty-courses-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS empty-feed-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS empty-feed-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS empty-vacancies-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS empty-vacancies-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS feed-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS feed-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS loading-action-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS loading-action-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS members-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS members-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS my-projects-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS my-projects-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS profile-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS profile-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS profile-edit-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS profile-edit-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS program-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS program-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS programs-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS programs-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS project-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS project-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS project-edit-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS project-edit-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS projects-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS projects-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS vacancies-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS vacancies-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS vacancy-1440: exact=0px; delta>8=0.0000% (1440, 844) -> (1440, 844) bbox=None +PASS vacancy-1920: exact=0px; delta>8=0.0000% (1920, 844) -> (1920, 844) bbox=None +PASS course-320: exact=0px; delta>8=0.0000% (320, 844) -> (320, 844) bbox=None +PASS course-390: exact=0px; delta>8=0.0000% (390, 844) -> (390, 844) bbox=None +PASS course-768: exact=0px; delta>8=0.0000% (768, 844) -> (768, 844) bbox=None +PASS courses-320: exact=0px; delta>8=0.0000% (320, 844) -> (320, 844) bbox=None +PASS courses-390: exact=0px; delta>8=0.0000% (390, 844) -> (390, 844) bbox=None +PASS courses-768: exact=0px; delta>8=0.0000% (768, 844) -> (768, 844) bbox=None +PASS feed-320: exact=0px; delta>8=0.0000% (320, 844) -> (320, 844) bbox=None +PASS feed-390: exact=0px; delta>8=0.0000% (390, 844) -> (390, 844) bbox=None +PASS feed-768: exact=0px; delta>8=0.0000% (768, 844) -> (768, 844) bbox=None +PASS members-320: exact=0px; delta>8=0.0000% (320, 844) -> (320, 844) bbox=None +PASS members-390: exact=0px; delta>8=0.0000% (390, 844) -> (390, 844) bbox=None +PASS members-768: exact=0px; delta>8=0.0000% (768, 844) -> (768, 844) bbox=None +PASS my-projects-320: exact=0px; delta>8=0.0000% (320, 844) -> (320, 844) bbox=None +PASS my-projects-390: exact=0px; delta>8=0.0000% (390, 844) -> (390, 844) bbox=None +PASS my-projects-768: exact=0px; delta>8=0.0000% (768, 844) -> (768, 844) bbox=None +PASS profile-320: exact=0px; delta>8=0.0000% (320, 844) -> (320, 844) bbox=None +PASS profile-390: exact=0px; delta>8=0.0000% (390, 844) -> (390, 844) bbox=None +PASS profile-768: exact=0px; delta>8=0.0000% (768, 844) -> (768, 844) bbox=None +PASS profile-edit-320: exact=0px; delta>8=0.0000% (320, 844) -> (320, 844) bbox=None +PASS profile-edit-390: exact=0px; delta>8=0.0000% (390, 844) -> (390, 844) bbox=None +PASS profile-edit-768: exact=0px; delta>8=0.0000% (768, 844) -> (768, 844) bbox=None +PASS program-320: exact=0px; delta>8=0.0000% (320, 844) -> (320, 844) bbox=None +PASS program-390: exact=0px; delta>8=0.0000% (390, 844) -> (390, 844) bbox=None +PASS program-768: exact=0px; delta>8=0.0000% (768, 844) -> (768, 844) bbox=None +PASS programs-320: exact=0px; delta>8=0.0000% (320, 844) -> (320, 844) bbox=None +PASS programs-390: exact=0px; delta>8=0.0000% (390, 844) -> (390, 844) bbox=None +PASS programs-768: exact=0px; delta>8=0.0000% (768, 844) -> (768, 844) bbox=None +PASS project-320: exact=0px; delta>8=0.0000% (320, 844) -> (320, 844) bbox=None +PASS project-390: exact=0px; delta>8=0.0000% (390, 844) -> (390, 844) bbox=None +PASS project-768: exact=0px; delta>8=0.0000% (768, 844) -> (768, 844) bbox=None +PASS project-edit-320: exact=0px; delta>8=0.0000% (320, 844) -> (320, 844) bbox=None +PASS project-edit-390: exact=0px; delta>8=0.0000% (390, 844) -> (390, 844) bbox=None +PASS project-edit-768: exact=0px; delta>8=0.0000% (768, 844) -> (768, 844) bbox=None +PASS projects-320: exact=0px; delta>8=0.0000% (320, 844) -> (320, 844) bbox=None +PASS projects-390: exact=0px; delta>8=0.0000% (390, 844) -> (390, 844) bbox=None +PASS projects-768: exact=0px; delta>8=0.0000% (768, 844) -> (768, 844) bbox=None +PASS vacancies-320: exact=0px; delta>8=0.0000% (320, 844) -> (320, 844) bbox=None +PASS vacancies-390: exact=0px; delta>8=0.0000% (390, 844) -> (390, 844) bbox=None +PASS vacancies-768: exact=0px; delta>8=0.0000% (768, 844) -> (768, 844) bbox=None +PASS vacancy-320: exact=0px; delta>8=0.0000% (320, 844) -> (320, 844) bbox=None +PASS vacancy-390: exact=0px; delta>8=0.0000% (390, 844) -> (390, 844) bbox=None +PASS vacancy-768: exact=0px; delta>8=0.0000% (768, 844) -> (768, 844) bbox=None diff --git a/docs/mobile-polish/.gitattributes b/docs/mobile-polish/.gitattributes new file mode 100644 index 000000000..8ea60f1b9 --- /dev/null +++ b/docs/mobile-polish/.gitattributes @@ -0,0 +1,3 @@ +*.json linguist-generated=true +*.log linguist-generated=true +screenshots/** linguist-generated=true diff --git a/docs/mobile-polish/README.md b/docs/mobile-polish/README.md new file mode 100644 index 000000000..0d74bdddc --- /dev/null +++ b/docs/mobile-polish/README.md @@ -0,0 +1,79 @@ + + +# Исправления мобильной компоновки после PR #401 + +Desktop-эталон и итоговое сравнение после восстановления ≥1000px находятся в +[desktop regression report](../desktop-regression/README.md). Desktop-снимки этого исторического +mobile-прохода не являются актуальным эталоном desktop. + +## Направление и критерии до реализации + +Запрос пользователя: устранить 12 проблем на приложенных mobile screenshots. Режим: исправление существующего интерфейса PROCOLLAB. Mont, семантические tokens, текущие иконки, роли, API и бизнес-действия сохраняются. Светлая нейтральная шапка с тёмными иконками явно выбрана пользователем. Существующие ListPage, DetailPage, ProjectList и ParticipantList остаются основой. + +Источники качества: `procollab-design-system-v1/docs/design-quality/mobile.md`, `antislop.md`, `patterns.md`, текущие shared-компоненты и screenshots пользователя. Применяются читаемость, группировка, компактная плотность и отсутствие декоративного пересечения иконок/текста. Внешние правила лендингов, шрифтов, иконок Fill и Figma не переносятся в runtime. Порядок блока «Моя активность» меняется по явному пункту 6 пользователя. Новая продуктовая функция и перенос в Figma не входят в задачу. + +| AC | Исправление | Приёмка | +| --- | ----------------------------------------------- | ----------------------------------------------------------------------------------------- | +| 1 | Заголовок шапки соответствует текущему маршруту | Новости/Профиль не наследуют «Программы», в том числе при переходе внутри приложения | +| 2 | Категории новостей без выступающих иконок | Иконка, название и счётчик в потоке, без пересечения | +| 3 | Удалён дублирующий «Фильтр» ленты | Один набор категорий; выбор меняет прежний query/filter и active state | +| 4 | Полные названия навыков | Перенос строк; дополнительные навыки раскрываются доступной кнопкой | +| 5 | Компактные карточки проектов | На mobile ширина не растягивается на всю страницу, CTA ≥44 px и внутри карточки | +| 6 | «Моя активность» выше списка | Полноценный summary по ширине контейнера, метрики 2×2, desktop sidebar сохранён | +| 7 | Компактные карточки участников | Ограниченная ширина, читаемые имя/специальность/навык, CTA по содержимому | +| 8 | Программа: география читается полностью | Даты и «для всей России» отдельными строками, без clipping | +| 9 | Понятные действия программы | Название программы, явно подписанные «Контакты» и «Положение», аккуратная группа действий | +| 10 | Действия профиля сгруппированы | Ровная сетка, без пустых разделителей и разнесённых по краям одиночных кнопок | +| 11 | Действия и metadata проекта | Общая сетка действий; metadata занимает всю доступную ширину mobile | +| 12 | Спокойная шапка с центром | Светлый фон, тёмные иконки, центр заголовка совпадает с центром viewport, цели ≥44 px | + +Проверка: 320/360/390/430/768/1440 px, обычный и длинный русский контент, before/after screenshots, переходы внутри приложения, категории и раскрытие навыков, keyboard/focus, применимые loading/disabled/validation состояния. Геометрия не заменяет ручной просмотр всех затронутых экранов. Реальные iOS/Android на dev по-прежнему требуют доступа к устройствам и стенду. + +## Итоговая реализация + +Светлая шапка использует существующий surface token и симметричные боковые зоны. Заголовок определяется текущим маршрутом при прямом открытии и SPA-переходах, поэтому поздний ответ программы не подменяет «Новости»/«Профиль». Выход доступен в мобильном drawer; уведомления и аватар имеют native controls с областью нажатия ≥44 px. + +В ленте остался один работающий набор категорий. Иконка, название и счётчик расположены в потоке. Навыки вакансии используют `VacancySkills` с полными подписями и раскрытием остальных. Проекты и участники используют общий token ширины 260 px до desktop breakpoint; списки размещают столько компактных карточек, сколько помещается. Активность показана над списком, метаданные проекта занимают всю ширину mobile. + +Общий `Detail` показывает название и существующую обложку, выравнивает secondary actions в две колонки, убирает пустые divider cells и подписывает «Контакты»/«Положение». Primary action программы расположен первым. В карточке программы даты и география разделены; registration state и его приоритет сохранены. При проверке дополнительно исправлена область пустого snackbar, которая перехватывала клик по аватару на tablet. + +Изменены shared-компоненты: `FeedFilter`, `InfoCard`, `VacancySkills`, `Detail`, `ProfileControlPanel`, `ProfileInfo`; shared стили `feed-card`, `ui-tokens`. На страницах изменены `Nav`/`Office`/`Snackbar`, `ProjectActivityCard`, `ProjectsLeftSide`, `ProgramCard`, `MemberCard`, сетки проектов/участников и отступы ленты. Mont, текущие иконки, Button/Card/PageHeader и UIKit adapters сохраняются. + +**Бизнес-логика не менялась.** Нет diff в API/domain/infrastructure, routes, permissions, payloads, dependencies или backend. Категории вызывают прежний `FeedFilterInfoService.setFilter`; навыки раскрывает существующий widget; logout вызывает прежний `Office.onLogout`. Условия ролей, сроки регистрации, status precedence, команды, заявки и отправка решений сохранены. Изменения TypeScript ограничены UI title/output/imports и удалением неиспользуемого dropdown UI. + +## Проверки и evidence + +Среда: Windows, headless Chrome/Playwright, production Angular build, локальный preview, синтетический API. Запросы и мутации не уходят на реальный сервер. В fixtures есть заведомо длинные строки и неполные данные; изображения/имена в evidence не являются реальными данными dev. + +| Проверка | Результат | Evidence | +| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | +| Unit/regression suite | 2006 tests / 406 files PASS | [tests.log](tests.log) | +| Повтор после последней правки шаблона названия | 41 InfoCard tests PASS | [info-card-tests.log](info-card-tests.log) | +| Production build | PASS; существующие template/CommonJS warnings | [build.log](build.log) | +| ESLint | 0 errors, 6 существующих warnings | [lint.log](lint.log) | +| Stylelint изменённых SCSS | PASS | [styles.log](styles.log) | +| Prettier, весь repo, Windows end-of-line auto | PASS | [format-all.log](format-all.log) | +| Геометрия и console errors | 48 экранов на 320/360/390/430/768/1440 px PASS | [after.json](after.json), [browser-check.cjs](browser-check.cjs) | +| Поведение и touch targets | 18 сценариев на 320/390/768 px PASS; SPA title, query/API filter, skill expansion, layout, Escape/focus | [interactions.json](interactions.json), [interactions.cjs](interactions.cjs) | +| Разделы и состояния | 48 проверок на 320/390/1440 px PASS; проекты, вакансии, программы, курсы, профиль/edit, onboarding | [states.json](states.json), [state-check.cjs](state-check.cjs) | + +Проверка состояний включает задержку ответа и блокировку повторной отправки, empty list, injected HTTP 500 и рабочий retry, disabled button/filter без запроса, validation регистрации/onboarding без мутации. Ожидаемые ошибки injected HTTP 500 отдельно отмечены в JSON. Before screenshots сняты с merged dev `ec57fa7c` до пересборки изменённых исходников; результат: [before.json](before.json). + +| Экран, 390 px | До | После | +| ------------------ | ------------------------------------------------ | ---------------------------------------------- | +| Новости | [before](screenshots/before/feed-390.png) | [after](screenshots/after/feed-390.png) | +| Dashboard проектов | [before](screenshots/before/projects-390.png) | [after](screenshots/after/projects-390.png) | +| Мои проекты | [before](screenshots/before/my-projects-390.png) | [after](screenshots/after/my-projects-390.png) | +| Участники | [before](screenshots/before/members-390.png) | [after](screenshots/after/members-390.png) | +| Программы | [before](screenshots/before/programs-390.png) | [after](screenshots/after/programs-390.png) | +| Программа | [before](screenshots/before/program-390.png) | [after](screenshots/after/program-390.png) | +| Профиль | [before](screenshots/before/profile-390.png) | [after](screenshots/after/profile-390.png) | +| Проект | [before](screenshots/before/project-390.png) | [after](screenshots/after/project-390.png) | + +## Ограничения и следующий этап + +Все 12 пунктов пользователя проверены исходниками, в браузере и визуально; [requirement audit](review.md). Автоматическая геометрия дополнена просмотром ключевых mobile screens, desktop и снимков состояний. Скриншоты, JSON и logs свёрнуты в GitHub diff через `.gitattributes`. + +**Not checked:** физические iOS Safari / Android Chrome на dev, реальные аккаунты и screen reader. Browser emulation не подтверждает эти среды и не заменяет запрошенный smoke-test. После merge этого отдельного fix PR нужен smoke-test на dev до prod: открыть все ключевые разделы, выполнить SPA navigation, фильтрацию/раскрытие навыков, проверить drawer/notifications, keyboard в формах и роли программы. Найденные на устройствах проблемы исправлять отдельными PR. Production merge/deploy в эту задачу не входят. + +API/data migration не требуются. Визуальные изменения shared компонентов распространяются на их consumers; поэтому перепроверены связанные разделы и состояния. Текущая палитра не объявляется полностью WCAG AA compliant. diff --git a/docs/mobile-polish/after.json b/docs/mobile-polish/after.json new file mode 100644 index 000000000..e0ad38261 --- /dev/null +++ b/docs/mobile-polish/after.json @@ -0,0 +1,2406 @@ +[ + { + "name": "feed", + "width": 320, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag" + ], + "text": "Новости\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости программ\n0\nобразование\n0\nНовая вакансия\n29.09.2026\nПроект / компания\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nДизайнер интерф", + "errors": [] + }, + { + "name": "projects", + "width": 320, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nпоказать раздел\n\nмои подписки\n\nГородские проекты\n\nСервис для студенческих команд\n\nОткрыть\nпок", + "errors": [] + }, + { + "name": "my-projects", + "width": 320, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nМоя активность\nПроектов\n1\nЯ лидер\n1\nВ программе\n0\nСд", + "errors": [] + }, + { + "name": "members", + "width": 320, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card" + ], + "text": "Участники\nучастники\nФильтры\nПерейти в профиль\nСтатистика\nВсего участников\n—\nВ проектах\n—\nВ программах\n—\nНе удалось загрузить статистику участников\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nРазработчик • 26 л", + "errors": [] + }, + { + "name": "programs", + "width": 320, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card" + ], + "text": "Программы\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026 - 01.01.2027\n\nдля всей России", + "errors": [] + }, + { + "name": "program", + "width": 320, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "Программы\nКейс-чемпионат студенческих проектов\nоценка проектов\nаналитика\nКонтакты\nпроекты-участники\nучастники\nматериалы\nаналитика\nорганизатор\nУчастники\n1\nПроекты\n1\nСдано\nрешений\n0\nБез проектов\n0\n0,0%\nОткрыть →\nо программе\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНаз", + "errors": [] + }, + { + "name": "profile", + "width": 320, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Профиль\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nнавыки\n\n0 / 15940\n\n01.10.2026\n\nОченьДлинно", + "errors": [] + }, + { + "name": "project", + "width": 320, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "Профиль проекта\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАкселератор студенческих проектов\nСфера\n\nИнформационные технологии\n\nРегион\n\nРостовская область\n\nTRL\n\n1\n\nСрок реализации\n\n2027-01-01\n\nЛидер\nТестовый ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ", + "errors": [] + }, + { + "name": "feed", + "width": 360, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 360, + "pageWidth": 360, + "bodyWidth": 360, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag" + ], + "text": "Новости\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости программ\n0\nобразование\n0\nНовая вакансия\n29.09.2026\nПроект / компания\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nДизайнер интерф", + "errors": [] + }, + { + "name": "projects", + "width": 360, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 360, + "pageWidth": 360, + "bodyWidth": 360, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nпоказать раздел\n\nмои подписки\n\nГородские проекты\n\nСервис для студенческих команд\n\nОткрыть\nпок", + "errors": [] + }, + { + "name": "my-projects", + "width": 360, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 360, + "pageWidth": 360, + "bodyWidth": 360, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nМоя активность\nПроектов\n1\nЯ лидер\n1\nВ программе\n0\nСд", + "errors": [] + }, + { + "name": "members", + "width": 360, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 360, + "pageWidth": 360, + "bodyWidth": 360, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card" + ], + "text": "Участники\nучастники\nФильтры\nПерейти в профиль\nСтатистика\nВсего участников\n—\nВ проектах\n—\nВ программах\n—\nНе удалось загрузить статистику участников\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nРазработчик • 26 л", + "errors": [] + }, + { + "name": "programs", + "width": 360, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 360, + "pageWidth": 360, + "bodyWidth": 360, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card" + ], + "text": "Программы\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026 - 01.01.2027\n\nдля всей России", + "errors": [] + }, + { + "name": "program", + "width": 360, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 360, + "pageWidth": 360, + "bodyWidth": 360, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "Программы\nКейс-чемпионат студенческих проектов\nоценка проектов\nаналитика\nКонтакты\nпроекты-участники\nучастники\nматериалы\nаналитика\nорганизатор\nУчастники\n1\nПроекты\n1\nСдано\nрешений\n0\nБез проектов\n0\n0,0%\nОткрыть →\nо программе\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНаз", + "errors": [] + }, + { + "name": "profile", + "width": 360, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 360, + "pageWidth": 360, + "bodyWidth": 360, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Профиль\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nнавыки\n\n0 / 15940\n\n01.10.2026\n\nОченьДлинно", + "errors": [] + }, + { + "name": "project", + "width": 360, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 360, + "pageWidth": 360, + "bodyWidth": 360, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "Профиль проекта\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАкселератор студенческих проектов\nСфера\n\nИнформационные технологии\n\nРегион\n\nРостовская область\n\nTRL\n\n1\n\nСрок реализации\n\n2027-01-01\n\nЛидер\nТестовый ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ", + "errors": [] + }, + { + "name": "feed", + "width": 390, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag" + ], + "text": "Новости\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости программ\n0\nобразование\n0\nНовая вакансия\n29.09.2026\nПроект / компания\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nДизайнер интерф", + "errors": [] + }, + { + "name": "projects", + "width": 390, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nпоказать раздел\n\nмои подписки\n\nГородские проекты\n\nСервис для студенческих команд\n\nОткрыть\nпок", + "errors": [] + }, + { + "name": "my-projects", + "width": 390, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nМоя активность\nПроектов\n1\nЯ лидер\n1\nВ программе\n0\nСд", + "errors": [] + }, + { + "name": "members", + "width": 390, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card" + ], + "text": "Участники\nучастники\nФильтры\nПерейти в профиль\nСтатистика\nВсего участников\n—\nВ проектах\n—\nВ программах\n—\nНе удалось загрузить статистику участников\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nРазработчик • 26 л", + "errors": [] + }, + { + "name": "programs", + "width": 390, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card" + ], + "text": "Программы\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026 - 01.01.2027\n\nдля всей России", + "errors": [] + }, + { + "name": "program", + "width": 390, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "Программы\nКейс-чемпионат студенческих проектов\nоценка проектов\nаналитика\nКонтакты\nпроекты-участники\nучастники\nматериалы\nаналитика\nорганизатор\nУчастники\n1\nПроекты\n1\nСдано\nрешений\n0\nБез проектов\n0\n0,0%\nОткрыть →\nо программе\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНаз", + "errors": [] + }, + { + "name": "profile", + "width": 390, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Профиль\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nнавыки\n\n0 / 15940\n\n01.10.2026\n\nОченьДлинно", + "errors": [] + }, + { + "name": "project", + "width": 390, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "Профиль проекта\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАкселератор студенческих проектов\nСфера\n\nИнформационные технологии\n\nРегион\n\nРостовская область\n\nTRL\n\n1\n\nСрок реализации\n\n2027-01-01\n\nЛидер\nТестовый ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ", + "errors": [] + }, + { + "name": "feed", + "width": 430, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 430, + "pageWidth": 430, + "bodyWidth": 430, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag" + ], + "text": "Новости\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости программ\n0\nобразование\n0\nНовая вакансия\n29.09.2026\nПроект / компания\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nДизайнер интерф", + "errors": [] + }, + { + "name": "projects", + "width": 430, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 430, + "pageWidth": 430, + "bodyWidth": 430, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nпоказать раздел\n\nмои подписки\n\nГородские проекты\n\nСервис для студенческих команд\n\nОткрыть\nпок", + "errors": [] + }, + { + "name": "my-projects", + "width": 430, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 430, + "pageWidth": 430, + "bodyWidth": 430, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nМоя активность\nПроектов\n1\nЯ лидер\n1\nВ программе\n0\nСд", + "errors": [] + }, + { + "name": "members", + "width": 430, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 430, + "pageWidth": 430, + "bodyWidth": 430, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card" + ], + "text": "Участники\nучастники\nФильтры\nПерейти в профиль\nСтатистика\nВсего участников\n—\nВ проектах\n—\nВ программах\n—\nНе удалось загрузить статистику участников\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nРазработчик • 26 л", + "errors": [] + }, + { + "name": "programs", + "width": 430, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 430, + "pageWidth": 430, + "bodyWidth": 430, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card" + ], + "text": "Программы\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026 - 01.01.2027\n\nдля всей России", + "errors": [] + }, + { + "name": "program", + "width": 430, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 430, + "pageWidth": 430, + "bodyWidth": 430, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "Программы\nКейс-чемпионат студенческих проектов\nоценка проектов\nаналитика\nКонтакты\nпроекты-участники\nучастники\nматериалы\nаналитика\nорганизатор\nУчастники\n1\nПроекты\n1\nСдано\nрешений\n0\nБез проектов\n0\n0,0%\nОткрыть →\nо программе\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНаз", + "errors": [] + }, + { + "name": "profile", + "width": 430, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 430, + "pageWidth": 430, + "bodyWidth": 430, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Профиль\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nнавыки\n\n0 / 15940\n\n01.10.2026\n\nОченьДлинно", + "errors": [] + }, + { + "name": "project", + "width": 430, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 430, + "pageWidth": 430, + "bodyWidth": 430, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "Профиль проекта\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАкселератор студенческих проектов\nСфера\n\nИнформационные технологии\n\nРегион\n\nРостовская область\n\nTRL\n\n1\n\nСрок реализации\n\n2027-01-01\n\nЛидер\nТестовый ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ", + "errors": [] + }, + { + "name": "feed", + "width": 768, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag" + ], + "text": "Новости\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости программ\n0\nобразование\n0\nНовая вакансия\n29.09.2026\nПроект / компания\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nДизайнер интерф", + "errors": [] + }, + { + "name": "projects", + "width": 768, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nпоказать раздел\n\nмои подписки\n\nГородские проекты\n\nСервис для студенческих команд\n\nОткрыть\nпок", + "errors": [] + }, + { + "name": "my-projects", + "width": 768, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nМоя активность\nПроектов\n1\nЯ лидер\n1\nВ программе\n0\nСд", + "errors": [] + }, + { + "name": "members", + "width": 768, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card" + ], + "text": "Участники\nучастники\nФильтры\nПерейти в профиль\nСтатистика\nВсего участников\n—\nВ проектах\n—\nВ программах\n—\nНе удалось загрузить статистику участников\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nРазработчик • 26 л", + "errors": [] + }, + { + "name": "programs", + "width": 768, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card" + ], + "text": "Программы\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026 - 01.01.2027\n\nдля всей России", + "errors": [] + }, + { + "name": "program", + "width": 768, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "Программы\nКейс-чемпионат студенческих проектов\nоценка проектов\nаналитика\nКонтакты\nпроекты-участники\nучастники\nматериалы\nаналитика\nорганизатор\nУчастники\n1\nПроекты\n1\nСдано\nрешений\n0\nБез проектов\n0\n0,0%\nОткрыть →\nо программе\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНаз", + "errors": [] + }, + { + "name": "profile", + "width": 768, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Профиль\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nнавыки\n\n0 / 15940\n\n01.10.2026\n\nОченьДлинно", + "errors": [] + }, + { + "name": "project", + "width": 768, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "Профиль проекта\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАкселератор студенческих проектов\nСфера\n\nИнформационные технологии\n\nРегион\n\nРостовская область\n\nTRL\n\n1\n\nСрок реализации\n\n2027-01-01\n\nЛидер\nТестовый ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ", + "errors": [] + }, + { + "name": "feed", + "width": 1440, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости прогр", + "errors": [] + }, + { + "name": "projects", + "width": 1440, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПро", + "errors": [] + }, + { + "name": "my-projects", + "width": 1440, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-project-activity-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПри", + "errors": [] + }, + { + "name": "members", + "width": 1440, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-search", + "app-member-card", + "app-button", + "app-members-filters", + "app-autocomplete-input", + "app-member-statistics-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-search", + "app-member-card", + "app-button", + "app-members-filters", + "app-autocomplete-input", + "app-member-statistics-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nучастники\n\nПоиск\n\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробело", + "errors": [] + }, + { + "name": "programs", + "width": 1440, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026 -", + "errors": [] + }, + { + "name": "program", + "width": 1440, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nКейс-чемпионат студенческих проектов\nоценка проектов\nаналитика\nпроекты-участники\nучастни", + "errors": [] + }, + { + "name": "profile", + "width": 1440, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26", + "errors": [] + }, + { + "name": "project", + "width": 1440, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАксе", + "errors": [] + } +] diff --git a/docs/mobile-polish/before.json b/docs/mobile-polish/before.json new file mode 100644 index 000000000..7787c80c8 --- /dev/null +++ b/docs/mobile-polish/before.json @@ -0,0 +1,2358 @@ +[ + { + "name": "feed", + "width": 320, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-open-vacancy" + ], + "text": "все новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости программ\n0\nобразование\n0\nФильтр\nНовая вакансия\n29.09.2026\nПроект / компания\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nДизайнер интерфе", + "errors": [] + }, + { + "name": "projects", + "width": 320, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nпоказать раздел\n\nмои подписки\n\nГородские проекты\n\nСервис для студенческих команд\n\nОткрыть\nпок", + "errors": [] + }, + { + "name": "my-projects", + "width": 320, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nМоя активность\nПроектов\n1\nЯ лидер\n1\nВ программе\n0\nСд", + "errors": [] + }, + { + "name": "members", + "width": 320, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card" + ], + "text": "Участники\nучастники\nФильтры\nПерейти в профиль\nСтатистика\nВсего участников\n—\nВ проектах\n—\nВ программах\n—\nНе удалось загрузить статистику участников\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nРазработчик • 26 л", + "errors": [] + }, + { + "name": "programs", + "width": 320, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card" + ], + "text": "Программы\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026\n\n-\n\n01.01.2027\n\n• для всей России", + "errors": [] + }, + { + "name": "program", + "width": 320, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "оценка проектов\nаналитика\nпроекты-участники\nучастники\nматериалы\nаналитика\nорганизатор\nУчастники\n1\nПроекты\n1\nСдано\nрешений\n0\nБез проектов\n0\n0,0%\nОткрыть →\nо программе\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nподробн", + "errors": [] + }, + { + "name": "profile", + "width": 320, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Алексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nнавыки\n\n0 / 15940\n\n01.10.2026\n\nОченьДлинноеНазвани", + "errors": [] + }, + { + "name": "project", + "width": 320, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "Профиль проекта\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАкселератор студенческих проектов\nСфера\n\nИнформационные технологии\n\nРегион\n\nРостовская область\n\nTRL\n\n1\n\nСрок реализации\n\n2027-01-01\n\nЛидер\nТестовый ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ", + "errors": [] + }, + { + "name": "feed", + "width": 360, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 360, + "pageWidth": 360, + "bodyWidth": 360, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-open-vacancy" + ], + "text": "все новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости программ\n0\nобразование\n0\nФильтр\nНовая вакансия\n29.09.2026\nПроект / компания\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nДизайнер интерфе", + "errors": [] + }, + { + "name": "projects", + "width": 360, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 360, + "pageWidth": 360, + "bodyWidth": 360, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nпоказать раздел\n\nмои подписки\n\nГородские проекты\n\nСервис для студенческих команд\n\nОткрыть\nпок", + "errors": [] + }, + { + "name": "my-projects", + "width": 360, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 360, + "pageWidth": 360, + "bodyWidth": 360, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nМоя активность\nПроектов\n1\nЯ лидер\n1\nВ программе\n0\nСд", + "errors": [] + }, + { + "name": "members", + "width": 360, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 360, + "pageWidth": 360, + "bodyWidth": 360, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card" + ], + "text": "Участники\nучастники\nФильтры\nПерейти в профиль\nСтатистика\nВсего участников\n—\nВ проектах\n—\nВ программах\n—\nНе удалось загрузить статистику участников\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nРазработчик • 26 л", + "errors": [] + }, + { + "name": "programs", + "width": 360, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 360, + "pageWidth": 360, + "bodyWidth": 360, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card" + ], + "text": "Программы\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026\n\n-\n\n01.01.2027\n\n• для всей России", + "errors": [] + }, + { + "name": "program", + "width": 360, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 360, + "pageWidth": 360, + "bodyWidth": 360, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "оценка проектов\nаналитика\nпроекты-участники\nучастники\nматериалы\nаналитика\nорганизатор\nУчастники\n1\nПроекты\n1\nСдано\nрешений\n0\nБез проектов\n0\n0,0%\nОткрыть →\nо программе\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nподробн", + "errors": [] + }, + { + "name": "profile", + "width": 360, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 360, + "pageWidth": 360, + "bodyWidth": 360, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Алексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nнавыки\n\n0 / 15940\n\n01.10.2026\n\nОченьДлинноеНазвани", + "errors": [] + }, + { + "name": "project", + "width": 360, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 360, + "pageWidth": 360, + "bodyWidth": 360, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "Профиль проекта\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАкселератор студенческих проектов\nСфера\n\nИнформационные технологии\n\nРегион\n\nРостовская область\n\nTRL\n\n1\n\nСрок реализации\n\n2027-01-01\n\nЛидер\nТестовый ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ", + "errors": [] + }, + { + "name": "feed", + "width": 390, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-open-vacancy" + ], + "text": "все новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости программ\n0\nобразование\n0\nФильтр\nНовая вакансия\n29.09.2026\nПроект / компания\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nДизайнер интерфе", + "errors": [] + }, + { + "name": "projects", + "width": 390, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nпоказать раздел\n\nмои подписки\n\nГородские проекты\n\nСервис для студенческих команд\n\nОткрыть\nпок", + "errors": [] + }, + { + "name": "my-projects", + "width": 390, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nМоя активность\nПроектов\n1\nЯ лидер\n1\nВ программе\n0\nСд", + "errors": [] + }, + { + "name": "members", + "width": 390, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card" + ], + "text": "Участники\nучастники\nФильтры\nПерейти в профиль\nСтатистика\nВсего участников\n—\nВ проектах\n—\nВ программах\n—\nНе удалось загрузить статистику участников\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nРазработчик • 26 л", + "errors": [] + }, + { + "name": "programs", + "width": 390, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card" + ], + "text": "Программы\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026\n\n-\n\n01.01.2027\n\n• для всей России", + "errors": [] + }, + { + "name": "program", + "width": 390, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "оценка проектов\nаналитика\nпроекты-участники\nучастники\nматериалы\nаналитика\nорганизатор\nУчастники\n1\nПроекты\n1\nСдано\nрешений\n0\nБез проектов\n0\n0,0%\nОткрыть →\nо программе\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nподробн", + "errors": [] + }, + { + "name": "profile", + "width": 390, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Алексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nнавыки\n\n0 / 15940\n\n01.10.2026\n\nОченьДлинноеНазвани", + "errors": [] + }, + { + "name": "project", + "width": 390, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "Профиль проекта\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАкселератор студенческих проектов\nСфера\n\nИнформационные технологии\n\nРегион\n\nРостовская область\n\nTRL\n\n1\n\nСрок реализации\n\n2027-01-01\n\nЛидер\nТестовый ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ", + "errors": [] + }, + { + "name": "feed", + "width": 430, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 430, + "pageWidth": 430, + "bodyWidth": 430, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-open-vacancy" + ], + "text": "все новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости программ\n0\nобразование\n0\nФильтр\nНовая вакансия\n29.09.2026\nПроект / компания\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nДизайнер интерфе", + "errors": [] + }, + { + "name": "projects", + "width": 430, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 430, + "pageWidth": 430, + "bodyWidth": 430, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nпоказать раздел\n\nмои подписки\n\nГородские проекты\n\nСервис для студенческих команд\n\nОткрыть\nпок", + "errors": [] + }, + { + "name": "my-projects", + "width": 430, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 430, + "pageWidth": 430, + "bodyWidth": 430, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nМоя активность\nПроектов\n1\nЯ лидер\n1\nВ программе\n0\nСд", + "errors": [] + }, + { + "name": "members", + "width": 430, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 430, + "pageWidth": 430, + "bodyWidth": 430, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card" + ], + "text": "Участники\nучастники\nФильтры\nПерейти в профиль\nСтатистика\nВсего участников\n—\nВ проектах\n—\nВ программах\n—\nНе удалось загрузить статистику участников\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nРазработчик • 26 л", + "errors": [] + }, + { + "name": "programs", + "width": 430, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 430, + "pageWidth": 430, + "bodyWidth": 430, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card" + ], + "text": "Программы\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026\n\n-\n\n01.01.2027\n\n• для всей России", + "errors": [] + }, + { + "name": "program", + "width": 430, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 430, + "pageWidth": 430, + "bodyWidth": 430, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "оценка проектов\nаналитика\nпроекты-участники\nучастники\nматериалы\nаналитика\nорганизатор\nУчастники\n1\nПроекты\n1\nСдано\nрешений\n0\nБез проектов\n0\n0,0%\nОткрыть →\nо программе\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\n0 / 159", + "errors": [] + }, + { + "name": "profile", + "width": 430, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 430, + "pageWidth": 430, + "bodyWidth": 430, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Алексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nнавыки\n\n0 / 15940\n\n01.10.2026\n\nОченьДлинноеНазвани", + "errors": [] + }, + { + "name": "project", + "width": 430, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 430, + "pageWidth": 430, + "bodyWidth": 430, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "Профиль проекта\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАкселератор студенческих проектов\nСфера\n\nИнформационные технологии\n\nРегион\n\nРостовская область\n\nTRL\n\n1\n\nСрок реализации\n\n2027-01-01\n\nЛидер\nТестовый ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ", + "errors": [] + }, + { + "name": "feed", + "width": 768, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-open-vacancy" + ], + "text": "все новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости программ\n0\nобразование\n0\nФильтр\nНовая вакансия\n29.09.2026\nПроект / компания\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nДизайнер интерфе", + "errors": [] + }, + { + "name": "projects", + "width": 768, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nпоказать раздел\n\nмои подписки\n\nГородские проекты\n\nСервис для студенческих команд\n\nОткрыть\nпок", + "errors": [] + }, + { + "name": "my-projects", + "width": 768, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nМоя активность\nПроектов\n1\nЯ лидер\n1\nВ программе\n0\nСд", + "errors": [] + }, + { + "name": "members", + "width": 768, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card" + ], + "text": "Участники\nучастники\nФильтры\nПерейти в профиль\nСтатистика\nВсего участников\n—\nВ проектах\n—\nВ программах\n—\nНе удалось загрузить статистику участников\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nРазработчик • 26 л", + "errors": [] + }, + { + "name": "programs", + "width": 768, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card" + ], + "text": "Программы\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026\n\n-\n\n01.01.2027\n\n• для всей России", + "errors": [] + }, + { + "name": "program", + "width": 768, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "оценка проектов\nаналитика\nпроекты-участники\nучастники\nматериалы\nаналитика\nорганизатор\nУчастники\n1\nПроекты\n1\nСдано\nрешений\n0\nБез проектов\n0\n0,0%\nОткрыть →\nо программе\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nподробн", + "errors": [] + }, + { + "name": "profile", + "width": 768, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Алексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nнавыки\n\n0 / 15940\n\n01.10.2026\n\nОченьДлинноеНазвани", + "errors": [] + }, + { + "name": "project", + "width": 768, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "Профиль проекта\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАкселератор студенческих проектов\nСфера\n\nИнформационные технологии\n\nРегион\n\nРостовская область\n\nTRL\n\n1\n\nСрок реализации\n\n2027-01-01\n\nЛидер\nТестовый ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ", + "errors": [] + }, + { + "name": "feed", + "width": 1440, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости прогр", + "errors": [] + }, + { + "name": "projects", + "width": 1440, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПро", + "errors": [] + }, + { + "name": "my-projects", + "width": 1440, + "actualPath": "/office/projects/my", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-project-activity-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nПри", + "errors": [] + }, + { + "name": "members", + "width": 1440, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-search", + "app-member-card", + "app-button", + "app-members-filters", + "app-autocomplete-input", + "app-member-statistics-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-search", + "app-member-card", + "app-button", + "app-members-filters", + "app-autocomplete-input", + "app-member-statistics-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nучастники\n\nПоиск\n\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробело", + "errors": [] + }, + { + "name": "programs", + "width": 1440, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nпрограммы\n\nПоиск\n\nКейс-чемпионат студенческих проектов\n\nты уже участвуешь!\n\n01.10.2026\n\n", + "errors": [] + }, + { + "name": "program", + "width": 1440, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nоценка проектов\nаналитика\nпроекты-участники\nучастники\nаналитика\nорганизатор\nУчастники\n1\n", + "errors": [] + }, + { + "name": "profile", + "width": 1440, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26", + "errors": [] + }, + { + "name": "project", + "width": 1440, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nКейс-чемпионат студенческих пр...\n\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАксе", + "errors": [] + } +] diff --git a/docs/mobile-polish/browser-check.cjs b/docs/mobile-polish/browser-check.cjs new file mode 100644 index 000000000..14769150f --- /dev/null +++ b/docs/mobile-polish/browser-check.cjs @@ -0,0 +1,54 @@ +/** @format */ + +const fs = require("node:fs"); +const path = require("node:path"); +const assert = require("node:assert/strict"); +const { launch, measure } = require("../responsive/browser-harness.cjs"); +const fixtures = require("./fixtures.cjs"); +const phase = process.argv[2] || "after"; +const widths = [320, 360, 390, 430, 768, 1440]; +const screens = [ + ["feed", "/office/feed", "app-open-vacancy"], + ["projects", "/office/projects/dashboard", "app-info-card"], + ["my-projects", "/office/projects/my", "app-info-card"], + ["members", "/office/members", "app-member-card"], + ["programs", "/office/program/all", "app-program-card"], + ["program", "/office/program/1", "app-detail"], + ["profile", "/office/profile/1", "app-detail"], + ["project", "/office/projects/1", "app-detail"], +]; +const directory = path.join(__dirname, "screenshots", phase); +fs.mkdirSync(directory, { recursive: true }); +(async () => { + const rows = []; + for (const width of widths) { + const h = await launch(width, { isMobile: width < 750, hasTouch: width < 750 }); + try { + for (const [name, route, selector] of screens) { + h.errors.length = 0; + await h.page.goto(h.base + route); + await h.page.waitForLoadState("networkidle"); + await h.page.locator(selector).first().waitFor({ state: "visible", timeout: 10000 }); + const measurement = await measure(h.page); + await h.page.screenshot({ + path: path.join(directory, `${name}-${width}.png`), + fullPage: true, + }); + if (phase === "after") { + assert.equal(measurement.pageWidth <= width + 1, true, `${name} ${width} page overflow`); + assert.deepEqual(measurement.overflows, [], `${name} ${width}`); + assert.deepEqual(h.errors, [], `${name} ${width}`); + } + rows.push({ name, width, ...measurement, errors: [...h.errors] }); + console.log(`${phase}: ${name} ${width}`); + } + } finally { + await h.browser.close(); + } + } + fs.writeFileSync(path.join(__dirname, `${phase}.json`), JSON.stringify(rows, null, 2) + "\n"); + console.log(`${rows.length} ${phase} captures completed`); +})().catch(error => { + console.error(error); + process.exitCode = 1; +}); diff --git a/docs/mobile-polish/browser.log b/docs/mobile-polish/browser.log new file mode 100644 index 000000000..07d173b08 --- /dev/null +++ b/docs/mobile-polish/browser.log @@ -0,0 +1,49 @@ +after: feed 320 +after: projects 320 +after: my-projects 320 +after: members 320 +after: programs 320 +after: program 320 +after: profile 320 +after: project 320 +after: feed 360 +after: projects 360 +after: my-projects 360 +after: members 360 +after: programs 360 +after: program 360 +after: profile 360 +after: project 360 +after: feed 390 +after: projects 390 +after: my-projects 390 +after: members 390 +after: programs 390 +after: program 390 +after: profile 390 +after: project 390 +after: feed 430 +after: projects 430 +after: my-projects 430 +after: members 430 +after: programs 430 +after: program 430 +after: profile 430 +after: project 430 +after: feed 768 +after: projects 768 +after: my-projects 768 +after: members 768 +after: programs 768 +after: program 768 +after: profile 768 +after: project 768 +after: feed 1440 +after: projects 1440 +after: my-projects 1440 +after: members 1440 +after: programs 1440 +after: program 1440 +after: profile 1440 +after: project 1440 +48 after captures completed diff --git a/docs/mobile-polish/build.log b/docs/mobile-polish/build.log new file mode 100644 index 000000000..4204a69cf --- /dev/null +++ b/docs/mobile-polish/build.log @@ -0,0 +1,1152 @@ + +> procollab@0.0.0 build:social:prod +> npm run build:sprite && ng build social_platform --configuration=production + + +> procollab@0.0.0 build:sprite +> svg-sprite -s --dest=projects/social_platform/src/assets/icons "projects/social_platform/src/assets/icons/svg/**/*.svg" + +> Building... +√ Building... +Initial chunk files | Names | Raw size | Estimated transfer size +chunk-3DFUC4ZD.js | - | 415.14 kB | 72.46 kB +chunk-EMX2ZQ7G.js | - | 213.04 kB | 60.81 kB +main-3G3JXXOW.js | main | 207.19 kB | 53.23 kB +styles-GQ6NWUF3.css | styles | 131.39 kB | 12.03 kB +chunk-32JCLU4R.js | - | 111.30 kB | 28.30 kB +chunk-FQQXBL2D.js | - | 83.07 kB | 25.83 kB +chunk-IQWATLI4.js | - | 73.82 kB | 17.10 kB +chunk-XZDUNLXR.js | - | 49.83 kB | 10.26 kB +chunk-SEBII2ES.js | - | 42.79 kB | 8.66 kB +chunk-LQCFT4Z5.js | - | 28.10 kB | 7.56 kB +chunk-53SHMX3B.js | - | 26.33 kB | 5.24 kB +chunk-AGYL4TXQ.js | - | 11.43 kB | 2.59 kB +chunk-U6SLWTRI.js | - | 9.38 kB | 3.00 kB +chunk-JL552RI3.js | - | 4.30 kB | 1.19 kB +chunk-LGEYGYTW.js | - | 4.04 kB | 1.47 kB +chunk-XZLEJTYL.js | - | 3.19 kB | 1.27 kB +chunk-JP4HTDU5.js | - | 1.47 kB | 386 bytes +chunk-VOSPIT4N.js | - | 1.22 kB | 521 bytes +chunk-UMKP35NR.js | - | 695 bytes | 695 bytes +chunk-JHUOFMVX.js | - | 483 bytes | 483 bytes +chunk-ZTXJLEZP.js | - | 474 bytes | 474 bytes +chunk-IAS7Y3HI.js | - | 465 bytes | 465 bytes +chunk-4WVOMZ3C.js | - | 352 bytes | 352 bytes +chunk-Y7FCNQPS.js | - | 195 bytes | 195 bytes +chunk-RQDRLMC2.js | - | 180 bytes | 180 bytes +chunk-W2ZPBHP5.js | - | 160 bytes | 160 bytes +chunk-N7PJCV3T.js | - | 128 bytes | 128 bytes +chunk-DKVRXEF2.js | - | 127 bytes | 127 bytes +chunk-PY5GJ2VA.js | - | 51 bytes | 51 bytes +chunk-GDMD5RKS.js | - | 51 bytes | 51 bytes +chunk-NCHAAQO5.js | - | 30 bytes | 30 bytes +chunk-KTRLVWC3.js | - | 30 bytes | 30 bytes +chunk-CRTRRB5R.js | - | 30 bytes | 30 bytes +chunk-PKT6RRYE.js | - | 30 bytes | 30 bytes +chunk-YIJ4Z6S4.js | - | 30 bytes | 30 bytes +chunk-KEPWQ2XV.js | - | 30 bytes | 30 bytes +chunk-FE3JRQRM.js | - | 30 bytes | 30 bytes +chunk-GAELZNYR.js | - | 25 bytes | 25 bytes +chunk-4CQUPGHG.js | - | 25 bytes | 25 bytes +chunk-PPZSTFUD.js | - | 25 bytes | 25 bytes +chunk-UYXSSEQD.js | - | 25 bytes | 25 bytes +chunk-FI4DW6KU.js | - | 25 bytes | 25 bytes +chunk-25HWN6II.js | - | 25 bytes | 25 bytes +chunk-SVFKPVOL.js | - | 25 bytes | 25 bytes +chunk-CRUTENDI.js | - | 0 bytes | 0 bytes +chunk-S7EUWH5W.js | - | 0 bytes | 0 bytes + + | Initial total | 1.42 MB | 315.65 kB + +Lazy chunk files | Names | Raw size | Estimated transfer size +chunk-KJV4655H.js | detail-routes | 268.07 kB | 41.83 kB +chunk-OYEHLSME.js | onboarding-routes | 111.52 kB | 15.02 kB +chunk-AUN646PD.js | office-routes | 102.43 kB | 19.00 kB +chunk-GNM5YFID.js | detail-routes | 91.14 kB | 16.82 kB +chunk-BTMT4Q3X.js | lesson-routes | 82.78 kB | 10.90 kB +chunk-XY3ULAHD.js | - | 82.17 kB | 16.11 kB +chunk-TLJCG35F.js | projects-routes | 74.57 kB | 13.85 kB +chunk-AJJJSWEY.js | index | 72.43 kB | 17.54 kB +chunk-WLMQT3DH.js | auth-routes | 69.69 kB | 9.69 kB +chunk-3PWCBJRN.js | - | 66.21 kB | 13.34 kB +chunk-LWIL3KQZ.js | vacancies-detail-routes | 42.99 kB | 8.81 kB +chunk-DNRR2I3P.js | project-team-step-component | 40.41 kB | 8.08 kB +chunk-6V3S7R7B.js | profile-detail-routes | 40.05 kB | 7.65 kB +chunk-SOJBAKOG.js | course-detail-routes | 39.61 kB | 7.10 kB +chunk-3UU3AKUA.js | project-main-step-component | 37.06 kB | 7.12 kB +...and 88 more lazy chunks files. Use "--verbose" to show all the files. + +Application bundle generation complete. [20.126 seconds] - 2026-10-04T20:04:35.688Z + +▲ [WARNING] 2 repetitive deprecation warnings omitted. +Run in verbose mode to see all warnings. [plugin angular-sass] + + null + + +▲ [WARNING] NG8113: BackComponent is not used within the template of CoursesComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/courses/courses.component.ts:19:4: + 19 │ BackComponent, + ╵ ~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: ButtonComponent is not used within the template of CourseComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/courses/list/course/course.component.ts:32:4: + 32 │ ButtonComponent, + ╵ ~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: LoaderComponent is not used within the template of CoursesListComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/courses/list/list.component.ts:18:73: + 18 │ ...nt, CommonModule, RouterModule, CourseComponent, LoaderComponent], + ╵ ~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: IconComponent is not used within the template of FeedComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/feed/feed.component.ts:36:4: + 36 │ IconComponent, + ╵ ~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.html:9:67: + 9 │ ...card__photo" [url]="member().personal?.avatar || ''" [size]="70" /> + ╵ ~~~~~~ + + Warning occurs in the template of component MemberCardComponent. + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.ts:16:15: + 16 │ templateUrl: "./member-card.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.html:15:66: + 15 │ ...er-card__secondary" [title]="member().personal?.speciality || ''"> + ╵ ~~~~~~~~~~ + + Warning occurs in the template of component MemberCardComponent. + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.ts:16:15: + 16 │ templateUrl: "./member-card.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.html:16:28: + 16 │ {{ member().personal?.speciality }} + ╵ ~~~~~~~~~~ + + Warning occurs in the template of component MemberCardComponent. + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.ts:16:15: + 16 │ templateUrl: "./member-card.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.html:17:30: + 17 │ @if (member().personal?.birthday; as birthday) { + ╵ ~~~~~~~~ + + Warning occurs in the template of component MemberCardComponent. + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.ts:16:15: + 16 │ templateUrl: "./member-card.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.html:18:30: + 18 │ {{ member().personal?.speciality ? " • " : "" }}{{ birth... + ╵ ~~~~~~~~~~ + + Warning occurs in the template of component MemberCardComponent. + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.ts:16:15: + 16 │ templateUrl: "./member-card.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: DialogFooterDirective is not used within the template of MemberFiltersDialogComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/members/member-filters-dialog/member-filters-dialog.component.ts:37:4: + 37 │ DialogFooterDirective, + ╵ ~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: ProfileInfoComponent is not used within the template of NavComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/office/nav/nav.component.ts:82:4: + 82 │ ProfileInfoComponent, + ╵ ~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: AlertDirective is not used within the template of SnackbarComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/office/snackbar/snackbar.component.ts:37:12: + 37 │ imports: [AlertDirective, CommonModule, IconComponent], + ╵ ~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/onboarding/stage-zero/stage-zero.component.html:435:45: + 435 │ ... @if (achievements.at(i)?.get("title"); as title) { + ╵ ~~~ + + Warning occurs in the template of component OnboardingStageZeroComponent. + + projects/social_platform/src/app/ui/pages/onboarding/stage-zero/stage-zero.component.ts:23:15: + 23 │ templateUrl: "./stage-zero.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8102: The left side of this nullish coalescing operation does not include 'null' or 'undefined' in its type, therefore the '??' operator can be safely removed. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-left-side/profile-left-side.component.html:28:15: + 28 │ ... {{ user()!.personal.speciality ?? "не указана" }} + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Warning occurs in the template of component ProfileLeftSideComponent. + + projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-left-side/profile-left-side.component.ts:23:15: + 23 │ templateUrl: "./profile-left-side.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: TruncatePipe is not used within the template of ProfileLeftSideComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-left-side/profile-left-side.component.ts:25:78: + 25 │ ...RouterModule, IconComponent, YearsFromBirthdayPipe, TruncatePipe], + ╵ ~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: TruncatePipe is not used within the template of ProfileRightSideComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-right-side/profile-right-side.component.ts:32:4: + 32 │ TruncatePipe, + ╵ ~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: UploadFileComponent is not used within the template of ProfileMainStepComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/profile/edit/components/profile-main-step/profile-main-step.component.ts:33:4: + 33 │ UploadFileComponent, + ╵ ~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/program/detail/list/list.component.html:95:52: + 95 │ ... [isSubscribed]="profileProjSubsIds()?.includes(listItem.id)" + ╵ ~~~~~~~~ + + Warning occurs in the template of component ProgramListComponent. + + projects/social_platform/src/app/ui/pages/program/detail/list/list.component.ts:40:15: + 40 │ templateUrl: "./list.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/program/detail/list/list.component.html:103:54: + 103 │ ... [isSubscribed]="profileProjSubsIds()?.includes(listItem.id)" + ╵ ~~~~~~~~ + + Warning occurs in the template of component ProgramListComponent. + + projects/social_platform/src/app/ui/pages/program/detail/list/list.component.ts:40:15: + 40 │ templateUrl: "./list.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/program/detail/main/main.component.html:73:64: + 73 │ ...)!.isUserMember && program()!.links?.length && program()!.links) { + ╵ ~~~~~~ + + Warning occurs in the template of component ProgramDetailMainComponent. + + projects/social_platform/src/app/ui/pages/program/detail/main/main.component.ts:38:15: + 38 │ templateUrl: "./main.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/program/detail/main/main.component.html:82:68: + 82 │ ... @if (program()!.isUserMember && program()!.materials?.length) { + ╵ ~~~~~~ + + Warning occurs in the template of component ProgramDetailMainComponent. + + projects/social_platform/src/app/ui/pages/program/detail/main/main.component.ts:38:15: + 38 │ templateUrl: "./main.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: BackComponent is not used within the template of ProgramComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/program/program.component.ts:22:4: + 22 │ BackComponent, + ╵ ~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: RouterLink is not used within the template of BarNewComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/bar-new/bar.component.ts:11:41: + 11 │ ...bsComponent, CommonModule, RouterLink, RouterLinkActive, IconCo... + ╵ ~~~~~~~~~~ + + +▲ [WARNING] NG8113: RouterLinkActive is not used within the template of BarNewComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/bar-new/bar.component.ts:11:53: + 11 │ ...onent, CommonModule, RouterLink, RouterLinkActive, IconComponent], + ╵ ~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: IconComponent is not used within the template of BarNewComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/bar-new/bar.component.ts:11:71: + 11 │ ...onent, CommonModule, RouterLink, RouterLinkActive, IconComponent], + ╵ ~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: MessageInputComponent is not used within the template of ProjectChatComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/detail/chat/chat.component.ts:34:4: + 34 │ MessageInputComponent, + ╵ ~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-achievement-step/project-achievement-step.component.html:10:39: + 10 │ ... @if (achievements.at(i)?.get("title"); as achievementsName) { + ╵ ~~~ + + Warning occurs in the template of component ProjectAchievementStepComponent. + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-achievement-step/project-achievement-step.component.ts:17:15: + 17 │ templateUrl: "./project-achievement-step.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-main-step/project-main-step.component.html:315:32: + 315 │ @if (goals.at(i)?.get("title"); as goalName) { + ╵ ~~~ + + Warning occurs in the template of component ProjectMainStepComponent. + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-main-step/project-main-step.component.ts:39:15: + 39 │ templateUrl: "./project-main-step.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-main-step/project-main-step.component.html:331:32: + 331 │ @if (goals.at(i)?.get("completionDate"); as goalDat... + ╵ ~~~ + + Warning occurs in the template of component ProjectMainStepComponent. + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-main-step/project-main-step.component.ts:39:15: + 39 │ templateUrl: "./project-main-step.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-main-step/project-main-step.component.html:353:32: + 353 │ @if (goals.at(i)?.get("responsible"); as goalLeader) { + ╵ ~~~ + + Warning occurs in the template of component ProjectMainStepComponent. + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-main-step/project-main-step.component.ts:39:15: + 39 │ templateUrl: "./project-main-step.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: IconComponent is not used within the template of ProjectNavigationComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-navigation/project-navigation.component.ts:25:27: + 25 │ imports: [TabsComponent, IconComponent, CommonModule], + ╵ ~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.html:11:37: + 11 │ @if (partners.at(i)?.get("name"); as name) { + ╵ ~~~ + + Warning occurs in the template of component ProjectPartnerResourcesStepComponent. + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.ts:20:15: + 20 │ templateUrl: "./project-partner-resources-step.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.html:27:37: + 27 │ @if (partners.at(i)?.get("inn"); as inn) { + ╵ ~~~ + + Warning occurs in the template of component ProjectPartnerResourcesStepComponent. + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.ts:20:15: + 20 │ templateUrl: "./project-partner-resources-step.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.html:46:35: + 46 │ ... @if (partners.at(i)?.get("contribution"); as contribut... + ╵ ~~~ + + Warning occurs in the template of component ProjectPartnerResourcesStepComponent. + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.ts:20:15: + 20 │ templateUrl: "./project-partner-resources-step.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.html:63:35: + 63 │ ... @if (partners.at(i)?.get("decisionMaker"); as decision... + ╵ ~~~ + + Warning occurs in the template of component ProjectPartnerResourcesStepComponent. + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.ts:20:15: + 20 │ templateUrl: "./project-partner-resources-step.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.html:116:36: + 116 │ @if (resources.at(i)?.get("type"); as type) { + ╵ ~~~ + + Warning occurs in the template of component ProjectPartnerResourcesStepComponent. + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.ts:20:15: + 20 │ templateUrl: "./project-partner-resources-step.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.html:133:36: + 133 │ ... @if (resources.at(i)?.get("description"); as descripti... + ╵ ~~~ + + Warning occurs in the template of component ProjectPartnerResourcesStepComponent. + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.ts:20:15: + 20 │ templateUrl: "./project-partner-resources-step.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.html:150:36: + 150 │ ... @if (resources.at(i)?.get("partnerCompany"); as partne... + ╵ ~~~ + + Warning occurs in the template of component ProjectPartnerResourcesStepComponent. + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.ts:20:15: + 20 │ templateUrl: "./project-partner-resources-step.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8109: isFilterOpen is a function and should be invoked: isFilterOpen() [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/projects.component.html:94:73: + 94 │ ...s="filter page__filter" [class.page__filter--open]="isFilterOpen"> + ╵ ~~~~~~~~~~~~ + + Warning occurs in the template of component ProjectsComponent. + + projects/social_platform/src/app/ui/pages/projects/projects.component.ts:30:15: + 30 │ templateUrl: "./projects.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: BackComponent is not used within the template of ProjectsComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/projects/projects.component.ts:42:4: + 42 │ BackComponent, + ╵ ~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-left-side/vacancies-left-side.component.html:7:29: + 7 │ @if (item.description?.trim()) { + ╵ ~~~~ + + Warning occurs in the template of component VacanciesLeftSideComponent. + + projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-left-side/vacancies-left-side.component.ts:9:15: + 9 │ templateUrl: "./vacancies-left-side.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8107: The left side of this optional chain operation does not include 'null' or 'undefined' in its type, therefore the '?.' operator can be replaced with the '.' operator. [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-right-side/vacancies-right-side.component.html:57:23: + 57 │ @if (item.project?.links?.length) { + ╵ ~~~~~ + + Warning occurs in the template of component VacanciesRightSideComponent. + + projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-right-side/vacancies-right-side.component.ts:14:15: + 14 │ templateUrl: "./vacancies-right-side.component.html", + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: IconComponent is not used within the template of VacanciesListComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/vacancies/list/list.component.ts:30:4: + 30 │ IconComponent, + ╵ ~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: BackComponent is not used within the template of VacanciesComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/pages/vacancies/vacancies.component.ts:27:4: + 27 │ BackComponent, + ╵ ~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: RouterLink is not used within the template of BarComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/primitives/bar/bar.component.ts:38:41: + 38 │ ...bsComponent, CommonModule, RouterLink, RouterLinkActive, BackCo... + ╵ ~~~~~~~~~~ + + +▲ [WARNING] NG8113: RouterLinkActive is not used within the template of BarComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/primitives/bar/bar.component.ts:38:53: + 38 │ ...onent, CommonModule, RouterLink, RouterLinkActive, BackComponent], + ╵ ~~~~~~~~~~~~~~~~ + + +▲ [WARNING] NG8113: CardDirective is not used within the template of NewsCardComponent [plugin angular-compiler] + + projects/social_platform/src/app/ui/widgets/news-card/news-card.component.ts:58:4: + 58 │ CardDirective, + ╵ ~~~~~~~~~~~~~ + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.scss:121:4: + 121 │ margin-top: auto; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.scss:128:2: + 128 │ padding-top: 45px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/projects/detail/team/team.component.scss:19:4: + 19 │ row-gap: 48px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/pages/projects/edit/components/project-additional-step/project-additional-step.component.scss:24:2: + 24 │ position: relative; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/autocomplete-input/autocomplete-input.component.scss:56:6: + 56 │ + &_arrow { + ╵ ^ + + + The selector "+ .field__input-slim:focus_arrow" is invalid CSS. + This will be an error in Dart Sass 2.0.0. + + More info: https://sass-lang.com/d/bogus-combinators + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/autocomplete-input/autocomplete-input.component.scss:59:8: + 59 │ i { + ╵ ^ + + + The selector "+ .field__input-slim:focus_arrow i" is invalid CSS. + This will be an error in Dart Sass 2.0.0. + + More info: https://sass-lang.com/d/bogus-combinators + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/modal/modal.component.scss:71:8: + 71 │ position: sticky; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/modal/modal.component.scss:72:8: + 72 │ bottom: 0; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/modal/modal.component.scss:73:8: + 73 │ z-index: 2; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/modal/modal.component.scss:74:8: + 74 │ justify-content: center; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/modal/modal.component.scss:75:8: + 75 │ padding-top: 8px; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/primitives/textarea/textarea.component.scss:62:4: + 62 │ border-radius: var(--ui-radius-card); + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/app/ui/widgets/info-card/info-card.component.scss:59:4: + 59 │ width: 100%; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/ui/src/lib/components/primitives/button/button.component.scss:14:2: + 14 │ position: relative; + ╵ ^ + + + Sass's behavior for declarations that appear after nested + rules will be changing to match the behavior specified by CSS in an upcoming + version. To keep the existing behavior, move the declaration above the nested + rule. To opt into the new behavior, wrap the declaration in `& {}`. + + More info: https://sass-lang.com/d/mixed-decls + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/styles.scss:9:8: + 9 │ @import "styles/colors.scss"; + ╵ ^ + + + Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0. + + More info and automated migrator: https://sass-lang.com/d/import + + The plugin "angular-sass" was triggered by this import + + angular:styles/global:styles:1:8: + 1 │ @import 'projects/social_platform/src/styles.scss'; + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/styles.scss:10:8: + 10 │ @import "styles/global.scss"; + ╵ ^ + + + Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0. + + More info and automated migrator: https://sass-lang.com/d/import + + The plugin "angular-sass" was triggered by this import + + angular:styles/global:styles:1:8: + 1 │ @import 'projects/social_platform/src/styles.scss'; + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/styles.scss:11:8: + 11 │ @import "styles/responsive.scss"; + ╵ ^ + + + Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0. + + More info and automated migrator: https://sass-lang.com/d/import + + The plugin "angular-sass" was triggered by this import + + angular:styles/global:styles:1:8: + 1 │ @import 'projects/social_platform/src/styles.scss'; + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/styles.scss:12:8: + 12 │ @import "styles/rounded.scss"; + ╵ ^ + + + Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0. + + More info and automated migrator: https://sass-lang.com/d/import + + The plugin "angular-sass" was triggered by this import + + angular:styles/global:styles:1:8: + 1 │ @import 'projects/social_platform/src/styles.scss'; + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] Deprecation [plugin angular-sass] + + projects/social_platform/src/styles.scss:13:8: + 13 │ @import "styles/typography.scss"; + ╵ ^ + + + Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0. + + More info and automated migrator: https://sass-lang.com/d/import + + The plugin "angular-sass" was triggered by this import + + angular:styles/global:styles:1:8: + 1 │ @import 'projects/social_platform/src/styles.scss'; + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +▲ [WARNING] 11 repetitive deprecation warnings omitted. +Run in verbose mode to see all warnings. [plugin angular-sass] + + angular:styles/global:styles:1:8: + 1 │ @import 'projects/social_platform/src/styles.scss'; + ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + null + + +▲ [WARNING] bundle initial exceeded maximum budget. Budget 500.00 kB was not met by 920.77 kB with a total of 1.42 MB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/office/office.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 1.33 kB with a total of 3.33 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/profile/edit/components/profile-skills-step/profile-skills-step.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 587 bytes with a total of 2.59 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-right-side/profile-right-side.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 1.40 kB with a total of 3.40 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/profile/edit/components/profile-achievements-step/profile-achievements-step.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 410 bytes with a total of 2.41 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/auth/email-verification/email-verification.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.38 kB with a total of 4.38 kB. + + +▲ [WARNING] projects/ui/src/lib/components/primitives/button/button.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 944 bytes with a total of 2.94 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/primitives/search/search.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 323 bytes with a total of 2.32 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/projects/list/list.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 519 bytes with a total of 2.52 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/news-card/news-card.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.80 kB with a total of 6.80 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/onboarding/stage-zero/stage-zero.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 1.06 kB with a total of 3.06 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/primitives/select/select.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.70 kB with a total of 6.70 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/feed/new-project/new-project.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 1.28 kB with a total of 3.28 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/courses/lesson/shared/radio-select-task/radio-select-task.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.75 kB with a total of 6.75 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/profile/edit/components/profile-education-step/profile-education-step.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 328 bytes with a total of 2.33 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/projects/edit/edit.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.37 kB with a total of 6.37 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-left-side/profile-left-side.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 1.25 kB with a total of 3.25 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/onboarding/stage-three/user-type-card/user-type-card.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.27 kB with a total of 4.27 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancy-responses/vacancy-responses.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 888 bytes with a total of 2.89 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/news-card/carousel/carousel.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.14 kB with a total of 5.14 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/program/detail/main/role-widget/program-role-widget.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.50 kB with a total of 4.50 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/profile/edit/edit.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 7.33 kB with a total of 9.33 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/skills-basket/skills-basket.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.01 kB with a total of 5.01 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/projects/edit/components/project-team-step/invite-card/invite-card.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 447 bytes with a total of 2.45 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/courses/lesson/shared/file-task/file-task.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.87 kB with a total of 6.87 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/project-rating/project-rating.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.37 kB with a total of 4.37 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/projects/edit/components/project-main-step/project-main-step.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 5.04 kB with a total of 7.04 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/project-rating/components/range-criterion-input/range-criterion-input.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.24 kB with a total of 4.24 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/rating-card.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.63 kB with a total of 6.63 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/primitives/tag/tag.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 1.12 kB with a total of 3.12 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/chat-window/chat-message/chat-message.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.23 kB with a total of 5.23 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/program/detail/analytics/analytics.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 11.24 kB with a total of 13.24 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/profile/edit/components/profile-experience-step/profile-experience-step.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 328 bytes with a total of 2.33 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/projects/edit/components/project-partner-resources-step/project-partner-resources-step.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.04 kB with a total of 4.04 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/courses/list/course/course.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.65 kB with a total of 4.65 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/program/detail/main/main.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.27 kB with a total of 6.27 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/primitives/avatar-control/avatar-control.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 262 bytes with a total of 2.26 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/project-direction-card/project-direction-card.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 1.74 kB with a total of 3.74 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/profile/edit/components/profile-main-step/profile-main-step.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 239 bytes with a total of 2.24 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/courses/lesson/shared/exclude-task/exclude-task.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.25 kB with a total of 6.25 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/vacancies/detail/info/info.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.11 kB with a total of 6.11 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/onboarding/stage-three/stage-three.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.13 kB with a total of 4.13 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/news-card/feed-news-preview/feed-news-preview.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.96 kB with a total of 5.96 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/projects-filter/projects-filter.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.85 kB with a total of 4.85 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/members/members-filters/members-filters.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.15 kB with a total of 4.15 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/courses/lesson/lesson.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.28 kB with a total of 5.28 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/primitives/autocomplete-input/autocomplete-input.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 6.50 kB with a total of 8.50 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/onboarding/stage-two/stage-two.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.49 kB with a total of 6.49 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/onboarding/stage-one/stage-one.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.50 kB with a total of 5.50 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/news-card/feed-news-modal/feed-news-modal.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 825 bytes with a total of 2.83 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/project-invite/project-invite-dialog.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 7.79 kB with a total of 9.79 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/projects/edit/components/project-achievement-step/project-achievement-step.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.19 kB with a total of 4.19 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/courses/lesson/complete/complete.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.27 kB with a total of 4.27 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/vacancy-filter/vacancy-filter.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.55 kB with a total of 5.55 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.30 kB with a total of 5.30 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/courses/detail/info/course-module-card/circle-progress-bar/circle-progress-bar.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.08 kB with a total of 4.08 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/message-input/message-input.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.54 kB with a total of 6.54 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/program/detail/list/list.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 6.26 kB with a total of 8.26 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/feed/open-vacancy/open-vacancy.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 1.11 kB with a total of 3.12 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/courses/detail/course-detail.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.42 kB with a total of 5.42 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/program/detail/analytics/drilldown/analytics-drilldown.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 8.02 kB with a total of 10.02 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/project-vacancy-card/project-vacancy-card.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 426 bytes with a total of 2.43 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/info-card/info-card.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 9.60 kB with a total of 11.60 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/program/detail/list/program-projects-filter/program-projects-filter.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.26 kB with a total of 5.26 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/primitives/textarea/textarea.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.48 kB with a total of 6.48 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/projects/edit/components/project-team-step/collaborator-card/collaborator-card.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 447 bytes with a total of 2.45 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/courses/detail/info/info.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.16 kB with a total of 5.16 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/primitives/input/input.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 5.90 kB with a total of 7.90 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/courses/lesson/shared/write-task/write-task.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 1.04 kB with a total of 3.04 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/auth/login/login.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.44 kB with a total of 5.44 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/primitives/tooltip/tooltip.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.80 kB with a total of 5.80 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/courses/courses.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 2.07 kB with a total of 4.07 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/widgets/detail/detail.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 8.08 kB with a total of 10.08 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/office/nav/nav.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.77 kB with a total of 5.77 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/projects/edit/components/project-additional-step/project-additional-step.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.22 kB with a total of 6.22 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/projects/edit/components/project-vacancy-step/project-vacancy-step.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 4.34 kB with a total of 6.34 kB. + + +▲ [WARNING] projects/social_platform/src/app/ui/pages/auth/register/register.component.scss exceeded maximum budget. Budget 2.00 kB was not met by 3.09 kB with a total of 5.09 kB. + + +▲ [WARNING] Module 'dayjs' used by 'projects/social_platform/src/app/api/auth/facades/ui/auth-ui-info.service.ts' is not ESM + + CommonJS or AMD dependencies can cause optimization bailouts. + For more information see: https://angular.dev/tools/cli/build#configuring-commonjs-dependencies + + +▲ [WARNING] Module 'snakecase-keys' used by 'projects/core/src/lib/interceptors/camelcase.interceptor.ts' is not ESM + + CommonJS or AMD dependencies can cause optimization bailouts. + For more information see: https://angular.dev/tools/cli/build#configuring-commonjs-dependencies + + +▲ [WARNING] Module 'dayjs/plugin/customParseFormat' used by 'projects/core/src/lib/services/validation/validation.service.ts' is not ESM + + CommonJS or AMD dependencies can cause optimization bailouts. + For more information see: https://angular.dev/tools/cli/build#configuring-commonjs-dependencies + + +▲ [WARNING] Module 'dayjs/plugin/relativeTime' used by 'projects/core/src/lib/services/validation/validation.service.ts' is not ESM + + CommonJS or AMD dependencies can cause optimization bailouts. + For more information see: https://angular.dev/tools/cli/build#configuring-commonjs-dependencies + + +▲ [WARNING] Module 'dayjs/plugin/isToday' used by 'projects/core/src/lib/pipes/formatters/dayjs.pipe.ts' is not ESM + + CommonJS or AMD dependencies can cause optimization bailouts. + For more information see: https://angular.dev/tools/cli/build#configuring-commonjs-dependencies + + +▲ [WARNING] Module 'dayjs/locale/ru' used by 'projects/core/src/lib/pipes/formatters/dayjs.pipe.ts' is not ESM + + CommonJS or AMD dependencies can cause optimization bailouts. + For more information see: https://angular.dev/tools/cli/build#configuring-commonjs-dependencies + + +▲ [WARNING] Module 'file-saver' used by 'projects/social_platform/src/app/utils/export-file.ts' is not ESM + + CommonJS or AMD dependencies can cause optimization bailouts. + For more information see: https://angular.dev/tools/cli/build#configuring-commonjs-dependencies + + +▲ [WARNING] Module 'map-obj' used by 'node_modules/camelcase-keys/index.js' is not ESM + + CommonJS or AMD dependencies can cause optimization bailouts. + For more information see: https://angular.dev/tools/cli/build#configuring-commonjs-dependencies + + +Output location: Z:\Документы\PROCOLLAB-dev\procollab-dev-platform-responsive\dist\social_platform + diff --git a/docs/mobile-polish/fixtures.cjs b/docs/mobile-polish/fixtures.cjs new file mode 100644 index 000000000..1ce136e31 --- /dev/null +++ b/docs/mobile-polish/fixtures.cjs @@ -0,0 +1,41 @@ +/** @format */ + +const fixtures = require("../responsive/fixtures.cjs"); +fixtures.user.firstName = "Алексей"; +fixtures.user.lastName = "Куделько"; +fixtures.project.name = "Городские проекты"; +fixtures.project.shortDescription = "Сервис для студенческих команд"; +fixtures.project.region = "Ростовская область"; +fixtures.project.partnerProgram = { + id: 1, + programId: 1, + programLinkId: 1, + name: "Акселератор студенческих проектов", + isSubmitted: false, + canSubmit: true, + programFields: [], + programFieldValues: [], +}; +fixtures.program.name = "Кейс-чемпионат студенческих проектов"; +fixtures.vacancy.role = "Дизайнер интерфейсов"; +fixtures.vacancy.description = "Помогите создавать понятные интерфейсы для студенческих команд."; +fixtures.vacancy.requiredSkills = [ + "Мотивированность", + "Глубинное интервью", + "Проектирование пользовательского опыта", + "Figma", +].map((name, id) => ({ id: id + 1, name, category: { id: 1, name: "Soft skills" }, approves: [] })); +const response = fixtures.response; +fixtures.response = (pathname, method, query, state) => + /\/feed\/$/.test(pathname) + ? { + count: 1, + next: null, + previous: null, + counts: { all: 88, project: 56, vacancy: 1, news: 31, partnerprogram: 0, education: 0 }, + results: [ + { typeModel: "vacancy", content: fixtures.vacancy, publishedAt: "2026-09-29T12:00:00Z" }, + ], + } + : response(pathname, method, query, state); +module.exports = fixtures; diff --git a/docs/mobile-polish/format-all.log b/docs/mobile-polish/format-all.log new file mode 100644 index 000000000..4aa0d16e7 --- /dev/null +++ b/docs/mobile-polish/format-all.log @@ -0,0 +1,2 @@ +Checking formatting... +All matched files use Prettier code style! diff --git a/docs/mobile-polish/format.log b/docs/mobile-polish/format.log new file mode 100644 index 000000000..4aa0d16e7 --- /dev/null +++ b/docs/mobile-polish/format.log @@ -0,0 +1,2 @@ +Checking formatting... +All matched files use Prettier code style! diff --git a/docs/mobile-polish/info-card-tests.log b/docs/mobile-polish/info-card-tests.log new file mode 100644 index 000000000..c00a8f3a4 --- /dev/null +++ b/docs/mobile-polish/info-card-tests.log @@ -0,0 +1,11 @@ + + RUN v3.2.6 Z:/Документы/PROCOLLAB-dev/procollab-dev-platform-responsive + + ✓ projects/social_platform/src/app/ui/widgets/info-card/info-card.component.spec.ts (41 tests) 1426ms + ✓ InfoCardComponent: статусы моих проектов > 'draft' / 'Лидер': статус, доступ и единственный корректный маршрут 340ms + + Test Files 1 passed (1) + Tests 41 passed (41) + Start at 22:52:23 + Duration 10.62s (transform 6.29s, setup 3.01s, collect 4.41s, tests 1.43s, environment 1.27s, prepare 1.47s) + diff --git a/docs/mobile-polish/interactions.cjs b/docs/mobile-polish/interactions.cjs new file mode 100644 index 000000000..75312ccca --- /dev/null +++ b/docs/mobile-polish/interactions.cjs @@ -0,0 +1,184 @@ +/** @format */ + +const fs = require("node:fs"); +const path = require("node:path"); +const assert = require("node:assert/strict"); +const { launch, assertViewport } = require("../responsive/browser-harness.cjs"); +const fixtures = require("./fixtures.cjs"); +const rows = []; +const directory = path.join(__dirname, "screenshots", "interactions"); +fs.mkdirSync(directory, { recursive: true }); + +async function goto(h, route, selector) { + h.errors.length = 0; + await h.page.goto(h.base + route); + await h.page.waitForLoadState("networkidle"); + await h.page.locator(selector).first().waitFor(); +} + +async function check(h, name, width, details = {}) { + const measurement = await assertViewport(h.page); + assert.deepEqual(h.errors, []); + const screenshot = `screenshots/interactions/${name}-${width}.png`; + await h.page.screenshot({ path: path.join(__dirname, screenshot), fullPage: true }); + rows.push({ name, width, passed: true, ...details, ...measurement, screenshot }); + console.log(`${name} ${width}: passed`); +} + +(async () => { + for (const width of [320, 390, 768]) { + const h = await launch(width, { isMobile: width < 750, hasTouch: width < 750 }); + h.page.setDefaultTimeout(10000); + try { + await goto(h, "/office/program/all", "app-program-card"); + const region = h.page.locator(".card__region").first(); + assert.equal((await region.textContent()).trim(), "для всей России"); + assert.ok(await region.evaluate(el => el.scrollWidth <= el.clientWidth + 1)); + await h.page.getByRole("button", { name: "Открыть меню", exact: true }).click(); + assert.equal(await h.page.getByRole("button", { name: "Выйти", exact: true }).count(), 1); + await h.page.locator("#mobile-navigation a[routerLink=feed]").click(); + await h.page.locator("app-open-vacancy").waitFor(); + await h.page.waitForLoadState("networkidle"); + assert.equal((await h.page.locator(".nav-bar__title").textContent()).trim(), "Новости"); + const title = await h.page.locator(".nav-bar__title").boundingBox(); + const header = await h.page.locator(".office__top").boundingBox(); + assert.ok(Math.abs(title.x + title.width / 2 - header.x - header.width / 2) <= 1); + assert.equal( + await h.page.locator(".office__top").evaluate(el => getComputedStyle(el).backgroundImage), + "none", + ); + for (const selector of [ + ".nav-bar__toggle", + "button.control-panel__action", + ".control-panel__profile .user", + ]) { + const box = await h.page.locator(selector).boundingBox(); + assert.ok(box.width >= 44 && box.height >= 44, selector + " target"); + } + assert.equal(await h.page.locator("app-feed-filter .filter__option").count(), 6); + assert.equal(await h.page.locator("app-feed-filter .select").count(), 0); + const notifications = h.page.getByRole("button", { name: "Уведомления", exact: true }); + await notifications.focus(); + await h.page.keyboard.press("Enter"); + await h.page.locator(".control-panel__notifications").waitFor(); + assert.equal(await notifications.getAttribute("aria-expanded"), "true"); + await h.page.locator("app-open-vacancy h3").click(); + await h.page.locator(".control-panel__notifications").waitFor({ state: "detached" }); + const noOverlap = await h.page + .locator("app-feed-filter .filter__option") + .evaluateAll(options => + options.every(option => { + const icon = option.querySelector(".filter__option--icon").getBoundingClientRect(); + const label = option.querySelector(".filter__title").getBoundingClientRect(); + const count = option.querySelector(".filter__count").getBoundingClientRect(); + return ( + icon.right <= label.left && (label.bottom <= count.top || label.right <= count.left) + ); + }), + ); + assert.ok(noOverlap); + const toggle = h.page.locator("app-open-vacancy .skills__toggle"); + await toggle.click(); + await h.page.locator("app-open-vacancy app-tag").nth(3).waitFor(); + assert.equal(await toggle.getAttribute("aria-expanded"), "true"); + assert.equal(await h.page.locator("app-open-vacancy app-tag").count(), 4); + const skillVisible = await h.page.locator("app-open-vacancy app-tag").evaluateAll(tags => + tags.every(tag => { + const el = tag.querySelector("p") || tag; + const s = getComputedStyle(el); + return s.textOverflow !== "ellipsis" && el.scrollWidth <= el.clientWidth + 1; + }), + ); + assert.ok(skillVisible); + const category = h.page.locator(".filter__option").filter({ hasText: "свежие вакансии" }); + await category.click(); + await h.page.waitForURL(/includes=vacancy/); + await h.page.waitForLoadState("networkidle"); + assert.equal(await category.getAttribute("aria-pressed"), "true"); + assert.ok(h.requests.some(r => /\/feed\/$/.test(r.path) && /type=vacancy/.test(r.query))); + const disabled = h.page.getByRole("button", { name: /образование/ }); + assert.equal(await disabled.isDisabled(), true); + const url = h.page.url(); + await disabled.evaluate(el => el.click()); + assert.equal(h.page.url(), url); + await check(h, "navigation-feed-skills", width); + + await goto(h, "/office/projects/dashboard", "app-info-card"); + const activity = await h.page.locator("app-project-activity-card").boundingBox(); + const list = await h.page.locator(".page__outlet").boundingBox(); + const parent = await h.page.locator(".page__info").boundingBox(); + assert.ok(activity.y + activity.height <= list.y + 1); + assert.ok(Math.abs(activity.width - parent.width) <= 1); + assert.equal( + await h.page + .locator(".activity__metrics") + .evaluate(el => getComputedStyle(el).gridTemplateColumns.split(" ").length), + 2, + ); + const card = await h.page.locator("app-info-card .card__body").first().boundingBox(); + assert.ok(card.width <= 261 && card.width < parent.width); + await check(h, "projects-activity", width); + + await goto(h, "/office/members", "app-member-card"); + const member = await h.page.locator("app-member-card .member-card").first().boundingBox(); + assert.ok(member.width <= 261); + await check(h, "members", width); + + for (const [name, route] of [ + ["profile", "/office/profile/1"], + ["project", "/office/projects/1"], + ["program", "/office/program/1"], + ]) { + await goto(h, route, ".info__actions app-button"); + const actions = await h.page.locator(".info__actions").boundingBox(); + const children = await h.page + .locator( + ".info__actions > a, .info__actions > app-button, .info__actions > .info__unavailable", + ) + .all(); + for (const child of children) { + if (!(await child.isVisible())) continue; + const box = await child.boundingBox(); + assert.ok(Math.abs(box.width - (actions.width - 12) / 2) <= 1, `${name} action column`); + const button = child.locator("button").first(); + const buttonBox = await button.boundingBox(); + assert.ok( + buttonBox.height >= 44 && Math.abs(buttonBox.width - box.width) <= 1, + `${name} button target`, + ); + } + assert.equal(await h.page.locator(".info__divider:visible").count(), 0); + assert.ok((await h.page.locator(".info__page-header").textContent()).trim().length > 0); + if (name === "project") { + const metadata = await h.page.locator("app-projects-left-side").boundingBox(); + assert.ok(metadata.width > actions.width - 2, "project metadata full width"); + } + if (name === "program") { + const contacts = h.page.getByRole("button", { name: "Контакты", exact: true }); + assert.equal(await contacts.count(), 1); + assert.equal(await contacts.isDisabled(), true); + } + await check(h, `${name}-actions`, width); + } + await h.page.getByRole("link", { name: "Мой профиль", exact: true }).click(); + await h.page.waitForURL(/\/office\/profile\/1$/); + await h.page.waitForLoadState("networkidle"); + assert.equal((await h.page.locator(".nav-bar__title").textContent()).trim(), "Профиль"); + await h.page.getByRole("button", { name: "Открыть меню", exact: true }).click(); + await h.page.keyboard.press("Escape"); + await h.page.locator("#mobile-navigation").waitFor({ state: "detached" }); + assert.equal(await h.page.locator("#mobile-navigation").count(), 0); + assert.equal( + await h.page.locator(".nav-bar__toggle").evaluate(el => document.activeElement === el), + true, + ); + } finally { + await h.browser.close(); + } + } + fs.writeFileSync(path.join(__dirname, "interactions.json"), JSON.stringify(rows, null, 2) + "\n"); + console.log(`${rows.length} interaction screens passed`); +})().catch(error => { + console.error(error); + process.exitCode = 1; +}); diff --git a/docs/mobile-polish/interactions.json b/docs/mobile-polish/interactions.json new file mode 100644 index 000000000..0ab753dd2 --- /dev/null +++ b/docs/mobile-polish/interactions.json @@ -0,0 +1,917 @@ +[ + { + "name": "navigation-feed-skills", + "width": 320, + "passed": true, + "actualPath": "/office/feed", + "actualQuery": "?includes=vacancy", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag" + ], + "text": "Новости\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости программ\n0\nобразование\n0\nНовая вакансия\n29.09.2026\nПроект / компания\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nДизайнер интерф", + "screenshot": "screenshots/interactions/navigation-feed-skills-320.png" + }, + { + "name": "projects-activity", + "width": 320, + "passed": true, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nпоказать раздел\n\nмои подписки\n\nГородские проекты\n\nСервис для студенческих команд\n\nОткрыть\nпок", + "screenshot": "screenshots/interactions/projects-activity-320.png" + }, + { + "name": "members", + "width": 320, + "passed": true, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card" + ], + "text": "Участники\nучастники\nФильтры\nПерейти в профиль\nСтатистика\nВсего участников\n—\nВ проектах\n—\nВ программах\n—\nНе удалось загрузить статистику участников\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nРазработчик • 26 л", + "screenshot": "screenshots/interactions/members-320.png" + }, + { + "name": "profile-actions", + "width": 320, + "passed": true, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Профиль\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nнавыки\n\n0 / 15940\n\n01.10.2026\n\nОченьДлинно", + "screenshot": "screenshots/interactions/profile-actions-320.png" + }, + { + "name": "project-actions", + "width": 320, + "passed": true, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "Профиль проекта\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАкселератор студенческих проектов\nСфера\n\nИнформационные технологии\n\nРегион\n\nРостовская область\n\nTRL\n\n1\n\nСрок реализации\n\n2027-01-01\n\nЛидер\nТестовый ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ", + "screenshot": "screenshots/interactions/project-actions-320.png" + }, + { + "name": "program-actions", + "width": 320, + "passed": true, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "Программы\nКейс-чемпионат студенческих проектов\nоценка проектов\nаналитика\nКонтакты\nпроекты-участники\nучастники\nматериалы\nаналитика\nорганизатор\nУчастники\n1\nПроекты\n1\nСдано\nрешений\n0\nБез проектов\n0\n0,0%\nОткрыть →\nо программе\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНаз", + "screenshot": "screenshots/interactions/program-actions-320.png" + }, + { + "name": "navigation-feed-skills", + "width": 390, + "passed": true, + "actualPath": "/office/feed", + "actualQuery": "?includes=vacancy", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag" + ], + "text": "Новости\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости программ\n0\nобразование\n0\nНовая вакансия\n29.09.2026\nПроект / компания\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nДизайнер интерф", + "screenshot": "screenshots/interactions/navigation-feed-skills-390.png" + }, + { + "name": "projects-activity", + "width": 390, + "passed": true, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nпоказать раздел\n\nмои подписки\n\nГородские проекты\n\nСервис для студенческих команд\n\nОткрыть\nпок", + "screenshot": "screenshots/interactions/projects-activity-390.png" + }, + { + "name": "members", + "width": 390, + "passed": true, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card" + ], + "text": "Участники\nучастники\nФильтры\nПерейти в профиль\nСтатистика\nВсего участников\n—\nВ проектах\n—\nВ программах\n—\nНе удалось загрузить статистику участников\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nРазработчик • 26 л", + "screenshot": "screenshots/interactions/members-390.png" + }, + { + "name": "profile-actions", + "width": 390, + "passed": true, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Профиль\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nнавыки\n\n0 / 15940\n\n01.10.2026\n\nОченьДлинно", + "screenshot": "screenshots/interactions/profile-actions-390.png" + }, + { + "name": "project-actions", + "width": 390, + "passed": true, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "Профиль проекта\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАкселератор студенческих проектов\nСфера\n\nИнформационные технологии\n\nРегион\n\nРостовская область\n\nTRL\n\n1\n\nСрок реализации\n\n2027-01-01\n\nЛидер\nТестовый ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ", + "screenshot": "screenshots/interactions/project-actions-390.png" + }, + { + "name": "program-actions", + "width": 390, + "passed": true, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "Программы\nКейс-чемпионат студенческих проектов\nоценка проектов\nаналитика\nКонтакты\nпроекты-участники\nучастники\nматериалы\nаналитика\nорганизатор\nУчастники\n1\nПроекты\n1\nСдано\nрешений\n0\nБез проектов\n0\n0,0%\nОткрыть →\nо программе\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНаз", + "screenshot": "screenshots/interactions/program-actions-390.png" + }, + { + "name": "navigation-feed-skills", + "width": 768, + "passed": true, + "actualPath": "/office/feed", + "actualQuery": "?includes=vacancy", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-open-vacancy", + "app-vacancy-skills", + "app-tag" + ], + "text": "Новости\nвсе новости\n88\nновости проектов\n56\nсвежие вакансии\n1\nновости сообщества\n31\nновости программ\n0\nобразование\n0\nНовая вакансия\n29.09.2026\nПроект / компания\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nДизайнер интерф", + "screenshot": "screenshots/interactions/navigation-feed-skills-768.png" + }, + { + "name": "projects-activity", + "width": 768, + "passed": true, + "actualPath": "/office/projects/dashboard", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-modal", + "app-state", + "app-project-activity-card", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-dashboard", + "app-dashboard-item", + "app-info-card", + "app-state", + "app-project-activity-card" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\n\nПривязан к программе\n\nГородские проекты\n\nПрограмма: Акселератор студенческих проектов\n\nСервис для студенческих команд\n\nЛидер\n\nможно редактировать\n\nОткрыть\nпоказать раздел\n\nмои подписки\n\nГородские проекты\n\nСервис для студенческих команд\n\nОткрыть\nпок", + "screenshot": "screenshots/interactions/projects-activity-768.png" + }, + { + "name": "members", + "width": 768, + "passed": true, + "actualPath": "/office/members", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-members", + "app-page-header", + "app-back", + "app-member-statistics-card", + "app-member-card" + ], + "text": "Участники\nучастники\nФильтры\nПерейти в профиль\nСтатистика\nВсего участников\n—\nВ проектах\n—\nВ программах\n—\nНе удалось загрузить статистику участников\nКандидат\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nРазработчик • 26 л", + "screenshot": "screenshots/interactions/members-768.png" + }, + { + "name": "profile-actions", + "width": 768, + "passed": true, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Профиль\nАлексей Куделько\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nнавыки\n\n0 / 15940\n\n01.10.2026\n\nОченьДлинно", + "screenshot": "screenshots/interactions/profile-actions-768.png" + }, + { + "name": "project-actions", + "width": 768, + "passed": true, + "actualPath": "/office/projects/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-modal", + "app-news-card", + "app-carousel", + "app-projects-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-projects-left-side", + "app-projects-mid-side", + "app-news-form", + "app-textarea", + "app-project-direction-card", + "app-news-card", + "app-projects-right-side" + ], + "text": "Профиль проекта\nГородские проекты\nрабочая зона\nчат проекта\nкоманда\nредактировать\nосновное\nПрограмма\nАкселератор студенческих проектов\nСфера\n\nИнформационные технологии\n\nРегион\n\nРостовская область\n\nTRL\n\n1\n\nСрок реализации\n\n2027-01-01\n\nЛидер\nТестовый ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ", + "screenshot": "screenshots/interactions/project-actions-768.png" + }, + { + "name": "program-actions", + "width": 768, + "passed": true, + "actualPath": "/office/program/1", + "actualQuery": "", + "viewport": 768, + "pageWidth": 753, + "bodyWidth": 753, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-main", + "app-program-role-widget", + "app-news-form", + "app-textarea", + "app-news-card" + ], + "text": "Программы\nКейс-чемпионат студенческих проектов\nоценка проектов\nаналитика\nКонтакты\nпроекты-участники\nучастники\nматериалы\nаналитика\nорганизатор\nУчастники\n1\nПроекты\n1\nСдано\nрешений\n0\nБез проектов\n0\n0,0%\nОткрыть →\nо программе\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНаз", + "screenshot": "screenshots/interactions/program-actions-768.png" + } +] diff --git a/docs/mobile-polish/interactions.log b/docs/mobile-polish/interactions.log new file mode 100644 index 000000000..d7b0bd150 --- /dev/null +++ b/docs/mobile-polish/interactions.log @@ -0,0 +1,19 @@ +navigation-feed-skills 320: passed +projects-activity 320: passed +members 320: passed +profile-actions 320: passed +project-actions 320: passed +program-actions 320: passed +navigation-feed-skills 390: passed +projects-activity 390: passed +members 390: passed +profile-actions 390: passed +project-actions 390: passed +program-actions 390: passed +navigation-feed-skills 768: passed +projects-activity 768: passed +members 768: passed +profile-actions 768: passed +project-actions 768: passed +program-actions 768: passed +18 interaction screens passed diff --git a/docs/mobile-polish/lint.log b/docs/mobile-polish/lint.log new file mode 100644 index 000000000..9008d29f4 --- /dev/null +++ b/docs/mobile-polish/lint.log @@ -0,0 +1,20 @@ + +> procollab@0.0.0 lint:ts +> eslint projects/**/*.ts + + +Z:\Документы\PROCOLLAB-dev\procollab-dev-platform-responsive\projects\core\src\lib\services\logger\logger.service.ts + 47:3 warning Unused eslint-disable directive (no problems were reported from 'no-console') + 61:3 warning Unused eslint-disable directive (no problems were reported from 'no-console') + 73:3 warning Unused eslint-disable directive (no problems were reported from 'no-console') + 85:3 warning Unused eslint-disable directive (no problems were reported from 'no-console') + +Z:\Документы\PROCOLLAB-dev\procollab-dev-platform-responsive\projects\social_platform\src\app\domain\chat\chat-message.model.ts + 22:3 warning Unused eslint-disable directive (no problems were reported from 'no-use-before-define') + +Z:\Документы\PROCOLLAB-dev\procollab-dev-platform-responsive\projects\social_platform\src\app\ui\widgets\message-input\message-input.component.ts + 176:3 warning Unused eslint-disable directive (no problems were reported from 'no-use-before-define') + +✖ 6 problems (0 errors, 6 warnings) + 0 errors and 6 warnings potentially fixable with the `--fix` option. + diff --git a/docs/mobile-polish/review.md b/docs/mobile-polish/review.md new file mode 100644 index 000000000..479f37b7b --- /dev/null +++ b/docs/mobile-polish/review.md @@ -0,0 +1,32 @@ + + +# Requirement audit и review + +Base: `origin/dev` / `ec57fa7cadb8ca7acef6859380a966a837783495` (merged PR #401). Head: `fix/dev-mobile-ui-composition`. Scope: 12 замечаний пользователя и выбранная им светлая шапка. Review выполнен в текущей задаче по `procollab-review`, PR оформлен по `procollab-pr`; отдельный агент не использовался. + +| AC | Реализация | Evidence | Verdict | +| --- | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ------- | +| 1 | `Nav.routeTitle`, initial URL, NavigationEnd + защита от позднего navTitle | Прямое открытие ленты/профиля; program → feed → profile SPA | PASS | +| 2 | `FeedFilter` grid, static icon | Проверка непересечения icon/label/count, screenshots 320/390 | PASS | +| 3 | Удалён dropdown; прежний `setFilter` | Один набор 6 категорий, includes=vacancy и API type=vacancy, disabled education | PASS | +| 4 | Общий `VacancySkills`, переносы | Видимость полного текста; native expand, все 4 навыка; unit integration | PASS | +| 5 | `InfoCard`, grids, token 260 px | Измерение ширины и visual dashboard/my/projects | PASS | +| 6 | `Projects` responsive order, `ProjectActivityCard` 2×2 | Activity выше outlet, полная ширина контейнера; desktop screenshot | PASS | +| 7 | `MemberCard`, `Members` grid | Ширина ≤260, навык переносится, CTA внутри; visual + overflow | PASS | +| 8 | `ProgramCard` avatar 64, dates/region отдельно | Полная строка geography, scrollWidth≤clientWidth, 6 widths | PASS | +| 9 | Общий `Detail`, PageHeader, подписанные контакты/положение | Program screenshot, native disabled contacts, равные secondary columns | PASS | +| 10 | `Detail` action grid без divider cells | Profile buttons геометрия и visual 320/390 | PASS | +| 11 | `Detail` + `ProjectsLeftSide` width | Project actions и metadata: полная mobile width | PASS | +| 12 | `Office`/`Nav` symmetric grid + surface | Центры title/header совпадают, neutral background, 44 px targets, Escape/focus | PASS | + +Checked by source: просмотрен diff относительно dev; call chains setFilter/logout/contacts/materials/roles сохранены. Нет изменений защищённых бизнес-слоёв/API. Существующий wrapper Button и директивы UIKit остаются canonical; новый card/control implementation не добавлен. Shared consumers проверены через экранные и state сценарии. Desktop sidebar и ограничения ролей сохранены. + +Checked by tests/build: 2006 regression tests, повтор 41 InfoCard tests после изменения textContent, production build, ESLint, Stylelint, Prettier. Полные команды/логи в [README](README.md). + +Checked in browser: 48 geometry screens + 18 interaction scenarios + 48 section/state checks. Просмотрены mobile list/detail/feed screens на 320/390 px, tablet projects и desktop, а также loading/empty/error/validation screenshots. Читаемость проверена на длинных строках; поля/кнопки не уходят за viewport. Навигация использует native keyboard controls и drawer focus return. Метрики активности не интерактивные, их CSS order не добавляет tab stops. + +Во время review исправлены пустой заголовок при первом открытии, слишком тесные категории на 320 px, intrinsic width вложенных action buttons и перехват клика пустым snackbar на tablet. Пробелы шаблона InfoCard и асинхронное ожидание DOM в проверках исправлены; итоговые прогоны успешные. Незакрытых BLOCKER/MAJOR в рамках указанных 12 AC нет. + +Not checked: реальные устройства/аккаунты dev, screen reader, полное WCAG соответствие. Эти ограничения явно перечислены в PR. Smoke-test на физических iOS/Android выполняется после merge в dev перед prod; он не отмечен пройденным. + +Verdict: готово к review и merge в dev после завершённых локальных проверок; production acceptance остаётся отдельным этапом. diff --git a/docs/mobile-polish/screenshots/after/feed-1440.png b/docs/mobile-polish/screenshots/after/feed-1440.png new file mode 100644 index 000000000..8a36187be Binary files /dev/null and b/docs/mobile-polish/screenshots/after/feed-1440.png differ diff --git a/docs/mobile-polish/screenshots/after/feed-320.png b/docs/mobile-polish/screenshots/after/feed-320.png new file mode 100644 index 000000000..c408ae762 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/feed-320.png differ diff --git a/docs/mobile-polish/screenshots/after/feed-360.png b/docs/mobile-polish/screenshots/after/feed-360.png new file mode 100644 index 000000000..f66ed0d7a Binary files /dev/null and b/docs/mobile-polish/screenshots/after/feed-360.png differ diff --git a/docs/mobile-polish/screenshots/after/feed-390.png b/docs/mobile-polish/screenshots/after/feed-390.png new file mode 100644 index 000000000..bc1e6810b Binary files /dev/null and b/docs/mobile-polish/screenshots/after/feed-390.png differ diff --git a/docs/mobile-polish/screenshots/after/feed-430.png b/docs/mobile-polish/screenshots/after/feed-430.png new file mode 100644 index 000000000..1f5fab453 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/feed-430.png differ diff --git a/docs/mobile-polish/screenshots/after/feed-768.png b/docs/mobile-polish/screenshots/after/feed-768.png new file mode 100644 index 000000000..ca58289fd Binary files /dev/null and b/docs/mobile-polish/screenshots/after/feed-768.png differ diff --git a/docs/mobile-polish/screenshots/after/members-1440.png b/docs/mobile-polish/screenshots/after/members-1440.png new file mode 100644 index 000000000..217bd49d2 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/members-1440.png differ diff --git a/docs/mobile-polish/screenshots/after/members-320.png b/docs/mobile-polish/screenshots/after/members-320.png new file mode 100644 index 000000000..a2d5c15a9 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/members-320.png differ diff --git a/docs/mobile-polish/screenshots/after/members-360.png b/docs/mobile-polish/screenshots/after/members-360.png new file mode 100644 index 000000000..3f808e1e4 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/members-360.png differ diff --git a/docs/mobile-polish/screenshots/after/members-390.png b/docs/mobile-polish/screenshots/after/members-390.png new file mode 100644 index 000000000..006cc3b44 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/members-390.png differ diff --git a/docs/mobile-polish/screenshots/after/members-430.png b/docs/mobile-polish/screenshots/after/members-430.png new file mode 100644 index 000000000..7657927b6 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/members-430.png differ diff --git a/docs/mobile-polish/screenshots/after/members-768.png b/docs/mobile-polish/screenshots/after/members-768.png new file mode 100644 index 000000000..3f2af2700 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/members-768.png differ diff --git a/docs/mobile-polish/screenshots/after/my-projects-1440.png b/docs/mobile-polish/screenshots/after/my-projects-1440.png new file mode 100644 index 000000000..a8cab8d1b Binary files /dev/null and b/docs/mobile-polish/screenshots/after/my-projects-1440.png differ diff --git a/docs/mobile-polish/screenshots/after/my-projects-320.png b/docs/mobile-polish/screenshots/after/my-projects-320.png new file mode 100644 index 000000000..0eb539b2f Binary files /dev/null and b/docs/mobile-polish/screenshots/after/my-projects-320.png differ diff --git a/docs/mobile-polish/screenshots/after/my-projects-360.png b/docs/mobile-polish/screenshots/after/my-projects-360.png new file mode 100644 index 000000000..4e8592c31 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/my-projects-360.png differ diff --git a/docs/mobile-polish/screenshots/after/my-projects-390.png b/docs/mobile-polish/screenshots/after/my-projects-390.png new file mode 100644 index 000000000..fdf04c57e Binary files /dev/null and b/docs/mobile-polish/screenshots/after/my-projects-390.png differ diff --git a/docs/mobile-polish/screenshots/after/my-projects-430.png b/docs/mobile-polish/screenshots/after/my-projects-430.png new file mode 100644 index 000000000..b2e5420ac Binary files /dev/null and b/docs/mobile-polish/screenshots/after/my-projects-430.png differ diff --git a/docs/mobile-polish/screenshots/after/my-projects-768.png b/docs/mobile-polish/screenshots/after/my-projects-768.png new file mode 100644 index 000000000..e8b7c1c01 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/my-projects-768.png differ diff --git a/docs/mobile-polish/screenshots/after/profile-1440.png b/docs/mobile-polish/screenshots/after/profile-1440.png new file mode 100644 index 000000000..2a1cd12c5 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/profile-1440.png differ diff --git a/docs/mobile-polish/screenshots/after/profile-320.png b/docs/mobile-polish/screenshots/after/profile-320.png new file mode 100644 index 000000000..6d986bb01 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/profile-320.png differ diff --git a/docs/mobile-polish/screenshots/after/profile-360.png b/docs/mobile-polish/screenshots/after/profile-360.png new file mode 100644 index 000000000..355c914c9 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/profile-360.png differ diff --git a/docs/mobile-polish/screenshots/after/profile-390.png b/docs/mobile-polish/screenshots/after/profile-390.png new file mode 100644 index 000000000..3dc0eef00 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/profile-390.png differ diff --git a/docs/mobile-polish/screenshots/after/profile-430.png b/docs/mobile-polish/screenshots/after/profile-430.png new file mode 100644 index 000000000..addfd2d3d Binary files /dev/null and b/docs/mobile-polish/screenshots/after/profile-430.png differ diff --git a/docs/mobile-polish/screenshots/after/profile-768.png b/docs/mobile-polish/screenshots/after/profile-768.png new file mode 100644 index 000000000..2792b9133 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/profile-768.png differ diff --git a/docs/mobile-polish/screenshots/after/program-1440.png b/docs/mobile-polish/screenshots/after/program-1440.png new file mode 100644 index 000000000..2d6178c3c Binary files /dev/null and b/docs/mobile-polish/screenshots/after/program-1440.png differ diff --git a/docs/mobile-polish/screenshots/after/program-320.png b/docs/mobile-polish/screenshots/after/program-320.png new file mode 100644 index 000000000..d227b6fc7 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/program-320.png differ diff --git a/docs/mobile-polish/screenshots/after/program-360.png b/docs/mobile-polish/screenshots/after/program-360.png new file mode 100644 index 000000000..f7b560fcc Binary files /dev/null and b/docs/mobile-polish/screenshots/after/program-360.png differ diff --git a/docs/mobile-polish/screenshots/after/program-390.png b/docs/mobile-polish/screenshots/after/program-390.png new file mode 100644 index 000000000..ca42ebed2 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/program-390.png differ diff --git a/docs/mobile-polish/screenshots/after/program-430.png b/docs/mobile-polish/screenshots/after/program-430.png new file mode 100644 index 000000000..94e495336 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/program-430.png differ diff --git a/docs/mobile-polish/screenshots/after/program-768.png b/docs/mobile-polish/screenshots/after/program-768.png new file mode 100644 index 000000000..6eb899bf8 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/program-768.png differ diff --git a/docs/mobile-polish/screenshots/after/programs-1440.png b/docs/mobile-polish/screenshots/after/programs-1440.png new file mode 100644 index 000000000..c0c1ebedc Binary files /dev/null and b/docs/mobile-polish/screenshots/after/programs-1440.png differ diff --git a/docs/mobile-polish/screenshots/after/programs-320.png b/docs/mobile-polish/screenshots/after/programs-320.png new file mode 100644 index 000000000..e64443230 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/programs-320.png differ diff --git a/docs/mobile-polish/screenshots/after/programs-360.png b/docs/mobile-polish/screenshots/after/programs-360.png new file mode 100644 index 000000000..4fa7e5b55 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/programs-360.png differ diff --git a/docs/mobile-polish/screenshots/after/programs-390.png b/docs/mobile-polish/screenshots/after/programs-390.png new file mode 100644 index 000000000..a5e1daef3 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/programs-390.png differ diff --git a/docs/mobile-polish/screenshots/after/programs-430.png b/docs/mobile-polish/screenshots/after/programs-430.png new file mode 100644 index 000000000..0f104efa7 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/programs-430.png differ diff --git a/docs/mobile-polish/screenshots/after/programs-768.png b/docs/mobile-polish/screenshots/after/programs-768.png new file mode 100644 index 000000000..d5d7f64fe Binary files /dev/null and b/docs/mobile-polish/screenshots/after/programs-768.png differ diff --git a/docs/mobile-polish/screenshots/after/project-1440.png b/docs/mobile-polish/screenshots/after/project-1440.png new file mode 100644 index 000000000..4d9c55831 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/project-1440.png differ diff --git a/docs/mobile-polish/screenshots/after/project-320.png b/docs/mobile-polish/screenshots/after/project-320.png new file mode 100644 index 000000000..270a2d0b3 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/project-320.png differ diff --git a/docs/mobile-polish/screenshots/after/project-360.png b/docs/mobile-polish/screenshots/after/project-360.png new file mode 100644 index 000000000..fc3e97427 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/project-360.png differ diff --git a/docs/mobile-polish/screenshots/after/project-390.png b/docs/mobile-polish/screenshots/after/project-390.png new file mode 100644 index 000000000..28c978850 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/project-390.png differ diff --git a/docs/mobile-polish/screenshots/after/project-430.png b/docs/mobile-polish/screenshots/after/project-430.png new file mode 100644 index 000000000..8e6be2380 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/project-430.png differ diff --git a/docs/mobile-polish/screenshots/after/project-768.png b/docs/mobile-polish/screenshots/after/project-768.png new file mode 100644 index 000000000..4b4882ef2 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/project-768.png differ diff --git a/docs/mobile-polish/screenshots/after/projects-1440.png b/docs/mobile-polish/screenshots/after/projects-1440.png new file mode 100644 index 000000000..69aac292a Binary files /dev/null and b/docs/mobile-polish/screenshots/after/projects-1440.png differ diff --git a/docs/mobile-polish/screenshots/after/projects-320.png b/docs/mobile-polish/screenshots/after/projects-320.png new file mode 100644 index 000000000..2bae40960 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/projects-320.png differ diff --git a/docs/mobile-polish/screenshots/after/projects-360.png b/docs/mobile-polish/screenshots/after/projects-360.png new file mode 100644 index 000000000..bb98a90f1 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/projects-360.png differ diff --git a/docs/mobile-polish/screenshots/after/projects-390.png b/docs/mobile-polish/screenshots/after/projects-390.png new file mode 100644 index 000000000..e45c85ef0 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/projects-390.png differ diff --git a/docs/mobile-polish/screenshots/after/projects-430.png b/docs/mobile-polish/screenshots/after/projects-430.png new file mode 100644 index 000000000..c8c36d8a5 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/projects-430.png differ diff --git a/docs/mobile-polish/screenshots/after/projects-768.png b/docs/mobile-polish/screenshots/after/projects-768.png new file mode 100644 index 000000000..52815ac85 Binary files /dev/null and b/docs/mobile-polish/screenshots/after/projects-768.png differ diff --git a/docs/mobile-polish/screenshots/before/feed-1440.png b/docs/mobile-polish/screenshots/before/feed-1440.png new file mode 100644 index 000000000..a6fb109dc Binary files /dev/null and b/docs/mobile-polish/screenshots/before/feed-1440.png differ diff --git a/docs/mobile-polish/screenshots/before/feed-320.png b/docs/mobile-polish/screenshots/before/feed-320.png new file mode 100644 index 000000000..d3f6881f9 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/feed-320.png differ diff --git a/docs/mobile-polish/screenshots/before/feed-360.png b/docs/mobile-polish/screenshots/before/feed-360.png new file mode 100644 index 000000000..462ebc2c9 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/feed-360.png differ diff --git a/docs/mobile-polish/screenshots/before/feed-390.png b/docs/mobile-polish/screenshots/before/feed-390.png new file mode 100644 index 000000000..24ba3c1a4 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/feed-390.png differ diff --git a/docs/mobile-polish/screenshots/before/feed-430.png b/docs/mobile-polish/screenshots/before/feed-430.png new file mode 100644 index 000000000..b2c1afd7b Binary files /dev/null and b/docs/mobile-polish/screenshots/before/feed-430.png differ diff --git a/docs/mobile-polish/screenshots/before/feed-768.png b/docs/mobile-polish/screenshots/before/feed-768.png new file mode 100644 index 000000000..7d88c3cc6 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/feed-768.png differ diff --git a/docs/mobile-polish/screenshots/before/members-1440.png b/docs/mobile-polish/screenshots/before/members-1440.png new file mode 100644 index 000000000..8ea904960 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/members-1440.png differ diff --git a/docs/mobile-polish/screenshots/before/members-320.png b/docs/mobile-polish/screenshots/before/members-320.png new file mode 100644 index 000000000..904dadfc6 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/members-320.png differ diff --git a/docs/mobile-polish/screenshots/before/members-360.png b/docs/mobile-polish/screenshots/before/members-360.png new file mode 100644 index 000000000..960d461c9 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/members-360.png differ diff --git a/docs/mobile-polish/screenshots/before/members-390.png b/docs/mobile-polish/screenshots/before/members-390.png new file mode 100644 index 000000000..405c60394 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/members-390.png differ diff --git a/docs/mobile-polish/screenshots/before/members-430.png b/docs/mobile-polish/screenshots/before/members-430.png new file mode 100644 index 000000000..063e20049 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/members-430.png differ diff --git a/docs/mobile-polish/screenshots/before/members-768.png b/docs/mobile-polish/screenshots/before/members-768.png new file mode 100644 index 000000000..f96fb9a69 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/members-768.png differ diff --git a/docs/mobile-polish/screenshots/before/my-projects-1440.png b/docs/mobile-polish/screenshots/before/my-projects-1440.png new file mode 100644 index 000000000..34757b044 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/my-projects-1440.png differ diff --git a/docs/mobile-polish/screenshots/before/my-projects-320.png b/docs/mobile-polish/screenshots/before/my-projects-320.png new file mode 100644 index 000000000..845e80252 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/my-projects-320.png differ diff --git a/docs/mobile-polish/screenshots/before/my-projects-360.png b/docs/mobile-polish/screenshots/before/my-projects-360.png new file mode 100644 index 000000000..4c0d782e5 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/my-projects-360.png differ diff --git a/docs/mobile-polish/screenshots/before/my-projects-390.png b/docs/mobile-polish/screenshots/before/my-projects-390.png new file mode 100644 index 000000000..796ff7b13 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/my-projects-390.png differ diff --git a/docs/mobile-polish/screenshots/before/my-projects-430.png b/docs/mobile-polish/screenshots/before/my-projects-430.png new file mode 100644 index 000000000..35ac02fc7 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/my-projects-430.png differ diff --git a/docs/mobile-polish/screenshots/before/my-projects-768.png b/docs/mobile-polish/screenshots/before/my-projects-768.png new file mode 100644 index 000000000..00fe2231a Binary files /dev/null and b/docs/mobile-polish/screenshots/before/my-projects-768.png differ diff --git a/docs/mobile-polish/screenshots/before/profile-1440.png b/docs/mobile-polish/screenshots/before/profile-1440.png new file mode 100644 index 000000000..c8c34f4ce Binary files /dev/null and b/docs/mobile-polish/screenshots/before/profile-1440.png differ diff --git a/docs/mobile-polish/screenshots/before/profile-320.png b/docs/mobile-polish/screenshots/before/profile-320.png new file mode 100644 index 000000000..2def8ec93 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/profile-320.png differ diff --git a/docs/mobile-polish/screenshots/before/profile-360.png b/docs/mobile-polish/screenshots/before/profile-360.png new file mode 100644 index 000000000..74a74b3ed Binary files /dev/null and b/docs/mobile-polish/screenshots/before/profile-360.png differ diff --git a/docs/mobile-polish/screenshots/before/profile-390.png b/docs/mobile-polish/screenshots/before/profile-390.png new file mode 100644 index 000000000..db102f671 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/profile-390.png differ diff --git a/docs/mobile-polish/screenshots/before/profile-430.png b/docs/mobile-polish/screenshots/before/profile-430.png new file mode 100644 index 000000000..2a8d696ac Binary files /dev/null and b/docs/mobile-polish/screenshots/before/profile-430.png differ diff --git a/docs/mobile-polish/screenshots/before/profile-768.png b/docs/mobile-polish/screenshots/before/profile-768.png new file mode 100644 index 000000000..f9af8d033 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/profile-768.png differ diff --git a/docs/mobile-polish/screenshots/before/program-1440.png b/docs/mobile-polish/screenshots/before/program-1440.png new file mode 100644 index 000000000..8a80a80c2 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/program-1440.png differ diff --git a/docs/mobile-polish/screenshots/before/program-320.png b/docs/mobile-polish/screenshots/before/program-320.png new file mode 100644 index 000000000..731b071dc Binary files /dev/null and b/docs/mobile-polish/screenshots/before/program-320.png differ diff --git a/docs/mobile-polish/screenshots/before/program-360.png b/docs/mobile-polish/screenshots/before/program-360.png new file mode 100644 index 000000000..fde57a1de Binary files /dev/null and b/docs/mobile-polish/screenshots/before/program-360.png differ diff --git a/docs/mobile-polish/screenshots/before/program-390.png b/docs/mobile-polish/screenshots/before/program-390.png new file mode 100644 index 000000000..683da9423 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/program-390.png differ diff --git a/docs/mobile-polish/screenshots/before/program-430.png b/docs/mobile-polish/screenshots/before/program-430.png new file mode 100644 index 000000000..c1c1ca2c0 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/program-430.png differ diff --git a/docs/mobile-polish/screenshots/before/program-768.png b/docs/mobile-polish/screenshots/before/program-768.png new file mode 100644 index 000000000..e80edd7f2 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/program-768.png differ diff --git a/docs/mobile-polish/screenshots/before/programs-1440.png b/docs/mobile-polish/screenshots/before/programs-1440.png new file mode 100644 index 000000000..731a92362 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/programs-1440.png differ diff --git a/docs/mobile-polish/screenshots/before/programs-320.png b/docs/mobile-polish/screenshots/before/programs-320.png new file mode 100644 index 000000000..3a3558d82 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/programs-320.png differ diff --git a/docs/mobile-polish/screenshots/before/programs-360.png b/docs/mobile-polish/screenshots/before/programs-360.png new file mode 100644 index 000000000..748997b3e Binary files /dev/null and b/docs/mobile-polish/screenshots/before/programs-360.png differ diff --git a/docs/mobile-polish/screenshots/before/programs-390.png b/docs/mobile-polish/screenshots/before/programs-390.png new file mode 100644 index 000000000..1cb98cc56 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/programs-390.png differ diff --git a/docs/mobile-polish/screenshots/before/programs-430.png b/docs/mobile-polish/screenshots/before/programs-430.png new file mode 100644 index 000000000..f6d577e49 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/programs-430.png differ diff --git a/docs/mobile-polish/screenshots/before/programs-768.png b/docs/mobile-polish/screenshots/before/programs-768.png new file mode 100644 index 000000000..8da9cdd2d Binary files /dev/null and b/docs/mobile-polish/screenshots/before/programs-768.png differ diff --git a/docs/mobile-polish/screenshots/before/project-1440.png b/docs/mobile-polish/screenshots/before/project-1440.png new file mode 100644 index 000000000..f4a62eae7 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/project-1440.png differ diff --git a/docs/mobile-polish/screenshots/before/project-320.png b/docs/mobile-polish/screenshots/before/project-320.png new file mode 100644 index 000000000..56d49a9aa Binary files /dev/null and b/docs/mobile-polish/screenshots/before/project-320.png differ diff --git a/docs/mobile-polish/screenshots/before/project-360.png b/docs/mobile-polish/screenshots/before/project-360.png new file mode 100644 index 000000000..b2ca47e61 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/project-360.png differ diff --git a/docs/mobile-polish/screenshots/before/project-390.png b/docs/mobile-polish/screenshots/before/project-390.png new file mode 100644 index 000000000..4c591e7d3 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/project-390.png differ diff --git a/docs/mobile-polish/screenshots/before/project-430.png b/docs/mobile-polish/screenshots/before/project-430.png new file mode 100644 index 000000000..4fc49dade Binary files /dev/null and b/docs/mobile-polish/screenshots/before/project-430.png differ diff --git a/docs/mobile-polish/screenshots/before/project-768.png b/docs/mobile-polish/screenshots/before/project-768.png new file mode 100644 index 000000000..1e11621b2 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/project-768.png differ diff --git a/docs/mobile-polish/screenshots/before/projects-1440.png b/docs/mobile-polish/screenshots/before/projects-1440.png new file mode 100644 index 000000000..ac4f2fdda Binary files /dev/null and b/docs/mobile-polish/screenshots/before/projects-1440.png differ diff --git a/docs/mobile-polish/screenshots/before/projects-320.png b/docs/mobile-polish/screenshots/before/projects-320.png new file mode 100644 index 000000000..9c9d6c08c Binary files /dev/null and b/docs/mobile-polish/screenshots/before/projects-320.png differ diff --git a/docs/mobile-polish/screenshots/before/projects-360.png b/docs/mobile-polish/screenshots/before/projects-360.png new file mode 100644 index 000000000..7f1ec4816 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/projects-360.png differ diff --git a/docs/mobile-polish/screenshots/before/projects-390.png b/docs/mobile-polish/screenshots/before/projects-390.png new file mode 100644 index 000000000..65a3365a9 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/projects-390.png differ diff --git a/docs/mobile-polish/screenshots/before/projects-430.png b/docs/mobile-polish/screenshots/before/projects-430.png new file mode 100644 index 000000000..e759f1907 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/projects-430.png differ diff --git a/docs/mobile-polish/screenshots/before/projects-768.png b/docs/mobile-polish/screenshots/before/projects-768.png new file mode 100644 index 000000000..679447f54 Binary files /dev/null and b/docs/mobile-polish/screenshots/before/projects-768.png differ diff --git a/docs/mobile-polish/screenshots/interactions/members-320.png b/docs/mobile-polish/screenshots/interactions/members-320.png new file mode 100644 index 000000000..a2d5c15a9 Binary files /dev/null and b/docs/mobile-polish/screenshots/interactions/members-320.png differ diff --git a/docs/mobile-polish/screenshots/interactions/members-390.png b/docs/mobile-polish/screenshots/interactions/members-390.png new file mode 100644 index 000000000..006cc3b44 Binary files /dev/null and b/docs/mobile-polish/screenshots/interactions/members-390.png differ diff --git a/docs/mobile-polish/screenshots/interactions/members-768.png b/docs/mobile-polish/screenshots/interactions/members-768.png new file mode 100644 index 000000000..3f2af2700 Binary files /dev/null and b/docs/mobile-polish/screenshots/interactions/members-768.png differ diff --git a/docs/mobile-polish/screenshots/interactions/navigation-feed-skills-320.png b/docs/mobile-polish/screenshots/interactions/navigation-feed-skills-320.png new file mode 100644 index 000000000..460708115 Binary files /dev/null and b/docs/mobile-polish/screenshots/interactions/navigation-feed-skills-320.png differ diff --git a/docs/mobile-polish/screenshots/interactions/navigation-feed-skills-390.png b/docs/mobile-polish/screenshots/interactions/navigation-feed-skills-390.png new file mode 100644 index 000000000..020a0578c Binary files /dev/null and b/docs/mobile-polish/screenshots/interactions/navigation-feed-skills-390.png differ diff --git a/docs/mobile-polish/screenshots/interactions/navigation-feed-skills-768.png b/docs/mobile-polish/screenshots/interactions/navigation-feed-skills-768.png new file mode 100644 index 000000000..27b430248 Binary files /dev/null and b/docs/mobile-polish/screenshots/interactions/navigation-feed-skills-768.png differ diff --git a/docs/mobile-polish/screenshots/interactions/profile-actions-320.png b/docs/mobile-polish/screenshots/interactions/profile-actions-320.png new file mode 100644 index 000000000..6d986bb01 Binary files /dev/null and b/docs/mobile-polish/screenshots/interactions/profile-actions-320.png differ diff --git a/docs/mobile-polish/screenshots/interactions/profile-actions-390.png b/docs/mobile-polish/screenshots/interactions/profile-actions-390.png new file mode 100644 index 000000000..3dc0eef00 Binary files /dev/null and b/docs/mobile-polish/screenshots/interactions/profile-actions-390.png differ diff --git a/docs/mobile-polish/screenshots/interactions/profile-actions-768.png b/docs/mobile-polish/screenshots/interactions/profile-actions-768.png new file mode 100644 index 000000000..2792b9133 Binary files /dev/null and b/docs/mobile-polish/screenshots/interactions/profile-actions-768.png differ diff --git a/docs/mobile-polish/screenshots/interactions/program-actions-320.png b/docs/mobile-polish/screenshots/interactions/program-actions-320.png new file mode 100644 index 000000000..d227b6fc7 Binary files /dev/null and b/docs/mobile-polish/screenshots/interactions/program-actions-320.png differ diff --git a/docs/mobile-polish/screenshots/interactions/program-actions-390.png b/docs/mobile-polish/screenshots/interactions/program-actions-390.png new file mode 100644 index 000000000..ca42ebed2 Binary files /dev/null and b/docs/mobile-polish/screenshots/interactions/program-actions-390.png differ diff --git a/docs/mobile-polish/screenshots/interactions/program-actions-768.png b/docs/mobile-polish/screenshots/interactions/program-actions-768.png new file mode 100644 index 000000000..6eb899bf8 Binary files /dev/null and b/docs/mobile-polish/screenshots/interactions/program-actions-768.png differ diff --git a/docs/mobile-polish/screenshots/interactions/project-actions-320.png b/docs/mobile-polish/screenshots/interactions/project-actions-320.png new file mode 100644 index 000000000..270a2d0b3 Binary files /dev/null and b/docs/mobile-polish/screenshots/interactions/project-actions-320.png differ diff --git a/docs/mobile-polish/screenshots/interactions/project-actions-390.png b/docs/mobile-polish/screenshots/interactions/project-actions-390.png new file mode 100644 index 000000000..28c978850 Binary files /dev/null and b/docs/mobile-polish/screenshots/interactions/project-actions-390.png differ diff --git a/docs/mobile-polish/screenshots/interactions/project-actions-768.png b/docs/mobile-polish/screenshots/interactions/project-actions-768.png new file mode 100644 index 000000000..4b4882ef2 Binary files /dev/null and b/docs/mobile-polish/screenshots/interactions/project-actions-768.png differ diff --git a/docs/mobile-polish/screenshots/interactions/projects-activity-320.png b/docs/mobile-polish/screenshots/interactions/projects-activity-320.png new file mode 100644 index 000000000..2bae40960 Binary files /dev/null and b/docs/mobile-polish/screenshots/interactions/projects-activity-320.png differ diff --git a/docs/mobile-polish/screenshots/interactions/projects-activity-390.png b/docs/mobile-polish/screenshots/interactions/projects-activity-390.png new file mode 100644 index 000000000..e45c85ef0 Binary files /dev/null and b/docs/mobile-polish/screenshots/interactions/projects-activity-390.png differ diff --git a/docs/mobile-polish/screenshots/interactions/projects-activity-768.png b/docs/mobile-polish/screenshots/interactions/projects-activity-768.png new file mode 100644 index 000000000..52815ac85 Binary files /dev/null and b/docs/mobile-polish/screenshots/interactions/projects-activity-768.png differ diff --git a/docs/mobile-polish/screenshots/states/courses-1440.png b/docs/mobile-polish/screenshots/states/courses-1440.png new file mode 100644 index 000000000..7a8c99b6c Binary files /dev/null and b/docs/mobile-polish/screenshots/states/courses-1440.png differ diff --git a/docs/mobile-polish/screenshots/states/courses-320.png b/docs/mobile-polish/screenshots/states/courses-320.png new file mode 100644 index 000000000..c03bda60e Binary files /dev/null and b/docs/mobile-polish/screenshots/states/courses-320.png differ diff --git a/docs/mobile-polish/screenshots/states/courses-390.png b/docs/mobile-polish/screenshots/states/courses-390.png new file mode 100644 index 000000000..9313fe831 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/courses-390.png differ diff --git a/docs/mobile-polish/screenshots/states/disabled-action-1440.png b/docs/mobile-polish/screenshots/states/disabled-action-1440.png new file mode 100644 index 000000000..2bc228551 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/disabled-action-1440.png differ diff --git a/docs/mobile-polish/screenshots/states/disabled-action-320.png b/docs/mobile-polish/screenshots/states/disabled-action-320.png new file mode 100644 index 000000000..f92508267 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/disabled-action-320.png differ diff --git a/docs/mobile-polish/screenshots/states/disabled-action-390.png b/docs/mobile-polish/screenshots/states/disabled-action-390.png new file mode 100644 index 000000000..4e9054b07 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/disabled-action-390.png differ diff --git a/docs/mobile-polish/screenshots/states/disabled-filter-1440.png b/docs/mobile-polish/screenshots/states/disabled-filter-1440.png new file mode 100644 index 000000000..3a9e481f3 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/disabled-filter-1440.png differ diff --git a/docs/mobile-polish/screenshots/states/disabled-filter-320.png b/docs/mobile-polish/screenshots/states/disabled-filter-320.png new file mode 100644 index 000000000..9c2c2d7d1 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/disabled-filter-320.png differ diff --git a/docs/mobile-polish/screenshots/states/disabled-filter-390.png b/docs/mobile-polish/screenshots/states/disabled-filter-390.png new file mode 100644 index 000000000..184878e47 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/disabled-filter-390.png differ diff --git a/docs/mobile-polish/screenshots/states/empty-1440.png b/docs/mobile-polish/screenshots/states/empty-1440.png new file mode 100644 index 000000000..7933c1ef1 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/empty-1440.png differ diff --git a/docs/mobile-polish/screenshots/states/empty-320.png b/docs/mobile-polish/screenshots/states/empty-320.png new file mode 100644 index 000000000..93d132e62 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/empty-320.png differ diff --git a/docs/mobile-polish/screenshots/states/empty-390.png b/docs/mobile-polish/screenshots/states/empty-390.png new file mode 100644 index 000000000..b593e4018 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/empty-390.png differ diff --git a/docs/mobile-polish/screenshots/states/error-1440.png b/docs/mobile-polish/screenshots/states/error-1440.png new file mode 100644 index 000000000..a34f54ac8 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/error-1440.png differ diff --git a/docs/mobile-polish/screenshots/states/error-320.png b/docs/mobile-polish/screenshots/states/error-320.png new file mode 100644 index 000000000..cdba1f904 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/error-320.png differ diff --git a/docs/mobile-polish/screenshots/states/error-390.png b/docs/mobile-polish/screenshots/states/error-390.png new file mode 100644 index 000000000..052424d60 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/error-390.png differ diff --git a/docs/mobile-polish/screenshots/states/loading-action-1440.png b/docs/mobile-polish/screenshots/states/loading-action-1440.png new file mode 100644 index 000000000..ba30a696f Binary files /dev/null and b/docs/mobile-polish/screenshots/states/loading-action-1440.png differ diff --git a/docs/mobile-polish/screenshots/states/loading-action-320.png b/docs/mobile-polish/screenshots/states/loading-action-320.png new file mode 100644 index 000000000..e16222a52 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/loading-action-320.png differ diff --git a/docs/mobile-polish/screenshots/states/loading-action-390.png b/docs/mobile-polish/screenshots/states/loading-action-390.png new file mode 100644 index 000000000..bbaba2f18 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/loading-action-390.png differ diff --git a/docs/mobile-polish/screenshots/states/loading-page-1440.png b/docs/mobile-polish/screenshots/states/loading-page-1440.png new file mode 100644 index 000000000..c9dcc8a80 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/loading-page-1440.png differ diff --git a/docs/mobile-polish/screenshots/states/loading-page-320.png b/docs/mobile-polish/screenshots/states/loading-page-320.png new file mode 100644 index 000000000..2f60a1c52 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/loading-page-320.png differ diff --git a/docs/mobile-polish/screenshots/states/loading-page-390.png b/docs/mobile-polish/screenshots/states/loading-page-390.png new file mode 100644 index 000000000..e39bf362e Binary files /dev/null and b/docs/mobile-polish/screenshots/states/loading-page-390.png differ diff --git a/docs/mobile-polish/screenshots/states/onboarding-0-1440.png b/docs/mobile-polish/screenshots/states/onboarding-0-1440.png new file mode 100644 index 000000000..66e1d9c09 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/onboarding-0-1440.png differ diff --git a/docs/mobile-polish/screenshots/states/onboarding-0-320.png b/docs/mobile-polish/screenshots/states/onboarding-0-320.png new file mode 100644 index 000000000..36dd2eeaa Binary files /dev/null and b/docs/mobile-polish/screenshots/states/onboarding-0-320.png differ diff --git a/docs/mobile-polish/screenshots/states/onboarding-0-390.png b/docs/mobile-polish/screenshots/states/onboarding-0-390.png new file mode 100644 index 000000000..3b81d2e46 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/onboarding-0-390.png differ diff --git a/docs/mobile-polish/screenshots/states/onboarding-1-1440.png b/docs/mobile-polish/screenshots/states/onboarding-1-1440.png new file mode 100644 index 000000000..adf775ba1 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/onboarding-1-1440.png differ diff --git a/docs/mobile-polish/screenshots/states/onboarding-1-320.png b/docs/mobile-polish/screenshots/states/onboarding-1-320.png new file mode 100644 index 000000000..f0e2ed53a Binary files /dev/null and b/docs/mobile-polish/screenshots/states/onboarding-1-320.png differ diff --git a/docs/mobile-polish/screenshots/states/onboarding-1-390.png b/docs/mobile-polish/screenshots/states/onboarding-1-390.png new file mode 100644 index 000000000..cc03fb3c6 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/onboarding-1-390.png differ diff --git a/docs/mobile-polish/screenshots/states/profile-1440.png b/docs/mobile-polish/screenshots/states/profile-1440.png new file mode 100644 index 000000000..39fcdf376 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/profile-1440.png differ diff --git a/docs/mobile-polish/screenshots/states/profile-320.png b/docs/mobile-polish/screenshots/states/profile-320.png new file mode 100644 index 000000000..3007d338d Binary files /dev/null and b/docs/mobile-polish/screenshots/states/profile-320.png differ diff --git a/docs/mobile-polish/screenshots/states/profile-390.png b/docs/mobile-polish/screenshots/states/profile-390.png new file mode 100644 index 000000000..23a1958f6 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/profile-390.png differ diff --git a/docs/mobile-polish/screenshots/states/profile-edit-1440.png b/docs/mobile-polish/screenshots/states/profile-edit-1440.png new file mode 100644 index 000000000..5d6dab113 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/profile-edit-1440.png differ diff --git a/docs/mobile-polish/screenshots/states/profile-edit-320.png b/docs/mobile-polish/screenshots/states/profile-edit-320.png new file mode 100644 index 000000000..3c7c46269 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/profile-edit-320.png differ diff --git a/docs/mobile-polish/screenshots/states/profile-edit-390.png b/docs/mobile-polish/screenshots/states/profile-edit-390.png new file mode 100644 index 000000000..0dde9893b Binary files /dev/null and b/docs/mobile-polish/screenshots/states/profile-edit-390.png differ diff --git a/docs/mobile-polish/screenshots/states/programs-1440.png b/docs/mobile-polish/screenshots/states/programs-1440.png new file mode 100644 index 000000000..86dc00093 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/programs-1440.png differ diff --git a/docs/mobile-polish/screenshots/states/programs-320.png b/docs/mobile-polish/screenshots/states/programs-320.png new file mode 100644 index 000000000..d7f61925a Binary files /dev/null and b/docs/mobile-polish/screenshots/states/programs-320.png differ diff --git a/docs/mobile-polish/screenshots/states/programs-390.png b/docs/mobile-polish/screenshots/states/programs-390.png new file mode 100644 index 000000000..d8f937994 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/programs-390.png differ diff --git a/docs/mobile-polish/screenshots/states/projects-1440.png b/docs/mobile-polish/screenshots/states/projects-1440.png new file mode 100644 index 000000000..3ba7a67f2 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/projects-1440.png differ diff --git a/docs/mobile-polish/screenshots/states/projects-320.png b/docs/mobile-polish/screenshots/states/projects-320.png new file mode 100644 index 000000000..3dcc89602 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/projects-320.png differ diff --git a/docs/mobile-polish/screenshots/states/projects-390.png b/docs/mobile-polish/screenshots/states/projects-390.png new file mode 100644 index 000000000..7dd67c6df Binary files /dev/null and b/docs/mobile-polish/screenshots/states/projects-390.png differ diff --git a/docs/mobile-polish/screenshots/states/vacancies-1440.png b/docs/mobile-polish/screenshots/states/vacancies-1440.png new file mode 100644 index 000000000..3b95c8404 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/vacancies-1440.png differ diff --git a/docs/mobile-polish/screenshots/states/vacancies-320.png b/docs/mobile-polish/screenshots/states/vacancies-320.png new file mode 100644 index 000000000..3f179ca86 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/vacancies-320.png differ diff --git a/docs/mobile-polish/screenshots/states/vacancies-390.png b/docs/mobile-polish/screenshots/states/vacancies-390.png new file mode 100644 index 000000000..a5e64f193 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/vacancies-390.png differ diff --git a/docs/mobile-polish/screenshots/states/validation-onboarding-1440.png b/docs/mobile-polish/screenshots/states/validation-onboarding-1440.png new file mode 100644 index 000000000..5c79cbb15 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/validation-onboarding-1440.png differ diff --git a/docs/mobile-polish/screenshots/states/validation-onboarding-320.png b/docs/mobile-polish/screenshots/states/validation-onboarding-320.png new file mode 100644 index 000000000..c71b8915e Binary files /dev/null and b/docs/mobile-polish/screenshots/states/validation-onboarding-320.png differ diff --git a/docs/mobile-polish/screenshots/states/validation-onboarding-390.png b/docs/mobile-polish/screenshots/states/validation-onboarding-390.png new file mode 100644 index 000000000..09e965491 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/validation-onboarding-390.png differ diff --git a/docs/mobile-polish/screenshots/states/validation-register-1440.png b/docs/mobile-polish/screenshots/states/validation-register-1440.png new file mode 100644 index 000000000..c333b9391 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/validation-register-1440.png differ diff --git a/docs/mobile-polish/screenshots/states/validation-register-320.png b/docs/mobile-polish/screenshots/states/validation-register-320.png new file mode 100644 index 000000000..d1d03bd33 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/validation-register-320.png differ diff --git a/docs/mobile-polish/screenshots/states/validation-register-390.png b/docs/mobile-polish/screenshots/states/validation-register-390.png new file mode 100644 index 000000000..fada82004 Binary files /dev/null and b/docs/mobile-polish/screenshots/states/validation-register-390.png differ diff --git a/docs/mobile-polish/state-check.cjs b/docs/mobile-polish/state-check.cjs new file mode 100644 index 000000000..ee89df52f --- /dev/null +++ b/docs/mobile-polish/state-check.cjs @@ -0,0 +1,232 @@ +/** @format */ + +const fs = require("node:fs"); +const path = require("node:path"); +const assert = require("node:assert/strict"); +const { launch, assertViewport } = require("../responsive/browser-harness.cjs"); +const fixtures = require("../responsive/fixtures.cjs"); + +const directory = path.join(__dirname, "screenshots", "states"); +fs.mkdirSync(directory, { recursive: true }); +const rows = []; +const widths = [320, 390, 1440]; +const sections = [ + ["projects", "/office/projects/all", "app-info-card"], + ["vacancies", "/office/vacancies/all", "app-project-vacancy-card"], + ["programs", "/office/program/all", "app-program-card"], + ["courses", "/office/courses/all", "app-course"], + ["profile", "/office/profile/1", "app-detail"], + ["profile-edit", "/office/profile/edit?editingStep=main", "app-page-header"], + [ + "onboarding-0", + "/office/onboarding/stage-0", + "app-stage-zero .page__form input:not([type=file])", + ], + ["onboarding-1", "/office/onboarding/stage-1", "app-stage-one app-autocomplete-input"], +]; + +async function goto(page, route, settled = true) { + await page.goto("http://127.0.0.1:4360" + route); + if (settled) await page.waitForLoadState("networkidle"); +} + +async function capture(harness, name, width, extra = {}) { + const measurement = await assertViewport(harness.page); + const expectedErrors = extra.injectedHttp500 + ? harness.errors.filter( + message => + /Failed to load resource.*500/.test(message) || + /\[ERROR\] \[HTTP\] GET https:\/\/(?:api|dev)\.procollab\.ru\/programs\/1\/manager-overview\/ 500 /.test( + message, + ), + ) + : []; + assert.deepEqual( + harness.errors.filter(message => !expectedErrors.includes(message)), + [], + ); + const screenshot = `screenshots/states/${name}-${width}.png`; + await harness.page.screenshot({ path: path.join(__dirname, screenshot), fullPage: true }); + rows.push({ name, width, passed: true, ...measurement, screenshot, expectedErrors, ...extra }); + console.log(JSON.stringify({ name, width, passed: true })); +} + +async function state(width, name, action) { + const harness = await launch(width, { isMobile: width < 750, hasTouch: width < 750 }); + harness.page.setDefaultTimeout(8000); + try { + await action(harness); + } finally { + await harness.browser.close(); + } +} + +(async () => { + for (const width of widths) { + const harness = await launch(width, { isMobile: width < 750, hasTouch: width < 750 }); + try { + for (const [name, route, content] of sections) { + harness.errors.length = 0; + await goto(harness.page, route); + await harness.page.locator(content).first().waitFor({ state: "visible" }); + await capture(harness, name, width, { category: "section" }); + } + } finally { + await harness.browser.close(); + } + + await state(width, "loading-page", async h => { + let release; + const pending = new Promise(resolve => { + release = resolve; + }); + await h.context.route("**/programs/1/manager-overview/**", async route => { + await pending; + const url = new URL(route.request().url()); + await route.fulfill({ json: fixtures.response(url.pathname, "GET", url.searchParams) }); + }); + try { + await goto(h.page, "/office/program/1/analytics", false); + await h.page.getByTestId("analytics-loading").waitFor(); + await capture(h, "loading-page", width, { category: "loading" }); + } finally { + release(); + } + await h.page.getByTestId("analytics-loading").waitFor({ state: "hidden" }); + }); + + await state(width, "loading-action", async h => { + await goto(h.page, "/office/courses/1/lesson/1"); + await h.page.locator("app-write-task textarea").fill("Ответ для финальной проверки UI Kit"); + let release; + const pending = new Promise(resolve => { + release = resolve; + }); + let submissions = 0; + await h.context.route("**/courses/tasks/1/answer/", async route => { + submissions++; + await pending; + const url = new URL(route.request().url()); + await route.fulfill({ json: fixtures.response(url.pathname, "POST", url.searchParams) }); + }); + try { + const button = h.page.getByRole("button", { name: "завершить урок", exact: true }); + await button.click(); + await h.page.locator("app-button app-loader").waitFor(); + assert.equal(await button.isDisabled(), true); + assert.equal(await button.getAttribute("aria-busy"), "true"); + await button.evaluate(element => element.click()); + assert.equal(submissions, 1, "Loading must prevent duplicate submission"); + await capture(h, "loading-action", width, { category: "loading", submissions }); + } finally { + release(); + } + await h.page.locator("app-complete").waitFor(); + }); + + await state(width, "empty", async h => { + await h.context.route( + url => /\/vacancies\/$/.test(url.pathname), + route => route.fulfill({ json: { count: 0, results: [], next: null, previous: null } }), + ); + await goto(h.page, "/office/vacancies/all"); + await h.page.locator("app-state").getByText("Вакансии не найдены", { exact: true }).waitFor(); + await capture(h, "empty", width, { category: "empty" }); + }); + + await state(width, "error", async h => { + let failing = true; + let attempts = 0; + await h.context.route("**/programs/1/manager-overview/**", async route => { + attempts++; + if (failing) return route.fulfill({ status: 500, json: { detail: "Injected QA failure" } }); + const url = new URL(route.request().url()); + return route.fulfill({ json: fixtures.response(url.pathname, "GET", url.searchParams) }); + }); + await goto(h.page, "/office/program/1/analytics"); + await h.page.getByTestId("analytics-error").waitFor({ timeout: 60000 }); + assert.equal(await h.page.getByTestId("analytics-error").getAttribute("role"), "alert"); + await capture(h, "error", width, { category: "error", injectedHttp500: true }); + failing = false; + await h.page.getByRole("button", { name: "Повторить", exact: true }).click(); + await h.page.getByTestId("analytics-error").waitFor({ state: "hidden" }); + await h.page.locator(".summary-card").first().waitFor(); + assert.ok(attempts >= 2, "Error retry must reload data"); + await assertViewport(h.page); + rows.at(-1).retryPassed = true; + }); + + await state(width, "disabled-action", async h => { + await goto(h.page, "/office/courses/1/lesson/1"); + const button = h.page.getByRole("button", { name: "завершить урок", exact: true }); + assert.equal(await button.isDisabled(), true); + const before = h.requests.filter(request => request.method !== "GET").length; + await button.evaluate(element => element.click()); + assert.equal(h.requests.filter(request => request.method !== "GET").length, before); + assert.equal( + await button.evaluate(element => { + element.focus(); + return document.activeElement !== element; + }), + true, + ); + await capture(h, "disabled-action", width, { category: "disabled" }); + }); + + await state(width, "disabled-filter", async h => { + await goto(h.page, "/office/feed"); + const button = h.page.getByRole("button", { name: /образование/ }); + assert.equal(await button.isDisabled(), true); + const before = h.page.url(); + await button.evaluate(element => element.click()); + assert.equal(h.page.url(), before); + await capture(h, "disabled-filter", width, { category: "disabled" }); + }); + + await state(width, "validation-register", async h => { + await goto(h.page, "/auth/register"); + if (width >= 1000) { + const register = await h.page.locator(".register").boundingBox(); + assert.ok(register.x >= 199, "Registration must retain the desktop auth gutter"); + } + for (const checkbox of await h.page.locator("app-checkbox .field").all()) + await checkbox.click(); + await h.page.getByRole("button", { name: "зарегистрироваться", exact: true }).click(); + await h.page.locator(".error").first().waitFor(); + assert.equal( + h.requests.some( + request => request.method === "POST" && /\/auth\/users\/$/.test(request.path), + ), + false, + ); + await capture(h, "validation-register", width, { category: "validation" }); + }); + + const avatar = fixtures.user.avatar; + fixtures.user.avatar = null; + try { + await state(width, "validation-onboarding", async h => { + await goto(h.page, "/office/onboarding/stage-0"); + await h.page.getByRole("button", { name: "продолжить", exact: true }).click(); + await h.page.locator(".error").first().waitFor(); + assert.equal(h.page.url().includes("stage-0"), true); + assert.equal( + h.requests.some(request => request.method === "PATCH"), + false, + ); + await capture(h, "validation-onboarding", width, { category: "validation" }); + }); + } finally { + fixtures.user.avatar = avatar; + } + } + assert.equal(rows.length, 48); + fs.writeFileSync( + path.join(__dirname, "states.json"), + JSON.stringify({ widths, rows }, null, 2) + "\n", + ); + console.log(`${rows.length} UI state checks passed`); +})().catch(error => { + console.error(error); + process.exitCode = 1; +}); diff --git a/docs/mobile-polish/states.json b/docs/mobile-polish/states.json new file mode 100644 index 000000000..0ed1dcf11 --- /dev/null +++ b/docs/mobile-polish/states.json @@ -0,0 +1,2336 @@ +{ + "widths": [320, 390, 1440], + "rows": [ + { + "name": "projects", + "width": 320, + "passed": true, + "actualPath": "/office/projects/all", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-projects-filter", + "app-select", + "app-dropdown", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-projects-filter", + "app-select" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\nФильтр\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nПроект для проверки адаптива\n\nОткрыть\n\nфильтры\n\nсбросить\nсфера проекта", + "screenshot": "screenshots/states/projects-320.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "vacancies", + "width": 320, + "passed": true, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter" + ], + "text": "Вакансии\nвакансии\n\nПоиск\n\nАктивна\n01.10.2026\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nПроект\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробело", + "screenshot": "screenshots/states/vacancies-320.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "programs", + "width": 320, + "passed": true, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card" + ], + "text": "Программы\nпрограммы\n\nПоиск\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nты уже участвуешь!\n\n01.10.2026 - 01.01.2027\n\nдля всей России", + "screenshot": "screenshots/states/programs-320.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "courses", + "width": 320, + "passed": true, + "actualPath": "/office/courses/all", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge", + "app-soon-card", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge" + ], + "text": "Курсы\nкурсы\n\nПоиск\n\nдоступно всем пользователям\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазвани...\n\n01.01.2026 — 01.01.2027\n\nпродолжить обучение", + "screenshot": "screenshots/states/courses-320.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "profile", + "width": 320, + "passed": true, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Профиль\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов Тестовый\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазвание", + "screenshot": "screenshots/states/profile-320.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "profile-edit", + "width": 320, + "passed": true, + "actualPath": "/office/profile/edit", + "actualQuery": "?editingStep=main", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-modal", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea" + ], + "text": "Редактирование профиля\nредактирование профиля\ncохранить\nосновные данные\nобразование\nработа\nдостижения\nнавыки\nдействия\nфото\nимя\nфамилия\nРегион\nдата рождения\nспециальность\nобо мне\n\n124 / 300\n\nуказать личные контакты\nдобавить контакт\nтелефон", + "screenshot": "screenshots/states/profile-edit-320.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "onboarding-0", + "width": 320, + "passed": true, + "actualPath": "/office/onboarding/stage-0", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-modal", + "app-region-select", + "app-select", + "app-dropdown", + "app-input", + "app-button", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-region-select", + "app-select", + "app-input", + "app-button" + ], + "text": "1\n2\n3\n4\nПривет, ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов Тестовый! ✌️\n\nРасскажите о себе, чтобы ваше резюме было сильным и отражало опыт\n\nФотография профиля*\n\nРегион*\n\nОбразование\n\nУровень образования\nВысшее образова", + "screenshot": "screenshots/states/onboarding-0-320.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "onboarding-1", + "width": 320, + "passed": true, + "actualPath": "/office/onboarding/stage-1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-onboarding", + "app-stage-one", + "app-tooltip", + "app-button", + "app-autocomplete-input", + "app-specializations-group", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-onboarding", + "app-stage-one", + "app-tooltip", + "app-button", + "app-autocomplete-input", + "app-specializations-group" + ], + "text": "1\n2\n3\n4\nКем хотите работать?\nзакончить регистрацию позже\nпродолжить\nпоиск по библиотеке\nбиблиотека\nРазработчик", + "screenshot": "screenshots/states/onboarding-1-320.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "loading-page", + "width": 320, + "passed": true, + "actualPath": "/office/program/1/analytics", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-modal", + "app-program-analytics", + "app-analytics-drilldown", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-program-analytics" + ], + "text": "Программы\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nназад\nКонтакты\n\nУправление программой\n\nАналитика\n\nСводка пути участников от регистрации до экспертной оценки.\n\nЗагружаем аналитику программы…", + "screenshot": "screenshots/states/loading-page-320.png", + "expectedErrors": [], + "category": "loading" + }, + { + "name": "loading-action", + "width": 320, + "passed": true, + "actualPath": "/office/courses/1/lesson/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task", + "app-loader", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task", + "app-loader" + ], + "text": "Курсы\nназад\n\nмодуль 1\n\nурок 1\n\nо курсе\n\n1\n\nзадание 1\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазван...\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nответ\n\n35 / 1000\n\nзавершить урок", + "screenshot": "screenshots/states/loading-action-320.png", + "expectedErrors": [], + "category": "loading", + "submissions": 1 + }, + { + "name": "empty", + "width": 320, + "passed": true, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-state", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-state", + "app-button", + "app-vacancy-filter" + ], + "text": "Вакансии\nвакансии\n\nПоиск\n\nВакансии не найдены\n\nПопробуйте изменить запрос или сбросить фильтры.\n\nСбросить фильтры\nфильтры\nмои отклики", + "screenshot": "screenshots/states/empty-320.png", + "expectedErrors": [], + "category": "empty" + }, + { + "name": "error", + "width": 320, + "passed": true, + "actualPath": "/office/program/1/analytics", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-modal", + "app-program-analytics", + "app-analytics-drilldown", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-program-analytics" + ], + "text": "Программы\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nназад\nКонтакты\n\nУправление программой\n\nАналитика\n\nСводка пути участников от регистрации до экспертной оценки.\n\nАналитика недоступна\n\nНе удалось загрузить аналитику. ", + "screenshot": "screenshots/states/error-320.png", + "expectedErrors": [ + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[23:06:35.412] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 55ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"", + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[23:06:37.419] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 4ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"", + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[23:06:41.425] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 4ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"", + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[23:06:49.431] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 4ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"" + ], + "category": "error", + "injectedHttp500": true, + "retryPassed": true + }, + { + "name": "disabled-action", + "width": 320, + "passed": true, + "actualPath": "/office/courses/1/lesson/1", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task" + ], + "text": "Курсы\nназад\n\nмодуль 1\n\nурок 1\n\nо курсе\n\n1\n\nзадание 1\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазван...\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nответ\n\n0 / 1000\n\nзавершить урок", + "screenshot": "screenshots/states/disabled-action-320.png", + "expectedErrors": [], + "category": "disabled" + }, + { + "name": "disabled-filter", + "width": 320, + "passed": true, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-state", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-state" + ], + "text": "Новости\nвсе новости\n0\nновости проектов\n0\nсвежие вакансии\n0\nновости сообщества\n0\nновости программ\n0\nобразование\n0\n\nв данном разделе пока нет новостей", + "screenshot": "screenshots/states/disabled-filter-320.png", + "expectedErrors": [], + "category": "disabled" + }, + { + "name": "validation-register", + "width": 320, + "passed": true, + "actualPath": "/auth/register", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-auth", + "app-login", + "app-input", + "app-checkbox", + "app-button", + "app-modal", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-auth", + "app-login", + "app-input", + "app-checkbox", + "app-button" + ], + "text": "имя\nфамилия\nдата рождения\nпочта\nпароль\nповторите пароль\nОбязательное поле\nя прочитал соглашение и даю согласие на обработку персональных данных\nнажимая на кнопку подтверждаете, что вам больше 14 лет\nзарегистрироваться\n\nесли есть аккаунт? - войдите", + "screenshot": "screenshots/states/validation-register-320.png", + "expectedErrors": [], + "category": "validation" + }, + { + "name": "validation-onboarding", + "width": 320, + "passed": true, + "actualPath": "/office/onboarding/stage-0", + "actualQuery": "", + "viewport": 320, + "pageWidth": 320, + "bodyWidth": 320, + "overflows": [], + "rendered": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-modal", + "app-region-select", + "app-select", + "app-dropdown", + "app-input", + "app-button", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-region-select", + "app-select", + "app-input", + "app-button" + ], + "text": "1\n2\n3\n4\nПривет, ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов Тестовый! ✌️\n\nРасскажите о себе, чтобы ваше резюме было сильным и отражало опыт\n\nФотография профиля*\n\nВыберите фото для профиля\nРегион*\n\nОбразование\n\nУровень о", + "screenshot": "screenshots/states/validation-onboarding-320.png", + "expectedErrors": [], + "category": "validation" + }, + { + "name": "projects", + "width": 390, + "passed": true, + "actualPath": "/office/projects/all", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-projects-filter", + "app-select", + "app-dropdown", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-projects-filter", + "app-select" + ], + "text": "Проекты\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\nФильтр\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nПроект для проверки адаптива\n\nОткрыть\n\nфильтры\n\nсбросить\nсфера проекта", + "screenshot": "screenshots/states/projects-390.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "vacancies", + "width": 390, + "passed": true, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter" + ], + "text": "Вакансии\nвакансии\n\nПоиск\n\nАктивна\n01.10.2026\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nПроект\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробело", + "screenshot": "screenshots/states/vacancies-390.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "programs", + "width": 390, + "passed": true, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card" + ], + "text": "Программы\nпрограммы\n\nПоиск\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nты уже участвуешь!\n\n01.10.2026 - 01.01.2027\n\nдля всей России", + "screenshot": "screenshots/states/programs-390.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "courses", + "width": 390, + "passed": true, + "actualPath": "/office/courses/all", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge", + "app-soon-card", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge" + ], + "text": "Курсы\nкурсы\n\nПоиск\n\nдоступно всем пользователям\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазвани...\n\n01.01.2026 — 01.01.2027\n\nпродолжить обучение", + "screenshot": "screenshots/states/courses-390.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "profile", + "width": 390, + "passed": true, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "Профиль\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов Тестовый\nподелиться профилем\nмои проекты\ncкачать CV\nредактировать\nметаданные\n\n26 лет\n\nМосква\n\nРазработчик\n\nобо мне\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазвание", + "screenshot": "screenshots/states/profile-390.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "profile-edit", + "width": 390, + "passed": true, + "actualPath": "/office/profile/edit", + "actualQuery": "?editingStep=main", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-modal", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea" + ], + "text": "Редактирование профиля\nредактирование профиля\ncохранить\nосновные данные\nобразование\nработа\nдостижения\nнавыки\nдействия\nфото\nимя\nфамилия\nРегион\nдата рождения\nспециальность\nобо мне\n\n124 / 300\n\nуказать личные контакты\nдобавить контакт\nтелефон", + "screenshot": "screenshots/states/profile-edit-390.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "onboarding-0", + "width": 390, + "passed": true, + "actualPath": "/office/onboarding/stage-0", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-modal", + "app-region-select", + "app-select", + "app-dropdown", + "app-input", + "app-button", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-region-select", + "app-select", + "app-input", + "app-button" + ], + "text": "1\n2\n3\n4\nПривет, ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов Тестовый! ✌️\n\nРасскажите о себе, чтобы ваше резюме было сильным и отражало опыт\n\nФотография профиля*\n\nРегион*\n\nОбразование\n\nУровень образования\nВысшее образова", + "screenshot": "screenshots/states/onboarding-0-390.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "onboarding-1", + "width": 390, + "passed": true, + "actualPath": "/office/onboarding/stage-1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-onboarding", + "app-stage-one", + "app-tooltip", + "app-button", + "app-autocomplete-input", + "app-specializations-group", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-onboarding", + "app-stage-one", + "app-tooltip", + "app-button", + "app-autocomplete-input", + "app-specializations-group" + ], + "text": "1\n2\n3\n4\nКем хотите работать?\nзакончить регистрацию позже\nпродолжить\nпоиск по библиотеке\nбиблиотека\nРазработчик", + "screenshot": "screenshots/states/onboarding-1-390.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "loading-page", + "width": 390, + "passed": true, + "actualPath": "/office/program/1/analytics", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-modal", + "app-program-analytics", + "app-analytics-drilldown", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-program-analytics" + ], + "text": "Программы\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nназад\nКонтакты\n\nУправление программой\n\nАналитика\n\nСводка пути участников от регистрации до экспертной оценки.\n\nЗагружаем аналитику программы…", + "screenshot": "screenshots/states/loading-page-390.png", + "expectedErrors": [], + "category": "loading" + }, + { + "name": "loading-action", + "width": 390, + "passed": true, + "actualPath": "/office/courses/1/lesson/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task", + "app-loader", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task", + "app-loader" + ], + "text": "Курсы\nназад\n\nмодуль 1\n\nурок 1\n\nо курсе\n\n1\n\nзадание 1\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазван...\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nответ\n\n35 / 1000\n\nзавершить урок", + "screenshot": "screenshots/states/loading-action-390.png", + "expectedErrors": [], + "category": "loading", + "submissions": 1 + }, + { + "name": "empty", + "width": 390, + "passed": true, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-state", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-state", + "app-button", + "app-vacancy-filter" + ], + "text": "Вакансии\nвакансии\n\nПоиск\n\nВакансии не найдены\n\nПопробуйте изменить запрос или сбросить фильтры.\n\nСбросить фильтры\nфильтры\nмои отклики", + "screenshot": "screenshots/states/empty-390.png", + "expectedErrors": [], + "category": "empty" + }, + { + "name": "error", + "width": 390, + "passed": true, + "actualPath": "/office/program/1/analytics", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-modal", + "app-program-analytics", + "app-analytics-drilldown", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-detail", + "app-page-header", + "app-button", + "app-program-analytics" + ], + "text": "Программы\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\nназад\nКонтакты\n\nУправление программой\n\nАналитика\n\nСводка пути участников от регистрации до экспертной оценки.\n\nАналитика недоступна\n\nНе удалось загрузить аналитику. ", + "screenshot": "screenshots/states/error-390.png", + "expectedErrors": [ + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[23:07:12.519] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 44ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"", + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[23:07:14.527] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 3ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"", + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[23:07:18.539] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 7ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"", + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[23:07:26.548] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 3ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"" + ], + "category": "error", + "injectedHttp500": true, + "retryPassed": true + }, + { + "name": "disabled-action", + "width": 390, + "passed": true, + "actualPath": "/office/courses/1/lesson/1", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task" + ], + "text": "Курсы\nназад\n\nмодуль 1\n\nурок 1\n\nо курсе\n\n1\n\nзадание 1\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазван...\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов\n\nответ\n\n0 / 1000\n\nзавершить урок", + "screenshot": "screenshots/states/disabled-action-390.png", + "expectedErrors": [], + "category": "disabled" + }, + { + "name": "disabled-filter", + "width": 390, + "passed": true, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-state", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-avatar", + "app-feed", + "app-feed-filter", + "app-state" + ], + "text": "Новости\nвсе новости\n0\nновости проектов\n0\nсвежие вакансии\n0\nновости сообщества\n0\nновости программ\n0\nобразование\n0\n\nв данном разделе пока нет новостей", + "screenshot": "screenshots/states/disabled-filter-390.png", + "expectedErrors": [], + "category": "disabled" + }, + { + "name": "validation-register", + "width": 390, + "passed": true, + "actualPath": "/auth/register", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-auth", + "app-login", + "app-input", + "app-checkbox", + "app-button", + "app-modal", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-auth", + "app-login", + "app-input", + "app-checkbox", + "app-button" + ], + "text": "имя\nфамилия\nдата рождения\nпочта\nпароль\nповторите пароль\nОбязательное поле\nя прочитал соглашение и даю согласие на обработку персональных данных\nнажимая на кнопку подтверждаете, что вам больше 14 лет\nзарегистрироваться\n\nесли есть аккаунт? - войдите", + "screenshot": "screenshots/states/validation-register-390.png", + "expectedErrors": [], + "category": "validation" + }, + { + "name": "validation-onboarding", + "width": 390, + "passed": true, + "actualPath": "/office/onboarding/stage-0", + "actualQuery": "", + "viewport": 390, + "pageWidth": 390, + "bodyWidth": 390, + "overflows": [], + "rendered": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-modal", + "app-region-select", + "app-select", + "app-dropdown", + "app-input", + "app-button", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-region-select", + "app-select", + "app-input", + "app-button" + ], + "text": "1\n2\n3\n4\nПривет, ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов Тестовый! ✌️\n\nРасскажите о себе, чтобы ваше резюме было сильным и отражало опыт\n\nФотография профиля*\n\nВыберите фото для профиля\nРегион*\n\nОбразование\n\nУровень о", + "screenshot": "screenshots/states/validation-onboarding-390.png", + "expectedErrors": [], + "category": "validation" + }, + { + "name": "projects", + "width": 1440, + "passed": true, + "actualPath": "/office/projects/all", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-modal", + "app-projects-filter", + "app-select", + "app-dropdown", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-projects", + "app-page-header", + "app-back", + "app-button", + "app-search", + "app-bar-new", + "app-tabs", + "app-list", + "app-info-card", + "app-projects-filter", + "app-select" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nОченьДлинноеНазваниеБезПробело...\n\nпроекты\nсоздать проект\n\nПоиск\n\nмои проекты\nмои подписки\nмои приглашения\nвсе проекты\n\nОче", + "screenshot": "screenshots/states/projects-1440.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "vacancies", + "width": 1440, + "passed": true, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-project-vacancy-card", + "app-vacancy-status", + "app-badge", + "app-vacancy-skills", + "app-tag", + "app-button", + "app-vacancy-filter", + "app-checkbox" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nОченьДлинноеНазваниеБезПробело...\n\nвакансии\n\nПоиск\n\nАктивна\n01.10.2026\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБ", + "screenshot": "screenshots/states/vacancies-1440.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "programs", + "width": 1440, + "passed": true, + "actualPath": "/office/program/all", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-program", + "app-page-header", + "app-back", + "app-search", + "app-main", + "app-program-card", + "app-checkbox", + "app-select" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nОченьДлинноеНазваниеБезПробело...\n\nпрограммы\n\nПоиск\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДли", + "screenshot": "screenshots/states/programs-1440.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "courses", + "width": 1440, + "passed": true, + "actualPath": "/office/courses/all", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge", + "app-soon-card", + "app-button", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-track-career", + "app-page-header", + "app-back", + "app-search", + "app-list", + "app-course", + "app-badge", + "app-soon-card", + "app-button" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nОченьДлинноеНазваниеБезПробело...\n\nкурсы\n\nПоиск\n\nдоступно всем пользователям\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНа", + "screenshot": "screenshots/states/courses-1440.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "profile", + "width": 1440, + "passed": true, + "actualPath": "/office/profile/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-modal", + "app-news-form", + "app-textarea", + "app-news-card", + "app-carousel", + "app-profile-right-side", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-profile-main", + "app-profile-left-side", + "app-profile-mid-side", + "app-project-direction-card", + "app-news-form", + "app-textarea", + "app-news-card", + "app-profile-right-side" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nОченьДлинноеНазваниеБезПробело...\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПро", + "screenshot": "screenshots/states/profile-1440.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "profile-edit", + "width": 1440, + "passed": true, + "actualPath": "/office/profile/edit", + "actualQuery": "?editingStep=main", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-modal", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-profile-edit", + "app-page-header", + "app-back", + "app-button", + "app-project-navigation", + "app-tabs", + "app-profile-main-step", + "app-avatar-control", + "app-input", + "app-region-select", + "app-autocomplete-input", + "app-textarea" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nОченьДлинноеНазваниеБезПробело...\n\nредактирование профиля\ncохранить\nосновные данные\nобразование\nработа\nдостижения\nнавыки\nде", + "screenshot": "screenshots/states/profile-edit-1440.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "onboarding-0", + "width": 1440, + "passed": true, + "actualPath": "/office/onboarding/stage-0", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-modal", + "app-region-select", + "app-select", + "app-dropdown", + "app-input", + "app-button", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-region-select", + "app-select", + "app-input", + "app-button" + ], + "text": "1\nОсновные данные\n2\nСпециальность\n3\nНавыки\n4\nТип аккаунта\nПривет, ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов Тестовый! ✌️\n\nРасскажите о себе, чтобы ваше резюме было сильным и отражало опыт\n\nФотография профиля*\n\nРегион*", + "screenshot": "screenshots/states/onboarding-0-1440.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "onboarding-1", + "width": 1440, + "passed": true, + "actualPath": "/office/onboarding/stage-1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-onboarding", + "app-stage-one", + "app-tooltip", + "app-button", + "app-autocomplete-input", + "app-specializations-group", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-onboarding", + "app-stage-one", + "app-tooltip", + "app-button", + "app-autocomplete-input", + "app-specializations-group" + ], + "text": "1\nОсновные данные\n2\nСпециальность\n3\nНавыки\n4\nТип аккаунта\nКем хотите работать?\nзакончить регистрацию позже\nпродолжить\nпоиск по библиотеке\nбиблиотека\nРазработчик", + "screenshot": "screenshots/states/onboarding-1-1440.png", + "expectedErrors": [], + "category": "section" + }, + { + "name": "loading-page", + "width": 1440, + "passed": true, + "actualPath": "/office/program/1/analytics", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-program-analytics", + "app-analytics-drilldown", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-program-analytics" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nОченьДлинноеНазваниеБезПробело...\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПро", + "screenshot": "screenshots/states/loading-page-1440.png", + "expectedErrors": [], + "category": "loading" + }, + { + "name": "loading-action", + "width": 1440, + "passed": true, + "actualPath": "/office/courses/1/lesson/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task", + "app-loader", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task", + "app-loader" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nОченьДлинноеНазваниеБезПробело...\n\nназад\nвернуться в программу\n\nмодуль 1\n\nурок 1\n\n1\n\nзадание 1\n\nОченьДлинноеНазваниеБезПроб", + "screenshot": "screenshots/states/loading-action-1440.png", + "expectedErrors": [], + "category": "loading", + "submissions": 1 + }, + { + "name": "empty", + "width": 1440, + "passed": true, + "actualPath": "/office/vacancies/all", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-state", + "app-button", + "app-vacancy-filter", + "app-checkbox", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-vacancies", + "app-page-header", + "app-back", + "app-search", + "app-vacancies-list", + "app-state", + "app-button", + "app-vacancy-filter", + "app-checkbox" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nОченьДлинноеНазваниеБезПробело...\n\nвакансии\n\nПоиск\n\nВакансии не найдены\n\nПопробуйте изменить запрос или сбросить фильтры.\n\n", + "screenshot": "screenshots/states/empty-1440.png", + "expectedErrors": [], + "category": "empty" + }, + { + "name": "error", + "width": 1440, + "passed": true, + "actualPath": "/office/program/1/analytics", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-program-analytics", + "app-analytics-drilldown", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-detail", + "app-page-header", + "app-button", + "app-program-analytics" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nОченьДлинноеНазваниеБезПробело...\n\nОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПро", + "screenshot": "screenshots/states/error-1440.png", + "expectedErrors": [ + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[23:07:49.507] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 46ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"", + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[23:07:51.513] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 3ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"", + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[23:07:55.520] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 3ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"", + "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", + "[23:08:03.527] [ERROR] [HTTP] GET https://api.procollab.ru/programs/1/manager-overview/ 500 3ms \"Http failure response for https://api.procollab.ru/programs/1/manager-overview/: 500 Internal Server Error\"" + ], + "category": "error", + "injectedHttp500": true, + "retryPassed": true + }, + { + "name": "disabled-action", + "width": 1440, + "passed": true, + "actualPath": "/office/courses/1/lesson/1", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-course-detail", + "app-button", + "app-lesson", + "app-write-task" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nОченьДлинноеНазваниеБезПробело...\n\nназад\nвернуться в программу\n\nмодуль 1\n\nурок 1\n\n1\n\nзадание 1\n\nОченьДлинноеНазваниеБезПроб", + "screenshot": "screenshots/states/disabled-action-1440.png", + "expectedErrors": [], + "category": "disabled" + }, + { + "name": "disabled-filter", + "width": 1440, + "passed": true, + "actualPath": "/office/feed", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-nav", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-state", + "app-modal", + "app-delete-confirm", + "app-snackbar", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-office", + "app-program-sidebar-card", + "app-avatar", + "app-profile-control-panel", + "app-profile-info", + "app-feed", + "app-feed-filter", + "app-state" + ], + "text": "мой профиль\nновости\nпроекты\nучастники\nпрограммы\nвакансии\nкурсы\n\nПлатформа создана компанией ООО «Молодежный форсайт»\n\nПолитика обработки персональных данных\n\n2026\n\nдо 01.01.27\n\nОченьДлинноеНазваниеБезПробело...\n\nвсе новости\n0\nновости проектов\n0\nсвежие вакансии\n0\nновости сообщества\n0\nновости программ", + "screenshot": "screenshots/states/disabled-filter-1440.png", + "expectedErrors": [], + "category": "disabled" + }, + { + "name": "validation-register", + "width": 1440, + "passed": true, + "actualPath": "/auth/register", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-auth", + "app-login", + "app-input", + "app-checkbox", + "app-button", + "app-modal", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-auth", + "app-login", + "app-input", + "app-checkbox", + "app-button" + ], + "text": "имя\nфамилия\nдата рождения\nпочта\nпароль\nповторите пароль\nОбязательное поле\nя прочитал соглашение и даю согласие на обработку персональных данных\nнажимая на кнопку подтверждаете, что вам больше 14 лет\nзарегистрироваться\n\nесли есть аккаунт? - войдите", + "screenshot": "screenshots/states/validation-register-1440.png", + "expectedErrors": [], + "category": "validation" + }, + { + "name": "validation-onboarding", + "width": 1440, + "passed": true, + "actualPath": "/office/onboarding/stage-0", + "actualQuery": "", + "viewport": 1440, + "pageWidth": 1425, + "bodyWidth": 1425, + "overflows": [], + "rendered": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-modal", + "app-region-select", + "app-select", + "app-dropdown", + "app-input", + "app-button", + "app-cookie-consent" + ], + "visibleApps": [ + "app-root", + "app-onboarding", + "app-stage-zero", + "app-tooltip", + "app-avatar-control", + "app-region-select", + "app-select", + "app-input", + "app-button" + ], + "text": "1\nОсновные данные\n2\nСпециальность\n3\nНавыки\n4\nТип аккаунта\nПривет, ОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробеловОченьДлинноеНазваниеБезПробелов Тестовый! ✌️\n\nРасскажите о себе, чтобы ваше резюме было сильным и отражало опыт\n\nФотография профиля*\n\nВыберит", + "screenshot": "screenshots/states/validation-onboarding-1440.png", + "expectedErrors": [], + "category": "validation" + } + ] +} diff --git a/docs/mobile-polish/states.log b/docs/mobile-polish/states.log new file mode 100644 index 000000000..a003b8544 --- /dev/null +++ b/docs/mobile-polish/states.log @@ -0,0 +1,49 @@ +{"name":"projects","width":320,"passed":true} +{"name":"vacancies","width":320,"passed":true} +{"name":"programs","width":320,"passed":true} +{"name":"courses","width":320,"passed":true} +{"name":"profile","width":320,"passed":true} +{"name":"profile-edit","width":320,"passed":true} +{"name":"onboarding-0","width":320,"passed":true} +{"name":"onboarding-1","width":320,"passed":true} +{"name":"loading-page","width":320,"passed":true} +{"name":"loading-action","width":320,"passed":true} +{"name":"empty","width":320,"passed":true} +{"name":"error","width":320,"passed":true} +{"name":"disabled-action","width":320,"passed":true} +{"name":"disabled-filter","width":320,"passed":true} +{"name":"validation-register","width":320,"passed":true} +{"name":"validation-onboarding","width":320,"passed":true} +{"name":"projects","width":390,"passed":true} +{"name":"vacancies","width":390,"passed":true} +{"name":"programs","width":390,"passed":true} +{"name":"courses","width":390,"passed":true} +{"name":"profile","width":390,"passed":true} +{"name":"profile-edit","width":390,"passed":true} +{"name":"onboarding-0","width":390,"passed":true} +{"name":"onboarding-1","width":390,"passed":true} +{"name":"loading-page","width":390,"passed":true} +{"name":"loading-action","width":390,"passed":true} +{"name":"empty","width":390,"passed":true} +{"name":"error","width":390,"passed":true} +{"name":"disabled-action","width":390,"passed":true} +{"name":"disabled-filter","width":390,"passed":true} +{"name":"validation-register","width":390,"passed":true} +{"name":"validation-onboarding","width":390,"passed":true} +{"name":"projects","width":1440,"passed":true} +{"name":"vacancies","width":1440,"passed":true} +{"name":"programs","width":1440,"passed":true} +{"name":"courses","width":1440,"passed":true} +{"name":"profile","width":1440,"passed":true} +{"name":"profile-edit","width":1440,"passed":true} +{"name":"onboarding-0","width":1440,"passed":true} +{"name":"onboarding-1","width":1440,"passed":true} +{"name":"loading-page","width":1440,"passed":true} +{"name":"loading-action","width":1440,"passed":true} +{"name":"empty","width":1440,"passed":true} +{"name":"error","width":1440,"passed":true} +{"name":"disabled-action","width":1440,"passed":true} +{"name":"disabled-filter","width":1440,"passed":true} +{"name":"validation-register","width":1440,"passed":true} +{"name":"validation-onboarding","width":1440,"passed":true} +48 UI state checks passed diff --git a/docs/mobile-polish/styles.log b/docs/mobile-polish/styles.log new file mode 100644 index 000000000..e69de29bb diff --git a/docs/mobile-polish/tests.log b/docs/mobile-polish/tests.log new file mode 100644 index 000000000..4b0aa0624 --- /dev/null +++ b/docs/mobile-polish/tests.log @@ -0,0 +1,1137 @@ + +> procollab@0.0.0 test:ci +> vitest run + + + RUN v3.2.6 Z:/Документы/PROCOLLAB-dev/procollab-dev-platform-responsive + + ✓ projects/social_platform/src/app/api/chat/use-cases/edit-message.use-case.spec.ts (1 test) 39ms + ✓ projects/social_platform/src/app/ui/widgets/project-invite/profile-project-invite-modal.component.spec.ts (21 tests) 2998ms + ✓ Окно выбора проекта > локальный поиск нормализует пробелы и регистр, строка выбирается целиком и выделяется 649ms +stderr | projects/social_platform/src/app/ui/widgets/info-card/info-card-subscription.spec.ts > InfoCard: асинхронная подписка (base) > не закрашивает закладку при ошибке подписки +[22:48:37.469] [ERROR] Error subscribing to project: {"kind":"add_project_subscription_error","cause":{}} + +stderr | projects/social_platform/src/app/ui/widgets/info-card/info-card-subscription.spec.ts > InfoCard: асинхронная подписка (base) > сохраняет подписку и подтверждение при ошибке, после успешного повтора закрывает +[22:48:37.609] [ERROR] Error unsubscribing from project: {"kind":"delete_project_subscription_error","cause":{}} + +stderr | projects/social_platform/src/app/ui/widgets/info-card/info-card-subscription.spec.ts > InfoCard: асинхронная подписка (subs) > не закрашивает закладку при ошибке подписки +[22:48:38.044] [ERROR] Error subscribing to project: {"kind":"add_project_subscription_error","cause":{}} + +stderr | projects/social_platform/src/app/ui/widgets/info-card/info-card-subscription.spec.ts > InfoCard: асинхронная подписка (subs) > сохраняет подписку и подтверждение при ошибке, после успешного повтора закрывает +[22:48:38.181] [ERROR] Error unsubscribing from project: {"kind":"delete_project_subscription_error","cause":{}} + + ✓ projects/social_platform/src/app/ui/widgets/info-card/info-card-subscription.spec.ts (8 tests) 2570ms + ✓ InfoCard: асинхронная подписка (base) > закрашивает закладку после отложенного ответа без перезагрузки и второго клика 1430ms + ✓ projects/social_platform/src/app/ui/pages/members/members-mobile.spec.ts (7 tests) 2752ms + ✓ Мобильное представление участников > держит статистику перед мобильным списком, под desktop-фильтрами и не перезагружает её при поиске 1381ms + ✓ Мобильное представление участников > открывает ту же форму отдельно, сохраняет фильтры после закрытия, возвращает фокус 338ms + ✓ projects/social_platform/src/app/ui/widgets/news-card/feed-news-preview/feed-news-preview.component.spec.ts (23 tests) 2856ms + ✓ FeedNewsPreviewComponent > project: нет пустой media-области; thumbnail появляется только с изображением 926ms + ✓ projects/social_platform/src/app/ui/pages/projects/edit/components/project-team-step/project-team-step.component.spec.ts (7 tests) 2897ms + ✓ Окно приглашения из редактора команды > CTA открывает окно с поиском, URL отсутствует, отправка неактивна до выбора и роли 1391ms + ✓ Окно приглашения из редактора команды > показывает public data, причины disabled, выбирает строку и очищает выбор 566ms + ✓ Окно приглашения из редактора команды > ошибка inline сохраняет выбор/роль, повтор защищён, успех закрывает и возвращает фокус 550ms + ✓ projects/social_platform/src/app/api/courses/use-cases/submit-task-answer.use-case.spec.ts (3 tests) 115ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/analytics/drilldown/analytics-drilldown.component.spec.ts (30 tests) 3809ms + ✓ AnalyticsDrilldownComponent: real overlay lifecycle > all: единое оформление списка и правильный заголовок 1066ms + ✓ projects/social_platform/src/app/ui/pages/projects/edit/components/project-main-step/project-main-step.component.spec.ts (12 tests) 4695ms + ✓ ProjectMainStepComponent > стандартная обложка предлагает загрузку и не выдаёт системный URL за загруженный файл 2189ms + ✓ ProjectMainStepComponent > пользовательская обложка предлагает только замену с клавиатуры, без кнопки сброса 354ms + ✓ projects/social_platform/src/app/ui/pages/profile/edit/components/profile-main-step/profile-main-step.component.spec.ts (6 tests) 5411ms + ✓ ProfileMainStepComponent user region > loads canonical city as selected user region without API side effects 3601ms + ✓ ProfileMainStepComponent user region > preserves untouched legacy city Набережные Челны through focus, blur and Escape 598ms + ✓ ProfileMainStepComponent user region > preserves untouched legacy city Мсква through focus, blur and Escape 423ms + ✓ projects/social_platform/src/app/ui/widgets/info-card/info-card.component.spec.ts (41 tests) 5868ms + ✓ InfoCardComponent: статусы моих проектов > 'draft' / 'Лидер': статус, доступ и единственный корректный маршрут 2351ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/analytics/drilldown/analytics-attention.component.spec.ts (19 tests) 6205ms + ✓ Attention views: real overlay > participants: реальные поля, local date, legacy city, fallback, актуальный count 2464ms + ✓ Attention views: real overlay > server search только submit, clear, count и pagination из detail 586ms + ✓ Attention views: real overlay > not-submitted: server search via submit/button, clear and page 411ms + ✓ projects/social_platform/src/app/ui/pages/onboarding/stage-zero/stage-zero.component.spec.ts (3 tests) 1581ms + ✓ StageZeroComponent > should create 1013ms + ✓ StageZeroComponent > preserves an initial legacy city without automatically selecting a region 301ms + ✓ projects/social_platform/src/app/ui/pages/projects/dashboard/dashboard.component.spec.ts (3 tests) 1402ms + ✓ ProjectsDashboard: контексты карточек > передаёт my/subs/base, ID и подписки; показывает нужный контекст каждого раздела 1210ms + ✓ projects/social_platform/src/app/ui/pages/projects/projects-presentation.spec.ts (6 tests) 1258ms + ✓ ProjectsComponent: приглашение и активность на странице > сохраняет размещение активности в разделе dashboard 687ms + ✓ projects/social_platform/src/app/ui/widgets/detail/detail-cleanup.component.spec.ts (5 tests) 1583ms + ✓ Detail cleanup actions > renders create, open-existing and submitted CTA states without changing submitted disabling 887ms + ✓ projects/social_platform/src/app/ui/pages/profile/edit/edit.component.spec.ts (3 tests) 1889ms + ✓ ProfileEditComponent > should create 1157ms + ✓ ProfileEditComponent > closes the skills library with the explicit close button 470ms +stderr | projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/rating-card.component.spec.ts > RatingCardComponent > keeps unrated CTA active and criteria editable when registration is past but evaluation is future + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + +stderr | projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/rating-card.component.spec.ts > RatingCardComponent > allows editing an existing rating until the evaluation deadline, then returns to readonly on success + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + ✓ projects/social_platform/src/app/ui/pages/program/detail/analytics/drilldown/analytics-case.component.spec.ts (12 tests) 2154ms + ✓ Case drilldown в существующем Overlay > selected: четыре колонки, реальные поля, null presentation и только один modal 1213ms +stderr | projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/rating-card.component.spec.ts > RatingCardComponent > allows editing an existing rating until the evaluation deadline, then returns to readonly on success + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + ✓ projects/social_platform/src/app/ui/pages/projects/list/list.component.spec.ts (9 tests) 2461ms + ✓ ProjectsListComponent: контекст и track > /my: CTA выполняет один переход в detail 1130ms +stderr | projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/rating-card.component.spec.ts > RatingCardComponent > keeps expired CTA visible and all criteria readonly (rated=false) + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + +stderr | projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/rating-card.component.spec.ts > RatingCardComponent > keeps expired CTA visible and all criteria readonly (rated=true) + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + +stderr | projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/rating-card.component.spec.ts > RatingCardComponent > keeps CTA and criteria available for deadline + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + +stderr | projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/rating-card.component.spec.ts > RatingCardComponent > keeps CTA and criteria available for invalid deadline + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + +stderr | projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/rating-card.component.spec.ts > RatingCardComponent > updates visible CTA and criteria on fresh closed/reopened program responses + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the `disabled` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); + + + ✓ projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/rating-card.component.spec.ts (8 tests) 1624ms + ✓ RatingCardComponent > should create 459ms + ✓ RatingCardComponent > allows editing an existing rating until the evaluation deadline, then returns to readonly on success 332ms + ✓ projects/social_platform/src/app/ui/pages/projects/edit/components/project-additional-step/project-additional-step.component.spec.ts (8 tests) 1874ms + ✓ ProjectAdditionalStepComponent canonical form > required indicators follow backend metadata; optional text has no fake required error 884ms + ✓ projects/social_platform/src/app/ui/pages/projects/edit/edit.component.spec.ts (3 tests) 1370ms + ✓ ProjectEditComponent > should create 1155ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/main/role-widget/program-role-widget.component.spec.ts (11 tests) 1257ms + ✓ ProgramRoleWidgetComponent > shows skeleton without bogus zero counters 400ms + ✓ projects/social_platform/src/app/ui/widgets/info-card/info-card-list-contract.spec.ts (8 tests) 1030ms + ✓ Мои проекты: HTTP list → преобразование контракта → карточка > is_submitted=true, draft=false: lifecycle и доступ независимы 582ms + ✓ projects/social_platform/src/app/ui/pages/profile/detail/main/main.component.spec.ts (1 test) 847ms + ✓ MainComponent > should create 845ms + ✓ projects/social_platform/src/app/ui/primitives/input/input.component.spec.ts (20 tests) 931ms + ✓ InputComponent > should create the component 356ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/main/main.roles.spec.ts (4 tests) 1069ms + ✓ Program page: program-scoped news and role visibility > loads and shows both existing and newly created news for manager without member role 810ms + ✓ projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-mid-side/profile-mid-side.component.spec.ts (4 tests) 995ms + ✓ ProfileMidSideComponent > показывает центрируемый empty state владельцу пустого профиля 667ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/list/list.component.spec.ts (2 tests) 1014ms + ✓ ProgramListComponent > should create 803ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/analytics/analytics.component.spec.ts (42 tests) 14302ms + ✓ ProgramAnalyticsComponent > cases from manager overview > не показывает общую выгрузку и не запрашивает проекты до открытия кейса 2473ms + ✓ ProgramAnalyticsComponent > cases from manager overview > клик строки 0 передаёт точный scope, включая нулевой кейс 448ms + ✓ ProgramAnalyticsComponent > cases from manager overview > клик строки 2 передаёт точный scope, включая нулевой кейс 397ms + ✓ ProgramAnalyticsComponent > cases from manager overview > клик строки 3 передаёт точный scope, включая нулевой кейс 408ms + ✓ ProgramAnalyticsComponent > cases from manager overview > keeps cases and evaluation as adjacent cards in the same two-column grid row 430ms + ✓ ProgramAnalyticsComponent > cases from manager overview > preserves backend counts/order/zero rows and appends withoutCase without mutations 342ms + ✓ ProgramAnalyticsComponent > cases from manager overview > renders controlled empty state when configured=true 319ms + ✓ ProgramAnalyticsComponent > Участники без команды: button, zero disabled, tooltip отдельно 302ms + ✓ ProgramAnalyticsComponent > Работы ожидают оценивания: button, zero disabled, tooltip отдельно 405ms + ✓ ProgramAnalyticsComponent > not-submitted: порядок, активная/нулевая строка и tooltip отдельно 390ms + ✓ ProgramAnalyticsComponent > non-competitive скрывает строку даже с notSubmitted > 0 и не делает detail request 363ms + ✓ ProgramAnalyticsComponent > строит воронки только из participantFunnel и solutionFunnel 406ms + ✓ ProgramAnalyticsComponent > в open mode показывает статусы проектов без partial и трактует max как лимит 368ms + ✓ ProgramAnalyticsComponent > использует attention backend напрямую, без frontend approximation 312ms + ✓ ProgramAnalyticsComponent > marks zero attention rows and keeps tooltip controls separate and keyboard accessible 368ms + ✓ ProgramAnalyticsComponent > exports each loaded region dataset independently and prevents repeated clicks 320ms + ✓ projects/social_platform/src/app/ui/pages/feed/feed.component.spec.ts (1 test) 937ms + ✓ FeedComponent: порядок и представление карточек #372 > сохраняет шесть начальных карточек, ключи type:id и append в DOM без перестановки 935ms + ✓ projects/social_platform/src/app/ui/widgets/news-form/news-form.component.spec.ts (7 tests) 832ms + ✓ NewsFormComponent > should create 367ms + ✓ projects/social_platform/src/app/ui/pages/vacancies/detail/info/info.component.spec.ts (3 tests) 892ms + ✓ VacancyInfoComponent PROCOLLAB CV > разрешает прикрепить PROCOLLAB CV при пустом accompanyingFile 654ms + ✓ projects/social_platform/src/app/ui/widgets/news-card/news-card.component.spec.ts (5 tests) 1060ms + ✓ NewsCardComponent > should create 684ms + ✓ projects/social_platform/src/app/ui/pages/projects/detail/info/info.component.spec.ts (1 test) 748ms + ✓ ProjectInfoComponent > should create 746ms + ✓ projects/social_platform/src/app/ui/pages/projects/detail/info/components/projects-mid-side/projects-mid-side.component.spec.ts (4 tests) 706ms + ✓ ProjectsMidSideComponent > shows the complete project description after expansion 693ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/analytics/drilldown/analytics-attention-route.spec.ts (3 tests) 946ms + ✓ Attention SPA: observable route → resolver → overview > participants-without-team отменяется до Program(13), без нового auto request 698ms + ✓ projects/social_platform/src/app/ui/pages/auth/register/register.component.spec.ts (4 tests) 915ms + ✓ RegisterComponent > should create 635ms + ✓ projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancy-responses/vacancy-responses.component.spec.ts (12 tests) 730ms + ✓ VacancyResponsesComponent > показывает два действия только для pending response 452ms + ✓ projects/social_platform/src/app/ui/widgets/project-vacancy-card/project-vacancy-card.component.spec.ts (10 tests) 580ms + ✓ ProjectVacancyCardComponent > should create 313ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/main/main.component.spec.ts (2 tests) 648ms + ✓ MainComponent > should create 586ms +stdout | projects/social_platform/src/app/ui/pages/program/detail/register/register.component.spec.ts > ProgramRegisterComponent > onSubmit > вызывает use-case с programId и значениями формы +[22:48:53.656] [DEBUG] Route changed from ProgramRegisterComponent + +stdout | projects/social_platform/src/app/ui/pages/program/detail/register/register.component.spec.ts > ProgramRegisterComponent > onSubmit > навигирует на детальную страницу программы при успехе use-case +[22:48:53.695] [DEBUG] Route changed from ProgramRegisterComponent + +stdout | projects/social_platform/src/app/ui/pages/program/detail/register/register.component.spec.ts > ProgramRegisterComponent > onSubmit > срабатывает по клику на кнопку submit в DOM +[22:48:53.777] [DEBUG] Route changed from ProgramRegisterComponent + + ✓ projects/social_platform/src/app/ui/pages/program/detail/register/register.component.spec.ts (7 tests) 698ms + ✓ ProgramRegisterComponent > ngOnInit строит форму из schema резолвера > создаёт FormGroup с полем под каждый ключ schema 434ms + ✓ projects/social_platform/src/app/ui/pages/profile/detail/profile-news/profile-news.component.spec.ts (1 test) 525ms + ✓ ProfileNewsComponent > should create 524ms + ✓ projects/social_platform/src/app/ui/pages/auth/login/login.component.spec.ts (4 tests) 668ms + ✓ LoginComponent > should create 475ms + ✓ projects/social_platform/src/app/ui/widgets/region-select/region-select.component.spec.ts (12 tests) 591ms + ✓ projects/social_platform/src/app/ui/pages/members/members.component.spec.ts (1 test) 577ms + ✓ MembersComponent > should create 575ms + ✓ projects/social_platform/src/app/ui/pages/onboarding/stage-two/stage-two.component.spec.ts (4 tests) 733ms + ✓ StageTwoComponent > should create 486ms + ✓ projects/social_platform/src/app/ui/pages/vacancies/vacancies.component.spec.ts (2 tests) 557ms + ✓ VacanciesComponent > should create 465ms + ✓ projects/social_platform/src/app/ui/pages/office/office.component.spec.ts (3 tests) 716ms + ✓ OfficeComponent > should create 599ms + ✓ projects/social_platform/src/app/ui/pages/vacancies/list/list.component.spec.ts (7 tests) 548ms + ✓ VacanciesListComponent > должен вызвать vacancyInfoService.init() при инициализации компонента 343ms + ✓ projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-left-side/profile-left-side.component.spec.ts (6 tests) 409ms + ✓ projects/social_platform/src/app/api/profile/facades/edit/profile-form.service.spec.ts (8 tests) 473ms +stderr | projects/social_platform/src/app/ui/pages/auth/set-password/set-password.component.spec.ts > SetPasswordComponent > should create +[22:48:56.392] [ERROR] Token is missing + + ✓ projects/social_platform/src/app/ui/pages/auth/set-password/set-password.component.spec.ts (1 test) 457ms + ✓ SetPasswordComponent > should create 456ms + ✓ projects/social_platform/src/app/ui/pages/chat/chat-direct/chat-direct.component.spec.ts (1 test) 480ms + ✓ ChatDirectComponent > should create 471ms + ✓ projects/social_platform/src/app/ui/pages/projects/detail/news-detail/news-detail.component.spec.ts (1 test) 444ms + ✓ NewsDetailComponent > should create 439ms + ✓ projects/social_platform/src/app/ui/widgets/news-card/feed-news-modal/feed-news-modal.component.spec.ts (1 test) 446ms + ✓ FeedNewsModalComponent > показывает полный текст, переносы, ссылку, все файлы и contain-карусель без detail HTTP 444ms + ✓ projects/social_platform/src/app/ui/pages/auth/reset-password/reset-password.component.spec.ts (1 test) 352ms + ✓ ResetPasswordComponent > should create 350ms + ✓ projects/social_platform/src/app/ui/pages/courses/detail/info/course-module-card/course-module-card.component.spec.ts (7 tests) 448ms + ✓ projects/social_platform/src/app/ui/pages/onboarding/stage-one/stage-one.component.spec.ts (1 test) 386ms + ✓ StageOneComponent > should create 384ms + ✓ projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-right-side/vacancies-right-side.component.spec.ts (9 tests) 421ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/list/program-projects-filter/program-projects-filter.component.spec.ts (2 tests) 430ms + ✓ ProjectsFilterComponent > should create 334ms + ✓ projects/social_platform/src/app/ui/primitives/select/select.component.spec.ts (7 tests) 438ms + ✓ projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-right-side/profile-right-side.component.spec.ts (2 tests) 393ms + ✓ ProfileRightSideComponent > keeps the complete long project title in the profile project list DOM 333ms + ✓ projects/social_platform/src/app/ui/primitives/textarea/textarea.component.spec.ts (6 tests) 390ms + ✓ projects/social_platform/src/app/ui/pages/members/member-card/member-card.component.spec.ts (7 tests) 445ms + ✓ projects/social_platform/src/app/ui/pages/projects/edit/components/project-team-step/invite-card/invite-card.component.spec.ts (4 tests) 436ms + ✓ InviteCardComponent > should create 341ms + ✓ projects/social_platform/src/app/ui/widgets/chat-window/chat-window.component.spec.ts (1 test) 470ms + ✓ ChatWindowComponent > should create 467ms + ✓ projects/social_platform/src/app/ui/primitives/avatar-control/avatar-control.component.spec.ts (1 test) 410ms + ✓ AvatarControlComponent > should create 407ms + ✓ projects/social_platform/src/app/ui/pages/program/main/main.component.spec.ts (1 test) 378ms + ✓ MainComponent > should create 376ms +stdout | projects/social_platform/src/app/ui/widgets/projects-filter/projects-filter.component.spec.ts > ProjectsFilterComponent > сохраняет справочник отраслей и фильтрацию через query-параметр industry +[22:48:59.612] [DEBUG] Query change from ProjectsComponent + + ✓ projects/social_platform/src/app/ui/widgets/projects-filter/projects-filter.component.spec.ts (2 tests) 418ms + ✓ ProjectsFilterComponent > should create 366ms + ✓ projects/social_platform/src/app/ui/pages/vacancies/detail/vacancies-detail.component.spec.ts (2 tests) 383ms + ✓ projects/social_platform/src/app/ui/pages/members/member-statistics-card/member-statistics-card.component.spec.ts (11 tests) 359ms + ✓ projects/social_platform/src/app/ui/primitives/modal/modal.component.spec.ts (4 tests) 363ms + ✓ projects/social_platform/src/app/ui/pages/projects/detail/chat/chat.component.spec.ts (1 test) 417ms + ✓ ChatComponent > should create 416ms + ✓ projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.spec.ts (5 tests) 558ms + ✓ VacancyCardComponent > should create 418ms + ✓ projects/social_platform/src/app/ui/primitives/tooltip/tooltip.component.spec.ts (4 tests) 543ms + ✓ TooltipComponent overlay mode > should use overlay mode for analytics tooltip 393ms + ✓ projects/social_platform/src/app/ui/pages/projects/project-activity-card/project-activity-card.component.spec.ts (11 tests) 411ms + ✓ projects/social_platform/src/app/utils/export-regions-workbook.spec.ts (1 test) 372ms + ✓ region XLSX workbook integration > generates a ZIP/OOXML workbook with real string and number cells 370ms + ✓ projects/social_platform/src/app/ui/primitives/upload-file/upload-file.component.spec.ts (15 tests) 421ms + ✓ projects/social_platform/src/app/infrastructure/repository/invite/invite.repository.spec.ts (9 tests) 97ms + ✓ projects/social_platform/src/app/ui/pages/chat/chat.component.spec.ts (1 test) 347ms + ✓ ChatComponent > should create 344ms + ✓ projects/social_platform/src/app/ui/pages/members/members-filters/members-filters.component.spec.ts (2 tests) 357ms + ✓ MembersFiltersComponent > should create 311ms + ✓ projects/social_platform/src/app/ui/pages/courses/lesson/shared/video-task/info-task.component.spec.ts (1 test) 284ms + ✓ projects/social_platform/src/app/ui/pages/courses/lesson/shared/write-task/write-task.component.spec.ts (1 test) 292ms + ✓ projects/social_platform/src/app/ui/widgets/vacancy-filter/vacancy-filter.component.spec.ts (1 test) 267ms + ✓ projects/social_platform/src/app/api/program/use-cases/program-case-projects.use-case.spec.ts (15 tests) 115ms + ✓ projects/social_platform/src/app/ui/pages/feed/open-vacancy/open-vacancy.component.spec.ts (1 test) 326ms + ✓ OpenVacancyComponent > показывает тип, дату, источник, роль, описание, навыки и CTA 321ms + ✓ projects/social_platform/src/app/ui/pages/vacancies/list/response-card/response-card.component.spec.ts (6 tests) 300ms + ✓ projects/social_platform/src/app/ui/primitives/autocomplete-input/autocomplete-input.component.spec.ts (3 tests) 317ms + ✓ projects/social_platform/src/app/ui/widgets/skills-group/skills-group.component.spec.ts (4 tests) 295ms + ✓ projects/social_platform/src/app/ui/widgets/message-input/message-input.component.spec.ts (1 test) 423ms + ✓ MessageInputComponent > should create 420ms + ✓ projects/social_platform/src/app/ui/widgets/project-invite/project-invite-role-input.component.spec.ts (4 tests) 336ms + ✓ projects/social_platform/src/app/ui/widgets/specializations-group/specializations-group.component.spec.ts (4 tests) 456ms + ✓ SpecializationsGroupComponent > should create 311ms + ✓ projects/social_platform/src/app/ui/pages/courses/lesson/shared/exclude-task/exclude-task.component.spec.ts (1 test) 233ms + ✓ projects/social_platform/src/app/ui/pages/projects/edit/components/project-team-step/collaborator-card/collaborator-card.component.spec.ts (2 tests) 269ms + ✓ projects/social_platform/src/app/ui/pages/onboarding/stage-three/stage-three.component.spec.ts (1 test) 254ms + ✓ projects/social_platform/src/app/api/project/facades/edit/projects-edit-info.service.spec.ts (22 tests) 288ms + ✓ projects/social_platform/src/app/api/project/facades/edit/project-cover-reset.service.spec.ts (11 tests) 309ms + ✓ projects/social_platform/src/app/ui/pages/office/delete-confirm/delete-confirm.component.spec.ts (1 test) 302ms + ✓ projects/social_platform/src/app/app.component.spec.ts (1 test) 274ms + ✓ projects/social_platform/src/app/api/program/facades/detail/program-analytics-info.service.spec.ts (15 tests) 149ms + ✓ projects/social_platform/src/app/ui/widgets/header/header.component.spec.ts (1 test) 252ms + ✓ projects/social_platform/src/app/ui/pages/projects/detail/info/components/projects-left-side/projects-left-side.component.spec.ts (4 tests) 285ms + ✓ projects/social_platform/src/app/ui/widgets/vacancy-skills/vacancy-skills.component.spec.ts (2 tests) 272ms + ✓ projects/social_platform/src/app/ui/widgets/chat-window/chat-message/chat-message.component.spec.ts (1 test) 298ms + ✓ projects/social_platform/src/app/api/project/use-cases/delete-resource.use-case.spec.ts (3 tests) 52ms + ✓ projects/ui/src/lib/components/layout/invite-manage-card/invite-manage-card.component.spec.ts (1 test) 237ms + ✓ projects/social_platform/src/app/ui/pages/onboarding/onboarding.component.spec.ts (1 test) 213ms + ✓ projects/social_platform/src/app/api/project/facades/edit/project-additional.service.spec.ts (39 tests) 279ms + ✓ projects/social_platform/src/app/ui/pages/courses/lesson/complete/complete.component.spec.ts (5 tests) 260ms + ✓ projects/social_platform/src/app/api/member/facades/members-info.service.spec.ts (16 tests) 189ms + ✓ projects/ui/src/lib/components/layout/profile-info/profile-info.component.spec.ts (1 test) 221ms + ✓ projects/social_platform/src/app/ui/primitives/checkbox/checkbox.component.spec.ts (5 tests) 283ms + ✓ projects/social_platform/src/app/api/vacancy/facades/vacancy-detail-info.service.spec.ts (17 tests) 170ms + ✓ projects/ui/src/lib/components/primitives/avatar/avatar.component.spec.ts (6 tests) 223ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/project-rating/components/range-criterion-input/range-criterion-input.component.spec.ts (5 tests) 199ms + ✓ projects/social_platform/src/app/api/project/facades/edit/project-form.service.spec.ts (13 tests) 221ms + ✓ projects/social_platform/src/app/ui/pages/courses/lesson/shared/radio-select-task/radio-select-task.component.spec.ts (1 test) 230ms + ✓ projects/social_platform/src/app/api/program/facades/detail/program-analytics-attention.service.spec.ts (42 tests) 262ms + ✓ projects/social_platform/src/app/ui/widgets/cookie-consent/cookie-consent.component.spec.ts (5 tests) 240ms +stdout | projects/social_platform/src/app/ui/widgets/feed-filter/feed-filter.component.spec.ts > FeedComponent > показывает счётчики всех шести категорий независимо от фильтра +[22:49:08.788] [DEBUG] Query change from FeedFilterComponent + + ✓ projects/social_platform/src/app/ui/widgets/feed-filter/feed-filter.component.spec.ts (2 tests) 281ms + ✓ projects/social_platform/src/app/ui/pages/error/error.component.spec.ts (1 test) 142ms + ✓ projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-left-side/vacancies-left-side.component.spec.ts (1 test) 216ms + ✓ projects/social_platform/src/app/ui/primitives/avatar/avatar.component.spec.ts (6 tests) 244ms + ✓ projects/social_platform/src/app/ui/widgets/skills-basket/skills-basket.component.spec.ts (4 tests) 260ms + ✓ projects/social_platform/src/app/ui/pages/courses/list/course/course.component.spec.ts (1 test) 282ms + ✓ projects/social_platform/src/app/ui/pages/onboarding/stage-three/user-type-card/user-type-card.component.spec.ts (1 test) 148ms + ✓ projects/social_platform/src/app/infrastructure/repository/project/project-news.repository.spec.ts (8 tests) 90ms + ✓ projects/ui/src/lib/components/primitives/button/button-states.spec.ts (2 tests) 204ms + ✓ projects/social_platform/src/app/infrastructure/repository/project/project-subscription.repository.spec.ts (4 tests) 78ms + ✓ projects/social_platform/src/app/api/program/facades/detail/program-role-widget.service.spec.ts (11 tests) 139ms + ✓ projects/social_platform/src/app/ui/pages/projects/bar-new/bar.component.spec.ts (1 test) 218ms + ✓ projects/social_platform/src/app/ui/primitives/button/button.component.spec.ts (6 tests) 247ms + ✓ projects/social_platform/src/app/ui/widgets/news-card/carousel/carousel.component.spec.ts (2 tests) 207ms + ✓ projects/social_platform/src/app/api/project/facades/edit/project-form-autosave.service.spec.ts (24 tests) 218ms + ✓ projects/social_platform/src/app/api/project/facades/edit/project-team.service.spec.ts (19 tests) 156ms + ✓ projects/social_platform/src/app/ui/pages/program/main/program-card/program-card.component.spec.ts (1 test) 211ms + ✓ projects/social_platform/src/app/ui/primitives/bar/bar.component.spec.ts (1 test) 199ms + ✓ projects/ui/src/lib/components/primitives/icon/icon.component.spec.ts (5 tests) 194ms + ✓ projects/social_platform/src/app/ui/primitives/loader/loader.component.spec.ts (4 tests) 179ms + ✓ projects/social_platform/src/app/ui/primitives/file-upload-item/file-upload-item.component.spec.ts (1 test) 211ms + ✓ projects/social_platform/src/app/ui/primitives/search/search.component.spec.ts (2 tests) 227ms + ✓ projects/social_platform/src/app/infrastructure/repository/program/program.repository.spec.ts (30 tests) 188ms + ✓ projects/social_platform/src/app/ui/pages/error/not-found/error-not-found.component.spec.ts (1 test) 145ms + ✓ projects/social_platform/src/app/ui/pages/auth/email-verification/email-verification.component.spec.ts (1 test) 223ms + ✓ projects/social_platform/src/app/ui/pages/feed/new-project/new-project.component.spec.ts (1 test) 238ms + ✓ projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.spec.ts (13 tests) 196ms + ✓ projects/ui/src/lib/components/layout/sidebar/sidebar.component.spec.ts (1 test) 193ms + ✓ projects/social_platform/src/app/api/feed/facades/feed-info.service.spec.ts (3 tests) 67ms + ✓ projects/social_platform/src/app/ui/primitives/icon/icon.component.spec.ts (5 tests) 195ms + ✓ projects/social_platform/src/app/ui/primitives/tag/tag.component.spec.ts (1 test) 180ms + ✓ projects/social_platform/src/app/api/feed/use-cases/toggle-feed-like.use-case.spec.ts (4 tests) 63ms + ✓ projects/social_platform/src/app/api/project/use-cases/delete-goal.use-case.spec.ts (3 tests) 79ms + ✓ projects/ui/src/lib/components/primitives/back/back.component.spec.ts (1 test) 292ms + ✓ projects/social_platform/src/app/ui/primitives/img-card/img-card.component.spec.ts (1 test) 205ms + ✓ projects/social_platform/src/app/api/project/use-cases/delete-partner.use-case.spec.ts (3 tests) 62ms + ✓ projects/social_platform/src/app/api/program/use-cases/get-all-projects.use-case.spec.ts (3 tests) 83ms + ✓ projects/social_platform/src/app/ui/primitives/switch/switch.component.spec.ts (4 tests) 324ms + ✓ projects/social_platform/src/app/domain/shared/chat-state.service.spec.ts (1 test) 56ms + ✓ projects/social_platform/src/app/infrastructure/repository/project/project.repository.spec.ts (21 tests) 189ms + ✓ projects/social_platform/src/app/api/project/use-cases/delete-project-subscription.use-case.spec.ts (3 tests) 90ms + ✓ projects/social_platform/src/app/api/program/use-cases/get-all-members.use-case.spec.ts (3 tests) 65ms + ✓ projects/social_platform/src/app/api/project/use-cases/add-project-news.use-case.spec.ts (3 tests) 78ms + ✓ projects/social_platform/src/app/ui/pages/auth/confirm-password-reset/confirm-password-reset.component.spec.ts (1 test) 196ms + ✓ projects/social_platform/src/app/api/project/use-cases/get-all-projects.use-case.spec.ts (3 tests) 66ms + ✓ projects/social_platform/src/app/api/program/facades/detail/program-analytics-drilldown.service.spec.ts (10 tests) 153ms + ✓ projects/social_platform/src/app/ui/pages/courses/detail/info/course-module-card/circle-progress-bar/circle-progress-bar.component.spec.ts (1 test) 322ms + ✓ CircleProgressBarComponent > should create 319ms + ✓ projects/social_platform/src/app/api/profile/use-cases/get-profile-news-detail.use-case.spec.ts (3 tests) 87ms + ✓ projects/social_platform/src/app/infrastructure/adapters/vacancy/vacancy-http.adapter.spec.ts (5 tests) 79ms + ✓ projects/social_platform/src/app/infrastructure/adapters/project/project-cover-contract.spec.ts (3 tests) 79ms + ✓ projects/social_platform/src/app/api/vacancy/use-cases/send-vacancy-response.use-case.spec.ts (4 tests) 77ms + ✓ projects/social_platform/src/app/api/program/facades/detail/program-case-projects.service.spec.ts (11 tests) 150ms + ✓ projects/social_platform/src/app/ui/pages/auth/confirm-email/confirm-email.component.spec.ts (1 test) 162ms + ✓ projects/social_platform/src/app/ui/primitives/file-item/file-item.component.spec.ts (1 test) 284ms + ✓ projects/social_platform/src/app/api/program/use-cases/get-program-manager-attention.use-case.spec.ts (23 tests) 163ms + ✓ projects/social_platform/src/app/ui/pages/office/snackbar/snackbar.component.spec.ts (1 test) 296ms + ✓ projects/social_platform/src/app/api/program/use-cases/assign-project-program.spec.ts (3 tests) 55ms + ✓ projects/social_platform/src/app/infrastructure/repository/project/project-resource.repository.spec.ts (4 tests) 68ms + ✓ projects/social_platform/src/app/ui/widgets/detail/services/program/detail-program-info.service.spec.ts (15 tests) 154ms + ✓ projects/social_platform/src/app/infrastructure/adapters/auth/auth-http.adapter.spec.ts (24 tests) 222ms + ✓ projects/social_platform/src/app/ui/widgets/detail/services/profile/detail-profile-invite.spec.ts (9 tests) 210ms + ✓ projects/social_platform/src/app/api/program/use-cases/get-program.use-case.spec.ts (3 tests) 117ms + ✓ projects/social_platform/src/app/api/chat/use-cases/load-project-files.use-case.spec.ts (3 tests) 111ms + ✓ projects/social_platform/src/app/api/project/use-cases/program-link-fields.use-cases.spec.ts (15 tests) 178ms + ✓ projects/social_platform/src/app/api/project/facades/edit/ui/project-vacancy-ui.service.spec.ts (17 tests) 314ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/detail.resolver.spec.ts (10 tests) 124ms + ✓ projects/social_platform/src/app/api/profile/use-cases/add-profile-news.use-case.spec.ts (3 tests) 68ms + ✓ projects/social_platform/src/app/api/program/use-cases/read-news.use-case.spec.ts (3 tests) 68ms + ✓ projects/social_platform/src/app/api/auth/use-cases/register.use-case.spec.ts (5 tests) 82ms + ✓ projects/social_platform/src/app/infrastructure/repository/vacancy/vacancy.repository.spec.ts (16 tests) 207ms + ✓ projects/social_platform/src/app/api/project/use-cases/get-project-subscribers.use-case.spec.ts (3 tests) 57ms + ✓ projects/social_platform/src/app/api/program/program-widget-presentation.spec.ts (30 tests) 78ms + ✓ projects/social_platform/src/app/api/project/use-cases/toggle-project-news-like.use-case.spec.ts (3 tests) 86ms + ✓ projects/social_platform/src/app/infrastructure/adapters/project/project-collaborators-http.adapter.spec.ts (3 tests) 69ms + ✓ projects/social_platform/src/app/infrastructure/repository/auth/auth.repository.spec.ts (17 tests) 357ms + ✓ projects/social_platform/src/app/infrastructure/adapters/feed/feed-http.adapter.spec.ts (1 test) 48ms + ✓ projects/social_platform/src/app/ui/pages/error/error-code/error-code.component.spec.ts (1 test) 191ms + ✓ projects/social_platform/src/app/infrastructure/adapters/program/program-http.adapter.spec.ts (22 tests) 174ms + ✓ projects/social_platform/src/app/api/onboarding/facades/stages/onboarding-stage-zero-info.service.spec.ts (7 tests) 160ms + ✓ projects/social_platform/src/app/ui/pages/auth/auth.component.spec.ts (1 test) 179ms + ✓ projects/social_platform/src/app/api/project/use-cases/add-project-subscription.use-case.spec.ts (3 tests) 82ms + ✓ projects/social_platform/src/app/api/profile/use-cases/toggle-profile-news-like.use-case.spec.ts (3 tests) 68ms + ✓ projects/social_platform/src/app/api/member/facades/member-statistics.facade.spec.ts (5 tests) 99ms + ✓ projects/social_platform/src/app/api/project/use-cases/get-project-news-detail.use-case.spec.ts (3 tests) 80ms + ✓ projects/social_platform/src/app/ui/pages/chat/chat.resolver.spec.ts (1 test) 49ms + ✓ projects/social_platform/src/app/api/auth/use-cases/reset-password.use-case.spec.ts (3 tests) 70ms + ✓ projects/social_platform/src/app/api/invite/use-cases/get-my-invites.use-case.spec.ts (3 tests) 69ms + ✓ projects/social_platform/src/app/api/project/use-cases/update-form.use-case.spec.ts (3 tests) 70ms + ✓ projects/social_platform/src/app/api/profile/facades/edit/profile-edit-info.service.spec.ts (4 tests) 150ms + ✓ projects/social_platform/src/app/infrastructure/adapters/project/project-news-http.adapter.spec.ts (7 tests) 110ms + ✓ projects/social_platform/src/app/infrastructure/repository/project/project-collaborators.repository.spec.ts (3 tests) 72ms + ✓ projects/social_platform/src/app/api/project/use-cases/fetch-project-news.use-case.spec.ts (3 tests) 58ms + ✓ projects/social_platform/src/app/api/program/use-cases/get-programs.use-case.spec.ts (3 tests) 78ms + ✓ projects/social_platform/src/app/api/project/use-cases/create-project.use-case.spec.ts (3 tests) 97ms + ✓ projects/social_platform/src/app/api/program/use-cases/delete-news.use-case.spec.ts (3 tests) 72ms + ✓ projects/social_platform/src/app/api/project/use-cases/reset-project-cover.use-case.spec.ts (13 tests) 127ms + ✓ projects/core/src/lib/interceptors/bearer-token.interceptor.spec.ts (1 test) 72ms + ✓ projects/social_platform/src/app/api/vacancy/use-cases/accept-response.use-case.spec.ts (3 tests) 71ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/list/program-projects-filter/service/program-projects-filter-info.service.spec.ts (1 test) 71ms + ✓ projects/social_platform/src/app/api/feed/use-cases/read-feed-news.use-case.spec.ts (4 tests) 76ms + ✓ projects/social_platform/src/app/api/project/facades/edit/project-contacts.service.spec.ts (3 tests) 74ms + ✓ projects/social_platform/src/app/infrastructure/adapters/chat/chat-ws.adapter.spec.ts (14 tests) 121ms + ✓ projects/social_platform/src/app/api/project/use-cases/get-project.use-case.spec.ts (3 tests) 51ms + ✓ projects/social_platform/src/app/api/chat/use-cases/delete-message.use-case.spec.ts (1 test) 45ms + ✓ projects/social_platform/src/app/api/project/use-cases/submit-competitive-project.use-case.spec.ts (3 tests) 67ms + ✓ projects/social_platform/src/app/infrastructure/repository/project/project-program.repository.spec.ts (5 tests) 91ms + ✓ projects/social_platform/src/app/infrastructure/adapters/project/project-goals-http.adapter.spec.ts (4 tests) 69ms + ✓ projects/social_platform/src/app/api/member/use-cases/get-members.use-case.spec.ts (4 tests) 84ms + ✓ projects/social_platform/src/app/ui/pages/projects/list/all.resolver.spec.ts (1 test) 55ms + ✓ projects/social_platform/src/app/api/auth/use-cases/download-cv.use-case.spec.ts (3 tests) 60ms + ✓ projects/social_platform/src/app/infrastructure/adapters/project/project-http.adapter.spec.ts (8 tests) 107ms + ✓ projects/social_platform/src/app/api/profile/use-cases/edit-profile-news.use-case.spec.ts (3 tests) 67ms + ✓ projects/social_platform/src/app/api/courses/facades/ui/course-detail-ui-info.service.spec.ts (5 tests) 65ms + ✓ projects/social_platform/src/app/api/program/use-cases/get-project-ratings.use-case.spec.ts (3 tests) 55ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/services/rating-card.service.spec.ts (9 tests) 169ms + ✓ projects/social_platform/src/app/infrastructure/adapters/profile/profile-news-http.adapter.spec.ts (7 tests) 95ms + ✓ projects/social_platform/src/app/infrastructure/adapters/member/member-statistics-contract.spec.ts (6 tests) 160ms + ✓ projects/social_platform/src/app/api/project/use-cases/get-project-partners.use-case.spec.ts (3 tests) 84ms + ✓ projects/social_platform/src/app/api/vacancy/use-cases/get-vacancies.use-case.spec.ts (3 tests) 66ms + ✓ projects/social_platform/src/app/api/auth/use-cases/login.use-case.spec.ts (4 tests) 92ms + ✓ projects/social_platform/src/app/api/project/use-cases/create-goals.use-case.spec.ts (3 tests) 91ms + ✓ projects/core/src/lib/interceptors/camelcase.interceptor.spec.ts (6 tests) 166ms + ✓ projects/social_platform/src/app/api/program/use-cases/get-program-data-schema.use-case.spec.ts (3 tests) 101ms + ✓ projects/social_platform/src/app/api/project/facades/projects-info.service.spec.ts (3 tests) 69ms + ✓ projects/social_platform/src/app/api/vacancy/facades/vacancy-info.service.spec.ts (4 tests) 94ms + ✓ projects/social_platform/src/app/api/kanban/use-cases/get-task.use-case.spec.ts (4 tests) 82ms + ✓ projects/social_platform/src/app/api/project/use-cases/update-goal.use-case.spec.ts (3 tests) 110ms + ✓ projects/social_platform/src/app/api/program/program-widget-refresh.spec.ts (8 tests) 99ms + ✓ projects/social_platform/src/app/infrastructure/repository/project/project-goals.repository.spec.ts (4 tests) 102ms + ✓ projects/social_platform/src/app/api/profile/use-cases/fetch-profile-news.use-case.spec.ts (3 tests) 74ms + ✓ projects/social_platform/src/app/ui/pages/projects/projects.resolver.spec.ts (2 tests) 61ms + ✓ projects/social_platform/src/app/api/profile/use-cases/delete-profile-news.use-case.spec.ts (3 tests) 67ms + ✓ projects/social_platform/src/app/infrastructure/repository/chat/chat-realtime.repository.spec.ts (3 tests) 75ms + ✓ projects/social_platform/src/app/api/chat/use-cases/observe-messages.use-case.spec.ts (2 tests) 66ms + ✓ projects/core/src/lib/services/file/file.service.spec.ts (1 test) 52ms + ✓ projects/social_platform/src/app/infrastructure/adapters/project/project-count-contract.spec.ts (1 test) 77ms + ✓ projects/social_platform/src/app/infrastructure/repository/industry/industry.repository.spec.ts (3 tests) 79ms + ✓ projects/social_platform/src/app/api/kanban/use-cases/get-column-tasks.use-case.spec.ts (3 tests) 100ms + ✓ projects/social_platform/src/app/infrastructure/adapters/courses/courses-http.adapter.spec.ts (5 tests) 90ms + ✓ projects/social_platform/src/app/infrastructure/adapters/project/project-partner-http.adapter.spec.ts (4 tests) 88ms + ✓ projects/social_platform/src/app/api/auth/use-cases/resend-email.use-case.spec.ts (3 tests) 83ms + ✓ projects/social_platform/src/app/infrastructure/repository/profile/profile-news.repository.spec.ts (8 tests) 217ms + ✓ projects/social_platform/src/app/infrastructure/adapters/program/program-news-http.adapter.spec.ts (6 tests) 123ms + ✓ projects/social_platform/src/app/api/invite/use-cases/send-for-user.use-case.spec.ts (3 tests) 162ms + ✓ projects/social_platform/src/app/infrastructure/adapters/chat/chat-http.adapter.spec.ts (4 tests) 140ms + ✓ projects/social_platform/src/app/infrastructure/adapters/specializations/specializations-http.adapter.spec.ts (2 tests) 166ms + ✓ projects/social_platform/src/app/api/searches/searches.service.spec.ts (5 tests) 147ms + ✓ projects/social_platform/src/app/api/skills/use-cases/get-skills-nested.use-case.spec.ts (3 tests) 58ms + ✓ projects/social_platform/src/app/api/vacancy/use-cases/post-vacancy.use-case.spec.ts (3 tests) 87ms + ✓ projects/social_platform/src/app/api/vacancy/use-cases/get-my-vacancies.use-case.spec.ts (3 tests) 91ms + ✓ projects/social_platform/src/app/api/profile/use-cases/read-profile-news.use-case.spec.ts (3 tests) 86ms + ✓ projects/social_platform/src/app/api/courses/use-cases/get-course-structure.use-case.spec.ts (3 tests) 108ms + ✓ projects/social_platform/src/app/infrastructure/repository/project/project-rating.repository.spec.ts (6 tests) 183ms + ✓ projects/social_platform/src/app/api/vacancy/use-cases/delete-vacancy.use-case.spec.ts (3 tests) 113ms + ✓ projects/social_platform/src/app/api/program/use-cases/rate-project.use-case.spec.ts (3 tests) 229ms + ✓ projects/social_platform/src/app/api/program/use-cases/register-program.use-case.spec.ts (3 tests) 215ms + ✓ projects/social_platform/src/app/api/program/use-cases/apply-project-to-program.use-case.spec.ts (3 tests) 179ms + ✓ projects/social_platform/src/app/infrastructure/adapters/project/project-program-http.adapter.spec.ts (3 tests) 283ms + ✓ projects/social_platform/src/app/api/project/use-cases/get-project-resources.use-case.spec.ts (3 tests) 119ms + ✓ projects/social_platform/src/app/api/program/use-cases/get-program-role-widget.use-case.spec.ts (7 tests) 164ms + ✓ projects/social_platform/src/app/api/chat/use-cases/load-messages.use-case.spec.ts (3 tests) 128ms + ✓ projects/social_platform/src/app/ui/pages/projects/list/my.resolver.spec.ts (1 test) 57ms + ✓ projects/social_platform/src/app/api/program/facades/detail/program-detail-main-info.service.spec.ts (3 tests) 235ms + ✓ projects/social_platform/src/app/infrastructure/repository/member/member.repository.spec.ts (1 test) 95ms + ✓ projects/social_platform/src/app/api/program/use-cases/get-program-manager-overview.use-case.spec.ts (2 tests) 119ms + ✓ projects/social_platform/src/app/api/project/use-cases/transfer-project-ownership.use-case.spec.ts (3 tests) 102ms + ✓ projects/core/src/lib/guards/auth/auth-required.guard.spec.ts (1 test) 157ms + ✓ projects/social_platform/src/app/api/invite/facades/invite-participant-search.facade.spec.ts (4 tests) 219ms + ✓ projects/social_platform/src/app/ui/pages/projects/detail/chat/chat.resolver.spec.ts (1 test) 119ms + ✓ projects/social_platform/src/app/api/courses/use-cases/get-course-detail.use-case.spec.ts (3 tests) 330ms + ✓ projects/social_platform/src/app/api/chat/use-cases/check-unreads.use-case.spec.ts (3 tests) 134ms + ✓ projects/social_platform/src/app/api/chat/use-cases/connect-chat.use-case.spec.ts (1 test) 62ms + ✓ projects/social_platform/src/app/api/invite/use-cases/accept-invite.use-case.spec.ts (3 tests) 78ms + ✓ projects/social_platform/src/app/api/invite/use-cases/get-project-invites.use-case.spec.ts (3 tests) 148ms + ✓ projects/social_platform/src/app/infrastructure/adapters/invite/invite-http.adapter.spec.ts (7 tests) 180ms + ✓ projects/social_platform/src/app/api/vacancy/use-cases/get-project-responses.use-case.spec.ts (3 tests) 160ms + ✓ projects/social_platform/src/app/api/chat/use-cases/observe-set-online.use-case.spec.ts (2 tests) 111ms + ✓ projects/social_platform/src/app/ui/pages/projects/detail/news-detail/news-detail.resolver.spec.ts (1 test) 105ms + ✓ projects/social_platform/src/app/api/program/use-cases/toggle-like.use-case.spec.ts (3 tests) 128ms + ✓ projects/social_platform/src/app/api/project/use-cases/get-my-projects.use-case.spec.ts (3 tests) 278ms + ✓ projects/social_platform/src/app/api/project/use-cases/create-partner.use-case.spec.ts (3 tests) 148ms + ✓ projects/social_platform/src/app/infrastructure/repository/program/program-news.repository.spec.ts (6 tests) 247ms + ✓ projects/social_platform/src/app/api/project/use-cases/get-project-goals.use-case.spec.ts (3 tests) 98ms + ✓ projects/social_platform/src/app/infrastructure/repository/chat/chat.repository.spec.ts (3 tests) 171ms + ✓ projects/social_platform/src/app/infrastructure/adapters/program/program-case-http.integration.spec.ts (2 tests) 170ms + ✓ projects/social_platform/src/app/api/project/facades/edit/ui/project-team-ui.service.spec.ts (2 tests) 123ms + ✓ projects/social_platform/src/app/infrastructure/adapters/industry/industry-http.adapter.spec.ts (1 test) 100ms + ✓ projects/social_platform/src/app/api/program/use-cases/edit-news.use-case.spec.ts (3 tests) 168ms + ✓ projects/social_platform/src/app/infrastructure/repository/project/project-partner.repository.spec.ts (4 tests) 185ms + ✓ projects/social_platform/src/app/infrastructure/repository/courses/courses.repository.spec.ts (5 tests) 237ms + ✓ projects/social_platform/src/app/api/vacancy/use-cases/update-vacancy.use-case.spec.ts (3 tests) 335ms + ✓ projects/social_platform/src/app/api/program/use-cases/get-program-manager-assignments.use-case.spec.ts (6 tests) 247ms + ✓ projects/core/src/lib/services/validation/validation.service.spec.ts (1 test) 160ms + ✓ projects/core/src/lib/services/api/api.service.spec.ts (1 test) 76ms + ✓ projects/social_platform/src/app/ui/pages/program/detail/register/register.resolver.spec.ts (1 test) 65ms + ✓ projects/core/src/lib/services/tokens/token.service.spec.ts (1 test) 139ms + ✓ projects/social_platform/src/app/infrastructure/adapters/project/project-resource-http.adapter.spec.ts (4 tests) 163ms + ✓ projects/social_platform/src/app/api/kanban/use-cases/get-board.use-case.spec.ts (4 tests) 271ms + ✓ projects/social_platform/src/app/api/project/use-cases/delete-project-news.use-case.spec.ts (3 tests) 94ms + ✓ projects/social_platform/src/app/api/vacancy/use-cases/reject-response.use-case.spec.ts (3 tests) 77ms + ✓ projects/social_platform/src/app/api/program/use-cases/add-news.use-case.spec.ts (3 tests) 85ms + ✓ projects/social_platform/src/app/api/vacancy/use-cases/get-vacancy-detail.use-case.spec.ts (3 tests) 90ms + ✓ projects/social_platform/src/app/api/skills/use-cases/search-skills.use-case.spec.ts (3 tests) 94ms + ✓ projects/social_platform/src/app/api/chat/use-cases/start-typing.use-case.spec.ts (1 test) 124ms + ✓ projects/core/src/lib/services/websockets/websocket.service.spec.ts (1 test) 140ms + ✓ projects/core/src/lib/services/error/error.service.spec.ts (1 test) 135ms + ✓ projects/social_platform/src/app/api/program/use-cases/participating-program.use-case.spec.ts (3 tests) 104ms + ✓ projects/social_platform/src/app/api/chat/use-cases/observe-edit-message.use-case.spec.ts (2 tests) 70ms + ✓ projects/social_platform/src/app/api/project/use-cases/delete-project.use-case.spec.ts (3 tests) 148ms + ✓ projects/social_platform/src/app/infrastructure/adapters/member/member-http.adapter.spec.ts (2 tests) 85ms + ✓ projects/social_platform/src/app/api/project/use-cases/update-resource.use-case.spec.ts (3 tests) 105ms + ✓ projects/social_platform/src/app/ui/pages/chat/chat-groups.resolver.spec.ts (1 test) 46ms + ✓ projects/social_platform/src/app/api/courses/use-cases/get-course-lesson.use-case.spec.ts (3 tests) 112ms + ✓ projects/social_platform/src/app/api/project/use-cases/create-resource.use-case.spec.ts (3 tests) 164ms + ✓ projects/social_platform/src/app/infrastructure/adapters/subscription/subscription-http.adapter.spec.ts (4 tests) 140ms + ✓ projects/core/src/lib/services/error/global-error-handler.service.spec.ts (1 test) 151ms + ✓ projects/social_platform/src/app/api/invite/use-cases/reject-invite.use-case.spec.ts (3 tests) 103ms + ✓ projects/social_platform/src/app/api/chat/use-cases/read-message.use-case.spec.ts (1 test) 120ms + ✓ projects/social_platform/src/app/api/profile/use-cases/save-profile.use-case.spec.ts (3 tests) 162ms + ✓ projects/social_platform/src/app/api/project/use-cases/remove-project-collaborator.use-case.spec.ts (3 tests) 158ms + ✓ projects/social_platform/src/app/api/program/use-cases/get-program-filters.use-case.spec.ts (3 tests) 170ms + ✓ projects/social_platform/src/app/infrastructure/adapters/project/project-rating-http.adapter.spec.ts (4 tests) 168ms + ✓ projects/social_platform/src/app/api/onboarding/facades/stages/ui/onboarding-stage-one-ui-info.service.spec.ts (1 test) 149ms + ✓ projects/social_platform/src/app/infrastructure/repository/feed/feed.repository.spec.ts (1 test) 83ms + ✓ projects/social_platform/src/app/domain/shared/entity-cache.spec.ts (11 tests) 89ms + ✓ projects/social_platform/src/app/api/chat/use-cases/observe-set-offline.use-case.spec.ts (2 tests) 165ms + ✓ projects/social_platform/src/app/api/chat/use-cases/observe-typing.use-case.spec.ts (2 tests) 88ms + ✓ projects/social_platform/src/app/api/project/use-cases/get-project-subscriptions.use-case.spec.ts (3 tests) 200ms + ✓ projects/social_platform/src/app/api/invite/use-cases/revoke-invite.use-case.spec.ts (3 tests) 195ms + ✓ projects/social_platform/src/app/api/project/use-cases/edit-project-news.use-case.spec.ts (3 tests) 175ms + ✓ projects/social_platform/src/app/api/auth/use-cases/set-password.use-case.spec.ts (3 tests) 177ms + ✓ projects/social_platform/src/app/api/chat/use-cases/observe-delete-message.use-case.spec.ts (2 tests) 92ms + ✓ projects/social_platform/src/app/api/onboarding/onboarding.service.spec.ts (1 test) 106ms + ✓ projects/social_platform/src/app/api/auth/auth.service.spec.ts (1 test) 131ms + ✓ projects/social_platform/src/app/infrastructure/repository/specializations/specializations.repository.spec.ts (2 tests) 100ms + ✓ projects/social_platform/src/app/api/project/use-cases/read-project-news.use-case.spec.ts (3 tests) 121ms + ✓ projects/social_platform/src/app/api/project/use-cases/leave-project.use-case.spec.ts (3 tests) 100ms + ✓ projects/social_platform/src/app/api/program/use-cases/create-program-filters.use-case.spec.ts (3 tests) 80ms + ✓ projects/social_platform/src/app/api/project/facades/edit/project-form.factory.spec.ts (4 tests) 55ms + ✓ projects/social_platform/src/app/api/chat/use-cases/observe-read-message.use-case.spec.ts (2 tests) 75ms + ✓ projects/social_platform/src/app/api/auth/use-cases/update-profile.use-case.spec.ts (3 tests) 138ms + ✓ projects/social_platform/src/app/infrastructure/repository/skills/skills.repository.spec.ts (2 tests) 137ms + ✓ projects/social_platform/src/app/api/invite/use-cases/update-invite.use-case.spec.ts (3 tests) 142ms + ✓ projects/social_platform/src/app/api/program/use-cases/fetch-news.use-case.spec.ts (3 tests) 139ms + ✓ projects/social_platform/src/app/api/vacancy/use-cases/get-vacancy-responses.use-case.spec.ts (2 tests) 97ms + ✓ projects/social_platform/src/app/api/courses/use-cases/get-courses.use-case.spec.ts (3 tests) 164ms + ✓ projects/social_platform/src/app/api/chat/use-cases/send-message.use-case.spec.ts (1 test) 111ms + ✓ projects/social_platform/src/app/ui/pages/chat/chat-direct/chat-direct.resolver.spec.ts (1 test) 87ms + ✓ projects/social_platform/src/app/api/feed/facades/ui/feed-ui-info.service.spec.ts (1 test) 33ms + ✓ projects/social_platform/src/app/infrastructure/adapters/skills/skills-http.adapter.spec.ts (2 tests) 127ms + ✓ projects/social_platform/src/app/api/feed/use-cases/fetch-feed.use-case.spec.ts (3 tests) 125ms + ✓ projects/social_platform/src/app/ui/pages/projects/detail/info/info.resolver.spec.ts (1 test) 75ms + ✓ projects/social_platform/src/app/api/program/use-cases/filter-project-ratings.use-case.spec.ts (3 tests) 340ms + ✓ projects/social_platform/src/app/ui/primitives/modal/modal.service.spec.ts (1 test) 79ms + ✓ projects/social_platform/src/app/ui/widgets/detail/services/detail-info.service.spec.ts (1 test) 115ms + ✓ projects/social_platform/src/app/ui/pages/office/snackbar/animation/animation.service.spec.ts (1 test) 101ms + ✓ projects/social_platform/src/app/ui/pages/projects/edit/edit.resolver.spec.ts (1 test) 121ms + ✓ projects/social_platform/src/app/api/program/facades/detail/ui/program-detail-main-ui-info.service.spec.ts (13 tests) 79ms + ✓ projects/social_platform/src/app/ui/services/notification/notification.service.spec.ts (1 test) 89ms + ✓ projects/social_platform/src/app/utils/export-regions.spec.ts (3 tests) 28ms + ✓ projects/social_platform/src/app/api/profile/facades/edit/profile-save-error.utils.spec.ts (5 tests) 34ms + ✓ projects/core/src/consts/lists/russian-regions-list.const.spec.ts (7 tests) 100ms + ✓ projects/core/src/lib/pipes/formatters/parse-breaks.pipe.spec.ts (1 test) 11ms + ✓ projects/social_platform/src/app/api/profile/facades/edit/profile-edit-validation.utils.spec.ts (9 tests) 125ms + ✓ projects/social_platform/src/app/utils/program-case-analytics.spec.ts (14 tests) 50ms + ✓ projects/social_platform/src/app/api/vacancy/vacancy-response-error.spec.ts (8 tests) 16ms + ✓ projects/social_platform/src/app/api/project/facades/detail/ui/projects-detail-ui.service.spec.ts (1 test) 11ms + ✓ projects/core/src/lib/pipes/controls/form-control.pipe.spec.ts (1 test) 7ms + ✓ projects/social_platform/src/app/infrastructure/adapters/courses/local-storage-seen-modules.adapter.spec.ts (4 tests) 10ms + ✓ projects/social_platform/src/app/api/invite/mappers/map-invite-send-error.spec.ts (24 tests) 30ms + ✓ projects/core/src/lib/pipes/user/user-role.pipe.spec.ts (1 test) 21ms + ✓ projects/social_platform/src/app/utils/program-analytics-assignment.spec.ts (9 tests) 29ms + ✓ projects/social_platform/src/app/ui/pages/projects/projects-activity-placement.spec.ts (4 tests) 50ms + ✓ projects/social_platform/src/app/domain/invite/invite-candidates.spec.ts (2 tests) 27ms + ✓ projects/social_platform/src/app/api/member/member-filters.spec.ts (10 tests) 17ms + ✓ projects/core/src/lib/pipes/user/user-links.pipe.spec.ts (1 test) 10ms + ✓ projects/social_platform/src/app/api/profile/facades/detail/ui/profile-detail-ui-info.service.spec.ts (4 tests) 21ms + ✓ projects/core/src/lib/pipes/formatters/parse-links.pipe.spec.ts (1 test) 12ms + ✓ projects/core/src/lib/pipes/transformers/salary-trasform.pipe.spec.ts (1 test) 12ms + ✓ projects/core/src/lib/pipes/formatters/years-from-birthday.pipe.spec.ts (1 test) 9ms + ✓ projects/core/src/lib/pipes/formatters/pluralize.pipe.spec.ts (1 test) 7ms + ✓ projects/core/src/lib/pipes/formatters/dayjs.pipe.spec.ts (1 test) 4ms + ✓ projects/core/src/lib/pipes/transformers/link-transform.pipe.spec.ts (1 test) 4ms + ✓ projects/social_platform/src/app/ui/pipes/file-type.pipe.spec.ts (1 test) 4ms + ✓ projects/core/src/lib/pipes/controls/control-error.pipe.spec.ts (1 test) 5ms + ✓ projects/social_platform/src/app/ui/routes/program/detail.routes.spec.ts (2 tests) 6ms + + Test Files 406 passed (406) + Tests 2006 passed (2006) + Start at 22:48:06 + Duration 116.49s (transform 45.72s, setup 634.27s, collect 326.70s, tests 151.59s, environment 41.13s, prepare 131.22s) + diff --git a/docs/mobile-polish/ui-tests.log b/docs/mobile-polish/ui-tests.log new file mode 100644 index 000000000..13434a99b --- /dev/null +++ b/docs/mobile-polish/ui-tests.log @@ -0,0 +1,15 @@ + + RUN v3.2.6 Z:/Документы/PROCOLLAB-dev/procollab-dev-platform-responsive + + ✓ projects/ui/src/lib/components/layout/profile-info/profile-info.component.spec.ts (1 test) 104ms + ✓ projects/social_platform/src/app/ui/pages/feed/open-vacancy/open-vacancy.component.spec.ts (1 test) 213ms +stdout | projects/social_platform/src/app/ui/widgets/feed-filter/feed-filter.component.spec.ts > FeedComponent > показывает счётчики всех шести категорий независимо от фильтра +[23:05:50.477] [DEBUG] Query change from FeedFilterComponent + + ✓ projects/social_platform/src/app/ui/widgets/feed-filter/feed-filter.component.spec.ts (2 tests) 159ms + + Test Files 3 passed (3) + Tests 4 passed (4) + Start at 23:05:32 + Duration 8.12s (transform 5.94s, setup 8.08s, collect 5.88s, tests 476ms, environment 3.24s, prepare 3.87s) + diff --git a/docs/responsive/browser-harness.cjs b/docs/responsive/browser-harness.cjs index 63f3306b2..fb634a509 100644 --- a/docs/responsive/browser-harness.cjs +++ b/docs/responsive/browser-harness.cjs @@ -3,9 +3,10 @@ const { chromium } = require(process.env.PLAYWRIGHT_MODULE || "playwright"); const assert = require("node:assert/strict"); const fixtures = require("./fixtures.cjs"); -const base = "http://127.0.0.1:4360"; +const defaultBase = "http://127.0.0.1:4360"; async function launch(width = 390, options = {}) { + const { baseUrl: base = defaultBase, ...contextOptions } = options; const browser = await chromium.launch({ headless: true, executablePath: process.env.CHROME_PATH, @@ -13,7 +14,7 @@ async function launch(width = 390, options = {}) { const context = await browser.newContext({ viewport: { width, height: 844 }, reducedMotion: "reduce", - ...options, + ...contextOptions, }); await context.addCookies( ["accessToken", "refreshToken", "devAccessToken", "devRefreshToken"].map(name => ({ @@ -117,4 +118,4 @@ async function assertViewport(page) { return result; } -module.exports = { launch, measure, assertViewport, base }; +module.exports = { launch, measure, assertViewport, base: defaultBase }; diff --git a/docs/ui-kit/UI-KIT.md b/docs/ui-kit/UI-KIT.md index 87a90eff5..b4e53e089 100644 --- a/docs/ui-kit/UI-KIT.md +++ b/docs/ui-kit/UI-KIT.md @@ -2,7 +2,17 @@ # UI Kit PROCOLLAB -Единые компоненты находятся в `projects/ui/src/lib/components` и экспортируются через `@uilib`. FormControl-компоненты приложения остаются в `@ui/primitives`: их CVA, валидация и доменные интеграции не меняются. Старые импорты Button, Avatar, Icon, Loader и канбан Badge — реэкспорты тех же классов, без второй Angular-реализации. +Единые компоненты находятся в `projects/ui/src/lib/components` и экспортируются через `@uilib`. FormControl-компоненты приложения остаются в `@ui/primitives`: их CVA, валидация и доменные интеграции не меняются. Старые импорты Button, Icon, Loader и канбан Badge — реэкспорты тех же классов. Social Avatar наследует inputs canonical Avatar и сохраняет прежнюю desktop presentation через compatibility adapter. + +## Desktop compatibility + +Responsive/UI Kit presentation ограничена `<1000px`. На desktop ≥1000px legacy consumers сохраняют +композицию и геометрию `dev` до #401: общие Card/Field/Form/Filters adapters не навязывают размеры, +отступы и сетки. Button, Icon, Avatar и PageHeader сохраняют прежние desktop contracts; +требование 44 px для мобильных targets не увеличивает старые desktop кнопки. + +Перед изменениями shared styles обязательны desktop pixel comparisons на 1440/1920 и +mobile/tablet проверки на 320/390/768: [gate, эталон и evidence](../desktop-regression/README.md). | Семейство | Источник | Правило | | --------------------------------------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | diff --git a/projects/social_platform/src/app/ui/pages/auth/auth.component.scss b/projects/social_platform/src/app/ui/pages/auth/auth.component.scss index b3287874c..3ddc634f4 100644 --- a/projects/social_platform/src/app/ui/pages/auth/auth.component.scss +++ b/projects/social_platform/src/app/ui/pages/auth/auth.component.scss @@ -11,10 +11,6 @@ @include responsive.apply-desktop { padding: 0 200px; - - &:has(.login) { - padding: 0; - } } &__header { @@ -30,16 +26,18 @@ } } -@include responsive.apply-below-desktop { - .page { - height: auto; - min-height: 100dvh; - padding: 0 var(--page-gutter); - } +@media screen and (max-width: 999px) { + @include responsive.apply-below-desktop { + .page { + height: auto; + min-height: 100dvh; + padding: 0 var(--page-gutter); + } - .page__body { - justify-content: flex-start; - height: auto; - min-height: 100dvh; + .page__body { + justify-content: flex-start; + height: auto; + min-height: 100dvh; + } } } diff --git a/projects/social_platform/src/app/ui/pages/auth/email-verification/email-verification.component.scss b/projects/social_platform/src/app/ui/pages/auth/email-verification/email-verification.component.scss index 1eb44e29a..345052222 100644 --- a/projects/social_platform/src/app/ui/pages/auth/email-verification/email-verification.component.scss +++ b/projects/social_platform/src/app/ui/pages/auth/email-verification/email-verification.component.scss @@ -37,11 +37,7 @@ @include responsive.apply-desktop { bottom: 0%; left: 30%; - width: min(852px, 70vw); - min-width: 0; - max-width: 70vw; - max-height: 92dvh; - object-fit: contain; + min-width: 852px; } } @@ -56,17 +52,19 @@ } } -@include responsive.apply-below-desktop { - .verification__img { - position: static; - width: 100%; - min-width: 0; - max-height: 40dvh; - object-fit: contain; - } +@media screen and (max-width: 999px) { + @include responsive.apply-below-desktop { + .verification__img { + position: static; + width: 100%; + min-width: 0; + max-height: 40dvh; + object-fit: contain; + } - .verification__action { - flex-wrap: wrap; - gap: 12px; + .verification__action { + flex-wrap: wrap; + gap: 12px; + } } } diff --git a/projects/social_platform/src/app/ui/pages/auth/login/login.component.scss b/projects/social_platform/src/app/ui/pages/auth/login/login.component.scss index c4da6f77a..775482494 100644 --- a/projects/social_platform/src/app/ui/pages/auth/login/login.component.scss +++ b/projects/social_platform/src/app/ui/pages/auth/login/login.component.scss @@ -5,20 +5,28 @@ .login { display: flex; - width: 100%; - min-width: 0; - min-height: 100vh; + + @media screen and (max-width: 999px) { + width: 100%; + min-width: 0; + min-height: 100vh; + } + + @media screen and (min-width: 1000px) { + min-width: 95vw; + min-height: 100vh; + } &__left { display: flex; flex: 1; flex-direction: column; - min-width: 0; - padding-left: 10px; - @include responsive.apply-desktop { - padding-left: clamp(32px, 14vw, 200px); + @media screen and (max-width: 999px) { + min-width: 0; } + + padding-left: 10px; } &__left-content { @@ -124,37 +132,39 @@ cursor: pointer; } -@include responsive.apply-below-desktop { - .login { - width: 100%; - min-width: 0; - min-height: 100dvh; - } +@media screen and (max-width: 999px) { + @include responsive.apply-below-desktop { + .login { + width: 100%; + min-width: 0; + min-height: 100dvh; + } - .login__left { - min-width: 0; - padding-left: 0; - } + .login__left { + min-width: 0; + padding-left: 0; + } - .login__left-content { - padding: 24px 0; - } + .login__left-content { + padding: 24px 0; + } - .login .auth__wrapper { - width: 100%; - max-width: none; - } + .login .auth__wrapper { + width: 100%; + max-width: none; + } - .login__password { - flex-wrap: wrap; - gap: 12px; - } + .login__password { + flex-wrap: wrap; + gap: 12px; + } - .tooltip__wrapper { - position: fixed; - right: var(--page-gutter); - bottom: max(16px, env(safe-area-inset-bottom)); - left: var(--page-gutter); - width: auto; + .tooltip__wrapper { + position: fixed; + right: var(--page-gutter); + bottom: max(16px, env(safe-area-inset-bottom)); + left: var(--page-gutter); + width: auto; + } } } diff --git a/projects/social_platform/src/app/ui/pages/courses/lesson/shared/exclude-task/exclude-task.component.scss b/projects/social_platform/src/app/ui/pages/courses/lesson/shared/exclude-task/exclude-task.component.scss index a9905591a..9e97fb9c1 100644 --- a/projects/social_platform/src/app/ui/pages/courses/lesson/shared/exclude-task/exclude-task.component.scss +++ b/projects/social_platform/src/app/ui/pages/courses/lesson/shared/exclude-task/exclude-task.component.scss @@ -14,14 +14,6 @@ gap: 20px; } - /* &--hasContent { */ - - /* display: flex; */ - - /* flex-direction: row-reverse; */ - - /* } */ - &__answer { color: var(--grey-for-text); } @@ -176,4 +168,6 @@ } } -@include course-task.responsive-layout("exclude"); +@media screen and (max-width: 999px) { + @include course-task.responsive-layout("exclude"); +} diff --git a/projects/social_platform/src/app/ui/pages/courses/lesson/shared/file-task/file-task.component.scss b/projects/social_platform/src/app/ui/pages/courses/lesson/shared/file-task/file-task.component.scss index d5c0e6515..9f2785e3c 100644 --- a/projects/social_platform/src/app/ui/pages/courses/lesson/shared/file-task/file-task.component.scss +++ b/projects/social_platform/src/app/ui/pages/courses/lesson/shared/file-task/file-task.component.scss @@ -1,3 +1,5 @@ +/** @format */ + @use "styles/course-task"; @use "styles/responsive"; @use "styles/typography"; @@ -203,4 +205,6 @@ } } -@include course-task.responsive-layout("file-task"); +@media screen and (max-width: 999px) { + @include course-task.responsive-layout("file-task"); +} diff --git a/projects/social_platform/src/app/ui/pages/courses/lesson/shared/radio-select-task/radio-select-task.component.scss b/projects/social_platform/src/app/ui/pages/courses/lesson/shared/radio-select-task/radio-select-task.component.scss index 3444e8a2b..02d7fc8b7 100644 --- a/projects/social_platform/src/app/ui/pages/courses/lesson/shared/radio-select-task/radio-select-task.component.scss +++ b/projects/social_platform/src/app/ui/pages/courses/lesson/shared/radio-select-task/radio-select-task.component.scss @@ -12,12 +12,6 @@ @include responsive.apply-desktop { flex-direction: row; gap: 20px; - - /* &--hasContent { */ - - /* flex-direction: row-reverse; */ - - /* } */ } &__answer { @@ -195,21 +189,25 @@ } } -@include responsive.apply-mobile { - .radio__item { - min-width: 0; - min-height: 44px; - padding: 4px 0; - } +@media screen and (max-width: 999px) { + @include responsive.apply-mobile { + .radio__item { + min-width: 0; + min-height: 44px; + padding: 4px 0; + } - .radio__item input { - flex-shrink: 0; - } + .radio__item input { + flex-shrink: 0; + } - .radio__item label { - min-width: 0; - overflow-wrap: anywhere; + .radio__item label { + min-width: 0; + overflow-wrap: anywhere; + } } } -@include course-task.responsive-layout("radio"); +@media screen and (max-width: 999px) { + @include course-task.responsive-layout("radio"); +} diff --git a/projects/social_platform/src/app/ui/pages/courses/lesson/shared/video-task/info-task.component.scss b/projects/social_platform/src/app/ui/pages/courses/lesson/shared/video-task/info-task.component.scss index bb4028444..5cec502c3 100644 --- a/projects/social_platform/src/app/ui/pages/courses/lesson/shared/video-task/info-task.component.scss +++ b/projects/social_platform/src/app/ui/pages/courses/lesson/shared/video-task/info-task.component.scss @@ -1,3 +1,5 @@ +/** @format */ + @use "styles/course-task"; @use "styles/responsive"; @@ -114,4 +116,6 @@ } } -@include course-task.responsive-layout("video"); +@media screen and (max-width: 999px) { + @include course-task.responsive-layout("video"); +} diff --git a/projects/social_platform/src/app/ui/pages/courses/lesson/shared/write-task/write-task.component.scss b/projects/social_platform/src/app/ui/pages/courses/lesson/shared/write-task/write-task.component.scss index 1cfc2352d..8c33ebfa7 100644 --- a/projects/social_platform/src/app/ui/pages/courses/lesson/shared/write-task/write-task.component.scss +++ b/projects/social_platform/src/app/ui/pages/courses/lesson/shared/write-task/write-task.component.scss @@ -1,3 +1,5 @@ +/** @format */ + @use "styles/course-task"; @use "styles/responsive"; @@ -178,4 +180,6 @@ } } -@include course-task.responsive-layout("write-task"); +@media screen and (max-width: 999px) { + @include course-task.responsive-layout("write-task"); +} diff --git a/projects/social_platform/src/app/ui/pages/courses/list/course/course.component.html b/projects/social_platform/src/app/ui/pages/courses/list/course/course.component.html index b3b048a50..68e8192f4 100644 --- a/projects/social_platform/src/app/ui/pages/courses/list/course/course.component.html +++ b/projects/social_platform/src/app/ui/pages/courses/list/course/course.component.html @@ -4,17 +4,33 @@
- + @if (desktopLayout()) { + + {{ + isMember() + ? "для участников программы" + : isSubs() + ? "доступно по подписке" + : "доступно всем пользователям" + }} + + } @else { + + } course-cover
diff --git a/projects/social_platform/src/app/ui/pages/courses/list/course/course.component.scss b/projects/social_platform/src/app/ui/pages/courses/list/course/course.component.scss index 809b09d6f..ca983f44d 100644 --- a/projects/social_platform/src/app/ui/pages/courses/list/course/course.component.scss +++ b/projects/social_platform/src/app/ui/pages/courses/list/course/course.component.scss @@ -5,7 +5,11 @@ @use "styles/typography"; .course { - @include ui-foundation.card; + @media screen and (max-width: 999px) { + @include ui-foundation.card; + + max-width: 333px; + } position: relative; width: 100%; @@ -13,8 +17,49 @@ overflow: hidden; cursor: pointer; + @media screen and (min-width: 1000px) { + background-color: var(--light-white); + } + + @media screen and (min-width: 1000px) { + border: 0.5px solid var(--medium-grey-for-outline); + } + + @media screen and (min-width: 1000px) { + border-radius: var(--rounded-lg); + } + &__cover { border-radius: var(--rounded-lg); + + @media screen and (min-width: 1000px) { + app-button { + ::ng-deep { + .button { + position: absolute; + top: 15px; + right: 24px; + width: 166px; + padding: 0; + } + } + } + } + + @media screen and (min-width: 1000px) { + app-avatar { + ::ng-deep { + .avatar { + img { + position: absolute; + top: 35px; + left: 24px; + box-shadow: 0 0 8px rgba($color: #333, $alpha: 30%); + } + } + } + } + } } &__image { @@ -66,18 +111,22 @@ } } -.course__cover app-avatar { - position: absolute; - top: 35px; - left: 24px; - z-index: 1; - border-radius: 50%; - box-shadow: var(--ui-card-hover-shadow); +@media screen and (max-width: 999px) { + .course__cover app-avatar { + position: absolute; + top: 35px; + left: 24px; + z-index: 1; + border-radius: 50%; + box-shadow: var(--ui-card-hover-shadow); + } } -.course__access { - position: absolute; - top: 15px; - right: 24px; - max-width: 166px; +@media screen and (max-width: 999px) { + .course__access { + position: absolute; + top: 15px; + right: 24px; + max-width: 166px; + } } diff --git a/projects/social_platform/src/app/ui/pages/courses/list/course/course.component.ts b/projects/social_platform/src/app/ui/pages/courses/list/course/course.component.ts index a3d255ed5..642af949d 100644 --- a/projects/social_platform/src/app/ui/pages/courses/list/course/course.component.ts +++ b/projects/social_platform/src/app/ui/pages/courses/list/course/course.component.ts @@ -1,10 +1,18 @@ /** @format */ -import { CardDirective, BadgeComponent } from "@uilib"; +import { DesktopLayoutService, CardDirective, BadgeComponent } from "@uilib"; /** @format */ import { CommonModule } from "@angular/common"; -import { ChangeDetectionStrategy, Component, input, Input, OnInit, signal } from "@angular/core"; +import { + ChangeDetectionStrategy, + Component, + inject, + input, + Input, + OnInit, + signal, +} from "@angular/core"; import { RouterModule } from "@angular/router"; import { IconComponent, ButtonComponent } from "@ui/primitives"; import { AvatarComponent } from "@ui/primitives/avatar/avatar.component"; @@ -36,6 +44,7 @@ import { TruncatePipe } from "@corelib"; changeDetection: ChangeDetectionStrategy.OnPush, }) export class CourseComponent implements OnInit { + protected readonly desktopLayout = inject(DesktopLayoutService).desktop; readonly course = input.required(); ngOnInit(): void { diff --git a/projects/social_platform/src/app/ui/pages/courses/list/list.component.html b/projects/social_platform/src/app/ui/pages/courses/list/list.component.html index beae97dae..85016ce40 100644 --- a/projects/social_platform/src/app/ui/pages/courses/list/list.component.html +++ b/projects/social_platform/src/app/ui/pages/courses/list/list.component.html @@ -2,7 +2,11 @@
@if (loading()) { - + @if (desktopLayout()) { +
+ } @else { + + } } @else if (coursesList().length) {
@for (course of coursesList(); track course.id) { @@ -12,6 +16,8 @@ }
} @else { - + @if (!desktopLayout()) { + + } }
diff --git a/projects/social_platform/src/app/ui/pages/courses/list/list.component.ts b/projects/social_platform/src/app/ui/pages/courses/list/list.component.ts index 7794dcce6..7fba4fd49 100644 --- a/projects/social_platform/src/app/ui/pages/courses/list/list.component.ts +++ b/projects/social_platform/src/app/ui/pages/courses/list/list.component.ts @@ -1,6 +1,6 @@ /** @format */ -import { StateComponent } from "@uilib"; +import { DesktopLayoutService, StateComponent } from "@uilib"; /** @format */ import { ChangeDetectionStrategy, Component, inject, OnInit } from "@angular/core"; @@ -22,6 +22,7 @@ import { AppRoutes } from "@api/paths/app-routes"; changeDetection: ChangeDetectionStrategy.OnPush, }) export class CoursesListComponent implements OnInit { + protected readonly desktopLayout = inject(DesktopLayoutService).desktop; private readonly coursesListInfoService = inject(CoursesListInfoService); private readonly coursesListUIInfoService = inject(CoursesListUIInfoService); diff --git a/projects/social_platform/src/app/ui/pages/error/error-code/error-code.component.scss b/projects/social_platform/src/app/ui/pages/error/error-code/error-code.component.scss index 408198756..6c671a8e7 100644 --- a/projects/social_platform/src/app/ui/pages/error/error-code/error-code.component.scss +++ b/projects/social_platform/src/app/ui/pages/error/error-code/error-code.component.scss @@ -15,12 +15,19 @@ height: 580px; margin-bottom: 20px; color: var(--error-code); - background: - radial-gradient( - 50% 50% at 50% 50%, - var(--ui-success-glow) 0%, - var(--ui-success-glow-end) 100% - ); + + @media screen and (max-width: 999px) { + background: + radial-gradient( + 50% 50% at 50% 50%, + var(--ui-success-glow) 0%, + var(--ui-success-glow-end) 100% + ); + } + + @media screen and (min-width: 1000px) { + background: radial-gradient(50% 50% at 50% 50%, rgb(0 200 147 / 51%) 0%, rgb(0 200 147 / 0%) 100%); + } } &__title { @@ -35,24 +42,26 @@ } } -@include responsive.apply-below-desktop { - .error { - padding: 24px var(--page-gutter); - } +@media screen and (max-width: 999px) { + @include responsive.apply-below-desktop { + .error { + padding: 24px var(--page-gutter); + } - .error__body { - width: 100%; - min-width: 0; - } + .error__body { + width: 100%; + min-width: 0; + } - .error__code { - width: 100%; - height: auto; - min-height: 240px; - font-size: clamp(96px, 30vw, 240px); - } + .error__code { + width: 100%; + height: auto; + min-height: 240px; + font-size: clamp(96px, 30vw, 240px); + } - .error__link { - min-height: 44px; + .error__link { + min-height: 44px; + } } } diff --git a/projects/social_platform/src/app/ui/pages/feed/feed.component.html b/projects/social_platform/src/app/ui/pages/feed/feed.component.html index c4a83e34c..ba9368ea4 100644 --- a/projects/social_platform/src/app/ui/pages/feed/feed.component.html +++ b/projects/social_platform/src/app/ui/pages/feed/feed.component.html @@ -34,7 +34,14 @@ } } } @else { - + @if (desktopLayout()) { +
+ +

в данном разделе пока нет новостей

+
+ } @else { + + } }
diff --git a/projects/social_platform/src/app/ui/pages/feed/feed.component.scss b/projects/social_platform/src/app/ui/pages/feed/feed.component.scss index 9450e77a6..1fbddad33 100644 --- a/projects/social_platform/src/app/ui/pages/feed/feed.component.scss +++ b/projects/social_platform/src/app/ui/pages/feed/feed.component.scss @@ -41,6 +41,11 @@ } @include responsive.apply-below-desktop { + .page { + padding-top: 24px; + margin: 0 var(--page-gutter); + } + .filter { position: fixed; z-index: 300; diff --git a/projects/social_platform/src/app/ui/pages/feed/feed.component.ts b/projects/social_platform/src/app/ui/pages/feed/feed.component.ts index 31d4e1838..2ce41490d 100644 --- a/projects/social_platform/src/app/ui/pages/feed/feed.component.ts +++ b/projects/social_platform/src/app/ui/pages/feed/feed.component.ts @@ -1,6 +1,6 @@ /** @format */ -import { StateComponent } from "@uilib"; +import { DesktopLayoutService, StateComponent } from "@uilib"; /** @format */ import { @@ -42,6 +42,7 @@ import { FeedItem } from "@domain/feed/feed-item.model"; providers: [FeedInfoService, FeedUIInfoService, ProjectTeamUIService], }) export class FeedComponent implements AfterViewInit, OnDestroy { + protected readonly desktopLayout = inject(DesktopLayoutService).desktop; readonly feedRoot = viewChild>("feedRoot"); private readonly feedInfoService = inject(FeedInfoService); diff --git a/projects/social_platform/src/app/ui/pages/feed/open-vacancy/open-vacancy.component.html b/projects/social_platform/src/app/ui/pages/feed/open-vacancy/open-vacancy.component.html index c4ee6e578..27501fc5f 100644 --- a/projects/social_platform/src/app/ui/pages/feed/open-vacancy/open-vacancy.component.html +++ b/projects/social_platform/src/app/ui/pages/feed/open-vacancy/open-vacancy.component.html @@ -29,21 +29,25 @@

{{ feedItem() >

} + } diff --git a/projects/social_platform/src/app/ui/pages/office/nav/nav.component.scss b/projects/social_platform/src/app/ui/pages/office/nav/nav.component.scss index 8a5bf28dd..06e059c65 100644 --- a/projects/social_platform/src/app/ui/pages/office/nav/nav.component.scss +++ b/projects/social_platform/src/app/ui/pages/office/nav/nav.component.scss @@ -3,6 +3,12 @@ @use "styles/responsive"; @use "styles/typography"; +@media screen and (max-width: 999px) { + .nav-bar__logout { + margin-top: auto; + } +} + .nav-bar { display: block; @@ -13,10 +19,26 @@ } &__inner { - display: flex; - gap: 8px; - align-items: center; - justify-content: space-between; + @media screen and (max-width: 999px) { + display: grid; + } + + @media screen and (min-width: 1000px) { + display: flex; + } + + @media screen and (max-width: 999px) { + grid-template-columns: 88px minmax(0, 1fr) 88px; + } + + @media screen and (max-width: 999px) { + align-items: center; + } + + @media screen and (min-width: 1000px) { + justify-content: space-between; + } + max-width: responsive.$container-md; margin: 0 auto; @@ -47,9 +69,18 @@ cursor: pointer; border-radius: var(--rounded-sm); - > .attention { - top: 9px; - right: 11px; + @media screen and (max-width: 999px) { + > .attention { + top: 9px; + right: 11px; + } + } + + @media screen and (min-width: 1000px) { + >.attention { + top: 9px; + right: 11px; + } } &--active { @@ -61,17 +92,49 @@ &__toggle { position: relative; z-index: 100; - display: flex; - flex-shrink: 0; - align-items: center; - justify-content: center; - width: 44px; - height: 44px; + + @media screen and (max-width: 999px) { + display: flex; + } + + @media screen and (min-width: 1000px) { + display: block; + } + + @media screen and (max-width: 999px) { + flex-shrink: 0; + } + + @media screen and (max-width: 999px) { + align-items: center; + } + + @media screen and (max-width: 999px) { + justify-content: center; + } + + @media screen and (max-width: 999px) { + width: 44px; + } + + @media screen and (max-width: 999px) { + height: 44px; + } + cursor: pointer; - > .attention { - top: 8px; - right: 2px; + @media screen and (max-width: 999px) { + > .attention { + top: 8px; + right: 2px; + } + } + + @media screen and (min-width: 1000px) { + >.attention { + top: 8px; + right: 2px; + } } @include responsive.apply-desktop { @@ -84,48 +147,72 @@ top: 0; bottom: 0; left: 0; - z-index: 201; display: flex; flex-direction: column; - width: min(360px, calc(100% - 32px)); - max-height: 100dvh; - padding: max(16px, env(safe-area-inset-top)) 16px max(24px, env(safe-area-inset-bottom)); - overflow-y: auto; - overscroll-behavior: contain; background-color: var(--white); + + @media screen and (max-width: 999px) { + z-index: 201; + width: min(360px, calc(100% - 32px)); + max-height: 100dvh; + padding: max(16px, env(safe-area-inset-top)) 16px max(24px, env(safe-area-inset-bottom)); + overflow-y: auto; + overscroll-behavior: contain; + } + + @media screen and (min-width: 1000px) { + right: 0; + z-index: 50; + padding: 25px 15px 30px; + } } - &__backdrop { - position: fixed; - inset: 0; - z-index: 200; - background: var(--ui-scrim); + @media screen and (max-width: 999px) { + &__backdrop { + position: fixed; + inset: 0; + z-index: 200; + background: var(--ui-scrim); + } } - &__close { - display: flex; - align-items: center; - justify-content: center; - width: 44px; - height: 44px; - margin-right: auto; - color: var(--dark-grey); - cursor: pointer; + @media screen and (max-width: 999px) { + &__close { + display: flex; + align-items: center; + justify-content: center; + width: 44px; + height: 44px; + margin-right: auto; + color: var(--dark-grey); + cursor: pointer; + } } - &__title { - min-width: 0; - color: var(--white); - overflow-wrap: anywhere; + @media screen and (max-width: 999px) { + &__title { + grid-row: 1; + grid-column: 2; + min-width: 0; + font-weight: 600; + line-height: 18px; + color: var(--ui-text); + text-align: center; + overflow-wrap: anywhere; + } } - ::ng-deep .nav__link { - width: 100%; - margin-bottom: 12px; + @media screen and (max-width: 999px) { + ::ng-deep .nav__link { + width: 100%; + margin-bottom: 12px; + } } - ::ng-deep .nav__item { - min-height: 44px; + @media screen and (max-width: 999px) { + ::ng-deep .nav__item { + min-height: 44px; + } } &__user { diff --git a/projects/social_platform/src/app/ui/pages/office/nav/nav.component.ts b/projects/social_platform/src/app/ui/pages/office/nav/nav.component.ts index da9e3de2e..97e35dca5 100644 --- a/projects/social_platform/src/app/ui/pages/office/nav/nav.component.ts +++ b/projects/social_platform/src/app/ui/pages/office/nav/nav.component.ts @@ -21,10 +21,17 @@ import { OnDestroy, OnInit, inject, + output, } from "@angular/core"; import { AsyncPipe, CommonModule } from "@angular/common"; import { IconComponent } from "@ui/primitives"; -import { NavigationStart, Router, RouterLink, RouterLinkActive } from "@angular/router"; +import { + NavigationEnd, + NavigationStart, + Router, + RouterLink, + RouterLinkActive, +} from "@angular/router"; import { NavService } from "@api/shared/nav.service"; import { InviteInfoService } from "@api/invite/facades/invite-info.service"; import { A11yModule } from "@angular/cdk/a11y"; @@ -86,6 +93,7 @@ export class NavComponent implements OnInit, OnDestroy { private menuTrigger?: HTMLElement; readonly invites = this.inviteInfoService.invites; + readonly logout = output(); constructor( private readonly router: Router, @@ -96,17 +104,22 @@ export class NavComponent implements OnInit, OnDestroy { ) {} ngOnInit(): void { + this.title = this.routeTitle(this.router.url); // Подписка на события роутера для закрытия мобильного меню this.router.events.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(event => { if (event instanceof NavigationStart) { this.closeMenu(); this.cdref.markForCheck(); } + if (event instanceof NavigationEnd) { + this.title = this.routeTitle(event.urlAfterRedirects) || this.title; + this.cdref.markForCheck(); + } }); // Подписка на изменения заголовка страницы this.navService.navTitle.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(title => { - this.title = title; + this.title = this.routeTitle(this.router.url) || title; this.cdref.detectChanges(); }); } @@ -115,6 +128,25 @@ export class NavComponent implements OnInit, OnDestroy { this.menuScrollStrategy.disable(); } + private routeTitle(url: string): string { + const path = url.split(/[?#]/)[0]; + if (/^\/office\/profile\/edit(?:\/|$)/.test(path)) return "Редактирование профиля"; + if (/^\/office\/projects\/create(?:\/|$)/.test(path)) return "Создание проекта"; + if (/^\/office\/projects\/\d+\/edit(?:\/|$)/.test(path)) return "Редактирование проекта"; + if (/^\/office\/projects\/\d+(?:\/|$)/.test(path)) return "Профиль проекта"; + const sections: Record = { + feed: "Новости", + projects: "Проекты", + members: "Участники", + program: "Программы", + courses: "Курсы", + vacancies: "Вакансии", + profile: "Профиль", + chats: "Чаты", + }; + return sections[path.split("/")[2]] || ""; + } + @HostListener("window:resize") onViewportResize(): void { if (this.mobileMenuOpen && window.innerWidth >= desktop) this.closeMenu(); diff --git a/projects/social_platform/src/app/ui/pages/office/office.component.html b/projects/social_platform/src/app/ui/pages/office/office.component.html index 5f840178f..ce1d59b4b 100644 --- a/projects/social_platform/src/app/ui/pages/office/office.component.html +++ b/projects/social_platform/src/app/ui/pages/office/office.component.html @@ -39,7 +39,7 @@
- + @if (profile() !== undefined && invites() !== undefined) { app-nav { - flex: 1; - min-width: 0; + @media screen and (max-width: 999px) { + &__top > app-nav { + grid-row: 1; + grid-column: 1 / -1; + min-width: 0; + } + } + + @media screen and (max-width: 999px) { + &__top > app-profile-control-panel { + grid-row: 1; + grid-column: 3; + justify-self: end; + min-width: 0; + } } &__header { diff --git a/projects/social_platform/src/app/ui/pages/office/snackbar/snackbar.component.scss b/projects/social_platform/src/app/ui/pages/office/snackbar/snackbar.component.scss index d6da495e1..60046c083 100644 --- a/projects/social_platform/src/app/ui/pages/office/snackbar/snackbar.component.scss +++ b/projects/social_platform/src/app/ui/pages/office/snackbar/snackbar.component.scss @@ -2,8 +2,6 @@ @use "styles/responsive"; -/** @format */ - .snackbar { position: absolute; top: 0; @@ -13,7 +11,15 @@ padding-right: 50px; overflow-x: hidden; + @media screen and (max-width: 999px) { + pointer-events: none; + } + &__item { + @media screen and (max-width: 999px) { + pointer-events: auto; + } + &:not(:last-child) { margin-bottom: 10px; } @@ -44,20 +50,22 @@ } } -@include responsive.apply-mobile { - .snackbar { - position: fixed; - top: max(12px, env(safe-area-inset-top)); - right: var(--page-gutter); - left: var(--page-gutter); - max-height: calc(100dvh - 24px); - padding: 0; - overflow-y: auto; - } +@media screen and (max-width: 999px) { + @include responsive.apply-mobile { + .snackbar { + position: fixed; + top: max(12px, env(safe-area-inset-top)); + right: var(--page-gutter); + left: var(--page-gutter); + max-height: calc(100dvh - 24px); + padding: 0; + overflow-y: auto; + } - .item { - min-width: 0; - padding: 12px; - overflow-wrap: anywhere; + .item { + min-width: 0; + padding: 12px; + overflow-wrap: anywhere; + } } } diff --git a/projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-left-side/profile-left-side.component.scss b/projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-left-side/profile-left-side.component.scss index b7d5313f6..ae0c8110d 100644 --- a/projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-left-side/profile-left-side.component.scss +++ b/projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-left-side/profile-left-side.component.scss @@ -111,8 +111,8 @@ background-color: var(--accent-light); } - /* stylelint-disable value-no-vendor-prefix */ &__program-name { + /* stylelint-disable-next-line value-no-vendor-prefix */ display: -webkit-box; min-width: 0; overflow: hidden; @@ -122,14 +122,21 @@ -webkit-line-clamp: 2; &--compact { - font-size: var(--ui-font-caption); - font-weight: 400; line-height: 14px; word-break: normal; overflow-wrap: normal; + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + font-weight: 400; + } + + @media screen and (min-width: 1000px) { + font-size: 10px; + font-weight: 400; + } } } - /* stylelint-enable value-no-vendor-prefix */ &__icon { color: var(--accent); diff --git a/projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-right-side/profile-right-side.component.scss b/projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-right-side/profile-right-side.component.scss index a8d873e0b..98008d770 100644 --- a/projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-right-side/profile-right-side.component.scss +++ b/projects/social_platform/src/app/ui/pages/profile/detail/main/components/profile-right-side/profile-right-side.component.scss @@ -107,17 +107,31 @@ } &--subtext { - font-size: var(--ui-font-caption); line-height: 16px; color: var(--grey-for-text) !important; word-break: break-word; overflow-wrap: anywhere; + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + } + + @media screen and (min-width: 1000px) { + font-size: 11px; + } } &--more { - font-size: var(--ui-font-caption); line-height: 16px; color: var(--accent) !important; + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + } + + @media screen and (min-width: 1000px) { + font-size: 11px; + } } img { @@ -125,8 +139,8 @@ } } - /* stylelint-disable value-no-vendor-prefix */ &__project-name { + /* stylelint-disable-next-line value-no-vendor-prefix */ display: -webkit-box; overflow: hidden; font-size: var(--ui-font-small); @@ -140,12 +154,18 @@ &__project-role { margin-top: 3px; - font-size: var(--ui-font-caption); line-height: 15px; color: var(--dark-grey); overflow-wrap: anywhere; + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + } + + @media screen and (min-width: 1000px) { + font-size: 11px; + } } - /* stylelint-enable value-no-vendor-prefix */ &__date { display: flex; @@ -158,9 +178,16 @@ border-radius: var(--rounded-xl); p { - font-size: var(--ui-font-caption); line-height: 14px; color: var(--dark-grey); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + } + + @media screen and (min-width: 1000px) { + font-size: 11px; + } } } diff --git a/projects/social_platform/src/app/ui/pages/profile/detail/profile-news/profile-news.component.scss b/projects/social_platform/src/app/ui/pages/profile/detail/profile-news/profile-news.component.scss index 0219fccd0..3195861cc 100644 --- a/projects/social_platform/src/app/ui/pages/profile/detail/profile-news/profile-news.component.scss +++ b/projects/social_platform/src/app/ui/pages/profile/detail/profile-news/profile-news.component.scss @@ -6,7 +6,6 @@ display: block; @include responsive.apply-desktop { - width: 100%; - min-width: 0; + min-width: 800px; } } diff --git a/projects/social_platform/src/app/ui/pages/profile/edit/components/profile-achievements-step/profile-achievements-step.component.scss b/projects/social_platform/src/app/ui/pages/profile/edit/components/profile-achievements-step/profile-achievements-step.component.scss index c394c4427..fab36a81e 100644 --- a/projects/social_platform/src/app/ui/pages/profile/edit/components/profile-achievements-step/profile-achievements-step.component.scss +++ b/projects/social_platform/src/app/ui/pages/profile/edit/components/profile-achievements-step/profile-achievements-step.component.scss @@ -1,7 +1,6 @@ -@use "styles/profile-form"; - /** @format */ +@use "styles/profile-form"; @use "styles/responsive"; .profile__wrapper--education { @@ -119,4 +118,6 @@ } } -@include profile-form.responsive-layout; +@media screen and (max-width: 999px) { + @include profile-form.responsive-layout; +} diff --git a/projects/social_platform/src/app/ui/pages/profile/edit/components/profile-education-step/profile-education-step.component.scss b/projects/social_platform/src/app/ui/pages/profile/edit/components/profile-education-step/profile-education-step.component.scss index fc3d2503b..bbf8e84bb 100644 --- a/projects/social_platform/src/app/ui/pages/profile/edit/components/profile-education-step/profile-education-step.component.scss +++ b/projects/social_platform/src/app/ui/pages/profile/edit/components/profile-education-step/profile-education-step.component.scss @@ -1,7 +1,6 @@ -@use "styles/profile-form"; - /** @format */ +@use "styles/profile-form"; @use "styles/responsive"; .profile__wrapper--education { @@ -113,4 +112,6 @@ } } -@include profile-form.responsive-layout; +@media screen and (max-width: 999px) { + @include profile-form.responsive-layout; +} diff --git a/projects/social_platform/src/app/ui/pages/profile/edit/components/profile-experience-step/profile-experience-step.component.scss b/projects/social_platform/src/app/ui/pages/profile/edit/components/profile-experience-step/profile-experience-step.component.scss index fc3d2503b..bbf8e84bb 100644 --- a/projects/social_platform/src/app/ui/pages/profile/edit/components/profile-experience-step/profile-experience-step.component.scss +++ b/projects/social_platform/src/app/ui/pages/profile/edit/components/profile-experience-step/profile-experience-step.component.scss @@ -1,7 +1,6 @@ -@use "styles/profile-form"; - /** @format */ +@use "styles/profile-form"; @use "styles/responsive"; .profile__wrapper--education { @@ -113,4 +112,6 @@ } } -@include profile-form.responsive-layout; +@media screen and (max-width: 999px) { + @include profile-form.responsive-layout; +} diff --git a/projects/social_platform/src/app/ui/pages/profile/edit/components/profile-main-step/profile-main-step.component.scss b/projects/social_platform/src/app/ui/pages/profile/edit/components/profile-main-step/profile-main-step.component.scss index 220ea437a..4163ebdc8 100644 --- a/projects/social_platform/src/app/ui/pages/profile/edit/components/profile-main-step/profile-main-step.component.scss +++ b/projects/social_platform/src/app/ui/pages/profile/edit/components/profile-main-step/profile-main-step.component.scss @@ -1,7 +1,6 @@ -@use "styles/profile-form"; - /** @format */ +@use "styles/profile-form"; @use "styles/responsive"; .profile__wrapper--main { @@ -114,4 +113,6 @@ margin-bottom: 10px; } -@include profile-form.responsive-layout; +@media screen and (max-width: 999px) { + @include profile-form.responsive-layout; +} diff --git a/projects/social_platform/src/app/ui/pages/profile/edit/components/profile-skills-step/profile-skills-step.component.scss b/projects/social_platform/src/app/ui/pages/profile/edit/components/profile-skills-step/profile-skills-step.component.scss index 40a17ae90..bafc5d9dd 100644 --- a/projects/social_platform/src/app/ui/pages/profile/edit/components/profile-skills-step/profile-skills-step.component.scss +++ b/projects/social_platform/src/app/ui/pages/profile/edit/components/profile-skills-step/profile-skills-step.component.scss @@ -1,7 +1,6 @@ -@use "styles/profile-form"; - /** @format */ +@use "styles/profile-form"; @use "styles/responsive"; :host, @@ -129,4 +128,6 @@ fieldset { } } -@include profile-form.responsive-layout; +@media screen and (max-width: 999px) { + @include profile-form.responsive-layout; +} diff --git a/projects/social_platform/src/app/ui/pages/profile/edit/edit.component.html b/projects/social_platform/src/app/ui/pages/profile/edit/edit.component.html index a3e98136b..64fdfabd8 100644 --- a/projects/social_platform/src/app/ui/pages/profile/edit/edit.component.html +++ b/projects/social_platform/src/app/ui/pages/profile/edit/edit.component.html @@ -2,10 +2,21 @@ @if (profileForm.get("userType"); as currentType) {
- + @if (desktopLayout()) { +
+ +

редактирование профиля

+
+ + } @else { + + + + } +
-
+
diff --git a/projects/social_platform/src/app/ui/pages/profile/edit/edit.component.scss b/projects/social_platform/src/app/ui/pages/profile/edit/edit.component.scss index 108f39d41..cc72026a6 100644 --- a/projects/social_platform/src/app/ui/pages/profile/edit/edit.component.scss +++ b/projects/social_platform/src/app/ui/pages/profile/edit/edit.component.scss @@ -327,10 +327,17 @@ flex-direction: column; gap: 20px; align-items: center; - width: 100%; - min-width: 0; - max-width: 100%; - padding: 0; + + @media screen and (max-width: 999px) { + width: 100%; + min-width: 0; + max-width: 100%; + padding: 0; + } + + @media screen and (min-width: 1000px) { + width: 672px; + } } &__close { @@ -416,32 +423,34 @@ } } -@include responsive.apply-below-desktop { - :host { - display: block; - min-width: 0; - } +@media screen and (max-width: 999px) { + @include responsive.apply-below-desktop { + :host { + display: block; + min-width: 0; + } - .profile { - padding: 16px var(--page-gutter) max(24px, env(safe-area-inset-bottom)); - } + .profile { + padding: 16px var(--page-gutter) max(24px, env(safe-area-inset-bottom)); + } - .profile__top { - position: static; - gap: 12px; - justify-content: space-between; - padding: 8px var(--page-gutter); - } + .profile__top { + position: static; + gap: 12px; + justify-content: space-between; + padding: 8px var(--page-gutter); + } - .profile__left form { - width: 100%; - } + .profile__left form { + width: 100%; + } - .profile__save { - @include responsive.mobile-actions; - } + .profile__save { + @include responsive.mobile-actions; + } - .profile__wrapper--settings { - min-width: 0; + .profile__wrapper--settings { + min-width: 0; + } } } diff --git a/projects/social_platform/src/app/ui/pages/profile/edit/edit.component.ts b/projects/social_platform/src/app/ui/pages/profile/edit/edit.component.ts index af9259bc4..63f9fb9b1 100644 --- a/projects/social_platform/src/app/ui/pages/profile/edit/edit.component.ts +++ b/projects/social_platform/src/app/ui/pages/profile/edit/edit.component.ts @@ -1,6 +1,11 @@ /** @format */ -import { ButtonDirective, FormLayoutDirective, PageHeaderComponent } from "@uilib"; +import { + ButtonDirective, + DesktopLayoutService, + FormLayoutDirective, + PageHeaderComponent, +} from "@uilib"; /** @format */ import { @@ -93,6 +98,7 @@ import { ProfileEditAchievementsInfoService } from "@api/profile/facades/edit/pr changeDetection: ChangeDetectionStrategy.OnPush, }) export class ProfileEditComponent implements OnInit, AfterViewInit { + protected readonly desktopLayout = inject(DesktopLayoutService).desktop; private readonly profileFormService = inject(ProfileFormService); private readonly profileEditInfoService = inject(ProfileEditInfoService); private readonly projectStepService = inject(ProjectStepService); diff --git a/projects/social_platform/src/app/ui/pages/program/detail/analytics/analytics.component.scss b/projects/social_platform/src/app/ui/pages/program/detail/analytics/analytics.component.scss index 1e304f650..91cb4e3be 100644 --- a/projects/social_platform/src/app/ui/pages/program/detail/analytics/analytics.component.scss +++ b/projects/social_platform/src/app/ui/pages/program/detail/analytics/analytics.component.scss @@ -208,10 +208,18 @@ &__value { display: block; margin-top: 6px; - font-size: var(--ui-font-h1); - font-weight: 700; line-height: 1; color: var(--black); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-h1); + font-weight: 700; + } + + @media screen and (min-width: 1000px) { + font-size: 24px; + font-weight: 700; + } } &--skeleton { @@ -258,10 +266,18 @@ } &__section-label { - font-size: var(--ui-font-body); - font-weight: 600; line-height: 18px; color: var(--black); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-body); + font-weight: 600; + } + + @media screen and (min-width: 1000px) { + font-size: 13px; + font-weight: 600; + } } } @@ -279,7 +295,6 @@ max-height: 380px; @include responsive.apply-desktop { - /* Let the evaluation card size the row; keep the case list scrolling inside it. */ align-self: stretch; max-height: none; contain: size; @@ -341,7 +356,7 @@ } &__name { - /* stylelint-disable-next-line value-no-vendor-prefix -- Required for two-line clamp. */ + /* stylelint-disable-next-line value-no-vendor-prefix */ display: -webkit-box; min-width: 0; overflow: hidden; @@ -363,17 +378,33 @@ } &__total-value { - font-size: var(--ui-font-h2); - font-weight: 700; line-height: 20px; + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-h2); + font-weight: 700; + } + + @media screen and (min-width: 1000px) { + font-size: 17px; + font-weight: 700; + } } &__total-label, &__meta { - font-size: var(--ui-font-caption); - font-weight: 500; line-height: 16px; color: var(--dark-grey); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + font-weight: 500; + } + + @media screen and (min-width: 1000px) { + font-size: 10px; + font-weight: 500; + } } &__bar { @@ -470,10 +501,18 @@ } strong { - font-size: var(--ui-font-h2); - font-weight: 700; line-height: 20px; color: var(--black); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-h2); + font-weight: 700; + } + + @media screen and (min-width: 1000px) { + font-size: 17px; + font-weight: 700; + } } } @@ -569,8 +608,15 @@ color: var(--dark-grey); strong { - font-size: var(--ui-font-body); color: var(--black); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-body); + } + + @media screen and (min-width: 1000px) { + font-size: 13px; + } } .text-body-10 { @@ -851,8 +897,15 @@ span { position: absolute; - font-size: var(--ui-font-caption); transform: translateX(-50%); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + } + + @media screen and (min-width: 1000px) { + font-size: 11px; + } } } } diff --git a/projects/social_platform/src/app/ui/pages/program/detail/analytics/drilldown/analytics-drilldown.component.scss b/projects/social_platform/src/app/ui/pages/program/detail/analytics/drilldown/analytics-drilldown.component.scss index be07e5b72..b0d3775ba 100644 --- a/projects/social_platform/src/app/ui/pages/program/detail/analytics/drilldown/analytics-drilldown.component.scss +++ b/projects/social_platform/src/app/ui/pages/program/detail/analytics/drilldown/analytics-drilldown.component.scss @@ -1,13 +1,20 @@ /** @format */ + @use "styles/responsive"; -/* Только case-вариант: shared modal задаёт width своим stylesheet после подключения overlay. */ .modal__body.analytics-drilldown-body.analytics-drilldown-body--case { box-sizing: border-box; width: min(880px, calc(100% - 24px)); - max-height: calc(var(--visual-viewport-height, 100dvh) - 32px); padding: 20px; overflow-y: auto; + + @media screen and (max-width: 999px) { + max-height: calc(var(--visual-viewport-height, 100dvh) - 32px); + } + + @media screen and (min-width: 1000px) { + max-height: calc(100dvh - 32px); + } } .analytics-case { @@ -102,7 +109,7 @@ } th { - font-size: var(--ui-font-body); + font-size: 13px; } th:first-child, @@ -128,16 +135,21 @@ } } -/* Overlay лежит вне host: единственное глобальное правило ограничено собственным bodyClass. */ .modal__body.analytics-drilldown-body { box-sizing: border-box; width: min(880px, calc(100vw - 24px)); - max-height: calc(var(--visual-viewport-height, 100dvh) - 32px); padding: 20px; overflow-y: auto; + + @media screen and (max-width: 999px) { + max-height: calc(var(--visual-viewport-height, 100dvh) - 32px); + } + + @media screen and (min-width: 1000px) { + max-height: calc(100dvh - 32px); + } } -/* Тот же шаблон используется в backlog: оформление меняется только у трёх списков назначений. */ .modal__body.analytics-drilldown-body.analytics-drilldown-body--assignments { width: min(980px, calc(100vw - 32px)); padding: 16px; @@ -151,8 +163,15 @@ margin-bottom: 24px; h2 { - font-size: var(--ui-font-h1); line-height: 30px; + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-h1); + } + + @media screen and (min-width: 1000px) { + font-size: 24px; + } } } @@ -446,7 +465,7 @@ } th { - font-size: var(--ui-font-body); + font-size: 13px; font-weight: 600; } @@ -520,9 +539,17 @@ .analytics-drilldown__action { padding: 4px 0; - font-size: var(--ui-font-body); - font-weight: 500; line-height: 20px; + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-body); + font-weight: 500; + } + + @media screen and (min-width: 1000px) { + font-size: 13px; + font-weight: 500; + } } @include responsive.apply-desktop { diff --git a/projects/social_platform/src/app/ui/pages/program/detail/list/list.component.scss b/projects/social_platform/src/app/ui/pages/program/detail/list/list.component.scss index 53f7b4266..f3ab345b7 100644 --- a/projects/social_platform/src/app/ui/pages/program/detail/list/list.component.scss +++ b/projects/social_platform/src/app/ui/pages/program/detail/list/list.component.scss @@ -138,9 +138,19 @@ &__tooltip { position: fixed; - right: calc((100vw - 1080px) / 2); bottom: 24px; z-index: 30; + + @media screen and (max-width: 999px) { + right: calc((100vw - 1080px) / 2); + } + + @media screen and (min-width: 1000px) { + right: + calc( + (100vw - 1080px) / 2 + ); + } } } @@ -265,11 +275,33 @@ flex-direction: column; align-items: center; justify-content: center; - width: 100%; - min-width: 0; - max-width: 100%; + + @media screen and (max-width: 999px) { + width: 100%; + } + + @media screen and (min-width: 1000px) { + width: 80%; + } + + @media screen and (max-width: 999px) { + min-width: 0; + } + + @media screen and (max-width: 999px) { + max-width: 100%; + } + max-height: calc(100vh - 40px); - padding: 0; + + @media screen and (max-width: 999px) { + padding: 0; + } + + @media screen and (min-width: 1000px) { + padding: 0 24px; + } + overflow-y: auto; @include responsive.apply-desktop { @@ -313,39 +345,43 @@ } } -@include responsive.apply-mobile { - .page__list { - @include responsive.single-column; - } +@media screen and (max-width: 999px) { + @include responsive.apply-mobile { + .page__list { + @include responsive.single-column; + } - .page__mobile-filter-row { - @include responsive.mobile-actions; - } + .page__mobile-filter-row { + @include responsive.mobile-actions; + } - .page__tooltip { - right: var(--page-gutter); - bottom: max(16px, env(safe-area-inset-bottom)); - } + .page__tooltip { + right: var(--page-gutter); + bottom: max(16px, env(safe-area-inset-bottom)); + } - .tooltip__wrapper { - position: fixed; - right: var(--page-gutter); - bottom: 60px; - left: auto; - width: calc(100vw - 2 * var(--page-gutter)); + .tooltip__wrapper { + position: fixed; + right: var(--page-gutter); + bottom: 60px; + left: auto; + width: calc(100vw - 2 * var(--page-gutter)); + } } } -@include responsive.apply-below-desktop { - .filter { - position: fixed; - z-index: 300; - } +@media screen and (max-width: 999px) { + @include responsive.apply-below-desktop { + .filter { + position: fixed; + z-index: 300; + } - .filter__body { - min-height: 0; - max-height: calc(var(--visual-viewport-height, 100dvh) - 80px); - padding-bottom: env(safe-area-inset-bottom, 0); - overscroll-behavior: contain; + .filter__body { + min-height: 0; + max-height: calc(var(--visual-viewport-height, 100dvh) - 80px); + padding-bottom: env(safe-area-inset-bottom, 0); + overscroll-behavior: contain; + } } } diff --git a/projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/project-rating/components/boolean-criterion/boolean-criterion.component.scss b/projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/project-rating/components/boolean-criterion/boolean-criterion.component.scss index 500b43267..09137139f 100644 --- a/projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/project-rating/components/boolean-criterion/boolean-criterion.component.scss +++ b/projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/project-rating/components/boolean-criterion/boolean-criterion.component.scss @@ -6,11 +6,13 @@ display: block; } -@include responsive.apply-mobile { - .container { - justify-content: center; - min-width: 44px; - min-height: 44px; +@media screen and (max-width: 999px) { + @include responsive.apply-mobile { + .container { + justify-content: center; + min-width: 44px; + min-height: 44px; + } } } diff --git a/projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/project-rating/components/range-criterion-input/range-criterion-input.component.scss b/projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/project-rating/components/range-criterion-input/range-criterion-input.component.scss index 8701d4225..9d620ee46 100644 --- a/projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/project-rating/components/range-criterion-input/range-criterion-input.component.scss +++ b/projects/social_platform/src/app/ui/pages/program/detail/list/rating-card/project-rating/components/range-criterion-input/range-criterion-input.component.scss @@ -36,27 +36,35 @@ &:focus { border-color: var(--accent); - box-shadow: var(--ui-focus-ring); + + @media screen and (max-width: 999px) { + box-shadow: var(--ui-focus-ring); + } + + @media screen and (min-width: 1000px) { + box-shadow: 0 0 6px rgb(109 40 255 / 30%); + } } } } -/* stylelint-disable property-no-vendor-prefix */ input { &::-webkit-outer-spin-button, &::-webkit-inner-spin-button { - -webkit-appearance: none; + appearance: none; } &[type="number"] { - -moz-appearance: textfield; + appearance: textfield; } } -@include responsive.apply-mobile { - .field__input { - width: 44px; - height: 44px; - font-size: var(--ui-font-h3); +@media screen and (max-width: 999px) { + @include responsive.apply-mobile { + .field__input { + width: 44px; + height: 44px; + font-size: var(--ui-font-h3); + } } } diff --git a/projects/social_platform/src/app/ui/pages/program/detail/main/role-widget/program-role-widget.component.scss b/projects/social_platform/src/app/ui/pages/program/detail/main/role-widget/program-role-widget.component.scss index d2b8e90f8..3861bff23 100644 --- a/projects/social_platform/src/app/ui/pages/program/detail/main/role-widget/program-role-widget.component.scss +++ b/projects/social_platform/src/app/ui/pages/program/detail/main/role-widget/program-role-widget.component.scss @@ -13,17 +13,22 @@ grid-template-rows: 18px minmax(0, 1fr) 22px; row-gap: 5px; width: 100%; - - /* Исходная карточка при 100%: 157 × 140.984375 CSS px (Mont, desktop). */ height: 140.9844px; padding: 7px 8px; - font-size: var(--ui-font-caption); line-height: 13px; color: var(--black); background: var(--light-white); border: 0.5px solid var(--medium-grey-for-outline); border-radius: var(--rounded-lg); + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + } + + @media screen and (min-width: 1000px) { + font-size: 10px; + } + &__header { display: flex; gap: 5px; @@ -87,9 +92,16 @@ &__stage-state { height: 12px; margin-top: 3px; - font-size: var(--ui-font-caption); line-height: 12px; color: var(--grey-for-text); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + } + + @media screen and (min-width: 1000px) { + font-size: 10px; + } } &__steps { @@ -161,9 +173,16 @@ } dt { - font-size: var(--ui-font-caption); line-height: 12px; color: var(--grey-for-text); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + } + + @media screen and (min-width: 1000px) { + font-size: 10px; + } } dd { @@ -214,8 +233,15 @@ align-content: center; min-height: 28px; margin-top: 6px; - font-size: var(--ui-font-caption); line-height: 12px; + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + } + + @media screen and (min-width: 1000px) { + font-size: 10px; + } } &__status-label { @@ -297,34 +323,36 @@ } } -@include responsive.apply-below-desktop { - :host { - width: 100%; - min-width: 0; - } - - .widget { - grid-template-rows: auto minmax(0, 1fr) auto; - gap: 12px; - height: auto; - min-height: 160px; - padding: 16px; - font-size: var(--ui-font-body); - line-height: 1.5; - } - - .widget__footer a, - .widget__footer button { - min-height: 44px; - font-size: var(--ui-font-body); - } - - .widget__ellipsis { - overflow-wrap: anywhere; - white-space: normal; - } - - .widget__badge { - font-size: var(--ui-font-small); +@media screen and (max-width: 999px) { + @include responsive.apply-below-desktop { + :host { + width: 100%; + min-width: 0; + } + + .widget { + grid-template-rows: auto minmax(0, 1fr) auto; + gap: 12px; + height: auto; + min-height: 160px; + padding: 16px; + font-size: var(--ui-font-body); + line-height: 1.5; + } + + .widget__footer a, + .widget__footer button { + min-height: 44px; + font-size: var(--ui-font-body); + } + + .widget__ellipsis { + overflow-wrap: anywhere; + white-space: normal; + } + + .widget__badge { + font-size: var(--ui-font-small); + } } } diff --git a/projects/social_platform/src/app/ui/pages/program/main/program-card/program-card.component.html b/projects/social_platform/src/app/ui/pages/program/main/program-card/program-card.component.html index 42654715f..826edca5b 100644 --- a/projects/social_platform/src/app/ui/pages/program/main/program-card/program-card.component.html +++ b/projects/social_platform/src/app/ui/pages/program/main/program-card/program-card.component.html @@ -1,44 +1,86 @@ -@if (program()) { -
-
- -
- -
-

{{ program().name }}

+@if (desktopLayout()) { + @if (program()) { +
+
+ +
-

- - {{ - registerDateExpired - ? "регистрация завершена" - : program().isUserMember - ? "ты уже участвуешь!" - : "Регистрация до " + (program().datetimeRegistrationEnds | date: "dd MMMM") - }} -

+
+

{{ program().name }}

-
-

- {{ program().datetimeStarted | date: "dd.MM.yyyy" }} +

+ + {{ + registerDateExpired + ? "регистрация завершена" + : program().isUserMember + ? "ты уже участвуешь!" + : "Регистрация до " + (program().datetimeRegistrationEnds | date: "dd MMMM") + }}

-

-

-

- {{ program().datetimeFinished | date: "dd.MM.yyyy" }} + +

+

+ {{ program().datetimeStarted | date: "dd.MM.yyyy" }} +

+

-

+

+ {{ program().datetimeFinished | date: "dd.MM.yyyy" }} +

+ +

• для всей России

+
+
+
+ } +} @else { + @if (program()) { +
+
+ +
+ +
+

{{ program().name }}

+ +

+ + {{ + registerDateExpired + ? "регистрация завершена" + : program().isUserMember + ? "ты уже участвуешь!" + : "Регистрация до " + (program().datetimeRegistrationEnds | date: "dd MMMM") + }}

- -

• для всей России

+ +
+

+ {{ program().datetimeStarted | date: "dd.MM.yyyy" }} - + {{ program().datetimeFinished | date: "dd.MM.yyyy" }} +

+ +

для всей России

+
-
+ } } diff --git a/projects/social_platform/src/app/ui/pages/program/main/program-card/program-card.component.scss b/projects/social_platform/src/app/ui/pages/program/main/program-card/program-card.component.scss index d9bfd33a4..e66ff0477 100644 --- a/projects/social_platform/src/app/ui/pages/program/main/program-card/program-card.component.scss +++ b/projects/social_platform/src/app/ui/pages/program/main/program-card/program-card.component.scss @@ -1,77 +1,145 @@ /** @format */ @use "styles/ui-foundation"; - -/** @format */ - @use "styles/responsive"; -.card { - position: relative; - display: flex; - gap: 20px; - align-items: center; - max-width: 333px; +@media screen and (max-width: 999px) { + .card { + @include ui-foundation.card; - &__photo { position: relative; - z-index: 10; - flex-shrink: 0; - width: 123px; - height: 123px; - padding: 12px; - background: var(--white); - border: 0.5px solid var(--dark-grey); - border-radius: 50%; - } + display: grid; + grid-template-columns: 64px minmax(0, 1fr); + gap: 12px; + align-items: start; - &__info { - @include ui-foundation.card; + &__photo { + width: 64px; + height: 64px; + } - position: relative; - z-index: 1; - min-width: 0; - margin-left: -18%; - overflow: hidden; - } + &__info { + display: grid; + gap: 8px; + min-width: 0; + } + + &__name { + /* stylelint-disable-next-line value-no-vendor-prefix */ + display: -webkit-box; + overflow: hidden; + font-size: var(--ui-font-body); + font-weight: 600; + line-height: 20px; + color: var(--black); + overflow-wrap: anywhere; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; + } + + &__dates { + display: grid; + gap: 4px; + } + + &__description { + font-size: var(--ui-font-small); + line-height: 18px; + color: var(--dark-grey); + } - &__name { - overflow: hidden; - color: var(--black); - text-overflow: ellipsis; - white-space: nowrap; + &__registration { + justify-self: start; + max-width: 100%; + padding: 4px 8px; + color: var(--white); + overflow-wrap: anywhere; + border-radius: var(--rounded-lg); + + &--actual { + background-color: var(--accent); + } + + &--ended { + background-color: var(--red) !important; + } + + &--participating { + background-color: var(--green); + } + } } +} - &__dates { +@media screen and (min-width: 1000px) { + .card { + position: relative; display: flex; - gap: 2px; - white-space: nowrap; - } + gap: 20px; + align-items: center; + max-width: 333px; - &__description { - color: var(--dark-grey); - } + &__photo { + position: relative; + z-index: 10; + flex-shrink: 0; + width: 123px; + height: 123px; + padding: 12px; + background: var(--white); + border: 0.5px solid var(--dark-grey); + border-radius: 50%; + } + + &__info { + position: relative; + z-index: 1; + min-width: 0; + padding: 22px; + margin-left: -18%; + overflow: hidden; + border: 0.5px solid var(--dark-grey); + border-radius: var(--rounded-lg); + } + + &__name { + overflow: hidden; + color: var(--black); + text-overflow: ellipsis; + white-space: nowrap; + } - &__registration { - padding: 2px 2px 2px 25px; - margin-top: 2px; - margin-bottom: 6px; - overflow: hidden; - color: var(--white); - text-overflow: ellipsis; - white-space: nowrap; - border-radius: var(--rounded-lg); - - &--actual { - background-color: var(--accent); + &__dates { + display: flex; + gap: 2px; + white-space: nowrap; } - &--ended { - background-color: var(--red) !important; + &__description { + color: var(--dark-grey); } - &--participating { - background-color: var(--green); + &__registration { + padding: 2px 2px 2px 25px; + margin-top: 2px; + margin-bottom: 6px; + overflow: hidden; + color: var(--white); + text-overflow: ellipsis; + white-space: nowrap; + border-radius: var(--rounded-lg); + + &--actual { + background-color: var(--accent); + } + + &--ended { + background-color: var(--red) !important; + } + + &--participating { + background-color: var(--green); + } } } } diff --git a/projects/social_platform/src/app/ui/pages/program/main/program-card/program-card.component.ts b/projects/social_platform/src/app/ui/pages/program/main/program-card/program-card.component.ts index a92fc222e..6034b1ab9 100644 --- a/projects/social_platform/src/app/ui/pages/program/main/program-card/program-card.component.ts +++ b/projects/social_platform/src/app/ui/pages/program/main/program-card/program-card.component.ts @@ -1,9 +1,12 @@ /** @format */ +import { DesktopLayoutService } from "@uilib"; +/** @format */ + import { CardDirective } from "@uilib"; /** @format */ -import { ChangeDetectionStrategy, Component, input, Input, OnInit } from "@angular/core"; +import { ChangeDetectionStrategy, Component, inject, input, Input, OnInit } from "@angular/core"; import { AvatarComponent } from "@ui/primitives/avatar/avatar.component"; import { DatePipe, NgClass } from "@angular/common"; import { Program } from "@domain/program/program.model"; @@ -17,6 +20,8 @@ import { Program } from "@domain/program/program.model"; changeDetection: ChangeDetectionStrategy.OnPush, }) export class ProgramCardComponent implements OnInit { + protected readonly desktopLayout = inject(DesktopLayoutService).desktop; + readonly program = input.required(); ngOnInit(): void { diff --git a/projects/social_platform/src/app/ui/pages/projects/bar-new/bar.component.html b/projects/social_platform/src/app/ui/pages/projects/bar-new/bar.component.html index 12887372a..7b993203c 100644 --- a/projects/social_platform/src/app/ui/pages/projects/bar-new/bar.component.html +++ b/projects/social_platform/src/app/ui/pages/projects/bar-new/bar.component.html @@ -1,3 +1,31 @@ - +@if (desktopLayout()) { +
+ +
+} @else { + +} + + diff --git a/projects/social_platform/src/app/ui/pages/projects/bar-new/bar.component.scss b/projects/social_platform/src/app/ui/pages/projects/bar-new/bar.component.scss index ce99ec2cc..5fd5a3124 100644 --- a/projects/social_platform/src/app/ui/pages/projects/bar-new/bar.component.scss +++ b/projects/social_platform/src/app/ui/pages/projects/bar-new/bar.component.scss @@ -1,7 +1,66 @@ /** @format */ -:host { - display: block; - min-width: 0; - max-width: 100%; +@use "styles/responsive"; + +@media screen and (max-width: 999px) { + :host { + display: block; + min-width: 0; + max-width: 100%; + } +} + +@media screen and (min-width: 1000px) { + .bar { + display: block; + background-color: var(--medium-grey-for-outline); + border-radius: var(--rounded-xl); + + &__nav { + display: flex; + align-items: center; + } + + &__tabs { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + padding: 2px; + } + + &__item { + display: flex; + gap: 4px; + align-items: center; + padding: 5px 30px; + color: var(--grey-for-text); + cursor: pointer; + border-radius: var(--rounded-xl); + transition: color 0.2s; + + &:hover { + i { + color: var(--accent); + } + } + } + + &__link { + color: var(--black); + + &--active { + .bar__item { + background-color: var(--light-white); + border: 0.5px solid var(--dark-grey); + } + } + + &:hover { + .bar__item { + background-color: var(--white); + } + } + } + } } diff --git a/projects/social_platform/src/app/ui/pages/projects/bar-new/bar.component.ts b/projects/social_platform/src/app/ui/pages/projects/bar-new/bar.component.ts index 3c89bfda7..dc1c91175 100644 --- a/projects/social_platform/src/app/ui/pages/projects/bar-new/bar.component.ts +++ b/projects/social_platform/src/app/ui/pages/projects/bar-new/bar.component.ts @@ -1,6 +1,9 @@ /** @format */ -import { ChangeDetectionStrategy, Component, input, Input } from "@angular/core"; +import { DesktopLayoutService } from "@uilib"; +/** @format */ + +import { inject, ChangeDetectionStrategy, Component, input, Input } from "@angular/core"; import { CommonModule } from "@angular/common"; import { RouterLink, RouterLinkActive } from "@angular/router"; import { IconComponent, TabsComponent } from "@uilib"; @@ -14,6 +17,8 @@ import { IconComponent, TabsComponent } from "@uilib"; changeDetection: ChangeDetectionStrategy.OnPush, }) export class BarNewComponent { + protected readonly desktopLayout = inject(DesktopLayoutService).desktop; + /** Массив навигационных ссылок */ readonly links = input.required< { diff --git a/projects/social_platform/src/app/ui/pages/projects/dashboard/dashboardItem/dashboardItem.component.scss b/projects/social_platform/src/app/ui/pages/projects/dashboard/dashboardItem/dashboardItem.component.scss index 7ccc0f217..dc829ac00 100644 --- a/projects/social_platform/src/app/ui/pages/projects/dashboard/dashboardItem/dashboardItem.component.scss +++ b/projects/social_platform/src/app/ui/pages/projects/dashboard/dashboardItem/dashboardItem.component.scss @@ -48,10 +48,9 @@ } } -@include responsive.apply-mobile { +@include responsive.apply-below-desktop { .dashboard__list { - @include responsive.single-column; - + grid-template-columns: repeat(auto-fill, minmax(0, var(--ui-mobile-entity-card-width))); row-gap: 48px; } diff --git a/projects/social_platform/src/app/ui/pages/projects/detail/info/components/projects-left-side/projects-left-side.component.scss b/projects/social_platform/src/app/ui/pages/projects/detail/info/components/projects-left-side/projects-left-side.component.scss index a8f20c411..6d7e055cc 100644 --- a/projects/social_platform/src/app/ui/pages/projects/detail/info/components/projects-left-side/projects-left-side.component.scss +++ b/projects/social_platform/src/app/ui/pages/projects/detail/info/components/projects-left-side/projects-left-side.component.scss @@ -1,3 +1,7 @@ +/** @format */ + +@use "styles/responsive"; + @mixin expandable-list { &__remaining { display: grid; @@ -68,7 +72,6 @@ align-items: flex-start; min-width: 0; - // Длинное имя программы использует всю ширину существующего metadata блока. &--program { display: grid; grid-template-columns: 22px minmax(0, 1fr); @@ -141,3 +144,23 @@ @include expandable-list; } + +@media screen and (max-width: 999px) { + @include responsive.apply-below-desktop { + .project__left { + width: 100%; + } + + .project__section { + padding: 16px; + } + + .lists__list { + gap: 16px; + } + + .lists__item { + gap: 12px; + } + } +} diff --git a/projects/social_platform/src/app/ui/pages/projects/detail/news-detail/news-detail.component.scss b/projects/social_platform/src/app/ui/pages/projects/detail/news-detail/news-detail.component.scss index 0219fccd0..3195861cc 100644 --- a/projects/social_platform/src/app/ui/pages/projects/detail/news-detail/news-detail.component.scss +++ b/projects/social_platform/src/app/ui/pages/projects/detail/news-detail/news-detail.component.scss @@ -6,7 +6,6 @@ display: block; @include responsive.apply-desktop { - width: 100%; - min-width: 0; + min-width: 800px; } } diff --git a/projects/social_platform/src/app/ui/pages/projects/detail/team/team.component.scss b/projects/social_platform/src/app/ui/pages/projects/detail/team/team.component.scss index 75fd64eee..c9b55a441 100644 --- a/projects/social_platform/src/app/ui/pages/projects/detail/team/team.component.scss +++ b/projects/social_platform/src/app/ui/pages/projects/detail/team/team.component.scss @@ -5,17 +5,27 @@ .project { &__team { display: grid; - grid-template-columns: repeat(auto-fit, minmax(min(100%, 156px), 1fr)); - grid-gap: 20px; align-items: center; margin-top: 30px; + + @media screen and (max-width: 999px) { + grid-template-columns: repeat(auto-fit, minmax(min(100%, 156px), 1fr)); + grid-gap: 20px; + } + + @media screen and (min-width: 1000px) { + grid-template-columns: repeat(5, 1fr); + grid-gap: 20px; + } } } -@include responsive.apply-mobile { - .project__team { - @include responsive.single-column; +@media screen and (max-width: 999px) { + @include responsive.apply-mobile { + .project__team { + @include responsive.single-column; - row-gap: 48px; + row-gap: 48px; + } } } diff --git a/projects/social_platform/src/app/ui/pages/projects/detail/work-section/work-section.component.scss b/projects/social_platform/src/app/ui/pages/projects/detail/work-section/work-section.component.scss index 47675d170..129459f98 100644 --- a/projects/social_platform/src/app/ui/pages/projects/detail/work-section/work-section.component.scss +++ b/projects/social_platform/src/app/ui/pages/projects/detail/work-section/work-section.component.scss @@ -39,12 +39,14 @@ } } -@include responsive.apply-below-desktop { - .work-section { - @include responsive.single-column; - } - - .work-section__section { - padding: 16px; +@media screen and (max-width: 999px) { + @include responsive.apply-below-desktop { + .work-section { + @include responsive.single-column; + } + + .work-section__section { + padding: 16px; + } } } diff --git a/projects/social_platform/src/app/ui/pages/projects/edit/components/project-achievement-step/project-achievement-step.component.scss b/projects/social_platform/src/app/ui/pages/projects/edit/components/project-achievement-step/project-achievement-step.component.scss index 86075f6a1..520d4d254 100644 --- a/projects/social_platform/src/app/ui/pages/projects/edit/components/project-achievement-step/project-achievement-step.component.scss +++ b/projects/social_platform/src/app/ui/pages/projects/edit/components/project-achievement-step/project-achievement-step.component.scss @@ -56,8 +56,16 @@ } &__list { - width: 100%; margin-top: 10px; + + @media screen and (max-width: 999px) { + width: 100%; + } + + @media screen and (min-width: 1000px) { + width: 557px; + width: 100%; + } } } diff --git a/projects/social_platform/src/app/ui/pages/projects/edit/components/project-additional-step/project-additional-step.component.scss b/projects/social_platform/src/app/ui/pages/projects/edit/components/project-additional-step/project-additional-step.component.scss index 1bd624765..fd0e4d5ca 100644 --- a/projects/social_platform/src/app/ui/pages/projects/edit/components/project-additional-step/project-additional-step.component.scss +++ b/projects/social_platform/src/app/ui/pages/projects/edit/components/project-additional-step/project-additional-step.component.scss @@ -166,8 +166,16 @@ } &__list { - width: 100%; margin-top: 10px; + + @media screen and (max-width: 999px) { + width: 100%; + } + + @media screen and (min-width: 1000px) { + width: 557px; + width: 100%; + } } } diff --git a/projects/social_platform/src/app/ui/pages/projects/edit/components/project-main-step/project-main-step.component.scss b/projects/social_platform/src/app/ui/pages/projects/edit/components/project-main-step/project-main-step.component.scss index 15b291323..6627519ac 100644 --- a/projects/social_platform/src/app/ui/pages/projects/edit/components/project-main-step/project-main-step.component.scss +++ b/projects/social_platform/src/app/ui/pages/projects/edit/components/project-main-step/project-main-step.component.scss @@ -203,13 +203,21 @@ flex-direction: column; align-items: center; justify-content: center; - width: 100%; - min-width: 0; max-width: 100%; max-height: calc(100vh - 40px); - padding: 0; overflow-y: auto; + @media screen and (max-width: 999px) { + width: 100%; + min-width: 0; + padding: 0; + } + + @media screen and (min-width: 1000px) { + width: 700px; + padding: 40px 0 80px; + } + &__cross { position: absolute; top: 0; @@ -271,20 +279,22 @@ } } -@include responsive.apply-mobile { - .project__grid, - .project__info--additional { - @include responsive.single-column; - } +@media screen and (max-width: 999px) { + @include responsive.apply-mobile { + .project__grid, + .project__info--additional { + @include responsive.single-column; + } - .invite__item { - flex-wrap: wrap; - gap: 12px; - width: 100%; - min-width: 0; - } + .invite__item { + flex-wrap: wrap; + gap: 12px; + width: 100%; + min-width: 0; + } - .invite__item--info { - min-width: 0; + .invite__item--info { + min-width: 0; + } } } diff --git a/projects/social_platform/src/app/ui/pages/projects/edit/components/project-navigation/project-navigation.component.html b/projects/social_platform/src/app/ui/pages/projects/edit/components/project-navigation/project-navigation.component.html index 03bd430e7..713ab43d6 100644 --- a/projects/social_platform/src/app/ui/pages/projects/edit/components/project-navigation/project-navigation.component.html +++ b/projects/social_platform/src/app/ui/pages/projects/edit/components/project-navigation/project-navigation.component.html @@ -1,8 +1,37 @@ - +@if (desktopLayout()) { + +} @else { + +} diff --git a/projects/social_platform/src/app/ui/pages/projects/edit/components/project-navigation/project-navigation.component.scss b/projects/social_platform/src/app/ui/pages/projects/edit/components/project-navigation/project-navigation.component.scss index f11ac252e..182d419dd 100644 --- a/projects/social_platform/src/app/ui/pages/projects/edit/components/project-navigation/project-navigation.component.scss +++ b/projects/social_platform/src/app/ui/pages/projects/edit/components/project-navigation/project-navigation.component.scss @@ -1,10 +1,94 @@ /** @format */ -:host { - display: block; - min-width: 0; - max-width: 100%; - padding-block: var(--ui-space-md); - margin-bottom: var(--ui-space-md); - border-bottom: 1px solid var(--ui-border-subtle); +@use "styles/responsive"; +@use "styles/typography"; + +@media screen and (max-width: 999px) { + :host { + display: block; + min-width: 0; + max-width: 100%; + padding-block: var(--ui-space-md); + margin-bottom: var(--ui-space-md); + border-bottom: 1px solid var(--ui-border-subtle); + } +} + +@media screen and (min-width: 1000px) { + .project { + &__navigation { + padding: 22px 0; + margin-bottom: 22px; + border-bottom: 1px solid var(--grey-button); + } + + &__nav { + display: flex; + flex-wrap: wrap; + gap: 10px; + align-items: center; + justify-content: center; + padding: 2px 10px; + background-color: var(--medium-grey-for-outline); + border-radius: var(--rounded-xxl); + + @include responsive.apply-desktop { + gap: 0; + justify-content: space-between; + } + } + + &__item { + display: flex; + gap: 5px; + align-items: center; + cursor: pointer; + + &--active { + padding: 0 8px; + margin-right: -8px; + margin-left: -8px; + background-color: var(--white); + border-radius: var(--rounded-xxl); + } + } + + &__subtitle { + color: var(--dark-grey); + + @include typography.body-12; + + &--active { + color: var(--black); + } + } + + &__icon { + opacity: 0.1; + + &--active { + color: var(--accent); + opacity: 1; + } + } + + &__nav-item { + color: var(--dark-grey); + cursor: pointer; + + @include typography.heading-4; + + @include responsive.apply-desktop { + @include typography.heading-3; + } + + &:not(:last-child) { + margin-right: 24px; + } + + &--active { + color: var(--black); + } + } + } } diff --git a/projects/social_platform/src/app/ui/pages/projects/edit/components/project-navigation/project-navigation.component.ts b/projects/social_platform/src/app/ui/pages/projects/edit/components/project-navigation/project-navigation.component.ts index b77683c0f..bbe01bc1c 100644 --- a/projects/social_platform/src/app/ui/pages/projects/edit/components/project-navigation/project-navigation.component.ts +++ b/projects/social_platform/src/app/ui/pages/projects/edit/components/project-navigation/project-navigation.component.ts @@ -12,7 +12,7 @@ import { output, } from "@angular/core"; import { ProjectStepService } from "@api/project/project-step.service"; -import { IconComponent, TabsComponent } from "@uilib"; +import { DesktopLayoutService, IconComponent, TabsComponent } from "@uilib"; import { CommonModule } from "@angular/common"; import { Navigation } from "@core/lib/models/navigation.model"; import { EditStep } from "@core/lib/models/edit-step"; @@ -26,6 +26,7 @@ import { EditStep } from "@core/lib/models/edit-step"; changeDetection: ChangeDetectionStrategy.OnPush, }) export class ProjectNavigationComponent { + protected readonly desktopLayout = inject(DesktopLayoutService).desktop; readonly navItems = input.required(); readonly stepChange = output(); protected readonly tabs = computed(() => diff --git a/projects/social_platform/src/app/ui/pages/projects/edit/components/project-team-step/project-team-step.component.scss b/projects/social_platform/src/app/ui/pages/projects/edit/components/project-team-step/project-team-step.component.scss index c4dffdf56..92bd6bb77 100644 --- a/projects/social_platform/src/app/ui/pages/projects/edit/components/project-team-step/project-team-step.component.scss +++ b/projects/social_platform/src/app/ui/pages/projects/edit/components/project-team-step/project-team-step.component.scss @@ -55,6 +55,12 @@ } ::ng-deep .invite__submit button { + @media screen and (min-width: 1000px) { + min-height: 25px; + padding: 4px 12px; + line-height: 16px; + } + &:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; @@ -139,6 +145,11 @@ } .team ::ng-deep .invite__submit button { + @media screen and (min-width: 1000px) { + min-height: 44px; + max-height: none; + } + i { position: absolute; left: 12px; diff --git a/projects/social_platform/src/app/ui/pages/projects/edit/components/project-vacancy-step/project-vacancy-step.component.scss b/projects/social_platform/src/app/ui/pages/projects/edit/components/project-vacancy-step/project-vacancy-step.component.scss index 83d16bdc2..2b2a5f909 100644 --- a/projects/social_platform/src/app/ui/pages/projects/edit/components/project-vacancy-step/project-vacancy-step.component.scss +++ b/projects/social_platform/src/app/ui/pages/projects/edit/components/project-vacancy-step/project-vacancy-step.component.scss @@ -114,9 +114,16 @@ &__error { margin-top: 12px; - font-size: var(--ui-font-body); line-height: 20px; color: var(--black); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-body); + } + + @media screen and (min-width: 1000px) { + font-size: 13px; + } } &__city { diff --git a/projects/social_platform/src/app/ui/pages/projects/edit/edit.component.html b/projects/social_platform/src/app/ui/pages/projects/edit/edit.component.html index f544b22d8..86056f6a0 100644 --- a/projects/social_platform/src/app/ui/pages/projects/edit/edit.component.html +++ b/projects/social_platform/src/app/ui/pages/projects/edit/edit.component.html @@ -146,7 +146,7 @@

📢 внимание!

[open]="isSendDescisionLate()" (openChange)="isSendDescisionLate.set(!isSendDescisionLate())" > -
+

Подача проектов завершена!

@@ -159,7 +159,7 @@

📢 внимание!

@defer (when fromProgramOpen()) { -
+

Начнем создавать историю!

diff --git a/projects/social_platform/src/app/ui/pages/projects/edit/edit.component.scss b/projects/social_platform/src/app/ui/pages/projects/edit/edit.component.scss index 0f1db861c..2dd6d64f4 100644 --- a/projects/social_platform/src/app/ui/pages/projects/edit/edit.component.scss +++ b/projects/social_platform/src/app/ui/pages/projects/edit/edit.component.scss @@ -144,6 +144,12 @@ } .cancel { + @media screen and (min-width: 1000px) { + &.cancel--fixed-width { + width: 605px; + } + } + display: flex; flex-direction: column; align-items: center; diff --git a/projects/social_platform/src/app/ui/pages/projects/list/list.component.scss b/projects/social_platform/src/app/ui/pages/projects/list/list.component.scss index 88722d855..5ab519922 100644 --- a/projects/social_platform/src/app/ui/pages/projects/list/list.component.scss +++ b/projects/social_platform/src/app/ui/pages/projects/list/list.component.scss @@ -176,10 +176,9 @@ } } -@include responsive.apply-mobile { +@include responsive.apply-below-desktop { .page__list { - @include responsive.single-column; - + grid-template-columns: repeat(auto-fill, minmax(0, var(--ui-mobile-entity-card-width))); row-gap: 48px; } diff --git a/projects/social_platform/src/app/ui/pages/projects/project-activity-card/project-activity-card.component.scss b/projects/social_platform/src/app/ui/pages/projects/project-activity-card/project-activity-card.component.scss index 1c3e7c1c7..2c03035ef 100644 --- a/projects/social_platform/src/app/ui/pages/projects/project-activity-card/project-activity-card.component.scss +++ b/projects/social_platform/src/app/ui/pages/projects/project-activity-card/project-activity-card.component.scss @@ -1,5 +1,7 @@ /** @format */ +@use "styles/responsive"; + :host { display: block; width: 156px; @@ -48,10 +50,18 @@ gap: 4px; align-items: center; min-width: 0; - font-size: var(--ui-font-caption); - font-weight: 400; line-height: 14px; color: var(--black); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + font-weight: 400; + } + + @media screen and (min-width: 1000px) { + font-size: 11px; + font-weight: 400; + } } &__icon { @@ -67,8 +77,6 @@ &__value { flex: 0 0 auto; - - /* Очень большие числа не вытесняют подпись; полное значение остаётся в DOM и title. */ max-width: 45px; margin: 0 0 0 4px; overflow: hidden; @@ -82,3 +90,30 @@ white-space: nowrap; } } + +@media screen and (max-width: 999px) { + @include responsive.apply-below-desktop { + :host { + width: 100%; + height: auto; + } + + .activity { + padding: 16px; + } + + .activity__title { + color: var(--ui-text); + } + + .activity__metrics { + grid-template-rows: auto; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 12px 16px; + } + + .activity__metric + .activity__metric { + border-top: 0; + } + } +} diff --git a/projects/social_platform/src/app/ui/pages/projects/projects-activity-placement.spec.ts b/projects/social_platform/src/app/ui/pages/projects/projects-activity-placement.spec.ts index a2ede1797..eb7c116ea 100644 --- a/projects/social_platform/src/app/ui/pages/projects/projects-activity-placement.spec.ts +++ b/projects/social_platform/src/app/ui/pages/projects/projects-activity-placement.spec.ts @@ -2,6 +2,14 @@ import { readFileSync } from "node:fs"; import { join } from "node:path"; +import { + parseTemplate, + TmplAstElement, + TmplAstForLoopBlock, + TmplAstIfBlock, + TmplAstNode, + TmplAstTemplate, +} from "@angular/compiler"; describe("ProjectsComponent: размещение проектной активности", () => { const template = readFileSync( @@ -12,17 +20,35 @@ describe("ProjectsComponent: размещение проектной актив "utf8", ); + const activityConditions: string[][] = []; + const walk = (nodes: TmplAstNode[], conditions: string[] = []) => { + for (const node of nodes) { + if (node instanceof TmplAstIfBlock) { + for (const branch of node.branches) { + walk(branch.children, [...conditions, branch.expression?.source || "else"]); + } + } else if (node instanceof TmplAstElement || node instanceof TmplAstTemplate) { + if (node instanceof TmplAstElement && node.name === "app-project-activity-card") { + activityConditions.push(conditions); + } + walk(node.children, conditions); + } else if (node instanceof TmplAstForLoopBlock) { + walk(node.children, conditions); + } + } + }; + walk(parseTemplate(template, "projects.component.html").nodes); + it("показывает блок только для dashboard и my", () => { - expect(template).toMatch( - /@if \(isMy\(\) \|\| isDashboard\(\)\) \{\s* { - const conditionalBlock = new RegExp( - `@if \\(${condition.replace(/[()]/g, "\\$&")}\\) \\{[\\s\\S]*?
- - создать проект - + @if (desktopLayout()) { + + } @else { + + создать проект + + }
@@ -60,6 +67,17 @@
+ @if (desktopLayout()) { + + создать проект + + + }
@if (isDashboard()) {
@@ -80,7 +98,13 @@ } } @else { - + @if (desktopLayout()) { +
+

пока нет приглашений

+
+ } @else { + + } }
} diff --git a/projects/social_platform/src/app/ui/pages/projects/projects.component.scss b/projects/social_platform/src/app/ui/pages/projects/projects.component.scss index 3bb497f99..48f5563df 100644 --- a/projects/social_platform/src/app/ui/pages/projects/projects.component.scss +++ b/projects/social_platform/src/app/ui/pages/projects/projects.component.scss @@ -1,3 +1,5 @@ +/** @format */ + @use "styles/responsive"; .page { @@ -32,11 +34,6 @@ display: flex; flex-direction: column; align-items: center; - - @include responsive.apply-desktop { - flex: 0 0 var(--ui-compact-sidebar-width); - width: var(--ui-compact-sidebar-width); - } } &__left { @@ -85,5 +82,42 @@ } .bar__add-project { - margin-bottom: 0; + @media screen and (max-width: 999px) { + margin-bottom: 0; + } + + @media screen and (min-width: 1000px) { + margin-bottom: 15px; + } +} + +@media screen and (max-width: 999px) { + @include responsive.apply-below-desktop { + .page { + margin: 24px var(--page-gutter) 0; + } + + .page__info { + gap: 24px; + padding-bottom: 32px; + } + + .page__outlet { + order: 2; + } + + .page__create, + .page__left { + display: contents; + } + + .page__left > app-project-activity-card { + order: 1; + } + + .page__invites { + order: 3; + margin-top: 16px; + } + } } diff --git a/projects/social_platform/src/app/ui/pages/projects/projects.component.ts b/projects/social_platform/src/app/ui/pages/projects/projects.component.ts index fb05448a0..b04dddb2f 100644 --- a/projects/social_platform/src/app/ui/pages/projects/projects.component.ts +++ b/projects/social_platform/src/app/ui/pages/projects/projects.component.ts @@ -1,5 +1,8 @@ /** @format */ +import { DesktopLayoutService } from "@uilib"; +/** @format */ + import { ChangeDetectionStrategy, Component, @@ -48,6 +51,8 @@ import { ProjectActivityCardComponent } from "./project-activity-card/project-ac changeDetection: ChangeDetectionStrategy.OnPush, }) export class ProjectsComponent implements OnInit { + protected readonly desktopLayout = inject(DesktopLayoutService).desktop; + readonly filterBody = viewChild>("filterBody"); private readonly projectsInfoService = inject(ProjectsInfoService); diff --git a/projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-right-side/vacancies-right-side.component.scss b/projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-right-side/vacancies-right-side.component.scss index 03e6e05c6..ec8524c92 100644 --- a/projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-right-side/vacancies-right-side.component.scss +++ b/projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancies-right-side/vacancies-right-side.component.scss @@ -62,7 +62,14 @@ } a { - font-size: var(--ui-font-body); + @media screen and (max-width: 999px) { + font-size: var(--ui-font-body); + } + + @media screen and (min-width: 1000px) { + font-size: 13px; + } + line-height: 20px; @include vacancy-ui.link; diff --git a/projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancy-responses/vacancy-responses.component.scss b/projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancy-responses/vacancy-responses.component.scss index e2064dedb..1e83f4ce9 100644 --- a/projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancy-responses/vacancy-responses.component.scss +++ b/projects/social_platform/src/app/ui/pages/vacancies/detail/info/components/vacancy-responses/vacancy-responses.component.scss @@ -132,18 +132,33 @@ &__label { margin-bottom: 8px; - font-size: var(--ui-font-body); - font-weight: 600; line-height: 20px; color: var(--accent-dark); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-body); + font-weight: 600; + } + + @media screen and (min-width: 1000px) { + font-size: 13px; + font-weight: 600; + } } &__file-row { display: flex; flex-wrap: wrap; gap: 6px 10px; - font-size: var(--ui-font-body); line-height: 20px; + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-body); + } + + @media screen and (min-width: 1000px) { + font-size: 13px; + } } &__file { diff --git a/projects/social_platform/src/app/ui/pages/vacancies/detail/vacancies-detail.component.scss b/projects/social_platform/src/app/ui/pages/vacancies/detail/vacancies-detail.component.scss index 7ddd5f975..ffc9cb05f 100644 --- a/projects/social_platform/src/app/ui/pages/vacancies/detail/vacancies-detail.component.scss +++ b/projects/social_platform/src/app/ui/pages/vacancies/detail/vacancies-detail.component.scss @@ -60,7 +60,15 @@ &__specialization { margin-top: 12px; - font-size: var(--ui-font-body); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-body); + } + + @media screen and (min-width: 1000px) { + font-size: 13px; + } + line-height: 20px; @include vacancy-ui.secondary; diff --git a/projects/social_platform/src/app/ui/pages/vacancies/list/list.component.html b/projects/social_platform/src/app/ui/pages/vacancies/list/list.component.html index 4dd2495fd..2eb39c448 100644 --- a/projects/social_platform/src/app/ui/pages/vacancies/list/list.component.html +++ b/projects/social_platform/src/app/ui/pages/vacancies/list/list.component.html @@ -12,28 +12,49 @@ }
@if (hasNoResults()) { - - Сбросить фильтры +

Вакансии не найдены

+

Попробуйте изменить запрос или сбросить фильтры.

+ Сбросить фильтры + + } @else { + - + Сбросить фильтры +
+ } } } @if (type() === "my") { @for (response of responsesList(); track response.id) { } @empty { - - Перейти к вакансиям + +

У вас пока нет откликов

+

Найдите подходящую вакансию и расскажите проекту о себе.

+ Перейти к вакансиям + + } @else { + - + Перейти к вакансиям +
+ } } }
diff --git a/projects/social_platform/src/app/ui/pages/vacancies/list/list.component.ts b/projects/social_platform/src/app/ui/pages/vacancies/list/list.component.ts index c7a3b94af..e46219a3d 100644 --- a/projects/social_platform/src/app/ui/pages/vacancies/list/list.component.ts +++ b/projects/social_platform/src/app/ui/pages/vacancies/list/list.component.ts @@ -1,6 +1,6 @@ /** @format */ -import { StateComponent } from "@uilib"; +import { DesktopLayoutService, StateComponent } from "@uilib"; /** @format */ // list.component.ts @@ -35,6 +35,7 @@ import { AppRoutes } from "@api/paths/app-routes"; providers: [VacancyInfoService, VacancyUIInfoService], }) export class VacanciesListComponent { + protected readonly desktopLayout = inject(DesktopLayoutService).desktop; private readonly vacancyInfoService = inject(VacancyInfoService); private readonly vacancyUIInfoService = inject(VacancyUIInfoService); diff --git a/projects/social_platform/src/app/ui/pages/vacancies/list/response-card/response-card.component.scss b/projects/social_platform/src/app/ui/pages/vacancies/list/response-card/response-card.component.scss index 44ad04fa5..479244524 100644 --- a/projects/social_platform/src/app/ui/pages/vacancies/list/response-card/response-card.component.scss +++ b/projects/social_platform/src/app/ui/pages/vacancies/list/response-card/response-card.component.scss @@ -42,7 +42,14 @@ } &__project { - font-size: var(--ui-font-body); + @media screen and (max-width: 999px) { + font-size: var(--ui-font-body); + } + + @media screen and (min-width: 1000px) { + font-size: 13px; + } + line-height: 20px; @include vacancy-ui.link; @@ -63,10 +70,18 @@ h3 { margin-bottom: 10px; - font-size: var(--ui-font-body); - font-weight: 600; line-height: 20px; color: var(--accent-dark); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-body); + font-weight: 600; + } + + @media screen and (min-width: 1000px) { + font-size: 13px; + font-weight: 600; + } } } @@ -76,10 +91,17 @@ gap: 6px 12px; padding-top: 16px; margin-top: 16px; - font-size: var(--ui-font-body); line-height: 20px; border-top: 1px solid var(--medium-grey-for-outline); + @media screen and (max-width: 999px) { + font-size: var(--ui-font-body); + } + + @media screen and (min-width: 1000px) { + font-size: 13px; + } + span { @include vacancy-ui.secondary; } diff --git a/projects/social_platform/src/app/ui/primitives/autocomplete-input/autocomplete-input.component.scss b/projects/social_platform/src/app/ui/primitives/autocomplete-input/autocomplete-input.component.scss index 158add79f..7e14134a4 100644 --- a/projects/social_platform/src/app/ui/primitives/autocomplete-input/autocomplete-input.component.scss +++ b/projects/social_platform/src/app/ui/primitives/autocomplete-input/autocomplete-input.component.scss @@ -1,217 +1,367 @@ /** @format */ @use "styles/ui-foundation"; - -/** @format */ - @use "styles/responsive"; @use "styles/typography"; -.field { - position: relative; - width: 100%; - - &__input-wrapper { - z-index: 3; - width: 100%; - overflow: hidden; - } - - &__input { +@media screen and (max-width: 999px) { + .field { + position: relative; width: 100%; - padding: 12px; - &::placeholder { - color: var(--dark-grey); + &__input-wrapper { + z-index: 3; + width: 100%; + overflow: hidden; } - &--error { - border-color: var(--red); + &__input { + width: 100%; + padding: 12px; + + &::placeholder { + color: var(--dark-grey); + } + + &--error { + border-color: var(--red); + } + + &:focus { + border-color: var(--accent); + box-shadow: var(--ui-focus-ring); + } + + &--no-icon { + padding-right: 45px; + } + + @include ui-foundation.control; } - &:focus { - border-color: var(--accent); - box-shadow: var(--ui-focus-ring); + &__input-slim { + width: 100%; + padding: 6px 30px 6px 10px; + font-size: var(--ui-font-small); + background: transparent; + border: none; + border-bottom: 1px solid var(--grey-button); + outline: none; + + &:focus { + border-color: var(--accent); + + + &_arrow { + color: var(--accent); + + i { + transform: rotate(0); + } + } + } + + @include ui-foundation.control; } - &--no-icon { - padding-right: 45px; + &__dropdown { + position: relative; + right: 0; + left: 0; + z-index: 4; + background-color: transparent; + box-shadow: 5px 5px 25px 0 var(--gray); + transform-origin: center top; + + &--options, + &--no-results { + max-height: 300px; + max-height: min(300px, calc(var(--visual-viewport-height, 100dvh) - 24px)); + padding: 10px; + overflow-y: auto; + overscroll-behavior: contain; + background-color: var(--white); + scrollbar-width: thin; + } } - @include ui-foundation.control; - } + &__option { + padding: 7px; + color: var(--dark-grey); + cursor: pointer; + border-radius: var(--rounded-lg); + transition: background-color 0.2s; - &__input-slim { - width: 100%; - padding: 6px 30px 6px 10px; - font-size: var(--ui-font-small); - background: transparent; - border: none; - border-bottom: 1px solid var(--grey-button); - outline: none; + &:hover { + background-color: var(--light-gray); + } - &:focus { - border-color: var(--accent); + @include typography.body-12; + + &-slim { + padding: 3px; + } + } - + &_arrow { - color: var(--accent); + &__chip { + position: absolute; + top: 50%; + left: 10px; + z-index: 4; + display: flex; + align-items: center; + justify-content: center; + max-width: 100%; + padding: 5px 10px; + color: var(--white); + background-color: var(--accent); + border-radius: var(--rounded-md); + transform: translateY(-50%); + + span { + display: inline-block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } - i { - transform: rotate(0); - } + i { + flex-shrink: 0; + margin-left: 10px; + cursor: pointer; } } - @include ui-foundation.control; - } + &__icons { + position: absolute; + top: 50%; + right: 15px; + z-index: 2; + display: flex; + align-items: center; + cursor: pointer; + opacity: 1; + transform: translateY(-50%); - &__dropdown { - position: relative; - right: 0; - left: 0; - z-index: 4; - background-color: transparent; - box-shadow: 5px 5px 25px 0 var(--gray); - transform-origin: center top; - - &--options, - &--no-results { - max-height: 300px; - max-height: min(300px, calc(var(--visual-viewport-height, 100dvh) - 24px)); - padding: 10px; - overflow-y: auto; - overscroll-behavior: contain; - background-color: var(--white); - scrollbar-width: thin; + &:hover { + opacity: 0.6; + } + } + + &__loading-icon { + margin-right: 5px; } } - &__option { - padding: 7px; - color: var(--dark-grey); - cursor: pointer; - border-radius: var(--rounded-lg); - transition: background-color 0.2s; + :host { + display: block; + min-width: 0; + max-width: 100%; + } + + .field, + .search, + .search__input { + min-width: 0; + max-width: 100%; + } + + @include responsive.apply-mobile { + .field__input, + .field__input-slim, + .search__input input { + min-width: 0; + max-width: 100%; + min-height: 44px; + font-size: var(--ui-font-h3); + } - &:hover { - background-color: var(--light-gray); + .field--small, + .field__input--small { + min-width: 0; } - @include typography.body-12; + .field__input--with-tooltip { + padding-right: 44px; + } - &-slim { - padding: 3px; + .field__option { + min-height: 44px; + overflow-wrap: anywhere; } - } - &__chip { - position: absolute; - top: 50%; - left: 10px; - z-index: 4; - display: flex; - align-items: center; - justify-content: center; - max-width: 100%; - padding: 5px 10px; - color: var(--white); - background-color: var(--accent); - border-radius: var(--rounded-md); - transform: translateY(-50%); - - span { - display: inline-block; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; + .field__chip { + max-width: calc(100% - 44px); } - i { - flex-shrink: 0; - margin-left: 10px; - cursor: pointer; + .field__chip span { + overflow-wrap: anywhere; + white-space: normal; } - } - &__icons { - position: absolute; - top: 50%; - right: 15px; - z-index: 2; - display: flex; - align-items: center; - cursor: pointer; - opacity: 1; - transform: translateY(-50%); + .field__calendar-button { + right: 4px; + width: 44px; + height: 44px; + } - &:hover { - opacity: 0.6; + .field__input[type="date"] { + padding-right: 48px; } } - &__loading-icon { - margin-right: 5px; + .field__input, + .field__input-slim { + padding-right: 44px; } } -:host { - display: block; - min-width: 0; - max-width: 100%; -} +@media screen and (min-width: 1000px) { + .field { + position: relative; + width: 100%; -.field, -.search, -.search__input { - min-width: 0; - max-width: 100%; -} + &__input-wrapper { + z-index: 3; + width: 100%; + overflow: hidden; + } -@include responsive.apply-mobile { - .field__input, - .field__input-slim, - .search__input input { - min-width: 0; - max-width: 100%; - min-height: 44px; - font-size: var(--ui-font-h3); - } + &__input { + width: 100%; + padding: 12px; + color: var(--black); + background-color: var(--white); + border: 0.5px solid var(--gray); + border-radius: var(--rounded-xxl); + outline: none; + transition: all 0.2s; - .field--small, - .field__input--small { - min-width: 0; - } + &::placeholder { + color: var(--dark-grey); + } - .field__input--with-tooltip { - padding-right: 44px; - } + &--error { + border-color: var(--red); + } - .field__option { - min-height: 44px; - overflow-wrap: anywhere; - } + &:focus { + border-color: var(--accent); + box-shadow: 0 0 6px rgb(109 40 255 / 30%); + } - .field__chip { - max-width: calc(100% - 44px); - } + &--no-icon { + padding-right: 45px; + } - .field__chip span { - overflow-wrap: anywhere; - white-space: normal; - } + @include typography.body-12; + } - .field__calendar-button { - right: 4px; - width: 44px; - height: 44px; - } + &__input-slim { + width: 100%; + padding: 6px 30px 6px 10px; + font-size: 12px; + background: transparent; + border: none; + border-bottom: 1px solid var(--grey-button); + outline: none; - .field__input[type="date"] { - padding-right: 48px; - } -} + &:focus { + border-color: var(--accent); -.field__input, -.field__input-slim { - padding-right: 44px; + +&_arrow { + color: var(--accent); + + i { + transform: rotate(0); + } + } + } + } + + &__dropdown { + position: absolute; + right: 0; + left: 0; + z-index: 4; + background-color: transparent; + box-shadow: 5px 5px 25px 0 var(--gray); + transform-origin: center top; + + &--options, + &--no-results { + scrollbar-width: thin; + max-height: 300px; + padding: 10px; + overflow-y: auto; + background-color: var(--white); + } + } + + &__option { + padding: 7px; + color: var(--dark-grey); + cursor: pointer; + border-radius: var(--rounded-lg); + transition: background-color 0.2s; + + &:hover { + background-color: var(--light-gray); + } + + @include typography.body-12; + + &-slim { + padding: 3px; + } + } + + &__chip { + position: absolute; + top: 50%; + left: 10px; + z-index: 4; + display: flex; + align-items: center; + justify-content: center; + max-width: 100%; + padding: 5px 10px; + color: var(--white); + background-color: var(--accent); + border-radius: var(--rounded-md); + transform: translateY(-50%); + + span { + display: inline-block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + i { + flex-shrink: 0; + margin-left: 10px; + cursor: pointer; + } + } + + &__icons { + position: absolute; + top: 50%; + right: 15px; + z-index: 2; + display: flex; + align-items: center; + cursor: pointer; + opacity: 1; + transform: translateY(-50%); + + &:hover { + opacity: 0.6; + } + } + + &__loading-icon { + margin-right: 5px; + } + } } diff --git a/projects/social_platform/src/app/ui/primitives/avatar/avatar.component.html b/projects/social_platform/src/app/ui/primitives/avatar/avatar.component.html new file mode 100644 index 000000000..803a1e35e --- /dev/null +++ b/projects/social_platform/src/app/ui/primitives/avatar/avatar.component.html @@ -0,0 +1,71 @@ + +@if (desktopLayout()) { +
+
+ @if (progress()) { +
+ } + + avatar + + @if (isOnline()) { +
+ } +
+
+} @else { +
+
+ @if (progress()) { +
+ } + + avatar + + @if (isOnline()) { +
+ } +
+
+} diff --git a/projects/social_platform/src/app/ui/primitives/avatar/avatar.component.scss b/projects/social_platform/src/app/ui/primitives/avatar/avatar.component.scss new file mode 100644 index 000000000..9e1c9b40a --- /dev/null +++ b/projects/social_platform/src/app/ui/primitives/avatar/avatar.component.scss @@ -0,0 +1,56 @@ +/** @format */ +@use "../../../../../../ui/src/lib/components/primitives/avatar/avatar.component.scss"; + +@media screen and (min-width: 1000px) { + .avatar { + position: relative; + + &__progress { + position: absolute; + top: 0; + left: 0; + z-index: 3; + width: 100%; + height: 100%; + background: + conic-gradient( + var(--progress-color) 0 var(--progress), + transparent var(--progress) 100% + ); + border-radius: 50%; + mask: + radial-gradient( + circle, + transparent calc(50% - var(--progress-width)), + white calc(50% - var(--progress-width)) + ); + } + + img { + position: relative; + z-index: 1; + border-radius: 50%; + object-fit: cover; + object-position: center; + } + + &__online { + position: absolute; + right: 0; + bottom: -1.5px; + z-index: 3; + width: 16px; + height: 16px; + background-color: var(--green); + border: 3px solid var(--white); + border-radius: 50%; + } + + &--border { + img { + border-style: solid; + border-width: 0.5px; + } + } + } +} diff --git a/projects/social_platform/src/app/ui/primitives/avatar/avatar.component.ts b/projects/social_platform/src/app/ui/primitives/avatar/avatar.component.ts index 1e644a4a2..d08067f51 100644 --- a/projects/social_platform/src/app/ui/primitives/avatar/avatar.component.ts +++ b/projects/social_platform/src/app/ui/primitives/avatar/avatar.component.ts @@ -1,7 +1,14 @@ -/** - * Compatibility export. Canonical implementation: @uilib. - * - * @format - */ +/** @format */ +import { ChangeDetectionStrategy, Component, inject } from "@angular/core"; +import { AvatarComponent as CanonicalAvatar, DesktopLayoutService } from "@uilib"; -export { AvatarComponent } from "@uilib"; +/** Legacy desktop presentation with the canonical avatar inputs and mobile view. */ +@Component({ + selector: "app-avatar", + templateUrl: "./avatar.component.html", + styleUrl: "./avatar.component.scss", + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class AvatarComponent extends CanonicalAvatar { + protected readonly desktopLayout = inject(DesktopLayoutService).desktop; +} diff --git a/projects/social_platform/src/app/ui/primitives/bar/bar.component.html b/projects/social_platform/src/app/ui/primitives/bar/bar.component.html index 122ca075e..4a722ae71 100644 --- a/projects/social_platform/src/app/ui/primitives/bar/bar.component.html +++ b/projects/social_platform/src/app/ui/primitives/bar/bar.component.html @@ -1,8 +1,46 @@ -
- @if (backHave()) { - - } - -
+@if (desktopLayout()) { +
+ +
+} @else { +
+ @if (backHave()) { + + } + +
+} + + diff --git a/projects/social_platform/src/app/ui/primitives/bar/bar.component.scss b/projects/social_platform/src/app/ui/primitives/bar/bar.component.scss index fb75299fb..0aac735eb 100644 --- a/projects/social_platform/src/app/ui/primitives/bar/bar.component.scss +++ b/projects/social_platform/src/app/ui/primitives/bar/bar.component.scss @@ -1,18 +1,123 @@ /** @format */ -:host { - display: block; - min-width: 0; - max-width: 100%; +@use "styles/responsive"; + +@media screen and (max-width: 999px) { + :host { + display: block; + min-width: 0; + max-width: 100%; + } } .bar { - display: flex; - gap: var(--ui-space-sm); - align-items: center; - min-width: 0; + @media screen and (max-width: 999px) { + display: flex; + gap: var(--ui-space-sm); + align-items: center; + min-width: 0; + } + + @media screen and (min-width: 1000px) { + display: block; + height: 63px !important; + margin-bottom: 15px; + overflow: hidden; + background-color: var(--white); + border: 1px solid var(--medium-grey-for-outline); + border-radius: var(--rounded-xl); + } + + @media screen and (min-width: 1000px) { + &__nav { + display: flex; + align-items: center; + height: 100%; + margin-right: 25px; + } + } + + @media screen and (min-width: 1000px) { + &__tabs { + display: flex; + + li { + text-align: center; + } + } + } + + @media screen and (min-width: 1000px) { + &__item { + display: flex; + align-items: center; + padding: 20px 10px; + color: var(--dark-grey); + cursor: pointer; + transition: color 0.2s; + + @include responsive.apply-desktop { + padding: 20px; + } + } + } + + @media screen and (min-width: 1000px) { + &__ball { + display: flex; + align-items: center; + justify-content: center; + min-width: 22px; + min-height: 22px; + padding: 1px 6px; + margin-left: 6px; + line-height: 1; + color: var(--white); + background-color: var(--gray); + border-radius: 7px; + transition: background-color 0.2s; + + &--small { + padding: 0; + border-radius: 100px; + } + } + } + + @media screen and (min-width: 1000px) { + &__link { + &--active { + .bar__item { + color: var(--black); + border-bottom: 2px solid var(--black); + } + + .bar__ball { + background-color: var(--accent); + } + } + + &:hover { + .bar__item { + color: var(--black); + } + + .bar__ball { + background-color: var(--accent); + } + } + } + } + + @media screen and (min-width: 1000px) { + &__back { + margin-top: 45px; + } + } } -app-tabs { - flex: 1; +@media screen and (max-width: 999px) { + app-tabs { + flex: 1; + } } diff --git a/projects/social_platform/src/app/ui/primitives/bar/bar.component.ts b/projects/social_platform/src/app/ui/primitives/bar/bar.component.ts index 8bec03119..07f865540 100644 --- a/projects/social_platform/src/app/ui/primitives/bar/bar.component.ts +++ b/projects/social_platform/src/app/ui/primitives/bar/bar.component.ts @@ -1,6 +1,9 @@ /** @format */ -import { ChangeDetectionStrategy, Component, input } from "@angular/core"; +import { DesktopLayoutService } from "@uilib"; +/** @format */ + +import { inject, ChangeDetectionStrategy, Component, input } from "@angular/core"; import { CommonModule } from "@angular/common"; import { RouterLink, RouterLinkActive } from "@angular/router"; import { BackComponent, TabsComponent } from "@uilib"; @@ -41,6 +44,8 @@ interface BarLinks { changeDetection: ChangeDetectionStrategy.OnPush, }) export class BarComponent { + protected readonly desktopLayout = inject(DesktopLayoutService).desktop; + /** Массив навигационных ссылок */ links = input.required(); diff --git a/projects/social_platform/src/app/ui/primitives/checkbox/checkbox.component.scss b/projects/social_platform/src/app/ui/primitives/checkbox/checkbox.component.scss index e6686a225..6bdcd2551 100644 --- a/projects/social_platform/src/app/ui/primitives/checkbox/checkbox.component.scss +++ b/projects/social_platform/src/app/ui/primitives/checkbox/checkbox.component.scss @@ -1,13 +1,12 @@ /** @format */ @use "styles/ui-foundation"; - -/** @format */ - @use "styles/responsive"; .field { - @include ui-foundation.choice; + @media screen and (max-width: 999px) { + @include ui-foundation.choice; + } position: relative; display: flex; @@ -28,29 +27,35 @@ color: var(--light-white); } - &:focus-visible { - outline: 2px solid var(--accent-dark); - outline-offset: 3px; + @media screen and (max-width: 999px) { + &:focus-visible { + outline: 2px solid var(--accent-dark); + outline-offset: 3px; + } } - &:disabled { - cursor: not-allowed; - opacity: var(--ui-disabled-opacity); + @media screen and (max-width: 999px) { + &:disabled { + cursor: not-allowed; + opacity: var(--ui-disabled-opacity); + } } } -@include responsive.apply-mobile { - :host { - display: inline-flex; - align-items: center; - justify-content: center; - min-width: 44px; - min-height: 44px; - } - - .field::before { - position: absolute; - inset: -12px; - content: ""; +@media screen and (max-width: 999px) { + @include responsive.apply-mobile { + :host { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 44px; + min-height: 44px; + } + + .field::before { + position: absolute; + inset: -12px; + content: ""; + } } } diff --git a/projects/social_platform/src/app/ui/primitives/dropdown/dropdown.component.scss b/projects/social_platform/src/app/ui/primitives/dropdown/dropdown.component.scss index 0030c716b..0664e3524 100644 --- a/projects/social_platform/src/app/ui/primitives/dropdown/dropdown.component.scss +++ b/projects/social_platform/src/app/ui/primitives/dropdown/dropdown.component.scss @@ -10,17 +10,27 @@ gap: 5px; align-items: flex-start; width: 100%; - min-width: 0; - max-width: calc(100vw - 24px); - max-height: min(300px, calc(var(--visual-viewport-height, 100dvh) - 24px)); - padding: var(--ui-space-sm); overflow-y: auto; - overscroll-behavior: contain; background-color: var(--light-white); - border: 0.5px solid var(--medium-grey-for-outline); - border-color: var(--ui-border); - border-radius: var(--ui-radius-card); - box-shadow: var(--ui-card-hover-shadow); + + @media screen and (max-width: 999px) { + min-width: 0; + max-width: calc(100vw - 24px); + max-height: min(300px, calc(var(--visual-viewport-height, 100dvh) - 24px)); + padding: var(--ui-space-sm); + overscroll-behavior: contain; + border: 0.5px solid var(--medium-grey-for-outline); + border-color: var(--ui-border); + border-radius: var(--ui-radius-card); + box-shadow: var(--ui-card-hover-shadow); + } + + @media screen and (min-width: 1000px) { + max-height: 200px; + padding: 12px; + border: 0.5px solid var(--medium-grey-for-outline); + border-radius: var(--rounded-lg); + } } &__option { @@ -28,14 +38,17 @@ gap: 5px; align-items: center; justify-content: space-between; - width: 100%; - min-width: 0; - min-height: var(--ui-control-height); - padding: 8px 12px; cursor: pointer; - border-radius: var(--rounded-lg); transition: color 0.2s ease-in-out; + @media screen and (max-width: 999px) { + width: 100%; + min-width: 0; + min-height: var(--ui-control-height); + padding: 8px 12px; + border-radius: var(--rounded-lg); + } + &--add-object { display: flex; align-items: center; @@ -101,13 +114,17 @@ } } -.field__option p { - min-width: 0; - overflow-wrap: anywhere; +@media screen and (max-width: 999px) { + .field__option p { + min-width: 0; + overflow-wrap: anywhere; + } } -@include responsive.apply-mobile { - .field__option { - min-height: 44px; +@media screen and (max-width: 999px) { + @include responsive.apply-mobile { + .field__option { + min-height: 44px; + } } } diff --git a/projects/social_platform/src/app/ui/primitives/file-item/file-item.component.scss b/projects/social_platform/src/app/ui/primitives/file-item/file-item.component.scss index 97ef30871..03db598dd 100644 --- a/projects/social_platform/src/app/ui/primitives/file-item/file-item.component.scss +++ b/projects/social_platform/src/app/ui/primitives/file-item/file-item.component.scss @@ -2,8 +2,6 @@ @use "styles/responsive"; -/** @format */ - .file { display: flex; gap: 10px; @@ -23,9 +21,12 @@ &__left { display: flex; - flex: 1; gap: 5px; align-items: center; + + @media screen and (max-width: 999px) { + flex: 1; + } } &__meta { @@ -34,7 +35,6 @@ &__icon { display: flex; - flex-shrink: 0; align-items: center; align-self: center; justify-content: center; @@ -44,6 +44,10 @@ border: 0.5px solid var(--medium-grey-for-outline); border-radius: var(--rounded-xxl); + @media screen and (max-width: 999px) { + flex-shrink: 0; + } + &--delete { color: var(--red); cursor: pointer; @@ -61,23 +65,27 @@ } } -.file, -.file__left { - min-width: 0; +@media screen and (max-width: 999px) { + .file, + .file__left { + min-width: 0; + } } -@include responsive.apply-mobile { - .file { - flex-wrap: wrap; - } +@media screen and (max-width: 999px) { + @include responsive.apply-mobile { + .file { + flex-wrap: wrap; + } - .file__name { - overflow-wrap: anywhere; - white-space: normal; - } + .file__name { + overflow-wrap: anywhere; + white-space: normal; + } - .file__icon { - width: 44px; - height: 44px; + .file__icon { + width: 44px; + height: 44px; + } } } diff --git a/projects/social_platform/src/app/ui/primitives/input/input.component.scss b/projects/social_platform/src/app/ui/primitives/input/input.component.scss index 5ff66aaa9..f0ae4a8cf 100644 --- a/projects/social_platform/src/app/ui/primitives/input/input.component.scss +++ b/projects/social_platform/src/app/ui/primitives/input/input.component.scss @@ -1,251 +1,442 @@ /** @format */ @use "styles/ui-foundation"; - -/** @format */ - @use "styles/typography"; @use "styles/responsive"; -.field { - position: relative; +@media screen and (max-width: 999px) { + .field { + position: relative; - &__input { - &::placeholder { - color: var(--dark-grey); - } + &__input { + &::placeholder { + color: var(--dark-grey); + } - &--small { - max-width: 70px; - padding: 12px 0; - text-align: center; + &--small { + max-width: 70px; + padding: 12px 0; + text-align: center; - &--error { - text-align: start; + &--error { + text-align: start; + } } - } - &--big { - width: 100%; - padding: 12px; - } + &--big { + width: 100%; + padding: 12px; + } - &--with-tooltip { - padding-right: 60px; - } + &--with-tooltip { + padding-right: 60px; + } - &--border { - border: 0.5px solid var(--gray); - border-radius: var(--rounded-xxl); + &--border { + border: 0.5px solid var(--gray); + border-radius: var(--rounded-xxl); - &:focus { - border-color: var(--accent); - box-shadow: var(--ui-focus-ring); + &:focus { + border-color: var(--accent); + box-shadow: var(--ui-focus-ring); + } } - } - &--error, - &--overflow { - border: 0.5px solid var(--red); + &--error, + &--overflow { + border: 0.5px solid var(--red); - &:focus { - border-color: var(--red); - box-shadow: var(--ui-error-ring); + &:focus { + border-color: var(--red); + box-shadow: var(--ui-error-ring); + } } - } - @include responsive.apply-desktop { - @include typography.body-12; - } - - @include ui-foundation.control; - } + @include responsive.apply-desktop { + @include typography.body-12; + } - &__input[type="date"]::-webkit-inner-spin-button, - &__input[type="date"]::-webkit-calendar-picker-indicator { - display: none; - appearance: none; - } + @include ui-foundation.control; + } - &__input[type="radio"] { - position: relative; - width: 10px; - height: 10px; - padding: 4px; - cursor: pointer; - border: 0.5px solid var(--dark-grey); - border-radius: 50%; - transition: - border-color 0.2s, - background-color 0.2s; - appearance: none; - - &:hover::after { - position: absolute; - top: 50%; - left: 50%; - width: 4px; - height: 4px; - content: ""; - background-color: var(--accent); - border-radius: 50%; - transform: translate(-50%, -50%); + &__input[type="date"]::-webkit-inner-spin-button, + &__input[type="date"]::-webkit-calendar-picker-indicator { + display: none; + appearance: none; } - &:checked { - z-index: 1; - background-color: var(--accent); - border-color: var(--accent); + &__input[type="radio"] { + position: relative; + width: 10px; + height: 10px; + padding: 4px; + cursor: pointer; + border: 0.5px solid var(--dark-grey); + border-radius: 50%; + transition: + border-color 0.2s, + background-color 0.2s; + appearance: none; - &::after { + &:hover::after { position: absolute; top: 50%; left: 50%; width: 4px; height: 4px; content: ""; - background-color: var(--light-gray); + background-color: var(--accent); border-radius: 50%; transform: translate(-50%, -50%); } + + &:checked { + z-index: 1; + background-color: var(--accent); + border-color: var(--accent); + + &::after { + position: absolute; + top: 50%; + left: 50%; + width: 4px; + height: 4px; + content: ""; + background-color: var(--light-gray); + border-radius: 50%; + transform: translate(-50%, -50%); + } + } + } + + &__error-icon { + position: absolute; + top: 50%; + right: 26px; + display: flex; + align-items: center; + justify-content: center; + color: var(--red) !important; + pointer-events: none; + transform: translateY(-50%); + + &--bare { + padding: 0; + background: transparent; + } } - } - &__error-icon { - position: absolute; - top: 50%; - right: 26px; - display: flex; - align-items: center; - justify-content: center; - color: var(--red) !important; - pointer-events: none; - transform: translateY(-50%); - - &--bare { + &__right-icon { + position: absolute; + top: 27%; + display: flex; + align-items: center; + justify-content: center; + } + + &__calendar-button { + position: absolute; + top: 50%; + right: 18px; + display: flex; + align-items: center; + justify-content: center; padding: 0; + color: var(--accent); + cursor: pointer; background: transparent; + border: none; + transform: translateY(-50%); } - } - &__right-icon { - position: absolute; - top: 27%; - display: flex; - align-items: center; - justify-content: center; + &__datepicker-anchor { + position: absolute; + right: 0; + bottom: 0; + width: 0; + height: 0; + padding: 0; + pointer-events: none; + opacity: 0; + } + + &__tooltip-wrapper { + position: absolute; + top: 55%; + right: 20px; + z-index: 10; + padding: 2px; + background-color: var(--light-gray); + border-radius: 100%; + transform: translateY(-50%); + + &--small { + top: 15%; + right: -3px; + } + } + + &__counter { + position: absolute; + right: 18px; + bottom: 0; + + p { + color: var(--dark-grey); + } + + &--overflow { + color: var(--red) !important; + } + } } - &__calendar-button { - position: absolute; - top: 50%; - right: 18px; - display: flex; - align-items: center; - justify-content: center; - padding: 0; - color: var(--accent); - cursor: pointer; - background: transparent; - border: none; - transform: translateY(-50%); + :host { + display: block; + min-width: 0; + max-width: 100%; } - &__datepicker-anchor { - position: absolute; - right: 0; - bottom: 0; - width: 0; - height: 0; - padding: 0; - pointer-events: none; - opacity: 0; + .field, + .search, + .search__input { + min-width: 0; + max-width: 100%; } - &__tooltip-wrapper { - position: absolute; - top: 55%; - right: 20px; - z-index: 10; - padding: 2px; - background-color: var(--light-gray); - border-radius: 100%; - transform: translateY(-50%); + @include responsive.apply-mobile { + .field__input, + .field__input-slim, + .search__input input { + min-width: 0; + max-width: 100%; + min-height: 44px; + font-size: var(--ui-font-h3); + } - &--small { - top: 15%; - right: -3px; + .field--small, + .field__input--small { + min-width: 0; + } + + .field__input--with-tooltip { + padding-right: 44px; } - } - &__counter { - position: absolute; - right: 18px; - bottom: 0; + .field__option { + min-height: 44px; + overflow-wrap: anywhere; + } - p { - color: var(--dark-grey); + .field__chip { + max-width: calc(100% - 44px); } - &--overflow { - color: var(--red) !important; + .field__chip span { + overflow-wrap: anywhere; + white-space: normal; + } + + .field__calendar-button { + right: 4px; + width: 44px; + height: 44px; + } + + .field__input[type="date"] { + padding-right: 48px; } } } -:host { - display: block; - min-width: 0; - max-width: 100%; -} +@media screen and (min-width: 1000px) { + .field { + position: relative; -.field, -.search, -.search__input { - min-width: 0; - max-width: 100%; -} + &__input { + color: var(--black) !important; + background-color: var(--white); + border: none; + outline: none; + transition: all 0.2s; -@include responsive.apply-mobile { - .field__input, - .field__input-slim, - .search__input input { - min-width: 0; - max-width: 100%; - min-height: 44px; - font-size: var(--ui-font-h3); - } + &::placeholder { + color: var(--dark-grey); + } - .field--small, - .field__input--small { - min-width: 0; - } + &--small { + max-width: 70px; + padding: 12px 0; + text-align: center; - .field__input--with-tooltip { - padding-right: 44px; - } + &--error { + text-align: start; + } + } - .field__option { - min-height: 44px; - overflow-wrap: anywhere; - } + &--big { + width: 100%; + padding: 12px; + } - .field__chip { - max-width: calc(100% - 44px); - } + &--with-tooltip { + padding-right: 60px; + } - .field__chip span { - overflow-wrap: anywhere; - white-space: normal; - } + &--border { + border: 0.5px solid var(--gray); + border-radius: var(--rounded-xxl); - .field__calendar-button { - right: 4px; - width: 44px; - height: 44px; - } + &:focus { + border-color: var(--accent); + box-shadow: 0 0 6px rgb(109 40 255 / 30%); + } + } + + &--error, + &--overflow { + border: 0.5px solid var(--red); + + &:focus { + border-color: var(--red); + box-shadow: 0 0 6px rgb(255 40 40 / 30.8%); + } + } + + @include typography.body-10; + + @include responsive.apply-desktop { + @include typography.body-12; + } + } + + &__input[type="date"]::-webkit-inner-spin-button, + &__input[type="date"]::-webkit-calendar-picker-indicator { + display: none; + appearance: none; + } + + &__input[type="radio"] { + position: relative; + width: 10px; + height: 10px; + padding: 4px; + cursor: pointer; + border: 0.5px solid var(--dark-grey); + border-radius: 50%; + transition: border-color 0.2s, background-color 0.2s; + appearance: none; + + &:hover::after { + position: absolute; + top: 50%; + left: 50%; + width: 4px; + height: 4px; + content: ""; + background-color: var(--accent); + border-radius: 50%; + transform: translate(-50%, -50%); + } + + &:checked { + z-index: 1; + background-color: var(--accent); + border-color: var(--accent); + + &::after { + position: absolute; + top: 50%; + left: 50%; + width: 4px; + height: 4px; + content: ""; + background-color: var(--light-gray); + border-radius: 50%; + transform: translate(-50%, -50%); + } + } + } + + &__error-icon { + position: absolute; + top: 50%; + right: 26px; + display: flex; + align-items: center; + justify-content: center; + color: var(--red) !important; + pointer-events: none; + transform: translateY(-50%); + + &--bare { + padding: 0; + background: transparent; + } + } + + &__right-icon { + position: absolute; + top: 27%; + display: flex; + align-items: center; + justify-content: center; + } + + &__calendar-button { + position: absolute; + top: 50%; + right: 18px; + display: flex; + align-items: center; + justify-content: center; + padding: 0; + color: var(--accent); + cursor: pointer; + background: transparent; + border: none; + transform: translateY(-50%); + } + + &__datepicker-anchor { + position: absolute; + right: 0; + bottom: 0; + width: 0; + height: 0; + padding: 0; + pointer-events: none; + opacity: 0; + } + + &__tooltip-wrapper { + position: absolute; + top: 55%; + right: 20px; + z-index: 10; + padding: 2px; + background-color: var(--light-gray); + border-radius: 100%; + transform: translateY(-50%); + + &--small { + top: 15%; + right: -3px; + } + } + + &__counter { + position: absolute; + right: 18px; + bottom: 0; - .field__input[type="date"] { - padding-right: 48px; + p { + color: var(--dark-grey); + } + + &--overflow { + color: var(--red) !important; + } + } } } diff --git a/projects/social_platform/src/app/ui/primitives/modal/modal.component.scss b/projects/social_platform/src/app/ui/primitives/modal/modal.component.scss index cded98e6d..18d997d11 100644 --- a/projects/social_platform/src/app/ui/primitives/modal/modal.component.scss +++ b/projects/social_platform/src/app/ui/primitives/modal/modal.component.scss @@ -16,7 +16,14 @@ right: 0; bottom: 0; left: 0; - background-color: var(--ui-backdrop); + + @media screen and (max-width: 999px) { + background-color: var(--ui-backdrop); + } + + @media screen and (min-width: 1000px) { + background-color: rgb(51 46 45 / 50%); + } } &__body { @@ -25,18 +32,54 @@ left: 50%; display: flex; justify-content: center; - width: min(var(--ui-dialog-width, var(--ui-dialog-md)), calc(100vw - 24px)); - min-width: 0; - max-width: calc(100vw - 24px); - max-height: calc(var(--visual-viewport-height, 100dvh) - 24px); - padding: var(--ui-dialog-padding); - overflow-y: auto; - overscroll-behavior: contain; + + @media screen and (max-width: 999px) { + width: min(var(--ui-dialog-width, var(--ui-dialog-md)), calc(100vw - 24px)); + } + + @media screen and (min-width: 1000px) { + width: 90%; + } + + @media screen and (max-width: 999px) { + min-width: 0; + } + + @media screen and (max-width: 999px) { + max-width: calc(100vw - 24px); + } + + @media screen and (max-width: 999px) { + max-height: calc(var(--visual-viewport-height, 100dvh) - 24px); + } + + @media screen and (max-width: 999px) { + padding: var(--ui-dialog-padding); + } + + @media screen and (min-width: 1000px) { + padding: 24px; + } + + @media screen and (max-width: 999px) { + overflow-y: auto; + } + + @media screen and (max-width: 999px) { + overscroll-behavior: contain; + } + + @media screen and (min-width: 1000px) { + overflow: hidden; + } + background: var(--white); border-radius: var(--ui-radius-dialog); transform: translate(-50%, -50%); @include responsive.apply-desktop { + width: unset; + max-height: 98vh; overflow-y: auto; } @@ -48,66 +91,74 @@ display: block; } - ::ng-deep > * { - flex-shrink: 1; - min-width: 0; - max-width: 100%; - } - - @include responsive.apply-below-desktop { - top: calc(var(--visual-viewport-top, 0px) + var(--visual-viewport-height, 100dvh) / 2); - padding: var(--ui-dialog-padding); - - ::ng-deep .cancel { + @media screen and (max-width: 999px) { + ::ng-deep > * { + flex-shrink: 1; min-width: 0; max-width: 100%; - max-height: none; - padding: 12px; } + } - ::ng-deep .cancel__buttons { - @include responsive.mobile-actions; + @media screen and (max-width: 999px) { + @include responsive.apply-below-desktop { + top: calc(var(--visual-viewport-top, 0px) + var(--visual-viewport-height, 100dvh) / 2); + padding: var(--ui-dialog-padding); - position: sticky; - bottom: 0; - z-index: 2; - justify-content: center; - padding-top: 8px; - padding-bottom: env(safe-area-inset-bottom, 0); - background: var(--white); - } + ::ng-deep .cancel { + min-width: 0; + max-width: 100%; + max-height: none; + padding: 12px; + } - ::ng-deep .cancel__text { - width: 100%; - } + ::ng-deep .cancel__buttons { + @include responsive.mobile-actions; - ::ng-deep .cancel__top { - position: sticky; - top: 0; - z-index: 2; - background: var(--white); - } + position: sticky; + bottom: 0; + z-index: 2; + justify-content: center; + padding-top: 8px; + padding-bottom: env(safe-area-inset-bottom, 0); + background: var(--white); + } - ::ng-deep .cancel__cross { - display: inline-flex; - align-items: center; - justify-content: center; - min-width: 44px; - min-height: 44px; + ::ng-deep .cancel__text { + width: 100%; + } + + ::ng-deep .cancel__top { + position: sticky; + top: 0; + z-index: 2; + background: var(--white); + } - svg { - max-width: 16px; - max-height: 16px; + ::ng-deep .cancel__cross { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 44px; + min-height: 44px; + + svg { + max-width: 16px; + max-height: 16px; + } } } } } } -.modal__body--small { - --ui-dialog-width: var(--ui-dialog-sm); +@media screen and (max-width: 999px) { + .modal__body--small { + --ui-dialog-width: var(--ui-dialog-sm); + } } -.modal__body--large { - --ui-dialog-width: var(--ui-dialog-lg); +@media screen and (max-width: 999px) { + .modal__body--large { + --ui-dialog-width: var(--ui-dialog-lg); + } } diff --git a/projects/social_platform/src/app/ui/primitives/search/search.component.scss b/projects/social_platform/src/app/ui/primitives/search/search.component.scss index 5e00182a9..a4416338a 100644 --- a/projects/social_platform/src/app/ui/primitives/search/search.component.scss +++ b/projects/social_platform/src/app/ui/primitives/search/search.component.scss @@ -1,112 +1,159 @@ /** @format */ @use "styles/ui-foundation"; - -/** @format */ - @use "styles/responsive"; -.search { - display: flex; - align-items: center; - width: 100%; - cursor: pointer; - border-bottom: 0.5px solid var(--dark-grey); - - &__other { - flex-grow: 1; - } - - &__icon { - margin-right: 4px; - margin-bottom: 2px; - color: var(--dark-grey); +@media screen and (max-width: 999px) { + .search { + display: flex; + align-items: center; + width: 100%; + cursor: pointer; + border-bottom: 0.5px solid var(--dark-grey); - &--open { - margin-top: 4px; - margin-bottom: 0; + &__other { + flex-grow: 1; } - } - &__text { - color: var(--dark-grey); - } + &__icon { + margin-right: 4px; + margin-bottom: 2px; + color: var(--dark-grey); - &__input { - width: 100%; + &--open { + margin-top: 4px; + margin-bottom: 0; + } + } - @include responsive.apply-desktop { - width: 200px; + &__text { + color: var(--dark-grey); } - input { + &__input { width: 100%; - background-color: transparent; - border: none; - outline: none; - &::placeholder { - color: var(--dark-grey); + @include responsive.apply-desktop { + width: 200px; } - @include ui-foundation.control; - } - } -} + input { + width: 100%; + background-color: transparent; + border: none; + outline: none; -:host { - display: block; - min-width: 0; - max-width: 100%; -} + &::placeholder { + color: var(--dark-grey); + } -.field, -.search, -.search__input { - min-width: 0; - max-width: 100%; -} + @include ui-foundation.control; + } + } + } -@include responsive.apply-mobile { - .field__input, - .field__input-slim, - .search__input input { + :host { + display: block; min-width: 0; max-width: 100%; - min-height: 44px; - font-size: var(--ui-font-h3); } - .field--small, - .field__input--small { + .field, + .search, + .search__input { min-width: 0; + max-width: 100%; } - .field__input--with-tooltip { - padding-right: 44px; - } + @include responsive.apply-mobile { + .field__input, + .field__input-slim, + .search__input input { + min-width: 0; + max-width: 100%; + min-height: 44px; + font-size: var(--ui-font-h3); + } - .field__option { - min-height: 44px; - overflow-wrap: anywhere; - } + .field--small, + .field__input--small { + min-width: 0; + } - .field__chip { - max-width: calc(100% - 44px); - } + .field__input--with-tooltip { + padding-right: 44px; + } - .field__chip span { - overflow-wrap: anywhere; - white-space: normal; - } + .field__option { + min-height: 44px; + overflow-wrap: anywhere; + } + + .field__chip { + max-width: calc(100% - 44px); + } + + .field__chip span { + overflow-wrap: anywhere; + white-space: normal; + } + + .field__calendar-button { + right: 4px; + width: 44px; + height: 44px; + } - .field__calendar-button { - right: 4px; - width: 44px; - height: 44px; + .field__input[type="date"] { + padding-right: 48px; + } } +} + +@media screen and (min-width: 1000px) { + .search { + display: flex; + align-items: center; + width: 100%; + cursor: pointer; + border-bottom: 0.5px solid var(--dark-grey); + + &__other { + flex-grow: 1; + } - .field__input[type="date"] { - padding-right: 48px; + &__icon { + margin-right: 4px; + margin-bottom: 2px; + color: var(--dark-grey); + + &--open { + margin-top: 4px; + margin-bottom: 0; + } + } + + &__text { + color: var(--dark-grey); + } + + &__input { + width: 100%; + + @include responsive.apply-desktop { + width: 200px; + } + + input { + width: 100%; + background-color: transparent; + border: none; + outline: none; + + &::placeholder { + color: var(--dark-grey); + } + } + } } } diff --git a/projects/social_platform/src/app/ui/primitives/select/select.component.scss b/projects/social_platform/src/app/ui/primitives/select/select.component.scss index 26758630c..8afe52e48 100644 --- a/projects/social_platform/src/app/ui/primitives/select/select.component.scss +++ b/projects/social_platform/src/app/ui/primitives/select/select.component.scss @@ -1,177 +1,284 @@ /** @format */ @use "styles/ui-foundation"; - -/** @format */ - @use "styles/typography"; @use "styles/responsive"; -.field { - position: relative; - width: 100%; - - &__input { +@media screen and (max-width: 999px) { + .field { position: relative; - z-index: 2; - display: flex; - align-items: center; - justify-content: space-between; - cursor: pointer; - - &--small { - max-width: 70px; - padding: 12px; - text-align: center; + width: 100%; + + &__input { + position: relative; + z-index: 2; + display: flex; + align-items: center; + justify-content: space-between; + cursor: pointer; + + &--small { + max-width: 70px; + padding: 12px; + text-align: center; + } + + &--big { + width: 100%; + padding: 12px; + } + + &--placeholder { + color: var(--dark-grey); + } + + &--open { + border-color: var(--accent); + box-shadow: var(--ui-focus-ring); + } + + &--error { + border-color: var(--red) !important; + } + + &--disabled { + cursor: not-allowed; + opacity: 0.5; + } + + @include ui-foundation.control; } - &--big { - width: 100%; - padding: 12px; + &__options { + position: absolute; + right: 0; + bottom: -6px; + left: 5%; + z-index: 11; + width: 90%; + max-height: 200px; + overflow-y: auto; + background-color: var(--white); + border: 0.5px solid var(--gray); + border-radius: var(--rounded-lg); + transform: translateY(100%); } - &--placeholder { + &__option { + display: flex; + align-items: center; + justify-content: space-between; + padding: 12px 18px; color: var(--dark-grey); - } + cursor: pointer; + border-radius: var(--rounded-lg); + transition: background-color 0.2s; - &--open { - border-color: var(--accent); - box-shadow: var(--ui-focus-ring); - } + &--highlighted { + background-color: var(--light-gray); + } - &--error { - border-color: var(--red) !important; + &:hover { + color: var(--accent); + } } - &--disabled { - cursor: not-allowed; - opacity: 0.5; + &__arrow { + color: var(--dark-grey); + transition: all 0.2s; + transform: rotate(180deg); + + &--filpped { + color: var(--accent); + transform: rotate(0deg); + } } - @include ui-foundation.control; + &__error-icon { + flex: 0 0 auto; + color: var(--red); + pointer-events: none; + + &--bare { + padding: 0; + background: transparent; + } + } } - &__options { - position: absolute; - right: 0; - bottom: -6px; - left: 5%; - z-index: 11; - width: 90%; - max-height: 200px; - overflow-y: auto; - background-color: var(--white); - border: 0.5px solid var(--gray); - border-radius: var(--rounded-lg); - transform: translateY(100%); + :host { + display: block; + min-width: 0; + max-width: 100%; } - &__option { - display: flex; - align-items: center; - justify-content: space-between; - padding: 12px 18px; - color: var(--dark-grey); - cursor: pointer; - border-radius: var(--rounded-lg); - transition: background-color 0.2s; + .field, + .search, + .search__input { + min-width: 0; + max-width: 100%; + } - &--highlighted { - background-color: var(--light-gray); + @include responsive.apply-mobile { + .field__input, + .field__input-slim, + .search__input input { + min-width: 0; + max-width: 100%; + min-height: 44px; + font-size: var(--ui-font-h3); } - &:hover { - color: var(--accent); + .field--small, + .field__input--small { + min-width: 0; } - } - &__arrow { - color: var(--dark-grey); - transition: all 0.2s; - transform: rotate(180deg); - - &--filpped { - color: var(--accent); - transform: rotate(0deg); + .field__input--with-tooltip { + padding-right: 44px; } - } - &__error-icon { - flex: 0 0 auto; - color: var(--red); - pointer-events: none; + .field__option { + min-height: 44px; + overflow-wrap: anywhere; + } - &--bare { - padding: 0; - background: transparent; + .field__chip { + max-width: calc(100% - 44px); } - } -} -:host { - display: block; - min-width: 0; - max-width: 100%; -} + .field__chip span { + overflow-wrap: anywhere; + white-space: normal; + } -.field, -.search, -.search__input { - min-width: 0; - max-width: 100%; -} + .field__calendar-button { + right: 4px; + width: 44px; + height: 44px; + } -@include responsive.apply-mobile { - .field__input, - .field__input-slim, - .search__input input { - min-width: 0; - max-width: 100%; - min-height: 44px; - font-size: var(--ui-font-h3); + .field__input[type="date"] { + padding-right: 48px; + } } - .field--small, - .field__input--small { + .field__input > span, + .field__input > p { min-width: 0; + overflow-wrap: anywhere; } - .field__input--with-tooltip { - padding-right: 44px; + .field__arrow, + .field__error-icon { + flex-shrink: 0; } +} - .field__option { - min-height: 44px; - overflow-wrap: anywhere; - } +@media screen and (min-width: 1000px) { + .field { + position: relative; + width: 100%; + + &__input { + position: relative; + z-index: 2; + display: flex; + align-items: center; + justify-content: space-between; + color: var(--black); + cursor: pointer; + background-color: var(--white); + border: 0.5px solid var(--gray); + border-radius: var(--rounded-xxl); + outline: none; + + &--small { + max-width: 70px; + padding: 12px; + text-align: center; + } + + &--big { + width: 100%; + padding: 12px; + } + + &--placeholder { + color: var(--dark-grey); + } + + &--open { + border-color: var(--accent); + box-shadow: 0 0 6px rgb(109 40 255 / 30%); + } + + &--error { + border-color: var(--red) !important; + } + + &--disabled { + cursor: not-allowed; + opacity: 0.5; + } + + @include typography.body-12; + } - .field__chip { - max-width: calc(100% - 44px); - } + &__options { + position: absolute; + right: 0; + bottom: -6px; + left: 5%; + z-index: 11; + width: 90%; + max-height: 200px; + overflow-y: auto; + background-color: var(--white); + border: 0.5px solid var(--gray); + border-radius: var(--rounded-lg); + transform: translateY(100%); + } - .field__chip span { - overflow-wrap: anywhere; - white-space: normal; - } + &__option { + display: flex; + align-items: center; + justify-content: space-between; + padding: 12px 18px; + color: var(--dark-grey); + cursor: pointer; + border-radius: var(--rounded-lg); + transition: background-color 0.2s; - .field__calendar-button { - right: 4px; - width: 44px; - height: 44px; - } + &--highlighted { + background-color: var(--light-gray); + } - .field__input[type="date"] { - padding-right: 48px; - } -} + &:hover { + color: var(--accent); + } + } -.field__input > span, -.field__input > p { - min-width: 0; - overflow-wrap: anywhere; -} + &__arrow { + color: var(--dark-grey); + transition: all 0.2s; + transform: rotate(180deg); + + &--filpped { + color: var(--accent); + transform: rotate(0deg); + } + } -.field__arrow, -.field__error-icon { - flex-shrink: 0; + &__error-icon { + flex: 0 0 auto; + color: var(--red); + pointer-events: none; + + &--bare { + padding: 0; + background: transparent; + } + } + } } diff --git a/projects/social_platform/src/app/ui/primitives/switch/switch.component.scss b/projects/social_platform/src/app/ui/primitives/switch/switch.component.scss index ff0112559..b589397ea 100644 --- a/projects/social_platform/src/app/ui/primitives/switch/switch.component.scss +++ b/projects/social_platform/src/app/ui/primitives/switch/switch.component.scss @@ -31,18 +31,20 @@ } } -@include responsive.apply-mobile { - :host { - display: inline-flex; - align-items: center; - justify-content: center; - min-width: 44px; - min-height: 44px; - } +@media screen and (max-width: 999px) { + @include responsive.apply-mobile { + :host { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 44px; + min-height: 44px; + } - .switch::before { - position: absolute; - inset: -12px -2px; - content: ""; + .switch::before { + position: absolute; + inset: -12px -2px; + content: ""; + } } } diff --git a/projects/social_platform/src/app/ui/primitives/tag/tag.component.scss b/projects/social_platform/src/app/ui/primitives/tag/tag.component.scss index 14d8f9629..b0190ed62 100644 --- a/projects/social_platform/src/app/ui/primitives/tag/tag.component.scss +++ b/projects/social_platform/src/app/ui/primitives/tag/tag.component.scss @@ -1,15 +1,12 @@ /** @format */ @use "styles/ui-foundation"; - -/** @format */ - @use "styles/responsive"; -/** @format */ - .tag { - @include ui-foundation.badge; + @media screen and (max-width: 999px) { + @include ui-foundation.badge; + } position: relative; display: flex; @@ -17,10 +14,25 @@ justify-content: center; width: 100%; max-width: 120px; - padding: 4px 12px; + + @media screen and (max-width: 999px) { + padding: 4px 12px; + } + + @media screen and (min-width: 1000px) { + padding: 2px 20px; + } + overflow: hidden; - font-size: var(--ui-font-caption); - line-height: 1.5; + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + } + + @media screen and (max-width: 999px) { + line-height: 1.5; + } + color: var(--accent); text-overflow: ellipsis; white-space: nowrap; @@ -192,25 +204,27 @@ } } -@include responsive.apply-mobile { - .tag { - max-width: 100%; - padding: 4px 12px; - overflow-wrap: anywhere; - white-space: normal; - } +@media screen and (max-width: 999px) { + @include responsive.apply-mobile { + .tag { + max-width: 100%; + padding: 4px 12px; + overflow-wrap: anywhere; + white-space: normal; + } - .tag p { - min-width: 0; - } + .tag p { + min-width: 0; + } - .tag:has(.tag__icons) { - padding-right: 40px; - } + .tag:has(.tag__icons) { + padding-right: 40px; + } - .tag__icons { - top: 0; - bottom: 0; - align-items: center; + .tag__icons { + top: 0; + bottom: 0; + align-items: center; + } } } diff --git a/projects/social_platform/src/app/ui/primitives/textarea/textarea.component.scss b/projects/social_platform/src/app/ui/primitives/textarea/textarea.component.scss index 6c32da48c..3003879cf 100644 --- a/projects/social_platform/src/app/ui/primitives/textarea/textarea.component.scss +++ b/projects/social_platform/src/app/ui/primitives/textarea/textarea.component.scss @@ -1,33 +1,12 @@ /** @format */ @use "styles/ui-foundation"; - -/** @format */ - @use "styles/typography"; @use "styles/responsive"; -.field { - position: relative; - - &--small { - min-width: 245px; - } - - &--big { - width: 100%; - } - - &__input { - display: block; - width: 100%; - min-height: 162px; - padding: 12px 18px; - resize: none; - - &::placeholder { - color: var(--dark-grey); - } +@media screen and (max-width: 999px) { + .field { + position: relative; &--small { min-width: 245px; @@ -37,131 +16,256 @@ width: 100%; } - &--with-tooltip { - padding-right: 130px; - padding-right: 60px; - } + &__input { + display: block; + width: 100%; + min-height: 162px; + padding: 12px 18px; + resize: none; - &--error, - &--overflow { - border: 0.5px solid var(--red); + &::placeholder { + color: var(--dark-grey); + } + + &--small { + min-width: 245px; + } + + &--big { + width: 100%; + } + + &--with-tooltip { + padding-right: 130px; + padding-right: 60px; + } + + &--error, + &--overflow { + border: 0.5px solid var(--red); + + &:focus { + border-color: var(--red) !important; + box-shadow: var(--ui-error-ring) !important; + } + } &:focus { - border-color: var(--red) !important; - box-shadow: var(--ui-error-ring) !important; + border-color: var(--accent); + box-shadow: var(--ui-focus-ring); } - } - &:focus { - border-color: var(--accent); - box-shadow: var(--ui-focus-ring); + @include ui-foundation.control; + + border-radius: var(--ui-radius-card); } - @include ui-foundation.control; + &__error-icon { + position: absolute; + top: 25px; + right: 15px; + display: flex; + align-items: center; + justify-content: center; + color: var(--red) !important; + pointer-events: none; + transform: translateY(-50%); - border-radius: var(--ui-radius-card); - } + i { + color: var(--red) !important; + } - &__error-icon { - position: absolute; - top: 25px; - right: 15px; - display: flex; - align-items: center; - justify-content: center; - color: var(--red) !important; - pointer-events: none; - transform: translateY(-50%); - - i { - color: var(--red) !important; + &--bare { + padding: 0; + background: transparent; + } + } + + &__tooltip-wrapper { + position: absolute; + top: 25px; + right: 15px; + z-index: 10; + padding: 2px; + background-color: var(--light-gray); + border-radius: 100%; + transform: translateY(-50%); } - &--bare { - padding: 0; - background: transparent; + &__counter { + position: absolute; + right: 18px; + bottom: 4px; + + p { + color: var(--dark-grey); + } + + &--overflow { + color: var(--red) !important; + } } } - &__tooltip-wrapper { - position: absolute; - top: 25px; - right: 15px; - z-index: 10; - padding: 2px; - background-color: var(--light-gray); - border-radius: 100%; - transform: translateY(-50%); + :host { + display: block; + min-width: 0; + max-width: 100%; + } + + .field, + .search, + .search__input { + min-width: 0; + max-width: 100%; } - &__counter { - position: absolute; - right: 18px; - bottom: 4px; + @include responsive.apply-mobile { + .field__input, + .field__input-slim, + .search__input input { + min-width: 0; + max-width: 100%; + min-height: 44px; + font-size: var(--ui-font-h3); + } - p { - color: var(--dark-grey); + .field--small, + .field__input--small { + min-width: 0; } - &--overflow { - color: var(--red) !important; + .field__input--with-tooltip { + padding-right: 44px; + } + + .field__option { + min-height: 44px; + overflow-wrap: anywhere; + } + + .field__chip { + max-width: calc(100% - 44px); + } + + .field__chip span { + overflow-wrap: anywhere; + white-space: normal; + } + + .field__calendar-button { + right: 4px; + width: 44px; + height: 44px; + } + + .field__input[type="date"] { + padding-right: 48px; } } } -:host { - display: block; - min-width: 0; - max-width: 100%; -} +@media screen and (min-width: 1000px) { + .field { + position: relative; -.field, -.search, -.search__input { - min-width: 0; - max-width: 100%; -} + &--small { + min-width: 245px; + } -@include responsive.apply-mobile { - .field__input, - .field__input-slim, - .search__input input { - min-width: 0; - max-width: 100%; - min-height: 44px; - font-size: var(--ui-font-h3); - } + &--big { + width: 100%; + } - .field--small, - .field__input--small { - min-width: 0; - } + &__input { + display: block; + width: 100%; + min-height: 162px; + padding: 12px 18px; + color: var(--black); + resize: none; + background-color: var(--white); + border: 0.5px solid var(--gray); + border-radius: var(--rounded-xl); + outline: none; + transition: all 0.2s; + + &::placeholder { + color: var(--dark-grey); + } - .field__input--with-tooltip { - padding-right: 44px; - } + &--small { + min-width: 245px; + } - .field__option { - min-height: 44px; - overflow-wrap: anywhere; - } + &--big { + width: 100%; + } - .field__chip { - max-width: calc(100% - 44px); - } + &--with-tooltip { + padding-right: 130px; + } - .field__chip span { - overflow-wrap: anywhere; - white-space: normal; - } + &--error, + &--overflow { + border: 0.5px solid var(--red); - .field__calendar-button { - right: 4px; - width: 44px; - height: 44px; - } + &:focus { + border-color: var(--red) !important; + box-shadow: 0 0 6px rgb(255 40 40 / 30.8%) !important; + } + } + + &:focus { + border-color: var(--accent); + box-shadow: 0 0 6px rgb(109 40 255 / 30%); + } + } + + &__error-icon { + position: absolute; + top: 25px; + right: 15px; + display: flex; + align-items: center; + justify-content: center; + color: var(--red) !important; + pointer-events: none; + transform: translateY(-50%); - .field__input[type="date"] { - padding-right: 48px; + i { + color: var(--red) !important; + } + + &--bare { + padding: 0; + background: transparent; + } + } + + &__tooltip-wrapper { + position: absolute; + top: 25px; + right: 15px; + z-index: 10; + padding: 2px; + background-color: var(--light-gray); + border-radius: 100%; + transform: translateY(-50%); + } + + &__counter { + position: absolute; + right: 18px; + bottom: 4px; + + p { + color: var(--dark-grey); + } + + &--overflow { + color: var(--red) !important; + } + } } } diff --git a/projects/social_platform/src/app/ui/primitives/upload-file/upload-file.component.scss b/projects/social_platform/src/app/ui/primitives/upload-file/upload-file.component.scss index fc2230911..a71af676a 100644 --- a/projects/social_platform/src/app/ui/primitives/upload-file/upload-file.component.scss +++ b/projects/social_platform/src/app/ui/primitives/upload-file/upload-file.component.scss @@ -56,7 +56,6 @@ border-radius: var(--rounded-lg); &__title { - /* width: 80%; */ overflow: hidden; color: var(--black); text-overflow: ellipsis; @@ -88,34 +87,36 @@ } } -@include responsive.apply-mobile { - .control { - height: auto; - min-height: 120px; - } +@media screen and (max-width: 999px) { + @include responsive.apply-mobile { + .control { + height: auto; + min-height: 120px; + } - .control label { - min-height: 120px; - padding: 16px; - } + .control label { + min-height: 120px; + padding: 16px; + } - .control__success, - .file { - flex-wrap: wrap; - min-width: 0; - max-width: 100%; - } + .control__success, + .file { + flex-wrap: wrap; + min-width: 0; + max-width: 100%; + } - .file__title { - min-width: 0; - max-width: 100%; - overflow-wrap: anywhere; - white-space: normal; - } + .file__title { + min-width: 0; + max-width: 100%; + overflow-wrap: anywhere; + white-space: normal; + } - .file__basket, - .file__replace { - min-width: 44px; - min-height: 44px; + .file__basket, + .file__replace { + min-width: 44px; + min-height: 44px; + } } } diff --git a/projects/social_platform/src/app/ui/widgets/cookie-consent/cookie-consent.component.scss b/projects/social_platform/src/app/ui/widgets/cookie-consent/cookie-consent.component.scss index de7c55c2d..e9302095a 100644 --- a/projects/social_platform/src/app/ui/widgets/cookie-consent/cookie-consent.component.scss +++ b/projects/social_platform/src/app/ui/widgets/cookie-consent/cookie-consent.component.scss @@ -2,8 +2,6 @@ @use "styles/responsive"; -/** @format */ - .cookie-consent { position: fixed; right: 20px; @@ -38,18 +36,20 @@ } } -@include responsive.apply-mobile { - .cookie-consent { - right: var(--page-gutter); - bottom: max(12px, env(safe-area-inset-bottom)); - left: var(--page-gutter); - max-width: none; - max-height: calc(100dvh - 24px); - padding: 16px; - overflow-y: auto; - } +@media screen and (max-width: 999px) { + @include responsive.apply-mobile { + .cookie-consent { + right: var(--page-gutter); + bottom: max(12px, env(safe-area-inset-bottom)); + left: var(--page-gutter); + max-width: none; + max-height: calc(100dvh - 24px); + padding: 16px; + overflow-y: auto; + } - .cookie-consent__buttons { - @include responsive.mobile-actions; + .cookie-consent__buttons { + @include responsive.mobile-actions; + } } } diff --git a/projects/social_platform/src/app/ui/widgets/detail/detail.component.html b/projects/social_platform/src/app/ui/widgets/detail/detail.component.html index 8b90c4323..703713ece 100644 --- a/projects/social_platform/src/app/ui/widgets/detail/detail.component.html +++ b/projects/social_platform/src/app/ui/widgets/detail/detail.component.html @@ -5,20 +5,16 @@ @if (info()) {
- @if (appWidth > 1000) { - cover - } - -
+ cover
- @if (listType() === "project") { + @if (appWidth >= 1000 && (listType() === "project" || listType() === "profile")) {

- @if (listType() === "profile") { + @if (appWidth < 1000) { }
@@ -121,6 +119,9 @@ (click)="isContactsModalOpen.set(true)" > + @if (appWidth < 1000) { + Контакты + } оценка проектов @@ -186,8 +187,8 @@ @if (isUserManager()) { аналитика @@ -197,27 +198,25 @@ - @if (appWidth > 1000) { - {{ - info().name.includes("Технолидеры Будущего") - ? "Каталог лучших стартапов 2022/23" - : "положение" - }} - } + {{ + info().name.includes("Технолидеры Будущего") + ? "Каталог лучших стартапов 2022/23" + : "положение" + }} } - @if (appWidth > 1000) { + @if (appWidth >= 1000) {
} @if (appWidth < 1000) { @@ -230,9 +229,12 @@ (click)="isContactsModalOpen.set(true)" > + @if (appWidth < 1000) { + Контакты + } } - @if (isUserManager() || (isUserExpert() && appWidth > 1000)) { + @if (isUserManager() || (isUserExpert() && appWidth >= 1000)) { } - @if (!isUserManager() && !isUserExpert() && appWidth > 1000) { + @if (!isUserManager() && !isUserExpert() && appWidth >= 1000) { } - @if (isUserManager() || (isUserExpert() && appWidth > 1000)) { + @if (isUserManager() || (isUserExpert() && appWidth >= 1000)) { - {{ appWidth > 1000 ? "перейти в курс" : "курс" }} + {{ appWidth >= 1000 ? "перейти в курс" : "курс" }} } diff --git a/projects/social_platform/src/app/ui/widgets/detail/detail.component.scss b/projects/social_platform/src/app/ui/widgets/detail/detail.component.scss index 502d1191c..bfe10888d 100644 --- a/projects/social_platform/src/app/ui/widgets/detail/detail.component.scss +++ b/projects/social_platform/src/app/ui/widgets/detail/detail.component.scss @@ -64,15 +64,17 @@ $detail-bar-mb: 12px; object-position: center; } - &--mobile { - display: block; - max-width: 100%; - height: 136px; - background: linear-gradient(90deg, var(--accent) 0%, var(--lime) 100%); - border-radius: 15px; - - @include responsive.apply-desktop { - display: none; + @media screen and (min-width: 1000px) { + &--mobile { + display: block; + max-width: 100%; + height: 136px; + background: linear-gradient(90deg, var(--accent) 0%, var(--lime) 100%); + border-radius: 15px; + + @include responsive.apply-desktop { + display: none; + } } } } @@ -421,55 +423,119 @@ $detail-bar-mb: 12px; } } -@include responsive.apply-below-desktop { - .detail { - height: auto; - margin: 0 var(--page-gutter); - } +@media screen and (max-width: 999px) { + @include responsive.apply-below-desktop { + .detail { + height: auto; + margin: 0 var(--page-gutter); + } - .detail__body { - max-height: none; - } + .detail__body { + max-height: none; + } - .info__row { - @include responsive.mobile-actions; - } + .info__row { + @include responsive.mobile-actions; + } - .approve { - min-width: 0; - padding: 8px; - } + .approve { + min-width: 0; + padding: 8px; + } - .project__item, - .project__item--info { - @include responsive.mobile-actions; - } + .project__item, + .project__item--info { + @include responsive.mobile-actions; + } - .approves__text { - overflow-wrap: anywhere; - white-space: normal; + .approves__text { + overflow-wrap: anywhere; + white-space: normal; + } } } -.info__page-header { - padding-top: 80px; +@media screen and (max-width: 999px) { + .info__page-header { + padding-top: 80px; + } } -@media (max-width: 999px) { - .info__page-header { - padding-top: 150px; +@media screen and (max-width: 999px) { + @include responsive.apply-below-desktop { + .info__cover, + .info__cover--program { + height: 136px; + } + + .info__avatar, + .info__avatar--program { + bottom: -32px; + left: 16px; + transform: none; + } + + .info__page-header { + padding-top: 52px; + margin-bottom: 16px; + } + + .info__actions { + grid-template-columns: repeat(2, minmax(0, 1fr)); + align-items: stretch; + padding: 0 0 24px; + + > a, + > app-button, + > .info__unavailable, + > .info__primary-action { + display: block; + justify-self: stretch; + width: 100%; + min-width: 0; + } + + ::ng-deep app-button { + display: block; + width: 100%; + height: 100%; + } + + ::ng-deep app-button > button { + width: 100%; + height: 100%; + padding-right: 12px; + padding-left: 12px; + } + } + + .info__divider { + display: none; + } + + .info__primary-action { + order: 0; + } + + .info__materials--full { + grid-column: auto; + } } } -.approve, -.cancel, -.support { - width: 100%; - min-width: 0; - max-width: 100%; - padding: 0; +@media screen and (max-width: 999px) { + .approve, + .cancel, + .support { + width: 100%; + min-width: 0; + max-width: 100%; + padding: 0; + } } -.info__page-header + .info__actions { - padding-top: 0; +@media screen and (max-width: 999px) { + .info__page-header + .info__actions { + padding-top: 0; + } } diff --git a/projects/social_platform/src/app/ui/widgets/feed-filter/feed-filter.component.html b/projects/social_platform/src/app/ui/widgets/feed-filter/feed-filter.component.html index fcb69c083..253ce92d7 100644 --- a/projects/social_platform/src/app/ui/widgets/feed-filter/feed-filter.component.html +++ b/projects/social_platform/src/app/ui/widgets/feed-filter/feed-filter.component.html @@ -4,31 +4,6 @@
-
-
-
- Фильтр -
- - @if (filterOpen()) { -
- - -
- } -
-
-
@for (filterItem of feedFilterOptions; track $index) { diff --git a/projects/social_platform/src/app/ui/widgets/feed-filter/feed-filter.component.scss b/projects/social_platform/src/app/ui/widgets/feed-filter/feed-filter.component.scss index c0502a6d8..16cb04fa0 100644 --- a/projects/social_platform/src/app/ui/widgets/feed-filter/feed-filter.component.scss +++ b/projects/social_platform/src/app/ui/widgets/feed-filter/feed-filter.component.scss @@ -1,150 +1,232 @@ /** @format */ -@use "styles/typography"; @use "styles/responsive"; +@use "styles/typography"; -.mobile { - display: grid; - grid-template-columns: 0.6fr 0.4fr; - gap: 5px; - margin-bottom: 20px; +@media screen and (min-width: 1000px) { + .mobile { + display: grid; + grid-template-columns: 0.6fr 0.4fr; + gap: 5px; + margin-bottom: 20px; - @include responsive.apply-desktop { - display: none; + @include responsive.apply-desktop { + display: none; + } + + app-button { + &::ng-deep .button--inline { + min-height: 38px; + padding: 0; + } + } } } -.select { - position: relative; - - &__input { +@media screen and (min-width: 1000px) { + .select { position: relative; - z-index: 4; - display: flex; - align-items: center; - width: 100%; - height: 38px; - padding: 13px 80px 13px 20px; - background-color: var(--white); - border: 1px solid var(--gray); - border-radius: var(--rounded-lg); - transition: all 0.2s; - - &::placeholder { - color: var(--dark-grey); - } - &:hover, - &--open { - cursor: pointer; - border-color: var(--accent); - } + &__input { + position: relative; + z-index: 4; + display: flex; + align-items: center; + width: 100%; + height: 38px; + padding: 13px 80px 13px 20px; + background-color: var(--white); + border: 1px solid var(--gray); + border-radius: var(--rounded-lg); + transition: all 0.2s; - @include typography.body-14; - } + &::placeholder { + color: var(--dark-grey); + } - &__dropdown { - position: absolute; - top: 80%; - right: 0; - left: 0; - z-index: 3; - padding: 20px 10px 10px; - background-color: var(--white); - border: 1px solid var(--gray); - border-radius: var(--rounded-lg); - box-shadow: 5px 5px 25px 0 var(--gray-for-shadow); - transform-origin: center top; - } + &:hover, + &--open { + cursor: pointer; + border-color: var(--accent); + } - &__dropdown-icon { - position: absolute; - top: 50%; - right: 15px; - z-index: 4; - color: var(--dark-grey); - pointer-events: none; - transform: translateY(-50%) rotate(180deg); + @include typography.body-14; + } + + &__dropdown { + position: absolute; + top: 80%; + right: 0; + left: 0; + z-index: 3; + padding: 20px 10px 10px; + background-color: var(--white); + border: 1px solid var(--gray); + border-radius: var(--rounded-lg); + box-shadow: 5px 5px 25px 0 var(--gray-for-shadow); + transform-origin: center top; + } + + &__dropdown-icon { + position: absolute; + top: 50%; + right: 15px; + z-index: 4; + color: var(--dark-grey); + pointer-events: none; + transform: translateY(-50%) rotate(180deg); + } } } .filter { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: 30px 12px; - padding-top: 25px; + + @media screen and (max-width: 999px) { + gap: 8px; + } + + @media screen and (min-width: 1000px) { + gap: 30px 12px; + } + + @media screen and (min-width: 1000px) { + padding-top: 25px; + } @include responsive.apply-desktop { grid-template-columns: repeat(6, minmax(0, 1fr)); } - &__option { - position: relative; - display: grid; - grid-template-rows: 32px 18px; - row-gap: 4px; - align-items: center; - justify-items: center; - min-width: 0; - height: 104px; - padding: 36px 6px 12px; - cursor: pointer; - background-color: var(--light-white); - border: 0.5px solid var(--medium-grey-for-outline); - border-radius: var(--rounded-xl); + @media screen and (max-width: 999px) { + &__option.ui-button { + position: relative; + display: grid; + grid-template-columns: 20px minmax(0, 1fr); + gap: 4px 8px; + align-items: center; + min-width: 0; + height: auto; + min-height: 64px; + padding: 12px; + white-space: normal; + cursor: pointer; + background-color: var(--ui-surface); + border: 1px solid var(--ui-border-subtle); + border-radius: var(--rounded-lg); - &--disable { - cursor: not-allowed; - opacity: 0.5; + &:focus-visible { + outline: 2px solid var(--accent-dark); + outline-offset: 3px; + } } + } - &--active { + @media screen and (max-width: 999px) { + &__option--active.ui-button { + background-color: var(--accent-light); border-color: var(--accent); + } + } - i { - color: var(--light-white) !important; - } - - .filter__option--icon { - background-color: var(--accent); - } - - .filter__title { - color: var(--accent); - } + @media screen and (max-width: 999px) { + &__option--disable.ui-button { + cursor: not-allowed; + opacity: 0.5; } + } - &--icon { - position: absolute; - bottom: 100%; - left: 50%; + @media screen and (max-width: 999px) { + &__option--icon { + position: static; display: flex; + grid-row: 1 / 3; align-items: center; justify-content: center; - width: 50px; - height: 50px; + width: 20px; + height: 20px; + color: var(--accent); + } + } + + @media screen and (min-width: 1000px) { + &__option { + position: relative; + display: grid; + grid-template-rows: 32px 18px; + row-gap: 4px; + align-items: center; + justify-items: center; + min-width: 0; + height: 104px; + padding: 36px 6px 12px; + cursor: pointer; background-color: var(--light-white); border: 0.5px solid var(--medium-grey-for-outline); - border-radius: 50%; - transform: translate(-50%, 50%); + border-radius: var(--rounded-xl); - i { - color: var(--accent); + &--disable { + cursor: not-allowed; + opacity: 0.5; } - } - &:focus-visible { - outline: 2px solid var(--accent-dark); - outline-offset: 3px; + &--active { + border-color: var(--accent); + + i { + color: var(--light-white) !important; + } + + .filter__option--icon { + background-color: var(--accent); + } + + .filter__title { + color: var(--accent); + } + } + + &--icon { + position: absolute; + bottom: 100%; + left: 50%; + display: flex; + align-items: center; + justify-content: center; + width: 50px; + height: 50px; + background-color: var(--light-white); + border: 0.5px solid var(--medium-grey-for-outline); + border-radius: 50%; + transform: translate(-50%, 50%); + + i { + color: var(--accent); + } + } + + &:focus-visible { + outline: 2px solid var(--accent-dark); + outline-offset: 3px; + } } } - /* Одна двухстрочная область названия задаёт общую базовую линию всех счётчиков. */ &__title { - font-size: var(--ui-font-caption); line-height: 16px; - color: var(--grey-for-text); - text-align: center; + color: var(--ui-text-muted); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-small); + text-align: left; + overflow-wrap: anywhere; + } + + @media screen and (min-width: 1000px) { + font-size: 11px; + text-align: center; + } } &__count { @@ -154,21 +236,30 @@ font-variant-numeric: tabular-nums; line-height: 18px; color: var(--accent); + + @media screen and (max-width: 999px) { + grid-column: 2; + text-align: left; + } } - &__checkbox { - display: flex; - align-items: center; - margin-bottom: 6px; - color: var(--black); - cursor: pointer; + @media screen and (min-width: 1000px) { + &__checkbox { + display: flex; + align-items: center; + margin-bottom: 6px; + color: var(--black); + cursor: pointer; - app-checkbox { - margin-right: 15px; + app-checkbox { + margin-right: 15px; + } } } } -a:hover { - cursor: pointer; +@media screen and (min-width: 1000px) { + a:hover { + cursor: pointer; + } } diff --git a/projects/social_platform/src/app/ui/widgets/feed-filter/feed-filter.component.ts b/projects/social_platform/src/app/ui/widgets/feed-filter/feed-filter.component.ts index 3a8e8fc37..a57db3db7 100644 --- a/projects/social_platform/src/app/ui/widgets/feed-filter/feed-filter.component.ts +++ b/projects/social_platform/src/app/ui/widgets/feed-filter/feed-filter.component.ts @@ -3,11 +3,9 @@ import { ButtonDirective, FiltersDirective } from "@uilib"; /** @format */ -import { animate, style, transition, trigger } from "@angular/animations"; import { CommonModule } from "@angular/common"; import { ChangeDetectionStrategy, Component, inject, OnInit } from "@angular/core"; import { IconComponent } from "@ui/primitives"; -import { ClickOutsideModule } from "ng-click-outside"; import { feedFilter } from "@core/consts/filters/feed-filter.const"; import { FeedFilterInfoService } from "./service/feed-filter-info.service"; import { DetailProfileInfoService } from "../detail/services/profile/detail-profile-info.service"; @@ -18,28 +16,16 @@ import { FeedCategoryCounts } from "@domain/feed/feed-item.model"; /** Компонент фильтрации ленты по типам контента с мгновенной синхронизацией через URL. */ @Component({ selector: "app-feed-filter", - imports: [FiltersDirective, ButtonDirective, CommonModule, ClickOutsideModule, IconComponent], + imports: [FiltersDirective, ButtonDirective, CommonModule, IconComponent], templateUrl: "./feed-filter.component.html", styleUrl: "./feed-filter.component.scss", changeDetection: ChangeDetectionStrategy.OnPush, - animations: [ - trigger("dropdownAnimation", [ - transition(":enter", [ - style({ opacity: 0, transform: "scaleY(0.8)" }), - animate(".12s cubic-bezier(0, 0, 0.2, 1)"), - ]), - transition(":leave", [animate(".1s linear", style({ opacity: 0 }))]), - ]), - ], providers: [FeedFilterInfoService, ProfileDetailUIInfoService, DetailProfileInfoService], }) export class FeedFilterComponent implements OnInit { private readonly feedFilterInfoService = inject(FeedFilterInfoService); private readonly feedUIInfoService = inject(FeedUIInfoService); - // Состояние выпадающего меню фильтров - protected readonly filterOpen = this.feedFilterInfoService.filterOpen; - // Массив активных фильтров protected readonly includedFilters = this.feedFilterInfoService.includedFilters; @@ -57,12 +43,4 @@ export class FeedFilterComponent implements OnInit { setFilter(keyword: string): void { this.feedFilterInfoService.setFilter(keyword); } - - resetFilter(): void { - this.feedFilterInfoService.resetFilter(); - } - - onClickOutside(): void { - this.feedFilterInfoService.onClickOutside(); - } } diff --git a/projects/social_platform/src/app/ui/widgets/info-card/info-card.component.html b/projects/social_platform/src/app/ui/widgets/info-card/info-card.component.html index da10464c3..b30e41b1f 100644 --- a/projects/social_platform/src/app/ui/widgets/info-card/info-card.component.html +++ b/projects/social_platform/src/app/ui/widgets/info-card/info-card.component.html @@ -47,7 +47,7 @@ [routerLink]="AppRoutes.projects.detail(info()?.id)" [attr.aria-label]=" 'Открыть проект «' + - info()?.name + + (info()?.name?.trim() || 'Проект без названия') + '»' + (programName() ? '. Программа: ' + programName() : '') " @@ -143,7 +143,11 @@ @if (isProjectCard()) { -

{{ info().name }}

+

} @else if (type() === "projects" || type() === "invite") { @if (info().name) {

{{ info().name }}

diff --git a/projects/social_platform/src/app/ui/widgets/info-card/info-card.component.scss b/projects/social_platform/src/app/ui/widgets/info-card/info-card.component.scss index aace0eabf..541dd8399 100644 --- a/projects/social_platform/src/app/ui/widgets/info-card/info-card.component.scss +++ b/projects/social_platform/src/app/ui/widgets/info-card/info-card.component.scss @@ -1,21 +1,46 @@ /** @format */ @use "styles/ui-foundation"; - -/** @format */ - @use "styles/responsive"; .card { &__body { - @include ui-foundation.card; + @media screen and (max-width: 999px) { + @include ui-foundation.card; + } position: relative; display: flex; flex-direction: column; width: 156px; - height: auto; - min-height: 180px; + + @media screen and (max-width: 999px) { + height: auto; + } + + @media screen and (min-width: 1000px) { + height: 180px; + } + + @media screen and (max-width: 999px) { + min-height: 180px; + } + + @media screen and (min-width: 1000px) { + padding: 15px 0 12px; + } + + @media screen and (min-width: 1000px) { + background-color: var(--light-white); + } + + @media screen and (min-width: 1000px) { + border: 0.5px solid var(--medium-grey-for-outline); + } + + @media screen and (min-width: 1000px) { + border-radius: var(--rounded-xl); + } &--empty { background: transparent; @@ -38,7 +63,6 @@ } } - /* Ссылка занимает прежнее место контента; CTA внутри не создаёт второй tab stop. */ &__project-link { display: flex; flex: 1; @@ -52,11 +76,55 @@ } } - /* CTA занимает ширину контента, сохраняя единственную ссылку на проект. */ &__project-action { - @include ui-foundation.button; + @media screen and (max-width: 999px) { + @include ui-foundation.button; + } + + @media screen and (min-width: 1000px) { + display: inline-flex; + } + + @media screen and (min-width: 1000px) { + align-items: center; + } + + @media screen and (min-width: 1000px) { + justify-content: center; + } width: 100%; + + @media screen and (min-width: 1000px) { + padding: 4px 24px; + } + + @media screen and (min-width: 1000px) { + color: var(--white); + } + + @media screen and (min-width: 1000px) { + background: var(--accent); + } + + @media screen and (min-width: 1000px) { + border: 0.5px solid transparent; + } + + @media screen and (min-width: 1000px) { + border-radius: var(--rounded-xxl); + } + + @media screen and (min-width: 1000px) { + transition: all 0.2s; + } + + @media screen and (min-width: 1000px) { + &:hover { + background-color: var(--accent-medium); + box-shadow: -2px 3px 3px rgb(51 51 51 / 20%); + } + } } &__subscription-action { @@ -237,7 +305,6 @@ width: 100px; } - /* Общая геометрия проектов не затрагивает приглашения, участников и пустые карточки. */ &--project { .card__content { padding: 27px 12px 0; @@ -245,8 +312,6 @@ .card__head { width: 100%; - - /* Короткое название не резервирует пустую вторую строку перед описанием. */ margin-bottom: 2px; > div { @@ -256,7 +321,7 @@ } .card__name { - /* stylelint-disable-next-line value-no-vendor-prefix -- Префикс нужен для двухстрочного ellipsis. */ + /* stylelint-disable-next-line value-no-vendor-prefix */ display: -webkit-box; max-height: 30px; margin: 0; @@ -270,28 +335,42 @@ } .card__description { - /* Место удалённой отрасли отдано описанию без увеличения внешней карточки. */ flex: 0 0 52px; width: 100%; height: 52px; min-height: 52px; p { - /* stylelint-disable-next-line value-no-vendor-prefix -- Префикс ограничивает описание четырьмя строками. */ + /* stylelint-disable-next-line value-no-vendor-prefix */ display: -webkit-box; overflow: hidden; - font-size: var(--ui-font-caption); line-height: 13px; -webkit-line-clamp: 4; -webkit-box-orient: vertical; + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + } + + @media screen and (min-width: 1000px) { + font-size: 10px; + } } } .card__project-action-label { - font-size: var(--ui-font-caption); - font-weight: 600; line-height: 12px; white-space: nowrap; + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + font-weight: 600; + } + + @media screen and (min-width: 1000px) { + font-size: 10px; + font-weight: 600; + } } .card__footer, @@ -301,7 +380,6 @@ } } - /* Нижний блок имеет постоянную высоту: длинный текст не сдвигает роль и CTA. */ &--my-project { .card__body { padding-bottom: 8px; @@ -321,9 +399,16 @@ .card__name { max-height: 28px; - font-size: var(--ui-font-caption); line-height: 14px; text-align: center; + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + } + + @media screen and (min-width: 1000px) { + font-size: 11px; + } } .card__description { @@ -367,7 +452,6 @@ } } - /* Приглашения в списке и правой колонке используют одну компактную геометрию. */ &--invite { .card__body { padding-bottom: 6px; @@ -388,7 +472,7 @@ } .card__name { - /* stylelint-disable-next-line value-no-vendor-prefix -- Освободившаяся строка сохраняет длинное название. */ + /* stylelint-disable-next-line value-no-vendor-prefix */ display: -webkit-box; max-height: 30px; overflow: hidden; @@ -405,12 +489,19 @@ } .card__user { - font-size: var(--ui-font-caption); line-height: 13px; + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + } + + @media screen and (min-width: 1000px) { + font-size: 10px; + } } .card__user--invite { - /* stylelint-disable-next-line value-no-vendor-prefix -- Две строки сохраняют место для действий. */ + /* stylelint-disable-next-line value-no-vendor-prefix */ display: -webkit-box; overflow: hidden; font-size: var(--ui-font-small); @@ -556,78 +647,93 @@ } } -@include responsive.apply-mobile { - :host { - display: block; - width: 100%; - min-width: 0; - } - - .card__body { - width: 100%; - height: auto; - min-height: 200px; - } +@media screen and (max-width: 999px) { + @include responsive.apply-below-desktop { + :host { + display: block; + width: min(100%, var(--ui-mobile-entity-card-width)); + min-width: 0; + } - .card__content { - padding-right: 16px; - padding-left: 16px; - overflow: visible; - } + .card__body { + width: 100%; + height: auto; + min-height: 244px; + } - .card__head { - width: 100%; - } + .card__content { + padding-right: 16px; + padding-left: 16px; + overflow: visible; + } - .card__name { - max-width: 100%; - overflow-wrap: anywhere; - white-space: normal; - } + .card__head { + width: 100%; + } - .card--project, - .card--my-project { .card__name { - display: block; - max-height: none; - font-size: var(--ui-font-body); - line-height: 20px; - -webkit-line-clamp: unset; + max-width: 100%; + overflow-wrap: anywhere; + white-space: normal; } - .card__description { + .card--project, + .card--my-project { + .card__name { + display: block; + max-height: none; + font-size: var(--ui-font-body); + line-height: 20px; + -webkit-line-clamp: unset; + } + + .card__description { + height: auto; + font-size: var(--ui-font-body); + line-height: 20px; + } + } + + .card__context { height: auto; - font-size: var(--ui-font-body); - line-height: 20px; + min-height: 24px; + overflow-wrap: anywhere; + white-space: normal; } - } - .card__context { - height: auto; - min-height: 24px; - overflow-wrap: anywhere; - white-space: normal; - } + .card__role, + .card__access-label { + font-size: var(--ui-font-small); + line-height: 16px; + } - .card__role, - .card__access-label { - font-size: var(--ui-font-small); - line-height: 16px; - } + .card__description { + flex-basis: auto; + width: 100%; + height: auto; + min-height: 24px; + } - .card__description { - flex-basis: auto; - width: 100%; - height: auto; - min-height: 24px; - } + .card__project-action { + align-self: center; + width: auto; + min-height: 44px; + } - .card__project-action { - min-height: 44px; - } + .card--my-project .card__program-name { + font-size: var(--ui-font-small); + line-height: 16px; + } - .card__subscription-action { - width: 44px; - height: 44px; + .card--project .card__description p, + .card--my-project .card__description p { + font-size: var(--ui-font-small); + line-height: 18px; + } + + .card__subscription-action { + width: 44px; + height: 44px; + } } } diff --git a/projects/social_platform/src/app/ui/widgets/news-card/feed-news-modal/feed-news-modal.component.scss b/projects/social_platform/src/app/ui/widgets/news-card/feed-news-modal/feed-news-modal.component.scss index 2c89b44b7..6ba478aee 100644 --- a/projects/social_platform/src/app/ui/widgets/news-card/feed-news-modal/feed-news-modal.component.scss +++ b/projects/social_platform/src/app/ui/widgets/news-card/feed-news-modal/feed-news-modal.component.scss @@ -1,6 +1,5 @@ /** @format */ -/* Overlay находится вне host. Все правила ограничены локальным классом окна чтения. */ .modal .modal__body.feed-news-modal-body { box-sizing: border-box; display: block; @@ -35,19 +34,35 @@ &__badge { padding: 4px 10px; - font-size: var(--ui-font-caption); - font-weight: 600; color: var(--accent-dark); background: var(--accent-light); border-radius: var(--rounded-xxl); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + font-weight: 600; + } + + @media screen and (min-width: 1000px) { + font-size: 11px; + font-weight: 600; + } } time { margin-left: auto; - font-size: var(--ui-font-caption); - font-variant-numeric: tabular-nums; color: var(--grey-for-text); white-space: nowrap; + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + font-variant-numeric: tabular-nums; + } + + @media screen and (min-width: 1000px) { + font-size: 11px; + font-variant-numeric: tabular-nums; + } } button { @@ -69,7 +84,14 @@ padding: 0; font-size: 28px; line-height: 1; - border-radius: var(--ui-radius-dialog); + + @media screen and (max-width: 999px) { + border-radius: var(--ui-radius-dialog); + } + + @media screen and (min-width: 1000px) { + border-radius: var(--rounded-lg); + } } &__scroll { @@ -101,8 +123,15 @@ } &__source span { - font-size: var(--ui-font-caption); color: var(--grey-for-text); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + } + + @media screen and (min-width: 1000px) { + font-size: 11px; + } } &__source a { diff --git a/projects/social_platform/src/app/ui/widgets/news-card/feed-news-preview/feed-news-preview.component.scss b/projects/social_platform/src/app/ui/widgets/news-card/feed-news-preview/feed-news-preview.component.scss index 46b9097bf..d3e1c564e 100644 --- a/projects/social_platform/src/app/ui/widgets/news-card/feed-news-preview/feed-news-preview.component.scss +++ b/projects/social_platform/src/app/ui/widgets/news-card/feed-news-preview/feed-news-preview.component.scss @@ -1,9 +1,6 @@ /** @format */ @use "styles/ui-foundation"; - -/** @format */ - @use "styles/feed-card"; :host { @@ -12,7 +9,9 @@ } .feed-preview { - @include ui-foundation.card; + @media screen and (max-width: 999px) { + @include ui-foundation.card; + } cursor: pointer; @@ -23,7 +22,6 @@ outline-offset: 3px; } - /* Ссылки полного текста доступны в окне: скрытая часть clamp не создаёт невидимые tab-stop. */ .feed-card__description { white-space: pre-line; } @@ -98,10 +96,17 @@ right: 4px; bottom: 4px; padding: 2px 4px; - font-size: var(--ui-font-caption); color: var(--white); background: var(--ui-media-backdrop); border-radius: 4px; + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + } + + @media screen and (min-width: 1000px) { + font-size: 10px; + } } button.feed-preview__more { @@ -112,9 +117,16 @@ } &__attachments { - font-size: var(--ui-font-caption); line-height: 16px; color: var(--grey-for-text); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + } + + @media screen and (min-width: 1000px) { + font-size: 11px; + } } &__actions { diff --git a/projects/social_platform/src/app/ui/widgets/news-card/news-card.component.scss b/projects/social_platform/src/app/ui/widgets/news-card/news-card.component.scss index d49de7666..6fe340394 100644 --- a/projects/social_platform/src/app/ui/widgets/news-card/news-card.component.scss +++ b/projects/social_platform/src/app/ui/widgets/news-card/news-card.component.scss @@ -1,9 +1,6 @@ /** @format */ @use "styles/ui-foundation"; - -/** @format */ - @use "styles/typography"; @use "styles/responsive"; @@ -101,12 +98,12 @@ align-items: center; } - /* stylelint-disable value-no-vendor-prefix */ &__text { color: var(--grey-for-text); white-space: break-spaces; p { + /* stylelint-disable-next-line value-no-vendor-prefix */ display: -webkit-box; overflow: hidden; color: var(--black); @@ -127,7 +124,6 @@ -webkit-line-clamp: 3; } } - /* stylelint-enable value-no-vendor-prefix */ &__edit-files { display: flex; @@ -256,6 +252,8 @@ } } -.news { - @include ui-foundation.card; +@media screen and (max-width: 999px) { + .news { + @include ui-foundation.card; + } } diff --git a/projects/social_platform/src/app/ui/widgets/news-form/news-form.component.scss b/projects/social_platform/src/app/ui/widgets/news-form/news-form.component.scss index 4d65c475d..f8b4d5e3f 100644 --- a/projects/social_platform/src/app/ui/widgets/news-form/news-form.component.scss +++ b/projects/social_platform/src/app/ui/widgets/news-form/news-form.component.scss @@ -83,23 +83,25 @@ } } -@include responsive.apply-mobile { - .form__input { - min-width: 0; - } +@media screen and (max-width: 999px) { + @include responsive.apply-mobile { + .form__input { + min-width: 0; + } - .form__send { - flex-shrink: 0; - min-width: 44px; - min-height: 44px; - margin-left: 8px; - } + .form__send { + flex-shrink: 0; + min-width: 44px; + min-height: 44px; + margin-left: 8px; + } - .footer__attach { - display: inline-flex; - align-items: center; - justify-content: center; - min-width: 44px; - min-height: 44px; + .footer__attach { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 44px; + min-height: 44px; + } } } diff --git a/projects/social_platform/src/app/ui/widgets/project-invite/project-invite-dialog.component.scss b/projects/social_platform/src/app/ui/widgets/project-invite/project-invite-dialog.component.scss index c61da7a54..a164e32c7 100644 --- a/projects/social_platform/src/app/ui/widgets/project-invite/project-invite-dialog.component.scss +++ b/projects/social_platform/src/app/ui/widgets/project-invite/project-invite-dialog.component.scss @@ -1,25 +1,43 @@ /** @format */ -/* Стили portal ограничены оболочкой приглашения и не меняют остальные app-modal. */ .modal .modal__body.project-invite-body { left: 50%; display: block; - width: min(var(--ui-dialog-md), calc(100% - 24px)); - max-width: calc(100% - 24px); - max-height: min(720px, calc(var(--visual-viewport-height, 100dvh) - 48px)); padding: 0; overflow: visible; - border-radius: var(--ui-radius-dialog); + + @media screen and (max-width: 999px) { + width: min(var(--ui-dialog-md), calc(100% - 24px)); + max-width: calc(100% - 24px); + max-height: min(720px, calc(var(--visual-viewport-height, 100dvh) - 48px)); + border-radius: var(--ui-radius-dialog); + } + + @media screen and (min-width: 1000px) { + width: min(552px, calc(100% - 24px)); + max-width: calc(100% - 24px); + max-height: min(720px, calc(100dvh - 48px)); + border-radius: var(--rounded-lg); + } } .project-invite { display: flex; flex-direction: column; - max-height: min(720px, calc(var(--visual-viewport-height, 100dvh) - 48px)); - padding: var(--ui-dialog-padding); color: var(--black); background: var(--white); - border-radius: var(--ui-radius-dialog); + + @media screen and (max-width: 999px) { + max-height: min(720px, calc(var(--visual-viewport-height, 100dvh) - 48px)); + padding: var(--ui-dialog-padding); + border-radius: var(--ui-radius-dialog); + } + + @media screen and (min-width: 1000px) { + max-height: min(720px, calc(100dvh - 48px)); + padding: 24px; + border-radius: var(--rounded-lg); + } &, * { @@ -78,7 +96,14 @@ height: 48px; color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, white); - border-radius: var(--ui-radius-dialog); + + @media screen and (max-width: 999px) { + border-radius: var(--ui-radius-dialog); + } + + @media screen and (min-width: 1000px) { + border-radius: var(--rounded-lg); + } } &__close { @@ -144,13 +169,23 @@ justify-content: center; min-height: 44px; padding: 9px 12px; - font-size: var(--ui-font-body); - font-weight: 600; line-height: 1.4; color: var(--accent); background: var(--white); - border: 1px solid var(--accent); - border-radius: var(--ui-radius-dialog); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-body); + font-weight: 600; + border: 1px solid var(--accent); + border-radius: var(--ui-radius-dialog); + } + + @media screen and (min-width: 1000px) { + font-size: 13px; + font-weight: 600; + border: 1px solid var(--accent); + border-radius: var(--rounded-lg); + } } .invite-button--primary { @@ -169,8 +204,16 @@ min-height: 44px; padding: 0 12px; color: var(--grey-for-text); - border: 1px solid color-mix(in srgb, var(--accent) 45%, white); - border-radius: var(--ui-radius-dialog); + + @media screen and (max-width: 999px) { + border: 1px solid color-mix(in srgb, var(--accent) 45%, white); + border-radius: var(--ui-radius-dialog); + } + + @media screen and (min-width: 1000px) { + border: 1px solid color-mix(in srgb, var(--accent) 45%, white); + border-radius: var(--rounded-lg); + } } .invite-search:focus-within { @@ -196,9 +239,17 @@ .invite-label { display: block; margin-bottom: 8px; - font-size: var(--ui-font-body); - font-weight: 600; color: var(--accent); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-body); + font-weight: 600; + } + + @media screen and (min-width: 1000px) { + font-size: 13px; + font-weight: 600; + } } .invite-rows { @@ -216,8 +267,16 @@ padding: 10px 12px; text-align: left; background: var(--white); - border: 1px solid var(--medium-grey-for-outline); - border-radius: var(--ui-radius-dialog); + + @media screen and (max-width: 999px) { + border: 1px solid var(--medium-grey-for-outline); + border-radius: var(--ui-radius-dialog); + } + + @media screen and (min-width: 1000px) { + border: 1px solid var(--medium-grey-for-outline); + border-radius: var(--rounded-lg); + } } .invite-row--selected { @@ -260,19 +319,34 @@ .invite-copy strong { display: block; - font-size: var(--ui-font-body); - font-weight: 600; line-height: 1.5; overflow-wrap: anywhere; + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-body); + font-weight: 600; + } + + @media screen and (min-width: 1000px) { + font-size: 13px; + font-weight: 600; + } } .invite-meta { display: block; margin-top: 3px; - font-size: var(--ui-font-caption); line-height: 1.4; color: var(--grey-for-text); overflow-wrap: anywhere; + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + } + + @media screen and (min-width: 1000px) { + font-size: 11px; + } } .invite-avatar { @@ -286,7 +360,14 @@ font-weight: 600; color: var(--accent); background: color-mix(in srgb, var(--accent) 9%, white); - border-radius: var(--ui-radius-dialog); + + @media screen and (max-width: 999px) { + border-radius: var(--ui-radius-dialog); + } + + @media screen and (min-width: 1000px) { + border-radius: var(--rounded-lg); + } } .invite-avatar img { @@ -297,10 +378,17 @@ .invite-helper { padding: 22px 12px; - font-size: var(--ui-font-body); line-height: 1.6; color: var(--grey-for-text); text-align: center; + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-body); + } + + @media screen and (min-width: 1000px) { + font-size: 13px; + } } .invite-error { @@ -391,7 +479,6 @@ } } -/* Opt-in для окон команды: приглашение из профиля сохраняет прежнюю композицию. */ .project-invite.project-invite--compact { .project-invite__symbol { display: none; diff --git a/projects/social_platform/src/app/ui/widgets/project-invite/project-invite-role-input.component.scss b/projects/social_platform/src/app/ui/widgets/project-invite/project-invite-role-input.component.scss index b4657998d..9a3df46ff 100644 --- a/projects/social_platform/src/app/ui/widgets/project-invite/project-invite-role-input.component.scss +++ b/projects/social_platform/src/app/ui/widgets/project-invite/project-invite-role-input.component.scss @@ -1,4 +1,5 @@ /** @format */ + :host { display: block; min-width: 0; @@ -10,9 +11,17 @@ label { display: block; margin-bottom: 8px; - font-size: var(--ui-font-body); - font-weight: 600; color: var(--accent); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-body); + font-weight: 600; + } + + @media screen and (min-width: 1000px) { + font-size: 13px; + font-weight: 600; + } } input { @@ -39,9 +48,16 @@ p { margin: 6px 0 0; - font-size: var(--ui-font-caption); line-height: 1.4; color: var(--grey-for-text); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-caption); + } + + @media screen and (min-width: 1000px) { + font-size: 11px; + } } p.invalid { @@ -68,14 +84,22 @@ width: 100%; min-height: 44px; padding: 10px; - font: inherit; - font-size: var(--ui-font-body); color: var(--black); text-align: left; cursor: pointer; background: transparent; border: 0; border-radius: var(--rounded-lg); + + @media screen and (max-width: 999px) { + font: inherit; + font-size: var(--ui-font-body); + } + + @media screen and (min-width: 1000px) { + font: inherit; + font-size: 13px; + } } button.active, diff --git a/projects/social_platform/src/app/ui/widgets/project-vacancy-card/project-vacancy-card.component.scss b/projects/social_platform/src/app/ui/widgets/project-vacancy-card/project-vacancy-card.component.scss index caaca621c..333a2f7a2 100644 --- a/projects/social_platform/src/app/ui/widgets/project-vacancy-card/project-vacancy-card.component.scss +++ b/projects/social_platform/src/app/ui/widgets/project-vacancy-card/project-vacancy-card.component.scss @@ -1,9 +1,6 @@ /** @format */ @use "styles/ui-foundation"; - -/** @format */ - @use "styles/components/vacancy-ui"; :host { @@ -13,7 +10,10 @@ } .vacancy { - @include ui-foundation.card; + @media screen and (max-width: 999px) { + @include ui-foundation.card; + } + @include vacancy-ui.surface; display: flex; @@ -83,9 +83,16 @@ } &__project-name { - font-size: var(--ui-font-body); line-height: 20px; color: var(--black); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-body); + } + + @media screen and (min-width: 1000px) { + font-size: 13px; + } } &__specialization { @@ -99,12 +106,13 @@ font-size: var(--ui-font-body); line-height: 21px; } - /* stylelint-disable value-no-vendor-prefix */ + &__role, &__project-name, &__specialization, &__salary, &__description p { + /* stylelint-disable-next-line value-no-vendor-prefix */ display: -webkit-box; overflow: hidden; overflow-wrap: anywhere; @@ -124,7 +132,7 @@ @include vacancy-ui.link; } } - /* stylelint-enable value-no-vendor-prefix */ + &__empty { @include vacancy-ui.secondary; } diff --git a/projects/social_platform/src/app/ui/widgets/projects-filter/projects-filter.component.scss b/projects/social_platform/src/app/ui/widgets/projects-filter/projects-filter.component.scss index 3f54ff98b..2cdf708cb 100644 --- a/projects/social_platform/src/app/ui/widgets/projects-filter/projects-filter.component.scss +++ b/projects/social_platform/src/app/ui/widgets/projects-filter/projects-filter.component.scss @@ -106,3 +106,14 @@ } } } + +@media screen and (min-width: 1000px) { + .filter__titles button.ui-button { + font-family: Mont, sans-serif; + font-size: 10px; + font-style: normal; + font-weight: 400; + line-height: 130%; + color: var(--accent); + } +} diff --git a/projects/social_platform/src/app/ui/widgets/region-select/region-select.component.scss b/projects/social_platform/src/app/ui/widgets/region-select/region-select.component.scss index 30cd0e0f2..d23d13459 100644 --- a/projects/social_platform/src/app/ui/widgets/region-select/region-select.component.scss +++ b/projects/social_platform/src/app/ui/widgets/region-select/region-select.component.scss @@ -24,7 +24,14 @@ &:focus { border-color: var(--accent); - box-shadow: var(--ui-focus-ring); + + @media screen and (max-width: 999px) { + box-shadow: var(--ui-focus-ring); + } + + @media screen and (min-width: 1000px) { + box-shadow: 0 0 6px rgb(109 40 255 / 30%); + } } } @@ -36,7 +43,6 @@ &__clear { position: absolute; top: 50%; - right: var(--ui-space-xs); display: grid; place-items: center; padding: 4px; @@ -45,6 +51,14 @@ background: transparent; border: 0; transform: translateY(-50%); + + @media screen and (max-width: 999px) { + right: var(--ui-space-xs); + } + + @media screen and (min-width: 1000px) { + right: 14px; + } } &__legacy { diff --git a/projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.scss b/projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.scss index bdd14a950..2235c0b71 100644 --- a/projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.scss +++ b/projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.scss @@ -1,9 +1,6 @@ /** @format */ @use "styles/ui-foundation"; - -/** @format */ - @use "styles/components/vacancy-ui"; :host { @@ -13,13 +10,19 @@ } .vacancy { - @include ui-foundation.card; + @media screen and (max-width: 999px) { + @include ui-foundation.card; + } display: flex; flex-direction: column; gap: 16px; height: 100%; + @media screen and (min-width: 1000px) { + padding: 16px; + } + @include vacancy-ui.surface; &__header { diff --git a/projects/social_platform/src/app/ui/widgets/vacancy-created-dialog/vacancy-created-dialog.component.scss b/projects/social_platform/src/app/ui/widgets/vacancy-created-dialog/vacancy-created-dialog.component.scss index 6823383d3..cf4495263 100644 --- a/projects/social_platform/src/app/ui/widgets/vacancy-created-dialog/vacancy-created-dialog.component.scss +++ b/projects/social_platform/src/app/ui/widgets/vacancy-created-dialog/vacancy-created-dialog.component.scss @@ -55,5 +55,11 @@ app-button { flex-basis: auto; } + + @media screen and (min-width: 1000px) { + ::ng-deep .button { + min-height: 40px; + } + } } } diff --git a/projects/social_platform/src/app/ui/widgets/vacancy-filter/vacancy-filter.component.scss b/projects/social_platform/src/app/ui/widgets/vacancy-filter/vacancy-filter.component.scss index 85928ae79..1747438ee 100644 --- a/projects/social_platform/src/app/ui/widgets/vacancy-filter/vacancy-filter.component.scss +++ b/projects/social_platform/src/app/ui/widgets/vacancy-filter/vacancy-filter.component.scss @@ -53,6 +53,10 @@ > a ::ng-deep .button { width: 100%; + + @media screen and (min-width: 1000px) { + height: 38px; + } } @include responsive.apply-desktop { @@ -166,3 +170,14 @@ a:hover { cursor: pointer; } + +@media screen and (min-width: 1000px) { + .desktop__header button.ui-button { + font-family: Mont, sans-serif; + font-size: 10px; + font-style: normal; + font-weight: 400; + line-height: 130%; + color: var(--accent); + } +} diff --git a/projects/social_platform/src/app/ui/widgets/vacancy-skills/vacancy-skills.component.scss b/projects/social_platform/src/app/ui/widgets/vacancy-skills/vacancy-skills.component.scss index b47228d1e..576d749ac 100644 --- a/projects/social_platform/src/app/ui/widgets/vacancy-skills/vacancy-skills.component.scss +++ b/projects/social_platform/src/app/ui/widgets/vacancy-skills/vacancy-skills.component.scss @@ -22,10 +22,25 @@ } &__toggle { - min-height: 28px; + @media screen and (max-width: 999px) { + min-height: 44px; + } + + @media screen and (min-width: 1000px) { + min-height: 28px; + } + padding: 4px 10px; font: inherit; - font-size: var(--ui-font-body); + + @media screen and (max-width: 999px) { + font-size: var(--ui-font-body); + } + + @media screen and (min-width: 1000px) { + font-size: 13px; + } + line-height: 18px; color: var(--black); cursor: pointer; diff --git a/projects/social_platform/src/app/ui/widgets/vacancy-status/vacancy-status.component.scss b/projects/social_platform/src/app/ui/widgets/vacancy-status/vacancy-status.component.scss index ac84ea190..793a7890e 100644 --- a/projects/social_platform/src/app/ui/widgets/vacancy-status/vacancy-status.component.scss +++ b/projects/social_platform/src/app/ui/widgets/vacancy-status/vacancy-status.component.scss @@ -5,3 +5,38 @@ flex-shrink: 0; max-width: 100%; } + +@media screen and (min-width: 1000px) { + .status { + display: inline-flex; + align-items: center; + min-height: 26px; + padding: 3px 10px; + font-size: 12px; + font-weight: 400; + line-height: 18px; + color: var(--black); + overflow-wrap: anywhere; + background: var(--light-gray); + border: 1px solid var(--gray); + border-radius: var(--rounded-xxl); + + &--success { + color: var(--green-dark); + background: var(--green-light); + border-color: var(--green); + } + + &--pending { + color: var(--black); + background: var(--accent-light); + border-color: var(--accent-light); + } + + &--declined { + color: var(--black); + background: var(--red-light); + border-color: var(--red-light); + } + } +} diff --git a/projects/social_platform/src/styles.scss b/projects/social_platform/src/styles.scss index 61133c798..de6d8b584 100644 --- a/projects/social_platform/src/styles.scss +++ b/projects/social_platform/src/styles.scss @@ -27,10 +27,13 @@ :root { --app-height: 100vh; - --page-gutter: 16px; - @supports (height: 100dvh) { - --app-height: 100dvh; + @media screen and (max-width: 999px) { + --page-gutter: 16px; + + @supports (height: 100dvh) { + --app-height: 100dvh; + } } } diff --git a/projects/social_platform/src/styles/_course-task.scss b/projects/social_platform/src/styles/_course-task.scss index c68503472..c5e36045d 100644 --- a/projects/social_platform/src/styles/_course-task.scss +++ b/projects/social_platform/src/styles/_course-task.scss @@ -13,14 +13,12 @@ max-width: 100%; overflow-wrap: anywhere; } - .#{$name}__header, .#{$name}__body, .#{$name}__content { min-height: 0; padding: 16px; } - .#{$name}__files, .#{$name}__content { ::ng-deep app-upload-file .control { diff --git a/projects/social_platform/src/styles/_feed-card.scss b/projects/social_platform/src/styles/_feed-card.scss index 9ab53c322..83a269b96 100644 --- a/projects/social_platform/src/styles/_feed-card.scss +++ b/projects/social_platform/src/styles/_feed-card.scss @@ -1,198 +1,392 @@ /** @format */ -// Высоту задаёт содержимое самого высокого соседа в строке grid, а не общий media slot. -// CTA остаётся снизу строки; detail/profile этот миксин не используют. @mixin layout { - box-sizing: border-box; - display: flex; - flex-direction: column; - gap: 10px; - width: 100%; - min-width: 0; - height: 100%; - padding: 20px; - color: var(--feed-text, var(--black)); - background: var(--feed-background, var(--light-white)); - border: 1px solid var(--medium-grey-for-outline); - border-radius: var(--rounded-xl); - - > * { - flex-shrink: 0; + @media screen and (max-width: 999px) { + box-sizing: border-box; + display: flex; + flex-direction: column; + gap: 10px; + width: 100%; min-width: 0; - min-height: 0; - } + height: 100%; + padding: 20px; + color: var(--feed-text, var(--black)); + background: var(--feed-background, var(--light-white)); + border: 1px solid var(--medium-grey-for-outline); + border-radius: var(--rounded-xl); - a:focus-visible, - button:focus-visible { - outline: 2px solid var(--feed-text, var(--accent-dark)); - outline-offset: 3px; - } + > * { + flex-shrink: 0; + min-width: 0; + min-height: 0; + } - .feed-card__meta { - display: flex; - gap: 8px; - align-items: center; - justify-content: space-between; - min-height: 26px; - } + a:focus-visible, + button:focus-visible { + outline: 2px solid var(--feed-text, var(--accent-dark)); + outline-offset: 3px; + } - .feed-card__type { - display: inline-flex; - align-items: center; - height: 26px; - padding: 0 10px; - overflow: hidden; - font-size: 11px; - font-weight: 600; - line-height: 16px; - color: var(--accent-dark); - text-overflow: ellipsis; - white-space: nowrap; - background: var(--accent-light); - border: 1px solid transparent; - border-radius: var(--rounded-xxl); - } + .feed-card__meta { + display: flex; + gap: 8px; + align-items: center; + justify-content: space-between; + min-height: 26px; + } - .feed-card__date { - flex-shrink: 0; - font-size: 10px; - font-variant-numeric: tabular-nums; - line-height: 14px; - color: var(--feed-secondary, var(--grey-for-text)); - } + .feed-card__type { + display: inline-flex; + align-items: center; + height: 26px; + padding: 0 10px; + overflow: hidden; + font-size: 11px; + font-weight: 600; + line-height: 16px; + color: var(--accent-dark); + text-overflow: ellipsis; + white-space: nowrap; + background: var(--accent-light); + border: 1px solid transparent; + border-radius: var(--rounded-xxl); + } - .feed-card__source { - display: flex; - gap: 10px; - align-items: center; - min-height: 40px; - } + .feed-card__date { + flex-shrink: 0; + font-size: 10px; + font-variant-numeric: tabular-nums; + line-height: 14px; + color: var(--feed-secondary, var(--grey-for-text)); + } - .feed-card__avatar { - flex: 0 0 40px; - width: 40px; - height: 40px; - border-radius: 50%; - object-fit: cover; - } + .feed-card__source { + display: flex; + gap: 10px; + align-items: center; + min-height: 40px; + } - .feed-card__source-text { - display: flex; - flex-direction: column; - gap: 3px; - min-width: 0; - } + .feed-card__avatar { + flex: 0 0 40px; + width: 40px; + height: 40px; + border-radius: 50%; + object-fit: cover; + } - .feed-card__eyebrow { - font-size: 10px; - line-height: 14px; - color: var(--feed-secondary, var(--grey-for-text)); - } + .feed-card__source-text { + display: flex; + flex-direction: column; + gap: 3px; + min-width: 0; + } - .feed-card__source-name { - overflow: hidden; - font-size: 13px; - font-weight: 600; - line-height: 17px; - color: inherit; - text-overflow: ellipsis; - white-space: nowrap; - } + .feed-card__eyebrow { + font-size: 10px; + line-height: 14px; + color: var(--feed-secondary, var(--grey-for-text)); + } - /* stylelint-disable value-no-vendor-prefix -- Line-clamp ограничивает текст, сохраняя полное значение в DOM. */ - .feed-card__title, - .feed-card__description { - display: -webkit-box; - margin: 0; - overflow: hidden; - overflow-wrap: anywhere; - -webkit-box-orient: vertical; - } - /* stylelint-enable value-no-vendor-prefix */ + .feed-card__source-name { + overflow: hidden; + font-size: 13px; + font-weight: 600; + line-height: 17px; + color: inherit; + text-overflow: ellipsis; + white-space: nowrap; + } - .feed-card__title { - font-size: 18px; - font-weight: 600; - line-height: 22px; - -webkit-line-clamp: 2; - } + .feed-card__title, + .feed-card__description { + /* stylelint-disable-next-line value-no-vendor-prefix */ + display: -webkit-box; + margin: 0; + overflow: hidden; + overflow-wrap: anywhere; + -webkit-box-orient: vertical; + } - .feed-card__description { - font-size: 12px; - font-weight: 400; - line-height: 18px; - color: var(--feed-secondary, var(--grey-for-text)); - -webkit-line-clamp: 3; - } + .feed-card__title { + font-size: 18px; + font-weight: 600; + line-height: 22px; + -webkit-line-clamp: 2; + } - .feed-card__metadata { - display: flex; - flex-direction: column; - gap: 8px; - align-items: flex-start; - min-width: 0; + .feed-card__description { + font-size: 12px; + font-weight: 400; + line-height: 18px; + color: var(--feed-secondary, var(--grey-for-text)); + -webkit-line-clamp: 3; + } + + .feed-card__metadata { + display: flex; + flex-direction: column; + gap: 8px; + align-items: flex-start; + min-width: 0; - &:empty { - display: none; + &:empty { + display: none; + } } - } - .feed-card__skills { - display: flex; - gap: 6px; - width: 100%; - padding: 0; - margin: 0; - list-style: none; - } + .feed-card__skills { + display: flex; + flex-wrap: wrap; + gap: 6px; + width: 100%; + padding: 0; + margin: 0; + list-style: none; + } - .feed-card__chip { - box-sizing: border-box; - flex-shrink: 0; - max-width: 100%; - height: 24px; - padding: 4px 8px; - overflow: hidden; - font-size: 10px; - font-weight: 400; - line-height: 16px; - color: var(--accent-dark); - text-overflow: ellipsis; - white-space: nowrap; - background: var(--accent-light); - border-radius: var(--rounded-lg); - - &--skill { - flex-shrink: 1; - max-width: calc((100% - 18px) / 4); - } - - &--industry { - color: var(--green-dark); - background: var(--green-light); + .feed-card__chip { + box-sizing: border-box; + flex-shrink: 0; + max-width: 100%; + min-height: 24px; + padding: 4px 8px; + font-size: 12px; + font-weight: 400; + line-height: 16px; + color: var(--accent-dark); + overflow-wrap: anywhere; + white-space: normal; + background: var(--accent-light); + border-radius: var(--rounded-lg); + + &--skill { + flex-shrink: 1; + max-width: 100%; + } + + &--industry { + color: var(--green-dark); + background: var(--green-light); + } + } + + .feed-card__cta { + box-sizing: border-box; + display: flex; + align-items: center; + align-self: flex-start; + justify-content: center; + max-width: 100%; + min-height: 44px; + padding: 10px 16px; + margin-top: auto; + font-size: 12px; + font-weight: 600; + line-height: 16px; + color: var(--feed-cta-text, var(--white)); + text-align: center; + background: var(--feed-cta-background, var(--accent)); + border: 1px solid transparent; + border-radius: var(--rounded-xxl); + + &:hover { + filter: brightness(0.95); + } } } - .feed-card__cta { + @media screen and (min-width: 1000px) { box-sizing: border-box; display: flex; - align-items: center; - justify-content: center; + flex-direction: column; + gap: 10px; width: 100%; - height: 36px; - padding: 0 12px; - margin-top: auto; - font-size: 12px; - font-weight: 600; - line-height: 16px; - color: var(--feed-cta-text, var(--white)); - text-align: center; - background: var(--feed-cta-background, var(--accent)); - border: 1px solid transparent; - border-radius: var(--rounded-xxl); - - &:hover { - filter: brightness(0.95); + min-width: 0; + height: 100%; + padding: 20px; + color: var(--feed-text, var(--black)); + background: var(--feed-background, var(--light-white)); + border: 1px solid var(--medium-grey-for-outline); + border-radius: var(--rounded-xl); + + > * { + flex-shrink: 0; + min-width: 0; + min-height: 0; + } + + a:focus-visible, + button:focus-visible { + outline: 2px solid var(--feed-text, var(--accent-dark)); + outline-offset: 3px; + } + + .feed-card__meta { + display: flex; + gap: 8px; + align-items: center; + justify-content: space-between; + min-height: 26px; + } + + .feed-card__type { + display: inline-flex; + align-items: center; + height: 26px; + padding: 0 10px; + overflow: hidden; + font-size: 11px; + font-weight: 600; + line-height: 16px; + color: var(--accent-dark); + text-overflow: ellipsis; + white-space: nowrap; + background: var(--accent-light); + border: 1px solid transparent; + border-radius: var(--rounded-xxl); + } + + .feed-card__date { + flex-shrink: 0; + font-size: 10px; + font-variant-numeric: tabular-nums; + line-height: 14px; + color: var(--feed-secondary, var(--grey-for-text)); + } + + .feed-card__source { + display: flex; + gap: 10px; + align-items: center; + min-height: 40px; + } + + .feed-card__avatar { + flex: 0 0 40px; + width: 40px; + height: 40px; + border-radius: 50%; + object-fit: cover; + } + + .feed-card__source-text { + display: flex; + flex-direction: column; + gap: 3px; + min-width: 0; + } + + .feed-card__eyebrow { + font-size: 10px; + line-height: 14px; + color: var(--feed-secondary, var(--grey-for-text)); + } + + .feed-card__source-name { + overflow: hidden; + font-size: 13px; + font-weight: 600; + line-height: 17px; + color: inherit; + text-overflow: ellipsis; + white-space: nowrap; + } + + .feed-card__title, + .feed-card__description { + /* stylelint-disable-next-line value-no-vendor-prefix */ + display: -webkit-box; + margin: 0; + overflow: hidden; + overflow-wrap: anywhere; + -webkit-box-orient: vertical; + } + + .feed-card__title { + font-size: 18px; + font-weight: 600; + line-height: 22px; + -webkit-line-clamp: 2; + } + + .feed-card__description { + font-size: 12px; + font-weight: 400; + line-height: 18px; + color: var(--feed-secondary, var(--grey-for-text)); + -webkit-line-clamp: 3; + } + + .feed-card__metadata { + display: flex; + flex-direction: column; + gap: 8px; + align-items: flex-start; + min-width: 0; + + &:empty { + display: none; + } + } + + .feed-card__skills { + display: flex; + gap: 6px; + width: 100%; + padding: 0; + margin: 0; + list-style: none; + } + + .feed-card__chip { + box-sizing: border-box; + flex-shrink: 0; + max-width: 100%; + height: 24px; + padding: 4px 8px; + overflow: hidden; + font-size: 10px; + font-weight: 400; + line-height: 16px; + color: var(--accent-dark); + text-overflow: ellipsis; + white-space: nowrap; + background: var(--accent-light); + border-radius: var(--rounded-lg); + + &--skill { + flex-shrink: 1; + max-width: calc((100% - 18px) / 4); + } + + &--industry { + color: var(--green-dark); + background: var(--green-light); + } + } + + .feed-card__cta { + box-sizing: border-box; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 36px; + padding: 0 12px; + margin-top: auto; + font-size: 12px; + font-weight: 600; + line-height: 16px; + color: var(--feed-cta-text, var(--white)); + text-align: center; + background: var(--feed-cta-background, var(--accent)); + border: 1px solid transparent; + border-radius: var(--rounded-xxl); + + &:hover { + filter: brightness(0.95); + } } } } diff --git a/projects/social_platform/src/styles/_platform-responsive.scss b/projects/social_platform/src/styles/_platform-responsive.scss index 26ca0420e..164404ec5 100644 --- a/projects/social_platform/src/styles/_platform-responsive.scss +++ b/projects/social_platform/src/styles/_platform-responsive.scss @@ -2,119 +2,138 @@ @use "responsive"; -// Intrinsic sizing is shared by every page and every projected control. -app-root, -app-input, -app-textarea, -app-select, -app-autocomplete-input, -app-search, -app-upload-file, -app-file-item, -app-file-upload-item, -app-button, -ui-button { - min-width: 0; - max-width: 100%; -} - -h1, -h2, -h3, -h4, -p, -label, -.error { - overflow-wrap: anywhere; -} - -video, -iframe, -canvas { - max-width: 100%; -} - -// Connected controls opened inside the shared modal must stay above its backdrop. -.cdk-overlay-container { - z-index: 10010; -} - -// Opt-in primitives for new screens; use the same boundaries as existing components. -.responsive-header, -.responsive-actions { - display: flex; - flex-wrap: wrap; - gap: 12px; - align-items: center; - justify-content: space-between; - min-width: 0; -} - -.responsive-table { - min-width: 0; - max-width: 100%; - overflow-x: auto; - overscroll-behavior-inline: contain; -} - -.responsive-dialog-header, -.responsive-dialog-actions { - position: sticky; - z-index: 2; - background: inherit; -} - -.responsive-dialog-header { - top: 0; +@media screen and (max-width: 999px) { + app-root, + app-input, + app-textarea, + app-select, + app-autocomplete-input, + app-search, + app-upload-file, + app-file-item, + app-file-upload-item, + app-button, + ui-button { + min-width: 0; + max-width: 100%; + } } -.responsive-dialog-actions { - bottom: 0; - padding-bottom: env(safe-area-inset-bottom, 0); +@media screen and (max-width: 999px) { + h1, + h2, + h3, + h4, + p, + label, + .error { + overflow-wrap: anywhere; + } } -@include responsive.apply-mobile { - html { - scrollbar-gutter: auto; +@media screen and (max-width: 999px) { + video, + iframe, + canvas { + max-width: 100%; } +} - .text-body-10 { - font-size: 12px; - line-height: 18px; +@media screen and (max-width: 999px) { + .cdk-overlay-container { + z-index: 10010; } +} - .text-body-12 { - font-size: 14px; - line-height: 20px; +@media screen and (max-width: 999px) { + .responsive-header, + .responsive-actions { + display: flex; + flex-wrap: wrap; + gap: 12px; + align-items: center; + justify-content: space-between; + min-width: 0; } +} - input:not([type="checkbox"], [type="radio"]), - textarea, - select { +@media screen and (max-width: 999px) { + .responsive-table { min-width: 0; max-width: 100%; - font-size: 16px; + overflow-x: auto; + overscroll-behavior-inline: contain; } +} - .responsive-header, - .responsive-actions { - flex-direction: column; - align-items: stretch; +@media screen and (max-width: 999px) { + .responsive-dialog-header, + .responsive-dialog-actions { + position: sticky; + z-index: 2; + background: inherit; + } +} + +@media screen and (max-width: 999px) { + .responsive-dialog-header { + top: 0; } +} - .cdk-overlay-pane { - max-width: calc(100vw - 24px); +@media screen and (max-width: 999px) { + .responsive-dialog-actions { + bottom: 0; + padding-bottom: env(safe-area-inset-bottom, 0); } +} - .mat-datepicker-content { - max-width: 100%; - max-height: calc(100dvh - 24px); - overflow: auto; +@media screen and (max-width: 999px) { + @include responsive.apply-mobile { + html { + scrollbar-gutter: auto; + } + + .text-body-10 { + font-size: 12px; + line-height: 18px; + } + + .text-body-12 { + font-size: 14px; + line-height: 20px; + } + + input:not([type="checkbox"], [type="radio"]), + textarea, + select { + min-width: 0; + max-width: 100%; + font-size: 16px; + } + + .responsive-header, + .responsive-actions { + flex-direction: column; + align-items: stretch; + } + + .cdk-overlay-pane { + max-width: calc(100vw - 24px); + } + + .mat-datepicker-content { + max-width: 100%; + max-height: calc(100dvh - 24px); + overflow: auto; + } } } -@media screen and (max-width: 359px) { - :root { - --page-gutter: 12px; +@media screen and (max-width: 999px) { + @media screen and (max-width: 359px) { + :root { + --page-gutter: 12px; + } } } diff --git a/projects/social_platform/src/styles/_typography.scss b/projects/social_platform/src/styles/_typography.scss index d2c957ca1..80483ed1e 100644 --- a/projects/social_platform/src/styles/_typography.scss +++ b/projects/social_platform/src/styles/_typography.scss @@ -1,5 +1,155 @@ /** @format */ +@mixin heading-1 { + font-family: Mont, sans-serif; + font-size: 18px; + font-style: normal; + font-weight: 400; + line-height: 150%; +} + +@mixin heading-1-bold { + font-family: Mont, sans-serif; + font-size: 18px; + font-style: normal; + font-weight: 600; + line-height: 150%; +} + +@mixin heading-2 { + font-family: Mont, sans-serif; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 150%; +} + +@mixin heading-2-bold { + font-family: Mont, sans-serif; + font-size: 16px; + font-style: normal; + font-weight: 600; + line-height: 150%; +} + +@mixin heading-3 { + font-family: Mont, sans-serif; + font-size: 24px; + font-style: normal; + font-weight: 700; + line-height: 150%; +} + +@mixin heading-4 { + font-family: Mont, sans-serif; + font-size: 18px; + font-style: normal; + font-weight: 700; + line-height: 150%; +} + +@mixin body-18 { + font-family: Mont, sans-serif; + font-size: 18px; + font-style: normal; + font-weight: 600; + line-height: 150%; +} + +@mixin body-bold-18 { + font-family: Mont, sans-serif; + font-size: 18px; + font-style: normal; + font-weight: 800; + line-height: 130%; +} + +@mixin bold-body-16 { + font-family: Mont, sans-serif; + font-size: 16px; + font-style: normal; + font-weight: 700; + line-height: 150%; +} + +@mixin body-16 { + font-family: Mont, sans-serif; + font-size: 16px; + font-style: normal; + font-weight: 600; + line-height: 150%; +} + +@mixin bold-body-14 { + font-family: Mont, sans-serif; + font-size: 14px; + font-style: normal; + font-weight: 700; + line-height: 150%; +} + +@mixin body-14 { + font-family: Mont, sans-serif; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 150%; +} + +@mixin body-12 { + font-family: Mont, sans-serif; + font-size: 12px; + font-style: normal; + font-weight: 400; + line-height: 130%; +} + +@mixin body-12-bold { + font-family: Mont, sans-serif; + font-size: 12px; + font-style: normal; + font-weight: 600; + line-height: 130%; +} + +@mixin body-10 { + @media screen and (max-width: 999px) { + font-family: Mont, sans-serif; + font-size: var(--ui-font-caption); + font-style: normal; + font-weight: 400; + line-height: 130%; + color: var(--ui-text-muted); + } + + @media screen and (min-width: 1000px) { + font-family: Mont, sans-serif; + font-size: 10px; + font-style: normal; + font-weight: 400; + line-height: 130%; + color: var(--grey-button); + } +} + +@mixin body-6 { + @media screen and (max-width: 999px) { + font-family: Mont, sans-serif; + font-size: var(--ui-font-caption); + font-style: normal; + font-weight: 400; + line-height: 130%; + } + + @media screen and (min-width: 1000px) { + font-family: Mont, sans-serif; + font-size: 6px; + font-style: normal; + font-weight: 400; + line-height: 130%; + } +} + @font-face { font-family: Mont; font-style: normal; @@ -64,195 +214,66 @@ url("../assets/font/Mont-Regular.ttf") format("truetype"); } -@mixin heading-1 { - font-family: Mont, sans-serif; - font-size: 18px; - font-style: normal; - font-weight: 400; - line-height: 150%; -} - .text-heading-1 { @include heading-1; } -@mixin heading-1-bold { - font-family: Mont, sans-serif; - font-size: 18px; - font-style: normal; - font-weight: 600; - line-height: 150%; -} - .text-heading-1-bold { @include heading-1-bold; } -@mixin heading-2 { - font-family: Mont, sans-serif; - font-size: 16px; - font-style: normal; - font-weight: 400; - line-height: 150%; -} - .text-heading-2 { @include heading-2; } -@mixin heading-2-bold { - font-family: Mont, sans-serif; - font-size: 16px; - font-style: normal; - font-weight: 600; - line-height: 150%; -} - .text-heading-2-bold { @include heading-2-bold; } -@mixin heading-3 { - font-family: Mont, sans-serif; - font-size: 24px; - font-style: normal; - font-weight: 700; - line-height: 150%; -} - .text-heading-3 { @include heading-3; } -@mixin heading-4 { - font-family: Mont, sans-serif; - font-size: 18px; - font-style: normal; - font-weight: 700; - line-height: 150%; -} - .text-heading-4 { @include heading-4; } -@mixin body-18 { - font-family: Mont, sans-serif; - font-size: 18px; - font-style: normal; - font-weight: 600; - line-height: 150%; -} - .text-body-18 { @include body-18; } -@mixin body-bold-18 { - font-family: Mont, sans-serif; - font-size: 18px; - font-style: normal; - font-weight: 800; - line-height: 130%; -} - .text-body-bold-18 { @include body-18; } -@mixin bold-body-16 { - font-family: Mont, sans-serif; - font-size: 16px; - font-style: normal; - font-weight: 700; - line-height: 150%; -} - .text-bold-body-16 { @include bold-body-16; } -@mixin body-16 { - font-family: Mont, sans-serif; - font-size: 16px; - font-style: normal; - font-weight: 600; - line-height: 150%; -} - .text-body-16 { @include body-16; } -@mixin bold-body-14 { - font-family: Mont, sans-serif; - font-size: 14px; - font-style: normal; - font-weight: 700; - line-height: 150%; -} - .text-bold-body-14 { @include bold-body-14; } -@mixin body-14 { - font-family: Mont, sans-serif; - font-size: 14px; - font-style: normal; - font-weight: 400; - line-height: 150%; -} - .text-body-14 { @include body-14; } -@mixin body-12 { - font-family: Mont, sans-serif; - font-size: 12px; - font-style: normal; - font-weight: 400; - line-height: 130%; -} - .text-body-12 { @include body-12; } -@mixin body-12-bold { - font-family: Mont, sans-serif; - font-size: 12px; - font-style: normal; - font-weight: 600; - line-height: 130%; -} - .text-body-12-bold { @include body-12-bold; } -@mixin body-10 { - font-family: Mont, sans-serif; - font-size: var(--ui-font-caption); - font-style: normal; - font-weight: 400; - line-height: 130%; - color: var(--ui-text-muted); -} - .text-body-10 { @include body-10; } -@mixin body-6 { - font-family: Mont, sans-serif; - font-size: var(--ui-font-caption); - font-style: normal; - font-weight: 400; - line-height: 130%; -} - .text-body-6 { @include body-6; } diff --git a/projects/social_platform/src/styles/_ui-system.scss b/projects/social_platform/src/styles/_ui-system.scss index 75abcc461..397f054b0 100644 --- a/projects/social_platform/src/styles/_ui-system.scss +++ b/projects/social_platform/src/styles/_ui-system.scss @@ -2,206 +2,268 @@ @use "ui-foundation"; -button.ui-button.ui-button { - @include ui-foundation.button($layout: false); -} - -.ui-button { - display: inline-flex; - gap: var(--ui-space-sm); - align-items: center; - justify-content: center; +@media screen and (min-width: 1000px) { + :where(button.ui-button) { + padding: 0; + font: inherit; + color: inherit; + text-align: inherit; + cursor: pointer; + background: transparent; + border: 0; + } } -button.ui-button[role="radio"] { - justify-content: space-between; - width: 100%; - padding: var(--ui-control-padding); - color: var(--ui-text); - text-align: left; - background: var(--ui-surface-subtle); - border-color: var(--ui-border-subtle); - border-radius: var(--ui-radius-card); - - &[aria-checked="true"] { - background: var(--accent-light); - border-color: var(--ui-accent); +@media screen and (max-width: 999px) { + button.ui-button.ui-button { + @include ui-foundation.button($layout: false); } } -.ui-field { - @include ui-foundation.control; +@media screen and (max-width: 999px) { + .ui-button { + display: inline-flex; + gap: var(--ui-space-sm); + align-items: center; + justify-content: center; + } } -input.ui-choice.ui-choice { - min-height: 18px; - padding: 0; - background: transparent; - - @include ui-foundation.choice; +@media screen and (max-width: 999px) { + button.ui-button[role="radio"] { + justify-content: space-between; + width: 100%; + padding: var(--ui-control-padding); + color: var(--ui-text); + text-align: left; + background: var(--ui-surface-subtle); + border-color: var(--ui-border-subtle); + border-radius: var(--ui-radius-card); - appearance: auto; + &[aria-checked="true"] { + background: var(--accent-light); + border-color: var(--ui-accent); + } + } } -.ui-card { - @include ui-foundation.card; - - &--interactive { - transition: - box-shadow 0.2s, - border-color 0.2s; +@media screen and (max-width: 999px) { + .ui-field { + @include ui-foundation.control; } +} - &--interactive:hover { - border-color: var(--ui-accent); - box-shadow: var(--ui-card-hover-shadow); - } +@media screen and (max-width: 999px) { + input.ui-choice.ui-choice { + min-height: 18px; + padding: 0; + background: transparent; - &:focus-visible { - outline: 2px solid var(--accent-dark); - outline-offset: 3px; - } -} + @include ui-foundation.choice; -.ui-form { - min-width: 0; + appearance: auto; + } } -.ui-form label.field-label, -label.field-label { - margin-bottom: var(--ui-space-sm); - font-size: var(--ui-font-small); - line-height: 1.5; - color: var(--ui-text); +@media screen and (max-width: 999px) { + .ui-card { + @include ui-foundation.card; + + &--interactive { + transition: + box-shadow 0.2s, + border-color 0.2s; + } + + &--interactive:hover { + border-color: var(--ui-accent); + box-shadow: var(--ui-card-hover-shadow); + } + + &:focus-visible { + outline: 2px solid var(--accent-dark); + outline-offset: 3px; + } + } } -.ui-form .error, -.error { - font-size: var(--ui-font-small); - line-height: 1.5; - color: var(--ui-danger); +@media screen and (max-width: 999px) { + .ui-form { + min-width: 0; + } } -.ui-filters { - display: flex; - flex-direction: column; - gap: var(--ui-space-md); - min-width: 0; +@media screen and (max-width: 999px) { + .ui-form label.field-label, + label.field-label { + margin-bottom: var(--ui-space-sm); + font-size: var(--ui-font-small); + line-height: 1.5; + color: var(--ui-text); + } } -.ui-filters__header { - display: flex; - flex-wrap: wrap; - gap: var(--ui-space-xs); - align-items: center; - justify-content: space-between; - - > p, - > .ui-button { - flex-shrink: 0; +@media screen and (max-width: 999px) { + .ui-form .error, + .error { + font-size: var(--ui-font-small); + line-height: 1.5; + color: var(--ui-danger); } } -.ui-dialog-body { - min-width: 0; - font-size: var(--ui-font-body); - line-height: 1.5; - overflow-wrap: anywhere; +@media screen and (max-width: 999px) { + .ui-filters { + display: flex; + flex-direction: column; + gap: var(--ui-space-md); + min-width: 0; + } } -.ui-dialog-footer { - display: flex; - flex-wrap: wrap; - gap: var(--ui-space-sm); - align-items: center; - justify-content: flex-end; - padding-top: var(--ui-space-md); - margin-top: var(--ui-space-md); +@media screen and (max-width: 999px) { + .ui-filters__header { + display: flex; + flex-wrap: wrap; + gap: var(--ui-space-xs); + align-items: center; + justify-content: space-between; + + > p, + > .ui-button { + flex-shrink: 0; + } + } } -.ui-alert { - padding: var(--ui-space-md); - color: var(--ui-text); - background: var(--accent-light); - border-radius: var(--ui-radius-card); +@media screen and (max-width: 999px) { + .ui-dialog-body { + min-width: 0; + font-size: var(--ui-font-body); + line-height: 1.5; + overflow-wrap: anywhere; + } } -.ui-alert--error { - color: var(--red-dark); - background: var(--red-light); +@media screen and (max-width: 999px) { + .ui-dialog-footer { + display: flex; + flex-wrap: wrap; + gap: var(--ui-space-sm); + align-items: center; + justify-content: flex-end; + padding-top: var(--ui-space-md); + margin-top: var(--ui-space-md); + } } -.ui-alert--success { - color: var(--green-dark); - background: var(--green-light); +@media screen and (max-width: 999px) { + .ui-alert { + padding: var(--ui-space-md); + color: var(--ui-text); + background: var(--accent-light); + border-radius: var(--ui-radius-card); + } } -.ui-alert--warning { - color: var(--gold-dark); - background: var(--gold-light); +@media screen and (max-width: 999px) { + .ui-alert--error { + color: var(--red-dark); + background: var(--red-light); + } } -.ui-drawer { - min-width: 0; - max-width: 100vw; - overscroll-behavior: contain; +@media screen and (max-width: 999px) { + .ui-alert--success { + color: var(--green-dark); + background: var(--green-light); + } } -table.ui-table { - width: 100%; - font-size: var(--ui-font-small); - line-height: 1.5; - color: var(--ui-text); - border-collapse: collapse; - - th { - padding: 12px 16px; - font-weight: 600; - text-align: left; - background: var(--ui-surface-subtle); - border-bottom: 1px solid var(--ui-border); +@media screen and (max-width: 999px) { + .ui-alert--warning { + color: var(--gold-dark); + background: var(--gold-light); } +} - td { - padding: 12px 16px; - border-bottom: 1px solid var(--ui-border-subtle); +@media screen and (max-width: 999px) { + .ui-drawer { + min-width: 0; + max-width: 100vw; + overscroll-behavior: contain; } +} - tbody tr:hover { - background: var(--accent-light); +@media screen and (max-width: 999px) { + table.ui-table { + width: 100%; + font-size: var(--ui-font-small); + line-height: 1.5; + color: var(--ui-text); + border-collapse: collapse; + + th { + padding: 12px 16px; + font-weight: 600; + text-align: left; + background: var(--ui-surface-subtle); + border-bottom: 1px solid var(--ui-border); + } + + td { + padding: 12px 16px; + border-bottom: 1px solid var(--ui-border-subtle); + } + + tbody tr:hover { + background: var(--accent-light); + } } } -.ui-h1 { - font-size: var(--ui-font-h1); - font-weight: 600; - line-height: 1.3; +@media screen and (max-width: 999px) { + .ui-h1 { + font-size: var(--ui-font-h1); + font-weight: 600; + line-height: 1.3; + } } -.ui-h2 { - font-size: var(--ui-font-h2); - font-weight: 600; - line-height: 1.4; +@media screen and (max-width: 999px) { + .ui-h2 { + font-size: var(--ui-font-h2); + font-weight: 600; + line-height: 1.4; + } } -.ui-h3 { - font-size: var(--ui-font-h3); - font-weight: 600; - line-height: 1.4; +@media screen and (max-width: 999px) { + .ui-h3 { + font-size: var(--ui-font-h3); + font-weight: 600; + line-height: 1.4; + } } -.ui-body { - font-size: var(--ui-font-body); - line-height: 1.5; +@media screen and (max-width: 999px) { + .ui-body { + font-size: var(--ui-font-body); + line-height: 1.5; + } } -.ui-small { - font-size: var(--ui-font-small); - line-height: 1.5; +@media screen and (max-width: 999px) { + .ui-small { + font-size: var(--ui-font-small); + line-height: 1.5; + } } -.ui-caption { - font-size: var(--ui-font-caption); - line-height: 1.5; - color: var(--ui-text-muted); +@media screen and (max-width: 999px) { + .ui-caption { + font-size: var(--ui-font-caption); + line-height: 1.5; + color: var(--ui-text-muted); + } } diff --git a/projects/social_platform/src/styles/_ui-tokens.scss b/projects/social_platform/src/styles/_ui-tokens.scss index 765fa3aae..e67559647 100644 --- a/projects/social_platform/src/styles/_ui-tokens.scss +++ b/projects/social_platform/src/styles/_ui-tokens.scss @@ -18,6 +18,7 @@ --ui-radius-dialog: var(--rounded-xl); --ui-control-height: 44px; --ui-compact-sidebar-width: 157px; + --ui-mobile-entity-card-width: 260px; --ui-control-padding: 12px 16px; --ui-card-padding: 16px; --ui-dialog-padding: 24px; diff --git a/projects/social_platform/src/styles/components/_vacancy-ui.scss b/projects/social_platform/src/styles/components/_vacancy-ui.scss index 02d37e78f..185bdc471 100644 --- a/projects/social_platform/src/styles/components/_vacancy-ui.scss +++ b/projects/social_platform/src/styles/components/_vacancy-ui.scss @@ -3,15 +3,27 @@ @use "styles/ui-foundation"; @mixin surface { - @include ui-foundation.card; + @media screen and (max-width: 999px) { + @include ui-foundation.card; - min-width: 0; - padding: var(--ui-card-padding); - color: var(--black); - overflow-wrap: anywhere; - background: var(--white); - border: 1px solid var(--medium-grey-for-outline); - border-radius: var(--ui-radius-card); + min-width: 0; + padding: var(--ui-card-padding); + color: var(--black); + overflow-wrap: anywhere; + background: var(--white); + border: 1px solid var(--medium-grey-for-outline); + border-radius: var(--ui-radius-card); + } + + @media screen and (min-width: 1000px) { + min-width: 0; + padding: 20px; + color: var(--black); + overflow-wrap: anywhere; + background: var(--white); + border: 1px solid var(--medium-grey-for-outline); + border-radius: var(--rounded-lg); + } } @mixin secondary { @@ -38,7 +50,6 @@ } } -// Feature-адаптер Pattern / PageHeader; глобальный BackComponent не меняется. @mixin page-header { display: flex; flex-direction: column; @@ -71,12 +82,42 @@ } @mixin actions { - display: flex; - flex-wrap: wrap; - gap: 8px; + @media screen and (max-width: 999px) { + display: flex; + flex-wrap: wrap; + gap: 8px; + + app-button { + flex: 1 1 140px; + min-width: 0; + } + } - app-button { - flex: 1 1 140px; - min-width: 0; + @media screen and (min-width: 1000px) { + display: flex; + flex-wrap: wrap; + gap: 8px; + + app-button { + flex: 1 1 140px; + min-width: 0; + } + + ::ng-deep .button { + gap: 6px; + width: 100%; + min-height: 36px; + max-height: none; + padding: 8px 12px; + font-size: 12px; + line-height: 18px; + + @include focus; + + &.button--outline.button--red { + color: var(--black); + background: transparent; + } + } } } diff --git a/projects/ui/src/lib/components/layout/page-header/page-header.component.scss b/projects/ui/src/lib/components/layout/page-header/page-header.component.scss index 4fccfa53b..594c404d4 100644 --- a/projects/ui/src/lib/components/layout/page-header/page-header.component.scss +++ b/projects/ui/src/lib/components/layout/page-header/page-header.component.scss @@ -1,61 +1,78 @@ /** @format */ -:host { - display: block; - width: 100%; - min-width: 0; -} +@media screen and (min-width: 1000px) { + :host, + .page-header, + .page-header__heading, + .page-header__title-row { + display: contents; + } -.page-header { - display: flex; - flex-wrap: wrap; - gap: var(--ui-space-md); - align-items: center; - justify-content: space-between; - margin-bottom: var(--ui-space-lg); + .page-header__title { + display: none; + } +} - &__heading { +@media screen and (max-width: 999px) { + :host { + display: block; + width: 100%; min-width: 0; } +} - &__title-row { +@media screen and (max-width: 999px) { + .page-header { display: flex; - gap: var(--ui-space-sm); + flex-wrap: wrap; + gap: var(--ui-space-md); align-items: center; - } + justify-content: space-between; + margin-bottom: var(--ui-space-lg); - &__title { - font-size: var(--ui-font-h1); - font-weight: 600; - line-height: 1.3; - color: var(--ui-text); - overflow-wrap: anywhere; - } + &__heading { + min-width: 0; + } - &__description { - margin-top: var(--ui-space-sm); - font-size: var(--ui-font-body); - line-height: 1.5; - color: var(--ui-text-muted); - } + &__title-row { + display: flex; + gap: var(--ui-space-sm); + align-items: center; + } - &__breadcrumbs { - display: flex; - flex-wrap: wrap; - gap: var(--ui-space-sm); - margin-bottom: var(--ui-space-sm); - font-size: var(--ui-font-caption); - } + &__title { + font-size: var(--ui-font-h1); + font-weight: 600; + line-height: 1.3; + color: var(--ui-text); + overflow-wrap: anywhere; + } - &__actions { - display: flex; - flex-wrap: wrap; - gap: var(--ui-space-sm); - align-items: center; - max-width: 100%; - } + &__description { + margin-top: var(--ui-space-sm); + font-size: var(--ui-font-body); + line-height: 1.5; + color: var(--ui-text-muted); + } - &__actions:empty { - display: none; + &__breadcrumbs { + display: flex; + flex-wrap: wrap; + gap: var(--ui-space-sm); + margin-bottom: var(--ui-space-sm); + font-size: var(--ui-font-caption); + } + + &__actions { + display: flex; + flex-wrap: wrap; + gap: var(--ui-space-sm); + align-items: center; + max-width: 100%; + } + + &__actions:empty { + display: none; + } } } diff --git a/projects/ui/src/lib/components/layout/page-header/page-header.component.ts b/projects/ui/src/lib/components/layout/page-header/page-header.component.ts index 00d1abb72..31d08a3dc 100644 --- a/projects/ui/src/lib/components/layout/page-header/page-header.component.ts +++ b/projects/ui/src/lib/components/layout/page-header/page-header.component.ts @@ -1,8 +1,9 @@ /** @format */ -import { ChangeDetectionStrategy, Component, input } from "@angular/core"; +import { ChangeDetectionStrategy, Component, inject, input } from "@angular/core"; import { RouterLink } from "@angular/router"; import { BackComponent } from "../../primitives/back/back.component"; +import { DesktopLayoutService } from "../../../services/desktop-layout.service"; export interface PageBreadcrumb { label: string; @@ -28,7 +29,11 @@ export interface PageBreadcrumb { }
@if (backRoute()) { - + }

{{ title() }}

@@ -43,6 +48,7 @@ export interface PageBreadcrumb { changeDetection: ChangeDetectionStrategy.OnPush, }) export class PageHeaderComponent { + protected readonly desktopLayout = inject(DesktopLayoutService).desktop; readonly title = input.required(); readonly description = input(); readonly breadcrumbs = input([]); diff --git a/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.html b/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.html index 7727bd3eb..5a5c47002 100644 --- a/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.html +++ b/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.html @@ -2,17 +2,39 @@
-
-
- @if (hasNotifications() || hasInvites) { -
- } - - @if (invites().length) { -
- } + @if (desktopLayout()) { +
+
+ @if (hasNotifications() || hasInvites) { +
+ } + + @if (invites().length) { +
+ } +
-
+ } @else { + + } @if (showNotifications) {
    @@ -30,7 +52,7 @@
} -
+
diff --git a/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.scss b/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.scss index d582e47ea..eeb01e411 100644 --- a/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.scss +++ b/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.scss @@ -64,7 +64,13 @@ } i { - color: var(--light-white); + @media screen and (max-width: 999px) { + color: var(--ui-text-muted); + } + + @media screen and (min-width: 1000px) { + color: var(--light-white); + } @include responsive.apply-desktop { color: var(--dark-grey); @@ -72,30 +78,44 @@ } } -@include responsive.apply-below-desktop { - .control-panel { - position: static; - } +@media screen and (max-width: 999px) { + @include responsive.apply-below-desktop { + .control-panel { + position: static; + } - .control-panel__actions { - gap: 0; - margin-right: 4px; - } + .control-panel__actions { + gap: 0; + margin-right: 0; + } - .control-panel__action { - display: flex; - align-items: center; - justify-content: center; - min-width: 44px; - min-height: 44px; - } + .control-panel__action { + display: flex; + align-items: center; + justify-content: center; + min-width: 44px; + min-height: 44px; + } + + .control-panel__action--logout { + display: none; + } + + .control-panel__profile { + display: flex; + align-items: center; + justify-content: center; + width: 44px; + min-height: 44px; + } - .control-panel__notifications { - position: fixed; - top: 64px; - right: var(--page-gutter); - left: var(--page-gutter); - max-height: calc(var(--visual-viewport-height, 100dvh) - 80px); - overflow-y: auto; + .control-panel__notifications { + position: fixed; + top: 64px; + right: var(--page-gutter); + left: var(--page-gutter); + max-height: calc(var(--visual-viewport-height, 100dvh) - 80px); + overflow-y: auto; + } } } diff --git a/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.ts b/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.ts index 80ecd205d..b6e9f1dbb 100644 --- a/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.ts +++ b/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.ts @@ -1,7 +1,11 @@ /** @format */ +import { DesktopLayoutService } from "../../../services/desktop-layout.service"; +/** @format */ + import { CommonModule } from "@angular/common"; import { + inject, ChangeDetectionStrategy, Component, Input, @@ -18,6 +22,7 @@ import type { Invite } from "projects/social_platform/src/app/domain/invite/invi import { RouterLink } from "@angular/router"; import { EmptyManageCardComponent } from "../empty-manage-card/empty-manage-card.component"; import { User } from "@domain/auth/user.model"; +import { ButtonDirective } from "../../primitives/button/button.directive"; /** * Компонент панели управления профилем @@ -48,12 +53,14 @@ import { User } from "@domain/auth/user.model"; ClickOutsideModule, IconComponent, EmptyManageCardComponent, + ButtonDirective, ], templateUrl: "./profile-control-panel.component.html", styleUrl: "./profile-control-panel.component.scss", changeDetection: ChangeDetectionStrategy.OnPush, }) export class ProfileControlPanelComponent { + protected readonly desktopLayout = inject(DesktopLayoutService).desktop; /** Данные текущего пользователя */ readonly user = input.required(); diff --git a/projects/ui/src/lib/components/layout/profile-info/profile-info.component.html b/projects/ui/src/lib/components/layout/profile-info/profile-info.component.html index c9885743e..57394a0d7 100644 --- a/projects/ui/src/lib/components/layout/profile-info/profile-info.component.html +++ b/projects/ui/src/lib/components/layout/profile-info/profile-info.component.html @@ -1,7 +1,7 @@ @if (user()) { -
+
- - @if (loader()) { + + @if (loader() && desktopLayout()) { + + } @else if (loader()) { diff --git a/projects/ui/src/lib/components/primitives/button/button.component.scss b/projects/ui/src/lib/components/primitives/button/button.component.scss index ec35247f7..1436af14a 100644 --- a/projects/ui/src/lib/components/primitives/button/button.component.scss +++ b/projects/ui/src/lib/components/primitives/button/button.component.scss @@ -1,35 +1,265 @@ /** @format */ @use "styles/ui-foundation"; +@use "styles/typography"; -:host { - display: inline-block; - min-width: 0; - max-width: 100%; +@media screen and (min-width: 1000px) { + .button.button--loading .button__content.button__content--desktop-loading { + position: absolute; + display: block; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip-path: inset(50%); + white-space: nowrap; + border: 0; + } + + .button.button--loading:not(.button--disabled):disabled { + opacity: 1; + } + + .button__content, + .button.button--inline .button__content, + .button.button--outline .button__content { + display: contents; + } +} + +@media screen and (max-width: 999px) { + :host { + display: inline-block; + min-width: 0; + max-width: 100%; + } } .button { - @include ui-foundation.button; + @media screen and (max-width: 999px) { + @include ui-foundation.button; + } position: relative; - &__content { + @media screen and (max-width: 999px) { + &__content { + display: inline-flex; + gap: var(--ui-space-sm); + align-items: center; + justify-content: center; + min-width: 0; + } + } + + @media screen and (max-width: 999px) { + &__content--loading { + opacity: 0; + } + } + + @media screen and (max-width: 999px) { + &__loader { + position: absolute; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + } + } + + @media screen and (min-width: 1000px) { display: inline-flex; - gap: var(--ui-space-sm); + } + + @media screen and (min-width: 1000px) { align-items: center; + } + + @media screen and (min-width: 1000px) { justify-content: center; - min-width: 0; } - &__content--loading { - opacity: 0; + @media screen and (min-width: 1000px) { + max-height: 40px; } - &__loader { - position: absolute; - inset: 0; - display: flex; - align-items: center; - justify-content: center; + @media screen and (min-width: 1000px) { + text-align: center; + } + + @media screen and (min-width: 1000px) { + cursor: pointer; + } + + @media screen and (min-width: 1000px) { + border-radius: var(--rounded-xxl); + } + + @media screen and (min-width: 1000px) { + transition: all 0.2s; + } + + @media screen and (min-width: 1000px) { + &:disabled { + cursor: not-allowed; + opacity: 0.5; + } + } + + @media screen and (min-width: 1000px) { + &.button--inline { + font-weight: 400; + color: var(--white); + background: var(--accent); + border: 0.5px solid transparent; + outline: none; + + &:hover { + background-color: var(--accent-medium); + box-shadow: -2px 3px 3px rgb(51 51 51 / 20%); + } + + ::ng-deep *:not(.dot-wave) { + display: block; + + &:not(:last-child) { + margin-right: 10px; + } + } + + &.button--red { + background-color: var(--red); + + &:hover { + background-color: var(--red-dark); + } + } + + &.button--gradient { + background: var(--gradient); + + &:hover { + background: var(--gradient-mild); + } + } + + &.button--grey { + color: var(--black); + background-color: var(--grey-button); + } + + &.button--green { + color: var(--white); + background-color: var(--green); + } + + &.button--gold { + color: var(--white); + background: var(--gold-dark); + } + + &.button--white { + color: var(--accent); + background: var(--white); + } + + &.button--no-border { + border: none; + } + } + } + + @media screen and (min-width: 1000px) { + &.button--outline { + color: var(--accent); + background: transparent; + border: 0.5px solid var(--accent); + + &:hover { + color: var(--accent-medium); + border-color: var(--accent-medium); + box-shadow: -2px 3px 3px rgb(51 51 51 / 20%); + } + + &.button--red { + color: var(--red); + border-color: var(--red); + + &:hover { + color: var(--red-dark); + border-color: var(--red-dark); + } + } + + &.button--gold { + color: var(--gold); + border-color: var(--gold); + } + + &.button--white { + color: var(--white); + border: 0.5px solid var(--white); + } + + &.button--green { + color: var(--green); + border: 0.5px solid var(--green); + } + + &.button--no-border { + border: none; + } + + ::ng-deep *:not(.dot-wave) { + display: block; + + &:not(:last-child) { + margin-right: 10px; + } + } + } + } + + @media screen and (min-width: 1000px) { + &--extra-small { + width: 70px; + padding: 2px 10px; + } + } + + @media screen and (min-width: 1000px) { + &--small { + width: 100px; + padding: 4px 24px; + + &--icon { + padding: 12px 24px; + } + } + } + + @media screen and (min-width: 1000px) { + &--medium { + width: 157px; + padding: 4px 0; + + &--icon { + padding: 12px 60px; + } + } + } + + @media screen and (min-width: 1000px) { + &--big { + width: 100%; + padding: 4px 24px; + + &--icon { + width: 100%; + padding: 12px 24px; + } + } } } diff --git a/projects/ui/src/lib/components/primitives/button/button.component.ts b/projects/ui/src/lib/components/primitives/button/button.component.ts index 066f49ec9..a38f2ec99 100644 --- a/projects/ui/src/lib/components/primitives/button/button.component.ts +++ b/projects/ui/src/lib/components/primitives/button/button.component.ts @@ -1,8 +1,9 @@ /** @format */ -import { ChangeDetectionStrategy, Component, computed, input } from "@angular/core"; +import { ChangeDetectionStrategy, Component, computed, inject, input } from "@angular/core"; import { CommonModule } from "@angular/common"; import { LoaderComponent } from "../loader/loader.component"; +import { DesktopLayoutService } from "../../../services/desktop-layout.service"; @Component({ selector: "app-button", @@ -12,6 +13,7 @@ import { LoaderComponent } from "../loader/loader.component"; changeDetection: ChangeDetectionStrategy.OnPush, }) export class ButtonComponent { + protected readonly desktopLayout = inject(DesktopLayoutService).desktop; variant = input<"primary" | "secondary" | "danger">(); color = input<"primary" | "red" | "grey" | "green" | "gold" | "gradient" | "white">("primary"); loader = input(false); diff --git a/projects/ui/src/lib/components/primitives/icon/icon.component.html b/projects/ui/src/lib/components/primitives/icon/icon.component.html index 9620d9a58..6cf79770d 100644 --- a/projects/ui/src/lib/components/primitives/icon/icon.component.html +++ b/projects/ui/src/lib/components/primitives/icon/icon.component.html @@ -2,9 +2,17 @@