Move View action to the Name column in Payouts & Payment Requests (#3873)

* ui+paymentrequest: moves 'view' link to name

* ui+pull: moves 'view' link to name column

* Update links, fix tests

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
This commit is contained in:
dstrukt 2022-06-19 19:52:12 -07:00 committed by GitHub
parent c56821300a
commit cade6c6c38
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 118 additions and 89 deletions

View file

@ -759,35 +759,38 @@ namespace BTCPayServer.Tests
currencyInput.SendKeys("BTC");
s.Driver.FindElement(By.Id("SaveButton")).Click();
s.Driver.FindElement(By.XPath($"//a[starts-with(@id, 'Edit-')]")).Click();
s.Driver.FindElement(By.XPath("//a[starts-with(@id, 'Edit-')]")).Click();
var editUrl = s.Driver.Url;
s.Driver.FindElement(By.Id("ViewPaymentRequest")).Click();
s.Driver.SwitchTo().Window(s.Driver.WindowHandles.Last());
var viewUrl = s.Driver.Url;
Assert.Equal("Amount due", s.Driver.FindElement(By.CssSelector("[data-test='amount-due-title']")).Text);
Assert.Equal("Pay Invoice",
s.Driver.FindElement(By.CssSelector("[data-test='pay-button']")).Text.Trim());
// expire
s.Driver.SwitchTo().Window(s.Driver.WindowHandles.First());
s.GoToUrl(editUrl);
s.Driver.ExecuteJavaScript("document.getElementById('ExpiryDate').value = '2021-01-21T21:00:00.000Z'");
s.Driver.FindElement(By.Id("SaveButton")).Click();
s.Driver.FindElement(By.XPath($"//a[starts-with(@id, 'Edit-')]")).Click();
s.Driver.SwitchTo().Window(s.Driver.WindowHandles.Last());
s.Driver.Navigate().Refresh();
s.Driver.FindElement(By.XPath("//a[starts-with(@id, 'Edit-')]")).Click();
s.GoToUrl(viewUrl);
Assert.Equal("Expired", s.Driver.WaitForElement(By.CssSelector("[data-test='status']")).Text);
// unexpire
s.Driver.SwitchTo().Window(s.Driver.WindowHandles.First());
s.GoToUrl(editUrl);
s.Driver.FindElement(By.Id("ClearExpiryDate")).Click();
s.Driver.FindElement(By.Id("SaveButton")).Click();
s.Driver.FindElement(By.XPath($"//a[starts-with(@id, 'Edit-')]")).Click();
s.Driver.SwitchTo().Window(s.Driver.WindowHandles.Last());
s.Driver.Navigate().Refresh();
s.Driver.FindElement(By.XPath("//a[starts-with(@id, 'Edit-')]")).Click();
s.GoToUrl(viewUrl);
s.Driver.AssertElementNotFound(By.CssSelector("[data-test='status']"));
Assert.Equal("Pay Invoice",
s.Driver.FindElement(By.CssSelector("[data-test='pay-button']")).Text.Trim());
s.Driver.SwitchTo().Window(s.Driver.WindowHandles.First());
// archive (from details page)
s.GoToUrl(editUrl);
var payReqId = s.Driver.Url.Split('/').Last();
s.Driver.FindElement(By.Id("ArchivePaymentRequest")).Click();
Assert.Contains("The payment request has been archived", s.FindAlertMessage().Text);
@ -1365,11 +1368,10 @@ namespace BTCPayServer.Tests
newStore = s.CreateNewStore();
s.AddLightningNode();
//Currently an onchain wallet is required to use the Lightning payouts feature..
s.GenerateWallet("BTC", "", true, true);
s.GoToStore(newStore.storeId, StoreNavPages.PullPayments);
s.Driver.FindElement(By.Id("NewPullPayment")).Click();
var paymentMethodOptions = s.Driver.FindElements(By.CssSelector("input[name='PaymentMethods']"));

View file

@ -76,6 +76,11 @@ public class StoreLightningBalance : ViewComponent
// not all implementations support balance fetching
vm.ProblemDescription = "Your node does not support balance fetching.";
}
catch
{
// general error
vm.ProblemDescription = "Could not fetch Lightning balance.";
}
}
else
{

View file

@ -148,7 +148,7 @@ namespace BTCPayServer.Controllers
data = await _PaymentRequestRepository.CreateOrUpdatePaymentRequest(data);
_EventAggregator.Publish(new PaymentRequestUpdated { Data = data, PaymentRequestId = data.Id, });
TempData[WellKnownTempData.SuccessMessage] = $"Payment request [{viewModel.Title}] {(isNewPaymentRequest ? "created" : "updated")} successfully";
TempData[WellKnownTempData.SuccessMessage] = $"Payment request \"{viewModel.Title}\" {(isNewPaymentRequest ? "created" : "updated")} successfully";
return RedirectToAction(nameof(GetPaymentRequests), new { storeId = store.Id, payReqId = data.Id });
}

View file

@ -19,6 +19,7 @@ namespace BTCPayServer.Models
public ViewPullPaymentModel(PullPaymentData data, DateTimeOffset now)
{
Id = data.Id;
StoreId = data.StoreId;
var blob = data.GetBlob();
PaymentMethods = blob.SupportedPaymentMethods;
SelectedPaymentMethod = PaymentMethods.First().ToString();
@ -64,6 +65,8 @@ namespace BTCPayServer.Models
}
}
public string StoreId { get; set; }
public string SelectedPaymentMethod { get; set; }
public PaymentMethodId[] PaymentMethods { get; set; }
@ -87,7 +90,7 @@ namespace BTCPayServer.Models
public string Description { get; set; }
public string EmbeddedCSS { get; set; }
public string CustomCSSLink { get; set; }
public List<PayoutLine> Payouts { get; set; } = new List<PayoutLine>();
public List<PayoutLine> Payouts { get; set; } = new ();
public DateTimeOffset StartDate { get; set; }
public DateTime LastRefreshed { get; set; }
public CurrencyData CurrencyData { get; set; }

View file

@ -27,7 +27,7 @@
else
{
<button type="submit" class="btn btn-primary order-sm-1" id="SaveButton">Save</button>
<a class="btn btn-secondary" target="_blank" asp-action="ViewPaymentRequest" asp-route-payReqId="@Model.Id" id="ViewPaymentRequest">View</a>
<a class="btn btn-secondary" asp-action="ViewPaymentRequest" asp-route-payReqId="@Model.Id" id="ViewPaymentRequest">View</a>
}
</div>
</div>
@ -128,19 +128,22 @@
</div>
</form>
<div class="d-flex gap-3 mt-3">
<a class="btn btn-secondary"
target="_blank"
asp-action="ListInvoices"
asp-controller="UIInvoice"
asp-route-searchterm="@($"orderid:{PaymentRequestRepository.GetOrderIdForPaymentRequest(Model.Id)}")">Invoices</a>
<a class="btn btn-secondary" asp-route-payReqId="@Model.Id" asp-action="ClonePaymentRequest" id="ClonePaymentRequest">Clone</a>
@if (!Model.Archived)
{
<a class="btn btn-secondary" data-bs-toggle="tooltip" title="Archive this payment request so that it does not appear in the payment request list by default" asp-controller="UIPaymentRequest" asp-action="TogglePaymentRequestArchival" asp-route-payReqId="@Model.Id" id="ArchivePaymentRequest">Archive</a>
}
else
{
<a class="btn btn-secondary" data-bs-toggle="tooltip" title="Unarchive this payment request" asp-controller="UIPaymentRequest" asp-action="TogglePaymentRequestArchival" asp-route-payReqId="@Model.Id" id="UnarchivePaymentRequest">Unarchive</a>
}
</div>
@if (!string.IsNullOrEmpty(Model.Id))
{
<div class="d-flex gap-3 mt-3">
<a class="btn btn-secondary"
asp-action="ListInvoices"
asp-controller="UIInvoice"
asp-route-searchterm="@($"orderid:{PaymentRequestRepository.GetOrderIdForPaymentRequest(Model.Id)}")">Invoices</a>
<a class="btn btn-secondary" asp-route-payReqId="@Model.Id" asp-action="ClonePaymentRequest" id="ClonePaymentRequest">Clone</a>
@if (!Model.Archived)
{
<a class="btn btn-secondary" data-bs-toggle="tooltip" title="Archive this payment request so that it does not appear in the payment request list by default" asp-controller="UIPaymentRequest" asp-action="TogglePaymentRequestArchival" asp-route-payReqId="@Model.Id" id="ArchivePaymentRequest">Archive</a>
}
else
{
<a class="btn btn-secondary" data-bs-toggle="tooltip" title="Unarchive this payment request" asp-controller="UIPaymentRequest" asp-action="TogglePaymentRequestArchival" asp-route-payReqId="@Model.Id" id="UnarchivePaymentRequest">Unarchive</a>
}
</div>
}

View file

@ -65,22 +65,20 @@
@foreach (var item in Model.Items)
{
<tr>
<td>@item.Title</td>
<td>
<a asp-action="EditPaymentRequest" asp-route-storeId="@item.StoreId" asp-route-payReqId="@item.Id" id="Edit-@item.Id">@item.Title</a>
</td>
<td>@(item.ExpiryDate?.ToString("g") ?? "No Expiry")</td>
<td class="text-end">@item.Amount @item.Currency</td>
<td class="text-end">@item.Status</td>
<td class="text-end">
<a asp-action="EditPaymentRequest" asp-route-storeId="@item.StoreId" asp-route-payReqId="@item.Id" id="Edit-@item.Id">Edit</a>
<a asp-controller="UIInvoice" asp-action="ListInvoices" asp-route-searchterm="@($"orderid:{PaymentRequestRepository.GetOrderIdForPaymentRequest(item.Id)}")">Invoices</a>
<span> - </span>
<a asp-action="ViewPaymentRequest" asp-route-payReqId="@item.Id">View</a>
<span> - </span>
<a target="_blank" asp-controller="UIInvoice" asp-action="ListInvoices" asp-route-searchterm="@($"orderid:{PaymentRequestRepository.GetOrderIdForPaymentRequest(item.Id)}")">Invoices</a>
<span> - </span>
<a target="_blank" asp-action="PayPaymentRequest" asp-route-payReqId="@item.Id">Pay</a>
<span> - </span>
<a target="_blank" asp-action="ClonePaymentRequest" asp-route-storeId="@item.StoreId" asp-route-payReqId="@item.Id" id="Clone-@item.Id">Clone</a>
<a asp-action="ClonePaymentRequest" asp-route-storeId="@item.StoreId" asp-route-payReqId="@item.Id" id="Clone-@item.Id">Clone</a>
<span> - </span>
<a asp-action="TogglePaymentRequestArchival" asp-route-storeId="@item.StoreId" asp-route-payReqId="@item.Id" id="ToggleArchival-@item.Id">@(item.Archived ? "Unarchive" : "Archive")</a>
<span> - </span>
<a asp-action="ViewPaymentRequest" asp-route-payReqId="@item.Id" id="PaymentRequest-@item.Id">View</a>
</td>
</tr>
}

View file

@ -1,6 +1,11 @@
@using BTCPayServer.Services.Invoices
@using BTCPayServer.Client.Models
@using BTCPayServer.Abstractions.Contracts
@using BTCPayServer.Client
@using BTCPayServer.Components.ThemeSwitch
@using BTCPayServer.TagHelpers
@using BundlerMinifier.TagHelpers
@using Microsoft.AspNetCore.Mvc.TagHelpers
@model BTCPayServer.Models.PaymentRequestViewModels.ViewPaymentRequestViewModel
@addTagHelper *, BundlerMinifier.TagHelpers
@inject BTCPayServer.Services.BTCPayServerEnvironment env
@ -361,6 +366,11 @@
</div>
</main>
<footer class="pt-2 pb-4 d-print-none">
<p class="container text-center" permission="@Policies.CanModifyStoreSettings">
<a asp-controller="UIPaymentRequest" asp-action="EditPaymentRequest" asp-route-storeId="@Model.StoreId" asp-route-payReqId="@Model.Id">
Edit payment request
</a>
</p>
<div class="container d-flex flex-wrap align-items-center justify-content-center">
<span class="text-muted mx-2">
Powered by <a href="https://btcpayserver.org" target="_blank" rel="noreferrer noopener">BTCPay Server</a>

View file

@ -1,9 +1,12 @@
@inject BTCPayServer.Services.BTCPayServerEnvironment env
@inject BTCPayServer.Services.BTCPayServerEnvironment Env
@inject BTCPayServer.Services.ThemeSettings Theme
@using NUglify.Helpers
@using BTCPayServer.Abstractions.Contracts
@using BTCPayServer.Abstractions.Extensions
@using BTCPayServer.Client
@using BTCPayServer.Components.ThemeSwitch
@using Microsoft.AspNetCore.Mvc.TagHelpers
@using BundlerMinifier.TagHelpers
@using BTCPayServer.TagHelpers
@model BTCPayServer.Models.ViewPullPaymentModel
@addTagHelper *, BundlerMinifier.TagHelpers
@ -25,7 +28,7 @@
}
}
<!DOCTYPE html>
<html lang="en" @(env.IsDeveloping ? " data-devenv" : "")>
<html lang="en" @(Env.IsDeveloping ? " data-devenv" : "")>
<head>
<partial name="LayoutHead" />
<bundle name="wwwroot/bundles/payment-request-bundle.min.css" asp-append-version="true"></bundle>
@ -43,8 +46,8 @@
@if (Model.IsPending)
{
<nav class="btcpay-header navbar sticky-top py-3 py-lg-4 d-print-none">
<div class="container">
<form asp-action="ClaimPullPayment" asp-route-pullPaymentId="@Model.Id" class="w-100">
<div class="container gap-3">
<form asp-action="ClaimPullPayment" asp-route-pullPaymentId="@Model.Id" class="flex-fill">
<div class="row align-items-center" style="width:calc(100% + 30px)">
<div class="col-12 mb-3 col-lg-6 mb-lg-0">
<div class="input-group">
@ -145,9 +148,9 @@
<div class="col">
<div class="bg-tile h-100 m-0 p-3 p-sm-5 rounded">
<h2 class="h4 mb-0">Claims</h2>
<div class="table-responsive">
@if (Model.Payouts.Any())
{
@if (Model.Payouts.Any())
{
<div class="table-responsive">
<table class="table my-0">
<thead>
<tr class="table-borderless">
@ -180,18 +183,23 @@
}
</tbody>
</table>
}
else
{
<p class="text-muted mt-3 mb-0">No claim made yet.</p>
}
</div>
</div>
}
else
{
<p class="text-muted mt-3 mb-0">No claim made yet.</p>
}
</div>
</div>
</div>
</div>
</main>
<footer class="pt-2 pb-4 d-print-none">
<p class="container text-center" permission="@Policies.CanViewStoreSettings">
<a asp-controller="UIStorePullPayments" asp-action="Payouts" asp-route-storeId="@Model.StoreId">
Back to payouts
</a>
</p>
<div class="container d-flex flex-wrap align-items-center justify-content-center">
<span class="text-muted mx-2">
Powered by <a href="https://btcpayserver.org" target="_blank" rel="noreferrer noopener">BTCPay Server</a>

View file

@ -29,7 +29,7 @@
}
@section PageHeadContent {
<style type="text/css">
<style>
.tooltip-inner {
text-align: left;
}
@ -90,30 +90,36 @@
}
<table class="table table-hover table-responsive-lg">
<thead class="thead-inverse">
<tr>
<th scope="col">
<a
asp-action="PullPayments"
asp-route-sortOrder="@(nextStartDateSortOrder ?? "asc")"
asp-route-pullPaymentState="@Model.ActiveState"
class="text-nowrap"
title="@(nextStartDateSortOrder == "desc" ? sortByAsc : sortByDesc)">
Start
<span class="fa @(sortIconClass)"></span>
</a>
</th>
<th scope="col">Name</th>
<th scope="col">Automatically Approved</th>
<th scope="col">Refunded</th>
<th scope="col" class="text-end" >Actions</th>
</tr>
<tr>
<th scope="col">Name</th>
<th scope="col">
<a asp-action="PullPayments"
asp-route-sortOrder="@(nextStartDateSortOrder ?? "asc")"
asp-route-pullPaymentState="@Model.ActiveState"
class="text-nowrap"
title="@(nextStartDateSortOrder == "desc" ? sortByAsc : sortByDesc)">
Start
<span class="fa @(sortIconClass)"></span>
</a>
</th>
<th scope="col">Automatically Approved</th>
<th scope="col">Refunded</th>
<th scope="col" class="text-end">Actions</th>
</tr>
</thead>
<tbody>
@foreach (var pp in Model.PullPayments)
{
<tr>
<td>
<a class="pp-payout"
asp-action="Payouts"
asp-route-storeId="@Context.GetRouteValue("storeId")"
asp-route-pullPaymentId="@pp.Id">
@pp.Name
</a>
</td>
<td>@pp.StartDate.ToBrowserDate()</td>
<td>@pp.Name</td>
<td>@pp.AutoApproveClaims</td>
<td class="align-middle">
<div class="progress ppProgress" data-pp="@pp.Id" data-bs-toggle="tooltip" data-bs-html="true">
@ -130,25 +136,19 @@
asp-controller="UIPullPayment"
asp-route-pullPaymentId="@pp.Id">
View
</a> -
<a class="pp-payout"
asp-action="Payouts"
asp-route-storeId="@Context.GetRouteValue("storeId")"
asp-route-pullPaymentId="@pp.Id">
Payouts
</a>
@if (!pp.Archived)
{
<span permission="@Policies.CanModifyStoreSettings"> - </span>
<span permission="@Policies.CanModifyStoreSettings"> - </span>
<a asp-action="ArchivePullPayment"
permission="@Policies.CanModifyStoreSettings"
asp-route-storeId="@Context.GetRouteValue("storeId")"
asp-route-pullPaymentId="@pp.Id"
data-bs-toggle="modal"
data-bs-target="#ConfirmModal"
data-description="Do you really want to archive the pull payment <strong>@pp.Name</strong>?">
permission="@Policies.CanModifyStoreSettings"
asp-route-storeId="@Context.GetRouteValue("storeId")"
asp-route-pullPaymentId="@pp.Id"
data-bs-toggle="modal"
data-bs-target="#ConfirmModal"
data-description="Do you really want to archive the pull payment <strong>@pp.Name</strong>?">
Archive
</a>
</a>
}
</td>
</tr>