< Summary

Information
Class: AspNetCoreGeneratedDocument.Areas_Admin_Views_Pages_Index
Assembly: OzonOrdersWeb
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Areas/Admin/Views/Pages/Index.cshtml
Line coverage
0%
Covered lines: 0
Uncovered lines: 10
Coverable lines: 10
Total lines: 82
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 22
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%420200%
<ExecuteAsync()0%620%
<ExecuteAsync()100%210%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Areas/Admin/Views/Pages/Index.cshtml

#LineLine coverage
 1@model List<PageListItemVm>
 2@{
 03    var discovered = ViewBag.DiscoveredNew as List<OzonOrdersWeb.Authorization.Discovery.DiscoveredPage> ?? new();
 04    var json = new System.Text.Json.JsonSerializerOptions(System.Text.Json.JsonSerializerDefaults.Web);
 5}
 6
 7<section class="admin-hero">
 8    <h1>Страницы</h1>
 9    <p class="subtitle">Реестр разделов приложения для управления правами доступа.</p>
 10    <p class="subtitle-help">Синхронизация подтягивает новые controller/action из кода.</p>
 11</section>
 12
 13<nav class="admin-quick-links">
 14    <a asp-area="Admin" asp-controller="Roles" asp-action="Index"><i class="bi bi-person-badge"></i>Роли</a>
 15    <a asp-area="Admin" asp-controller="Fields" asp-action="Index"><i class="bi bi-input-cursor-text"></i>Колонки</a>
 16    <a asp-area="Admin" asp-controller="Home" asp-action="Index"><i class="bi bi-speedometer2"></i>Обзор</a>
 17</nav>
 18
 19<section class="admin-intro">
 20    <i class="bi bi-info-circle"></i>
 21    <div>Иерархия, коды и видимость в меню используются в матрице ролей. Порядок дерева — колонка «№»; двойной клик по с
 22</section>
 23
 24<div class="admin-toolbar admin-surface">
 25    <form asp-action="SyncFromCode" method="post" class="d-flex gap-2 align-items-center">
 026        @Html.AntiForgeryToken()
 27        <button type="submit" class="btn btn-outline-success btn-sm"><i class="bi bi-arrow-repeat"></i> Синхронизировать
 028        @if (discovered.Any()) { <span class="bsx-dir-stat bsx-dir-stat--warn">Новых страниц <b>@discovered.Count</b></s
 29    </form>
 30    <a asp-action="Create" class="btn btn-primary btn-sm"><i class="bi bi-plus-lg"></i> Добавить вручную</a>
 31</div>
 32
 033@if (discovered.Any())
 34{
 35    <div class="alert alert-warning">
 36        <h6>Найдены новые страницы, не зарегистрированные в системе:</h6>
 37        <ul class="small mb-0">
 038            @foreach (var d in discovered.Take(20)) { <li><code>@d.Code</code> — @d.DisplayName (@d.Area/@d.Controller/@
 039            @if (discovered.Count > 20) { <li>… и ещё @(discovered.Count - 20)</li> }
 40        </ul>
 41        <div class="mt-2 small">Нажмите «Синхронизировать с кодом», чтобы добавить их все.</div>
 42    </div>
 43}
 44
 045@await Html.PartialAsync("~/Areas/Studio2/Views/Shared/_BsxDirectoryGrid.cshtml", new BsxDirectoryGridViewModel("admPage
 046<script type="application/json" id="admPagesData">@Html.Raw(System.Text.Json.JsonSerializer.Serialize(AdminGridRows.Page
 47
 48@section Scripts {
 49    <script>
 50        (function () {
 51            const A = window.AdminGrid, D = window.BsxDirectory, esc = A.esc;
 052            const url = (action, id) => '@Url.Action("Index")'.replace(/\/Index$/, '') + '/' + action + '/' + id;
 53            A.grid({
 54                key: 'admPages', prefix: 'admPages', rows: A.data('admPagesData'),
 55                rowUrl: r => url('Edit', r.id),
 56                columnDefs: [
 57                    D.numCol({ colId: 'treeOrder', field: 'treeOrder', headerName: '№', width: 80, sort: 'asc', valueFor
 58                    {
 59                        colId: 'displayName', field: 'displayName', headerName: 'Код / Название', minWidth: 300, flex: 3
 60                        getQuickFilterText: p => p.data.displayName + ' ' + p.data.code,
 61                        cellRenderer: p => {
 62                            const r = p.data; if (!r) return '';
 63                            return '<span class="admin-tree-cell" style="padding-left:' + (r.depth * 18) + 'px">' +
 64                                (r.depth > 0 ? '<i class="fas fa-turn-up fa-rotate-90"></i>' : '') +
 65                                '<span class="bsx-cell-stack"><b>' + esc(r.displayName) + '</b><span class="admin-code">
 66                        }
 67                    },
 68                    D.setCol({ colId: 'area', field: 'area', headerName: 'Area', width: 120, valueFormatter: p => p.valu
 69                    D.setCol({ colId: 'controller', field: 'controller', headerName: 'Controller', minWidth: 150, flex: 
 70                    { colId: 'action', field: 'action', headerName: 'Action', minWidth: 120, flex: 1 },
 71                    A.check({ colId: 'isMenuItem', field: 'isMenuItem', headerName: 'В меню' }),
 72                    A.check({ colId: 'isActive', field: 'isActive', headerName: 'Активна' }),
 73                    D.actionsCol(r => [
 74                        { icon: 'fa-pen', title: 'Изменить', kind: 'edit', href: url('Edit', r.id) },
 75                        { icon: 'fa-trash', title: 'Удалить из реестра', kind: 'danger',
 76                          onClick: row => A.confirmPost(url('Delete', row.id), {}, { title: 'Удалить страницу', message:
 77                    ], { width: 110 })
 78                ]
 79            });
 80        })();
 81    </script>
 82}