@fleetbase/fleetops-engine 0.6.24 → 0.6.26
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/DRIVER_SCHEDULING.md +186 -0
- package/addon/components/driver/schedule.hbs +100 -0
- package/addon/components/driver/schedule.js +267 -0
- package/addon/components/order/kanban-card.hbs +2 -2
- package/addon/components/vehicle/details.hbs +594 -4
- package/addon/components/vehicle/form.hbs +467 -41
- package/addon/controllers/analytics/reports/index.js +3 -2
- package/addon/controllers/connectivity/devices/index.js +3 -3
- package/addon/controllers/connectivity/events/index.js +3 -2
- package/addon/controllers/connectivity/sensors/index.js +3 -5
- package/addon/controllers/connectivity/telematics/index.js +3 -1
- package/addon/controllers/maintenance/equipment/index.js +4 -4
- package/addon/controllers/maintenance/parts/index.js +4 -4
- package/addon/controllers/maintenance/work-orders/index.js +4 -4
- package/addon/controllers/management/contacts/customers.js +12 -10
- package/addon/controllers/management/contacts/index.js +3 -10
- package/addon/controllers/management/drivers/index/details.js +26 -13
- package/addon/controllers/management/drivers/index.js +4 -16
- package/addon/controllers/management/fleets/index.js +3 -13
- package/addon/controllers/management/fuel-reports/index.js +3 -10
- package/addon/controllers/management/issues/index.js +3 -12
- package/addon/controllers/management/places/index.js +4 -12
- package/addon/controllers/management/vehicles/index.js +3 -13
- package/addon/controllers/management/vendors/index.js +3 -13
- package/addon/controllers/operations/orders/index.js +5 -22
- package/addon/controllers/operations/scheduler/index.js +195 -6
- package/addon/controllers/operations/service-rates/index.js +34 -34
- package/addon/controllers/settings/payments/index.js +0 -6
- package/addon/routes.js +1 -0
- package/addon/services/driver-scheduling.js +171 -0
- package/addon/services/leaflet-layer-visibility-manager.js +4 -1
- package/addon/services/service-rate-actions.js +5 -1
- package/addon/templates/management/drivers/index/details/positions.hbs +1 -2
- package/addon/templates/management/drivers/index/details/schedule.hbs +1 -2
- package/addon/templates/operations/scheduler/index.hbs +48 -10
- package/addon/utils/fleet-ops-options.js +86 -0
- package/app/services/driver-scheduling.js +1 -0
- package/composer.json +1 -1
- package/extension.json +1 -1
- package/package.json +3 -3
- package/server/migrations/2025_11_17_033648_add_additional_columns_to_vehicles_table.php +142 -0
- package/server/src/Constraints/HOSConstraint.php +244 -0
- package/server/src/Http/Controllers/Api/v1/DriverController.php +14 -4
- package/server/src/Http/Controllers/Api/v1/OrderController.php +1 -1
- package/server/src/Http/Controllers/Api/v1/VehicleController.php +2 -2
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +8 -3
- package/server/src/Http/Resources/v1/Driver.php +1 -1
- package/server/src/Http/Resources/v1/Vehicle.php +197 -19
- package/server/src/Http/Resources/v1/VehicleWithoutDriver.php +211 -28
- package/server/src/Models/Driver.php +15 -8
- package/server/src/Models/Vehicle.php +101 -15
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
<div class="form-wrapper" ...attributes>
|
|
2
|
+
{{! DETAILS / IDENTIFICATION }}
|
|
2
3
|
<ContentPanel @title={{t "common.details"}} @open={{true}} @wrapperClass="bordered-top">
|
|
3
4
|
<div class="flex flex-row space-x-3 mb-3">
|
|
4
5
|
<div class="flex items-center justify-start rounded-full">
|
|
5
|
-
<Image
|
|
6
|
+
<Image
|
|
7
|
+
src={{@resource.photo_url}}
|
|
8
|
+
@fallbackSrc={{config "defaultValues.vehicleImage"}}
|
|
9
|
+
alt={{@resource.name}}
|
|
10
|
+
height="48"
|
|
11
|
+
width="48"
|
|
12
|
+
class="h-14 w-14 rounded-full shadow-sm"
|
|
13
|
+
/>
|
|
6
14
|
<Attach::Tooltip @class="clean" @animation="scale" @placement="top">
|
|
7
15
|
<InputInfo @text={{t "vehicle.fields.upload-new-photo"}} />
|
|
8
16
|
</Attach::Tooltip>
|
|
@@ -22,61 +30,51 @@
|
|
|
22
30
|
</div>
|
|
23
31
|
</div>
|
|
24
32
|
</div>
|
|
33
|
+
|
|
25
34
|
<div class="grid grid-cols-1 gap-2 lg:grid-cols-2 lg:gap-2 no-input-group-padding text-xs">
|
|
35
|
+
{{! Vehicle Identification }}
|
|
36
|
+
<div class="col-span-1 lg:col-span-2 text-[11px] uppercase tracking-wide text-gray-500 font-semibold mt-1">
|
|
37
|
+
Vehicle Identification
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
<InputGroup @name={{t "common.name"}}>
|
|
41
|
+
<Input @value={{@resource.name}} @type="text" class="w-full form-input" placeholder={{t "common.name"}} disabled={{cannot-write @resource}} />
|
|
42
|
+
</InputGroup>
|
|
43
|
+
|
|
26
44
|
<InputGroup @name={{t "common.internal-id"}}>
|
|
27
45
|
<Input @value={{@resource.internal_id}} @type="text" class="w-full form-input" placeholder={{t "common.internal-id"}} disabled={{cannot-write @resource}} />
|
|
28
46
|
</InputGroup>
|
|
29
47
|
|
|
30
48
|
<InputGroup @name={{t "vehicle.fields.plate-number"}}>
|
|
31
|
-
<Input
|
|
32
|
-
@value={{@resource.plate_number}}
|
|
33
|
-
@type="text"
|
|
34
|
-
class="w-full form-input"
|
|
35
|
-
placeholder={{t "vehicle.fields.plate-number"}}
|
|
36
|
-
disabled={{cannot-write @resource}}
|
|
37
|
-
/>
|
|
49
|
+
<Input @value={{@resource.plate_number}} @type="text" class="w-full form-input" placeholder={{t "vehicle.fields.plate-number"}} disabled={{cannot-write @resource}} />
|
|
38
50
|
</InputGroup>
|
|
39
51
|
|
|
40
52
|
<InputGroup @name={{t "vehicle.fields.vin-number"}}>
|
|
41
|
-
<Input
|
|
42
|
-
@value={{@resource.vin}}
|
|
43
|
-
@type="text"
|
|
44
|
-
class="w-full form-input"
|
|
45
|
-
placeholder={{t "vehicle.fields.vin-number"}}
|
|
46
|
-
disabled={{cannot-write @resource}}
|
|
47
|
-
/>
|
|
53
|
+
<Input @value={{@resource.vin}} @type="text" class="w-full form-input" placeholder={{t "vehicle.fields.vin-number"}} disabled={{cannot-write @resource}} />
|
|
48
54
|
</InputGroup>
|
|
49
55
|
|
|
50
56
|
<InputGroup @name={{t "vehicle.fields.make"}}>
|
|
51
|
-
<Input
|
|
52
|
-
@value={{@resource.make}}
|
|
53
|
-
@type="text"
|
|
54
|
-
class="w-full form-input"
|
|
55
|
-
placeholder={{t "vehicle.fields.vehicle-make"}}
|
|
56
|
-
disabled={{cannot-write @resource}}
|
|
57
|
-
/>
|
|
57
|
+
<Input @value={{@resource.make}} @type="text" class="w-full form-input" placeholder={{t "vehicle.fields.vehicle-make"}} disabled={{cannot-write @resource}} />
|
|
58
58
|
</InputGroup>
|
|
59
59
|
|
|
60
60
|
<InputGroup @name={{t "vehicle.fields.model"}}>
|
|
61
|
-
<Input
|
|
62
|
-
@value={{@resource.model}}
|
|
63
|
-
@type="text"
|
|
64
|
-
class="w-full form-input"
|
|
65
|
-
placeholder={{t "vehicle.fields.vehicle-model"}}
|
|
66
|
-
disabled={{cannot-write @resource}}
|
|
67
|
-
/>
|
|
61
|
+
<Input @value={{@resource.model}} @type="text" class="w-full form-input" placeholder={{t "vehicle.fields.vehicle-model"}} disabled={{cannot-write @resource}} />
|
|
68
62
|
</InputGroup>
|
|
69
63
|
|
|
70
64
|
<InputGroup @name={{t "vehicle.fields.year"}}>
|
|
71
|
-
<Input
|
|
72
|
-
@value={{@resource.year}}
|
|
73
|
-
@type="text"
|
|
74
|
-
class="w-full form-input"
|
|
75
|
-
placeholder={{t "vehicle.fields.vehicle-year"}}
|
|
76
|
-
disabled={{cannot-write @resource}}
|
|
77
|
-
/>
|
|
65
|
+
<Input @value={{@resource.year}} @type="text" class="w-full form-input" placeholder={{t "vehicle.fields.vehicle-year"}} disabled={{cannot-write @resource}} />
|
|
78
66
|
</InputGroup>
|
|
79
67
|
|
|
68
|
+
<InputGroup @value={{@resource.trim}} @name="Trim" @placeholder="Trim" />
|
|
69
|
+
<InputGroup @value={{@resource.color}} @name="Color" @placeholder="Vehicle Color" />
|
|
70
|
+
<InputGroup @value={{@resource.serial_number}} @name="Serial Number" @placeholder="Serial Number" />
|
|
71
|
+
<InputGroup @value={{@resource.class}} @name="Class" @placeholder="Class" />
|
|
72
|
+
|
|
73
|
+
{{! Assignment & Status }}
|
|
74
|
+
<div class="col-span-1 lg:col-span-2 text-[11px] uppercase tracking-wide text-gray-500 font-semibold mt-3">
|
|
75
|
+
Assignment & Status
|
|
76
|
+
</div>
|
|
77
|
+
|
|
80
78
|
<InputGroup @name={{t "vehicle.fields.driver-assigned"}}>
|
|
81
79
|
<ModelSelect
|
|
82
80
|
@modelName="driver"
|
|
@@ -96,27 +94,455 @@
|
|
|
96
94
|
<InputGroup @name={{t "common.status"}}>
|
|
97
95
|
<div class="fleetbase-model-select fleetbase-power-select ember-model-select">
|
|
98
96
|
<PowerSelect
|
|
99
|
-
@options={{
|
|
100
|
-
@selected={{@resource.status}}
|
|
101
|
-
@onChange={{
|
|
97
|
+
@options={{get-fleet-ops-options "vehicleStatuses"}}
|
|
98
|
+
@selected={{find-by "value" @resource.status (get-fleet-ops-options "vehicleStatuses")}}
|
|
99
|
+
@onChange={{set-model-attr @resource "status"}}
|
|
102
100
|
@placeholder={{t "common.status"}}
|
|
103
101
|
@triggerClass="form-select form-input"
|
|
104
102
|
@disabled={{cannot-write @resource}}
|
|
105
|
-
as |
|
|
103
|
+
as |option|
|
|
106
104
|
>
|
|
107
|
-
|
|
105
|
+
<div class="text-sm">
|
|
106
|
+
<div class="font-semibold normalize-in-trigger">{{option.label}}</div>
|
|
107
|
+
<div class="hide-from-trigger">{{option.description}}</div>
|
|
108
|
+
</div>
|
|
108
109
|
</PowerSelect>
|
|
109
110
|
</div>
|
|
110
111
|
</InputGroup>
|
|
112
|
+
|
|
113
|
+
<InputGroup @value={{@resource.call_sign}} @name="Call Sign" @placeholder="Call Sign" />
|
|
114
|
+
|
|
115
|
+
{{! Location }}
|
|
116
|
+
<div class="col-span-1 lg:col-span-2 text-[11px] uppercase tracking-wide text-gray-500 font-semibold mt-3">
|
|
117
|
+
Location
|
|
118
|
+
</div>
|
|
119
|
+
|
|
111
120
|
<InputGroup @name={{t "common.coordinates"}} @wrapperClass="col-span-2">
|
|
112
121
|
<ModelCoordinatesInput @model={{@resource}} @disabled={{cannot-write @resource}} @autocomplete="location" />
|
|
113
122
|
</InputGroup>
|
|
114
123
|
</div>
|
|
124
|
+
|
|
115
125
|
<RegistryYield @registry="fleet-ops:component:vehicle:form:details" as |RegistryComponent|>
|
|
116
126
|
<RegistryComponent @resource={{@resource}} @controller={{this.controller}} @permission={{get-write-permission @resource}} />
|
|
117
127
|
</RegistryYield>
|
|
118
128
|
</ContentPanel>
|
|
119
129
|
|
|
130
|
+
{{! MEASUREMENT & UNITS / ODOMETER }}
|
|
131
|
+
<ContentPanel @title="Measurement & Units" @open={{true}} @wrapperClass="bordered-top">
|
|
132
|
+
<div class="grid grid-cols-1 gap-2 lg:grid-cols-2 lg:gap-2 no-input-group-padding text-xs">
|
|
133
|
+
<div class="col-span-1 lg:col-span-2 text-[11px] uppercase tracking-wide text-gray-500 font-semibold mt-1">
|
|
134
|
+
Measurement & Units
|
|
135
|
+
</div>
|
|
136
|
+
|
|
137
|
+
<InputGroup @name="System of Measurement">
|
|
138
|
+
<div class="fleetbase-model-select fleetbase-power-select ember-model-select">
|
|
139
|
+
<PowerSelect
|
|
140
|
+
@options={{get-fleet-ops-options "measurementSystems"}}
|
|
141
|
+
@selected={{find-by "value" @resource.measurement_system (get-fleet-ops-options "measurementSystems")}}
|
|
142
|
+
@onChange={{set-model-attr @resource "measurement_system"}}
|
|
143
|
+
@placeholder="Select System of Measurement"
|
|
144
|
+
@triggerClass="form-select form-input"
|
|
145
|
+
@disabled={{cannot-write @resource}}
|
|
146
|
+
as |option|
|
|
147
|
+
>
|
|
148
|
+
<div class="text-sm">
|
|
149
|
+
<div class="font-semibold normalize-in-trigger">{{option.label}}</div>
|
|
150
|
+
<div class="hide-from-trigger">{{option.description}}</div>
|
|
151
|
+
</div>
|
|
152
|
+
</PowerSelect>
|
|
153
|
+
</div>
|
|
154
|
+
</InputGroup>
|
|
155
|
+
|
|
156
|
+
<InputGroup @name="Fuel Volume Unit">
|
|
157
|
+
<div class="fleetbase-model-select fleetbase-power-select ember-model-select">
|
|
158
|
+
<PowerSelect
|
|
159
|
+
@options={{get-fleet-ops-options "fuelVolumeUnits"}}
|
|
160
|
+
@selected={{find-by "value" @resource.fuel_volume_unit (get-fleet-ops-options "fuelVolumeUnits")}}
|
|
161
|
+
@onChange={{set-model-attr @resource "fuel_volume_unit"}}
|
|
162
|
+
@placeholder="Select Fuel Volume Unit"
|
|
163
|
+
@triggerClass="form-select form-input"
|
|
164
|
+
@disabled={{cannot-write @resource}}
|
|
165
|
+
as |option|
|
|
166
|
+
>
|
|
167
|
+
<div class="text-sm">
|
|
168
|
+
<div class="font-semibold normalize-in-trigger">{{option.label}}</div>
|
|
169
|
+
<div class="hide-from-trigger">{{option.description}}</div>
|
|
170
|
+
</div>
|
|
171
|
+
</PowerSelect>
|
|
172
|
+
</div>
|
|
173
|
+
</InputGroup>
|
|
174
|
+
|
|
175
|
+
<div class="col-span-1 lg:col-span-2 text-[11px] uppercase tracking-wide text-gray-500 font-semibold mt-3">
|
|
176
|
+
Odometer & Usage
|
|
177
|
+
</div>
|
|
178
|
+
|
|
179
|
+
<InputGroup @value={{@resource.odometer}} @name={{concat "Current Odometer (" @resource.odometer_unit ")"}} @type="number" @placeholder="Current Odometer Reading" />
|
|
180
|
+
|
|
181
|
+
<InputGroup @name="Odometer Unit">
|
|
182
|
+
<div class="fleetbase-model-select fleetbase-power-select ember-model-select">
|
|
183
|
+
<PowerSelect
|
|
184
|
+
@options={{get-fleet-ops-options "odometerUnits"}}
|
|
185
|
+
@selected={{find-by "value" @resource.odometer_unit (get-fleet-ops-options "odometerUnits")}}
|
|
186
|
+
@onChange={{set-model-attr @resource "odometer_unit"}}
|
|
187
|
+
@placeholder="Select unit"
|
|
188
|
+
@triggerClass="form-select form-input"
|
|
189
|
+
@disabled={{cannot-write @resource}}
|
|
190
|
+
as |option|
|
|
191
|
+
>
|
|
192
|
+
<div class="text-sm">
|
|
193
|
+
<div class="font-semibold normalize-in-trigger">{{option.label}}</div>
|
|
194
|
+
<div class="hide-from-trigger">{{option.description}}</div>
|
|
195
|
+
</div>
|
|
196
|
+
</PowerSelect>
|
|
197
|
+
</div>
|
|
198
|
+
</InputGroup>
|
|
199
|
+
|
|
200
|
+
<InputGroup @value={{@resource.odometer_at_purchase}} @name="Odometer at Purchase" @type="number" @placeholder="Odometer reading at purchase" />
|
|
201
|
+
</div>
|
|
202
|
+
</ContentPanel>
|
|
203
|
+
|
|
204
|
+
{{! BODY & USAGE }}
|
|
205
|
+
<ContentPanel @title="Body & Usage" @open={{true}} @wrapperClass="bordered-top">
|
|
206
|
+
<div class="grid grid-cols-1 gap-2 lg:grid-cols-2 lg:gap-2 no-input-group-padding text-xs">
|
|
207
|
+
<div class="col-span-1 lg:col-span-2 text-[11px] uppercase tracking-wide text-gray-500 font-semibold mt-1">
|
|
208
|
+
Body & Usage
|
|
209
|
+
</div>
|
|
210
|
+
|
|
211
|
+
<InputGroup @name="Body Type">
|
|
212
|
+
<div class="fleetbase-model-select fleetbase-power-select ember-model-select">
|
|
213
|
+
<PowerSelect
|
|
214
|
+
@options={{get-fleet-ops-options "vehicleBodyTypes"}}
|
|
215
|
+
@selected={{find-by "value" @resource.body_type (get-fleet-ops-options "vehicleBodyTypes")}}
|
|
216
|
+
@onChange={{set-model-attr @resource "body_type"}}
|
|
217
|
+
@placeholder="Select body type"
|
|
218
|
+
@triggerClass="form-select form-input"
|
|
219
|
+
@disabled={{cannot-write @resource}}
|
|
220
|
+
as |option|
|
|
221
|
+
>
|
|
222
|
+
<div class="text-sm">
|
|
223
|
+
<div class="font-semibold normalize-in-trigger">{{option.label}}</div>
|
|
224
|
+
<div class="hide-from-trigger">{{option.description}}</div>
|
|
225
|
+
</div>
|
|
226
|
+
</PowerSelect>
|
|
227
|
+
</div>
|
|
228
|
+
</InputGroup>
|
|
229
|
+
|
|
230
|
+
<InputGroup @name="Body Subtype">
|
|
231
|
+
<div class="fleetbase-model-select fleetbase-power-select ember-model-select">
|
|
232
|
+
<PowerSelect
|
|
233
|
+
@options={{get-fleet-ops-options "vehicleBodySubTypes"}}
|
|
234
|
+
@selected={{find-by "value" @resource.body_sub_type (get-fleet-ops-options "vehicleBodySubTypes")}}
|
|
235
|
+
@onChange={{set-model-attr @resource "body_sub_type"}}
|
|
236
|
+
@placeholder="Select body sub-type"
|
|
237
|
+
@triggerClass="form-select form-input"
|
|
238
|
+
@disabled={{cannot-write @resource}}
|
|
239
|
+
as |option|
|
|
240
|
+
>
|
|
241
|
+
<div class="text-sm">
|
|
242
|
+
<div class="font-semibold normalize-in-trigger">{{option.label}}</div>
|
|
243
|
+
<div class="hide-from-trigger">{{option.description}}</div>
|
|
244
|
+
</div>
|
|
245
|
+
</PowerSelect>
|
|
246
|
+
</div>
|
|
247
|
+
</InputGroup>
|
|
248
|
+
|
|
249
|
+
<InputGroup @name="Usage Type">
|
|
250
|
+
<div class="fleetbase-model-select fleetbase-power-select ember-model-select">
|
|
251
|
+
<PowerSelect
|
|
252
|
+
@options={{get-fleet-ops-options "vehicleUsageTypes"}}
|
|
253
|
+
@selected={{find-by "value" @resource.usage_type (get-fleet-ops-options "vehicleUsageTypes")}}
|
|
254
|
+
@onChange={{set-model-attr @resource "usage_type"}}
|
|
255
|
+
@placeholder="Select usage type"
|
|
256
|
+
@triggerClass="form-select form-input"
|
|
257
|
+
@disabled={{cannot-write @resource}}
|
|
258
|
+
as |option|
|
|
259
|
+
>
|
|
260
|
+
<div class="text-sm">
|
|
261
|
+
<div class="font-semibold normalize-in-trigger">{{option.label}}</div>
|
|
262
|
+
<div class="hide-from-trigger">{{option.description}}</div>
|
|
263
|
+
</div>
|
|
264
|
+
</PowerSelect>
|
|
265
|
+
</div>
|
|
266
|
+
</InputGroup>
|
|
267
|
+
|
|
268
|
+
<InputGroup @name="Ownership Type">
|
|
269
|
+
<div class="fleetbase-model-select fleetbase-power-select ember-model-select">
|
|
270
|
+
<PowerSelect
|
|
271
|
+
@options={{get-fleet-ops-options "vehicleOwnershipTypes"}}
|
|
272
|
+
@selected={{find-by "value" @resource.ownership_type (get-fleet-ops-options "vehicleOwnershipTypes")}}
|
|
273
|
+
@onChange={{set-model-attr @resource "ownership_type"}}
|
|
274
|
+
@placeholder="Select ownership type"
|
|
275
|
+
@triggerClass="form-select form-input"
|
|
276
|
+
@disabled={{cannot-write @resource}}
|
|
277
|
+
as |option|
|
|
278
|
+
>
|
|
279
|
+
<div class="text-sm">
|
|
280
|
+
<div class="font-semibold normalize-in-trigger">{{option.label}}</div>
|
|
281
|
+
<div class="hide-from-trigger">{{option.description}}</div>
|
|
282
|
+
</div>
|
|
283
|
+
</PowerSelect>
|
|
284
|
+
</div>
|
|
285
|
+
</InputGroup>
|
|
286
|
+
|
|
287
|
+
<InputGroup @name="Fuel Type">
|
|
288
|
+
<div class="fleetbase-model-select fleetbase-power-select ember-model-select">
|
|
289
|
+
<PowerSelect
|
|
290
|
+
@options={{get-fleet-ops-options "fuelTypes"}}
|
|
291
|
+
@selected={{find-by "value" @resource.fuel_type (get-fleet-ops-options "fuelTypes")}}
|
|
292
|
+
@onChange={{set-model-attr @resource "fuel_type"}}
|
|
293
|
+
@placeholder="Select fuel type"
|
|
294
|
+
@triggerClass="form-select form-input"
|
|
295
|
+
@disabled={{cannot-write @resource}}
|
|
296
|
+
as |option|
|
|
297
|
+
>
|
|
298
|
+
<div class="text-sm">
|
|
299
|
+
<div class="font-semibold normalize-in-trigger">{{option.label}}</div>
|
|
300
|
+
<div class="hide-from-trigger">{{option.description}}</div>
|
|
301
|
+
</div>
|
|
302
|
+
</PowerSelect>
|
|
303
|
+
</div>
|
|
304
|
+
</InputGroup>
|
|
305
|
+
|
|
306
|
+
<InputGroup @name="Transmission">
|
|
307
|
+
<div class="fleetbase-model-select fleetbase-power-select ember-model-select">
|
|
308
|
+
<PowerSelect
|
|
309
|
+
@options={{get-fleet-ops-options "transmissionTypes"}}
|
|
310
|
+
@selected={{find-by "value" @resource.transmission (get-fleet-ops-options "transmissionTypes")}}
|
|
311
|
+
@onChange={{set-model-attr @resource "transmission"}}
|
|
312
|
+
@placeholder="Select transmission"
|
|
313
|
+
@triggerClass="form-select form-input"
|
|
314
|
+
@disabled={{cannot-write @resource}}
|
|
315
|
+
as |option|
|
|
316
|
+
>
|
|
317
|
+
<div class="text-sm">
|
|
318
|
+
<div class="font-semibold normalize-in-trigger">{{option.label}}</div>
|
|
319
|
+
<div class="hide-from-trigger">{{option.description}}</div>
|
|
320
|
+
</div>
|
|
321
|
+
</PowerSelect>
|
|
322
|
+
</div>
|
|
323
|
+
</InputGroup>
|
|
324
|
+
</div>
|
|
325
|
+
</ContentPanel>
|
|
326
|
+
|
|
327
|
+
{{! TECHNICAL SPECIFICATIONS (ENGINE, CAPACITY, REGULATORY) }}
|
|
328
|
+
<ContentPanel @title="Technical Specifications" @open={{true}} @wrapperClass="bordered-top">
|
|
329
|
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-2 no-input-group-padding text-xs">
|
|
330
|
+
|
|
331
|
+
{{! Powertrain & Engine }}
|
|
332
|
+
<div class="col-span-1 lg:col-span-2 text-[11px] uppercase tracking-wide text-gray-500 font-semibold mt-1">
|
|
333
|
+
Powertrain & Engine
|
|
334
|
+
</div>
|
|
335
|
+
|
|
336
|
+
<InputGroup @value={{@resource.engine_number}} @name="Engine Number" @placeholder="Engine Number" />
|
|
337
|
+
<InputGroup @value={{@resource.engine_make}} @name="Engine Make" @placeholder="Engine Manufacturer" />
|
|
338
|
+
<InputGroup @value={{@resource.engine_model}} @name="Engine Model" @placeholder="Engine Model" />
|
|
339
|
+
<InputGroup @value={{@resource.engine_family}} @name="Engine Family" @placeholder="Engine Family" />
|
|
340
|
+
<InputGroup @value={{@resource.engine_configuration}} @name="Engine Configuration" @placeholder="e.g., Inline-4, V6" />
|
|
341
|
+
<InputGroup @value={{@resource.cylinder_arrangement}} @name="Cylinder Arrangement" @placeholder="e.g., I, V, H" />
|
|
342
|
+
<InputGroup @value={{@resource.number_of_cylinders}} @name="Number of Cylinders" @type="number" @placeholder="e.g., 4, 6" />
|
|
343
|
+
|
|
344
|
+
<InputGroup @name="Engine Size">
|
|
345
|
+
<UnitInput class="w-full" @value={{@resource.engine_size}} @unit="L" @type="number" @step="0.1" @placeholder="Engine Size" />
|
|
346
|
+
</InputGroup>
|
|
347
|
+
|
|
348
|
+
<InputGroup @name="Engine Displacement">
|
|
349
|
+
<UnitInput class="w-full" @value={{@resource.engine_displacement}} @unit="cc" @type="number" @placeholder="Engine Displacement" />
|
|
350
|
+
</InputGroup>
|
|
351
|
+
|
|
352
|
+
<InputGroup @name="Horsepower">
|
|
353
|
+
<UnitInput class="w-full" @value={{@resource.horsepower}} @unit="hp" @type="number" @placeholder="Horsepower" />
|
|
354
|
+
</InputGroup>
|
|
355
|
+
|
|
356
|
+
<InputGroup @value={{@resource.horsepower_rpm}} @name="Horsepower RPM" @type="number" @placeholder="RPM at Max Horsepower" />
|
|
357
|
+
|
|
358
|
+
<InputGroup @name="Torque">
|
|
359
|
+
<UnitInput class="w-full" @value={{@resource.torque}} @unit="Nm" @type="number" @placeholder="Torque" />
|
|
360
|
+
</InputGroup>
|
|
361
|
+
|
|
362
|
+
<InputGroup @value={{@resource.torque_rpm}} @name="Torque RPM" @type="number" @placeholder="RPM at Max Torque" />
|
|
363
|
+
|
|
364
|
+
{{! Capacity & Dimensions }}
|
|
365
|
+
<div class="col-span-1 lg:col-span-2 text-[11px] uppercase tracking-wide text-gray-500 font-semibold mt-3">
|
|
366
|
+
Capacity & Dimensions
|
|
367
|
+
</div>
|
|
368
|
+
|
|
369
|
+
<div class="grid grid-cols-1 lg:grid-cols-3 col-span-1 lg:col-span-2 gap-2">
|
|
370
|
+
<InputGroup @name="Fuel Capacity">
|
|
371
|
+
<UnitInput class="w-full" @value={{@resource.fuel_capacity}} @unit="L" @placeholder="Fuel Tank Capacity" />
|
|
372
|
+
</InputGroup>
|
|
373
|
+
|
|
374
|
+
<InputGroup @name="Payload Capacity">
|
|
375
|
+
<UnitInput class="w-full" @value={{@resource.payload_capacity}} @unit="kg" @placeholder="Maximum Payload" />
|
|
376
|
+
</InputGroup>
|
|
377
|
+
|
|
378
|
+
<InputGroup @name="Towing Capacity">
|
|
379
|
+
<UnitInput class="w-full" @value={{@resource.towing_capacity}} @unit="kg" @placeholder="Towing Capacity" />
|
|
380
|
+
</InputGroup>
|
|
381
|
+
|
|
382
|
+
<InputGroup @name="Seating Capacity">
|
|
383
|
+
<Input @value={{@resource.seating_capacity}} @type="number" class="form-input w-full" placeholder="Number of Seats" />
|
|
384
|
+
</InputGroup>
|
|
385
|
+
|
|
386
|
+
<InputGroup @name="Vehicle Weight">
|
|
387
|
+
<UnitInput class="w-full" @value={{@resource.weight}} @unit="kg" @placeholder="Vehicle Weight" />
|
|
388
|
+
</InputGroup>
|
|
389
|
+
|
|
390
|
+
<InputGroup @name="Length">
|
|
391
|
+
<UnitInput class="w-full" @value={{@resource.length}} @unit="cm" @placeholder="Length" />
|
|
392
|
+
</InputGroup>
|
|
393
|
+
|
|
394
|
+
<InputGroup @name="Width">
|
|
395
|
+
<UnitInput class="w-full" @value={{@resource.width}} @unit="cm" @placeholder="Width" />
|
|
396
|
+
</InputGroup>
|
|
397
|
+
|
|
398
|
+
<InputGroup @name="Height">
|
|
399
|
+
<UnitInput class="w-full" @value={{@resource.height}} @unit="cm" @placeholder="Height" />
|
|
400
|
+
</InputGroup>
|
|
401
|
+
|
|
402
|
+
<InputGroup @name="Cargo Volume">
|
|
403
|
+
<UnitInput class="w-full" @value={{@resource.cargo_volume}} @unit="L" @placeholder="Cargo Volume" />
|
|
404
|
+
</InputGroup>
|
|
405
|
+
|
|
406
|
+
<InputGroup @name="Passenger Volume">
|
|
407
|
+
<UnitInput class="w-full" @value={{@resource.passenger_volume}} @unit="L" @placeholder="Passenger Volume" />
|
|
408
|
+
</InputGroup>
|
|
409
|
+
|
|
410
|
+
<InputGroup @name="Interior Volume">
|
|
411
|
+
<UnitInput class="w-full" @value={{@resource.interior_volume}} @unit="L" @placeholder="Interior Volume" />
|
|
412
|
+
</InputGroup>
|
|
413
|
+
|
|
414
|
+
<InputGroup @name="Ground Clearance">
|
|
415
|
+
<UnitInput class="w-full" @value={{@resource.ground_clearance}} @unit="cm" @placeholder="Ground Clearance" />
|
|
416
|
+
</InputGroup>
|
|
417
|
+
|
|
418
|
+
<InputGroup @name="Bed Length">
|
|
419
|
+
<UnitInput class="w-full" @value={{@resource.bed_length}} @unit="cm" @placeholder="Bed Length" />
|
|
420
|
+
</InputGroup>
|
|
421
|
+
</div>
|
|
422
|
+
|
|
423
|
+
{{! Regulatory & Compliance }}
|
|
424
|
+
<div class="col-span-1 lg:col-span-2 text-[11px] uppercase tracking-wide text-gray-500 font-semibold mt-3">
|
|
425
|
+
Regulatory & Compliance
|
|
426
|
+
</div>
|
|
427
|
+
|
|
428
|
+
<InputGroup @value={{@resource.emission_standard}} @name="Emission Standard" @placeholder="e.g., Euro 6, EPA Tier 3" />
|
|
429
|
+
|
|
430
|
+
<div></div>
|
|
431
|
+
|
|
432
|
+
<InputGroup @name="GVWR (Gross Vehicle Weight Rating)">
|
|
433
|
+
<UnitInput class="w-full" @value={{@resource.gvwr}} @unit="kg" @placeholder="GVWR" />
|
|
434
|
+
</InputGroup>
|
|
435
|
+
|
|
436
|
+
<InputGroup @name="GCWR (Gross Combined Weight Rating)">
|
|
437
|
+
<UnitInput class="w-full" @value={{@resource.gcwr}} @unit="kg" @placeholder="GCWR" />
|
|
438
|
+
</InputGroup>
|
|
439
|
+
|
|
440
|
+
<InputGroup @wrapperClass="mt-1 space-y-2">
|
|
441
|
+
<Checkbox @value={{@resource.dpf_equipped}} @label="DPF Equipped" @onToggle={{fn (mut @resource.dpf_equipped)}} />
|
|
442
|
+
<Checkbox @value={{@resource.scr_equipped}} @label="SCR Equipped" @onToggle={{fn (mut @resource.scr_equipped)}} />
|
|
443
|
+
</InputGroup>
|
|
444
|
+
</div>
|
|
445
|
+
</ContentPanel>
|
|
446
|
+
|
|
447
|
+
{{! FINANCIAL & LIFECYCLE }}
|
|
448
|
+
<ContentPanel @title="Financial & Lifecycle" @open={{true}} @wrapperClass="bordered-top">
|
|
449
|
+
<div class="grid grid-cols-1 gap-2 lg:grid-cols-2 lg:gap-2 no-input-group-padding text-xs">
|
|
450
|
+
<div class="col-span-1 lg:col-span-2 text-[11px] uppercase tracking-wide text-gray-500 font-semibold mt-1">
|
|
451
|
+
Asset Values
|
|
452
|
+
</div>
|
|
453
|
+
|
|
454
|
+
<InputGroup @name="Currency" @value={{@resource.currency}}>
|
|
455
|
+
<CurrencySelect @currency={{@resource.currency}} @onCurrencyChange={{fn (mut @resource.currency)}} @triggerClass="w-full form-select" />
|
|
456
|
+
</InputGroup>
|
|
457
|
+
<div></div>
|
|
458
|
+
|
|
459
|
+
<InputGroup @name="Acquisition Cost">
|
|
460
|
+
<MoneyInput @value={{@resource.acquisition_cost}} @currency={{@resource.currency}} />
|
|
461
|
+
</InputGroup>
|
|
462
|
+
|
|
463
|
+
<InputGroup @name="Current Value">
|
|
464
|
+
<MoneyInput @value={{@resource.current_value}} @currency={{@resource.currency}} />
|
|
465
|
+
</InputGroup>
|
|
466
|
+
|
|
467
|
+
<InputGroup @name="Insurance Value">
|
|
468
|
+
<MoneyInput @value={{@resource.insurance_value}} @currency={{@resource.currency}} />
|
|
469
|
+
</InputGroup>
|
|
470
|
+
|
|
471
|
+
<InputGroup @name="Depreciation Rate (%)">
|
|
472
|
+
<Input @value={{@resource.depreciation_rate}} @type="number" step="0.01" class="form-input w-full" />
|
|
473
|
+
</InputGroup>
|
|
474
|
+
|
|
475
|
+
<div class="col-span-1 lg:col-span-2 text-[11px] uppercase tracking-wide text-gray-500 font-semibold mt-3">
|
|
476
|
+
Lifecycle & Service Life
|
|
477
|
+
</div>
|
|
478
|
+
|
|
479
|
+
<InputGroup @name="Estimated Service Life (Distance)">
|
|
480
|
+
<Input @value={{@resource.estimated_service_life_distance}} @type="number" class="form-input w-full" placeholder="Total distance" />
|
|
481
|
+
</InputGroup>
|
|
482
|
+
|
|
483
|
+
<InputGroup @name="Service Life Distance Unit">
|
|
484
|
+
<div class="fleetbase-model-select fleetbase-power-select ember-model-select">
|
|
485
|
+
<PowerSelect
|
|
486
|
+
@options={{get-fleet-ops-options "odometerUnits"}}
|
|
487
|
+
@selected={{find-by "value" @resource.estimated_service_life_distance_unit (get-fleet-ops-options "odometerUnits")}}
|
|
488
|
+
@onChange={{set-model-attr @resource "estimated_service_life_distance_unit"}}
|
|
489
|
+
@placeholder="Select unit"
|
|
490
|
+
@triggerClass="form-select form-input"
|
|
491
|
+
@disabled={{cannot-write @resource}}
|
|
492
|
+
as |option|
|
|
493
|
+
>
|
|
494
|
+
<div class="text-sm">
|
|
495
|
+
<div class="font-semibold normalize-in-trigger">{{option.label}}</div>
|
|
496
|
+
<div class="hide-from-trigger">{{option.description}}</div>
|
|
497
|
+
</div>
|
|
498
|
+
</PowerSelect>
|
|
499
|
+
</div>
|
|
500
|
+
</InputGroup>
|
|
501
|
+
|
|
502
|
+
<InputGroup @name="Estimated Service Life (Months)">
|
|
503
|
+
<Input @value={{@resource.estimated_service_life_months}} @type="number" class="form-input w-full" />
|
|
504
|
+
</InputGroup>
|
|
505
|
+
|
|
506
|
+
<InputGroup @name="Purchase Date">
|
|
507
|
+
<DatePicker
|
|
508
|
+
@value={{or (format-date-fns @resource.purchased_at "dd-MM-yyyy") null}}
|
|
509
|
+
@onChange={{fn (mut @resource.purchased_at)}}
|
|
510
|
+
@placeholder="DD-MM-YYYY"
|
|
511
|
+
class="filter-date-input w-full flex-1"
|
|
512
|
+
/>
|
|
513
|
+
</InputGroup>
|
|
514
|
+
|
|
515
|
+
<InputGroup @name="Lease Expiry Date">
|
|
516
|
+
<DatePicker
|
|
517
|
+
@value={{or (format-date-fns @resource.lease_expires_at "dd-MM-yyyy") null}}
|
|
518
|
+
@onChange={{fn (mut @resource.lease_expires_at)}}
|
|
519
|
+
@placeholder="DD-MM-YYYY"
|
|
520
|
+
class="filter-date-input w-full flex-1"
|
|
521
|
+
/>
|
|
522
|
+
</InputGroup>
|
|
523
|
+
|
|
524
|
+
<div class="col-span-1 lg:col-span-2 text-[11px] uppercase tracking-wide text-gray-500 font-semibold mt-3">
|
|
525
|
+
Financing (Loan)
|
|
526
|
+
</div>
|
|
527
|
+
|
|
528
|
+
<InputGroup @name="Loan Amount">
|
|
529
|
+
<MoneyInput @value={{@resource.loan_amount}} @currency={{@resource.currency}} />
|
|
530
|
+
</InputGroup>
|
|
531
|
+
|
|
532
|
+
<InputGroup @value={{@resource.loan_number_of_payments}} @name="Number of Payments" @type="number" @placeholder="Number of payments" />
|
|
533
|
+
|
|
534
|
+
<InputGroup @name="First Payment Date">
|
|
535
|
+
<DatePicker
|
|
536
|
+
@value={{or (format-date-fns @resource.loan_first_payment "dd-MM-yyyy") null}}
|
|
537
|
+
@onChange={{fn (mut @resource.loan_first_payment)}}
|
|
538
|
+
@placeholder="DD-MM-YYYY"
|
|
539
|
+
class="filter-date-input w-full flex-1"
|
|
540
|
+
/>
|
|
541
|
+
</InputGroup>
|
|
542
|
+
</div>
|
|
543
|
+
</ContentPanel>
|
|
544
|
+
|
|
545
|
+
{{! CUSTOM FIELDS, REGISTRY, AVATAR, METADATA }}
|
|
120
546
|
<CustomField::Yield @subject={{@resource}} @wrapperClass="bordered-top" />
|
|
121
547
|
|
|
122
548
|
<RegistryYield @registry="fleet-ops:component:vehicle:form" as |RegistryComponent|>
|
|
@@ -46,6 +46,7 @@ export default class AnalyticsReportsIndexController extends Controller {
|
|
|
46
46
|
get columns() {
|
|
47
47
|
return [
|
|
48
48
|
{
|
|
49
|
+
sticky: true,
|
|
49
50
|
label: 'Title',
|
|
50
51
|
valuePath: 'title',
|
|
51
52
|
cellComponent: 'table/cell/anchor',
|
|
@@ -58,7 +59,6 @@ export default class AnalyticsReportsIndexController extends Controller {
|
|
|
58
59
|
{
|
|
59
60
|
label: 'ID',
|
|
60
61
|
valuePath: 'public_id',
|
|
61
|
-
width: '130px',
|
|
62
62
|
cellComponent: 'click-to-copy',
|
|
63
63
|
resizable: true,
|
|
64
64
|
sortable: true,
|
|
@@ -75,7 +75,8 @@ export default class AnalyticsReportsIndexController extends Controller {
|
|
|
75
75
|
ddMenuLabel: this.intl.t('common.resource-actions', { resource: this.intl.t('resource.Driver') }),
|
|
76
76
|
cellClassNames: 'overflow-visible',
|
|
77
77
|
wrapperClass: 'flex items-center justify-end mx-2',
|
|
78
|
-
|
|
78
|
+
sticky: 'right',
|
|
79
|
+
width: 60,
|
|
79
80
|
actions: [
|
|
80
81
|
{
|
|
81
82
|
label: 'View report...',
|
|
@@ -56,6 +56,7 @@ export default class ConnectivityDevicesIndexController extends Controller {
|
|
|
56
56
|
/** columns */
|
|
57
57
|
@tracked columns = [
|
|
58
58
|
{
|
|
59
|
+
sticky: true,
|
|
59
60
|
label: this.intl.t('column.name'),
|
|
60
61
|
valuePath: 'displayName',
|
|
61
62
|
cellComponent: 'table/cell/anchor',
|
|
@@ -104,7 +105,6 @@ export default class ConnectivityDevicesIndexController extends Controller {
|
|
|
104
105
|
label: this.intl.t('column.status'),
|
|
105
106
|
valuePath: 'status',
|
|
106
107
|
cellComponent: 'table/cell/status',
|
|
107
|
-
width: '10%',
|
|
108
108
|
resizable: true,
|
|
109
109
|
sortable: true,
|
|
110
110
|
filterable: true,
|
|
@@ -124,7 +124,6 @@ export default class ConnectivityDevicesIndexController extends Controller {
|
|
|
124
124
|
label: this.intl.t('column.updated-at'),
|
|
125
125
|
valuePath: 'updatedAt',
|
|
126
126
|
sortParam: 'updated_at',
|
|
127
|
-
width: '10%',
|
|
128
127
|
resizable: true,
|
|
129
128
|
sortable: true,
|
|
130
129
|
hidden: true,
|
|
@@ -141,7 +140,8 @@ export default class ConnectivityDevicesIndexController extends Controller {
|
|
|
141
140
|
ddMenuLabel: this.intl.t('common.resource-actions', { resource: this.intl.t('resource.device') }),
|
|
142
141
|
cellClassNames: 'overflow-visible',
|
|
143
142
|
wrapperClass: 'flex items-center justify-end mx-2',
|
|
144
|
-
|
|
143
|
+
sticky: 'right',
|
|
144
|
+
width: 60,
|
|
145
145
|
actions: [
|
|
146
146
|
{
|
|
147
147
|
label: this.intl.t('common.view-resource', { resource: this.intl.t('resource.device') }),
|
|
@@ -30,6 +30,7 @@ export default class ConnectivityEventsIndexController extends Controller {
|
|
|
30
30
|
/** columns */
|
|
31
31
|
@tracked columns = [
|
|
32
32
|
{
|
|
33
|
+
sticky: true,
|
|
33
34
|
label: 'Event',
|
|
34
35
|
valuePath: 'event_type',
|
|
35
36
|
cellComponent: 'table/cell/anchor',
|
|
@@ -107,7 +108,6 @@ export default class ConnectivityEventsIndexController extends Controller {
|
|
|
107
108
|
label: this.intl.t('column.created-at'),
|
|
108
109
|
valuePath: 'createdAt',
|
|
109
110
|
sortParam: 'created_at',
|
|
110
|
-
width: '10%',
|
|
111
111
|
resizable: true,
|
|
112
112
|
sortable: true,
|
|
113
113
|
filterable: true,
|
|
@@ -122,7 +122,8 @@ export default class ConnectivityEventsIndexController extends Controller {
|
|
|
122
122
|
ddMenuLabel: this.intl.t('common.resource-actions', { resource: this.intl.t('resource.device-event') }),
|
|
123
123
|
cellClassNames: 'overflow-visible',
|
|
124
124
|
wrapperClass: 'flex items-center justify-end mx-2',
|
|
125
|
-
|
|
125
|
+
sticky: 'right',
|
|
126
|
+
width: 60,
|
|
126
127
|
actions: [
|
|
127
128
|
{
|
|
128
129
|
label: this.intl.t('common.view-resource', { resource: this.intl.t('resource.device-event') }),
|