@fleetbase/fleetops-engine 0.2.8 → 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 (88) hide show
  1. package/addon/components/context-panel.hbs +5 -0
  2. package/addon/components/context-panel.js +6 -0
  3. package/addon/components/driver-card-mini.js +34 -13
  4. package/addon/components/driver-form-panel.hbs +23 -23
  5. package/addon/components/driver-form-panel.js +96 -13
  6. package/addon/components/driver-panel.hbs +12 -12
  7. package/addon/components/driver-panel.js +125 -21
  8. package/addon/components/fleet-vehicle-listing.hbs +1 -1
  9. package/addon/components/live-map.hbs +20 -9
  10. package/addon/components/live-map.js +1255 -353
  11. package/addon/components/map-container/toolbar/visibility-control-panel.hbs +66 -0
  12. package/addon/components/map-container/toolbar/visibility-control-panel.js +74 -0
  13. package/addon/components/map-container/toolbar/zones-panel.hbs +10 -10
  14. package/addon/components/map-container/toolbar/zones-panel.js +90 -61
  15. package/addon/components/map-container/toolbar.hbs +12 -7
  16. package/addon/components/modals/vehicle-form.hbs +35 -35
  17. package/addon/components/settings-window.hbs +1 -1
  18. package/addon/components/vehicle-form-panel.hbs +25 -26
  19. package/addon/components/vehicle-form-panel.js +95 -12
  20. package/addon/components/vehicle-panel.hbs +12 -13
  21. package/addon/components/vehicle-panel.js +130 -20
  22. package/addon/controllers/management/drivers/index/details.js +53 -0
  23. package/addon/controllers/management/drivers/index/edit.js +77 -46
  24. package/addon/controllers/management/drivers/index/new.js +39 -79
  25. package/addon/controllers/management/drivers/index.js +17 -221
  26. package/addon/controllers/management/fleets/index/edit.js +1 -1
  27. package/addon/controllers/management/fleets/index/new.js +1 -1
  28. package/addon/controllers/management/fuel-reports/index.js +2 -2
  29. package/addon/controllers/management/vehicles/index/details.js +49 -0
  30. package/addon/controllers/management/vehicles/index/edit.js +104 -1
  31. package/addon/controllers/management/vehicles/index/new.js +71 -0
  32. package/addon/controllers/operations/orders/index/new.js +4 -6
  33. package/addon/controllers/operations/orders/index/view.js +22 -14
  34. package/addon/controllers/operations/orders/index.js +124 -50
  35. package/addon/controllers/operations/service-rates/index/edit.js +1 -1
  36. package/addon/controllers/operations/service-rates/index/new.js +1 -1
  37. package/addon/engine.js +6 -0
  38. package/addon/helpers/is-visibility-control-visible.js +18 -0
  39. package/addon/routes/application.js +1 -1
  40. package/addon/routes/home.js +1 -1
  41. package/addon/routes/management/drivers/index/details.js +5 -0
  42. package/addon/routes/operations/orders/index/view.js +4 -2
  43. package/addon/routes/operations/orders/index.js +5 -1
  44. package/addon/routes/operations/service-rates/index.js +1 -1
  45. package/addon/routes/operations/zones/index.js +1 -1
  46. package/addon/services/context-panel.js +173 -0
  47. package/addon/services/leaflet-contextmenu-manager.js +311 -0
  48. package/addon/services/leaflet-map-manager.js +61 -0
  49. package/addon/services/service-areas.js +242 -32
  50. package/addon/templates/application.hbs +2 -1
  51. package/addon/templates/management/drivers/index/details.hbs +1 -1
  52. package/addon/templates/management/drivers/index/edit.hbs +1 -1
  53. package/addon/templates/management/drivers/index/new.hbs +1 -1
  54. package/addon/templates/management/vehicles/index/details.hbs +1 -1
  55. package/addon/templates/management/vehicles/index/edit.hbs +1 -1
  56. package/addon/templates/management/vehicles/index/new.hbs +1 -1
  57. package/addon/templates/operations/orders/index/view.hbs +2 -2
  58. package/addon/templates/operations/orders/index.hbs +1 -1
  59. package/addon/utils/apply-context-component-arguments.js +31 -0
  60. package/addon/utils/context-component-callback.js +16 -0
  61. package/addon/utils/find-leaflet-layer.js +13 -0
  62. package/addon/utils/fly-to-leaflet-layer.js +25 -0
  63. package/addon/utils/get-leaflet-layer-by-id.js +12 -0
  64. package/addon/utils/layer-can-bind-contextmenu.js +3 -0
  65. package/app/components/context-panel.js +1 -0
  66. package/app/components/map-container/toolbar/visibility-control-panel.js +1 -0
  67. package/app/helpers/is-visibility-control-visible.js +1 -0
  68. package/app/services/context-panel.js +1 -0
  69. package/app/services/leaflet-contextmenu-manager.js +1 -0
  70. package/app/services/leaflet-map-manager.js +1 -0
  71. package/app/utils/apply-context-component-arguments.js +1 -0
  72. package/app/utils/context-component-callback.js +1 -0
  73. package/app/utils/find-leaflet-layer.js +1 -0
  74. package/app/utils/fly-to-leaflet-layer.js +1 -0
  75. package/app/utils/get-leaflet-layer-by-id.js +1 -0
  76. package/app/utils/layer-can-bind-contextmenu.js +1 -0
  77. package/composer.json +11 -1
  78. package/extension.json +1 -1
  79. package/package.json +3 -3
  80. package/server/migrations/2023_09_14_074512_update_vehicles_table.php +89 -88
  81. package/server/migrations/2023_10_25_093014_create_vehicle_device_events_table.php +56 -0
  82. package/server/src/Http/Controllers/Internal/v1/LiveController.php +7 -4
  83. package/server/src/Http/Filter/VehicleFilter.php +7 -0
  84. package/server/src/Http/Resources/v1/Vehicle.php +52 -39
  85. package/server/src/Models/VehicleDevice.php +17 -3
  86. package/server/src/Models/VehicleDeviceEvent.php +90 -0
  87. package/addon/services/map-manager.js +0 -3
  88. package/app/services/map-manager.js +0 -1
@@ -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
  /**
@@ -113,6 +112,20 @@ export default class OperationsOrdersIndexController extends Controller {
113
112
  'layout',
114
113
  ];
115
114
 
115
+ /**
116
+ * The current driver being focused.
117
+ *
118
+ * @var {DriverModel|null}
119
+ */
120
+ @tracked focusedDriver;
121
+
122
+ /**
123
+ * The current vehicle being focused.
124
+ *
125
+ * @var {VehicleModel|null}
126
+ */
127
+ @tracked focusedVehicle;
128
+
116
129
  /**
117
130
  * The current page of data being viewed
118
131
  *
@@ -616,39 +629,59 @@ export default class OperationsOrdersIndexController extends Controller {
616
629
  this.query = value;
617
630
  }
618
631
 
619
- @action viewPlacesOnMap() {
620
- const {
621
- leafletMap: { liveMap },
622
- } = this;
623
-
624
- if (liveMap) {
625
- liveMap.togglePlaces();
626
- }
627
- }
628
-
632
+ /**
633
+ * Hides all elements on the live map.
634
+ * @action
635
+ * @memberof OperationsOrdersIndexController
636
+ */
629
637
  @action resetView() {
630
638
  if (this.leafletMap && this.leafletMap.liveMap) {
631
- this.leafletMap.liveMap.hideDrivers();
632
- this.leafletMap.liveMap.hideRoutes();
639
+ this.leafletMap.liveMap.hideAll();
633
640
  }
634
641
  }
635
642
 
643
+ /**
644
+ * Toggles the visibility of the search interface.
645
+ * @action
646
+ * @memberof OperationsOrdersIndexController
647
+ */
636
648
  @action toggleSearch() {
637
649
  this.isSearchVisible = !this.isSearchVisible;
638
650
  }
639
651
 
652
+ /**
653
+ * Toggles the visibility of the orders panel.
654
+ * @action
655
+ * @memberof OperationsOrdersIndexController
656
+ */
640
657
  @action toggleOrdersPanel() {
641
658
  this.isOrdersPanelVisible = !this.isOrdersPanelVisible;
642
659
  }
643
660
 
661
+ /**
662
+ * Hides the orders panel.
663
+ * @action
664
+ * @memberof OperationsOrdersIndexController
665
+ */
644
666
  @action hideOrdersPanel() {
645
667
  this.isOrdersPanelVisible = false;
646
668
  }
647
669
 
670
+ /**
671
+ * Shows the orders panel.
672
+ * @action
673
+ * @memberof OperationsOrdersIndexController
674
+ */
648
675
  @action showOrdersPanel() {
649
676
  this.isOrdersPanelVisible = true;
650
677
  }
651
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
+ */
652
685
  @action zoomMap(direction = 'in') {
653
686
  if (direction === 'in') {
654
687
  this.leafletMap?.zoomIn();
@@ -657,6 +690,12 @@ export default class OperationsOrdersIndexController extends Controller {
657
690
  }
658
691
  }
659
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
+ */
660
699
  @action setLayoutMode(mode) {
661
700
  this.layout = mode;
662
701
 
@@ -667,22 +706,57 @@ export default class OperationsOrdersIndexController extends Controller {
667
706
  this.universe.trigger('dashboard.layout.changed', mode);
668
707
  }
669
708
 
670
- @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 } }) {
671
721
  this.leafletMap = target;
722
+ this.liveMap = liveMap;
672
723
  }
673
724
 
725
+ /**
726
+ * Exports all orders.
727
+ * @action
728
+ * @memberof OperationsOrdersIndexController
729
+ */
674
730
  @action exportOrders() {
675
731
  this.crud.export('order');
676
732
  }
677
733
 
734
+ /**
735
+ * Redirects to the new order creation page.
736
+ * @action
737
+ * @memberof OperationsOrdersIndexController
738
+ */
678
739
  @action createOrder() {
679
740
  return this.transitionToRoute('operations.orders.index.new');
680
741
  }
681
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
+ */
682
749
  @action viewOrder(order) {
683
750
  return this.transitionToRoute('operations.orders.index.view', order);
684
751
  }
685
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
+ */
686
760
  @action cancelOrder(order, options = {}) {
687
761
  this.modalsManager.confirm({
688
762
  title: `Are you sure you wish to cancel this order?`,
@@ -700,6 +774,13 @@ export default class OperationsOrdersIndexController extends Controller {
700
774
  });
701
775
  }
702
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
+ */
703
784
  @action dispatchOrder(order, options = {}) {
704
785
  this.modalsManager.confirm({
705
786
  title: `Are you sure you want to dispatch this order?`,
@@ -726,6 +807,13 @@ export default class OperationsOrdersIndexController extends Controller {
726
807
  });
727
808
  }
728
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
+ */
729
817
  @action deleteOrder(order, options = {}) {
730
818
  this.crud.delete(order, {
731
819
  onSuccess: () => {
@@ -735,6 +823,12 @@ export default class OperationsOrdersIndexController extends Controller {
735
823
  });
736
824
  }
737
825
 
826
+ /**
827
+ * Deletes multiple selected orders.
828
+ * @param {Array} [selected=[]] - Orders selected for deletion.
829
+ * @action
830
+ * @memberof OperationsOrdersIndexController
831
+ */
738
832
  @action bulkDeleteOrders(selected = []) {
739
833
  selected = selected.length > 0 ? selected : this.table.selectedRows;
740
834
 
@@ -747,6 +841,12 @@ export default class OperationsOrdersIndexController extends Controller {
747
841
  });
748
842
  }
749
843
 
844
+ /**
845
+ * Cancels multiple selected orders.
846
+ * @param {Array} [selected=[]] - Orders selected for cancellation.
847
+ * @action
848
+ * @memberof OperationsOrdersIndexController
849
+ */
750
850
  @action bulkCancelOrders(selected = []) {
751
851
  selected = selected.length > 0 ? selected : this.table.selectedRows;
752
852
 
@@ -772,46 +872,20 @@ export default class OperationsOrdersIndexController extends Controller {
772
872
  });
773
873
  }
774
874
 
775
- @action applyFilters(columns) {
776
- columns.forEach((column) => {
777
- // if value is a model only filter by id
778
- if (isModel(column.filterValue)) {
779
- column.filterValue = column.filterValue.id;
780
- }
781
-
782
- // if value is an array of models map to ids
783
- if (isArray(column.filterValue) && column.filterValue.every((v) => isModel(v))) {
784
- column.filterValue = column.filterValue.map((v) => v.id);
785
- }
786
-
787
- // only if filter is active continue
788
- if (column.isFilterActive && column.filterValue) {
789
- this[column.filterParam || column.valuePath] = column.filterValue;
790
- } else {
791
- this[column.filterParam || column.valuePath] = undefined;
792
- column.isFilterActive = false;
793
- column.filterValue = undefined;
794
- }
795
- });
796
-
797
- this.columns = columns;
798
- }
799
-
800
- @action setFilterOptions(valuePath, options) {
801
- const updatedColumns = this.columns.map((column) => {
802
- if (column.valuePath === valuePath) {
803
- column.filterOptions = options;
804
- }
805
- return column;
806
- });
807
-
808
- this.columns = updatedColumns;
809
- }
810
-
875
+ /**
876
+ * Triggers when the map container is ready.
877
+ * @action
878
+ * @memberof OperationsOrdersIndexController
879
+ */
811
880
  @action onMapContainerReady() {
812
881
  this.fetchActiveOrdersCount();
813
882
  }
814
883
 
884
+ /**
885
+ * Fetches the count of active orders.
886
+ * @action
887
+ * @memberof OperationsOrdersIndexController
888
+ */
815
889
  @action fetchActiveOrdersCount() {
816
890
  this.fetch.get('fleet-ops/metrics/all', { discover: ['orders_in_progress'] }).then((response) => {
817
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
package/addon/engine.js CHANGED
@@ -42,6 +42,12 @@ export default class FleetOpsEngine extends Engine {
42
42
 
43
43
  // register the driver panel
44
44
  universe.createRegistry('component:driver-panel');
45
+
46
+ // register vehicle context menu
47
+ universe.createRegistry('contextmenu:vehicle');
48
+
49
+ // register driver context menu
50
+ universe.createRegistry('contextmenu:driver');
45
51
  };
46
52
  }
47
53
 
@@ -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
  }
@@ -8,8 +8,10 @@ export default class OperationsOrdersIndexViewRoute extends Route {
8
8
  @service store;
9
9
  @service socket;
10
10
 
11
- @action willTransition() {
12
- if (this.controller) {
11
+ @action willTransition(transition) {
12
+ const shouldReset = typeof transition.to.name === 'string' && !transition.to.name.includes('operations.orders');
13
+
14
+ if (this.controller && shouldReset) {
13
15
  this.controller.resetView();
14
16
  }
15
17
  }
@@ -28,7 +28,11 @@ export default class OperationsOrdersIndexRoute extends Route {
28
28
  };
29
29
 
30
30
  @action willTransition(transition) {
31
- this.controller?.resetView(transition);
31
+ const shouldReset = typeof transition.to.name === 'string' && !transition.to.name.includes('operations.orders');
32
+
33
+ if (this.controller && shouldReset) {
34
+ this.controller.resetView(transition);
35
+ }
32
36
  }
33
37
 
34
38
  @action model(params) {
@@ -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() {
@@ -0,0 +1,173 @@
1
+ import Service from '@ember/service';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { action } from '@ember/object';
4
+ import getModelName from '@fleetbase/ember-core/utils/get-model-name';
5
+
6
+ /**
7
+ * Service for managing the state and interactions of the context panel.
8
+ *
9
+ * @class ContextPanelService
10
+ * @memberof @fleetbase/fleetops
11
+ * @extends Service
12
+ */
13
+ export default class ContextPanelService extends Service {
14
+ /**
15
+ * Registry mapping model names to their corresponding component details.
16
+ * @type {Object}
17
+ */
18
+ registry = {
19
+ driver: {
20
+ viewing: {
21
+ component: 'driver-panel',
22
+ componentArguments: [{ isResizable: true }, { width: '600px' }],
23
+ },
24
+ editing: {
25
+ component: 'driver-form-panel',
26
+ componentArguments: [{ isResizable: true }, { width: '600px' }],
27
+ },
28
+ },
29
+ vehicle: {
30
+ viewing: {
31
+ component: 'vehicle-panel',
32
+ componentArguments: [{ isResizable: true }, { width: '600px' }],
33
+ },
34
+ editing: {
35
+ component: 'vehicle-form-panel',
36
+ componentArguments: [{ isResizable: true }, { width: '600px' }],
37
+ },
38
+ },
39
+ };
40
+
41
+ /**
42
+ * The current context or model object.
43
+ * @type {Object}
44
+ * @tracked
45
+ */
46
+ @tracked currentContext;
47
+
48
+ /**
49
+ * The current registry configuration for the current context.
50
+ * @type {Object}
51
+ * @tracked
52
+ */
53
+ @tracked currentContextRegistry;
54
+
55
+ /**
56
+ * Arguments for the current context component.
57
+ * @type {Object}
58
+ * @tracked
59
+ */
60
+ @tracked currentContextComponentArguments = {};
61
+
62
+ /**
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
73
+ * @param {Object} model - The model to focus on.
74
+ * @param {String} [intent='viewing'] - The type of intent ('viewing' or 'editing').
75
+ * @action
76
+ */
77
+ @action focus(model, intent = 'viewing', options = {}) {
78
+ const modelName = getModelName(model);
79
+ const registry = this.registry[modelName];
80
+
81
+ if (registry && registry[intent]) {
82
+ this.currentContext = model;
83
+ this.currentContextRegistry = registry[intent];
84
+ this.currentContextComponentArguments = this.createDynamicArgsFromRegistry(registry[intent], model);
85
+ this.contextOptions = options;
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Clears the current context and associated details.
91
+ *
92
+ * @method
93
+ * @action
94
+ */
95
+ @action clear() {
96
+ this.currentContext = null;
97
+ this.currentContextRegistry = null;
98
+ this.currentContextComponentArguments = {};
99
+ this.contextOptions = {};
100
+ }
101
+
102
+ /**
103
+ * Changes the intent for the current context.
104
+ *
105
+ * @method
106
+ * @param {String} intent - The new intent.
107
+ * @action
108
+ */
109
+ @action changeIntent(intent) {
110
+ if (this.currentContext) {
111
+ return this.focus(this.currentContext, intent);
112
+ }
113
+ }
114
+
115
+ /**
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.
153
+ * @returns {Object} The dynamic arguments.
154
+ */
155
+ createDynamicArgsFromRegistry(registry, model) {
156
+ // Generate dynamic arguments object
157
+ const dynamicArgs = {};
158
+ const componentArguments = registry.componentArguments || [];
159
+
160
+ componentArguments.forEach((arg, index) => {
161
+ if (typeof arg === 'string') {
162
+ dynamicArgs[arg] = model[arg]; // Map string arguments to model properties
163
+ } else if (typeof arg === 'object' && arg !== null) {
164
+ Object.assign(dynamicArgs, arg);
165
+ } else {
166
+ // Handle other types of arguments as needed
167
+ dynamicArgs[`arg${index}`] = arg;
168
+ }
169
+ });
170
+
171
+ return dynamicArgs;
172
+ }
173
+ }