@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.
Files changed (161) hide show
  1. package/addon/components/admin/map-settings.hbs +1 -1
  2. package/addon/components/ai/create-order-preview.hbs +297 -0
  3. package/addon/components/ai/create-order-preview.js +362 -0
  4. package/addon/components/ai/route-preview-map.hbs +79 -0
  5. package/addon/components/ai/route-preview-map.js +527 -0
  6. package/addon/components/device/details.js +1 -1
  7. package/addon/components/device-event/details.hbs +192 -0
  8. package/addon/components/device-event/details.js +151 -0
  9. package/addon/components/driver/schedule.js +1 -1
  10. package/addon/components/fleet/details.hbs +21 -8
  11. package/addon/components/fleet/details.js +55 -1
  12. package/addon/components/fleet/hierarchy-tree.hbs +137 -0
  13. package/addon/components/fleet/hierarchy-tree.js +528 -0
  14. package/addon/components/layout/fleet-ops-sidebar.js +15 -9
  15. package/addon/components/map/drawer/device-event-listing.js +1 -0
  16. package/addon/components/map/drawer/driver-listing.js +1 -0
  17. package/addon/components/map/drawer/place-listing.js +1 -0
  18. package/addon/components/map/drawer/vehicle-listing.js +1 -0
  19. package/addon/components/order/details.hbs +34 -1
  20. package/addon/components/order/form/details.hbs +4 -0
  21. package/addon/components/order/form.hbs +9 -1
  22. package/addon/components/telematic/details.hbs +1 -1
  23. package/addon/components/telematic/form.hbs +2 -2
  24. package/addon/components/telematic/settings.hbs +1 -1
  25. package/addon/components/vehicle/card.hbs +14 -2
  26. package/addon/components/vehicle/form.hbs +13 -1
  27. package/addon/controllers/connectivity/devices/index/details/events.js +1 -1
  28. package/addon/controllers/connectivity/devices/index/details/vehicle.js +2 -2
  29. package/addon/controllers/connectivity/events/details.js +68 -1
  30. package/addon/controllers/connectivity/sensors/index.js +4 -0
  31. package/addon/controllers/connectivity/telematics/details/events.js +1 -1
  32. package/addon/controllers/connectivity/telematics/details/sensors.js +4 -0
  33. package/addon/controllers/settings/map.js +19 -0
  34. package/addon/extension.js +14 -0
  35. package/addon/instance-initializers/register-vroom-allocation.js +1 -1
  36. package/addon/routes/connectivity/events/details.js +26 -1
  37. package/addon/routes/management/fleets/index/details.js +1 -1
  38. package/addon/routes/management/vehicles/index/details.js +3 -1
  39. package/addon/services/map-adapter/google.js +66 -1
  40. package/addon/services/map-adapter/leaflet.js +1 -1
  41. package/addon/services/map-adapter-interface.js +1 -1
  42. package/addon/services/map-manager.js +16 -1
  43. package/addon/services/map-settings.js +15 -0
  44. package/addon/styles/fleetops-engine.css +487 -1
  45. package/addon/templates/connectivity/devices/index/details/vehicle.hbs +2 -1
  46. package/addon/templates/connectivity/events/details.hbs +40 -1
  47. package/addon/templates/settings/map.hbs +38 -9
  48. package/addon/utils/leaflet-plugin-loader.js +5 -5
  49. package/addon/utils/map-drawer-dropdown-position.js +11 -13
  50. package/addon/utils/route-colors.js +1 -1
  51. package/app/components/ai/create-order-preview.js +1 -0
  52. package/app/components/ai/route-preview-map.js +1 -0
  53. package/app/components/device-event/details.hbs +192 -0
  54. package/app/components/device-event/details.js +1 -0
  55. package/app/components/fleet/hierarchy-tree.js +1 -0
  56. package/app/services/route-engine.js +1 -0
  57. package/composer.json +1 -1
  58. package/extension.json +1 -1
  59. package/package.json +6 -4
  60. package/scripts/normalize-rgba-alpha.js +90 -0
  61. package/server/migrations/2026_06_23_000001_delete_bad_afaqy_telematics_sensors.php +34 -0
  62. package/server/src/Exports/ContactExport.php +12 -5
  63. package/server/src/Exports/DeviceExport.php +92 -0
  64. package/server/src/Exports/DriverExport.php +28 -3
  65. package/server/src/Exports/EquipmentExport.php +94 -0
  66. package/server/src/Exports/FleetExport.php +22 -7
  67. package/server/src/Exports/FuelReportExport.php +16 -1
  68. package/server/src/Exports/IssueExport.php +25 -3
  69. package/server/src/Exports/MaintenanceExport.php +106 -0
  70. package/server/src/Exports/MaintenanceScheduleExport.php +99 -0
  71. package/server/src/Exports/OrderExport.php +24 -5
  72. package/server/src/Exports/PartExport.php +99 -0
  73. package/server/src/Exports/PlaceExport.php +33 -7
  74. package/server/src/Exports/SensorExport.php +94 -0
  75. package/server/src/Exports/ServiceAreaExport.php +31 -7
  76. package/server/src/Exports/ServiceRateExport.php +41 -1
  77. package/server/src/Exports/TelematicExport.php +90 -0
  78. package/server/src/Exports/VehicleExport.php +274 -8
  79. package/server/src/Exports/VendorExport.php +15 -2
  80. package/server/src/Exports/WorkOrderExport.php +92 -0
  81. package/server/src/Http/Controllers/Api/v1/Concerns/ResolvesFleetOpsApiResources.php +176 -0
  82. package/server/src/Http/Controllers/Api/v1/DeviceController.php +225 -0
  83. package/server/src/Http/Controllers/Api/v1/EquipmentController.php +114 -0
  84. package/server/src/Http/Controllers/Api/v1/FuelTransactionController.php +185 -0
  85. package/server/src/Http/Controllers/Api/v1/PartController.php +120 -0
  86. package/server/src/Http/Controllers/Api/v1/SensorController.php +132 -0
  87. package/server/src/Http/Controllers/Api/v1/WorkOrderController.php +161 -0
  88. package/server/src/Http/Controllers/Internal/v1/DeviceController.php +18 -0
  89. package/server/src/Http/Controllers/Internal/v1/EquipmentController.php +17 -0
  90. package/server/src/Http/Controllers/Internal/v1/MaintenanceController.php +17 -0
  91. package/server/src/Http/Controllers/Internal/v1/MaintenanceScheduleController.php +17 -0
  92. package/server/src/Http/Controllers/Internal/v1/PartController.php +17 -0
  93. package/server/src/Http/Controllers/Internal/v1/SensorController.php +18 -0
  94. package/server/src/Http/Controllers/Internal/v1/SettingController.php +29 -5
  95. package/server/src/Http/Controllers/Internal/v1/TelematicController.php +18 -0
  96. package/server/src/Http/Controllers/Internal/v1/WorkOrderController.php +17 -0
  97. package/server/src/Http/Filter/DeviceFilter.php +33 -10
  98. package/server/src/Http/Filter/EquipmentFilter.php +23 -0
  99. package/server/src/Http/Filter/FuelProviderTransactionFilter.php +57 -2
  100. package/server/src/Http/Filter/PartFilter.php +47 -0
  101. package/server/src/Http/Filter/SensorFilter.php +34 -6
  102. package/server/src/Http/Filter/WorkOrderFilter.php +23 -0
  103. package/server/src/Http/Requests/CreateDeviceRequest.php +51 -0
  104. package/server/src/Http/Requests/CreateEquipmentRequest.php +35 -0
  105. package/server/src/Http/Requests/CreateFuelTransactionRequest.php +50 -0
  106. package/server/src/Http/Requests/CreatePartRequest.php +40 -0
  107. package/server/src/Http/Requests/CreateSensorRequest.php +47 -0
  108. package/server/src/Http/Requests/CreateWorkOrderRequest.php +42 -0
  109. package/server/src/Http/Requests/UpdateDeviceRequest.php +7 -0
  110. package/server/src/Http/Requests/UpdateEquipmentRequest.php +7 -0
  111. package/server/src/Http/Requests/UpdateFuelTransactionRequest.php +7 -0
  112. package/server/src/Http/Requests/UpdatePartRequest.php +7 -0
  113. package/server/src/Http/Requests/UpdateSensorRequest.php +7 -0
  114. package/server/src/Http/Requests/UpdateWorkOrderRequest.php +7 -0
  115. package/server/src/Http/Resources/v1/Device.php +72 -0
  116. package/server/src/Http/Resources/v1/Equipment.php +57 -0
  117. package/server/src/Http/Resources/v1/Fleet.php +8 -2
  118. package/server/src/Http/Resources/v1/FuelTransaction.php +69 -0
  119. package/server/src/Http/Resources/v1/Part.php +64 -0
  120. package/server/src/Http/Resources/v1/Sensor.php +68 -0
  121. package/server/src/Jobs/SyncTelematicDevicesJob.php +194 -38
  122. package/server/src/Models/Driver.php +6 -0
  123. package/server/src/Models/Order.php +20 -7
  124. package/server/src/Models/Place.php +11 -3
  125. package/server/src/Observers/PurchaseRateObserver.php +2 -1
  126. package/server/src/Providers/FleetOpsServiceProvider.php +26 -0
  127. package/server/src/Support/Ai/Capabilities/AbstractFleetOpsAICapability.php +88 -0
  128. package/server/src/Support/Ai/Capabilities/AssetStatusCapability.php +108 -0
  129. package/server/src/Support/Ai/Capabilities/ConsoleNavigationCapability.php +55 -0
  130. package/server/src/Support/Ai/Capabilities/CreateOrderPreviewCapability.php +508 -0
  131. package/server/src/Support/Ai/Capabilities/DocsHelpCapability.php +49 -0
  132. package/server/src/Support/Ai/Capabilities/ImportOrdersPreviewCapability.php +66 -0
  133. package/server/src/Support/Ai/Capabilities/OperationalQueryCapability.php +319 -0
  134. package/server/src/Support/Ai/Capabilities/OptimizeOrderRouteCapability.php +240 -0
  135. package/server/src/Support/Ai/Capabilities/OrderInsightsCapability.php +95 -0
  136. package/server/src/Support/Ai/Capabilities/SearchResourcesCapability.php +195 -0
  137. package/server/src/Support/Ai/FleetOpsAiQueryResources.php +150 -0
  138. package/server/src/Support/Analytics/RevenueTrend.php +3 -8
  139. package/server/src/Support/Metrics/ActiveRevenueQuery.php +121 -0
  140. package/server/src/Support/Metrics/AvgOrderValueMetric.php +1 -7
  141. package/server/src/Support/Metrics/EarningsMetric.php +1 -10
  142. package/server/src/Support/Telematics/Providers/AfaqyProvider.php +104 -5
  143. package/server/src/Support/Telematics/Providers/SafeeProvider.php +550 -54
  144. package/server/src/Support/Telematics/TelematicService.php +28 -9
  145. package/server/src/Support/Utils.php +52 -0
  146. package/server/src/routes.php +67 -14
  147. package/server/tests/AiCreateOrderPreviewCapabilityTest.php +131 -0
  148. package/server/tests/AiOperationalQueryCapabilityTest.php +75 -0
  149. package/server/tests/ExportCoverageTest.php +79 -0
  150. package/server/tests/FleetHierarchyResourceTest.php +12 -0
  151. package/server/tests/MetricsRegistryTest.php +45 -5
  152. package/server/tests/OrderPayloadPlaceResolutionTest.php +53 -0
  153. package/server/tests/PointResolutionTest.php +63 -0
  154. package/server/tests/PublicFleetOpsRestEndpointsTest.php +191 -0
  155. package/server/tests/TelematicsHardeningTest.php +636 -1
  156. package/addon/components/table/cell/dropdown/action-item.hbs +0 -31
  157. package/addon/components/table/cell/dropdown/action-item.js +0 -62
  158. package/addon/components/table/cell/dropdown.hbs +0 -28
  159. package/addon/components/table/cell/dropdown.js +0 -91
  160. package/app/components/table/cell/dropdown/action-item.js +0 -1
  161. package/app/components/table/cell/dropdown.js +0 -1
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * MapManagerService
3
3
  *
4
- * Provider-agnostic central map service for FleetOps. Replaces the
4
+ * Provider-agnostic central map service for Fleet-Ops. Replaces the
5
5
  * Leaflet-specific `leaflet-map-manager` as the single point of contact
6
6
  * for all map operations across the application.
7
7
  *
@@ -139,6 +139,9 @@ export default class MapManagerService extends Service {
139
139
  ...options,
140
140
  apiKey: options.apiKey ?? this.mapSettings.googleMapsApiKey,
141
141
  mapId: options.mapId ?? this.mapSettings.googleMapsMapId,
142
+ mapTypeId: options.mapTypeId ?? this.mapSettings.googleMapsMapType,
143
+ showTrafficLayer: options.showTrafficLayer ?? this.mapSettings.showGoogleMapsTrafficLayer,
144
+ showTransitLayer: options.showTransitLayer ?? this.mapSettings.showGoogleMapsTransitLayer,
142
145
  });
143
146
 
144
147
  return Promise.resolve(map).then((nativeMap) => {
@@ -167,6 +170,18 @@ export default class MapManagerService extends Service {
167
170
  this.adapter?.invalidateSize();
168
171
  }
169
172
 
173
+ @action applyViewSettingsFromSettings() {
174
+ if (this.providerName !== 'google' || typeof this.adapter?.applyViewSettings !== 'function') {
175
+ return;
176
+ }
177
+
178
+ return this.adapter.applyViewSettings({
179
+ mapTypeId: this.mapSettings.googleMapsMapType,
180
+ showTrafficLayer: this.mapSettings.showGoogleMapsTrafficLayer,
181
+ showTransitLayer: this.mapSettings.showGoogleMapsTransitLayer,
182
+ });
183
+ }
184
+
170
185
  /**
171
186
  * Set the live map component reference.
172
187
  *
@@ -6,6 +6,9 @@ const DEFAULT_SETTINGS = {
6
6
  mapProvider: 'leaflet',
7
7
  googleMapsApiKey: '',
8
8
  googleMapsMapId: '',
9
+ googleMapsMapType: 'roadmap',
10
+ showGoogleMapsTrafficLayer: false,
11
+ showGoogleMapsTransitLayer: false,
9
12
  };
10
13
 
11
14
  export default class MapSettingsService extends Service {
@@ -26,6 +29,18 @@ export default class MapSettingsService extends Service {
26
29
  return this.settings.googleMapsMapId ?? '';
27
30
  }
28
31
 
32
+ get googleMapsMapType() {
33
+ return this.settings.googleMapsMapType ?? 'roadmap';
34
+ }
35
+
36
+ get showGoogleMapsTrafficLayer() {
37
+ return Boolean(this.settings.showGoogleMapsTrafficLayer);
38
+ }
39
+
40
+ get showGoogleMapsTransitLayer() {
41
+ return Boolean(this.settings.showGoogleMapsTransitLayer);
42
+ }
43
+
29
44
  get isGoogleMaps() {
30
45
  return this.mapProvider === 'google';
31
46
  }
@@ -1,4 +1,3 @@
1
- /* stylelint-disable alpha-value-notation -- FleetOps lazy engine production CSS is minified by legacy clean-css, which corrupts comma-form rgba() percent alpha values. */
2
1
  .scheduler-left-sidebar {
3
2
  border-right: 1px rgb(229 231 235 / 100%) solid;
4
3
  height: 100vh;
@@ -2242,6 +2241,20 @@ body[data-theme='dark'] .fleet-ops-operations-monitor-divider::before {
2242
2241
  padding-left: 2.75rem !important;
2243
2242
  }
2244
2243
 
2244
+ .fleet-hierarchy-tree-row-depth-1 {
2245
+ padding-left: 1.5rem !important;
2246
+ }
2247
+
2248
+ .fleet-hierarchy-tree-row-depth-2 {
2249
+ padding-left: 2.5rem !important;
2250
+ }
2251
+
2252
+ .fleet-hierarchy-tree-row-depth-3,
2253
+ .fleet-hierarchy-tree-row-depth-4,
2254
+ .fleet-hierarchy-tree-row-depth-5 {
2255
+ padding-left: 3.5rem !important;
2256
+ }
2257
+
2245
2258
  .fleet-ops-operations-monitor-child-row {
2246
2259
  margin-top: -0.125rem;
2247
2260
  }
@@ -8049,3 +8062,476 @@ body[data-theme='dark'] .issue-timeline-card time,
8049
8062
  body[data-theme='dark'] .issue-timeline-card p {
8050
8063
  color: #d1d5db;
8051
8064
  }
8065
+
8066
+ .fleetbase-ai-create-order-preview {
8067
+ display: flex;
8068
+ flex-direction: column;
8069
+ gap: 8px;
8070
+ padding: 8px;
8071
+ }
8072
+
8073
+ .fleetbase-ai-create-order-preview__header {
8074
+ display: flex;
8075
+ align-items: flex-start;
8076
+ justify-content: space-between;
8077
+ gap: 8px;
8078
+ }
8079
+
8080
+ .fleetbase-ai-create-order-preview__map {
8081
+ position: relative;
8082
+ overflow: hidden;
8083
+ border: 1px solid rgb(148 163 184 / 20%);
8084
+ border-radius: 7px;
8085
+ background: rgb(15 23 42 / 5%);
8086
+ }
8087
+
8088
+ .fleetbase-ai-create-order-preview__leaflet,
8089
+ .fleetbase-ai-create-order-preview__google,
8090
+ .fleetbase-ai-create-order-preview__empty-map {
8091
+ width: 100%;
8092
+ height: 190px;
8093
+ }
8094
+
8095
+ .fleetbase-ai-create-order-preview__empty-map {
8096
+ display: flex;
8097
+ align-items: center;
8098
+ justify-content: center;
8099
+ gap: 8px;
8100
+ color: #64748b;
8101
+ font-size: 12px;
8102
+ }
8103
+
8104
+ .fleetbase-ai-create-order-preview__map-status {
8105
+ position: absolute;
8106
+ right: 8px;
8107
+ bottom: 8px;
8108
+ display: inline-flex;
8109
+ align-items: center;
8110
+ gap: 6px;
8111
+ border: 1px solid rgb(255 255 255 / 28%);
8112
+ border-radius: 999px;
8113
+ background: rgb(15 23 42 / 62%);
8114
+ padding: 4px 8px;
8115
+ color: #f8fafc;
8116
+ font-size: 11px;
8117
+ line-height: 1;
8118
+ backdrop-filter: blur(5px);
8119
+ }
8120
+
8121
+ .fleetbase-ai-create-order-preview__map-status--error {
8122
+ border-color: rgb(245 158 11 / 32%);
8123
+ background: rgb(120 53 15 / 64%);
8124
+ }
8125
+
8126
+ .fleetbase-ai-create-order-preview__fields {
8127
+ display: grid;
8128
+ grid-template-columns: repeat(2, minmax(0, 1fr));
8129
+ gap: 4px 8px;
8130
+ }
8131
+
8132
+ .fleetbase-ai-create-order-preview__field-row {
8133
+ display: flex;
8134
+ min-width: 0;
8135
+ align-items: center;
8136
+ justify-content: space-between;
8137
+ gap: 6px;
8138
+ border-radius: 7px;
8139
+ padding: 5px 6px;
8140
+ transition:
8141
+ background 120ms ease,
8142
+ box-shadow 120ms ease;
8143
+ }
8144
+
8145
+ .fleetbase-ai-create-order-preview__field-row:hover,
8146
+ .fleetbase-ai-create-order-preview__field-row:focus-within {
8147
+ background: rgb(255 255 255 / 20%);
8148
+ box-shadow: inset 0 0 0 1px rgb(148 163 184 / 14%);
8149
+ }
8150
+
8151
+ .fleetbase-ai-create-order-preview__field-row--notes {
8152
+ grid-column: 1 / -1;
8153
+ }
8154
+
8155
+ .fleetbase-ai-create-order-preview__field-copy {
8156
+ min-width: 0;
8157
+ flex: 1 1 auto;
8158
+ }
8159
+
8160
+ .fleetbase-ai-create-order-preview__field-copy > span {
8161
+ display: block;
8162
+ margin-bottom: 1px;
8163
+ color: #64748b;
8164
+ font-size: 10px;
8165
+ font-weight: 700;
8166
+ letter-spacing: 0;
8167
+ line-height: 1.1;
8168
+ text-transform: uppercase;
8169
+ }
8170
+
8171
+ .fleetbase-ai-create-order-preview__field-copy > strong {
8172
+ display: block;
8173
+ overflow: hidden;
8174
+ color: #0f172a;
8175
+ font-size: 12px;
8176
+ font-weight: 650;
8177
+ line-height: 1.25;
8178
+ text-overflow: ellipsis;
8179
+ white-space: nowrap;
8180
+ }
8181
+
8182
+ .fleetbase-ai-create-order-preview__field-row--notes .fleetbase-ai-create-order-preview__field-copy > strong {
8183
+ white-space: normal;
8184
+ }
8185
+
8186
+ .fleetbase-ai-create-order-preview__edit-wrapper {
8187
+ width: 24px;
8188
+ height: 24px;
8189
+ flex: 0 0 24px;
8190
+ box-shadow: none;
8191
+ }
8192
+
8193
+ .fleetbase-ai-create-order-preview__edit-button {
8194
+ display: inline-flex;
8195
+ width: 24px;
8196
+ height: 24px;
8197
+ align-items: center;
8198
+ justify-content: center;
8199
+ border: 0;
8200
+ border-radius: 6px;
8201
+ color: #64748b;
8202
+ }
8203
+
8204
+ .fleetbase-ai-create-order-preview__edit-button:hover {
8205
+ background: rgb(148 163 184 / 16%);
8206
+ color: #2563eb;
8207
+ }
8208
+
8209
+ .fleetbase-ai-create-order-preview__inline-select,
8210
+ .fleetbase-ai-create-order-preview__inline-native-select,
8211
+ .fleetbase-ai-create-order-preview__inline-datetime,
8212
+ .fleetbase-ai-create-order-preview__inline-textarea {
8213
+ width: 100%;
8214
+ min-height: 24px;
8215
+ border: 0;
8216
+ background: transparent;
8217
+ color: #0f172a;
8218
+ font-size: 12px;
8219
+ line-height: 1.25;
8220
+ outline: 0;
8221
+ box-shadow: none;
8222
+ }
8223
+
8224
+ .fleetbase-ai-create-order-preview__inline-select.ember-power-select-trigger {
8225
+ display: flex;
8226
+ min-height: 24px;
8227
+ align-items: center;
8228
+ border: 0;
8229
+ border-radius: 0;
8230
+ background: transparent;
8231
+ padding: 0;
8232
+ color: #0f172a;
8233
+ box-shadow: none;
8234
+ }
8235
+
8236
+ .fleetbase-ai-create-order-preview .ember-power-select-trigger,
8237
+ .fleetbase-ai-create-order-preview .ember-basic-dropdown-trigger,
8238
+ .fleetbase-ai-create-order-preview .ember-model-select,
8239
+ .fleetbase-ai-create-order-preview .fleetbase-model-select,
8240
+ .fleetbase-ai-create-order-preview .ember-power-select-status-icon,
8241
+ .fleetbase-ai-create-order-preview .ember-power-select-clear-btn {
8242
+ border: 0;
8243
+ background: transparent;
8244
+ box-shadow: none;
8245
+ }
8246
+
8247
+ .fleetbase-ai-create-order-preview .ember-power-select-trigger {
8248
+ min-height: 24px;
8249
+ padding: 0;
8250
+ }
8251
+
8252
+ .fleetbase-ai-create-order-preview .ember-power-select-status-icon {
8253
+ right: 0;
8254
+ width: 12px;
8255
+ height: 12px;
8256
+ }
8257
+
8258
+ .fleetbase-ai-create-order-preview .ember-power-select-clear-btn {
8259
+ right: 14px;
8260
+ color: #94a3b8;
8261
+ }
8262
+
8263
+ .fleetbase-ai-create-order-preview .ember-power-select-search-input,
8264
+ .fleetbase-ai-create-order-preview .ember-power-select-search-input:focus {
8265
+ border: 0;
8266
+ background: transparent;
8267
+ color: inherit;
8268
+ outline: 0;
8269
+ box-shadow: none;
8270
+ }
8271
+
8272
+ .fleetbase-ai-create-order-preview__inline-select .ember-power-select-selected-item,
8273
+ .fleetbase-ai-create-order-preview__inline-select .ember-power-select-placeholder {
8274
+ overflow: hidden;
8275
+ margin-left: 0;
8276
+ margin-right: 16px;
8277
+ color: inherit;
8278
+ font-size: 12px;
8279
+ line-height: 1.25;
8280
+ text-overflow: ellipsis;
8281
+ white-space: nowrap;
8282
+ }
8283
+
8284
+ .fleetbase-ai-create-order-preview__inline-native-select {
8285
+ width: auto;
8286
+ max-width: 150px;
8287
+ appearance: none;
8288
+ border-radius: 0;
8289
+ padding: 0 16px 0 0;
8290
+ font-weight: 650;
8291
+ cursor: pointer;
8292
+ }
8293
+
8294
+ .fleetbase-ai-create-order-preview__inline-textarea {
8295
+ resize: vertical;
8296
+ }
8297
+
8298
+ .fleetbase-ai-create-order-preview__inline-datetime,
8299
+ .fleetbase-ai-create-order-preview__inline-datetime input {
8300
+ border: 0;
8301
+ background: transparent;
8302
+ padding: 0;
8303
+ color: inherit;
8304
+ font-size: 12px;
8305
+ line-height: 1.25;
8306
+ outline: 0;
8307
+ box-shadow: none;
8308
+ }
8309
+
8310
+ .fleetbase-ai-create-order-preview__inline-datetime {
8311
+ display: grid;
8312
+ grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
8313
+ gap: 6px;
8314
+ }
8315
+
8316
+ .fleetbase-ai-create-order-preview__inline-datetime input {
8317
+ width: 100%;
8318
+ min-width: 0;
8319
+ }
8320
+
8321
+ .fleetbase-ai-create-order-preview__toggles {
8322
+ display: flex;
8323
+ flex-direction: column;
8324
+ gap: 8px;
8325
+ }
8326
+
8327
+ .fleetbase-ai-create-order-preview__toggle-row {
8328
+ display: flex;
8329
+ min-height: 28px;
8330
+ align-items: center;
8331
+ justify-content: space-between;
8332
+ gap: 10px;
8333
+ border-top: 1px solid rgb(148 163 184 / 14%);
8334
+ padding: 7px 2px 0;
8335
+ }
8336
+
8337
+ .fleetbase-ai-create-order-preview__inline-pill {
8338
+ display: inline-flex;
8339
+ align-items: center;
8340
+ gap: 5px;
8341
+ border: 0;
8342
+ border-radius: 999px;
8343
+ background: rgb(148 163 184 / 14%);
8344
+ padding: 3px 7px;
8345
+ color: #475569;
8346
+ font-size: 11px;
8347
+ line-height: 1;
8348
+ }
8349
+
8350
+ .fleetbase-ai-create-order-preview__inline-pill:hover {
8351
+ background: rgb(37 99 235 / 14%);
8352
+ color: #2563eb;
8353
+ }
8354
+
8355
+ .fleetbase-ai-create-order-preview__select-label {
8356
+ overflow: hidden;
8357
+ color: #0f172a;
8358
+ font-size: 12px;
8359
+ font-weight: 600;
8360
+ line-height: 1.25;
8361
+ text-overflow: ellipsis;
8362
+ text-transform: uppercase;
8363
+ white-space: nowrap;
8364
+ }
8365
+
8366
+ .fleetbase-ai-create-order-preview__controls {
8367
+ display: flex;
8368
+ align-items: center;
8369
+ gap: 8px;
8370
+ }
8371
+
8372
+ .fleetbase-ai-create-order-preview__refreshing {
8373
+ color: #64748b;
8374
+ font-size: 11px;
8375
+ }
8376
+
8377
+ .fleetbase-ai-create-order-preview__applying,
8378
+ .fleetbase-ai-create-order-preview__completed,
8379
+ .fleetbase-ai-create-order-preview__cancelled {
8380
+ display: flex;
8381
+ align-items: center;
8382
+ gap: 7px;
8383
+ border-radius: 7px;
8384
+ padding: 8px 9px;
8385
+ font-size: 12px;
8386
+ }
8387
+
8388
+ .fleetbase-ai-create-order-preview__applying {
8389
+ border: 1px solid rgb(96 165 250 / 20%);
8390
+ background: rgb(37 99 235 / 10%);
8391
+ color: #1d4ed8;
8392
+ }
8393
+
8394
+ .fleetbase-ai-create-order-preview__magic-loader {
8395
+ display: inline-flex;
8396
+ align-items: center;
8397
+ gap: 3px;
8398
+ }
8399
+
8400
+ .fleetbase-ai-create-order-preview__magic-loader span {
8401
+ width: 5px;
8402
+ height: 5px;
8403
+ border-radius: 999px;
8404
+ background: currentcolor;
8405
+ opacity: 0.45;
8406
+ animation: fleetbase-ai-create-order-dot 900ms ease-in-out infinite;
8407
+ }
8408
+
8409
+ .fleetbase-ai-create-order-preview__magic-loader span:nth-child(2) {
8410
+ animation-delay: 120ms;
8411
+ }
8412
+
8413
+ .fleetbase-ai-create-order-preview__magic-loader span:nth-child(3) {
8414
+ animation-delay: 240ms;
8415
+ }
8416
+
8417
+ @keyframes fleetbase-ai-create-order-dot {
8418
+ 0%,
8419
+ 80%,
8420
+ 100% {
8421
+ opacity: 0.35;
8422
+ transform: translateY(0);
8423
+ }
8424
+
8425
+ 40% {
8426
+ opacity: 1;
8427
+ transform: translateY(-2px);
8428
+ }
8429
+ }
8430
+
8431
+ .fleetbase-ai-create-order-preview__completed {
8432
+ border: 1px solid rgb(34 197 94 / 20%);
8433
+ background: rgb(22 163 74 / 10%);
8434
+ color: #166534;
8435
+ }
8436
+
8437
+ .fleetbase-ai-create-order-preview__completed-icon {
8438
+ display: inline-flex;
8439
+ width: 26px;
8440
+ height: 26px;
8441
+ flex: 0 0 26px;
8442
+ align-items: center;
8443
+ justify-content: center;
8444
+ border-radius: 999px;
8445
+ background: rgb(34 197 94 / 16%);
8446
+ }
8447
+
8448
+ .fleetbase-ai-create-order-preview__completed-copy {
8449
+ display: flex;
8450
+ min-width: 0;
8451
+ flex: 1 1 auto;
8452
+ flex-direction: column;
8453
+ gap: 2px;
8454
+ }
8455
+
8456
+ .fleetbase-ai-create-order-preview__completed-copy strong,
8457
+ .fleetbase-ai-create-order-preview__completed-copy span {
8458
+ overflow: hidden;
8459
+ text-overflow: ellipsis;
8460
+ white-space: nowrap;
8461
+ }
8462
+
8463
+ .fleetbase-ai-create-order-preview__completed-copy span {
8464
+ opacity: 0.8;
8465
+ }
8466
+
8467
+ .fleetbase-ai-create-order-preview__cancelled {
8468
+ border: 1px solid rgb(239 68 68 / 20%);
8469
+ background: rgb(239 68 68 / 10%);
8470
+ color: #991b1b;
8471
+ }
8472
+
8473
+ body[data-theme='dark'] .fleetbase-ai-create-order-preview__map,
8474
+ body[data-theme='dark'] .fleetbase-ai-create-order-preview__field-row:hover,
8475
+ body[data-theme='dark'] .fleetbase-ai-create-order-preview__field-row:focus-within {
8476
+ border-color: rgb(148 163 184 / 20%);
8477
+ background: rgb(15 23 42 / 30%);
8478
+ }
8479
+
8480
+ body[data-theme='dark'] .fleetbase-ai-create-order-preview__field-copy > strong,
8481
+ body[data-theme='dark'] .fleetbase-ai-create-order-preview__inline-select,
8482
+ body[data-theme='dark'] .fleetbase-ai-create-order-preview__inline-native-select,
8483
+ body[data-theme='dark'] .fleetbase-ai-create-order-preview__inline-datetime,
8484
+ body[data-theme='dark'] .fleetbase-ai-create-order-preview__inline-textarea,
8485
+ body[data-theme='dark'] .fleetbase-ai-create-order-preview__inline-select.ember-power-select-trigger,
8486
+ body[data-theme='dark'] .fleetbase-ai-create-order-preview__select-label {
8487
+ color: #f8fafc;
8488
+ }
8489
+
8490
+ body[data-theme='dark'] .fleetbase-ai-create-order-preview__field-copy > span,
8491
+ body[data-theme='dark'] .fleetbase-ai-create-order-preview__edit-button,
8492
+ body[data-theme='dark'] .fleetbase-ai-create-order-preview__refreshing,
8493
+ body[data-theme='dark'] .fleetbase-ai-create-order-preview__empty-map {
8494
+ color: #cbd5e1;
8495
+ }
8496
+
8497
+ body[data-theme='dark'] .fleetbase-ai-create-order-preview__toggle-row {
8498
+ border-top-color: rgb(148 163 184 / 18%);
8499
+ }
8500
+
8501
+ body[data-theme='dark'] .fleetbase-ai-create-order-preview__inline-pill {
8502
+ background: rgb(148 163 184 / 14%);
8503
+ color: #cbd5e1;
8504
+ }
8505
+
8506
+ body[data-theme='dark'] .fleetbase-ai-create-order-preview__inline-pill:hover {
8507
+ background: rgb(96 165 250 / 14%);
8508
+ color: #bfdbfe;
8509
+ }
8510
+
8511
+ body[data-theme='dark'] .fleetbase-ai-create-order-preview__applying {
8512
+ border-color: rgb(96 165 250 / 24%);
8513
+ background: rgb(30 64 175 / 24%);
8514
+ color: #bfdbfe;
8515
+ }
8516
+
8517
+ body[data-theme='dark'] .fleetbase-ai-create-order-preview__completed {
8518
+ border-color: rgb(74 222 128 / 22%);
8519
+ background: rgb(20 83 45 / 28%);
8520
+ color: #bbf7d0;
8521
+ }
8522
+
8523
+ body[data-theme='dark'] .fleetbase-ai-create-order-preview__completed-icon {
8524
+ background: rgb(34 197 94 / 18%);
8525
+ }
8526
+
8527
+ body[data-theme='dark'] .fleetbase-ai-create-order-preview__cancelled {
8528
+ border-color: rgb(248 113 113 / 22%);
8529
+ background: rgb(127 29 29 / 22%);
8530
+ color: #fecaca;
8531
+ }
8532
+
8533
+ @media (prefers-reduced-motion: reduce) {
8534
+ .fleetbase-ai-create-order-preview__magic-loader span {
8535
+ animation: none;
8536
+ }
8537
+ }
@@ -1,5 +1,5 @@
1
1
  <div class="flex flex-col gap-3 p-3">
2
- <div class="flex items-start justify-between gap-3">
2
+ <div class="flex flex-col items-start justify-between gap-3">
3
3
  <div class="min-w-0">
4
4
  <h2 class="text-base font-bold text-gray-900 dark:text-gray-100">Vehicle Attachment</h2>
5
5
  <p class="mt-0.5 text-xs text-gray-500 dark:text-gray-300">Fleet context for telemetry from this device.</p>
@@ -119,6 +119,7 @@
119
119
  <div class="border-t border-gray-200 dark:border-gray-700">
120
120
  <PositionsReplay @resource={{this.vehicle}} @mapHeight={{180}} class="max-h-[360px] overflow-hidden" />
121
121
  </div>
122
+ <Spacer @height="150px" />
122
123
  {{else}}
123
124
  <div class="p-3">
124
125
  <Telematic::TabEmptyState
@@ -1 +1,40 @@
1
- {{outlet}}
1
+ <div class="h-full overflow-y-auto bg-gray-50 dark:bg-gray-900">
2
+ <section class="sticky top-0 z-40 border-b border-gray-200 bg-white shadow-sm dark:border-gray-700 dark:bg-gray-900">
3
+ <div class="mx-auto flex w-full max-w-7xl flex-col gap-3 px-4 py-3 md:px-6 lg:flex-row lg:items-start lg:justify-between">
4
+ <div class="min-w-0 flex-1">
5
+ <div class="flex flex-wrap items-center gap-2">
6
+ <h1 class="truncate text-lg font-bold text-gray-900 dark:text-gray-100">{{smart-humanize this.event.event_type}}</h1>
7
+ <Badge @status={{this.event.severity}} @hideStatusDot={{true}}>{{smart-humanize this.event.severity}}</Badge>
8
+ <Badge @status={{this.processedStatus}} @hideStatusDot={{true}}>{{this.processedLabel}}</Badge>
9
+ </div>
10
+ <div class="mt-1 flex flex-wrap gap-2 text-xs text-gray-500 dark:text-gray-300">
11
+ <span>{{n-a this.event.public_id}}</span>
12
+ <span>Device: {{n-a (or this.event.device_name this.event.device_id this.event.ident)}}</span>
13
+ <span>Provider: {{n-a (or this.event.telematic_name this.event.provider)}}</span>
14
+ <span>Occurred: {{n-a (format-date-fns this.event.occurred_at "dd MMM yyyy, HH:mm")}}</span>
15
+ </div>
16
+ </div>
17
+
18
+ <div class="flex shrink-0 flex-row flex-nowrap items-center gap-2 whitespace-nowrap">
19
+ <Button @icon="arrow-left" @text="Back" @size="xs" @wrapperClass="shrink-0" @onClick={{this.goBack}} />
20
+ <Button @icon="refresh" @text="Refresh" @size="xs" @wrapperClass="shrink-0" @onClick={{this.refresh}} />
21
+ {{#unless this.isProcessed}}
22
+ <Button
23
+ @icon="check"
24
+ @text="Mark Processed"
25
+ @type="primary"
26
+ @size="xs"
27
+ @wrapperClass="shrink-0"
28
+ @isLoading={{this.isMarkingProcessed}}
29
+ @disabled={{this.isMarkingProcessed}}
30
+ @onClick={{this.markProcessed}}
31
+ />
32
+ {{/unless}}
33
+ </div>
34
+ </div>
35
+ </section>
36
+
37
+ <section class="mx-auto w-full max-w-7xl">
38
+ <DeviceEvent::Details @resource={{this.event}} />
39
+ </section>
40
+ </div>
@@ -14,15 +14,12 @@
14
14
  <div class="container mx-auto h-screen">
15
15
  <div class="max-w-3xl my-10 mx-auto space-y-6">
16
16
 
17
- {{!-- ─── Map Provider Panel ──────────────────────────────────────────── --}}
17
+ {{! ─── Map Provider Panel ──────────────────────────────────────────── }}
18
18
  <ContentPanel @title={{t "settings.map.configure-map"}} @open={{true}} @wrapperClass="bordered-classic">
19
19
  {{#if this.settingsLoaded}}
20
20
 
21
- {{!-- Provider selector --}}
22
- <InputGroup
23
- @name={{t "settings.map.map-provider"}}
24
- @helpText={{t "settings.map.map-provider-help-text"}}
25
- >
21
+ {{! Provider selector }}
22
+ <InputGroup @name={{t "settings.map.map-provider"}} @helpText={{t "settings.map.map-provider-help-text"}}>
26
23
  <Select
27
24
  class="w-full flex-1"
28
25
  @value={{this.mapProvider}}
@@ -34,15 +31,47 @@
34
31
  />
35
32
  </InputGroup>
36
33
 
34
+ {{#if this.isGoogleMapsSelected}}
35
+ <InputGroup @name={{t "settings.map.google-maps-map-type"}} @helpText={{t "settings.map.google-maps-map-type-help-text"}}>
36
+ <Select
37
+ class="w-full flex-1"
38
+ @value={{this.googleMapsMapType}}
39
+ @options={{this.googleMapsMapTypeOptions}}
40
+ @optionLabel="label"
41
+ @optionValue="value"
42
+ @placeholder={{t "settings.map.select-map-type"}}
43
+ @onSelect={{fn (mut this.googleMapsMapType)}}
44
+ />
45
+ </InputGroup>
46
+
47
+ <InputGroup>
48
+ <Toggle
49
+ @label={{t "settings.map.show-traffic-layer"}}
50
+ @isToggled={{this.showGoogleMapsTrafficLayer}}
51
+ @onToggle={{fn (mut this.showGoogleMapsTrafficLayer)}}
52
+ @helpText={{t "settings.map.show-traffic-layer-help-text"}}
53
+ />
54
+ </InputGroup>
55
+
56
+ <InputGroup>
57
+ <Toggle
58
+ @label={{t "settings.map.show-transit-layer"}}
59
+ @isToggled={{this.showGoogleMapsTransitLayer}}
60
+ @onToggle={{fn (mut this.showGoogleMapsTransitLayer)}}
61
+ @helpText={{t "settings.map.show-transit-layer-help-text"}}
62
+ />
63
+ </InputGroup>
64
+ {{/if}}
65
+
37
66
  {{else}}
38
- {{!-- Loading state --}}
67
+ {{! Loading state }}
39
68
  <div class="flex items-center justify-center py-8">
40
69
  <Spinner />
41
70
  </div>
42
71
  {{/if}}
43
72
  </ContentPanel>
44
73
 
45
- {{!-- Extension point for third-party panels --}}
74
+ {{! Extension point for third-party panels }}
46
75
  <RegistryYield @registry="fleet-ops:template:settings:map" as |RegistryComponent|>
47
76
  <RegistryComponent @controller={{this}} />
48
77
  </RegistryYield>
@@ -50,4 +79,4 @@
50
79
  </div>
51
80
  </div>
52
81
  <Spacer @height="600px" />
53
- </Layout::Section::Body>
82
+ </Layout::Section::Body>