@fleetbase/fleetops-engine 0.2.8 → 0.3.0

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 (88) hide show
  1. package/addon/components/context-panel.hbs +5 -0
  2. package/addon/components/context-panel.js +6 -0
  3. package/addon/components/driver-card-mini.js +34 -13
  4. package/addon/components/driver-form-panel.hbs +23 -23
  5. package/addon/components/driver-form-panel.js +96 -13
  6. package/addon/components/driver-panel.hbs +12 -12
  7. package/addon/components/driver-panel.js +125 -21
  8. package/addon/components/fleet-vehicle-listing.hbs +1 -1
  9. package/addon/components/live-map.hbs +20 -9
  10. package/addon/components/live-map.js +1255 -353
  11. package/addon/components/map-container/toolbar/visibility-control-panel.hbs +66 -0
  12. package/addon/components/map-container/toolbar/visibility-control-panel.js +74 -0
  13. package/addon/components/map-container/toolbar/zones-panel.hbs +10 -10
  14. package/addon/components/map-container/toolbar/zones-panel.js +90 -61
  15. package/addon/components/map-container/toolbar.hbs +12 -7
  16. package/addon/components/modals/vehicle-form.hbs +35 -35
  17. package/addon/components/settings-window.hbs +1 -1
  18. package/addon/components/vehicle-form-panel.hbs +25 -26
  19. package/addon/components/vehicle-form-panel.js +95 -12
  20. package/addon/components/vehicle-panel.hbs +12 -13
  21. package/addon/components/vehicle-panel.js +130 -20
  22. package/addon/controllers/management/drivers/index/details.js +53 -0
  23. package/addon/controllers/management/drivers/index/edit.js +77 -46
  24. package/addon/controllers/management/drivers/index/new.js +39 -79
  25. package/addon/controllers/management/drivers/index.js +17 -221
  26. package/addon/controllers/management/fleets/index/edit.js +1 -1
  27. package/addon/controllers/management/fleets/index/new.js +1 -1
  28. package/addon/controllers/management/fuel-reports/index.js +2 -2
  29. package/addon/controllers/management/vehicles/index/details.js +49 -0
  30. package/addon/controllers/management/vehicles/index/edit.js +104 -1
  31. package/addon/controllers/management/vehicles/index/new.js +71 -0
  32. package/addon/controllers/operations/orders/index/new.js +4 -6
  33. package/addon/controllers/operations/orders/index/view.js +22 -14
  34. package/addon/controllers/operations/orders/index.js +124 -50
  35. package/addon/controllers/operations/service-rates/index/edit.js +1 -1
  36. package/addon/controllers/operations/service-rates/index/new.js +1 -1
  37. package/addon/engine.js +6 -0
  38. package/addon/helpers/is-visibility-control-visible.js +18 -0
  39. package/addon/routes/application.js +1 -1
  40. package/addon/routes/home.js +1 -1
  41. package/addon/routes/management/drivers/index/details.js +5 -0
  42. package/addon/routes/operations/orders/index/view.js +4 -2
  43. package/addon/routes/operations/orders/index.js +5 -1
  44. package/addon/routes/operations/service-rates/index.js +1 -1
  45. package/addon/routes/operations/zones/index.js +1 -1
  46. package/addon/services/context-panel.js +173 -0
  47. package/addon/services/leaflet-contextmenu-manager.js +311 -0
  48. package/addon/services/leaflet-map-manager.js +61 -0
  49. package/addon/services/service-areas.js +242 -32
  50. package/addon/templates/application.hbs +2 -1
  51. package/addon/templates/management/drivers/index/details.hbs +1 -1
  52. package/addon/templates/management/drivers/index/edit.hbs +1 -1
  53. package/addon/templates/management/drivers/index/new.hbs +1 -1
  54. package/addon/templates/management/vehicles/index/details.hbs +1 -1
  55. package/addon/templates/management/vehicles/index/edit.hbs +1 -1
  56. package/addon/templates/management/vehicles/index/new.hbs +1 -1
  57. package/addon/templates/operations/orders/index/view.hbs +2 -2
  58. package/addon/templates/operations/orders/index.hbs +1 -1
  59. package/addon/utils/apply-context-component-arguments.js +31 -0
  60. package/addon/utils/context-component-callback.js +16 -0
  61. package/addon/utils/find-leaflet-layer.js +13 -0
  62. package/addon/utils/fly-to-leaflet-layer.js +25 -0
  63. package/addon/utils/get-leaflet-layer-by-id.js +12 -0
  64. package/addon/utils/layer-can-bind-contextmenu.js +3 -0
  65. package/app/components/context-panel.js +1 -0
  66. package/app/components/map-container/toolbar/visibility-control-panel.js +1 -0
  67. package/app/helpers/is-visibility-control-visible.js +1 -0
  68. package/app/services/context-panel.js +1 -0
  69. package/app/services/leaflet-contextmenu-manager.js +1 -0
  70. package/app/services/leaflet-map-manager.js +1 -0
  71. package/app/utils/apply-context-component-arguments.js +1 -0
  72. package/app/utils/context-component-callback.js +1 -0
  73. package/app/utils/find-leaflet-layer.js +1 -0
  74. package/app/utils/fly-to-leaflet-layer.js +1 -0
  75. package/app/utils/get-leaflet-layer-by-id.js +1 -0
  76. package/app/utils/layer-can-bind-contextmenu.js +1 -0
  77. package/composer.json +11 -1
  78. package/extension.json +1 -1
  79. package/package.json +3 -3
  80. package/server/migrations/2023_09_14_074512_update_vehicles_table.php +89 -88
  81. package/server/migrations/2023_10_25_093014_create_vehicle_device_events_table.php +56 -0
  82. package/server/src/Http/Controllers/Internal/v1/LiveController.php +7 -4
  83. package/server/src/Http/Filter/VehicleFilter.php +7 -0
  84. package/server/src/Http/Resources/v1/Vehicle.php +52 -39
  85. package/server/src/Models/VehicleDevice.php +17 -3
  86. package/server/src/Models/VehicleDeviceEvent.php +90 -0
  87. package/addon/services/map-manager.js +0 -3
  88. package/app/services/map-manager.js +0 -1
@@ -0,0 +1,66 @@
1
+ <div class="next-dd-menu overflow-visible">
2
+ <div class="px-1">
3
+ <div class="text-sm flex flex-row items-center px-3 py-0.5 rounded-md my-1 text-gray-800 dark:text-gray-300">
4
+ Visibility Controls
5
+ </div>
6
+ </div>
7
+ <div class="next-dd-menu-seperator"></div>
8
+ <div class="px-1">
9
+ <a href="javascript:;" class="next-dd-item flex-row items-center justify-between relative" {{on "click" (fn this.triggerCallback "toggleVisibility" "places")}}>
10
+ <div class="flex flex-row items-center">
11
+ <div class="w-6">
12
+ <FaIcon @icon="building" />
13
+ </div>
14
+ <span>
15
+ {{#if (is-visibility-control-visible this.liveMap "places")}}
16
+ Hide all places...
17
+ {{else}}
18
+ Show all places...
19
+ {{/if}}
20
+ </span>
21
+ </div>
22
+ <div>
23
+ <Badge @status="info" @hideStatusDot={{true}} @spanClass="rounded-full -mr-2">{{this.liveMap.originalResources.places.length}}</Badge>
24
+ </div>
25
+ </a>
26
+ <BasicDropdownHover @horizontalPosition="right" @calculatePosition={{this.calculatePosition}} @renderInPlace={{true}} as |dd|>
27
+ <dd.Trigger class="next-dd-item flex-row items-center justify-between relative {{if dd.isOpen 'active'}}">
28
+ <div class="flex flex-row items-center">
29
+ <div class="w-6">
30
+ <FaIcon @icon="car" />
31
+ </div>
32
+ <span>Vehicles</span>
33
+ </div>
34
+ <div>
35
+ <Badge @status="info" @hideStatusDot={{true}} @spanClass="rounded-full -mr-2">{{this.liveMap.originalResources.vehicles.length}}</Badge>
36
+ </div>
37
+ </dd.Trigger>
38
+ <dd.Content>
39
+ <div class="next-dd-menu">
40
+ <div class="px-1">
41
+ <div class="text-sm flex flex-row items-center px-3 py-0.5 rounded-md my-1 text-gray-800 dark:text-gray-300 truncate">
42
+ <FaIcon @icon="binoculars" class="mr-2" />
43
+ <span>Vehicle Visibility Controls...</span>
44
+ </div>
45
+ </div>
46
+ <div class="next-dd-menu-seperator"></div>
47
+ <div class="px-1">
48
+ <a href="javascript:;" class="next-dd-item" {{on "click" (fn this.triggerCallback "toggleAllOnlineOffline" "vehicles")}}>
49
+ {{#if (is-visibility-control-visible this.liveMap "vehicles")}}
50
+ Hide all vehicles...
51
+ {{else}}
52
+ Show all vehicles...
53
+ {{/if}}
54
+ </a>
55
+ <a href="javascript:;" class="next-dd-item" {{on "click" (fn this.triggerCallback "showOnline" "vehicles")}}>
56
+ Only show online vehicles...
57
+ </a>
58
+ <a href="javascript:;" class="next-dd-item" {{on "click" (fn this.triggerCallback "showOffline" "vehicles")}}>
59
+ Only show offline vehicles...
60
+ </a>
61
+ </div>
62
+ </div>
63
+ </dd.Content>
64
+ </BasicDropdownHover>
65
+ </div>
66
+ </div>
@@ -0,0 +1,74 @@
1
+ import Component from '@glimmer/component';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { action } from '@ember/object';
4
+ import { classify } from '@ember/string';
5
+ import { calculateInPlacePosition } from 'ember-basic-dropdown/utils/calculate-position';
6
+
7
+ /**
8
+ * @class MapContainerToolbarVisibilityControlPanelComponent
9
+ * @extends {Component}
10
+ * @memberof @fleetbase/fleetops-engine
11
+ */
12
+ export default class MapContainerToolbarVisibilityControlPanelComponent extends Component {
13
+ /**
14
+ * Reference to the map instance.
15
+ * @type {L.Map}
16
+ * @memberof MapContainerToolbarZonesPanelComponent
17
+ */
18
+ @tracked map;
19
+
20
+ /**
21
+ * Reference to the live map component instance.
22
+ * @type {LiveMapComponent}
23
+ * @memberof MapContainerToolbarZonesPanelComponent
24
+ */
25
+ @tracked liveMap;
26
+
27
+ /**
28
+ * Class constructor.
29
+ * @memberof MapContainerToolbarZonesPanelComponent
30
+ */
31
+ constructor() {
32
+ super(...arguments);
33
+ this.map = this.args.map;
34
+ this.liveMap = this.args.liveMap;
35
+ }
36
+
37
+ /**
38
+ * Calculate position for dropdown.
39
+ * @param {Element} trigger The triggering element
40
+ * @returns {Object} Position style object
41
+ * @memberof MapContainerToolbarZonesPanelComponent
42
+ */
43
+ @action calculatePosition(trigger) {
44
+ const position = calculateInPlacePosition(...arguments);
45
+ const rect = trigger.getBoundingClientRect();
46
+
47
+ position.style.top = '-0.5rem';
48
+ position.style.left = `calc(${rect.width}px + 0.75rem)`;
49
+
50
+ return position;
51
+ }
52
+
53
+ /**
54
+ * Generic callback trigger function.
55
+ * @param {string} callbackFn Callback function name
56
+ * @param {...any} params Parameters for the callback function
57
+ * @memberof MapContainerToolbarZonesPanelComponent
58
+ */
59
+ @action triggerCallback(callbackFn, ...params) {
60
+ const tryInvoke = (context, fnName) => {
61
+ if (context && typeof context[fnName] === 'function') {
62
+ context[fnName](...params);
63
+ }
64
+ };
65
+
66
+ tryInvoke(this, callbackFn);
67
+ tryInvoke(this.args, callbackFn);
68
+ tryInvoke(this.liveMap, callbackFn);
69
+
70
+ // Additional check for event callback function in args
71
+ const eventCallbackFn = `on${classify(callbackFn)}`;
72
+ tryInvoke(this.args, eventCallbackFn);
73
+ }
74
+ }
@@ -1,4 +1,4 @@
1
- <div class="next-dd-menu overflow-visible" {{did-insert this.setupZonesPanel}}>
1
+ <div class="next-dd-menu overflow-visible">
2
2
  <div class="px-1">
3
3
  <div class="text-sm flex flex-row items-center px-3 py-0.5 rounded-md my-1 text-gray-800 dark:text-gray-300">
4
4
  Service Areas
@@ -6,9 +6,9 @@
6
6
  </div>
7
7
  <div class="next-dd-menu-seperator"></div>
8
8
  <div class="px-1">
9
- <a href="javascript:;" class="next-dd-item" {{on "click" (fn this.serviceAreaAction "createServiceArea" @dd)}}>Create new service area...</a>
10
- <a href="javascript:;" class="next-dd-item" {{on "click" (fn this.liveMapAction "focusAllServiceAreas" @dd)}}>Show all service areas</a>
11
- <a href="javascript:;" class="next-dd-item" {{on "click" (fn this.liveMapAction "blurAllServiceAreas" @dd)}}>Hide all service areas</a>
9
+ <a href="javascript:;" class="next-dd-item" {{on "click" (dropdown-fn @dd this.triggerCallback "createServiceArea")}}>Create new service area...</a>
10
+ <a href="javascript:;" class="next-dd-item" {{on "click" (dropdown-fn @dd this.triggerCallback "focusAllServiceAreas")}}>Show all service areas</a>
11
+ <a href="javascript:;" class="next-dd-item" {{on "click" (dropdown-fn @dd this.triggerCallback "blurAllServiceAreas")}}>Hide all service areas</a>
12
12
  {{#each this.serviceAreaRecords as |serviceArea|}}
13
13
  <BasicDropdownHover @horizontalPosition="right" @calculatePosition={{this.calculatePosition}} @renderInPlace={{true}} as |dd|>
14
14
  <dd.Trigger class="next-dd-item {{if dd.isOpen 'active'}}">
@@ -25,13 +25,13 @@
25
25
  </div>
26
26
  <div class="next-dd-menu-seperator"></div>
27
27
  <div class="px-1">
28
- <a href="javascript:;" class="next-dd-item" {{on "click" (fn this.liveMapAction "focusServiceArea" dd serviceArea)}}>Focus {{serviceArea.name}}...</a>
29
- {{#if (eq serviceArea this.activeServiceArea)}}
30
- <a href="javascript:;" class="next-dd-item" {{on "click" (fn this.liveMapAction "blurServiceArea" dd serviceArea)}}>Blur service area...</a>
28
+ <a href="javascript:;" class="next-dd-item" {{on "click" (dropdown-fn dd this.triggerCallback "focusServiceArea" serviceArea)}}>Focus {{serviceArea.name}}...</a>
29
+ {{#if (eq serviceArea this.liveMap.activeServiceArea)}}
30
+ <a href="javascript:;" class="next-dd-item" {{on "click" (dropdown-fn dd this.triggerCallback "blurServiceArea" serviceArea)}}>Blur service area...</a>
31
31
  {{/if}}
32
- <a href="javascript:;" class="next-dd-item" {{on "click" (fn this.serviceAreaAction "createZone" dd serviceArea)}}>Create zone inside...</a>
33
- <a href="javascript:;" class="next-dd-item" {{on "click" (fn this.serviceAreaAction "editServiceAreaDetails" dd serviceArea)}}>Edit {{serviceArea.name}}...</a>
34
- <a href="javascript:;" class="next-dd-item" {{on "click" (fn this.serviceAreaAction "deleteServiceArea" dd serviceArea)}}>Delete {{serviceArea.name}}...</a>
32
+ <a href="javascript:;" class="next-dd-item" {{on "click" (dropdown-fn dd this.triggerCallback "createZone" serviceArea)}}>Create zone inside...</a>
33
+ <a href="javascript:;" class="next-dd-item" {{on "click" (dropdown-fn dd this.triggerCallback "editServiceAreaDetails" serviceArea)}}>Edit {{serviceArea.name}}...</a>
34
+ <a href="javascript:;" class="next-dd-item" {{on "click" (dropdown-fn dd this.triggerCallback "deleteServiceArea" serviceArea)}}>Delete {{serviceArea.name}}...</a>
35
35
  </div>
36
36
  </div>
37
37
  </dd.Content>
@@ -2,30 +2,82 @@ import Component from '@glimmer/component';
2
2
  import { tracked } from '@glimmer/tracking';
3
3
  import { inject as service } from '@ember/service';
4
4
  import { action } from '@ember/object';
5
- import { alias } from '@ember/object/computed';
5
+ import { classify } from '@ember/string';
6
6
  import { calculateInPlacePosition } from 'ember-basic-dropdown/utils/calculate-position';
7
7
 
8
+ /**
9
+ * @class MapContainerToolbarZonesPanelComponent
10
+ * @extends {Component}
11
+ * @memberof @fleetbase/fleetops-engine
12
+ */
8
13
  export default class MapContainerToolbarZonesPanelComponent extends Component {
14
+ /**
15
+ * Ember Data store service.
16
+ * @type {Service}
17
+ * @memberof MapContainerToolbarZonesPanelComponent
18
+ */
9
19
  @service store;
10
- @service modalsManager;
11
- @service notifications;
12
- @service crud;
20
+
21
+ /**
22
+ * Service areas service.
23
+ * @type {Service}
24
+ * @memberof MapContainerToolbarZonesPanelComponent
25
+ */
13
26
  @service serviceAreas;
27
+
28
+ /**
29
+ * Application cache service.
30
+ * @type {Service}
31
+ * @memberof MapContainerToolbarZonesPanelComponent
32
+ */
14
33
  @service appCache;
15
34
 
35
+ /**
36
+ * Indicates if the component is in a loading state.
37
+ * @type {boolean}
38
+ * @memberof MapContainerToolbarZonesPanelComponent
39
+ */
16
40
  @tracked isLoading = false;
41
+
42
+ /**
43
+ * Holds the records for service areas.
44
+ * @type {Array}
45
+ * @memberof MapContainerToolbarZonesPanelComponent
46
+ */
17
47
  @tracked serviceAreaRecords = [];
18
- @tracked editableLayers = [];
19
- @tracked serviceAreaTypes = ['neighborhood', 'city', 'region', 'state', 'province', 'country', 'continent'];
20
- @alias('args.map') leafletMap;
21
- @alias('args.map.liveMap.activeServiceArea') activeServiceArea;
22
- @alias('args.map.liveMap.activeFeatureGroup') activeFeatureGroup;
23
48
 
24
- @action setupZonesPanel() {
49
+ /**
50
+ * Reference to the map instance.
51
+ * @type {L.Map}
52
+ * @memberof MapContainerToolbarZonesPanelComponent
53
+ */
54
+ @tracked map;
55
+
56
+ /**
57
+ * Reference to the live map component instance.
58
+ * @type {LiveMapComponent}
59
+ * @memberof MapContainerToolbarZonesPanelComponent
60
+ */
61
+ @tracked liveMap;
62
+
63
+ /**
64
+ * Class constructor.
65
+ * @memberof MapContainerToolbarZonesPanelComponent
66
+ */
67
+ constructor() {
68
+ super(...arguments);
69
+ this.map = this.args.map;
70
+ this.liveMap = this.args.liveMap;
25
71
  this.fetchServiceAreas();
26
- this.serviceAreas.setMapInstance(this.leafletMap);
72
+ this.serviceAreas.setMapInstance(this.args.map);
27
73
  }
28
74
 
75
+ /**
76
+ * Calculate position for dropdown.
77
+ * @param {Element} trigger The triggering element
78
+ * @returns {Object} Position style object
79
+ * @memberof MapContainerToolbarZonesPanelComponent
80
+ */
29
81
  @action calculatePosition(trigger) {
30
82
  const position = calculateInPlacePosition(...arguments);
31
83
  const rect = trigger.getBoundingClientRect();
@@ -36,64 +88,41 @@ export default class MapContainerToolbarZonesPanelComponent extends Component {
36
88
  return position;
37
89
  }
38
90
 
39
- @action onAction(actionName, dd, ...params) {
40
- if (typeof dd?.actions?.close === 'function') {
41
- dd.actions.close();
42
- }
43
-
44
- if (typeof this[actionName] === 'function') {
45
- this[actionName](...params);
46
- }
47
-
48
- if (typeof this.args[actionName] === 'function') {
49
- this.args[actionName](...params);
50
- }
51
-
52
- if (typeof this.args[`on${actionName?.toUpperCase()}`] === 'function') {
53
- this.args[`on${actionName?.toUpperCase()}`](...params);
54
- }
55
- }
56
-
57
- @action serviceAreaAction(actionName, dropdown, ...params) {
58
- const { dd } = this.args;
59
-
60
- if (typeof dd?.actions?.close === 'function') {
61
- dd.actions.close();
62
- }
63
-
64
- if (typeof dropdown?.actions?.close === 'function') {
65
- dropdown.actions.close();
66
- }
67
-
68
- if (typeof this.serviceAreas[actionName] === 'function') {
69
- this.serviceAreas[actionName](...params);
70
- }
71
- }
72
-
73
- @action liveMapAction(actionName, dropdown, ...params) {
74
- const { dd } = this.args;
75
-
76
- if (typeof dd?.actions?.close === 'function') {
77
- dd.actions.close();
78
- }
79
-
80
- if (typeof dropdown?.actions?.close === 'function') {
81
- dropdown.actions.close();
82
- }
83
-
84
- if (typeof this.leafletMap?.liveMap[actionName] === 'function') {
85
- this.leafletMap?.liveMap[actionName](...params);
86
- }
91
+ /**
92
+ * Generic callback trigger function.
93
+ * @param {string} callbackFn Callback function name
94
+ * @param {...any} params Parameters for the callback function
95
+ * @memberof MapContainerToolbarZonesPanelComponent
96
+ */
97
+ @action triggerCallback(callbackFn, ...params) {
98
+ const tryInvoke = (context, fnName) => {
99
+ if (context && typeof context[fnName] === 'function') {
100
+ context[fnName](...params);
101
+ }
102
+ };
103
+
104
+ tryInvoke(this, callbackFn);
105
+ tryInvoke(this.args, callbackFn);
106
+ tryInvoke(this.liveMap, callbackFn);
107
+ tryInvoke(this.serviceAreas, callbackFn);
108
+
109
+ // Additional check for event callback function in args
110
+ const eventCallbackFn = `on${classify(callbackFn)}`;
111
+ tryInvoke(this.args, eventCallbackFn);
87
112
  }
88
113
 
89
- @action fetchServiceAreas() {
114
+ /**
115
+ * Fetch service areas and update state.
116
+ * @memberof MapContainerToolbarZonesPanelComponent
117
+ */
118
+ fetchServiceAreas() {
90
119
  this.isLoading = true;
91
120
 
92
121
  if (this.appCache.has('serviceAreas')) {
93
122
  this.serviceAreaRecords = this.appCache.getEmberData('serviceAreas', 'service-area');
94
123
  }
95
124
 
96
- this.store
125
+ return this.store
97
126
  .query('service-area', { with: ['zones'] })
98
127
  .then((serviceAreaRecords) => {
99
128
  this.serviceAreaRecords = serviceAreaRecords;
@@ -44,14 +44,19 @@
44
44
  </Attach::Tooltip>
45
45
  </dd.Trigger>
46
46
  <dd.Content>
47
- <MapContainer::Toolbar::ZonesPanel @dd={{dd}} @map={{@map}} @onPressCreateServiceArea={{@onPressCreateServiceArea}} />
47
+ <MapContainer::Toolbar::ZonesPanel @dd={{dd}} @liveMap={{@liveMap}} @map={{@map}} @onPressCreateServiceArea={{@onPressCreateServiceArea}} />
48
+ </dd.Content>
49
+ </BasicDropdown>
50
+ <BasicDropdown @horizontalPosition="right" @calculatePosition={{this.calculatePosition}} @renderInPlace={{true}} as |dd|>
51
+ <dd.Trigger class="toolbar-button">
52
+ <FaIcon @icon="eye" />
53
+ <Attach::Tooltip @class="clean" @animation="scale" @placement="right">
54
+ <InputInfo @text="Visibility Controls" @iconClass="hidden" class="{{if dd.isOpen 'hidden'}} py-1 px-2 bg-gray-900 -mt-1" />
55
+ </Attach::Tooltip>
56
+ </dd.Trigger>
57
+ <dd.Content>
58
+ <MapContainer::Toolbar::VisibilityControlPanel @dd={{dd}} @liveMap={{@liveMap}} @map={{@map}} />
48
59
  </dd.Content>
49
60
  </BasicDropdown>
50
- <button type="button" class="toolbar-button relative" {{on "click" (fn this.onAction "onPressDisplayPlaces")}}>
51
- <FaIcon @icon="city" />
52
- <Attach::Tooltip @class="clean" @animation="scale" @placement="right">
53
- <InputInfo @text="Toggle Places" @iconClass="hidden" class="py-1 px-2 bg-gray-900 -mt-1" />
54
- </Attach::Tooltip>
55
- </button>
56
61
  </div>
57
62
  </MapContainer::ToolbarContainer>