neo.mjs 4.0.89 → 4.0.92

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.89",
3
+ "version": "4.0.92",
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.4",
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
  },
@@ -0,0 +1,3 @@
1
+ .neo-iframe {
2
+ border: none;
3
+ }
@@ -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;
@@ -163,9 +163,9 @@ class Base extends CoreBase {
163
163
  /**
164
164
  * Used for hide and show and defines if the component
165
165
  * should use css visibility:'hidden' or vdom:removeDom
166
- * @member {String} hideMode_='visibility'
166
+ * @member {String} hideMode_='removeDom'
167
167
  */
168
- hideMode_: 'visibility',
168
+ hideMode_: 'removeDom',
169
169
  /**
170
170
  * The top level innerHTML of the component
171
171
  * @member {String|null} html_=null
@@ -1121,10 +1121,9 @@ class Base extends CoreBase {
1121
1121
  * @param {Number} timeout
1122
1122
  */
1123
1123
  hide(timeout) {
1124
- let me = this,
1125
- doRemove = me.hideMode !== 'visibility';
1124
+ let me = this;
1126
1125
 
1127
- if (doRemove) {
1126
+ if (me.hideMode !== 'visibility') {
1128
1127
  let removeFn = function() {
1129
1128
  let vdom = me.vdom;
1130
1129
  vdom.removeDom = true;
@@ -1142,7 +1141,7 @@ class Base extends CoreBase {
1142
1141
  me.style = style;
1143
1142
  }
1144
1143
 
1145
- this._hidden = true;
1144
+ me._hidden = true;
1146
1145
  }
1147
1146
 
1148
1147
  /**
@@ -1505,10 +1504,9 @@ class Base extends CoreBase {
1505
1504
  * hideMode: 'visibility' uses css visibility.
1506
1505
  */
1507
1506
  show() {
1508
- let me = this,
1509
- doAdd = me.hideMode !== 'visibility';
1507
+ let me = this;
1510
1508
 
1511
- if (doAdd) {
1509
+ if (me.hideMode !== 'visibility') {
1512
1510
  let vdom = me.vdom;
1513
1511
  vdom.removeDom = false;
1514
1512
  me.vdom = vdom;
@@ -1518,7 +1516,7 @@ class Base extends CoreBase {
1518
1516
  me.style = style;
1519
1517
  }
1520
1518
 
1521
- this._hidden = false;
1519
+ me._hidden = false;
1522
1520
  }
1523
1521
 
1524
1522
  /**
@@ -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);
@@ -0,0 +1,42 @@
1
+ import Base from '../component/Base.mjs';
2
+
3
+ /**
4
+ * @class Neo.component.Iframe
5
+ * @extends Neo.component.Base
6
+ */
7
+ class Iframe extends Base {
8
+ static getConfig() {return {
9
+ /*
10
+ * @member {String} className='Neo.component.Iframe'
11
+ * @protected
12
+ */
13
+ className: 'Neo.component.Iframe',
14
+ /*
15
+ * @member {String[]} cls=['neo-iframe']
16
+ */
17
+ cls: ['neo-iframe'],
18
+ /*
19
+ * @member {String|null} src_=null
20
+ */
21
+ src_: null,
22
+ /*
23
+ * @member {Object} _vdom
24
+ */
25
+ _vdom:
26
+ {tag: 'iframe'}
27
+ }}
28
+
29
+ /**
30
+ * Triggered after the src config got changed
31
+ * @param {String|null} value
32
+ * @param {String|null} oldValue
33
+ * @protected
34
+ */
35
+ afterSetSrc(value, oldValue) {
36
+ this.changeVdomRootKey('src', value);
37
+ }
38
+ }
39
+
40
+ Neo.applyClassConfig(Iframe);
41
+
42
+ export default Iframe;
package/src/list/Base.mjs CHANGED
@@ -405,9 +405,10 @@ class Base extends Component {
405
405
  getItemRecordId(vnodeId) {
406
406
  let itemId = vnodeId.split('__')[1],
407
407
  model = this.store.model,
408
- keyField = model?.getField(model.keyProperty);
408
+ keyField = model?.getField(model.keyProperty),
409
+ keyType = keyField?.type.toLowerCase();
409
410
 
410
- if (keyField?.type.toLowerCase() === 'integer' || keyField?.type.toLowerCase() === 'number') {
411
+ if (keyType === 'integer' || keyType === 'number') {
411
412
  itemId = parseInt(itemId);
412
413
  }
413
414
 
@@ -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
  /**
@@ -178,33 +180,60 @@ class Container extends Base {
178
180
  }
179
181
 
180
182
  /**
181
- * Override as needed
183
+ * @param {String} vnodeId
184
+ * @returns {String|Number} itemId
185
+ */
186
+ getRecordId(vnodeId) {
187
+ let itemId = vnodeId.split('__')[1],
188
+ model = this.store.model,
189
+ keyField = model?.getField(model.keyProperty),
190
+ keyType = keyField?.type.toLowerCase();
191
+
192
+ if (keyType === 'integer' || keyType === 'number') {
193
+ itemId = parseInt(itemId);
194
+ }
195
+
196
+ return itemId;
197
+ }
198
+
199
+ /**
200
+ * Override as needed (e.g. unmounting an overlay)
182
201
  * @param {Object} data
183
202
  */
184
203
  onItemClick(data) {}
185
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
+
186
215
  /**
187
216
  *
188
217
  */
189
- onItemStoreFilter() {
190
- this.createColumns();
218
+ onStoreFilter() {
219
+ this.createItems();
191
220
  }
192
221
 
193
222
  /**
194
223
  *
195
224
  */
196
- onItemStoreLoad() {
197
- this.createColumns();
225
+ onStoreLoad() {
226
+ this.createItems();
198
227
  }
199
228
 
200
229
  /**
201
230
  *
202
231
  */
203
- onItemStoreRecordChange() {
204
- this.createColumns();
232
+ onStoreRecordChange() {
233
+ this.createItems();
205
234
  }
206
235
  }
207
236
 
208
- Neo.applyClassConfig(Container);
237
+ Neo.applyClassConfig(Component);
209
238
 
210
- 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;