Skip to content

Commit

Permalink
Merge pull request #168 from vtex-apps/feature/long-export-list
Browse files Browse the repository at this point in the history
Feature: Long exporlist
  • Loading branch information
cdcs0128 authored Mar 8, 2024
2 parents 7c9e4da + f62f668 commit 697c795
Show file tree
Hide file tree
Showing 13 changed files with 223 additions and 20 deletions.
1 change: 1 addition & 0 deletions dotnet/Data/IWishListRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ public interface IWishListRepository
Task VerifySchema();
Task <int> GetListsSize();
Task <WishListsWrapper> GetAllLists();
Task <WishListsWrapper> GetAllListsPaged(int pageSize);
}
}
59 changes: 59 additions & 0 deletions dotnet/Data/WishListRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ private async Task<string> FirstScroll()
string responseContent = string.Empty;
try
{

var client = _clientFactory.CreateClient();
var request = new HttpRequestMessage
{
Expand All @@ -289,6 +290,7 @@ private async Task<string> FirstScroll()
};

string authToken = this._httpContextAccessor.HttpContext.Request.Headers[WishListConstants.HEADER_VTEX_CREDENTIAL];

if (authToken != null)
{
request.Headers.Add(WishListConstants.AUTHORIZATION_HEADER_NAME, authToken);
Expand All @@ -297,6 +299,8 @@ private async Task<string> FirstScroll()
}
request.Headers.Add("Cache-Control", "no-cache");
var response = await client.SendAsync(request);

Console.WriteLine(response.Headers);
tokenResponse = response.Headers.GetValues("X-VTEX-MD-TOKEN").FirstOrDefault();

responseContent = await response.Content.ReadAsStringAsync();
Expand Down Expand Up @@ -438,5 +442,60 @@ public async Task<WishListsWrapper> GetAllLists()

return wishListsWrapper;
}

public async Task<WishListsWrapper> GetAllListsPaged(int pageList)
{
await this.VerifySchema();
var i = 0;
var status = true;
JArray searchResult = new JArray();

while (status)
{
if( i == 0)
{
var res = await FirstScroll();
JArray resArray = JArray.Parse(res);
searchResult.Merge(resArray);
}
else
{
var res = await SubScroll();
JArray resArray = JArray.Parse(res);
if (resArray.Count < 200)
{
status = false;
}
searchResult.Merge(resArray);
}
i++;
}

WishListsWrapper wishListsWrapper = new WishListsWrapper();
wishListsWrapper.WishLists = new List<WishListWrapper>();
WishListWrapper responseListWrapper = new WishListWrapper();

try
{
for (int l = (pageList - 1) * 5000; l < pageList * 5000; l++)
{
JToken listWrapper = searchResult[l];
if (listWrapper != null)
{
responseListWrapper = JsonConvert.DeserializeObject<WishListWrapper>(listWrapper.ToString());
if (responseListWrapper != null)
{
wishListsWrapper.WishLists.Add(responseListWrapper);
}
}
}
}
catch (Exception ex)
{
_context.Vtex.Logger.Error("GetAllLists", null, "Error getting lists", ex);
}

return wishListsWrapper;
}
}
}
25 changes: 25 additions & 0 deletions dotnet/GraphQL/Query.cs
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,31 @@ public Query(IWishListService wishListService)
return wishListsWrapper.WishLists;
}
);

FieldAsync<ListGraphType<WishListWrapperType>>(
"exportListPaged",
arguments: new QueryArguments(
new QueryArgument<NonNullGraphType<IntGraphType>> { Name = "pageList", Description = "page list" }
),
resolve: async context =>
{
HttpStatusCode isValidAuthUser = await wishListService.IsValidAuthUser();
if (isValidAuthUser != HttpStatusCode.OK)
{
context.Errors.Add(new ExecutionError(isValidAuthUser.ToString())
{
Code = isValidAuthUser.ToString()
});

return null;
}

int pageList = context.GetArgument<int>("pageList");

WishListsWrapper wishListsWrapper = await wishListService.ExportAllWishListsPaged(pageList);
return wishListsWrapper.WishLists;
}
);
}
}
}
1 change: 1 addition & 0 deletions dotnet/Services/IWishListService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ public interface IWishListService
Task<ValidatedUser> ValidateUserToken(string token);
Task<int> GetListSizeBase();
Task<WishListsWrapper> ExportAllWishLists();
Task<WishListsWrapper> ExportAllWishListsPaged(int pageList);
}
}
6 changes: 6 additions & 0 deletions dotnet/Services/WishListService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -351,5 +351,11 @@ public async Task<WishListsWrapper> ExportAllWishLists()
WishListsWrapper wishListsWrapper = await _wishListRepository.GetAllLists();
return wishListsWrapper;
}

public async Task<WishListsWrapper> ExportAllWishListsPaged(int pageList)
{
WishListsWrapper wishListsWrapper = await _wishListRepository.GetAllListsPaged(pageList);
return wishListsWrapper;
}
}
}
2 changes: 2 additions & 0 deletions graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ type Query {
@cacheControl(scope: PRIVATE)
exportList: [WishListWrapperType]
@cacheControl(scope: PRIVATE)
exportListPaged(pageList: Int!): [WishListWrapperType]
@cacheControl(scope: PRIVATE)
}

type Mutation {
Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"vendor": "vtex",
"version": "1.16.6",
"title": "Wish List",
"description": "The Wishlist app is designed for B2C. It adds a heart icon to the Shelfs and Product Page, so the user can add it to the Wishlist, you can list all the Wishlisted items at /wishlist",
"description": "The Wishlist a pp is designed for B2C. It adds a heart icon to the Shelfs and Product Page, so the user can add it to the Wishlist, you can list all the Wishlisted items at /wishlist",
"categories": [],
"settingsSchema": {},
"builders": {
Expand Down
3 changes: 2 additions & 1 deletion messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
"store/wishlist-not-logged": "You need to log in before adding it to the list",
"admin/wishlist.menu.label": "Wishlist",
"admin/settings.title": "Wishlist Export",
"admin/settings.download": "Download Wishlists"
"admin/settings.download": "Download Wishlists",
"admin/settings.page": "Page"
}
3 changes: 2 additions & 1 deletion messages/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
"store/wishlist-not-logged": "Necesitas iniciar sesión antes de agregar un producto a la lista",
"admin/wishlist.menu.label": "Lista de deseos",
"admin/settings.title": "Exportar lista de deseos",
"admin/settings.download": "Descargar listas de deseos"
"admin/settings.download": "Descargar listas de deseos",
"admin/settings.page": "Página"
}
3 changes: 2 additions & 1 deletion messages/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
"store/wishlist-not-logged": "Você precisa entrar antes de adicionar um produto à sua lista",
"admin/wishlist.menu.label": "Lista de desejos",
"admin/settings.title": "Exportar lista de desejos",
"admin/settings.download": "Baixar lista de desejos"
"admin/settings.download": "Baixar lista de desejos",
"admin/settings.page": "Página"
}
119 changes: 105 additions & 14 deletions react/WishlistAdmin.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { FC, useState } from 'react'
import React, { FC, useEffect, useState } from 'react'
import { injectIntl, defineMessages } from 'react-intl'
import { useQuery } from 'react-apollo'
import {
Expand All @@ -7,15 +7,21 @@ import {
PageHeader,
ButtonWithIcon,
IconDownload,
Dropdown

Check failure on line 10 in react/WishlistAdmin.tsx

View workflow job for this annotation

GitHub Actions / QE / Lint Node.js

Insert `,`
} from 'vtex.styleguide'
import XLSX from 'xlsx'

import exportList from './queries/exportList.gql'
import exportListPaged from './queries/exportListPaged.gql'
import listSize from './queries/listSize.gql'

const WishlistAdmin: FC<any> = ({ intl }) => {
const [state, setState] = useState<any>({
loading: false,
})
const [isLongList, setIsLongList] = useState<boolean>(false)
const [selected1, setSelected1] = useState<any>(null)
const [options, setOptions] = useState<any>([])

const { loading } = state

Expand All @@ -39,19 +45,70 @@ const WishlistAdmin: FC<any> = ({ intl }) => {
}
}


Check failure on line 48 in react/WishlistAdmin.tsx

View workflow job for this annotation

GitHub Actions / QE / Lint Node.js

Delete `⏎····`
const ws = XLSX.utils.json_to_sheet(data, { header })
const wb = XLSX.utils.book_new()
XLSX.utils.book_append_sheet(wb, ws, 'Sheet1')
const exportFileName = `wishlists.xls`
XLSX.writeFile(wb, exportFileName)
if(selected1 != null) {

Check failure on line 52 in react/WishlistAdmin.tsx

View workflow job for this annotation

GitHub Actions / QE / Lint Node.js

Insert `·`
const exportFileName = `wishlists_page_${selected1}.xls`
XLSX.writeFile(wb, exportFileName)
} else {
const exportFileName = `wishlists.xls`
XLSX.writeFile(wb, exportFileName)

Check failure on line 57 in react/WishlistAdmin.tsx

View workflow job for this annotation

GitHub Actions / QE / Lint Node.js

Delete `⏎`

}
}

const { data, loading: queryLoading } = useQuery(exportList, {
fetchPolicy: 'no-cache',
variables: { pageList: 1 },
})

const { data: dataSize, loading: queryLoadingSize } = useQuery(listSize, {
fetchPolicy: 'no-cache'

Check failure on line 68 in react/WishlistAdmin.tsx

View workflow job for this annotation

GitHub Actions / QE / Lint Node.js

Insert `,`
})

Check failure on line 69 in react/WishlistAdmin.tsx

View workflow job for this annotation

GitHub Actions / QE / Lint Node.js

Delete `···`

const { data: dataPaged, loading: queryLoadingPaged, refetch } = useQuery(exportListPaged, {

Check failure on line 71 in react/WishlistAdmin.tsx

View workflow job for this annotation

GitHub Actions / QE / Lint Node.js

Replace `exportListPaged,` with `⏎····exportListPaged,⏎···`
fetchPolicy: 'no-cache',

Check failure on line 72 in react/WishlistAdmin.tsx

View workflow job for this annotation

GitHub Actions / QE / Lint Node.js

Insert `··`
variables: { pageList: selected1 },

Check failure on line 73 in react/WishlistAdmin.tsx

View workflow job for this annotation

GitHub Actions / QE / Lint Node.js

Insert `··`
})

Check failure on line 74 in react/WishlistAdmin.tsx

View workflow job for this annotation

GitHub Actions / QE / Lint Node.js

Replace `··}` with `····}⏎··`

useEffect(() => {

if(queryLoadingSize) return

let pages: number = dataSize.listSize/5000 + 1

for(let i=1; i <= pages; i++) {

setOptions((current: any) => [...current,
{
value: `${i}`,
label: `${i}`
}
])
}

if(dataSize?.listSize > 5000) {
setIsLongList(true)
}

},[queryLoadingSize, dataSize])

const GetAllWishlistsPaged = async () => {

setState({ ...state, loading: true })

if (!queryLoadingPaged) {
const parsedDataPaged = dataPaged?.exportListPaged
downloadWishlist(parsedDataPaged)
}
setState({ ...state, loading: false })
}

const GetAllWishlists = async () => {
setState({ ...state, loading: true })
console.log(loading)

if (!queryLoading) {
const parsedData = data?.exportList
Expand All @@ -73,6 +130,10 @@ const WishlistAdmin: FC<any> = ({ intl }) => {
id: 'admin/settings.download',
defaultMessage: 'Download Wishlists',
},
page: {
id: 'admin/settings.page',
defaultMessage: 'Page',
},
})

const download = <IconDownload />
Expand All @@ -81,17 +142,47 @@ const WishlistAdmin: FC<any> = ({ intl }) => {
<Layout
pageHeader={<PageHeader title={intl.formatMessage(messages.title)} />}
>
<PageBlock variation="full">
<ButtonWithIcon
icon={download}
isLoading={loading}
onClick={() => {
GetAllWishlists()
}}
>
{intl.formatMessage(messages.download)}
</ButtonWithIcon>
</PageBlock>
{isLongList ?
<PageBlock variation="full">
<div className="w-100 mb4">
<div className="w-30">
<Dropdown
size="small"
label={intl.formatMessage(messages.page)}
options={options}
value={selected1}
onChange={(event: any) => {
console.log(event.target.value)
setSelected1(event.target.value)
setTimeout(()=>{refetch()},500)

}}
/>
</div>
</div>
<ButtonWithIcon
icon={download}
isLoading={queryLoadingPaged}
onClick={() => {
GetAllWishlistsPaged()
}}
>
{intl.formatMessage(messages.download)}
</ButtonWithIcon>
</PageBlock>
:
<PageBlock variation="full">
<ButtonWithIcon
icon={download}
isLoading={loading}
onClick={() => {
GetAllWishlists()
}}
>
{intl.formatMessage(messages.download)}
</ButtonWithIcon>
</PageBlock>
}
</Layout>
)
}
Expand Down
15 changes: 15 additions & 0 deletions react/queries/exportListPaged.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
query ExportListPaged(
$pageList: Int!
) {
exportListPaged(pageList: $pageList) @context(provider: "vtex.wish-list") {
email
listItemsWrapper {
listItems {
id
productId
sku
title
}
}
}
}
4 changes: 2 additions & 2 deletions react/queries/listSize.gql
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
query ListSise {
listSise @context(provider: "vtex.wish-list")
query ListSize {
listSize
}

0 comments on commit 697c795

Please sign in to comment.