< Summary

Information
Class: AspNetCoreGeneratedDocument.Views_Shared__Layout
Assembly: OzonOrdersWeb
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Views/Shared/_Layout.cshtml
Line coverage
0%
Covered lines: 0
Uncovered lines: 27
Coverable lines: 27
Total lines: 704
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 160
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
ExecuteAsync()0%1482380%
<ExecuteAsync()0%1806420%
<ExecuteAsync()100%210%
<ExecuteAsync()0%6480800%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Views/Shared/_Layout.cshtml

#LineLine coverage
 1@{
 02    var currentControllerName = ViewContext.RouteData.Values["controller"]?.ToString() ?? string.Empty;
 03    var currentActionName = ViewContext.RouteData.Values["action"]?.ToString() ?? string.Empty;
 04    var suppressToastsOnTransactionForm = currentControllerName.EndsWith("Transaction", StringComparison.OrdinalIgnoreCa
 05                                        && currentActionName.StartsWith("Create", StringComparison.OrdinalIgnoreCase);
 6}
 7<!DOCTYPE html>
 8<html lang="en">
 9<head>
 10    <meta charset="utf-8"/>
 11    <partial name="_ConsoleGuard" />
 12    <meta name="studio2-instance" content="@OzonOrdersWeb.Observability.AppInstanceInfo.InstanceId"/>
 13    @* Наблюдатель доступности сервера. Грузится ДО телеметрии: так он захватывает нативный fetch
 14         для health-проб, а телеметрия ложится поверх и продолжает видеть обычные запросы. *@
 15    <script src="~/js/layout/server-availability.js" asp-append-version="true"></script>
 16    <script src="~/js/observability/client-telemetry.js" asp-append-version="true"></script>
 17    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
 018    <title>@ViewData["Title"] - Studio2</title>
 19    <link id="studio2-favicon" rel="icon" type="image/svg+xml" href="~/images/branding/tab-icon-default.svg" asp-append-
 20    <link rel="apple-touch-icon" href="~/favicon.svg" asp-append-version="true"/>
 21    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css"/>
 22    @* Шрифт Inter, иконочные наборы и бандл слоя _Layout — всё локально (без внешних CDN / SPOF).
 23       inter.css идёт до бандла: design-tokens.css внутри бандла уже ссылается на Inter. *@
 24    <link rel="stylesheet" href="~/lib/inter/inter.css" asp-append-version="true"/>
 25    <link rel="stylesheet" href="~/lib/bootstrap-icons/bootstrap-icons.css" asp-append-version="true"/>
 26    <link rel="stylesheet" href="~/lib/fontawesome/css/all.min.css" asp-append-version="true"/>
 27    @* Один бандл вместо ~14 отдельных CSS-файлов слоя _Layout (собирается WebOptimizer, content-hash в ?v=). *@
 28    <link rel="stylesheet" href="~/css/layout.bundle.css"/>
 29    <link rel="stylesheet" href="~/css/st2-dialog.css" asp-append-version="true"/>
 30    <link rel="stylesheet" href="~/css/empty-state.css" asp-append-version="true"/>
 31    <link rel="stylesheet" href="~/css/operation-feedback.css" asp-append-version="true"/>
 32    <link rel="stylesheet" href="~/css/order-number-emphasis.css" asp-append-version="true"/>
 33    <link rel="stylesheet" href="~/css/Studio2/shared/section-hero.css" asp-append-version="true"/>
 34    @* Локальная копия jQuery: вторая загрузка расщепляет состояние (обработчики и патчи остаются на предыдущем экземпля
 35    <script src="~/lib/jquery/dist/jquery.min.js" asp-append-version="true"></script>
 36    <script src="~/js/empty-state.js" asp-append-version="true"></script>
 37    <script src="~/js/Studio2/transaction-return.js" asp-append-version="true"></script>
 38    <script src="~/js/app-toast.js" asp-append-version="true" defer></script>
 39
 40    <style>
 41        @* scrollbar-width: thin  ; *@
 42        @* scrollbar-color: rgba  (  0  ,  0  ,  0  ,  0.5  )  transparent  ; *@
 43        .pagination-wrapper {
 44            display: flex;
 45            align-items: center;
 46        }
 47
 48        /* Для веб-браузеров на основе WebKit (Chrome, Safari) */
 49        ::-webkit-scrollbar {
 50            width: 7px; /* Ширина вертикальной полосы прокрутки */
 51            height: 7px; /* Высота горизонтальной полосы прокрутки */
 52        }
 53
 54        ::-webkit-scrollbar-track {
 55            background: transparent; /* Фон полосы прокрутки */
 56        }
 57
 58        ::-webkit-scrollbar-thumb {
 59            background: rgba(0, 0, 0, 0.3); /* Цвет ползунка прокрутки */
 60        }
 61
 62        .btn-link svg {
 63            transition: transform 0.1s ease; /* Плавное увеличение */
 64        }
 65
 66        .btn-link:hover svg {
 67            transform: scale(1.2); /* Увеличиваем SVG на 20% */
 68        }
 69
 70        .chat-widget-new {
 71            position: fixed;
 72            bottom: 20px;
 73            right: 20px;
 74            z-index: 1050;
 75        }
 76
 77        .chat-toggle {
 78            width: 45px;
 79            height: 45px;
 80            border-radius: 50%;
 81            font-size: 18px;
 82            display: flex;
 83            align-items: center;
 84            justify-content: center;
 85            box-shadow: 0 2px 8px rgba(37,99,235,0.3);
 86            border: none;
 87            background: linear-gradient(135deg, var(--color-primary), var(--color-primary-dark));
 88            transition: all 0.3s ease;
 89            position: relative;
 90        }
 91
 92        .chat-toggle:hover {
 93            transform: translateY(-1px);
 94            box-shadow: 0 4px 12px rgba(37,99,235,0.4);
 95            background: linear-gradient(135deg, var(--color-primary-dark), var(--color-primary-dark));
 96        }
 97
 98        .chat-card {
 99            width: 450px;
 100            height: 500px;
 101            display: flex;
 102            flex-direction: column;
 103            border: none;
 104            border-radius: 0.75rem;
 105            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
 106            background-color: var(--bg-surface);
 107        }
 108
 109        .chat-card .card-header {
 110            background-color: var(--bg-page);
 111            border-bottom: 1px solid var(--border-default);
 112            padding: 1rem 1.25rem;
 113            font-size: 1rem;
 114            color: var(--text-secondary);
 115            flex-shrink: 0;
 116        }
 117
 118        .chat-card .card-body {
 119            flex-grow: 1;
 120            overflow-y: auto;
 121            padding: 1rem;
 122            background-color: var(--bg-surface);
 123        }
 124
 125        .chat-card .card-footer {
 126            background-color: var(--bg-page);
 127            border-top: 1px solid var(--border-default);
 128            flex-shrink: 0;
 129        }
 130
 131        .chat-badge {
 132            position: absolute;
 133            top: 6px;
 134            right: 6px;
 135            width: 8px;
 136            height: 8px;
 137            background: var(--color-danger);
 138            border: 1.5px solid var(--bg-surface);
 139            border-radius: 50%;
 140            animation: pulse 2s infinite;
 141        }
 142
 143        .message {
 144            padding: 0.5rem 0.65rem;
 145            margin-bottom: 0.4rem;
 146            border-radius: var(--radius-md);
 147            background-color: var(--bg-page);
 148            border-left: 3px solid var(--color-primary);
 149            font-size: 0.8rem;
 150            line-height: 1.32;
 151            word-wrap: break-word;
 152            transition: background-color 0.15s ease;
 153        }
 154
 155        .message:hover {
 156            background-color: var(--border-subtle);
 157        }
 158
 159        .message strong {
 160            color: var(--text-secondary);
 161            font-weight: 600;
 162            display: block;
 163            margin-bottom: 0.2rem;
 164            font-size: 0.72rem;
 165            opacity: 0.8;
 166        }
 167
 168        .message:last-child {
 169            margin-bottom: 0;
 170        }
 171
 172        .chat-message {
 173            border-left-width: 3px;
 174            border-left-style: solid;
 175            background: var(--bg-page);
 176        }
 177
 178        .chat-message.chat-success {
 179            border-left-color: var(--color-success);
 180            background: var(--color-success-light);
 181        }
 182
 183        .chat-message.chat-error {
 184            border-left-color: var(--color-danger);
 185            background: var(--color-danger-light);
 186        }
 187
 188        .chat-message.chat-warning {
 189            border-left-color: var(--color-warning);
 190            background: var(--color-warning-light);
 191        }
 192
 193        .chat-message.chat-info {
 194            border-left-color: var(--color-primary);
 195            background: var(--color-primary-light);
 196        }
 197
 198        .chat-message-head {
 199            display: flex;
 200            align-items: center;
 201            gap: 0.3rem;
 202            margin-bottom: 0.15rem;
 203        }
 204
 205        .chat-message-icon {
 206            display: inline-flex;
 207            align-items: center;
 208            justify-content: center;
 209            width: 14px;
 210            flex-shrink: 0;
 211            font-size: 0.7rem;
 212        }
 213
 214        .chat-message.chat-success .chat-message-icon { color: var(--color-success); }
 215        .chat-message.chat-error   .chat-message-icon { color: var(--color-danger); }
 216        .chat-message.chat-warning .chat-message-icon { color: var(--color-warning); }
 217        .chat-message.chat-info    .chat-message-icon { color: var(--color-primary); }
 218
 219        .chat-message-source {
 220            display: inline-flex;
 221            align-items: center;
 222            gap: 0.3rem;
 223            font-size: 0.68rem;
 224            font-weight: 700;
 225            line-height: 1;
 226            padding: 0.18rem 0.45rem;
 227            border-radius: var(--radius-pill);
 228            background: var(--bg-surface);
 229            white-space: nowrap;
 230        }
 231
 232        .chat-message-source-dot {
 233            width: 6px;
 234            height: 6px;
 235            border-radius: 50%;
 236            flex-shrink: 0;
 237        }
 238
 239        .chat-message-time {
 240            font-size: 0.68rem;
 241            color: var(--text-muted);
 242            font-weight: 500;
 243            margin-left: auto;
 244            white-space: nowrap;
 245            flex-shrink: 0;
 246        }
 247
 248        .chat-message-content {
 249            font-size: 0.78rem;
 250            line-height: 1.3;
 251            white-space: pre-wrap;
 252            word-wrap: break-word;
 253        }
 254
 255        .chat-message-content .alert {
 256            margin: 0.3rem 0 0;
 257            padding: 0.4rem 0.5rem;
 258            font-size: 0.74rem;
 259            border-radius: var(--radius-sm);
 260        }
 261
 262        .chat-copyable-id {
 263            display: inline-flex;
 264            align-items: center;
 265            gap: .25rem;
 266            padding: .08rem .35rem;
 267            border: 1px solid var(--border-default);
 268            border-radius: var(--radius-pill);
 269            background: var(--bg-surface);
 270            color: var(--text-primary);
 271            font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
 272            font-size: .72rem;
 273            cursor: copy;
 274        }
 275
 276        .chat-copyable-id:hover { border-color: var(--color-primary); color: var(--color-primary); }
 277        .chat-status-chip { display: inline-flex; padding: .08rem .38rem; border-radius: var(--radius-pill); background:
 278        .chat-operation-summary { display: flex; align-items: center; flex-wrap: wrap; gap: .35rem; }
 279
 280        /* Стили для скроллбара */
 281        .chat-body::-webkit-scrollbar {
 282            width: 4px;
 283        }
 284
 285        .chat-body::-webkit-scrollbar-track {
 286            background: var(--bg-page);
 287            border-radius: 2px;
 288        }
 289
 290        .chat-body::-webkit-scrollbar-thumb {
 291            background: var(--border-default);
 292            border-radius: 2px;
 293        }
 294
 295        .chat-body::-webkit-scrollbar-thumb:hover {
 296            background: var(--text-muted);
 297        }
 298
 299        /* Анимация для бейджа */
 300        @@keyframes pulse {
 301            0% {
 302                transform: scale(1);
 303                opacity: 1;
 304            }
 305            50% {
 306                transform: scale(1.1);
 307                opacity: 0.8;
 308            }
 309            100% {
 310                transform: scale(1);
 311                opacity: 1;
 312            }
 313        }
 314
 315        /* Анимация появления сообщений */
 316        @@keyframes slideIn {
 317            from {
 318                opacity: 0;
 319                transform: translateY(10px);
 320            }
 321            to {
 322                opacity: 1;
 323                transform: translateY(0);
 324            }
 325        }
 326
 327        .message {
 328            animation: slideIn 0.3s ease;
 329        }
 330
 331        /* Адаптивность для мобильных устройств */
 332        @@media (max-width: 768px) {
 333            .chat-widget-new {
 334                bottom: 15px;
 335                right: 15px;
 336            }
 337
 338            .chat-card {
 339                width: calc(100vw - 30px);
 340                height: 60vh;
 341                max-width: 350px;
 342            }
 343
 344            .chat-toggle {
 345                width: 40px;
 346                height: 40px;
 347                font-size: 16px;
 348            }
 349
 350            .chat-badge {
 351                top: 5px;
 352                right: 5px;
 353                width: 7px;
 354                height: 7px;
 355            }
 356        }
 357
 358        @@media (max-width: 576px) {
 359            .chat-widget-new {
 360                bottom: 10px;
 361                right: 10px;
 362            }
 363
 364            .chat-card {
 365                width: calc(100vw - 20px);
 366                height: 50vh;
 367            }
 368
 369            .chat-toggle {
 370                width: 38px;
 371                height: 38px;
 372                font-size: 15px;
 373            }
 374        }
 375
 376        /* Убираем обводки у кнопок */
 377        .btn:focus,
 378        .btn:active {
 379            outline: none !important;
 380            box-shadow: none !important;
 381            border: none !important;
 382        }
 383
 384        /* Иконки Font Awesome */
 385        .fas {
 386            width: 16px;
 387            text-align: center;
 388        }
 389
 390        /* Тултипы вынесены в ~/css/tooltip.css + ~/js/tooltip.js */
 391        body {
 392            position: relative;
 393        }
 394
 395        /* Класс для контейнеров которые не должны обрезать тултипы */
 396        .tooltip-safe-container {
 397            overflow: visible !important;
 398            position: relative;
 399            z-index: auto;
 400        }
 401
 402        /* Стили для кнопок с иконками и подсказками под ними */
 403        .file-action-btn-wrapper {
 404            position: relative;
 405            display: inline-flex;
 406            flex-direction: column;
 407            align-items: center;
 408        }
 409
 410        /* Для кнопок только с иконками */
 411        .file-action-btn-wrapper .file-upload-btn,
 412        .file-action-btn-wrapper .create-order-btn {
 413            padding: 0.375rem 0.5rem;
 414            min-width: 32px;
 415            height: 32px;
 416            display: flex;
 417            align-items: center;
 418            justify-content: center;
 419        }
 420
 421        /* Для кнопок с текстом - сохраняем стандартные стили */
 422        .file-action-btn-wrapper .dropdown {
 423            display: inline-block;
 424        }
 425
 426        /* Убеждаемся, что dropdown меню отображается поверх подсказок */
 427        .file-action-btn-wrapper .dropdown-menu {
 428            z-index: 1050;
 429        }
 430
 431        .file-action-hover-text {
 432            position: absolute;
 433            top: calc(100% + 8px);
 434            left: 50%;
 435            transform: translateX(-50%);
 436            padding: 6px 10px;
 437            background-color: var(--text-primary);
 438            color: var(--text-inverse);
 439            font-size: 0.75rem;
 440            border-radius: 4px;
 441            opacity: 0;
 442            visibility: hidden;
 443            transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out;
 444            pointer-events: none;
 445            z-index: 1000;
 446            max-width: 280px;
 447            min-width: 120px;
 448            text-align: center;
 449            white-space: normal;
 450            word-wrap: break-word;
 451            line-height: 1.4;
 452            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
 453        }
 454
 455        .file-action-hover-text::before {
 456            content: '';
 457            position: absolute;
 458            bottom: 100%;
 459            left: 50%;
 460            transform: translateX(-50%);
 461            border: 5px solid transparent;
 462            border-bottom-color: var(--text-primary);
 463        }
 464
 465        .file-action-btn-wrapper:hover .file-action-hover-text {
 466            visibility: visible;
 467            opacity: 1;
 468        }
 469
 470        /* Тултип скрыт по умолчанию */
 471        .file-action-hover-text {
 472            opacity: 0;
 473            visibility: hidden;
 474            transition: opacity 0.2s ease, visibility 0.2s ease;
 475        }
 476
 477        /* Скрываем тултип, когда меню открыто */
 478        .nav-group .dropdown-menu.show ~ .file-action-hover-text {
 479            opacity: 0 !important;
 480            visibility: hidden !important;
 481        }
 482
 483        /* Скрываем подсказку, когда dropdown открыт */
 484        .file-action-btn-wrapper .dropdown.show ~ .file-action-hover-text,
 485        .file-action-btn-wrapper:hover .dropdown.show ~ .file-action-hover-text {
 486            opacity: 0;
 487            visibility: hidden;
 488        }
 489
 490        /* Убеждаемся, что dropdown меню отображается поверх подсказок */
 491        .file-action-btn-wrapper .dropdown-menu {
 492            z-index: 1050;
 493        }
 494
 495        /* Первый UL растягивается, но элементы не сжимаются меньше min-width */
 496        .first-ul {
 497            flex: 1 1 auto;
 498            min-width: 0;
 499        }
 500
 501        .first-ul .nav-item {
 502            flex: 0 1 auto;
 503        }
 504
 505        /* Чтобы текст не съезжал */
 506        .first-ul .nav-link {
 507            white-space: nowrap;
 508            overflow: hidden;
 509            text-overflow: ellipsis;
 510        }
 511
 512    </style>
 513    @{
 0514        var pimNavAllowed = ViewData["PimNavAllowedCodes"] as IList<string> ?? new List<string>();
 0515        var useAppPagePimNav = ViewData["UseAppPagePimNav"] as bool? ?? false;
 0516        var isAppSuperPim = ViewData["IsAppSuperAdminPim"] as bool? ?? false;
 517    }
 518    <script>
 0519        window.pimNavIsWebAdmin = @Json.Serialize(User.IsInRole("Admin"));
 0520        window.isAppSuperAdminPim = @Json.Serialize(isAppSuperPim);
 0521        window.useAppPagePimNav = @Json.Serialize(useAppPagePimNav);
 0522        window.pimNavAllowedCodes = @Html.Raw(System.Text.Json.JsonSerializer.Serialize(pimNavAllowed));
 523    </script>
 524    @* Скрипты прогрессивного улучшения (nav-фильтр, даты, sync колонок, селекты) перенесены
 525       в конец <body> — они не нужны для первого рендера и незачем блокировать парсинг <head>.
 526       Конфиг window.pimNav* остаётся здесь: выставляется до того, как отложенный скрипт его прочитает. *@
 527</head>
 0528<body data-app-toast-disabled="@(suppressToastsOnTransactionForm ? "true" : "false")">
 0529    @await Html.PartialAsync("_Sidebar")
 530
 0531    @{var _pageTitle = ViewData["Title"]?.ToString() ?? "st2";}
 532    <header class="app-header" id="appHeader">
 533        <div class="header-left">
 534            <div class="header-breadcrumb">
 535                <a asp-area="Studio2" asp-controller="Orders" asp-action="Index">
 536                    <i class="fas fa-home"></i>
 537                </a>
 538                <span class="header-breadcrumb-separator">/</span>
 0539                <span class="header-breadcrumb-current">@_pageTitle</span>
 540            </div>
 0541            @await RenderSectionAsync("HeaderActions", required: false)
 542        </div>
 543
 544        <div class="header-right">
 545            <div class="header-search">
 546                <i class="fas fa-search header-search-icon"></i>
 547                <input type="text" class="header-search-input"
 548                       placeholder="Номер, артикул или название..." id="globalSearchInput" autocomplete="off">
 549            </div>
 550            <div class="oc-header-notifications">
 551                <button class="header-action-btn" type="button" title="Контрольные задачи" id="notificationBtn" aria-exp
 552                    <i class="fas fa-bell"></i>
 553                    <span class="badge" id="notificationBadge" style="display:none;"></span>
 554                </button>
 555                <section class="oc-notification-menu" id="orderControlNotificationMenu" hidden aria-label="Контрольные з
 0556                    @Html.AntiForgeryToken()
 557                    <div class="oc-notification-menu-head"><div><strong>Требует действий</strong><span id="orderControlN
 558                    <div id="orderControlNotificationItems" class="oc-notification-menu-items"></div>
 559                </section>
 560            </div>
 561            <div class="dropdown">
 562                <button class="header-action-btn" data-bs-toggle="dropdown" aria-expanded="false" title="Профиль" data-o
 563                    <i class="fas fa-user"></i>
 564                </button>
 565                <ul class="dropdown-menu dropdown-menu-end ou-menu">
 566                    <partial name="_OnlineUsersMenu"/>
 567                    <li><a class="dropdown-item" asp-area="Studio2" asp-controller="Profile" asp-action="Index"><i class
 568                    <li><hr class="dropdown-divider"></li>
 569                    <li>
 570                        <form asp-area="Identity" asp-controller="Account" asp-action="Logout" method="post">
 571                            <button type="submit" class="dropdown-item"><i class="fas fa-sign-out-alt me-2"></i>Выйти</b
 572                        </form>
 573                    </li>
 574                </ul>
 575            </div>
 576        </div>
 577        <div id="page-loading-bar"></div>
 578    </header>
 579
 580    <div class="app-main">
 0581        @if (User.IsInRole("Admin") || User.IsInRole("SuperAdmin"))
 582        {
 583            @* Постоянные предупреждения для админов: наполняет job-logs-badges.js из /Studio2/JobLogs/badge-summary. *@
 584            <div id="st2SystemAlerts" class="st2-system-alerts" role="alert" aria-live="polite"></div>
 585        }
 586        <partial name="_AppToastNotifications" />
 0587        @RenderBody()
 588    </div>
 589
 0590@if (User.IsInRole("Admin") || User.IsInRole("SuperAdmin"))
 591{
 592    <div class="modal fade daily-summary-modal" id="orderDailySummaryModal" tabindex="-1"
 593         aria-labelledby="orderDailySummaryTitle" aria-hidden="true"
 0594         data-endpoint="@Url.Action("Yesterday", "DailyOrderSummary", new { area = "Studio2" })"
 0595         data-orders-base="@Url.Action("Orders", "DailyOrderSummary", new { area = "Studio2" })"
 0596         data-user-id="@(User.Identity?.Name ?? "admin")">
 597        <div class="modal-dialog modal-dialog-centered">
 598            <div class="modal-content">
 599                <div class="daily-summary-hero">
 600                    <div class="d-flex align-items-start justify-content-between gap-3">
 601                        <div>
 602                            <div class="text-uppercase small fw-semibold opacity-75 mb-1" data-summary-greeting>Здравств
 603                            <h2 class="mb-1" id="orderDailySummaryTitle">Итоги за вчера</h2>
 604                            <div class="daily-summary-period" data-summary-period>Загружаем данные…</div>
 605                        </div>
 606                        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
 607                    </div>
 608                </div>
 609                <div class="modal-body p-4">
 610                    <div class="daily-summary-grid">
 611                        <a class="daily-summary-kpi daily-summary-kpi-link processing" data-summary-link="processing" hr
 612                        <a class="daily-summary-kpi daily-summary-kpi-link cancelled" data-summary-link="cancelled" href
 613                        <a class="daily-summary-kpi daily-summary-kpi-link delivered" data-summary-link="delivered" href
 614                        <a class="daily-summary-kpi daily-summary-kpi-link missing-status" href="@Url.Action("Orders", "
 615                        <a class="daily-summary-kpi daily-summary-kpi-link active" href="@Url.Action("Index", "OrderCont
 616                        <a class="daily-summary-kpi daily-summary-kpi-link overdue" href="@Url.Action("Index", "OrderCon
 617                    </div>
 618                    <div class="daily-summary-sla-note"><i class="fas fa-circle-info text-primary"></i><span>Нажмите на 
 619                </div>
 620                <div class="modal-footer border-0 pt-0 px-4 pb-4">
 621                    <button type="button" class="btn btn-primary" data-bs-dismiss="modal">Понятно</button>
 622                </div>
 623            </div>
 624        </div>
 625    </div>
 626}
 627
 628<!-- Chat widget -->
 629<div class="chat-widget-new">
 630    <button id="chatToggle" class="btn btn-primary chat-toggle" type="button" data-bs-toggle="collapse"
 631            data-bs-target="#chatCollapse" aria-expanded="false">
 632        <i class="fas fa-bell"></i>
 633        <span id="chatBadge" class="chat-badge d-none"></span>
 634    </button>
 635    <div class="collapse" id="chatCollapse">
 636        <div class="card shadow-lg chat-card d-flex flex-column">
 637            <div class="card-header d-flex justify-content-between align-items-center">
 638                <span class="fw-semibold">Процессы</span>
 639                <button id="chatClose" type="button" class="btn-close"></button>
 640            </div>
 641            <div id="chatBody" class="card-body chat-body flex-grow-1">
 642                <!-- Сообщения будут загружаться сюда -->
 643            </div>
 644            <div class="card-footer p-2 text-center small text-muted">Система уведомлений о процессах</div>
 645        </div>
 646    </div>
 647</div>
 648
 649
 650<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
 651<script src="~/js/st2-dialog.js" asp-append-version="true"></script>
 652<script src="~/js/operation-feedback.js" asp-append-version="true"></script>
 653
 654@* SignalR + скрипты прогрессивного улучшения — перенесены из <head>, чтобы не блокировать
 655   первый рендер. Все потребители (чат, online-меню, badge-и) инициализируются на
 656   DOMContentLoaded/позже и защищены проверками typeof, а section Scripts идут ниже. *@
 657<script src="~/lib/microsoft-signalr/signalr.min.js" asp-append-version="true"></script>
 658<script src="~/js/layout/signalr-logging.js" asp-append-version="true"></script>
 659<script src="~/js/status-color-contrast.js" asp-append-version="true"></script>
 660<script src="~/js/pim-nav-menu-filter.js" asp-append-version="true"></script>
 661<script src="~/js/order-date-display.js" asp-append-version="true"></script>
 662<script src="~/js/table-sync.js" asp-append-version="true"></script>
 663<script src="~/js/shared/custom-select.js" asp-append-version="true"></script>
 664<script src="~/js/shared/combobox.js" asp-append-version="true"></script>
 665<script src="~/js/shared/skeleton-loader.js" asp-append-version="true"></script>
 666
 667<script src="~/js/layout/request-error.js" asp-append-version="true"></script>
 668<script src="~/js/system-notification-modal.js" asp-append-version="true"></script>
 669<script src="~/js/layout/chat-widget.js" asp-append-version="true"></script>
 670
 671<script src="~/js/site.js" asp-append-version="true"></script>
 672<script src="~/js/tooltip.js" asp-append-version="true"></script>
 673<script src="~/js/page-loading-bar.js" asp-append-version="true"></script>
 674<script src="~/js/layout/tab-status.js" asp-append-version="true"></script>
 675<script src="~/js/shared/order-number-emphasis.js" asp-append-version="true"></script>
 676<script src="~/js/global-search.js" asp-append-version="true"></script>
 677<script src="~/js/productImageViewer.js" asp-append-version="true"></script>
 678
 679<script src="~/js/layout/nav-filters-sync.js" asp-append-version="true"></script>
 680<script src="~/js/layout/nav-dropdowns.js" asp-append-version="true"></script>
 681@* AG Grid Community — боковое меню (sidebar-navigation.js) и страница /Studio2/OrdersGrid; грузится один раз здесь. *@
 682<script src="~/lib/ag-grid/ag-grid-community.min.js" asp-append-version="true"></script>
 683<script src="~/js/layout/sidebar-navigation.js" asp-append-version="true"></script>
 684
 0685@await RenderSectionAsync("Scripts", required: false)
 686
 687</body>
 688</html>
 689
 690
 691
 692<script src="~/js/layout/page-history.js" asp-append-version="true"></script>
 0693@if (User.Identity?.IsAuthenticated == true)
 694{
 695    <script src="~/js/layout/badge-refresh.js" asp-append-version="true"></script>
 696    <script src="~/js/layout/ozon-chat-badge.js" asp-append-version="true"></script>
 697    <script src="~/js/layout/fidstat-anomaly-badge.js" asp-append-version="true"></script>
 698    <script src="~/js/job-logs-badges.js" asp-append-version="true"></script>
 699    <script src="~/js/order-control-notification-menu.js" asp-append-version="true"></script>
 700}
 0701@if (User.IsInRole("Admin") || User.IsInRole("SuperAdmin"))
 702{
 703    <script src="~/js/order-daily-summary.js" asp-append-version="true"></script>
 704}