Веб-часть админки на всю ширину (edge-to-edge, как в request-portal)
Tests / frontend-test (pull_request) Successful in 47s
Tests / backend-test (pull_request) Successful in 1m48s

Канву SharePoint мы и раньше разжимали (тот же :global хак + supportsFullBleed
в манифесте), но содержимое упиралось в max-width: 1080px у .content и
центрировалось — визуально это читалось как «не открывается на всю ширину».

Переношу раскладку портала (RequestPortal.module.scss):
- корень .approvalAdmin — width: 100%, padding: 0;
- .shell больше не карточка: без рамки, тени, скруглений и overflow: hidden
  (последний ломает sticky), align-items: flex-start, min-height: 78vh;
- .side — заливка $navy-800 на колонке (align-self: stretch), сам Sidebar
  внутри sticky на 100vh: градиент не плывёт от высоты соседа, и под рейлом
  на длинных таблицах нет белого провала, если sticky не включился;
- .content — сняты max-width и margin: auto, остались только отступы;
- мобильный брейкпоинт обновлён под новую схему: десктопные правила рейла
  снимаются явно, иначе sticky+100vh спорил бы с position: fixed, который
  ui-kit ставит drawer'у, при равной специфичности.

Разметка AdminApp.tsx не менялась — структура уже совпадала с портальной.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
gorbenko.pavel
2026-08-25 13:37:22 +05:00
parent ba48ed1a0e
commit 3421922a08
2 changed files with 49 additions and 11 deletions
@@ -14,6 +14,16 @@
.approvalAdmin { .approvalAdmin {
font-family: $font-sans; font-family: $font-sans;
box-sizing: border-box;
// Полная ширина обеспечивается через "supportsFullBleed": true в манифесте
// + снятым max-width канвы выше. Корень занимает 100% контейнера, без
// CSS-трюков с 100vw.
width: 100%;
// App-shell «edge-to-edge» (как в request-portal): рейл примыкает к левому
// краю, отступы — внутри main.
padding: 0;
} }
.stateBox { .stateBox {
@@ -2,39 +2,54 @@
// Раскладка — тот же боковой рейл + основная область, что и в request-portal // Раскладка — тот же боковой рейл + основная область, что и в request-portal
// (@tnsu/ui-kit Sidebar, см. RequestPortal.module.scss): единый стиль // (@tnsu/ui-kit Sidebar, см. RequestPortal.module.scss): единый стиль
// навигации во всех веб-частях Tnsu. В отличие от request-portal (рейл во всю // навигации во всех веб-частях Tnsu. Как и там, это не карточка на странице
// высоту окна, edge-to-edge), здесь виджет — ограниченная карточка на странице // SharePoint, а edge-to-edge app-shell: без рамки/тени/скруглений и без
// SharePoint, поэтому без sticky/100vh-трюков: рейл просто растягивается по // ограничения ширины контента — рейл примыкает к левому краю канвы.
// высоте своего соседа (.main) через align-items: stretch.
.shell { .shell {
display: flex; display: flex;
align-items: stretch; align-items: flex-start; // рейл тянется не по контенту, а по своей колонке — см. .side
border-radius: $r-lg; width: 100%;
border: 1px solid $gray-200; min-height: 78vh; // «присутствие» рейла даже когда контента мало
overflow: hidden;
box-shadow: $sh-1;
font-family: $font-sans; font-family: $font-sans;
font-size: $fs-body; font-size: $fs-body;
line-height: 1.55; line-height: 1.55;
} }
// Рейл-колонка. Ровно та же схема, что в request-portal: КОЛОНКА тянется во всю
// высоту раскладки и закрашена $navy-800 (цветом, которым градиент рейла
// заканчивается), а сам РЕЙЛ внутри — sticky на 100vh поверх этой заливки.
// Так градиент не меняет оттенок от высоты соседней колонки, а под рейлом на
// длинных таблицах нет белого провала, даже если sticky в SharePoint не
// включился (прокручивается внутренний контейнер страницы, а не окно).
// Из-за sticky у .shell не должно быть overflow: hidden.
.side { .side {
flex: 0 0 auto; flex: 0 0 auto;
display: flex; display: flex;
align-self: stretch;
background: $navy-800; background: $navy-800;
// Прямой потомок — корень Sidebar из @tnsu/ui-kit (своего класса снаружи не
// видно, поэтому селектор по структуре, а не по имени).
> * {
position: sticky;
top: 0;
height: 100vh;
}
} }
.main { .main {
flex: 1 1 auto; flex: 1 1 auto;
min-width: 0; // чтобы контент не распирал колонку min-width: 0; // чтобы контент не распирал колонку
display: flex;
flex-direction: column;
background: linear-gradient(180deg, #F6F8FA 0%, #EEF2F6 100%); background: linear-gradient(180deg, #F6F8FA 0%, #EEF2F6 100%);
color: $gray-900; color: $gray-900;
} }
// Отступы контента — здесь, а не на .main: без max-width/margin:auto контент
// занимает всю доступную ширину (edge-to-edge, как в портале).
.content { .content {
padding: 28px 30px 36px; padding: 28px 30px 36px;
max-width: 1080px;
margin: 0 auto;
} }
// Мобильная кнопка-бургер (открывает выезжающий Sidebar). На десктопе скрыта. // Мобильная кнопка-бургер (открывает выезжающий Sidebar). На десктопе скрыта.
@@ -48,13 +63,26 @@
// media-query, без участия JS) — НЕ display:none на .side: рейл вёрстке всё // media-query, без участия JS) — НЕ display:none на .side: рейл вёрстке всё
// равно нужен в потоке, чтобы при mobileOpen выехать поверх контента. // равно нужен в потоке, чтобы при mobileOpen выехать поверх контента.
@media (max-width: 768px) { @media (max-width: 768px) {
.shell {
min-height: 0;
}
.mobileNav { .mobileNav {
display: block; display: block;
} }
// Снимаем десктопные правила рейла явно. Здесь ui-kit сам делает Sidebar
// position:fixed (top/bottom/left), и наш sticky+100vh спорил бы с ним при
// равной специфичности — исход решался бы порядком подключения стилей.
// Заливка колонки тоже не нужна: колонка схлопнута, drawer красит себя сам.
.side { .side {
align-self: flex-start; align-self: flex-start;
background: none; background: none;
> * {
position: static;
height: auto;
}
} }
} }