@fleetbase/fleetops-engine 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/addon/components/admin/visibility-controls.js +1 -0
- package/addon/components/contact-form-panel.hbs +28 -6
- package/addon/components/driver-form-panel.hbs +10 -0
- package/addon/components/driver-form-panel.js +51 -0
- package/addon/components/driver-panel/details.hbs +1 -5
- package/addon/components/driver-panel.hbs +21 -3
- package/addon/components/fleet-form-panel.hbs +60 -6
- package/addon/components/fleet-panel/details.hbs +1 -1
- package/addon/components/fuel-report-form-panel.hbs +84 -8
- package/addon/components/fuel-report-form-panel.js +6 -0
- package/addon/components/fuel-report-panel/details.hbs +4 -0
- package/addon/components/issue-form-panel.hbs +99 -11
- package/addon/components/issue-form-panel.js +5 -13
- package/addon/components/layout/fleet-ops-sidebar.js +10 -1
- package/addon/components/live-map-drawer/driver-listing.hbs +6 -0
- package/addon/components/live-map-drawer/driver-listing.js +240 -0
- package/addon/components/live-map-drawer/place-listing.hbs +6 -0
- package/addon/components/live-map-drawer/place-listing.js +204 -0
- package/addon/components/live-map-drawer/vehicle-listing.hbs +6 -0
- package/addon/components/live-map-drawer/vehicle-listing.js +216 -0
- package/addon/components/live-map-drawer.hbs +17 -0
- package/addon/components/live-map-drawer.js +104 -0
- package/addon/components/live-map.hbs +5 -1
- package/addon/components/live-map.js +107 -15
- package/addon/components/map-container/toolbar.hbs +6 -0
- package/addon/components/modals/driver-assign-vehicle.hbs +2 -11
- package/addon/components/modals/driver-assign-vendor.hbs +1 -9
- package/addon/components/modals/fuel-report-details.hbs +4 -0
- package/addon/components/modals/order-event.hbs +1 -1
- package/addon/components/order/schedule-card.hbs +35 -7
- package/addon/components/order/schedule-card.js +163 -6
- package/addon/components/place-form-panel.hbs +14 -7
- package/addon/components/place-form-panel.js +71 -0
- package/addon/components/place-panel/details.hbs +11 -21
- package/addon/components/vehicle-form-panel.hbs +67 -7
- package/addon/components/vehicle-form-panel.js +37 -0
- package/addon/components/vehicle-panel/details.hbs +9 -5
- package/addon/components/vehicle-panel.hbs +18 -4
- package/addon/components/vendor-form-panel/create-form.hbs +72 -11
- package/addon/components/vendor-form-panel/edit-form.hbs +1 -1
- package/addon/components/vendor-form-panel.hbs +70 -30
- package/addon/components/vendor-form-panel.js +4 -40
- package/addon/components/vendor-panel/details.hbs +2 -2
- package/addon/components/vendor-panel.hbs +16 -2
- package/addon/controllers/management/contacts/index.js +42 -3
- package/addon/controllers/management/fleets/index.js +12 -23
- package/addon/controllers/management/fuel-reports/index/new.js +1 -1
- package/addon/controllers/management/fuel-reports/index.js +73 -20
- package/addon/controllers/management/issues/index/new.js +2 -2
- package/addon/controllers/management/issues/index.js +65 -45
- package/addon/controllers/management/places/index.js +59 -18
- package/addon/controllers/management/vehicles/index.js +67 -8
- package/addon/controllers/management/vendors/index.js +63 -8
- package/addon/controllers/operations/orders/index.js +70 -15
- package/addon/controllers/operations/scheduler/index.js +45 -30
- package/addon/routes/management/contacts/index.js +8 -0
- package/addon/routes/management/fleets/index.js +8 -2
- package/addon/routes/management/fuel-reports/index.js +6 -0
- package/addon/routes/management/issues/index.js +9 -1
- package/addon/routes/management/places/index.js +11 -1
- package/addon/routes/management/vehicles/index.js +3 -3
- package/addon/routes/management/vendors/index.js +8 -0
- package/addon/routes/operations/scheduler/index.js +26 -1
- package/addon/styles/fleetops-engine.css +28 -0
- package/addon/templates/operations/orders/index.hbs +2 -2
- package/addon/templates/operations/scheduler/index.hbs +33 -9
- package/addon/utils/create-full-calendar-event-from-order.js +8 -0
- package/addon/utils/get-issue-categories.js +30 -0
- package/addon/utils/get-issue-types.js +3 -0
- package/addon/utils/get-vendor-status-options.js +3 -0
- package/addon/utils/get-vendor-type-options.js +41 -0
- package/app/components/live-map-drawer/driver-listing.js +1 -0
- package/app/components/live-map-drawer/place-listing.js +1 -0
- package/app/components/live-map-drawer/vehicle-listing.js +1 -0
- package/app/components/live-map-drawer.js +1 -0
- package/app/utils/create-full-calendar-event-from-order.js +1 -0
- package/app/utils/get-issue-categories.js +1 -0
- package/app/utils/get-issue-types.js +1 -0
- package/app/utils/get-vendor-categories.js +1 -0
- package/app/utils/get-vendor-status-options.js +1 -0
- package/app/utils/get-vendor-type-options.js +1 -0
- package/app/utils/get-vendor-types.js +1 -0
- package/composer.json +1 -1
- package/extension.json +1 -1
- package/package.json +4 -4
- package/server/migrations/2023_11_09_041807_add_status_column_to_fuel_reports_table.php +32 -0
- package/server/migrations/2023_11_15_062814_add_comments_column_and_resolved_at_column_to_vehicle_device_events_table.php +33 -0
- package/server/src/Http/Controllers/Api/v1/DriverController.php +2 -2
- package/server/src/Http/Controllers/Api/v1/VehicleController.php +2 -2
- package/server/src/Http/Controllers/Internal/v1/DriverController.php +5 -13
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +1 -3
- package/server/src/Http/Filter/ContactFilter.php +10 -0
- package/server/src/Http/Filter/FleetFilter.php +8 -6
- package/server/src/Http/Filter/FuelReportFilter.php +51 -0
- package/server/src/Http/Filter/IssueFilter.php +61 -5
- package/server/src/Http/Filter/PlaceFilter.php +48 -6
- package/server/src/Http/Filter/VehicleFilter.php +21 -6
- package/server/src/Http/Filter/VendorFilter.php +11 -8
- package/server/src/Http/Middleware/TransformLocationMiddleware.php +1 -1
- package/server/src/Http/Resources/Internal/v1/IntegratedVendorFacilitator.php +17 -18
- package/server/src/Http/Resources/v1/Contact.php +16 -19
- package/server/src/Http/Resources/v1/CurrentJob.php +13 -16
- package/server/src/Http/Resources/v1/Driver.php +59 -57
- package/server/src/Http/Resources/v1/Entity.php +30 -33
- package/server/src/Http/Resources/v1/FuelReport.php +16 -14
- package/server/src/Http/Resources/v1/Order.php +1 -1
- package/server/src/Http/Resources/v1/Payload.php +21 -24
- package/server/src/Http/Resources/v1/Place.php +27 -30
- package/server/src/Http/Resources/v1/Proof.php +13 -16
- package/server/src/Http/Resources/v1/PurchaseRate.php +14 -17
- package/server/src/Http/Resources/v1/ServiceArea.php +13 -16
- package/server/src/Http/Resources/v1/ServiceQuote.php +15 -18
- package/server/src/Http/Resources/v1/ServiceRate.php +33 -36
- package/server/src/Http/Resources/v1/ServiceRateFee.php +14 -17
- package/server/src/Http/Resources/v1/ServiceRateParcelFee.php +9 -12
- package/server/src/Http/Resources/v1/TrackingNumber.php +18 -21
- package/server/src/Http/Resources/v1/TrackingStatus.php +18 -21
- package/server/src/Http/Resources/v1/Vehicle.php +31 -34
- package/server/src/Http/Resources/v1/VehicleDevice.php +23 -25
- package/server/src/Http/Resources/v1/VehicleWithoutDriver.php +38 -32
- package/server/src/Http/Resources/v1/Vendor.php +31 -26
- package/server/src/Http/Resources/v1/Zone.php +14 -17
- package/server/src/Models/Driver.php +7 -1
- package/server/src/Models/FuelReport.php +2 -1
- package/server/src/Models/IntegratedVendor.php +6 -1
- package/server/src/Models/Order.php +24 -2
- package/server/src/Models/Place.php +2 -2
- package/server/src/Models/VehicleDevice.php +1 -1
- package/server/src/Models/VehicleDeviceEvent.php +2 -1
- package/server/src/Models/Vendor.php +1 -1
- package/server/src/Observers/DriverObserver.php +15 -0
- package/server/src/Observers/FleetObserver.php +19 -0
- package/server/src/Providers/FleetOpsServiceProvider.php +1 -0
- package/addon/components/full-calendar/draggable.js +0 -1
- package/addon/components/full-calendar.js +0 -1
- package/app/components/full-calendar/draggable.js +0 -1
- package/app/components/full-calendar.js +0 -1
|
@@ -5,7 +5,7 @@ import { action } from '@ember/object';
|
|
|
5
5
|
import { isBlank } from '@ember/utils';
|
|
6
6
|
import { timeout } from 'ember-concurrency';
|
|
7
7
|
import { task } from 'ember-concurrency-decorators';
|
|
8
|
-
|
|
8
|
+
import getVendorStatusOptions from '../../../utils/get-vendor-status-options';
|
|
9
9
|
export default class ManagementVendorsIndexController extends Controller {
|
|
10
10
|
/**
|
|
11
11
|
* Inject the `management.places.index` controller
|
|
@@ -68,7 +68,7 @@ export default class ManagementVendorsIndexController extends Controller {
|
|
|
68
68
|
*
|
|
69
69
|
* @var {Array}
|
|
70
70
|
*/
|
|
71
|
-
queryParams = ['page', 'limit', 'sort', 'query', 'public_id', 'internal_id', 'created_by', 'updated_by', 'status'];
|
|
71
|
+
queryParams = ['page', 'limit', 'sort', 'query', 'public_id', 'internal_id', 'created_by', 'updated_by', 'status', 'name', 'email', 'phone', 'type', 'country', 'address', 'website_url'];
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
74
|
* The current page of data being viewed
|
|
@@ -112,6 +112,48 @@ export default class ManagementVendorsIndexController extends Controller {
|
|
|
112
112
|
*/
|
|
113
113
|
@tracked status;
|
|
114
114
|
|
|
115
|
+
/**
|
|
116
|
+
* The filterable param `type`
|
|
117
|
+
*
|
|
118
|
+
* @var {Array|String}
|
|
119
|
+
*/
|
|
120
|
+
@tracked type;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* The filterable param `name`
|
|
124
|
+
*
|
|
125
|
+
* @var {String}
|
|
126
|
+
*/
|
|
127
|
+
@tracked name;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* The filterable param `website_url`
|
|
131
|
+
*
|
|
132
|
+
* @var {String}
|
|
133
|
+
*/
|
|
134
|
+
@tracked website_url;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* The filterable param `phone`
|
|
138
|
+
*
|
|
139
|
+
* @var {String}
|
|
140
|
+
*/
|
|
141
|
+
@tracked phone;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* The filterable param `email`
|
|
145
|
+
*
|
|
146
|
+
* @var {String}
|
|
147
|
+
*/
|
|
148
|
+
@tracked email;
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* The filterable param `country`
|
|
152
|
+
*
|
|
153
|
+
* @var {String}
|
|
154
|
+
*/
|
|
155
|
+
@tracked country;
|
|
156
|
+
|
|
115
157
|
/**
|
|
116
158
|
* Rows for the table
|
|
117
159
|
*
|
|
@@ -168,6 +210,17 @@ export default class ManagementVendorsIndexController extends Controller {
|
|
|
168
210
|
filterable: true,
|
|
169
211
|
filterComponent: 'filter/string',
|
|
170
212
|
},
|
|
213
|
+
{
|
|
214
|
+
label: 'Website URL',
|
|
215
|
+
valuePath: 'website_url',
|
|
216
|
+
cellComponent: 'click-to-copy',
|
|
217
|
+
width: '80px',
|
|
218
|
+
resizable: true,
|
|
219
|
+
sortable: true,
|
|
220
|
+
hidden: true,
|
|
221
|
+
filterable: true,
|
|
222
|
+
filterComponent: 'filter/string',
|
|
223
|
+
},
|
|
171
224
|
{
|
|
172
225
|
label: 'Phone',
|
|
173
226
|
valuePath: 'phone',
|
|
@@ -194,11 +247,13 @@ export default class ManagementVendorsIndexController extends Controller {
|
|
|
194
247
|
{
|
|
195
248
|
label: 'Type',
|
|
196
249
|
valuePath: 'type',
|
|
197
|
-
cellComponent: 'table/cell/
|
|
198
|
-
|
|
250
|
+
cellComponent: 'table/cell/anchor',
|
|
251
|
+
action: this.viewVendorPlace,
|
|
252
|
+
width: '150px',
|
|
199
253
|
resizable: true,
|
|
200
254
|
sortable: true,
|
|
201
255
|
filterable: true,
|
|
256
|
+
filterParam: 'type',
|
|
202
257
|
filterComponent: 'filter/string',
|
|
203
258
|
},
|
|
204
259
|
{
|
|
@@ -206,12 +261,12 @@ export default class ManagementVendorsIndexController extends Controller {
|
|
|
206
261
|
valuePath: 'country',
|
|
207
262
|
cellComponent: 'table/cell/base',
|
|
208
263
|
cellClassNames: 'uppercase',
|
|
209
|
-
width: '
|
|
264
|
+
width: '120px',
|
|
210
265
|
resizable: true,
|
|
211
266
|
sortable: true,
|
|
212
|
-
hidden: true,
|
|
213
267
|
filterable: true,
|
|
214
|
-
filterComponent: 'filter/
|
|
268
|
+
filterComponent: 'filter/country',
|
|
269
|
+
filterParam: 'country',
|
|
215
270
|
},
|
|
216
271
|
{
|
|
217
272
|
label: 'Created At',
|
|
@@ -243,7 +298,7 @@ export default class ManagementVendorsIndexController extends Controller {
|
|
|
243
298
|
sortable: true,
|
|
244
299
|
filterable: true,
|
|
245
300
|
filterComponent: 'filter/multi-option',
|
|
246
|
-
filterOptions:
|
|
301
|
+
filterOptions: getVendorStatusOptions(),
|
|
247
302
|
},
|
|
248
303
|
{
|
|
249
304
|
label: '',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import Controller
|
|
1
|
+
import Controller from '@ember/controller';
|
|
2
2
|
import { inject as service } from '@ember/service';
|
|
3
3
|
import { tracked } from '@glimmer/tracking';
|
|
4
4
|
import { action } from '@ember/object';
|
|
@@ -9,20 +9,6 @@ import { timeout } from 'ember-concurrency';
|
|
|
9
9
|
import { task } from 'ember-concurrency-decorators';
|
|
10
10
|
|
|
11
11
|
export default class OperationsOrdersIndexController extends Controller {
|
|
12
|
-
/**
|
|
13
|
-
* Injection of the `ManagementDriversIndexController` controller
|
|
14
|
-
*
|
|
15
|
-
* @memberof OperationsOrdersIndexController
|
|
16
|
-
*/
|
|
17
|
-
@controller('management.drivers.index') driversController;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Injection of the `ManagementFleetIndexController` controller
|
|
21
|
-
*
|
|
22
|
-
* @memberof OperationsOrdersIndexController
|
|
23
|
-
*/
|
|
24
|
-
@controller('management.fleets.index') fleetController;
|
|
25
|
-
|
|
26
12
|
/**
|
|
27
13
|
* Inject the `currentUser` service
|
|
28
14
|
*
|
|
@@ -110,6 +96,8 @@ export default class OperationsOrdersIndexController extends Controller {
|
|
|
110
96
|
'status',
|
|
111
97
|
'type',
|
|
112
98
|
'layout',
|
|
99
|
+
'drawerOpen',
|
|
100
|
+
'drawerTab',
|
|
113
101
|
];
|
|
114
102
|
|
|
115
103
|
/**
|
|
@@ -266,6 +254,13 @@ export default class OperationsOrdersIndexController extends Controller {
|
|
|
266
254
|
*/
|
|
267
255
|
@tracked leafletMap;
|
|
268
256
|
|
|
257
|
+
/**
|
|
258
|
+
* Reference to the drawer context API.
|
|
259
|
+
*
|
|
260
|
+
* @type {Object}
|
|
261
|
+
*/
|
|
262
|
+
@tracked drawer;
|
|
263
|
+
|
|
269
264
|
/**
|
|
270
265
|
* Current layout type (e.g., 'map', 'table', 'kanban', 'analytics')
|
|
271
266
|
*
|
|
@@ -273,6 +268,20 @@ export default class OperationsOrdersIndexController extends Controller {
|
|
|
273
268
|
*/
|
|
274
269
|
@tracked layout = 'map';
|
|
275
270
|
|
|
271
|
+
/**
|
|
272
|
+
* Decides if scope drawer is open.
|
|
273
|
+
*
|
|
274
|
+
* @type {Boolean}
|
|
275
|
+
*/
|
|
276
|
+
@tracked drawerOpen = 0;
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* The drawer tab that is active.
|
|
280
|
+
*
|
|
281
|
+
* @type {Boolean}
|
|
282
|
+
*/
|
|
283
|
+
@tracked drawerTab;
|
|
284
|
+
|
|
276
285
|
/**
|
|
277
286
|
* Flag to determine if the layout is 'map'
|
|
278
287
|
*
|
|
@@ -722,6 +731,52 @@ export default class OperationsOrdersIndexController extends Controller {
|
|
|
722
731
|
this.liveMap = liveMap;
|
|
723
732
|
}
|
|
724
733
|
|
|
734
|
+
/**
|
|
735
|
+
* Sets the drawer component context api.
|
|
736
|
+
*
|
|
737
|
+
* @param {Object} drawerApi
|
|
738
|
+
* @memberof OperationsOrdersIndexController
|
|
739
|
+
*/
|
|
740
|
+
@action setDrawerContext(drawerApi) {
|
|
741
|
+
this.drawer = drawerApi;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* Toggles the LiveMap drawer component.
|
|
746
|
+
*
|
|
747
|
+
* @memberof OperationsOrdersIndexController
|
|
748
|
+
*/
|
|
749
|
+
@action onPressLiveMapDrawerToggle() {
|
|
750
|
+
if (this.drawer) {
|
|
751
|
+
this.drawer.toggleMinimize({
|
|
752
|
+
onToggle: (drawerApi) => {
|
|
753
|
+
this.drawerOpen = drawerApi.isMinimized ? 0 : 1;
|
|
754
|
+
},
|
|
755
|
+
});
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
/**
|
|
760
|
+
* Handles the resize end event for the `<LiveMapDrawer />` component.
|
|
761
|
+
*
|
|
762
|
+
* @params {Object} event
|
|
763
|
+
* @params {Object.drawerPanelNode|HTMLElement}
|
|
764
|
+
* @memberof OperationsOrdersIndexController
|
|
765
|
+
*/
|
|
766
|
+
@action onDrawerResizeEnd({ drawerPanelNode }) {
|
|
767
|
+
const rect = drawerPanelNode.getBoundingClientRect();
|
|
768
|
+
|
|
769
|
+
if (rect.height === 0) {
|
|
770
|
+
this.drawerOpen = 0;
|
|
771
|
+
} else if (rect.height > 1) {
|
|
772
|
+
this.drawerOpen = 1;
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
@action onDrawerTabChanged(tabName) {
|
|
777
|
+
this.drawerTab = tabName;
|
|
778
|
+
}
|
|
779
|
+
|
|
725
780
|
/**
|
|
726
781
|
* Exports all orders.
|
|
727
782
|
* @action
|
|
@@ -1,31 +1,26 @@
|
|
|
1
1
|
import Controller from '@ember/controller';
|
|
2
|
+
import { tracked } from '@glimmer/tracking';
|
|
2
3
|
import { inject as service } from '@ember/service';
|
|
3
|
-
import {
|
|
4
|
+
import { action } from '@ember/object';
|
|
4
5
|
import { format, isValid as isValidDate } from 'date-fns';
|
|
6
|
+
import createFullCalendarEventFromOrder from '../../../utils/create-full-calendar-event-from-order';
|
|
5
7
|
|
|
6
8
|
export default class OperationsSchedulerIndexController extends Controller {
|
|
7
9
|
@service modalsManager;
|
|
8
10
|
@service notifications;
|
|
9
|
-
|
|
10
|
-
@
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@computed('scheduledOrders.@each.scheduled_at') get events() {
|
|
19
|
-
return this.scheduledOrders.map((order) => ({
|
|
20
|
-
id: order.id,
|
|
21
|
-
title: `${order.scheduledAtTime} - ${order.public_id}`,
|
|
22
|
-
start: order.scheduled_at,
|
|
23
|
-
allDay: true,
|
|
24
|
-
}));
|
|
11
|
+
@service store;
|
|
12
|
+
@service hostRouter;
|
|
13
|
+
@tracked scheduledOrders = [];
|
|
14
|
+
@tracked unscheduledOrders = [];
|
|
15
|
+
@tracked events = [];
|
|
16
|
+
|
|
17
|
+
@action setCalendarApi(calendar) {
|
|
18
|
+
this.calendar = calendar;
|
|
25
19
|
}
|
|
26
20
|
|
|
27
|
-
@action viewEvent(order
|
|
28
|
-
|
|
21
|
+
@action viewEvent(order) {
|
|
22
|
+
// get the event from the calendar
|
|
23
|
+
let event = this.calendar.getEventById(order.id);
|
|
29
24
|
|
|
30
25
|
this.modalsManager.show('modals/order-event', {
|
|
31
26
|
title: `Scheduling for ${order.public_id}`,
|
|
@@ -34,7 +29,7 @@ export default class OperationsSchedulerIndexController extends Controller {
|
|
|
34
29
|
hideDeclineButton: true,
|
|
35
30
|
order,
|
|
36
31
|
reschedule: (date) => {
|
|
37
|
-
if (typeof date
|
|
32
|
+
if (date && typeof date.toDate === 'function') {
|
|
38
33
|
date = date.toDate();
|
|
39
34
|
}
|
|
40
35
|
|
|
@@ -51,15 +46,27 @@ export default class OperationsSchedulerIndexController extends Controller {
|
|
|
51
46
|
}
|
|
52
47
|
|
|
53
48
|
return order.save().then((order) => {
|
|
54
|
-
|
|
49
|
+
// remove event from calendar
|
|
50
|
+
if (event) {
|
|
51
|
+
event.remove();
|
|
52
|
+
}
|
|
55
53
|
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
if (order.scheduled_at) {
|
|
55
|
+
// notify order has been scheduled
|
|
56
|
+
this.notifications.success(`Order '${order.public_id}' has been scheduled at ${order.scheduledAt}.`);
|
|
57
|
+
// add event to calendar
|
|
58
|
+
event = this.calendar.addEvent(createFullCalendarEventFromOrder(order));
|
|
59
|
+
} else {
|
|
60
|
+
this.notifications.info(`Order '${order.public_id}' has been unscheduled.`);
|
|
61
|
+
}
|
|
58
62
|
|
|
59
|
-
//
|
|
60
|
-
if (
|
|
61
|
-
event.
|
|
63
|
+
// update event props
|
|
64
|
+
if (event && typeof event.setProp === 'function') {
|
|
65
|
+
event.setProp('title', order.eventTitle);
|
|
62
66
|
}
|
|
67
|
+
|
|
68
|
+
// refresh route
|
|
69
|
+
this.hostRouter.refresh();
|
|
63
70
|
});
|
|
64
71
|
},
|
|
65
72
|
});
|
|
@@ -80,7 +87,9 @@ export default class OperationsSchedulerIndexController extends Controller {
|
|
|
80
87
|
const order = this.store.peekRecord('order', data.id);
|
|
81
88
|
|
|
82
89
|
order.set('scheduled_at', date);
|
|
83
|
-
order.save()
|
|
90
|
+
return order.save().then(() => {
|
|
91
|
+
this.hostRouter.refresh();
|
|
92
|
+
});
|
|
84
93
|
}
|
|
85
94
|
|
|
86
95
|
@action receivedEvent(eventReceivedInfo) {
|
|
@@ -88,7 +97,9 @@ export default class OperationsSchedulerIndexController extends Controller {
|
|
|
88
97
|
const order = this.store.peekRecord('order', event.id);
|
|
89
98
|
|
|
90
99
|
// update event props
|
|
91
|
-
event
|
|
100
|
+
if (typeof event.setProp === 'function') {
|
|
101
|
+
event.setProp('title', order.eventTitle);
|
|
102
|
+
}
|
|
92
103
|
}
|
|
93
104
|
|
|
94
105
|
@action rescheduleEventFromDrag(eventDropInfo) {
|
|
@@ -102,9 +113,13 @@ export default class OperationsSchedulerIndexController extends Controller {
|
|
|
102
113
|
|
|
103
114
|
// set and save order props
|
|
104
115
|
order.set('scheduled_at', isValidDate(newDate) ? newDate : start);
|
|
105
|
-
order.save()
|
|
116
|
+
order.save().then(() => {
|
|
117
|
+
this.hostRouter.refresh();
|
|
118
|
+
});
|
|
106
119
|
|
|
107
120
|
// update event props
|
|
108
|
-
event
|
|
121
|
+
if (typeof event.setProp === 'function') {
|
|
122
|
+
event.setProp('title', order.eventTitle);
|
|
123
|
+
}
|
|
109
124
|
}
|
|
110
125
|
}
|
|
@@ -15,6 +15,14 @@ export default class ManagementContactsIndexRoute extends Route {
|
|
|
15
15
|
sort: { refreshModel: true },
|
|
16
16
|
query: { refreshModel: true },
|
|
17
17
|
status: { refreshModel: true },
|
|
18
|
+
name: { refreshModel: true },
|
|
19
|
+
title: { refreshModel: true },
|
|
20
|
+
phone: { refreshModel: true },
|
|
21
|
+
email: { refreshModel: true },
|
|
22
|
+
type: { refreshModel: true },
|
|
23
|
+
internal_id: { refreshModel: true },
|
|
24
|
+
createdAt: { refreshModel: true },
|
|
25
|
+
updatedAt: { refreshModel: true },
|
|
18
26
|
};
|
|
19
27
|
|
|
20
28
|
model(params) {
|
|
@@ -15,11 +15,17 @@ export default class ManagementFleetsIndexRoute extends Route {
|
|
|
15
15
|
sort: { refreshModel: true },
|
|
16
16
|
query: { refreshModel: true },
|
|
17
17
|
status: { refreshModel: true },
|
|
18
|
-
|
|
18
|
+
public_id: { refreshModel: true },
|
|
19
19
|
zone: { refreshModel: true },
|
|
20
20
|
service_area: { refreshModel: true },
|
|
21
|
-
|
|
21
|
+
parent_fleet_uuid: { refreshModel: true },
|
|
22
22
|
task: { refreshModel: true },
|
|
23
|
+
name: { refreshModel: true },
|
|
24
|
+
vendor: { refreshModel: true },
|
|
25
|
+
drivers_count: { refreshModel: true },
|
|
26
|
+
drivers_online_count: { refreshModel: true },
|
|
27
|
+
createdAt: { refreshModel: true },
|
|
28
|
+
updatedAt: { refreshModel: true },
|
|
23
29
|
};
|
|
24
30
|
|
|
25
31
|
model(params) {
|
|
@@ -15,8 +15,14 @@ export default class ManagementFuelReportsIndexRoute extends Route {
|
|
|
15
15
|
sort: { refreshModel: true },
|
|
16
16
|
query: { refreshModel: true },
|
|
17
17
|
vehicle: { refreshModel: true },
|
|
18
|
+
reporter: { refreshModel: true },
|
|
18
19
|
driver: { refreshModel: true },
|
|
19
20
|
status: { refreshModel: true },
|
|
21
|
+
createdAt: { refreshModel: true },
|
|
22
|
+
updatedAt: { refreshModel: true },
|
|
23
|
+
public_id: { refreshModel: true },
|
|
24
|
+
volume: { refreshModel: true },
|
|
25
|
+
odometer: { refreshModel: true },
|
|
20
26
|
};
|
|
21
27
|
|
|
22
28
|
model(params) {
|
|
@@ -14,8 +14,16 @@ export default class ManagementIssuesIndexRoute extends Route {
|
|
|
14
14
|
limit: { refreshModel: true },
|
|
15
15
|
sort: { refreshModel: true },
|
|
16
16
|
query: { refreshModel: true },
|
|
17
|
-
|
|
17
|
+
priority: { refreshModel: true },
|
|
18
18
|
status: { refreshModel: true },
|
|
19
|
+
vehicle: { refreshModel: true },
|
|
20
|
+
driver: { refreshModel: true },
|
|
21
|
+
assignee: { refreshModel: true },
|
|
22
|
+
reporter: { refreshModel: true },
|
|
23
|
+
type: { refreshModel: true },
|
|
24
|
+
category: { refreshModel: true },
|
|
25
|
+
updatedAt: { refreshModel: true },
|
|
26
|
+
createdAt: { refreshModel: true },
|
|
19
27
|
};
|
|
20
28
|
|
|
21
29
|
model(params) {
|
|
@@ -15,9 +15,19 @@ export default class ManagementPlacesIndexRoute extends Route {
|
|
|
15
15
|
sort: { refreshModel: true },
|
|
16
16
|
query: { refreshModel: true },
|
|
17
17
|
country: { refreshModel: true },
|
|
18
|
+
name: { refreshModel: true },
|
|
19
|
+
address: { refreshModel: true },
|
|
20
|
+
public_id: { refreshModel: true },
|
|
21
|
+
city: { refreshModel: true },
|
|
22
|
+
phone: { refreshModel: true },
|
|
23
|
+
neighborhood: { refreshModel: true },
|
|
24
|
+
postal_code: { refreshModel: true },
|
|
25
|
+
state: { refreshModel: true },
|
|
26
|
+
createdAt: { refreshModel: true },
|
|
27
|
+
updatedAt: { refreshModel: true },
|
|
18
28
|
};
|
|
19
29
|
|
|
20
30
|
model(params) {
|
|
21
|
-
return this.store.query('place', { params });
|
|
31
|
+
return this.store.query('place', { ...params });
|
|
22
32
|
}
|
|
23
33
|
}
|
|
@@ -10,14 +10,14 @@ export default class ManagementVehiclesIndexRoute extends Route {
|
|
|
10
10
|
sort: { refreshModel: true },
|
|
11
11
|
query: { refreshModel: true },
|
|
12
12
|
status: { refreshModel: true },
|
|
13
|
-
|
|
13
|
+
display_name: { refreshModel: true },
|
|
14
14
|
public_id: { refreshModel: true },
|
|
15
15
|
vin: { refreshModel: true },
|
|
16
16
|
plate_number: { refreshModel: true },
|
|
17
|
-
|
|
18
|
-
vehicle_model: { refreshModel: true },
|
|
17
|
+
model: { refreshModel: true },
|
|
19
18
|
year: { refreshModel: true },
|
|
20
19
|
country: { refreshModel: true },
|
|
20
|
+
make: { refreshModel: true },
|
|
21
21
|
fleet: { refreshModel: true },
|
|
22
22
|
vendor: { refreshModel: true },
|
|
23
23
|
driver: { refreshModel: true },
|
|
@@ -16,6 +16,14 @@ export default class ManagementVendorsIndexRoute extends Route {
|
|
|
16
16
|
query: { refreshModel: true },
|
|
17
17
|
country: { refreshModel: true },
|
|
18
18
|
status: { refreshModel: true },
|
|
19
|
+
name: { refreshModel: true },
|
|
20
|
+
email: { refreshModel: true },
|
|
21
|
+
address: { refreshModel: true },
|
|
22
|
+
phone: { refreshModel: true },
|
|
23
|
+
type: { refreshModel: true },
|
|
24
|
+
createdAt: { refreshModel: true },
|
|
25
|
+
updatedAt: { refreshModel: true },
|
|
26
|
+
website_url: { refreshModel: true },
|
|
19
27
|
};
|
|
20
28
|
|
|
21
29
|
model(params) {
|
|
@@ -1,10 +1,35 @@
|
|
|
1
1
|
import Route from '@ember/routing/route';
|
|
2
2
|
import { inject as service } from '@ember/service';
|
|
3
|
+
import { isValid as isValidDate } from 'date-fns';
|
|
4
|
+
import { isNone } from '@ember/utils';
|
|
5
|
+
import createFullCalendarEventFromOrder from '../../../utils/create-full-calendar-event-from-order';
|
|
6
|
+
|
|
7
|
+
const getUnscheduledOrder = (order) => {
|
|
8
|
+
return isNone(order.scheduled_at);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const getScheduledOrder = (order) => {
|
|
12
|
+
return isValidDate(order.scheduled_at);
|
|
13
|
+
};
|
|
3
14
|
|
|
4
15
|
export default class OperationsSchedulerIndexRoute extends Route {
|
|
5
16
|
@service store;
|
|
6
17
|
|
|
7
18
|
model() {
|
|
8
|
-
return this.store.query('order', { status: 'created', with: ['payload'] });
|
|
19
|
+
return this.store.query('order', { status: 'created', with: ['payload', 'driverAssigned.vehicle'] });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
setupController(controller, model) {
|
|
23
|
+
// get orders
|
|
24
|
+
const orders = model.toArray();
|
|
25
|
+
|
|
26
|
+
// set unscheduled orders
|
|
27
|
+
controller.unscheduledOrders = orders.filter(getUnscheduledOrder);
|
|
28
|
+
|
|
29
|
+
// set scheduled orders
|
|
30
|
+
controller.scheduledOrders = orders.filter(getScheduledOrder);
|
|
31
|
+
|
|
32
|
+
// create events from scheduledOrders
|
|
33
|
+
controller.events = controller.scheduledOrders.map(createFullCalendarEventFromOrder);
|
|
9
34
|
}
|
|
10
35
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
.scheduler-left-sidebar {
|
|
2
|
+
border-right: 1px rgba(229, 231, 235, 1) solid;
|
|
3
|
+
height: 100vh;
|
|
4
|
+
overflow-y: scroll;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
body[data-theme="dark"] .scheduler-left-sidebar {
|
|
8
|
+
border-right: 1px rgba(55, 65, 81, 1) solid;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.scheduler-left-sidebar > .next-content-panel-wrapper > .next-content-panel-container > .next-content-panel > .next-content-panel-header.next-content-panel-is-closed {
|
|
12
|
+
border-bottom-left-radius: 0;
|
|
13
|
+
border-bottom-right-radius: 0;
|
|
14
|
+
}
|
|
15
|
+
.scheduler-left-sidebar > .next-content-panel-wrapper > .next-content-panel-container > .next-content-panel > .next-content-panel-header {
|
|
16
|
+
border-top-left-radius: 0;
|
|
17
|
+
border-top-right-radius: 0;
|
|
18
|
+
border-top: 0;
|
|
19
|
+
border-left: 0;
|
|
20
|
+
border-right: 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.scheduler-left-sidebar > .next-content-panel-wrapper > .next-content-panel-container > .next-content-panel > .next-content-panel-body {
|
|
24
|
+
border-left: 0;
|
|
25
|
+
border-right: 0;
|
|
26
|
+
border-bottom-left-radius: 0;
|
|
27
|
+
border-bottom-right-radius: 0;
|
|
28
|
+
}
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
{{#if this.isMapLayout}}
|
|
14
14
|
<MapContainer @layout={{this.layout}} @onReady={{this.onMapContainerReady}}>
|
|
15
15
|
<GlobalSearch @visible={{this.isSearchVisible}} @onPressOrder={{this.viewOrder}} />
|
|
16
|
-
<MapContainer::Toolbar @activeOrdersCount={{this.activeOrdersCount}} @liveMap={{this.liveMap}} @map={{this.leafletMap}} @onPressViewOrders={{this.toggleOrdersPanel}} @onPressSearch={{this.toggleSearch}} @onPressCreateOrder={{this.createOrder}} @
|
|
16
|
+
<MapContainer::Toolbar @activeOrdersCount={{this.activeOrdersCount}} @liveMap={{this.liveMap}} @map={{this.leafletMap}} @onPressViewOrders={{this.toggleOrdersPanel}} @onPressSearch={{this.toggleSearch}} @onPressCreateOrder={{this.createOrder}} @onPressLiveMapDrawerToggle={{this.onPressLiveMapDrawerToggle}} />
|
|
17
17
|
<OrderListOverlay @noBackdrop={{true}} @fullHeight={{true}} @outView={{not this.isOrdersPanelVisible}} @width={{if (media 'isMobile') "100%" "338px"}} @onPressCancel={{this.hideOrdersPanel}} @onPressCreateOrder={{this.createOrder}} @onPressViewOrder={{this.viewOrder}} @onPressCreateFleet={{this.fleetController.createFleet}} @onPressManageFleet={{this.fleetController.viewFleet}} @onPressCancelOrders={{this.bulkCancelOrders}} @onPressDeleteOrders={{this.bulkDeleteOrders}} />
|
|
18
|
-
<LiveMap id="leafletMap" class="next-leaflet-container-map" @lat={{1.3521}} @lng={{103.8198}} @zoom={{12}} @zoomControl={{false}} @onLoad={{this.setMapReference}} {{set-container-dimensions}} />
|
|
18
|
+
<LiveMap id="leafletMap" class="next-leaflet-container-map" @lat={{1.3521}} @lng={{103.8198}} @zoom={{12}} @zoomControl={{false}} @onLoad={{this.setMapReference}} @onDrawerReady={{this.setDrawerContext}} @isDrawerMinimized={{not this.drawerOpen}} @onDrawerResizeEnd={{this.onDrawerResizeEnd}} @onDrawerTabChanged={{this.onDrawerTabChanged}} @drawerTab={{this.drawerTab}} {{set-container-dimensions}} />
|
|
19
19
|
</MapContainer>
|
|
20
20
|
{{/if}}
|
|
21
21
|
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
<Layout::Section::Header @title="Scheduler" />
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
<div class="
|
|
5
|
-
<div class="grid grid-cols-
|
|
6
|
-
<div class="
|
|
7
|
-
<ContentPanel
|
|
3
|
+
<Layout::Section::Body class="overflow-y-scroll h-screen">
|
|
4
|
+
<div class="h-screen">
|
|
5
|
+
<div class="grid grid-cols-1 lg:grid-cols-3">
|
|
6
|
+
<div class="scheduler-left-sidebar">
|
|
7
|
+
<ContentPanel
|
|
8
|
+
@title="Unscheduled Orders"
|
|
9
|
+
@titleStatuRight={{this.unscheduledOrders.length}}
|
|
10
|
+
@titleStatuRightClass="info-status-badge"
|
|
11
|
+
@hideStatusDot={{true}}
|
|
12
|
+
@open={{true}}
|
|
13
|
+
@pad={{true}}
|
|
14
|
+
@panelBodyClass="bg-white dark:bg-gray-900"
|
|
15
|
+
>
|
|
8
16
|
<div class="space-y-4">
|
|
9
17
|
{{#each this.unscheduledOrders as |order|}}
|
|
10
18
|
<FullCalendar::Draggable @eventData={{json-hash id=order.id title=order.eventTitle allDay=true}}>
|
|
@@ -13,7 +21,15 @@
|
|
|
13
21
|
{{/each}}
|
|
14
22
|
</div>
|
|
15
23
|
</ContentPanel>
|
|
16
|
-
<ContentPanel
|
|
24
|
+
<ContentPanel
|
|
25
|
+
@title="Scheduled Orders"
|
|
26
|
+
@titleStatuRight={{this.scheduledOrders.length}}
|
|
27
|
+
@titleStatusRightClass="info-status-badge"
|
|
28
|
+
@hideStatusDot={{true}}
|
|
29
|
+
@open={{true}}
|
|
30
|
+
@pad={{true}}
|
|
31
|
+
@panelBodyClass="bg-white dark:bg-gray-900"
|
|
32
|
+
>
|
|
17
33
|
<div class="space-y-4">
|
|
18
34
|
{{#each this.scheduledOrders as |order|}}
|
|
19
35
|
<Order::ScheduleCard @order={{order}} @titleClass="cursor-pointer" @onTitleClick={{fn this.viewEvent order}} />
|
|
@@ -22,9 +38,17 @@
|
|
|
22
38
|
</ContentPanel>
|
|
23
39
|
</div>
|
|
24
40
|
|
|
25
|
-
<div class="col-span-2">
|
|
26
|
-
<FullCalendar
|
|
41
|
+
<div class="col-span-2 p-4">
|
|
42
|
+
<FullCalendar
|
|
43
|
+
@events={{this.events}}
|
|
44
|
+
@editable={{true}}
|
|
45
|
+
@onDrop={{this.scheduleEventFromDrop}}
|
|
46
|
+
@onEventReceive={{this.receivedEvent}}
|
|
47
|
+
@onEventDrop={{this.rescheduleEventFromDrag}}
|
|
48
|
+
@onEventClick={{this.viewOrderAsEvent}}
|
|
49
|
+
@onInit={{this.setCalendarApi}}
|
|
50
|
+
/>
|
|
27
51
|
</div>
|
|
28
52
|
</div>
|
|
29
53
|
</div>
|
|
30
|
-
</
|
|
54
|
+
</Layout::Section::Body>
|