< Summary

Information
Class: AspNetCoreGeneratedDocument.Areas_Admin_Views_Roles_Fields
Assembly: OzonOrdersWeb
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Areas/Admin/Views/Roles/Fields.cshtml
Line coverage
0%
Covered lines: 0
Uncovered lines: 19
Coverable lines: 19
Total lines: 121
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 34
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%1332360%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()0%620%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Areas/Admin/Views/Roles/Fields.cshtml

#LineLine coverage
 1@model List<RoleFieldMatrixRow>
 2@{
 03    var role = (OzonDomains.Models.Authorization.AppRole)ViewBag.Role;
 04    var entities = (List<string>)ViewBag.Entities;
 05    var selected = (string?)ViewBag.SelectedEntity;
 06    var json = new System.Text.Json.JsonSerializerOptions(System.Text.Json.JsonSerializerDefaults.Web);
 7}
 8
 9<section class="admin-hero">
 10    <h1>Матрица полей</h1>
 011    <p class="subtitle">Права чтения и записи полей для роли @role.DisplayName.</p>
 12    <p class="subtitle-help">Массовые операции применяются к выбранной сущности.</p>
 13</section>
 14
 15<nav class="admin-quick-links">
 016    <a asp-area="Admin" asp-controller="Roles" asp-action="Edit" asp-route-id="@role.Id"><i class="bi bi-arrow-left"></i
 17    <a asp-area="Admin" asp-controller="Fields" asp-action="Index"><i class="bi bi-input-cursor-text"></i>Реестр полей</
 18    <a asp-area="Admin" asp-controller="Pages" asp-action="Index"><i class="bi bi-window-stack"></i>Страницы</a>
 19</nav>
 20
 21<div class="card mb-3">
 22    <div class="card-body d-flex justify-content-between align-items-center">
 23        <div>
 24            <div class="text-muted small">Роль</div>
 025            <h5 class="mb-0">@role.DisplayName</h5>
 26        </div>
 027        <a asp-action="Edit" asp-route-id="@role.Id" class="btn btn-outline-secondary btn-sm"><i class="bi bi-arrow-left
 28    </div>
 29</div>
 30
 31<div class="admin-toolbar admin-surface">
 32    <div class="admin-matrix-toolbar">
 33        <label class="me-2 mb-0">Сущность:</label>
 34        <select class="form-select form-select-sm w-auto" id="entitySelect">
 035            @foreach (var e in entities)
 36            {
 037                if (e == selected)
 38                {
 039                    <option value="@e" selected>@e</option>
 40                }
 41                else
 42                {
 043                    <option value="@e">@e</option>
 44                }
 45            }
 46        </select>
 047        @if (!string.IsNullOrEmpty(selected) && Model.Any())
 48        {
 49            <div class="btn-group btn-group-sm ms-2" role="group">
 50                <button type="button" class="btn btn-outline-success" id="btnAllOn" title="Включить чтение и запись для 
 51                <button type="button" class="btn btn-outline-danger" id="btnAllOff" title="Снять чтение и запись — колон
 52                <button type="button" class="btn btn-outline-primary" id="btnReadAll" title="Включить только чтение, зап
 53            </div>
 54        }
 55        <span class="admin-field-hint ms-2"><i class="bi bi-check-circle"></i> Авто-сохранение по строке</span>
 56    </div>
 57    </div>
 58</div>
 59
 060@await Html.PartialAsync("~/Areas/Studio2/Views/Shared/_BsxDirectoryGrid.cshtml", new BsxDirectoryGridViewModel("admRole
 061<script type="application/json" id="admRoleFieldsData">@Html.Raw(System.Text.Json.JsonSerializer.Serialize(Model, json))
 62
 63@section Scripts {
 64    <script>
 65    (function () {
 66        const A = window.AdminGrid;
 067        const roleId = @role.Id;
 068        const entity = @Html.Raw(System.Text.Json.JsonSerializer.Serialize(selected ?? ""));
 069        const saveUrl = '@Url.Action("SaveFieldPermission")?roleId=' + roleId;
 070        const setAllUrl = '@Url.Action("SetAllFieldPermission")?roleId=' + roleId;
 71        const rows = A.data('admRoleFieldsData').map(r => Object.assign(r, { id: r.fieldId }));
 72        let api = null;
 73        const toast = (title, message, variant) => window.AppToast ? AppToast.show({ title, message, variant: variant ||
 74        const redraw = r => api && api.redrawRows({ rowNodes: [api.getRowNode(String(r.id))].filter(Boolean) });
 75
 76        document.getElementById('entitySelect')?.addEventListener('change', e => {
 77            location.href = '?id=' + roleId + '&entity=' + encodeURIComponent(e.target.value);
 78        });
 79
 80        async function save(row) {
 81            row.__saving = true; redraw(row);
 82            const resp = await fetch(saveUrl, {
 83                method: 'POST', credentials: 'same-origin',
 84                headers: { 'Content-Type': 'application/json', RequestVerificationToken: BsxGrid.token() },
 85                body: JSON.stringify({ FieldId: row.fieldId, CanRead: !!row.canRead, CanWrite: !!row.canWrite })
 86            }).catch(() => null);
 87            row.__saving = false; redraw(row);
 88            if (!resp || !resp.ok) toast('Ошибка сохранения', 'Не удалось сохранить право на поле «' + row.displayName +
 89        }
 90
 91        async function setAll(read, write) {
 92            if (!entity) return;
 93            const body = new URLSearchParams({ __RequestVerificationToken: BsxGrid.token(), entity, read: String(read), 
 94            const resp = await fetch(setAllUrl, {
 95                method: 'POST', credentials: 'same-origin',
 96                headers: { 'Content-Type': 'application/x-www-form-urlencoded', RequestVerificationToken: BsxGrid.token(
 97                body: body.toString()
 98            }).catch(() => null);
 99            if (resp && resp.ok) location.reload(); else toast('Ошибка сохранения', 'Не удалось выполнить массовое сохра
 100        }
 101
 102        const toggle = (r, f, v) => { r[f] = v; save(r); };
 103        A.grid({
 104            key: 'admRoleFields', prefix: 'admRoleFields', rows: rows,
 105            columnDefs: [
 106                { colId: 'displayName', field: 'displayName', headerName: 'Поле', minWidth: 220, flex: 2 },
 107                A.code({ colId: 'fieldName', field: 'fieldName', headerName: 'Системное имя' }),
 108                A.checkboxCol('canRead', 'Чтение', { onToggle: toggle, width: 120 }),
 109                A.checkboxCol('canWrite', 'Запись', { onToggle: toggle, width: 120 })
 110            ],
 111            rowClassRules: { 'admin-row-saving': p => !!(p.data && p.data.__saving) },
 112            gridOptions: { overlayNoRowsTemplate: '<span class="bsx-grid-empty">Нет зарегистрированных полей для этой су
 113            onReady: a => { api = a; }
 114        });
 115
 116        document.getElementById('btnAllOn')?.addEventListener('click', () => setAll(true, true));
 117        document.getElementById('btnAllOff')?.addEventListener('click', () => setAll(false, false));
 118        document.getElementById('btnReadAll')?.addEventListener('click', () => setAll(true, false));
 119    })();
 120    </script>
 121}