From 00066dc180f7f55a43d9b31fa98920ed0de21084 Mon Sep 17 00:00:00 2001 From: "cristian.cifuentes" Date: Mon, 4 Mar 2024 12:43:38 -0500 Subject: [PATCH 1/4] Feature: Long exporlist --- dotnet/Data/IWishListRepository.cs | 1 + dotnet/Data/WishListRepository.cs | 55 ++++++++++++++ dotnet/GraphQL/Query.cs | 25 +++++++ dotnet/Services/IWishListService.cs | 1 + dotnet/Services/WishListService.cs | 6 ++ graphql/schema.graphql | 2 + messages/en.json | 3 +- messages/es.json | 3 +- messages/pt.json | 3 +- react/WishlistAdmin.tsx | 107 ++++++++++++++++++++++++---- react/queries/exportListPaged.gql | 15 ++++ react/queries/listSize.gql | 4 +- 12 files changed, 208 insertions(+), 17 deletions(-) create mode 100644 react/queries/exportListPaged.gql diff --git a/dotnet/Data/IWishListRepository.cs b/dotnet/Data/IWishListRepository.cs index add7a91..a837d01 100644 --- a/dotnet/Data/IWishListRepository.cs +++ b/dotnet/Data/IWishListRepository.cs @@ -12,5 +12,6 @@ public interface IWishListRepository Task VerifySchema(); Task GetListsSize(); Task GetAllLists(); + Task GetAllListsPaged(int pageSize); } } diff --git a/dotnet/Data/WishListRepository.cs b/dotnet/Data/WishListRepository.cs index 9c8ad97..508f24b 100644 --- a/dotnet/Data/WishListRepository.cs +++ b/dotnet/Data/WishListRepository.cs @@ -438,5 +438,60 @@ public async Task GetAllLists() return wishListsWrapper; } + + public async Task 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 responseListWrapper = new WishListWrapper(); + + try + { + for (int l = (pageList - 1) * 5000; l < pageList * 5000; l++) + { + JToken listWrapper = searchResult[l]; + if (listWrapper != null) + { + responseListWrapper = JsonConvert.DeserializeObject(listWrapper.ToString()); + if (responseListWrapper != null) + { + wishListsWrapper.WishLists.Add(responseListWrapper); + } + } + } + } + catch (Exception ex) + { + _context.Vtex.Logger.Error("GetAllLists", null, "Error getting lists", ex); + } + + return wishListsWrapper; + } } } diff --git a/dotnet/GraphQL/Query.cs b/dotnet/GraphQL/Query.cs index 0993312..7e2f276 100644 --- a/dotnet/GraphQL/Query.cs +++ b/dotnet/GraphQL/Query.cs @@ -302,6 +302,31 @@ public Query(IWishListService wishListService) return wishListsWrapper.WishLists; } ); + + FieldAsync>( + "exportListPaged", + arguments: new QueryArguments( + new QueryArgument> { 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("pageList"); + + WishListsWrapper wishListsWrapper = await wishListService.ExportAllWishListsPaged(pageList); + return wishListsWrapper.WishLists; + } + ); } } } \ No newline at end of file diff --git a/dotnet/Services/IWishListService.cs b/dotnet/Services/IWishListService.cs index 1cdf167..dc8b6e9 100644 --- a/dotnet/Services/IWishListService.cs +++ b/dotnet/Services/IWishListService.cs @@ -17,5 +17,6 @@ public interface IWishListService Task ValidateUserToken(string token); Task GetListSizeBase(); Task ExportAllWishLists(); + Task ExportAllWishListsPaged(int pageList); } } \ No newline at end of file diff --git a/dotnet/Services/WishListService.cs b/dotnet/Services/WishListService.cs index 73664fe..6c9fb36 100644 --- a/dotnet/Services/WishListService.cs +++ b/dotnet/Services/WishListService.cs @@ -351,5 +351,11 @@ public async Task ExportAllWishLists() WishListsWrapper wishListsWrapper = await _wishListRepository.GetAllLists(); return wishListsWrapper; } + + public async Task ExportAllWishListsPaged(int pageList) + { + WishListsWrapper wishListsWrapper = await _wishListRepository.GetAllListsPaged(pageList); + return wishListsWrapper; + } } } diff --git a/graphql/schema.graphql b/graphql/schema.graphql index 34123e9..e102ac0 100644 --- a/graphql/schema.graphql +++ b/graphql/schema.graphql @@ -57,6 +57,8 @@ type Query { @cacheControl(scope: PRIVATE) exportList: [WishListWrapperType] @cacheControl(scope: PRIVATE) + exportListPaged(pageList: Int!): [WishListWrapperType] + @cacheControl(scope: PRIVATE) } type Mutation { diff --git a/messages/en.json b/messages/en.json index b5995b8..928840c 100644 --- a/messages/en.json +++ b/messages/en.json @@ -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" } diff --git a/messages/es.json b/messages/es.json index 17d803d..ecb7059 100644 --- a/messages/es.json +++ b/messages/es.json @@ -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" } diff --git a/messages/pt.json b/messages/pt.json index b67eb82..7272d0e 100644 --- a/messages/pt.json +++ b/messages/pt.json @@ -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" } diff --git a/react/WishlistAdmin.tsx b/react/WishlistAdmin.tsx index c66e86c..ff4512b 100644 --- a/react/WishlistAdmin.tsx +++ b/react/WishlistAdmin.tsx @@ -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 { @@ -7,15 +7,21 @@ import { PageHeader, ButtonWithIcon, IconDownload, + Dropdown } 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 = ({ intl }) => { const [state, setState] = useState({ loading: false, }) + const [isLongList, setIsLongList] = useState(false) + const [selected1, setSelected1] = useState(null) + const [options, setOptions] = useState([]) const { loading } = state @@ -48,8 +54,51 @@ const WishlistAdmin: FC = ({ intl }) => { const { data, loading: queryLoading } = useQuery(exportList, { fetchPolicy: 'no-cache', + variables: { pageList: 1 }, }) + const { data: dataSize, loading: queryLoadingSize } = useQuery(listSize, { + fetchPolicy: 'no-cache' + }) + + const { data: dataPaged, loading: queryLoadingPaged, refetch } = useQuery(exportListPaged, { + fetchPolicy: 'no-cache', + variables: { pageList: selected1 }, + }) + + 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 }) @@ -73,6 +122,10 @@ const WishlistAdmin: FC = ({ intl }) => { id: 'admin/settings.download', defaultMessage: 'Download Wishlists', }, + page: { + id: 'admin/settings.page', + defaultMessage: 'Page', + }, }) const download = @@ -81,17 +134,47 @@ const WishlistAdmin: FC = ({ intl }) => { } > - - { - GetAllWishlists() - }} - > - {intl.formatMessage(messages.download)} - - + {isLongList ? + +
+
+ { + console.log(event.target.value) + setSelected1(event.target.value) + setTimeout(()=>{refetch()},500) + + }} + /> +
+
+ { + GetAllWishlistsPaged() + }} + > + {intl.formatMessage(messages.download)} + +
+ : + + { + GetAllWishlists() + }} + > + {intl.formatMessage(messages.download)} + + + }
) } diff --git a/react/queries/exportListPaged.gql b/react/queries/exportListPaged.gql new file mode 100644 index 0000000..0944069 --- /dev/null +++ b/react/queries/exportListPaged.gql @@ -0,0 +1,15 @@ +query ExportListPaged( + $pageList: Int! +) { + exportListPaged(pageList: $pageList) @context(provider: "vtex.wish-list") { + email + listItemsWrapper { + listItems { + id + productId + sku + title + } + } + } +} \ No newline at end of file diff --git a/react/queries/listSize.gql b/react/queries/listSize.gql index 87feeb3..c59cecc 100644 --- a/react/queries/listSize.gql +++ b/react/queries/listSize.gql @@ -1,3 +1,3 @@ -query ListSise { - listSise @context(provider: "vtex.wish-list") +query ListSize { + listSize } \ No newline at end of file From 12465ea667b20ca5de80cf91d532144d92a98b31 Mon Sep 17 00:00:00 2001 From: "cristian.cifuentes" Date: Mon, 4 Mar 2024 12:48:08 -0500 Subject: [PATCH 2/4] Release v1.16.7-beta.0 --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index febf5ad..c3d6e9a 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "name": "wish-list", "vendor": "vtex", - "version": "1.16.6", + "version": "1.16.7-beta.0", "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", "categories": [], From 8ed5d318553213fd1d9311ef87818fb628b16bf9 Mon Sep 17 00:00:00 2001 From: "cristian.cifuentes" Date: Thu, 7 Mar 2024 11:41:51 -0500 Subject: [PATCH 3/4] add wishlist page name --- dotnet/Data/WishListRepository.cs | 4 ++++ manifest.json | 2 +- react/WishlistAdmin.tsx | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/dotnet/Data/WishListRepository.cs b/dotnet/Data/WishListRepository.cs index 508f24b..7b94741 100644 --- a/dotnet/Data/WishListRepository.cs +++ b/dotnet/Data/WishListRepository.cs @@ -281,6 +281,7 @@ private async Task FirstScroll() string responseContent = string.Empty; try { + var client = _clientFactory.CreateClient(); var request = new HttpRequestMessage { @@ -289,6 +290,7 @@ private async Task FirstScroll() }; string authToken = this._httpContextAccessor.HttpContext.Request.Headers[WishListConstants.HEADER_VTEX_CREDENTIAL]; + if (authToken != null) { request.Headers.Add(WishListConstants.AUTHORIZATION_HEADER_NAME, authToken); @@ -297,6 +299,8 @@ private async Task 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(); diff --git a/manifest.json b/manifest.json index c3d6e9a..febf5ad 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "name": "wish-list", "vendor": "vtex", - "version": "1.16.7-beta.0", + "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", "categories": [], diff --git a/react/WishlistAdmin.tsx b/react/WishlistAdmin.tsx index ff4512b..f9c80b3 100644 --- a/react/WishlistAdmin.tsx +++ b/react/WishlistAdmin.tsx @@ -48,7 +48,7 @@ const WishlistAdmin: FC = ({ intl }) => { 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` + const exportFileName = `wishlists_page_${selected1}.xls` XLSX.writeFile(wb, exportFileName) } @@ -101,6 +101,7 @@ const WishlistAdmin: FC = ({ intl }) => { const GetAllWishlists = async () => { setState({ ...state, loading: true }) + console.log(loading) if (!queryLoading) { const parsedData = data?.exportList From f62f668fa38e8e1708192205419348de495af362 Mon Sep 17 00:00:00 2001 From: "cristian.cifuentes" Date: Thu, 7 Mar 2024 12:09:07 -0500 Subject: [PATCH 4/4] fix wishlist file name --- manifest.json | 2 +- react/WishlistAdmin.tsx | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/manifest.json b/manifest.json index febf5ad..9ba9b76 100644 --- a/manifest.json +++ b/manifest.json @@ -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": { diff --git a/react/WishlistAdmin.tsx b/react/WishlistAdmin.tsx index f9c80b3..25275f4 100644 --- a/react/WishlistAdmin.tsx +++ b/react/WishlistAdmin.tsx @@ -45,11 +45,18 @@ const WishlistAdmin: FC = ({ intl }) => { } } + 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_page_${selected1}.xls` - XLSX.writeFile(wb, exportFileName) + if(selected1 != null) { + const exportFileName = `wishlists_page_${selected1}.xls` + XLSX.writeFile(wb, exportFileName) + } else { + const exportFileName = `wishlists.xls` + XLSX.writeFile(wb, exportFileName) + + } } const { data, loading: queryLoading } = useQuery(exportList, {