neo.mjs 6.15.11 → 6.16.1
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/apps/colors/app.mjs +6 -0
- package/apps/colors/childapps/widget/app.mjs +7 -0
- package/apps/colors/childapps/widget/index.html +11 -0
- package/apps/colors/childapps/widget/neo-config.json +10 -0
- package/apps/colors/childapps/widget/view/Viewport.mjs +19 -0
- package/apps/colors/index.html +11 -0
- package/apps/colors/model/Color.mjs +59 -0
- package/apps/colors/neo-config.json +9 -0
- package/apps/colors/store/Colors.mjs +24 -0
- package/apps/colors/view/BarChartComponent.mjs +67 -0
- package/apps/colors/view/PieChartComponent.mjs +53 -0
- package/apps/colors/view/TableContainer.mjs +73 -0
- package/apps/colors/view/Viewport.mjs +83 -0
- package/apps/colors/view/ViewportController.mjs +268 -0
- package/apps/colors/view/ViewportModel.mjs +32 -0
- package/apps/covid/view/MainContainerController.mjs +1 -1
- package/apps/sharedcovid/view/MainContainerController.mjs +1 -1
- package/buildScripts/webpack/json/myApps.template.json +1 -0
- package/examples/layout/card/MainContainer.mjs +148 -0
- package/examples/layout/card/app.mjs +6 -0
- package/examples/layout/card/index.html +11 -0
- package/examples/layout/card/neo-config.json +6 -0
- package/package.json +9 -9
- package/resources/scss/src/apps/colors/BarChartComponent.scss +3 -0
- package/resources/scss/src/apps/colors/PieChartComponent.scss +3 -0
- package/resources/scss/src/apps/colors/TableContainer.scss +44 -0
- package/resources/scss/src/apps/colors/Viewport.scss +17 -0
- package/resources/scss/src/layout/Card.scss +17 -0
- package/src/component/Base.mjs +6 -0
- package/src/component/wrapper/AmChart.mjs +16 -16
- package/src/core/Base.mjs +2 -2
- package/src/date/SelectorContainer.mjs +3 -0
- package/src/layout/Card.mjs +115 -24
- package/src/main/addon/AmCharts.mjs +3 -0
- package/src/model/Component.mjs +5 -1
- package/src/table/Container.mjs +42 -0
- package/src/worker/App.mjs +2 -1
- package/test/components/files/form/field/ComboBox.mjs +4 -3
@@ -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
|
77
|
-
data
|
78
|
-
dataPath
|
79
|
-
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
|
103
|
+
appName,
|
105
104
|
combineSeriesTooltip: me.combineSeriesTooltip,
|
106
105
|
config : me.chartConfig,
|
107
|
-
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
|
-
|
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
|
252
|
+
console.error(`Supported values for ${name} are:`, ...values, this);
|
253
253
|
return oldValue
|
254
254
|
}
|
255
255
|
|
package/src/layout/Card.mjs
CHANGED
@@ -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.
|
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
|
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 (
|
120
|
-
|
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;
|
package/src/model/Component.mjs
CHANGED
@@ -682,7 +682,11 @@ class Component extends Base {
|
|
682
682
|
* @param {String} storeName
|
683
683
|
*/
|
684
684
|
resolveStore(component, configName, storeName) {
|
685
|
-
|
685
|
+
let store = this.getStore(storeName);
|
686
|
+
|
687
|
+
if (component[configName] !== store) {
|
688
|
+
component[configName] = store
|
689
|
+
}
|
686
690
|
}
|
687
691
|
|
688
692
|
/**
|
package/src/table/Container.mjs
CHANGED
@@ -161,6 +161,26 @@ class Container extends BaseContainer {
|
|
161
161
|
me.createColumns(me.columns)
|
162
162
|
}
|
163
163
|
|
164
|
+
/**
|
165
|
+
* Triggered after the columns config got changed
|
166
|
+
* @param {Object[]|null} value
|
167
|
+
* @param {Object[]|null} oldValue
|
168
|
+
* @protected
|
169
|
+
*/
|
170
|
+
afterSetColumns(value, oldValue) {
|
171
|
+
if (Array.isArray(oldValue) && oldValue.length > 0) {
|
172
|
+
let me = this,
|
173
|
+
headerToolbar = me.headerToolbar;
|
174
|
+
|
175
|
+
if (headerToolbar) {
|
176
|
+
headerToolbar.items = value;
|
177
|
+
headerToolbar.createItems()
|
178
|
+
}
|
179
|
+
|
180
|
+
me.view?.createViewData(me.store.items)
|
181
|
+
}
|
182
|
+
}
|
183
|
+
|
164
184
|
/**
|
165
185
|
* Triggered after the selectionModel config got changed
|
166
186
|
* @param {Neo.selection.Model} value
|
@@ -312,6 +332,28 @@ class Container extends BaseContainer {
|
|
312
332
|
return value || oldValue
|
313
333
|
}
|
314
334
|
|
335
|
+
/**
|
336
|
+
* In case you want to update multiple existing records in parallel,
|
337
|
+
* using this method is faster than updating each record one by one.
|
338
|
+
* At least until we introduce row based vdom updates.
|
339
|
+
* @param {Object[]} records
|
340
|
+
*/
|
341
|
+
bulkUpdateRecords(records) {
|
342
|
+
let {view} = this;
|
343
|
+
|
344
|
+
if (view) {
|
345
|
+
view.silentVdomUpdate = true;
|
346
|
+
|
347
|
+
this.store.items.forEach((record, index) => {
|
348
|
+
record.set(records[index])
|
349
|
+
});
|
350
|
+
|
351
|
+
view.silentVdomUpdate = false;
|
352
|
+
|
353
|
+
view.update()
|
354
|
+
}
|
355
|
+
}
|
356
|
+
|
315
357
|
/**
|
316
358
|
* @param {Object[]} columns
|
317
359
|
* @returns {*}
|
package/src/worker/App.mjs
CHANGED
@@ -45,8 +45,9 @@ StartTest(t => {
|
|
45
45
|
|
46
46
|
t.it('Editable', async t => {
|
47
47
|
await setup({
|
48
|
-
editable
|
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
|
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
|
93
|
+
// Focus never leaves the input field
|
93
94
|
t.is(blurCount, 0);
|
94
95
|
|
95
96
|
await t.type(null, '[TAB]');
|