Add Pagination to Campaign View

(cherry picked from commit 86e40512352a44021ea69ed948062d0b510141cf)
This commit is contained in:
Christian Arenas 2017-06-16 16:50:15 +02:00
parent c88ece26e6
commit db4403b75c
14 changed files with 185 additions and 109 deletions

View File

@ -1,17 +1,18 @@
namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers
{ {
using Infrastructure.Repositories;
using Microsoft.AspNetCore.Mvc;
using Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure;
using System.Threading.Tasks;
using Microsoft.eShopOnContainers.Services.Marketing.API.Model;
using Microsoft.EntityFrameworkCore;
using Microsoft.eShopOnContainers.Services.Marketing.API.Dto;
using System.Collections.Generic;
using Microsoft.AspNetCore.Authorization;
using System; using System;
using System.Linq; using System.Linq;
using Microsoft.Extensions.Options; using System.Collections.Generic;
using Infrastructure.Repositories;
using AspNetCore.Mvc;
using Infrastructure;
using System.Threading.Tasks;
using Catalog.API.ViewModel;
using Model;
using EntityFrameworkCore;
using Dto;
using AspNetCore.Authorization;
using Extensions.Options;
[Route("api/v1/[controller]")] [Route("api/v1/[controller]")]
[Authorize] [Authorize]
@ -124,7 +125,7 @@
} }
[HttpGet("user/{userId:guid}")] [HttpGet("user/{userId:guid}")]
public async Task<IActionResult> GetCampaignsByUserId(Guid userId) public async Task<IActionResult> GetCampaignsByUserId(Guid userId, int pageSize = 10, int pageIndex = 0)
{ {
var marketingData = await _marketingDataRepository.GetAsync(userId.ToString()); var marketingData = await _marketingDataRepository.GetAsync(userId.ToString());
@ -136,13 +137,13 @@
var campaignDtoList = new List<CampaignDTO>(); var campaignDtoList = new List<CampaignDTO>();
//Get User Location Campaign //Get User Location Campaign
foreach(var userLocation in marketingData.Locations) foreach (var userLocation in marketingData.Locations)
{ {
var userCampaignList = await _context.Rules var userCampaignList = await _context.Rules
.OfType<UserLocationRule>() .OfType<UserLocationRule>()
.Include(c => c.Campaign) .Include(c => c.Campaign)
.Where(c => c.Campaign.From <= DateTime.Now .Where(c => c.Campaign.From <= DateTime.Now
&& c.Campaign.To >= DateTime.Now && c.Campaign.To >= DateTime.Now
&& c.LocationId == userLocation.LocationId) && c.LocationId == userLocation.LocationId)
.Select(c => c.Campaign) .Select(c => c.Campaign)
.ToListAsync(); .ToListAsync();
@ -154,7 +155,15 @@
} }
} }
return Ok(campaignDtoList); var totalItems = campaignDtoList.Count();
campaignDtoList = campaignDtoList
.Skip(pageSize * pageIndex)
.Take(pageSize).ToList();
var model = new PaginatedItemsViewModel<CampaignDTO>(
pageIndex, pageSize, totalItems, campaignDtoList);
return Ok(model);
} }

View File

@ -0,0 +1,24 @@
namespace Microsoft.eShopOnContainers.Services.Catalog.API.ViewModel
{
using System.Collections.Generic;
public class PaginatedItemsViewModel<TEntity> where TEntity : class
{
public int PageIndex { get; private set; }
public int PageSize { get; private set; }
public long Count { get; private set; }
public IEnumerable<TEntity> Data { get; private set; }
public PaginatedItemsViewModel(int pageIndex, int pageSize, long count, IEnumerable<TEntity> data)
{
this.PageIndex = pageIndex;
this.PageSize = pageSize;
this.Count = count;
this.Data = data;
}
}
}

View File

@ -1,33 +1,44 @@
using Microsoft.EntityFrameworkCore.Query.Internal;
using WebMVC.ViewModels;
namespace Microsoft.eShopOnContainers.WebMVC.Controllers namespace Microsoft.eShopOnContainers.WebMVC.Controllers
{ {
using Microsoft.AspNetCore.Authorization; using AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using AspNetCore.Mvc;
using Microsoft.eShopOnContainers.WebMVC.Models; using Services;
using Microsoft.eShopOnContainers.WebMVC.Services; using ViewModels;
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using System;
using ViewModels.Pagination;
[Authorize] [Authorize]
public class CampaignsController : Controller public class CampaignsController : Controller
{ {
private ICampaignService _campaignService; private readonly ICampaignService _campaignService;
public CampaignsController(ICampaignService campaignService) => public CampaignsController(ICampaignService campaignService) =>
_campaignService = campaignService; _campaignService = campaignService;
public async Task<IActionResult> Index() public async Task<IActionResult> Index(int page = 0, int pageSize = 10)
{ {
var campaignDtoList = await _campaignService.GetCampaigns(); var campaignList = await _campaignService.GetCampaigns(pageSize, page);
if(campaignDtoList is null) var vm = new CampaignViewModel()
{ {
return View(); CampaignItems = campaignList.Data,
} PaginationInfo = new PaginationInfo()
{
ActualPage = page,
ItemsPerPage = pageSize,
TotalItems = campaignList.Count,
TotalPages = (int)Math.Ceiling(((decimal)campaignList.Count / pageSize))
}
};
var campaignList = MapCampaignModelListToDtoList(campaignDtoList); vm.PaginationInfo.Next = (vm.PaginationInfo.ActualPage == vm.PaginationInfo.TotalPages - 1) ? "is-disabled" : "";
vm.PaginationInfo.Previous = (vm.PaginationInfo.ActualPage == 0) ? "is-disabled" : "";
return View(campaignList); return View(vm);
} }
public async Task<IActionResult> Details(int id) public async Task<IActionResult> Details(int id)
@ -39,7 +50,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
return NotFound(); return NotFound();
} }
var campaign = new Campaign var campaign = new CampaignItem
{ {
Id = campaignDto.Id, Id = campaignDto.Id,
Name = campaignDto.Name, Name = campaignDto.Name,
@ -51,30 +62,5 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
return View(campaign); return View(campaign);
} }
private List<Campaign> MapCampaignModelListToDtoList(IEnumerable<CampaignDTO> campaignDtoList)
{
var campaignList = new List<Campaign>();
foreach(var campaignDto in campaignDtoList)
{
campaignList.Add(MapCampaignDtoToModel(campaignDto));
}
return campaignList;
}
private Campaign MapCampaignDtoToModel(CampaignDTO campaign)
{
return new Campaign
{
Id = campaign.Id,
Name = campaign.Name,
Description = campaign.Description,
From = campaign.From,
To = campaign.To,
PictureUri = campaign.PictureUri
};
}
} }
} }

View File

@ -84,9 +84,9 @@ namespace WebMVC.Infrastructure
public static class Marketing public static class Marketing
{ {
public static string GetAllCampaigns(string baseUri, Guid userId) public static string GetAllCampaigns(string baseUri, string userId, int take, int page)
{ {
return $"{baseUri}user/{userId}"; return $"{baseUri}user/{userId}?pageSize={take}&pageIndex={page}";
} }
public static string GetAllCampaignById(string baseUri, int id) public static string GetAllCampaignById(string baseUri, int id)
@ -95,4 +95,4 @@ namespace WebMVC.Infrastructure
} }
} }
} }
} }

View File

@ -1,15 +1,14 @@
namespace Microsoft.eShopOnContainers.WebMVC.Services namespace Microsoft.eShopOnContainers.WebMVC.Services
{ {
using global::WebMVC.Infrastructure; using global::WebMVC.Infrastructure;
using Microsoft.AspNetCore.Authentication; using AspNetCore.Authentication;
using Microsoft.AspNetCore.Http; using AspNetCore.Http;
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http; using BuildingBlocks.Resilience.Http;
using Microsoft.eShopOnContainers.WebMVC.Models; using ViewModels;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
public class CampaignService : ICampaignService public class CampaignService : ICampaignService
@ -31,28 +30,28 @@
_httpContextAccesor = httpContextAccesor ?? throw new ArgumentNullException(nameof(httpContextAccesor)); _httpContextAccesor = httpContextAccesor ?? throw new ArgumentNullException(nameof(httpContextAccesor));
} }
public async Task<IEnumerable<CampaignDTO>> GetCampaigns() public async Task<Campaign> GetCampaigns(int pageSize, int pageIndex)
{ {
var userId = GetUserIdentity(); var userId = GetUserIdentity();
var allCampaignItemsUri = API.Marketing.GetAllCampaigns(_remoteServiceBaseUrl, Guid.Parse(userId)); var allCampaignItemsUri = API.Marketing.GetAllCampaigns(_remoteServiceBaseUrl,
userId, pageSize, pageIndex);
var authorizationToken = await GetUserTokenAsync(); var authorizationToken = await GetUserTokenAsync();
var dataString = await _apiClient.GetStringAsync(allCampaignItemsUri, authorizationToken); var dataString = await _apiClient.GetStringAsync(allCampaignItemsUri, authorizationToken);
var response = JsonConvert.DeserializeObject<IEnumerable<CampaignDTO>>(dataString); var response = JsonConvert.DeserializeObject<Campaign>(dataString);
return response; return response;
} }
public async Task<CampaignDTO> GetCampaignById(int id) public async Task<CampaignItem> GetCampaignById(int id)
{ {
var userId = GetUserIdentity();
var campaignByIdItemUri = API.Marketing.GetAllCampaignById(_remoteServiceBaseUrl, id); var campaignByIdItemUri = API.Marketing.GetAllCampaignById(_remoteServiceBaseUrl, id);
var authorizationToken = await GetUserTokenAsync(); var authorizationToken = await GetUserTokenAsync();
var dataString = await _apiClient.GetStringAsync(campaignByIdItemUri, authorizationToken); var dataString = await _apiClient.GetStringAsync(campaignByIdItemUri, authorizationToken);
var response = JsonConvert.DeserializeObject<CampaignDTO>(dataString); var response = JsonConvert.DeserializeObject<CampaignItem>(dataString);
return response; return response;
} }

View File

@ -1,13 +1,13 @@
namespace Microsoft.eShopOnContainers.WebMVC.Services namespace Microsoft.eShopOnContainers.WebMVC.Services
{ {
using Microsoft.eShopOnContainers.WebMVC.Models;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using ViewModels;
public interface ICampaignService public interface ICampaignService
{ {
Task<IEnumerable<CampaignDTO>> GetCampaigns(); Task<Campaign> GetCampaigns(int pageSize, int pageIndex);
Task<CampaignDTO> GetCampaignById(int id); Task<CampaignItem> GetCampaignById(int id);
} }
} }

View File

@ -1,19 +1,12 @@
namespace Microsoft.eShopOnContainers.WebMVC.ViewModels namespace Microsoft.eShopOnContainers.WebMVC.ViewModels
{ {
using System; using System.Collections.Generic;
public class Campaign public class Campaign
{ {
public int Id { get; set; } public int PageIndex { get; set; }
public int PageSize { get; set; }
public string Name { get; set; } public int Count { get; set; }
public List<CampaignItem> Data { get; set; }
public string Description { get; set; }
public DateTime From { get; set; }
public DateTime To { get; set; }
public string PictureUri { get; set; }
} }
} }

View File

@ -1,8 +1,8 @@
namespace Microsoft.eShopOnContainers.WebMVC.Models namespace Microsoft.eShopOnContainers.WebMVC.ViewModels
{ {
using System; using System;
public class CampaignDTO public class CampaignItem
{ {
public int Id { get; set; } public int Id { get; set; }

View File

@ -0,0 +1,12 @@
namespace WebMVC.ViewModels
{
using System.Collections.Generic;
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
using Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination;
public class CampaignViewModel
{
public IEnumerable<CampaignItem> CampaignItems { get; set; }
public PaginationInfo PaginationInfo { get; set; }
}
}

View File

@ -1,6 +1,6 @@
@{ @{
ViewData["Title"] = "Campaign details"; ViewData["Title"] = "Campaign details";
@model Microsoft.eShopOnContainers.WebMVC.ViewModels.Campaign @model CampaignItem
} }
<section class="esh-campaigns-hero"> <section class="esh-campaigns-hero">
<div class="container"> <div class="container">

View File

@ -1,6 +1,6 @@
@{ @{
ViewData["Title"] = "Campaigns"; ViewData["Title"] = "Campaigns";
@model IEnumerable<Campaign> @model WebMVC.ViewModels.CampaignViewModel
} }
<section class="esh-campaigns-hero"> <section class="esh-campaigns-hero">
@ -9,28 +9,29 @@
</div> </div>
</section> </section>
@Html.Partial("_Header", new List<Header>() { @Html.Partial("_Header", new List<Header>() {
new Header() { Controller = "Catalog", Text = "Back to catalog" } }) new Header() { Controller = "Catalog", Text = "Back to catalog" } })
<div class="container"> <div class="container">
<div class="card-group esh-campaigns-items row"> @if (Model.CampaignItems != null && Model.CampaignItems.Any())
@foreach (var campaign in Model ?? Enumerable.Empty<Campaign>()) {
{ @Html.Partial("_pagination", Model.PaginationInfo)
<div class="esh-campaigns-item col-md-4">
<form asp-controller="Campaigns" asp-action="Details" asp-route-id="@campaign.Id">
<div class="card-block">
<h4 class="card-title esh-campaigns-name">@campaign.Name</h4>
<img class="card-img-top esh-campaigns-thumbnail" src="@campaign.PictureUri" alt="@campaign.Name">
<input class="esh-campaigns-button" type="submit" value="More details">
</div>
<div class="card-footer">
<small class="text-muted"> <div class="card-group esh-campaigns-items row">
From @campaign.From.ToString("MMMM dd, yyyy") until @campaign.To.ToString("MMMM dd, yyyy") @foreach (var catalogItem in Model.CampaignItems)
</small> {
</div> <div class="esh-campaigns-item col-md-4">
</form> @Html.Partial("_campaign", catalogItem)
</div> </div>
} }
</div> </div>
</div>
@Html.Partial("_pagination", Model.PaginationInfo)
}
else
{
<div class="esh-campaigns-items row">
THERE ARE NO CAMPAIGNS
</div>
}
</div>

View File

@ -0,0 +1,17 @@
@model CampaignItem
<form asp-controller="Campaigns" asp-action="Details" asp-route-id="@Model.Id">
<div class="card-block">
<h4 class="card-title esh-campaigns-name">@Model.Name</h4>
<img class="card-img-top esh-campaigns-thumbnail" src="@Model.PictureUri" alt="@Model.Name">
<input class="esh-campaigns-button" type="submit" value="More details">
</div>
<div class="card-footer">
<small class="text-muted">
From @Model.From.ToString("MMMM dd, yyyy") until @Model.To.ToString("MMMM dd, yyyy")
</small>
</div>
</form>

View File

@ -0,0 +1,32 @@
@model Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination.PaginationInfo
<div class="esh-pager">
<div class="container">
<article class="esh-pager-wrapper row">
<nav>
<a class="esh-pager-item esh-pager-item--navigable @Model.Previous"
id="Previous"
asp-controller="Campaigns"
asp-action="Index"
asp-route-page="@(Model.ActualPage -1)"
aria-label="Previous">
Previous
</a>
<span class="esh-pager-item">
Showing @Model.ItemsPerPage of @Model.TotalItems products - Page @(Model.ActualPage + 1) - @Model.TotalPages
</span>
<a class="esh-pager-item esh-pager-item--navigable @Model.Next"
id="Next"
asp-controller="Campaigns"
asp-action="Index"
asp-route-page="@(Model.ActualPage + 1)"
aria-label="Next">
Next
</a>
</nav>
</article>
</div>
</div>

View File

@ -79,8 +79,11 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Views\Campaigns\" />
<Folder Include="wwwroot\lib\" /> <Folder Include="wwwroot\lib\" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="ViewModels\CampaignItem.cs" />
</ItemGroup>
</Project> </Project>