@fleetbase/fleetops-engine 0.6.55 → 0.6.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/addon/components/admin/map-settings.hbs +1 -1
- package/addon/components/ai/create-order-preview.hbs +297 -0
- package/addon/components/ai/create-order-preview.js +362 -0
- package/addon/components/ai/route-preview-map.hbs +79 -0
- package/addon/components/ai/route-preview-map.js +527 -0
- package/addon/components/device/details.js +1 -1
- package/addon/components/device-event/details.hbs +192 -0
- package/addon/components/device-event/details.js +151 -0
- package/addon/components/driver/schedule.js +1 -1
- package/addon/components/fleet/details.hbs +21 -8
- package/addon/components/fleet/details.js +55 -1
- package/addon/components/fleet/hierarchy-tree.hbs +137 -0
- package/addon/components/fleet/hierarchy-tree.js +528 -0
- package/addon/components/layout/fleet-ops-sidebar.js +15 -9
- package/addon/components/map/drawer/device-event-listing.js +1 -0
- package/addon/components/map/drawer/driver-listing.js +1 -0
- package/addon/components/map/drawer/place-listing.js +1 -0
- package/addon/components/map/drawer/vehicle-listing.js +1 -0
- package/addon/components/order/details.hbs +34 -1
- package/addon/components/order/form/details.hbs +4 -0
- package/addon/components/order/form.hbs +9 -1
- package/addon/components/telematic/details.hbs +1 -1
- package/addon/components/telematic/form.hbs +2 -2
- package/addon/components/telematic/settings.hbs +1 -1
- package/addon/components/vehicle/card.hbs +14 -2
- package/addon/components/vehicle/form.hbs +13 -1
- package/addon/controllers/connectivity/devices/index/details/events.js +1 -1
- package/addon/controllers/connectivity/devices/index/details/vehicle.js +2 -2
- package/addon/controllers/connectivity/events/details.js +68 -1
- package/addon/controllers/connectivity/sensors/index.js +4 -0
- package/addon/controllers/connectivity/telematics/details/events.js +1 -1
- package/addon/controllers/connectivity/telematics/details/sensors.js +4 -0
- package/addon/controllers/settings/map.js +19 -0
- package/addon/extension.js +14 -0
- package/addon/instance-initializers/register-vroom-allocation.js +1 -1
- package/addon/routes/connectivity/events/details.js +26 -1
- package/addon/routes/management/fleets/index/details.js +1 -1
- package/addon/routes/management/vehicles/index/details.js +3 -1
- package/addon/services/map-adapter/google.js +66 -1
- package/addon/services/map-adapter/leaflet.js +1 -1
- package/addon/services/map-adapter-interface.js +1 -1
- package/addon/services/map-manager.js +16 -1
- package/addon/services/map-settings.js +15 -0
- package/addon/styles/fleetops-engine.css +487 -1
- package/addon/templates/connectivity/devices/index/details/vehicle.hbs +2 -1
- package/addon/templates/connectivity/events/details.hbs +40 -1
- package/addon/templates/settings/map.hbs +38 -9
- package/addon/utils/leaflet-plugin-loader.js +5 -5
- package/addon/utils/map-drawer-dropdown-position.js +11 -13
- package/addon/utils/route-colors.js +1 -1
- package/app/components/ai/create-order-preview.js +1 -0
- package/app/components/ai/route-preview-map.js +1 -0
- package/app/components/device-event/details.hbs +192 -0
- package/app/components/device-event/details.js +1 -0
- package/app/components/fleet/hierarchy-tree.js +1 -0
- package/app/services/route-engine.js +1 -0
- package/composer.json +1 -1
- package/extension.json +1 -1
- package/package.json +6 -4
- package/scripts/normalize-rgba-alpha.js +90 -0
- package/server/migrations/2026_06_23_000001_delete_bad_afaqy_telematics_sensors.php +34 -0
- package/server/src/Exports/ContactExport.php +12 -5
- package/server/src/Exports/DeviceExport.php +92 -0
- package/server/src/Exports/DriverExport.php +28 -3
- package/server/src/Exports/EquipmentExport.php +94 -0
- package/server/src/Exports/FleetExport.php +22 -7
- package/server/src/Exports/FuelReportExport.php +16 -1
- package/server/src/Exports/IssueExport.php +25 -3
- package/server/src/Exports/MaintenanceExport.php +106 -0
- package/server/src/Exports/MaintenanceScheduleExport.php +99 -0
- package/server/src/Exports/OrderExport.php +24 -5
- package/server/src/Exports/PartExport.php +99 -0
- package/server/src/Exports/PlaceExport.php +33 -7
- package/server/src/Exports/SensorExport.php +94 -0
- package/server/src/Exports/ServiceAreaExport.php +31 -7
- package/server/src/Exports/ServiceRateExport.php +41 -1
- package/server/src/Exports/TelematicExport.php +90 -0
- package/server/src/Exports/VehicleExport.php +274 -8
- package/server/src/Exports/VendorExport.php +15 -2
- package/server/src/Exports/WorkOrderExport.php +92 -0
- package/server/src/Http/Controllers/Api/v1/Concerns/ResolvesFleetOpsApiResources.php +176 -0
- package/server/src/Http/Controllers/Api/v1/DeviceController.php +225 -0
- package/server/src/Http/Controllers/Api/v1/EquipmentController.php +114 -0
- package/server/src/Http/Controllers/Api/v1/FuelTransactionController.php +185 -0
- package/server/src/Http/Controllers/Api/v1/PartController.php +120 -0
- package/server/src/Http/Controllers/Api/v1/SensorController.php +132 -0
- package/server/src/Http/Controllers/Api/v1/WorkOrderController.php +161 -0
- package/server/src/Http/Controllers/Internal/v1/DeviceController.php +18 -0
- package/server/src/Http/Controllers/Internal/v1/EquipmentController.php +17 -0
- package/server/src/Http/Controllers/Internal/v1/MaintenanceController.php +17 -0
- package/server/src/Http/Controllers/Internal/v1/MaintenanceScheduleController.php +17 -0
- package/server/src/Http/Controllers/Internal/v1/PartController.php +17 -0
- package/server/src/Http/Controllers/Internal/v1/SensorController.php +18 -0
- package/server/src/Http/Controllers/Internal/v1/SettingController.php +29 -5
- package/server/src/Http/Controllers/Internal/v1/TelematicController.php +18 -0
- package/server/src/Http/Controllers/Internal/v1/WorkOrderController.php +17 -0
- package/server/src/Http/Filter/DeviceFilter.php +33 -10
- package/server/src/Http/Filter/EquipmentFilter.php +23 -0
- package/server/src/Http/Filter/FuelProviderTransactionFilter.php +57 -2
- package/server/src/Http/Filter/PartFilter.php +47 -0
- package/server/src/Http/Filter/SensorFilter.php +34 -6
- package/server/src/Http/Filter/WorkOrderFilter.php +23 -0
- package/server/src/Http/Requests/CreateDeviceRequest.php +51 -0
- package/server/src/Http/Requests/CreateEquipmentRequest.php +35 -0
- package/server/src/Http/Requests/CreateFuelTransactionRequest.php +50 -0
- package/server/src/Http/Requests/CreatePartRequest.php +40 -0
- package/server/src/Http/Requests/CreateSensorRequest.php +47 -0
- package/server/src/Http/Requests/CreateWorkOrderRequest.php +42 -0
- package/server/src/Http/Requests/UpdateDeviceRequest.php +7 -0
- package/server/src/Http/Requests/UpdateEquipmentRequest.php +7 -0
- package/server/src/Http/Requests/UpdateFuelTransactionRequest.php +7 -0
- package/server/src/Http/Requests/UpdatePartRequest.php +7 -0
- package/server/src/Http/Requests/UpdateSensorRequest.php +7 -0
- package/server/src/Http/Requests/UpdateWorkOrderRequest.php +7 -0
- package/server/src/Http/Resources/v1/Device.php +72 -0
- package/server/src/Http/Resources/v1/Equipment.php +57 -0
- package/server/src/Http/Resources/v1/Fleet.php +8 -2
- package/server/src/Http/Resources/v1/FuelTransaction.php +69 -0
- package/server/src/Http/Resources/v1/Part.php +64 -0
- package/server/src/Http/Resources/v1/Sensor.php +68 -0
- package/server/src/Jobs/SyncTelematicDevicesJob.php +194 -38
- package/server/src/Models/Driver.php +6 -0
- package/server/src/Models/Order.php +20 -7
- package/server/src/Models/Place.php +11 -3
- package/server/src/Observers/PurchaseRateObserver.php +2 -1
- package/server/src/Providers/FleetOpsServiceProvider.php +26 -0
- package/server/src/Support/Ai/Capabilities/AbstractFleetOpsAICapability.php +88 -0
- package/server/src/Support/Ai/Capabilities/AssetStatusCapability.php +108 -0
- package/server/src/Support/Ai/Capabilities/ConsoleNavigationCapability.php +55 -0
- package/server/src/Support/Ai/Capabilities/CreateOrderPreviewCapability.php +508 -0
- package/server/src/Support/Ai/Capabilities/DocsHelpCapability.php +49 -0
- package/server/src/Support/Ai/Capabilities/ImportOrdersPreviewCapability.php +66 -0
- package/server/src/Support/Ai/Capabilities/OperationalQueryCapability.php +319 -0
- package/server/src/Support/Ai/Capabilities/OptimizeOrderRouteCapability.php +240 -0
- package/server/src/Support/Ai/Capabilities/OrderInsightsCapability.php +95 -0
- package/server/src/Support/Ai/Capabilities/SearchResourcesCapability.php +195 -0
- package/server/src/Support/Ai/FleetOpsAiQueryResources.php +150 -0
- package/server/src/Support/Analytics/RevenueTrend.php +3 -8
- package/server/src/Support/Metrics/ActiveRevenueQuery.php +121 -0
- package/server/src/Support/Metrics/AvgOrderValueMetric.php +1 -7
- package/server/src/Support/Metrics/EarningsMetric.php +1 -10
- package/server/src/Support/Telematics/Providers/AfaqyProvider.php +104 -5
- package/server/src/Support/Telematics/Providers/SafeeProvider.php +550 -54
- package/server/src/Support/Telematics/TelematicService.php +28 -9
- package/server/src/Support/Utils.php +52 -0
- package/server/src/routes.php +67 -14
- package/server/tests/AiCreateOrderPreviewCapabilityTest.php +131 -0
- package/server/tests/AiOperationalQueryCapabilityTest.php +75 -0
- package/server/tests/ExportCoverageTest.php +79 -0
- package/server/tests/FleetHierarchyResourceTest.php +12 -0
- package/server/tests/MetricsRegistryTest.php +45 -5
- package/server/tests/OrderPayloadPlaceResolutionTest.php +53 -0
- package/server/tests/PointResolutionTest.php +63 -0
- package/server/tests/PublicFleetOpsRestEndpointsTest.php +191 -0
- package/server/tests/TelematicsHardeningTest.php +636 -1
- package/addon/components/table/cell/dropdown/action-item.hbs +0 -31
- package/addon/components/table/cell/dropdown/action-item.js +0 -62
- package/addon/components/table/cell/dropdown.hbs +0 -28
- package/addon/components/table/cell/dropdown.js +0 -91
- package/app/components/table/cell/dropdown/action-item.js +0 -1
- package/app/components/table/cell/dropdown.js +0 -1
|
@@ -2,8 +2,24 @@
|
|
|
2
2
|
{{#if (has-block)}}
|
|
3
3
|
{{yield
|
|
4
4
|
(hash
|
|
5
|
+
RegistryYieldStart=(component
|
|
6
|
+
"registry-yield"
|
|
7
|
+
registry="fleet-ops:component:order:details:start"
|
|
8
|
+
resource=@resource
|
|
9
|
+
controller=@controller
|
|
10
|
+
permission=(get-write-permission @resource)
|
|
11
|
+
isLoading=@isLoading
|
|
12
|
+
)
|
|
5
13
|
Activity=(component "order/details/activity" resource=@resource onChange=this.handleActivityChanged isLoadingActivity=@isLoadingActivity isLoading=@isLoading)
|
|
6
14
|
Detail=(component "order/details/detail" resource=@resource onChange=@onDetailsChanged isLoading=@isLoading)
|
|
15
|
+
RegistryYieldAfterDetails=(component
|
|
16
|
+
"registry-yield"
|
|
17
|
+
registry="fleet-ops:component:order:details:after-details"
|
|
18
|
+
resource=@resource
|
|
19
|
+
controller=@controller
|
|
20
|
+
permission=(get-write-permission @resource)
|
|
21
|
+
isLoading=@isLoading
|
|
22
|
+
)
|
|
7
23
|
CustomFields=(component "order/details/custom-fields" resource=@resource onChange=@onCustomFieldsChanged isLoading=@isLoading)
|
|
8
24
|
PurchaseRate=(component "order/details/purchase-rate" resource=@resource isLoading=@isLoading)
|
|
9
25
|
Tracking=(component "order/details/tracking" resource=@resource isLoading=@isLoading)
|
|
@@ -18,11 +34,25 @@
|
|
|
18
34
|
Documents=(component "order/details/documents" resource=@resource onChange=@onDocumentsChanged isLoading=@isLoading)
|
|
19
35
|
Comments=(component "order/details/comments" resource=@resource onChange=@onCommentsChanged isLoading=@isLoading)
|
|
20
36
|
Metadata=(component "order/details/metadata" resource=@resource onChange=@onMetadataChanged isLoading=@isLoading)
|
|
37
|
+
RegistryYieldEnd=(component
|
|
38
|
+
"registry-yield"
|
|
39
|
+
registry="fleet-ops:component:order:details:end"
|
|
40
|
+
resource=@resource
|
|
41
|
+
controller=@controller
|
|
42
|
+
permission=(get-write-permission @resource)
|
|
43
|
+
isLoading=@isLoading
|
|
44
|
+
)
|
|
21
45
|
)
|
|
22
46
|
}}
|
|
23
47
|
{{else}}
|
|
48
|
+
<RegistryYield @registry="fleet-ops:component:order:details:start" as |RegistryComponent|>
|
|
49
|
+
<RegistryComponent @resource={{@resource}} @controller={{@controller}} @permission={{get-write-permission @resource}} @isLoading={{@isLoading}} />
|
|
50
|
+
</RegistryYield>
|
|
24
51
|
<Order::Details::Activity @resource={{@resource}} @onChange={{this.handleActivityChanged}} @isLoadingActivity={{@isLoadingActivity}} @isLoading={{@isLoading}} />
|
|
25
52
|
<Order::Details::Detail @resource={{@resource}} @onChange={{@onDetailsChanged}} @isLoading={{@isLoading}} />
|
|
53
|
+
<RegistryYield @registry="fleet-ops:component:order:details:after-details" as |RegistryComponent|>
|
|
54
|
+
<RegistryComponent @resource={{@resource}} @controller={{@controller}} @permission={{get-write-permission @resource}} @isLoading={{@isLoading}} />
|
|
55
|
+
</RegistryYield>
|
|
26
56
|
<Order::Details::CustomFields @resource={{@resource}} @onChange={{@onCustomFieldsChanged}} @isLoading={{@isLoading}} />
|
|
27
57
|
<Order::Details::PurchaseRate @resource={{@resource}} @isLoading={{@isLoading}} />
|
|
28
58
|
<Order::Details::Tracking @resource={{@resource}} @isLoading={{@isLoading}} />
|
|
@@ -37,5 +67,8 @@
|
|
|
37
67
|
<Order::Details::Documents @resource={{@resource}} @onChange={{@onDocumentsChanged}} @isLoading={{@isLoading}} />
|
|
38
68
|
<Order::Details::Comments @resource={{@resource}} @onChange={{@onCommentsChanged}} @isLoading={{@isLoading}} />
|
|
39
69
|
<Order::Details::Metadata @resource={{@resource}} @onChange={{@onMetadataChanged}} @isLoading={{@isLoading}} />
|
|
70
|
+
<RegistryYield @registry="fleet-ops:component:order:details:end" as |RegistryComponent|>
|
|
71
|
+
<RegistryComponent @resource={{@resource}} @controller={{@controller}} @permission={{get-write-permission @resource}} @isLoading={{@isLoading}} />
|
|
72
|
+
</RegistryYield>
|
|
40
73
|
{{/if}}
|
|
41
|
-
</div>
|
|
74
|
+
</div>
|
|
@@ -234,6 +234,10 @@
|
|
|
234
234
|
/>
|
|
235
235
|
</InputGroup>
|
|
236
236
|
</div>
|
|
237
|
+
|
|
238
|
+
<RegistryYield @registry="fleet-ops:component:order:form:details" as |RegistryComponent|>
|
|
239
|
+
<RegistryComponent @order={{@resource}} @resource={{@resource}} />
|
|
240
|
+
</RegistryYield>
|
|
237
241
|
</div>
|
|
238
242
|
</ContentPanel>
|
|
239
243
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
{{#if (has-block)}}
|
|
3
3
|
{{yield
|
|
4
4
|
(hash
|
|
5
|
+
RegistryYieldStart=(component "registry-yield" registry="fleet-ops:component:order:form:start" order=@resource)
|
|
5
6
|
Details=(component "order/form/details" resource=@resource)
|
|
6
7
|
CustomFields=(component "order/form/custom-fields" resource=@resource customFields=@customFields)
|
|
7
8
|
Route=(component "order/form/route" resource=@resource)
|
|
@@ -12,9 +13,13 @@
|
|
|
12
13
|
Documents=(component "order/form/documents" resource=@resource)
|
|
13
14
|
OrchestratorConstraints=(component "order/form/orchestrator-constraints" resource=@resource)
|
|
14
15
|
Metadata=(component "order/form/metadata" resource=@resource)
|
|
16
|
+
RegistryYieldEnd=(component "registry-yield" registry="fleet-ops:component:order:form:end" order=@resource)
|
|
15
17
|
)
|
|
16
18
|
}}
|
|
17
19
|
{{else}}
|
|
20
|
+
<RegistryYield @registry="fleet-ops:component:order:form:start" as |RegistryComponent|>
|
|
21
|
+
<RegistryComponent @order={{@resource}} @resource={{@resource}} />
|
|
22
|
+
</RegistryYield>
|
|
18
23
|
<Order::Form::Details @resource={{@resource}} />
|
|
19
24
|
<Order::Form::Route @resource={{@resource}} />
|
|
20
25
|
<RegistryYield @registry="fleet-ops:component:order:form" as |RegistryComponent|>
|
|
@@ -26,5 +31,8 @@
|
|
|
26
31
|
<Order::Form::Documents @resource={{@resource}} />
|
|
27
32
|
<Order::Form::OrchestratorConstraints @resource={{@resource}} />
|
|
28
33
|
<Order::Form::Metadata @resource={{@resource}} />
|
|
34
|
+
<RegistryYield @registry="fleet-ops:component:order:form:end" as |RegistryComponent|>
|
|
35
|
+
<RegistryComponent @order={{@resource}} @resource={{@resource}} />
|
|
36
|
+
</RegistryYield>
|
|
29
37
|
{{/if}}
|
|
30
|
-
</div>
|
|
38
|
+
</div>
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
<div class="rounded-md border border-gray-200 p-3 dark:border-gray-700 md:col-span-2">
|
|
93
93
|
<div class="text-gray-400 dark:text-gray-500">Update Mode</div>
|
|
94
94
|
<div class="mt-1 font-semibold text-gray-900 dark:text-gray-100">Provider polling</div>
|
|
95
|
-
<div class="mt-1 text-gray-500 dark:text-gray-400">
|
|
95
|
+
<div class="mt-1 text-gray-500 dark:text-gray-400">Fleet-Ops polls this provider for device snapshots and telemetry updates.</div>
|
|
96
96
|
</div>
|
|
97
97
|
{{/if}}
|
|
98
98
|
</div>
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
<div class="mb-3">
|
|
71
71
|
<div>
|
|
72
72
|
<h2 class="text-sm font-bold text-gray-900 dark:text-gray-100">Credentials</h2>
|
|
73
|
-
<p class="text-xs text-gray-500 dark:text-gray-300">
|
|
73
|
+
<p class="text-xs text-gray-500 dark:text-gray-300">Fleet-Ops uses these credentials to test the connection and sync devices.</p>
|
|
74
74
|
</div>
|
|
75
75
|
</div>
|
|
76
76
|
|
|
@@ -266,7 +266,7 @@
|
|
|
266
266
|
</InputGroup>
|
|
267
267
|
{{else}}
|
|
268
268
|
<div class="rounded-md border border-dashed border-gray-300 p-3 text-xs text-gray-500 dark:border-gray-700 dark:text-gray-300 lg:col-span-2">
|
|
269
|
-
This provider does not require
|
|
269
|
+
This provider does not require Fleet-Ops webhook configuration.
|
|
270
270
|
</div>
|
|
271
271
|
{{/if}}
|
|
272
272
|
</div>
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
{{/if}}
|
|
113
113
|
{{else}}
|
|
114
114
|
<div class="rounded-md border border-dashed border-gray-300 p-3 text-xs text-gray-500 dark:border-gray-700 dark:text-gray-300">
|
|
115
|
-
This provider does not require
|
|
115
|
+
This provider does not require Fleet-Ops webhook configuration.
|
|
116
116
|
</div>
|
|
117
117
|
{{/if}}
|
|
118
118
|
</section>
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
<Layout::Resource::Card ...attributes as |Card|>
|
|
2
2
|
<Card.header class="{{@headerClass}}">
|
|
3
|
+
<RegistryYield @registry="fleet-ops:component:vehicle:card:header:start" as |RegistryComponent|>
|
|
4
|
+
<RegistryComponent @order={{@resource}} @resource={{@resource}} />
|
|
5
|
+
</RegistryYield>
|
|
3
6
|
<div class="font-semibold w-full truncate">{{or @resource.name @resource.yearMakeModel}}</div>
|
|
4
|
-
<div class="text-gray-
|
|
7
|
+
<div class="text-gray-400 dark:text-gray-500 text-sm w-full truncate">{{or @resource.plate_number @resource.vin @resource.serial_number @resource.call_sign @resource.public_id}}</div>
|
|
5
8
|
{{#if (has-block "header")}}
|
|
6
9
|
{{yield to="header"}}
|
|
7
10
|
{{/if}}
|
|
11
|
+
<RegistryYield @registry="fleet-ops:component:vehicle:card:header:end" as |RegistryComponent|>
|
|
12
|
+
<RegistryComponent @order={{@resource}} @resource={{@resource}} />
|
|
13
|
+
</RegistryYield>
|
|
8
14
|
</Card.header>
|
|
9
15
|
<Card.body class={{@bodyClass}}>
|
|
10
16
|
<Image src={{@resource.photo_url}} class="card-img-lg" />
|
|
@@ -13,16 +19,22 @@
|
|
|
13
19
|
{{/if}}
|
|
14
20
|
</Card.body>
|
|
15
21
|
<Card.footer class={{@footerClass}}>
|
|
22
|
+
<RegistryYield @registry="fleet-ops:component:vehicle:card:footer:start" as |RegistryComponent|>
|
|
23
|
+
<RegistryComponent @order={{@resource}} @resource={{@resource}} />
|
|
24
|
+
</RegistryYield>
|
|
16
25
|
<div class="flex flex-row items-center space-x-1">
|
|
17
26
|
<Button @icon="eye" @size="xs" @onClick={{fn this.vehicleActions.transition.view @resource}} />
|
|
18
27
|
<Button @icon="pencil" @size="xs" @onClick={{fn this.vehicleActions.transition.edit @resource}} />
|
|
19
28
|
<Button @icon="trash" @size="xs" @type="danger" @onClick={{fn this.vehicleActions.delete @resource}} />
|
|
20
29
|
</div>
|
|
30
|
+
<RegistryYield @registry="fleet-ops:component:vehicle:card:footer:end" as |RegistryComponent|>
|
|
31
|
+
<RegistryComponent @order={{@resource}} @resource={{@resource}} />
|
|
32
|
+
</RegistryYield>
|
|
21
33
|
{{#if (has-block "footer")}}
|
|
22
34
|
{{yield to="footer"}}
|
|
23
35
|
{{/if}}
|
|
24
36
|
<div class="mt-1.5">
|
|
25
|
-
<div class="text-gray-
|
|
37
|
+
<div class="text-gray-400 dark:text-gray-500 text-xs">Last Modified: {{@resource.updatedAt}}</div>
|
|
26
38
|
</div>
|
|
27
39
|
</Card.footer>
|
|
28
40
|
</Layout::Resource::Card>
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
<div class="form-wrapper" ...attributes>
|
|
2
|
+
<RegistryYield @registry="fleet-ops:component:vehicle:form:start" as |RegistryComponent|>
|
|
3
|
+
<RegistryComponent @resource={{@resource}} @controller={{this.controller}} @permission={{get-write-permission @resource}} />
|
|
4
|
+
</RegistryYield>
|
|
5
|
+
|
|
2
6
|
{{! DETAILS / IDENTIFICATION }}
|
|
3
7
|
<ContentPanel @title={{t "common.details"}} @open={{true}} @wrapperClass="bordered-top">
|
|
4
8
|
<div class="flex flex-row space-x-3 mb-3">
|
|
@@ -128,6 +132,10 @@
|
|
|
128
132
|
</RegistryYield>
|
|
129
133
|
</ContentPanel>
|
|
130
134
|
|
|
135
|
+
<RegistryYield @registry="fleet-ops:component:vehicle:form:after-details" as |RegistryComponent|>
|
|
136
|
+
<RegistryComponent @resource={{@resource}} @controller={{this.controller}} @permission={{get-write-permission @resource}} />
|
|
137
|
+
</RegistryYield>
|
|
138
|
+
|
|
131
139
|
{{! MEASUREMENT & UNITS / ODOMETER }}
|
|
132
140
|
<ContentPanel @title="Measurement & Units" @open={{true}} @wrapperClass="bordered-top">
|
|
133
141
|
<div class="grid grid-cols-1 gap-2 lg:grid-cols-2 lg:gap-2 no-input-group-padding text-xs">
|
|
@@ -608,4 +616,8 @@
|
|
|
608
616
|
<ContentPanel @title={{t "common.metadata"}} @open={{true}} @wrapperClass="bordered-top">
|
|
609
617
|
<MetadataEditor @value={{@resource.meta}} @onChange={{fn (mut @resource.meta)}} />
|
|
610
618
|
</ContentPanel>
|
|
611
|
-
|
|
619
|
+
|
|
620
|
+
<RegistryYield @registry="fleet-ops:component:vehicle:form:end" as |RegistryComponent|>
|
|
621
|
+
<RegistryComponent @resource={{@resource}} @controller={{this.controller}} @permission={{get-write-permission @resource}} />
|
|
622
|
+
</RegistryYield>
|
|
623
|
+
</div>
|
|
@@ -56,7 +56,7 @@ export default class ConnectivityDevicesIndexDetailsEventsController extends Con
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
get unprocessedEventsCount() {
|
|
59
|
-
return this.events.filter((event) => !event.processed_at
|
|
59
|
+
return this.events.filter((event) => !event.processed_at).length;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
get processedEventsCount() {
|
|
@@ -86,13 +86,13 @@ export default class ConnectivityDevicesIndexDetailsVehicleController extends Co
|
|
|
86
86
|
|
|
87
87
|
@action openVehicle() {
|
|
88
88
|
if (this.vehicle?.id) {
|
|
89
|
-
return this.hostRouter.transitionTo('console.fleet-ops.management.vehicles.index.details', this.vehicle);
|
|
89
|
+
return this.hostRouter.transitionTo('console.fleet-ops.management.vehicles.index.details', this.vehicle.public_id);
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
@action openVehiclePositions() {
|
|
94
94
|
if (this.vehicle?.id) {
|
|
95
|
-
return this.hostRouter.transitionTo('console.fleet-ops.management.vehicles.index.details.positions', this.vehicle);
|
|
95
|
+
return this.hostRouter.transitionTo('console.fleet-ops.management.vehicles.index.details.positions', this.vehicle.public_id);
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
|
|
@@ -1,3 +1,70 @@
|
|
|
1
1
|
import Controller from '@ember/controller';
|
|
2
|
+
import { action, set } from '@ember/object';
|
|
3
|
+
import { inject as service } from '@ember/service';
|
|
4
|
+
import { tracked } from '@glimmer/tracking';
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
function firstPresent(...values) {
|
|
7
|
+
return values.find((value) => value !== undefined && value !== null && value !== '');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function toDate(value) {
|
|
11
|
+
if (value instanceof Date) {
|
|
12
|
+
return value;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const date = new Date(value);
|
|
16
|
+
|
|
17
|
+
return Number.isNaN(date.getTime()) ? value : date;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default class ConnectivityEventsDetailsController extends Controller {
|
|
21
|
+
@service deviceEventActions;
|
|
22
|
+
@service hostRouter;
|
|
23
|
+
|
|
24
|
+
@tracked isMarkingProcessed = false;
|
|
25
|
+
|
|
26
|
+
get event() {
|
|
27
|
+
return this.model;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
get isProcessed() {
|
|
31
|
+
return Boolean(firstPresent(this.event?.processed_at, this.event?.processedAt));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get processedStatus() {
|
|
35
|
+
return this.isProcessed ? 'success' : 'warning';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
get processedLabel() {
|
|
39
|
+
return this.isProcessed ? 'Processed' : 'Unprocessed';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@action goBack() {
|
|
43
|
+
return this.hostRouter.transitionTo('console.fleet-ops.connectivity.events.index');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@action refresh() {
|
|
47
|
+
return this.hostRouter.refresh();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@action async markProcessed() {
|
|
51
|
+
if (this.isMarkingProcessed) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
this.isMarkingProcessed = true;
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
const response = await this.deviceEventActions.markProcessed(this.event);
|
|
59
|
+
const processedAt = firstPresent(response?.device_event?.processed_at, response?.device_event?.processedAt, new Date());
|
|
60
|
+
|
|
61
|
+
if (this.event) {
|
|
62
|
+
set(this.event, 'processed_at', toDate(processedAt));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return response;
|
|
66
|
+
} finally {
|
|
67
|
+
this.isMarkingProcessed = false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -178,6 +178,8 @@ export default class ConnectivitySensorsIndexController extends Controller {
|
|
|
178
178
|
filterParam: 'type',
|
|
179
179
|
filterComponent: 'filter/multi-option',
|
|
180
180
|
filterOptions: fleetOpsOptions('sensorTypes'),
|
|
181
|
+
filterOptionLabel: 'label',
|
|
182
|
+
filterOptionValue: 'value',
|
|
181
183
|
},
|
|
182
184
|
{
|
|
183
185
|
label: 'Last Value',
|
|
@@ -200,6 +202,8 @@ export default class ConnectivitySensorsIndexController extends Controller {
|
|
|
200
202
|
filterable: true,
|
|
201
203
|
filterComponent: 'filter/multi-option',
|
|
202
204
|
filterOptions: fleetOpsOptions('sensorStatuses'),
|
|
205
|
+
filterOptionLabel: 'label',
|
|
206
|
+
filterOptionValue: 'value',
|
|
203
207
|
},
|
|
204
208
|
{
|
|
205
209
|
label: 'Threshold',
|
|
@@ -40,7 +40,7 @@ export default class ConnectivityTelematicsDetailsEventsController extends Contr
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
get unprocessedEventsCount() {
|
|
43
|
-
return this.events.filter((event) => !event.processed_at
|
|
43
|
+
return this.events.filter((event) => !event.processed_at).length;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
get deviceCount() {
|
|
@@ -171,6 +171,8 @@ export default class ConnectivityTelematicsDetailsSensorsController extends Cont
|
|
|
171
171
|
filterParam: 'type',
|
|
172
172
|
filterComponent: 'filter/multi-option',
|
|
173
173
|
filterOptions: fleetOpsOptions('sensorTypes'),
|
|
174
|
+
filterOptionLabel: 'label',
|
|
175
|
+
filterOptionValue: 'value',
|
|
174
176
|
},
|
|
175
177
|
{
|
|
176
178
|
label: 'Device',
|
|
@@ -209,6 +211,8 @@ export default class ConnectivityTelematicsDetailsSensorsController extends Cont
|
|
|
209
211
|
filterable: true,
|
|
210
212
|
filterComponent: 'filter/multi-option',
|
|
211
213
|
filterOptions: fleetOpsOptions('sensorStatuses'),
|
|
214
|
+
filterOptionLabel: 'label',
|
|
215
|
+
filterOptionValue: 'value',
|
|
212
216
|
},
|
|
213
217
|
{
|
|
214
218
|
label: 'Last Reading',
|
|
@@ -19,6 +19,12 @@ export default class SettingsMapController extends Controller {
|
|
|
19
19
|
* @var {Array}
|
|
20
20
|
*/
|
|
21
21
|
@tracked mapProviderOptions = MAP_PROVIDER_OPTIONS;
|
|
22
|
+
@tracked googleMapsMapTypeOptions = [
|
|
23
|
+
{ label: 'Roadmap', value: 'roadmap' },
|
|
24
|
+
{ label: 'Satellite', value: 'satellite' },
|
|
25
|
+
{ label: 'Hybrid', value: 'hybrid' },
|
|
26
|
+
{ label: 'Terrain', value: 'terrain' },
|
|
27
|
+
];
|
|
22
28
|
|
|
23
29
|
/**
|
|
24
30
|
* The currently-selected map provider key (e.g. 'leaflet' or 'google').
|
|
@@ -27,6 +33,9 @@ export default class SettingsMapController extends Controller {
|
|
|
27
33
|
* @var {String}
|
|
28
34
|
*/
|
|
29
35
|
@tracked mapProvider = 'leaflet';
|
|
36
|
+
@tracked googleMapsMapType = 'roadmap';
|
|
37
|
+
@tracked showGoogleMapsTrafficLayer = false;
|
|
38
|
+
@tracked showGoogleMapsTransitLayer = false;
|
|
30
39
|
|
|
31
40
|
/**
|
|
32
41
|
* Whether settings have been loaded from the server.
|
|
@@ -68,6 +77,9 @@ export default class SettingsMapController extends Controller {
|
|
|
68
77
|
@task *saveSettings() {
|
|
69
78
|
const settings = {
|
|
70
79
|
mapProvider: this.mapProvider,
|
|
80
|
+
googleMapsMapType: this.googleMapsMapType,
|
|
81
|
+
showGoogleMapsTrafficLayer: this.showGoogleMapsTrafficLayer,
|
|
82
|
+
showGoogleMapsTransitLayer: this.showGoogleMapsTransitLayer,
|
|
71
83
|
};
|
|
72
84
|
|
|
73
85
|
try {
|
|
@@ -78,6 +90,10 @@ export default class SettingsMapController extends Controller {
|
|
|
78
90
|
this.mapManager.setActiveProvider(this.mapProvider);
|
|
79
91
|
}
|
|
80
92
|
|
|
93
|
+
if (this.mapProvider === 'google' && typeof this.mapManager?.applyViewSettingsFromSettings === 'function') {
|
|
94
|
+
yield this.mapManager.applyViewSettingsFromSettings();
|
|
95
|
+
}
|
|
96
|
+
|
|
81
97
|
this.notifications.success(this.intl.t('settings.map.settings-saved'));
|
|
82
98
|
} catch (error) {
|
|
83
99
|
this.notifications.serverError(error);
|
|
@@ -89,6 +105,9 @@ export default class SettingsMapController extends Controller {
|
|
|
89
105
|
const response = yield this.mapSettings.load({ force: true });
|
|
90
106
|
|
|
91
107
|
this.mapProvider = response?.mapProvider ?? 'leaflet';
|
|
108
|
+
this.googleMapsMapType = response?.googleMapsMapType ?? 'roadmap';
|
|
109
|
+
this.showGoogleMapsTrafficLayer = Boolean(response?.showGoogleMapsTrafficLayer);
|
|
110
|
+
this.showGoogleMapsTransitLayer = Boolean(response?.showGoogleMapsTransitLayer);
|
|
92
111
|
this.settingsLoaded = true;
|
|
93
112
|
} catch (error) {
|
|
94
113
|
this.notifications.serverError(error);
|
package/addon/extension.js
CHANGED
|
@@ -116,6 +116,7 @@ export default {
|
|
|
116
116
|
|
|
117
117
|
// Create registries
|
|
118
118
|
this.createRegistries(registryService);
|
|
119
|
+
registryService.registerRenderableComponent('ai:action-preview:fleet-ops.create_order', new ExtensionComponent('@fleetbase/fleetops-engine', 'ai/create-order-preview'));
|
|
119
120
|
|
|
120
121
|
// // Register console home guidance
|
|
121
122
|
// this.registerHomeComponents(registryService);
|
|
@@ -368,6 +369,13 @@ export default {
|
|
|
368
369
|
'fleet-ops:component:place:form:details',
|
|
369
370
|
'fleet-ops:component:vehicle:form',
|
|
370
371
|
'fleet-ops:component:vehicle:form:details',
|
|
372
|
+
'fleet-ops:component:vehicle:form:after-details',
|
|
373
|
+
'fleet-ops:component:vehicle:form:start',
|
|
374
|
+
'fleet-ops:component:vehicle:form:end',
|
|
375
|
+
'fleet-ops:component:vehicle:card:header:start',
|
|
376
|
+
'fleet-ops:component:vehicle:card:header:end',
|
|
377
|
+
'fleet-ops:component:vehicle:card:footer:start',
|
|
378
|
+
'fleet-ops:component:vehicle:card:footer:end',
|
|
371
379
|
'fleet-ops:component:vendor:form:edit',
|
|
372
380
|
'fleet-ops:component:vendor:form:edit:details',
|
|
373
381
|
'fleet-ops:component:vendor:form:create',
|
|
@@ -392,6 +400,12 @@ export default {
|
|
|
392
400
|
'fleet-ops:contextmenu:driver',
|
|
393
401
|
'fleet-ops:component:order:details',
|
|
394
402
|
'fleet-ops:component:order:form',
|
|
403
|
+
'fleet-ops:component:order:form:start',
|
|
404
|
+
'fleet-ops:component:order:form:end',
|
|
405
|
+
'fleet-ops:component:order:form:details',
|
|
406
|
+
'fleet-ops:component:order:form:details:start',
|
|
407
|
+
'fleet-ops:component:order:form:details:end',
|
|
408
|
+
'fleet-ops:component:order:form:details:after-details',
|
|
395
409
|
'fleet-ops:component:order:form:payload:entity',
|
|
396
410
|
'fleet-ops:component:order:form:payload:entity:form',
|
|
397
411
|
'fleet-ops:template:settings:routing',
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* Third-party orchestration engines follow the same pattern:
|
|
11
11
|
* 1. Create a service extending OrchestrationEngineInterfaceService
|
|
12
12
|
* 2. Create an instance initializer that calls orchestrationEngine.register()
|
|
13
|
-
* 3. The engine will appear in the
|
|
13
|
+
* 3. The engine will appear in the Fleet-Ops orchestrator settings dropdown
|
|
14
14
|
*/
|
|
15
15
|
export function initialize(appInstance) {
|
|
16
16
|
const orchestrationEngine = appInstance.lookup('service:orchestration-engine');
|
|
@@ -1,3 +1,28 @@
|
|
|
1
1
|
import Route from '@ember/routing/route';
|
|
2
|
+
import { action } from '@ember/object';
|
|
3
|
+
import { inject as service } from '@ember/service';
|
|
2
4
|
|
|
3
|
-
export default class ConnectivityEventsDetailsRoute extends Route {
|
|
5
|
+
export default class ConnectivityEventsDetailsRoute extends Route {
|
|
6
|
+
@service abilities;
|
|
7
|
+
@service hostRouter;
|
|
8
|
+
@service intl;
|
|
9
|
+
@service notifications;
|
|
10
|
+
@service store;
|
|
11
|
+
|
|
12
|
+
@action error(error) {
|
|
13
|
+
this.notifications.serverError(error);
|
|
14
|
+
|
|
15
|
+
return this.hostRouter.transitionTo('console.fleet-ops.connectivity.events.index');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
beforeModel() {
|
|
19
|
+
if (this.abilities.cannot('fleet-ops view device-event')) {
|
|
20
|
+
this.notifications.warning(this.intl.t('common.unauthorized-access'));
|
|
21
|
+
return this.hostRouter.transitionTo('console.fleet-ops.connectivity.events.index');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
model({ public_id }) {
|
|
26
|
+
return this.store.findRecord('device-event', public_id);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -24,6 +24,6 @@ export default class ManagementFleetsIndexDetailsRoute extends Route {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
model({ public_id }) {
|
|
27
|
-
return this.store.queryRecord('fleet', { public_id, single: true, with: ['parent_fleet', 'service_area', 'zone'] });
|
|
27
|
+
return this.store.queryRecord('fleet', { public_id, single: true, with: ['parent_fleet', 'service_area', 'zone', 'subfleets', 'drivers', 'vehicles'] });
|
|
28
28
|
}
|
|
29
29
|
}
|
|
@@ -62,6 +62,16 @@ const DEFAULT_GOOGLE_MAP_STYLES = [
|
|
|
62
62
|
},
|
|
63
63
|
];
|
|
64
64
|
|
|
65
|
+
function buildGoogleMapStyles({ showTransitLayer = false, googleOptions = {} } = {}) {
|
|
66
|
+
const baseStyles = showTransitLayer ? DEFAULT_GOOGLE_MAP_STYLES.filter((style) => style.featureType !== 'transit') : DEFAULT_GOOGLE_MAP_STYLES;
|
|
67
|
+
|
|
68
|
+
if (googleOptions.styles === undefined) {
|
|
69
|
+
return baseStyles;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return [...baseStyles, ...googleOptions.styles];
|
|
73
|
+
}
|
|
74
|
+
|
|
65
75
|
function buildWaypointMarkerContent(label, color) {
|
|
66
76
|
const wrapper = document.createElement('div');
|
|
67
77
|
wrapper.className = 'fleetops-map-marker';
|
|
@@ -108,6 +118,12 @@ export default class GoogleMapsAdapter extends MapAdapterInterface {
|
|
|
108
118
|
/** @type {google.maps.ImageMapType|null} */
|
|
109
119
|
_customTileLayer = null;
|
|
110
120
|
|
|
121
|
+
/** @type {google.maps.TrafficLayer|null} */
|
|
122
|
+
_trafficLayer = null;
|
|
123
|
+
|
|
124
|
+
/** @type {google.maps.TransitLayer|null} */
|
|
125
|
+
_transitLayer = null;
|
|
126
|
+
|
|
111
127
|
/** @type {Map<string, Function[]>} Normalized event name → array of [handler, gmListener] pairs */
|
|
112
128
|
_eventListeners = new Map();
|
|
113
129
|
|
|
@@ -160,7 +176,10 @@ export default class GoogleMapsAdapter extends MapAdapterInterface {
|
|
|
160
176
|
const { AdvancedMarkerElement } = await googleMaps.maps.importLibrary('marker');
|
|
161
177
|
this._advancedMarkerElementClass = AdvancedMarkerElement;
|
|
162
178
|
const mergedGoogleOptions = options.googleOptions ?? {};
|
|
163
|
-
const mergedMapStyles =
|
|
179
|
+
const mergedMapStyles = buildGoogleMapStyles({
|
|
180
|
+
showTransitLayer: options.showTransitLayer,
|
|
181
|
+
googleOptions: mergedGoogleOptions,
|
|
182
|
+
});
|
|
164
183
|
const mapId = options.mapId ?? mergedGoogleOptions.mapId ?? this.#getConfig()?.googleMaps?.mapId ?? this.#getConfig()?.GOOGLE_MAPS_MAP_ID ?? null;
|
|
165
184
|
this._supportsAdvancedMarkers = Boolean(mapId && mapId !== 'FLEETOPS_MAP');
|
|
166
185
|
|
|
@@ -176,6 +195,7 @@ export default class GoogleMapsAdapter extends MapAdapterInterface {
|
|
|
176
195
|
styles: mergedMapStyles,
|
|
177
196
|
});
|
|
178
197
|
|
|
198
|
+
await this.applyViewSettings(options);
|
|
179
199
|
await this.#initDrawingManager();
|
|
180
200
|
|
|
181
201
|
debug('[GoogleMapsAdapter] Map initialized');
|
|
@@ -231,6 +251,10 @@ export default class GoogleMapsAdapter extends MapAdapterInterface {
|
|
|
231
251
|
this._tooltipOverlayView?.setMap?.(null);
|
|
232
252
|
this._tooltipOverlayView = null;
|
|
233
253
|
this._supportsAdvancedMarkers = false;
|
|
254
|
+
this._trafficLayer?.setMap(null);
|
|
255
|
+
this._trafficLayer = null;
|
|
256
|
+
this._transitLayer?.setMap(null);
|
|
257
|
+
this._transitLayer = null;
|
|
234
258
|
|
|
235
259
|
this._map = null;
|
|
236
260
|
debug('[GoogleMapsAdapter] Map destroyed');
|
|
@@ -241,6 +265,47 @@ export default class GoogleMapsAdapter extends MapAdapterInterface {
|
|
|
241
265
|
google.maps.event.trigger(this._map, 'resize');
|
|
242
266
|
}
|
|
243
267
|
|
|
268
|
+
async applyViewSettings(options = {}) {
|
|
269
|
+
if (!this._map) return;
|
|
270
|
+
|
|
271
|
+
const googleMaps = window.google;
|
|
272
|
+
const { TrafficLayer, TransitLayer } = await googleMaps.maps.importLibrary('maps');
|
|
273
|
+
const mapTypeId = options.mapTypeId ?? googleMaps.maps.MapTypeId.ROADMAP;
|
|
274
|
+
const showTrafficLayer = Boolean(options.showTrafficLayer);
|
|
275
|
+
const showTransitLayer = Boolean(options.showTransitLayer);
|
|
276
|
+
const googleOptions = options.googleOptions ?? {};
|
|
277
|
+
|
|
278
|
+
this._map.setMapTypeId?.(mapTypeId);
|
|
279
|
+
this._map.setOptions?.({
|
|
280
|
+
styles: buildGoogleMapStyles({
|
|
281
|
+
showTransitLayer,
|
|
282
|
+
googleOptions,
|
|
283
|
+
}),
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
if (showTrafficLayer) {
|
|
287
|
+
if (!this._trafficLayer) {
|
|
288
|
+
this._trafficLayer = new TrafficLayer();
|
|
289
|
+
}
|
|
290
|
+
this._trafficLayer.setMap(this._map);
|
|
291
|
+
} else if (this._trafficLayer) {
|
|
292
|
+
this._trafficLayer.setMap(null);
|
|
293
|
+
this._trafficLayer = null;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (showTransitLayer) {
|
|
297
|
+
if (!this._transitLayer) {
|
|
298
|
+
this._transitLayer = new TransitLayer();
|
|
299
|
+
}
|
|
300
|
+
this._transitLayer.setMap(this._map);
|
|
301
|
+
} else if (this._transitLayer) {
|
|
302
|
+
this._transitLayer.setMap(null);
|
|
303
|
+
this._transitLayer = null;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
debug(`[GoogleMapsAdapter] Applied view settings: mapTypeId=${mapTypeId}, traffic=${showTrafficLayer}, transit=${showTransitLayer}`);
|
|
307
|
+
}
|
|
308
|
+
|
|
244
309
|
// ─── Viewport ──────────────────────────────────────────────────────────────
|
|
245
310
|
|
|
246
311
|
setCenter(lat, lng, zoom) {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Implements the MapAdapterInterface using the Leaflet library (via ember-leaflet).
|
|
5
5
|
* This adapter wraps all existing Leaflet-specific logic, preserving 100% of
|
|
6
|
-
* the original
|
|
6
|
+
* the original Fleet-Ops map functionality while conforming to the provider-agnostic
|
|
7
7
|
* interface.
|
|
8
8
|
*
|
|
9
9
|
* All Leaflet-specific plugins are supported:
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* MapAdapterInterface
|
|
3
3
|
*
|
|
4
4
|
* Abstract base class that defines the standardized contract all map provider
|
|
5
|
-
* adapters must implement. This enables
|
|
5
|
+
* adapters must implement. This enables Fleet-Ops to support multiple map
|
|
6
6
|
* providers (Leaflet, Google Maps, Mapbox, etc.) without changing any
|
|
7
7
|
* application-level business logic.
|
|
8
8
|
*
|