mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-18 14:34:23 +01:00
Refactor: Remove cshtml duplication for back/url buttons in wizards
This commit is contained in:
@@ -1960,7 +1960,7 @@ namespace BTCPayServer.Tests
|
|||||||
s.Driver.FindElement(By.Id("SignTransaction")).Click();
|
s.Driver.FindElement(By.Id("SignTransaction")).Click();
|
||||||
// Back button should lead back to the previous page inside the send wizard
|
// Back button should lead back to the previous page inside the send wizard
|
||||||
var backUrl = s.Driver.FindElement(By.Id("GoBack")).GetAttribute("href");
|
var backUrl = s.Driver.FindElement(By.Id("GoBack")).GetAttribute("href");
|
||||||
Assert.EndsWith($"/send?returnUrl={walletTransactionUri.AbsolutePath}", backUrl);
|
Assert.EndsWith($"/send?returnUrl={Uri.EscapeDataString(walletTransactionUri.AbsolutePath)}", backUrl);
|
||||||
// Cancel button should lead to the page that referred to the send wizard
|
// Cancel button should lead to the page that referred to the send wizard
|
||||||
var cancelUrl = s.Driver.FindElement(By.Id("CancelWizard")).GetAttribute("href");
|
var cancelUrl = s.Driver.FindElement(By.Id("CancelWizard")).GetAttribute("href");
|
||||||
Assert.EndsWith(walletTransactionUri.AbsolutePath, cancelUrl);
|
Assert.EndsWith(walletTransactionUri.AbsolutePath, cancelUrl);
|
||||||
|
|||||||
@@ -12,6 +12,10 @@ namespace Microsoft.AspNetCore.Mvc
|
|||||||
public static class UrlHelperExtensions
|
public static class UrlHelperExtensions
|
||||||
{
|
{
|
||||||
#nullable enable
|
#nullable enable
|
||||||
|
public static string? WalletSend(this IUrlHelper helper, WalletId walletId) => helper.Action(nameof(UIWalletsController.WalletSend), new { walletId });
|
||||||
|
public static string? WalletTransactions(this IUrlHelper helper, string walletId) => WalletTransactions(helper, WalletId.Parse(walletId));
|
||||||
|
public static string? WalletTransactions(this IUrlHelper helper, WalletId walletId)
|
||||||
|
=> helper.Action(nameof(UIWalletsController.WalletTransactions), new { walletId });
|
||||||
public static Uri ActionAbsolute(this IUrlHelper helper, HttpRequest request, string? action, string? controller, object? values)
|
public static Uri ActionAbsolute(this IUrlHelper helper, HttpRequest request, string? action, string? controller, object? values)
|
||||||
=> request.GetAbsoluteUriNoPathBase(new Uri(helper.Action(action, controller, values) ?? "", UriKind.Relative));
|
=> request.GetAbsoluteUriNoPathBase(new Uri(helper.Action(action, controller, values) ?? "", UriKind.Relative));
|
||||||
public static Uri ActionAbsolute(this IUrlHelper helper, HttpRequest request, string? action, string? controller)
|
public static Uri ActionAbsolute(this IUrlHelper helper, HttpRequest request, string? action, string? controller)
|
||||||
|
|||||||
25
BTCPayServer/Models/IHasBackAndReturnUrl.cs
Normal file
25
BTCPayServer/Models/IHasBackAndReturnUrl.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System;
|
||||||
|
using BTCPayServer.Controllers;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Models
|
||||||
|
{
|
||||||
|
public interface IHasBackAndReturnUrl
|
||||||
|
{
|
||||||
|
string? BackUrl { get; set; }
|
||||||
|
string? ReturnUrl { get; set; }
|
||||||
|
(string? backUrl, string? returnUrl) NormalizeBackAndReturnUrl()
|
||||||
|
{
|
||||||
|
var backUrl = BackUrl;
|
||||||
|
if (backUrl is not null && ReturnUrl is not null)
|
||||||
|
{
|
||||||
|
var queryParam = $"returnUrl={Uri.EscapeDataString(ReturnUrl)}";
|
||||||
|
if (backUrl.Contains('?'))
|
||||||
|
backUrl = $"{backUrl}&{queryParam}";
|
||||||
|
else
|
||||||
|
backUrl = $"{backUrl}?{queryParam}";
|
||||||
|
}
|
||||||
|
return (backUrl, ReturnUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ using NBitcoin;
|
|||||||
|
|
||||||
namespace BTCPayServer.Models.WalletViewModels
|
namespace BTCPayServer.Models.WalletViewModels
|
||||||
{
|
{
|
||||||
public class SignWithSeedViewModel
|
public class SignWithSeedViewModel : IHasBackAndReturnUrl
|
||||||
{
|
{
|
||||||
public SigningContextModel SigningContext { get; set; } = new SigningContextModel();
|
public SigningContextModel SigningContext { get; set; } = new SigningContextModel();
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using NBitcoin;
|
|||||||
|
|
||||||
namespace BTCPayServer.Models.WalletViewModels
|
namespace BTCPayServer.Models.WalletViewModels
|
||||||
{
|
{
|
||||||
public class WalletPSBTCombineViewModel
|
public class WalletPSBTCombineViewModel : IHasBackAndReturnUrl
|
||||||
{
|
{
|
||||||
public string OtherPSBT { get; set; }
|
public string OtherPSBT { get; set; }
|
||||||
[Display(Name = "PSBT to combine with…")]
|
[Display(Name = "PSBT to combine with…")]
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using NBitcoin;
|
|||||||
|
|
||||||
namespace BTCPayServer.Models.WalletViewModels
|
namespace BTCPayServer.Models.WalletViewModels
|
||||||
{
|
{
|
||||||
public class WalletPSBTReadyViewModel
|
public class WalletPSBTReadyViewModel : IHasBackAndReturnUrl
|
||||||
{
|
{
|
||||||
public SigningContextModel SigningContext { get; set; } = new SigningContextModel();
|
public SigningContextModel SigningContext { get; set; } = new SigningContextModel();
|
||||||
public string SigningKey { get; set; }
|
public string SigningKey { get; set; }
|
||||||
@@ -27,6 +27,12 @@ namespace BTCPayServer.Models.WalletViewModels
|
|||||||
public string BalanceChange { get; set; }
|
public string BalanceChange { get; set; }
|
||||||
public IEnumerable<TransactionTagModel> Labels { get; set; } = new List<TransactionTagModel>();
|
public IEnumerable<TransactionTagModel> Labels { get; set; } = new List<TransactionTagModel>();
|
||||||
}
|
}
|
||||||
|
public class AmountViewModel
|
||||||
|
{
|
||||||
|
public bool Positive { get; set; }
|
||||||
|
public string BalanceChange { get; set; }
|
||||||
|
}
|
||||||
|
public AmountViewModel ReplacementBalanceChange { get; set; }
|
||||||
public bool HasErrors => Inputs.Count == 0 || Inputs.Any(i => !string.IsNullOrEmpty(i.Error));
|
public bool HasErrors => Inputs.Count == 0 || Inputs.Any(i => !string.IsNullOrEmpty(i.Error));
|
||||||
public string BalanceChange { get; set; }
|
public string BalanceChange { get; set; }
|
||||||
public bool CanCalculateBalance { get; set; }
|
public bool CanCalculateBalance { get; set; }
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using BTCPayServer.Services.Labels;
|
|||||||
|
|
||||||
namespace BTCPayServer.Models.WalletViewModels
|
namespace BTCPayServer.Models.WalletViewModels
|
||||||
{
|
{
|
||||||
public class WalletSendModel
|
public class WalletSendModel : IHasBackAndReturnUrl
|
||||||
{
|
{
|
||||||
public enum ThreeStateBool
|
public enum ThreeStateBool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace BTCPayServer.Models.WalletViewModels
|
namespace BTCPayServer.Models.WalletViewModels
|
||||||
{
|
{
|
||||||
public class WalletSendVaultModel
|
public class WalletSendVaultModel : IHasBackAndReturnUrl
|
||||||
{
|
{
|
||||||
public string WalletId { get; set; }
|
public string WalletId { get; set; }
|
||||||
public string WebsocketPath { get; set; }
|
public string WebsocketPath { get; set; }
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ using System;
|
|||||||
|
|
||||||
namespace BTCPayServer.Models.WalletViewModels
|
namespace BTCPayServer.Models.WalletViewModels
|
||||||
{
|
{
|
||||||
public class WalletSigningOptionsModel
|
public class WalletSigningOptionsModel : IHasBackAndReturnUrl
|
||||||
{
|
{
|
||||||
public SigningContextModel SigningContext { get; set; }
|
public SigningContextModel SigningContext { get; set; }
|
||||||
public string BackUrl { get; set; }
|
public string BackUrl { get; set; }
|
||||||
|
|||||||
15
BTCPayServer/Views/Shared/_BackAndReturn.cshtml
Normal file
15
BTCPayServer/Views/Shared/_BackAndReturn.cshtml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
@model BTCPayServer.Models.IHasBackAndReturnUrl
|
||||||
|
@{
|
||||||
|
(var backUrl, var cancelUrl) = this.Model.NormalizeBackAndReturnUrl();
|
||||||
|
cancelUrl ??= Context.Request.Query["returnUrl"].ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (backUrl != null)
|
||||||
|
{
|
||||||
|
<a href="@Url.EnsureLocal(backUrl, Context.Request)" id="GoBack">
|
||||||
|
<vc:icon symbol="back" />
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
<a href="@Url.EnsureLocal(cancelUrl, Context.Request)" id="CancelWizard" class="cancel">
|
||||||
|
<vc:icon symbol="cross" />
|
||||||
|
</a>
|
||||||
@@ -1,23 +1,14 @@
|
|||||||
@using BTCPayServer.Controllers
|
@using BTCPayServer.Controllers
|
||||||
@model SignWithSeedViewModel
|
@model SignWithSeedViewModel
|
||||||
@{
|
@{
|
||||||
var walletId = Context.GetRouteValue("walletId").ToString();
|
var walletId = Context.GetRouteValue("walletId").ToString();
|
||||||
var cancelUrl = Model.ReturnUrl ?? Url.Action(nameof(UIWalletsController.WalletTransactions), new { walletId });
|
Model.ReturnUrl ??= Url.WalletTransactions(walletId);
|
||||||
var backUrl = Model.BackUrl != null ? $"{Model.BackUrl}?returnUrl={Model.ReturnUrl}" : null;
|
|
||||||
Layout = "_LayoutWizard";
|
Layout = "_LayoutWizard";
|
||||||
ViewData.SetActivePage(WalletsNavPages.Send, StringLocalizer["Sign PSBT"], walletId);
|
ViewData.SetActivePage(WalletsNavPages.Send, StringLocalizer["Sign PSBT"], walletId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@section Navbar {
|
@section Navbar {
|
||||||
@if (backUrl != null)
|
<partial name="_BackAndReturn" model="Model" />
|
||||||
{
|
|
||||||
<a href="@Url.EnsureLocal(backUrl, Context.Request)" id="GoBack">
|
|
||||||
<vc:icon symbol="back" />
|
|
||||||
</a>
|
|
||||||
}
|
|
||||||
<a href="@Url.EnsureLocal(cancelUrl, Context.Request)" id="CancelWizard" class="cancel">
|
|
||||||
<vc:icon symbol="cross" />
|
|
||||||
</a>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<header class="text-center">
|
<header class="text-center">
|
||||||
|
|||||||
@@ -3,23 +3,14 @@
|
|||||||
@model WalletPSBTViewModel
|
@model WalletPSBTViewModel
|
||||||
@{
|
@{
|
||||||
var walletId = Context.GetRouteValue("walletId").ToString();
|
var walletId = Context.GetRouteValue("walletId").ToString();
|
||||||
var cancelUrl = Model.ReturnUrl ?? Url.Action(nameof(UIWalletsController.WalletTransactions), new { walletId });
|
Model.ReturnUrl ??= Url.WalletTransactions(walletId);
|
||||||
var backUrl = Model.BackUrl != null ? $"{Model.BackUrl}?returnUrl={Model.ReturnUrl}" : null;
|
|
||||||
Layout = "_LayoutWizard";
|
Layout = "_LayoutWizard";
|
||||||
ViewData.SetActivePage(WalletsNavPages.PSBT, StringLocalizer["Decode PSBT"], walletId);
|
ViewData.SetActivePage(WalletsNavPages.PSBT, StringLocalizer["Decode PSBT"], walletId);
|
||||||
Csp.UnsafeEval();
|
Csp.UnsafeEval();
|
||||||
}
|
}
|
||||||
|
|
||||||
@section Navbar {
|
@section Navbar {
|
||||||
@if (backUrl != null)
|
<partial name="_BackAndReturn" model="Model" />
|
||||||
{
|
|
||||||
<a href="@Url.EnsureLocal(backUrl, Context.Request)" id="GoBack">
|
|
||||||
<vc:icon symbol="back" />
|
|
||||||
</a>
|
|
||||||
}
|
|
||||||
<a href="@Url.EnsureLocal(cancelUrl, Context.Request)" id="CancelWizard" class="cancel">
|
|
||||||
<vc:icon symbol="cross" />
|
|
||||||
</a>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@section PageHeadContent {
|
@section PageHeadContent {
|
||||||
|
|||||||
@@ -2,22 +2,13 @@
|
|||||||
@model WalletPSBTCombineViewModel
|
@model WalletPSBTCombineViewModel
|
||||||
@{
|
@{
|
||||||
var walletId = Context.GetRouteValue("walletId").ToString();
|
var walletId = Context.GetRouteValue("walletId").ToString();
|
||||||
var cancelUrl = Model.ReturnUrl ?? Url.Action(nameof(UIWalletsController.WalletTransactions), new { walletId });
|
Model.ReturnUrl ??= Url.WalletTransactions(walletId);
|
||||||
var backUrl = Model.BackUrl != null ? $"{Model.BackUrl}?returnUrl={Model.ReturnUrl}" : null;
|
|
||||||
Layout = "_LayoutWizard";
|
Layout = "_LayoutWizard";
|
||||||
ViewData.SetActivePage(WalletsNavPages.PSBT, StringLocalizer["Combine PSBT"], walletId);
|
ViewData.SetActivePage(WalletsNavPages.PSBT, StringLocalizer["Combine PSBT"], walletId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@section Navbar {
|
@section Navbar {
|
||||||
@if (backUrl != null)
|
<partial name="_BackAndReturn" model="Model" />
|
||||||
{
|
|
||||||
<a href="@Url.EnsureLocal(backUrl, Context.Request)" id="GoBack">
|
|
||||||
<vc:icon symbol="back" />
|
|
||||||
</a>
|
|
||||||
}
|
|
||||||
<a href="@Url.EnsureLocal(cancelUrl, Context.Request)" id="CancelWizard" class="cancel">
|
|
||||||
<vc:icon symbol="cross" />
|
|
||||||
</a>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<header class="text-center">
|
<header class="text-center">
|
||||||
|
|||||||
@@ -2,10 +2,9 @@
|
|||||||
@inject BTCPayServer.Security.ContentSecurityPolicies Csp
|
@inject BTCPayServer.Security.ContentSecurityPolicies Csp
|
||||||
@model WalletPSBTViewModel
|
@model WalletPSBTViewModel
|
||||||
@{
|
@{
|
||||||
var walletId = Context.GetRouteValue("walletId").ToString();
|
var walletId = Context.GetRouteValue("walletId").ToString();
|
||||||
var cancelUrl = Model.ReturnUrl ?? Url.Action(nameof(UIWalletsController.WalletTransactions), new {walletId});
|
Model.ReturnUrl ??= Url.WalletTransactions(walletId);
|
||||||
var backUrl = Model.BackUrl != null ? $"{Model.BackUrl}?returnUrl={Model.ReturnUrl}" : null;
|
var isReady = !Model.HasErrors;
|
||||||
var isReady = !Model.HasErrors;
|
|
||||||
var isSignable = !isReady;
|
var isSignable = !isReady;
|
||||||
var needsExport = !isSignable && !isReady;
|
var needsExport = !isSignable && !isReady;
|
||||||
Layout = "_LayoutWizard";
|
Layout = "_LayoutWizard";
|
||||||
@@ -78,15 +77,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@section Navbar {
|
@section Navbar {
|
||||||
@if (backUrl != null)
|
<partial name="_BackAndReturn" model="Model" />
|
||||||
{
|
|
||||||
<a href="@Url.EnsureLocal(backUrl, Context.Request)" id="GoBack">
|
|
||||||
<vc:icon symbol="back" />
|
|
||||||
</a>
|
|
||||||
}
|
|
||||||
<a href="@Url.EnsureLocal(cancelUrl, Context.Request)" id="CancelWizard" class="cancel">
|
|
||||||
<vc:icon symbol="cross" />
|
|
||||||
</a>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<header class="text-center mb-3">
|
<header class="text-center mb-3">
|
||||||
|
|||||||
@@ -7,8 +7,7 @@
|
|||||||
@model WalletSendModel
|
@model WalletSendModel
|
||||||
@{
|
@{
|
||||||
var walletId = Context.GetRouteValue("walletId").ToString();
|
var walletId = Context.GetRouteValue("walletId").ToString();
|
||||||
var cancelUrl = Model.ReturnUrl ?? Url.Action(nameof(UIWalletsController.WalletTransactions), new { walletId });
|
Model.ReturnUrl ??= Url.WalletTransactions(walletId);
|
||||||
var backUrl = Model.BackUrl != null ? $"{Model.BackUrl}?returnUrl={Model.ReturnUrl}" : null;
|
|
||||||
Layout = "_LayoutWizard";
|
Layout = "_LayoutWizard";
|
||||||
ViewData.SetActivePage(WalletsNavPages.Send, StringLocalizer["Send {0}", Model.CryptoCode], walletId);
|
ViewData.SetActivePage(WalletsNavPages.Send, StringLocalizer["Send {0}", Model.CryptoCode], walletId);
|
||||||
Csp.Add("worker-src", "blob:");
|
Csp.Add("worker-src", "blob:");
|
||||||
@@ -16,15 +15,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@section Navbar {
|
@section Navbar {
|
||||||
@if (backUrl != null)
|
<partial name="_BackAndReturn" model="Model" />
|
||||||
{
|
|
||||||
<a href="@Url.EnsureLocal(backUrl, Context.Request)" id="GoBack">
|
|
||||||
<vc:icon symbol="back" />
|
|
||||||
</a>
|
|
||||||
}
|
|
||||||
<a href="@Url.EnsureLocal(cancelUrl, Context.Request)" id="CancelWizard" class="cancel">
|
|
||||||
<vc:icon symbol="cross" />
|
|
||||||
</a>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@section PageHeadContent
|
@section PageHeadContent
|
||||||
|
|||||||
@@ -2,22 +2,13 @@
|
|||||||
@model WalletSendVaultModel
|
@model WalletSendVaultModel
|
||||||
@{
|
@{
|
||||||
var walletId = Context.GetRouteValue("walletId").ToString();
|
var walletId = Context.GetRouteValue("walletId").ToString();
|
||||||
var cancelUrl = Model.ReturnUrl ?? Url.Action(nameof(UIWalletsController.WalletTransactions), new { walletId });
|
Model.ReturnUrl ??= Url.WalletTransactions(walletId);
|
||||||
var backUrl = Model.BackUrl != null ? $"{Model.BackUrl}?returnUrl={Model.ReturnUrl}" : null;
|
|
||||||
Layout = "_LayoutWizard";
|
Layout = "_LayoutWizard";
|
||||||
ViewData.SetActivePage(WalletsNavPages.Send, StringLocalizer["Sign the transaction"], walletId);
|
ViewData.SetActivePage(WalletsNavPages.Send, StringLocalizer["Sign the transaction"], walletId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@section Navbar {
|
@section Navbar {
|
||||||
@if (backUrl != null)
|
<partial name="_BackAndReturn" model="Model" />
|
||||||
{
|
|
||||||
<a href="@Url.EnsureLocal(backUrl, Context.Request)" id="GoBack">
|
|
||||||
<vc:icon symbol="back" />
|
|
||||||
</a>
|
|
||||||
}
|
|
||||||
<a href="@Url.EnsureLocal(cancelUrl, Context.Request)" id="CancelWizard" class="cancel">
|
|
||||||
<vc:icon symbol="cross" />
|
|
||||||
</a>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<header class="text-center">
|
<header class="text-center">
|
||||||
|
|||||||
@@ -3,22 +3,13 @@
|
|||||||
@inject BTCPayNetworkProvider BTCPayNetworkProvider
|
@inject BTCPayNetworkProvider BTCPayNetworkProvider
|
||||||
@{
|
@{
|
||||||
var walletId = WalletId.Parse(Context.GetRouteValue("walletId").ToString());
|
var walletId = WalletId.Parse(Context.GetRouteValue("walletId").ToString());
|
||||||
var cancelUrl = Model.ReturnUrl ?? Url.Action(nameof(UIWalletsController.WalletTransactions), new { walletId });
|
Model.ReturnUrl ??= Url.WalletTransactions(walletId);
|
||||||
var backUrl = Model.BackUrl != null ? $"{Model.BackUrl}?returnUrl={Model.ReturnUrl}" : null;
|
|
||||||
Layout = "_LayoutWizard";
|
Layout = "_LayoutWizard";
|
||||||
ViewData.SetActivePage(WalletsNavPages.Send, StringLocalizer["Sign the transaction"], walletId.ToString());
|
ViewData.SetActivePage(WalletsNavPages.Send, StringLocalizer["Sign the transaction"], walletId.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@section Navbar {
|
@section Navbar {
|
||||||
@if (backUrl != null)
|
<partial name="_BackAndReturn" model="Model" />
|
||||||
{
|
|
||||||
<a href="@Url.EnsureLocal(backUrl, Context.Request)" id="GoBack">
|
|
||||||
<vc:icon symbol="back" />
|
|
||||||
</a>
|
|
||||||
}
|
|
||||||
<a href="@Url.EnsureLocal(cancelUrl, Context.Request)" id="CancelWizard" class="cancel">
|
|
||||||
<vc:icon symbol="cross" />
|
|
||||||
</a>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<header class="text-center">
|
<header class="text-center">
|
||||||
|
|||||||
Reference in New Issue
Block a user