Initializing BasePagingViewModels from cookie

This commit is contained in:
rockstardev 2020-07-30 09:10:10 -05:00
parent 19ffd031ec
commit 77f5d0be35
5 changed files with 48 additions and 56 deletions

View file

@ -1354,7 +1354,7 @@ namespace BTCPayServer.Tests
{ {
var result = var result =
(Models.InvoicingModels.InvoicesModel)((ViewResult)acc.GetController<InvoiceController>() (Models.InvoicingModels.InvoicesModel)((ViewResult)acc.GetController<InvoiceController>()
.ListInvoices(searchTerm:filter).Result).Model; .ListInvoices(new InvoicesModel { SearchTerm = filter }).Result).Model;
Assert.Equal(expected, result.Invoices.Any(i => i.InvoiceId == invoiceId)); Assert.Equal(expected, result.Invoices.Any(i => i.InvoiceId == invoiceId));
} }

View file

@ -601,25 +601,19 @@ namespace BTCPayServer.Controllers
[Route("invoices")] [Route("invoices")]
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie)] [Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie)]
[BitpayAPIConstraint(false)] [BitpayAPIConstraint(false)]
public async Task<IActionResult> ListInvoices(int skip = 0, int count = 50, string searchTerm = null, int? timezoneOffset = null) public async Task<IActionResult> ListInvoices(InvoicesModel model = null)
{ {
this.InvoicesQuery(ref searchTerm, ref timezoneOffset); model = this.ParseListQuery(model ?? new InvoicesModel());
var fs = new SearchString(searchTerm); var fs = new SearchString(model.SearchTerm);
var storeIds = fs.GetFilterArray("storeid") != null ? fs.GetFilterArray("storeid") : new List<string>().ToArray(); var storeIds = fs.GetFilterArray("storeid") != null ? fs.GetFilterArray("storeid") : new List<string>().ToArray();
var model = new InvoicesModel model.StoreIds = storeIds;
{
SearchTerm = searchTerm, InvoiceQuery invoiceQuery = GetInvoiceQuery(model.SearchTerm, model.TimezoneOffset ?? 0);
Skip = skip,
Count = count,
StoreIds = storeIds,
TimezoneOffset = timezoneOffset
};
InvoiceQuery invoiceQuery = GetInvoiceQuery(searchTerm, timezoneOffset ?? 0);
var counting = _InvoiceRepository.GetInvoicesTotal(invoiceQuery); var counting = _InvoiceRepository.GetInvoicesTotal(invoiceQuery);
invoiceQuery.Count = count; invoiceQuery.Count = model.Count;
invoiceQuery.Skip = skip; invoiceQuery.Skip = model.Skip;
var list = await _InvoiceRepository.GetInvoices(invoiceQuery); var list = await _InvoiceRepository.GetInvoices(invoiceQuery);
foreach (var invoice in list) foreach (var invoice in list)

View file

@ -61,27 +61,22 @@ namespace BTCPayServer.Controllers
[HttpGet] [HttpGet]
[Route("")] [Route("")]
[BitpayAPIConstraint(false)] [BitpayAPIConstraint(false)]
public async Task<IActionResult> GetPaymentRequests(int skip = 0, int count = 50, string searchTerm = null, int? timezoneOffset = null) public async Task<IActionResult> GetPaymentRequests(ListPaymentRequestsViewModel model = null)
{ {
this.PaymentRequestsQuery(ref searchTerm, ref timezoneOffset); model = this.ParseListQuery(model ?? new ListPaymentRequestsViewModel());
var includeArchived = new SearchString(searchTerm).GetFilterBool("includearchived") == true; var includeArchived = new SearchString(model.SearchTerm).GetFilterBool("includearchived") == true;
var result = await _PaymentRequestRepository.FindPaymentRequests(new PaymentRequestQuery() var result = await _PaymentRequestRepository.FindPaymentRequests(new PaymentRequestQuery()
{ {
UserId = GetUserId(), UserId = GetUserId(),
Skip = skip, Skip = model.Skip,
Count = count, Count = model.Count,
IncludeArchived = includeArchived IncludeArchived = includeArchived
}); });
return View(new ListPaymentRequestsViewModel()
{ model.Total = result.Total;
Skip = skip, model.Items = result.Items.Select(data => new ViewPaymentRequestViewModel(data)).ToList();
Count = count, return View(model);
Total = result.Total,
SearchTerm = searchTerm,
TimezoneOffset = timezoneOffset,
Items = result.Items.Select(data => new ViewPaymentRequestViewModel(data)).ToList()
});
} }
[HttpGet] [HttpGet]

View file

@ -1,33 +1,37 @@
using System; using System;
using System.Reflection;
using BTCPayServer.Models;
using BTCPayServer.Models.InvoicingModels;
using BTCPayServer.Models.PaymentRequestViewModels;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace BTCPayServer namespace BTCPayServer
{ {
public static class ControllerBaseExtensions
{
public static void InvoicesQuery(this ControllerBase ctrl, ref string searchTerm, ref int? timezoneOffset)
{
ListCookiePreference.Parse(ctrl, "InvoicesQuery", ref searchTerm, ref timezoneOffset);
}
public static void PaymentRequestsQuery(this ControllerBase ctrl, ref string searchTerm, ref int? timezoneOffset)
{
ListCookiePreference.Parse(ctrl, "PaymentRequestsQuery", ref searchTerm, ref timezoneOffset);
}
}
// Classes here remember users preferences on certain pages and store them in unified blob cookie "UserPreferCookie" // Classes here remember users preferences on certain pages and store them in unified blob cookie "UserPreferCookie"
class ListCookiePreference public static class ControllerBaseExtension
{ {
internal static void Parse(ControllerBase ctrl, string propName, public static T ParseListQuery<T>(this ControllerBase ctrl, T model) where T : BasePagingViewModel
ref string searchTerm, ref int? timezoneOffset) {
PropertyInfo prop;
if (model is InvoicesModel)
prop = typeof(UserPrefsCookie).GetProperty(nameof(UserPrefsCookie.InvoicesQuery));
else if (model is ListPaymentRequestsViewModel)
prop = typeof(UserPrefsCookie).GetProperty(nameof(UserPrefsCookie.PaymentRequestsQuery));
else
throw new Exception("Unsupported BasePagingViewModel for cookie user preferences saving");
return ProcessParse(ctrl, model, prop);
}
private static T ProcessParse<T>(ControllerBase ctrl, T model, PropertyInfo prop) where T : BasePagingViewModel
{ {
var prop = typeof(UserPrefsCookie).GetProperty(propName);
var prefCookie = parsePrefCookie(ctrl); var prefCookie = parsePrefCookie(ctrl);
// If the user enter an empty searchTerm, then the variable will be null and not empty string // If the user enter an empty searchTerm, then the variable will be null and not empty string
// but we want searchTerm to be null only if the user is browsing the page via some link // but we want searchTerm to be null only if the user is browsing the page via some link
// NOT if the user entered some empty search // NOT if the user entered some empty search
var searchTerm = model.SearchTerm;
searchTerm = searchTerm is string ? searchTerm : searchTerm = searchTerm is string ? searchTerm :
ctrl.Request.Query.ContainsKey(nameof(searchTerm)) ? string.Empty : ctrl.Request.Query.ContainsKey(nameof(searchTerm)) ? string.Empty :
null; null;
@ -36,15 +40,17 @@ namespace BTCPayServer
var section = prop.GetValue(prefCookie) as ListQueryDataHolder; var section = prop.GetValue(prefCookie) as ListQueryDataHolder;
if (section != null && !String.IsNullOrEmpty(section.SearchTerm)) if (section != null && !String.IsNullOrEmpty(section.SearchTerm))
{ {
searchTerm = section.SearchTerm; model.SearchTerm = section.SearchTerm;
timezoneOffset = section.TimezoneOffset ?? 0; model.TimezoneOffset = section.TimezoneOffset ?? 0;
} }
} }
else else
{ {
prop.SetValue(prefCookie, new ListQueryDataHolder(searchTerm, timezoneOffset)); prop.SetValue(prefCookie, new ListQueryDataHolder(model.SearchTerm, model.TimezoneOffset));
ctrl.Response.Cookies.Append(nameof(UserPrefsCookie), JsonConvert.SerializeObject(prefCookie)); ctrl.Response.Cookies.Append(nameof(UserPrefsCookie), JsonConvert.SerializeObject(prefCookie));
} }
return model;
} }
private static UserPrefsCookie parsePrefCookie(ControllerBase ctrl) private static UserPrefsCookie parsePrefCookie(ControllerBase ctrl)

View file

@ -1,16 +1,13 @@
using System; using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BTCPayServer.Models namespace BTCPayServer.Models
{ {
public class BasePagingViewModel public abstract class BasePagingViewModel
{ {
public int Skip { get; set; } public int Skip { get; set; } = 0;
public int Count { get; set; } public int Count { get; set; } = 50;
public int Total { get; set; } public int Total { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string SearchTerm { get; set; } public string SearchTerm { get; set; }
public int? TimezoneOffset { get; set; } public int? TimezoneOffset { get; set; }
} }