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 , css , state , customElement } from "@umbraco-cms/backoffice/external/lit" ;
4
+ import { html , state , customElement , css } from "@umbraco-cms/backoffice/external/lit" ;
5
5
import type { 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
- import type { UmbTableColumn , UmbTableConfig , UmbTableItem , UmbTableSelectedEvent , UmbTableElement , UmbTableDeselectedEvent } from '@umbraco-cms/backoffice/components' ;
9
- import type { ShopifyCollectionModel } from "../types/types.js" ;
8
+ import type { UmbTableColumn , UmbTableConfig , UmbTableItem , UmbTableSelectedEvent , UmbTableElement , UmbTableDeselectedEvent , UmbTableItemData } from '@umbraco-cms/backoffice/components' ;
9
+ import type { ShopifyCollectionModel } from "../types/types.js" ;
10
10
import type { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collection' ;
11
11
import { UMB_COLLECTION_CONTEXT } from '@umbraco-cms/backoffice/collection' ;
12
12
@@ -16,15 +16,35 @@ const elementName = "shopify-products-modal";
16
16
export default class ShopifyProductsModalElement extends UmbModalBaseElement < ShopifyProductPickerModalData , ShopifyProductPickerModalValue > {
17
17
#shopifyContext! : typeof SHOPIFY_CONTEXT_TOKEN . TYPE ;
18
18
#collectionContext! : UmbDefaultCollectionContext < ShopifyCollectionModel > ;
19
-
19
+ _modalSelectedProducts : Array < ProductDtoModel > = [ ] ;
20
+ _numberOfSelection : number = 0 ;
21
+ _selectionIdList : Array < string | null > = [ ] ;
22
+
20
23
@state ( )
21
- private _selection : Array < string > = [ ] ;
24
+ private _selection : Array < string | null > = [ ] ;
22
25
23
26
@state ( )
24
27
private _tableConfig : UmbTableConfig = {
25
28
allowSelection : true ,
26
29
} ;
27
30
31
+ @state ( )
32
+ private _tableItems : Array < UmbTableItem > = [ ] ;
33
+
34
+ @state ( )
35
+ private _serviceStatus : ShopifyServiceStatus = {
36
+ isValid : false ,
37
+ type : "" ,
38
+ description : "" ,
39
+ useOAuth : false
40
+ } ;
41
+
42
+ @state ( )
43
+ private _loading = false ;
44
+
45
+ @state ( )
46
+ private _products : Array < ProductDtoModel > = [ ] ;
47
+
28
48
@state ( )
29
49
private _tableColumns : Array < UmbTableColumn > = [
30
50
{
@@ -61,23 +81,6 @@ export default class ShopifyProductsModalElement extends UmbModalBaseElement<Sho
61
81
} ,
62
82
] ;
63
83
64
- @state ( )
65
- private _tableItems : Array < UmbTableItem > = [ ] ;
66
-
67
- @state ( )
68
- private _serviceStatus : ShopifyServiceStatus = {
69
- isValid : false ,
70
- type : "" ,
71
- description : "" ,
72
- useOAuth : false
73
- } ;
74
-
75
- @state ( )
76
- private _loading = false ;
77
-
78
- @state ( )
79
- private _products : Array < ProductDtoModel > = [ ] ;
80
-
81
84
constructor ( ) {
82
85
super ( ) ;
83
86
@@ -87,7 +90,14 @@ export default class ShopifyProductsModalElement extends UmbModalBaseElement<Sho
87
90
88
91
this . consumeContext ( UMB_COLLECTION_CONTEXT , ( instance ) => {
89
92
this . #collectionContext = instance ;
93
+ this . observe (
94
+ this . #collectionContext. selection . selection ,
95
+ ( selection ) => ( this . _selection = selection ) ,
96
+ 'umbCollectionSelectionObserver' ,
97
+ ) ;
90
98
} ) ;
99
+
100
+
91
101
}
92
102
93
103
async connectedCallback ( ) {
@@ -124,21 +134,61 @@ export default class ShopifyProductsModalElement extends UmbModalBaseElement<Sho
124
134
}
125
135
126
136
this . #createTableItems( this . _products ) ;
137
+ this . _selection = this . data ! . selectedItemIdList ;
127
138
}
128
139
129
140
#onSelected( event : UmbTableSelectedEvent ) {
130
- event . stopPropagation ( ) ;
131
- const table = event . target as UmbTableElement ;
132
- const selection = table . selection ;
133
- this . #collectionContext?. selection . setSelection ( selection ) ;
141
+ this . #onEventRun( event ) ;
134
142
}
135
143
136
144
#onDeselected( event : UmbTableDeselectedEvent ) {
137
- event . stopPropagation ( ) ;
145
+ this . #onEventRun( event ) ;
146
+ }
147
+
148
+ #onEventRun( event : UmbTableSelectedEvent | UmbTableDeselectedEvent ) {
149
+ event . stopPropagation ( ) ;
138
150
const table = event . target as UmbTableElement ;
139
151
const selection = table . selection ;
152
+ const items = table . items ;
140
153
this . #collectionContext?. selection . setSelection ( selection ) ;
141
- }
154
+
155
+ this . #getSelectedProduct( selection , items ) ;
156
+ this . _numberOfSelection = selection . length ;
157
+ }
158
+
159
+ #getSelectedProduct( selectedRows : Array < string > , allRows : Array < UmbTableItem > ) {
160
+ let lst : Array < UmbTableItem [ ] > = [ ] ;
161
+ selectedRows . forEach ( selectedRow => {
162
+ const selectedProduct = allRows . filter ( r => r . id == selectedRow ) ;
163
+ lst . push ( selectedProduct ) ;
164
+ } ) ;
165
+
166
+ let lstData = lst . map ( l => l [ 0 ] . data ) ;
167
+ let lstId = lst . map ( l => l [ 0 ] . id ) ;
168
+ this . _modalSelectedProducts = this . #mapToDto( lstData , lstId ) ;
169
+ }
170
+
171
+ #mapToDto( lstData : UmbTableItemData [ ] [ ] , lstId : string [ ] ) {
172
+ let productList : Array < ProductDtoModel > = [ ] ;
173
+ for ( let i = 0 ; i < lstData . length ; i ++ ) {
174
+ let dto : ProductDtoModel = {
175
+ title : lstData [ i ] . find ( x => x . columnAlias == "productName" ) ?. value ,
176
+ vendor : lstData [ i ] . find ( x => x . columnAlias == "vendor" ) ?. value ,
177
+ id : Number ( lstId [ i ] ) ,
178
+ body : "" ,
179
+ status : lstData [ i ] . find ( x => x . columnAlias == "status" ) ?. value ,
180
+ tags : lstData [ i ] . find ( x => x . columnAlias == "tags" ) ?. value ,
181
+ variants : [ ] ,
182
+ image : {
183
+ src : ""
184
+ }
185
+ }
186
+
187
+ productList . push ( dto ) ;
188
+ }
189
+
190
+ return productList ;
191
+ }
142
192
143
193
private async _showError ( message : string ) {
144
194
const notificationContext = await this . getContext ( UMB_NOTIFICATION_CONTEXT ) ;
@@ -185,10 +235,23 @@ export default class ShopifyProductsModalElement extends UmbModalBaseElement<Sho
185
235
} ) ;
186
236
}
187
237
238
+ _onSubmit ( ) {
239
+ if ( this . _numberOfSelection > 2 ) {
240
+ this . _showError ( "Cannot select more than 2 products." ! ) ;
241
+ } else {
242
+ if ( this . _modalSelectedProducts . length == 0 ) {
243
+ this . _rejectModal ( ) ;
244
+ }
245
+
246
+ this . value = { productList : this . _modalSelectedProducts } ;
247
+ this . _submitModal ( ) ;
248
+ }
249
+ }
250
+
188
251
render ( ) {
189
252
return html `
190
253
<umb- body- layout>
191
- < uui-box headline =" Shopify Products " >
254
+ <uui- box headline= ${ this . data ! . headline } >
192
255
${ this . _loading ? html `<div class= "center" > <uui- loader> </ uui- loader> </ div> ` : "" }
193
256
<umb- table
194
257
.config = ${ this . _tableConfig }
@@ -199,11 +262,23 @@ export default class ShopifyProductsModalElement extends UmbModalBaseElement<Sho
199
262
@deselected = "${ this . #onDeselected} " > </ umb- table>
200
263
201
264
</ uui- box>
202
- < span > Add up to x items(s)</ span >
203
265
204
- < uui-button slot ="actions " label ="Submit " @click =${ this . _submitModal } > </ uui-button >
266
+ <div class= "maximum-selection" >
267
+ <span>
268
+ Add up to 2 items(s)
269
+ </ span>
270
+ </ div>
271
+
272
+ <uui- butto n look= "primary" slot = "actions" label = "Submit" @click = ${ this . _onSubmit } > </ uui- butto n>
205
273
<uui- butto n slot= "actions" label = "Close" @click = ${ this . _rejectModal } > </ uui- butto n>
206
274
</ umb- body- layout>
207
275
` ;
208
276
}
277
+
278
+ static styles = [ css `
279
+ .maximum-selection {
280
+ margin-top : 10px ;
281
+ font-weight : bold;
282
+ }
283
+ ` ] ;
209
284
}
0 commit comments