| | | 1 | | @using OzonDomains.Models.AccessControl |
| | | 2 | | @model AccessProfile |
| | | 3 | | |
| | | 4 | | @{ |
| | 0 | 5 | | ViewData["Title"] = $"Профиль: {Model.Name}"; |
| | 0 | 6 | | Layout = "_AdminLayout"; |
| | 0 | 7 | | ViewData["Breadcrumb"] = new List<(string, string?)> |
| | 0 | 8 | | { |
| | 0 | 9 | | ("Администрирование", null), |
| | 0 | 10 | | ("Профили доступа", Url.Action("Index", "AccessProfiles", new { area = "Studio2" })), |
| | 0 | 11 | | (Model.Name ?? "Редактирование", null) |
| | 0 | 12 | | }; |
| | 0 | 13 | | var allSets = ViewBag.AllDataScopeSets as List<DataScopeSet> ?? new(); |
| | 0 | 14 | | var selectedIds = Model.DataScopeSets.Select(s => s.Id).ToHashSet(); |
| | | 15 | | } |
| | | 16 | | |
| | | 17 | | <form asp-action="Edit" method="post"> |
| | | 18 | | <input type="hidden" asp-for="Id"/> |
| | | 19 | | <div class="row"> |
| | | 20 | | <!-- Left: basic settings --> |
| | | 21 | | <div class="col-md-5"> |
| | | 22 | | <div class="card mb-3"> |
| | | 23 | | <div class="card-header"> |
| | | 24 | | <h3 class="card-title"><i class="ti ti-settings me-2"></i>Основное</h3> |
| | | 25 | | </div> |
| | | 26 | | <div class="card-body"> |
| | | 27 | | <div class="mb-3"> |
| | | 28 | | <label asp-for="Name" class="form-label">Название <span class="text-red">*</span></label> |
| | | 29 | | <input asp-for="Name" class="form-control"/> |
| | | 30 | | <span asp-validation-for="Name" class="text-danger small"></span> |
| | | 31 | | </div> |
| | | 32 | | |
| | | 33 | | <div class="mb-1"> |
| | | 34 | | <label class="form-label"> |
| | | 35 | | Доступные столбцы заказов |
| | | 36 | | <span class="text-muted">(пусто = все)</span> |
| | | 37 | | </label> |
| | | 38 | | <div id="columnsContainer"> |
| | 0 | 39 | | @if (Model.AvailableOrderColumns?.Any() == true) |
| | | 40 | | { |
| | 0 | 41 | | @for (var i = 0; i < Model.AvailableOrderColumns.Count; i++) |
| | | 42 | | { |
| | | 43 | | <div class="input-group mb-2"> |
| | | 44 | | <input type="text" name="AvailableOrderColumns" class="form-control form-control |
| | | 45 | | value="@Model.AvailableOrderColumns[i]"/> |
| | | 46 | | <button type="button" class="btn btn-sm btn-outline-danger" |
| | | 47 | | onclick="this.parentElement.remove()"> |
| | | 48 | | <i class="ti ti-x"></i> |
| | | 49 | | </button> |
| | | 50 | | </div> |
| | | 51 | | } |
| | | 52 | | } |
| | | 53 | | </div> |
| | | 54 | | <button type="button" class="btn btn-sm btn-outline-secondary mt-1" onclick="addColumn()"> |
| | | 55 | | <i class="ti ti-plus me-1"></i>Добавить |
| | | 56 | | </button> |
| | | 57 | | </div> |
| | | 58 | | </div> |
| | | 59 | | </div> |
| | | 60 | | </div> |
| | | 61 | | |
| | | 62 | | <!-- Right: scope sets --> |
| | | 63 | | <div class="col-md-7"> |
| | | 64 | | <div class="card mb-3"> |
| | | 65 | | <div class="card-header"> |
| | | 66 | | <h3 class="card-title"> |
| | | 67 | | <i class="ti ti-filter me-2"></i>Наборы ограничений данных |
| | | 68 | | </h3> |
| | | 69 | | <div class="card-options"> |
| | | 70 | | <a asp-area="Studio2" asp-controller="DataScopeSets" asp-action="Index" |
| | | 71 | | class="btn btn-sm btn-outline-secondary" target="_blank"> |
| | | 72 | | <i class="ti ti-external-link me-1"></i>Управление наборами |
| | | 73 | | </a> |
| | | 74 | | </div> |
| | | 75 | | </div> |
| | | 76 | | <div class="card-body"> |
| | 0 | 77 | | @if (!allSets.Any()) |
| | | 78 | | { |
| | | 79 | | <div class="text-muted text-center py-3"> |
| | | 80 | | <i class="ti ti-inbox mb-2" style="font-size:2rem"></i> |
| | | 81 | | <p>Наборов ещё нет. <a asp-area="Studio2" asp-controller="DataScopeSets" asp-action="Create" |
| | | 82 | | </div> |
| | | 83 | | } |
| | | 84 | | else |
| | | 85 | | { |
| | | 86 | | <p class="text-muted small mb-3"> |
| | | 87 | | Если ни один набор не выбран — пользователь видит <strong>все данные</strong>. |
| | | 88 | | </p> |
| | | 89 | | <div class="list-group"> |
| | 0 | 90 | | @foreach (var set in allSets) |
| | | 91 | | { |
| | 0 | 92 | | var isSelected = selectedIds.Contains(set.Id); |
| | | 93 | | <label class="list-group-item list-group-item-action d-flex gap-3 cursor-pointer @(isSel |
| | | 94 | | <input class="form-check-input flex-shrink-0 mt-1" type="checkbox" |
| | | 95 | | name="selectedDataScopeSetIds" value="@set.Id" checked="@isSelected"/> |
| | | 96 | | <span class="w-100"> |
| | 0 | 97 | | <strong class="d-block">@set.Name</strong> |
| | 0 | 98 | | @if (!string.IsNullOrEmpty(set.Description)) |
| | | 99 | | { |
| | 0 | 100 | | <span class="text-muted small">@set.Description</span> |
| | | 101 | | } |
| | 0 | 102 | | <span class="badge bg-azure-lt mt-1">@set.Items.Count ограничений</span> |
| | | 103 | | </span> |
| | | 104 | | </label> |
| | | 105 | | } |
| | | 106 | | </div> |
| | | 107 | | } |
| | | 108 | | </div> |
| | | 109 | | </div> |
| | | 110 | | </div> |
| | | 111 | | </div> |
| | | 112 | | |
| | | 113 | | <div class="d-flex gap-2"> |
| | | 114 | | <button type="submit" class="btn btn-primary"> |
| | | 115 | | <i class="ti ti-check me-1"></i>Сохранить |
| | | 116 | | </button> |
| | | 117 | | <a asp-action="Index" class="btn btn-outline-secondary">Отмена</a> |
| | | 118 | | </div> |
| | | 119 | | </form> |
| | | 120 | | |
| | | 121 | | @section Scripts { |
| | | 122 | | <script> |
| | | 123 | | function addColumn() { |
| | | 124 | | const div = document.createElement('div'); |
| | | 125 | | div.className = 'input-group mb-2'; |
| | | 126 | | div.innerHTML = `<input type="text" name="AvailableOrderColumns" class="form-control form-control-sm" placeholder="Н |
| | | 127 | | <button type="button" class="btn btn-sm btn-outline-danger" onclick="this.parentElement.remove()"> |
| | | 128 | | <i class="ti ti-x"></i></button>`; |
| | | 129 | | document.getElementById('columnsContainer').appendChild(div); |
| | | 130 | | div.querySelector('input').focus(); |
| | | 131 | | } |
| | | 132 | | // Highlight selected checkboxes on click |
| | | 133 | | document.querySelectorAll('.list-group-item input[type=checkbox]').forEach(cb => { |
| | | 134 | | cb.addEventListener('change', () => cb.closest('.list-group-item').classList.toggle('active', cb.checked)); |
| | | 135 | | }); |
| | | 136 | | </script> |
| | | 137 | | } |