mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-01-19 05:33:31 +01:00
0f8da123b8
* UI: Move section navigation to sidebar * Scroll active nav link into view * Move CTAs to top right * Server Settings: Make Policies first page * Responsive table fixes * Spacing fixes * Add breadcrumb samples * store settings fixes * payment request fixes * updates pull payment title * adds invoice detail fix * updates server settings breadcrumbs + copy fix * Don't open Server Settings on Plugins page * Add breadcrumbs to pull payment views * adds breadcrumbs to account * server and store breadcrumb fixes * fixes access tokens * Fix payment processor breadcrumbs * fixes webhook 404 * Final touches * Fix test * Add breadcrumb for email rules page * Design system updates --------- Co-authored-by: dstrukt <gfxdsign@gmail.com>
121 lines
5.6 KiB
Plaintext
121 lines
5.6 KiB
Plaintext
@using BTCPayServer.Abstractions.Models
|
|
@using BTCPayServer.Services.Stores
|
|
@using BTCPayServer.Client
|
|
@using Microsoft.AspNetCore.Mvc.TagHelpers
|
|
@model StoreUsersViewModel
|
|
@inject StoreRepository StoreRepository
|
|
@{
|
|
var storeId = Context.GetStoreData().Id;
|
|
var roles = new SelectList(
|
|
await StoreRepository.GetStoreRoles(storeId),
|
|
nameof(StoreRepository.StoreRole.Id), nameof(StoreRepository.StoreRole.Role),
|
|
Model.Role);
|
|
ViewData.SetActivePage(StoreNavPages.Users, "Store Users", storeId);
|
|
}
|
|
@section PageHeadContent {
|
|
<style>
|
|
@@media (min-width: 576px) {
|
|
#Role { width: auto !important; }
|
|
}
|
|
</style>
|
|
}
|
|
<h2 class="mb-2 mb-lg-3">@ViewData["Title"]</h2>
|
|
<partial name="_StatusMessage" />
|
|
<div class="row">
|
|
<div class="col-xxl-constrain col-xl-8">
|
|
<p>
|
|
Give other registered BTCPay Server users access to your store. See the
|
|
<a asp-controller="UIStores" asp-action="ListRoles" asp-route-storeId="@storeId">roles</a>
|
|
for granted permissions.
|
|
</p>
|
|
|
|
@if (!ViewContext.ModelState.IsValid)
|
|
{
|
|
<div asp-validation-summary="All"></div>
|
|
}
|
|
|
|
<form method="post" class="d-flex flex-wrap align-items-center gap-3" permission="@Policies.CanModifyStoreSettings">
|
|
<input asp-for="Email" type="text" class="form-control" placeholder="user@example.com" style="flex: 1 1 14rem">
|
|
<select asp-for="Role" class="form-select" asp-items="roles"></select>
|
|
<button type="submit" role="button" class="btn btn-primary text-nowrap flex-grow-1 flex-sm-grow-0" id="AddUser">Add User</button>
|
|
</form>
|
|
|
|
<div class="table-responsive-md">
|
|
<table class="table table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th>Email</th>
|
|
<th>Role</th>
|
|
<th class="actions-col" permission="@Policies.CanModifyStoreSettings">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="StoreUsersList">
|
|
@foreach (var user in Model.Users)
|
|
{
|
|
<tr>
|
|
<td>@user.Email</td>
|
|
<td>@user.Role</td>
|
|
<td class="actions-col" permission="@Policies.CanModifyStoreSettings">
|
|
<div class="d-inline-flex align-items-center gap-3">
|
|
<a asp-action="UpdateStoreUser" asp-route-storeId="@Model.StoreId" asp-route-userId="@user.Id" data-bs-toggle="modal" data-bs-target="#EditModal" data-user-email="@user.Email" data-user-role="@user.Role">Change Role</a>
|
|
<a asp-action="DeleteStoreUser" asp-route-storeId="@Model.StoreId" asp-route-userId="@user.Id" data-bs-toggle="modal" data-bs-target="#ConfirmModal" data-description="This action will prevent <strong>@Html.Encode(user.Email)</strong> from accessing this store and its settings." data-confirm-input="REMOVE">Remove</a>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<partial name="_Confirm" model="@(new ConfirmModel("Remove store user", "This action will prevent the user from accessing this store and its settings. Are you sure?", "Delete"))" permission="@Policies.CanModifyStoreSettings" />
|
|
|
|
<div class="modal fade" id="EditModal" tabindex="-1" aria-labelledby="EditTitle" aria-hidden="true" permission="@Policies.CanModifyStoreSettings">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h4 class="modal-title" id="EditTitle">Edit <span id="EditUserEmail">store user</span></h4>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
|
|
<vc:icon symbol="close" />
|
|
</button>
|
|
</div>
|
|
<form id="EditForm" method="post" rel="noreferrer noopener">
|
|
<div class="modal-body">
|
|
<label asp-for="Role" for="EditUserRole" class="form-label">New role</label>
|
|
<select asp-for="Role" id="EditUserRole" class="form-select w-auto" asp-items="roles"></select>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary only-for-js" data-bs-dismiss="modal" id="EditCancel">Cancel</button>
|
|
<button type="submit" class="btn btn-primary" id="EditContinue">Change Role</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
(function () {
|
|
const modal = document.getElementById('EditModal')
|
|
modal.addEventListener('show.bs.modal', event => {
|
|
const $target = event.relatedTarget
|
|
const $form = document.getElementById('EditForm')
|
|
const $role = document.getElementById('EditUserRole')
|
|
const $email = document.getElementById('EditUserEmail')
|
|
const { userEmail, userRole } = $target.dataset
|
|
const action = $target.dataset.action || ($target.nodeName === 'A'
|
|
? $target.getAttribute('href')
|
|
: $target.form.getAttribute('action'))
|
|
|
|
if ($form && !$form.hasAttribute('action')) $form.setAttribute('action', action)
|
|
if (userEmail) $email.textContent = userEmail
|
|
if (userRole) $role.value = userRole
|
|
});
|
|
})()
|
|
</script>
|
|
|
|
|
|
@section PageFootContent {
|
|
<partial name="_ValidationScriptsPartial" />
|
|
}
|