neo.mjs 4.0.90 → 4.0.93

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.
@@ -118,7 +118,9 @@ if (programOpts.info) {
118
118
  'core.Base',
119
119
  'data.Model',
120
120
  'data.Store',
121
- 'model.Component'
121
+ 'model.Component',
122
+ 'tab.Container',
123
+ 'table.Container'
122
124
  ]
123
125
  });
124
126
  }
@@ -581,6 +583,19 @@ if (programOpts.info) {
581
583
  ` className: '${className}'`
582
584
  );
583
585
 
586
+ baseClass === 'table.Container' && addComma(classContent).push(
587
+ " /*",
588
+ " * @member {Object[]} columns",
589
+ " */",
590
+ " columns: [{",
591
+ " dataField: 'id',",
592
+ " text : 'Id'",
593
+ " }, {",
594
+ " dataField: 'name',",
595
+ " text : 'Name'",
596
+ " }]"
597
+ );
598
+
584
599
  baseClass === 'data.Model' && addComma(classContent).push(
585
600
  " /*",
586
601
  " * @member {Object[]} fields",
@@ -598,6 +613,27 @@ if (programOpts.info) {
598
613
  " items: []"
599
614
  );
600
615
 
616
+ baseClass === 'tab.Container' && addComma(classContent).push(
617
+ " /*",
618
+ " * @member {Object[]} items",
619
+ " */",
620
+ " items: [{",
621
+ " ntype: 'component',",
622
+ "",
623
+ " tabButtonConfig: {",
624
+ " iconCls: 'fa fa-home',",
625
+ " text : 'Tab 1'",
626
+ " }",
627
+ " }, {",
628
+ " ntype: 'component',",
629
+ "",
630
+ " tabButtonConfig: {",
631
+ " iconCls: 'fa fa-play-circle',",
632
+ " text : 'Tab 2'",
633
+ " }",
634
+ " }]",
635
+ );
636
+
601
637
  isSingleton && addComma(classContent).push(
602
638
  " /*",
603
639
  " * @member {Boolean} singleton=true",
@@ -642,6 +678,8 @@ if (programOpts.info) {
642
678
  }
643
679
 
644
680
  function guessBaseClass(className) {
681
+ className = className.toLowerCase();
682
+
645
683
  if (className.includes('.model.')) {
646
684
  return 'data.Model';
647
685
  }
@@ -650,14 +688,22 @@ if (programOpts.info) {
650
688
  return 'data.Store';
651
689
  }
652
690
 
653
- if (className.endsWith('Controller')) {
691
+ if (className.endsWith('controller')) {
654
692
  return 'controller.Component';
655
693
  }
656
694
 
657
- if (className.endsWith('Model')) {
695
+ if (className.endsWith('model')) {
658
696
  return 'model.Component';
659
697
  }
660
698
 
699
+ if (className.includes('table')) {
700
+ return 'table.Container';
701
+ }
702
+
703
+ if (className.includes('tab')) {
704
+ return 'tab.Container';
705
+ }
706
+
661
707
  return 'container.Base';
662
708
  }
663
709
  }
@@ -44,7 +44,40 @@ class MainContainer extends ConfigurationViewport {
44
44
  createExampleComponent() {
45
45
  return Neo.create(Carousel, {
46
46
  height: 500,
47
- width : 500
47
+ width : 500,
48
+ // will automatically change to the next extry every 5500 ms
49
+ // if not set or 0, this will show arrows to navigate
50
+ // cannot be changed after created
51
+ autoRun: 5500,
52
+ store: {
53
+ data: [{
54
+ "quote": "We love the German inspired dishes on the menu",
55
+ "publisher": "Trip Advisor",
56
+ "date": "Dezember 2020"
57
+ },{
58
+ "quote": "Everything about this place was excellent, from start to finish",
59
+ "publisher": "Trip Advisor",
60
+ "date": "Dezember 2021"
61
+ },{
62
+ "quote": "We had three courses and everything was great",
63
+ "publisher": "Trip Advisor",
64
+ "date": "September 2020"
65
+ },{
66
+ "quote": "Excellent Food, Wine and Service",
67
+ "publisher": "Best Food",
68
+ "date": "August 2020"
69
+ }]
70
+ },
71
+ // custom item cls
72
+ itemCls: 'example-carousel-item',
73
+ // each item will be created like the itemTpl structure
74
+ itemTpl: data => [{
75
+ cls: 'example-quote',
76
+ html: data.quote
77
+ }, {
78
+ cls: 'example-details',
79
+ html: `${data.publisher} - ${data.date}`
80
+ }]
48
81
  });
49
82
  }
50
83
  }
@@ -336,8 +336,8 @@ class MainContainer extends Viewport {
336
336
  construct(config) {
337
337
  super.construct(config);
338
338
 
339
- const me = this,
340
- url = 'https://corona.lmao.ninja/v3/covid-19/countries';
339
+ let me = this,
340
+ url = 'https://disease.sh/v3/covid-19/countries';
341
341
 
342
342
  me.gallery = Neo.create({
343
343
  module: CountryGallery,
@@ -411,8 +411,8 @@ class MainContainer extends Viewport {
411
411
  construct(config) {
412
412
  super.construct(config);
413
413
 
414
- const me = this,
415
- url = 'https://corona.lmao.ninja/v3/covid-19/countries';
414
+ let me = this,
415
+ url = 'https://disease.sh/v3/covid-19/countries';
416
416
 
417
417
  me.helix = Neo.create({
418
418
  module: CountryHelix,
@@ -34,14 +34,14 @@ class EditUserDialog extends Dialog {
34
34
  */
35
35
  items: [{
36
36
  module : TextField,
37
- bind : {value: data => `${data.user.firstname}`},
37
+ bind : {value: data => data.user.firstname},
38
38
  flex : 'none',
39
39
  labelText : 'Firstname:',
40
40
  labelWidth: 110,
41
41
  listeners : {change: 'onFirstnameTextFieldChange'}
42
42
  }, {
43
43
  module : TextField,
44
- bind : {value: data => `${data.user.lastname}`},
44
+ bind : {value: data => data.user.lastname},
45
45
  flex : 'none',
46
46
  labelText : 'Lastname:',
47
47
  labelWidth: 110,
@@ -1,6 +1,6 @@
1
1
  import ConfigurationViewport from '../ConfigurationViewport.mjs';
2
2
  import RangeField from '../../src/form/field/Range.mjs';
3
- import SiteMapContainer from '../../src/sitemap/Container.mjs';
3
+ import SiteMapComponent from '../../src/sitemap/Component.mjs';
4
4
 
5
5
  /**
6
6
  * @class Neo.examples.sitemap.MainContainer
@@ -36,11 +36,15 @@ class MainContainer extends ConfigurationViewport {
36
36
  }
37
37
 
38
38
  createExampleComponent() {
39
- return Neo.create(SiteMapContainer, {
39
+ return Neo.create(SiteMapComponent, {
40
40
  height: 600,
41
41
  width : 800,
42
42
 
43
- itemStore: {
43
+ myHandler(record) {
44
+ console.log('myHandler', record);
45
+ },
46
+
47
+ store: {
44
48
  data: [
45
49
  {id: 1, column: 0, name: 'Group 1', level: 0},
46
50
  {id: 2, column: 0, name: 'Item 1', level: 1, action: 'item1'},
@@ -48,7 +52,7 @@ class MainContainer extends ConfigurationViewport {
48
52
  {id: 4, column: 0, name: 'Item 3', level: 2, action: 'https://github.com/neomjs/neo', actionType: 'url'},
49
53
  {id: 5, column: 0, name: 'Item 4', level: 2, disabled: true},
50
54
  {id: 6, column: 1, name: 'Group 2', level: 0},
51
- {id: 7, column: 1, name: 'Item 1', level: 1},
55
+ {id: 7, column: 1, name: 'Item 1', level: 1, action: 'myHandler', actionType: 'handler'},
52
56
  {id: 8, column: 1, name: 'Item 2', level: 1, hidden: true},
53
57
  {id: 9, column: 1, name: 'Item 3', level: 1},
54
58
  {id: 10, column: 1, name: 'Item 4', level: 2}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neo.mjs",
3
- "version": "4.0.90",
3
+ "version": "4.0.93",
4
4
  "description": "The webworkers driven UI framework",
5
5
  "type": "module",
6
6
  "repository": {
@@ -40,24 +40,24 @@
40
40
  "homepage": "https://neomjs.github.io/pages/",
41
41
  "dependencies": {
42
42
  "@fortawesome/fontawesome-free": "^6.1.2",
43
- "@material/mwc-button": "^0.26.1",
44
- "@material/mwc-textfield": "^0.26.1",
43
+ "@material/mwc-button": "^0.27.0",
44
+ "@material/mwc-textfield": "^0.27.0",
45
45
  "autoprefixer": "^10.4.8",
46
46
  "chalk": "^5.0.1",
47
47
  "clean-webpack-plugin": "^4.0.0",
48
48
  "commander": "^9.4.0",
49
- "cssnano": "^5.1.12",
49
+ "cssnano": "^5.1.13",
50
50
  "envinfo": "^7.8.1",
51
51
  "fs-extra": "^10.1.0",
52
52
  "highlightjs-line-numbers.js": "^2.8.0",
53
53
  "inquirer": "^9.1.0",
54
54
  "neo-jsdoc": "^1.0.1",
55
55
  "neo-jsdoc-x": "^1.0.4",
56
- "postcss": "^8.4.14",
57
- "sass": "^1.54.3",
56
+ "postcss": "^8.4.16",
57
+ "sass": "^1.54.5",
58
58
  "webpack": "^5.74.0",
59
59
  "webpack-cli": "^4.10.0",
60
- "webpack-dev-server": "4.9.3",
60
+ "webpack-dev-server": "4.10.0",
61
61
  "webpack-hook-plugin": "^1.0.7",
62
62
  "webpack-node-externals": "^3.0.0"
63
63
  },
@@ -18,6 +18,10 @@
18
18
  display : flex;
19
19
  font-size : 0.625em;
20
20
  justify-content: center;
21
+
22
+ > div {
23
+ height: 1em;
24
+ }
21
25
  }
22
26
  }
23
27
 
@@ -29,4 +33,4 @@
29
33
  left : unset;
30
34
  right : 0;
31
35
  }
32
- }
36
+ }
@@ -1,5 +1,6 @@
1
1
  .neo-sitemap {
2
2
  border : 1px solid v(panel-border-color);
3
+ display: flex;
3
4
  padding: 30px 100px 60px;
4
5
 
5
6
  .neo-action {
@@ -9,7 +10,8 @@
9
10
  text-decoration: none;
10
11
  }
11
12
 
12
- .neo-action[href] {
13
+ .neo-action[href],
14
+ .neo-action-handler {
13
15
  &:hover {
14
16
  text-decoration: underline;
15
17
  }
@@ -33,6 +35,8 @@
33
35
  }
34
36
 
35
37
  .neo-sitemap-column {
38
+ flex: 1;
39
+
36
40
  &:not(:last-child) {
37
41
  border-right: 1px solid v(panel-border-color);
38
42
  margin-right: 25px;
@@ -42,14 +42,16 @@ class Canvas extends Component {
42
42
  afterSetMounted(value, oldValue) {
43
43
  super.afterSetMounted(value, oldValue);
44
44
 
45
- let me = this,
46
- id = me.getCanvasId(),
47
- worker = Neo.currentWorker;
45
+ let me = this,
46
+ id = me.getCanvasId(),
47
+ offscreen = me.offscreen,
48
+ worker = Neo.currentWorker;
48
49
 
49
- if (value && me.offscreen) {
50
+ if (value && offscreen) {
50
51
  worker.promiseMessage('main', {
51
- action: 'getOffscreenCanvas',
52
- nodeId: id
52
+ action : 'getOffscreenCanvas',
53
+ appName: me.appName,
54
+ nodeId : id
53
55
  }).then(data => {
54
56
  worker.promiseMessage('canvas', {
55
57
  action: 'registerCanvas',
@@ -59,6 +61,8 @@ class Canvas extends Component {
59
61
  me.offscreenRegistered = true;
60
62
  });
61
63
  });
64
+ } else if (offscreen) {
65
+ me.offscreenRegistered = false;
62
66
  }
63
67
  }
64
68
 
@@ -20,6 +20,11 @@ class Carousel extends Component {
20
20
  * @member {String[]} positionArray
21
21
  */
22
22
  positionArray = ['neo-carousel--translate-x-full', 'neo-carousel-translate-x-0', 'neo-carousel-translate-x-full']
23
+ /**
24
+ * keeps track of the data for the onClickEvent
25
+ * @type {null}
26
+ */
27
+ itemData = {}
23
28
 
24
29
  static getConfig() {return {
25
30
  /**
@@ -57,8 +62,14 @@ class Carousel extends Component {
57
62
  * but it is a string instead of surrounding "`"
58
63
  * @member {String|null} tpl=null
59
64
  * @example
60
- * record = {foo: ... , bar: ...}
61
- * "[{cls: 'css-foo-class', html: '${foo}'}, {html: '${baa}'}]"
65
+ * record = {foo: ... , bar: ...}
66
+ * data => [{
67
+ * cls: 'css-foo-class',
68
+ * html: data.foo
69
+ * },
70
+ * {
71
+ * html: data.baa
72
+ * }]"
62
73
  */
63
74
  itemTpl_: null,
64
75
  /**
@@ -91,14 +102,18 @@ class Carousel extends Component {
91
102
  let me = this,
92
103
  domListeners = me.domListeners;
93
104
 
94
- if(me.autoRun) return;
95
-
96
105
  domListeners.push({
97
106
  click: {
98
107
  fn : me.onCarouselBtnClick,
99
108
  delegate: '.neo-carousel-btn',
100
109
  scope : me
101
110
  }
111
+ }, {
112
+ click: {
113
+ fn : me.onClick,
114
+ delegate: '.neo-carousel-item',
115
+ scope : me
116
+ }
102
117
  });
103
118
 
104
119
  me.domListeners = domListeners;
@@ -146,25 +161,6 @@ class Carousel extends Component {
146
161
  value?.getCount() > 0 && me.onStoreLoad();
147
162
  }
148
163
 
149
- /**
150
- * Ensure the itemTpl is setup correctly to match a valid JSON
151
- * @param {String|null} value
152
- * @param {String|null} oldValue
153
- * @returns {String}
154
- * @protected
155
- */
156
- beforeSetItemTpl(value, oldValue) {
157
- if (value) {
158
- value = value.replaceAll('\'', '"');
159
-
160
- value = value.replace(/(\w+:)|(\w+ :)/g, function(matchedStr) {
161
- return `"${matchedStr.substring(0, matchedStr.length - 1)}":`;
162
- });
163
- }
164
-
165
- return value;
166
- }
167
-
168
164
  /**
169
165
  * Triggered before the store config gets changed.
170
166
  * @param {Neo.data.Store|Object|null} value
@@ -207,16 +203,18 @@ class Carousel extends Component {
207
203
  positionArray = me.positionArray,
208
204
  store = me.store,
209
205
  data = store.getAt(recordIndex),
210
- itemTpl = me.#formatTpl(me.itemTpl, data),
206
+ cn = me.itemTpl(data),
211
207
 
212
208
  newItem = {
213
209
  cls: [positionArray[positionIndex], 'neo-carousel-item'],
214
- cn : itemTpl,
210
+ cn,
215
211
  recordIndex
216
212
  };
217
213
 
218
214
  itemCls && newItem.cls.push(itemCls);
219
215
 
216
+ me.itemData[positionIndex] = data;
217
+
220
218
  return newItem;
221
219
  }
222
220
 
@@ -273,6 +271,48 @@ class Carousel extends Component {
273
271
  me.vdom = vdom;
274
272
  }
275
273
 
274
+ /**
275
+ * Check if the user clicked an item or the container
276
+ * @param data
277
+ */
278
+ onClick(data) {
279
+ let me = this,
280
+ item;
281
+
282
+ if (data.path[0].id === me.id) {
283
+ me.onContainerClick(data);
284
+ } else {
285
+ for (item of data.path) {
286
+ if (item.cls.includes(me.itemCls)) {
287
+ me.onItemClick(item, data);
288
+ break;
289
+ }
290
+ }
291
+ }
292
+ }
293
+
294
+ /**
295
+ * If the user wants to listen for the container click
296
+ * @param {Object} data
297
+ */
298
+ onContainerClick(data){}
299
+
300
+ /**
301
+ * @param {Object} node
302
+ * @param {Object} data
303
+ */
304
+ onItemClick(node, data) {
305
+ let me = this;
306
+
307
+ /**
308
+ * The itemClick event fires when a click occurs on a list item
309
+ * @event itemClick
310
+ * @param {String} id the record matching the list item
311
+ * @returns {Object}
312
+ */
313
+ me.fire('itemClick', me.itemData[me.itemIndex]);
314
+ }
315
+
276
316
  /**
277
317
  * As soon as the store is loaded we want to
278
318
  * - create the three items
@@ -292,12 +332,6 @@ class Carousel extends Component {
292
332
  #arrayRotate(arr, n) {
293
333
  return n ? [...arr.slice(n, arr.length), ...arr.slice(0, n)] : arr;
294
334
  }
295
-
296
- #formatTpl(tpl, record) {
297
- let resultStr = tpl.replace(/\$\{[^\}]+\}/g, (m) => record[m.slice(2, -1).trim()]);
298
-
299
- return JSON.parse(resultStr);
300
- }
301
335
  }
302
336
 
303
337
  Neo.applyClassConfig(Carousel);
@@ -36,9 +36,10 @@ class Container extends BaseContainer {
36
36
  * @returns {Neo.form.field.Base|null} fields
37
37
  */
38
38
  getField(name) {
39
- let fields = ComponentManager.getChildren(this);
39
+ let fields = ComponentManager.getChildren(this),
40
+ field;
40
41
 
41
- for (let field of fields) {
42
+ for (field of fields) {
42
43
  if (field instanceof BaseField) {
43
44
  if (field.id === name || field.name === name) {
44
45
  return field;
@@ -53,10 +54,9 @@ class Container extends BaseContainer {
53
54
  * @returns {Neo.form.field.Base[]} fields
54
55
  */
55
56
  getFields() {
56
- let children = ComponentManager.getChildren(this),
57
- fields = [];
57
+ let fields = [];
58
58
 
59
- children.forEach(item => {
59
+ ComponentManager.getChildren(this).forEach(item => {
60
60
  item instanceof BaseField && fields.push(item);
61
61
  });
62
62
 
@@ -67,10 +67,9 @@ class Container extends BaseContainer {
67
67
  * @returns {Object}
68
68
  */
69
69
  getSubmitValues() {
70
- let fields = this.getFields(),
71
- values = {};
70
+ let values = {};
72
71
 
73
- fields.forEach(item => {
72
+ this.getFields().forEach(item => {
74
73
  values[item.name || item.id] = item.getSubmitValue();
75
74
  });
76
75
 
@@ -81,10 +80,9 @@ class Container extends BaseContainer {
81
80
  * @returns {Object}
82
81
  */
83
82
  getValues() {
84
- let fields = this.getFields(),
85
- values = {};
83
+ let values = {};
86
84
 
87
- fields.forEach(item => {
85
+ this.getFields().forEach(item => {
88
86
  values[item.name || item.id] = item.value;
89
87
  });
90
88
 
@@ -115,11 +113,10 @@ class Container extends BaseContainer {
115
113
  * @param {Object} [values]
116
114
  */
117
115
  reset(values={}) {
118
- let fields = this.getFields(),
119
- keys = values ? Object.keys(values) : [],
116
+ let keys = values ? Object.keys(values) : [],
120
117
  index;
121
118
 
122
- fields.forEach(item => {
119
+ this.getFields().forEach(item => {
123
120
  index = keys.indexOf(item.name);
124
121
 
125
122
  if (index < 0) {
@@ -135,11 +132,10 @@ class Container extends BaseContainer {
135
132
  * @param {Object} values={}
136
133
  */
137
134
  setValues(values={}) {
138
- let fields = this.getFields(),
139
- keys = Object.keys(values),
135
+ let keys = Object.keys(values),
140
136
  index;
141
137
 
142
- fields.forEach(item => {
138
+ this.getFields().forEach(item => {
143
139
  index = keys.indexOf(item.name);
144
140
 
145
141
  if (index < 0) {
@@ -157,9 +153,7 @@ class Container extends BaseContainer {
157
153
  * This can be useful for create entity forms which show up "clean", when pressing a submit button.
158
154
  */
159
155
  validate() {
160
- let fields = this.getFields();
161
-
162
- fields.forEach(item => {
156
+ this.getFields().forEach(item => {
163
157
  item.validate?.(false);
164
158
  });
165
159
  }
@@ -1,12 +1,12 @@
1
- import Base from '../container/Base.mjs';
1
+ import Base from '../component/Base.mjs';
2
2
  import ClassSystemUtil from '../util/ClassSystem.mjs';
3
- import ItemStore from './store/Items.mjs';
3
+ import Store from './Store.mjs';
4
4
 
5
5
  /**
6
- * @class Neo.sitemap.Container
7
- * @extends Neo.container.Base
6
+ * @class Neo.sitemap.Component
7
+ * @extends Neo.component.Base
8
8
  */
9
- class Container extends Base {
9
+ class Component extends Base {
10
10
  static getStaticConfig() {return {
11
11
  /**
12
12
  * Valid values for itemHideMode
@@ -19,26 +19,19 @@ class Container extends Base {
19
19
 
20
20
  static getConfig() {return {
21
21
  /*
22
- * @member {String} className='Neo.sitemap.Container'
22
+ * @member {String} className='Neo.sitemap.Component'
23
23
  * @protected
24
24
  */
25
- className: 'Neo.sitemap.Container',
25
+ className: 'Neo.sitemap.Component',
26
26
  /*
27
27
  * @member {String} ntype='sitemap'
28
28
  * @protected
29
29
  */
30
30
  ntype: 'sitemap',
31
31
  /*
32
- * @member {String[} cls=['neo-sitemap','neo-container']
32
+ * @member {String[} cls=['neo-sitemap']
33
33
  */
34
- cls: ['neo-sitemap', 'neo-container'],
35
- /*
36
- * @member {Object} itemDefaults
37
- */
38
- itemDefaults: {
39
- ntype: 'component',
40
- cls : ['neo-sitemap-column', 'neo-container']
41
- },
34
+ cls: ['neo-sitemap'],
42
35
  /**
43
36
  * Valid values: removeDom, visibility
44
37
  * Defines if the component items should use css visibility:'hidden' or vdom:removeDom
@@ -46,13 +39,9 @@ class Container extends Base {
46
39
  */
47
40
  itemHideMode_: 'removeDom',
48
41
  /*
49
- * @member {Neo.sitemap.store.Items|null} itemStore_=null
50
- */
51
- itemStore_: null,
52
- /**
53
- * @member {Object} layout={ntype:'hbox',align:'stretch'}
42
+ * @member {Neo.sitemap.Store|null} store_=null
54
43
  */
55
- layout: {ntype: 'hbox', align: 'stretch'}
44
+ store_: null
56
45
  }}
57
46
 
58
47
  /**
@@ -64,28 +53,32 @@ class Container extends Base {
64
53
  let me = this,
65
54
  domListeners = me.domListeners;
66
55
 
67
- domListeners.push({click: me.onItemClick, delegate: '.neo-action', scope: me});
56
+ domListeners.push(
57
+ {click: me.onItemHandlerClick, delegate: '.neo-action-handler', scope: me},
58
+ {click: me.onItemClick, delegate: '.neo-action', scope: me}
59
+ );
68
60
 
69
61
  me.domListeners = domListeners;
70
62
  }
71
63
 
72
64
  /**
73
- * Triggered after the itemStore config got changed
74
- * @param {Neo.sitemap.store.Items|null} value
75
- * @param {Neo.sitemap.store.Items|null} oldValue
65
+ * Triggered after the store config got changed
66
+ * @param {Neo.sitemap.Store|null} value
67
+ * @param {Neo.sitemap.Store|null} oldValue
76
68
  * @protected
77
69
  */
78
- afterSetItemStore(value, oldValue) {
79
- let me = this;
80
-
81
- value?.on({
82
- filter : 'onItemStoreFilter',
83
- load : 'onItemStoreLoad',
84
- recordChange: 'onItemStoreRecordChange',
85
- scope : me
86
- });
87
-
88
- value?.getCount() > 0 && me.createColumns();
70
+ afterSetStore(value, oldValue) {
71
+ let listeners = {
72
+ filter : 'onStoreFilter',
73
+ load : 'onStoreLoad',
74
+ recordChange: 'onStoreRecordChange',
75
+ scope : this
76
+ };
77
+
78
+ oldValue?.un(listeners);
79
+ value ?.on(listeners);
80
+
81
+ value?.getCount() > 0 && this.createItems();
89
82
  }
90
83
 
91
84
  /**
@@ -99,32 +92,41 @@ class Container extends Base {
99
92
  }
100
93
 
101
94
  /**
102
- * Triggered before the itemStore config gets changed.
95
+ * Triggered before the store config gets changed.
103
96
  * @param {Object|Neo.data.Store} value
104
97
  * @param {Object|Neo.data.Store} oldValue
105
98
  * @returns {Neo.data.Store}
106
99
  * @protected
107
100
  */
108
- beforeSetItemStore(value, oldValue) {
101
+ beforeSetStore(value, oldValue) {
109
102
  oldValue?.destroy();
110
- return ClassSystemUtil.beforeSetInstance(value, ItemStore);
103
+ return ClassSystemUtil.beforeSetInstance(value, Store);
111
104
  }
112
105
 
113
106
  /**
114
107
  *
115
108
  */
116
- createColumns() {
109
+ createItems() {
117
110
  let me = this,
118
- records = me.itemStore.items,
111
+ records = me.store.items,
119
112
  columnIndex = -1,
120
- items = [],
113
+ vdom = me.vdom,
121
114
  action, column, item, record;
122
115
 
116
+ vdom.cn = [];
117
+
123
118
  for (record of records) {
124
119
  if (record.column !== columnIndex) {
125
120
  columnIndex++;
126
- column = {vdom: {cn: []}};
127
- items.push(column);
121
+
122
+ column = {
123
+ ...me.itemDefaults,
124
+ cls: ['neo-sitemap-column'],
125
+ cn : [],
126
+ id : `${me.id}__column-${columnIndex}`
127
+ };
128
+
129
+ vdom.cn.push(column);
128
130
  }
129
131
 
130
132
  action = record.action;
@@ -163,10 +165,10 @@ class Container extends Base {
163
165
  }
164
166
  }
165
167
 
166
- column.vdom.cn.push(item);
168
+ column.cn.push(item);
167
169
  }
168
170
 
169
- me.items = items;
171
+ me.vdom = vdom;
170
172
  }
171
173
 
172
174
  /**
@@ -181,7 +183,7 @@ class Container extends Base {
181
183
  * @param {String} vnodeId
182
184
  * @returns {String|Number} itemId
183
185
  */
184
- getItemRecordId(vnodeId) {
186
+ getRecordId(vnodeId) {
185
187
  let itemId = vnodeId.split('__')[1],
186
188
  model = this.store.model,
187
189
  keyField = model?.getField(model.keyProperty),
@@ -195,33 +197,43 @@ class Container extends Base {
195
197
  }
196
198
 
197
199
  /**
198
- * Override as needed
200
+ * Override as needed (e.g. unmounting an overlay)
199
201
  * @param {Object} data
200
202
  */
201
203
  onItemClick(data) {}
202
204
 
205
+ /**
206
+ * @param {Object} data
207
+ */
208
+ onItemHandlerClick(data) {
209
+ let me = this,
210
+ record = me.store.get(me.getRecordId(data.path[0].id));
211
+
212
+ me[record.action](record);
213
+ }
214
+
203
215
  /**
204
216
  *
205
217
  */
206
- onItemStoreFilter() {
207
- this.createColumns();
218
+ onStoreFilter() {
219
+ this.createItems();
208
220
  }
209
221
 
210
222
  /**
211
223
  *
212
224
  */
213
- onItemStoreLoad() {
214
- this.createColumns();
225
+ onStoreLoad() {
226
+ this.createItems();
215
227
  }
216
228
 
217
229
  /**
218
230
  *
219
231
  */
220
- onItemStoreRecordChange() {
221
- this.createColumns();
232
+ onStoreRecordChange() {
233
+ this.createItems();
222
234
  }
223
235
  }
224
236
 
225
- Neo.applyClassConfig(Container);
237
+ Neo.applyClassConfig(Component);
226
238
 
227
- export default Container;
239
+ export default Component;
@@ -1,16 +1,16 @@
1
- import Model from '../../data/Model.mjs';
1
+ import BaseModel from '../data/Model.mjs';
2
2
 
3
3
  /**
4
- * @class Neo.sitemap.model.Item
4
+ * @class Neo.sitemap.Model
5
5
  * @extends Neo.data.Model
6
6
  */
7
- class Item extends Model {
7
+ class Model extends BaseModel {
8
8
  static getConfig() {return {
9
9
  /*
10
- * @member {String} className='Neo.sitemap.model.Item'
10
+ * @member {String} className='Neo.sitemap.Model'
11
11
  * @protected
12
12
  */
13
- className: 'Neo.sitemap.model.Item',
13
+ className: 'Neo.sitemap.Model',
14
14
  /*
15
15
  * @member {Object[]} fields
16
16
  */
@@ -18,7 +18,7 @@ class Item extends Model {
18
18
  name: 'action',
19
19
  type: 'String'
20
20
  }, {
21
- name : 'actionType',
21
+ name : 'actionType', // handler, route, url
22
22
  defaultValue: 'route',
23
23
  type : 'String'
24
24
  }, {
@@ -46,6 +46,6 @@ class Item extends Model {
46
46
  }}
47
47
  }
48
48
 
49
- Neo.applyClassConfig(Item);
49
+ Neo.applyClassConfig(Model);
50
50
 
51
- export default Item;
51
+ export default Model;
@@ -0,0 +1,24 @@
1
+ import Model from './Model.mjs';
2
+ import BaseStore from '../data/Store.mjs';
3
+
4
+ /**
5
+ * @class Neo.sitemap.Store
6
+ * @extends Neo.data.Store
7
+ */
8
+ class Store extends BaseStore {
9
+ static getConfig() {return {
10
+ /*
11
+ * @member {String} className='Neo.sitemap.Store'
12
+ * @protected
13
+ */
14
+ className: 'Neo.sitemap.Store',
15
+ /*
16
+ * @member {Neo.data.Model} model=Model
17
+ */
18
+ model: Model
19
+ }}
20
+ }
21
+
22
+ Neo.applyClassConfig(Store);
23
+
24
+ export default Store;
@@ -1,24 +0,0 @@
1
- import ItemModel from '../model/Item.mjs';
2
- import Store from '../../data/Store.mjs';
3
-
4
- /**
5
- * @class Neo.sitemap.store.Items
6
- * @extends Neo.data.Store
7
- */
8
- class Items extends Store {
9
- static getConfig() {return {
10
- /*
11
- * @member {String} className='Neo.sitemap.store.Items'
12
- * @protected
13
- */
14
- className: 'Neo.sitemap.store.Items',
15
- /*
16
- * @member {Neo.data.Model} model=ItemModel
17
- */
18
- model: ItemModel
19
- }}
20
- }
21
-
22
- Neo.applyClassConfig(Items);
23
-
24
- export default Items;