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"); currencyInput.SendKeys("BTC");
s.Driver.FindElement(By.Id("SaveButton")).Click(); 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.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("Amount due", s.Driver.FindElement(By.CssSelector("[data-test='amount-due-title']")).Text);
Assert.Equal("Pay Invoice", Assert.Equal("Pay Invoice",
s.Driver.FindElement(By.CssSelector("[data-test='pay-button']")).Text.Trim()); s.Driver.FindElement(By.CssSelector("[data-test='pay-button']")).Text.Trim());
// expire // 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.ExecuteJavaScript("document.getElementById('ExpiryDate').value = '2021-01-21T21:00:00.000Z'");
s.Driver.FindElement(By.Id("SaveButton")).Click(); 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();
s.Driver.SwitchTo().Window(s.Driver.WindowHandles.Last());
s.Driver.Navigate().Refresh(); s.GoToUrl(viewUrl);
Assert.Equal("Expired", s.Driver.WaitForElement(By.CssSelector("[data-test='status']")).Text); Assert.Equal("Expired", s.Driver.WaitForElement(By.CssSelector("[data-test='status']")).Text);
// unexpire // unexpire
s.Driver.SwitchTo().Window(s.Driver.WindowHandles.First()); s.GoToUrl(editUrl);
s.Driver.FindElement(By.Id("ClearExpiryDate")).Click(); s.Driver.FindElement(By.Id("ClearExpiryDate")).Click();
s.Driver.FindElement(By.Id("SaveButton")).Click(); 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();
s.Driver.SwitchTo().Window(s.Driver.WindowHandles.Last());
s.Driver.Navigate().Refresh(); s.GoToUrl(viewUrl);
s.Driver.AssertElementNotFound(By.CssSelector("[data-test='status']")); s.Driver.AssertElementNotFound(By.CssSelector("[data-test='status']"));
Assert.Equal("Pay Invoice", Assert.Equal("Pay Invoice",
s.Driver.FindElement(By.CssSelector("[data-test='pay-button']")).Text.Trim()); s.Driver.FindElement(By.CssSelector("[data-test='pay-button']")).Text.Trim());
s.Driver.SwitchTo().Window(s.Driver.WindowHandles.First());
// archive (from details page) // archive (from details page)
s.GoToUrl(editUrl);
var payReqId = s.Driver.Url.Split('/').Last(); var payReqId = s.Driver.Url.Split('/').Last();
s.Driver.FindElement(By.Id("ArchivePaymentRequest")).Click(); s.Driver.FindElement(By.Id("ArchivePaymentRequest")).Click();
Assert.Contains("The payment request has been archived", s.FindAlertMessage().Text); Assert.Contains("The payment request has been archived", s.FindAlertMessage().Text);
@ -1365,11 +1368,10 @@ namespace BTCPayServer.Tests
newStore = s.CreateNewStore(); newStore = s.CreateNewStore();
s.AddLightningNode(); s.AddLightningNode();
//Currently an onchain wallet is required to use the Lightning payouts feature.. //Currently an onchain wallet is required to use the Lightning payouts feature..
s.GenerateWallet("BTC", "", true, true); s.GenerateWallet("BTC", "", true, true);
s.GoToStore(newStore.storeId, StoreNavPages.PullPayments); s.GoToStore(newStore.storeId, StoreNavPages.PullPayments);
s.Driver.FindElement(By.Id("NewPullPayment")).Click(); s.Driver.FindElement(By.Id("NewPullPayment")).Click();
var paymentMethodOptions = s.Driver.FindElements(By.CssSelector("input[name='PaymentMethods']")); 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 // not all implementations support balance fetching
vm.ProblemDescription = "Your node does not support balance fetching."; vm.ProblemDescription = "Your node does not support balance fetching.";
} }
catch
{
// general error
vm.ProblemDescription = "Could not fetch Lightning balance.";
}
} }
else else
{ {

View file

@ -148,7 +148,7 @@ namespace BTCPayServer.Controllers
data = await _PaymentRequestRepository.CreateOrUpdatePaymentRequest(data); data = await _PaymentRequestRepository.CreateOrUpdatePaymentRequest(data);
_EventAggregator.Publish(new PaymentRequestUpdated { Data = data, PaymentRequestId = data.Id, }); _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 }); 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) public ViewPullPaymentModel(PullPaymentData data, DateTimeOffset now)
{ {
Id = data.Id; Id = data.Id;
StoreId = data.StoreId;
var blob = data.GetBlob(); var blob = data.GetBlob();
PaymentMethods = blob.SupportedPaymentMethods; PaymentMethods = blob.SupportedPaymentMethods;
SelectedPaymentMethod = PaymentMethods.First().ToString(); SelectedPaymentMethod = PaymentMethods.First().ToString();
@ -64,6 +65,8 @@ namespace BTCPayServer.Models
} }
} }
public string StoreId { get; set; }
public string SelectedPaymentMethod { get; set; } public string SelectedPaymentMethod { get; set; }
public PaymentMethodId[] PaymentMethods { get; set; } public PaymentMethodId[] PaymentMethods { get; set; }
@ -87,7 +90,7 @@ namespace BTCPayServer.Models
public string Description { get; set; } public string Description { get; set; }
public string EmbeddedCSS { get; set; } public string EmbeddedCSS { get; set; }
public string CustomCSSLink { 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 DateTimeOffset StartDate { get; set; }
public DateTime LastRefreshed { get; set; } public DateTime LastRefreshed { get; set; }
public CurrencyData CurrencyData { get; set; } public CurrencyData CurrencyData { get; set; }

View file

@ -27,7 +27,7 @@
else else
{ {
<button type="submit" class="btn btn-primary order-sm-1" id="SaveButton">Save</button> <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>
</div> </div>
@ -128,9 +128,10 @@
</div> </div>
</form> </form>
<div class="d-flex gap-3 mt-3"> @if (!string.IsNullOrEmpty(Model.Id))
{
<div class="d-flex gap-3 mt-3">
<a class="btn btn-secondary" <a class="btn btn-secondary"
target="_blank"
asp-action="ListInvoices" asp-action="ListInvoices"
asp-controller="UIInvoice" asp-controller="UIInvoice"
asp-route-searchterm="@($"orderid:{PaymentRequestRepository.GetOrderIdForPaymentRequest(Model.Id)}")">Invoices</a> asp-route-searchterm="@($"orderid:{PaymentRequestRepository.GetOrderIdForPaymentRequest(Model.Id)}")">Invoices</a>
@ -143,4 +144,6 @@
{ {
<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> <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> </div>
}

View file

@ -65,22 +65,20 @@
@foreach (var item in Model.Items) @foreach (var item in Model.Items)
{ {
<tr> <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>@(item.ExpiryDate?.ToString("g") ?? "No Expiry")</td>
<td class="text-end">@item.Amount @item.Currency</td> <td class="text-end">@item.Amount @item.Currency</td>
<td class="text-end">@item.Status</td> <td class="text-end">@item.Status</td>
<td class="text-end"> <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> <span> - </span>
<a asp-action="ViewPaymentRequest" asp-route-payReqId="@item.Id">View</a> <a asp-action="ClonePaymentRequest" asp-route-storeId="@item.StoreId" asp-route-payReqId="@item.Id" id="Clone-@item.Id">Clone</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>
<span> - </span> <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> <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> </td>
</tr> </tr>
} }

View file

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

View file

@ -29,7 +29,7 @@
} }
@section PageHeadContent { @section PageHeadContent {
<style type="text/css"> <style>
.tooltip-inner { .tooltip-inner {
text-align: left; text-align: left;
} }
@ -91,9 +91,9 @@
<table class="table table-hover table-responsive-lg"> <table class="table table-hover table-responsive-lg">
<thead class="thead-inverse"> <thead class="thead-inverse">
<tr> <tr>
<th scope="col">Name</th>
<th scope="col"> <th scope="col">
<a <a asp-action="PullPayments"
asp-action="PullPayments"
asp-route-sortOrder="@(nextStartDateSortOrder ?? "asc")" asp-route-sortOrder="@(nextStartDateSortOrder ?? "asc")"
asp-route-pullPaymentState="@Model.ActiveState" asp-route-pullPaymentState="@Model.ActiveState"
class="text-nowrap" class="text-nowrap"
@ -102,18 +102,24 @@
<span class="fa @(sortIconClass)"></span> <span class="fa @(sortIconClass)"></span>
</a> </a>
</th> </th>
<th scope="col">Name</th>
<th scope="col">Automatically Approved</th> <th scope="col">Automatically Approved</th>
<th scope="col">Refunded</th> <th scope="col">Refunded</th>
<th scope="col" class="text-end" >Actions</th> <th scope="col" class="text-end">Actions</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@foreach (var pp in Model.PullPayments) @foreach (var pp in Model.PullPayments)
{ {
<tr> <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.StartDate.ToBrowserDate()</td>
<td>@pp.Name</td>
<td>@pp.AutoApproveClaims</td> <td>@pp.AutoApproveClaims</td>
<td class="align-middle"> <td class="align-middle">
<div class="progress ppProgress" data-pp="@pp.Id" data-bs-toggle="tooltip" data-bs-html="true"> <div class="progress ppProgress" data-pp="@pp.Id" data-bs-toggle="tooltip" data-bs-html="true">
@ -130,12 +136,6 @@
asp-controller="UIPullPayment" asp-controller="UIPullPayment"
asp-route-pullPaymentId="@pp.Id"> asp-route-pullPaymentId="@pp.Id">
View View
</a> -
<a class="pp-payout"
asp-action="Payouts"
asp-route-storeId="@Context.GetRouteValue("storeId")"
asp-route-pullPaymentId="@pp.Id">
Payouts
</a> </a>
@if (!pp.Archived) @if (!pp.Archived)
{ {