@fleetbase/fleetops-engine 0.6.56 → 0.6.58

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 (82) hide show
  1. package/addon/components/ai/create-order-preview.hbs +297 -0
  2. package/addon/components/ai/create-order-preview.js +362 -0
  3. package/addon/components/ai/route-preview-map.hbs +79 -0
  4. package/addon/components/ai/route-preview-map.js +527 -0
  5. package/addon/components/fleet/details.hbs +21 -8
  6. package/addon/components/fleet/details.js +55 -1
  7. package/addon/components/fleet/hierarchy-tree.hbs +137 -0
  8. package/addon/components/fleet/hierarchy-tree.js +528 -0
  9. package/addon/components/map/drawer/device-event-listing.js +1 -0
  10. package/addon/components/map/drawer/driver-listing.js +1 -0
  11. package/addon/components/map/drawer/place-listing.js +1 -0
  12. package/addon/components/map/drawer/vehicle-listing.js +1 -0
  13. package/addon/components/order/details.hbs +34 -1
  14. package/addon/components/order/form/details.hbs +4 -0
  15. package/addon/components/order/form.hbs +9 -1
  16. package/addon/components/vehicle/card.hbs +14 -2
  17. package/addon/components/vehicle/form.hbs +13 -1
  18. package/addon/controllers/settings/map.js +4 -0
  19. package/addon/extension.js +14 -0
  20. package/addon/routes/management/fleets/index/details.js +1 -1
  21. package/addon/services/map-adapter/google.js +56 -16
  22. package/addon/services/map-manager.js +12 -0
  23. package/addon/styles/fleetops-engine.css +487 -1
  24. package/addon/utils/map-drawer-dropdown-position.js +11 -13
  25. package/app/components/ai/create-order-preview.js +1 -0
  26. package/app/components/ai/route-preview-map.js +1 -0
  27. package/app/components/fleet/hierarchy-tree.js +1 -0
  28. package/app/services/route-engine.js +1 -0
  29. package/composer.json +9 -2
  30. package/extension.json +1 -1
  31. package/package.json +6 -4
  32. package/phpunit.xml.dist +4 -4
  33. package/pnpm-workspace.yaml +2 -1
  34. package/scripts/coverage-runner.php +51 -0
  35. package/scripts/coverage-summary.php +110 -0
  36. package/scripts/normalize-rgba-alpha.js +90 -0
  37. package/scripts/pest-bootstrap.php +177 -0
  38. package/scripts/pest-file-runner.php +82 -0
  39. package/scripts/pest-runner.php +64 -0
  40. package/server/src/Http/Resources/v1/Fleet.php +8 -2
  41. package/server/src/Models/Driver.php +6 -0
  42. package/server/src/Models/Order.php +18 -6
  43. package/server/src/Models/Place.php +11 -3
  44. package/server/src/Orchestration/Support/OrchestrationPayloadBuilder.php +3 -1
  45. package/server/src/Providers/FleetOpsServiceProvider.php +26 -0
  46. package/server/src/Support/Ai/Capabilities/AbstractFleetOpsAICapability.php +88 -0
  47. package/server/src/Support/Ai/Capabilities/AssetStatusCapability.php +108 -0
  48. package/server/src/Support/Ai/Capabilities/ConsoleNavigationCapability.php +55 -0
  49. package/server/src/Support/Ai/Capabilities/CreateOrderPreviewCapability.php +508 -0
  50. package/server/src/Support/Ai/Capabilities/DocsHelpCapability.php +49 -0
  51. package/server/src/Support/Ai/Capabilities/ImportOrdersPreviewCapability.php +66 -0
  52. package/server/src/Support/Ai/Capabilities/OperationalQueryCapability.php +319 -0
  53. package/server/src/Support/Ai/Capabilities/OptimizeOrderRouteCapability.php +240 -0
  54. package/server/src/Support/Ai/Capabilities/OrderInsightsCapability.php +95 -0
  55. package/server/src/Support/Ai/Capabilities/SearchResourcesCapability.php +195 -0
  56. package/server/src/Support/Ai/FleetOpsAiQueryResources.php +150 -0
  57. package/server/src/Support/Utils.php +52 -0
  58. package/server/src/Tracking/TrackingOptions.php +6 -1
  59. package/server/src/routes.php +0 -11
  60. package/server/tests/AiCreateOrderPreviewCapabilityTest.php +131 -0
  61. package/server/tests/AiOperationalQueryCapabilityTest.php +75 -0
  62. package/server/tests/AnalyticsRoutesTest.php +5 -3
  63. package/server/tests/CustomerEndpointTest.php +1 -0
  64. package/server/tests/DeviceFilterTest.php +1 -2
  65. package/server/tests/FleetHierarchyResourceTest.php +12 -0
  66. package/server/tests/FuelProviderRegistryTest.php +7 -9
  67. package/server/tests/LiveControllerViewportTest.php +8 -16
  68. package/server/tests/LiveOrderQueryTest.php +18 -24
  69. package/server/tests/OrderPayloadPlaceResolutionTest.php +53 -0
  70. package/server/tests/PointResolutionTest.php +63 -0
  71. package/server/tests/ServiceAreaZoneApiShapeTest.php +8 -9
  72. package/server/tests/ServiceRateAlgorithmWeightVariablesTest.php +1 -1
  73. package/server/tests/TelematicsHardeningTest.php +31 -26
  74. package/server/tests/TrackingIntelligenceTest.php +65 -25
  75. package/server/tests/VehicleDriverAssignmentTest.php +8 -9
  76. package/addon/components/table/cell/dropdown/action-item.hbs +0 -31
  77. package/addon/components/table/cell/dropdown/action-item.js +0 -62
  78. package/addon/components/table/cell/dropdown.hbs +0 -28
  79. package/addon/components/table/cell/dropdown.js +0 -91
  80. package/app/components/table/cell/dropdown/action-item.js +0 -1
  81. package/app/components/table/cell/dropdown.js +0 -1
  82. package/server/src/Http/Controllers/Api/v1/OrganizationController.php +0 -45
@@ -1,3 +1,57 @@
1
1
  import Component from '@glimmer/component';
2
+ import { inject as service } from '@ember/service';
3
+ import { action } from '@ember/object';
2
4
 
3
- export default class FleetDetailsComponent extends Component {}
5
+ export default class FleetDetailsComponent extends Component {
6
+ @service fleetActions;
7
+ @service driverActions;
8
+ @service vehicleActions;
9
+
10
+ get resource() {
11
+ return this.args.resource ?? this.args.fleet;
12
+ }
13
+
14
+ get drivers() {
15
+ return this.resourceArray(this.resource?.drivers);
16
+ }
17
+
18
+ get driversCount() {
19
+ return Number(this.resource?.drivers_count ?? this.drivers.length ?? 0);
20
+ }
21
+
22
+ get driversOnlineCount() {
23
+ return Number(this.resource?.drivers_online_count ?? this.drivers.filter((driver) => driver?.online).length ?? 0);
24
+ }
25
+
26
+ resourceArray(resources) {
27
+ if (!resources) {
28
+ return [];
29
+ }
30
+
31
+ if (typeof resources.toArray === 'function') {
32
+ return resources.toArray();
33
+ }
34
+
35
+ return Array.isArray(resources) ? resources : [];
36
+ }
37
+
38
+ @action viewFleet(fleet) {
39
+ return this.fleetActions.panel.view(fleet);
40
+ }
41
+
42
+ @action viewDriver(driver) {
43
+ return this.driverActions.panel.view(driver);
44
+ }
45
+
46
+ @action viewVehicle(vehicle) {
47
+ return this.vehicleActions.panel.view(vehicle);
48
+ }
49
+
50
+ @action assignDriver(fleet) {
51
+ return this.fleetActions.assignDriver(fleet);
52
+ }
53
+
54
+ @action assignVehicle(fleet) {
55
+ return this.fleetActions.assignVehicle(fleet);
56
+ }
57
+ }
@@ -0,0 +1,137 @@
1
+ <div class="fleet-hierarchy-tree" data-test-fleet-hierarchy-tree {{did-insert this.loadVisibleFleetResources}} ...attributes>
2
+ <div class="flex flex-col gap-2 border-b border-gray-200 bg-gray-50 px-2.5 pb-2 dark:border-gray-700 dark:bg-gray-800">
3
+ <div class="flex flex-col gap-2 md:flex-row md:items-center md:justify-between">
4
+ <div class="flex min-w-0 flex-1 items-center gap-1.5 rounded border border-gray-200 bg-white px-2 py-1 text-gray-400 dark:border-gray-700 dark:bg-gray-900">
5
+ <FaIcon @icon="magnifying-glass" @size="xs" />
6
+ <input
7
+ type="search"
8
+ value={{this.query}}
9
+ placeholder="Search hierarchy..."
10
+ class="min-w-0 flex-1 appearance-none rounded-md border-0 bg-transparent p-0 text-xs leading-5 text-gray-700 outline-none shadow-none ring-0 focus:border-transparent focus:outline-none focus:ring-0 dark:text-gray-100"
11
+ data-test-fleet-hierarchy-search
12
+ {{on "input" this.updateQuery}}
13
+ />
14
+ </div>
15
+ <div class="flex shrink-0 items-center gap-1 rounded bg-gray-100 p-1 dark:bg-gray-900" data-test-fleet-hierarchy-filters>
16
+ {{#each this.filters as |filter|}}
17
+ <button
18
+ type="button"
19
+ class="rounded px-2 py-1 text-xs font-medium {{if (eq this.activeFilter filter.id) 'bg-white text-gray-900 shadow-sm dark:bg-gray-700 dark:text-white' 'text-gray-500 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white'}}"
20
+ data-test-fleet-hierarchy-filter={{filter.id}}
21
+ {{on "click" (fn this.setFilter filter.id)}}
22
+ >
23
+ {{filter.label}}
24
+ </button>
25
+ {{/each}}
26
+ </div>
27
+ <div class="flex shrink-0 items-center gap-1">
28
+ <Button
29
+ @type="default"
30
+ @size="xs"
31
+ @icon={{this.expandCollapseIcon}}
32
+ @helpText={{this.expandCollapseHelpText}}
33
+ @onClick={{this.toggleExpandCollapseAll}}
34
+ data-test-fleet-hierarchy-expand-toggle
35
+ />
36
+ </div>
37
+ </div>
38
+ </div>
39
+
40
+ <div class="fleet-hierarchy-tree-list bg-white dark:bg-gray-900" aria-label="Fleet hierarchy">
41
+ {{#if this.visibleRows.length}}
42
+ {{#each this.visibleRows as |row|}}
43
+ {{#if (eq row.type "fleet")}}
44
+ <div
45
+ class="fleet-hierarchy-tree-row {{row.depthClass}} group flex min-w-0 items-start gap-2 border-b border-gray-100 px-3 py-2 text-sm text-gray-700 hover:bg-gray-50 dark:border-gray-800 dark:text-gray-200 dark:hover:bg-gray-800"
46
+ data-test-fleet-hierarchy-row="fleet"
47
+ >
48
+ <button
49
+ type="button"
50
+ class="flex min-w-0 flex-1 items-start gap-2 text-left"
51
+ aria-expanded={{if (this.fleetHasChildren row.fleet) (if (this.isFleetExpanded row.fleet) "true" "false")}}
52
+ {{on "click" (fn this.toggleFleet row.fleet)}}
53
+ >
54
+ <span class="mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded bg-gray-100 text-gray-400 dark:bg-gray-800" aria-hidden="true">
55
+ {{#if (this.fleetHasChildren row.fleet)}}
56
+ <FaIcon @icon={{if (this.isFleetExpanded row.fleet) "chevron-down" "chevron-right"}} @size="xs" />
57
+ {{else}}
58
+ <FaIcon @icon="user-group" @size="xs" />
59
+ {{/if}}
60
+ </span>
61
+ <span class="min-w-0 flex-1">
62
+ <span class="block truncate font-semibold leading-5" title={{this.displayName row.fleet}}>{{this.displayName row.fleet}}</span>
63
+ <span class="block truncate text-xs leading-4 text-gray-400">{{this.fleetSubtitle row.fleet}}</span>
64
+ </span>
65
+ </button>
66
+ <div class="flex shrink-0 items-center gap-1">
67
+ <span class="hidden rounded bg-gray-100 px-1.5 py-0.5 text-xs text-gray-500 dark:bg-gray-800 dark:text-gray-400 md:inline-flex">
68
+ {{this.fleetSubfleetCount row.fleet}} subfleets
69
+ </span>
70
+ <DropdownButton
71
+ @icon="ellipsis-h"
72
+ @iconPrefix="fas"
73
+ @size="xs"
74
+ @buttonClass="fleetops-btn-xxs"
75
+ @contentClass="dropdown-menu"
76
+ @horizontalPosition="left"
77
+ @calculatePosition={{this.calculateDropdownLeftPosition}}
78
+ as |dd|
79
+ >
80
+ <div class="next-dd-menu mx-0 mt-1" role="menu">
81
+ <a href="javascript:;" class="next-dd-item" {{on "click" (dropdown-fn dd this.viewFleet row.fleet)}}>View details</a>
82
+ <div class="next-dd-menu-seperator"></div>
83
+ <a href="javascript:;" class="next-dd-item" {{on "click" (dropdown-fn dd this.assignDriver row.fleet)}}>Assign driver</a>
84
+ <a href="javascript:;" class="next-dd-item" {{on "click" (dropdown-fn dd this.assignVehicle row.fleet)}}>Assign vehicle</a>
85
+ </div>
86
+ </DropdownButton>
87
+ </div>
88
+ </div>
89
+ {{else if (eq row.type "driver")}}
90
+ <button
91
+ type="button"
92
+ class="fleet-hierarchy-tree-row {{row.depthClass}} flex w-full min-w-0 items-start gap-2 border-b border-gray-100 px-3 py-1.5 text-left text-xs text-gray-600 hover:bg-gray-50 dark:border-gray-800 dark:text-gray-300 dark:hover:bg-gray-800"
93
+ data-test-fleet-hierarchy-row="driver"
94
+ {{on "click" (fn this.viewDriver row.driver)}}
95
+ >
96
+ <span class="mt-1 h-1.5 w-1.5 shrink-0 rounded-full {{if row.driver.online 'bg-green-500' 'bg-yellow-300'}}" aria-hidden="true"></span>
97
+ <span class="min-w-0 flex-1">
98
+ <span class="block truncate font-medium leading-4" title={{this.displayName row.driver}}>{{this.displayName row.driver}}</span>
99
+ <span class="block truncate text-xs leading-4 text-gray-400">Driver - {{this.driverSubtitle row.driver}}</span>
100
+ </span>
101
+ </button>
102
+ {{else}}
103
+ <button
104
+ type="button"
105
+ class="fleet-hierarchy-tree-row {{row.depthClass}} flex w-full min-w-0 items-start gap-2 border-b border-gray-100 px-3 py-1.5 text-left text-xs text-gray-600 hover:bg-gray-50 dark:border-gray-800 dark:text-gray-300 dark:hover:bg-gray-800"
106
+ data-test-fleet-hierarchy-row="vehicle"
107
+ {{on "click" (fn this.viewVehicle row.vehicle)}}
108
+ >
109
+ <span class="mt-1 h-1.5 w-1.5 shrink-0 rounded-full {{if row.vehicle.online 'bg-green-500' 'bg-yellow-300'}}" aria-hidden="true"></span>
110
+ <span class="min-w-0 flex-1">
111
+ <span class="block truncate font-medium leading-4" title={{this.displayName row.vehicle}}>{{this.displayName row.vehicle}}</span>
112
+ <span class="block truncate text-xs leading-4 text-gray-400">Vehicle - {{this.vehicleSubtitle row.vehicle}}</span>
113
+ </span>
114
+ </button>
115
+ {{/if}}
116
+ {{/each}}
117
+ {{else}}
118
+ <div class="flex flex-col items-center justify-center gap-2 p-6 text-center" data-test-fleet-hierarchy-empty>
119
+ <span class="flex h-8 w-8 items-center justify-center rounded bg-gray-100 text-gray-400 dark:bg-gray-800">
120
+ <FaIcon @icon={{if this.hasControlsApplied "magnifying-glass" "diagram-project"}} @size="sm" />
121
+ </span>
122
+ <div>
123
+ <div class="text-sm font-semibold text-gray-900 dark:text-gray-100">{{this.emptyTitle}}</div>
124
+ <div class="mt-1 text-xs leading-5 text-gray-500 dark:text-gray-400">{{this.emptyDescription}}</div>
125
+ </div>
126
+ {{#if this.hasControlsApplied}}
127
+ <Button @type="default" @size="xs" @icon="times" @text="Clear filters" @onClick={{this.clearFilters}} data-test-fleet-hierarchy-clear-filters />
128
+ {{else}}
129
+ <div class="flex items-center gap-1">
130
+ <Button @type="default" @size="xs" @icon="user-plus" @text="Assign driver" @onClick={{fn this.assignDriver this.rootFleet}} />
131
+ <Button @type="default" @size="xs" @icon="car" @text="Assign vehicle" @onClick={{fn this.assignVehicle this.rootFleet}} />
132
+ </div>
133
+ {{/if}}
134
+ </div>
135
+ {{/if}}
136
+ </div>
137
+ </div>