@fleetbase/fleetops-engine 0.3.1 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/addon/components/admin/visibility-controls.js +1 -0
  2. package/addon/components/contact-form-panel.hbs +82 -0
  3. package/addon/components/contact-form-panel.js +195 -0
  4. package/addon/components/contact-panel/details.hbs +36 -0
  5. package/addon/components/contact-panel/details.js +3 -0
  6. package/addon/components/contact-panel.hbs +52 -0
  7. package/addon/components/contact-panel.js +161 -0
  8. package/addon/components/driver-form-panel.hbs +39 -55
  9. package/addon/components/driver-form-panel.js +41 -0
  10. package/addon/components/driver-panel/details.hbs +2 -2
  11. package/addon/components/driver-panel.hbs +12 -10
  12. package/addon/components/driver-panel.js +13 -0
  13. package/addon/components/fleet-form-panel.hbs +28 -28
  14. package/addon/components/fleet-form-panel.js +150 -1
  15. package/addon/components/fleet-listing-panel.hbs +8 -0
  16. package/addon/components/fleet-listing-panel.js +34 -0
  17. package/addon/components/fleet-panel/details.hbs +30 -0
  18. package/addon/components/fleet-panel/driver-listing.hbs +72 -0
  19. package/addon/components/fleet-panel/driver-listing.js +149 -0
  20. package/addon/components/fleet-panel/vehicle-listing.hbs +72 -0
  21. package/addon/components/fleet-panel/vehicle-listing.js +149 -0
  22. package/addon/components/fleet-panel.hbs +12 -58
  23. package/addon/components/fleet-panel.js +148 -26
  24. package/addon/components/fleet-vehicle-listing.hbs +0 -1
  25. package/addon/components/fuel-report-form-panel.hbs +41 -0
  26. package/addon/components/fuel-report-form-panel.js +122 -0
  27. package/addon/components/fuel-report-panel/details.hbs +38 -0
  28. package/addon/components/fuel-report-panel.hbs +30 -0
  29. package/addon/components/fuel-report-panel.js +161 -0
  30. package/addon/components/issue-form-panel.hbs +85 -0
  31. package/addon/components/issue-form-panel.js +211 -0
  32. package/addon/components/issue-panel/details.hbs +48 -0
  33. package/addon/components/issue-panel.hbs +30 -0
  34. package/addon/components/issue-panel.js +160 -0
  35. package/addon/components/layout/fleet-ops-sidebar.hbs +2 -2
  36. package/addon/components/layout/fleet-ops-sidebar.js +2 -1
  37. package/addon/components/live-map-drawer/driver-listing.hbs +6 -0
  38. package/addon/components/live-map-drawer/driver-listing.js +240 -0
  39. package/addon/components/live-map-drawer/place-listing.hbs +6 -0
  40. package/addon/components/live-map-drawer/place-listing.js +204 -0
  41. package/addon/components/live-map-drawer/vehicle-listing.hbs +6 -0
  42. package/addon/components/live-map-drawer/vehicle-listing.js +216 -0
  43. package/addon/components/live-map-drawer.hbs +17 -0
  44. package/addon/components/live-map-drawer.js +104 -0
  45. package/addon/components/live-map.hbs +5 -1
  46. package/addon/components/live-map.js +109 -15
  47. package/addon/components/map-container/toolbar.hbs +15 -9
  48. package/addon/components/map-container/topbar.hbs +1 -1
  49. package/addon/components/modals/issue-details.hbs +38 -0
  50. package/addon/components/modals/issue-from.hbs +138 -0
  51. package/addon/components/modals/order-event.hbs +1 -1
  52. package/addon/components/order/schedule-card.hbs +4 -4
  53. package/addon/components/order/schedule-card.js +13 -6
  54. package/addon/components/place-form-panel.hbs +50 -0
  55. package/addon/components/place-form-panel.js +134 -0
  56. package/addon/components/place-panel/details.hbs +95 -0
  57. package/addon/components/place-panel.hbs +30 -0
  58. package/addon/components/place-panel.js +161 -0
  59. package/addon/components/vehicle-form-panel.hbs +35 -44
  60. package/addon/components/vehicle-form-panel.js +41 -0
  61. package/addon/components/vehicle-panel/details.hbs +8 -2
  62. package/addon/components/vehicle-panel.hbs +8 -6
  63. package/addon/components/vendor-form-panel/create-form.hbs +114 -0
  64. package/addon/components/vendor-form-panel/create-form.js +158 -0
  65. package/addon/components/vendor-form-panel/edit-form.hbs +98 -0
  66. package/addon/components/vendor-form-panel/edit-form.js +51 -0
  67. package/addon/components/vendor-form-panel.hbs +48 -0
  68. package/addon/components/vendor-form-panel.js +226 -0
  69. package/addon/components/vendor-panel/details.hbs +77 -0
  70. package/addon/components/vendor-panel/details.js +12 -0
  71. package/addon/components/vendor-panel.hbs +58 -0
  72. package/addon/components/vendor-panel.js +161 -0
  73. package/addon/controllers/management/contacts/index/details.js +55 -0
  74. package/addon/controllers/management/contacts/index/edit.js +111 -0
  75. package/addon/controllers/management/contacts/index/new.js +88 -0
  76. package/addon/controllers/management/contacts/index.js +23 -128
  77. package/addon/controllers/management/drivers/index/new.js +2 -2
  78. package/addon/controllers/management/drivers/index.js +18 -32
  79. package/addon/controllers/management/fleets/index/details.js +53 -0
  80. package/addon/controllers/management/fleets/index/edit.js +75 -41
  81. package/addon/controllers/management/fleets/index/new.js +42 -57
  82. package/addon/controllers/management/fleets/index.js +0 -1
  83. package/addon/controllers/management/fuel-reports/index/details.js +63 -0
  84. package/addon/controllers/management/fuel-reports/index/edit.js +111 -0
  85. package/addon/controllers/management/fuel-reports/index/new.js +95 -0
  86. package/addon/controllers/management/fuel-reports/index.js +57 -127
  87. package/addon/controllers/management/issues/index/details.js +54 -0
  88. package/addon/controllers/management/issues/index/edit.js +111 -0
  89. package/addon/controllers/management/issues/index/new.js +94 -0
  90. package/addon/controllers/management/issues/index.js +131 -26
  91. package/addon/controllers/management/places/index/details.js +55 -0
  92. package/addon/controllers/management/places/index/edit.js +111 -0
  93. package/addon/controllers/management/places/index/new.js +88 -0
  94. package/addon/controllers/management/places/index.js +21 -182
  95. package/addon/controllers/management/vehicles/index/new.js +2 -6
  96. package/addon/controllers/management/vendors/index/details.js +55 -0
  97. package/addon/controllers/management/vendors/index/edit.js +111 -0
  98. package/addon/controllers/management/vendors/index/new.js +88 -0
  99. package/addon/controllers/management/vendors/index.js +43 -247
  100. package/addon/controllers/operations/orders/index.js +29 -15
  101. package/addon/controllers/operations/scheduler/index.js +45 -30
  102. package/addon/routes/management/contacts/index/details.js +14 -0
  103. package/addon/routes/management/contacts/index/edit.js +10 -0
  104. package/addon/routes/management/contacts/index/new.js +3 -0
  105. package/addon/routes/management/contacts/index.js +1 -1
  106. package/addon/routes/management/fleets/index/details.js +1 -1
  107. package/addon/routes/management/fleets/index/edit.js +1 -1
  108. package/addon/routes/management/fleets/index.js +1 -1
  109. package/addon/routes/management/fuel-reports/index/details.js +14 -0
  110. package/addon/routes/management/fuel-reports/index/edit.js +10 -0
  111. package/addon/routes/management/fuel-reports/index/new.js +3 -0
  112. package/addon/routes/management/fuel-reports/index.js +3 -1
  113. package/addon/routes/management/issues/index/details.js +14 -0
  114. package/addon/routes/management/issues/index/edit.js +10 -0
  115. package/addon/routes/management/issues/index/new.js +3 -0
  116. package/addon/routes/management/issues/index.js +1 -1
  117. package/addon/routes/management/places/index/details.js +14 -0
  118. package/addon/routes/management/places/index/edit.js +10 -0
  119. package/addon/routes/management/places/index/new.js +3 -0
  120. package/addon/routes/management/places/index.js +6 -1
  121. package/addon/routes/management/vendors/index/details.js +15 -0
  122. package/addon/routes/management/vendors/index/edit.js +11 -0
  123. package/addon/routes/management/vendors/index/new.js +3 -0
  124. package/addon/routes/management/vendors/index.js +1 -0
  125. package/addon/routes/operations/scheduler/index.js +25 -0
  126. package/addon/routes.js +27 -7
  127. package/addon/services/context-panel.js +60 -0
  128. package/addon/styles/fleetops-engine.css +28 -0
  129. package/addon/templates/management/contacts/index/details.hbs +1 -0
  130. package/addon/templates/management/contacts/index/edit.hbs +1 -0
  131. package/addon/templates/management/contacts/index/new.hbs +1 -0
  132. package/addon/templates/management/contacts/index.hbs +22 -3
  133. package/addon/templates/management/drivers/index.hbs +29 -5
  134. package/addon/templates/management/fleets/index/details.hbs +1 -1
  135. package/addon/templates/management/fleets/index/edit.hbs +1 -1
  136. package/addon/templates/management/fleets/index/new.hbs +1 -1
  137. package/addon/templates/management/fuel-reports/index/details.hbs +1 -0
  138. package/addon/templates/management/fuel-reports/index/edit.hbs +1 -0
  139. package/addon/templates/management/fuel-reports/index/new.hbs +1 -0
  140. package/addon/templates/management/fuel-reports/index.hbs +25 -4
  141. package/addon/templates/management/issues/index/details.hbs +1 -0
  142. package/addon/templates/management/issues/index/edit.hbs +1 -0
  143. package/addon/templates/management/issues/index/new.hbs +1 -0
  144. package/addon/templates/management/issues/index.hbs +5 -3
  145. package/addon/templates/management/places/index/details.hbs +1 -0
  146. package/addon/templates/management/places/index/edit.hbs +1 -0
  147. package/addon/templates/management/places/index/new.hbs +1 -0
  148. package/addon/templates/management/vendors/index/details.hbs +1 -0
  149. package/addon/templates/management/vendors/index/edit.hbs +1 -0
  150. package/addon/templates/management/vendors/index/new.hbs +1 -0
  151. package/addon/templates/operations/orders/index.hbs +5 -5
  152. package/addon/templates/operations/scheduler/index.hbs +33 -9
  153. package/addon/utils/create-full-calendar-event-from-order.js +8 -0
  154. package/app/components/contact-form-panel.js +1 -0
  155. package/app/components/contact-panel/details.js +1 -0
  156. package/app/components/contact-panel.js +1 -0
  157. package/app/components/{full-calendar/draggable.js → fleet-listing-panel.js} +1 -1
  158. package/app/components/fleet-panel/details.js +1 -0
  159. package/app/components/fleet-panel/driver-listing.js +1 -0
  160. package/app/components/fleet-panel/vehicle-listing.js +1 -0
  161. package/app/components/fuel-report-form-panel.js +1 -0
  162. package/app/components/{full-calendar.js → fuel-report-panel.js} +1 -1
  163. package/app/components/issue-form-panel.js +1 -0
  164. package/app/components/issue-panel.js +1 -0
  165. package/app/components/live-map-drawer/driver-listing.js +1 -0
  166. package/app/components/live-map-drawer/place-listing.js +1 -0
  167. package/app/components/live-map-drawer/vehicle-listing.js +1 -0
  168. package/app/components/live-map-drawer.js +1 -0
  169. package/app/components/place-form-panel.js +1 -0
  170. package/app/components/place-panel.js +1 -0
  171. package/app/components/vendor-form-panel/create-form.js +1 -0
  172. package/app/components/vendor-form-panel/edit-form.js +1 -0
  173. package/app/components/vendor-form-panel.js +1 -0
  174. package/app/components/vendor-panel/details.js +1 -0
  175. package/app/components/vendor-panel.js +1 -0
  176. package/app/controllers/management/contacts/index/details.js +1 -0
  177. package/app/controllers/management/contacts/index/edit.js +1 -0
  178. package/app/controllers/management/contacts/index/new.js +1 -0
  179. package/app/controllers/management/fuel-reports/index/details.js +1 -0
  180. package/app/controllers/management/fuel-reports/index/edit.js +1 -0
  181. package/app/controllers/management/fuel-reports/index/new.js +1 -0
  182. package/app/controllers/management/issues/index/details.js +1 -0
  183. package/app/controllers/management/issues/index/edit.js +1 -0
  184. package/app/controllers/management/issues/index/new.js +1 -0
  185. package/app/controllers/management/places/index/details.js +1 -0
  186. package/app/controllers/management/places/index/edit.js +1 -0
  187. package/app/controllers/management/places/index/new.js +1 -0
  188. package/app/controllers/management/vendors/index/edit.js +1 -0
  189. package/app/controllers/management/vendors/index/new.js +1 -0
  190. package/app/routes/addon/routes/management/places/index/new.js +1 -0
  191. package/app/routes/management/contacts/index/details.js +1 -0
  192. package/app/routes/management/contacts/index/edit.js +1 -0
  193. package/app/routes/management/contacts/index/new.js +1 -0
  194. package/app/routes/management/fuel-reports/index/details.js +1 -0
  195. package/app/routes/management/fuel-reports/index/edit.js +1 -0
  196. package/app/routes/management/fuel-reports/index/new.js +1 -0
  197. package/app/routes/management/issues/index/details.js +1 -0
  198. package/app/routes/management/issues/index/edit.js +1 -0
  199. package/app/routes/management/issues/index/new.js +1 -0
  200. package/app/routes/management/places/index/details.js +1 -0
  201. package/app/routes/management/places/index/edit.js +1 -0
  202. package/app/routes/management/places/index/new.js +1 -0
  203. package/app/routes/management/vendors/index/details.js +1 -0
  204. package/app/routes/management/vendors/index/edit.js +1 -0
  205. package/app/routes/management/vendors/index/new.js +1 -0
  206. package/app/templates/addon/routes/management/places/index/new.js +1 -0
  207. package/app/templates/management/contacts/index/details.js +1 -0
  208. package/app/templates/management/contacts/index/edit.js +1 -0
  209. package/app/templates/management/contacts/index/new.js +1 -0
  210. package/app/templates/management/fuel-reports/index/details.js +1 -0
  211. package/app/templates/management/fuel-reports/index/edit.js +1 -0
  212. package/app/templates/management/fuel-reports/index/new.js +1 -0
  213. package/app/templates/management/issues/index/details.js +1 -0
  214. package/app/templates/management/issues/index/edit.js +1 -0
  215. package/app/templates/management/issues/index/new.js +1 -0
  216. package/app/templates/management/places/index/details.js +1 -0
  217. package/app/templates/management/places/index/edit.js +1 -0
  218. package/app/templates/management/places/index/new.js +1 -0
  219. package/app/templates/management/vendors/index/details.js +1 -0
  220. package/app/templates/management/vendors/index/edit.js +1 -0
  221. package/app/templates/management/vendors/index/new.js +1 -0
  222. package/app/utils/create-full-calendar-event-from-order.js +1 -0
  223. package/composer.json +1 -1
  224. package/config/environment.js +2 -1
  225. package/extension.json +1 -1
  226. package/package.json +5 -4
  227. package/server/migrations/2023_11_03_072503_refactor_issues_table_columns.php +42 -0
  228. package/server/migrations/2023_11_06_040645_refactor_fuel_reports_table.php +38 -0
  229. package/server/src/Casts/Point.php +15 -1
  230. package/server/src/Http/Controllers/Internal/v1/DriverController.php +33 -15
  231. package/server/src/Http/Filter/FleetFilter.php +7 -0
  232. package/server/src/Http/Filter/FuelReportFilter.php +58 -0
  233. package/server/src/Http/Filter/IssueFilter.php +69 -0
  234. package/server/src/Http/Filter/VehicleFilter.php +10 -0
  235. package/server/src/Http/Middleware/TransformLocationMiddleware.php +48 -0
  236. package/server/src/Http/Resources/v1/Driver.php +1 -0
  237. package/server/src/Http/Resources/v1/Fleet.php +20 -21
  238. package/server/src/Http/Resources/v1/FuelReport.php +37 -35
  239. package/server/src/Http/Resources/v1/Issue.php +77 -0
  240. package/server/src/Http/Resources/v1/ParentFleet.php +60 -0
  241. package/server/src/Http/Resources/v1/SubFleet.php +60 -0
  242. package/server/src/Http/Resources/v1/Vehicle.php +4 -2
  243. package/server/src/Integrations/Lalamove/Lalamove.php +6 -6
  244. package/server/src/Models/Contact.php +7 -0
  245. package/server/src/Models/Driver.php +1 -1
  246. package/server/src/Models/Fleet.php +35 -4
  247. package/server/src/Models/FuelReport.php +53 -3
  248. package/server/src/Models/Issue.php +106 -7
  249. package/server/src/Models/Order.php +22 -0
  250. package/server/src/Models/Vehicle.php +1 -1
  251. package/server/src/Models/VehicleDevice.php +4 -2
  252. package/server/src/Models/VehicleDeviceEvent.php +8 -4
  253. package/server/src/Notifications/OrderAssigned.php +0 -6
  254. package/server/src/Notifications/OrderCanceled.php +0 -6
  255. package/server/src/Notifications/OrderDispatchFailed.php +0 -6
  256. package/server/src/Notifications/OrderDispatched.php +0 -6
  257. package/server/src/Notifications/OrderPing.php +0 -6
  258. package/server/src/Notifications/OrderSplit.php +0 -6
  259. package/server/src/Observers/FleetObserver.php +19 -0
  260. package/server/src/Providers/FleetOpsServiceProvider.php +1 -0
  261. package/server/src/Providers/NotificationServiceProvider.php +1 -1
  262. package/server/src/routes.php +2 -2
  263. package/addon/components/full-calendar/draggable.js +0 -1
  264. package/addon/components/full-calendar.js +0 -1
@@ -0,0 +1,240 @@
1
+ import Component from '@glimmer/component';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { inject as service } from '@ember/service';
4
+ import { action } from '@ember/object';
5
+ import { isBlank } from '@ember/utils';
6
+ import { later } from '@ember/runloop';
7
+ import getWithDefault from '@fleetbase/ember-core/utils/get-with-default';
8
+
9
+ /**
10
+ * Represents a live map drawer driver listing component.
11
+ * This component is responsible for displaying and interacting with a list of drivers on a live map.
12
+ *
13
+ * @extends Component
14
+ */
15
+ export default class LiveMapDrawerDriverListingComponent extends Component {
16
+ /**
17
+ * Service for managing context panels within the application.
18
+ * @service
19
+ */
20
+ @service contextPanel;
21
+
22
+ /**
23
+ * Service for triggering notifications.
24
+ * @service
25
+ */
26
+ @service notifications;
27
+
28
+ /**
29
+ * Service for triggering notifications.
30
+ * @service
31
+ */
32
+ @service hostRouter;
33
+
34
+ /**
35
+ * Service for CRUD operations.
36
+ * @service
37
+ */
38
+ @service crud;
39
+
40
+ /**
41
+ * The list of drivers to display, tracked for reactivity.
42
+ * @tracked
43
+ */
44
+ @tracked drivers = [];
45
+
46
+ /**
47
+ * The internal list of drivers used for searching, tracked for reactivity.
48
+ * @tracked
49
+ */
50
+ @tracked _drivers = [];
51
+
52
+ /**
53
+ * The current search query, tracked for reactivity.
54
+ * @tracked
55
+ */
56
+ @tracked query = '';
57
+
58
+ /**
59
+ * The table component reference, tracked for reactivity.
60
+ * @tracked
61
+ */
62
+ @tracked table = null;
63
+
64
+ /**
65
+ * The configuration for table columns including details like label, valuePath, and cellComponent,
66
+ * tracked for reactivity.
67
+ * @tracked
68
+ */
69
+ @tracked columns = [
70
+ {
71
+ label: 'Driver',
72
+ valuePath: 'name',
73
+ photoPath: 'photo_url',
74
+ width: '100px',
75
+ cellComponent: 'cell/driver-name',
76
+ onClick: this.focus,
77
+ },
78
+ {
79
+ label: 'Location',
80
+ valuePath: 'location',
81
+ width: '80px',
82
+ cellComponent: 'table/cell/point',
83
+ onClick: this.locate,
84
+ },
85
+ {
86
+ label: 'Current Job',
87
+ valuePath: 'current_job_id',
88
+ width: '80px',
89
+ cellComponent: 'table/cell/anchor',
90
+ onClick: this.job,
91
+ },
92
+ {
93
+ label: 'Status',
94
+ valuePath: 'status',
95
+ cellComponent: 'table/cell/status',
96
+ width: '60px',
97
+ },
98
+ {
99
+ label: 'Last Seen',
100
+ valuePath: 'updatedAgo',
101
+ width: '60px',
102
+ },
103
+ {
104
+ label: '',
105
+ cellComponent: 'table/cell/dropdown',
106
+ ddButtonText: false,
107
+ ddButtonIcon: 'ellipsis-h',
108
+ ddButtonIconPrefix: 'fas',
109
+ ddMenuLabel: 'Actions',
110
+ cellClassNames: 'overflow-visible',
111
+ wrapperClass: 'flex items-center justify-end mx-2',
112
+ width: '90px',
113
+ actions: [
114
+ {
115
+ label: 'View driver details...',
116
+ fn: this.focus,
117
+ },
118
+ {
119
+ label: 'Edit driver...',
120
+ fn: (driver) => {
121
+ return this.focus(driver, 'editing');
122
+ },
123
+ },
124
+ {
125
+ label: 'Locate driver...',
126
+ fn: this.locate,
127
+ },
128
+ {
129
+ label: 'Delete driver...',
130
+ fn: this.delete,
131
+ },
132
+ ],
133
+ sortable: false,
134
+ filterable: false,
135
+ resizable: false,
136
+ searchable: false,
137
+ },
138
+ ];
139
+
140
+ /**
141
+ * Initializes the component with drivers passed in from `this.args` and sets up the live map reference.
142
+ */
143
+ constructor() {
144
+ super(...arguments);
145
+ this.drivers = getWithDefault(this.args, 'drivers', []);
146
+ this._drivers = [...this.drivers];
147
+ this.liveMap = this.args.liveMap;
148
+ }
149
+
150
+ /**
151
+ * Filters the drivers list based on a query.
152
+ *
153
+ * @param {string} query - The query string to filter the drivers list.
154
+ */
155
+ search(query) {
156
+ if (typeof query !== 'string' && !isBlank(query)) {
157
+ return;
158
+ }
159
+
160
+ this.drivers = [
161
+ ...this._drivers.filter((driver) => {
162
+ return typeof driver.name === 'string' && driver.name.toLowerCase().includes(query.toLowerCase());
163
+ }),
164
+ ];
165
+ }
166
+
167
+ /**
168
+ * Action to perform a search based on the input event's value.
169
+ *
170
+ * @param {Event} event - The input event containing the search value.
171
+ */
172
+ @action performSearch({ target: { value } }) {
173
+ this.search(value);
174
+ }
175
+
176
+ /**
177
+ * Action to focus on a driver in the live map and context panel.
178
+ *
179
+ * @param {object} driver - The driver object to focus on.
180
+ * @param {string} intent - The intent for focusing, default is 'viewing'.
181
+ */
182
+ @action focus(driver, intent = 'viewing') {
183
+ if (this.liveMap) {
184
+ this.liveMap.focusLayerByRecord(driver, 16, {
185
+ onAfterFocusWithRecord: () => {
186
+ later(
187
+ this,
188
+ () => {
189
+ this.contextPanel.focus(driver, intent);
190
+ },
191
+ 600 * 2
192
+ );
193
+ },
194
+ });
195
+ } else {
196
+ this.contextPanel.focus(driver, intent);
197
+ }
198
+ }
199
+
200
+ /**
201
+ * Action to locate a driver on the live map.
202
+ *
203
+ * @param {object} driver - The driver object to locate.
204
+ */
205
+ @action locate(driver) {
206
+ if (this.liveMap) {
207
+ this.liveMap.focusLayerByRecord(driver, 18);
208
+ } else {
209
+ this.notifications.warning('Unable to locate driver.');
210
+ }
211
+ }
212
+
213
+ /**
214
+ * Transitino to view the drivers current job
215
+ *
216
+ * @param {DriverModel} driver
217
+ * @memberof LiveMapDrawerDriverListingComponent
218
+ */
219
+ @action job(driver) {
220
+ if (driver.current_job_id) {
221
+ this.hostRouter.transitionTo('console.fleet-ops.operations.orders.index.view', driver.current_job_id);
222
+ }
223
+ }
224
+
225
+ /**
226
+ * Action to delete a driver from the list and perform cleanup.
227
+ *
228
+ * @param {object} driver - The driver object to delete.
229
+ * @param {object} options - Additional options for the delete operation.
230
+ */
231
+ @action delete(driver, options = {}) {
232
+ this.crud.delete(driver, {
233
+ onSuccess: () => {
234
+ this._drivers.removeObject(driver);
235
+ this.drivers.removeObject(driver);
236
+ },
237
+ ...options,
238
+ });
239
+ }
240
+ }
@@ -0,0 +1,6 @@
1
+ <div class="flex flex-row items-center px-5 py-2 border-b border-gray-200 dark:border-gray-700">
2
+ <div>
3
+ <Input @value={{this.query}} {{on "input" this.performSearch}} @type="text" class="form-input form-input-sm w-60" placeholder="Filter places by keyword..." />
4
+ </div>
5
+ </div>
6
+ <Table @rows={{this.places}} @columns={{this.columns}} @onSetup={{fn (mut this.table)}} />
@@ -0,0 +1,204 @@
1
+ import Component from '@glimmer/component';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { inject as service } from '@ember/service';
4
+ import { action } from '@ember/object';
5
+ import { isBlank } from '@ember/utils';
6
+ import { later } from '@ember/runloop';
7
+ import getWithDefault from '@fleetbase/ember-core/utils/get-with-default';
8
+
9
+ /**
10
+ * Represents a live map drawer place listing component.
11
+ * This component is responsible for displaying and interacting with a list of places on a live map.
12
+ *
13
+ * @extends Component
14
+ */
15
+ export default class LiveMapDrawerPlaceListingComponent extends Component {
16
+ /**
17
+ * Service for managing context panels within the application.
18
+ * @service
19
+ */
20
+ @service contextPanel;
21
+
22
+ /**
23
+ * Service for triggering notifications.
24
+ * @service
25
+ */
26
+ @service notifications;
27
+
28
+ /**
29
+ * Service for CRUD operations.
30
+ * @service
31
+ */
32
+ @service crud;
33
+
34
+ /**
35
+ * The list of places to display, tracked for reactivity.
36
+ * @tracked
37
+ */
38
+ @tracked places = [];
39
+
40
+ /**
41
+ * The internal list of places used for searching, tracked for reactivity.
42
+ * @tracked
43
+ */
44
+ @tracked _places = [];
45
+
46
+ /**
47
+ * The current search query, tracked for reactivity.
48
+ * @tracked
49
+ */
50
+ @tracked query = '';
51
+
52
+ /**
53
+ * The table component reference, tracked for reactivity.
54
+ * @tracked
55
+ */
56
+ @tracked table = null;
57
+
58
+ /**
59
+ * The configuration for table columns including details like label, valuePath, and cellComponent,
60
+ * tracked for reactivity.
61
+ * @tracked
62
+ */
63
+ @tracked columns = [
64
+ {
65
+ label: 'Place',
66
+ valuePath: 'address',
67
+ width: '200px',
68
+ cellComponent: 'table/cell/anchor',
69
+ onClick: this.focus,
70
+ showOnlineIndicator: true,
71
+ },
72
+ {
73
+ label: 'Location',
74
+ valuePath: 'location',
75
+ width: '80px',
76
+ cellComponent: 'table/cell/point',
77
+ onClick: this.locate,
78
+ },
79
+ {
80
+ label: '',
81
+ cellComponent: 'table/cell/dropdown',
82
+ ddButtonText: false,
83
+ ddButtonIcon: 'ellipsis-h',
84
+ ddButtonIconPrefix: 'fas',
85
+ ddMenuLabel: 'Actions',
86
+ cellClassNames: 'overflow-visible',
87
+ wrapperClass: 'flex items-center justify-end mx-2',
88
+ width: '90px',
89
+ actions: [
90
+ {
91
+ label: 'View place details...',
92
+ fn: this.focus,
93
+ },
94
+ {
95
+ label: 'Edit place...',
96
+ fn: (place) => {
97
+ return this.focus(place, 'editing');
98
+ },
99
+ },
100
+ {
101
+ label: 'Locate place...',
102
+ fn: this.locate,
103
+ },
104
+ {
105
+ label: 'Delete place...',
106
+ fn: this.delete,
107
+ },
108
+ ],
109
+ sortable: false,
110
+ filterable: false,
111
+ resizable: false,
112
+ searchable: false,
113
+ },
114
+ ];
115
+
116
+ /**
117
+ * Initializes the component with places passed in from `this.args` and sets up the live map reference.
118
+ */
119
+ constructor() {
120
+ super(...arguments);
121
+ this.places = getWithDefault(this.args, 'places', []);
122
+ this._places = [...this.places];
123
+ this.liveMap = this.args.liveMap;
124
+ }
125
+
126
+ /**
127
+ * Filters the places list based on a query.
128
+ *
129
+ * @param {string} query - The query string to filter the places list.
130
+ */
131
+ search(query) {
132
+ if (typeof query !== 'string' && !isBlank(query)) {
133
+ return;
134
+ }
135
+
136
+ this.places = [
137
+ ...this._places.filter((place) => {
138
+ return typeof place.address === 'string' && place.address.toLowerCase().includes(query.toLowerCase());
139
+ }),
140
+ ];
141
+ }
142
+
143
+ /**
144
+ * Action to perform a search based on the input event's value.
145
+ *
146
+ * @param {Event} event - The input event containing the search value.
147
+ */
148
+ @action performSearch({ target: { value } }) {
149
+ this.search(value);
150
+ }
151
+
152
+ /**
153
+ * Action to focus on a place in the live map and context panel.
154
+ *
155
+ * @param {object} place - The place object to focus on.
156
+ * @param {string} intent - The intent for focusing, default is 'viewing'.
157
+ */
158
+ @action focus(place, intent = 'viewing') {
159
+ if (this.liveMap) {
160
+ this.liveMap.focusLayerByRecord(place, 17, {
161
+ onAfterFocusWithRecord: () => {
162
+ later(
163
+ this,
164
+ () => {
165
+ this.contextPanel.focus(place, intent);
166
+ },
167
+ 600 * 2
168
+ );
169
+ },
170
+ });
171
+ } else {
172
+ this.contextPanel.focus(place, intent);
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Action to locate a place on the live map.
178
+ *
179
+ * @param {object} place - The place object to locate.
180
+ */
181
+ @action locate(place) {
182
+ if (this.liveMap) {
183
+ this.liveMap.focusLayerByRecord(place, 18);
184
+ } else {
185
+ this.notifications.warning('Unable to locate place.');
186
+ }
187
+ }
188
+
189
+ /**
190
+ * Action to delete a place from the list and perform cleanup.
191
+ *
192
+ * @param {object} place - The place object to delete.
193
+ * @param {object} options - Additional options for the delete operation.
194
+ */
195
+ @action delete(place, options = {}) {
196
+ this.crud.delete(place, {
197
+ onSuccess: () => {
198
+ this._places.removeObject(place);
199
+ this.places.removeObject(place);
200
+ },
201
+ ...options,
202
+ });
203
+ }
204
+ }
@@ -0,0 +1,6 @@
1
+ <div class="flex flex-row items-center px-5 py-2 border-b border-gray-200 dark:border-gray-700">
2
+ <div>
3
+ <Input @value={{this.query}} {{on "input" this.performSearch}} @type="text" class="form-input form-input-sm w-60" placeholder="Filter vehicles by keyword..." />
4
+ </div>
5
+ </div>
6
+ <Table @rows={{this.vehicles}} @columns={{this.columns}} @onSetup={{fn (mut this.table)}} />
@@ -0,0 +1,216 @@
1
+ import Component from '@glimmer/component';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { inject as service } from '@ember/service';
4
+ import { action } from '@ember/object';
5
+ import { isBlank } from '@ember/utils';
6
+ import { later } from '@ember/runloop';
7
+ import getWithDefault from '@fleetbase/ember-core/utils/get-with-default';
8
+
9
+ /**
10
+ * Represents a live map drawer vehicle listing component.
11
+ * This component is responsible for displaying and interacting with a list of vehicles on a live map.
12
+ *
13
+ * @extends Component
14
+ */
15
+ export default class LiveMapDrawerVehicleListingComponent extends Component {
16
+ /**
17
+ * Service for managing context panels within the application.
18
+ * @service
19
+ */
20
+ @service contextPanel;
21
+
22
+ /**
23
+ * Service for triggering notifications.
24
+ * @service
25
+ */
26
+ @service notifications;
27
+
28
+ /**
29
+ * Service for CRUD operations.
30
+ * @service
31
+ */
32
+ @service crud;
33
+
34
+ /**
35
+ * The list of vehicles to display, tracked for reactivity.
36
+ * @tracked
37
+ */
38
+ @tracked vehicles = [];
39
+
40
+ /**
41
+ * The internal list of vehicles used for searching, tracked for reactivity.
42
+ * @tracked
43
+ */
44
+ @tracked _vehicles = [];
45
+
46
+ /**
47
+ * The current search query, tracked for reactivity.
48
+ * @tracked
49
+ */
50
+ @tracked query = '';
51
+
52
+ /**
53
+ * The table component reference, tracked for reactivity.
54
+ * @tracked
55
+ */
56
+ @tracked table = null;
57
+
58
+ /**
59
+ * The configuration for table columns including details like label, valuePath, and cellComponent,
60
+ * tracked for reactivity.
61
+ * @tracked
62
+ */
63
+ @tracked columns = [
64
+ {
65
+ label: 'Vehicle',
66
+ valuePath: 'display_name',
67
+ photoPath: 'avatar_url',
68
+ width: '100px',
69
+ cellComponent: 'table/cell/vehicle-name',
70
+ onClick: this.focus,
71
+ showOnlineIndicator: true,
72
+ },
73
+ {
74
+ label: 'Location',
75
+ valuePath: 'location',
76
+ width: '80px',
77
+ cellComponent: 'table/cell/point',
78
+ onClick: this.locate,
79
+ },
80
+ {
81
+ label: 'Status',
82
+ valuePath: 'status',
83
+ cellComponent: 'table/cell/status',
84
+ width: '60px',
85
+ },
86
+ {
87
+ label: 'Last Seen',
88
+ valuePath: 'updatedAgo',
89
+ width: '60px',
90
+ },
91
+ {
92
+ label: '',
93
+ cellComponent: 'table/cell/dropdown',
94
+ ddButtonText: false,
95
+ ddButtonIcon: 'ellipsis-h',
96
+ ddButtonIconPrefix: 'fas',
97
+ ddMenuLabel: 'Actions',
98
+ cellClassNames: 'overflow-visible',
99
+ wrapperClass: 'flex items-center justify-end mx-2',
100
+ width: '90px',
101
+ actions: [
102
+ {
103
+ label: 'View vehicle details...',
104
+ fn: this.focus,
105
+ },
106
+ {
107
+ label: 'Edit vehicle...',
108
+ fn: (vehicle) => {
109
+ return this.focus(vehicle, 'editing');
110
+ },
111
+ },
112
+ {
113
+ label: 'Locate vehicle...',
114
+ fn: this.locate,
115
+ },
116
+ {
117
+ label: 'Delete vehicle...',
118
+ fn: this.delete,
119
+ },
120
+ ],
121
+ sortable: false,
122
+ filterable: false,
123
+ resizable: false,
124
+ searchable: false,
125
+ },
126
+ ];
127
+
128
+ /**
129
+ * Initializes the component with vehicles passed in from `this.args` and sets up the live map reference.
130
+ */
131
+ constructor() {
132
+ super(...arguments);
133
+ this.vehicles = getWithDefault(this.args, 'vehicles', []);
134
+ this._vehicles = [...this.vehicles];
135
+ this.liveMap = this.args.liveMap;
136
+ }
137
+
138
+ /**
139
+ * Filters the vehicles list based on a query.
140
+ *
141
+ * @param {string} query - The query string to filter the vehicles list.
142
+ */
143
+ search(query) {
144
+ if (typeof query !== 'string' && !isBlank(query)) {
145
+ return;
146
+ }
147
+
148
+ this.vehicles = [
149
+ ...this._vehicles.filter((vehicle) => {
150
+ return typeof vehicle.displayName === 'string' && vehicle.displayName.toLowerCase().includes(query.toLowerCase());
151
+ }),
152
+ ];
153
+ }
154
+
155
+ /**
156
+ * Action to perform a search based on the input event's value.
157
+ *
158
+ * @param {Event} event - The input event containing the search value.
159
+ */
160
+ @action performSearch({ target: { value } }) {
161
+ this.search(value);
162
+ }
163
+
164
+ /**
165
+ * Action to focus on a vehicle in the live map and context panel.
166
+ *
167
+ * @param {object} vehicle - The vehicle object to focus on.
168
+ * @param {string} intent - The intent for focusing, default is 'viewing'.
169
+ */
170
+ @action focus(vehicle, intent = 'viewing') {
171
+ if (this.liveMap) {
172
+ this.liveMap.focusLayerByRecord(vehicle, 16, {
173
+ onAfterFocusWithRecord: () => {
174
+ later(
175
+ this,
176
+ () => {
177
+ this.contextPanel.focus(vehicle, intent);
178
+ },
179
+ 600 * 2
180
+ );
181
+ },
182
+ });
183
+ } else {
184
+ this.contextPanel.focus(vehicle, intent);
185
+ }
186
+ }
187
+
188
+ /**
189
+ * Action to locate a vehicle on the live map.
190
+ *
191
+ * @param {object} vehicle - The vehicle object to locate.
192
+ */
193
+ @action locate(vehicle) {
194
+ if (this.liveMap) {
195
+ this.liveMap.focusLayerByRecord(vehicle, 18);
196
+ } else {
197
+ this.notifications.warning('Unable to locate vehicle.');
198
+ }
199
+ }
200
+
201
+ /**
202
+ * Action to delete a vehicle from the list and perform cleanup.
203
+ *
204
+ * @param {object} vehicle - The vehicle object to delete.
205
+ * @param {object} options - Additional options for the delete operation.
206
+ */
207
+ @action delete(vehicle, options = {}) {
208
+ this.crud.delete(vehicle, {
209
+ onSuccess: () => {
210
+ this._vehicles.removeObject(vehicle);
211
+ this.vehicles.removeObject(vehicle);
212
+ },
213
+ ...options,
214
+ });
215
+ }
216
+ }
@@ -0,0 +1,17 @@
1
+ <Drawer @isMinimized={{true}} @notchEnabled={{true}} @onLoad={{this.setDrawerContext}}>
2
+ <div class="ui-tabs pt-4">
3
+ <nav>
4
+ {{#each this.tabs as |tab|}}
5
+ <a href="javascript:;" class="ui-tab {{if (eq this.tab.slug tab.slug) 'active' }}" {{on "click" (fn this.onTabChanged tab.slug)}}>
6
+ <FaIcon @icon={{tab.icon}} class="mr-1" />
7
+ <span>{{tab.title}}</span>
8
+ </a>
9
+ {{/each}}
10
+ </nav>
11
+ </div>
12
+ <div class="tab-content tab-{{this.tab.slug}}">
13
+ {{#if this.drawer}}
14
+ {{component this.tab.component drivers=@drivers vehicles=@vehicles places=@places drawer=this.drawer liveMap=@liveMap tabOptions=this.tab options=this.tab.componentParams}}
15
+ {{/if}}
16
+ </div>
17
+ </Drawer>