@fleetbase/fleetops-engine 0.2.8 → 0.2.9
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/context-panel.hbs +5 -0
- package/addon/components/context-panel.js +6 -0
- package/addon/components/driver-form-panel.hbs +22 -22
- package/addon/components/driver-form-panel.js +28 -3
- package/addon/components/driver-panel.hbs +8 -8
- package/addon/components/driver-panel.js +23 -6
- package/addon/components/fleet-vehicle-listing.hbs +1 -1
- package/addon/components/live-map.hbs +20 -9
- package/addon/components/live-map.js +1045 -354
- package/addon/components/settings-window.hbs +1 -1
- package/addon/components/vehicle-form-panel.hbs +24 -24
- package/addon/components/vehicle-form-panel.js +26 -3
- package/addon/components/vehicle-panel.hbs +8 -9
- package/addon/components/vehicle-panel.js +21 -4
- package/addon/controllers/operations/orders/index/new.js +3 -5
- package/addon/controllers/operations/orders/index/view.js +5 -7
- package/addon/controllers/operations/orders/index.js +15 -2
- package/addon/engine.js +6 -0
- package/addon/routes/operations/orders/index/view.js +4 -2
- package/addon/routes/operations/orders/index.js +5 -1
- package/addon/services/context-panel.js +106 -0
- package/addon/services/leaflet-contextmenu-manager.js +311 -0
- package/addon/services/leaflet-map-manager.js +61 -0
- package/addon/services/service-areas.js +242 -32
- package/addon/templates/application.hbs +2 -1
- package/addon/utils/find-leaflet-layer.js +13 -0
- package/addon/utils/fly-to-leaflet-layer.js +25 -0
- package/addon/utils/get-leaflet-layer-by-id.js +12 -0
- package/addon/utils/layer-can-bind-contextmenu.js +3 -0
- package/app/components/context-panel.js +1 -0
- package/app/services/context-panel.js +1 -0
- package/app/services/leaflet-contextmenu-manager.js +1 -0
- package/app/services/leaflet-map-manager.js +1 -0
- package/app/utils/find-leaflet-layer.js +1 -0
- package/app/utils/fly-to-leaflet-layer.js +1 -0
- package/app/utils/get-leaflet-layer-by-id.js +1 -0
- package/app/utils/layer-can-bind-contextmenu.js +1 -0
- package/composer.json +11 -1
- package/extension.json +1 -1
- package/package.json +2 -2
- package/server/src/Http/Controllers/Internal/v1/LiveController.php +7 -4
- package/server/src/Http/Filter/VehicleFilter.php +7 -0
- package/server/src/Http/Resources/v1/Vehicle.php +51 -39
- package/addon/services/map-manager.js +0 -3
- package/app/services/map-manager.js +0 -1
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import Service from '@ember/service';
|
|
2
|
+
import { tracked } from '@glimmer/tracking';
|
|
3
|
+
import { camelize } from '@ember/string';
|
|
4
|
+
import { later } from '@ember/runloop';
|
|
5
|
+
import getWithDefault from '@fleetbase/ember-core/utils/get-with-default';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Service for managing context menus in Leaflet maps.
|
|
9
|
+
*
|
|
10
|
+
* This service provides functions to toggle context menu items, create context menus for specific
|
|
11
|
+
* layers, and manage the context menu registry. It also includes utility functions for internal use.
|
|
12
|
+
*
|
|
13
|
+
* @class
|
|
14
|
+
*/
|
|
15
|
+
export default class LeafletContextmenuManagerService extends Service {
|
|
16
|
+
/**
|
|
17
|
+
* Registry for context menus associated with specific layers.
|
|
18
|
+
*
|
|
19
|
+
* @type {Object}
|
|
20
|
+
*/
|
|
21
|
+
@tracked contextMenuRegistry = {};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Creates a context menu for a specific layer with the given items.
|
|
25
|
+
*
|
|
26
|
+
* @param {string} registryName - The name of the context menu registry.
|
|
27
|
+
* @param {Object} layer - The Leaflet layer associated with the context menu.
|
|
28
|
+
* @param {Array} items - An array of context menu items to add.
|
|
29
|
+
* @returns {Object} The created context menu registry.
|
|
30
|
+
*/
|
|
31
|
+
createContextMenu(registryName, layer, contextmenuItems = [], additionalContext = {}) {
|
|
32
|
+
// create internal registry name
|
|
33
|
+
const internalRegistryName = this.createInternalRegistryName(registryName);
|
|
34
|
+
|
|
35
|
+
// get layer contextmenu api
|
|
36
|
+
const contextmenuApi = layer.contextmenu;
|
|
37
|
+
|
|
38
|
+
// bind contextmenu first
|
|
39
|
+
if (typeof layer.bindContextMenu === 'function') {
|
|
40
|
+
layer.bindContextMenu({
|
|
41
|
+
contextmenu: true,
|
|
42
|
+
contextmenuItems,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// setup context menu
|
|
47
|
+
if (contextmenuApi) {
|
|
48
|
+
// remove all items first
|
|
49
|
+
contextmenuApi.removeAllItems();
|
|
50
|
+
|
|
51
|
+
// add items
|
|
52
|
+
for (let i = 0; i < contextmenuItems.length; i++) {
|
|
53
|
+
const item = contextmenuItems.objectAt(i);
|
|
54
|
+
contextmenuApi.addItem(item);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// enable contextmenu
|
|
58
|
+
contextmenuApi.enable();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// create contextmenu registry
|
|
62
|
+
this.contextMenuRegistry[internalRegistryName] = {
|
|
63
|
+
contextmenuItems,
|
|
64
|
+
layer,
|
|
65
|
+
contextmenuApi,
|
|
66
|
+
...additionalContext,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
return this.contextMenuRegistry[internalRegistryName];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Retrieves a context menu registry by its name.
|
|
74
|
+
*
|
|
75
|
+
* @param {string} registryName - The name of the context menu registry to retrieve.
|
|
76
|
+
* @returns {Object|null} The context menu registry or null if not found.
|
|
77
|
+
*/
|
|
78
|
+
getRegistry(registryName) {
|
|
79
|
+
const internalRegistryName = this.createInternalRegistryName(registryName);
|
|
80
|
+
|
|
81
|
+
if (this.contextMenuRegistry[internalRegistryName]) {
|
|
82
|
+
return this.contextMenuRegistry[internalRegistryName];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Creates an internal registry name by camelizing the provided registry name and appending "ConextmenuRegistry" to it.
|
|
90
|
+
*
|
|
91
|
+
* @method createInternalRegistryName
|
|
92
|
+
* @public
|
|
93
|
+
* @memberof LeafletContextmenuManagerService
|
|
94
|
+
* @param {String} registryName - The name of the registry to be camelized and formatted.
|
|
95
|
+
* @returns {String} The formatted internal registry name.
|
|
96
|
+
*/
|
|
97
|
+
createInternalRegistryName(registryName) {
|
|
98
|
+
return `${camelize(registryName.replace(/[^a-zA-Z0-9]/g, '-'))}ConextmenuRegistry`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Toggles a context menu item in the specified registry.
|
|
103
|
+
*
|
|
104
|
+
* @method createInternalRegistryName
|
|
105
|
+
* @public
|
|
106
|
+
* @param {string} registryName - The name of the context menu registry to toggle the item in.
|
|
107
|
+
* @param {string|Function} selector - The selector or callback for the item to toggle.
|
|
108
|
+
* @param {Object} options - Additional options for toggling the item (optional).
|
|
109
|
+
*/
|
|
110
|
+
toggleContextMenuItem(registryName, selector, options = {}) {
|
|
111
|
+
const registry = this.getRegistry(registryName);
|
|
112
|
+
|
|
113
|
+
// get the context menu api
|
|
114
|
+
const { contextmenuApi } = registry;
|
|
115
|
+
|
|
116
|
+
// if just toggling text
|
|
117
|
+
const toggle = getWithDefault(options, 'toggle', true);
|
|
118
|
+
const onText = getWithDefault(options, 'onText');
|
|
119
|
+
const offText = getWithDefault(options, 'offText');
|
|
120
|
+
const callback = getWithDefault(options, 'callback');
|
|
121
|
+
|
|
122
|
+
if (registry) {
|
|
123
|
+
const index = registry.contextmenuItems.findIndex((item) => {
|
|
124
|
+
if (typeof selector === 'string' && typeof item.text === 'string') {
|
|
125
|
+
return item.text.includes(selector);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (typeof selector === 'function') {
|
|
129
|
+
return selector(item);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
if (index > 0) {
|
|
134
|
+
const item = registry.contextmenuItems.objectAt(index);
|
|
135
|
+
|
|
136
|
+
if (item) {
|
|
137
|
+
item.text = toggle ? onText : offText;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (typeof callback === 'function') {
|
|
141
|
+
callback(toggle, item, registry);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// insert back into contextmenu
|
|
145
|
+
if (contextmenuApi) {
|
|
146
|
+
contextmenuApi.removeItem(index);
|
|
147
|
+
contextmenuApi.insertItem(item, index);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Change the text of a context menu item within a specified registry.
|
|
155
|
+
*
|
|
156
|
+
* @param {string} registryName - The name of the context menu registry.
|
|
157
|
+
* @param {string|function} selector - A string or function to select the menu item to change.
|
|
158
|
+
* @param {string} newText - The new text to set for the menu item.
|
|
159
|
+
* @param {Object} [options={}] - Additional options.
|
|
160
|
+
* @param {function} [options.callback] - A callback function to execute.
|
|
161
|
+
* @memberof LeafletContextmenuManagerService
|
|
162
|
+
*/
|
|
163
|
+
changeMenuItemText(registryName, selector, newText, options = {}) {
|
|
164
|
+
const registry = this.getRegistry(registryName);
|
|
165
|
+
|
|
166
|
+
// get the context menu api
|
|
167
|
+
const { contextmenuApi } = registry;
|
|
168
|
+
|
|
169
|
+
// if just toggling text
|
|
170
|
+
const callback = getWithDefault(options, 'callback');
|
|
171
|
+
|
|
172
|
+
if (registry) {
|
|
173
|
+
const index = registry.contextmenuItems.findIndex((item) => {
|
|
174
|
+
if (typeof selector === 'string' && typeof item.text === 'string') {
|
|
175
|
+
return item.text.includes(selector);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (typeof selector === 'function') {
|
|
179
|
+
return selector(item);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
if (index > 0) {
|
|
184
|
+
const item = registry.contextmenuItems.objectAt(index);
|
|
185
|
+
|
|
186
|
+
if (item) {
|
|
187
|
+
item.text = newText;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (typeof callback === 'function') {
|
|
191
|
+
callback(item, registry);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// insert back into contextmenu
|
|
195
|
+
if (contextmenuApi) {
|
|
196
|
+
contextmenuApi.removeItem(index);
|
|
197
|
+
contextmenuApi.insertItem(item, index);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Removes a specific item from the context menu associated with the given registry name.
|
|
205
|
+
*
|
|
206
|
+
* @method createInternalRegistryName
|
|
207
|
+
* @public
|
|
208
|
+
* @param {string} registryName - The name of the context menu registry to target.
|
|
209
|
+
* @param {string|Function} selector - A string or function used to identify the item to remove.
|
|
210
|
+
* @param {Object} options - Additional options for removing the item.
|
|
211
|
+
* @param {Function} options.callback - A callback function to execute after item removal.
|
|
212
|
+
*/
|
|
213
|
+
removeItemFromContextMenu(registryName, selector, options = {}) {
|
|
214
|
+
const registry = this.getRegistry(registryName);
|
|
215
|
+
|
|
216
|
+
// get the context menu api
|
|
217
|
+
const { contextmenuApi } = registry;
|
|
218
|
+
|
|
219
|
+
// if just toggling text
|
|
220
|
+
const callback = getWithDefault(options, 'callback');
|
|
221
|
+
|
|
222
|
+
if (registry) {
|
|
223
|
+
const index = registry.contextmenuItems.findIndex((item) => {
|
|
224
|
+
if (typeof selector === 'string' && typeof item.text === 'string') {
|
|
225
|
+
return item.text.includes(selector);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (typeof selector === 'function') {
|
|
229
|
+
return selector(item);
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
if (index > 0) {
|
|
234
|
+
const item = registry.contextmenuItems.objectAt(index);
|
|
235
|
+
|
|
236
|
+
if (typeof callback === 'function') {
|
|
237
|
+
callback(item, registry);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// remove from context menu
|
|
241
|
+
if (contextmenuApi) {
|
|
242
|
+
contextmenuApi.removeItem(index);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Find a context menu registry by layer.
|
|
250
|
+
*
|
|
251
|
+
* @param {Layer} layer - The layer for which to find the registry.
|
|
252
|
+
* @returns {Object|null} The context menu registry associated with the provided layer, or null if not found.
|
|
253
|
+
*/
|
|
254
|
+
findRegistryByLayer(layer) {
|
|
255
|
+
for (const registryName in this.contextMenuRegistry) {
|
|
256
|
+
const registry = this.contextMenuRegistry[registryName];
|
|
257
|
+
if (registry.layer === layer) {
|
|
258
|
+
return registry;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// If no matching registry is found, return null or handle the case accordingly.
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Rebind the context menu for a layer and update the registry if it exists.
|
|
268
|
+
*
|
|
269
|
+
* @param {Layer} layer - The layer to rebind the context menu for.
|
|
270
|
+
* @param {Array} contextmenuItems - An array of context menu items to bind.
|
|
271
|
+
*/
|
|
272
|
+
rebindContextMenu(layer, contextmenuItems = []) {
|
|
273
|
+
// make sure layer is instance of leaflet
|
|
274
|
+
if (!(layer instanceof L.Layer)) {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const registry = this.findRegistryByLayer(layer);
|
|
279
|
+
|
|
280
|
+
if (registry) {
|
|
281
|
+
later(
|
|
282
|
+
this,
|
|
283
|
+
() => {
|
|
284
|
+
try {
|
|
285
|
+
if (typeof layer.unbindContextMenu === 'function') {
|
|
286
|
+
layer.unbindContextMenu().bindContextMenu({
|
|
287
|
+
contextmenu: true,
|
|
288
|
+
contextmenuItems,
|
|
289
|
+
});
|
|
290
|
+
} else {
|
|
291
|
+
// just bind
|
|
292
|
+
layer.bindContextMenu({
|
|
293
|
+
contextmenu: true,
|
|
294
|
+
contextmenuItems,
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
} catch (error) {
|
|
298
|
+
// silence
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// if found registry update layer and contextmenu api
|
|
302
|
+
if (registry) {
|
|
303
|
+
registry.layer = layer;
|
|
304
|
+
registry.contextmenuApi = layer.contextmenu;
|
|
305
|
+
}
|
|
306
|
+
},
|
|
307
|
+
300
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import Service from '@ember/service';
|
|
2
|
+
import { tracked } from '@glimmer/tracking';
|
|
3
|
+
import getLeafletLayerById from '../utils/get-leaflet-layer-by-id';
|
|
4
|
+
import findLeafletLayer from '../utils/find-leaflet-layer';
|
|
5
|
+
import flyToLeafletLayer from '../utils/fly-to-leaflet-layer';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Service for managing Leaflet maps and layers.
|
|
9
|
+
*
|
|
10
|
+
* This service provides functions to work with Leaflet maps, including accessing layers by ID,
|
|
11
|
+
* finding layers based on a custom callback, and flying to specific layers with optional zoom and options.
|
|
12
|
+
*
|
|
13
|
+
* @class
|
|
14
|
+
*/
|
|
15
|
+
export default class LeafletMapManagerService extends Service {
|
|
16
|
+
/**
|
|
17
|
+
* An array of editable layers on the map.
|
|
18
|
+
*
|
|
19
|
+
* @memberof LeafletMapManagerService
|
|
20
|
+
* @type {Array}
|
|
21
|
+
*/
|
|
22
|
+
@tracked editableLayers = [];
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Get a Leaflet layer by its ID from the given map.
|
|
26
|
+
*
|
|
27
|
+
* @memberof LeafletMapManagerService
|
|
28
|
+
* @param {Object} map - The Leaflet map instance.
|
|
29
|
+
* @param {string} layerId - The ID of the layer to retrieve.
|
|
30
|
+
* @returns {Object|null} The Leaflet layer with the specified ID, or null if not found.
|
|
31
|
+
*/
|
|
32
|
+
getLeafletLayerById(map, layerId) {
|
|
33
|
+
return getLeafletLayerById(map, layerId);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Find a Leaflet layer in the given map using a custom callback.
|
|
38
|
+
*
|
|
39
|
+
* @memberof LeafletMapManagerService
|
|
40
|
+
* @param {Object} map - The Leaflet map instance.
|
|
41
|
+
* @param {Function} findCallback - A custom callback function to find the desired layer.
|
|
42
|
+
* @returns {Object|null} The found Leaflet layer, or null if not found.
|
|
43
|
+
*/
|
|
44
|
+
findLeafletLayer(map, findCallback) {
|
|
45
|
+
return findLeafletLayer(map, findCallback);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Fly to a specific Leaflet layer on the map with optional zoom and options.
|
|
50
|
+
*
|
|
51
|
+
* @memberof LeafletMapManagerService
|
|
52
|
+
* @param {Object} map - The Leaflet map instance.
|
|
53
|
+
* @param {Object} layer - The Leaflet layer to fly to.
|
|
54
|
+
* @param {number} zoom - The zoom level to apply (optional).
|
|
55
|
+
* @param {Object} options - Additional options for the fly animation (optional).
|
|
56
|
+
* @returns {Object} The Leaflet map instance.
|
|
57
|
+
*/
|
|
58
|
+
flyToLayer(map, layer, zoom, options = {}) {
|
|
59
|
+
return flyToLeafletLayer(map, layer, zoom, options);
|
|
60
|
+
}
|
|
61
|
+
}
|