Refactoring: Remove StoreData object from view models (#6363)

This commit is contained in:
d11n
2024-11-07 00:58:47 +01:00
committed by GitHub
parent 641bdcff31
commit 392ec623c0
26 changed files with 120 additions and 138 deletions

View File

@@ -1,11 +1,5 @@
using System;
using System.Security.AccessControl;
using System.Threading.Tasks; using System.Threading.Tasks;
using BTCPayServer.Data;
using BTCPayServer.Models.AppViewModels;
using BTCPayServer.Services.Apps; using BTCPayServer.Services.Apps;
using BTCPayServer.Services.Stores;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ViewComponents; using Microsoft.AspNetCore.Mvc.ViewComponents;
using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Mvc.ViewFeatures;

View File

@@ -1,6 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using BTCPayServer.Client.Models; using BTCPayServer.Client.Models;
using BTCPayServer.Services.Apps;
namespace BTCPayServer.Components.AppSales; namespace BTCPayServer.Components.AppSales;

View File

@@ -45,7 +45,6 @@ if (!window.appSales) {
function addEventListeners() { function addEventListeners() {
delegate('change', `#${id} [name="AppSalesPeriod-${appId}"]`, async e => { delegate('change', `#${id} [name="AppSalesPeriod-${appId}"]`, async e => {
console.log("CHANGED", id)
const type = e.target.value; const type = e.target.value;
await update(type); await update(type);
}); });

View File

@@ -4,7 +4,6 @@ using BTCPayServer.Client.Models;
using BTCPayServer.Lightning; using BTCPayServer.Lightning;
using BTCPayServer.Services.Rates; using BTCPayServer.Services.Rates;
using NBitcoin; using NBitcoin;
using StoreData = BTCPayServer.Data.StoreData;
namespace BTCPayServer.Components.StoreLightningBalance; namespace BTCPayServer.Components.StoreLightningBalance;

View File

@@ -2,14 +2,14 @@
@if (Model.Services != null && Model.Services.Any()) @if (Model.Services != null && Model.Services.Any())
{ {
<div id="StoreLightningServices-@Model.Store.Id" class="widget store-lightning-services"> <div id="StoreLightningServices-@Model.StoreId" class="widget store-lightning-services">
<header class="mb-4"> <header class="mb-4">
<h6 text-translate="true">Lightning Services</h6> <h6 text-translate="true">Lightning Services</h6>
<a <a
asp-controller="UIPublicLightningNodeInfo" asp-controller="UIPublicLightningNodeInfo"
asp-action="ShowLightningNodeInfo"app-top-items asp-action="ShowLightningNodeInfo"app-top-items
asp-route-cryptoCode="@Model.CryptoCode" asp-route-cryptoCode="@Model.CryptoCode"
asp-route-storeId="@Model.Store.Id" asp-route-storeId="@Model.StoreId"
target="_blank" target="_blank"
id="PublicNodeInfo" id="PublicNodeInfo"
text-translate="true"> text-translate="true">

View File

@@ -2,15 +2,16 @@ using System;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using BTCPayServer.Abstractions.Extensions; using BTCPayServer.Abstractions.Extensions;
using BTCPayServer.Client;
using BTCPayServer.Configuration; using BTCPayServer.Configuration;
using BTCPayServer.Data; using BTCPayServer.Data;
using BTCPayServer.Lightning;
using BTCPayServer.Models; using BTCPayServer.Models;
using BTCPayServer.Models.StoreViewModels; using BTCPayServer.Models.StoreViewModels;
using BTCPayServer.Payments; using BTCPayServer.Payments;
using BTCPayServer.Payments.Lightning; using BTCPayServer.Payments.Lightning;
using BTCPayServer.Services; using BTCPayServer.Security;
using BTCPayServer.Services.Stores; using BTCPayServer.Services.Invoices;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
@@ -20,24 +21,38 @@ public class StoreLightningServices : ViewComponent
{ {
private readonly BTCPayServerOptions _btcpayServerOptions; private readonly BTCPayServerOptions _btcpayServerOptions;
private readonly BTCPayNetworkProvider _networkProvider; private readonly BTCPayNetworkProvider _networkProvider;
private readonly IAuthorizationService _authorizationService;
private readonly PaymentMethodHandlerDictionary _handlers;
private readonly IOptions<LightningNetworkOptions> _lightningNetworkOptions;
private readonly IOptions<ExternalServicesOptions> _externalServiceOptions; private readonly IOptions<ExternalServicesOptions> _externalServiceOptions;
public StoreLightningServices( public StoreLightningServices(
BTCPayNetworkProvider networkProvider, BTCPayNetworkProvider networkProvider,
BTCPayServerOptions btcpayServerOptions, BTCPayServerOptions btcpayServerOptions,
IAuthorizationService authorizationService,
PaymentMethodHandlerDictionary handlers,
IOptions<LightningNetworkOptions> lightningNetworkOptions,
IOptions<ExternalServicesOptions> externalServiceOptions) IOptions<ExternalServicesOptions> externalServiceOptions)
{ {
_networkProvider = networkProvider; _networkProvider = networkProvider;
_btcpayServerOptions = btcpayServerOptions; _btcpayServerOptions = btcpayServerOptions;
_lightningNetworkOptions = lightningNetworkOptions;
_externalServiceOptions = externalServiceOptions; _externalServiceOptions = externalServiceOptions;
_authorizationService = authorizationService;
_handlers = handlers;
} }
public IViewComponentResult Invoke(StoreLightningServicesViewModel vm) public async Task<IViewComponentResult> InvokeAsync(StoreData store, string cryptoCode)
{ {
if (vm.Store == null) var vm = new StoreLightningServicesViewModel { StoreId = store.Id, CryptoCode = cryptoCode };
throw new ArgumentNullException(nameof(vm.Store)); var id = PaymentTypes.LN.GetPaymentMethodId(cryptoCode);
if (vm.CryptoCode == null) var existing = store.GetPaymentMethodConfig<LightningPaymentMethodConfig>(id, _handlers);
throw new ArgumentNullException(nameof(vm.CryptoCode)); if (existing?.IsInternalNode is true && _lightningNetworkOptions.Value.InternalLightningByCryptoCode.TryGetValue(cryptoCode, out _))
{
var result = await _authorizationService.AuthorizeAsync(HttpContext.User, null, new PolicyRequirement(Policies.CanUseInternalLightningNode));
vm.LightningNodeType = result.Succeeded ? LightningNodeType.Internal : null;
}
if (vm.LightningNodeType != LightningNodeType.Internal) if (vm.LightningNodeType != LightningNodeType.Internal)
return View(vm); return View(vm);
if (!User.IsInRole(Roles.ServerAdmin)) if (!User.IsInRole(Roles.ServerAdmin))

View File

@@ -8,8 +8,8 @@ namespace BTCPayServer.Components.StoreLightningServices;
public class StoreLightningServicesViewModel public class StoreLightningServicesViewModel
{ {
public string StoreId { get; set; }
public string CryptoCode { get; set; } public string CryptoCode { get; set; }
public StoreData Store { get; set; } public LightningNodeType? LightningNodeType { get; set; }
public LightningNodeType LightningNodeType { get; set; }
public List<AdditionalServiceViewModel> Services { get; set; } public List<AdditionalServiceViewModel> Services { get; set; }
} }

View File

@@ -1,7 +1,7 @@
@using BTCPayServer.Client @using BTCPayServer.Client
@model BTCPayServer.Components.StoreNumbers.StoreNumbersViewModel @model BTCPayServer.Components.StoreNumbers.StoreNumbersViewModel
<div class="widget store-numbers" id="StoreNumbers-@Model.Store.Id"> <div class="widget store-numbers" id="StoreNumbers-@Model.StoreId">
@if (Model.InitialRendering) @if (Model.InitialRendering)
{ {
<div class="loading d-flex justify-content-center p-3"> <div class="loading d-flex justify-content-center p-3">
@@ -11,8 +11,8 @@
</div> </div>
<script> <script>
(async () => { (async () => {
const url = @Safe.Json(Url.Action("StoreNumbers", "UIStores", new { storeId = Model.Store.Id, cryptoCode = Model.CryptoCode })); const url = @Safe.Json(Url.Action("StoreNumbers", "UIStores", new { storeId = Model.StoreId, cryptoCode = Model.CryptoCode }));
const storeId = @Safe.Json(Model.Store.Id); const storeId = @Safe.Json(Model.StoreId);
const response = await fetch(url); const response = await fetch(url);
if (response.ok) { if (response.ok) {
document.getElementById(`StoreNumbers-${storeId}`).outerHTML = await response.text(); document.getElementById(`StoreNumbers-${storeId}`).outerHTML = await response.text();
@@ -24,10 +24,10 @@
{ {
<div class="store-number"> <div class="store-number">
<header> <header>
<h6 text-translate="true">@ViewLocalizer["Paid invoices in the last {0} days", @Model.TimeframeDays]</h6> <h6 text-translate="true">@ViewLocalizer["Paid invoices in the last {0} days", Model.TimeframeDays]</h6>
@if (Model.PaidInvoices > 0) @if (Model.PaidInvoices > 0)
{ {
<a asp-controller="UIInvoice" asp-action="ListInvoices" asp-route-storeId="@Model.Store.Id" permission="@Policies.CanViewInvoices">View All</a> <a asp-controller="UIInvoice" asp-action="ListInvoices" asp-route-storeId="@Model.StoreId" permission="@Policies.CanViewInvoices" text-translate="true">View All</a>
} }
</header> </header>
<div class="h3">@Model.PaidInvoices</div> <div class="h3">@Model.PaidInvoices</div>
@@ -35,7 +35,7 @@
<div class="store-number"> <div class="store-number">
<header> <header>
<h6 text-translate="true">Payouts Pending</h6> <h6 text-translate="true">Payouts Pending</h6>
<a asp-controller="UIStorePullPayments" asp-action="Payouts" asp-route-storeId="@Model.Store.Id" permission="@Policies.CanManagePullPayments" text-translate="true">Manage</a> <a asp-controller="UIStorePullPayments" asp-action="Payouts" asp-route-storeId="@Model.StoreId" permission="@Policies.CanManagePullPayments" text-translate="true">Manage</a>
</header> </header>
<div class="h3">@Model.PayoutsPending</div> <div class="h3">@Model.PayoutsPending</div>
</div> </div>

View File

@@ -1,19 +1,12 @@
using System; using System;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using BTCPayServer.Client.Models; using BTCPayServer.Client.Models;
using BTCPayServer.Components.StoreRecentTransactions;
using BTCPayServer.Data; using BTCPayServer.Data;
using BTCPayServer.Services;
using BTCPayServer.Services.Invoices; using BTCPayServer.Services.Invoices;
using BTCPayServer.Services.Stores; using BTCPayServer.Services.Stores;
using BTCPayServer.Services.Wallets;
using Dapper;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Npgsql;
using StoreData = BTCPayServer.Data.StoreData; using StoreData = BTCPayServer.Data.StoreData;
namespace BTCPayServer.Components.StoreNumbers; namespace BTCPayServer.Components.StoreNumbers;
@@ -34,14 +27,15 @@ public class StoreNumbers : ViewComponent
_invoiceRepository = invoiceRepository; _invoiceRepository = invoiceRepository;
} }
public async Task<IViewComponentResult> InvokeAsync(StoreNumbersViewModel vm) public async Task<IViewComponentResult> InvokeAsync(StoreData store, string cryptoCode, bool initialRendering)
{ {
if (vm.Store == null) var vm = new StoreNumbersViewModel
throw new ArgumentNullException(nameof(vm.Store)); {
if (vm.CryptoCode == null) StoreId = store.Id,
throw new ArgumentNullException(nameof(vm.CryptoCode)); CryptoCode = cryptoCode,
InitialRendering = initialRendering,
vm.WalletId = new WalletId(vm.Store.Id, vm.CryptoCode); WalletId = new WalletId(store.Id, cryptoCode)
};
if (vm.InitialRendering) if (vm.InitialRendering)
return View(vm); return View(vm);
@@ -50,12 +44,12 @@ public class StoreNumbers : ViewComponent
var offset = DateTimeOffset.Now.AddDays(-vm.TimeframeDays).ToUniversalTime(); var offset = DateTimeOffset.Now.AddDays(-vm.TimeframeDays).ToUniversalTime();
vm.PaidInvoices = await _invoiceRepository.GetInvoiceCount( vm.PaidInvoices = await _invoiceRepository.GetInvoiceCount(
new InvoiceQuery { StoreId = new [] { vm.Store.Id }, StartDate = offset, Status = new [] { "paid", "confirmed" } }); new InvoiceQuery { StoreId = [store.Id], StartDate = offset, Status = ["paid", "confirmed"] });
vm.PayoutsPending = await ctx.Payouts vm.PayoutsPending = await ctx.Payouts
.Where(p => p.PullPaymentData.StoreId == vm.Store.Id && !p.PullPaymentData.Archived && p.State == PayoutState.AwaitingApproval) .Where(p => p.PullPaymentData.StoreId == store.Id && !p.PullPaymentData.Archived && p.State == PayoutState.AwaitingApproval)
.CountAsync(); .CountAsync();
vm.RefundsIssued = await ctx.Invoices vm.RefundsIssued = await ctx.Invoices
.Where(i => i.StoreData.Id == vm.Store.Id && !i.Archived && i.Created >= offset) .Where(i => i.StoreData.Id == store.Id && !i.Archived && i.Created >= offset)
.SelectMany(i => i.Refunds) .SelectMany(i => i.Refunds)
.CountAsync(); .CountAsync();

View File

@@ -1,10 +1,8 @@
using BTCPayServer.Data;
namespace BTCPayServer.Components.StoreNumbers; namespace BTCPayServer.Components.StoreNumbers;
public class StoreNumbersViewModel public class StoreNumbersViewModel
{ {
public StoreData Store { get; set; } public string StoreId { get; set; }
public WalletId WalletId { get; set; } public WalletId WalletId { get; set; }
public int PayoutsPending { get; set; } public int PayoutsPending { get; set; }
public int TimeframeDays { get; set; } = 7; public int TimeframeDays { get; set; } = 7;

View File

@@ -1,15 +1,14 @@
@using BTCPayServer.Client.Models @using BTCPayServer.Client.Models
@using BTCPayServer.Services @using BTCPayServer.Services
@using BTCPayServer.Services.Invoices
@inject DisplayFormatter DisplayFormatter @inject DisplayFormatter DisplayFormatter
@model BTCPayServer.Components.StoreRecentInvoices.StoreRecentInvoicesViewModel @model BTCPayServer.Components.StoreRecentInvoices.StoreRecentInvoicesViewModel
<div class="widget store-recent-invoices" id="StoreRecentInvoices-@Model.Store.Id"> <div class="widget store-recent-invoices" id="StoreRecentInvoices-@Model.StoreId">
<header> <header>
<h3 text-translate="true">Recent Invoices</h3> <h3 text-translate="true">Recent Invoices</h3>
@if (Model.Invoices.Any()) @if (Model.Invoices.Any())
{ {
<a asp-controller="UIInvoice" asp-action="ListInvoices" asp-route-storeId="@Model.Store.Id" text-translate="true">View All</a> <a asp-controller="UIInvoice" asp-action="ListInvoices" asp-route-storeId="@Model.StoreId" text-translate="true">View All</a>
} }
</header> </header>
@if (Model.InitialRendering) @if (Model.InitialRendering)
@@ -21,8 +20,8 @@
</div> </div>
<script> <script>
(async () => { (async () => {
const url = @Safe.Json(Url.Action("RecentInvoices", "UIStores", new { storeId = Model.Store.Id, cryptoCode = Model.CryptoCode })); const url = @Safe.Json(Url.Action("RecentInvoices", "UIStores", new { storeId = Model.StoreId, cryptoCode = Model.CryptoCode }));
const storeId = @Safe.Json(Model.Store.Id); const storeId = @Safe.Json(Model.StoreId);
const response = await fetch(url); const response = await fetch(url);
if (response.ok) { if (response.ok) {
document.getElementById(`StoreRecentInvoices-${storeId}`).outerHTML = await response.text(); document.getElementById(`StoreRecentInvoices-${storeId}`).outerHTML = await response.text();
@@ -68,7 +67,7 @@
<p class="text-secondary my-3" text-translate="true"> <p class="text-secondary my-3" text-translate="true">
There are no recent invoices. There are no recent invoices.
</p> </p>
<a asp-controller="UIInvoice" asp-action="CreateInvoice" asp-route-storeId="@Model.Store.Id" class="fw-semibold" text-translate="true"> <a asp-controller="UIInvoice" asp-action="CreateInvoice" asp-route-storeId="@Model.StoreId" class="fw-semibold" text-translate="true">
Create Invoice Create Invoice
</a> </a>
} }

View File

@@ -1,5 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using BTCPayServer.Data; using BTCPayServer.Data;
@@ -9,7 +7,6 @@ using BTCPayServer.Services.Rates;
using BTCPayServer.Services.Stores; using BTCPayServer.Services.Stores;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using NBitcoin;
namespace BTCPayServer.Components.StoreRecentInvoices; namespace BTCPayServer.Components.StoreRecentInvoices;
@@ -35,12 +32,15 @@ public class StoreRecentInvoices : ViewComponent
_dbContextFactory = dbContextFactory; _dbContextFactory = dbContextFactory;
} }
public async Task<IViewComponentResult> InvokeAsync(StoreRecentInvoicesViewModel vm) public async Task<IViewComponentResult> InvokeAsync(StoreData store, string cryptoCode, bool initialRendering)
{ {
if (vm.Store == null) var vm = new StoreRecentInvoicesViewModel
throw new ArgumentNullException(nameof(vm.Store)); {
if (vm.CryptoCode == null) StoreId = store.Id,
throw new ArgumentNullException(nameof(vm.CryptoCode)); CryptoCode = cryptoCode,
InitialRendering = initialRendering
};
if (vm.InitialRendering) if (vm.InitialRendering)
return View(vm); return View(vm);
@@ -48,7 +48,7 @@ public class StoreRecentInvoices : ViewComponent
var invoiceEntities = await _invoiceRepo.GetInvoices(new InvoiceQuery var invoiceEntities = await _invoiceRepo.GetInvoices(new InvoiceQuery
{ {
UserId = userId, UserId = userId,
StoreId = new[] { vm.Store.Id }, StoreId = [store.Id],
IncludeArchived = false, IncludeArchived = false,
IncludeRefunds = true, IncludeRefunds = true,
Take = 5 Take = 5

View File

@@ -5,7 +5,7 @@ namespace BTCPayServer.Components.StoreRecentInvoices;
public class StoreRecentInvoicesViewModel public class StoreRecentInvoicesViewModel
{ {
public StoreData Store { get; set; } public string StoreId { get; set; }
public IList<StoreRecentInvoiceViewModel> Invoices { get; set; } = new List<StoreRecentInvoiceViewModel>(); public IList<StoreRecentInvoiceViewModel> Invoices { get; set; } = new List<StoreRecentInvoiceViewModel>();
public bool InitialRendering { get; set; } public bool InitialRendering { get; set; }
public string CryptoCode { get; set; } public string CryptoCode { get; set; }

View File

@@ -2,7 +2,7 @@
@inject DisplayFormatter DisplayFormatter @inject DisplayFormatter DisplayFormatter
@model BTCPayServer.Components.StoreRecentTransactions.StoreRecentTransactionsViewModel @model BTCPayServer.Components.StoreRecentTransactions.StoreRecentTransactionsViewModel
<div class="widget store-recent-transactions" id="StoreRecentTransactions-@Model.Store.Id"> <div class="widget store-recent-transactions" id="StoreRecentTransactions-@Model.StoreId">
<header> <header>
<h3 text-translate="true">Recent Transactions</h3> <h3 text-translate="true">Recent Transactions</h3>
@if (Model.Transactions.Any()) @if (Model.Transactions.Any())
@@ -19,8 +19,8 @@
</div> </div>
<script> <script>
(async () => { (async () => {
const url = @Safe.Json(Url.Action("RecentTransactions", "UIStores", new { storeId = Model.Store.Id, cryptoCode = Model.CryptoCode })); const url = @Safe.Json(Url.Action("RecentTransactions", "UIStores", new { storeId = Model.StoreId, cryptoCode = Model.CryptoCode }));
const storeId = @Safe.Json(Model.Store.Id); const storeId = @Safe.Json(Model.StoreId);
const response = await fetch(url); const response = await fetch(url);
if (response.ok) { if (response.ok) {
document.getElementById(`StoreRecentTransactions-${storeId}`).outerHTML = await response.text(); document.getElementById(`StoreRecentTransactions-${storeId}`).outerHTML = await response.text();

View File

@@ -1,27 +1,16 @@
#nullable enable #nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using BTCPayServer.Abstractions.Extensions;
using BTCPayServer.Data; using BTCPayServer.Data;
using BTCPayServer.Models.StoreViewModels;
using BTCPayServer.Payments; using BTCPayServer.Payments;
using BTCPayServer.Payments.Bitcoin; using BTCPayServer.Payments.Bitcoin;
using BTCPayServer.Services; using BTCPayServer.Services;
using BTCPayServer.Services.Invoices; using BTCPayServer.Services.Invoices;
using BTCPayServer.Services.Labels; using BTCPayServer.Services.Labels;
using BTCPayServer.Services.Stores;
using BTCPayServer.Services.Wallets; using BTCPayServer.Services.Wallets;
using Dapper;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NBitcoin;
using NBXplorer;
using NBXplorer.Client;
using static BTCPayServer.Components.StoreRecentTransactions.StoreRecentTransactionsViewModel;
namespace BTCPayServer.Components.StoreRecentTransactions; namespace BTCPayServer.Components.StoreRecentTransactions;
@@ -47,26 +36,27 @@ public class StoreRecentTransactions : ViewComponent
_transactionLinkProviders = transactionLinkProviders; _transactionLinkProviders = transactionLinkProviders;
} }
public async Task<IViewComponentResult> InvokeAsync(StoreRecentTransactionsViewModel vm) public async Task<IViewComponentResult> InvokeAsync(StoreData store, string cryptoCode, bool initialRendering)
{ {
if (vm.Store == null) var vm = new StoreRecentTransactionsViewModel
throw new ArgumentNullException(nameof(vm.Store)); {
if (vm.CryptoCode == null) StoreId = store.Id,
throw new ArgumentNullException(nameof(vm.CryptoCode)); CryptoCode = cryptoCode,
InitialRendering = initialRendering,
vm.WalletId = new WalletId(vm.Store.Id, vm.CryptoCode); WalletId = new WalletId(store.Id, cryptoCode)
};
if (vm.InitialRendering) if (vm.InitialRendering)
return View(vm); return View(vm);
var derivationSettings = vm.Store.GetDerivationSchemeSettings(_handlers, vm.CryptoCode); var derivationSettings = store.GetDerivationSchemeSettings(_handlers, vm.CryptoCode);
var transactions = new List<StoreRecentTransactionViewModel>(); var transactions = new List<StoreRecentTransactionViewModel>();
if (derivationSettings?.AccountDerivation is not null) if (derivationSettings?.AccountDerivation is not null)
{ {
var pmi = PaymentTypes.CHAIN.GetPaymentMethodId(vm.CryptoCode); var pmi = PaymentTypes.CHAIN.GetPaymentMethodId(vm.CryptoCode);
var network = ((IHasNetwork)_handlers[pmi]).Network; var network = ((IHasNetwork)_handlers[pmi]).Network;
var wallet = _walletProvider.GetWallet(network); var wallet = _walletProvider.GetWallet(network);
var allTransactions = await wallet.FetchTransactionHistory(derivationSettings.AccountDerivation, 0, 5, TimeSpan.FromDays(31.0), cancellationToken: this.HttpContext.RequestAborted); var allTransactions = await wallet.FetchTransactionHistory(derivationSettings.AccountDerivation, 0, 5, TimeSpan.FromDays(31.0), cancellationToken: HttpContext.RequestAborted);
var walletTransactionsInfo = await _walletRepository.GetWalletTransactionsInfo(vm.WalletId, allTransactions.Select(t => t.TransactionId.ToString()).ToArray()); var walletTransactionsInfo = await _walletRepository.GetWalletTransactionsInfo(vm.WalletId, allTransactions.Select(t => t.TransactionId.ToString()).ToArray());
transactions = allTransactions transactions = allTransactions

View File

@@ -1,11 +1,10 @@
using System.Collections.Generic; using System.Collections.Generic;
using BTCPayServer.Data;
namespace BTCPayServer.Components.StoreRecentTransactions; namespace BTCPayServer.Components.StoreRecentTransactions;
public class StoreRecentTransactionsViewModel public class StoreRecentTransactionsViewModel
{ {
public StoreData Store { get; set; } public string StoreId { get; set; }
public IList<StoreRecentTransactionViewModel> Transactions { get; set; } = new List<StoreRecentTransactionViewModel>(); public IList<StoreRecentTransactionViewModel> Transactions { get; set; } = new List<StoreRecentTransactionViewModel>();
public WalletId WalletId { get; set; } public WalletId WalletId { get; set; }
public bool InitialRendering { get; set; } public bool InitialRendering { get; set; }

View File

@@ -1,16 +1,11 @@
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using BTCPayServer.Abstractions.Contracts;
using BTCPayServer.Abstractions.Extensions; using BTCPayServer.Abstractions.Extensions;
using BTCPayServer.Client;
using BTCPayServer.Data; using BTCPayServer.Data;
using BTCPayServer.Payments.Bitcoin;
using BTCPayServer.Services; using BTCPayServer.Services;
using BTCPayServer.Services.Invoices;
using BTCPayServer.Services.Stores; using BTCPayServer.Services.Stores;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
namespace BTCPayServer.Components.StoreSelector namespace BTCPayServer.Components.StoreSelector
{ {
@@ -38,13 +33,11 @@ namespace BTCPayServer.Components.StoreSelector
var archivedCount = stores.Count(s => s.Archived); var archivedCount = stores.Count(s => s.Archived);
var options = stores var options = stores
.Where(store => !store.Archived) .Where(store => !store.Archived)
.Select(store => .Select(store => new StoreSelectorOption
new StoreSelectorOption
{ {
Text = store.StoreName, Text = store.StoreName,
Value = store.Id, Value = store.Id,
Selected = store.Id == currentStore?.Id, Selected = store.Id == currentStore?.Id
Store = store
}) })
.OrderBy(s => s.Text) .OrderBy(s => s.Text)
.ToList(); .ToList();

View File

@@ -1,5 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using BTCPayServer.Data;
namespace BTCPayServer.Components.StoreSelector namespace BTCPayServer.Components.StoreSelector
{ {
@@ -17,6 +16,5 @@ namespace BTCPayServer.Components.StoreSelector
public bool Selected { get; set; } public bool Selected { get; set; }
public string Text { get; set; } public string Text { get; set; }
public string Value { get; set; } public string Value { get; set; }
public StoreData Store { get; set; }
} }
} }

View File

@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using BTCPayServer.Client.Models; using BTCPayServer.Client.Models;
using BTCPayServer.Services.Rates; using BTCPayServer.Services.Rates;
using StoreData = BTCPayServer.Data.StoreData;
namespace BTCPayServer.Components.StoreWalletBalance; namespace BTCPayServer.Components.StoreWalletBalance;

View File

@@ -43,11 +43,21 @@ namespace BTCPayServer.Controllers
if (!ValidUserClaim(out var userId)) if (!ValidUserClaim(out var userId))
return RedirectToAction("Index", "UIHome"); return RedirectToAction("Index", "UIHome");
var stores = await _storeRepo.GetStoresByUserId(userId);
model.Stores = stores.Where(store => !store.Archived).OrderBy(s => s.StoreName).ToList();
var searchTerm = string.IsNullOrEmpty(model.SearchText) ? model.SearchTerm : $"{model.SearchText},{model.SearchTerm}"; var searchTerm = string.IsNullOrEmpty(model.SearchText) ? model.SearchTerm : $"{model.SearchText},{model.SearchTerm}";
var fs = new SearchString(searchTerm, timezoneOffset); var fs = new SearchString(searchTerm, timezoneOffset);
var storeIds = fs.GetFilterArray("storeid");
var stores = await _storeRepo.GetStoresByUserId(userId);
model.StoreFilterOptions = stores
.Where(store => !store.Archived)
.OrderBy(s => s.StoreName)
.Select(s => new StoreFilterOption
{
Selected = storeIds?.Contains(s.Id) is true,
Text = s.StoreName,
Value = s.Id
})
.ToList();
model.Search = fs; model.Search = fs;
var res = await _notificationManager.GetNotifications(new NotificationsQuery var res = await _notificationManager.GetNotifications(new NotificationsQuery
@@ -57,7 +67,7 @@ namespace BTCPayServer.Controllers
UserId = userId, UserId = userId,
SearchText = model.SearchText, SearchText = model.SearchText,
Type = fs.GetFilterArray("type"), Type = fs.GetFilterArray("type"),
StoreIds = fs.GetFilterArray("storeid"), StoreIds = storeIds,
Seen = model.Status == "Unread" ? false : null Seen = model.Status == "Unread" ? false : null
}); });
model.Items = res.Items; model.Items = res.Items;

View File

@@ -6,10 +6,6 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using BTCPayServer.Abstractions.Constants; using BTCPayServer.Abstractions.Constants;
using BTCPayServer.Client; using BTCPayServer.Client;
using BTCPayServer.Components.StoreLightningBalance;
using BTCPayServer.Components.StoreNumbers;
using BTCPayServer.Components.StoreRecentInvoices;
using BTCPayServer.Components.StoreRecentTransactions;
using BTCPayServer.Data; using BTCPayServer.Data;
using BTCPayServer.Models.StoreViewModels; using BTCPayServer.Models.StoreViewModels;
using BTCPayServer.Payments.Bitcoin; using BTCPayServer.Payments.Bitcoin;
@@ -74,10 +70,9 @@ public partial class UIStoresController
public IActionResult LightningBalance(string storeId, string cryptoCode) public IActionResult LightningBalance(string storeId, string cryptoCode)
{ {
var store = HttpContext.GetStoreData(); var store = HttpContext.GetStoreData();
if (store == null) return store != null
return NotFound(); ? ViewComponent("StoreLightningBalance", new { Store = store, CryptoCode = cryptoCode })
: NotFound();
return ViewComponent("StoreLightningBalance", new { Store = store, CryptoCode = cryptoCode });
} }
[HttpGet("{storeId}/dashboard/{cryptoCode}/numbers")] [HttpGet("{storeId}/dashboard/{cryptoCode}/numbers")]
@@ -85,11 +80,9 @@ public partial class UIStoresController
public IActionResult StoreNumbers(string storeId, string cryptoCode) public IActionResult StoreNumbers(string storeId, string cryptoCode)
{ {
var store = HttpContext.GetStoreData(); var store = HttpContext.GetStoreData();
if (store == null) return store != null
return NotFound(); ? ViewComponent("StoreNumbers", new { Store = store, CryptoCode = cryptoCode })
: NotFound();
var vm = new StoreNumbersViewModel { Store = store, CryptoCode = cryptoCode };
return ViewComponent("StoreNumbers", new { vm });
} }
[HttpGet("{storeId}/dashboard/{cryptoCode}/recent-transactions")] [HttpGet("{storeId}/dashboard/{cryptoCode}/recent-transactions")]
@@ -97,11 +90,9 @@ public partial class UIStoresController
public IActionResult RecentTransactions(string storeId, string cryptoCode) public IActionResult RecentTransactions(string storeId, string cryptoCode)
{ {
var store = HttpContext.GetStoreData(); var store = HttpContext.GetStoreData();
if (store == null) return store != null
return NotFound(); ? ViewComponent("StoreRecentTransactions", new { Store = store, CryptoCode = cryptoCode })
: NotFound();
var vm = new StoreRecentTransactionsViewModel { Store = store, CryptoCode = cryptoCode };
return ViewComponent("StoreRecentTransactions", new { vm });
} }
[HttpGet("{storeId}/dashboard/{cryptoCode}/recent-invoices")] [HttpGet("{storeId}/dashboard/{cryptoCode}/recent-invoices")]
@@ -109,11 +100,9 @@ public partial class UIStoresController
public IActionResult RecentInvoices(string storeId, string cryptoCode) public IActionResult RecentInvoices(string storeId, string cryptoCode)
{ {
var store = HttpContext.GetStoreData(); var store = HttpContext.GetStoreData();
if (store == null) return store != null
return NotFound(); ? ViewComponent("StoreRecentInvoices", new { Store = store, CryptoCode = cryptoCode })
: NotFound();
var vm = new StoreRecentInvoicesViewModel { Store = store, CryptoCode = cryptoCode };
return ViewComponent("StoreRecentInvoices", new { vm });
} }
internal void AddPaymentMethods(StoreData store, StoreBlob storeBlob, internal void AddPaymentMethods(StoreData store, StoreBlob storeBlob,

View File

@@ -15,6 +15,13 @@ namespace BTCPayServer.Models.NotificationViewModels
public class NotificationIndexViewModel : IndexViewModel public class NotificationIndexViewModel : IndexViewModel
{ {
public List<StoreData> Stores { get; set; } public List<StoreFilterOption> StoreFilterOptions { get; set; }
}
public class StoreFilterOption
{
public bool Selected { get; set; }
public string Text { get; set; }
public string Value { get; set; }
} }
} }

View File

@@ -96,14 +96,14 @@
} }
</button> </button>
<div class="dropdown-menu" aria-labelledby="StoresOptionsToggle"> <div class="dropdown-menu" aria-labelledby="StoresOptionsToggle">
@foreach (var store in Model.Stores) @foreach (var store in Model.StoreFilterOptions)
{ {
<a asp-action="Index" <a asp-action="Index"
asp-route-count="@Model.Count" asp-route-count="@Model.Count"
asp-route-status="@Model.Status" asp-route-status="@Model.Status"
asp-route-searchTerm="@Model.Search.Toggle("storeid", store.Id)" asp-route-searchTerm="@Model.Search.Toggle("storeid", store.Value)"
class="dropdown-item @(HasArrayFilter("storeid", store.Id) ? "custom-active" : "")"> class="dropdown-item @(store.Selected ? "custom-active" : "")">
@store.StoreName @store.Text
</a> </a>
} }
</div> </div>

View File

@@ -78,17 +78,17 @@
</div> </div>
</div> </div>
} }
<vc:store-numbers vm="@(new StoreNumbersViewModel { Store = store, CryptoCode = Model.CryptoCode, InitialRendering = true })" /> <vc:store-numbers store="store" crypto-code="@Model.CryptoCode" initial-rendering="true" />
@if (Model.LightningEnabled) @if (Model.LightningEnabled)
{ {
<vc:store-lightning-balance store="store" crypto-code="@Model.CryptoCode" initial-rendering="true" /> <vc:store-lightning-balance store="store" crypto-code="@Model.CryptoCode" initial-rendering="true" />
<vc:store-lightning-services vm="@(new StoreLightningServicesViewModel { Store = store, CryptoCode = Model.CryptoCode })" permission="@Policies.CanModifyServerSettings" /> <vc:store-lightning-services store="store" crypto-code="@Model.CryptoCode" permission="@Policies.CanModifyServerSettings" />
} }
@if (Model.WalletEnabled) @if (Model.WalletEnabled)
{ {
<vc:store-recent-transactions vm="@(new StoreRecentTransactionsViewModel { Store = store, CryptoCode = Model.CryptoCode, InitialRendering = true })" /> <vc:store-recent-transactions store="store" crypto-code="@Model.CryptoCode" initial-rendering="true" />
} }
<vc:store-recent-invoices vm="@(new StoreRecentInvoicesViewModel { Store = store, CryptoCode = Model.CryptoCode, InitialRendering = true })" /> <vc:store-recent-invoices store="store" crypto-code="@Model.CryptoCode" initial-rendering="true" />
@foreach (var app in Model.Apps) @foreach (var app in Model.Apps)
{ {
<vc:app-sales app-id="@app.Id" app-type="@app.AppType" /> <vc:app-sales app-id="@app.Id" app-type="@app.AppType" />

View File

@@ -1,7 +1,7 @@
@model LightningNodeViewModel @model LightningNodeViewModel
@{ @{
Layout = "_LayoutWalletSetup.cshtml"; Layout = "_LayoutWalletSetup.cshtml";
ViewData.SetActivePage(StoreNavPages.LightningSettings, StringLocalizer["Connect to a Lightning node"], Context.GetStoreData().Id); ViewData.SetActivePage(StoreNavPages.LightningSettings, StringLocalizer["Connect to a Lightning node"], Model.StoreId);
} }
@section PageHeadContent { @section PageHeadContent {

View File

@@ -5,7 +5,7 @@
@model StoreUsersViewModel @model StoreUsersViewModel
@inject StoreRepository StoreRepository @inject StoreRepository StoreRepository
@{ @{
var storeId = Context.GetStoreData().Id; var storeId = Model.StoreId;
var roles = new SelectList( var roles = new SelectList(
await StoreRepository.GetStoreRoles(storeId), await StoreRepository.GetStoreRoles(storeId),
nameof(StoreRepository.StoreRole.Id), nameof(StoreRepository.StoreRole.Role), nameof(StoreRepository.StoreRole.Id), nameof(StoreRepository.StoreRole.Role),