@osimatic/helpers-js 1.5.18 → 1.5.20

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.
@@ -56,10 +56,6 @@ class TelephoneNumber {
56
56
  TelephoneNumber.localCountryCode = countryCode;
57
57
  }
58
58
 
59
- static setIntlTelInputUtilsPath(path) {
60
- TelephoneNumber.intlTelInputUtilsPath = path;
61
- }
62
-
63
59
  static getCountryIsoCode(phoneNumber, localCountryIsoCode=TelephoneNumber.localCountryCode) {
64
60
  try {
65
61
  const number = libphonenumber.parsePhoneNumber(phoneNumber, localCountryIsoCode.toUpperCase());
@@ -172,12 +168,10 @@ class TelephoneNumber {
172
168
 
173
169
  static setIntlTelInput(input, placeholderNumberType) {
174
170
  TelephoneNumber.localCountryCode = typeof TelephoneNumber.localCountryCode != 'undefined' ? TelephoneNumber.localCountryCode : null;
175
- TelephoneNumber.intlTelInputUtilsPath = typeof TelephoneNumber.intlTelInputUtilsPath != 'undefined' ? TelephoneNumber.intlTelInputUtilsPath : null;
176
171
 
177
172
  return intlTelInputLib(input[0], {
178
173
  initialCountry: null != TelephoneNumber.localCountryCode ? TelephoneNumber.localCountryCode.toLowerCase() : null, // depuis version 19.x, le code pays doit être en minuscule
179
174
  placeholderNumberType: placeholderNumberType || 'FIXED_LINE_OR_MOBILE',
180
- utilsScript: TelephoneNumber.intlTelInputUtilsPath
181
175
  });
182
176
  }
183
177
 
package/location.js CHANGED
@@ -17,6 +17,9 @@ class Country {
17
17
 
18
18
  static fillCountrySelect(select, defaultValue=null, countriesList=null, addNoneValue=false, noneLabel='- Aucun -') {
19
19
  select = toEl(select);
20
+ if (!select) {
21
+ return;
22
+ }
20
23
  if (select.children.length === 0) {
21
24
  if (addNoneValue) {
22
25
  select.insertAdjacentHTML('beforeend', '<option value="">'+noneLabel+'</option>');
@@ -1,4 +1,5 @@
1
1
  const L = require('leaflet');
2
+ require('leaflet-draw');
2
3
  const { toEl } = require('./util');
3
4
 
4
5
  /**
@@ -7,27 +8,6 @@ const { toEl } = require('./util');
7
8
  * https://www.openstreetmap.org/help
8
9
  */
9
10
  class OpenStreetMap {
10
-
11
- constructor(mapContainer, options={}) {
12
- mapContainer = toEl(mapContainer);
13
- /*let [lat, lng] = button.data('coordinates').split(',');
14
- let map = L.map('modal_map_canvas2').setView([lat, lng], 17);
15
-
16
- L.marker([lat, lng], {
17
- icon: L.icon({iconUrl: getIconOfMapMarker(button.data('type_marker'))}),
18
- title: popoverContent.title
19
- //popupopen: setTimeout(displayEmployeesAndCompaniesAndTasks, 250)
20
- }).addTo(map)
21
- .bindPopup(popoverContent.content)
22
- //.openPopup()
23
- ;*/
24
-
25
- this.markers = [];
26
- this.locations = [];
27
-
28
- this.map = OpenStreetMap.createMap(mapContainer, options);
29
- }
30
-
31
11
  static createMap(mapContainer, options={}) {
32
12
  mapContainer = toEl(mapContainer);
33
13
  if (!mapContainer) {
@@ -51,6 +31,58 @@ class OpenStreetMap {
51
31
  return map;
52
32
  }
53
33
 
34
+ /**
35
+ * Initialize a draw control on a Leaflet map.
36
+ * @param {L.Map} map
37
+ * @param {object} options
38
+ * @param {boolean} options.polygonAllowed
39
+ * @param {function} options.onCreated - callback(type: 'point'|'polygon', data: {lat,long}|{latlngs})
40
+ * @param {function} options.onDeleted - callback()
41
+ * @param {function} options.onEdited - callback(type, data)
42
+ * @returns {L.Control.Draw}
43
+ */
44
+ static initDrawControl(map, options = {}) {
45
+ if (!map) {
46
+ return null;
47
+ }
48
+
49
+ const { polygonAllowed = false, onCreated, onDeleted, onEdited } = options;
50
+
51
+ const drawn = new L.FeatureGroup().addTo(map);
52
+ const drawControl = new L.Control.Draw({
53
+ draw: {
54
+ polygon: polygonAllowed ? { allowIntersection: false, showArea: true } : false,
55
+ polyline: false, rectangle: false, circle: false, circlemarker: false,
56
+ marker: true
57
+ },
58
+ edit: { featureGroup: drawn, remove: true }
59
+ });
60
+ map.addControl(drawControl);
61
+
62
+ if (typeof onCreated === 'function') {
63
+ map.on('draw:created', (e) => {
64
+ if (e.layerType === 'marker') {
65
+ const { lat, lng: long } = e.layer.getLatLng();
66
+ onCreated('point', { lat, long }, e.layer);
67
+ } else if (polygonAllowed && e.layerType === 'polygon') {
68
+ onCreated('polygon', { latlngs: e.layer.getLatLngs()[0] }, e.layer);
69
+ }
70
+ drawn.addLayer(e.layer);
71
+ });
72
+ }
73
+ if (typeof onDeleted === 'function') {
74
+ map.on('draw:deleted', () => onDeleted());
75
+ }
76
+ if (typeof onEdited === 'function') {
77
+ map.on('draw:edited', (e) => {
78
+ // pass raw event for flexibility
79
+ onEdited(e);
80
+ });
81
+ }
82
+
83
+ return drawControl;
84
+ }
85
+
54
86
  static getUrl(latitude, longitude) {
55
87
  return 'https://www.openstreetmap.org/?mlat='+latitude+'&mlon='+longitude+'#map=17/'+latitude+'/'+longitude+'&layers=N';
56
88
  //return 'https://www.openstreetmap.org/#map=17/'+latitude+'/'+longitude+'';
@@ -61,57 +93,261 @@ class OpenStreetMap {
61
93
  return OpenStreetMap.getUrl(parseFloat(locationCoordinates[0]), parseFloat(locationCoordinates[1]));
62
94
  }
63
95
 
64
- setZoom(zoom) {
65
- this.map.setZoom(zoom);
96
+ static centerOnFrance(map) {
97
+ if (!map) {
98
+ return;
99
+ }
100
+
101
+ map.setView([46.52863469527167, 2.43896484375], 6);
66
102
  }
67
103
 
68
- deleteMarkers() {
69
- this.locations = [];
104
+ static getCountryBoundingBoxes() {
105
+ return {
106
+ // Europe
107
+ "fr": [[41.333, -5.142], [51.091, 9.559]], // France,
108
+ "de": [[47.270, 5.866], [55.058, 15.041]], // Germany
109
+ "es": [[27.642, -18.167], [43.792, 4.327]], // Spain incl. Canaries (approx)
110
+ "it": [[36.619, 6.627], [47.095, 18.520]], // Italy
111
+ "pt": [[36.840, -9.500], [42.280, -6.190]], // Portugal
112
+ "be": [[49.497, 2.545], [51.505, 6.407]], // Belgium
113
+ "nl": [[50.753, 3.358], [53.555, 7.227]], // Netherlands
114
+ "ch": [[45.818, 5.957], [47.808, 10.492]], // Switzerland
115
+ "at": [[46.372, 9.530], [49.021, 17.162]], // Austria
116
+ "gb": [[49.959, -8.649], [59.478, 1.759]], // United Kingdom,
117
+ "ie": [[51.390, -10.480], [55.387, -5.432]], // Ireland
118
+ "pl": [[49.003, 14.123], [54.836, 24.145]], // Poland
119
+ "se": [[55.340, 11.112], [69.061, 24.177]], // Sweden
120
+ "no": [[57.980, 4.500], [71.188, 31.078]], // Norway (Mainland approx)
121
+ "fi": [[59.810, 20.556], [70.092, 31.586]], // Finland
122
+ "dk": [[54.560, 8.089], [57.752, 12.690]], // Denmark
123
+
124
+ // Afrique / Moyen-Orient
125
+ "ma": [[27.662, -13.172], [35.922, -0.996]], // Morocco
126
+ "dz": [[18.976, -8.669], [37.093, 11.999]], // Algeria
127
+ "tn": [[30.233, 7.524], [37.544, 11.598]], // Tunisia
128
+ "eg": [[21.725, 24.700], [31.667, 36.895]], // Egypt
129
+ "za": [[-34.833, 16.470], [-22.126, 32.893]], // South Africa
130
+ "sa": [[15.615, 34.495], [32.154, 55.666]], // Saudi Arabia
131
+ "ae": [[22.634, 51.570], [26.084, 56.383]], // United Arab Emirates
132
+ "il": [[29.487, 34.268], [33.277, 35.876]], // Israel
70
133
 
71
- //this.markers.forEach(marker => marker.setMap(null));
134
+ // Amériques
135
+ "us": [[24.396, -124.848], [49.384, -66.885]], // United States (Contiguous)
136
+ "ca": [[41.675, -141.000], [83.113, -52.648]], // Canada
137
+ "mx": [[14.538, -118.365], [32.720, -86.711]], // Mexico
138
+ "br": [[-33.751, -73.987], [5.271, -34.729]], // Brazil
139
+ "ar": [[-55.051, -73.582], [-21.781, -53.591]], // Argentina
72
140
 
73
- this.markers.length = 0;
74
- this.markers = [];
141
+ // Asie / Océanie
142
+ "cn": [[18.159, 73.499], [53.560, 134.772]], // China (mainland approx)
143
+ "in": [[6.554, 68.176], [35.674, 97.402]], // India
144
+ "jp": [[24.249, 122.938], [45.557, 153.987]], // Japan
145
+ "au": [[-43.740, 112.921], [-10.668, 153.639]], // Australia
146
+ "nz": [[-47.290, 166.509], [-34.392, 178.517]], // New Zealand
147
+ };
75
148
  }
76
149
 
77
- addMarkers(listLocations, icon) {
78
- if (listLocations.length === 0) {
150
+ static getCountryBoundingBox(countryIsoCode) {
151
+ if (!countryIsoCode) {
152
+ return null;
153
+ }
154
+
155
+ const key = countryIsoCode.toLowerCase().trim();
156
+ const countryBox = OpenStreetMap.getCountryBoundingBoxes()[key];
157
+ return countryBox ? countryBox : null;
158
+ }
159
+
160
+ static centerMapOnCountry(map, countryIsoCode, opts = {}) {
161
+ if (!map) {
162
+ return;
163
+ }
164
+
165
+ const boundingBox = OpenStreetMap.getCountryBoundingBox(countryIsoCode);
166
+ if (null === boundingBox) {
79
167
  return;
80
168
  }
81
169
 
82
- listLocations.forEach(location => this.addMarker(location, icon));
170
+ const padding = Array.isArray(opts.padding) ? opts.padding : [20, 20];
171
+ const minZoom = Number.isFinite(opts.minZoom) ? opts.minZoom : 3;
172
+ const maxZoomSmall = Number.isFinite(opts.maxZoomSmall) ? opts.maxZoomSmall : 10;
173
+ const maxZoomTiny = Number.isFinite(opts.maxZoomTiny) ? opts.maxZoomTiny : 12;
174
+
175
+ // Estimation de "taille" en degrés
176
+ const [[S, W], [N, E]] = boundingBox;
177
+ const latSpan = Math.max(0.0001, Math.abs(N - S));
178
+ const lonSpan = Math.max(0.0001, Math.abs(E - W));
179
+ const areaDeg = latSpan * lonSpan;
180
+
181
+ // Heuristique de zoom maximal selon la taille du pays (en degrés²)
182
+ // (fitBounds choisira le zoom, plafonné par maxZoom ci-dessous)
183
+ let maxZoom;
184
+ if (areaDeg > 200) { // très grand (US, CA, AU, BR, CN)
185
+ maxZoom = 7;
186
+ } else if (areaDeg > 50) { // grand
187
+ maxZoom = 8;
188
+ } else if (areaDeg > 20) { // moyen+
189
+ maxZoom = 9;
190
+ } else if (areaDeg > 5) { // moyen/petit
191
+ maxZoom = maxZoomSmall; // ~10
192
+ } else { // petit/micro-état
193
+ maxZoom = maxZoomTiny; // ~12
194
+ }
195
+
196
+ // fitBounds avec maxZoom pour éviter d'over-zoomer les petits pays
197
+ const bounds = L.latLngBounds([ [S, W], [N, E] ]);
198
+ map.fitBounds(bounds, { padding, maxZoom });
199
+ if (map.getZoom() < minZoom) {
200
+ map.setZoom(minZoom);
201
+ }
83
202
  }
84
203
 
85
- addMarker(coordinates, options) {
204
+ static centerMapToLocations(map, locationsList, padding=[20,20], maxZoom=18) {
205
+ if (!map || locationsList.length === 0) {
206
+ return;
207
+ }
208
+
209
+ map.invalidateSize(false);
210
+
211
+ const bounds = L.latLngBounds(locationsList);
212
+ map.fitBounds(bounds, { padding: padding });
213
+ if (map.getZoom() > maxZoom) {
214
+ map.setZoom(maxZoom);
215
+ }
216
+ }
217
+
218
+ static centerMapToGooglePlace(map, place) {
219
+ if (place && place.geometry && place.geometry.location) {
220
+ const loc = place.geometry.location;
221
+ OpenStreetMap.centerMapToCoordinates(map, loc.lat(), loc.lng());
222
+ }
223
+ }
224
+
225
+ static centerMapToCoordinates(map, lat, long) {
226
+ if (!map) {
227
+ return;
228
+ }
229
+ map.setView([lat, long], Math.max(map.getZoom(), 15));
230
+ }
231
+
232
+ static clearSelections(map) {
233
+ if (map) {
234
+ map.eachLayer((layer) => {
235
+ if (layer instanceof L.Marker) {
236
+ layer.remove();
237
+ }
238
+ });
239
+ }
240
+ }
241
+
242
+ static addTempMarker(map, lat, lon, onDragEnd) {
243
+ const tempLayer = L.marker([lat, lon], { draggable: true });
244
+ map.addLayer(tempLayer);
245
+ if (typeof onDragEnd === 'function') {
246
+ tempLayer.on('dragend', function(e) {
247
+ onDragEnd(e.target);
248
+ });
249
+ }
250
+ return tempLayer;
251
+ }
252
+
253
+ static resetTempSelection(map, tempLayer) {
254
+ if (tempLayer && map) {
255
+ map.removeLayer(tempLayer);
256
+ }
257
+ }
258
+
259
+ static destroyMap(map) {
260
+ if (!map) {
261
+ return;
262
+ }
263
+
264
+ map.off();
265
+ map.remove();
266
+ }
267
+
268
+ static setZoom(map, zoom) {
269
+ if (!map) {
270
+ return;
271
+ }
272
+
273
+ map.setZoom(zoom);
274
+ }
275
+
276
+ static setView(map, location, zoom) {
277
+ if (!map) {
278
+ return;
279
+ }
280
+
281
+ map.setView(location, zoom);
282
+ }
283
+
284
+ static addMarker(map, coordinates, options) {
285
+ if (!map) {
286
+ return null;
287
+ }
288
+
86
289
  let locationCoordinates = coordinates.split(',');
87
290
  let latitude = parseFloat(locationCoordinates[0]);
88
291
  let longitude = parseFloat(locationCoordinates[1]);
89
292
 
90
- let marker = L.marker([latitude, longitude], {
91
- icon: L.icon({
293
+ const markerOptions = {};
294
+ if (options['icon']) {
295
+ markerOptions.icon = L.icon({
92
296
  iconUrl: options['icon'],
93
- iconSize: [22, 32],
94
- }),
95
- title: options['title'],
96
- });
297
+ iconSize: [22, 32]
298
+ });
299
+ }
300
+ if (options['title']) {
301
+ markerOptions.title = options['title'];
302
+ }
97
303
 
98
- //marker.on('click', () => {
99
- marker.on('popupopen', () => {
100
- //console.log('popupopen');
101
- if (typeof options['on_click'] == 'function') {
102
- options['on_click']();
103
- }
104
- return false;
105
- });
106
- marker.addTo(this.map);
107
- marker.bindPopup(options['popup']);
304
+ let marker = L.marker([latitude, longitude], markerOptions);
108
305
 
109
- this.markers.push(marker);
110
- this.locations.push([latitude, longitude]);
306
+ if (options['on_click'] || options['popupopen']) {
307
+ marker.on('popupopen', () => {
308
+ if (typeof options['on_click'] == 'function') {
309
+ options['on_click']();
310
+ }
311
+ if (typeof options['popupopen'] == 'function') {
312
+ options['popupopen']();
313
+ }
314
+ return false;
315
+ });
316
+ }
317
+
318
+ marker.addTo(map);
319
+
320
+ if (options['popup']) {
321
+ marker.bindPopup(options['popup']);
322
+ }
323
+
324
+ return marker;
111
325
  }
112
326
 
113
- addGeoJson(geoJson, options) {
114
- OpenStreetMap.displayGeoJSONOnMap(this.map, geoJson, options);
327
+ static addMarkers(map, listLocations, icon) {
328
+ if (!map || listLocations.length === 0) {
329
+ return [];
330
+ }
331
+ return listLocations.map(location => OpenStreetMap.addMarker(map, location, icon));
332
+ }
333
+
334
+ static connectMarkers(map, locations) {
335
+ if (!map || locations.length === 0) {
336
+ return;
337
+ }
338
+
339
+ let prevLocation = null;
340
+ let listLineCoordinates = [];
341
+ locations.forEach(location => {
342
+ if (prevLocation != null) {
343
+ listLineCoordinates.push([prevLocation, location]);
344
+ }
345
+ prevLocation = location;
346
+ });
347
+
348
+ listLineCoordinates.forEach(line => {
349
+ L.polyline(line, {color: '#728bec'}).addTo(map);
350
+ });
115
351
  }
116
352
 
117
353
  /**
@@ -199,7 +435,7 @@ class OpenStreetMap {
199
435
  console.warn('displayGeoJSONOnMap: Polygon invalide');
200
436
  return null;
201
437
  }
202
- // Leaflet accepte un tableau danneaux pour L.polygon
438
+ // Leaflet accepte un tableau d'anneaux pour L.polygon
203
439
  const poly = L.polygon(rings, polygonStyle);
204
440
  addLayer(poly);
205
441
 
@@ -215,168 +451,102 @@ class OpenStreetMap {
215
451
  return null;
216
452
  }
217
453
 
218
- setView(location, zoom) {
219
- this.map.setView(location, zoom);
220
- }
454
+ }
221
455
 
222
- centerOnFrance() {
223
- OpenStreetMap.centerOnFrance(this.map);
224
- }
456
+ class OsmMap {
225
457
 
226
- static centerOnFrance(map) {
227
- map.setView([46.52863469527167, 2.43896484375], 6);
458
+ constructor(mapContainer, options={}) {
459
+ mapContainer = toEl(mapContainer);
460
+ this.markers = [];
461
+ this.locations = [];
462
+ this.tempSelection = null;
463
+ this.tempLayer = null;
464
+ this.map = OpenStreetMap.createMap(mapContainer, options);
228
465
  }
229
466
 
230
- static getCountryBoundingBoxes() {
231
- return {
232
- // Europe
233
- "fr": [[41.333, -5.142], [51.091, 9.559]], // France,
234
- "de": [[47.270, 5.866], [55.058, 15.041]], // Germany
235
- "es": [[27.642, -18.167], [43.792, 4.327]], // Spain incl. Canaries (approx)
236
- "it": [[36.619, 6.627], [47.095, 18.520]], // Italy
237
- "pt": [[36.840, -9.500], [42.280, -6.190]], // Portugal
238
- "be": [[49.497, 2.545], [51.505, 6.407]], // Belgium
239
- "nl": [[50.753, 3.358], [53.555, 7.227]], // Netherlands
240
- "ch": [[45.818, 5.957], [47.808, 10.492]], // Switzerland
241
- "at": [[46.372, 9.530], [49.021, 17.162]], // Austria
242
- "gb": [[49.959, -8.649], [59.478, 1.759]], // United Kingdom,
243
- "ie": [[51.390, -10.480], [55.387, -5.432]], // Ireland
244
- "pl": [[49.003, 14.123], [54.836, 24.145]], // Poland
245
- "se": [[55.340, 11.112], [69.061, 24.177]], // Sweden
246
- "no": [[57.980, 4.500], [71.188, 31.078]], // Norway (Mainland approx)
247
- "fi": [[59.810, 20.556], [70.092, 31.586]], // Finland
248
- "dk": [[54.560, 8.089], [57.752, 12.690]], // Denmark
467
+ setZoom(zoom) {
468
+ OpenStreetMap.setZoom(this.map, zoom);
469
+ }
249
470
 
250
- // Afrique / Moyen-Orient
251
- "ma": [[27.662, -13.172], [35.922, -0.996]], // Morocco
252
- "dz": [[18.976, -8.669], [37.093, 11.999]], // Algeria
253
- "tn": [[30.233, 7.524], [37.544, 11.598]], // Tunisia
254
- "eg": [[21.725, 24.700], [31.667, 36.895]], // Egypt
255
- "za": [[-34.833, 16.470], [-22.126, 32.893]], // South Africa
256
- "sa": [[15.615, 34.495], [32.154, 55.666]], // Saudi Arabia
257
- "ae": [[22.634, 51.570], [26.084, 56.383]], // United Arab Emirates
258
- "il": [[29.487, 34.268], [33.277, 35.876]], // Israel
471
+ deleteMarkers() {
472
+ this.locations = [];
473
+ this.markers.length = 0;
474
+ this.markers = [];
475
+ }
259
476
 
260
- // Amériques
261
- "us": [[24.396, -124.848], [49.384, -66.885]], // United States (Contiguous)
262
- "ca": [[41.675, -141.000], [83.113, -52.648]], // Canada
263
- "mx": [[14.538, -118.365], [32.720, -86.711]], // Mexico
264
- "br": [[-33.751, -73.987], [5.271, -34.729]], // Brazil
265
- "ar": [[-55.051, -73.582], [-21.781, -53.591]], // Argentina
477
+ clearSelections() {
478
+ OpenStreetMap.clearSelections(this.map);
479
+ }
266
480
 
267
- // Asie / Océanie
268
- "cn": [[18.159, 73.499], [53.560, 134.772]], // China (mainland approx)
269
- "in": [[6.554, 68.176], [35.674, 97.402]], // India
270
- "jp": [[24.249, 122.938], [45.557, 153.987]], // Japan
271
- "au": [[-43.740, 112.921], [-10.668, 153.639]], // Australia
272
- "nz": [[-47.290, 166.509], [-34.392, 178.517]], // New Zealand
273
- };
481
+ addTempMarker(lat, lon) {
482
+ this.tempLayer = OpenStreetMap.addTempMarker(this.map, lat, lon, (selection) => {
483
+ const ll = selection.getLatLng();
484
+ this.tempSelection = { type: 'point', lat: ll.lat, long: ll.lng };
485
+ });
274
486
  }
275
487
 
276
- static getCountryBoundingBox(countryIsoCode) {
277
- if (!countryIsoCode) {
278
- return null;
279
- }
488
+ resetTempSelection() {
489
+ this.tempLayer = OpenStreetMap.resetTempSelection(this.map, this.tempLayer);
490
+ this.tempSelection = null;
491
+ }
280
492
 
281
- const key = countryIsoCode.toLowerCase().trim();
282
- const countryBox = OpenStreetMap.getCountryBoundingBoxes()[key];
283
- return countryBox ? countryBox : null;
493
+ addMarkers(listLocations, icon) {
494
+ OpenStreetMap.addMarkers(this.map, listLocations, icon).forEach(marker => {
495
+ const { lat, lng } = marker.getLatLng();
496
+ this.markers.push(marker);
497
+ this.locations.push([lat, lng]);
498
+ });
284
499
  }
285
500
 
286
- static centerMapOnCountry(map, countryIsoCode, opts = {}) {
287
- if (!map) {
501
+ addMarker(coordinates, options) {
502
+ const marker = OpenStreetMap.addMarker(this.map, coordinates, options);
503
+ if (!marker) {
288
504
  return;
289
505
  }
506
+ const { lat, lng } = marker.getLatLng();
507
+ this.markers.push(marker);
508
+ this.locations.push([lat, lng]);
509
+ }
290
510
 
291
- const boundingBox = OpenStreetMap.getCountryBoundingBox(countryIsoCode);
292
- if (null === boundingBox) {
293
- return;
294
- }
511
+ addGeoJson(geoJson, options) {
512
+ OpenStreetMap.displayGeoJSONOnMap(this.map, geoJson, options);
513
+ }
295
514
 
296
- const padding = Array.isArray(opts.padding) ? opts.padding : [20, 20];
297
- const minZoom = Number.isFinite(opts.minZoom) ? opts.minZoom : 3;
298
- const maxZoomSmall = Number.isFinite(opts.maxZoomSmall) ? opts.maxZoomSmall : 10;
299
- const maxZoomTiny = Number.isFinite(opts.maxZoomTiny) ? opts.maxZoomTiny : 12;
515
+ destroyMap() {
516
+ OpenStreetMap.destroyMap(this.map);
517
+ }
300
518
 
301
- // Estimation de "taille" en degrés
302
- const [[S, W], [N, E]] = boundingBox;
303
- const latSpan = Math.max(0.0001, Math.abs(N - S));
304
- const lonSpan = Math.max(0.0001, Math.abs(E - W));
305
- const areaDeg = latSpan * lonSpan;
519
+ setView(location, zoom) {
520
+ OpenStreetMap.setView(this.map, location, zoom);
521
+ }
306
522
 
307
- // Heuristique de zoom maximal selon la taille du pays (en degrés²)
308
- // (fitBounds choisira le zoom, plafonné par maxZoom ci-dessous)
309
- let maxZoom;
310
- if (areaDeg > 200) { // très grand (US, CA, AU, BR, CN)
311
- maxZoom = 7;
312
- } else if (areaDeg > 50) { // grand
313
- maxZoom = 8;
314
- } else if (areaDeg > 20) { // moyen+
315
- maxZoom = 9;
316
- } else if (areaDeg > 5) { // moyen/petit
317
- maxZoom = maxZoomSmall; // ~10
318
- } else { // petit/micro-état
319
- maxZoom = maxZoomTiny; // ~12
320
- }
523
+ centerOnFrance() {
524
+ OpenStreetMap.centerOnFrance(this.map);
525
+ }
321
526
 
322
- // fitBounds avec maxZoom pour éviter d'over-zoomer les petits pays
323
- const bounds = L.latLngBounds([ [S, W], [N, E] ]);
324
- map.fitBounds(bounds, { padding, maxZoom });
325
- if (map.getZoom() < minZoom) {
326
- map.setZoom(minZoom);
327
- }
527
+ centerOnCountry(countryIsoCode, opts) {
528
+ OpenStreetMap.centerMapOnCountry(this.map, countryIsoCode, opts);
328
529
  }
329
530
 
330
531
  centerOnMarkers(padding) {
331
532
  OpenStreetMap.centerMapToLocations(this.map, this.locations, padding);
332
533
  }
333
534
 
334
- static centerMapToLocations(map, locationsList, padding=[20,20], maxZoom=18) {
335
- if (!map || locationsList.length === 0) {
336
- return;
337
- }
338
-
339
- map.invalidateSize(false);
340
-
341
- const bounds = L.latLngBounds(locationsList);
342
- map.fitBounds(bounds, { padding: padding });
343
- if (map.getZoom() > maxZoom) {
344
- map.setZoom(maxZoom);
345
- }
535
+ centerOnGooglePlace(place) {
536
+ OpenStreetMap.centerMapToGooglePlace(this.map, place);
346
537
  }
347
538
 
348
- static centerMapToGooglePlace(map, place) {
349
- if (place && place.geometry && place.geometry.location) {
350
- const loc = place.geometry.location;
351
- OpenStreetMap.centerMapToCoordinates(map, loc.lat(), loc.lng());
352
- }
539
+ centerOnCoordinates(lat, long) {
540
+ OpenStreetMap.centerMapToCoordinates(this.map, lat, long);
353
541
  }
354
542
 
355
- static centerMapToCoordinates(map, lat, long) {
356
- if (!map) {
357
- return;
358
- }
359
- map.setView([lat, long], Math.max(map.getZoom(), 15));
543
+ initDrawControl(options) {
544
+ return OpenStreetMap.initDrawControl(this.map, options);
360
545
  }
361
546
 
362
547
  connectMarkers() {
363
- if (this.locations.length === 0) {
364
- return;
365
- }
366
-
367
- let prevLocation = null;
368
- let listLineCoordinates = [];
369
- this.locations.forEach(location => {
370
- if (prevLocation != null) {
371
- listLineCoordinates.push([prevLocation, location]);
372
- }
373
- prevLocation = location;
374
- });
375
-
376
- listLineCoordinates.forEach(line => {
377
- L.polyline(line, {color: '#728bec'}).addTo(this.map);
378
- });
548
+ OpenStreetMap.connectMarkers(this.map, this.locations);
379
549
  }
380
550
  }
381
551
 
382
- module.exports = { OpenStreetMap };
552
+ module.exports = { OpenStreetMap, OsmMap };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@osimatic/helpers-js",
3
- "version": "1.5.18",
3
+ "version": "1.5.20",
4
4
  "main": "main.js",
5
5
  "scripts": {
6
6
  "test": "jest",
@@ -21,11 +21,14 @@
21
21
  "peerDependencies": {
22
22
  "intl-tel-input": ">=19.0",
23
23
  "leaflet": ">=1.9",
24
+ "leaflet-draw": ">=1.0",
24
25
  "papaparse": ">=5.0"
25
26
  },
26
27
  "devDependencies": {
27
28
  "jest": "^30.2.0",
28
- "jest-environment-jsdom": "^30.2.0"
29
+ "jest-environment-jsdom": "^30.2.0",
30
+ "leaflet-draw": "^1.0.4",
31
+ "papaparse": "^5.5.3"
29
32
  },
30
33
  "publishConfig": {
31
34
  "access": "public"
package/paging.js CHANGED
@@ -133,7 +133,14 @@ class Pagination {
133
133
 
134
134
  class Navigation {
135
135
  static activateTab(a) {
136
+ a = toEl(a);
137
+ if (!a) {
138
+ return;
139
+ }
136
140
  let ulNav = a.closest('.nav');
141
+ if (!ulNav) {
142
+ return;
143
+ }
137
144
  let tabContent = ulNav.parentElement.querySelector('.tab-content');
138
145
 
139
146
  ulNav.querySelectorAll('a.nav-link').forEach(navLink => {
@@ -179,13 +179,6 @@ describe('TelephoneNumber', () => {
179
179
  });
180
180
  });
181
181
 
182
- describe('setIntlTelInputUtilsPath', () => {
183
- test('should set intl tel input utils path', () => {
184
- const path = '/path/to/utils.js';
185
- TelephoneNumber.setIntlTelInputUtilsPath(path);
186
- expect(TelephoneNumber.intlTelInputUtilsPath).toBe(path);
187
- });
188
- });
189
182
 
190
183
  describe('getCountryIsoCode', () => {
191
184
  test('should return country code for valid phone number', () => {