neo.mjs 7.8.0 → 7.9.1

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.
Files changed (33) hide show
  1. package/apps/ServiceWorker.mjs +2 -2
  2. package/apps/portal/index.html +1 -1
  3. package/apps/portal/view/home/FooterContainer.mjs +1 -1
  4. package/apps/portal/view/learn/MainContainerController.mjs +1 -1
  5. package/examples/ServiceWorker.mjs +2 -2
  6. package/examples/dialog/DemoDialog.mjs +2 -1
  7. package/examples/dialog/MainContainer.mjs +16 -10
  8. package/examples/table/nestedRecordFields/EditUserDialog.mjs +137 -0
  9. package/examples/table/nestedRecordFields/MainContainer.mjs +113 -0
  10. package/examples/table/nestedRecordFields/MainContainerModel.mjs +61 -0
  11. package/examples/table/nestedRecordFields/MainModel.mjs +41 -0
  12. package/examples/table/nestedRecordFields/MainStore.mjs +54 -0
  13. package/examples/table/nestedRecordFields/app.mjs +6 -0
  14. package/examples/table/nestedRecordFields/index.html +11 -0
  15. package/examples/table/nestedRecordFields/neo-config.json +6 -0
  16. package/package.json +4 -4
  17. package/resources/data/deck/learnneo/pages/tutorials/Earthquakes.md +51 -49
  18. package/resources/scss/src/apps/portal/learn/PageContainer.scss +5 -0
  19. package/src/DefaultConfig.mjs +2 -2
  20. package/src/Neo.mjs +7 -12
  21. package/src/core/Base.mjs +0 -8
  22. package/src/core/IdGenerator.mjs +0 -9
  23. package/src/data/Model.mjs +0 -7
  24. package/src/data/RecordFactory.mjs +82 -61
  25. package/src/data/Store.mjs +7 -0
  26. package/src/dialog/Base.mjs +26 -2
  27. package/src/form/field/CheckBox.mjs +12 -7
  28. package/src/form/field/ComboBox.mjs +8 -7
  29. package/src/grid/View.mjs +2 -2
  30. package/src/list/Base.mjs +1 -1
  31. package/src/model/Component.mjs +10 -1
  32. package/src/table/View.mjs +31 -15
  33. package/src/table/header/Button.mjs +33 -18
@@ -346,6 +346,7 @@ class ComboBox extends Picker {
346
346
  role : 'listbox',
347
347
  selectionModel: {stayInList: false},
348
348
  store : me.store,
349
+ windowId : me.windowId,
349
350
  ...me.listConfig
350
351
  });
351
352
 
@@ -580,18 +581,18 @@ class ComboBox extends Picker {
580
581
  }
581
582
 
582
583
  /**
583
- * @param {Object} record
584
+ * @param {Object} data
584
585
  * @protected
585
586
  */
586
- onListItemNavigate(record) {
587
- let {activeIndex} = record;
587
+ onListItemNavigate(data) {
588
+ let {activeIndex} = data;
588
589
 
589
590
  if (activeIndex >= 0) {
590
591
  let me = this,
591
592
  {store} = me;
592
593
 
593
- me.activeRecord = store.getAt(activeIndex);
594
- me.activeRecordId = me.activeRecord[store.keyProperty || model.keyProperty];
594
+ me.activeRecord = data.record || store.getAt(activeIndex);
595
+ me.activeRecordId = me.activeRecord[store.getKeyProperty()];
595
596
 
596
597
  // Update typeahead hint (which updates DOM), or update DOM
597
598
  me.typeAhead ? me.updateTypeAheadValue(me.lastManualInput) : me.update()
@@ -737,7 +738,7 @@ class ComboBox extends Picker {
737
738
  if (match && inputHintEl) {
738
739
  inputHintEl.value = value + match[displayField].substr(value.length);
739
740
  me.activeRecord = match;
740
- me.activeRecordId = match[store.keyProperty || store.model.keyProperty]
741
+ me.activeRecordId = match[store.getKeyProperty()]
741
742
  }
742
743
  }
743
744
 
@@ -771,7 +772,7 @@ class ComboBox extends Picker {
771
772
  * The select event fires when a list item gets selected
772
773
  * @event select
773
774
  * @param {Object} record
774
- * @param {value} record[store.keyProperty]
775
+ * @param {value} record[store.getKeyProperty()]
775
776
  * @returns {Object}
776
777
  */
777
778
 
package/src/grid/View.mjs CHANGED
@@ -95,9 +95,9 @@ class View extends Component {
95
95
 
96
96
  for (; j < colCount; j++) {
97
97
  column = columns[j];
98
- rendererValue = record[column.field];
98
+ rendererValue = Neo.ns(column.field, false, record);
99
99
 
100
- if (rendererValue === undefined) {
100
+ if (rendererValue === null || rendererValue === undefined) {
101
101
  rendererValue = ''
102
102
  }
103
103
 
package/src/list/Base.mjs CHANGED
@@ -689,7 +689,7 @@ class Base extends Component {
689
689
  getItemRecordId(vnodeId) {
690
690
  let itemId = vnodeId.split('__')[1],
691
691
  {model} = this.store,
692
- keyField = model?.getField(model.keyProperty),
692
+ keyField = model?.getField(this.getKeyProperty()),
693
693
  keyType = keyField?.type?.toLowerCase();
694
694
 
695
695
  if (keyType === 'int' || keyType === 'integer') {
@@ -155,10 +155,19 @@ class Component extends Base {
155
155
  */
156
156
  beforeSetStores(value, oldValue) {
157
157
  if (value) {
158
- let controller = this.component.getController();
158
+ let me = this,
159
+ controller = me.getController();
159
160
 
160
161
  Object.entries(value).forEach(([key, storeValue]) => {
161
162
  controller?.parseConfig(storeValue);
163
+
164
+ // support mapping string based listeners into the model instance
165
+ Object.entries(storeValue.listeners || {}).forEach(([listenerKey,listener]) => {
166
+ if (Neo.isString(listener) && Neo.isFunction(me[listener])) {
167
+ storeValue.listeners[listenerKey] = me[listener].bind(me)
168
+ }
169
+ })
170
+
162
171
  value[key] = ClassSystemUtil.beforeSetInstance(storeValue)
163
172
  })
164
173
  }
@@ -1,4 +1,5 @@
1
1
  import Component from '../component/Base.mjs';
2
+ import NeoArray from '../util/Array.mjs';
2
3
  import VDomUtil from '../util/VDom.mjs';
3
4
 
4
5
  /**
@@ -35,6 +36,10 @@ class View extends Component {
35
36
  * @member {Object} recordVnodeMap={}
36
37
  */
37
38
  recordVnodeMap: {},
39
+ /**
40
+ * @member {String} selectedRecordField='annotations.selected'
41
+ */
42
+ selectedRecordField: 'annotations.selected',
38
43
  /**
39
44
  * @member {Neo.data.Store|null} store=null
40
45
  */
@@ -86,7 +91,7 @@ class View extends Component {
86
91
  cellCls = ['neo-table-cell'],
87
92
  colspan = record[me.colspanField],
88
93
  {dataField} = column,
89
- fieldValue = record[dataField],
94
+ fieldValue = Neo.ns(dataField, false, record),
90
95
  hasStore = tableContainer.store?.model, // todo: remove as soon as all tables use stores (examples table)
91
96
  {vdom} = me,
92
97
  cellConfig, rendererOutput;
@@ -189,6 +194,10 @@ class View extends Component {
189
194
 
190
195
  trCls = me.getTrClass(record, i);
191
196
 
197
+ if (selectedRows && Neo.ns(me.selectedRecordField, false, record)) {
198
+ NeoArray.add(selectedRows, id)
199
+ }
200
+
192
201
  if (selectedRows?.includes(id)) {
193
202
  trCls.push('neo-selected');
194
203
 
@@ -432,11 +441,12 @@ class View extends Component {
432
441
  * @param {Object} opts.record
433
442
  */
434
443
  onStoreRecordChange(opts) {
435
- let me = this,
436
- fieldNames = opts.fields.map(field => field.name),
437
- needsUpdate = false,
438
- tableContainer = me.parent,
439
- {vdom} = me,
444
+ let me = this,
445
+ fieldNames = opts.fields.map(field => field.name),
446
+ needsUpdate = false,
447
+ tableContainer = me.parent,
448
+ {selectionModel} = tableContainer,
449
+ {vdom} = me,
440
450
  cellId, cellNode, column, index, scope;
441
451
 
442
452
  if (fieldNames.includes(me.colspanField)) {
@@ -444,17 +454,23 @@ class View extends Component {
444
454
  me.createViewData(me.store.items)
445
455
  } else {
446
456
  opts.fields.forEach(field => {
447
- cellId = me.getCellId(opts.record, field.name);
448
- cellNode = VDomUtil.findVdomChild(vdom, cellId);
457
+ if (field.name === me.selectedRecordField) {
458
+ if (selectionModel.ntype === 'selection-table-rowmodel') {
459
+ selectionModel[!field.value && selectionModel.singleSelect ? 'deselect' : 'select'](me.getRowId(opts.record))
460
+ }
461
+ } else {
462
+ cellId = me.getCellId(opts.record, field.name);
463
+ cellNode = VDomUtil.findVdomChild(vdom, cellId);
449
464
 
450
- // the vdom might not exist yet => nothing to do in this case
451
- if (cellNode?.vdom) {
452
- column = me.getColumn(field.name);
453
- index = cellNode.index;
454
- needsUpdate = true;
455
- scope = column.rendererScope || tableContainer;
465
+ // the vdom might not exist yet => nothing to do in this case
466
+ if (cellNode?.vdom) {
467
+ column = me.getColumn(field.name);
468
+ index = cellNode.index;
469
+ needsUpdate = true;
470
+ scope = column.rendererScope || tableContainer;
456
471
 
457
- cellNode.parentNode.cn[index] = me.applyRendererOutput({cellId, column, record: opts.record, index, tableContainer})
472
+ cellNode.parentNode.cn[index] = me.applyRendererOutput({cellId, column, record: opts.record, index, tableContainer})
473
+ }
458
474
  }
459
475
  })
460
476
  }
@@ -1,6 +1,7 @@
1
- import BaseButton from '../../button/Base.mjs';
2
- import NeoArray from '../../util/Array.mjs';
3
- import TextField from '../../form/field/Text.mjs';
1
+ import BaseButton from '../../button/Base.mjs';
2
+ import NeoArray from '../../util/Array.mjs';
3
+ import TextField from '../../form/field/Text.mjs';
4
+ import {resolveCallback} from '../../util/Function.mjs';
4
5
 
5
6
  /**
6
7
  * @class Neo.table.header.Button
@@ -75,6 +76,10 @@ class Button extends BaseButton {
75
76
  * @protected
76
77
  */
77
78
  isSorted_: null,
79
+ /**
80
+ * @member {Function|String|null} renderer_='cellRenderer'
81
+ */
82
+ renderer_: 'cellRenderer',
78
83
  /**
79
84
  * Scope to execute the column renderer.
80
85
  * Defaults to the matching table.Container
@@ -261,7 +266,31 @@ class Button extends BaseButton {
261
266
  * @protected
262
267
  */
263
268
  beforeSetCellAlign(value, oldValue) {
264
- return this.beforeSetEnumValue(value, oldValue, 'cellAlign', 'cellAlignValues');
269
+ return this.beforeSetEnumValue(value, oldValue, 'cellAlign', 'cellAlignValues')
270
+ }
271
+
272
+ /**
273
+ * Triggered before the renderer config gets changed
274
+ * @param {Function|String|null} value
275
+ * @param {Function|String|null} oldValue
276
+ * @protected
277
+ */
278
+ beforeSetRenderer(value, oldValue) {
279
+ return resolveCallback(value, this).fn
280
+ }
281
+
282
+ /**
283
+ * @param {Object} data
284
+ * @param {Neo.button.Base} data.column
285
+ * @param {String} data.dataField
286
+ * @param {Number} data.index
287
+ * @param {Object} data.record
288
+ * @param {Neo.table.Container} data.tableContainer
289
+ * @param {Number|String} data.value
290
+ * @returns {*}
291
+ */
292
+ cellRenderer(data) {
293
+ return data.value
265
294
  }
266
295
 
267
296
  /**
@@ -461,20 +490,6 @@ class Button extends BaseButton {
461
490
  me.cls = cls;
462
491
  me._isSorted = null
463
492
  }
464
-
465
- /**
466
- * @param {Object} data
467
- * @param {Neo.button.Base} data.column
468
- * @param {String} data.dataField
469
- * @param {Number} data.index
470
- * @param {Object} data.record
471
- * @param {Neo.table.Container} data.tableContainer
472
- * @param {Number|String} data.value
473
- * @returns {*}
474
- */
475
- renderer(data) {
476
- return data.value
477
- }
478
493
  }
479
494
 
480
495
  export default Neo.setupClass(Button);