Added pagination to transactions #53

Merged
Blizliam merged 1 commits from feature/pagination into stage 2024-04-11 14:25:13 -05:00
6 changed files with 146 additions and 18 deletions

View File

@ -17,6 +17,8 @@ export default function AccountDashboard() {
const search = useLocation().search; const search = useLocation().search;
const id = new URLSearchParams(search).get('id') const id = new URLSearchParams(search).get('id')
const [page, setPage] = useState(1);
useEffect(() => { useEffect(() => {
getData(EndPoints.ACCOUNTS + "/" + id).then( getData(EndPoints.ACCOUNTS + "/" + id).then(
(result) => { (result) => {
@ -36,7 +38,7 @@ export default function AccountDashboard() {
} }
); );
getAllTransactionsData(); getAllTransactionsData(page);
getAllAccountsData(); getAllAccountsData();
getAccountEnvelopeData(); getAccountEnvelopeData();
getAccountAutoclassRulesData(id); getAccountAutoclassRulesData(id);
@ -80,8 +82,24 @@ export default function AccountDashboard() {
navigate(Routes.TRANSACTIONS_DELETE + query); navigate(Routes.TRANSACTIONS_DELETE + query);
} }
function getAllTransactionsData() { function previousPage()
getData(EndPoints.TRANSACTIONS + "?accountId=" + id).then( {
setLoading(true);
setPage(page > 1 ? page - 1 : 1)
getAllTransactionsData(page)
}
function nextPage()
{
setLoading(true);
setPage(page + 1);
getAllTransactionsData(page)
}
function getAllTransactionsData(dataPage) {
let pageSize = 50;
let query = "?PageNumber=" + dataPage + "&PageSize=" + pageSize + "&accountId=" + id
getData(EndPoints.TRANSACTIONS + query).then(
(result) => { (result) => {
if (result) { if (result) {
console.log() console.log()
@ -406,6 +424,26 @@ export default function AccountDashboard() {
</h3> </h3>
</div> </div>
</div> </div>
<div className="row">
<div className="col-md-4">
</div>
<div className="col-md-1">
<button onClick={() => previousPage()} className="btn btn-primary">Previous Page</button>
</div>
<div className="col-md-2">
<div className="text-center">
<h3>
{page}
</h3>
</div>
</div>
<div className="col-md-1">
<button onClick={() => nextPage()} className="btn btn-primary">Next Page</button>
</div>
<div className="col-md-4">
</div>
</div>
{transactionsContent} {transactionsContent}
</div> </div>
</div> </div>

View File

@ -23,17 +23,32 @@ export default function Transactions() {
const [accounts, setAccounts] = useState([]); const [accounts, setAccounts] = useState([]);
const [envelopes, setEnvelopes] = useState([]); const [envelopes, setEnvelopes] = useState([]);
const [page, setPage] = useState(1);
function onTransactionCreate() { function onTransactionCreate() {
navigate(Routes.TRANSACTIONS_CREATE); navigate(Routes.TRANSACTIONS_CREATE);
} }
function previousPage()
{
setPage(page > 1 ? page - 1 : 1)
getAllTransactionsData()
}
function nextPage()
{
setPage(page + 1);
getAllTransactionsData()
}
function getAllTransactionsData() { function getAllTransactionsData() {
//let url = EndPoints.TRANSACTIONS + '/'; //let url = EndPoints.TRANSACTIONS + '/';
/*if (accountId) { /*if (accountId) {
url += '?accountId=' + accountId; url += '?accountId=' + accountId;
}*/ }*/
let pageSize = 50;
getData(EndPoints.TRANSACTIONS).then( let query = "?PageNumber=" + page + "&PageSize=" + pageSize
getData(EndPoints.TRANSACTIONS + query).then(
(result) => { (result) => {
if (result) { if (result) {
setTransactions(result); setTransactions(result);
@ -93,6 +108,14 @@ export default function Transactions() {
<h3>List of Transactions</h3> <h3>List of Transactions</h3>
<button onClick={() => onTransactionCreate()} className="btn btn-primary">Create new transaction</button> <button onClick={() => onTransactionCreate()} className="btn btn-primary">Create new transaction</button>
<hr /> <hr />
<button onClick={() => previousPage()} className="btn btn-primary">Previous Page</button>
&nbsp;
<p>{page}</p>
&nbsp;
<button onClick={() => nextPage()} className="btn btn-primary">Next Page</button>
<br />
<br />
{content} {content}
</div> </div>
); );

View File

@ -11,6 +11,8 @@ using ActiveAllocator.API.Entities;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using ActiveAllocator.API.Models.Transactions.VendorSpecific; using ActiveAllocator.API.Models.Transactions.VendorSpecific;
using ActiveAllocator.API.Helpers;
using Newtonsoft.Json;
[Authorize] [Authorize]
[ApiController] [ApiController]
@ -20,23 +22,28 @@ public class TransactionsController : ControllerBase
private ITransactionService _transactionService; private ITransactionService _transactionService;
private IMapper _mapper; private IMapper _mapper;
private readonly AppSettings _appSettings; private readonly AppSettings _appSettings;
private readonly ILogger<TransactionsController> _logger;
public TransactionsController( public TransactionsController(
ITransactionService transactionService, ITransactionService transactionService,
IMapper mapper, IMapper mapper,
IOptions<AppSettings> appSettings) IOptions<AppSettings> appSettings,
ILogger<TransactionsController> logger)
{ {
_transactionService = transactionService; _transactionService = transactionService;
_mapper = mapper; _mapper = mapper;
_appSettings = appSettings.Value; _appSettings = appSettings.Value;
_logger = logger;
} }
[HttpGet] [HttpGet]
public IActionResult GetAll(int? accountId = null) public IActionResult GetAll([FromQuery]PaginationParameters paginationParameters, int? accountId = null)
{ {
List<TransactionDto> transactionDtos = new List<TransactionDto>(); List<TransactionDto> transactionDtos = new List<TransactionDto>();
foreach (Transaction tran in _transactionService.GetAll()) PagedList<Transaction> transactions = _transactionService.GetTransactions(paginationParameters, accountId);
foreach (Transaction tran in transactions)
{ {
if (accountId.HasValue if (accountId.HasValue
&& (tran.DebitAccount == null || tran.DebitAccount.Id != accountId) && (tran.DebitAccount == null || tran.DebitAccount.Id != accountId)
@ -47,8 +54,21 @@ public class TransactionsController : ControllerBase
} }
// Sort by Date // Sort by Date
transactionDtos.Sort((t1, t2) => t2.Date.CompareTo(t1.Date)); //transactionDtos.Sort((t1, t2) => t2.Date.CompareTo(t1.Date));
var metadata = new
{
transactions.TotalCount,
transactions.PageSize,
transactions.CurrentPage,
transactions.TotalPages,
transactions.HasNext,
transactions.HasPrevious
};
Response.Headers.Add("X-Pagination", JsonConvert.SerializeObject(metadata));
_logger.LogInformation($"Returned {transactions.PageSize} transactions from database.");
return Ok(transactionDtos); return Ok(transactionDtos);
} }

View File

@ -0,0 +1,27 @@
namespace ActiveAllocator.API.Helpers;
public class PagedList<T> : List<T>
{
public int CurrentPage { get; private set; }
public int TotalPages { get; private set; }
public int PageSize { get; private set; }
public int TotalCount { get; private set; }
public bool HasPrevious => CurrentPage > 1;
public bool HasNext => CurrentPage < TotalPages;
public PagedList(List<T> items, int count, int pageNumber, int pageSize)
{
TotalCount = count;
PageSize = pageSize;
CurrentPage = pageNumber;
TotalPages = (int)Math.Ceiling(count / (double)pageSize);
AddRange(items);
}
public static PagedList<T> ToPagedList(IQueryable<T> source, int pageNumber, int pageSize)
{
var count = source.Count();
var items = source.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList();
return new PagedList<T>(items, count, pageNumber, pageSize);
}
}

View File

@ -0,0 +1,7 @@
namespace ActiveAllocator.API.Helpers;
public class PaginationParameters
{
public int PageNumber { get; set; }
public int PageSize { get; set; }
}

View File

@ -12,10 +12,11 @@ using System;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Internal; using Internal;
using System.Collections.Immutable; using System.Collections.Immutable;
using ActiveAllocator.API.Helpers;
public interface ITransactionService public interface ITransactionService
{ {
IEnumerable<Transaction> GetAll(); PagedList<Transaction> GetTransactions(PaginationParameters paginationParameters, int? accountId);
Transaction GetById(int id); Transaction GetById(int id);
IEnumerable<Transaction> BulkCreate(List<TransactionCreate> model); IEnumerable<Transaction> BulkCreate(List<TransactionCreate> model);
Transaction Create(TransactionCreate model, bool errorOnFail = true); Transaction Create(TransactionCreate model, bool errorOnFail = true);
@ -42,15 +43,17 @@ public class TransactionService : ITransactionService
_autoclassService = autoclassService; _autoclassService = autoclassService;
} }
public IEnumerable<Transaction> GetAll() public PagedList<Transaction> GetTransactions(PaginationParameters paginationParameters, int? accountId)
{ {
return _context.Transactions IQueryable<Transaction> queryable = FindAllTransactions();
.Include(t => t.CurrencyType)
.Include(t => t.DebitAccount) if (accountId.HasValue)
.Include(t => t.CreditAccount) queryable = queryable.Where(t => (t.DebitAccount != null && t.DebitAccount.Id == accountId.Value) || (t.CreditAccount != null && t.CreditAccount.Id == accountId.Value));
.Include(t => t.DebitEnvelope)
.Include(t => t.CreditEnvelope) return PagedList<Transaction>.ToPagedList(
.ToList(); queryable.OrderByDescending(t => t.Date),
paginationParameters.PageNumber,
paginationParameters.PageSize);
} }
public Transaction GetById(int id) public Transaction GetById(int id)
@ -353,4 +356,14 @@ public class TransactionService : ITransactionService
return transaction; return transaction;
} }
private IQueryable<Transaction> FindAllTransactions()
{
return _context.Transactions
.Include(t => t.CurrencyType)
.Include(t => t.DebitAccount)
.Include(t => t.CreditAccount)
.Include(t => t.DebitEnvelope)
.Include(t => t.CreditEnvelope);
}
} }