neo.mjs 8.0.0-alpha.2 → 8.0.0-beta.2
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/.github/CODING_GUIDELINES.md +5 -5
- package/.github/CONCEPT.md +10 -10
- package/apps/ServiceWorker.mjs +2 -2
- package/apps/colors/view/Viewport.mjs +9 -9
- package/apps/colors/view/ViewportController.mjs +13 -13
- package/apps/colors/view/{ViewportModel.mjs → ViewportStateProvider.mjs} +8 -8
- package/apps/covid/view/MainContainer.mjs +22 -22
- package/apps/covid/view/MainContainerController.mjs +8 -10
- package/apps/covid/view/{MainContainerModel.mjs → MainContainerStateProvider.mjs} +7 -7
- package/apps/covid/view/TableContainer.mjs +2 -2
- package/apps/covid/view/TableContainerController.mjs +1 -1
- package/apps/form/view/FormContainerController.mjs +2 -2
- package/apps/form/view/SideNavList.mjs +3 -3
- package/apps/form/view/Viewport.mjs +7 -7
- package/apps/form/view/ViewportController.mjs +4 -4
- package/apps/form/view/{ViewportModel.mjs → ViewportStateProvider.mjs} +8 -8
- package/apps/portal/index.html +1 -1
- package/apps/portal/resources/data/examples_devmode.json +3 -3
- package/apps/portal/resources/data/examples_dist_dev.json +3 -3
- package/apps/portal/resources/data/examples_dist_prod.json +3 -3
- package/apps/portal/view/Viewport.mjs +12 -12
- package/apps/portal/view/ViewportController.mjs +2 -2
- package/apps/portal/view/ViewportStateProvider.mjs +27 -0
- package/apps/portal/view/examples/TabContainer.mjs +11 -11
- package/apps/portal/view/home/FooterContainer.mjs +1 -1
- package/apps/portal/view/home/parts/MainNeo.mjs +6 -2
- package/apps/portal/view/learn/ContentComponent.mjs +2 -2
- package/apps/portal/view/learn/ContentTreeList.mjs +1 -1
- package/apps/portal/view/learn/MainContainer.mjs +9 -9
- package/apps/portal/view/learn/MainContainerController.mjs +12 -12
- package/apps/portal/view/learn/{MainContainerModel.mjs → MainContainerStateProvider.mjs} +7 -7
- package/apps/portal/view/learn/PageSectionsList.mjs +1 -1
- package/apps/realworld/view/article/CreateComponent.mjs +1 -1
- package/apps/realworld2/view/HomeContainer.mjs +7 -7
- package/apps/sharedcovid/view/GalleryContainer.mjs +2 -2
- package/apps/sharedcovid/view/HelixContainer.mjs +2 -2
- package/apps/sharedcovid/view/MainContainer.mjs +25 -25
- package/apps/sharedcovid/view/MainContainerController.mjs +10 -11
- package/apps/sharedcovid/view/{MainContainerModel.mjs → MainContainerStateProvider.mjs} +8 -8
- package/apps/sharedcovid/view/TableContainer.mjs +2 -2
- package/apps/sharedcovid/view/TableContainerController.mjs +1 -1
- package/apps/sharedcovid/view/mapboxGl/Container.mjs +2 -2
- package/buildScripts/createApp.mjs +2 -2
- package/buildScripts/createClass.mjs +15 -17
- package/buildScripts/createComponent.mjs +4 -4
- package/docs/app/view/ContentTabContainer.mjs +1 -1
- package/docs/app/view/MainContainer.mjs +3 -3
- package/docs/app/view/MainContainerController.mjs +15 -15
- package/examples/ServiceWorker.mjs +2 -2
- package/examples/component/mwc/buttons/MainContainer.mjs +2 -2
- package/examples/component/mwc/textFields/MainContainer.mjs +2 -2
- package/examples/fields/MainContainer.mjs +197 -228
- package/examples/preloadingAssets/view/MainContainer.mjs +2 -2
- package/examples/{model → stateProvider}/advanced/MainContainer.mjs +12 -12
- package/examples/{model → stateProvider}/advanced/MainContainerController.mjs +10 -10
- package/examples/stateProvider/advanced/app.mjs +6 -0
- package/examples/{model/dialog → stateProvider/advanced}/index.html +1 -1
- package/examples/{model/inline → stateProvider/advanced}/neo-config.json +1 -1
- package/examples/{model → stateProvider}/dialog/EditUserDialog.mjs +3 -3
- package/examples/{model → stateProvider}/dialog/EditUserDialogController.mjs +5 -5
- package/examples/{model → stateProvider}/dialog/MainContainer.mjs +7 -7
- package/examples/{model → stateProvider}/dialog/MainContainerController.mjs +5 -5
- package/examples/{model → stateProvider}/dialog/app.mjs +1 -1
- package/examples/{model/multiWindow2 → stateProvider/dialog}/index.html +1 -1
- package/examples/{model → stateProvider}/dialog/neo-config.json +1 -1
- package/examples/{model → stateProvider}/extendedClass/MainContainer.mjs +13 -13
- package/examples/{model/inline → stateProvider/extendedClass}/MainContainerController.mjs +7 -7
- package/examples/stateProvider/extendedClass/MainContainerStateProvider.mjs +24 -0
- package/examples/stateProvider/extendedClass/app.mjs +6 -0
- package/examples/stateProvider/extendedClass/index.html +11 -0
- package/examples/stateProvider/extendedClass/neo-config.json +7 -0
- package/examples/{model → stateProvider}/inline/MainContainer.mjs +10 -10
- package/examples/{model/extendedClass → stateProvider/inline}/MainContainerController.mjs +7 -7
- package/examples/{model/extendedClass → stateProvider/inline}/app.mjs +1 -1
- package/examples/{model/extendedClass → stateProvider/inline}/index.html +1 -1
- package/examples/{model/extendedClass → stateProvider/inline}/neo-config.json +1 -1
- package/examples/{model/inlineNoModel → stateProvider/inlineNoStateProvider}/MainContainer.mjs +4 -4
- package/examples/{model/inlineNoModel → stateProvider/inlineNoStateProvider}/MainContainerController.mjs +3 -3
- package/examples/stateProvider/inlineNoStateProvider/README.md +8 -0
- package/examples/stateProvider/inlineNoStateProvider/app.mjs +6 -0
- package/examples/{model/inline → stateProvider/inlineNoStateProvider}/index.html +1 -1
- package/examples/stateProvider/inlineNoStateProvider/neo-config.json +7 -0
- package/examples/{model → stateProvider}/multiWindow/EditUserDialog.mjs +3 -3
- package/examples/{model → stateProvider}/multiWindow/EditUserDialogController.mjs +5 -5
- package/examples/{model → stateProvider}/multiWindow/MainContainer.mjs +3 -3
- package/examples/{model → stateProvider}/multiWindow/MainContainerController.mjs +6 -6
- package/examples/{model → stateProvider}/multiWindow/Viewport.mjs +3 -3
- package/examples/{model → stateProvider}/multiWindow/ViewportController.mjs +14 -14
- package/examples/{model/multiWindow2 → stateProvider/multiWindow}/app.mjs +1 -1
- package/examples/{model/advanced → stateProvider/multiWindow}/index.html +1 -1
- package/examples/{model → stateProvider}/multiWindow/neo-config.json +1 -1
- package/examples/{model → stateProvider}/multiWindow2/Viewport.mjs +3 -3
- package/examples/{model/multiWindow → stateProvider/multiWindow2}/app.mjs +1 -1
- package/examples/{model/multiWindow → stateProvider/multiWindow2}/index.html +1 -1
- package/examples/{model → stateProvider}/multiWindow2/neo-config.json +1 -1
- package/examples/{model → stateProvider}/nestedData/MainContainer.mjs +9 -9
- package/examples/{model → stateProvider}/nestedData/MainContainerController.mjs +7 -7
- package/examples/stateProvider/nestedData/app.mjs +6 -0
- package/examples/stateProvider/nestedData/index.html +11 -0
- package/examples/stateProvider/nestedData/neo-config.json +7 -0
- package/examples/{model → stateProvider}/table/MainContainer.mjs +8 -8
- package/examples/stateProvider/table/MainContainerStateProvider.mjs +24 -0
- package/examples/{model → stateProvider}/table/MainModel.mjs +2 -2
- package/examples/{model → stateProvider}/table/MainStore.mjs +2 -2
- package/examples/{model/advanced → stateProvider/table}/app.mjs +1 -1
- package/examples/{model/advanced → stateProvider/table}/neo-config.json +1 -1
- package/examples/{model → stateProvider}/twoWay/MainContainer.mjs +9 -9
- package/examples/{model/inline → stateProvider/twoWay}/app.mjs +1 -1
- package/examples/stateProvider/twoWay/index.html +11 -0
- package/examples/{model → stateProvider}/twoWay/neo-config.json +1 -1
- package/examples/tab/container/MainContainer.mjs +7 -9
- package/examples/table/nestedRecordFields/EditUserDialog.mjs +3 -3
- package/examples/table/nestedRecordFields/MainContainer.mjs +8 -8
- package/examples/table/nestedRecordFields/{MainContainerModel.mjs → MainContainerStateProvider.mjs} +10 -10
- package/examples/tabs/MainContainer.mjs +3 -3
- package/examples/tabs/MainContainer2.mjs +4 -4
- package/examples/toolbar/paging/view/MainContainer.mjs +7 -7
- package/examples/toolbar/paging/view/{MainContainerModel.mjs → MainContainerStateProvider.mjs} +8 -8
- package/examples/treeAccordion/MainContainer.mjs +2 -2
- package/examples/videoMove/MainContainer.mjs +14 -7
- package/examples/viewport/MainContainer.mjs +3 -3
- package/package.json +6 -6
- package/resources/data/deck/learnneo/pages/benefits/FormsEngine.md +13 -13
- package/resources/data/deck/learnneo/pages/guides/{ViewModels.md → StateProviders.md} +52 -58
- package/resources/data/deck/learnneo/tree.json +46 -46
- package/resources/data/deck/training/pages/2022-12-27T21-55-23-144Z.md +2 -2
- package/resources/data/deck/training/pages/2022-12-28T17-11-34-653Z.md +6 -6
- package/resources/data/deck/training/pages/2022-12-29T18-36-08-226Z.md +2 -2
- package/resources/data/deck/training/pages/2022-12-29T18-36-56-893Z.md +2 -2
- package/resources/data/deck/training/pages/2022-12-29T20-37-08-919Z.md +2 -2
- package/resources/data/deck/training/pages/2022-12-29T20-37-20-344Z.md +2 -2
- package/resources/data/deck/training/pages/2023-01-01T21-11-58-025Z.md +3 -3
- package/resources/data/deck/training/pages/2023-01-16T20-24-09-690Z.md +4 -4
- package/resources/data/deck/training/pages/2023-02-05T17-44-53-815Z.md +3 -3
- package/resources/data/deck/training/pages/2023-02-05T17-45-40-114Z.md +1 -1
- package/src/DefaultConfig.mjs +2 -2
- package/src/button/Base.mjs +7 -7
- package/src/calendar/view/EditEventContainer.mjs +3 -3
- package/src/calendar/view/MainContainer.mjs +27 -27
- package/src/calendar/view/{MainContainerModel.mjs → MainContainerStateProvider.mjs} +7 -7
- package/src/calendar/view/SettingsContainer.mjs +13 -28
- package/src/calendar/view/YearComponent.mjs +5 -5
- package/src/calendar/view/calendars/ColorsList.mjs +5 -0
- package/src/calendar/view/calendars/EditContainer.mjs +1 -1
- package/src/calendar/view/calendars/List.mjs +1 -1
- package/src/calendar/view/month/Component.mjs +6 -6
- package/src/calendar/view/settings/GeneralContainer.mjs +2 -2
- package/src/calendar/view/week/Component.mjs +10 -10
- package/src/calendar/view/week/EventDragZone.mjs +1 -1
- package/src/code/LivePreview.mjs +10 -10
- package/src/component/Base.mjs +123 -105
- package/src/container/Base.mjs +4 -4
- package/src/controller/Component.mjs +29 -12
- package/src/core/Base.mjs +0 -1
- package/src/core/Compare.mjs +128 -83
- package/src/date/SelectorContainer.mjs +12 -12
- package/src/date/{SelectorContainerModel.mjs → SelectorContainerStateProvider.mjs} +7 -7
- package/src/form/field/Text.mjs +1 -1
- package/src/form/field/Time.mjs +5 -3
- package/src/form/field/trigger/Time.mjs +2 -1
- package/src/layout/Base.mjs +6 -6
- package/src/list/Base.mjs +7 -1
- package/src/list/Color.mjs +3 -3
- package/src/main/DomEvents.mjs +1 -1
- package/src/main/DomUtils.mjs +39 -36
- package/src/{model/Component.mjs → state/Provider.mjs} +67 -69
- package/src/tab/Container.mjs +3 -5
- package/src/toolbar/Base.mjs +26 -8
- package/src/tree/Accordion.mjs +15 -13
- package/src/util/VNode.mjs +6 -8
- package/src/worker/App.mjs +2 -2
- package/apps/portal/view/ViewportModel.mjs +0 -27
- package/examples/model/extendedClass/MainContainerModel.mjs +0 -24
- package/examples/model/inlineNoModel/README.md +0 -8
- package/examples/model/inlineNoModel/app.mjs +0 -6
- package/examples/model/inlineNoModel/index.html +0 -11
- package/examples/model/inlineNoModel/neo-config.json +0 -7
- package/examples/model/nestedData/app.mjs +0 -6
- package/examples/model/nestedData/index.html +0 -11
- package/examples/model/nestedData/neo-config.json +0 -7
- package/examples/model/table/MainContainerModel.mjs +0 -24
- package/examples/model/table/app.mjs +0 -6
- package/examples/model/table/neo-config.json +0 -7
- package/examples/model/twoWay/app.mjs +0 -6
- package/examples/model/twoWay/index.html +0 -11
- /package/examples/{model → stateProvider}/table/index.html +0 -0
@@ -8,11 +8,11 @@ const dataVariableRegex = /data((?!(\.[a-z_]\w*\(\)))\.[a-z_]\w*)+/gi,
|
|
8
8
|
variableNameRegex = /^\w*/;
|
9
9
|
|
10
10
|
/**
|
11
|
-
* An optional component
|
12
|
-
* @class Neo.
|
11
|
+
* An optional component state provider for adding bindings to configs
|
12
|
+
* @class Neo.state.Provider
|
13
13
|
* @extends Neo.core.Base
|
14
14
|
*/
|
15
|
-
class
|
15
|
+
class Provider extends Base {
|
16
16
|
/**
|
17
17
|
* True automatically applies the core.Observable mixin
|
18
18
|
* @member {Boolean} observable=true
|
@@ -22,15 +22,15 @@ class Component extends Base {
|
|
22
22
|
|
23
23
|
static config = {
|
24
24
|
/**
|
25
|
-
* @member {String} className='Neo.
|
25
|
+
* @member {String} className='Neo.state.Provider'
|
26
26
|
* @protected
|
27
27
|
*/
|
28
|
-
className: 'Neo.
|
28
|
+
className: 'Neo.state.Provider',
|
29
29
|
/**
|
30
|
-
* @member {String} ntype='
|
30
|
+
* @member {String} ntype='state-provider'
|
31
31
|
* @protected
|
32
32
|
*/
|
33
|
-
ntype: '
|
33
|
+
ntype: 'state-provider',
|
34
34
|
/**
|
35
35
|
* @member {Object|null} bindings_=null
|
36
36
|
* @protected
|
@@ -67,7 +67,7 @@ class Component extends Base {
|
|
67
67
|
*/
|
68
68
|
formulas_: null,
|
69
69
|
/**
|
70
|
-
* @member {Neo.
|
70
|
+
* @member {Neo.state.Provider|null} parent_=null
|
71
71
|
*/
|
72
72
|
parent_: null,
|
73
73
|
/**
|
@@ -80,13 +80,13 @@ class Component extends Base {
|
|
80
80
|
* @param {Object} config
|
81
81
|
*/
|
82
82
|
construct(config) {
|
83
|
-
Neo.currentWorker.
|
83
|
+
Neo.currentWorker.isUsingStateProviders = true;
|
84
84
|
super.construct(config);
|
85
85
|
this.bindings = {}
|
86
86
|
}
|
87
87
|
|
88
88
|
/**
|
89
|
-
* Adds a given key/value combination on this
|
89
|
+
* Adds a given key/value combination on this stateProvider level.
|
90
90
|
* The method is used by setData() & setDataAtSameLevel()
|
91
91
|
* in case the data property does not exist yet.
|
92
92
|
* @param {String} key
|
@@ -138,8 +138,8 @@ class Component extends Base {
|
|
138
138
|
|
139
139
|
/**
|
140
140
|
* Triggered before the parent config gets changed
|
141
|
-
* @param {Neo.
|
142
|
-
* @param {Neo.
|
141
|
+
* @param {Neo.state.Provider|null} value
|
142
|
+
* @param {Neo.state.Provider|null} oldValue
|
143
143
|
* @protected
|
144
144
|
*/
|
145
145
|
beforeSetParent(value, oldValue) {
|
@@ -161,7 +161,7 @@ class Component extends Base {
|
|
161
161
|
Object.entries(value).forEach(([key, storeValue]) => {
|
162
162
|
controller?.parseConfig(storeValue);
|
163
163
|
|
164
|
-
// support mapping string based listeners into the
|
164
|
+
// support mapping string based listeners into the stateProvider instance
|
165
165
|
Object.entries(storeValue.listeners || {}).forEach(([listenerKey,listener]) => {
|
166
166
|
if (Neo.isString(listener) && Neo.isFunction(me[listener])) {
|
167
167
|
storeValue.listeners[listenerKey] = me[listener].bind(me)
|
@@ -190,7 +190,7 @@ class Component extends Base {
|
|
190
190
|
|
191
191
|
/**
|
192
192
|
* Registers a new binding in case a matching data property does exist.
|
193
|
-
* Otherwise it will use the closest
|
193
|
+
* Otherwise, it will use the closest stateProvider with a match.
|
194
194
|
* @param {String} componentId
|
195
195
|
* @param {String} key
|
196
196
|
* @param {String} value
|
@@ -201,25 +201,25 @@ class Component extends Base {
|
|
201
201
|
data = me.getDataScope(key),
|
202
202
|
scope = data.scope,
|
203
203
|
keyLeaf = data.key,
|
204
|
-
bindingScope,
|
204
|
+
bindingScope, parentStateProvider;
|
205
205
|
|
206
206
|
if (scope?.hasOwnProperty(keyLeaf)) {
|
207
207
|
bindingScope = Neo.ns(`${key}.${componentId}`, true, me.bindings);
|
208
208
|
bindingScope[value] = formatter
|
209
209
|
} else {
|
210
|
-
|
210
|
+
parentStateProvider = me.getParent();
|
211
211
|
|
212
|
-
if (
|
213
|
-
|
212
|
+
if (parentStateProvider) {
|
213
|
+
parentStateProvider.createBinding(componentId, key, value, formatter)
|
214
214
|
} else {
|
215
|
-
console.error('No
|
215
|
+
console.error('No state.Provider found with the specified data property', componentId, keyLeaf, value)
|
216
216
|
}
|
217
217
|
}
|
218
218
|
}
|
219
219
|
|
220
220
|
/**
|
221
221
|
* Registers a new binding in case a matching data property does exist.
|
222
|
-
* Otherwise, it will use the closest
|
222
|
+
* Otherwise, it will use the closest stateProvider with a match.
|
223
223
|
* @param {String} componentId
|
224
224
|
* @param {String} formatter
|
225
225
|
* @param {String} value
|
@@ -341,29 +341,29 @@ class Component extends Base {
|
|
341
341
|
}
|
342
342
|
|
343
343
|
/**
|
344
|
-
* Access the closest data property inside the
|
344
|
+
* Access the closest data property inside the parent chain.
|
345
345
|
* @param {String} key
|
346
|
-
* @param {Neo.
|
346
|
+
* @param {Neo.state.Provider} originStateProvider=this for internal usage only
|
347
347
|
* @returns {*} value
|
348
348
|
*/
|
349
|
-
getData(key,
|
349
|
+
getData(key, originStateProvider=this) {
|
350
350
|
let me = this,
|
351
351
|
data = me.getDataScope(key),
|
352
352
|
{scope} = data,
|
353
353
|
keyLeaf = data.key,
|
354
|
-
|
354
|
+
parentStateProvider;
|
355
355
|
|
356
356
|
if (scope?.hasOwnProperty(keyLeaf)) {
|
357
357
|
return scope[keyLeaf]
|
358
358
|
}
|
359
359
|
|
360
|
-
|
360
|
+
parentStateProvider = me.getParent();
|
361
361
|
|
362
|
-
if (!
|
363
|
-
console.error(`data property '${key}' does not exist.`,
|
362
|
+
if (!parentStateProvider) {
|
363
|
+
console.error(`data property '${key}' does not exist.`, originStateProvider)
|
364
364
|
}
|
365
365
|
|
366
|
-
return
|
366
|
+
return parentStateProvider.getData(key, originStateProvider)
|
367
367
|
}
|
368
368
|
|
369
369
|
/**
|
@@ -471,8 +471,8 @@ class Component extends Base {
|
|
471
471
|
}
|
472
472
|
|
473
473
|
/**
|
474
|
-
* Get the closest
|
475
|
-
* @returns {Neo.
|
474
|
+
* Get the closest stateProvider inside the components parent tree
|
475
|
+
* @returns {Neo.state.Provider|null}
|
476
476
|
*/
|
477
477
|
getParent() {
|
478
478
|
let {parent} = this;
|
@@ -481,56 +481,56 @@ class Component extends Base {
|
|
481
481
|
return parent
|
482
482
|
}
|
483
483
|
|
484
|
-
return this.component.parent?.
|
484
|
+
return this.component.parent?.getStateProvider() || null
|
485
485
|
}
|
486
486
|
|
487
487
|
/**
|
488
488
|
* Access the closest store inside the VM parent chain.
|
489
489
|
* @param {String} key
|
490
|
-
* @param {Neo.
|
490
|
+
* @param {Neo.state.Provider} originStateProvider=this for internal usage only
|
491
491
|
* @returns {Neo.data.Store}
|
492
492
|
*/
|
493
|
-
getStore(key,
|
493
|
+
getStore(key, originStateProvider=this) {
|
494
494
|
let me = this,
|
495
495
|
{stores} = me,
|
496
|
-
|
496
|
+
parentStateProvider;
|
497
497
|
|
498
498
|
if (stores?.hasOwnProperty(key)) {
|
499
499
|
return stores[key]
|
500
500
|
}
|
501
501
|
|
502
|
-
|
502
|
+
parentStateProvider = me.getParent();
|
503
503
|
|
504
|
-
if (!
|
505
|
-
console.error(`store '${key}' not found inside this
|
504
|
+
if (!parentStateProvider) {
|
505
|
+
console.error(`store '${key}' not found inside this stateProvider or parents.`, originStateProvider)
|
506
506
|
}
|
507
507
|
|
508
|
-
return
|
508
|
+
return parentStateProvider.getStore(key, originStateProvider)
|
509
509
|
}
|
510
510
|
|
511
511
|
/**
|
512
512
|
* Internal method to avoid code redundancy.
|
513
513
|
* Use setData() or setDataAtSameLevel() instead.
|
514
514
|
*
|
515
|
-
* Passing an
|
516
|
-
* inside the parent
|
517
|
-
* Not passing it will set all values on the
|
515
|
+
* Passing an originStateProvider param will try to set each key on the closest property match
|
516
|
+
* inside the parent stateProvider chain => setData()
|
517
|
+
* Not passing it will set all values on the stateProvider where the method gets called => setDataAtSameLevel()
|
518
518
|
* @param {Object|String} key
|
519
519
|
* @param {*} value
|
520
|
-
* @param {Neo.
|
520
|
+
* @param {Neo.state.Provider} [originStateProvider]
|
521
521
|
* @protected
|
522
522
|
*/
|
523
|
-
internalSetData(key, value,
|
523
|
+
internalSetData(key, value, originStateProvider) {
|
524
524
|
let me = this,
|
525
|
-
data, keyLeaf,
|
525
|
+
data, keyLeaf, parentStateProvider, scope;
|
526
526
|
|
527
527
|
if (Neo.isObject(value) && !value.isRecord) {
|
528
528
|
Object.entries(value).forEach(([dataKey, dataValue]) => {
|
529
|
-
me.internalSetData(`${key}.${dataKey}`, dataValue,
|
529
|
+
me.internalSetData(`${key}.${dataKey}`, dataValue, originStateProvider)
|
530
530
|
})
|
531
531
|
} else if (Neo.isObject(key)) {
|
532
532
|
Object.entries(key).forEach(([dataKey, dataValue]) => {
|
533
|
-
me.internalSetData(dataKey, dataValue,
|
533
|
+
me.internalSetData(dataKey, dataValue, originStateProvider)
|
534
534
|
})
|
535
535
|
} else {
|
536
536
|
data = me.getDataScope(key);
|
@@ -540,13 +540,13 @@ class Component extends Base {
|
|
540
540
|
if (scope?.hasOwnProperty(keyLeaf)) {
|
541
541
|
scope[keyLeaf] = value
|
542
542
|
} else {
|
543
|
-
if (
|
544
|
-
|
543
|
+
if (originStateProvider) {
|
544
|
+
parentStateProvider = me.getParent();
|
545
545
|
|
546
|
-
if (
|
547
|
-
|
546
|
+
if (parentStateProvider) {
|
547
|
+
parentStateProvider.internalSetData(key, value, originStateProvider)
|
548
548
|
} else {
|
549
|
-
|
549
|
+
originStateProvider.addDataProperty(key, value)
|
550
550
|
}
|
551
551
|
} else {
|
552
552
|
me.addDataProperty(key, value)
|
@@ -586,24 +586,24 @@ class Component extends Base {
|
|
586
586
|
onDataPropertyChange(key, value, oldValue) {
|
587
587
|
let me = this,
|
588
588
|
binding = me.bindings && Neo.ns(key, false, me.bindings),
|
589
|
-
component, config, hierarchyData,
|
589
|
+
component, config, hierarchyData, stateProvider;
|
590
590
|
|
591
591
|
if (binding) {
|
592
592
|
hierarchyData = {};
|
593
593
|
|
594
594
|
Object.entries(binding).forEach(([componentId, configObject]) => {
|
595
|
-
component
|
596
|
-
config
|
597
|
-
|
595
|
+
component = Neo.getComponent(componentId) || Neo.get(componentId); // timing issue: the cmp might not be registered inside manager.Component yet
|
596
|
+
config = {};
|
597
|
+
stateProvider = component.getStateProvider() || me;
|
598
598
|
|
599
|
-
if (!hierarchyData[
|
600
|
-
hierarchyData[
|
599
|
+
if (!hierarchyData[stateProvider.id]) {
|
600
|
+
hierarchyData[stateProvider.id] = stateProvider.getHierarchyData()
|
601
601
|
}
|
602
602
|
|
603
603
|
Object.entries(configObject).forEach(([configField, formatter]) => {
|
604
|
-
// we can not call me.callFormatter(), since a data property inside a parent
|
605
|
-
// could have changed which is relying on data properties inside a closer
|
606
|
-
config[configField] =
|
604
|
+
// we can not call me.callFormatter(), since a data property inside a parent stateProvider
|
605
|
+
// could have changed which is relying on data properties inside a closer stateProvider
|
606
|
+
config[configField] = stateProvider.callFormatter(formatter, hierarchyData[stateProvider.id])
|
607
607
|
});
|
608
608
|
|
609
609
|
component?.set(config)
|
@@ -645,19 +645,17 @@ class Component extends Base {
|
|
645
645
|
}
|
646
646
|
|
647
647
|
/**
|
648
|
-
* Removes all bindings for a given component id inside this
|
649
|
-
* as well as inside all parent models.
|
648
|
+
* Removes all bindings for a given component id inside this stateProvider as well as inside all parent stateProviders.
|
650
649
|
* @param {String} componentId
|
651
650
|
*/
|
652
651
|
removeBindings(componentId) {
|
653
|
-
let me
|
654
|
-
parentModel = me.getParent();
|
652
|
+
let me = this;
|
655
653
|
|
656
654
|
Object.entries(me.bindings).forEach(([dataProperty, binding]) => {
|
657
655
|
delete binding[componentId]
|
658
656
|
});
|
659
657
|
|
660
|
-
|
658
|
+
me.getParent()?.removeBindings(componentId)
|
661
659
|
}
|
662
660
|
|
663
661
|
/**
|
@@ -672,7 +670,7 @@ class Component extends Base {
|
|
672
670
|
|
673
671
|
if (formulas) {
|
674
672
|
if (!initialRun && (!data.key || !data.value)) {
|
675
|
-
console.warn('[
|
673
|
+
console.warn('[StateProvider:formulas] missing key or value', data.key, data.value)
|
676
674
|
}
|
677
675
|
|
678
676
|
for ([key, value] of Object.entries(formulas)) {
|
@@ -720,7 +718,7 @@ class Component extends Base {
|
|
720
718
|
}
|
721
719
|
|
722
720
|
/**
|
723
|
-
* The method will assign all values to the closest
|
721
|
+
* The method will assign all values to the closest stateProvider where it finds an existing key.
|
724
722
|
* In case no match is found inside the parent chain, a new data property will get generated.
|
725
723
|
* @param {Object|String} key
|
726
724
|
* @param {*} value
|
@@ -731,7 +729,7 @@ class Component extends Base {
|
|
731
729
|
|
732
730
|
/**
|
733
731
|
* Use this method instead of setData() in case you want to enforce
|
734
|
-
* setting all keys on this instance instead of looking for matches inside parent
|
732
|
+
* setting all keys on this instance instead of looking for matches inside parent stateProviders.
|
735
733
|
* @param {Object|String} key
|
736
734
|
* @param {*} value
|
737
735
|
*/
|
@@ -740,4 +738,4 @@ class Component extends Base {
|
|
740
738
|
}
|
741
739
|
}
|
742
740
|
|
743
|
-
export default Neo.setupClass(
|
741
|
+
export default Neo.setupClass(Provider);
|
package/src/tab/Container.mjs
CHANGED
@@ -243,7 +243,7 @@ class Container extends BaseContainer {
|
|
243
243
|
});
|
244
244
|
|
245
245
|
items.forEach((item, index) => {
|
246
|
-
tabButtons.push(me.getTabButtonConfig(item.
|
246
|
+
tabButtons.push(me.getTabButtonConfig(item.header, index));
|
247
247
|
|
248
248
|
if (!(item instanceof Neo.component.Base)) {
|
249
249
|
item = {flex: 1, ...me.itemDefaults, isTab: true, ...item}
|
@@ -410,7 +410,7 @@ class Container extends BaseContainer {
|
|
410
410
|
cardContainer = me.getCardContainer(),
|
411
411
|
tabBar = me.getTabBar(),
|
412
412
|
hasItem = false,
|
413
|
-
i, len, returnArray, superItem, tab
|
413
|
+
i, len, returnArray, superItem, tab;
|
414
414
|
|
415
415
|
if (Array.isArray(item)) {
|
416
416
|
i = 0;
|
@@ -441,9 +441,7 @@ class Container extends BaseContainer {
|
|
441
441
|
}
|
442
442
|
|
443
443
|
if (!hasItem) {
|
444
|
-
|
445
|
-
|
446
|
-
tab = tabBar.insert(index, me.getTabButtonConfig(tabButtonConfig, index));
|
444
|
+
tab = tabBar.insert(index, me.getTabButtonConfig(item.header, index));
|
447
445
|
|
448
446
|
// todo: non index based matching of tab buttons and cards
|
449
447
|
i = 0;
|
package/src/toolbar/Base.mjs
CHANGED
@@ -151,14 +151,7 @@ class Base extends Container {
|
|
151
151
|
let items = this._items;
|
152
152
|
|
153
153
|
if (Array.isArray(items)) {
|
154
|
-
items.
|
155
|
-
if (item === '->') {
|
156
|
-
items[index] = Neo.create({
|
157
|
-
module: Component,
|
158
|
-
flex : 1
|
159
|
-
})
|
160
|
-
}
|
161
|
-
})
|
154
|
+
this._items = items.map(item => this.replaceSpacer(item))
|
162
155
|
}
|
163
156
|
|
164
157
|
return super.createItems()
|
@@ -203,6 +196,31 @@ class Base extends Container {
|
|
203
196
|
|
204
197
|
return layoutConfig || me.layout
|
205
198
|
}
|
199
|
+
|
200
|
+
/**
|
201
|
+
* Inserts an item or array of items at a specific index
|
202
|
+
* @param {Number} index
|
203
|
+
* @param {Array|Object} item
|
204
|
+
* @param {Boolean} [silent=false]
|
205
|
+
* @returns {Neo.component.Base|Neo.component.Base[]}
|
206
|
+
*/
|
207
|
+
insert(index, item, silent=false) {
|
208
|
+
if (Array.isArray(item)) {
|
209
|
+
item = item.map(item => this.replaceSpacer(item))
|
210
|
+
} else {
|
211
|
+
item = this.replaceSpacer(item)
|
212
|
+
}
|
213
|
+
|
214
|
+
return super.insert(index, item, silent)
|
215
|
+
}
|
216
|
+
|
217
|
+
/**
|
218
|
+
* @param {Array|Object|String} item
|
219
|
+
* @returns {Array|Object}
|
220
|
+
*/
|
221
|
+
replaceSpacer(item) {
|
222
|
+
return item === '->' ? {module: Component, flex: 1} : item
|
223
|
+
}
|
206
224
|
}
|
207
225
|
|
208
226
|
export default Neo.setupClass(Base);
|
package/src/tree/Accordion.mjs
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
+
import ClassSystemUtil from '../util/ClassSystem.mjs';
|
2
|
+
import NeoArray from '../util/Array.mjs';
|
1
3
|
import TreeList from '../tree/List.mjs';
|
2
|
-
import TreeAccordionModel from
|
3
|
-
import
|
4
|
-
import ClassSystemUtil from "../util/ClassSystem.mjs";
|
5
|
-
import VDomUtil from "../util/VDom.mjs";
|
4
|
+
import TreeAccordionModel from '../selection/TreeAccordionModel.mjs';
|
5
|
+
import VDomUtil from '../util/VDom.mjs';
|
6
6
|
|
7
7
|
/**
|
8
8
|
* @class Neo.tree.Accordion
|
@@ -38,11 +38,6 @@ class AccordionTree extends TreeList {
|
|
38
38
|
* @member {String[]} baseCls=['neo-tree-accordion']
|
39
39
|
*/
|
40
40
|
baseCls: ['neo-tree-list'],
|
41
|
-
/**
|
42
|
-
* Set to false to hide the initial root item
|
43
|
-
* @member {Boolean} firstParentIsVisible=true
|
44
|
-
*/
|
45
|
-
firstParentIsVisible_: true,
|
46
41
|
/**
|
47
42
|
* Define the field names for the store to show header, text and icon
|
48
43
|
* @member {Object} fields={header:'name',icon:'iconCls',text:'content'}
|
@@ -52,6 +47,11 @@ class AccordionTree extends TreeList {
|
|
52
47
|
icon : 'iconCls',
|
53
48
|
text : 'content'
|
54
49
|
},
|
50
|
+
/**
|
51
|
+
* Set to false to hide the initial root item
|
52
|
+
* @member {Boolean} firstParentIsVisible=true
|
53
|
+
*/
|
54
|
+
firstParentIsVisible_: true,
|
55
55
|
/**
|
56
56
|
* Set to false will auto expand root parent items and disallow collapsing
|
57
57
|
* @member {Boolean} rootParentIsCollapsible=false
|
@@ -109,10 +109,12 @@ class AccordionTree extends TreeList {
|
|
109
109
|
* @param {Boolean} oldValue
|
110
110
|
*/
|
111
111
|
afterSetFirstParentIsVisible(value, oldValue) {
|
112
|
-
|
112
|
+
let firstRecord = this.store.first();
|
113
|
+
|
114
|
+
this.toggleCls('first-parent-not-visible', !value);
|
113
115
|
|
114
|
-
if (
|
115
|
-
|
116
|
+
if (firstRecord) {
|
117
|
+
firstRecord.visible = value
|
116
118
|
}
|
117
119
|
}
|
118
120
|
|
@@ -154,7 +156,7 @@ class AccordionTree extends TreeList {
|
|
154
156
|
store.items.forEach((record) => {
|
155
157
|
const itemId = me.getItemId(record[me.getKeyProperty()]),
|
156
158
|
vdom = me.getVdomChild(itemId),
|
157
|
-
itemVdom = VDomUtil.getByFlag(vdom, '
|
159
|
+
itemVdom = VDomUtil.getByFlag(vdom, 'iconCls');
|
158
160
|
|
159
161
|
if (record.isLeaf) {
|
160
162
|
itemVdom.removeDom = hide
|
package/src/util/VNode.mjs
CHANGED
@@ -25,7 +25,7 @@ class VNode extends Base {
|
|
25
25
|
* {String} parentId
|
26
26
|
* {Object} vnode
|
27
27
|
*/
|
28
|
-
static
|
28
|
+
static find(vnode, opts, index, parentNode) {
|
29
29
|
vnode = VNode.getVnode(vnode);
|
30
30
|
|
31
31
|
index = index || 0;
|
@@ -68,7 +68,7 @@ class VNode extends Base {
|
|
68
68
|
}
|
69
69
|
} else if (Neo.isArray(value) && Neo.isArray(vnode[key])) {
|
70
70
|
// todo: either search the vnode array for all keys or compare if the arrays are equal.
|
71
|
-
throw new Error('
|
71
|
+
throw new Error('find: cls matching not supported for target & source types of Arrays')
|
72
72
|
}
|
73
73
|
break
|
74
74
|
case 'style':
|
@@ -98,7 +98,7 @@ class VNode extends Base {
|
|
98
98
|
}
|
99
99
|
|
100
100
|
for (; i < len; i++) {
|
101
|
-
subChild = VNode.
|
101
|
+
subChild = VNode.find(vnode.childNodes[i], opts, i, vnode);
|
102
102
|
|
103
103
|
if (subChild) {
|
104
104
|
return subChild
|
@@ -114,7 +114,7 @@ class VNode extends Base {
|
|
114
114
|
* @param {String|null} id
|
115
115
|
* @returns {Object|null} child vnode or null
|
116
116
|
*/
|
117
|
-
static
|
117
|
+
static getById(vnode, id) {
|
118
118
|
vnode = VNode.getVnode(vnode);
|
119
119
|
|
120
120
|
let childNodes = vnode.childNodes || [],
|
@@ -133,7 +133,7 @@ class VNode extends Base {
|
|
133
133
|
return childNode
|
134
134
|
}
|
135
135
|
|
136
|
-
childNode = VNode.
|
136
|
+
childNode = VNode.getById(childNode, id);
|
137
137
|
|
138
138
|
if (childNode) {
|
139
139
|
return childNode
|
@@ -150,9 +150,7 @@ class VNode extends Base {
|
|
150
150
|
* @returns {String[]} childIds
|
151
151
|
*/
|
152
152
|
static getChildIds(vnode, childIds=[]) {
|
153
|
-
|
154
|
-
|
155
|
-
childNodes.forEach(childNode => {
|
153
|
+
vnode?.childNodes?.forEach(childNode => {
|
156
154
|
if (childNode.id && !childNode.componentId) {
|
157
155
|
childIds.push(childNode.id)
|
158
156
|
}
|
package/src/worker/App.mjs
CHANGED
@@ -52,10 +52,10 @@ class App extends Base {
|
|
52
52
|
*/
|
53
53
|
data = null
|
54
54
|
/**
|
55
|
-
* @member {Boolean}
|
55
|
+
* @member {Boolean} isUsingStateProviders=false
|
56
56
|
* @protected
|
57
57
|
*/
|
58
|
-
|
58
|
+
isUsingStateProviders = false
|
59
59
|
/**
|
60
60
|
* We are storing the params of insertThemeFiles() calls here, in case the method does get triggered
|
61
61
|
* before the json theme structure got loaded.
|
@@ -1,27 +0,0 @@
|
|
1
|
-
import Component from '../../../src/model/Component.mjs';
|
2
|
-
|
3
|
-
/**
|
4
|
-
* @class Portal.view.ViewportModel
|
5
|
-
* @extends Neo.model.Component
|
6
|
-
*/
|
7
|
-
class ViewportModel extends Component {
|
8
|
-
static config = {
|
9
|
-
/**
|
10
|
-
* @member {String} className='Portal.view.ViewportModel'
|
11
|
-
* @protected
|
12
|
-
*/
|
13
|
-
className: 'Portal.view.ViewportModel',
|
14
|
-
/**
|
15
|
-
* @member {Object} data
|
16
|
-
*/
|
17
|
-
data: {
|
18
|
-
/**
|
19
|
-
* Values are: large, medium, small, xSmall, null
|
20
|
-
* @member {String|null} size
|
21
|
-
*/
|
22
|
-
size: null
|
23
|
-
}
|
24
|
-
}
|
25
|
-
}
|
26
|
-
|
27
|
-
export default Neo.setupClass(ViewportModel);
|
@@ -1,24 +0,0 @@
|
|
1
|
-
import Model from '../../../src/model/Component.mjs';
|
2
|
-
|
3
|
-
/**
|
4
|
-
* @class Neo.examples.model.extendedClass.MainContainerModel
|
5
|
-
* @extends Neo.model.Component
|
6
|
-
*/
|
7
|
-
class MainContainerModel extends Model {
|
8
|
-
static config = {
|
9
|
-
/**
|
10
|
-
* @member {String} className='Neo.examples.model.extendedClass.MainContainerModel'
|
11
|
-
* @protected
|
12
|
-
*/
|
13
|
-
className: 'Neo.examples.model.extendedClass.MainContainerModel',
|
14
|
-
/**
|
15
|
-
* @member {Object} data
|
16
|
-
*/
|
17
|
-
data: {
|
18
|
-
button1Text: 'Button 1',
|
19
|
-
button2Text: 'Button 2'
|
20
|
-
}
|
21
|
-
}
|
22
|
-
}
|
23
|
-
|
24
|
-
export default Neo.setupClass(MainContainerModel);
|
@@ -1,8 +0,0 @@
|
|
1
|
-
This example covers the same business logic as examples/model/inline.
|
2
|
-
|
3
|
-
Instead of using a model.Component (view model) instance, the view controller is storing the data properties directly.
|
4
|
-
|
5
|
-
Compare the MainContainer.mjs as well as the MainContainerController.mjs files inside both examples to get the idea.
|
6
|
-
|
7
|
-
While this implementation is beautifully easy, it does get a lot more complex in case you want to use nested data
|
8
|
-
or a nested view model & controller hierarchy.
|
@@ -1,11 +0,0 @@
|
|
1
|
-
<!DOCTYPE HTML>
|
2
|
-
<html>
|
3
|
-
<head>
|
4
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
5
|
-
<meta charset="UTF-8">
|
6
|
-
<title>inline example without using a model.Component</title>
|
7
|
-
</head>
|
8
|
-
<body>
|
9
|
-
<script src="../../../src/MicroLoader.mjs" type="module"></script>
|
10
|
-
</body>
|
11
|
-
</html>
|
@@ -1,11 +0,0 @@
|
|
1
|
-
<!DOCTYPE HTML>
|
2
|
-
<html>
|
3
|
-
<head>
|
4
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
5
|
-
<meta charset="UTF-8">
|
6
|
-
<title>model.Component: nested data</title>
|
7
|
-
</head>
|
8
|
-
<body>
|
9
|
-
<script src="../../../src/MicroLoader.mjs" type="module"></script>
|
10
|
-
</body>
|
11
|
-
</html>
|