neo.mjs 6.15.10 → 6.16.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 (47) hide show
  1. package/apps/ServiceWorker.mjs +2 -2
  2. package/apps/colors/app.mjs +6 -0
  3. package/apps/colors/childapps/widget/app.mjs +7 -0
  4. package/apps/colors/childapps/widget/index.html +11 -0
  5. package/apps/colors/childapps/widget/neo-config.json +10 -0
  6. package/apps/colors/childapps/widget/view/Viewport.mjs +19 -0
  7. package/apps/colors/index.html +11 -0
  8. package/apps/colors/model/Color.mjs +59 -0
  9. package/apps/colors/neo-config.json +9 -0
  10. package/apps/colors/store/Colors.mjs +24 -0
  11. package/apps/colors/view/BarChartComponent.mjs +67 -0
  12. package/apps/colors/view/PieChartComponent.mjs +53 -0
  13. package/apps/colors/view/TableContainer.mjs +73 -0
  14. package/apps/colors/view/Viewport.mjs +83 -0
  15. package/apps/colors/view/ViewportController.mjs +268 -0
  16. package/apps/colors/view/ViewportModel.mjs +32 -0
  17. package/apps/covid/view/MainContainerController.mjs +1 -1
  18. package/apps/portal/view/home/MainContainer.mjs +2 -12
  19. package/apps/sharedcovid/view/MainContainerController.mjs +1 -1
  20. package/buildScripts/webpack/json/myApps.template.json +1 -0
  21. package/examples/ServiceWorker.mjs +2 -2
  22. package/examples/layout/card/MainContainer.mjs +148 -0
  23. package/examples/layout/card/app.mjs +6 -0
  24. package/examples/layout/card/index.html +11 -0
  25. package/examples/layout/card/neo-config.json +6 -0
  26. package/package.json +3 -3
  27. package/resources/data/deck/learnneo/pages/2023-10-14T19-25-08-153Z.md +2 -2
  28. package/resources/data/deck/learnneo/pages/Earthquakes.md +3 -3
  29. package/resources/data/deck/learnneo/pages/Setup.md +1 -1
  30. package/resources/data/deck/learnneo/pages/WhyNeo-Speed.md +1 -1
  31. package/resources/data/deck/learnneo/tree.json +1 -1
  32. package/resources/scss/src/apps/colors/BarChartComponent.scss +3 -0
  33. package/resources/scss/src/apps/colors/PieChartComponent.scss +3 -0
  34. package/resources/scss/src/apps/colors/TableContainer.scss +44 -0
  35. package/resources/scss/src/apps/colors/Viewport.scss +17 -0
  36. package/resources/scss/src/layout/Card.scss +17 -0
  37. package/src/DefaultConfig.mjs +2 -2
  38. package/src/component/Base.mjs +6 -0
  39. package/src/component/wrapper/AmChart.mjs +16 -16
  40. package/src/core/Base.mjs +2 -2
  41. package/src/data/RecordFactory.mjs +3 -0
  42. package/src/date/SelectorContainer.mjs +3 -0
  43. package/src/layout/Card.mjs +115 -24
  44. package/src/main/addon/AmCharts.mjs +3 -0
  45. package/src/model/Component.mjs +5 -1
  46. package/src/worker/App.mjs +2 -1
  47. package/test/components/files/form/field/ComboBox.mjs +4 -3
@@ -0,0 +1,44 @@
1
+ $base-color: #1c60a0;
2
+
3
+ .colors-table-container.neo-table-container {
4
+ width: 100%;
5
+
6
+ .color-1 {
7
+ background-color: lighten($base-color, 10%);
8
+ }
9
+
10
+ .color-2 {
11
+ background-color: lighten($base-color, 20%);
12
+ }
13
+
14
+ .color-3 {
15
+ background-color: lighten($base-color, 30%);
16
+ }
17
+
18
+ .color-4 {
19
+ background-color: lighten($base-color, 40%);
20
+ }
21
+
22
+ .color-5 {
23
+ background-color: lighten($base-color, 50%);
24
+ }
25
+
26
+ .neo-index-column {
27
+ max-width: 40px;
28
+ min-width: 40px;
29
+ width : 40px;
30
+ }
31
+
32
+ .neo-table-view {
33
+ .neo-table-row {
34
+ &:hover .neo-table-cell {
35
+ background-color: #d0aa72;
36
+ color : #2b2b2b;
37
+ }
38
+ }
39
+ }
40
+
41
+ td, th {
42
+ min-width: 10%;
43
+ }
44
+ }
@@ -0,0 +1,17 @@
1
+ .colors-viewport {
2
+ padding: 2em;
3
+
4
+ > * {
5
+ &:not(:first-child) {
6
+ margin-top: 2em;
7
+ }
8
+ }
9
+
10
+ .portal-header-toolbar {
11
+ .neo-button {
12
+ &:not(:first-child) {
13
+ margin-left: .5em;
14
+ }
15
+ }
16
+ }
17
+ }
@@ -9,4 +9,21 @@
9
9
  display: none !important;
10
10
  }
11
11
  }
12
+
13
+ .neo-animation-wrapper {
14
+ display : flex;
15
+ transition : transform 300ms cubic-bezier(0.47, 0, 0.745, 0.715);
16
+ will-change: transform;
17
+
18
+ > * {
19
+ flex: 1 0 auto;
20
+ }
21
+ }
22
+
23
+ .neo-relative {
24
+ height : 100%;
25
+ overflow: hidden;
26
+ position: relative;
27
+ width : 100%;
28
+ }
12
29
  }
@@ -260,12 +260,12 @@ const DefaultConfig = {
260
260
  useVdomWorker: true,
261
261
  /**
262
262
  * buildScripts/injectPackageVersion.mjs will update this value
263
- * @default '6.15.10'
263
+ * @default '6.15.11'
264
264
  * @memberOf! module:Neo
265
265
  * @name config.version
266
266
  * @type String
267
267
  */
268
- version: '6.15.10'
268
+ version: '6.15.11'
269
269
  };
270
270
 
271
271
  Object.assign(DefaultConfig, {
@@ -944,6 +944,12 @@ class Base extends CoreBase {
944
944
  if (controller && value) {
945
945
  controller.windowId = value
946
946
  }
947
+
948
+ // If a component gets moved into a different window, an update cycle might still be running.
949
+ // Since the update might no longer get mapped, we want to re-enable this instance for future updates.
950
+ if (oldValue) {
951
+ this.isVdomUpdating = false
952
+ }
947
953
  }
948
954
 
949
955
  /**
@@ -1,5 +1,4 @@
1
1
  import Component from '../Base.mjs';
2
- import Logger from '../../util/Logger.mjs';
3
2
 
4
3
  /**
5
4
  * Convenience class to render an amChart
@@ -69,15 +68,17 @@ class AmChart extends Component {
69
68
  * @protected
70
69
  */
71
70
  afterSetChartData(value, oldValue) {
72
- let me = this;
71
+ let me = this,
72
+ {appName, dataPath, id, windowId} = me;
73
73
 
74
74
  if (value) {
75
75
  Neo.main.addon.AmCharts.updateData({
76
- appName : me.appName,
77
- data : value,
78
- dataPath: me.dataPath,
79
- id : me.id
80
- });
76
+ appName,
77
+ data: value,
78
+ dataPath,
79
+ id,
80
+ windowId
81
+ })
81
82
  }
82
83
  }
83
84
 
@@ -88,25 +89,24 @@ class AmChart extends Component {
88
89
  * @protected
89
90
  */
90
91
  afterSetMounted(value, oldValue) {
91
- let me = this;
92
+ let me = this,
93
+ {appName, id, windowId} = me;
92
94
 
93
95
  if (value === false && oldValue !== undefined) {
94
- Neo.main.addon.AmCharts.destroy({
95
- appName: me.appName,
96
- id : me.id
97
- });
96
+ Neo.main.addon.AmCharts.destroy({appName, id, windowId})
98
97
  }
99
98
 
100
99
  super.afterSetMounted(value, oldValue);
101
100
 
102
101
  if (value) {
103
102
  let opts = {
104
- appName : me.appName,
103
+ appName,
105
104
  combineSeriesTooltip: me.combineSeriesTooltip,
106
105
  config : me.chartConfig,
107
- id : me.id,
106
+ id,
108
107
  package : me.package,
109
- type : me.chartType
108
+ type : me.chartType,
109
+ windowId
110
110
  };
111
111
 
112
112
  if (me.chartData) {
@@ -115,7 +115,7 @@ class AmChart extends Component {
115
115
  }
116
116
 
117
117
  setTimeout(() => {
118
- Neo.main.addon.AmCharts.create(opts).then(me.onChartMounted);
118
+ Neo.main.addon.AmCharts.create(opts).then(me.onChartMounted)
119
119
  }, 50);
120
120
  }
121
121
  }
package/src/core/Base.mjs CHANGED
@@ -233,7 +233,7 @@ class Base {
233
233
  }
234
234
 
235
235
  // Apply configs to prototype
236
- overwrites && Object.assign(cfg, overwrites)
236
+ Object.assign(cfg, overwrites)
237
237
  }
238
238
  }
239
239
 
@@ -249,7 +249,7 @@ class Base {
249
249
  let values = Array.isArray(staticName) ? staticName : this.getStaticConfig(staticName);
250
250
 
251
251
  if (!values.includes(value)) {
252
- console.error(`Supported values for ${name} are: ${values.join(', ')}`, this);
252
+ console.error(`Supported values for ${name} are:`, ...values, this);
253
253
  return oldValue
254
254
  }
255
255
 
@@ -63,6 +63,9 @@ class RecordFactory extends Base {
63
63
  key = nsArray.pop();
64
64
  ns = Neo.ns(nsArray, true);
65
65
  cls = ns[key] = class Record {
66
+ // We do not want to minify the ctor class name in dist/production
67
+ static name = 'Record'
68
+
66
69
  constructor(config) {
67
70
  let me = this,
68
71
  properties;
@@ -92,6 +92,9 @@ class SelectorContainer extends Container {
92
92
  items : [{
93
93
  module : DayViewComponent,
94
94
  reference: 'day-view'
95
+ }, {
96
+ module : DayViewComponent,
97
+ reference: 'day-view-next'
95
98
  }]
96
99
  }],
97
100
  /**
@@ -24,6 +24,13 @@ class Card extends Base {
24
24
  * @static
25
25
  */
26
26
  static itemCls = 'neo-layout-card-item'
27
+ /**
28
+ * Valid values for slideDirection
29
+ * @member {String[]} iconPositions=['horizontal','vertical',null]
30
+ * @protected
31
+ * @static
32
+ */
33
+ static slideDirections = ['horizontal', 'vertical', null]
27
34
 
28
35
  static config = {
29
36
  /**
@@ -47,7 +54,12 @@ class Card extends Base {
47
54
  * This will keep the instances & vdom trees
48
55
  * @member {Boolean} removeInactiveCards=true
49
56
  */
50
- removeInactiveCards: true
57
+ removeInactiveCards: true,
58
+ /*
59
+ * Valid values: 'horizontal', 'vertical', null
60
+ * @member {String|null} slideDirection_=null
61
+ */
62
+ slideDirection_: null
51
63
  }
52
64
 
53
65
  /**
@@ -63,6 +75,7 @@ class Card extends Base {
63
75
  containerId = me.containerId,
64
76
  container = Neo.getComponent(containerId) || Neo.get(containerId), // the instance might not be registered yet
65
77
  sCfg = me.constructor,
78
+ needsTransition = me.slideDirection && oldValue !== undefined,
66
79
  needsUpdate = false,
67
80
  removeInactiveCards = me.removeInactiveCards,
68
81
  i, isActiveIndex, item, items, len, module, wrapperCls;
@@ -72,7 +85,7 @@ class Card extends Base {
72
85
  len = items.length;
73
86
 
74
87
  if (!items[value]) {
75
- Neo.error('Trying to activate a non existing card', value, items);
88
+ Neo.error('Trying to activate a non existing card', value, items)
76
89
  }
77
90
 
78
91
  // we need to run the loop twice, since lazy loading a module at a higher index does affect lower indexes
@@ -81,7 +94,7 @@ class Card extends Base {
81
94
 
82
95
  if (i === value && Neo.typeOf(module) === 'Function') {
83
96
  needsUpdate = true;
84
- break;
97
+ break
85
98
  }
86
99
  }
87
100
 
@@ -91,33 +104,33 @@ class Card extends Base {
91
104
  module = item.module;
92
105
 
93
106
  if (isActiveIndex && Neo.typeOf(module) === 'Function') {
94
- item = await me.loadModule(item, i);
107
+ item = await me.loadModule(item, i)
95
108
  }
96
109
 
97
- if (item instanceof Neo.core.Base) {
110
+ if (item instanceof Neo.component.Base) {
98
111
  wrapperCls = item.wrapperCls;
99
112
 
100
113
  NeoArray.remove(wrapperCls, isActiveIndex ? sCfg.inactiveItemCls : sCfg.activeItemCls);
101
114
  NeoArray.add( wrapperCls, isActiveIndex ? sCfg.activeItemCls : sCfg.inactiveItemCls);
102
115
 
103
116
  if (removeInactiveCards || needsUpdate) {
104
- item.wrapperCls = wrapperCls;
105
-
106
117
  if (isActiveIndex) {
107
118
  delete item.vdom.removeDom;
108
- item.activate?.();
119
+ !needsTransition && item.activate?.()
109
120
  } else if (removeInactiveCards) {
110
- item.mounted = false;
111
- item.vdom.removeDom = true;
121
+ item.mounted = false;
122
+ item.vdom.removeDom = true
112
123
  }
113
- } else {
114
- item.wrapperCls = wrapperCls;
115
124
  }
125
+
126
+ item.wrapperCls = wrapperCls;
116
127
  }
117
128
  }
118
129
 
119
- if (removeInactiveCards || needsUpdate) {
120
- container.update();
130
+ if (needsTransition) {
131
+ await me.slideCards(value, oldValue)
132
+ } else if (removeInactiveCards || needsUpdate) {
133
+ container.update()
121
134
  }
122
135
  }
123
136
  }
@@ -139,11 +152,11 @@ class Card extends Base {
139
152
  NeoArray.add(childCls, isActiveIndex ? sCfg.activeItemCls : sCfg.inactiveItemCls);
140
153
 
141
154
  if (!keepInDom && me.removeInactiveCards) {
142
- item.wrapperCls = childCls;
143
155
  vdom.removeDom = !isActiveIndex;
144
- item.update();
145
- } else {
146
156
  item.wrapperCls = childCls;
157
+ item.update()
158
+ } else {
159
+ item.wrapperCls = childCls
147
160
  }
148
161
  }
149
162
 
@@ -156,12 +169,23 @@ class Card extends Base {
156
169
  wrapperCls = container?.wrapperCls || [];
157
170
 
158
171
  if (!container) {
159
- Neo.logError('layout.Card: applyRenderAttributes -> container not yet created', me.containerId);
172
+ Neo.logError('layout.Card: applyRenderAttributes -> container not yet created', me.containerId)
160
173
  }
161
174
 
162
175
  NeoArray.add(wrapperCls, 'neo-layout-card');
163
176
 
164
- container.wrapperCls = wrapperCls;
177
+ container.wrapperCls = wrapperCls
178
+ }
179
+
180
+ /**
181
+ * Triggered before the slideDirection config gets changed
182
+ * @param {String} value
183
+ * @param {String} oldValue
184
+ * @returns {String}
185
+ * @protected
186
+ */
187
+ beforeSetSlideDirection(value, oldValue) {
188
+ return this.beforeSetEnumValue(value, oldValue, 'slideDirection')
165
189
  }
166
190
 
167
191
  /**
@@ -181,7 +205,7 @@ class Card extends Base {
181
205
  proto, wrapperCls;
182
206
 
183
207
  if (!Neo.isNumber(index)) {
184
- index = items.indexOf(item);
208
+ index = items.indexOf(item)
185
209
  }
186
210
 
187
211
  item.isLoading = true; // prevent the item from getting queued multiple times inside form.Container
@@ -201,14 +225,14 @@ class Card extends Base {
201
225
  items[index] = item = Neo.create(item);
202
226
 
203
227
  if (me.removeInactiveCards) {
204
- item.vdom.removeDom = true;
228
+ item.vdom.removeDom = true
205
229
  }
206
230
 
207
231
  container.fire('cardLoaded', {item});
208
232
 
209
233
  vdom.cn[index] = item.vdom;
210
234
 
211
- return item;
235
+ return item
212
236
  }
213
237
 
214
238
  /**
@@ -221,12 +245,79 @@ class Card extends Base {
221
245
  wrapperCls = container?.wrapperCls || [];
222
246
 
223
247
  if (!container) {
224
- Neo.logError('layout.Card: removeRenderAttributes -> container not yet created', me.containerId);
248
+ Neo.logError('layout.Card: removeRenderAttributes -> container not yet created', me.containerId)
225
249
  }
226
250
 
227
251
  NeoArray.remove(wrapperCls, 'neo-layout-card');
228
252
 
229
- container.wrapperCls = wrapperCls;
253
+ container.wrapperCls = wrapperCls
254
+ }
255
+
256
+ /**
257
+ * @param {Number} index
258
+ * @param {Number} oldIndex
259
+ */
260
+ async slideCards(index, oldIndex) {
261
+ let me = this,
262
+ {container} = me,
263
+ slideVertical = me.slideDirection === 'vertical',
264
+ {items, vdom} = container,
265
+ card = items[index],
266
+ oldCard = items[oldIndex],
267
+ slideIn = index > oldIndex,
268
+ rect = await container.getDomRect(container.id),
269
+ animationWrapper, style, x, y;
270
+
271
+ delete oldCard.vdom.removeDom;
272
+
273
+ if (slideVertical) {
274
+ y = slideIn ? 0 : -rect.height;
275
+
276
+ style = {
277
+ flexDirection: 'column',
278
+ height : `${2 * rect.height}px`,
279
+ transform : `translateY(${y}px)`,
280
+ width : `${rect.width}px`
281
+ }
282
+ } else {
283
+ x = slideIn ? 0 : -rect.width;
284
+
285
+ style = {
286
+ height : `${rect.height}px`,
287
+ transform: `translateX(${x}px)`,
288
+ width : `${2 * rect.width}px`
289
+ }
290
+ }
291
+
292
+ vdom.cn = [
293
+ {cls: ['neo-relative'], cn: [
294
+ {cls: ['neo-animation-wrapper'], style, cn: [card.vdom]}
295
+ ]}
296
+ ];
297
+
298
+ animationWrapper = vdom.cn[0].cn[0];
299
+
300
+ animationWrapper.cn[slideIn ? 'unshift' : 'push'](oldCard.vdom);
301
+
302
+ await container.promiseUpdate();
303
+
304
+ animationWrapper.style.transform = slideVertical ?
305
+ `translateY(${slideIn ? -rect.height : 0}px)` :
306
+ `translateX(${slideIn ? -rect.width : 0}px)`;
307
+
308
+ await container.promiseUpdate();
309
+
310
+ await me.timeout(300); // transition duration defined via CSS for now
311
+
312
+ vdom.cn = [];
313
+
314
+ container.items.forEach(item => {
315
+ vdom.cn.push(item.vdom)
316
+ });
317
+
318
+ oldCard.vdom.removeDom = true;
319
+
320
+ await container.promiseUpdate()
230
321
  }
231
322
  }
232
323
 
@@ -154,6 +154,8 @@ class AmCharts extends Base {
154
154
  } else {
155
155
  // todo: check if globalThis[data.package] exists, if not load it and call create afterwards
156
156
 
157
+ am4core.useTheme(am4themes_dark);
158
+
157
159
  me.charts[data.id] = am4core.createFromConfig(data.config, data.id, globalThis[data.package][data.type || 'XYChart']);
158
160
 
159
161
  if (data.combineSeriesTooltip) {
@@ -204,6 +206,7 @@ class AmCharts extends Base {
204
206
  Promise.all([
205
207
  DomAccess.loadScript(basePath + 'charts.js'),
206
208
  DomAccess.loadScript(basePath + 'maps.js'),
209
+ DomAccess.loadScript(basePath + 'themes/dark.js'),
207
210
  DomAccess.loadScript(basePath + 'geodata/worldLow.js')
208
211
  ]).then(() => {
209
212
  me.scriptsLoaded = true;
@@ -682,7 +682,11 @@ class Component extends Base {
682
682
  * @param {String} storeName
683
683
  */
684
684
  resolveStore(component, configName, storeName) {
685
- component[configName] = this.getStore(storeName)
685
+ let store = this.getStore(storeName);
686
+
687
+ if (component[configName] !== store) {
688
+ component[configName] = store
689
+ }
686
690
  }
687
691
 
688
692
  /**
@@ -323,7 +323,8 @@ class App extends Base {
323
323
  Neo.main.addon.Stylesheet.addThemeFiles({
324
324
  appName,
325
325
  className: mapClassName || className,
326
- folders : themeFolders
326
+ folders : themeFolders,
327
+ windowId
327
328
  })
328
329
  }
329
330
  }
@@ -45,8 +45,9 @@ StartTest(t => {
45
45
 
46
46
  t.it('Editable', async t => {
47
47
  await setup({
48
- editable : false
48
+ editable: false
49
49
  });
50
+
50
51
  const blurEl = document.createElement('input');
51
52
  document.body.appendChild(blurEl);
52
53
 
@@ -72,7 +73,7 @@ StartTest(t => {
72
73
  // Nothing selected
73
74
  t.hasAttributeValue(inputField, 'aria-activedescendant', '');
74
75
 
75
- // Should activate the first list item. editable : false means we can still be focused
76
+ // Should activate the first list item. editable: false means we can still be focused
76
77
  // and select values, just that the filter input is read-only.
77
78
  await t.type(null, '[DOWN]');
78
79
 
@@ -89,7 +90,7 @@ StartTest(t => {
89
90
 
90
91
  t.is(inputField.value, 'Alabama');
91
92
 
92
- // Focus nebver leaves the input field
93
+ // Focus never leaves the input field
93
94
  t.is(blurCount, 0);
94
95
 
95
96
  await t.type(null, '[TAB]');