1
1
import { UmbModalBaseElement } from "@umbraco-cms/backoffice/modal" ;
2
2
import { SHOPIFY_CONTEXT_TOKEN } from "../context/shopify.context.js" ;
3
3
import { UMB_NOTIFICATION_CONTEXT } from "@umbraco-cms/backoffice/notification" ;
4
- import { html , state , customElement , css } from "@umbraco-cms/backoffice/external/lit" ;
4
+ import { html , state , customElement , css , nothing } from "@umbraco-cms/backoffice/external/lit" ;
5
5
import type { EditorSettingsModel , ProductDtoModel } from "../../generated" ;
6
6
import type { ShopifyProductPickerModalData , ShopifyProductPickerModalValue } from "./shopify.modal-token.js" ;
7
7
import type { ShopifyServiceStatus } from "../models/shopify-service.model.js" ;
8
8
import type { UmbTableColumn , UmbTableConfig , UmbTableItem , UmbTableSelectedEvent , UmbTableElement , UmbTableDeselectedEvent , UmbTableItemData } from '@umbraco-cms/backoffice/components' ;
9
9
import type { ShopifyCollectionModel } from "../types/types.js" ;
10
- import type { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collection' ;
11
- import { UMB_COLLECTION_CONTEXT } from '@umbraco-cms/backoffice/collection' ;
10
+ import type { UmbDefaultCollectionContext } from "@umbraco-cms/backoffice/collection" ;
11
+ import { UMB_COLLECTION_CONTEXT } from "@umbraco-cms/backoffice/collection" ;
12
+ import { UmbPaginationManager } from "@umbraco-cms/backoffice/utils" ;
13
+ import type { UUIPaginationEvent } from "@umbraco-cms/backoffice/external/uui" ;
12
14
13
15
const elementName = "shopify-products-modal" ;
14
16
@@ -17,10 +19,23 @@ export default class ShopifyProductsModalElement extends UmbModalBaseElement<Sho
17
19
#shopifyContext! : typeof SHOPIFY_CONTEXT_TOKEN . TYPE ;
18
20
#settingsModel?: EditorSettingsModel ;
19
21
#collectionContext! : UmbDefaultCollectionContext < ShopifyCollectionModel > ;
22
+ #paginationManager = new UmbPaginationManager ( ) ;
20
23
_modalSelectedProducts : Array < ProductDtoModel > = [ ] ;
21
24
_numberOfSelection : number = 0 ;
22
25
_addUpToItems : number = 0 ;
23
26
_selectionIdList : Array < string | null > = [ ] ;
27
+
28
+ @state ( )
29
+ _currentPageNumber = 1 ;
30
+
31
+ @state ( )
32
+ _totalPages = 1 ;
33
+
34
+ @state ( )
35
+ _nextPageInfo ?: string ;
36
+
37
+ @state ( )
38
+ _previousPageInfo ?: string ;
24
39
25
40
@state ( )
26
41
private _selection : Array < string | null > = [ ] ;
@@ -101,7 +116,7 @@ export default class ShopifyProductsModalElement extends UmbModalBaseElement<Sho
101
116
( selection ) => ( this . _selection = selection ) ,
102
117
'umbCollectionSelectionObserver' ,
103
118
) ;
104
- } ) ;
119
+ } ) ;
105
120
}
106
121
107
122
async connectedCallback ( ) {
@@ -119,25 +134,49 @@ export default class ShopifyProductsModalElement extends UmbModalBaseElement<Sho
119
134
useOAuth : this . #settingsModel. isValid && this . #settingsModel. type . value === "OAuth"
120
135
}
121
136
122
- await this . #loadProducts( ) ;
137
+ if ( ! this . _serviceStatus . isValid ) {
138
+ this . _showError ( "Invalid Shopify API Configuration" ) ;
139
+ return ;
140
+ }
141
+
142
+ await this . #getTotalPages( ) ;
143
+ await this . #loadProducts( "" ) ;
123
144
}
124
145
125
- async #loadProducts( ) {
146
+ async #loadProducts( pageInfo ?: string ) {
147
+ await this . #getTotalPages( ) ;
148
+
126
149
this . _loading = true ;
127
- const { data } = await this . #shopifyContext. getList ( "" ) ;
150
+ const { data } = await this . #shopifyContext. getList ( pageInfo ) ;
128
151
if ( ! data ) return ;
129
152
153
+ if ( ! data . isValid ) {
154
+ this . _showError ( "Cannot access Shopify API." ) ;
155
+ this . _loading = false ;
156
+ return ;
157
+ }
158
+
130
159
this . _products = data . result . products ?? [ ] ;
131
160
this . _loading = false ;
132
161
133
162
if ( ! data . isValid || data . isExpired ) {
134
163
this . _showError ( "Data is invalid or expired." ! ) ;
135
164
}
136
165
166
+ this . _nextPageInfo = data . nextPageInfo ;
167
+ this . _previousPageInfo = data . previousPageInfo ;
168
+
137
169
this . #createTableItems( this . _products ) ;
138
170
this . #loadSelectionItems( ) ;
139
171
}
140
172
173
+ async #getTotalPages( ) {
174
+ const { data } = await this . #shopifyContext. getTotalPages ( ) ;
175
+ if ( ! data ) return ;
176
+
177
+ this . _totalPages = data ;
178
+ }
179
+
141
180
#createTableItems( products : Array < ProductDtoModel > ) {
142
181
this . _tableItems = products . map ( ( product ) => {
143
182
return {
@@ -246,6 +285,17 @@ export default class ShopifyProductsModalElement extends UmbModalBaseElement<Sho
246
285
}
247
286
}
248
287
288
+ #onPageChange( event : UUIPaginationEvent ) {
289
+ const forward = event . target ?. current > this . _currentPageNumber ;
290
+
291
+ const currentPageNumber = forward ? this . _currentPageNumber + 1 : this . _currentPageNumber - 1
292
+
293
+ this . #paginationManager. setCurrentPageNumber ( currentPageNumber ) ;
294
+
295
+ this . _currentPageNumber = currentPageNumber ;
296
+ this . #loadProducts( forward ? this . _nextPageInfo : this . _previousPageInfo ) ;
297
+ }
298
+
249
299
private async _showError ( message : string ) {
250
300
const notificationContext = await this . getContext ( UMB_NOTIFICATION_CONTEXT ) ;
251
301
notificationContext ?. peek ( "danger" , {
@@ -257,15 +307,16 @@ export default class ShopifyProductsModalElement extends UmbModalBaseElement<Sho
257
307
return html `
258
308
<umb- body- layout>
259
309
<uui- box headline= ${ this . data ! . headline } >
260
- ${ this . _loading ? html `<div class= "center" > <uui- loader> </ uui- loader> </ div> ` : "" }
310
+ ${ this . _loading ? html `<div class= "center loader " > <uui- loader> </ uui- loader> </ div> ` : "" }
261
311
<umb- table
262
312
.config = ${ this . _tableConfig }
263
313
.columns = ${ this . _tableColumns }
264
314
.items = ${ this . _tableItems }
265
315
.selection = ${ this . _selection }
266
316
@selected = "${ this . #onSelected} "
267
- @deselected = "${ this . #onDeselected} " > </ umb- table>
268
-
317
+ @deselected = "${ this . #onDeselected} " >
318
+ </ umb- table>
319
+ ${ this . #renderPagination( ) }
269
320
</ uui- box>
270
321
271
322
<div class= "maximum-selection" >
@@ -280,10 +331,36 @@ export default class ShopifyProductsModalElement extends UmbModalBaseElement<Sho
280
331
` ;
281
332
}
282
333
334
+ #renderPagination( ) {
335
+ return html `
336
+ ${ this . _totalPages > 1
337
+ ? html `
338
+ <div class= "shopify-pagination" >
339
+ <uui- pagination
340
+ class= "pagination"
341
+ .current = ${ this . _currentPageNumber }
342
+ .total = ${ this . _totalPages }
343
+ @change = ${ this . #onPageChange} > </ uui- pagination>
344
+ </ div>
345
+ `
346
+ : nothing }
347
+ ` ;
348
+ }
349
+
283
350
static styles = [ css `
351
+ .loader {
352
+ display : flex;
353
+ justify-content : center;
354
+ }
284
355
.maximum-selection {
285
356
margin-top : 10px ;
286
357
font-weight : bold;
287
358
}
359
+ .shopify-pagination {
360
+ width : 50% ;
361
+ margin-top : 10px ;
362
+ margin-left : auto;
363
+ margin-right : auto;
364
+ }
288
365
` ] ;
289
366
}
0 commit comments