@fleetbase/fleetops-engine 0.6.50 → 0.6.51
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/README.md +185 -67
- package/addon/components/contact/panel-header.hbs +11 -48
- package/addon/components/customer/details.hbs +1 -2
- package/addon/components/customer/form.hbs +63 -51
- package/addon/components/customer/form.js +27 -1
- package/addon/components/customer/orders.hbs +48 -0
- package/addon/components/customer/orders.js +67 -5
- package/addon/components/driver/form.hbs +1 -1
- package/addon/components/home/getting-started-guidance.hbs +113 -0
- package/addon/components/home/getting-started-guidance.js +107 -0
- package/addon/components/issue/details/comments.hbs +3 -0
- package/addon/components/issue/details/comments.js +3 -0
- package/addon/components/issue/details/correspondence.hbs +9 -0
- package/addon/components/issue/details/correspondence.js +83 -0
- package/addon/components/issue/details/documents.hbs +69 -0
- package/addon/components/issue/details/documents.js +85 -0
- package/addon/components/issue/details.hbs +220 -59
- package/addon/components/issue/details.js +245 -0
- package/addon/components/issue/form.hbs +19 -1
- package/addon/components/issue/panel-header.hbs +43 -0
- package/addon/components/issue/panel-header.js +22 -0
- package/addon/components/issue/timeline.hbs +40 -0
- package/addon/components/issue/timeline.js +45 -0
- package/addon/components/leaflet-tracking-marker.js +3 -0
- package/addon/components/map/drawer/position-listing.js +3 -0
- package/addon/components/map/leaflet-live-map.hbs +2 -2
- package/addon/components/map/leaflet-live-map.js +17 -0
- package/addon/components/map/order-list-overlay.hbs +4 -4
- package/addon/components/modals/convert-customer-to-vendor.hbs +30 -0
- package/addon/components/modals/convert-customer-to-vendor.js +55 -0
- package/addon/components/modals/issue-assign.hbs +20 -0
- package/addon/components/modals/issue-assign.js +49 -0
- package/addon/components/modals/issue-close.hbs +30 -0
- package/addon/components/modals/issue-close.js +73 -0
- package/addon/components/modals/issue-status.hbs +20 -0
- package/addon/components/modals/issue-status.js +43 -0
- package/addon/components/modals/reset-customer-credentials.js +12 -6
- package/addon/components/modals/update-order-activity.hbs +51 -17
- package/addon/components/modals/update-order-activity.js +59 -5
- package/addon/components/order/details/activity.js +2 -2
- package/addon/components/order/details/proof.hbs +40 -38
- package/addon/components/order/details/proof.js +31 -4
- package/addon/components/order/details.hbs +5 -5
- package/addon/components/order/details.js +19 -1
- package/addon/components/order/header.hbs +1 -1
- package/addon/components/route-list.hbs +0 -12
- package/addon/components/service-rate/details.hbs +1 -1
- package/addon/components/service-rate/form.hbs +1 -1
- package/addon/components/service-rate/form.js +4 -0
- package/addon/components/vendor/personnel-manager.hbs +166 -0
- package/addon/components/vendor/personnel-manager.js +143 -0
- package/addon/components/widget/live-fleet.hbs +1 -0
- package/addon/components/widget/live-fleet.js +2 -7
- package/addon/components/widget/revenue-trend.hbs +1 -1
- package/addon/components/widget/revenue-trend.js +75 -2
- package/addon/controllers/management/contacts/customers/details.js +31 -13
- package/addon/controllers/management/contacts/customers.js +16 -5
- package/addon/controllers/management/contacts/index/details.js +31 -13
- package/addon/controllers/management/contacts/index.js +7 -0
- package/addon/controllers/management/issues/index/details.js +52 -6
- package/addon/controllers/management/vendors/index/details.js +4 -0
- package/addon/controllers/operations/orders/index/details.js +11 -3
- package/addon/controllers/operations/orders/index.js +1 -1
- package/addon/extension.js +19 -12
- package/addon/helpers/format-duration.js +1 -38
- package/addon/initializers/load-leaflet-assets.js +5 -6
- package/addon/initializers/patch-ember-leaflet-tooltip-layer.js +51 -0
- package/addon/routes/management/issues/index/details.js +1 -1
- package/addon/routes.js +1 -0
- package/addon/services/contact-actions.js +231 -1
- package/addon/services/getting-started.js +44 -0
- package/addon/services/issue-actions.js +71 -0
- package/addon/services/leaflet-map-manager.js +2 -0
- package/addon/services/map-adapter/leaflet.js +19 -0
- package/addon/services/service-areas.js +3 -0
- package/addon/styles/fleetops-engine.css +1036 -0
- package/addon/templates/management/contacts/customers/details.hbs +1 -1
- package/addon/templates/management/contacts/index/details.hbs +1 -1
- package/addon/templates/management/contacts.hbs +2 -2
- package/addon/templates/management/issues/index/details/index.hbs +3 -1
- package/addon/templates/management/issues/index/details.hbs +3 -2
- package/addon/templates/management/vendors/index/details/personnel.hbs +1 -2
- package/addon/templates/operations/orders/index/details/index.hbs +2 -2
- package/addon/templates/operations/orders/index.hbs +1 -1
- package/addon/templates/operations/service-rates/index/edit.hbs +1 -0
- package/addon/templates/operations/service-rates/index/new.hbs +1 -0
- package/addon/templates/settings/payments/onboard.hbs +8 -8
- package/addon/utils/leaflet-draw-namespace-guard.js +22 -0
- package/addon/utils/leaflet-plugin-loader.js +219 -0
- package/addon/utils/setup-customer-portal.js +4 -64
- package/app/components/home/getting-started-guidance.js +1 -0
- package/app/components/issue/details/comments.js +1 -0
- package/app/components/issue/details/correspondence.js +1 -0
- package/app/components/issue/details/documents.js +1 -0
- package/app/components/issue/panel-header.js +1 -0
- package/app/components/modals/convert-customer-to-vendor.js +1 -0
- package/app/components/modals/issue-assign.js +1 -0
- package/app/components/modals/issue-close.js +1 -0
- package/app/components/modals/issue-status.js +1 -0
- package/app/components/vendor/personnel-manager.js +1 -0
- package/app/helpers/format-duration.js +1 -1
- package/app/services/getting-started.js +1 -0
- package/app/utils/leaflet-draw-namespace-guard.js +1 -0
- package/app/utils/leaflet-plugin-loader.js +1 -0
- package/composer.json +1 -1
- package/extension.json +1 -1
- package/package.json +5 -5
- package/server/migrations/2026_05_31_000001_add_portal_fields_to_vendor_personnels_table.php +30 -0
- package/server/migrations/2026_06_03_000000_ensure_tags_column_on_issues_table.php +31 -0
- package/server/migrations/2026_06_03_000001_add_order_uuid_to_issues_table.php +25 -0
- package/server/migrations/2026_06_04_000001_backfill_order_transaction_subjects.php +39 -0
- package/server/migrations/2026_06_04_000002_backfill_order_transaction_directions.php +24 -0
- package/server/resources/views/mail/customer-credentials.blade.php +16 -13
- package/server/src/Expansions/UserFilterExpansion.php +28 -0
- package/server/src/Http/Controllers/Api/v1/IssueController.php +2 -0
- package/server/src/Http/Controllers/Api/v1/OrderController.php +26 -25
- package/server/src/Http/Controllers/Api/v1/PlaceController.php +10 -58
- package/server/src/Http/Controllers/Internal/v1/ContactController.php +135 -0
- package/server/src/Http/Controllers/Internal/v1/CustomerController.php +116 -6
- package/server/src/Http/Controllers/Internal/v1/GettingStartedController.php +17 -0
- package/server/src/Http/Controllers/Internal/v1/IssueController.php +251 -0
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +172 -97
- package/server/src/Http/Controllers/Internal/v1/PlaceController.php +10 -68
- package/server/src/Http/Controllers/Internal/v1/VendorController.php +89 -0
- package/server/src/Http/Requests/CreateIssueRequest.php +4 -0
- package/server/src/Http/Requests/UpdateIssueRequest.php +4 -0
- package/server/src/Http/Resources/v1/Index/Order.php +12 -9
- package/server/src/Http/Resources/v1/Issue.php +25 -0
- package/server/src/Http/Resources/v1/Order.php +20 -18
- package/server/src/Mail/CustomerCredentialsMail.php +5 -6
- package/server/src/Models/Contact.php +30 -51
- package/server/src/Models/Issue.php +47 -6
- package/server/src/Models/Order.php +33 -6
- package/server/src/Models/ServiceArea.php +1 -1
- package/server/src/Models/VendorPersonnel.php +10 -1
- package/server/src/Models/Zone.php +1 -1
- package/server/src/Observers/PurchaseRateObserver.php +20 -0
- package/server/src/Observers/ZoneObserver.php +56 -0
- package/server/src/Providers/FleetOpsServiceProvider.php +1 -0
- package/server/src/Support/Analytics/TopDrivers.php +9 -1
- package/server/src/Support/GettingStarted.php +144 -0
- package/server/src/Support/PlaceSearch.php +282 -0
- package/server/src/Support/ResolvesOrderServiceStops.php +22 -12
- package/server/src/routes.php +33 -1
- package/server/tests/AnalyticsRoutesTest.php +8 -0
- package/server/tests/CustomerContactIdentitySafetyTest.php +41 -0
- package/server/tests/DriverVehicleStatusDefaultTest.php +2 -2
- package/server/tests/GettingStartedStatusTest.php +21 -0
- package/server/tests/OrderActivityFlowRegressionTest.php +116 -0
- package/server/tests/ServiceAreaZoneApiShapeTest.php +44 -0
- package/translations/ar-ae.yml +9 -0
- package/translations/bg-bg.yaml +9 -0
- package/translations/en-us.yaml +11 -0
- package/translations/es-pa.yaml +9 -0
- package/translations/fr-fr.yaml +9 -0
- package/translations/mn-mn.yaml +9 -0
- package/translations/pt-br.yaml +9 -0
- package/translations/ru-ru.yaml +9 -0
- package/translations/vi-vn.yaml +9 -0
|
@@ -2,6 +2,7 @@ import ResourceActionService from '@fleetbase/ember-core/services/resource-actio
|
|
|
2
2
|
import { inject as service } from '@ember/service';
|
|
3
3
|
import { action } from '@ember/object';
|
|
4
4
|
import { format } from 'date-fns';
|
|
5
|
+
import { issueStatuses } from '../utils/fleet-ops-options';
|
|
5
6
|
|
|
6
7
|
export default class IssueActionsService extends ResourceActionService {
|
|
7
8
|
@service driverActions;
|
|
@@ -92,6 +93,76 @@ export default class IssueActionsService extends ResourceActionService {
|
|
|
92
93
|
},
|
|
93
94
|
};
|
|
94
95
|
|
|
96
|
+
get closedStatuses() {
|
|
97
|
+
return ['closed', 'resolved', 'completed'];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
openStatusModal(issue, options = {}) {
|
|
101
|
+
return this.modalsManager.show('modals/issue-status', {
|
|
102
|
+
issue,
|
|
103
|
+
statusOptions: issueStatuses,
|
|
104
|
+
onSaved: options.onSaved,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
openAssignModal(issue, options = {}) {
|
|
109
|
+
return this.modalsManager.show('modals/issue-assign', {
|
|
110
|
+
issue,
|
|
111
|
+
onSaved: options.onSaved,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
openCloseIssueModal(issue, options = {}) {
|
|
116
|
+
return this.modalsManager.show('modals/issue-close', {
|
|
117
|
+
issue,
|
|
118
|
+
onSaved: options.onSaved,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
confirmReopenIssue(issue, options = {}) {
|
|
123
|
+
this.modalsManager.confirm({
|
|
124
|
+
title: `Re-open ${issue.public_id || 'issue'}?`,
|
|
125
|
+
body: 'This will move the issue back into an active re-opened state and clear the active resolution date.',
|
|
126
|
+
acceptButtonText: 'Re-open Issue',
|
|
127
|
+
acceptButtonIcon: 'rotate-left',
|
|
128
|
+
confirm: async (modal) => {
|
|
129
|
+
modal.startLoading();
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
const meta = issue.meta ?? {};
|
|
133
|
+
const reopenHistory = Array.isArray(meta.reopen_history) ? meta.reopen_history : [];
|
|
134
|
+
const user = this.currentUser.user;
|
|
135
|
+
|
|
136
|
+
issue.status = 're_opened';
|
|
137
|
+
issue.resolved_at = null;
|
|
138
|
+
issue.meta = {
|
|
139
|
+
...meta,
|
|
140
|
+
reopen_history: [
|
|
141
|
+
...reopenHistory,
|
|
142
|
+
{
|
|
143
|
+
reopened_at: new Date().toISOString(),
|
|
144
|
+
reopened_by_uuid: user?.id,
|
|
145
|
+
reopened_by_name: user?.name,
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
await issue.save();
|
|
151
|
+
this.notifications.success('Issue re-opened.');
|
|
152
|
+
|
|
153
|
+
if (typeof options.onSaved === 'function') {
|
|
154
|
+
await options.onSaved(issue);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
modal.done();
|
|
158
|
+
} catch (error) {
|
|
159
|
+
this.notifications.serverError(error);
|
|
160
|
+
modal.stopLoading();
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
95
166
|
@action async viewDriver(issue) {
|
|
96
167
|
const driver = await issue.loadDriver();
|
|
97
168
|
if (driver) {
|
|
@@ -7,6 +7,7 @@ import { renderCompleted, waitForInsertedAndSized } from '@fleetbase/ember-ui/ut
|
|
|
7
7
|
import { Control as RoutingControl } from '@fleetbase/leaflet-routing-machine';
|
|
8
8
|
import { getLayerById, findLayer, flyToLayer } from '../utils/leaflet';
|
|
9
9
|
import isUuid from '@fleetbase/ember-core/utils/is-uuid';
|
|
10
|
+
import ensureLeafletPluginsReady from '../utils/leaflet-plugin-loader';
|
|
10
11
|
|
|
11
12
|
export default class LeafletMapManagerService extends Service {
|
|
12
13
|
@service leafletRoutingControl;
|
|
@@ -92,6 +93,7 @@ export default class LeafletMapManagerService extends Service {
|
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
async ensureInteractive({ timeoutMs = 8000 } = {}) {
|
|
96
|
+
await ensureLeafletPluginsReady({ timeoutMs });
|
|
95
97
|
await this.whenMapLoaded({ timeoutMs });
|
|
96
98
|
|
|
97
99
|
// always ask Leaflet for the live container
|
|
@@ -21,9 +21,16 @@ import { isNone } from '@ember/utils';
|
|
|
21
21
|
import { next } from '@ember/runloop';
|
|
22
22
|
import { createGeoJsonFromLayer } from '../../utils/leaflet-to-geojson';
|
|
23
23
|
import { waypointIconHtml } from '../../utils/route-colors';
|
|
24
|
+
import ensureLeafletDrawEditNamespace from '../../utils/leaflet-draw-namespace-guard';
|
|
25
|
+
import ensureLeafletPluginsReady from '../../utils/leaflet-plugin-loader';
|
|
24
26
|
|
|
25
27
|
const L = window.leaflet || window.L;
|
|
26
28
|
|
|
29
|
+
function ensureLeafletConstructorNamespace() {
|
|
30
|
+
ensureLeafletDrawEditNamespace(L);
|
|
31
|
+
ensureLeafletDrawEditNamespace();
|
|
32
|
+
}
|
|
33
|
+
|
|
27
34
|
export default class LeafletAdapter extends MapAdapterInterface {
|
|
28
35
|
// ─── Internal State ────────────────────────────────────────────────────────
|
|
29
36
|
|
|
@@ -65,6 +72,8 @@ export default class LeafletAdapter extends MapAdapterInterface {
|
|
|
65
72
|
return this._map;
|
|
66
73
|
}
|
|
67
74
|
|
|
75
|
+
ensureLeafletConstructorNamespace();
|
|
76
|
+
|
|
68
77
|
const mapOptions = {
|
|
69
78
|
center: [options.lat ?? 1.3521, options.lng ?? 103.8198],
|
|
70
79
|
zoom: options.zoom ?? 12,
|
|
@@ -113,6 +122,11 @@ export default class LeafletAdapter extends MapAdapterInterface {
|
|
|
113
122
|
this._map?.invalidateSize(false);
|
|
114
123
|
}
|
|
115
124
|
|
|
125
|
+
async ensureInteractive({ timeoutMs = 8000, map = null } = {}) {
|
|
126
|
+
await ensureLeafletPluginsReady({ timeoutMs });
|
|
127
|
+
return map ?? this._map;
|
|
128
|
+
}
|
|
129
|
+
|
|
116
130
|
// ─── Viewport ──────────────────────────────────────────────────────────────
|
|
117
131
|
|
|
118
132
|
setCenter(lat, lng, zoom) {
|
|
@@ -183,6 +197,7 @@ export default class LeafletAdapter extends MapAdapterInterface {
|
|
|
183
197
|
|
|
184
198
|
addMarker(id, lat, lng, options = {}) {
|
|
185
199
|
if (!this._map) return null;
|
|
200
|
+
ensureLeafletConstructorNamespace();
|
|
186
201
|
|
|
187
202
|
const iconOptions = options.iconUrl
|
|
188
203
|
? L.icon({
|
|
@@ -258,6 +273,7 @@ export default class LeafletAdapter extends MapAdapterInterface {
|
|
|
258
273
|
|
|
259
274
|
addPolygon(id, coordinates, options = {}) {
|
|
260
275
|
if (!this._map) return null;
|
|
276
|
+
ensureLeafletConstructorNamespace();
|
|
261
277
|
const polygon = L.polygon(coordinates, {
|
|
262
278
|
color: options.color ?? '#3388ff',
|
|
263
279
|
fillColor: options.fillColor ?? options.color ?? '#3388ff',
|
|
@@ -276,6 +292,7 @@ export default class LeafletAdapter extends MapAdapterInterface {
|
|
|
276
292
|
|
|
277
293
|
addPolyline(id, coordinates, options = {}) {
|
|
278
294
|
if (!this._map) return null;
|
|
295
|
+
ensureLeafletConstructorNamespace();
|
|
279
296
|
const polyline = L.polyline(coordinates, {
|
|
280
297
|
color: options.color ?? '#3388ff',
|
|
281
298
|
weight: options.weight ?? 3,
|
|
@@ -289,6 +306,7 @@ export default class LeafletAdapter extends MapAdapterInterface {
|
|
|
289
306
|
|
|
290
307
|
addCircle(id, lat, lng, radiusMeters, options = {}) {
|
|
291
308
|
if (!this._map) return null;
|
|
309
|
+
ensureLeafletConstructorNamespace();
|
|
292
310
|
const circle = L.circle([lat, lng], {
|
|
293
311
|
radius: radiusMeters,
|
|
294
312
|
color: options.color ?? '#3388ff',
|
|
@@ -671,6 +689,7 @@ export default class LeafletAdapter extends MapAdapterInterface {
|
|
|
671
689
|
return Promise.reject(new Error('LeafletAdapter editPolygon: layer has no coordinates'));
|
|
672
690
|
}
|
|
673
691
|
|
|
692
|
+
ensureLeafletConstructorNamespace();
|
|
674
693
|
const proxy = L.polygon(latlngs, {
|
|
675
694
|
color: originalLayer.options?.color || '#3388ff',
|
|
676
695
|
weight: 3,
|
|
@@ -10,6 +10,7 @@ import MultiPolygon from '@fleetbase/fleetops-data/utils/geojson/multi-polygon';
|
|
|
10
10
|
import Polygon from '@fleetbase/fleetops-data/utils/geojson/polygon';
|
|
11
11
|
import FeatureCollection from '@fleetbase/fleetops-data/utils/geojson/feature-collection';
|
|
12
12
|
import wrapCoordinates from '../utils/leaflet-wrap-coordinates';
|
|
13
|
+
import ensureLeafletDrawEditNamespace from '../utils/leaflet-draw-namespace-guard';
|
|
13
14
|
|
|
14
15
|
const L = window.L;
|
|
15
16
|
export default class ServiceAreasService extends Service {
|
|
@@ -194,6 +195,8 @@ export default class ServiceAreasService extends Service {
|
|
|
194
195
|
|
|
195
196
|
// If you need a Leaflet polygon, you might need to convert back to LatLng arrays.
|
|
196
197
|
// Here we assume Leaflet can work with [lng, lat] arrays, or you convert them as needed.
|
|
198
|
+
ensureLeafletDrawEditNamespace(L);
|
|
199
|
+
ensureLeafletDrawEditNamespace();
|
|
197
200
|
const polygon = L.polygon(latLngs, options);
|
|
198
201
|
return polygon;
|
|
199
202
|
}
|