neo.mjs 7.9.0 → 7.9.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/ServiceWorker.mjs +2 -2
- package/apps/portal/index.html +1 -1
- package/apps/portal/view/home/FooterContainer.mjs +1 -1
- package/examples/ServiceWorker.mjs +2 -2
- package/examples/dialog/DemoDialog.mjs +2 -1
- package/examples/dialog/MainContainer.mjs +16 -10
- package/examples/table/nestedRecordFields/EditUserDialog.mjs +11 -1
- package/package.json +3 -3
- package/resources/data/deck/learnneo/pages/tutorials/Earthquakes.md +51 -49
- package/src/DefaultConfig.mjs +2 -2
- package/src/Neo.mjs +7 -12
- package/src/core/Base.mjs +0 -8
- package/src/core/IdGenerator.mjs +0 -9
- package/src/dialog/Base.mjs +26 -2
package/apps/ServiceWorker.mjs
CHANGED
package/apps/portal/index.html
CHANGED
@@ -135,7 +135,8 @@ class DemoDialog extends Dialog {
|
|
135
135
|
trapFocus : true,
|
136
136
|
optionalAnimateTargetId: button.id,
|
137
137
|
style : {left: me.getOffset(), top: me.getOffset()},
|
138
|
-
title : 'Dialog ' + nextIndex
|
138
|
+
title : 'Dialog ' + nextIndex,
|
139
|
+
windowId : me.windowId
|
139
140
|
})
|
140
141
|
}
|
141
142
|
|
@@ -58,7 +58,6 @@ class MainContainer extends Viewport {
|
|
58
58
|
checked : true,
|
59
59
|
hideLabel : true,
|
60
60
|
hideValueLabel: false,
|
61
|
-
listeners : {change: me.onConfigChange.bind(me, 'animated')},
|
62
61
|
style : {marginLeft: '3em'},
|
63
62
|
valueLabelText: 'Animated'
|
64
63
|
}, {
|
@@ -66,7 +65,6 @@ class MainContainer extends Viewport {
|
|
66
65
|
checked : true,
|
67
66
|
hideLabel : true,
|
68
67
|
hideValueLabel: false,
|
69
|
-
listeners : {change: me.onConfigChange.bind(me, 'modal')},
|
70
68
|
style : {marginLeft: '1em'},
|
71
69
|
valueLabelText: 'Modal'
|
72
70
|
}, '->', {
|
@@ -82,19 +80,22 @@ class MainContainer extends Viewport {
|
|
82
80
|
* @param {Object} data
|
83
81
|
*/
|
84
82
|
createDialog(data) {
|
85
|
-
let me
|
83
|
+
let me = this,
|
84
|
+
button = data.component,
|
85
|
+
{appName, boundaryContainerId, windowId} = me;
|
86
86
|
|
87
|
-
|
87
|
+
button.disabled = true;
|
88
88
|
|
89
89
|
me.dialog = Neo.create(DemoDialog, {
|
90
90
|
animated : me.down({valueLabelText: 'Animated'}).checked,
|
91
|
-
appName
|
92
|
-
boundaryContainerId
|
91
|
+
appName,
|
92
|
+
boundaryContainerId,
|
93
93
|
listeners : {close: me.onWindowClose, scope: me},
|
94
94
|
modal : me.down({valueLabelText: 'Modal'}).checked,
|
95
95
|
trapFocus : true,
|
96
|
-
optionalAnimateTargetId:
|
97
|
-
title : 'Dialog 1'
|
96
|
+
optionalAnimateTargetId: button.id,
|
97
|
+
title : 'Dialog 1',
|
98
|
+
windowId
|
98
99
|
})
|
99
100
|
}
|
100
101
|
|
@@ -103,8 +104,13 @@ class MainContainer extends Viewport {
|
|
103
104
|
* @param {Object} opts
|
104
105
|
*/
|
105
106
|
onConfigChange(config, opts) {
|
106
|
-
|
107
|
-
|
107
|
+
let me = this,
|
108
|
+
boundaryContainerId = opts.value ? 'document.body' : null;
|
109
|
+
|
110
|
+
me.boundaryContainerId = boundaryContainerId
|
111
|
+
|
112
|
+
if (me.dialog) {
|
113
|
+
me.dialog[config] = boundaryContainerId
|
108
114
|
}
|
109
115
|
}
|
110
116
|
|
@@ -120,7 +120,17 @@ class EditUserDialog extends Dialog {
|
|
120
120
|
* @param {Object} data
|
121
121
|
*/
|
122
122
|
onSelectedFieldChange(data) {
|
123
|
-
|
123
|
+
let me = this,
|
124
|
+
store = me.getModel().getStore('mainStore');
|
125
|
+
|
126
|
+
if (data.value === false) {
|
127
|
+
me.record.annotations.selected = false
|
128
|
+
} else {
|
129
|
+
// Assuming we want to support a single row selection
|
130
|
+
store.items.forEach(record => {
|
131
|
+
record.annotations.selected = record === me.record ? data.value : false
|
132
|
+
})
|
133
|
+
}
|
124
134
|
}
|
125
135
|
}
|
126
136
|
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "neo.mjs",
|
3
|
-
"version": "7.9.
|
3
|
+
"version": "7.9.1",
|
4
4
|
"description": "The webworkers driven UI framework",
|
5
5
|
"type": "module",
|
6
6
|
"repository": {
|
@@ -54,13 +54,13 @@
|
|
54
54
|
"envinfo": "^7.14.0",
|
55
55
|
"fs-extra": "^11.2.0",
|
56
56
|
"highlightjs-line-numbers.js": "^2.8.0",
|
57
|
-
"inquirer": "^11.0
|
57
|
+
"inquirer": "^11.1.0",
|
58
58
|
"marked": "^14.1.2",
|
59
59
|
"monaco-editor": "0.50.0",
|
60
60
|
"neo-jsdoc": "1.0.1",
|
61
61
|
"neo-jsdoc-x": "1.0.5",
|
62
62
|
"postcss": "^8.4.47",
|
63
|
-
"sass": "^1.79.
|
63
|
+
"sass": "^1.79.4",
|
64
64
|
"siesta-lite": "5.5.2",
|
65
65
|
"url": "^0.11.4",
|
66
66
|
"webpack": "^5.95.0",
|
@@ -523,16 +523,16 @@ class MainView extends Base {
|
|
523
523
|
module: Store,
|
524
524
|
model: {
|
525
525
|
fields: [{
|
526
|
-
name: "
|
526
|
+
name: "location",
|
527
527
|
}, {
|
528
|
-
name: "
|
528
|
+
name: "magnitude",
|
529
529
|
}, {
|
530
530
|
name: "timestamp",
|
531
531
|
type: "Date",
|
532
532
|
}],
|
533
533
|
},
|
534
534
|
url: "https://nameless-tundra-27404.herokuapp.com/go/?fn=earthquakes",
|
535
|
-
responseRoot: "
|
535
|
+
responseRoot: "data",
|
536
536
|
autoLoad: true,
|
537
537
|
},
|
538
538
|
style: {width: '100%'},
|
@@ -543,10 +543,10 @@ class MainView extends Base {
|
|
543
543
|
{weekday: "long", year: "numeric", month: "long", day: "numeric"}
|
544
544
|
)
|
545
545
|
}, {
|
546
|
-
dataField: "
|
546
|
+
dataField: "location",
|
547
547
|
text: "Location"
|
548
548
|
}, {
|
549
|
-
dataField: "
|
549
|
+
dataField: "magnitude",
|
550
550
|
text: "Magnitude",
|
551
551
|
align: "right",
|
552
552
|
renderer: (data) => data.value.toLocaleString()
|
@@ -595,36 +595,38 @@ Here's the config for the store.
|
|
595
595
|
module: Store,
|
596
596
|
model: {
|
597
597
|
fields: [{
|
598
|
-
name: "
|
598
|
+
name: "location",
|
599
599
|
}, {
|
600
|
-
name: "
|
600
|
+
name: "magnitude",
|
601
601
|
}, {
|
602
602
|
name: "timestamp",
|
603
603
|
type: "Date",
|
604
604
|
}],
|
605
605
|
},
|
606
606
|
url: "https://nameless-tundra-27404.herokuapp.com/go/?fn=earthquakes",
|
607
|
-
responseRoot: "
|
607
|
+
responseRoot: "data",
|
608
608
|
autoLoad: true,
|
609
609
|
}
|
610
610
|
</pre>
|
611
611
|
|
612
|
-
The feed looks like this.
|
612
|
+
The feed looks like this.
|
613
613
|
<pre data-javascript>
|
614
614
|
{
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
615
|
+
"data": [{
|
616
|
+
"timestamp": "2024-09-29T16:45:14.000Z",
|
617
|
+
"lat": "64.012",
|
618
|
+
"lng": "-16.659",
|
619
|
+
"location": "1.2 km ESE of Hvannadalshnjúkur",
|
620
|
+
"magnitude": "0.32964",
|
621
|
+
"depth": "1.2"
|
621
622
|
}, {
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
623
|
+
"timestamp": "2024-09-29T16:16:25.000Z",
|
624
|
+
"lat": "63.929",
|
625
|
+
"lng": "-21.447",
|
626
|
+
"location": "2.8 km WSW of Raufarhólshellir",
|
627
|
+
"magnitude": "0.80979",
|
628
|
+
"depth": "10.2"
|
629
|
+
}, ...
|
628
630
|
]
|
629
631
|
}
|
630
632
|
</pre>
|
@@ -644,10 +646,10 @@ columns: [{
|
|
644
646
|
text: "Date",
|
645
647
|
renderer: (data) => data.value.toLocaleDateString(undefined, {weekday: "long", year: "numeric", month: "long", day: "numeric"}),
|
646
648
|
}, {
|
647
|
-
dataField: "
|
649
|
+
dataField: "location",
|
648
650
|
text: "Location",
|
649
651
|
}, {
|
650
|
-
dataField: "
|
652
|
+
dataField: "magnitude",
|
651
653
|
text: "Magnitude",
|
652
654
|
align: "right",
|
653
655
|
renderer: (data) => data.value.toLocaleString(),
|
@@ -692,10 +694,10 @@ class Table extends Base {
|
|
692
694
|
text: "Date",
|
693
695
|
renderer: (data) => data.value.toLocaleDateString(undefined, {weekday: "long", year: "numeric", month: "long", day: "numeric"}),
|
694
696
|
}, {
|
695
|
-
dataField: "
|
697
|
+
dataField: "location",
|
696
698
|
text: "Location",
|
697
699
|
}, {
|
698
|
-
dataField: "
|
700
|
+
dataField: "magnitude",
|
699
701
|
text: "Magnitude",
|
700
702
|
align: "right",
|
701
703
|
renderer: (data) => data.value.toLocaleString(),
|
@@ -765,16 +767,16 @@ static config = {
|
|
765
767
|
module: Store,
|
766
768
|
model: {
|
767
769
|
fields: [{
|
768
|
-
name: "
|
770
|
+
name: "location",
|
769
771
|
}, {
|
770
|
-
name: "
|
772
|
+
name: "magnitude",
|
771
773
|
}, {
|
772
774
|
name: "timestamp",
|
773
775
|
type: "Date",
|
774
776
|
}],
|
775
777
|
},
|
776
778
|
url: "https://nameless-tundra-27404.herokuapp.com/go/?fn=earthquakes",
|
777
|
-
responseRoot: "
|
779
|
+
responseRoot: "data",
|
778
780
|
autoLoad: true,
|
779
781
|
},
|
780
782
|
style: {width: '100%'},
|
@@ -888,16 +890,16 @@ class MainView extends Base {
|
|
888
890
|
module: Store,
|
889
891
|
model: {
|
890
892
|
fields: [{
|
891
|
-
name: "
|
893
|
+
name: "location"
|
892
894
|
}, {
|
893
|
-
name: "
|
895
|
+
name: "magnitude"
|
894
896
|
}, {
|
895
897
|
name: "timestamp",
|
896
898
|
type: "Date"
|
897
899
|
}]
|
898
900
|
},
|
899
901
|
url: "https://nameless-tundra-27404.herokuapp.com/go/?fn=earthquakes",
|
900
|
-
responseRoot: "
|
902
|
+
responseRoot: "data",
|
901
903
|
autoLoad: true
|
902
904
|
},
|
903
905
|
}
|
@@ -912,16 +914,16 @@ class MainView extends Base {
|
|
912
914
|
module: Store,
|
913
915
|
model: {
|
914
916
|
fields: [{
|
915
|
-
name: "
|
917
|
+
name: "location"
|
916
918
|
}, {
|
917
|
-
name: "
|
919
|
+
name: "magnitude"
|
918
920
|
}, {
|
919
921
|
name: "timestamp",
|
920
922
|
type: "Date"
|
921
923
|
}]
|
922
924
|
},
|
923
925
|
url: "https://nameless-tundra-27404.herokuapp.com/go/?fn=earthquakes",
|
924
|
-
responseRoot: "
|
926
|
+
responseRoot: "data",
|
925
927
|
autoLoad: true
|
926
928
|
},
|
927
929
|
style: {width: '100%'}
|
@@ -931,16 +933,16 @@ class MainView extends Base {
|
|
931
933
|
module: Store,
|
932
934
|
model: {
|
933
935
|
fields: [{
|
934
|
-
name: "
|
936
|
+
name: "location"
|
935
937
|
}, {
|
936
|
-
name: "
|
938
|
+
name: "magnitude"
|
937
939
|
}, {
|
938
940
|
name: "timestamp",
|
939
941
|
type: "Date"
|
940
942
|
}]
|
941
943
|
},
|
942
944
|
url: "https://nameless-tundra-27404.herokuapp.com/go/?fn=earthquakes",
|
943
|
-
responseRoot: "
|
945
|
+
responseRoot: "data",
|
944
946
|
autoLoad: true
|
945
947
|
},
|
946
948
|
style: {width: '100%'}
|
@@ -1004,16 +1006,16 @@ class MainView extends Base {
|
|
1004
1006
|
module: Store,
|
1005
1007
|
model: {
|
1006
1008
|
fields: [{
|
1007
|
-
name: "
|
1009
|
+
name: "location"
|
1008
1010
|
}, {
|
1009
|
-
name: "
|
1011
|
+
name: "magnitude"
|
1010
1012
|
}, {
|
1011
1013
|
name: "timestamp",
|
1012
1014
|
type: "Date"
|
1013
1015
|
}]
|
1014
1016
|
},
|
1015
1017
|
url: "https://nameless-tundra-27404.herokuapp.com/go/?fn=earthquakes",
|
1016
|
-
responseRoot: "
|
1018
|
+
responseRoot: "data",
|
1017
1019
|
autoLoad: true
|
1018
1020
|
},
|
1019
1021
|
}
|
@@ -1084,16 +1086,16 @@ class MainViewModel extends Model {
|
|
1084
1086
|
module: Store,
|
1085
1087
|
model: {
|
1086
1088
|
fields: [{
|
1087
|
-
name: "
|
1089
|
+
name: "location"
|
1088
1090
|
}, {
|
1089
|
-
name: "
|
1091
|
+
name: "magnitude"
|
1090
1092
|
}, {
|
1091
1093
|
name: "timestamp",
|
1092
1094
|
type: "Date"
|
1093
1095
|
}]
|
1094
1096
|
},
|
1095
1097
|
url: "https://nameless-tundra-27404.herokuapp.com/go/?fn=earthquakes",
|
1096
|
-
responseRoot: "
|
1098
|
+
responseRoot: "data",
|
1097
1099
|
autoLoad: true
|
1098
1100
|
},
|
1099
1101
|
}
|
@@ -1247,22 +1249,22 @@ Edit `apps/earthquakes/view/MainViewModel.mjs` and modify `fields` as follows.
|
|
1247
1249
|
|
1248
1250
|
<pre data-javascript>
|
1249
1251
|
fields: [{
|
1250
|
-
name: "
|
1252
|
+
name: "location",
|
1251
1253
|
}, {
|
1252
|
-
name: "
|
1254
|
+
name: "magnitude",
|
1253
1255
|
}, {
|
1254
1256
|
name: "timestamp",
|
1255
1257
|
type: "Date",
|
1256
1258
|
}, {
|
1257
1259
|
name: 'title',
|
1258
|
-
mapping: "
|
1260
|
+
mapping: "location"
|
1259
1261
|
}, {
|
1260
1262
|
name: "position",
|
1261
1263
|
calculate: (data, field, item)=>({lat: item.latitude, lng: item.longitude})
|
1262
1264
|
}],
|
1263
1265
|
</pre>
|
1264
1266
|
|
1265
|
-
As you can see, _title_ is mapped to the existing feed value
|
1267
|
+
As you can see, _title_ is mapped to the existing feed value _location_, and _position_ is
|
1266
1268
|
calculated by returning an object with _lat_ and _lng_ set to the corresponding values from the feed.
|
1267
1269
|
|
1268
1270
|
Save and refresh _earthquakes_. You can use the debugger to inspect the store via _Shift-Ctrl-right-click_ and
|
@@ -1391,9 +1393,9 @@ Add this table config:
|
|
1391
1393
|
|
1392
1394
|
Save and refresh, then click on a table row. If you look at the debugger console you'll see the record being logged.
|
1393
1395
|
|
1394
|
-
Just for fun, expand the logged value and look for the
|
1396
|
+
Just for fun, expand the logged value and look for the `magnitude` property. If you recall, that's a value from the feed, and one of the things we configured in the store's fields:[].
|
1395
1397
|
|
1396
|
-
In the console, click on the ellipses by
|
1398
|
+
In the console, click on the ellipses by `magnitude` and enter a new value, like 2.5. (Don't enter a larger value, or you may destroy that part of Iceland.)
|
1397
1399
|
|
1398
1400
|
<img style="width:80%" src="https://s3.amazonaws.com/mjs.neo.learning.images/earthquakes/LogTableClick.png"></img>
|
1399
1401
|
|
package/src/DefaultConfig.mjs
CHANGED
@@ -262,12 +262,12 @@ const DefaultConfig = {
|
|
262
262
|
useVdomWorker: true,
|
263
263
|
/**
|
264
264
|
* buildScripts/injectPackageVersion.mjs will update this value
|
265
|
-
* @default '7.9.
|
265
|
+
* @default '7.9.1'
|
266
266
|
* @memberOf! module:Neo
|
267
267
|
* @name config.version
|
268
268
|
* @type String
|
269
269
|
*/
|
270
|
-
version: '7.9.
|
270
|
+
version: '7.9.1'
|
271
271
|
};
|
272
272
|
|
273
273
|
Object.assign(DefaultConfig, {
|
package/src/Neo.mjs
CHANGED
@@ -92,17 +92,13 @@ Neo = globalThis.Neo = Object.assign({
|
|
92
92
|
* @param {Neo.core.Base} cls
|
93
93
|
*/
|
94
94
|
applyToGlobalNs(cls) {
|
95
|
-
let proto
|
96
|
-
className
|
95
|
+
let proto = typeof cls === 'function' ? cls.prototype : cls,
|
96
|
+
className = proto.isClass ? proto.config.className : proto.className,
|
97
|
+
nsArray = className.split('.'),
|
98
|
+
key = nsArray.pop(),
|
99
|
+
ns = Neo.ns(nsArray, true);
|
97
100
|
|
98
|
-
|
99
|
-
className = proto.isClass ? proto.config.className : proto.className;
|
100
|
-
|
101
|
-
nsArray = className.split('.');
|
102
|
-
key = nsArray.pop();
|
103
|
-
ns = Neo.ns(nsArray, true);
|
104
|
-
ns[key] = cls
|
105
|
-
}
|
101
|
+
ns[key] = cls
|
106
102
|
},
|
107
103
|
|
108
104
|
/**
|
@@ -571,8 +567,7 @@ const ignoreMixin = [
|
|
571
567
|
'isClass',
|
572
568
|
'mixin',
|
573
569
|
'ntype',
|
574
|
-
'observable'
|
575
|
-
'registerToGlobalNs'
|
570
|
+
'observable'
|
576
571
|
],
|
577
572
|
|
578
573
|
charsRegex = /\d+/g,
|
package/src/core/Base.mjs
CHANGED
@@ -52,14 +52,6 @@ class Base {
|
|
52
52
|
* @static
|
53
53
|
*/
|
54
54
|
static overwrittenMethods = {}
|
55
|
-
/**
|
56
|
-
* Set this one to false in case you don't want to stick
|
57
|
-
* to the "anti-pattern" to apply classes to the global Neo or App namespace
|
58
|
-
* @member {Boolean} registerToGlobalNs=true
|
59
|
-
* @protected
|
60
|
-
* @static
|
61
|
-
*/
|
62
|
-
static registerToGlobalNs = true
|
63
55
|
/**
|
64
56
|
* Configs will get merged throughout the class hierarchy
|
65
57
|
* @returns {Object} config
|
package/src/core/IdGenerator.mjs
CHANGED
@@ -5,15 +5,6 @@
|
|
5
5
|
* @singleton
|
6
6
|
*/
|
7
7
|
class IdGenerator {
|
8
|
-
/**
|
9
|
-
* Set this one to false in case you don't want to stick
|
10
|
-
* to the "anti-pattern" to apply classes to the global Neo or App namespace
|
11
|
-
* @member {Boolean} registerToGlobalNs=true
|
12
|
-
* @protected
|
13
|
-
* @static
|
14
|
-
*/
|
15
|
-
static registerToGlobalNs = true
|
16
|
-
|
17
8
|
static config = {
|
18
9
|
/**
|
19
10
|
* @member {String} className='Neo.core.IdGenerator'
|
package/src/dialog/Base.mjs
CHANGED
@@ -274,7 +274,7 @@ class Base extends Panel {
|
|
274
274
|
super.afterSetMounted(value, oldValue);
|
275
275
|
|
276
276
|
// Ensure focus trapping is up-to-date, enabled or disabled.
|
277
|
-
this.syncTrapFocus()
|
277
|
+
oldValue !== undefined && this.syncTrapFocus()
|
278
278
|
}
|
279
279
|
|
280
280
|
/**
|
@@ -730,6 +730,30 @@ class Base extends Panel {
|
|
730
730
|
this.hidden = true
|
731
731
|
}
|
732
732
|
|
733
|
+
/**
|
734
|
+
* @param {Boolean} [mount] Mount the DOM after the vnode got created
|
735
|
+
*/
|
736
|
+
async render(mount) {
|
737
|
+
let me = this,
|
738
|
+
{wrapperStyle} = me;
|
739
|
+
|
740
|
+
// If there is no animation target, we need to ensure that the initial offscreen positioning
|
741
|
+
// from .neo-floating gets reverted
|
742
|
+
if (!me.animateTargetId) {
|
743
|
+
if (!wrapperStyle.left) {
|
744
|
+
wrapperStyle.left = 'initial'
|
745
|
+
}
|
746
|
+
|
747
|
+
if (!wrapperStyle.top) {
|
748
|
+
wrapperStyle.top = 'initial'
|
749
|
+
}
|
750
|
+
|
751
|
+
me.wrapperStyle = wrapperStyle
|
752
|
+
}
|
753
|
+
|
754
|
+
await super.render(mount)
|
755
|
+
}
|
756
|
+
|
733
757
|
/**
|
734
758
|
* @param {Boolean} animate=!!this.animateTargetId
|
735
759
|
*/
|
@@ -739,7 +763,7 @@ class Base extends Panel {
|
|
739
763
|
if (animate) {
|
740
764
|
me.animateShow()
|
741
765
|
} else {
|
742
|
-
if (!me.
|
766
|
+
if (!me.mounted) {
|
743
767
|
me.render(true)
|
744
768
|
}
|
745
769
|
|