@fleetbase/fleetops-engine 0.2.9 → 0.3.0

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 (59) hide show
  1. package/addon/components/context-panel.hbs +1 -1
  2. package/addon/components/driver-card-mini.js +34 -13
  3. package/addon/components/driver-form-panel.hbs +3 -3
  4. package/addon/components/driver-form-panel.js +87 -29
  5. package/addon/components/driver-panel.hbs +5 -5
  6. package/addon/components/driver-panel.js +118 -31
  7. package/addon/components/live-map.js +221 -10
  8. package/addon/components/map-container/toolbar/visibility-control-panel.hbs +66 -0
  9. package/addon/components/map-container/toolbar/visibility-control-panel.js +74 -0
  10. package/addon/components/map-container/toolbar/zones-panel.hbs +10 -10
  11. package/addon/components/map-container/toolbar/zones-panel.js +90 -61
  12. package/addon/components/map-container/toolbar.hbs +12 -7
  13. package/addon/components/modals/vehicle-form.hbs +35 -35
  14. package/addon/components/vehicle-form-panel.hbs +6 -7
  15. package/addon/components/vehicle-form-panel.js +86 -26
  16. package/addon/components/vehicle-panel.hbs +5 -5
  17. package/addon/components/vehicle-panel.js +124 -31
  18. package/addon/controllers/management/drivers/index/details.js +53 -0
  19. package/addon/controllers/management/drivers/index/edit.js +77 -46
  20. package/addon/controllers/management/drivers/index/new.js +39 -79
  21. package/addon/controllers/management/drivers/index.js +17 -221
  22. package/addon/controllers/management/fleets/index/edit.js +1 -1
  23. package/addon/controllers/management/fleets/index/new.js +1 -1
  24. package/addon/controllers/management/fuel-reports/index.js +2 -2
  25. package/addon/controllers/management/vehicles/index/details.js +49 -0
  26. package/addon/controllers/management/vehicles/index/edit.js +104 -1
  27. package/addon/controllers/management/vehicles/index/new.js +71 -0
  28. package/addon/controllers/operations/orders/index/new.js +1 -1
  29. package/addon/controllers/operations/orders/index/view.js +17 -7
  30. package/addon/controllers/operations/orders/index.js +109 -48
  31. package/addon/controllers/operations/service-rates/index/edit.js +1 -1
  32. package/addon/controllers/operations/service-rates/index/new.js +1 -1
  33. package/addon/helpers/is-visibility-control-visible.js +18 -0
  34. package/addon/routes/application.js +1 -1
  35. package/addon/routes/home.js +1 -1
  36. package/addon/routes/management/drivers/index/details.js +5 -0
  37. package/addon/routes/operations/service-rates/index.js +1 -1
  38. package/addon/routes/operations/zones/index.js +1 -1
  39. package/addon/services/context-panel.js +81 -14
  40. package/addon/templates/management/drivers/index/details.hbs +1 -1
  41. package/addon/templates/management/drivers/index/edit.hbs +1 -1
  42. package/addon/templates/management/drivers/index/new.hbs +1 -1
  43. package/addon/templates/management/vehicles/index/details.hbs +1 -1
  44. package/addon/templates/management/vehicles/index/edit.hbs +1 -1
  45. package/addon/templates/management/vehicles/index/new.hbs +1 -1
  46. package/addon/templates/operations/orders/index/view.hbs +2 -2
  47. package/addon/templates/operations/orders/index.hbs +1 -1
  48. package/addon/utils/apply-context-component-arguments.js +31 -0
  49. package/addon/utils/context-component-callback.js +16 -0
  50. package/app/components/map-container/toolbar/visibility-control-panel.js +1 -0
  51. package/app/helpers/is-visibility-control-visible.js +1 -0
  52. package/app/utils/apply-context-component-arguments.js +1 -0
  53. package/app/utils/context-component-callback.js +1 -0
  54. package/package.json +3 -3
  55. package/server/migrations/2023_09_14_074512_update_vehicles_table.php +89 -88
  56. package/server/migrations/2023_10_25_093014_create_vehicle_device_events_table.php +56 -0
  57. package/server/src/Http/Resources/v1/Vehicle.php +1 -0
  58. package/server/src/Models/VehicleDevice.php +17 -3
  59. package/server/src/Models/VehicleDeviceEvent.php +90 -0
@@ -4,8 +4,34 @@ import { inject as service } from '@ember/service';
4
4
  import { action } from '@ember/object';
5
5
 
6
6
  export default class ManagementVehiclesIndexNewController extends Controller {
7
+ /**
8
+ * Inject the `store` service
9
+ *
10
+ * @memberof ManagementVehiclesIndexNewController
11
+ */
7
12
  @service store;
8
13
 
14
+ /**
15
+ * Inject the `hostRouter` service
16
+ *
17
+ * @memberof ManagementVehiclesIndexNewController
18
+ */
19
+ @service hostRouter;
20
+
21
+ /**
22
+ * Inject the `hostRouter` service
23
+ *
24
+ * @memberof ManagementVehiclesIndexNewController
25
+ */
26
+ @service modalsManager;
27
+
28
+ /**
29
+ * The overlay component context.
30
+ *
31
+ * @memberof ManagementVehiclesIndexNewController
32
+ */
33
+ @tracked overlay;
34
+
9
35
  /**
10
36
  * The vehicle being created.
11
37
  *
@@ -15,7 +41,52 @@ export default class ManagementVehiclesIndexNewController extends Controller {
15
41
  status: `active`,
16
42
  });
17
43
 
44
+ /**
45
+ * Set the overlay component context object.
46
+ *
47
+ * @param {OverlayContext} overlay
48
+ * @memberof ManagementVehiclesIndexNewController
49
+ */
50
+ @action setOverlayContext(overlay) {
51
+ this.overlay = overlay;
52
+ }
53
+
54
+ /**
55
+ * When exiting the overlay.
56
+ *
57
+ * @return {Transition}
58
+ * @memberof ManagementVehiclesIndexNewController
59
+ */
18
60
  @action transitionBack() {
19
61
  return this.transitionToRoute('management.vehicles.index');
20
62
  }
63
+
64
+ /**
65
+ * Trigger a route refresh and focus the new vehicle created.
66
+ *
67
+ * @param {VehicleModel} vehicle
68
+ * @return {Promise}
69
+ * @memberof ManagementVehiclesIndexNewController
70
+ */
71
+ @action onAfterSave(vehicle) {
72
+ if (this.overlay) {
73
+ this.overlay.close();
74
+ }
75
+
76
+ this.hostRouter.refresh();
77
+ return this.transitionToRoute('management.vehicles.index.details', vehicle).then(() => {
78
+ this.resetForm();
79
+ });
80
+ }
81
+
82
+ /**
83
+ * Resets the form with a new vehicle record
84
+ *
85
+ * @memberof ManagementVehiclesIndexNewController
86
+ */
87
+ resetForm() {
88
+ this.vehicle = this.store.createRecord('vehicle', {
89
+ status: `active`,
90
+ });
91
+ }
21
92
  }
@@ -253,7 +253,7 @@ export default class OperationsOrdersIndexNewController extends Controller {
253
253
  }
254
254
 
255
255
  this.previewRoute(false);
256
- this.loader.showLoader('body', 'Creating Order...');
256
+ this.loader.showLoader('body', { loadingMessage: 'Creating Order...' });
257
257
 
258
258
  const { order, groupedMetaFields, payload, entities, waypoints, isMultipleDropoffOrder } = this;
259
259
  const route = this.leafletOptimizedRoute ? this.getOptimizedRoute() : this.getRoute();
@@ -95,6 +95,13 @@ export default class OperationsOrdersIndexViewController extends Controller {
95
95
  */
96
96
  @service universe;
97
97
 
98
+ /**
99
+ * Inject the `contextPanel` service
100
+ *
101
+ * @var {Service}
102
+ */
103
+ @service contextPanel;
104
+
98
105
  @tracked isLoadingAdditionalData = false;
99
106
  @tracked isWaypointsCollapsed;
100
107
  @tracked leafletRoute;
@@ -782,15 +789,18 @@ export default class OperationsOrdersIndexViewController extends Controller {
782
789
  this.vendorsController.viewVendor(customer);
783
790
  }
784
791
 
785
- @action async viewDriver(order) {
786
- if (order.canLoadDriver) {
787
- this.modalsManager.displayLoader();
788
-
789
- order.driver = await this.store.findRecord('driver', order.driver_uuid);
790
- await this.modalsManager.done();
792
+ @action focusOrderAssignedDriver({ driver_assigned, driver_assigned_uuid, canLoadDriver }) {
793
+ // if can load the driver then load and display via context
794
+ if (canLoadDriver) {
795
+ return this.store.findRecord('driver', driver_assigned_uuid).then((driver) => {
796
+ this.contextPanel.focus(driver);
797
+ });
791
798
  }
792
799
 
793
- this.driversController.viewDriver(order.driver_assigned);
800
+ // if driver already loaded use this
801
+ if (driver_assigned) {
802
+ this.contextPanel.focus(driver_assigned);
803
+ }
794
804
  }
795
805
 
796
806
  @action async viewFacilitator({ facilitator, facilitator_is_contact }) {
@@ -7,7 +7,6 @@ import { isArray } from '@ember/array';
7
7
  import { isBlank } from '@ember/utils';
8
8
  import { timeout } from 'ember-concurrency';
9
9
  import { task } from 'ember-concurrency-decorators';
10
- import isModel from '@fleetbase/ember-core/utils/is-model';
11
10
 
12
11
  export default class OperationsOrdersIndexController extends Controller {
13
12
  /**
@@ -630,38 +629,59 @@ export default class OperationsOrdersIndexController extends Controller {
630
629
  this.query = value;
631
630
  }
632
631
 
633
- @action viewPlacesOnMap() {
634
- const {
635
- leafletMap: { liveMap },
636
- } = this;
637
-
638
- if (liveMap) {
639
- liveMap.togglePlaces();
640
- }
641
- }
642
-
632
+ /**
633
+ * Hides all elements on the live map.
634
+ * @action
635
+ * @memberof OperationsOrdersIndexController
636
+ */
643
637
  @action resetView() {
644
638
  if (this.leafletMap && this.leafletMap.liveMap) {
645
639
  this.leafletMap.liveMap.hideAll();
646
640
  }
647
641
  }
648
642
 
643
+ /**
644
+ * Toggles the visibility of the search interface.
645
+ * @action
646
+ * @memberof OperationsOrdersIndexController
647
+ */
649
648
  @action toggleSearch() {
650
649
  this.isSearchVisible = !this.isSearchVisible;
651
650
  }
652
651
 
652
+ /**
653
+ * Toggles the visibility of the orders panel.
654
+ * @action
655
+ * @memberof OperationsOrdersIndexController
656
+ */
653
657
  @action toggleOrdersPanel() {
654
658
  this.isOrdersPanelVisible = !this.isOrdersPanelVisible;
655
659
  }
656
660
 
661
+ /**
662
+ * Hides the orders panel.
663
+ * @action
664
+ * @memberof OperationsOrdersIndexController
665
+ */
657
666
  @action hideOrdersPanel() {
658
667
  this.isOrdersPanelVisible = false;
659
668
  }
660
669
 
670
+ /**
671
+ * Shows the orders panel.
672
+ * @action
673
+ * @memberof OperationsOrdersIndexController
674
+ */
661
675
  @action showOrdersPanel() {
662
676
  this.isOrdersPanelVisible = true;
663
677
  }
664
678
 
679
+ /**
680
+ * Zooms the map in or out.
681
+ * @param {string} [direction='in'] - The direction to zoom. Either 'in' or 'out'.
682
+ * @action
683
+ * @memberof OperationsOrdersIndexController
684
+ */
665
685
  @action zoomMap(direction = 'in') {
666
686
  if (direction === 'in') {
667
687
  this.leafletMap?.zoomIn();
@@ -670,6 +690,12 @@ export default class OperationsOrdersIndexController extends Controller {
670
690
  }
671
691
  }
672
692
 
693
+ /**
694
+ * Sets the layout mode and triggers a layout change event.
695
+ * @param {string} mode - The layout mode to set. E.g., 'table'.
696
+ * @action
697
+ * @memberof OperationsOrdersIndexController
698
+ */
673
699
  @action setLayoutMode(mode) {
674
700
  this.layout = mode;
675
701
 
@@ -680,22 +706,57 @@ export default class OperationsOrdersIndexController extends Controller {
680
706
  this.universe.trigger('dashboard.layout.changed', mode);
681
707
  }
682
708
 
683
- @action setMapReference({ target }) {
709
+ /**
710
+ * Sets the map references for this component.
711
+ * Extracts the `liveMap` from the `target` object passed in the event and sets it as `this.liveMap`.
712
+ * Also, sets `target` as `this.leafletMap`.
713
+ *
714
+ * @param {Object} event - The event object containing the map references.
715
+ * @param {Object} event.target - The target map object.
716
+ * @param {Object} event.target.liveMap - The live map reference.
717
+ * @action
718
+ * @memberof OperationsOrdersIndexController
719
+ */
720
+ @action setMapReference({ target, target: { liveMap } }) {
684
721
  this.leafletMap = target;
722
+ this.liveMap = liveMap;
685
723
  }
686
724
 
725
+ /**
726
+ * Exports all orders.
727
+ * @action
728
+ * @memberof OperationsOrdersIndexController
729
+ */
687
730
  @action exportOrders() {
688
731
  this.crud.export('order');
689
732
  }
690
733
 
734
+ /**
735
+ * Redirects to the new order creation page.
736
+ * @action
737
+ * @memberof OperationsOrdersIndexController
738
+ */
691
739
  @action createOrder() {
692
740
  return this.transitionToRoute('operations.orders.index.new');
693
741
  }
694
742
 
743
+ /**
744
+ * Redirects to the view page of a specific order.
745
+ * @param {Object} order - The order to view.
746
+ * @action
747
+ * @memberof OperationsOrdersIndexController
748
+ */
695
749
  @action viewOrder(order) {
696
750
  return this.transitionToRoute('operations.orders.index.view', order);
697
751
  }
698
752
 
753
+ /**
754
+ * Cancels a specific order after confirmation.
755
+ * @param {Object} order - The order to cancel.
756
+ * @param {Object} [options={}] - Additional options for the modal.
757
+ * @action
758
+ * @memberof OperationsOrdersIndexController
759
+ */
699
760
  @action cancelOrder(order, options = {}) {
700
761
  this.modalsManager.confirm({
701
762
  title: `Are you sure you wish to cancel this order?`,
@@ -713,6 +774,13 @@ export default class OperationsOrdersIndexController extends Controller {
713
774
  });
714
775
  }
715
776
 
777
+ /**
778
+ * Dispatches a specific order after confirmation.
779
+ * @param {Object} order - The order to dispatch.
780
+ * @param {Object} [options={}] - Additional options for the modal.
781
+ * @action
782
+ * @memberof OperationsOrdersIndexController
783
+ */
716
784
  @action dispatchOrder(order, options = {}) {
717
785
  this.modalsManager.confirm({
718
786
  title: `Are you sure you want to dispatch this order?`,
@@ -739,6 +807,13 @@ export default class OperationsOrdersIndexController extends Controller {
739
807
  });
740
808
  }
741
809
 
810
+ /**
811
+ * Deletes a specific order.
812
+ * @param {Object} order - The order to delete.
813
+ * @param {Object} [options={}] - Additional options for deletion.
814
+ * @action
815
+ * @memberof OperationsOrdersIndexController
816
+ */
742
817
  @action deleteOrder(order, options = {}) {
743
818
  this.crud.delete(order, {
744
819
  onSuccess: () => {
@@ -748,6 +823,12 @@ export default class OperationsOrdersIndexController extends Controller {
748
823
  });
749
824
  }
750
825
 
826
+ /**
827
+ * Deletes multiple selected orders.
828
+ * @param {Array} [selected=[]] - Orders selected for deletion.
829
+ * @action
830
+ * @memberof OperationsOrdersIndexController
831
+ */
751
832
  @action bulkDeleteOrders(selected = []) {
752
833
  selected = selected.length > 0 ? selected : this.table.selectedRows;
753
834
 
@@ -760,6 +841,12 @@ export default class OperationsOrdersIndexController extends Controller {
760
841
  });
761
842
  }
762
843
 
844
+ /**
845
+ * Cancels multiple selected orders.
846
+ * @param {Array} [selected=[]] - Orders selected for cancellation.
847
+ * @action
848
+ * @memberof OperationsOrdersIndexController
849
+ */
763
850
  @action bulkCancelOrders(selected = []) {
764
851
  selected = selected.length > 0 ? selected : this.table.selectedRows;
765
852
 
@@ -785,46 +872,20 @@ export default class OperationsOrdersIndexController extends Controller {
785
872
  });
786
873
  }
787
874
 
788
- @action applyFilters(columns) {
789
- columns.forEach((column) => {
790
- // if value is a model only filter by id
791
- if (isModel(column.filterValue)) {
792
- column.filterValue = column.filterValue.id;
793
- }
794
-
795
- // if value is an array of models map to ids
796
- if (isArray(column.filterValue) && column.filterValue.every((v) => isModel(v))) {
797
- column.filterValue = column.filterValue.map((v) => v.id);
798
- }
799
-
800
- // only if filter is active continue
801
- if (column.isFilterActive && column.filterValue) {
802
- this[column.filterParam || column.valuePath] = column.filterValue;
803
- } else {
804
- this[column.filterParam || column.valuePath] = undefined;
805
- column.isFilterActive = false;
806
- column.filterValue = undefined;
807
- }
808
- });
809
-
810
- this.columns = columns;
811
- }
812
-
813
- @action setFilterOptions(valuePath, options) {
814
- const updatedColumns = this.columns.map((column) => {
815
- if (column.valuePath === valuePath) {
816
- column.filterOptions = options;
817
- }
818
- return column;
819
- });
820
-
821
- this.columns = updatedColumns;
822
- }
823
-
875
+ /**
876
+ * Triggers when the map container is ready.
877
+ * @action
878
+ * @memberof OperationsOrdersIndexController
879
+ */
824
880
  @action onMapContainerReady() {
825
881
  this.fetchActiveOrdersCount();
826
882
  }
827
883
 
884
+ /**
885
+ * Fetches the count of active orders.
886
+ * @action
887
+ * @memberof OperationsOrdersIndexController
888
+ */
828
889
  @action fetchActiveOrdersCount() {
829
890
  this.fetch.get('fleet-ops/metrics/all', { discover: ['orders_in_progress'] }).then((response) => {
830
891
  this.activeOrdersCount = response.orders_in_progress;
@@ -34,7 +34,7 @@ export default class OperationsServiceRatesIndexEditController extends Operation
34
34
  }
35
35
 
36
36
  this.isUpdatingServiceRate = true;
37
- this.loader.showLoader('.overlay-inner-content', 'Updating service rate...');
37
+ this.loader.showLoader('.overlay-inner-content', { loadingMessage: 'Updating service rate...' });
38
38
 
39
39
  try {
40
40
  return serviceRate
@@ -294,7 +294,7 @@ export default class OperationsServiceRatesIndexNewController extends Controller
294
294
  }
295
295
 
296
296
  this.isCreatingServiceRate = true;
297
- this.loader.showLoader('.overlay-inner-content', 'Creating service rate...');
297
+ this.loader.showLoader('.overlay-inner-content', { loadingMessage: 'Creating service rate...' });
298
298
 
299
299
  try {
300
300
  return serviceRate
@@ -0,0 +1,18 @@
1
+ import { helper } from '@ember/component/helper';
2
+ import { isNone } from '@ember/utils';
3
+
4
+ /**
5
+ * Helper function to determine if a visibility control is set to true.
6
+ *
7
+ * @param {Array} params - An array containing the control object and the name of the control.
8
+ * @returns {boolean} - True if the control is set to true, otherwise false.
9
+ */
10
+ export default helper(function isVisibilityControlVisible([control, name]) {
11
+ // Check if an object with visibilityControls is passed
12
+ if (!isNone(control) && !isNone(control.visibilityControls)) {
13
+ return control.visibilityControls[name] === true;
14
+ }
15
+
16
+ // Check if control property directly exists and is true
17
+ return !isNone(control) && control[name] === true;
18
+ });
@@ -7,7 +7,7 @@ export default class ApplicationRoute extends Route {
7
7
 
8
8
  loading(transition) {
9
9
  const resourceName = this.getResouceName(transition);
10
- this.loader.showOnInitialTransition(transition, 'section.next-view-section', resourceName ? `Loading ${resourceName}...` : `Loading...`);
10
+ this.loader.showOnInitialTransition(transition, 'section.next-view-section', { loadingMessage: resourceName ? `Loading ${resourceName}...` : `Loading...` });
11
11
  }
12
12
 
13
13
  model() {
@@ -11,7 +11,7 @@ export default class HomeRoute extends Route {
11
11
  @service loader;
12
12
 
13
13
  @action loading(transition) {
14
- const loader = this.loader.show(`Loading FleetOps...`);
14
+ const loader = this.loader.show({ loadingMessage: `Loading Fleet-Ops...` });
15
15
 
16
16
  transition.finally(() => {
17
17
  this.loader.removeLoader(loader);
@@ -1,8 +1,13 @@
1
1
  import Route from '@ember/routing/route';
2
2
  import { inject as service } from '@ember/service';
3
+
3
4
  export default class ManagementDriversIndexDetailsRoute extends Route {
4
5
  @service store;
5
6
 
7
+ queryParams = {
8
+ view: { refreshModel: false },
9
+ };
10
+
6
11
  model({ public_id }) {
7
12
  return this.store.findRecord('driver', public_id);
8
13
  }
@@ -23,7 +23,7 @@ export default class OperationsServiceRatesIndexRoute extends Route {
23
23
  * @param {Transition} transition
24
24
  */
25
25
  @action loading(transition) {
26
- this.loader.showOnInitialTransition(transition, 'section.next-view-section', 'Loading service rates...');
26
+ this.loader.showOnInitialTransition(transition, 'section.next-view-section', { loadingMessage: 'Loading service rates...' });
27
27
  }
28
28
 
29
29
  /**
@@ -16,7 +16,7 @@ export default class OperationsZonesIndexRoute extends Route {
16
16
  * @param {Transition} transition
17
17
  */
18
18
  @action loading(transition) {
19
- this.loader.showOnInitialTransition(transition, 'section.next-view-section', 'Loading zones...');
19
+ this.loader.showOnInitialTransition(transition, 'section.next-view-section', { loadingMessage: 'Loading zones...' });
20
20
  }
21
21
 
22
22
  model() {
@@ -4,21 +4,26 @@ import { action } from '@ember/object';
4
4
  import getModelName from '@fleetbase/ember-core/utils/get-model-name';
5
5
 
6
6
  /**
7
- * Service to manage the context panel in the application.
7
+ * Service for managing the state and interactions of the context panel.
8
+ *
9
+ * @class ContextPanelService
10
+ * @memberof @fleetbase/fleetops
11
+ * @extends Service
8
12
  */
9
13
  export default class ContextPanelService extends Service {
10
14
  /**
11
- * Registry to map models to their corresponding components and arguments.
15
+ * Registry mapping model names to their corresponding component details.
16
+ * @type {Object}
12
17
  */
13
18
  registry = {
14
19
  driver: {
15
20
  viewing: {
16
21
  component: 'driver-panel',
17
- componentArguments: [{ isResizable: true }, { width: '550px' }],
22
+ componentArguments: [{ isResizable: true }, { width: '600px' }],
18
23
  },
19
24
  editing: {
20
25
  component: 'driver-form-panel',
21
- componentArguments: [{ isResizable: true }, { width: '550px' }],
26
+ componentArguments: [{ isResizable: true }, { width: '600px' }],
22
27
  },
23
28
  },
24
29
  vehicle: {
@@ -34,26 +39,42 @@ export default class ContextPanelService extends Service {
34
39
  };
35
40
 
36
41
  /**
37
- * The current context model.
42
+ * The current context or model object.
43
+ * @type {Object}
44
+ * @tracked
38
45
  */
39
46
  @tracked currentContext;
40
47
 
41
48
  /**
42
- * The current context registry.
49
+ * The current registry configuration for the current context.
50
+ * @type {Object}
51
+ * @tracked
43
52
  */
44
53
  @tracked currentContextRegistry;
45
54
 
46
55
  /**
47
- * The current context component arguments.
56
+ * Arguments for the current context component.
57
+ * @type {Object}
58
+ * @tracked
48
59
  */
49
60
  @tracked currentContextComponentArguments = {};
50
61
 
51
62
  /**
52
- * Focuses on a given model with a specific intent.
63
+ * Additional options for controlling the context.
64
+ * @type {Object}
65
+ * @tracked
66
+ */
67
+ @tracked contextOptions = {};
68
+
69
+ /**
70
+ * Focuses on a given model and intent.
71
+ *
72
+ * @method
53
73
  * @param {Object} model - The model to focus on.
54
- * @param {string} [intent='viewing'] - The intent for focusing (e.g., 'viewing', 'editing').
74
+ * @param {String} [intent='viewing'] - The type of intent ('viewing' or 'editing').
75
+ * @action
55
76
  */
56
- @action focus(model, intent = 'viewing') {
77
+ @action focus(model, intent = 'viewing', options = {}) {
57
78
  const modelName = getModelName(model);
58
79
  const registry = this.registry[modelName];
59
80
 
@@ -61,18 +82,30 @@ export default class ContextPanelService extends Service {
61
82
  this.currentContext = model;
62
83
  this.currentContextRegistry = registry[intent];
63
84
  this.currentContextComponentArguments = this.createDynamicArgsFromRegistry(registry[intent], model);
85
+ this.contextOptions = options;
64
86
  }
65
87
  }
66
88
 
67
89
  /**
68
- * Clears the current context.
90
+ * Clears the current context and associated details.
91
+ *
92
+ * @method
93
+ * @action
69
94
  */
70
95
  @action clear() {
71
96
  this.currentContext = null;
72
97
  this.currentContextRegistry = null;
73
98
  this.currentContextComponentArguments = {};
99
+ this.contextOptions = {};
74
100
  }
75
101
 
102
+ /**
103
+ * Changes the intent for the current context.
104
+ *
105
+ * @method
106
+ * @param {String} intent - The new intent.
107
+ * @action
108
+ */
76
109
  @action changeIntent(intent) {
77
110
  if (this.currentContext) {
78
111
  return this.focus(this.currentContext, intent);
@@ -80,9 +113,43 @@ export default class ContextPanelService extends Service {
80
113
  }
81
114
 
82
115
  /**
83
- * Creates dynamic arguments from the registry.
84
- * @param {Object} registry - The registry for the current context.
85
- * @param {Object} model - The model to focus on.
116
+ * Sets an option key-value pair.
117
+ *
118
+ * @method
119
+ * @param {String} key - The option key.
120
+ * @param {*} value - The option value.
121
+ */
122
+ setOption(key, value) {
123
+ this.contextOptions = {
124
+ ...this.contextOptions,
125
+ [key]: value,
126
+ };
127
+ }
128
+
129
+ /**
130
+ * Retrieves the value of an option key.
131
+ *
132
+ * @method
133
+ * @param {String} key - The option key.
134
+ * @param {*} [defaultValue=null] - The default value to return if the key is not found.
135
+ * @returns {*}
136
+ */
137
+ getOption(key, defaultValue = null) {
138
+ const value = this.contextOptions[key];
139
+
140
+ if (value === undefined) {
141
+ return defaultValue;
142
+ }
143
+
144
+ return value;
145
+ }
146
+
147
+ /**
148
+ * Generates dynamic arguments for a given registry and model.
149
+ *
150
+ * @method
151
+ * @param {Object} registry - The registry details for a given model.
152
+ * @param {Object} model - The model object.
86
153
  * @returns {Object} The dynamic arguments.
87
154
  */
88
155
  createDynamicArgsFromRegistry(registry, model) {
@@ -1 +1 @@
1
- <DriverPanel @driver={{@model}} @tab={{this.view}} @onPressCancel={{this.transitionBack}} />
1
+ <DriverPanel @driver={{@model}} @tab={{this.view}} @onTabChanged={{this.onTabChanged}} @onPressCancel={{this.transitionBack}} @onEdit={{this.onEdit}} />
@@ -1 +1 @@
1
- <DriverFormPanel @driver={{@model}} @onUpdateDriver={{this.updateDriver}} @onPressCancel={{this.transitionBack}}/>
1
+ <DriverFormPanel @driver={{@model}} @onPressCancel={{this.transitionBack}} @onAfterSave={{this.onAfterSave}} @onViewDetails={{this.onViewDetails}} @onLoad={{this.setOverlayContext}} />
@@ -1 +1 @@
1
- <DriverFormPanel @driver={{this.driver}} @onCreateDriver={{this.createDriver}} @onPressCancel={{this.transitionBack}}/>
1
+ <DriverFormPanel @driver={{this.driver}} @onPressCancel={{this.transitionBack}} @onAfterSave={{this.onAfterSave}} @onLoad={{this.setOverlayContext}} />
@@ -1 +1 @@
1
- <VehiclePanel @vehicle={{@model}} @tab={{this.view}} @onTabChanged={{mut this.view}} @onPressCancel={{this.transitionBack}} />
1
+ <VehiclePanel @vehicle={{@model}} @tab={{this.view}} @onTabChanged={{this.onTabChanged}} @onPressCancel={{this.transitionBack}} @onEdit={{this.onEdit}} />
@@ -1 +1 @@
1
- <VehicleFormPanel @vehicle={{@model}} @onPressCancel={{this.transitionBack}}/>
1
+ <VehicleFormPanel @vehicle={{@model}} @onPressCancel={{this.transitionBack}} @onAfterSave={{this.onAfterSave}} @onViewDetails={{this.onViewDetails}} @onLoad={{this.setOverlayContext}} />
@@ -1 +1 @@
1
- <VehicleFormPanel @vehicle={{this.vehicle}} @onPressCancel={{this.transitionBack}} />
1
+ <VehicleFormPanel @vehicle={{this.vehicle}} @onPressCancel={{this.transitionBack}} @onAfterSave={{this.onAfterSave}} @onLoad={{this.setOverlayContext}} />