neo.mjs 4.3.10 → 4.3.12

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/README.md CHANGED
@@ -12,7 +12,7 @@
12
12
  </p>
13
13
 
14
14
  # Welcome to neo.mjs!
15
- neo.mjs enables you to create scalable & high performant Apps using more than just one CPU.
15
+ neo.mjs enables you to create scalable & high performant Apps using more than just one CPU core.
16
16
  No need to take care of a workers setup, and the cross channel communication on your own.
17
17
 
18
18
  <p align="center">
@@ -24,7 +24,11 @@ class ServiceWorker extends ServiceBase {
24
24
  * @member {Boolean} singleton=true
25
25
  * @protected
26
26
  */
27
- singleton: true
27
+ singleton: true,
28
+ /**
29
+ * @member {String} version='4.3.11'
30
+ */
31
+ version: '4.3.11'
28
32
  }}
29
33
  }
30
34
 
@@ -374,7 +374,7 @@
374
374
  "publisher" : "ITNEXT",
375
375
  "selectedInto": [],
376
376
  "type" : "Blog Post",
377
- "url" : "https://tobiasuhlig.medium.com/enhance-your-frontend-state-management-with-view-models-7bf49e1a0991?source=friends_link&sk=ac04c44c7cd7af4c34068a87b1207c7e"
377
+ "url" : "https://itnext.io/enhance-your-frontend-state-management-with-view-models-7bf49e1a0991?source=friends_link&sk=ac04c44c7cd7af4c34068a87b1207c7e"
378
378
  },
379
379
  {
380
380
  "author" : "Tobias Uhlig",
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env node
2
+
3
+ import chalk from 'chalk';
4
+ import envinfo from 'envinfo';
5
+ import fs from 'fs-extra';
6
+ import os from 'os';
7
+ import path from 'path';
8
+
9
+ const
10
+ __dirname = path.resolve(),
11
+ cwd = process.cwd(),
12
+ requireJson = path => JSON.parse(fs.readFileSync((path))),
13
+ packageJson = requireJson(path.join(__dirname, 'package.json')),
14
+ insideNeo = packageJson.name === 'neo.mjs',
15
+ neoPath = insideNeo ? './' : './node_modules/neo.mjs/',
16
+ programName = `${packageJson.name} inject-package-version`;
17
+
18
+ let startDate = new Date(),
19
+ configPath = path.join(__dirname, 'src/DefaultConfig.mjs'),
20
+ contentArray = fs.readFileSync(configPath).toString().split(os.EOL),
21
+ i = 0,
22
+ len = contentArray.length,
23
+ serviceWorkerFolders = ['apps'],
24
+ versionString = `'${packageJson.version}'`,
25
+ serviceContentArray, serviceWorkerPath
26
+
27
+ if (!insideNeo) {
28
+ // todo
29
+ } else {
30
+ serviceWorkerFolders.push('examples');
31
+ }
32
+
33
+ for (; i < len; i++) {
34
+ if (contentArray[i].includes('version:')) {
35
+ // we want to update the comment inside the DefaultConfig.mjs as well
36
+ contentArray[i - 5] = contentArray[i - 5].replace(/'\d.+'/, versionString);
37
+ contentArray[i] = contentArray[i] .replace(/'\d.+'/, versionString);
38
+ break;
39
+ }
40
+ }
41
+
42
+ fs.writeFileSync(configPath, contentArray.join(os.EOL));
43
+
44
+ serviceWorkerFolders.forEach(folder => {
45
+ serviceWorkerPath = path.join(__dirname, folder, 'ServiceWorker.mjs');
46
+ serviceContentArray = fs.readFileSync(serviceWorkerPath).toString().split(os.EOL);
47
+
48
+ i = 0;
49
+ len = serviceContentArray.length;
50
+
51
+ for (; i < len; i++) {
52
+ if (serviceContentArray[i].includes('version:')) {
53
+ // we want to update the comment inside ServiceWorker.mjs as well
54
+ serviceContentArray[i - 2] = serviceContentArray[i - 2].replace(/'\d.+'/, versionString);
55
+ serviceContentArray[i] = serviceContentArray[i] .replace(/'\d.+'/, versionString);
56
+ break;
57
+ }
58
+ }
59
+
60
+ fs.writeFileSync(serviceWorkerPath, serviceContentArray.join(os.EOL));
61
+ });
62
+
63
+ const processTime = (Math.round((new Date - startDate) * 100) / 100000).toFixed(2);
64
+ console.log(`\nTotal time for ${programName}: ${processTime}s`);
65
+
66
+ process.exit(0);
@@ -24,7 +24,11 @@ class ServiceWorker extends ServiceBase {
24
24
  * @member {Boolean} singleton=true
25
25
  * @protected
26
26
  */
27
- singleton: true
27
+ singleton: true,
28
+ /**
29
+ * @member {String} version='4.3.11'
30
+ */
31
+ version: '4.3.11'
28
32
  }}
29
33
  }
30
34
 
@@ -31,43 +31,6 @@ class CountryGallery extends Gallery {
31
31
  * @member {Number} itemHeight=240
32
32
  */
33
33
  itemHeight: 280,
34
- /**
35
- * @member {Object} itemTpl_
36
- */
37
- itemTpl:
38
- {cls: ['neo-gallery-item', 'image-wrap', 'view', 'neo-transition-1000'], tabIndex: '-1', cn: [
39
- {cls: ['neo-item-wrapper'], style: {}, cn: [
40
- {tag: 'div', cls: ['neo-country-gallery-item'], style: {}, cn: [
41
- {cls: ['neo-item-header'], cn: [
42
- {tag: 'img', cls: ['neo-flag']},
43
- {}
44
- ]},
45
- {tag: 'table', cls: ['neo-content-table'], cn: [
46
- {tag: 'tr', cn: [
47
- {tag: 'td', html: 'Cases'},
48
- {tag: 'td', cls: ['neo-align-right']},
49
- {tag: 'td', style: {width: '100%'}},
50
- {tag: 'td', html: 'Cases today'},
51
- {tag: 'td', cls: ['neo-align-right']}
52
- ]},
53
- {tag: 'tr', cn: [
54
- {tag: 'td', html: 'Deaths'},
55
- {tag: 'td', cls: ['neo-align-right', 'neo-content-deaths']},
56
- {tag: 'td', style: {width: '100%'}},
57
- {tag: 'td', html: 'Deaths today'},
58
- {tag: 'td', cls: ['neo-align-right', 'neo-content-deaths']}
59
- ]},
60
- {tag: 'tr', cn: [
61
- {tag: 'td', html: 'Recovered'},
62
- {tag: 'td', cls: ['neo-align-right', 'neo-content-recovered']},
63
- {tag: 'td', style: {width: '100%'}},
64
- {tag: 'td', html: 'Critical'},
65
- {tag: 'td', cls: ['neo-align-right', 'neo-content-critical']}
66
- ]}
67
- ]}
68
- ]}
69
- ]}
70
- ]},
71
34
  /**
72
35
  * The item width of the gallery
73
36
  * @member {Number} itemWidth=320
@@ -97,29 +60,43 @@ class CountryGallery extends Gallery {
97
60
  * @returns {Object} vdomItem
98
61
  */
99
62
  createItem(vdomItem, record, index) {
100
- let me = this,
101
- firstChild = vdomItem.cn[0].cn[0],
102
- table = firstChild.cn[1];
103
-
104
- vdomItem.id = me.getItemVnodeId(record[me.keyProperty]);
105
-
106
- vdomItem.cn[0].style.height = me.itemHeight + 'px';
63
+ let me = this,
64
+ cls = ['neo-gallery-item', 'image-wrap', 'view', 'neo-transition-1000'],
65
+ style = {height: (me.itemHeight - 70) + 'px', width: me.itemWidth + 'px'};
107
66
 
108
- firstChild.style.height = (me.itemHeight - 70) + 'px';
109
- firstChild.style.width = me.itemWidth + 'px';
110
-
111
- firstChild.cn[0].cn[0].src = me.getCountryFlagUrl(record.country);
112
- firstChild.cn[0].cn[1].html = record.country;
113
-
114
- table.cn[0].cn[1].html = record.cases;
115
- table.cn[1].cn[1].html = record.deaths;
116
- table.cn[2].cn[1].html = record.recovered;
117
-
118
- table.cn[0].cn[4].html = record.todayCases;
119
- table.cn[1].cn[4].html = record.todayDeaths;
120
- table.cn[2].cn[4].html = record.critical;
121
-
122
- return vdomItem;
67
+ return {cls, id: me.getItemVnodeId(record[me.keyProperty]), tabIndex: '-1', cn: [
68
+ {cls: ['neo-item-wrapper'], style: {height: me.itemHeight + 'px'}, cn: [
69
+ {tag: 'div', cls: ['neo-country-gallery-item'], style, cn: [
70
+ {cls: ['neo-item-header'], cn: [
71
+ {tag: 'img', cls: ['neo-flag'], src: me.getCountryFlagUrl(record.country)},
72
+ {html: record.country}
73
+ ]},
74
+ {tag: 'table', cls: ['neo-content-table'], cn: [
75
+ {tag: 'tr', cn: [
76
+ {tag: 'td', html: 'Cases'},
77
+ {tag: 'td', cls: ['neo-align-right'], html: record.cases},
78
+ {tag: 'td', style: {width: '100%'}},
79
+ {tag: 'td', html: 'Cases today'},
80
+ {tag: 'td', cls: ['neo-align-right'], html: record.todayCases}
81
+ ]},
82
+ {tag: 'tr', cn: [
83
+ {tag: 'td', html: 'Deaths'},
84
+ {tag: 'td', cls: ['neo-align-right', 'neo-content-deaths'], html: record.deaths},
85
+ {tag: 'td', style: {width: '100%'}},
86
+ {tag: 'td', html: 'Deaths today'},
87
+ {tag: 'td', cls: ['neo-align-right', 'neo-content-deaths'], html: record.todayDeaths}
88
+ ]},
89
+ {tag: 'tr', cn: [
90
+ {tag: 'td', html: 'Recovered'},
91
+ {tag: 'td', cls: ['neo-align-right', 'neo-content-recovered'], html: record.recovered},
92
+ {tag: 'td', style: {width: '100%'}},
93
+ {tag: 'td', html: 'Critical'},
94
+ {tag: 'td', cls: ['neo-align-right', 'neo-content-critical'], html: record.critical}
95
+ ]}
96
+ ]}
97
+ ]}
98
+ ]}
99
+ ]};
123
100
  }
124
101
 
125
102
  /**
@@ -121,7 +121,7 @@ class MainContainer extends ConfigurationViewport {
121
121
  labelText : 'Label',
122
122
  labelWidth : 70,
123
123
  value : DateUtil.convertToyyyymmdd(new Date()),
124
- width : 250
124
+ width : 270
125
125
  });
126
126
  }
127
127
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neo.mjs",
3
- "version": "4.3.10",
3
+ "version": "4.3.12",
4
4
  "description": "The webworkers driven UI framework",
5
5
  "type": "module",
6
6
  "repository": {
@@ -20,6 +20,7 @@
20
20
  "create-app": "node ./buildScripts/createApp.mjs",
21
21
  "create-class": "node ./buildScripts/createClass.mjs",
22
22
  "generate-docs-json": "node ./buildScripts/docs/jsdocx.mjs",
23
+ "inject-package-version": "node ./buildScripts/injectPackageVersion.mjs",
23
24
  "server-start": "webpack serve -c ./buildScripts/webpack/webpack.server.config.mjs --open",
24
25
  "test": "echo \"Error: no test specified\" && exit 1",
25
26
  "watch-themes": "node ./buildScripts/watchThemes.mjs"
@@ -43,19 +44,19 @@
43
44
  "@fortawesome/fontawesome-free": "^6.2.0",
44
45
  "@material/mwc-button": "^0.27.0",
45
46
  "@material/mwc-textfield": "^0.27.0",
46
- "autoprefixer": "^10.4.12",
47
- "chalk": "^5.1.0",
47
+ "autoprefixer": "^10.4.13",
48
+ "chalk": "^5.1.2",
48
49
  "clean-webpack-plugin": "^4.0.0",
49
50
  "commander": "^9.4.1",
50
- "cssnano": "^5.1.13",
51
+ "cssnano": "^5.1.14",
51
52
  "envinfo": "^7.8.1",
52
53
  "fs-extra": "^10.1.0",
53
54
  "highlightjs-line-numbers.js": "^2.8.0",
54
- "inquirer": "^9.1.3",
55
+ "inquirer": "^9.1.4",
55
56
  "neo-jsdoc": "^1.0.1",
56
57
  "neo-jsdoc-x": "^1.0.4",
57
- "postcss": "^8.4.17",
58
- "sass": "^1.55.0",
58
+ "postcss": "^8.4.18",
59
+ "sass": "^1.56.0",
59
60
  "webpack": "^5.74.0",
60
61
  "webpack-cli": "^4.10.0",
61
62
  "webpack-dev-server": "4.11.1",
@@ -1,5 +1,7 @@
1
1
  .neo-dragproxy.neo-tree-list {
2
2
  .neo-list {
3
+ overflow: hidden;
4
+
3
5
  .neo-list-item {
4
6
  margin-right: 0;
5
7
  }
@@ -10,4 +12,4 @@
10
12
  content: "\f07b" !important;
11
13
  }
12
14
  }
13
- }
15
+ }
@@ -226,7 +226,15 @@ const DefaultConfig = {
226
226
  * @name config.useVdomWorker
227
227
  * @type Boolean
228
228
  */
229
- useVdomWorker: true
229
+ useVdomWorker: true,
230
+ /**
231
+ * buildScripts/injectPackageVersion.mjs will update this value
232
+ * @default '4.3.11'
233
+ * @memberOf! module:Neo
234
+ * @name config.version
235
+ * @type String
236
+ */
237
+ version: '4.3.11'
230
238
  };
231
239
 
232
240
  Object.assign(DefaultConfig, {
@@ -143,14 +143,15 @@ class Base extends Component {
143
143
  * @protected
144
144
  */
145
145
  afterSetBadgePosition(value, oldValue) {
146
- let me = this,
147
- badgeEl = me.getBadgeNode(),
148
- cls = badgeEl.cls || [];
146
+ let me = this,
147
+ badgeNode = me.getBadgeNode(),
148
+ cls = badgeNode.cls || [];
149
149
 
150
150
  NeoArray.remove(cls, 'neo-' + oldValue);
151
151
  NeoArray.add(cls, 'neo-' + value);
152
152
 
153
- badgeEl.cls = cls;
153
+ badgeNode.cls = cls;
154
+
154
155
  me.update();
155
156
  }
156
157
 
@@ -392,8 +392,8 @@ class Base extends CoreBase {
392
392
  * @protected
393
393
  */
394
394
  afterSetCls(value, oldValue) {
395
- oldValue = oldValue ? oldValue : [];
396
- value = value ? value : [];
395
+ oldValue = oldValue || [];
396
+ value = value || [];
397
397
 
398
398
  let me = this,
399
399
  vdom = me.vdom,
@@ -695,9 +695,7 @@ class Base extends CoreBase {
695
695
  * @protected
696
696
  */
697
697
  afterSetVnode(value, oldValue) {
698
- if (oldValue !== undefined) {
699
- this.syncVnodeTree();
700
- }
698
+ oldValue !== undefined && this.syncVnodeTree();
701
699
  }
702
700
 
703
701
  /**
@@ -717,8 +715,8 @@ class Base extends CoreBase {
717
715
  * @protected
718
716
  */
719
717
  afterSetWrapperCls(value, oldValue) {
720
- oldValue = oldValue ? oldValue : [];
721
- value = value ? value : [];
718
+ oldValue = oldValue || [];
719
+ value = value || [];
722
720
 
723
721
  let me = this,
724
722
  vdom = me.vdom,
@@ -1551,8 +1549,7 @@ class Base extends CoreBase {
1551
1549
  * @returns {Promise<*>}
1552
1550
  */
1553
1551
  set(values={}, silent=false) {
1554
- let me = this,
1555
- vdom = me.vdom;
1552
+ let me = this;
1556
1553
 
1557
1554
  me.silentVdomUpdate = true;
1558
1555
 
@@ -1723,8 +1720,7 @@ class Base extends CoreBase {
1723
1720
  updateCls(cls, oldCls, id=this.id) {
1724
1721
  let me = this,
1725
1722
  vnode = me.vnode,
1726
- vnodeTarget = VNodeUtil.findChildVnode(me.vnode, {id})?.vnode,
1727
- opts;
1723
+ vnodeTarget = VNodeUtil.findChildVnode(me.vnode, {id})?.vnode;
1728
1724
 
1729
1725
  if (!Neo.isEqual(cls, oldCls)) {
1730
1726
  if (vnodeTarget) {
@@ -1732,25 +1728,12 @@ class Base extends CoreBase {
1732
1728
  me.vnode = vnode;
1733
1729
  }
1734
1730
 
1735
- opts = {
1736
- action: 'updateDom',
1737
- deltas: [{
1738
- id,
1739
- cls: {
1740
- add : NeoArray.difference(cls, oldCls),
1741
- remove: NeoArray.difference(oldCls, cls)
1742
- }
1743
- }]
1744
- };
1745
-
1746
- if (Neo.currentWorker.isSharedWorker) {
1747
- opts.appName = me.appName;
1748
- }
1749
-
1750
- Neo.currentWorker.promiseMessage('main', opts).then(() => {
1751
- //console.log(me.vnode);
1752
- }).catch(err => {
1753
- console.log('Error attempting to update Component cls', err, me);
1731
+ Neo.applyDeltas(me.appName, {
1732
+ id,
1733
+ cls: {
1734
+ add : NeoArray.difference(cls, oldCls),
1735
+ remove: NeoArray.difference(oldCls, cls)
1736
+ }
1754
1737
  });
1755
1738
  }
1756
1739
  }
@@ -68,6 +68,10 @@ class Panel extends Container {
68
68
  * @returns {Object}
69
69
  */
70
70
  static createHeaderConfig(header) {
71
+ if (Neo.typeOf(header) === 'NeoInstance') {
72
+ return header;
73
+ }
74
+
71
75
  let config = {
72
76
  ntype: 'toolbar',
73
77
  cls : ['neo-panel-header-toolbar', 'neo-toolbar'],
@@ -1,5 +1,6 @@
1
1
  import Panel from '../container/Panel.mjs';
2
2
  import NeoArray from '../util/Array.mjs';
3
+ import Toolbar from './header/Toolbar.mjs';
3
4
  import VDomUtil from '../util/VDom.mjs';
4
5
 
5
6
  let DragZone;
@@ -12,11 +13,11 @@ class Base extends Panel {
12
13
  static getStaticConfig() {return {
13
14
  /**
14
15
  * Valid values for closeAction
15
- * @member {String[]} closeActions=['close', 'hide']
16
+ * @member {String[]} closeActions=['close','hide']
16
17
  * @protected
17
18
  * @static
18
19
  */
19
- iconPositions: ['top', 'right', 'bottom', 'left']
20
+ closeActions: ['close', 'hide']
20
21
  }}
21
22
 
22
23
  static getConfig() {return {
@@ -80,6 +81,10 @@ class Base extends Panel {
80
81
  * @member {Object} dragZoneConfig=null
81
82
  */
82
83
  dragZoneConfig: null,
84
+ /**
85
+ * @member {Object} headerConfig=null
86
+ */
87
+ headerConfig: null,
83
88
  /**
84
89
  * @member {Neo.toolbar.Base|null} headerToolbar=null
85
90
  */
@@ -112,7 +117,7 @@ class Base extends Panel {
112
117
  /**
113
118
  * @member {String} title='Dialog Title'
114
119
  */
115
- title_: 'Dialog Title',
120
+ title: 'Dialog Title',
116
121
  /**
117
122
  * @member {Object} _vdom
118
123
  */
@@ -233,14 +238,10 @@ class Base extends Panel {
233
238
  let me = this;
234
239
 
235
240
  if (value && me.animateTargetId) {
236
- Neo.currentWorker.promiseMessage('main', {
237
- action : 'updateDom',
238
- appName: me.appName,
239
- deltas : [{
240
- action: 'removeNode',
241
- id : me.getAnimateTargetId()
242
- }]
243
- });
241
+ Neo.applyDeltas(me.appName, {
242
+ action: 'removeNode',
243
+ id : me.getAnimateTargetId()
244
+ })
244
245
  }
245
246
  }
246
247
 
@@ -269,18 +270,6 @@ class Base extends Panel {
269
270
  });
270
271
  }
271
272
 
272
- /**
273
- * Triggered after the title config got changed
274
- * @param {String} value
275
- * @param {String} oldValue
276
- * @protected
277
- */
278
- afterSetTitle(value, oldValue) {
279
- if (oldValue) {
280
- this.down({flag: 'title-label'}).text = value;
281
- }
282
- }
283
-
284
273
  /**
285
274
  *
286
275
  */
@@ -404,26 +393,36 @@ class Base extends Panel {
404
393
 
405
394
  me.draggable && cls.push('neo-draggable');
406
395
 
407
- headers.unshift({
408
- cls : cls,
409
- dock : 'top',
410
- id : me.getHeaderToolbarId(),
411
- items: [{
412
- ntype: 'label',
413
- flag : 'title-label',
414
- text : me.title
415
- }, '->', {
416
- iconCls: 'far fa-window-maximize',
417
- handler: me.maximize.bind(me)
418
- }, {
419
- iconCls: 'far fa-window-close',
420
- handler: me.closeOrHide.bind(me)
421
- }]
396
+ me.headerToolbar = Neo.create({
397
+ module : Toolbar,
398
+ appName : me.appName,
399
+ cls,
400
+ dock : 'top',
401
+ id : me.getHeaderToolbarId(),
402
+ listeners: {headerAction: me.executeHeaderAction, scope: me},
403
+ title : me.title,
404
+ ...me.headerConfig
422
405
  });
423
406
 
407
+ headers.unshift(me.headerToolbar);
408
+
424
409
  me.headers = headers;
425
410
  }
426
411
 
412
+ /**
413
+ * {Object} data
414
+ */
415
+ executeHeaderAction(data) {
416
+ let me = this,
417
+
418
+ map = {
419
+ close : me.closeOrHide,
420
+ maximize: me.maximize
421
+ };
422
+
423
+ map[data.action].call(me, data);
424
+ }
425
+
427
426
  /**
428
427
  * Returns the id of the animation node
429
428
  * @returns {String}
@@ -490,7 +489,7 @@ class Base extends Panel {
490
489
  }
491
490
 
492
491
  /**
493
- * @param {Object} data
492
+ * @param {Object} [data]
494
493
  */
495
494
  maximize(data) {
496
495
  let me = this;
@@ -0,0 +1,105 @@
1
+ import Base from '../../toolbar/Base.mjs';
2
+
3
+ /**
4
+ * @class Neo.dialog.header.Toolbar
5
+ * @extends Neo.toolbar.Base
6
+ */
7
+ class Toolbar extends Base {
8
+ /**
9
+ * @member {Object} actionMap
10
+ */
11
+ actionMap = {
12
+ close : () => ({action: 'close', iconCls: 'far fa-window-close'}),
13
+ maximize: () => ({action: 'maximize', iconCls: 'far fa-window-maximize'})
14
+ }
15
+ /**
16
+ * You can define the action order and directly add custom actions.
17
+ * @example
18
+ * {
19
+ * actions: [
20
+ * 'close',
21
+ * 'maximize',
22
+ * {action: 'help', iconCls: 'far fa-circle-question'}
23
+ * ]
24
+ * }
25
+ *
26
+ * You can also extend the actionMap if needed.
27
+ * @member {Object[]|String[]|null} actions=['maximize','close']
28
+ */
29
+ actions = ['maximize', 'close']
30
+
31
+ static getConfig() {return {
32
+ /**
33
+ * @member {String} className='Neo.dialog.header.Toolbar'
34
+ * @protected
35
+ */
36
+ className: 'Neo.dialog.header.Toolbar',
37
+ /**
38
+ * @member {String|null} title=null
39
+ */
40
+ title_: null
41
+ }}
42
+
43
+ /**
44
+ * Triggered after the title config got changed
45
+ * @param {String} value
46
+ * @param {String} oldValue
47
+ * @protected
48
+ */
49
+ afterSetTitle(value, oldValue) {
50
+ oldValue && this.down({flag: 'title-label'})?.set({
51
+ removeDom: !value,
52
+ text : value
53
+ })
54
+ }
55
+
56
+ /**
57
+ *
58
+ */
59
+ createItems() {
60
+ let me = this,
61
+ handler = me.fireAction.bind(me),
62
+ items = me.items || [];
63
+
64
+ items.push({
65
+ ntype : 'label',
66
+ cls : ['neo-panel-header-text', 'neo-label'],
67
+ flag : 'title-label',
68
+ removeDom: !me.title,
69
+ text : me.title
70
+ });
71
+
72
+ if (me.actions) {
73
+ items.push('->');
74
+
75
+ me.actions.forEach(action => {
76
+ if (Neo.typeOf(action) !== 'Object') {
77
+ action = me.actionMap[action]()
78
+ }
79
+
80
+ items.push({handler, ...action})
81
+ })
82
+ }
83
+
84
+ me.items = items;
85
+
86
+ super.createItems();
87
+ }
88
+
89
+ /**
90
+ * @param {Object} data
91
+ */
92
+ fireAction(data) {
93
+ let component = data.component;
94
+
95
+ this.fire('headerAction', {
96
+ action: component.action,
97
+ component,
98
+ scope : this
99
+ })
100
+ }
101
+ }
102
+
103
+ Neo.applyClassConfig(Toolbar);
104
+
105
+ export default Toolbar;
@@ -243,9 +243,10 @@ class Text extends Base {
243
243
  * @protected
244
244
  */
245
245
  afterSetHideLabel(value, oldValue) {
246
- let me = this;
246
+ let me = this,
247
+ node = me.labelPosition === 'inline' ? me.getCenterBorderEl() : me.vdom.cn[0];
247
248
 
248
- me.vdom.cn[0].removeDom = value;
249
+ node.removeDom = value;
249
250
  me.updateInputWidth();
250
251
  }
251
252
 
@@ -309,16 +310,15 @@ class Text extends Base {
309
310
 
310
311
  vdom.cn[0] = me.getLabelEl(); // remove the wrapper
311
312
 
312
- vdom.cn[0].width = me.labelWidth;
313
+ vdom.cn[0].removeDom = me.hideLabel;
314
+ vdom.cn[0].width = me.labelWidth;
313
315
  me.updateInputWidth();
314
316
  } else if (value === 'inline') {
315
317
  centerBorderElCls = ['neo-center-border'];
316
318
  isEmpty = me.isEmpty();
317
319
  vdom = me.vdom;
318
320
 
319
- if (!isEmpty) {
320
- centerBorderElCls.push('neo-float-above');
321
- }
321
+ !isEmpty && centerBorderElCls.push('neo-float-above');
322
322
 
323
323
  delete vdom.cn[0].width;
324
324
 
@@ -327,8 +327,9 @@ class Text extends Base {
327
327
  cn : [{
328
328
  cls: ['neo-left-border']
329
329
  }, {
330
- cls: centerBorderElCls,
331
- cn : [vdom.cn[0]]
330
+ cls : centerBorderElCls,
331
+ cn : [vdom.cn[0]],
332
+ removeDom: me.hideLabel
332
333
  }, {
333
334
  cls: ['neo-right-border']
334
335
  }]
@@ -549,6 +550,8 @@ class Text extends Base {
549
550
  let me = this,
550
551
  cls = me.cls;
551
552
 
553
+ me.silentVdomUpdate = true;
554
+
552
555
  me.getInputEl().value = value;
553
556
 
554
557
  if (Neo.isEmpty(value) !== Neo.isEmpty(oldValue)) {
@@ -556,9 +559,12 @@ class Text extends Base {
556
559
  }
557
560
 
558
561
  NeoArray[me.originalConfig.value !== value ? 'add' : 'remove'](cls, 'neo-is-dirty');
562
+ me.cls = cls;
563
+
559
564
  me.validate(); // silent
560
565
 
561
- me.cls = cls;
566
+ me.silentVdomUpdate = false;
567
+
562
568
  me.update();
563
569
 
564
570
  super.afterSetValue(value, oldValue); // fires the change event
@@ -994,7 +1000,8 @@ class Text extends Base {
994
1000
  @param {Boolean} silent=false
995
1001
  */
996
1002
  updateError(value, silent=false) {
997
- let me = this,
1003
+ let me = this,
1004
+ cls = me.cls,
998
1005
  errorNode, isValid;
999
1006
 
1000
1007
  if (!(me.validBeforeMount && !me.mounted)) {
@@ -1002,7 +1009,8 @@ class Text extends Base {
1002
1009
 
1003
1010
  isValid = !value || value === '';
1004
1011
 
1005
- NeoArray[!isValid ? 'add' : 'remove'](me._cls, 'neo-invalid');
1012
+ NeoArray[!isValid ? 'add' : 'remove'](cls, 'neo-invalid');
1013
+ me.cls = cls; // todo: silent update
1006
1014
 
1007
1015
  errorNode = VDomUtil.findVdomChild(this.vdom, {cls: 'neo-textfield-error'}).vdom;
1008
1016
 
package/src/grid/View.mjs CHANGED
@@ -47,7 +47,7 @@ class View extends Component {
47
47
 
48
48
  for (; i < amountRows; i++) {
49
49
  record = inputData[i];
50
- id = me.getRowId(record, i);
50
+ id = me.getRowId(record, i);
51
51
 
52
52
  me.recordVnodeMap[id] = i;
53
53
 
@@ -109,7 +109,7 @@ class View extends Component {
109
109
 
110
110
  config = {
111
111
  id : me.getCellId(record, column.field),
112
- cls : rendererOutput.cls || ['neo-grid-cell'],
112
+ cls : cellCls,
113
113
  innerHTML: rendererOutput.html || '',
114
114
  style : cellStyle,
115
115
  tabIndex : '-1'
@@ -42,10 +42,19 @@ class ServiceWorker extends Base {
42
42
  serviceWorker.ready.then(() => {
43
43
  serviceWorker.onmessage = WorkerManager.onWorkerMessage.bind(WorkerManager);
44
44
 
45
+ if (!WorkerManager.getWorker('service')) {
46
+ /*
47
+ * navigator.serviceWorker.controller can be null in case we load a page for the first time
48
+ * or in case of a force refresh.
49
+ * See: https://www.w3.org/TR/service-workers/#navigator-service-worker-controller
50
+ */
51
+ WorkerManager.serviceWorker = registration.active;
52
+ }
53
+
45
54
  WorkerManager.sendMessage('service', {
46
55
  action: 'registerNeoConfig',
47
56
  data : config
48
- });
57
+ })
49
58
  });
50
59
  })
51
60
  }
@@ -70,7 +70,7 @@ class View extends Component {
70
70
 
71
71
  for (; i < amountRows; i++) {
72
72
  record = inputData[i];
73
- id = me.getRowId(record, i);
73
+ id = me.getRowId(record, i);
74
74
 
75
75
  me.recordVnodeMap[id] = i;
76
76
 
@@ -125,7 +125,7 @@ class View extends Component {
125
125
  };
126
126
  }
127
127
 
128
- // todo: remove the if part as soon as all tables use stores (examples table)
128
+ // todo: remove the else part as soon as all tables use stores (examples table)
129
129
  if (hasStore) {
130
130
  cellId = me.getCellId(record, column.dataField);
131
131
  } else {
@@ -135,7 +135,7 @@ class View extends Component {
135
135
  config = {
136
136
  tag : 'td',
137
137
  id : cellId,
138
- cls : rendererOutput.cls || ['neo-table-cell'],
138
+ cls : cellCls,
139
139
  innerHTML: rendererOutput.html || '',
140
140
  style : rendererOutput.style || {},
141
141
  tabIndex : '-1'
@@ -16,6 +16,15 @@ const NeoConfig = Neo.config,
16
16
  * @singleton
17
17
  */
18
18
  class Manager extends Base {
19
+ /**
20
+ * navigator.serviceWorker.controller can be null in case we load a page for the first time
21
+ * or in case of a force refresh.
22
+ * See: https://www.w3.org/TR/service-workers/#navigator-service-worker-controller
23
+ * Only in this case main.addon.ServiceWorker will store the active registration once ready here.
24
+ * @member {ServiceWorker|null} serviceWorker=null
25
+ */
26
+ serviceWorker = null
27
+
19
28
  static getConfig() {return {
20
29
  /**
21
30
  * @member {String} className='Neo.worker.Manager'
@@ -224,7 +233,7 @@ class Manager extends Base {
224
233
  */
225
234
  getWorker(name) {
226
235
  if (name === 'service') {
227
- return navigator.serviceWorker?.controller;
236
+ return navigator.serviceWorker?.controller || this.serviceWorker;
228
237
  }
229
238
 
230
239
  return name instanceof Worker ? name : this.workers[name].worker;
@@ -250,11 +250,17 @@ class ServiceBase extends Base {
250
250
  * @param {Object} msg
251
251
  * @param {ExtendableMessageEvent} event
252
252
  */
253
- onRegisterNeoConfig(msg, event) {
253
+ async onRegisterNeoConfig(msg, event) {
254
+ let me = this;
255
+
254
256
  Neo.config = Neo.config || {};
255
257
  Object.assign(Neo.config, msg.data);
256
258
 
257
- this.onConnect(event.source);
259
+ if (me.version !== Neo.config.version) {
260
+ await me.clearCaches()
261
+ }
262
+
263
+ me.onConnect(event.source);
258
264
  }
259
265
 
260
266
  /**