Skip to content

Commit

Permalink
Add Shopify pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
acoumb committed Feb 2, 2024
1 parent 4723fe3 commit e925263
Show file tree
Hide file tree
Showing 13 changed files with 349 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
{
<dt class="product-title">@product.Title</dt>
<dd class="product-body">@Html.Raw(product.Body)</dd>
<img class="product-image" src="@product.Image" alt="@product.Title" />
@if (!string.IsNullOrEmpty(product.Image))
{
<img class="product-image" src="@product.Image" alt="@product.Title" />
}
}
</dl>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
{
<dt class="product-title">@product.Title</dt>
<dd class="product-body">@Html.Raw(product.Body)</dd>
<img class="product-image" src="@product.Image" alt="@product.Title" />
@if (!string.IsNullOrEmpty(product.Image))
{
<img class="product-image" src="@product.Image" alt="@product.Title" />
}
}
</dl>
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,43 @@
}
}

// pagination
vm.pagination = {
pageNumber: 1,
totalPages: 1,
previousPageInfo: '',
nextPageInfo: ''
};
vm.nextPage = nextPage;
vm.prevPage = prevPage;
vm.changePage = togglePage;
vm.goToPage = togglePage;

// step 1. check configuration
checkConfiguration(function () {
// step 2. get products
getProducts();
// step 2.1 get total pages
getTotalPages();
// step 2.2 get products
getProducts('');
});

function getProducts() {
function getTotalPages() {
umbracoCmsIntegrationsCommerceShopifyResource.getTotalPages().then(function (response) {
vm.pagination.totalPages = response;
});
}

function getProducts(pageInfo) {
vm.loading = true;

umbracoCmsIntegrationsCommerceShopifyResource.getProductsList().then(function (response) {
umbracoCmsIntegrationsCommerceShopifyResource.getProductsList(pageInfo).then(function (response) {
if (response.isValid) {

if (response.previousPageInfo) {
vm.pagination.previousPageInfo = response.previousPageInfo;
}
if (response.nextPageInfo) {
vm.pagination.nextPageInfo = response.nextPageInfo;
}
vm.productsList = response.result.products;

if ($scope.model.value != undefined && $scope.model.value.length > 0) {
Expand Down Expand Up @@ -86,8 +111,9 @@
}

vm.remove = function (node) {
vm.submit(vm.selectedProducts.filter(el => el.id != node.alias));
loadProductsPreview();
vm.previewNodes = vm.previewNodes.filter(el => el.alias != node.alias);
vm.selectedProducts = vm.selectedProducts.filter(el => el.id != node.alias);
vm.submit(vm.previewNodes.length == 0 ? [] : vm.selectedProducts.filter(el => el.id != node.alias));
}

function checkConfiguration(callback) {
Expand All @@ -114,19 +140,17 @@
vm.previewNodes = [];

var ids = $scope.model.value.split(",");

var list = vm.productsList.filter(el => {
var id = ids.find(e => e == el.id);
return id !== undefined ? el : null;
});
vm.selectedProducts = list;

list.forEach(el => {
vm.previewNodes.push({
icon: "icon-shopping-basket",
name: el.title,
alias: el.id
});
umbracoCmsIntegrationsCommerceShopifyResource.getProductsByIds(ids).then(function (response) {
if (response.isValid) {
response.result.products.forEach(el => {
vm.selectedProducts.push(el);
vm.previewNodes.push({
icon: "icon-shopping-basket",
name: el.title,
alias: el.id
});
})
}
});
}

Expand All @@ -146,6 +170,28 @@
if (vm.config.validationLimit.max != null)
return vm.config.validationLimit.max >= updatedCount;
}

// pagination events
function nextPage(pageNumber) {
getProducts(vm.pagination.nextPageInfo);
}

function prevPage(pageNumber) {
getProducts(vm.pagination.previousPageInfo);
}

function togglePage(pageNumber) {
if (pageNumber > vm.pagination.pageNumber) {
// go to next
getProducts(vm.pagination.nextPageInfo);
vm.pagination.pageNumber = vm.pagination.pageNumber + 1;
}
else {
// go to previous
getProducts(vm.pagination.previousPageInfo);
vm.pagination.pageNumber = vm.pagination.pageNumber - 1;
}
}
}

angular.module("umbraco")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,17 @@
$http.get(`${apiEndpoint}/ValidateAccessToken`),
"Failed");
},
getProductsList: function() {
getProductsList: function(pageInfo) {
return umbRequestHelper.resourcePromise(
$http.get(`${apiEndpoint}/GetList`), "Failed to get resource");
$http.get(`${apiEndpoint}/GetList?pageInfo=${pageInfo}`), "Failed to get resource");
},
getProductsByIds: function (ids) {
return umbRequestHelper.resourcePromise(
$http.post(`${apiEndpoint}/GetListByIds`, { ids: ids }), "Failed to get resource");
},
getTotalPages: function () {
return umbRequestHelper.resourcePromise(
$http.get(`${apiEndpoint}/GetTotalPages`), "Failed to get resource");
}
};
});
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,16 @@
position="center">
<localize key="content_listViewNoItems">There are no products in the list.</localize>
</umb-empty-state>
<!-- Pagination -->
<div class="flex justify-center" ng-show="!vm.loading">
<umb-pagination page-number="vm.pagination.pageNumber"
total-pages="vm.pagination.totalPages"
on-next="vm.nextPage"
on-prev="vm.prevPage"
on-change="vm.changePage"
on-go-to-page="vm.goToPage">
</umb-pagination>
</div>

<!-- Min Max help messages-->
<div class="umb-contentpicker__min-max-help" ng-if="(model.config.validationLimit.max > 1 || model.config.validationLimit.min > 0)">
Expand Down
4 changes: 4 additions & 0 deletions src/Umbraco.Cms.Integrations.Commerce.Shopify/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ public static class Constants

public const string ProductsApiEndpoint = "https://{0}.myshopify.com/admin/api/{1}/products.json";

public const string ProductsCountApiEndpoint = "https://{0}.myshopify.com/admin/api/{1}/products/count.json";

public const int DEFAULT_PAGE_SIZE = 10;

public static class RenderingComponent
{
public const string DefaultV8ViewPath = AppPluginFolderPath + "/Render/Products.cshtml";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using Umbraco.Cms.Integrations.Commerce.Shopify.Configuration;

using static Umbraco.Cms.Integrations.Commerce.Shopify.ShopifyComposer;
using System.Linq;


#if NETCOREAPP
using Microsoft.Extensions.Options;
Expand Down Expand Up @@ -63,6 +65,17 @@ public async Task<string> GetAccessToken([FromBody] OAuthRequestDto authRequestD
[HttpPost]
public void RevokeAccessToken() => _apiService.RevokeAccessToken();

public async Task<ResponseDto<ProductsListDto>> GetList() => await _apiService.GetResults();
public async Task<ResponseDto<ProductsListDto>> GetList(string pageInfo) => await _apiService.GetResults(pageInfo);

public async Task<ResponseDto<ProductsListDto>> GetListByIds([FromBody] RequestDto dto) =>
await _apiService.GetProductsByIds(dto.Ids.Select(p => (long.Parse(p))).ToArray());

[HttpGet]
public async Task<int> GetTotalPages()
{
var productsCount = await _apiService.GetCount();

return productsCount / Constants.DEFAULT_PAGE_SIZE + 1;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,21 +48,20 @@ public override object ConvertIntermediateToObject(IPublishedElement owner, IPub
{
if (inter == null) return null;

var ids = (long[]) inter;
var ids = (long[])inter;

var t = Task.Run(async () => await _apiService.GetResults());
var t = Task.Run(async () => await _apiService.GetProductsByIds(ids));

var result = t.Result;

var products = from p in result.Result.Products
where ids.Contains(p.Id)
select new ProductViewModel
{
Id = p.Id,
Title = p.Title,
Body = p.Body,
Image = p.Image.Src
};
select new ProductViewModel
{
Id = p.Id,
Title = p.Title,
Body = p.Body,
Image = p.Image?.Src
};

return products.ToList();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System;
using System.Linq;
using System.Net.Http;
using System.Web;

namespace Umbraco.Cms.Integrations.Commerce.Shopify.Helpers
{
public static class HttpResponseHelper
{
/// <summary>
/// Retrieve Shopify page_info query string parameters used for pagination from forward/backwards operations.
/// </summary>
/// <param name="response"></param>
/// <returns></returns>
public static Tuple<string, string> GetPageInfo(this HttpResponseMessage response)
{
string previousPageInfo = string.Empty;
string nextPageInfo = string.Empty;

if (!response.Headers.Contains("Link"))
{
return default;
}

var linkHeader = response.Headers.GetValues("Link").FirstOrDefault();
if (linkHeader != null && linkHeader.Contains("rel"))
{
if (linkHeader.Contains("previous") && linkHeader.Contains("next"))
{
var relArr = linkHeader.Split(',');
foreach (var item in relArr)
{
var link = item.Split(';');
var servicePageInfo = HttpUtility.ParseQueryString(link[0].Replace("<", string.Empty).Replace(">", string.Empty)).Get("page_info");
if (link[1].Contains("previous"))
{
previousPageInfo = servicePageInfo;
}
else if (link[1].Contains("next"))
{
nextPageInfo = servicePageInfo;
}
}
}
else
{
var link = linkHeader.Split(';');
var servicePageInfo = HttpUtility.ParseQueryString(link[0].Replace("<", string.Empty).Replace(">", string.Empty)).Get("page_info");
if (link[1].Contains("previous"))
{
previousPageInfo = servicePageInfo;
}
else if (link[1].Contains("next"))
{
nextPageInfo = servicePageInfo;
}
}

}

return new Tuple<string, string>(previousPageInfo, nextPageInfo);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Newtonsoft.Json;

namespace Umbraco.Cms.Integrations.Commerce.Shopify.Models.Dtos
{
public class RequestDto
{
[JsonProperty("ids")]
public string[] Ids { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System.Collections.Generic;

using Newtonsoft.Json;
using Newtonsoft.Json;

namespace Umbraco.Cms.Integrations.Commerce.Shopify.Models.Dtos
{
Expand All @@ -10,6 +8,12 @@ public class ResponseDto<T>
[JsonProperty("isValid")]
public bool IsValid { get; set; }

[JsonProperty("nextPageInfo")]
public string NextPageInfo { get; set; }

[JsonProperty("previousPageInfo")]
public string PreviousPageInfo { get; set; }

[JsonProperty("isExpired")]
public bool IsExpired { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ public interface IShopifyService

void RevokeAccessToken();

Task<ResponseDto<ProductsListDto>> GetResults();
Task<ResponseDto<ProductsListDto>> GetResults(string pageInfo);

Task<ResponseDto<ProductsListDto>> GetProductsByIds(long[] ids);

Task<int> GetCount();
}
}
Loading

0 comments on commit e925263

Please sign in to comment.