neo.mjs 4.0.16 → 4.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/examples/toolbar/paging/store/Users.mjs +13 -0
- package/examples/toolbar/paging/view/MainContainer.mjs +33 -7
- package/examples/toolbar/paging/view/MainContainerController.mjs +9 -0
- package/package.json +3 -3
- package/src/Neo.mjs +1 -1
- package/src/collection/Base.mjs +42 -8
- package/src/collection/Filter.mjs +17 -0
- package/src/collection/Sorter.mjs +17 -1
- package/src/data/Store.mjs +76 -25
- package/src/main/addon/Mwc.mjs +2 -2
- package/src/table/header/Button.mjs +7 -11
- package/src/table/header/Toolbar.mjs +1 -1
- package/src/toolbar/Paging.mjs +2 -0
|
@@ -20,10 +20,23 @@ class Users extends Store {
|
|
|
20
20
|
* @member {Boolean} autoLoad=true
|
|
21
21
|
*/
|
|
22
22
|
autoLoad: true,
|
|
23
|
+
/**
|
|
24
|
+
* True to sort the collection items when adding / inserting new ones
|
|
25
|
+
* @member {Boolean} autoSort=false
|
|
26
|
+
*/
|
|
27
|
+
autoSort: false,
|
|
23
28
|
/**
|
|
24
29
|
* @member {Neo.data.Model} model=UserModel
|
|
25
30
|
*/
|
|
26
31
|
model: UserModel,
|
|
32
|
+
/**
|
|
33
|
+
* @member {Boolean} remoteFilter=true
|
|
34
|
+
*/
|
|
35
|
+
remoteFilter: true,
|
|
36
|
+
/**
|
|
37
|
+
* @member {Boolean} remoteSort=true
|
|
38
|
+
*/
|
|
39
|
+
remoteSort: true,
|
|
27
40
|
/**
|
|
28
41
|
* @member {Object[]} sorters
|
|
29
42
|
*/
|
|
@@ -10,13 +10,22 @@ import Viewport from '../../../../src/container/Viewport.mjs';
|
|
|
10
10
|
*/
|
|
11
11
|
class MainContainer extends Viewport {
|
|
12
12
|
static getConfig() {return {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
/**
|
|
14
|
+
* @member {String} className='Neo.examples.toolbar.paging.view.MainContainer'
|
|
15
|
+
* @protected
|
|
16
|
+
*/
|
|
17
|
+
className: 'Neo.examples.toolbar.paging.view.MainContainer',
|
|
18
|
+
/**
|
|
19
|
+
* @member {Boolean} autoMount=true
|
|
20
|
+
*/
|
|
21
|
+
autoMount: true,
|
|
22
|
+
/**
|
|
23
|
+
* @member {Neo.controller.Component} controller=MainContainerController
|
|
24
|
+
*/
|
|
15
25
|
controller: MainContainerController,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
26
|
+
/**
|
|
27
|
+
* @member {Object[]} items
|
|
28
|
+
*/
|
|
20
29
|
items: [{
|
|
21
30
|
ntype: 'toolbar',
|
|
22
31
|
flex : 'none',
|
|
@@ -24,6 +33,11 @@ class MainContainer extends Viewport {
|
|
|
24
33
|
handler: 'onAddUserButtonClick',
|
|
25
34
|
iconCls: 'fa fa-circle-plus',
|
|
26
35
|
text : 'Add User'
|
|
36
|
+
}, {
|
|
37
|
+
handler: 'onShowFiltersButtonClick',
|
|
38
|
+
iconCls: 'fa fa-filter',
|
|
39
|
+
style : {marginLeft: '2px'},
|
|
40
|
+
text : 'Show Filters'
|
|
27
41
|
}]
|
|
28
42
|
}, {
|
|
29
43
|
module : UserTableContainer,
|
|
@@ -35,7 +49,19 @@ class MainContainer extends Viewport {
|
|
|
35
49
|
module: PagingToolbar,
|
|
36
50
|
bind : {store: 'stores.users'},
|
|
37
51
|
flex : 'none'
|
|
38
|
-
}]
|
|
52
|
+
}],
|
|
53
|
+
/**
|
|
54
|
+
* @member {Object} layout={ntype:'vbox',align:'stretch'}
|
|
55
|
+
*/
|
|
56
|
+
layout: {ntype: 'vbox', align: 'stretch'},
|
|
57
|
+
/**
|
|
58
|
+
* @member {Neo.model.Component} model=MainContainerModel
|
|
59
|
+
*/
|
|
60
|
+
model: MainContainerModel,
|
|
61
|
+
/**
|
|
62
|
+
* @member {Object} style={padding:'20px'}
|
|
63
|
+
*/
|
|
64
|
+
style: {padding: '20px'}
|
|
39
65
|
}}
|
|
40
66
|
}
|
|
41
67
|
|
|
@@ -37,6 +37,15 @@ class MainContainerController extends ComponentController {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* @param {Object} data
|
|
42
|
+
*/
|
|
43
|
+
onShowFiltersButtonClick(data) {
|
|
44
|
+
let userTable = this.getReference('user-table');
|
|
45
|
+
|
|
46
|
+
userTable.showHeaderFilters = !userTable.showHeaderFilters;
|
|
47
|
+
}
|
|
48
|
+
|
|
40
49
|
/**
|
|
41
50
|
* Sending messages through a WebSocket inside the data worker
|
|
42
51
|
* @param {Object} data
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "neo.mjs",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.19",
|
|
4
4
|
"description": "The webworkers driven UI framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"homepage": "https://neomjs.github.io/pages/",
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@fortawesome/fontawesome-free": "^6.1.1",
|
|
38
|
-
"@material/mwc-button": "^0.26.
|
|
39
|
-
"@material/mwc-textfield": "^0.26.
|
|
38
|
+
"@material/mwc-button": "^0.26.1",
|
|
39
|
+
"@material/mwc-textfield": "^0.26.1",
|
|
40
40
|
"autoprefixer": "^10.4.7",
|
|
41
41
|
"chalk": "^5.0.1",
|
|
42
42
|
"clean-webpack-plugin": "^4.0.0",
|
package/src/Neo.mjs
CHANGED
package/src/collection/Base.mjs
CHANGED
|
@@ -41,13 +41,13 @@ class Base extends CoreBase {
|
|
|
41
41
|
/**
|
|
42
42
|
* When filtering the collection for the first time, allItems will become a new collection for the unfiltered
|
|
43
43
|
* state, using this id as the sourceCollectionId
|
|
44
|
-
* @member {Neo.collection.Base|null} allItems
|
|
44
|
+
* @member {Neo.collection.Base|null} allItems=null
|
|
45
45
|
* @protected
|
|
46
46
|
*/
|
|
47
47
|
allItems: null,
|
|
48
48
|
/**
|
|
49
49
|
* True to sort the collection items when adding / inserting new ones
|
|
50
|
-
* @member {Boolean} autoSort
|
|
50
|
+
* @member {Boolean} autoSort=true
|
|
51
51
|
*/
|
|
52
52
|
autoSort: true,
|
|
53
53
|
/**
|
|
@@ -352,11 +352,9 @@ class Base extends CoreBase {
|
|
|
352
352
|
}
|
|
353
353
|
});
|
|
354
354
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
});
|
|
359
|
-
}
|
|
355
|
+
oldValue?.forEach(key => {
|
|
356
|
+
key.destroy();
|
|
357
|
+
});
|
|
360
358
|
|
|
361
359
|
return value;
|
|
362
360
|
}
|
|
@@ -515,7 +513,7 @@ class Base extends CoreBase {
|
|
|
515
513
|
if (hasTransformValue) {
|
|
516
514
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Sorting_with_map
|
|
517
515
|
mappedItems = items.map((item, index) => {
|
|
518
|
-
obj = {index
|
|
516
|
+
obj = {index};
|
|
519
517
|
i = 0;
|
|
520
518
|
|
|
521
519
|
for (; i < countSorters; i++) {
|
|
@@ -597,6 +595,42 @@ class Base extends CoreBase {
|
|
|
597
595
|
}
|
|
598
596
|
}
|
|
599
597
|
|
|
598
|
+
/**
|
|
599
|
+
* Needed for remote filtering
|
|
600
|
+
* @returns {Object[]}
|
|
601
|
+
*/
|
|
602
|
+
exportFilters() {
|
|
603
|
+
let me = this,
|
|
604
|
+
filters = [],
|
|
605
|
+
filter;
|
|
606
|
+
|
|
607
|
+
me.filters?.forEach(key => {
|
|
608
|
+
filter = key.export();
|
|
609
|
+
|
|
610
|
+
filter && filters.push(filter);
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
return filters;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Needed for remote sorting
|
|
618
|
+
* @returns {Object[]}
|
|
619
|
+
*/
|
|
620
|
+
exportSorters() {
|
|
621
|
+
let me = this,
|
|
622
|
+
sorters = [],
|
|
623
|
+
sorter;
|
|
624
|
+
|
|
625
|
+
me.sorters?.forEach(key => {
|
|
626
|
+
sorter = key.export();
|
|
627
|
+
|
|
628
|
+
sorter && sorters.push(sorter);
|
|
629
|
+
});
|
|
630
|
+
|
|
631
|
+
return sorters;
|
|
632
|
+
}
|
|
633
|
+
|
|
600
634
|
/**
|
|
601
635
|
* @protected
|
|
602
636
|
*/
|
|
@@ -140,6 +140,23 @@ class Filter extends Base {
|
|
|
140
140
|
return this.beforeSetEnumValue(value, oldValue, 'operator');
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
+
/**
|
|
144
|
+
* Needed for remote filtering
|
|
145
|
+
* @returns {Object|null}
|
|
146
|
+
*/
|
|
147
|
+
export() {
|
|
148
|
+
let me = this,
|
|
149
|
+
operator = me.operator,
|
|
150
|
+
property = me.property,
|
|
151
|
+
value = me.value;
|
|
152
|
+
|
|
153
|
+
if (!me.filterBy) {
|
|
154
|
+
return {operator, property, value};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
|
|
143
160
|
/**
|
|
144
161
|
* @param value
|
|
145
162
|
* @param oldValue
|
|
@@ -27,7 +27,7 @@ class Sorter extends Base {
|
|
|
27
27
|
*/
|
|
28
28
|
ntype: 'sorter',
|
|
29
29
|
/**
|
|
30
|
-
* Internal config which
|
|
30
|
+
* Internal config which maps the direction ASC to 1, -1 otherwise
|
|
31
31
|
* @member {Number} directionMultiplier=1
|
|
32
32
|
* @protected
|
|
33
33
|
*/
|
|
@@ -121,6 +121,22 @@ class Sorter extends Base {
|
|
|
121
121
|
return 0;
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
/**
|
|
125
|
+
* Needed for remote sorting
|
|
126
|
+
* @returns {Object|null}
|
|
127
|
+
*/
|
|
128
|
+
export() {
|
|
129
|
+
let me = this,
|
|
130
|
+
direction = me.direction,
|
|
131
|
+
property = me.property;
|
|
132
|
+
|
|
133
|
+
if (!me.sortBy && direction && property) {
|
|
134
|
+
return {direction, property};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
|
|
124
140
|
/**
|
|
125
141
|
* @param {*} value
|
|
126
142
|
* @returns {*} value
|
package/src/data/Store.mjs
CHANGED
|
@@ -162,6 +162,21 @@ class Store extends Base {
|
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
+
/**
|
|
166
|
+
* @param {Object[]} value
|
|
167
|
+
* @param {Object[]} oldValue
|
|
168
|
+
* @protected
|
|
169
|
+
*/
|
|
170
|
+
afterSetFilters(value, oldValue) {
|
|
171
|
+
super.afterSetFilters(value, oldValue);
|
|
172
|
+
|
|
173
|
+
let me = this;
|
|
174
|
+
|
|
175
|
+
me._currentPage = 1; // silent update
|
|
176
|
+
|
|
177
|
+
oldValue && me.remoteFilter && me.load();
|
|
178
|
+
}
|
|
179
|
+
|
|
165
180
|
/**
|
|
166
181
|
* @param value
|
|
167
182
|
* @param oldValue
|
|
@@ -196,6 +211,21 @@ class Store extends Base {
|
|
|
196
211
|
}
|
|
197
212
|
}
|
|
198
213
|
|
|
214
|
+
/**
|
|
215
|
+
* @param {Object[]} value
|
|
216
|
+
* @param {Object[]} oldValue
|
|
217
|
+
* @protected
|
|
218
|
+
*/
|
|
219
|
+
afterSetSorters(value, oldValue) {
|
|
220
|
+
super.afterSetSorters(value, oldValue);
|
|
221
|
+
|
|
222
|
+
let me = this;
|
|
223
|
+
|
|
224
|
+
me._currentPage = 1; // silent update
|
|
225
|
+
|
|
226
|
+
oldValue && me.remoteSort && me.load();
|
|
227
|
+
}
|
|
228
|
+
|
|
199
229
|
/**
|
|
200
230
|
* @param {Object|String|null} value
|
|
201
231
|
* @param {Object|String|null} oldValue
|
|
@@ -237,8 +267,6 @@ class Store extends Base {
|
|
|
237
267
|
value[index] = RecordFactory.createRecord(me.model, key);
|
|
238
268
|
}
|
|
239
269
|
});
|
|
240
|
-
|
|
241
|
-
// console.log('beforeSetData', value);
|
|
242
270
|
}
|
|
243
271
|
|
|
244
272
|
return value;
|
|
@@ -265,9 +293,7 @@ class Store extends Base {
|
|
|
265
293
|
* @returns {Neo.data.Model}
|
|
266
294
|
*/
|
|
267
295
|
beforeSetModel(value, oldValue) {
|
|
268
|
-
|
|
269
|
-
oldValue.destroy();
|
|
270
|
-
}
|
|
296
|
+
oldValue?.destroy();
|
|
271
297
|
|
|
272
298
|
return ClassSystemUtil.beforeSetInstance(value, Model);
|
|
273
299
|
}
|
|
@@ -280,7 +306,16 @@ class Store extends Base {
|
|
|
280
306
|
}
|
|
281
307
|
|
|
282
308
|
load() {
|
|
283
|
-
let me = this
|
|
309
|
+
let me = this,
|
|
310
|
+
params = {page: me.currentPage, pageSize: me.pageSize};
|
|
311
|
+
|
|
312
|
+
if (me.remoteFilter) {
|
|
313
|
+
params.filters = me.exportFilters();
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (me.remoteSort) {
|
|
317
|
+
params.sorters = me.exportSorters();
|
|
318
|
+
}
|
|
284
319
|
|
|
285
320
|
if (me.api) {
|
|
286
321
|
let apiArray = me.api.read.split('.'),
|
|
@@ -290,10 +325,7 @@ class Store extends Base {
|
|
|
290
325
|
if (!service) {
|
|
291
326
|
console.log('Api is not defined', this);
|
|
292
327
|
} else {
|
|
293
|
-
service[fn]({
|
|
294
|
-
page : me.currentPage,
|
|
295
|
-
pageSize: me.pageSize
|
|
296
|
-
}).then(response => {
|
|
328
|
+
service[fn](params).then(response => {
|
|
297
329
|
if (response.success) {
|
|
298
330
|
me.totalCount = response.totalCount;
|
|
299
331
|
me.data = response.data; // fires the load event
|
|
@@ -301,8 +333,10 @@ class Store extends Base {
|
|
|
301
333
|
});
|
|
302
334
|
}
|
|
303
335
|
} else {
|
|
336
|
+
params.url = me.url;
|
|
337
|
+
|
|
304
338
|
Neo.Xhr.promiseJson({
|
|
305
|
-
url:
|
|
339
|
+
url: params
|
|
306
340
|
}).catch(err => {
|
|
307
341
|
console.log('Error for Neo.Xhr.request', err, me.id);
|
|
308
342
|
}).then(data => {
|
|
@@ -355,6 +389,21 @@ class Store extends Base {
|
|
|
355
389
|
}
|
|
356
390
|
}
|
|
357
391
|
|
|
392
|
+
/**
|
|
393
|
+
* @param {Object} opts
|
|
394
|
+
* @protected
|
|
395
|
+
*/
|
|
396
|
+
onFilterChange(opts) {
|
|
397
|
+
let me = this;
|
|
398
|
+
|
|
399
|
+
if (me.remoteFilter) {
|
|
400
|
+
me._currentPage = 1; // silent update
|
|
401
|
+
me.load();
|
|
402
|
+
} else {
|
|
403
|
+
super.onFilterChange(opts);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
358
407
|
/**
|
|
359
408
|
* Gets triggered after changing the value of a record field.
|
|
360
409
|
* E.g. myRecord.foo = 'bar';
|
|
@@ -371,28 +420,30 @@ class Store extends Base {
|
|
|
371
420
|
}
|
|
372
421
|
|
|
373
422
|
/**
|
|
374
|
-
* @param {Object} opts
|
|
423
|
+
* @param {Object} opts={}
|
|
375
424
|
* @param {String} opts.direction
|
|
376
425
|
* @param {String} opts.property
|
|
377
426
|
*/
|
|
378
427
|
sort(opts={}) {
|
|
379
428
|
let me = this;
|
|
380
429
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
}];
|
|
392
|
-
} else {
|
|
430
|
+
me._currentPage = 1; // silent update
|
|
431
|
+
|
|
432
|
+
if (me.configsApplied) {
|
|
433
|
+
if (opts.direction) {
|
|
434
|
+
me.sorters = [{
|
|
435
|
+
direction: opts.direction,
|
|
436
|
+
property : opts.property
|
|
437
|
+
}];
|
|
438
|
+
} else {
|
|
439
|
+
if (!me.remoteSort) {
|
|
393
440
|
me.startUpdate();
|
|
394
441
|
me.clear();
|
|
395
|
-
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
me.sorters = [];
|
|
445
|
+
|
|
446
|
+
if (!me.remoteSort) {
|
|
396
447
|
me.add([...me.initialData]);
|
|
397
448
|
me.endUpdate();
|
|
398
449
|
me.fire('sort');
|
package/src/main/addon/Mwc.mjs
CHANGED
|
@@ -49,7 +49,7 @@ class Mwc extends Base {
|
|
|
49
49
|
if (Neo.config.environment === 'development') {
|
|
50
50
|
import(
|
|
51
51
|
/* webpackIgnore: true */
|
|
52
|
-
'https://unpkg.com/@material/mwc-button@0.
|
|
52
|
+
'https://unpkg.com/@material/mwc-button@0.26.1/mwc-button.js?module'
|
|
53
53
|
);
|
|
54
54
|
} else {
|
|
55
55
|
// dist/development & dist/production
|
|
@@ -64,7 +64,7 @@ class Mwc extends Base {
|
|
|
64
64
|
if (Neo.config.environment === 'development') {
|
|
65
65
|
import(
|
|
66
66
|
/* webpackIgnore: true */
|
|
67
|
-
'https://unpkg.com/@material/mwc-textfield@0.
|
|
67
|
+
'https://unpkg.com/@material/mwc-textfield@0.26.1/mwc-textfield.js?module'
|
|
68
68
|
);
|
|
69
69
|
} else {
|
|
70
70
|
// dist/development & dist/production
|
|
@@ -178,12 +178,10 @@ class Button extends BaseButton {
|
|
|
178
178
|
return;
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
});
|
|
186
|
-
}
|
|
181
|
+
me.mounted && me.fire('sort', {
|
|
182
|
+
direction: value,
|
|
183
|
+
property : me.dataField
|
|
184
|
+
});
|
|
187
185
|
}
|
|
188
186
|
|
|
189
187
|
/**
|
|
@@ -243,9 +241,7 @@ class Button extends BaseButton {
|
|
|
243
241
|
*
|
|
244
242
|
*/
|
|
245
243
|
destroy(...args) {
|
|
246
|
-
|
|
247
|
-
this.filterField.destroy();
|
|
248
|
-
}
|
|
244
|
+
this.filterField?.destroy();
|
|
249
245
|
|
|
250
246
|
super.destroy(...args);
|
|
251
247
|
}
|
|
@@ -378,7 +374,7 @@ class Button extends BaseButton {
|
|
|
378
374
|
|
|
379
375
|
filters.push({
|
|
380
376
|
property: me.dataField,
|
|
381
|
-
operator
|
|
377
|
+
operator,
|
|
382
378
|
value : null,
|
|
383
379
|
...me.filterConfig
|
|
384
380
|
});
|
|
@@ -415,7 +411,7 @@ class Button extends BaseButton {
|
|
|
415
411
|
filters.push({
|
|
416
412
|
property: me.dataField,
|
|
417
413
|
operator: 'like',
|
|
418
|
-
value
|
|
414
|
+
value,
|
|
419
415
|
...me.filterConfig
|
|
420
416
|
});
|
|
421
417
|
|
|
@@ -87,7 +87,7 @@ class Toolbar extends BaseToolbar {
|
|
|
87
87
|
// todo: only add px if number
|
|
88
88
|
if (item.maxWidth) {style.maxWidth = item.maxWidth + 'px'}
|
|
89
89
|
if (item.minWidth) {style.minWidth = item.minWidth + 'px'}
|
|
90
|
-
if (item.width) {style.width = item.width
|
|
90
|
+
if (item.width) {style.width = item.width + 'px'}
|
|
91
91
|
|
|
92
92
|
if (item.dock) {
|
|
93
93
|
item.vdom.cls = ['neo-locked'];
|