mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2024-11-19 09:54:30 +01:00
Edit view for Pull Payments (#4016)
Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
This commit is contained in:
parent
7f41a1ef09
commit
8c8a5a4f5e
@ -30,7 +30,6 @@ using Newtonsoft.Json.Linq;
|
||||
using OpenQA.Selenium;
|
||||
using OpenQA.Selenium.Support.Extensions;
|
||||
using OpenQA.Selenium.Support.UI;
|
||||
using Renci.SshNet.Security.Cryptography;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
@ -1300,6 +1299,46 @@ namespace BTCPayServer.Tests
|
||||
s.Driver.AssertElementNotFound(By.Id("ActionsDropdownToggle"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Selenium", "Selenium")]
|
||||
[Trait("Lightning", "Lightning")]
|
||||
public async Task CanEditPullPaymentUI()
|
||||
{
|
||||
using var s = CreateSeleniumTester();
|
||||
s.Server.ActivateLightning(LightningConnectionType.LndREST);
|
||||
await s.StartAsync();
|
||||
await s.Server.EnsureChannelsSetup();
|
||||
s.RegisterNewUser(true);
|
||||
s.CreateNewStore();
|
||||
s.GenerateWallet("BTC", "", true, true);
|
||||
await s.Server.ExplorerNode.GenerateAsync(1);
|
||||
await s.FundStoreWallet(denomination: 50.0m);
|
||||
|
||||
s.GoToStore(s.StoreId, StoreNavPages.PullPayments);
|
||||
|
||||
s.Driver.FindElement(By.Id("NewPullPayment")).Click();
|
||||
s.Driver.FindElement(By.Id("Name")).SendKeys("PP1");
|
||||
s.Driver.FindElement(By.Id("Amount")).Clear();
|
||||
s.Driver.FindElement(By.Id("Amount")).SendKeys("99.0");
|
||||
s.Driver.FindElement(By.Id("Create")).Click();
|
||||
s.Driver.FindElement(By.LinkText("View")).Click();
|
||||
|
||||
s.GoToStore(s.StoreId, StoreNavPages.PullPayments);
|
||||
|
||||
s.Driver.FindElement(By.LinkText("PP1")).Click();
|
||||
var name = s.Driver.FindElement(By.Id("Name"));
|
||||
name.Clear();
|
||||
name.SendKeys("PP1 Edited");
|
||||
var description = s.Driver.FindElement(By.ClassName("card-block"));
|
||||
description.SendKeys("Description Edit");
|
||||
s.Driver.FindElement(By.Id("SaveButton")).Click();
|
||||
|
||||
s.Driver.FindElement(By.LinkText("PP1 Edited")).Click();
|
||||
|
||||
Assert.Contains("Description Edit", s.Driver.PageSource);
|
||||
Assert.Contains("PP1 Edited", s.Driver.PageSource);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Selenium", "Selenium")]
|
||||
[Trait("Lightning", "Lightning")]
|
||||
|
@ -1,14 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Abstractions.Constants;
|
||||
using BTCPayServer.Abstractions.Extensions;
|
||||
using BTCPayServer.Abstractions.Models;
|
||||
using BTCPayServer.Client;
|
||||
using BTCPayServer.Client.Models;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.HostedServices;
|
||||
using BTCPayServer.Models;
|
||||
using BTCPayServer.Models.WalletViewModels;
|
||||
using BTCPayServer.Payments;
|
||||
using BTCPayServer.Services;
|
||||
using BTCPayServer.Services.Rates;
|
||||
@ -19,7 +21,6 @@ using NBitcoin;
|
||||
|
||||
namespace BTCPayServer.Controllers
|
||||
{
|
||||
[AllowAnonymous]
|
||||
public class UIPullPaymentController : Controller
|
||||
{
|
||||
private readonly ApplicationDbContextFactory _dbContextFactory;
|
||||
@ -41,7 +42,8 @@ namespace BTCPayServer.Controllers
|
||||
_payoutHandlers = payoutHandlers;
|
||||
}
|
||||
|
||||
[Route("pull-payments/{pullPaymentId}")]
|
||||
[AllowAnonymous]
|
||||
[HttpGet("pull-payments/{pullPaymentId}")]
|
||||
public async Task<IActionResult> ViewPullPayment(string pullPaymentId)
|
||||
{
|
||||
using var ctx = _dbContextFactory.CreateContext();
|
||||
@ -92,6 +94,64 @@ namespace BTCPayServer.Controllers
|
||||
return View(nameof(ViewPullPayment), vm);
|
||||
}
|
||||
|
||||
[HttpGet("stores/{storeId}/pull-payments/edit/{pullPaymentId}")]
|
||||
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
|
||||
public async Task<IActionResult> EditPullPayment(string storeId, string pullPaymentId)
|
||||
{
|
||||
using var ctx = _dbContextFactory.CreateContext();
|
||||
Data.PullPaymentData pp = await ctx.PullPayments.FindAsync(pullPaymentId);
|
||||
if (pp == null && !string.IsNullOrEmpty(pullPaymentId))
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var vm = new UpdatePullPaymentModel(pp);
|
||||
return View(vm);
|
||||
}
|
||||
|
||||
[HttpPost("stores/{storeId}/pull-payments/edit/{pullPaymentId}")]
|
||||
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
|
||||
public async Task<IActionResult> EditPullPayment(string storeId, string pullPaymentId, UpdatePullPaymentModel viewModel)
|
||||
{
|
||||
using var ctx = _dbContextFactory.CreateContext();
|
||||
|
||||
var pp = await ctx.PullPayments.FindAsync(pullPaymentId);
|
||||
if (pp == null && !string.IsNullOrEmpty(pullPaymentId))
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
var blob = pp.GetBlob();
|
||||
blob.Description = viewModel.Description ?? string.Empty;
|
||||
blob.Name = viewModel.Name ?? string.Empty;
|
||||
blob.View = new PullPaymentBlob.PullPaymentView()
|
||||
{
|
||||
Title = viewModel.Name ?? string.Empty,
|
||||
Description = viewModel.Description ?? string.Empty,
|
||||
CustomCSSLink = viewModel.CustomCSSLink,
|
||||
Email = null,
|
||||
EmbeddedCSS = viewModel.EmbeddedCSS,
|
||||
};
|
||||
|
||||
pp.SetBlob(blob);
|
||||
ctx.PullPayments.Update(pp);
|
||||
await ctx.SaveChangesAsync();
|
||||
|
||||
TempData.SetStatusMessageModel(new StatusMessageModel
|
||||
{
|
||||
Message = "Pull payment updated successfully",
|
||||
Severity = StatusMessageModel.StatusSeverity.Success
|
||||
});
|
||||
|
||||
return RedirectToAction(nameof(UIStorePullPaymentsController.PullPayments), "UIStorePullPayments", new { storeId, pullPaymentId });
|
||||
}
|
||||
|
||||
[AllowAnonymous]
|
||||
[HttpPost("pull-payments/{pullPaymentId}/claim")]
|
||||
public async Task<IActionResult> ClaimPullPayment(string pullPaymentId, ViewPullPaymentModel vm)
|
||||
{
|
||||
|
@ -5,6 +5,7 @@ using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using BTCPayServer.Payments;
|
||||
using BTCPayServer.Client.Models;
|
||||
using BTCPayServer.Data;
|
||||
|
||||
namespace BTCPayServer.Models.WalletViewModels
|
||||
{
|
||||
@ -70,4 +71,37 @@ namespace BTCPayServer.Models.WalletViewModels
|
||||
[Display(Name = "Automatically approve claims")]
|
||||
public bool AutoApproveClaims { get; set; } = false;
|
||||
}
|
||||
|
||||
public class UpdatePullPaymentModel
|
||||
{
|
||||
|
||||
public string Id { get; set; }
|
||||
|
||||
public UpdatePullPaymentModel()
|
||||
{
|
||||
}
|
||||
|
||||
public UpdatePullPaymentModel(Data.PullPaymentData data)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Id = data.Id;
|
||||
var blob = data.GetBlob();
|
||||
Name = blob.Name;
|
||||
Description = blob.Description;
|
||||
CustomCSSLink = blob.View.CustomCSSLink;
|
||||
EmbeddedCSS = blob.View.EmbeddedCSS;
|
||||
}
|
||||
|
||||
[MaxLength(30)]
|
||||
public string Name { get; set; }
|
||||
public string Description { get; set; }
|
||||
[Display(Name = "Custom CSS URL")]
|
||||
public string CustomCSSLink { get; set; }
|
||||
[Display(Name = "Custom CSS Code")]
|
||||
public string EmbeddedCSS { get; set; }
|
||||
}
|
||||
}
|
||||
|
92
BTCPayServer/Views/UIPullPayment/EditPullPayment.cshtml
Normal file
92
BTCPayServer/Views/UIPullPayment/EditPullPayment.cshtml
Normal file
@ -0,0 +1,92 @@
|
||||
@using BTCPayServer.Views.Stores
|
||||
@using BTCPayServer.Abstractions.Extensions
|
||||
@model BTCPayServer.Models.WalletViewModels.UpdatePullPaymentModel
|
||||
|
||||
@{
|
||||
ViewData.SetActivePage(StoreNavPages.Create, "Edit Pull Payment", Model.Id);
|
||||
}
|
||||
|
||||
@section PageHeadContent {
|
||||
<link href="~/vendor/summernote/summernote-bs5.css" rel="stylesheet" asp-append-version="true" />
|
||||
}
|
||||
|
||||
@section PageFootContent {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
<script src="~/vendor/summernote/summernote-bs5.js" asp-append-version="true"></script>
|
||||
}
|
||||
|
||||
<form method="post" asp-action="EditPullPayment" asp-route-storeId="@Context.GetRouteValue("storeId")" asp-route-pullPaymentId="@Model.Id">
|
||||
<div class="sticky-header-setup"></div>
|
||||
<div class="sticky-header d-sm-flex align-items-center justify-content-between">
|
||||
<h2 class="mb-0">@ViewData["Title"]</h2>
|
||||
<div class="d-flex gap-3 mt-3 mt-sm-0">
|
||||
@if (string.IsNullOrEmpty(Model.Id))
|
||||
{
|
||||
<button type="submit" class="btn btn-primary" id="SaveButton">Create</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button type="submit" class="btn btn-primary order-sm-1" id="SaveButton">Save</button>
|
||||
<a class="btn btn-secondary" asp-action="ViewPullPayment" asp-route-pullPaymentId="@Model.Id" id="ViewPullPayment">View</a>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xl-8 col-xxl-constrain">
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Name" class="form-label" data-required></label>
|
||||
<input asp-for="Name" class="form-control" required />
|
||||
<span asp-validation-for="Name" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xl-10 col-xxl-constrain">
|
||||
<div class="form-group">
|
||||
<label asp-for="Description" class="form-label"></label>
|
||||
<textarea asp-for="Description" class="form-control richtext"></textarea>
|
||||
<span asp-validation-for="Description" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xl-8 col-xxl-constrain">
|
||||
<h4 class="mt-5 mb-2">Additional Options</h4>
|
||||
<div class="form-group">
|
||||
<div class="accordion" id="additional">
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="additional-custom-css-header">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#additional-custom-css" aria-expanded="false" aria-controls="additional-custom-css">
|
||||
Custom CSS
|
||||
<vc:icon symbol="caret-down" />
|
||||
</button>
|
||||
</h2>
|
||||
<div id="additional-custom-css" class="accordion-collapse collapse" aria-labelledby="additional-custom-css-header">
|
||||
<div class="accordion-body">
|
||||
<div class="form-group">
|
||||
<label asp-for="CustomCSSLink" class="form-label"></label>
|
||||
<a href="https://docs.btcpayserver.org/Development/Theme/#2-bootstrap-themes" target="_blank" rel="noreferrer noopener">
|
||||
<span class="fa fa-question-circle-o text-secondary" title="More information..."></span>
|
||||
</a>
|
||||
<input asp-for="CustomCSSLink" class="form-control" />
|
||||
<span asp-validation-for="CustomCSSLink" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="EmbeddedCSS" class="form-label"></label>
|
||||
<textarea asp-for="EmbeddedCSS" rows="10" cols="40" class="form-control"></textarea>
|
||||
<span asp-validation-for="EmbeddedCSS" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -215,8 +215,11 @@
|
||||
</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 asp-action="EditPullPayment"
|
||||
asp-controller="UIPullPayment"
|
||||
asp-route-storeId="@Model.StoreId"
|
||||
asp-route-pullPaymentId="@Model.Id">
|
||||
Edit pull payment
|
||||
</a>
|
||||
</p>
|
||||
<div class="container d-flex flex-wrap align-items-center justify-content-center">
|
||||
|
@ -113,8 +113,8 @@
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<a class="pp-payout"
|
||||
asp-action="Payouts"
|
||||
<a asp-action="EditPullPayment"
|
||||
asp-controller="UIPullPayment"
|
||||
asp-route-storeId="@Context.GetRouteValue("storeId")"
|
||||
asp-route-pullPaymentId="@pp.Id">
|
||||
@pp.Name
|
||||
@ -133,10 +133,11 @@
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<a asp-action="ViewPullPayment"
|
||||
asp-controller="UIPullPayment"
|
||||
<a class="pp-payout"
|
||||
asp-action="Payouts"
|
||||
asp-route-storeId="@Context.GetRouteValue("storeId")"
|
||||
asp-route-pullPaymentId="@pp.Id">
|
||||
View
|
||||
Payouts
|
||||
</a>
|
||||
@if (!pp.Archived)
|
||||
{
|
||||
@ -151,6 +152,12 @@
|
||||
Archive
|
||||
</a>
|
||||
}
|
||||
<span> - </span>
|
||||
<a asp-action="ViewPullPayment"
|
||||
asp-controller="UIPullPayment"
|
||||
asp-route-pullPaymentId="@pp.Id">
|
||||
View
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user