neo.mjs 8.0.0 → 8.1.0

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 (89) hide show
  1. package/apps/ServiceWorker.mjs +2 -2
  2. package/apps/portal/index.html +1 -1
  3. package/apps/portal/view/about/Container.mjs +0 -2
  4. package/apps/portal/view/about/MemberContainer.mjs +1 -20
  5. package/apps/portal/view/home/FooterContainer.mjs +1 -5
  6. package/examples/ConfigurationViewport.mjs +37 -32
  7. package/examples/ServiceWorker.mjs +2 -2
  8. package/examples/grid/cellEditing/MainContainer.mjs +175 -0
  9. package/examples/grid/cellEditing/MainContainerStateProvider.mjs +62 -0
  10. package/examples/grid/cellEditing/MainModel.mjs +30 -0
  11. package/examples/grid/cellEditing/MainStore.mjs +54 -0
  12. package/examples/grid/cellEditing/app.mjs +6 -0
  13. package/examples/grid/cellEditing/index.html +11 -0
  14. package/examples/grid/cellEditing/neo-config.json +6 -0
  15. package/examples/grid/container/MainContainer.mjs +7 -6
  16. package/examples/grid/covid/GridContainer.mjs +36 -36
  17. package/examples/grid/covid/Util.mjs +1 -1
  18. package/examples/grid/covid/neo-config.json +6 -5
  19. package/examples/table/cellEditing/MainContainer.mjs +174 -0
  20. package/examples/table/cellEditing/MainContainerStateProvider.mjs +62 -0
  21. package/examples/table/cellEditing/MainModel.mjs +30 -0
  22. package/examples/table/cellEditing/MainStore.mjs +54 -0
  23. package/examples/table/cellEditing/app.mjs +6 -0
  24. package/examples/table/cellEditing/index.html +11 -0
  25. package/examples/table/cellEditing/neo-config.json +6 -0
  26. package/examples/table/nestedRecordFields/MainContainerStateProvider.mjs +2 -1
  27. package/package.json +8 -8
  28. package/resources/scss/src/apps/portal/home/FooterContainer.scss +11 -2
  29. package/resources/scss/src/examples/grid/covid/GridContainer.scss +1 -1
  30. package/resources/scss/src/grid/Container.scss +13 -23
  31. package/resources/scss/src/grid/View.scss +45 -19
  32. package/resources/scss/src/grid/header/Button.scss +2 -4
  33. package/resources/scss/src/grid/header/Toolbar.scss +1 -2
  34. package/resources/scss/src/grid/plugin/CellEditing.scss +11 -0
  35. package/resources/scss/src/table/plugin/CellEditing.scss +11 -0
  36. package/src/DefaultConfig.mjs +2 -2
  37. package/src/Xhr.mjs +1 -1
  38. package/src/button/Base.mjs +2 -2
  39. package/src/collection/Base.mjs +5 -5
  40. package/src/component/Base.mjs +3 -3
  41. package/src/component/DateSelector.mjs +15 -0
  42. package/src/container/Base.mjs +2 -2
  43. package/src/controller/Base.mjs +3 -3
  44. package/src/dialog/Base.mjs +2 -2
  45. package/src/form/field/Base.mjs +3 -6
  46. package/src/form/field/CheckBox.mjs +2 -2
  47. package/src/form/field/ComboBox.mjs +18 -2
  48. package/src/form/field/Date.mjs +10 -4
  49. package/src/form/field/FileUpload.mjs +4 -4
  50. package/src/form/field/Hidden.mjs +2 -2
  51. package/src/form/field/Text.mjs +2 -2
  52. package/src/grid/Container.mjs +340 -43
  53. package/src/grid/View.mjs +599 -124
  54. package/src/grid/header/Button.mjs +331 -36
  55. package/src/grid/header/Toolbar.mjs +111 -4
  56. package/src/grid/plugin/CellEditing.mjs +30 -0
  57. package/src/layout/Base.mjs +3 -3
  58. package/src/list/Base.mjs +2 -2
  59. package/src/list/Circle.mjs +2 -2
  60. package/src/list/Color.mjs +2 -2
  61. package/src/list/Component.mjs +2 -2
  62. package/src/main/DomEvents.mjs +12 -3
  63. package/src/manager/Base.mjs +3 -3
  64. package/src/manager/Component.mjs +20 -11
  65. package/src/manager/DomEvent.mjs +5 -6
  66. package/src/manager/Focus.mjs +2 -2
  67. package/src/manager/Instance.mjs +4 -4
  68. package/src/manager/Task.mjs +2 -2
  69. package/src/manager/Toast.mjs +3 -3
  70. package/src/plugin/Base.mjs +18 -4
  71. package/src/plugin/Popover.mjs +3 -3
  72. package/src/plugin/PrefixField.mjs +2 -2
  73. package/src/plugin/Resizable.mjs +3 -7
  74. package/src/plugin/Responsive.mjs +2 -2
  75. package/src/selection/Model.mjs +17 -2
  76. package/src/selection/grid/CellColumnModel.mjs +1 -1
  77. package/src/selection/grid/CellColumnRowModel.mjs +1 -1
  78. package/src/selection/grid/CellModel.mjs +1 -1
  79. package/src/selection/grid/ColumnModel.mjs +2 -2
  80. package/src/table/Container.mjs +32 -3
  81. package/src/table/View.mjs +9 -4
  82. package/src/table/header/Toolbar.mjs +15 -1
  83. package/src/table/plugin/CellEditing.mjs +330 -0
  84. package/src/toolbar/Base.mjs +2 -2
  85. package/src/toolbar/Breadcrumb.mjs +1 -1
  86. package/src/tooltip/Base.mjs +2 -2
  87. package/src/util/KeyNavigation.mjs +14 -8
  88. package/src/worker/Base.mjs +3 -3
  89. package/src/grid/README.md +0 -3
@@ -1,11 +1,11 @@
1
- import Base from './Base.mjs';
1
+ import List from './Base.mjs';
2
2
 
3
3
  /**
4
4
  * A base class for lists which will use component based list items
5
5
  * @class Neo.list.Component
6
6
  * @extends Neo.list.Base
7
7
  */
8
- class Component extends Base {
8
+ class Component extends List {
9
9
  static config = {
10
10
  /**
11
11
  * @member {String} className='Neo.list.Component'
@@ -541,19 +541,28 @@ class DomEvents extends Base {
541
541
  * @param {KeyboardEvent} event
542
542
  */
543
543
  onKeyDown(event) {
544
- let {target} = event,
544
+ let me = this,
545
+ {target} = event,
545
546
  {tagName} = target,
546
547
  isInput = tagName === 'INPUT' || tagName === 'TEXTAREA';
547
548
 
548
549
  if (isInput && disabledInputKeys[target.id]?.includes(event.key)) {
549
550
  event.preventDefault()
550
551
  } else {
551
- this.sendMessageToApp(this.getKeyboardEventData(event));
552
+ me.sendMessageToApp(me.getKeyboardEventData(event));
553
+
554
+ if (
555
+ isInput &&
556
+ event.key === 'Tab' &&
557
+ me.testPathInclusion(event, ['neo-table-editor'], true)
558
+ ) {
559
+ event.preventDefault()
560
+ }
552
561
 
553
562
  if (
554
563
  !isInput &&
555
564
  ['ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowUp'].includes(event.key) &&
556
- this.testPathInclusion(event, ['neo-selection'], true)
565
+ me.testPathInclusion(event, ['neo-selection'], true)
557
566
  ) {
558
567
  event.preventDefault()
559
568
  }
@@ -1,11 +1,11 @@
1
- import CollectionBase from '../collection/Base.mjs';
1
+ import Collection from '../collection/Base.mjs';
2
2
 
3
3
  /**
4
4
  * Abstract base class for the other manager classes
5
5
  * @class Neo.manager.Base
6
6
  * @extends Neo.collection.Base
7
7
  */
8
- class Base extends CollectionBase{
8
+ class Manager extends Collection{
9
9
  static config = {
10
10
  /**
11
11
  * @member {String} className='Neo.manager.Base'
@@ -44,4 +44,4 @@ class Base extends CollectionBase{
44
44
  }
45
45
  }
46
46
 
47
- export default Neo.setupClass(Base);
47
+ export default Neo.setupClass(Manager);
@@ -1,4 +1,4 @@
1
- import Base from './Base.mjs';
1
+ import Manager from './Base.mjs';
2
2
  import VDomUtil from '../util/VDom.mjs';
3
3
  import VNodeUtil from '../util/VNode.mjs';
4
4
 
@@ -7,7 +7,7 @@ import VNodeUtil from '../util/VNode.mjs';
7
7
  * @extends Neo.manager.Base
8
8
  * @singleton
9
9
  */
10
- class Component extends Base {
10
+ class Component extends Manager {
11
11
  static config = {
12
12
  /**
13
13
  * @member {String} className='Neo.manager.Component'
@@ -177,6 +177,15 @@ class Component extends Base {
177
177
  return null
178
178
  }
179
179
 
180
+ /**
181
+ * Returns the object associated to the key, or null if there is none.
182
+ * @param key
183
+ * @returns {Neo.component.Base|null}
184
+ */
185
+ get(key) {
186
+ return this.wrapperNodes.get(key) || super.get(key)
187
+ }
188
+
180
189
  /**
181
190
  * Returns all child components which are recursively matched via their parentId
182
191
  * @param {Neo.component.Base} component
@@ -241,14 +250,14 @@ class Component extends Base {
241
250
  * @returns {Neo.component.Base|null|Neo.component.Base[]}
242
251
  *
243
252
  * @example
244
- // as String: ntype[comma separated propterties]
245
- Neo.first('toolbar button[text=Try me,icon=people]')
246
- // as Object: Add properties. ntype is optional
247
- Neo.first({
253
+ // as String: ntype[comma separated propterties]
254
+ Neo.first('toolbar button[text=Try me,icon=people]')
255
+ // as Object: Add properties. ntype is optional
256
+ Neo.first({
248
257
  icon: 'people'
249
258
  })
250
- // as Array: An Array of Objects. No Strings allowed
251
- Neo.first([{
259
+ // as Array: An Array of Objects. No Strings allowed
260
+ Neo.first([{
252
261
  ntype: 'toolbar'
253
262
  },{
254
263
  ntype: 'button', text: 'Try me', icon: 'people
@@ -258,7 +267,7 @@ class Component extends Base {
258
267
  * not stop after the first result.
259
268
  *
260
269
  * @example
261
- Neo.first('button', false) // => [Button, Button, Button]
270
+ Neo.first('button', false) // => [Button, Button, Button]
262
271
  */
263
272
  getFirst(componentDescription, returnFirstMatch = true) {
264
273
  let objects = [],
@@ -279,7 +288,7 @@ class Component extends Base {
279
288
 
280
289
  if (pairs) {
281
290
  const pairsRegex = /\[(.*?)\]/,
282
- pairsMatch = pairs.match(pairsRegex);
291
+ pairsMatch = pairs.match(pairsRegex);
283
292
 
284
293
  if (pairsMatch) {
285
294
  const pairs = pairsMatch[1].split(',');
@@ -345,7 +354,7 @@ class Component extends Base {
345
354
  len = path?.length || 0;
346
355
 
347
356
  for (; i < len; i++) {
348
- if (me.has(path[i])) {
357
+ if (me.has(path[i]) || me.wrapperNodes.get(path[i])) {
349
358
  componentPath.push(path[i])
350
359
  }
351
360
  }
@@ -202,7 +202,7 @@ class DomEvent extends Base {
202
202
  opts : config,
203
203
  priority : config.priority,
204
204
  scope : config.scope || scope,
205
- vnodeId : config.vnodeId || scope.id
205
+ vnodeId : config.vnodeId || scope.vdom.id
206
206
  };
207
207
  }
208
208
 
@@ -427,15 +427,15 @@ class DomEvent extends Base {
427
427
  if (!eventConfigKeys.includes(key)) {
428
428
  me.register({
429
429
  bubble : domListener.bubble || value.bubble,
430
- delegate : domListener.delegate || value.delegate || '#' + component.id,
430
+ delegate : domListener.delegate || value.delegate || '#' + component.vdom.id,
431
431
  eventName : key,
432
- id : component.id,
432
+ id : component.vdom.id, // honor wrapper nodes
433
433
  opts : value,
434
434
  originalConfig: domListener,
435
435
  ownerId : component.id,
436
436
  priority : domListener.priority || value.priority || 1,
437
437
  scope : domListener.scope || component,
438
- vnodeId : domListener.vnodeId || value.vnodeId || component.id
438
+ vnodeId : domListener.vnodeId || value.vnodeId || component.vdom.id
439
439
  })
440
440
  }
441
441
  })
@@ -468,8 +468,7 @@ class DomEvent extends Base {
468
468
  if (j != null) {
469
469
  targetId = path[j].id
470
470
  }
471
- }
472
- else {
471
+ } else {
473
472
  let delegationArray = delegate.split(' '),
474
473
  len = delegationArray.length,
475
474
  hasMatch, i, item, isId;
@@ -35,9 +35,9 @@ class Focus extends CoreBase {
35
35
  /**
36
36
  * The amount of time for a focusIn to occur after the last focusOut
37
37
  * to get combined into a focusmove event.
38
- * @member {Number} maxFocusInOutGap=10
38
+ * @member {Number} maxFocusInOutGap=50
39
39
  */
40
- maxFocusInOutGap: 10,
40
+ maxFocusInOutGap: 50,
41
41
  /**
42
42
  * The maximum amount of items stored inside the history array
43
43
  * @member {Number} maxHistoryLength=20
@@ -1,12 +1,12 @@
1
- import Base from './Base.mjs';
2
- import CoreBase from '../core/Base.mjs';
1
+ import Base from '../core/Base.mjs';
2
+ import Manager from './Base.mjs';
3
3
 
4
4
  /**
5
5
  * @class Neo.manager.Instance
6
6
  * @extends Neo.manager.Base
7
7
  * @singleton
8
8
  */
9
- class Instance extends Base {
9
+ class Instance extends Manager {
10
10
  static config = {
11
11
  /**
12
12
  * @member {String} className='Neo.manager.Instance'
@@ -28,7 +28,7 @@ class Instance extends Base {
28
28
 
29
29
  let me = this;
30
30
 
31
- CoreBase.instanceManagerAvailable = true;
31
+ Base.instanceManagerAvailable = true;
32
32
 
33
33
  me.consumeNeoIdMap();
34
34
 
@@ -1,4 +1,4 @@
1
- import Base from './Base.mjs';
1
+ import Manager from './Base.mjs';
2
2
 
3
3
  /**
4
4
  * @class Neo.manager.Task
@@ -32,7 +32,7 @@ import Base from './Base.mjs';
32
32
  * TaskManager.run(taskId);
33
33
  * TaskManager.get(taskId).repeat = 20;
34
34
  */
35
- class Task extends Base {
35
+ class Task extends Manager {
36
36
  static config = {
37
37
  /**
38
38
  * @member {String} className='Neo.manager.Task'
@@ -1,5 +1,5 @@
1
- import Base from './Base.mjs';
2
- import NeoArray from "../util/Array.mjs";
1
+ import Manager from './Base.mjs';
2
+ import NeoArray from '../util/Array.mjs';
3
3
 
4
4
  /**
5
5
  * See Neo.dialog.Toast for examples
@@ -7,7 +7,7 @@ import NeoArray from "../util/Array.mjs";
7
7
  * @extends Neo.manager.Base
8
8
  * @singleton
9
9
  */
10
- class Toast extends Base {
10
+ class Toast extends Manager {
11
11
  static config = {
12
12
  /**
13
13
  * @member {String} className='Neo.manager.Toast'
@@ -1,4 +1,4 @@
1
- import CoreBase from '../core/Base.mjs';
1
+ import Base from '../core/Base.mjs';
2
2
 
3
3
  /**
4
4
  * Abstract base class for plugin implementations.
@@ -7,7 +7,7 @@ import CoreBase from '../core/Base.mjs';
7
7
  * @class Neo.plugin.Base
8
8
  * @extends Neo.core.Base
9
9
  */
10
- class Base extends CoreBase {
10
+ class Plugin extends Base {
11
11
  static config = {
12
12
  /**
13
13
  * @member {String} className='Neo.plugin.Base'
@@ -24,7 +24,11 @@ class Base extends CoreBase {
24
24
  * @member {Neo.component.Base} owner=null
25
25
  * @protected
26
26
  */
27
- owner: null
27
+ owner: null,
28
+ /**
29
+ * @member {Number|null} windowId_=null
30
+ */
31
+ windowId_: null
28
32
  }
29
33
 
30
34
  /**
@@ -42,6 +46,16 @@ class Base extends CoreBase {
42
46
  }
43
47
  }
44
48
 
49
+ /**
50
+ * Triggered after the windowId config got changed
51
+ * @param {Number|null} value
52
+ * @param {Number|null} oldValue
53
+ * @protected
54
+ */
55
+ afterSetWindowId(value, oldValue) {
56
+ value && Neo.currentWorker.insertThemeFiles(value, this.__proto__)
57
+ }
58
+
45
59
  /**
46
60
  * Override this method to apply changes to the owner Component when it does get mounted
47
61
  */
@@ -50,4 +64,4 @@ class Base extends CoreBase {
50
64
  }
51
65
  }
52
66
 
53
- export default Neo.setupClass(Base);
67
+ export default Neo.setupClass(Plugin);
@@ -1,6 +1,6 @@
1
- import Base from './Base.mjs';
2
1
  import Container from '../container/Base.mjs'
3
- import NeoArray from "../util/Array.mjs";
2
+ import NeoArray from '../util/Array.mjs';
3
+ import Plugin from './Base.mjs';
4
4
 
5
5
  /**
6
6
  * Popover usable as tooltip
@@ -26,7 +26,7 @@ import NeoArray from "../util/Array.mjs";
26
26
  * }]
27
27
  * }]
28
28
  */
29
- class Popover extends Base {
29
+ class Popover extends Plugin {
30
30
  /**
31
31
  * Valid values for align
32
32
  * @member {String[]} alignValues=['bc-tc','tc-bc','tl-tr','tr-tl','cl-cr','cr-cl',null]
@@ -1,4 +1,4 @@
1
- import Base from './Base.mjs';
1
+ import Plugin from './Base.mjs';
2
2
 
3
3
  /**
4
4
  * @class Neo.plugin.PrefixField
@@ -17,7 +17,7 @@ import Base from './Base.mjs';
17
17
  * }]
18
18
  * }
19
19
  */
20
- class PrefixField extends Base {
20
+ class PrefixField extends Plugin {
21
21
  static config = {
22
22
  /**
23
23
  * @member {String} className='Neo.plugin.PrefixField'
@@ -1,12 +1,12 @@
1
- import Base from './Base.mjs';
2
1
  import DragZone from '../draggable/DragZone.mjs';
3
2
  import NeoArray from '../util/Array.mjs';
3
+ import Plugin from './Base.mjs';
4
4
 
5
5
  /**
6
6
  * @class Neo.plugin.Resizable
7
7
  * @extends Neo.plugin.Base
8
8
  */
9
- class Resizable extends Base {
9
+ class Resizable extends Plugin {
10
10
  /**
11
11
  * Resize cursor styles use north, south based names, so we need a mapping.
12
12
  * The order has to match the static positions array.
@@ -164,11 +164,7 @@ class Resizable extends Base {
164
164
  * @member {Object} targetNode=null
165
165
  * @protected
166
166
  */
167
- targetNode: null,
168
- /**
169
- * @member {Number|null} windowId_=null
170
- */
171
- windowId_: null
167
+ targetNode: null
172
168
  }
173
169
 
174
170
  /**
@@ -1,10 +1,10 @@
1
- import BasePlugin from './Base.mjs';
1
+ import Plugin from './Base.mjs';
2
2
 
3
3
  /**
4
4
  * @class Neo.plugin.Responsive
5
5
  * @extends Neo.plugin.Base
6
6
  */
7
- class Responsive extends BasePlugin {
7
+ class Responsive extends Plugin {
8
8
  static config = {
9
9
  /**
10
10
  * @member {String} className='Neo.plugin.Responsive'
@@ -110,6 +110,9 @@ class Model extends Base {
110
110
  NeoArray.remove(itemCollection, item);
111
111
 
112
112
  if (!silent) {
113
+ // We need a bigger depth, since grid.Container & table.Container use selection.Model as a top-level config.
114
+ // In case the config would get moved to grid.View & table.View, we would not need it.
115
+ view.updateDepth = -1;
113
116
  view.update();
114
117
 
115
118
  me.fire('selectionChange', {
@@ -136,6 +139,9 @@ class Model extends Base {
136
139
  });
137
140
 
138
141
  if (!silent && items.length > 0) {
142
+ // We need a bigger depth, since grid.Container & table.Container use selection.Model as a top-level config.
143
+ // In case the config would get moved to grid.View & table.View, we would not need it.
144
+ view.updateDepth = -1;
139
145
  view.update()
140
146
  }
141
147
 
@@ -191,7 +197,11 @@ class Model extends Base {
191
197
  }
192
198
 
193
199
  me.view = component;
194
- me.addDomListener()
200
+ me.addDomListener();
201
+
202
+ component.fire('selectionModelChange', {
203
+ value: me
204
+ })
195
205
  }
196
206
 
197
207
  /**
@@ -240,7 +250,12 @@ class Model extends Base {
240
250
 
241
251
  NeoArray.add(itemCollection, items);
242
252
 
243
- !view.silentSelect && view.update();
253
+ if (!view.silentSelect) {
254
+ // We need a bigger depth, since grid.Container & table.Container use selection.Model as a top-level config.
255
+ // In case the config would get moved to grid.View & table.View, we would not need it.
256
+ view.updateDepth = -1;
257
+ view.update()
258
+ }
244
259
 
245
260
  view.onSelect?.(items);
246
261
 
@@ -88,7 +88,7 @@ class CellColumnModel extends CellModel {
88
88
  idArray = ColumnModel.getCellId(data.path).split('__'),
89
89
  currentColumn = idArray[2],
90
90
  {view} = me,
91
- fields = view.columns.map(c => c.field),
91
+ fields = view.columns.map(c => c.dataField),
92
92
  newIndex = (fields.indexOf(currentColumn) + step) % fields.length,
93
93
  columnNodeIds, tbodyNode;
94
94
 
@@ -88,7 +88,7 @@ class CellColumnRowModel extends CellRowModel {
88
88
  idArray = ColumnModel.getCellId(data.path).split('__'),
89
89
  currentColumn = idArray[2],
90
90
  {view} = me,
91
- fields = view.columns.map(c => c.field),
91
+ fields = view.columns.map(c => c.dataField),
92
92
  newIndex = (fields.indexOf(currentColumn) + step) % fields.length,
93
93
  columnNodeIds, tbodyNode;
94
94
 
@@ -87,7 +87,7 @@ class CellModel extends BaseModel {
87
87
  {view} = me,
88
88
  idArray = data.path[0].id.split('__'),
89
89
  currentColumn = idArray[2],
90
- dataFields = view.columns.map(c => c.field),
90
+ dataFields = view.columns.map(c => c.dataField),
91
91
  newIndex = (dataFields.indexOf(currentColumn) + step) % dataFields.length,
92
92
  id;
93
93
 
@@ -72,7 +72,7 @@ class ColumnModel extends BaseModel {
72
72
  static getColumnIndex(cellId, columns) {
73
73
  let idArray = cellId.split('__'),
74
74
  currentColumn = idArray[2],
75
- dataFields = columns.map(c => c.field);
75
+ dataFields = columns.map(c => c.dataField);
76
76
 
77
77
  return dataFields.indexOf(currentColumn)
78
78
  }
@@ -117,7 +117,7 @@ class ColumnModel extends BaseModel {
117
117
  idArray = ColumnModel.getCellId(data.path).split('__'),
118
118
  currentColumn = idArray[2],
119
119
  {view} = me,
120
- fields = view.columns.map(c => c.field),
120
+ fields = view.columns.map(c => c.dataField),
121
121
  newIndex = (fields.indexOf(currentColumn) + step) % fields.length,
122
122
  columnNodeIds, id, tbodyNode;
123
123
 
@@ -27,6 +27,11 @@ class Container extends BaseContainer {
27
27
  * @member {String[]} baseCls=['neo-table-container']
28
28
  */
29
29
  baseCls: ['neo-table-container'],
30
+ /**
31
+ * true uses table.plugin.CellEditing
32
+ * @member {Boolean} cellEditing_=false
33
+ */
34
+ cellEditing_: false,
30
35
  /**
31
36
  * Default configs for each column
32
37
  * @member {Object} columnDefaults=null
@@ -150,6 +155,30 @@ class Container extends BaseContainer {
150
155
  me.createColumns(me.columns)
151
156
  }
152
157
 
158
+ /**
159
+ * Triggered after the cellEditing config got changed
160
+ * @param {Boolean} value
161
+ * @param {Boolean} oldValue
162
+ * @protected
163
+ */
164
+ afterSetCellEditing(value, oldValue) {
165
+ if (value) {
166
+ import('./plugin/CellEditing.mjs').then(module => {
167
+ let me = this,
168
+ {appName, windowId} = me,
169
+ plugins = me.plugins || [];
170
+
171
+ plugins.push({
172
+ module : module.default,
173
+ appName,
174
+ windowId
175
+ });
176
+
177
+ me.plugins = plugins
178
+ })
179
+ }
180
+ }
181
+
153
182
  /**
154
183
  * Triggered after the columns config got changed
155
184
  * @param {Object[]|null} value
@@ -350,9 +379,9 @@ class Container extends BaseContainer {
350
379
  * @returns {*}
351
380
  */
352
381
  createColumns(columns) {
353
- let me = this,
354
- columnDefaults = me.columnDefaults,
355
- sorters = me.store?.sorters,
382
+ let me = this,
383
+ {columnDefaults} = me,
384
+ sorters = me.store?.sorters,
356
385
  renderer;
357
386
 
358
387
  if (!columns || !columns.length) {
@@ -131,6 +131,7 @@ class View extends Component {
131
131
  }
132
132
  break
133
133
  }
134
+ case 'Date':
134
135
  case 'Number':
135
136
  case 'String': {
136
137
  rendererOutput = {
@@ -182,10 +183,14 @@ class View extends Component {
182
183
  /**
183
184
  * @param {Object} opts
184
185
  * @param {Object} opts.record
185
- * @param {Number} opts.rowIndex
186
+ * @param {Number} [opts.rowIndex]
186
187
  * @returns {Object}
187
188
  */
188
- createTableRow({record, rowIndex}) {
189
+ createRow({record, rowIndex}) {
190
+ if (!Neo.isNumber(rowIndex)) {
191
+ rowIndex = this.store.indexOf(record)
192
+ }
193
+
189
194
  let me = this,
190
195
  tableContainer = me.parent,
191
196
  colspan = record[me.colspanField],
@@ -276,7 +281,7 @@ class View extends Component {
276
281
  {selectedRows} = me;
277
282
 
278
283
  for (; i < amountRows; i++) {
279
- rows.push(me.createTableRow({record: inputData[i], rowIndex: i}))
284
+ rows.push(me.createRow({record: inputData[i], rowIndex: i}))
280
285
  }
281
286
 
282
287
  me.vdom.cn = rows;
@@ -472,7 +477,7 @@ class View extends Component {
472
477
 
473
478
  if (fieldNames.includes(me.colspanField)) {
474
479
  index = me.store.indexOf(record);
475
- me.vdom.cn[index] = me.createTableRow({record, rowIndex: index});
480
+ me.vdom.cn[index] = me.createRow({record, rowIndex: index});
476
481
  me.update()
477
482
  } else {
478
483
  fields.forEach(field => {
@@ -28,7 +28,7 @@ class Toolbar extends BaseToolbar {
28
28
  * @member {Object} itemDefaults={ntype : 'table-header-button'}
29
29
  */
30
30
  itemDefaults: {
31
- ntype : 'table-header-button'
31
+ ntype: 'table-header-button'
32
32
  },
33
33
  /**
34
34
  * @member {Boolean} showHeaderFilters_=false
@@ -143,6 +143,20 @@ class Toolbar extends BaseToolbar {
143
143
  me.update()
144
144
  }
145
145
 
146
+ /**
147
+ * @param {String} dataField
148
+ * @returns {Neo.button.Base|null}
149
+ */
150
+ getColumn(dataField) {
151
+ for (const item of this.items) {
152
+ if (item.dataField === dataField) {
153
+ return item
154
+ }
155
+ }
156
+
157
+ return null
158
+ }
159
+
146
160
  /**
147
161
  * @param {String} dock
148
162
  * @returns {String} layoutConfig