@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,134 @@
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 contextComponentCallback from '../utils/context-component-callback';
6
+ import applyContextComponentArguments from '../utils/apply-context-component-arguments';
7
+
8
+ export default class PlaceFormPanelComponent extends Component {
9
+ /**
10
+ * @service store
11
+ */
12
+ @service store;
13
+
14
+ /**
15
+ * @service fetch
16
+ */
17
+ @service fetch;
18
+
19
+ /**
20
+ * @service notifications
21
+ */
22
+ @service notifications;
23
+
24
+ /**
25
+ * @service hostRouter
26
+ */
27
+ @service hostRouter;
28
+
29
+ /**
30
+ * @service loader
31
+ */
32
+ @service loader;
33
+
34
+ /**
35
+ * @service contextPanel
36
+ */
37
+ @service contextPanel;
38
+
39
+ /**
40
+ * Overlay context.
41
+ * @type {any}
42
+ */
43
+ @tracked context;
44
+
45
+ /**
46
+ * Indicates whether the component is in a loading state.
47
+ * @type {boolean}
48
+ */
49
+ @tracked isLoading = false;
50
+
51
+ /**
52
+ * All possible place types
53
+ *
54
+ * @var {String}
55
+ */
56
+ @tracked placeTypes = ['place', 'customer'];
57
+
58
+ /**
59
+ * Constructs the component and applies initial state.
60
+ */
61
+ constructor() {
62
+ super(...arguments);
63
+ this.place = this.args.place;
64
+ applyContextComponentArguments(this);
65
+ }
66
+
67
+ /**
68
+ * Sets the overlay context.
69
+ *
70
+ * @action
71
+ * @param {OverlayContextObject} overlayContext
72
+ */
73
+ @action setOverlayContext(overlayContext) {
74
+ this.context = overlayContext;
75
+ contextComponentCallback(this, 'onLoad', ...arguments);
76
+ }
77
+
78
+ /**
79
+ * Saves the place changes.
80
+ *
81
+ * @action
82
+ * @returns {Promise<any>}
83
+ */
84
+ @action save() {
85
+ const { place } = this;
86
+
87
+ this.loader.showLoader('.next-content-overlay-panel-container', { loadingMessage: 'Saving place...', preserveTargetPosition: true });
88
+ this.isLoading = true;
89
+
90
+ contextComponentCallback(this, 'onBeforeSave', place);
91
+
92
+ try {
93
+ return place
94
+ .save()
95
+ .then((place) => {
96
+ this.notifications.success(`place (${place.address}) saved successfully.`);
97
+ contextComponentCallback(this, 'onAfterSave', place);
98
+ })
99
+ .catch((error) => {
100
+ this.notifications.serverError(error);
101
+ })
102
+ .finally(() => {
103
+ this.loader.removeLoader('.next-content-overlay-panel-container ');
104
+ this.isLoading = false;
105
+ });
106
+ } catch (error) {
107
+ this.loader.removeLoader('.next-content-overlay-panel-container ');
108
+ this.isLoading = false;
109
+ }
110
+ }
111
+
112
+ /**
113
+ * View the details of the place.
114
+ *
115
+ * @action
116
+ */
117
+ @action onViewDetails() {
118
+ const isActionOverrided = contextComponentCallback(this, 'onViewDetails', this.place);
119
+
120
+ if (!isActionOverrided) {
121
+ this.contextPanel.focus(this.place, 'viewing');
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Handles cancel button press.
127
+ *
128
+ * @action
129
+ * @returns {any}
130
+ */
131
+ @action onPressCancel() {
132
+ return contextComponentCallback(this, 'onPressCancel', this.place);
133
+ }
134
+ }
@@ -0,0 +1,95 @@
1
+ <div class="p-4 space-y-4">
2
+ <ContentPanel @title="Map" @open={{false}}>
3
+ <LeafletMap class="w-full h-48 rounded-b-md shadow-md" @lat={{@place.latitude}} @lng={{@place.longitude}} @zoom={{17}} @zoomControl={{false}} as |layers|>
4
+ <layers.tile @url="https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png" />
5
+ <layers.marker @id={{@place.id}} @icon={{icon iconUrl="/engines-dist/images/building-marker.png" iconSize=(array 16 16)}} @location={{point-to-coordinates @place.location}} @riseOnHover={{true}} @title={{@place.address}} @alt={{@place.address}} as |marker|>
6
+ <marker.popup>
7
+ <div>{{@place.address}}</div>
8
+ <div>{{format-point @place.location}}</div>
9
+ </marker.popup>
10
+ <marker.tooltip @permanent={{false}} @sticky={{true}} @direction="bottom">{{@place.name}}</marker.tooltip>
11
+ </layers.marker>
12
+ </LeafletMap>
13
+ </ContentPanel>
14
+ <ContentPanel @title="Details" @open={{true}} @pad={{true}} @panelBodyClass="bg-white dark:bg-gray-900">
15
+ <div class="grid grid-cols-1 lg:grid-cols-3 gap-2 text-xs dark:text-gray-100">
16
+ <div class="field-info-container col-span-3">
17
+ <div class="field-name">Name</div>
18
+ <div class="field-value">{{n-a @place.name}}</div>
19
+ </div>
20
+
21
+ <div class="field-info-container col-span-3">
22
+ <div class="field-name">Street</div>
23
+ <div class="field-value">{{n-a @place.street1}}</div>
24
+ </div>
25
+
26
+ <div class="field-info-container">
27
+ <div class="field-name">Neighborhood</div>
28
+ <div class="field-value">{{n-a @place.neighborhood}}</div>
29
+ </div>
30
+
31
+ <div class="field-info-container">
32
+ <div class="field-name">Building</div>
33
+ <div class="field-value">{{n-a @place.building}}</div>
34
+ </div>
35
+
36
+ <div class="field-info-container">
37
+ <div class="field-name">Security Access Code</div>
38
+ <div class="field-value">{{n-a @place.security_access_code}}</div>
39
+ </div>
40
+
41
+ <div class="field-info-container">
42
+ <div class="field-name">City</div>
43
+ <div class="field-value">{{n-a @place.city}}</div>
44
+ </div>
45
+
46
+ <div class="field-info-container">
47
+ <div class="field-name">State</div>
48
+ <div class="field-value">{{n-a @place.province}}</div>
49
+ </div>
50
+
51
+ <div class="field-info-container">
52
+ <div class="field-name">Country</div>
53
+ <div class="field-value">
54
+ <CountryName @country={{@place.country}} @showFlag={{true}} />
55
+ </div>
56
+ </div>
57
+
58
+ <div class="field-info-container">
59
+ <div class="field-name">Phone</div>
60
+ <div class="field-value">{{n-a @place.phone}}</div>
61
+ </div>
62
+
63
+ <div class="field-info-container">
64
+ <div class="field-name">Email</div>
65
+ <div class="field-value">{{n-a @place.email}}</div>
66
+ </div>
67
+
68
+ <div class="field-info-container">
69
+ <div class="field-name">Vendor</div>
70
+ <div class="field-value">
71
+ {{#if @place.vendor_uuid}}
72
+ <a href="javascript:;" {{on "click" @place.viewVendor}}>
73
+ {{@place.vendor_name}}
74
+ </a>
75
+ {{else}}
76
+ {{@place.vendor_name}}
77
+ {{/if}}
78
+ </div>
79
+ </div>
80
+
81
+ <div class="field-info-container col-span-3">
82
+ <div class="field-name">
83
+ Coordinates
84
+ {{!-- <a href="javascript:;" class="block ml-3" {{on "click" @place.viewPlaceOnMap}}>
85
+ <FaIcon @icon="map" class="mr-1" />
86
+ View on map
87
+ </a> --}}
88
+ </div>
89
+ <div class="field-value">
90
+ {{point-coordinates @place.location}}
91
+ </div>
92
+ </div>
93
+ </div>
94
+ </ContentPanel>
95
+ </div>
@@ -0,0 +1,30 @@
1
+ <Overlay
2
+ @onLoad={{this.setOverlayContext}}
3
+ @position="right"
4
+ @noBackdrop={{true}}
5
+ @fullHeight={{true}}
6
+ @isResizable={{or this.isResizable @isResizable}}
7
+ @width={{or this.width @width "600px"}}
8
+ >
9
+ <Overlay::Header @title={{this.place.name}} @status={{this.place.public_id}} @hideStatusDot={{true}} @createdAt={{this.place.createdAt}}>
10
+ <Button @type="default" @icon="pen" @helpText="Edit place" @onClick={{this.onEdit}} @wrapperClass="mr-2" />
11
+ <Button @type="default" @icon="times" @helpText={{if this.place.id "Cancel edit place" "Cancel new place"}} @onClick={{this.onPressCancel}} />
12
+ </Overlay::Header>
13
+ <Overlay::Body class="no-padding" @increaseInnerBodyHeightBy={{1000}}>
14
+ <div class="section-header-actions w-full overflow-x-scroll lg:overflow-x-auto">
15
+ <div class="ui-tabs mt-4">
16
+ <nav>
17
+ {{#each this.tabs as |tab|}}
18
+ <a href="javascript:;" class="ui-tab {{if (eq this.tab.slug tab.slug) 'active'}}" {{on "click" (fn this.onTabChanged tab.slug)}}>
19
+ <FaIcon @icon={{tab.icon}} class="mr-1" />
20
+ <span>{{tab.title}}</span>
21
+ </a>
22
+ {{/each}}
23
+ </nav>
24
+ </div>
25
+ </div>
26
+ <div class="tab-content tab-{{this.tab.slug}}">
27
+ {{component this.tab.component place=this.place tabOptions=this.tab options=this.tab.componentParams}}
28
+ </div>
29
+ </Overlay::Body>
30
+ </Overlay>
@@ -0,0 +1,161 @@
1
+ import Component from '@glimmer/component';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { action } from '@ember/object';
4
+ import { inject as service } from '@ember/service';
5
+ import { isArray } from '@ember/array';
6
+ import PlacePanelDetailComponent from './place-panel/details';
7
+ import contextComponentCallback from '../utils/context-component-callback';
8
+ import applyContextComponentArguments from '../utils/apply-context-component-arguments';
9
+
10
+ export default class PlacePanelComponent extends Component {
11
+ /**
12
+ * Service for fetching data.
13
+ *
14
+ * @type {Service}
15
+ */
16
+ @service fetch;
17
+
18
+ /**
19
+ * Service for managing modals.
20
+ *
21
+ * @type {Service}
22
+ */
23
+ @service modalsManager;
24
+
25
+ /**
26
+ * Universe service for managing global data and settings.
27
+ *
28
+ * @type {Service}
29
+ */
30
+ @service universe;
31
+
32
+ /**
33
+ * Ember data store service.
34
+ *
35
+ * @type {Service}
36
+ */
37
+ @service store;
38
+
39
+ /**
40
+ * Service for managing routing within the host app.
41
+ *
42
+ * @type {Service}
43
+ */
44
+ @service hostRouter;
45
+
46
+ /**
47
+ * Service for managing the context panel.
48
+ *
49
+ * @type {Service}
50
+ */
51
+ @service contextPanel;
52
+
53
+ /**
54
+ * The current active tab.
55
+ *
56
+ * @type {Object}
57
+ * @tracked
58
+ */
59
+ @tracked tab;
60
+
61
+ /**
62
+ * The place being displayed or edited.
63
+ *
64
+ * @type {placeModel}
65
+ * @tracked
66
+ */
67
+ @tracked place;
68
+
69
+ /**
70
+ * Returns the array of tabs available for the panel.
71
+ *
72
+ * @type {Array}
73
+ */
74
+ get tabs() {
75
+ const registeredTabs = this.universe.getMenuItemsFromRegistry('component:place-panel');
76
+ // this.universe._createMenuItem('Tracking', null, { icon: 'satellite-dish', component: placePanelTrackingComponent }),
77
+ const defaultTabs = [this.universe._createMenuItem('Details', null, { icon: 'circle-info', component: PlacePanelDetailComponent })];
78
+
79
+ if (isArray(registeredTabs)) {
80
+ return [...defaultTabs, ...registeredTabs];
81
+ }
82
+
83
+ return defaultTabs;
84
+ }
85
+
86
+ /**
87
+ * Initializes the place panel component.
88
+ */
89
+ constructor() {
90
+ super(...arguments);
91
+ this.place = this.args.place;
92
+ this.tab = this.getTabUsingSlug(this.args.tab);
93
+ applyContextComponentArguments(this);
94
+ }
95
+
96
+ /**
97
+ * Sets the overlay context.
98
+ *
99
+ * @action
100
+ * @param {OverlayContextObject} overlayContext
101
+ */
102
+ @action setOverlayContext(overlayContext) {
103
+ this.context = overlayContext;
104
+ contextComponentCallback(this, 'onLoad', ...arguments);
105
+ }
106
+
107
+ /**
108
+ * Handles changing the active tab.
109
+ *
110
+ * @method
111
+ * @param {String} tab - The new tab to switch to.
112
+ * @action
113
+ */
114
+ @action onTabChanged(tab) {
115
+ this.tab = this.getTabUsingSlug(tab);
116
+ contextComponentCallback(this, 'onTabChanged', tab);
117
+ }
118
+
119
+ /**
120
+ * Handles edit action for the place.
121
+ *
122
+ * @method
123
+ * @action
124
+ */
125
+ @action onEdit() {
126
+ const isActionOverrided = contextComponentCallback(this, 'onEdit', this.place);
127
+
128
+ if (!isActionOverrided) {
129
+ this.contextPanel.focus(this.place, 'editing', {
130
+ onAfterSave: () => {
131
+ this.contextPanel.clear();
132
+ },
133
+ });
134
+ }
135
+ }
136
+
137
+ /**
138
+ * Handles the cancel action.
139
+ *
140
+ * @method
141
+ * @action
142
+ * @returns {Boolean} Indicates whether the cancel action was overridden.
143
+ */
144
+ @action onPressCancel() {
145
+ return contextComponentCallback(this, 'onPressCancel', this.place);
146
+ }
147
+
148
+ /**
149
+ * Finds and returns a tab based on its slug.
150
+ *
151
+ * @param {String} tabSlug - The slug of the tab.
152
+ * @returns {Object|null} The found tab or null.
153
+ */
154
+ getTabUsingSlug(tabSlug) {
155
+ if (tabSlug) {
156
+ return this.tabs.find(({ slug }) => slug === tabSlug);
157
+ }
158
+
159
+ return this.tabs[0];
160
+ }
161
+ }
@@ -16,11 +16,16 @@
16
16
  <div class="flex flex-row justify-between w-full">
17
17
  <div class="flex flex-col flex-1 w-3/4">
18
18
  <div class="flex flex-row">
19
- <div class="w-14 flex items-center justify-center">
20
- <Image src={{this.vehicle.photo_url}} @fallbackSrc={{config "defaultValues.vehicleImage"}} alt={{this.vehicle.name}} height="48" width="48" class="h-12 w-12" />
21
- <Attach::Tooltip @class="clean" @animation="scale" @placement={{"top"}}>
22
- <InputInfo @text={{this.vehicle.public_id}} />
23
- </Attach::Tooltip>
19
+ <div class="w-14">
20
+ <div class="upload-avatar-overlay w-12 h-12 flex items-center justify-start rounded-lg">
21
+ <img src={{this.vehicle.photo_url}} alt={{this.vehicle.name}} height="48" width="48" class="h-12 w-12 rounded-lg shadow-sm" />
22
+ <Attach::Tooltip @class="clean" @animation="scale" @placement="top">
23
+ <InputInfo @text="Upload new photo" />
24
+ </Attach::Tooltip>
25
+ <div class="upload-avatar-button-wrapper rounded-lg">
26
+ <UploadButton @name="photos" @accept="image/*" @onFileAdded={{this.onUploadNewPhoto}} @icon="upload" @hideButtonText={{true}} @labelClass="upload-avatar-label-overlay" class="w-12 btn-reset" />
27
+ </div>
28
+ </div>
24
29
  </div>
25
30
  <div class="flex flex-col">
26
31
  <h1 class="text-gray-900 dark:text-white text-2xl">
@@ -58,61 +63,47 @@
58
63
  <div class="flex-1 space-y-4">
59
64
  <ContentPanel @title="Details" @open={{true}} @pad={{true}} @panelBodyClass="bg-white dark:bg-gray-800">
60
65
  <div class="grid grid-cols-1 gap-4 lg:grid-cols-2 lg:gap-2">
61
- <div class="input-group mb-2">
62
- <label>
63
- Internal ID
64
- </label>
66
+ <InputGroup @name="Internal ID">
65
67
  <Input @value={{this.vehicle.internal_id}} @type="text" class="w-full form-input" placeholder="Internal ID" />
66
- </div>
68
+ </InputGroup>
67
69
 
68
- <div class="input-group mb-2">
69
- <label>
70
- Plate Number
71
- </label>
70
+ <InputGroup @name="Plate Number">
72
71
  <Input @value={{this.vehicle.plate_number}} @type="text" class="w-full form-input" placeholder="Plate Number" />
73
- </div>
72
+ </InputGroup>
74
73
 
75
- <div class="input-group mb-2">
76
- <label>
77
- VIN Number
78
- </label>
74
+ <InputGroup @name="VIN Number">
79
75
  <Input @value={{this.vehicle.vin}} @type="text" class="w-full form-input" placeholder="VIN Number" />
80
- </div>
76
+ </InputGroup>
81
77
 
82
- <div class="input-group mb-2">
83
- <label>
84
- Make
85
- </label>
78
+ <InputGroup @name="Make">
86
79
  <Input @value={{this.vehicle.make}} @type="text" class="w-full form-input" placeholder="Vehicle Make" />
87
- </div>
80
+ </InputGroup>
88
81
 
89
- <div class="input-group mb-2">
90
- <label>
91
- Model
92
- </label>
82
+ <InputGroup @name="Model">
93
83
  <Input @value={{this.vehicle.model}} @type="text" class="w-full form-input" placeholder="Vehicle Model" />
94
- </div>
84
+ </InputGroup>
95
85
 
96
- <div class="input-group mb-2">
97
- <label>
98
- Year
99
- </label>
86
+ <InputGroup @name="Year">
100
87
  <Input @value={{this.vehicle.year}} @type="text" class="w-full form-input" placeholder="Vehicle Year" />
101
- </div>
88
+ </InputGroup>
102
89
 
103
- <div class="input-group mb-2">
104
- <label>
105
- Driver Assigned
106
- </label>
107
- <ModelSelect @modelName="driver" @selectedModel={{this.vehicle.driver}} @placeholder="Select Driver" @triggerClass="form-select form-input" @infiniteScroll={{false}} @renderInPlace={{true}} @onChange={{fn (mut
108
- this.vehicle.driver)}} as |model|>
90
+ <InputGroup @name="Driver Assigned">
91
+ <ModelSelect @modelName="driver" @selectedModel={{this.vehicle.driver}} @placeholder="Select Driver" @triggerClass="form-select form-input" @infiniteScroll={{false}} @renderInPlace={{true}} @onChange={{fn (mut this.vehicle.driver)}} as |model|>
109
92
  {{model.name}}
110
93
  </ModelSelect>
111
- </div>
94
+ </InputGroup>
95
+
96
+ <InputGroup @name="Status">
97
+ <div class="fleetbase-model-select fleetbase-power-select ember-model-select">
98
+ <PowerSelect @options={{this.vehicleStatusOptions}} @selected={{this.vehicle.status}} @onChange={{fn (mut this.vehicle.status)}} @placeholder="Select vehicle status" @triggerClass="form-select form-input" as |status|>
99
+ {{smart-humanize status}}
100
+ </PowerSelect>
101
+ </div>
102
+ </InputGroup>
112
103
  </div>
113
104
  </ContentPanel>
114
105
 
115
- <ContentPanel @title="Avatar" @open={{false}} @pad={{true}} @panelBodyClass="bg-white dark:bg-gray-800">
106
+ <ContentPanel @title="Avatar" @open={{true}} @pad={{true}} @panelBodyClass="bg-white dark:bg-gray-800">
116
107
  <div class="grid grid-cols-1 gap-4 lg:grid-cols-2 lg:gap-2">
117
108
  <div class="input-group mb-2">
118
109
  <InputLabel @labelText="Select map avatar" @helpText="Select an avatar to be used for rendering on maps when using geolocation tracking features." />
@@ -121,7 +112,7 @@
121
112
  </FetchSelect>
122
113
  </div>
123
114
  <div>
124
- <img alt={{this.vehicle.public_id}} src={{this.vehicle.avatar_url}} class="w-24 h-24" />
115
+ <img alt={{this.vehicle.displayName}} src={{this.vehicle.avatar_url}} class="w-24 h-24" />
125
116
  </div>
126
117
  </div>
127
118
  </ContentPanel>
@@ -11,6 +11,16 @@ export default class VehicleFormPanelComponent extends Component {
11
11
  */
12
12
  @service store;
13
13
 
14
+ /**
15
+ * @service store
16
+ */
17
+ @service fetch;
18
+
19
+ /**
20
+ * @service currentUser
21
+ */
22
+ @service currentUser;
23
+
14
24
  /**
15
25
  * @service notifications
16
26
  */
@@ -43,6 +53,12 @@ export default class VehicleFormPanelComponent extends Component {
43
53
  */
44
54
  @tracked isLoading = false;
45
55
 
56
+ /**
57
+ * Status options for vehicles.
58
+ * @type {Array}
59
+ */
60
+ @tracked vehicleStatusOptions = ['active', 'pending'];
61
+
46
62
  /**
47
63
  * Constructs the component and applies initial state.
48
64
  */
@@ -97,6 +113,31 @@ export default class VehicleFormPanelComponent extends Component {
97
113
  }
98
114
  }
99
115
 
116
+ /**
117
+ * Uploads a new photo for the vehicle.
118
+ *
119
+ * @param {File} file
120
+ * @memberof DriverFormPanelComponent
121
+ */
122
+ @action onUploadNewPhoto(file) {
123
+ this.fetch.uploadFile.perform(
124
+ file,
125
+ {
126
+ path: `uploads/${this.currentUser.companyId}/vehicles/${this.vehicle.id}`,
127
+ subject_uuid: this.vehicle.id,
128
+ subject_type: 'vehicle',
129
+ type: 'vehicle_photo',
130
+ },
131
+ (uploadedFile) => {
132
+ this.vehicle.setProperties({
133
+ photo_uuid: uploadedFile.id,
134
+ photo_url: uploadedFile.url,
135
+ photo: uploadedFile,
136
+ });
137
+ }
138
+ );
139
+ }
140
+
100
141
  /**
101
142
  * View the details of the vehicle.
102
143
  *
@@ -1,6 +1,6 @@
1
- <div class="p-4">
1
+ <div class="p-4 space-y-4">
2
2
  <ContentPanel @title="Details" @open={{true}} @pad={{true}} @panelBodyClass="bg-white dark:bg-gray-900">
3
- <div class="grid grid-cols-2 gap-2 text-xs md:mb-6 dark:text-gray-100">
3
+ <div class="grid grid-cols-2 gap-2 text-xs dark:text-gray-100">
4
4
  <div class="field-info-container">
5
5
  <div class="field-name">Name</div>
6
6
  <div class="field-value">{{n-a @vehicle.display_name}}</div>
@@ -31,4 +31,10 @@
31
31
  </div>
32
32
  </div>
33
33
  </ContentPanel>
34
+
35
+ <ContentPanel @title="Avatar" @open={{true}} @pad={{true}} @panelBodyClass="bg-white dark:bg-gray-800">
36
+ <div class="p-4">
37
+ <img alt={{@vehicle.displayName}} src={{@vehicle.avatar_url}} class="w-24 h-24" />
38
+ </div>
39
+ </ContentPanel>
34
40
  </div>
@@ -11,11 +11,13 @@
11
11
  <div class="flex flex-row justify-between w-full">
12
12
  <div class="flex flex-col flex-1 w-3/4">
13
13
  <div class="flex flex-row">
14
- <div class="w-14 flex items-center justify-center">
15
- <Image src={{this.vehicle.photo_url}} @fallbackSrc={{this.vehicle.avatar_url}} alt={{this.vehicle.name}} height="48" width="48" class="h-12 w-12" />
16
- <Attach::Tooltip @class="clean" @animation="scale" @placement={{"top"}}>
17
- <InputInfo @text={{this.vehicle.public_id}} />
18
- </Attach::Tooltip>
14
+ <div class="w-14">
15
+ <div class="w-12 h-12 flex items-center justify-start rounded-lg">
16
+ <Image src={{this.vehicle.photo_url}} @fallbackSrc={{config "defaultValues.vehicleImage"}} alt={{this.vehicle.name}} height="48" width="48" class="h-12 w-12 rounded-lg shadow-sm" />
17
+ <Attach::Tooltip @class="clean" @animation="scale" @placement="top">
18
+ <InputInfo @text={{this.vehicle.displayName}} />
19
+ </Attach::Tooltip>
20
+ </div>
19
21
  </div>
20
22
  <div class="flex flex-col">
21
23
  <h1 class="text-gray-900 dark:text-white text-2xl">{{this.vehicle.display_name}}</h1>
@@ -53,7 +55,7 @@
53
55
  </div>
54
56
  </div>
55
57
  <div class="tab-content tab-{{this.tab.slug}}">
56
- {{component this.tab.component vehicle=this.vehicle tabOptions=this.tab params=this.tab.componentParams}}
58
+ {{component this.tab.component vehicle=this.vehicle tabOptions=this.tab options=this.tab.componentParams}}
57
59
  </div>
58
60
  </Overlay::Body>
59
61
  </Overlay>