@controleonline/ui-default 1.0.263 → 1.0.265

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.
Files changed (61) hide show
  1. package/AGENTS.md +47 -45
  2. package/package.json +20 -20
  3. package/src/react/components/errors/DefaultErrors.js +307 -325
  4. package/src/react/components/files/DefaultFile.js +46 -46
  5. package/src/react/components/filters/CompactFilterSelector.js +78 -24
  6. package/src/react/components/filters/CompactFilterSelector.styles.js +17 -5
  7. package/src/react/components/filters/DefaultColumnFilter.js +191 -57
  8. package/src/react/components/filters/DefaultExternalFilters.js +245 -182
  9. package/src/react/components/filters/DefaultSearch.js +131 -92
  10. package/src/react/components/filters/DefaultSearch.styles.js +65 -70
  11. package/src/react/components/form/DefaultForm.js +172 -151
  12. package/src/react/components/form/DefaultForm.styles.js +71 -66
  13. package/src/react/components/help/DefaultTooltip.js +87 -87
  14. package/src/react/components/help/DefaultTooltip.styles.js +61 -61
  15. package/src/react/components/inputs/DefaultDateInput.js +150 -0
  16. package/src/react/components/inputs/DefaultInput.js +162 -127
  17. package/src/react/components/inputs/DefaultInput.styles.js +6 -0
  18. package/src/react/components/inputs/DefaultSelect.js +320 -152
  19. package/src/react/components/inputs/defaultInputUtils.js +40 -19
  20. package/src/react/components/map/DefaultGoogleMap.styles.js +115 -9
  21. package/src/react/components/map/DefaultGoogleMap.web.js +560 -446
  22. package/src/react/components/map/DefaultMap.native.js +73 -71
  23. package/src/react/components/map/DefaultMap.styles.js +16 -16
  24. package/src/react/components/map/DefaultMap.web.js +68 -66
  25. package/src/react/components/map/DefaultNativeMap.native.js +307 -183
  26. package/src/react/components/map/DefaultNativeMap.shared.js +439 -340
  27. package/src/react/components/map/DefaultNativeMap.styles.js +156 -122
  28. package/src/react/components/table/DefaultColumnMenu.js +108 -0
  29. package/src/react/components/table/DefaultDebug.js +233 -0
  30. package/src/react/components/table/DefaultFiltersModal.js +142 -0
  31. package/src/react/components/table/DefaultModalButton.js +18 -0
  32. package/src/react/components/table/DefaultSearchModal.js +49 -0
  33. package/src/react/components/table/DefaultTable.js +345 -1846
  34. package/src/react/components/table/DefaultTable.styles.js +247 -136
  35. package/src/react/components/table/DefaultTable.utils.js +502 -0
  36. package/src/react/components/table/DefaultTableBody.js +26 -0
  37. package/src/react/components/table/DefaultTableCards.js +171 -0
  38. package/src/react/components/table/DefaultTableControls.js +208 -0
  39. package/src/react/components/table/DefaultTableEmptyState.js +22 -0
  40. package/src/react/components/table/DefaultTableFooter.js +172 -0
  41. package/src/react/components/table/DefaultTableInput.js +145 -0
  42. package/src/react/components/table/DefaultTableRows.js +340 -0
  43. package/src/react/components/table/DefaultTableSearch.js +100 -0
  44. package/src/react/components/table/DefaultTableToolbar.js +98 -0
  45. package/src/react/components/table/DefaultToolbarAction.js +56 -0
  46. package/src/react/components/table/useDefaultTablePagination.js +370 -0
  47. package/src/react/components/table/useDefaultTableSorting.js +126 -0
  48. package/src/react/components/table/useDefaultTableTheme.js +58 -0
  49. package/src/react/index.js +10 -10
  50. package/src/react/utils/tableVisibleColumnsPreferences.js +239 -211
  51. package/src/store/default/actions.js +51 -13
  52. package/src/store/default/getters.js +10 -8
  53. package/src/store/default/mutation_types.js +4 -2
  54. package/src/store/default/mutations.js +10 -1
  55. package/src/tests/react/components/errors/DefaultErrors.test.js +162 -162
  56. package/src/tests/react/components/files/DefaultFile.test.js +80 -80
  57. package/src/tests/react/components/form/DefaultForm.test.js +81 -0
  58. package/src/tests/react/components/inputs/DefaultSelect.test.js +185 -0
  59. package/src/tests/react/components/table/DefaultTable.test.js +1183 -0
  60. package/src/tests/react/store/defaultActions.test.js +59 -0
  61. package/src/tests/react/utils/tableVisibleColumnsPreferences.test.js +247 -168
@@ -1,22 +1,47 @@
1
- import {resolveAppDomain} from '@controleonline/ui-common/src/utils/appDomain';
1
+ import {resolveAppDomain} from '@controleonline/ui-common/src/utils/appDomain';
2
2
 
3
3
  const serializeForHtml = value =>
4
4
  JSON.stringify(value).replace(/</g, '\\u003c');
5
5
 
6
+ const normalizeThemeColor = (value, fallback) => {
7
+ const normalizedValue = String(value || '').trim();
8
+ return normalizedValue || fallback;
9
+ };
10
+
11
+ export const resolveMapPopupTheme = popupTheme => ({
12
+ pageBackground: normalizeThemeColor(
13
+ popupTheme?.pageBackground,
14
+ popupTheme?.modalBackground || '#F8FAFC',
15
+ ),
16
+ modalBackground: normalizeThemeColor(popupTheme?.modalBackground, '#FFFFFF'),
17
+ modalHeaderText: normalizeThemeColor(popupTheme?.modalHeaderText, '#1A1A1A'),
18
+ modalText: normalizeThemeColor(popupTheme?.modalText, '#1A1A1A'),
19
+ textMuted: normalizeThemeColor(
20
+ popupTheme?.textMuted || popupTheme?.textSecondary,
21
+ '#64748B',
22
+ ),
23
+ dividerBorder: normalizeThemeColor(popupTheme?.dividerBorder, '#D7E1EC'),
24
+ buttonBackground: normalizeThemeColor(popupTheme?.buttonBackground, '#0E7490'),
25
+ buttonText: normalizeThemeColor(popupTheme?.buttonText, '#FFFFFF'),
26
+ modalShadow: normalizeThemeColor(popupTheme?.modalShadow, '#000000'),
27
+ });
28
+
6
29
  export const resolveWebViewBaseUrlForDomain = configuredDomain => {
7
30
  const host = resolveAppDomain(configuredDomain);
8
31
  return host ? `https://${host}/` : 'https://app.controleonline.com/';
9
32
  };
10
33
 
11
- export const buildAndroidWebMapHtml = ({
12
- apiKey,
13
- markerPayloads = [],
14
- paths = [],
15
- routeColor = '#0EA5E9',
16
- userCoordinates = null,
17
- }) => {
18
- const markers = Array.isArray(markerPayloads) ? markerPayloads : [];
19
- const routes = Array.isArray(paths) ? paths : [];
34
+ export const buildAndroidWebMapHtml = ({
35
+ apiKey,
36
+ markerPayloads = [],
37
+ paths = [],
38
+ routeColor = '#0EA5E9',
39
+ userCoordinates = null,
40
+ popupTheme = null,
41
+ }) => {
42
+ const markers = Array.isArray(markerPayloads) ? markerPayloads : [];
43
+ const routes = Array.isArray(paths) ? paths : [];
44
+ const resolvedPopupTheme = resolveMapPopupTheme(popupTheme);
20
45
 
21
46
  return `<!DOCTYPE html>
22
47
  <html lang="pt-BR">
@@ -32,7 +57,7 @@ export const buildAndroidWebMapHtml = ({
32
57
  width: 100%;
33
58
  height: 100%;
34
59
  overflow: hidden;
35
- background: #f8fafc;
60
+ background: ${resolvedPopupTheme.modalBackground};
36
61
  font-family: Arial, sans-serif;
37
62
  }
38
63
 
@@ -54,47 +79,67 @@ export const buildAndroidWebMapHtml = ({
54
79
  .popup {
55
80
  min-width: 220px;
56
81
  max-width: 280px;
57
- color: #0f172a;
82
+ color: ${resolvedPopupTheme.modalText};
58
83
  }
59
84
 
60
- .popup-company {
61
- font-size: 11px;
62
- font-weight: 700;
63
- text-transform: uppercase;
64
- letter-spacing: 0.08em;
65
- color: #0369a1;
66
- margin-bottom: 6px;
85
+ .popup-header {
86
+ display: flex;
87
+ align-items: center;
88
+ gap: 12px;
89
+ margin-bottom: 12px;
90
+ }
91
+
92
+ .popup-logoWrap {
93
+ width: 58px;
94
+ height: 58px;
95
+ border-radius: 16px;
96
+ overflow: hidden;
97
+ border: 1px solid ${resolvedPopupTheme.dividerBorder};
98
+ background: ${resolvedPopupTheme.modalBackground};
99
+ display: flex;
100
+ align-items: center;
101
+ justify-content: center;
102
+ flex-shrink: 0;
103
+ }
104
+
105
+ .popup-logo {
106
+ width: 100%;
107
+ height: 100%;
108
+ object-fit: cover;
109
+ display: block;
110
+ }
111
+
112
+ .popup-logoFallback {
113
+ color: ${resolvedPopupTheme.buttonBackground};
114
+ font-size: 18px;
115
+ font-weight: 800;
116
+ letter-spacing: 0.04em;
117
+ }
118
+
119
+ .popup-headerContent {
120
+ min-width: 0;
121
+ flex: 1;
67
122
  }
68
123
 
69
124
  .popup-title {
70
- font-size: 16px;
71
- font-weight: 700;
72
- margin-bottom: 8px;
125
+ font-size: 18px;
126
+ font-weight: 800;
127
+ color: ${resolvedPopupTheme.modalHeaderText};
128
+ line-height: 1.2;
73
129
  }
74
130
 
75
131
  .popup-line {
76
132
  font-size: 13px;
77
133
  line-height: 1.45;
78
- color: #0f172a;
134
+ color: ${resolvedPopupTheme.modalText};
79
135
  margin-bottom: 4px;
80
136
  }
81
137
 
82
- .popup-meta-list {
83
- display: grid;
84
- gap: 6px;
138
+ .popup-summary {
85
139
  margin-top: 10px;
86
- }
87
-
88
- .popup-meta {
89
- display: flex;
90
- justify-content: space-between;
91
- gap: 10px;
140
+ color: ${resolvedPopupTheme.textMuted};
92
141
  font-size: 12px;
93
- color: #334155;
94
- }
95
-
96
- .popup-meta-label {
97
- color: #64748b;
142
+ font-weight: 700;
98
143
  }
99
144
 
100
145
  .popup-actions {
@@ -106,20 +151,20 @@ export const buildAndroidWebMapHtml = ({
106
151
  .popup-action {
107
152
  flex: 1;
108
153
  border-radius: 999px;
109
- border: 1px solid #cbd5e1;
154
+ border: 1px solid ${resolvedPopupTheme.buttonBackground};
110
155
  padding: 10px 12px;
111
156
  text-align: center;
112
157
  text-decoration: none;
113
- color: #0f172a;
158
+ color: ${resolvedPopupTheme.buttonText};
114
159
  font-size: 12px;
115
160
  font-weight: 700;
116
- background: #ffffff;
161
+ background: ${resolvedPopupTheme.buttonBackground};
117
162
  }
118
163
 
119
164
  .popup-action.primary {
120
- border-color: transparent;
121
- background: #0ea5e9;
122
- color: #ffffff;
165
+ border-color: ${resolvedPopupTheme.buttonBackground};
166
+ background: ${resolvedPopupTheme.buttonBackground};
167
+ color: ${resolvedPopupTheme.buttonText};
123
168
  }
124
169
  </style>
125
170
  </head>
@@ -127,9 +172,9 @@ export const buildAndroidWebMapHtml = ({
127
172
  <div id="map"></div>
128
173
  <div id="error"></div>
129
174
  <script>
130
- window.__SHOP_MAP_MARKERS__ = ${serializeForHtml(markers)};
131
- window.__SHOP_MAP_PATHS__ = ${serializeForHtml(routes)};
132
- window.__SHOP_MAP_USER__ = ${serializeForHtml(userCoordinates || null)};
175
+ window.__SHOP_MAP_MARKERS__ = ${serializeForHtml(markers)};
176
+ window.__SHOP_MAP_PATHS__ = ${serializeForHtml(routes)};
177
+ window.__SHOP_MAP_USER__ = ${serializeForHtml(userCoordinates || null)};
133
178
 
134
179
  function escapeHtml(value) {
135
180
  return String(value || '')
@@ -197,74 +242,121 @@ export const buildAndroidWebMapHtml = ({
197
242
  return '<div class="popup-line">' + escapeHtml(value) + '</div>';
198
243
  }
199
244
 
200
- function buildPopupMeta(label, value) {
201
- if (!value) {
245
+ function buildPopupTravelSummary(item, routeSummary) {
246
+ var distanceLabel =
247
+ routeSummary && routeSummary.distanceLabel
248
+ ? routeSummary.distanceLabel
249
+ : item && item.distanceLabel
250
+ ? item.distanceLabel
251
+ : '';
252
+ var durationLabel =
253
+ routeSummary && routeSummary.durationLabel
254
+ ? routeSummary.durationLabel
255
+ : item && item.durationLabel
256
+ ? item.durationLabel
257
+ : item && item.travelDurationLabel
258
+ ? item.travelDurationLabel
259
+ : '';
260
+
261
+ if (!distanceLabel && !durationLabel) {
202
262
  return '';
203
263
  }
204
264
 
205
265
  return (
206
- '<div class="popup-meta">' +
207
- '<span class="popup-meta-label">' + escapeHtml(label) + '</span>' +
208
- '<span>' + escapeHtml(value) + '</span>' +
266
+ '<div class="popup-summary">' +
267
+ [distanceLabel, durationLabel].filter(Boolean).map(escapeHtml).join(' • ') +
209
268
  '</div>'
210
269
  );
211
270
  }
212
271
 
213
- function buildPopupAction(url, label, className) {
214
- return (
215
- '<a class="popup-action ' +
216
- className +
217
- '" href="' + escapeHtml(url) + '">' +
218
- escapeHtml(label) +
219
- '</a>'
220
- );
221
- }
222
-
223
- function buildNavigationUrl(provider, latitude, longitude) {
224
- if (!Number.isFinite(latitude) || !Number.isFinite(longitude)) {
225
- return '';
226
- }
227
-
228
- var coordinates = latitude + ',' + longitude;
229
-
230
- if (provider === 'waze') {
231
- return 'https://waze.com/ul?ll=' + encodeURIComponent(coordinates) + '&navigate=yes';
232
- }
233
-
234
- return 'https://www.google.com/maps/search/?api=1&query=' + encodeURIComponent(coordinates);
235
- }
236
-
237
- function resolveMarkerNavigationUrls(item) {
238
- var latitude = Number(item && item.latitude);
239
- var longitude = Number(item && item.longitude);
240
-
241
- return {
242
- googleMapsUrl: item && item.googleMapsUrl ? item.googleMapsUrl : buildNavigationUrl('google', latitude, longitude),
243
- wazeUrl: item && item.wazeUrl ? item.wazeUrl : buildNavigationUrl('waze', latitude, longitude),
244
- };
245
- }
246
-
247
- function buildPopupContent(item) {
248
- var navigationUrls = resolveMarkerNavigationUrls(item);
249
-
250
- return (
251
- '<div class="popup">' +
252
- '<div class="popup-company">' + escapeHtml(item.companyName) + '</div>' +
253
- '<div class="popup-title">' + escapeHtml(item.title) + '</div>' +
272
+ function buildPopupAction(url, label, className) {
273
+ return (
274
+ '<a class="popup-action ' +
275
+ className +
276
+ '" href="' + escapeHtml(url) + '">' +
277
+ escapeHtml(label) +
278
+ '</a>'
279
+ );
280
+ }
281
+
282
+ function buildNavigationUrl(provider, latitude, longitude) {
283
+ if (!Number.isFinite(latitude) || !Number.isFinite(longitude)) {
284
+ return '';
285
+ }
286
+
287
+ var coordinates = latitude + ',' + longitude;
288
+
289
+ if (provider === 'waze') {
290
+ return 'https://waze.com/ul?ll=' + encodeURIComponent(coordinates) + '&navigate=yes';
291
+ }
292
+
293
+ return 'https://www.google.com/maps/search/?api=1&query=' + encodeURIComponent(coordinates);
294
+ }
295
+
296
+ function resolveMarkerNavigationUrls(item) {
297
+ var latitude = Number(item && item.latitude);
298
+ var longitude = Number(item && item.longitude);
299
+
300
+ return {
301
+ googleMapsUrl: item && item.googleMapsUrl ? item.googleMapsUrl : buildNavigationUrl('google', latitude, longitude),
302
+ wazeUrl: item && item.wazeUrl ? item.wazeUrl : buildNavigationUrl('waze', latitude, longitude),
303
+ };
304
+ }
305
+
306
+ function buildPopupContent(item, routeSummary) {
307
+ var navigationUrls = resolveMarkerNavigationUrls(item);
308
+ var title =
309
+ item && item.unitAlias
310
+ ? item.unitAlias
311
+ : item && item.alias
312
+ ? item.alias
313
+ : item && item.companyName
314
+ ? item.companyName
315
+ : item && item.title
316
+ ? item.title
317
+ : '';
318
+ var logoFallback = escapeHtml(
319
+ String(title || 'CO')
320
+ .trim()
321
+ .split(/\s+/)
322
+ .slice(0, 2)
323
+ .map(function (chunk) {
324
+ return chunk[0] || '';
325
+ })
326
+ .join('')
327
+ .toUpperCase()
328
+ );
329
+ var logoMarkup =
330
+ item && item.companyLogoUrl
331
+ ? (
332
+ '<div class="popup-logoWrap">' +
333
+ '<img class="popup-logo" src="' + escapeHtml(item.companyLogoUrl) + '" alt="' + escapeHtml(title || 'Unidade') + '" />' +
334
+ '</div>'
335
+ )
336
+ : (
337
+ '<div class="popup-logoWrap">' +
338
+ '<div class="popup-logoFallback">' + logoFallback + '</div>' +
339
+ '</div>'
340
+ );
341
+
342
+ return (
343
+ '<div class="popup">' +
344
+ '<div class="popup-header">' +
345
+ logoMarkup +
346
+ '<div class="popup-headerContent">' +
347
+ '<div class="popup-title">' + escapeHtml(title) + '</div>' +
348
+ '</div>' +
349
+ '</div>' +
254
350
  buildPopupLine(item.addressLine) +
255
351
  buildPopupLine(item.addressExtra) +
256
- '<div class="popup-meta-list">' +
257
- buildPopupMeta('Telefone', item.phoneLabel) +
258
- buildPopupMeta('Distancia', item.distanceLabel) +
259
- buildPopupMeta('Horario', item.openingHours) +
352
+ buildPopupTravelSummary(item, routeSummary) +
353
+ '<div class="popup-actions">' +
354
+ buildPopupAction(navigationUrls.googleMapsUrl, 'Abrir no Maps', 'primary') +
355
+ buildPopupAction(navigationUrls.wazeUrl, 'Abrir no Waze', 'primary') +
260
356
  '</div>' +
261
- '<div class="popup-actions">' +
262
- buildPopupAction(navigationUrls.googleMapsUrl, 'Abrir no Maps', 'primary') +
263
- buildPopupAction(navigationUrls.wazeUrl, 'Waze', '') +
264
- '</div>' +
265
- '</div>'
266
- );
267
- }
357
+ '</div>'
358
+ );
359
+ }
268
360
 
269
361
  window.handleMapError = function handleMapError() {
270
362
  showError('Nao foi possivel carregar o Google Maps.');
@@ -282,243 +374,250 @@ export const buildAndroidWebMapHtml = ({
282
374
  postMessage({type: 'window-error', message: message});
283
375
  });
284
376
 
285
- function resolveMarkerPosition(item) {
286
- var latitude = Number(item && item.latitude);
287
- var longitude = Number(item && item.longitude);
288
-
289
- if (Number.isFinite(latitude) && Number.isFinite(longitude)) {
290
- return Promise.resolve({
291
- item: item,
292
- position: {
293
- lat: latitude,
294
- lng: longitude,
295
- },
296
- });
297
- }
298
-
299
- if (!item || !item.geocodeQuery || !window.google || !window.google.maps || !window.google.maps.Geocoder) {
300
- return Promise.resolve(null);
301
- }
302
-
303
- var geocoder = new window.google.maps.Geocoder();
304
-
305
- return new Promise(function (resolve) {
306
- geocoder.geocode({address: item.geocodeQuery}, function (results, status) {
307
- if (status !== 'OK' || !results || !results[0] || !results[0].geometry || !results[0].geometry.location) {
308
- resolve(null);
309
- return;
310
- }
311
-
312
- var location = results[0].geometry.location;
313
- var resolvedLatitude = Number(location.lat());
314
- var resolvedLongitude = Number(location.lng());
315
-
316
- if (!Number.isFinite(resolvedLatitude) || !Number.isFinite(resolvedLongitude)) {
317
- resolve(null);
318
- return;
319
- }
320
-
321
- resolve({
322
- item: item,
323
- position: {
324
- lat: resolvedLatitude,
325
- lng: resolvedLongitude,
326
- },
327
- });
328
- });
329
- });
330
- }
331
-
332
- window.initMap = function initMap() {
333
- try {
334
- var markers = window.__SHOP_MAP_MARKERS__ || [];
335
- var paths = window.__SHOP_MAP_PATHS__ || [];
336
- var userCoordinates = window.__SHOP_MAP_USER__;
337
-
338
- if (!window.google || (!markers.length && !paths.length && !userCoordinates)) {
339
- showError('Nao foi possivel localizar as franquias no mapa.');
340
- return;
341
- }
342
-
343
- Promise.all(markers.map(resolveMarkerPosition)).then(function (resolvedMarkers) {
344
- resolvedMarkers = (resolvedMarkers || []).filter(function (entry) {
345
- return entry && entry.position;
346
- });
347
-
348
- var map = new window.google.maps.Map(document.getElementById('map'), {
349
- mapTypeControl: false,
350
- streetViewControl: false,
351
- fullscreenControl: false,
352
- clickableIcons: false,
353
- gestureHandling: 'greedy',
354
- zoomControl: false,
355
- disableDefaultUI: true,
356
- });
357
-
358
- var bounds = new window.google.maps.LatLngBounds();
359
- var infoWindow = new window.google.maps.InfoWindow({maxWidth: 320});
360
- var hasUserCoordinates =
361
- userCoordinates &&
362
- Number.isFinite(userCoordinates.latitude) &&
363
- Number.isFinite(userCoordinates.longitude);
364
- var directionsService = hasUserCoordinates
365
- ? new window.google.maps.DirectionsService()
366
- : null;
367
- var directionsRenderer = directionsService
368
- ? new window.google.maps.DirectionsRenderer({
369
- map: map,
370
- suppressMarkers: true,
371
- preserveViewport: false,
372
- polylineOptions: {
373
- strokeColor: ${serializeForHtml(routeColor)},
374
- strokeOpacity: 0.92,
375
- strokeWeight: 5,
376
- },
377
- })
378
- : null;
379
- var activeRouteRequestId = 0;
380
- var resolvePathPosition = function resolvePathPosition(point) {
381
- if (!point) {
382
- return null;
383
- }
384
-
385
- var latitude = Number(point.latitude);
386
- var longitude = Number(point.longitude);
387
-
388
- if (!Number.isFinite(latitude) || !Number.isFinite(longitude)) {
389
- return null;
390
- }
391
-
392
- return {
393
- lat: latitude,
394
- lng: longitude,
395
- };
396
- };
397
-
398
- if (hasUserCoordinates) {
399
- var userPosition = {
400
- lat: userCoordinates.latitude,
401
- lng: userCoordinates.longitude,
402
- };
403
-
404
- new window.google.maps.Marker({
405
- position: userPosition,
406
- map: map,
407
- title: 'Sua localizacao',
408
- zIndex: 999,
409
- });
410
-
411
- bounds.extend(userPosition);
412
- }
413
-
414
- resolvedMarkers.forEach(function (entry) {
415
- var item = entry.item;
416
- var position = entry.position;
417
- var markerOptions = {
418
- position: position,
419
- map: map,
420
- title: item.title,
421
- animation: window.google.maps.Animation.DROP,
422
- };
423
-
424
- if (item.markerIconUrl) {
425
- markerOptions.icon = {
426
- url: item.markerIconUrl,
427
- scaledSize: new window.google.maps.Size(42, 42),
428
- };
429
- }
430
-
431
- var marker = new window.google.maps.Marker(markerOptions);
432
-
433
- bounds.extend(position);
434
-
435
- marker.addListener('click', function () {
436
- infoWindow.setContent(buildPopupContent(item));
437
- infoWindow.open({
438
- anchor: marker,
439
- map: map,
440
- shouldFocus: false,
441
- });
442
-
443
- if (!directionsService || !directionsRenderer) {
444
- return;
445
- }
446
-
447
- var routeRequestId = activeRouteRequestId + 1;
448
- activeRouteRequestId = routeRequestId;
449
-
450
- directionsService.route(
451
- {
452
- origin: {
453
- lat: userCoordinates.latitude,
454
- lng: userCoordinates.longitude,
455
- },
456
- destination: position,
457
- travelMode: window.google.maps.TravelMode.DRIVING,
458
- },
459
- function (response, status) {
460
- if (routeRequestId !== activeRouteRequestId) {
461
- return;
462
- }
463
-
464
- if (status === 'OK' && response) {
465
- directionsRenderer.setDirections(response);
466
- return;
467
- }
468
-
469
- directionsRenderer.set('directions', null);
470
- },
471
- );
472
- });
473
- });
474
-
475
- paths.forEach(function (path) {
476
- var from = resolvePathPosition(path && path.from);
477
- var to = resolvePathPosition(path && path.to);
478
-
479
- if (!from || !to) {
480
- return;
481
- }
482
-
483
- bounds.extend(from);
484
- bounds.extend(to);
485
-
486
- new window.google.maps.Polyline({
487
- path: [from, to],
488
- geodesic: true,
489
- strokeColor: path && path.color ? path.color : ${serializeForHtml(routeColor)},
490
- strokeOpacity: 0.72,
491
- strokeWeight: 4,
492
- map: map,
493
- });
494
- });
495
-
496
- if (bounds.isEmpty()) {
497
- showError('Nao foi possivel localizar as franquias no mapa.');
498
- return;
499
- }
500
-
501
- map.fitBounds(bounds, {
502
- top: 56,
503
- right: 32,
504
- bottom: 56,
505
- left: 32,
506
- });
507
-
508
- postMessage({type: 'ready'});
509
-
510
- window.google.maps.event.addListenerOnce(map, 'idle', function () {
511
- if (resolvedMarkers.length === 1 && map.getZoom() > 15) {
512
- map.setZoom(15);
513
- }
514
- });
515
- }).catch(function () {
516
- showError('Nao foi possivel localizar as franquias no mapa.');
517
- });
518
- } catch (error) {
519
- showError('Nao foi possivel carregar o Google Maps.');
520
- }
521
- };
377
+ function resolveMarkerPosition(item) {
378
+ var latitude = Number(item && item.latitude);
379
+ var longitude = Number(item && item.longitude);
380
+
381
+ if (Number.isFinite(latitude) && Number.isFinite(longitude)) {
382
+ return Promise.resolve({
383
+ item: item,
384
+ position: {
385
+ lat: latitude,
386
+ lng: longitude,
387
+ },
388
+ });
389
+ }
390
+
391
+ if (!item || !item.geocodeQuery || !window.google || !window.google.maps || !window.google.maps.Geocoder) {
392
+ return Promise.resolve(null);
393
+ }
394
+
395
+ var geocoder = new window.google.maps.Geocoder();
396
+
397
+ return new Promise(function (resolve) {
398
+ geocoder.geocode({address: item.geocodeQuery}, function (results, status) {
399
+ if (status !== 'OK' || !results || !results[0] || !results[0].geometry || !results[0].geometry.location) {
400
+ resolve(null);
401
+ return;
402
+ }
403
+
404
+ var location = results[0].geometry.location;
405
+ var resolvedLatitude = Number(location.lat());
406
+ var resolvedLongitude = Number(location.lng());
407
+
408
+ if (!Number.isFinite(resolvedLatitude) || !Number.isFinite(resolvedLongitude)) {
409
+ resolve(null);
410
+ return;
411
+ }
412
+
413
+ resolve({
414
+ item: item,
415
+ position: {
416
+ lat: resolvedLatitude,
417
+ lng: resolvedLongitude,
418
+ },
419
+ });
420
+ });
421
+ });
422
+ }
423
+
424
+ window.initMap = function initMap() {
425
+ try {
426
+ var markers = window.__SHOP_MAP_MARKERS__ || [];
427
+ var paths = window.__SHOP_MAP_PATHS__ || [];
428
+ var userCoordinates = window.__SHOP_MAP_USER__;
429
+
430
+ if (!window.google || (!markers.length && !paths.length && !userCoordinates)) {
431
+ showError('Nao foi possivel localizar as franquias no mapa.');
432
+ return;
433
+ }
434
+
435
+ Promise.all(markers.map(resolveMarkerPosition)).then(function (resolvedMarkers) {
436
+ resolvedMarkers = (resolvedMarkers || []).filter(function (entry) {
437
+ return entry && entry.position;
438
+ });
439
+
440
+ var map = new window.google.maps.Map(document.getElementById('map'), {
441
+ mapTypeControl: false,
442
+ streetViewControl: false,
443
+ fullscreenControl: false,
444
+ clickableIcons: false,
445
+ gestureHandling: 'greedy',
446
+ zoomControl: false,
447
+ disableDefaultUI: true,
448
+ });
449
+
450
+ var bounds = new window.google.maps.LatLngBounds();
451
+ var infoWindow = new window.google.maps.InfoWindow({maxWidth: 320});
452
+ var hasUserCoordinates =
453
+ userCoordinates &&
454
+ Number.isFinite(userCoordinates.latitude) &&
455
+ Number.isFinite(userCoordinates.longitude);
456
+ var directionsService = hasUserCoordinates
457
+ ? new window.google.maps.DirectionsService()
458
+ : null;
459
+ var directionsRenderer = directionsService
460
+ ? new window.google.maps.DirectionsRenderer({
461
+ map: map,
462
+ suppressMarkers: true,
463
+ preserveViewport: false,
464
+ polylineOptions: {
465
+ strokeColor: ${serializeForHtml(routeColor)},
466
+ strokeOpacity: 0.92,
467
+ strokeWeight: 5,
468
+ },
469
+ })
470
+ : null;
471
+ var activeRouteRequestId = 0;
472
+ var resolvePathPosition = function resolvePathPosition(point) {
473
+ if (!point) {
474
+ return null;
475
+ }
476
+
477
+ var latitude = Number(point.latitude);
478
+ var longitude = Number(point.longitude);
479
+
480
+ if (!Number.isFinite(latitude) || !Number.isFinite(longitude)) {
481
+ return null;
482
+ }
483
+
484
+ return {
485
+ lat: latitude,
486
+ lng: longitude,
487
+ };
488
+ };
489
+
490
+ if (hasUserCoordinates) {
491
+ var userPosition = {
492
+ lat: userCoordinates.latitude,
493
+ lng: userCoordinates.longitude,
494
+ };
495
+
496
+ new window.google.maps.Marker({
497
+ position: userPosition,
498
+ map: map,
499
+ title: 'Sua localizacao',
500
+ zIndex: 999,
501
+ });
502
+
503
+ bounds.extend(userPosition);
504
+ }
505
+
506
+ resolvedMarkers.forEach(function (entry) {
507
+ var item = entry.item;
508
+ var position = entry.position;
509
+ var markerOptions = {
510
+ position: position,
511
+ map: map,
512
+ title: item.title,
513
+ animation: window.google.maps.Animation.DROP,
514
+ };
515
+
516
+ if (item.markerIconUrl) {
517
+ markerOptions.icon = {
518
+ url: item.markerIconUrl,
519
+ scaledSize: new window.google.maps.Size(42, 42),
520
+ };
521
+ }
522
+
523
+ var marker = new window.google.maps.Marker(markerOptions);
524
+
525
+ bounds.extend(position);
526
+
527
+ marker.addListener('click', function () {
528
+ infoWindow.setContent(buildPopupContent(item));
529
+ infoWindow.open({
530
+ anchor: marker,
531
+ map: map,
532
+ shouldFocus: false,
533
+ });
534
+
535
+ if (!directionsService || !directionsRenderer) {
536
+ return;
537
+ }
538
+
539
+ var routeRequestId = activeRouteRequestId + 1;
540
+ activeRouteRequestId = routeRequestId;
541
+
542
+ directionsService.route(
543
+ {
544
+ origin: {
545
+ lat: userCoordinates.latitude,
546
+ lng: userCoordinates.longitude,
547
+ },
548
+ destination: position,
549
+ travelMode: window.google.maps.TravelMode.DRIVING,
550
+ },
551
+ function (response, status) {
552
+ if (routeRequestId !== activeRouteRequestId) {
553
+ return;
554
+ }
555
+
556
+ if (status === 'OK' && response) {
557
+ var activeLeg = response && response.routes && response.routes[0] && response.routes[0].legs
558
+ ? response.routes[0].legs[0]
559
+ : null;
560
+ directionsRenderer.setDirections(response);
561
+ infoWindow.setContent(buildPopupContent(item, {
562
+ distanceLabel: activeLeg && activeLeg.distance ? activeLeg.distance.text : '',
563
+ durationLabel: activeLeg && activeLeg.duration ? activeLeg.duration.text : '',
564
+ }));
565
+ return;
566
+ }
567
+
568
+ directionsRenderer.set('directions', null);
569
+ },
570
+ );
571
+ });
572
+ });
573
+
574
+ paths.forEach(function (path) {
575
+ var from = resolvePathPosition(path && path.from);
576
+ var to = resolvePathPosition(path && path.to);
577
+
578
+ if (!from || !to) {
579
+ return;
580
+ }
581
+
582
+ bounds.extend(from);
583
+ bounds.extend(to);
584
+
585
+ new window.google.maps.Polyline({
586
+ path: [from, to],
587
+ geodesic: true,
588
+ strokeColor: path && path.color ? path.color : ${serializeForHtml(routeColor)},
589
+ strokeOpacity: 0.72,
590
+ strokeWeight: 4,
591
+ map: map,
592
+ });
593
+ });
594
+
595
+ if (bounds.isEmpty()) {
596
+ showError('Nao foi possivel localizar as franquias no mapa.');
597
+ return;
598
+ }
599
+
600
+ map.fitBounds(bounds, {
601
+ top: 56,
602
+ right: 32,
603
+ bottom: 56,
604
+ left: 32,
605
+ });
606
+
607
+ postMessage({type: 'ready'});
608
+
609
+ window.google.maps.event.addListenerOnce(map, 'idle', function () {
610
+ if (resolvedMarkers.length === 1 && map.getZoom() > 15) {
611
+ map.setZoom(15);
612
+ }
613
+ });
614
+ }).catch(function () {
615
+ showError('Nao foi possivel localizar as franquias no mapa.');
616
+ });
617
+ } catch (error) {
618
+ showError('Nao foi possivel carregar o Google Maps.');
619
+ }
620
+ };
522
621
  </script>
523
622
  <script
524
623
  async