@fleetbase/fleetops-engine 0.6.56 → 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/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/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/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/vehicle/card.hbs +14 -2
- package/addon/components/vehicle/form.hbs +13 -1
- package/addon/controllers/settings/map.js +4 -0
- package/addon/extension.js +14 -0
- package/addon/routes/management/fleets/index/details.js +1 -1
- package/addon/services/map-adapter/google.js +56 -16
- package/addon/services/map-manager.js +12 -0
- package/addon/styles/fleetops-engine.css +487 -1
- package/addon/utils/map-drawer-dropdown-position.js +11 -13
- package/app/components/ai/create-order-preview.js +1 -0
- package/app/components/ai/route-preview-map.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/src/Http/Resources/v1/Fleet.php +8 -2
- package/server/src/Models/Driver.php +6 -0
- package/server/src/Models/Order.php +18 -6
- package/server/src/Models/Place.php +11 -3
- 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/Utils.php +52 -0
- package/server/tests/AiCreateOrderPreviewCapabilityTest.php +131 -0
- package/server/tests/AiOperationalQueryCapabilityTest.php +75 -0
- package/server/tests/FleetHierarchyResourceTest.php +12 -0
- package/server/tests/OrderPayloadPlaceResolutionTest.php +53 -0
- package/server/tests/PointResolutionTest.php +63 -0
- 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
|
@@ -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>
|
|
@@ -90,6 +90,10 @@ export default class SettingsMapController extends Controller {
|
|
|
90
90
|
this.mapManager.setActiveProvider(this.mapProvider);
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
if (this.mapProvider === 'google' && typeof this.mapManager?.applyViewSettingsFromSettings === 'function') {
|
|
94
|
+
yield this.mapManager.applyViewSettingsFromSettings();
|
|
95
|
+
}
|
|
96
|
+
|
|
93
97
|
this.notifications.success(this.intl.t('settings.map.settings-saved'));
|
|
94
98
|
} catch (error) {
|
|
95
99
|
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',
|
|
@@ -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';
|
|
@@ -166,7 +176,10 @@ export default class GoogleMapsAdapter extends MapAdapterInterface {
|
|
|
166
176
|
const { AdvancedMarkerElement } = await googleMaps.maps.importLibrary('marker');
|
|
167
177
|
this._advancedMarkerElementClass = AdvancedMarkerElement;
|
|
168
178
|
const mergedGoogleOptions = options.googleOptions ?? {};
|
|
169
|
-
const mergedMapStyles =
|
|
179
|
+
const mergedMapStyles = buildGoogleMapStyles({
|
|
180
|
+
showTransitLayer: options.showTransitLayer,
|
|
181
|
+
googleOptions: mergedGoogleOptions,
|
|
182
|
+
});
|
|
170
183
|
const mapId = options.mapId ?? mergedGoogleOptions.mapId ?? this.#getConfig()?.googleMaps?.mapId ?? this.#getConfig()?.GOOGLE_MAPS_MAP_ID ?? null;
|
|
171
184
|
this._supportsAdvancedMarkers = Boolean(mapId && mapId !== 'FLEETOPS_MAP');
|
|
172
185
|
|
|
@@ -182,7 +195,7 @@ export default class GoogleMapsAdapter extends MapAdapterInterface {
|
|
|
182
195
|
styles: mergedMapStyles,
|
|
183
196
|
});
|
|
184
197
|
|
|
185
|
-
this
|
|
198
|
+
await this.applyViewSettings(options);
|
|
186
199
|
await this.#initDrawingManager();
|
|
187
200
|
|
|
188
201
|
debug('[GoogleMapsAdapter] Map initialized');
|
|
@@ -252,6 +265,47 @@ export default class GoogleMapsAdapter extends MapAdapterInterface {
|
|
|
252
265
|
google.maps.event.trigger(this._map, 'resize');
|
|
253
266
|
}
|
|
254
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
|
+
|
|
255
309
|
// ─── Viewport ──────────────────────────────────────────────────────────────
|
|
256
310
|
|
|
257
311
|
setCenter(lat, lng, zoom) {
|
|
@@ -1195,20 +1249,6 @@ export default class GoogleMapsAdapter extends MapAdapterInterface {
|
|
|
1195
1249
|
}
|
|
1196
1250
|
}
|
|
1197
1251
|
|
|
1198
|
-
#syncGoogleLayers(options = {}) {
|
|
1199
|
-
if (!this._map) return;
|
|
1200
|
-
|
|
1201
|
-
if (options.showTrafficLayer) {
|
|
1202
|
-
this._trafficLayer = new google.maps.TrafficLayer();
|
|
1203
|
-
this._trafficLayer.setMap(this._map);
|
|
1204
|
-
}
|
|
1205
|
-
|
|
1206
|
-
if (options.showTransitLayer) {
|
|
1207
|
-
this._transitLayer = new google.maps.TransitLayer();
|
|
1208
|
-
this._transitLayer.setMap(this._map);
|
|
1209
|
-
}
|
|
1210
|
-
}
|
|
1211
|
-
|
|
1212
1252
|
#ensureDrawToolbar() {
|
|
1213
1253
|
if (this._drawControlEl || !this._map) return;
|
|
1214
1254
|
|
|
@@ -170,6 +170,18 @@ export default class MapManagerService extends Service {
|
|
|
170
170
|
this.adapter?.invalidateSize();
|
|
171
171
|
}
|
|
172
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
|
+
|
|
173
185
|
/**
|
|
174
186
|
* Set the live map component reference.
|
|
175
187
|
*
|