@fleetbase/fleetops-engine 0.6.63 → 0.6.65
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/RELEASE.md +7 -6
- package/addon/components/attachment-list.hbs +65 -0
- package/addon/components/attachment-list.js +8 -0
- package/addon/components/cell/attached-vehicle.hbs +1 -1
- package/addon/components/cell/attached-vehicle.js +3 -3
- package/addon/components/cell/driver-identity.js +4 -4
- package/addon/components/cell/driver-name.hbs +1 -1
- package/addon/components/cell/translated-value.hbs +9 -0
- package/addon/components/cell/translated-value.js +57 -0
- package/addon/components/contact/card.hbs +58 -0
- package/addon/components/contact/card.js +19 -0
- package/addon/components/contact/form.hbs +1 -1
- package/addon/components/contact/panel-header.hbs +1 -1
- package/addon/components/customer/form.hbs +2 -2
- package/addon/components/device/manager.hbs +26 -28
- package/addon/components/device/manager.js +28 -2
- package/addon/components/device/panel-tabs/vehicle.hbs +13 -13
- package/addon/components/device/panel-tabs/vehicle.js +8 -0
- package/addon/components/driver/card.hbs +24 -13
- package/addon/components/driver/card.js +20 -6
- package/addon/components/driver/form.hbs +3 -3
- package/addon/components/driver/panel-header.hbs +2 -2
- package/addon/components/driver/pill.hbs +2 -2
- package/addon/components/equipment/form.js +11 -4
- package/addon/components/equipment/pill.hbs +20 -0
- package/addon/components/equipment/pill.js +3 -0
- package/addon/components/filter/multi-model.hbs +19 -0
- package/addon/components/filter/multi-model.js +90 -0
- package/addon/components/fleet/driver-listing.hbs +1 -1
- package/addon/components/fleet/vehicle-listing.hbs +1 -1
- package/addon/components/fleet-panel/driver-listing.hbs +1 -1
- package/addon/components/fleet-panel/vehicle-listing.hbs +1 -1
- package/addon/components/layout/fleet-ops-sidebar.js +9 -7
- package/addon/components/maintenance/form.js +12 -4
- package/addon/components/maintenance-schedule/form.js +13 -7
- package/addon/components/map/leaflet-live-map.hbs +52 -0
- package/addon/components/map/order-list-overlay/order.hbs +4 -4
- package/addon/components/modals/attach-equipment.hbs +22 -0
- package/addon/components/modals/attach-equipment.js +3 -0
- package/addon/components/modals/attach-telematic-device.hbs +13 -8
- package/addon/components/modals/attach-telematic-device.js +11 -1
- package/addon/components/modals/attach-trailer.hbs +30 -0
- package/addon/components/modals/attach-trailer.js +3 -0
- package/addon/components/modals/contact-form.hbs +2 -2
- package/addon/components/modals/convert-customer-to-vendor.hbs +1 -1
- package/addon/components/modals/driver-form.hbs +2 -2
- package/addon/components/modals/select-trailer.hbs +35 -0
- package/addon/components/modals/select-trailer.js +3 -0
- package/addon/components/modals/vehicle-form.hbs +2 -2
- package/addon/components/orchestrator/resource-panel.hbs +2 -2
- package/addon/components/order/customer-avatar-stack.hbs +2 -2
- package/addon/components/order/details/detail.hbs +4 -4
- package/addon/components/order/details/payload.hbs +2 -2
- package/addon/components/order/kanban-card.hbs +4 -4
- package/addon/components/order-list-overlay/order.hbs +4 -4
- package/addon/components/trailer/card.hbs +68 -0
- package/addon/components/trailer/card.js +22 -0
- package/addon/components/trailer/details/connections.hbs +57 -0
- package/addon/components/trailer/details/connections.js +59 -0
- package/addon/components/trailer/details/equipment.hbs +25 -0
- package/addon/components/trailer/details/equipment.js +52 -0
- package/addon/components/trailer/details/maintenance-history.hbs +47 -0
- package/addon/components/trailer/details/maintenance-history.js +40 -0
- package/addon/components/trailer/details/schedules.hbs +45 -0
- package/addon/components/trailer/details/schedules.js +40 -0
- package/addon/components/trailer/details/work-orders.hbs +47 -0
- package/addon/components/trailer/details/work-orders.js +40 -0
- package/addon/components/trailer/details.hbs +399 -0
- package/addon/components/trailer/details.js +118 -0
- package/addon/components/trailer/form.hbs +447 -0
- package/addon/components/trailer/form.js +165 -0
- package/addon/components/trailer/panel-header.hbs +45 -0
- package/addon/components/trailer/panel-header.js +3 -0
- package/addon/components/trailer/pill.hbs +21 -0
- package/addon/components/trailer/pill.js +3 -0
- package/addon/components/vehicle/card.hbs +42 -11
- package/addon/components/vehicle/card.js +31 -0
- package/addon/components/vehicle/details/equipment.hbs +25 -0
- package/addon/components/vehicle/details/equipment.js +55 -0
- package/addon/components/vehicle/details/trailers.hbs +35 -0
- package/addon/components/vehicle/details/trailers.js +55 -0
- package/addon/components/vehicle/form.hbs +2 -2
- package/addon/components/vehicle/panel-header.hbs +2 -2
- package/addon/components/vehicle/pill.hbs +2 -2
- package/addon/components/vendor/card.hbs +58 -0
- package/addon/components/vendor/card.js +6 -0
- package/addon/components/vendor/panel-header.hbs +2 -2
- package/addon/components/vendor/personnel-manager.hbs +2 -2
- package/addon/components/work-order/form.js +12 -4
- package/addon/controllers/connectivity/devices/index/details/vehicle.js +11 -0
- package/addon/controllers/connectivity/devices/index/details.js +3 -3
- package/addon/controllers/connectivity/devices/index.js +1 -0
- package/addon/controllers/connectivity/telematics/details/attachments.js +28 -47
- package/addon/controllers/connectivity/telematics/details/devices.js +1 -0
- package/addon/controllers/management/contacts/customers.js +4 -0
- package/addon/controllers/management/contacts/index.js +32 -0
- package/addon/controllers/management/trailers/index/details.js +119 -0
- package/addon/controllers/management/trailers/index/edit.js +67 -0
- package/addon/controllers/management/trailers/index/new.js +43 -0
- package/addon/controllers/management/trailers/index.js +599 -0
- package/addon/controllers/management/vehicles/index/details.js +16 -0
- package/addon/controllers/management/vehicles/index.js +78 -4
- package/addon/controllers/management/vendors/index.js +32 -0
- package/addon/controllers/operations/orders/index.js +3 -1
- package/addon/controllers/settings/custom-fields.js +8 -0
- package/addon/extension.js +7 -0
- package/addon/helpers/placeholder-image.js +6 -0
- package/addon/helpers/resource-image.js +10 -0
- package/addon/helpers/trailer-placeholder-image.js +6 -0
- package/addon/routes/management/trailers/index/details/connections.js +2 -0
- package/addon/routes/management/trailers/index/details/devices.js +2 -0
- package/addon/routes/management/trailers/index/details/equipment.js +2 -0
- package/addon/routes/management/trailers/index/details/index.js +2 -0
- package/addon/routes/management/trailers/index/details/maintenance-history.js +2 -0
- package/addon/routes/management/trailers/index/details/positions.js +2 -0
- package/addon/routes/management/trailers/index/details/schedules.js +2 -0
- package/addon/routes/management/trailers/index/details/work-orders.js +2 -0
- package/addon/routes/management/trailers/index/details.js +30 -0
- package/addon/routes/management/trailers/index/edit.js +23 -0
- package/addon/routes/management/trailers/index/new.js +14 -0
- package/addon/routes/management/trailers/index.js +42 -0
- package/addon/routes/management/vehicles/index/details/trailers.js +2 -0
- package/addon/routes/management/vehicles/index.js +7 -1
- package/addon/routes.js +17 -0
- package/addon/services/device-actions.js +26 -16
- package/addon/services/trailer-actions.js +394 -0
- package/addon/services/vehicle-actions.js +111 -0
- package/addon/styles/fleetops-engine.css +349 -0
- package/addon/templates/connectivity/devices/index/details/vehicle.hbs +19 -19
- package/addon/templates/connectivity/telematics/details/attachments.hbs +15 -15
- package/addon/templates/management/contacts/customers.hbs +48 -29
- package/addon/templates/management/contacts/index.hbs +52 -33
- package/addon/templates/management/trailers/index/details/connections.hbs +1 -0
- package/addon/templates/management/trailers/index/details/devices.hbs +1 -0
- package/addon/templates/management/trailers/index/details/equipment.hbs +1 -0
- package/addon/templates/management/trailers/index/details/index.hbs +1 -0
- package/addon/templates/management/trailers/index/details/maintenance-history.hbs +1 -0
- package/addon/templates/management/trailers/index/details/positions.hbs +1 -0
- package/addon/templates/management/trailers/index/details/schedules.hbs +1 -0
- package/addon/templates/management/trailers/index/details/work-orders.hbs +1 -0
- package/addon/templates/management/trailers/index/details.hbs +15 -0
- package/addon/templates/management/trailers/index/edit.hbs +12 -0
- package/addon/templates/management/trailers/index/new.hbs +11 -0
- package/addon/templates/management/trailers/index.hbs +67 -0
- package/addon/templates/management/vehicles/index/details/equipment.hbs +1 -1
- package/addon/templates/management/vehicles/index/details/trailers.hbs +1 -0
- package/addon/templates/management/vehicles/index/details.hbs +1 -1
- package/addon/templates/management/vendors/index.hbs +66 -32
- package/addon/utils/device-table-columns.js +10 -6
- package/addon/utils/live-map-card-content.js +56 -0
- package/addon/utils/placeholder-images.js +71 -0
- package/addon/utils/trailer-placeholder-image.js +11 -0
- package/app/components/attachment-list.js +1 -0
- package/app/components/cell/translated-value.js +1 -0
- package/app/components/contact/card.js +1 -0
- package/app/components/equipment/pill.js +1 -0
- package/app/components/filter/multi-model.js +1 -0
- package/app/components/modals/attach-equipment.js +1 -0
- package/app/components/modals/attach-trailer.js +1 -0
- package/app/components/modals/select-trailer.js +1 -0
- package/app/components/trailer/card.js +1 -0
- package/app/components/trailer/details/connections.js +1 -0
- package/app/components/trailer/details/equipment.js +1 -0
- package/app/components/trailer/details/maintenance-history.js +1 -0
- package/app/components/trailer/details/schedules.js +1 -0
- package/app/components/trailer/details/work-orders.js +1 -0
- package/app/components/trailer/details.js +1 -0
- package/app/components/trailer/form.js +1 -0
- package/app/components/trailer/panel-header.js +1 -0
- package/app/components/trailer/pill.js +1 -0
- package/app/components/vehicle/details/equipment.js +1 -0
- package/app/components/vehicle/details/trailers.js +1 -0
- package/app/components/vendor/card.js +1 -0
- package/app/controllers/management/trailers/index/details.js +1 -0
- package/app/controllers/management/trailers/index/edit.js +1 -0
- package/app/controllers/management/trailers/index/new.js +1 -0
- package/app/controllers/management/trailers/index.js +1 -0
- package/app/helpers/placeholder-image.js +1 -0
- package/app/helpers/resource-image.js +1 -0
- package/app/helpers/trailer-placeholder-image.js +1 -0
- package/app/routes/management/trailers/index/details/connections.js +1 -0
- package/app/routes/management/trailers/index/details/devices.js +1 -0
- package/app/routes/management/trailers/index/details/equipment.js +1 -0
- package/app/routes/management/trailers/index/details/index.js +1 -0
- package/app/routes/management/trailers/index/details/maintenance-history.js +1 -0
- package/app/routes/management/trailers/index/details/positions.js +1 -0
- package/app/routes/management/trailers/index/details/schedules.js +1 -0
- package/app/routes/management/trailers/index/details/work-orders.js +1 -0
- package/app/routes/management/trailers/index/details.js +1 -0
- package/app/routes/management/trailers/index/edit.js +1 -0
- package/app/routes/management/trailers/index/new.js +1 -0
- package/app/routes/management/trailers/index.js +1 -0
- package/app/routes/management/vehicles/index/details/trailers.js +1 -0
- package/app/services/trailer-actions.js +1 -0
- package/app/templates/management/trailers/index/details/connections.js +1 -0
- package/app/templates/management/trailers/index/details/devices.js +1 -0
- package/app/templates/management/trailers/index/details/equipment.js +1 -0
- package/app/templates/management/trailers/index/details/index.js +1 -0
- package/app/templates/management/trailers/index/details/maintenance-history.js +1 -0
- package/app/templates/management/trailers/index/details/positions.js +1 -0
- package/app/templates/management/trailers/index/details/schedules.js +1 -0
- package/app/templates/management/trailers/index/details/work-orders.js +1 -0
- package/app/templates/management/trailers/index/details.js +1 -0
- package/app/templates/management/trailers/index/edit.js +1 -0
- package/app/templates/management/trailers/index/new.js +1 -0
- package/app/templates/management/trailers/index.js +1 -0
- package/app/templates/management/vehicles/index/details/trailers.js +1 -0
- package/composer.json +1 -1
- package/extension.json +1 -1
- package/package.json +1 -1
- package/server/migrations/2026_09_03_000001_add_first_class_trailer_columns_to_assets_table.php +58 -0
- package/server/migrations/2026_09_03_000002_create_asset_connections_table.php +43 -0
- package/server/migrations/2026_09_03_000003_create_device_installations_table.php +33 -0
- package/server/src/Auth/Schemas/FleetOps.php +7 -0
- package/server/src/Events/TrailerLocationChanged.php +70 -0
- package/server/src/Exceptions/DeviceAlreadyAttachedException.php +18 -0
- package/server/src/Exports/TrailerExport.php +31 -0
- package/server/src/Http/Controllers/Api/v1/Concerns/ResolvesFleetOpsApiResources.php +8 -2
- package/server/src/Http/Controllers/Api/v1/DeviceController.php +22 -15
- package/server/src/Http/Controllers/Api/v1/EquipmentController.php +47 -0
- package/server/src/Http/Controllers/Api/v1/TrailerController.php +362 -0
- package/server/src/Http/Controllers/Api/v1/VehicleController.php +1 -0
- package/server/src/Http/Controllers/Internal/v1/DeviceController.php +3 -0
- package/server/src/Http/Controllers/Internal/v1/LiveController.php +1 -1
- package/server/src/Http/Controllers/Internal/v1/SearchController.php +16 -0
- package/server/src/Http/Controllers/Internal/v1/TrailerController.php +360 -0
- package/server/src/Http/Controllers/Internal/v1/VehicleController.php +74 -0
- package/server/src/Http/Filter/EquipmentFilter.php +51 -0
- package/server/src/Http/Filter/OrderFilter.php +15 -0
- package/server/src/Http/Filter/TrailerFilter.php +269 -0
- package/server/src/Http/Filter/VehicleFilter.php +70 -3
- package/server/src/Http/Requests/CreateDeviceRequest.php +1 -1
- package/server/src/Http/Requests/CreateEquipmentRequest.php +1 -1
- package/server/src/Http/Requests/CreateTrailerRequest.php +54 -0
- package/server/src/Http/Requests/UpdateTrailerRequest.php +7 -0
- package/server/src/Http/Resources/v1/AssetConnection.php +90 -0
- package/server/src/Http/Resources/v1/Concerns/ResolvesPublicRelationFields.php +29 -3
- package/server/src/Http/Resources/v1/Device.php +3 -1
- package/server/src/Http/Resources/v1/Equipment.php +3 -1
- package/server/src/Http/Resources/v1/Fleet.php +3 -1
- package/server/src/Http/Resources/v1/Index/Vehicle.php +10 -0
- package/server/src/Http/Resources/v1/Trailer.php +199 -0
- package/server/src/Http/Resources/v1/Vehicle.php +2 -0
- package/server/src/Http/Resources/v1/VehicleWithoutDriver.php +3 -0
- package/server/src/Imports/TrailerImport.php +33 -0
- package/server/src/Models/Asset.php +39 -10
- package/server/src/Models/AssetConnection.php +43 -0
- package/server/src/Models/Device.php +39 -8
- package/server/src/Models/DeviceInstallation.php +27 -0
- package/server/src/Models/Equipment.php +2 -0
- package/server/src/Models/Trailer.php +181 -0
- package/server/src/Models/Vehicle.php +13 -0
- package/server/src/Providers/FleetOpsServiceProvider.php +4 -2
- package/server/src/Support/Ai/FleetOpsAiQueryResources.php +22 -0
- package/server/src/Support/Reporting/FleetOpsReportSchema.php +38 -0
- package/server/src/Support/Telematics/TelematicService.php +35 -0
- package/server/src/Support/TrailerSummary.php +35 -0
- package/server/src/routes.php +29 -0
- package/server/tests/CompactResourceSerializationTest.php +36 -0
- package/server/tests/ControllerFilterContractsTest.php +29 -0
- package/server/tests/Feature/Http/Api/DeviceControllerContractsTest.php +30 -13
- package/server/tests/Feature/Http/Api/TrailerControllerLifecycleTest.php +640 -0
- package/server/tests/Feature/Http/Api/VehiclePublicContractTest.php +23 -0
- package/server/tests/Feature/Http/Internal/DeviceControllerContractsTest.php +20 -5
- package/server/tests/Feature/Http/Internal/LiveControllerEndpointsTest.php +19 -0
- package/server/tests/ModelAccessorContractsTest.php +10 -0
- package/server/tests/OrderFilterExecutionTest.php +5 -0
- package/server/tests/PublicApiControllerInputContractsTest.php +11 -0
- package/server/tests/PublicFleetOpsRestEndpointsTest.php +15 -3
- package/server/tests/ReportSchemaContractsTest.php +4 -0
- package/server/tests/TelematicsHardeningTest.php +4 -2
- package/server/tests/TrailerSupportCoverageTest.php +524 -0
- package/server/tests/Unit/Http/Resources/FleetResourceTest.php +17 -0
- package/server/tests/Unit/Http/Resources/IndexVehicleResourceTest.php +35 -0
- package/server/tests/Unit/Models/EquipmentTest.php +22 -0
- package/server/tests/Unit/Models/ModelLookupFallbackSeamsTest.php +7 -3
- package/server/tests/Unit/Models/TrailerTest.php +204 -0
- package/server/tests/Unit/Support/Telematics/TelematicServiceTelemetryTest.php +93 -0
- package/server/tests/VehicleControllerHelperContractsTest.php +14 -0
- package/server/tests/VehicleResourceContractsTest.php +39 -0
- package/translations/ar-ae.yml +396 -0
- package/translations/bg-bg.yaml +424 -0
- package/translations/en-us.yaml +423 -0
- package/translations/es-pa.yaml +425 -0
- package/translations/fr-fr.yaml +424 -0
- package/translations/mn-mn.yaml +424 -0
- package/translations/pt-br.yaml +424 -0
- package/translations/ru-ru.yaml +424 -0
- package/translations/vi-vn.yaml +435 -0
|
@@ -1,34 +1,53 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
1
|
+
{{#if (eq this.layout "table")}}
|
|
2
|
+
<Layout::Resource::Tabular
|
|
3
|
+
@resource="contact"
|
|
4
|
+
@title={{t "resource.contacts"}}
|
|
5
|
+
@searchQuery={{this.query}}
|
|
6
|
+
@onSearch={{perform this.contactActions.controllerSearchTask this}}
|
|
7
|
+
@data={{@model}}
|
|
8
|
+
@columns={{this.columns}}
|
|
9
|
+
@page={{this.page}}
|
|
10
|
+
@onPageChange={{fn (mut this.page)}}
|
|
11
|
+
@setupTable={{fn (mut this.table)}}
|
|
12
|
+
@actionButtons={{this.actionButtons}}
|
|
13
|
+
@bulkActions={{this.bulkActions}}
|
|
14
|
+
@controller={{this}}
|
|
15
|
+
@emptyStateComponent={{component
|
|
16
|
+
"table/empty-state"
|
|
17
|
+
icon="address-book"
|
|
18
|
+
title="Add your first contact"
|
|
19
|
+
description="Contacts keep customer, vendor, and internal stakeholder details ready for orders and communication."
|
|
20
|
+
filteredTitle="No contacts match your filters"
|
|
21
|
+
filteredDescription="Adjust the search or filters to find another contact."
|
|
22
|
+
primaryText="New contact"
|
|
23
|
+
primaryIcon="plus"
|
|
24
|
+
primaryAction=this.contactActions.transition.create
|
|
25
|
+
secondaryText="Import"
|
|
26
|
+
secondaryIcon="upload"
|
|
27
|
+
secondaryAction=this.contactActions.import
|
|
28
|
+
docsSlug="fleet-ops/resources/contacts/overview"
|
|
29
|
+
docsTitle="Contacts guide"
|
|
30
|
+
docsText="Contacts guide"
|
|
31
|
+
docsSource="fleet-ops-empty-contacts"
|
|
32
|
+
}}
|
|
33
|
+
@withoutHeader={{true}}
|
|
34
|
+
/>
|
|
35
|
+
{{else}}
|
|
36
|
+
<Layout::Section::Body class="overflow-y-scroll-i h-full">
|
|
37
|
+
<Layout::Resource::CardsGrid
|
|
38
|
+
@resource="contact"
|
|
39
|
+
@data={{@model}}
|
|
40
|
+
@columns="4"
|
|
41
|
+
@showPagination={{true}}
|
|
42
|
+
@page={{this.page}}
|
|
43
|
+
@onPageChange={{fn (mut this.page)}}
|
|
44
|
+
@paginationMeta={{@model.meta}}
|
|
45
|
+
@containerClass="p-4"
|
|
46
|
+
class="h-full"
|
|
47
|
+
as |Item|
|
|
48
|
+
>
|
|
49
|
+
<Contact::Card @resource={{Item.model}} />
|
|
50
|
+
</Layout::Resource::CardsGrid>
|
|
51
|
+
</Layout::Section::Body>
|
|
52
|
+
{{/if}}
|
|
34
53
|
{{outlet}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<Trailer::Details::Connections @resource={{@model}} />
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<Device::Manager @resource={{@model}} @endpoint="trailers" />
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<Trailer::Details::Equipment @resource={{@model}} />
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<Trailer::Details @resource={{@model}} />
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<Trailer::Details::MaintenanceHistory @resource={{@model}} />
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<PositionsReplay @resource={{@model}} />
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<Trailer::Details::Schedules @resource={{@model}} />
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<Trailer::Details::WorkOrders @resource={{@model}} />
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<Layout::Resource::Panel
|
|
2
|
+
@resource={{@model}}
|
|
3
|
+
@controller={{this}}
|
|
4
|
+
@headerComponent={{component "trailer/panel-header" resource=@model actionButtons=this.actionButtons}}
|
|
5
|
+
@headerTitle={{@model.displayName}}
|
|
6
|
+
@actionButtons={{this.actionButtons}}
|
|
7
|
+
@onPressCancel={{transition-to "management.trailers.index"}}
|
|
8
|
+
@onOverlayReady={{fn (mut this.overlay)}}
|
|
9
|
+
@headerClass="no-bottom-border"
|
|
10
|
+
@bodyClass="no-scroll"
|
|
11
|
+
>
|
|
12
|
+
<TabNavigation @tabs={{this.tabs}} @containerClass="tab-navigation-fill" @contentClass="scrollable" @tablistClass="pl-2">
|
|
13
|
+
{{outlet}}
|
|
14
|
+
</TabNavigation>
|
|
15
|
+
</Layout::Resource::Panel>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<Layout::Resource::Panel
|
|
2
|
+
@resource={{@model}}
|
|
3
|
+
@controller={{this}}
|
|
4
|
+
@headerTitle={{t "common.edit-resource-name" resourceName=@model.displayName}}
|
|
5
|
+
@actionButtons={{this.actionButtons}}
|
|
6
|
+
@saveTask={{this.save}}
|
|
7
|
+
@onPressCancel={{this.cancel}}
|
|
8
|
+
@onOverlayReady={{fn (mut this.overlay)}}
|
|
9
|
+
>
|
|
10
|
+
<Trailer::Form @resource={{@model}} @controller={{this}} />
|
|
11
|
+
<Spacer @height="200px" />
|
|
12
|
+
</Layout::Resource::Panel>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<Layout::Resource::Panel
|
|
2
|
+
@resource={{this.trailer}}
|
|
3
|
+
@controller={{this}}
|
|
4
|
+
@headerTitle={{t "common.create-a-new-resource" resource=(t "resource.trailer")}}
|
|
5
|
+
@saveTask={{this.save}}
|
|
6
|
+
@onPressCancel={{transition-to "management.trailers.index"}}
|
|
7
|
+
@onOverlayReady={{fn (mut this.overlay)}}
|
|
8
|
+
>
|
|
9
|
+
<Trailer::Form @resource={{this.trailer}} @controller={{this}} />
|
|
10
|
+
<Spacer @height="200px" />
|
|
11
|
+
</Layout::Resource::Panel>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{{#if (eq this.layout "table")}}
|
|
2
|
+
<Layout::Resource::Tabular
|
|
3
|
+
@resource="trailer"
|
|
4
|
+
@title={{t "resource.trailers"}}
|
|
5
|
+
@searchQuery={{this.query}}
|
|
6
|
+
@onSearch={{perform this.trailerActions.controllerSearchTask this}}
|
|
7
|
+
@data={{@model}}
|
|
8
|
+
@columns={{this.columns}}
|
|
9
|
+
@page={{this.page}}
|
|
10
|
+
@onPageChange={{fn (mut this.page)}}
|
|
11
|
+
@setupTable={{fn (mut this.table)}}
|
|
12
|
+
@actionButtons={{this.actionButtons}}
|
|
13
|
+
@bulkActions={{this.bulkActions}}
|
|
14
|
+
@controller={{this}}
|
|
15
|
+
@emptyStateComponent={{component
|
|
16
|
+
"table/empty-state"
|
|
17
|
+
icon="trailer"
|
|
18
|
+
title=(t "trailer.empty.title")
|
|
19
|
+
description=(t "trailer.empty.description")
|
|
20
|
+
filteredTitle=(t "trailer.empty.filtered-title")
|
|
21
|
+
filteredDescription=(t "trailer.empty.filtered-description")
|
|
22
|
+
primaryText=(t "trailer.actions.new")
|
|
23
|
+
primaryIcon="plus"
|
|
24
|
+
primaryAction=this.trailerActions.transition.create
|
|
25
|
+
secondaryText=(t "common.import")
|
|
26
|
+
secondaryIcon="upload"
|
|
27
|
+
secondaryAction=this.trailerActions.import
|
|
28
|
+
docsSlug="fleet-ops/resources/trailers/overview"
|
|
29
|
+
docsTitle=(t "trailer.docs.title")
|
|
30
|
+
docsText=(t "trailer.docs.link")
|
|
31
|
+
docsSource="fleet-ops-empty-trailers"
|
|
32
|
+
}}
|
|
33
|
+
/>
|
|
34
|
+
{{else}}
|
|
35
|
+
<Layout::Section::Header @title={{t "resource.trailers"}} @actionsWrapperClass="space-x-1">
|
|
36
|
+
<Layout::Resource::TabularActions
|
|
37
|
+
@searchQuery={{this.query}}
|
|
38
|
+
@onSearch={{perform this.trailerActions.controllerSearchTask this}}
|
|
39
|
+
@columns={{this.columns}}
|
|
40
|
+
@page={{this.page}}
|
|
41
|
+
@onPageChange={{fn (mut this.page)}}
|
|
42
|
+
@setupTable={{fn (mut this.table)}}
|
|
43
|
+
@actionButtons={{this.actionButtons}}
|
|
44
|
+
@bulkActions={{this.bulkActions}}
|
|
45
|
+
@controller={{this}}
|
|
46
|
+
@hideColumnsPicker={{true}}
|
|
47
|
+
/>
|
|
48
|
+
</Layout::Section::Header>
|
|
49
|
+
|
|
50
|
+
<Layout::Section::Body class="overflow-y-scroll-i h-full">
|
|
51
|
+
<Layout::Resource::CardsGrid
|
|
52
|
+
@resource="trailer"
|
|
53
|
+
@data={{@model}}
|
|
54
|
+
@columns="4"
|
|
55
|
+
@showPagination={{true}}
|
|
56
|
+
@page={{this.page}}
|
|
57
|
+
@onPageChange={{fn (mut this.page)}}
|
|
58
|
+
@paginationMeta={{@model.meta}}
|
|
59
|
+
@containerClass="p-4"
|
|
60
|
+
class="h-full"
|
|
61
|
+
as |Item|
|
|
62
|
+
>
|
|
63
|
+
<Trailer::Card @resource={{Item.model}} />
|
|
64
|
+
</Layout::Resource::CardsGrid>
|
|
65
|
+
</Layout::Section::Body>
|
|
66
|
+
{{/if}}
|
|
67
|
+
{{outlet}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{{
|
|
1
|
+
<Vehicle::Details::Equipment @resource={{@model}} />
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<Vehicle::Details::Trailers @resource={{@model}} />
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
@headerClass="no-bottom-border"
|
|
10
10
|
@bodyClass="no-scroll"
|
|
11
11
|
>
|
|
12
|
-
<TabNavigation @tabs={{this.tabs}} @contentClass="scrollable" @tablistClass="pl-2">
|
|
12
|
+
<TabNavigation @tabs={{this.tabs}} @containerClass="tab-navigation-fill" @contentClass="scrollable" @tablistClass="pl-2">
|
|
13
13
|
{{outlet}}
|
|
14
14
|
</TabNavigation>
|
|
15
15
|
</Layout::Resource::Panel>
|
|
@@ -1,33 +1,67 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
1
|
+
{{#if (eq this.layout "table")}}
|
|
2
|
+
<Layout::Resource::Tabular
|
|
3
|
+
@resource="vendor"
|
|
4
|
+
@title={{t "resource.vendors"}}
|
|
5
|
+
@searchQuery={{this.query}}
|
|
6
|
+
@onSearch={{perform this.vendorActions.controllerSearchTask this}}
|
|
7
|
+
@data={{@model}}
|
|
8
|
+
@columns={{this.columns}}
|
|
9
|
+
@page={{this.page}}
|
|
10
|
+
@onPageChange={{fn (mut this.page)}}
|
|
11
|
+
@setupTable={{fn (mut this.table)}}
|
|
12
|
+
@actionButtons={{this.actionButtons}}
|
|
13
|
+
@bulkActions={{this.bulkActions}}
|
|
14
|
+
@controller={{this}}
|
|
15
|
+
@emptyStateComponent={{component
|
|
16
|
+
"table/empty-state"
|
|
17
|
+
icon="building"
|
|
18
|
+
title="Add your first vendor"
|
|
19
|
+
description="Vendors let your team manage external carriers, service providers, and operational partners."
|
|
20
|
+
filteredTitle="No vendors match your filters"
|
|
21
|
+
filteredDescription="Adjust the search or filters to find another vendor."
|
|
22
|
+
primaryText="New vendor"
|
|
23
|
+
primaryIcon="plus"
|
|
24
|
+
primaryAction=this.vendorActions.transition.create
|
|
25
|
+
secondaryText="Import"
|
|
26
|
+
secondaryIcon="upload"
|
|
27
|
+
secondaryAction=this.vendorActions.import
|
|
28
|
+
docsSlug="fleet-ops/resources/vendors/overview"
|
|
29
|
+
docsTitle="Vendors guide"
|
|
30
|
+
docsText="Vendor guide"
|
|
31
|
+
docsSource="fleet-ops-empty-vendors"
|
|
32
|
+
}}
|
|
33
|
+
/>
|
|
34
|
+
{{else}}
|
|
35
|
+
<Layout::Section::Header @title={{t "resource.vendors"}} @actionsWrapperClass="space-x-1">
|
|
36
|
+
<Layout::Resource::TabularActions
|
|
37
|
+
@searchQuery={{this.query}}
|
|
38
|
+
@onSearch={{perform this.vendorActions.controllerSearchTask this}}
|
|
39
|
+
@columns={{this.columns}}
|
|
40
|
+
@page={{this.page}}
|
|
41
|
+
@onPageChange={{fn (mut this.page)}}
|
|
42
|
+
@setupTable={{fn (mut this.table)}}
|
|
43
|
+
@actionButtons={{this.actionButtons}}
|
|
44
|
+
@bulkActions={{this.bulkActions}}
|
|
45
|
+
@controller={{this}}
|
|
46
|
+
@hideColumnsPicker={{true}}
|
|
47
|
+
/>
|
|
48
|
+
</Layout::Section::Header>
|
|
49
|
+
|
|
50
|
+
<Layout::Section::Body class="overflow-y-scroll-i h-full">
|
|
51
|
+
<Layout::Resource::CardsGrid
|
|
52
|
+
@resource="vendor"
|
|
53
|
+
@data={{@model}}
|
|
54
|
+
@columns="4"
|
|
55
|
+
@showPagination={{true}}
|
|
56
|
+
@page={{this.page}}
|
|
57
|
+
@onPageChange={{fn (mut this.page)}}
|
|
58
|
+
@paginationMeta={{@model.meta}}
|
|
59
|
+
@containerClass="p-4"
|
|
60
|
+
class="h-full"
|
|
61
|
+
as |Item|
|
|
62
|
+
>
|
|
63
|
+
<Vendor::Card @resource={{Item.model}} />
|
|
64
|
+
</Layout::Resource::CardsGrid>
|
|
65
|
+
</Layout::Section::Body>
|
|
66
|
+
{{/if}}
|
|
33
67
|
{{outlet}}
|
|
@@ -64,12 +64,16 @@ export default function buildDeviceTableColumns(controller, options = {}) {
|
|
|
64
64
|
filterComponent: 'filter/string',
|
|
65
65
|
};
|
|
66
66
|
const vehicleColumn = {
|
|
67
|
-
label: '
|
|
67
|
+
label: controller.intl?.t('device.attachment.asset') ?? 'Attached asset',
|
|
68
68
|
valuePath: 'attached_to_name',
|
|
69
69
|
cellComponent: 'cell/vehicle-identity',
|
|
70
70
|
action: async (vehicle) => {
|
|
71
71
|
const resolvedVehicle = vehicle?.loadResource ? ((await vehicle.loadResource()) ?? vehicle) : vehicle;
|
|
72
72
|
|
|
73
|
+
const type = `${vehicle?.attachable_type ?? resolvedVehicle?.constructor?.modelName ?? ''}`.toLowerCase();
|
|
74
|
+
if (type.includes('trailer') && resolvedVehicle?.id && controller.trailerActions?.transition?.view) {
|
|
75
|
+
return controller.trailerActions.transition.view(resolvedVehicle);
|
|
76
|
+
}
|
|
73
77
|
if (resolvedVehicle?.id && controller.vehicleActions?.panel?.view) {
|
|
74
78
|
return controller.vehicleActions.panel.view(resolvedVehicle);
|
|
75
79
|
}
|
|
@@ -81,7 +85,7 @@ export default function buildDeviceTableColumns(controller, options = {}) {
|
|
|
81
85
|
resourcePath: (device) => {
|
|
82
86
|
const attachableType = `${device?.attachable_type ?? ''}`.toLowerCase();
|
|
83
87
|
|
|
84
|
-
if (!device?.attachable_uuid || (attachableType && !attachableType.includes('vehicle'))) {
|
|
88
|
+
if (!device?.attachable_uuid || (attachableType && !attachableType.includes('vehicle') && !attachableType.includes('trailer'))) {
|
|
85
89
|
return null;
|
|
86
90
|
}
|
|
87
91
|
|
|
@@ -238,12 +242,12 @@ export default function buildDeviceTableColumns(controller, options = {}) {
|
|
|
238
242
|
permission: 'fleet-ops update device',
|
|
239
243
|
},
|
|
240
244
|
{
|
|
241
|
-
label: '
|
|
245
|
+
label: controller.intl.t('device.attachment.attach-or-change'),
|
|
242
246
|
fn: controller.openAttachDeviceModal ?? controller.deviceActions.attachToVehicle,
|
|
243
247
|
permission: 'fleet-ops update device',
|
|
244
248
|
},
|
|
245
249
|
{
|
|
246
|
-
label: controller.intl.t('device.
|
|
250
|
+
label: controller.intl.t('device.attachment.detach'),
|
|
247
251
|
fn: controller.deviceActions.detachFromVehicle,
|
|
248
252
|
permission: 'fleet-ops update device',
|
|
249
253
|
isVisible: controller.hasAttachedVehicle,
|
|
@@ -253,13 +257,13 @@ export default function buildDeviceTableColumns(controller, options = {}) {
|
|
|
253
257
|
isVisible: controller.hasAttachedVehicle,
|
|
254
258
|
},
|
|
255
259
|
{
|
|
256
|
-
label: '
|
|
260
|
+
label: controller.intl.t('device.attachment.view-attached'),
|
|
257
261
|
fn: controller.viewAttachedVehicle,
|
|
258
262
|
permission: 'fleet-ops view vehicle',
|
|
259
263
|
isVisible: controller.hasAttachedVehicle,
|
|
260
264
|
},
|
|
261
265
|
{
|
|
262
|
-
label: '
|
|
266
|
+
label: controller.intl.t('device.attachment.locate-attached'),
|
|
263
267
|
fn: controller.locateAttachedVehicle,
|
|
264
268
|
permission: 'fleet-ops view vehicle',
|
|
265
269
|
isVisible: controller.hasAttachedVehicle,
|
|
@@ -23,6 +23,44 @@ function buildStatusBadge(status, label = status) {
|
|
|
23
23
|
</div>`;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
function escapeHtml(value) {
|
|
27
|
+
return `${value ?? ''}`.replace(/[&<>"']/g, (character) => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' })[character]);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function toPlainArray(value) {
|
|
31
|
+
if (!value) {
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (typeof value.toArray === 'function') {
|
|
36
|
+
return value.toArray();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return isArray(value) ? Array.from(value) : [];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Stacked list of attached assets (trailers, devices) with an online dot per row,
|
|
44
|
+
* or a dash when nothing is attached. Names are user data, so they are escaped.
|
|
45
|
+
*/
|
|
46
|
+
function buildAttachmentList(items, resolveName) {
|
|
47
|
+
if (items.length === 0) {
|
|
48
|
+
return '-';
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return items
|
|
52
|
+
.map((item) => {
|
|
53
|
+
const onlineClass = item.online ? 'bg-green-400' : 'bg-gray-500';
|
|
54
|
+
|
|
55
|
+
return `
|
|
56
|
+
<div class="flex items-center gap-1 min-w-0">
|
|
57
|
+
<span class="inline-block w-1.5 h-1.5 rounded-full shrink-0 ${onlineClass}"></span>
|
|
58
|
+
<span class="truncate">${escapeHtml(resolveName(item))}</span>
|
|
59
|
+
</div>`;
|
|
60
|
+
})
|
|
61
|
+
.join('');
|
|
62
|
+
}
|
|
63
|
+
|
|
26
64
|
function buildMetaCell(label, value, valueClass = '') {
|
|
27
65
|
const shouldTruncate = valueClass.split(' ').includes('truncate');
|
|
28
66
|
const flowClass = shouldTruncate ? 'min-w-0 w-full' : 'whitespace-normal break-words';
|
|
@@ -65,6 +103,22 @@ function resolveVehicleNumber(vehicle) {
|
|
|
65
103
|
return vehicle.internal_id ?? vehicle.public_id ?? vehicle.plate_number ?? vehicle.serial_number ?? vehicle.vin ?? '-';
|
|
66
104
|
}
|
|
67
105
|
|
|
106
|
+
function resolveTrailerName(trailer) {
|
|
107
|
+
return trailer.displayName ?? trailer.display_name ?? trailer.name ?? trailer.public_id ?? '-';
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function resolveDeviceName(device) {
|
|
111
|
+
return device.displayName ?? device.display_name ?? device.name ?? device.device_id ?? device.public_id ?? '-';
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function resolveVehicleTrailers(vehicle) {
|
|
115
|
+
return toPlainArray(vehicle.trailers);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function resolveVehicleDevices(vehicle) {
|
|
119
|
+
return toPlainArray(vehicle.devices);
|
|
120
|
+
}
|
|
121
|
+
|
|
68
122
|
function resolveVehicleStatus(vehicle) {
|
|
69
123
|
return vehicle.meta?.status_label ?? vehicle.current_status ?? vehicle.status ?? '-';
|
|
70
124
|
}
|
|
@@ -143,6 +197,8 @@ export function buildVehicleLiveMapContent(vehicle, framed = false) {
|
|
|
143
197
|
<div class="grid grid-cols-2 gap-1">
|
|
144
198
|
${buildMetaCell('Vehicle #', resolveVehicleNumber(vehicle))}
|
|
145
199
|
${buildMetaCell('Driver', vehicle.driver_name ?? vehicle.driver?.name ?? '-')}
|
|
200
|
+
${buildMetaCell('Trailers', buildAttachmentList(resolveVehicleTrailers(vehicle), resolveTrailerName))}
|
|
201
|
+
${buildMetaCell('Devices', buildAttachmentList(resolveVehicleDevices(vehicle), resolveDeviceName))}
|
|
146
202
|
${buildMetaCell('Order', vehicle.meta?.current_order_reference ?? '-')}
|
|
147
203
|
${buildMetaCell('Speed', resolveVehicleSpeed(vehicle))}
|
|
148
204
|
${buildMetaCell('Heading', resolveVehicleHeading(vehicle))}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import config from 'ember-get-config';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Flat silhouettes shown wherever a resource has no photo, in one consistent style
|
|
5
|
+
* across the console. They are inline data URIs so the engine does not depend on a
|
|
6
|
+
* hosted asset; a console can override any of them through
|
|
7
|
+
* `defaultValues.placeholders.<type>` in its environment config.
|
|
8
|
+
*/
|
|
9
|
+
export const PLACEHOLDER_IMAGES = {
|
|
10
|
+
trailer:
|
|
11
|
+
'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NDAgNDgwIiB3aWR0aD0iNjQwIiBoZWlnaHQ9IjQ4MCI+PGcgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIj48cmVjdCB4PSI4OCIgeT0iMTI4IiB3aWR0aD0iNDcwIiBoZWlnaHQ9IjE5NiIgcng9IjE2IiBmaWxsPSIjYmRiZGJkIiBzdHJva2U9IiNkZWRlZGUiIHN0cm9rZS13aWR0aD0iMTAiLz48cmVjdCB4PSIxMDgiIHk9IjE1MCIgd2lkdGg9IjQzMCIgaGVpZ2h0PSIxNTIiIHJ4PSI4IiBmaWxsPSIjYzljOWM5Ii8+PHBhdGggZD0iTTEyOCAxNzhoMzkwTTEyOCAyMjZoMzkwTTEyOCAyNzRoMzkwIiBzdHJva2U9IiNiZGJkYmQiIHN0cm9rZS13aWR0aD0iNiIvPjxyZWN0IHg9IjUyMiIgeT0iMTQ2IiB3aWR0aD0iMTAiIGhlaWdodD0iMTYwIiByeD0iNCIgZmlsbD0iI2IwYjBiMCIvPjxyZWN0IHg9Ijg4IiB5PSIzMjQiIHdpZHRoPSI0NzAiIGhlaWdodD0iMTgiIHJ4PSI2IiBmaWxsPSIjYTlhOWE5Ii8+PHJlY3QgeD0iMTU2IiB5PSIzNDIiIHdpZHRoPSIxNCIgaGVpZ2h0PSI1MiIgcng9IjQiIGZpbGw9IiNhOWE5YTkiLz48cmVjdCB4PSIxNDYiIHk9IjM5MiIgd2lkdGg9IjM0IiBoZWlnaHQ9IjEwIiByeD0iNCIgZmlsbD0iI2E5YTlhOSIvPjxyZWN0IHg9Ijg4IiB5PSIzNDIiIHdpZHRoPSI1MiIgaGVpZ2h0PSIxNiIgcng9IjYiIGZpbGw9IiNhOWE5YTkiLz48Y2lyY2xlIGN4PSI0MTIiIGN5PSIzNjYiIHI9IjQwIiBmaWxsPSIjOGY4ZjhmIiBzdHJva2U9IiNkZWRlZGUiIHN0cm9rZS13aWR0aD0iOCIvPjxjaXJjbGUgY3g9IjQxMiIgY3k9IjM2NiIgcj0iMTYiIGZpbGw9IiNkOWQ5ZDkiLz48Y2lyY2xlIGN4PSI1MDAiIGN5PSIzNjYiIHI9IjQwIiBmaWxsPSIjOGY4ZjhmIiBzdHJva2U9IiNkZWRlZGUiIHN0cm9rZS13aWR0aD0iOCIvPjxjaXJjbGUgY3g9IjUwMCIgY3k9IjM2NiIgcj0iMTYiIGZpbGw9IiNkOWQ5ZDkiLz48L2c+PC9zdmc+',
|
|
12
|
+
vehicle:
|
|
13
|
+
'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NDAgNDgwIiB3aWR0aD0iNjQwIiBoZWlnaHQ9IjQ4MCI+PGcgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIDApIHNjYWxlKDEuMCkiIG9wYWNpdHk9IjEuMCI+PHJlY3QgeD0iMjE2IiB5PSIxMzIiIHdpZHRoPSIzNTAiIGhlaWdodD0iMTkyIiByeD0iMTQiIGZpbGw9IiNiZGJkYmQiIHN0cm9rZT0iI2RlZGVkZSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxyZWN0IHg9IjIzNiIgeT0iMTU0IiB3aWR0aD0iMzEwIiBoZWlnaHQ9IjE0OCIgcng9IjgiIGZpbGw9IiNjOWM5YzkiLz48cGF0aCBkPSJNMjU2IDE4MmgyNzBNMjU2IDIzMGgyNzBNMjU2IDI3OGgyNzAiIHN0cm9rZT0iI2JkYmRiZCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTIxNiAzMjRWMTkwSDk2Yy0xMiAwLTIyIDgtMjYgMjBMNjAgMjQ0djgweiIgZmlsbD0iI2JkYmRiZCIgc3Ryb2tlPSIjZGVkZWRlIiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTEwNCAyMDZoODh2NTJIODR6IiBmaWxsPSIjZDlkOWQ5Ii8+PHJlY3QgeD0iNjAiIHk9IjMyNCIgd2lkdGg9IjUwNiIgaGVpZ2h0PSIxOCIgcng9IjYiIGZpbGw9IiNhOWE5YTkiLz48cmVjdCB4PSI1NiIgeT0iMjkyIiB3aWR0aD0iMTgiIGhlaWdodD0iMzAiIHJ4PSI1IiBmaWxsPSIjZDlkOWQ5Ii8+PGNpcmNsZSBjeD0iMTUwIiBjeT0iMzY2IiByPSI0MCIgZmlsbD0iIzhmOGY4ZiIgc3Ryb2tlPSIjZGVkZWRlIiBzdHJva2Utd2lkdGg9IjgiLz48Y2lyY2xlIGN4PSIxNTAiIGN5PSIzNjYiIHI9IjE2IiBmaWxsPSIjZDlkOWQ5Ii8+PGNpcmNsZSBjeD0iNDcwIiBjeT0iMzY2IiByPSI0MCIgZmlsbD0iIzhmOGY4ZiIgc3Ryb2tlPSIjZGVkZWRlIiBzdHJva2Utd2lkdGg9IjgiLz48Y2lyY2xlIGN4PSI0NzAiIGN5PSIzNjYiIHI9IjE2IiBmaWxsPSIjZDlkOWQ5Ii8+PC9nPjwvZz48L3N2Zz4=',
|
|
14
|
+
driver: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NDAgNDgwIiB3aWR0aD0iNjQwIiBoZWlnaHQ9IjQ4MCI+PGcgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIj48cGF0aCBkPSJNMTEwIDQ4MGMwLTk2IDc2LTE2NiAyMTAtMTY2czIxMCA3MCAyMTAgMTY2eiIgZmlsbD0iI2JkYmRiZCIgc3Ryb2tlPSIjZGVkZWRlIiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTI3MCAzMjJsNTAgNTQgNTAtNTQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2Q5ZDlkOSIgc3Ryb2tlLXdpZHRoPSI4Ii8+PGNpcmNsZSBjeD0iMzIwIiBjeT0iMjA0IiByPSI5MiIgZmlsbD0iI2JkYmRiZCIgc3Ryb2tlPSIjZGVkZWRlIiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTIzMCAxODZjMC02MiA0Mi05NiA5MC05NnM5MCAzNCA5MCA5NnoiIGZpbGw9IiNhOWE5YTkiIHN0cm9rZT0iI2RlZGVkZSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxwYXRoIGQ9Ik0zMjAgOTZ2ODgiIHN0cm9rZT0iI2RlZGVkZSIgc3Ryb2tlLXdpZHRoPSI2Ii8+PGNpcmNsZSBjeD0iMzIwIiBjeT0iOTIiIHI9IjkiIGZpbGw9IiNhOWE5YTkiIHN0cm9rZT0iI2RlZGVkZSIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTIyMiAxODZoMTkwYzY2IDAgOTYgMTAgOTYgMjJzLTMwIDIyLTk2IDIySDIyMnoiIGZpbGw9IiNhOWE5YTkiIHN0cm9rZT0iI2RlZGVkZSIgc3Ryb2tlLXdpZHRoPSI4Ii8+PC9nPjwvc3ZnPg==',
|
|
15
|
+
contact:
|
|
16
|
+
'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NDAgNDgwIiB3aWR0aD0iNjQwIiBoZWlnaHQ9IjQ4MCI+PGcgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIj48cGF0aCBkPSJNMTEwIDQ4MGMwLTk2IDc2LTE2NiAyMTAtMTY2czIxMCA3MCAyMTAgMTY2eiIgZmlsbD0iI2JkYmRiZCIgc3Ryb2tlPSIjZGVkZWRlIiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTI3MCAzMjJsNTAgNTQgNTAtNTQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2Q5ZDlkOSIgc3Ryb2tlLXdpZHRoPSI4Ii8+PGNpcmNsZSBjeD0iMzIwIiBjeT0iMTg4IiByPSI5NiIgZmlsbD0iI2JkYmRiZCIgc3Ryb2tlPSIjZGVkZWRlIiBzdHJva2Utd2lkdGg9IjEwIi8+PC9nPjwvc3ZnPg==',
|
|
17
|
+
customer:
|
|
18
|
+
'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NDAgNDgwIiB3aWR0aD0iNjQwIiBoZWlnaHQ9IjQ4MCI+PGcgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIj48cGF0aCBkPSJNMTEwIDQ4MGMwLTk2IDc2LTE2NiAyMTAtMTY2czIxMCA3MCAyMTAgMTY2eiIgZmlsbD0iI2JkYmRiZCIgc3Ryb2tlPSIjZGVkZWRlIiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTI3MCAzMjJsNTAgNTQgNTAtNTQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2Q5ZDlkOSIgc3Ryb2tlLXdpZHRoPSI4Ii8+PGNpcmNsZSBjeD0iMzIwIiBjeT0iMTg4IiByPSI5NiIgZmlsbD0iI2JkYmRiZCIgc3Ryb2tlPSIjZGVkZWRlIiBzdHJva2Utd2lkdGg9IjEwIi8+PGNpcmNsZSBjeD0iNDkwIiBjeT0iMzkyIiByPSI2MCIgZmlsbD0iIzhmOGY4ZiIgc3Ryb2tlPSIjZGVkZWRlIiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTQ1OCAzOTRsMjIgMjIgNDQtNDgiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2Q5ZDlkOSIgc3Ryb2tlLXdpZHRoPSIxNCIvPjwvZz48L3N2Zz4=',
|
|
19
|
+
vendor: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NDAgNDgwIiB3aWR0aD0iNjQwIiBoZWlnaHQ9IjQ4MCI+PGcgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIj48cGF0aCBkPSJNNzIgMjAwTDMyMCA5NmwyNDggMTA0djI0SDcyeiIgZmlsbD0iI2E5YTlhOSIgc3Ryb2tlPSIjZGVkZWRlIiBzdHJva2Utd2lkdGg9IjEwIi8+PHJlY3QgeD0iMTAwIiB5PSIyMjIiIHdpZHRoPSI0NDAiIGhlaWdodD0iMTkwIiByeD0iOCIgZmlsbD0iI2JkYmRiZCIgc3Ryb2tlPSIjZGVkZWRlIiBzdHJva2Utd2lkdGg9IjEwIi8+PHJlY3QgeD0iMjcyIiB5PSIyOTIiIHdpZHRoPSI5NiIgaGVpZ2h0PSIxMjAiIHJ4PSI2IiBmaWxsPSIjOGY4ZjhmIiBzdHJva2U9IiNkZWRlZGUiIHN0cm9rZS13aWR0aD0iOCIvPjxyZWN0IHg9IjE0MCIgeT0iMjYyIiB3aWR0aD0iODgiIGhlaWdodD0iNjYiIHJ4PSI2IiBmaWxsPSIjZDlkOWQ5Ii8+PHJlY3QgeD0iNDEyIiB5PSIyNjIiIHdpZHRoPSI4OCIgaGVpZ2h0PSI2NiIgcng9IjYiIGZpbGw9IiNkOWQ5ZDkiLz48cGF0aCBkPSJNMTg0IDI2MnY2Nk0xNDAgMjk1aDg4TTQ1NiAyNjJ2NjZNNDEyIDI5NWg4OCIgc3Ryb2tlPSIjYmRiZGJkIiBzdHJva2Utd2lkdGg9IjYiLz48cmVjdCB4PSI2MCIgeT0iNDEyIiB3aWR0aD0iNTIwIiBoZWlnaHQ9IjE2IiByeD0iNiIgZmlsbD0iI2E5YTlhOSIvPjwvZz48L3N2Zz4=',
|
|
20
|
+
fleet: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NDAgNDgwIiB3aWR0aD0iNjQwIiBoZWlnaHQ9IjQ4MCI+PGcgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNTAgLTQwKSBzY2FsZSgwLjcyKSIgb3BhY2l0eT0iMC40NSI+PHJlY3QgeD0iMjE2IiB5PSIxMzIiIHdpZHRoPSIzNTAiIGhlaWdodD0iMTkyIiByeD0iMTQiIGZpbGw9IiNiZGJkYmQiIHN0cm9rZT0iI2RlZGVkZSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxyZWN0IHg9IjIzNiIgeT0iMTU0IiB3aWR0aD0iMzEwIiBoZWlnaHQ9IjE0OCIgcng9IjgiIGZpbGw9IiNjOWM5YzkiLz48cGF0aCBkPSJNMjU2IDE4MmgyNzBNMjU2IDIzMGgyNzBNMjU2IDI3OGgyNzAiIHN0cm9rZT0iI2JkYmRiZCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTIxNiAzMjRWMTkwSDk2Yy0xMiAwLTIyIDgtMjYgMjBMNjAgMjQ0djgweiIgZmlsbD0iI2JkYmRiZCIgc3Ryb2tlPSIjZGVkZWRlIiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTEwNCAyMDZoODh2NTJIODR6IiBmaWxsPSIjZDlkOWQ5Ii8+PHJlY3QgeD0iNjAiIHk9IjMyNCIgd2lkdGg9IjUwNiIgaGVpZ2h0PSIxOCIgcng9IjYiIGZpbGw9IiNhOWE5YTkiLz48cmVjdCB4PSI1NiIgeT0iMjkyIiB3aWR0aD0iMTgiIGhlaWdodD0iMzAiIHJ4PSI1IiBmaWxsPSIjZDlkOWQ5Ii8+PGNpcmNsZSBjeD0iMTUwIiBjeT0iMzY2IiByPSI0MCIgZmlsbD0iIzhmOGY4ZiIgc3Ryb2tlPSIjZGVkZWRlIiBzdHJva2Utd2lkdGg9IjgiLz48Y2lyY2xlIGN4PSIxNTAiIGN5PSIzNjYiIHI9IjE2IiBmaWxsPSIjZDlkOWQ5Ii8+PGNpcmNsZSBjeD0iNDcwIiBjeT0iMzY2IiByPSI0MCIgZmlsbD0iIzhmOGY4ZiIgc3Ryb2tlPSIjZGVkZWRlIiBzdHJva2Utd2lkdGg9IjgiLz48Y2lyY2xlIGN4PSI0NzAiIGN5PSIzNjYiIHI9IjE2IiBmaWxsPSIjZDlkOWQ5Ii8+PC9nPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDgwIDEwKSBzY2FsZSgwLjgpIiBvcGFjaXR5PSIwLjciPjxyZWN0IHg9IjIxNiIgeT0iMTMyIiB3aWR0aD0iMzUwIiBoZWlnaHQ9IjE5MiIgcng9IjE0IiBmaWxsPSIjYmRiZGJkIiBzdHJva2U9IiNkZWRlZGUiIHN0cm9rZS13aWR0aD0iMTAiLz48cmVjdCB4PSIyMzYiIHk9IjE1NCIgd2lkdGg9IjMxMCIgaGVpZ2h0PSIxNDgiIHJ4PSI4IiBmaWxsPSIjYzljOWM5Ii8+PHBhdGggZD0iTTI1NiAxODJoMjcwTTI1NiAyMzBoMjcwTTI1NiAyNzhoMjcwIiBzdHJva2U9IiNiZGJkYmQiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik0yMTYgMzI0VjE5MEg5NmMtMTIgMC0yMiA4LTI2IDIwTDYwIDI0NHY4MHoiIGZpbGw9IiNiZGJkYmQiIHN0cm9rZT0iI2RlZGVkZSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxwYXRoIGQ9Ik0xMDQgMjA2aDg4djUySDg0eiIgZmlsbD0iI2Q5ZDlkOSIvPjxyZWN0IHg9IjYwIiB5PSIzMjQiIHdpZHRoPSI1MDYiIGhlaWdodD0iMTgiIHJ4PSI2IiBmaWxsPSIjYTlhOWE5Ii8+PHJlY3QgeD0iNTYiIHk9IjI5MiIgd2lkdGg9IjE4IiBoZWlnaHQ9IjMwIiByeD0iNSIgZmlsbD0iI2Q5ZDlkOSIvPjxjaXJjbGUgY3g9IjE1MCIgY3k9IjM2NiIgcj0iNDAiIGZpbGw9IiM4ZjhmOGYiIHN0cm9rZT0iI2RlZGVkZSIgc3Ryb2tlLXdpZHRoPSI4Ii8+PGNpcmNsZSBjeD0iMTUwIiBjeT0iMzY2IiByPSIxNiIgZmlsbD0iI2Q5ZDlkOSIvPjxjaXJjbGUgY3g9IjQ3MCIgY3k9IjM2NiIgcj0iNDAiIGZpbGw9IiM4ZjhmOGYiIHN0cm9rZT0iI2RlZGVkZSIgc3Ryb2tlLXdpZHRoPSI4Ii8+PGNpcmNsZSBjeD0iNDcwIiBjeT0iMzY2IiByPSIxNiIgZmlsbD0iI2Q5ZDlkOSIvPjwvZz48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIDYwKSBzY2FsZSgwLjg4KSIgb3BhY2l0eT0iMS4wIj48cmVjdCB4PSIyMTYiIHk9IjEzMiIgd2lkdGg9IjM1MCIgaGVpZ2h0PSIxOTIiIHJ4PSIxNCIgZmlsbD0iI2JkYmRiZCIgc3Ryb2tlPSIjZGVkZWRlIiBzdHJva2Utd2lkdGg9IjEwIi8+PHJlY3QgeD0iMjM2IiB5PSIxNTQiIHdpZHRoPSIzMTAiIGhlaWdodD0iMTQ4IiByeD0iOCIgZmlsbD0iI2M5YzljOSIvPjxwYXRoIGQ9Ik0yNTYgMTgyaDI3ME0yNTYgMjMwaDI3ME0yNTYgMjc4aDI3MCIgc3Ryb2tlPSIjYmRiZGJkIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNMjE2IDMyNFYxOTBIOTZjLTEyIDAtMjIgOC0yNiAyMEw2MCAyNDR2ODB6IiBmaWxsPSIjYmRiZGJkIiBzdHJva2U9IiNkZWRlZGUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBkPSJNMTA0IDIwNmg4OHY1Mkg4NHoiIGZpbGw9IiNkOWQ5ZDkiLz48cmVjdCB4PSI2MCIgeT0iMzI0IiB3aWR0aD0iNTA2IiBoZWlnaHQ9IjE4IiByeD0iNiIgZmlsbD0iI2E5YTlhOSIvPjxyZWN0IHg9IjU2IiB5PSIyOTIiIHdpZHRoPSIxOCIgaGVpZ2h0PSIzMCIgcng9IjUiIGZpbGw9IiNkOWQ5ZDkiLz48Y2lyY2xlIGN4PSIxNTAiIGN5PSIzNjYiIHI9IjQwIiBmaWxsPSIjOGY4ZjhmIiBzdHJva2U9IiNkZWRlZGUiIHN0cm9rZS13aWR0aD0iOCIvPjxjaXJjbGUgY3g9IjE1MCIgY3k9IjM2NiIgcj0iMTYiIGZpbGw9IiNkOWQ5ZDkiLz48Y2lyY2xlIGN4PSI0NzAiIGN5PSIzNjYiIHI9IjQwIiBmaWxsPSIjOGY4ZjhmIiBzdHJva2U9IiNkZWRlZGUiIHN0cm9rZS13aWR0aD0iOCIvPjxjaXJjbGUgY3g9IjQ3MCIgY3k9IjM2NiIgcj0iMTYiIGZpbGw9IiNkOWQ5ZDkiLz48L2c+PC9nPjwvc3ZnPg==',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Hosted images the data models and console config fall back to when a record has no
|
|
25
|
+
* photo. Treat them as "no photo" so the styled placeholder wins over the legacy PNG.
|
|
26
|
+
*/
|
|
27
|
+
const LEGACY_DEFAULT_PATTERN = /(no-avatar|vehicle-placeholder|image-file-icon|fallback-placeholder|default-extension-icon)\.(png|svg|jpe?g)/i;
|
|
28
|
+
|
|
29
|
+
const CONFIG_KEYS = {
|
|
30
|
+
vehicle: 'vehicleImage',
|
|
31
|
+
driver: 'driverImage',
|
|
32
|
+
vendor: 'vendorImage',
|
|
33
|
+
contact: 'contactImage',
|
|
34
|
+
customer: 'customerImage',
|
|
35
|
+
fleet: 'fleetImage',
|
|
36
|
+
trailer: 'trailerImage',
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export function getPlaceholderImage(type = 'contact') {
|
|
40
|
+
const overrides = config?.defaultValues?.placeholders ?? {};
|
|
41
|
+
// A console that already replaced its hosted defaults with inline images wins;
|
|
42
|
+
// hosted PNG defaults are ignored so the silhouette set stays consistent.
|
|
43
|
+
const configured = config?.defaultValues?.[CONFIG_KEYS[type]];
|
|
44
|
+
const inlineConfigured = typeof configured === 'string' && configured.startsWith('data:') ? configured : null;
|
|
45
|
+
|
|
46
|
+
return overrides[type] || inlineConfigured || PLACEHOLDER_IMAGES[type] || PLACEHOLDER_IMAGES.contact;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function isDefaultImage(url) {
|
|
50
|
+
if (typeof url !== 'string' || url.trim() === '') {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (LEGACY_DEFAULT_PATTERN.test(url)) {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const defaults = Object.values(config?.defaultValues ?? {}).filter((value) => typeof value === 'string');
|
|
59
|
+
|
|
60
|
+
return defaults.includes(url);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The image to show for a record: its own photo, or the styled placeholder when the
|
|
65
|
+
* photo is missing or one of the legacy hosted defaults.
|
|
66
|
+
*/
|
|
67
|
+
export function resolveResourceImage(url, type) {
|
|
68
|
+
return isDefaultImage(url) ? getPlaceholderImage(type) : url;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export default getPlaceholderImage;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { PLACEHOLDER_IMAGES, getPlaceholderImage } from './placeholder-images';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Kept for callers that import the trailer placeholder directly; the full set lives in
|
|
5
|
+
* `placeholder-images`.
|
|
6
|
+
*/
|
|
7
|
+
export const TRAILER_PLACEHOLDER_IMAGE = PLACEHOLDER_IMAGES.trailer;
|
|
8
|
+
|
|
9
|
+
export default function getTrailerPlaceholderImage() {
|
|
10
|
+
return getPlaceholderImage('trailer');
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/attachment-list';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/cell/translated-value';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/contact/card';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/equipment/pill';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/filter/multi-model';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/modals/attach-equipment';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/modals/attach-trailer';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/modals/select-trailer';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/trailer/card';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/trailer/details/connections';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/trailer/details/equipment';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/trailer/details/maintenance-history';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/trailer/details/schedules';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/trailer/details/work-orders';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/trailer/details';
|