neo.mjs 4.4.14 → 4.4.16

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.
@@ -1,9 +1,9 @@
1
1
  import Button from '../../../../src/button/Base.mjs';
2
- import GoogleMapsComponent from '../../../../src/component/wrapper/GoogleMaps.mjs';
3
- import MainContainerController from './MainContainerController.mjs';
4
2
  import NumberField from '../../../../src/form/field/Number.mjs';
5
3
  import Toolbar from '../../../../src/toolbar/Base.mjs';
6
4
  import Viewport from '../../../../src/container/Viewport.mjs';
5
+ import MapComponent from "./MapComponent.mjs";
6
+ import MainContainerController from './MainContainerController.mjs';
7
7
 
8
8
  /**
9
9
  * @class Neo.examples.component.wrapper.googleMaps.MainContainer
@@ -17,25 +17,10 @@ class MainContainer extends Viewport {
17
17
  layout : {ntype: 'vbox', align: 'stretch'},
18
18
 
19
19
  items: [{
20
- module : GoogleMapsComponent,
20
+ module : MapComponent,
21
21
  flex : 1,
22
- reference: 'google-maps-component',
23
-
24
- listeners: {
25
- zoomChange: 'onMapZoomChance'
26
- },
27
-
28
- markerStoreConfig: {
29
- data: [{
30
- id : '1',
31
- position: {lat: -33.397, lng: 150.644},
32
- title : 'Hello neo'
33
- }, {
34
- id : '2',
35
- position: {lat: -34.397, lng: 150.644},
36
- title : 'Hello Max'
37
- }]
38
- }
22
+ listeners: {zoomChange: 'onMapZoomChange'},
23
+ reference: 'google-maps-component'
39
24
  }, {
40
25
  module: Toolbar,
41
26
  flex : 'none',
@@ -46,6 +31,13 @@ class MainContainer extends Viewport {
46
31
  height : 27,
47
32
  iconCls: 'fa-solid fa-plane',
48
33
  text : 'Fly to San Fran'
34
+ }, {
35
+ module : Button,
36
+ handler: 'onFlyToIcelandButtonClick',
37
+ height : 27,
38
+ iconCls: 'fa-solid fa-plane',
39
+ style : {marginLeft: '10px'},
40
+ text : 'Fly to Iceland'
49
41
  }, {
50
42
  module : NumberField,
51
43
  clearToOriginalValue: true,
@@ -56,7 +48,7 @@ class MainContainer extends Viewport {
56
48
  maxValue : 10,
57
49
  reference : 'zoom-field',
58
50
  style : {marginLeft: '10px'},
59
- value : 8,
51
+ value : 6,
60
52
  width : 100
61
53
  }, {
62
54
  module : Button,
@@ -65,7 +57,7 @@ class MainContainer extends Viewport {
65
57
  iconCls: 'fa-solid fa-trash',
66
58
  mode : 'hide',
67
59
  style : {marginLeft: '10px'},
68
- text : 'Hide marker 1'
60
+ text : 'Hide marker'
69
61
  }]
70
62
  }]
71
63
  }}
@@ -23,7 +23,14 @@ class MainContainerController extends ComponentController {
23
23
  /**
24
24
  * @param {Object} data
25
25
  */
26
- onMapZoomChance(data) {
26
+ onFlyToIcelandButtonClick(data) {
27
+ this.getReference('google-maps-component').panTo({ lat: 64.963051,lng: -19.020835})
28
+ }
29
+
30
+ /**
31
+ * @param {Object} data
32
+ */
33
+ onMapZoomChange(data) {
27
34
  this.getReference('zoom-field').value = data.value;
28
35
  }
29
36
 
@@ -38,18 +45,18 @@ class MainContainerController extends ComponentController {
38
45
  button.set({
39
46
  iconCls: 'fa fa-location-dot',
40
47
  mode : 'show',
41
- text : 'Show marker 1'
48
+ text : 'Show marker'
42
49
  });
43
50
 
44
- map.hideMarker('1')
51
+ map.hideMarker('-13')
45
52
  } else {
46
53
  button.set({
47
54
  iconCls: 'fa-solid fa-trash',
48
55
  mode : 'hide',
49
- text : 'Hide marker 1'
56
+ text : 'Hide marker'
50
57
  });
51
58
 
52
- map.showMarker('1')
59
+ map.showMarker('-13')
53
60
  }
54
61
  }
55
62
 
@@ -0,0 +1,160 @@
1
+ import GoogleMapsComponent from '../../../../src/component/wrapper/GoogleMaps.mjs';
2
+ import MarkerDialog from './MarkerDialog.mjs';
3
+
4
+ /**
5
+ * @class Neo.examples.component.wrapper.googleMaps.MapComponent
6
+ * @extends Neo.component.wrapper.GoogleMaps
7
+ */
8
+ class MapComponent extends GoogleMapsComponent {
9
+ static getConfig() {return {
10
+ className: 'Neo.examples.component.wrapper.googleMaps.MapComponent',
11
+ ntype: 'worldmap',
12
+
13
+ // Center the map initially to Island
14
+ center: {
15
+ lat: 64.963051,
16
+ lng: -19.020835
17
+ },
18
+
19
+ // Ensure only Island is visible
20
+ zoom: 6,
21
+
22
+ // Adding record to keep the original data
23
+ markerStore: {
24
+ model: {
25
+ fields: [{
26
+ name: 'id',
27
+ type: 'Number'
28
+ }, {
29
+ name: 'icon',
30
+ type: 'Object'
31
+ }, {
32
+ name: 'position',
33
+ type: 'Object'
34
+ }, {
35
+ name: 'record',
36
+ type: 'Object'
37
+ }, {
38
+ name: 'title',
39
+ type: 'String'
40
+ }]
41
+ }
42
+ },
43
+
44
+ onMarkerClick(data) {
45
+ let me = this,
46
+ record = data.record.record,
47
+ event = data.event;
48
+
49
+ me.disabled = true;
50
+
51
+ me.dialog = Neo.create(MarkerDialog, {
52
+ appName : me.appName,
53
+ record : record,
54
+ domEvent : data.domEvent,
55
+ boundaryContainerId : me.id
56
+ });
57
+ }
58
+ }}
59
+
60
+ construct(config) {
61
+ super.construct(config);
62
+
63
+ this.fetchData();
64
+ }
65
+
66
+ /**
67
+ * Ajax request to get the Marker Data
68
+ */
69
+ fetchData() {
70
+ let me = this,
71
+ url = '../../../../examples/component/wrapper/googleMaps/earthquakes.json',
72
+ callbackFn = me.createMarkersAndAddToMarkerStore.bind(me);
73
+
74
+ fetch(url)
75
+ .then(response => response.json())
76
+ .catch(err => console.log("Can't access + url, err"))
77
+ .then(data => callbackFn(data));
78
+ }
79
+
80
+ /**
81
+ * Create Marker records from the Server result and
82
+ * push all Markers to the MarkerStore
83
+ *
84
+ * @param {Object} data from earthquake.json
85
+ */
86
+ createMarkersAndAddToMarkerStore (data) {
87
+ let me = this;
88
+
89
+ const markers = data.results.map(function(record) {
90
+ const date = new Date(record.timestamp),
91
+ // DATE
92
+ day = date.toLocaleDateString('en-US', { day: 'numeric' }),
93
+ month = date.toLocaleDateString('en-US', { month: 'short' }),
94
+ year = date.toLocaleDateString('en-US', { year: 'numeric' }),
95
+ hour = date.toLocaleTimeString('en-US', { hour: 'numeric', hour12: true }),
96
+ minute = date.toLocaleTimeString('en-US', { minute: 'numeric' }),
97
+ // ICON
98
+ icon = me.getIcon(undefined, undefined, record.size);
99
+
100
+ // Create a single Marker
101
+ return {
102
+ position: {
103
+ lat: record.latitude,
104
+ lng: record.longitude
105
+ },
106
+ title: `${day}, ${month} ${year}\n[${hour}:${minute}] ${record.humanReadableLocation}`,
107
+ record: record,
108
+ icon: icon
109
+ }
110
+ });
111
+
112
+ // Add to MarkerStore
113
+ me.markerStore.add(markers);
114
+ }
115
+
116
+ /**
117
+ * google.maps.SymbolPaths are not available in the worker.
118
+ * Therefore we are solving it here
119
+ *
120
+ * @param {String} symbol
121
+ * @returns {Number}
122
+ */
123
+ getType(symbol) {
124
+ // google.maps.SymbolPath...
125
+ const symbolPaths = {
126
+ "CIRCLE": 0,
127
+ "FORWARD_CLOSED_ARROW": 1,
128
+ "FORWARD_OPEN_ARROW": 2,
129
+ "BACKWARD_CLOSED_ARROW": 3,
130
+ "BACKWARD_OPEN_ARROW": 4
131
+ }
132
+
133
+ return symbolPaths[symbol]
134
+ }
135
+
136
+ /**
137
+ * Create an icon based on color, symbol and size
138
+ *
139
+ * @param {String} [color=red]
140
+ * @param {'CIRCLE' | 'FORWARD_CLOSED_ARROW' | 'FORWARD_OPEN_ARROW' | 'BACKWARD_CLOSED_ARROW' | 'BACKWARD_OPEN_ARROW'} [symbol=CIRCLE]
141
+ * @param {Number} [scaleMultiplier=1]
142
+ * @returns {{fillColor: string, path: Number, fillOpacity: number, strokeWeight: number, scale: number, strokeColor: string}}
143
+ */
144
+ getIcon(color='red', symbol = 'CIRCLE', scaleMultiplier = 1) {
145
+ const path = this.getType(symbol);
146
+
147
+ return {
148
+ path: path,
149
+ scale: 10 * scaleMultiplier,
150
+ strokeColor: `dark${color}`,
151
+ strokeWeight: 2,
152
+ fillColor: color,
153
+ fillOpacity: 1.0
154
+ }
155
+ }
156
+ }
157
+
158
+ Neo.applyClassConfig(MapComponent);
159
+
160
+ export default MapComponent;
@@ -0,0 +1,113 @@
1
+ import DialogBase from '../../../../src/dialog/Base.mjs';
2
+
3
+ /**
4
+ * @class Neo.examples.component.wrapper.googleMaps.MarkerDialog
5
+ * @extends Neo.dialog.Base
6
+ */
7
+ class MarkerDialog extends DialogBase {
8
+ static getConfig() {return {
9
+ className: 'Neo.examples.component.wrapper.googleMaps.MarkerDialog',
10
+
11
+ // turn off dragging and resizing
12
+ draggable : false,
13
+ resizable : false,
14
+
15
+ // custom property
16
+ record_: null,
17
+
18
+ containerConfig: {style: {padding: '10px'}},
19
+ headerConfig: {actions: ['close']},
20
+ // custom config used to align the popup
21
+ offsetConfig: {x: -15,y: -15},
22
+
23
+ items: [{
24
+ ntype: 'component',
25
+ cls: ['detail-container'],
26
+ vdom: {/* here goes the itemTpl */}
27
+ }],
28
+
29
+ itemTpl: data => [{
30
+ cls: 'detail-depth',
31
+ innerHTML: `Depth: ${data.depth}`
32
+ }, {
33
+ cls: 'detail-date',
34
+ innerHTML: `${data.visualDate}`
35
+ }, {
36
+ cls: 'detail-quality',
37
+ innerHTML: `Quality: ${data.quality}`
38
+ }, {
39
+ cls: 'detail-quality',
40
+ innerHTML: `Size: ${data.size}`
41
+ }]
42
+ }}
43
+
44
+ /**
45
+ * Update the view based on the data
46
+ * @param value
47
+ * @param oldValue
48
+ *
49
+ * @example
50
+ * depth: 11.9
51
+ * humanReadableLocation: "19,9 km N af Sigöldustöð"
52
+ * latitude: 64.35
53
+ * longitude : -19.173
54
+ * quality: 53.79
55
+ * size: 0.9
56
+ * timestamp: "2017-10-11T18:34:56.000Z"
57
+ */
58
+ afterSetRecord(value, oldValue) {
59
+ let me = this,
60
+ outputContainer = me.items[0],
61
+ vdom = outputContainer.vdom;
62
+
63
+ value.visualDate = me.calcVisualDate(value.timestamp);
64
+
65
+ me.title = `${value.humanReadableLocation}$ | ${value.size}`;
66
+ vdom.cn = me.itemTpl(value);
67
+ }
68
+
69
+ calcVisualDate(dateString) {
70
+ const date = new Date(dateString),
71
+ day = date.toLocaleDateString('en-US', { day: 'numeric' }),
72
+ month = date.toLocaleDateString('en-US', { month: 'short' }),
73
+ year = date.toLocaleDateString('en-US', { year: 'numeric' }),
74
+ hour = date.toLocaleTimeString('en-US', { hour: 'numeric', hour12: false }),
75
+ minute = date.toLocaleTimeString('en-US', { minute: 'numeric' });
76
+
77
+ return `${day}.${month}.<b>${year}</b> ${hour}:${minute}`
78
+ }
79
+
80
+ async onRender(data, automount) {
81
+ super.onRender(data, automount)
82
+
83
+ let me = this;
84
+
85
+ /**
86
+ * Center on Map
87
+ */
88
+ // let futureParent = Neo.getComponent(me.boundaryContainerId),
89
+ // futureParentRect = await futureParent.getDomRect(),
90
+ // rect = await me.getDomRect();
91
+ //
92
+ // me.wrapperStyle = {
93
+ // top: (futureParentRect.top + (futureParentRect.height - rect.height) / 2) + 'px',
94
+ // left: (futureParentRect.left + (futureParentRect.width - rect.width) / 2) + 'px',
95
+ // height: me.height,
96
+ // width: me.width
97
+ // }
98
+
99
+ /**
100
+ * Add to click position
101
+ */
102
+ me.wrapperStyle = {
103
+ top: me.domEvent.clientY + me.offsetConfig.y + 'px',
104
+ left: me.domEvent.clientX + me.offsetConfig.x + 'px',
105
+ height: me.height,
106
+ width: me.width
107
+ }
108
+ }
109
+ }
110
+
111
+ Neo.applyClassConfig(MarkerDialog);
112
+
113
+ export default MarkerDialog;
@@ -0,0 +1,463 @@
1
+ {
2
+ "results":[
3
+ {
4
+ "timestamp":"2017-10-13T12:07:24.000Z",
5
+ "latitude":63.976,
6
+ "longitude":-21.949,
7
+ "depth":1.1,
8
+ "size":0.6,
9
+ "quality":58.73,
10
+ "humanReadableLocation":"6,1 km SV af Helgafelli"
11
+ },
12
+ {
13
+ "timestamp":"2017-10-13T09:50:50.000Z",
14
+ "latitude":65.124,
15
+ "longitude":-16.288,
16
+ "depth":7.2,
17
+ "size":0.9,
18
+ "quality":78.51,
19
+ "humanReadableLocation":"6,1 km NA af Herðubreiðartöglum"
20
+ },
21
+ {
22
+ "timestamp":"2017-10-13T09:41:09.000Z",
23
+ "latitude":63.945,
24
+ "longitude":-21.143,
25
+ "depth":7.4,
26
+ "size":0.2,
27
+ "quality":33.12,
28
+ "humanReadableLocation":"6,5 km SSA af Hveragerði"
29
+ },
30
+ {
31
+ "timestamp":"2017-10-13T09:37:45.000Z",
32
+ "latitude":65.114,
33
+ "longitude":-16.3,
34
+ "depth":6.3,
35
+ "size":1.2,
36
+ "quality":90.01,
37
+ "humanReadableLocation":"5,0 km NA af Herðubreiðartöglum"
38
+ },
39
+ {
40
+ "timestamp":"2017-10-13T09:37:21.000Z",
41
+ "latitude":65.113,
42
+ "longitude":-16.301,
43
+ "depth":5.9,
44
+ "size":1.4,
45
+ "quality":90.01,
46
+ "humanReadableLocation":"4,9 km NA af Herðubreiðartöglum"
47
+ },
48
+ {
49
+ "timestamp":"2017-10-13T07:51:29.000Z",
50
+ "latitude":65.182,
51
+ "longitude":-16.358,
52
+ "depth":5,
53
+ "size":0.7,
54
+ "quality":39.63,
55
+ "humanReadableLocation":"1,0 km NNV af Herðubreið"
56
+ },
57
+ {
58
+ "timestamp":"2017-10-13T07:49:40.000Z",
59
+ "latitude":65.165,
60
+ "longitude":-16.354,
61
+ "depth":13.7,
62
+ "size":1.2,
63
+ "quality":90.01,
64
+ "humanReadableLocation":"1,0 km SSV af Herðubreið"
65
+ },
66
+ {
67
+ "timestamp":"2017-10-13T07:22:49.000Z",
68
+ "latitude":64.012,
69
+ "longitude":-20.58,
70
+ "depth":6,
71
+ "size":0.3,
72
+ "quality":63.77,
73
+ "humanReadableLocation":"4,6 km A af Hestfjalli"
74
+ },
75
+ {
76
+ "timestamp":"2017-10-13T07:05:44.000Z",
77
+ "latitude":66.534,
78
+ "longitude":-18.013,
79
+ "depth":6.3,
80
+ "size":1.2,
81
+ "quality":42.6,
82
+ "humanReadableLocation":"0,8 km S af Grímsey"
83
+ },
84
+ {
85
+ "timestamp":"2017-10-13T06:41:34.000Z",
86
+ "latitude":63.954,
87
+ "longitude":-21.255,
88
+ "depth":7.4,
89
+ "size":0.9,
90
+ "quality":57.5,
91
+ "humanReadableLocation":"5,4 km SA af Skálafelli á Hellisheiði"
92
+ },
93
+ {
94
+ "timestamp":"2017-10-13T06:23:10.000Z",
95
+ "latitude":64.659,
96
+ "longitude":-17.533,
97
+ "depth":4.3,
98
+ "size":1.2,
99
+ "quality":90.01,
100
+ "humanReadableLocation":"2,1 km N af Bárðarbungu"
101
+ },
102
+ {
103
+ "timestamp":"2017-10-13T05:33:43.000Z",
104
+ "latitude":64.022,
105
+ "longitude":-16.613,
106
+ "depth":1.1,
107
+ "size":1.1,
108
+ "quality":48.2,
109
+ "humanReadableLocation":"3,4 km ANA af Hvannadalshnjúk"
110
+ },
111
+ {
112
+ "timestamp":"2017-10-13T05:18:22.000Z",
113
+ "latitude":64.621,
114
+ "longitude":-17.348,
115
+ "depth":1.1,
116
+ "size":2.4,
117
+ "quality":90.15,
118
+ "humanReadableLocation":"8,8 km ASA af Bárðarbungu"
119
+ },
120
+ {
121
+ "timestamp":"2017-10-13T04:05:44.000Z",
122
+ "latitude":65.708,
123
+ "longitude":-16.833,
124
+ "depth":2.9,
125
+ "size":0.3,
126
+ "quality":38.43,
127
+ "humanReadableLocation":"3,6 km V af Kröfluvirkjun"
128
+ },
129
+ {
130
+ "timestamp":"2017-10-13T03:46:36.000Z",
131
+ "latitude":65.712,
132
+ "longitude":-16.817,
133
+ "depth":2.9,
134
+ "size":1.1,
135
+ "quality":90.01,
136
+ "humanReadableLocation":"2,8 km V af Kröfluvirkjun"
137
+ },
138
+ {
139
+ "timestamp":"2017-10-13T02:56:40.000Z",
140
+ "latitude":63.972,
141
+ "longitude":-21.56,
142
+ "depth":10.1,
143
+ "size":0.5,
144
+ "quality":64.38,
145
+ "humanReadableLocation":"4,5 km ASA af Bláfjallaskála"
146
+ },
147
+ {
148
+ "timestamp":"2017-10-13T02:12:22.000Z",
149
+ "latitude":65.215,
150
+ "longitude":-16.363,
151
+ "depth":10.2,
152
+ "size":1.4,
153
+ "quality":90.02,
154
+ "humanReadableLocation":"4,6 km N af Herðubreið"
155
+ },
156
+ {
157
+ "timestamp":"2017-10-13T01:39:43.000Z",
158
+ "latitude":65.216,
159
+ "longitude":-16.349,
160
+ "depth":5.8,
161
+ "size":1.1,
162
+ "quality":90.01,
163
+ "humanReadableLocation":"4,6 km N af Herðubreið"
164
+ },
165
+ {
166
+ "timestamp":"2017-10-13T01:38:32.000Z",
167
+ "latitude":65.215,
168
+ "longitude":-16.358,
169
+ "depth":6.3,
170
+ "size":1.1,
171
+ "quality":90.02,
172
+ "humanReadableLocation":"4,6 km N af Herðubreið"
173
+ },
174
+ {
175
+ "timestamp":"2017-10-13T00:22:11.000Z",
176
+ "latitude":64.669,
177
+ "longitude":-17.38,
178
+ "depth":1.1,
179
+ "size":2.7,
180
+ "quality":90.14,
181
+ "humanReadableLocation":"7,7 km ANA af Bárðarbungu"
182
+ },
183
+ {
184
+ "timestamp":"2017-10-13T00:01:12.000Z",
185
+ "latitude":64.632,
186
+ "longitude":-20.636,
187
+ "depth":1.7,
188
+ "size":1.5,
189
+ "quality":64.89,
190
+ "humanReadableLocation":"13,4 km ASA af Húsafelli"
191
+ },
192
+ {
193
+ "timestamp":"2017-10-12T20:08:36.000Z",
194
+ "latitude":64.673,
195
+ "longitude":-17.541,
196
+ "depth":3.1,
197
+ "size":0.9,
198
+ "quality":30.43,
199
+ "humanReadableLocation":"3,7 km N af Bárðarbungu"
200
+ },
201
+ {
202
+ "timestamp":"2017-10-12T20:01:04.000Z",
203
+ "latitude":63.925,
204
+ "longitude":-20.163,
205
+ "depth":8.2,
206
+ "size":1.1,
207
+ "quality":90.01,
208
+ "humanReadableLocation":"13,7 km SSA af Árnesi"
209
+ },
210
+ {
211
+ "timestamp":"2017-10-12T17:49:38.000Z",
212
+ "latitude":63.613,
213
+ "longitude":-19.308,
214
+ "depth":4.9,
215
+ "size":0.8,
216
+ "quality":30.83,
217
+ "humanReadableLocation":"4,1 km SV af Goðabungu"
218
+ },
219
+ {
220
+ "timestamp":"2017-10-12T14:48:47.000Z",
221
+ "latitude":63.818,
222
+ "longitude":-20.659,
223
+ "depth":8.1,
224
+ "size":1.8,
225
+ "quality":49.76,
226
+ "humanReadableLocation":"12,6 km S af Þjórsárbrú"
227
+ },
228
+ {
229
+ "timestamp":"2017-10-12T14:47:07.000Z",
230
+ "latitude":63.672,
231
+ "longitude":-19.674,
232
+ "depth":1.3,
233
+ "size":2,
234
+ "quality":45.93,
235
+ "humanReadableLocation":"9,5 km V af Básum"
236
+ },
237
+ {
238
+ "timestamp":"2017-10-12T14:27:55.000Z",
239
+ "latitude":64.354,
240
+ "longitude":-20.674,
241
+ "depth":3.3,
242
+ "size":1.2,
243
+ "quality":90.01,
244
+ "humanReadableLocation":"6,8 km SSA af Skjaldbreið"
245
+ },
246
+ {
247
+ "timestamp":"2017-10-12T13:27:11.000Z",
248
+ "latitude":65.229,
249
+ "longitude":-16.357,
250
+ "depth":12.8,
251
+ "size":0.5,
252
+ "quality":32.22,
253
+ "humanReadableLocation":"6,1 km N af Herðubreið"
254
+ },
255
+ {
256
+ "timestamp":"2017-10-12T12:48:05.000Z",
257
+ "latitude":65.024,
258
+ "longitude":-16.677,
259
+ "depth":5.2,
260
+ "size":1.5,
261
+ "quality":41.19,
262
+ "humanReadableLocation":"3,7 km VSV af Dreka"
263
+ },
264
+ {
265
+ "timestamp":"2017-10-12T12:47:38.000Z",
266
+ "latitude":65.018,
267
+ "longitude":-16.672,
268
+ "depth":4.4,
269
+ "size":1,
270
+ "quality":44.51,
271
+ "humanReadableLocation":"3,9 km SV af Dreka"
272
+ },
273
+ {
274
+ "timestamp":"2017-10-12T12:46:20.000Z",
275
+ "latitude":65.036,
276
+ "longitude":-16.691,
277
+ "depth":2.3,
278
+ "size":0.6,
279
+ "quality":47.96,
280
+ "humanReadableLocation":"4,1 km V af Dreka"
281
+ },
282
+ {
283
+ "timestamp":"2017-10-12T11:45:39.000Z",
284
+ "latitude":63.513,
285
+ "longitude":-19.268,
286
+ "depth":1.1,
287
+ "size":1.3,
288
+ "quality":90.01,
289
+ "humanReadableLocation":"11,2 km SV af Hábungu"
290
+ },
291
+ {
292
+ "timestamp":"2017-10-12T11:40:49.000Z",
293
+ "latitude":63.628,
294
+ "longitude":-19.072,
295
+ "depth":1.1,
296
+ "size":-0.1,
297
+ "quality":44.18,
298
+ "humanReadableLocation":"5,5 km NNA af Hábungu"
299
+ },
300
+ {
301
+ "timestamp":"2017-10-12T08:25:28.000Z",
302
+ "latitude":63.618,
303
+ "longitude":-19.102,
304
+ "depth":0.6,
305
+ "size":0,
306
+ "quality":79.03,
307
+ "humanReadableLocation":"4,2 km N af Hábungu"
308
+ },
309
+ {
310
+ "timestamp":"2017-10-12T08:21:54.000Z",
311
+ "latitude":63.618,
312
+ "longitude":-19.094,
313
+ "depth":1.1,
314
+ "size":-0.5,
315
+ "quality":48.38,
316
+ "humanReadableLocation":"4,2 km N af Hábungu"
317
+ },
318
+ {
319
+ "timestamp":"2017-10-12T06:38:38.000Z",
320
+ "latitude":65.168,
321
+ "longitude":-16.417,
322
+ "depth":7.6,
323
+ "size":1.2,
324
+ "quality":68.29,
325
+ "humanReadableLocation":"3,3 km VSV af Herðubreið"
326
+ },
327
+ {
328
+ "timestamp":"2017-10-12T04:17:38.000Z",
329
+ "latitude":64.033,
330
+ "longitude":-21.221,
331
+ "depth":6.4,
332
+ "size":0.4,
333
+ "quality":85.02,
334
+ "humanReadableLocation":"4,0 km NNV af Hveragerði"
335
+ },
336
+ {
337
+ "timestamp":"2017-10-12T04:00:31.000Z",
338
+ "latitude":63.804,
339
+ "longitude":-22.793,
340
+ "depth":6.7,
341
+ "size":2.2,
342
+ "quality":90.02,
343
+ "humanReadableLocation":"4,3 km V af Reykjanestá"
344
+ },
345
+ {
346
+ "timestamp":"2017-10-12T03:19:07.000Z",
347
+ "latitude":64.014,
348
+ "longitude":-16.603,
349
+ "depth":1.2,
350
+ "size":0.9,
351
+ "quality":43.19,
352
+ "humanReadableLocation":"3,8 km A af Hvannadalshnjúk"
353
+ },
354
+ {
355
+ "timestamp":"2017-10-12T02:05:45.000Z",
356
+ "latitude":63.919,
357
+ "longitude":-21.719,
358
+ "depth":2.9,
359
+ "size":1,
360
+ "quality":90.01,
361
+ "humanReadableLocation":"8,0 km SSV af Bláfjallaskála"
362
+ },
363
+ {
364
+ "timestamp":"2017-10-12T01:50:54.000Z",
365
+ "latitude":63.798,
366
+ "longitude":-22.793,
367
+ "depth":6.6,
368
+ "size":1.4,
369
+ "quality":90.01,
370
+ "humanReadableLocation":"4,3 km V af Reykjanestá"
371
+ },
372
+ {
373
+ "timestamp":"2017-10-12T01:15:10.000Z",
374
+ "latitude":63.635,
375
+ "longitude":-19.142,
376
+ "depth":1.1,
377
+ "size":2,
378
+ "quality":90.01,
379
+ "humanReadableLocation":"5,4 km A af Goðabungu"
380
+ },
381
+ {
382
+ "timestamp":"2017-10-12T00:14:48.000Z",
383
+ "latitude":63.674,
384
+ "longitude":-19.125,
385
+ "depth":4.1,
386
+ "size":0.2,
387
+ "quality":34.25,
388
+ "humanReadableLocation":"7,2 km ANA af Goðabungu"
389
+ },
390
+ {
391
+ "timestamp":"2017-10-11T22:40:01.000Z",
392
+ "latitude":66.251,
393
+ "longitude":-16.709,
394
+ "depth":4.4,
395
+ "size":1,
396
+ "quality":34.97,
397
+ "humanReadableLocation":"12,8 km VSV af Kópaskeri"
398
+ },
399
+ {
400
+ "timestamp":"2017-10-11T21:09:29.000Z",
401
+ "latitude":66.283,
402
+ "longitude":-16.751,
403
+ "depth":5.6,
404
+ "size":1.1,
405
+ "quality":55.62,
406
+ "humanReadableLocation":"13,5 km V af Kópaskeri"
407
+ },
408
+ {
409
+ "timestamp":"2017-10-11T21:08:48.000Z",
410
+ "latitude":66.282,
411
+ "longitude":-16.743,
412
+ "depth":4.5,
413
+ "size":1.1,
414
+ "quality":80.86,
415
+ "humanReadableLocation":"13,2 km V af Kópaskeri"
416
+ },
417
+ {
418
+ "timestamp":"2017-10-11T19:21:13.000Z",
419
+ "latitude":66.559,
420
+ "longitude":-18.052,
421
+ "depth":9.1,
422
+ "size":2.8,
423
+ "quality":90.03,
424
+ "humanReadableLocation":"2,7 km NV af Grímsey"
425
+ },
426
+ {
427
+ "timestamp":"2017-10-11T18:34:56.000Z",
428
+ "latitude":64.35,
429
+ "longitude":-19.173,
430
+ "depth":11.9,
431
+ "size":0.9,
432
+ "quality":53.79,
433
+ "humanReadableLocation":"19,9 km N af Sigöldustöð"
434
+ },
435
+ {
436
+ "timestamp":"2017-10-11T17:28:01.000Z",
437
+ "latitude":64.794,
438
+ "longitude":-16.906,
439
+ "depth":2.8,
440
+ "size":0.9,
441
+ "quality":36.64,
442
+ "humanReadableLocation":"14,4 km A af Kistufelli"
443
+ },
444
+ {
445
+ "timestamp":"2017-10-11T14:34:29.000Z",
446
+ "latitude":65.234,
447
+ "longitude":-16.33,
448
+ "depth":6.2,
449
+ "size":0.9,
450
+ "quality":42.59,
451
+ "humanReadableLocation":"6,6 km NV af Herðubreiðarlindum"
452
+ },
453
+ {
454
+ "timestamp":"2017-10-11T14:16:22.000Z",
455
+ "latitude":64.662,
456
+ "longitude":-17.082,
457
+ "depth":2.3,
458
+ "size":0.7,
459
+ "quality":39.3,
460
+ "humanReadableLocation":"14,5 km SSA af Kistufelli"
461
+ }
462
+ ]
463
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neo.mjs",
3
- "version": "4.4.14",
3
+ "version": "4.4.16",
4
4
  "description": "The webworkers driven UI framework",
5
5
  "type": "module",
6
6
  "repository": {
@@ -44,6 +44,11 @@ class GoogleMaps extends Base {
44
44
  */
45
45
  className: 'Neo.component.wrapper.GoogleMaps',
46
46
  /**
47
+ * @member {String} ntype='googlemaps'
48
+ * @protected
49
+ */
50
+ ntype: 'googlemaps',
51
+ /**
47
52
  * Specify lat & lng for the current focus position
48
53
  * @member {Object} center_={lat: -34.397, lng: 150.644}
49
54
  */
@@ -58,6 +63,9 @@ class GoogleMaps extends Base {
58
63
  fields: [{
59
64
  name: 'id',
60
65
  type: 'String'
66
+ }, {
67
+ name: 'icon',
68
+ type: 'Object'
61
69
  }, {
62
70
  name: 'position',
63
71
  type: 'Object'
@@ -285,11 +293,13 @@ class GoogleMaps extends Base {
285
293
  let me = this,
286
294
  record = me.markerStore.get(data.id);
287
295
 
288
- me.onMarkerClick(record);
296
+ data.record = record;
297
+
298
+ me.onMarkerClick(data);
289
299
 
290
300
  me.fire('markerClick', {
291
301
  id: me.id,
292
- record
302
+ data
293
303
  })
294
304
  }
295
305
 
@@ -188,7 +188,7 @@ class Base extends Component {
188
188
  createItem(item, index) {
189
189
  let me = this,
190
190
  config = {appName: me.appName, parentId: me.id, parentIndex: index},
191
- defaults = me.itemDefaults,
191
+ defaults = {...me.itemDefaults},
192
192
  lazyLoadItem, module;
193
193
 
194
194
  if (defaults) {
@@ -164,13 +164,13 @@ class GoogleMaps extends Base {
164
164
  * @param {Object} event.domEvent
165
165
  */
166
166
  onMarkerClick(marker, event) {
167
- // in theory, we could parse and pass the entire DOM event.
168
- // feel free to open a feature request ticket, in case you need more data into the app worker.
167
+ let transformedEvent = DomEvents.getMouseEventData(event.domEvent);
169
168
 
170
169
  DomEvents.sendMessageToApp({
171
170
  id : marker.neoId,
172
171
  path: [{cls: [], id: marker.neoMapId}],
173
- type: 'googleMarkerClick'
172
+ type: 'googleMarkerClick',
173
+ domEvent: transformedEvent
174
174
  })
175
175
  }
176
176
 
@@ -26,6 +26,7 @@ class Component extends Base {
26
26
  construct(config) {
27
27
  super.construct(config);
28
28
  Neo.getComponent = this.getById.bind(this); // alias
29
+ Neo.first = this.getFirst.bind(this); // alias
29
30
  }
30
31
 
31
32
  /**
@@ -61,7 +62,9 @@ class Component extends Base {
61
62
  configLength = configArray.length;
62
63
 
63
64
  configArray.forEach(([key, value]) => {
64
- if (component[key] === value) {
65
+ if ((component[key] === value)
66
+ || (key === 'ntype' && me.hasPrototypePropertyValue(component, key, value)))
67
+ {
65
68
  matchArray.push(true);
66
69
  }
67
70
  });
@@ -144,6 +147,88 @@ class Component extends Base {
144
147
 
145
148
  return childComponents;
146
149
  }
150
+
151
+ /**
152
+ * !! For debugging purposes only !!
153
+ *
154
+ * Get the first component based on the nytpe or other properties
155
+ *
156
+ * @param {String|Object|Array} componentDescription
157
+ * @returns {Neo.component.Base|null|Neo.component.Base[]}
158
+ *
159
+ * @example
160
+ // as String: ntype[comma separated propterties]
161
+ Neo.first('toolbar button[text=Try me,icon=people]')
162
+ // as Object: Add properties. ntype is optional
163
+ Neo.first({
164
+ icon: 'people'
165
+ })
166
+ // as Array: An Array of Objects. No Strings allowed
167
+ Neo.first([{
168
+ ntype: 'toolbar'
169
+ },{
170
+ ntype: 'button', text: 'Try me', icon: 'people
171
+ }])
172
+
173
+ * The returnFirstMatch flag allows to return all items and
174
+ * not stop after the first result.
175
+ *
176
+ * @example
177
+ Neo.first('button', false) // => [Button, Button, Button]
178
+ */
179
+ getFirst(componentDescription, returnFirstMatch = true) {
180
+ let objects = [],
181
+ app = Neo.apps[Object.keys(Neo.apps)[0]],
182
+ root = app.mainView;
183
+
184
+ /* create an array of objects from string */
185
+ if(Neo.isString(componentDescription)) {
186
+ const regex = /(\w*)(\[[^\]]*\])|(\w*)/g;
187
+ let match;
188
+
189
+ /* generate objects which contain the information */
190
+ while (match = regex.exec(componentDescription)) {
191
+ let [, ntype, pairs, ntypeOnly] = match, obj;
192
+
193
+ ntype = ntype || ntypeOnly;
194
+ obj = {ntype};
195
+
196
+ if(pairs) {
197
+ const pairsRegex = /\[(.*?)\]/,
198
+ pairsMatch = pairs.match(pairsRegex);
199
+
200
+ if(pairsMatch) {
201
+ const pairs = pairsMatch[1].split(',');
202
+ pairs.forEach((pair) => {
203
+ const [key, value] = pair.split('=');
204
+ obj[key] = value.replace(/"/g, '');
205
+ });
206
+ }
207
+ }
208
+ objects.push(obj);
209
+
210
+ regex.lastIndex++;
211
+ }
212
+ } else if (Neo.isObject(componentDescription)){
213
+ objects.push(componentDescription);
214
+ } else if (Neo.isArray(componentDescription)) {
215
+ objects = componentDescription;
216
+ }
217
+
218
+ /* find the correct child using down() */
219
+ const result = objects.reduce((acc, key) => {
220
+ if(acc) {
221
+ let child = acc.down(key, returnFirstMatch);
222
+
223
+ if(!!child) {
224
+ return child;
225
+ }
226
+ }
227
+ return null;
228
+ }, root);
229
+
230
+ return result
231
+ }
147
232
 
148
233
  /**
149
234
  * Returns an Array containing the ids of all parent components for a given component
@@ -205,6 +290,25 @@ class Component extends Base {
205
290
 
206
291
  return parents;
207
292
  }
293
+
294
+ /**
295
+ * Check if the component had a property of any value somewhere in the Prototype chain
296
+ *
297
+ * @param {Neo.component.Base} component
298
+ * @param {String} property
299
+ * @param {*} value
300
+ * @returns {boolean}
301
+ */
302
+ hasPrototypePropertyValue(component, property, value) {
303
+ while (component !== null) {
304
+ if (component.hasOwnProperty(property) && component[property] === value) {
305
+ return true;
306
+ }
307
+ component = component.__proto__;
308
+ }
309
+
310
+ return false;
311
+ }
208
312
 
209
313
  /**
210
314
  * Returns the first component which matches the config-selector.
@@ -38,7 +38,7 @@ class Base extends Container {
38
38
  */
39
39
  dock_: 'top',
40
40
  /**
41
- * @member {Object} itemDefaults={ntype: 'button'}
41
+ * @member {Object} itemDefaults={ntype:'button'}
42
42
  */
43
43
  itemDefaults: {
44
44
  ntype: 'button'