| | | 1 | | @model List<PageListItemVm> |
| | | 2 | | @{ |
| | 0 | 3 | | var discovered = ViewBag.DiscoveredNew as List<OzonOrdersWeb.Authorization.Discovery.DiscoveredPage> ?? new(); |
| | 0 | 4 | | 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"> |
| | 0 | 26 | | @Html.AntiForgeryToken() |
| | | 27 | | <button type="submit" class="btn btn-outline-success btn-sm"><i class="bi bi-arrow-repeat"></i> Синхронизировать |
| | 0 | 28 | | @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 | | |
| | 0 | 33 | | @if (discovered.Any()) |
| | | 34 | | { |
| | | 35 | | <div class="alert alert-warning"> |
| | | 36 | | <h6>Найдены новые страницы, не зарегистрированные в системе:</h6> |
| | | 37 | | <ul class="small mb-0"> |
| | 0 | 38 | | @foreach (var d in discovered.Take(20)) { <li><code>@d.Code</code> — @d.DisplayName (@d.Area/@d.Controller/@ |
| | 0 | 39 | | @if (discovered.Count > 20) { <li>… и ещё @(discovered.Count - 20)</li> } |
| | | 40 | | </ul> |
| | | 41 | | <div class="mt-2 small">Нажмите «Синхронизировать с кодом», чтобы добавить их все.</div> |
| | | 42 | | </div> |
| | | 43 | | } |
| | | 44 | | |
| | 0 | 45 | | @await Html.PartialAsync("~/Areas/Studio2/Views/Shared/_BsxDirectoryGrid.cshtml", new BsxDirectoryGridViewModel("admPage |
| | 0 | 46 | | <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; |
| | 0 | 52 | | 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 | | } |