@fleetbase/fleetops-engine 0.4.16 → 0.4.18
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/.php-cs-fixer.php +2 -0
- package/addon/components/activity-event-selector.hbs +35 -0
- package/addon/components/activity-event-selector.js +85 -0
- package/addon/components/activity-form-panel.hbs +23 -0
- package/addon/components/activity-form-panel.js +90 -0
- package/addon/components/activity-logic-builder.hbs +80 -0
- package/addon/components/activity-logic-builder.js +260 -0
- package/addon/components/contact-form-panel.hbs +1 -1
- package/addon/components/contact-panel.hbs +1 -1
- package/addon/components/custom-entity-form-panel.hbs +43 -0
- package/addon/components/custom-entity-form-panel.js +129 -0
- package/addon/components/custom-field-form-panel/options-input.hbs +12 -0
- package/addon/components/custom-field-form-panel/options-input.js +139 -0
- package/addon/components/custom-field-form-panel.hbs +77 -0
- package/addon/components/custom-field-form-panel.js +144 -0
- package/addon/components/custom-field.hbs +63 -41
- package/addon/components/custom-field.js +123 -25
- package/addon/components/driver-form-panel.hbs +1 -1
- package/addon/components/driver-panel.hbs +1 -1
- package/addon/components/edit-order-route-panel.hbs +1 -1
- package/addon/components/fleet-form-panel.hbs +1 -1
- package/addon/components/fleet-panel.hbs +1 -1
- package/addon/components/fuel-report-form-panel.hbs +1 -1
- package/addon/components/fuel-report-panel.hbs +1 -1
- package/addon/components/issue-form-panel.hbs +1 -1
- package/addon/components/issue-panel.hbs +1 -1
- package/addon/components/joint-graph.hbs +1 -0
- package/addon/components/joint-graph.js +103 -0
- package/addon/components/layout/fleet-ops-sidebar.hbs +3 -3
- package/addon/components/layout/fleet-ops-sidebar.js +1 -0
- package/addon/components/live-map.js +71 -28
- package/addon/components/modals/new-custom-field-group.hbs +5 -0
- package/addon/components/modals/new-order-config.hbs +3 -3
- package/addon/components/modals/order-new-activity.hbs +1 -1
- package/addon/components/order-config-manager/activity-flow.hbs +11 -0
- package/addon/components/order-config-manager/activity-flow.js +964 -0
- package/addon/components/order-config-manager/custom-fields.hbs +50 -0
- package/addon/components/order-config-manager/custom-fields.js +276 -0
- package/addon/components/order-config-manager/details.hbs +23 -0
- package/addon/components/order-config-manager/details.js +106 -0
- package/addon/components/order-config-manager/entities.hbs +54 -0
- package/addon/components/order-config-manager/entities.js +227 -0
- package/addon/components/order-config-manager-overlay.hbs +26 -0
- package/addon/components/order-config-manager-overlay.js +60 -0
- package/addon/components/order-config-manager.hbs +15 -0
- package/addon/components/order-config-manager.js +298 -0
- package/addon/components/order-flow.hbs +1 -0
- package/addon/components/order-flow.js +3 -0
- package/addon/components/place-form-panel.hbs +1 -1
- package/addon/components/place-panel.hbs +1 -1
- package/addon/components/vehicle-form-panel.hbs +1 -1
- package/addon/components/vehicle-panel.hbs +1 -1
- package/addon/components/vendor-form-panel.hbs +1 -1
- package/addon/components/vendor-panel.hbs +1 -1
- package/addon/controllers/application.js +5 -1
- package/addon/controllers/operations/order-config.js +43 -0
- package/addon/controllers/operations/orders/index/new.js +125 -21
- package/addon/controllers/operations/orders/index/view.js +87 -4
- package/addon/controllers/operations/orders/index.js +2 -2
- package/addon/engine.js +10 -1
- package/addon/initializers/load-jointjs.js +16 -0
- package/addon/routes/application.js +1 -1
- package/addon/routes/operations/order-config.js +28 -0
- package/addon/routes/operations/orders/index/new.js +2 -3
- package/addon/routes/operations/orders/index/view.js +1 -1
- package/addon/routes.js +1 -0
- package/addon/services/context-panel.js +65 -3
- package/addon/styles/fleetops-engine.css +268 -0
- package/addon/templates/application.hbs +1 -1
- package/addon/templates/operations/order-config.hbs +55 -0
- package/addon/templates/operations/orders/index/new.hbs +98 -339
- package/addon/templates/operations/orders/index/view.hbs +36 -96
- package/addon/templates/operations/orders/index.hbs +0 -1
- package/addon/utils/apply-context-component-arguments.js +4 -2
- package/addon/utils/create-custom-entity.js +22 -0
- package/addon/utils/create-flow-activity.js +31 -0
- package/addon/utils/get-custom-field-type-map.js +34 -0
- package/app/components/activity-event-selector.js +1 -0
- package/app/components/activity-form-panel.js +1 -0
- package/app/components/activity-logic-builder.js +1 -0
- package/app/components/custom-entity-form-panel.js +1 -0
- package/app/components/custom-field-form-panel/options-input.js +1 -0
- package/app/components/custom-field-form-panel.js +1 -0
- package/app/components/joint-graph.js +1 -0
- package/app/components/modals/new-custom-field-group.js +1 -0
- package/app/components/order-config-manager/activity-flow.js +1 -0
- package/app/components/order-config-manager/custom-fields.js +1 -0
- package/app/components/order-config-manager/details.js +1 -0
- package/app/components/order-config-manager/entities.js +1 -0
- package/app/components/order-config-manager-overlay.js +1 -0
- package/app/components/order-config-manager.js +1 -0
- package/app/components/order-flow.js +1 -0
- package/app/controllers/operations/order-config.js +1 -0
- package/app/routes/operations/order-config.js +1 -0
- package/app/templates/operations/order-config.js +1 -0
- package/app/utils/create-custom-entity.js +1 -0
- package/app/utils/create-flow-activity.js +1 -0
- package/app/utils/get-custom-field-type-map.js +1 -0
- package/composer.json +4 -3
- package/config/environment.js +1 -0
- package/extension.json +1 -1
- package/index.js +20 -0
- package/package.json +7 -5
- package/server/config/api.php +3 -650
- package/server/migrations/2023_04_27_053456_create_contacts_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_drivers_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_entities_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_fleet_drivers_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_fleets_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_fuel_reports_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_integrated_vendors_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_issues_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_orders_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_payloads_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_places_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_positions_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_proofs_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_purchase_rates_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_routes_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_service_areas_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_service_quote_items_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_service_quotes_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_service_rate_fees_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_service_rate_parcel_fees_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_service_rates_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_tracking_numbers_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_tracking_statuses_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_vehicles_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_vendors_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_waypoints_table.php +1 -2
- package/server/migrations/2023_04_27_053456_create_zones_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_companies_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_contacts_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_drivers_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_entities_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_fleet_drivers_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_fleets_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_fuel_reports_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_integrated_vendors_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_issues_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_orders_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_payloads_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_places_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_positions_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_proofs_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_purchase_rates_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_routes_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_service_areas_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_service_quote_items_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_service_quotes_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_service_rate_fees_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_service_rate_parcel_fees_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_service_rates_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_tracking_numbers_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_tracking_statuses_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_vehicles_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_vendors_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_waypoints_table.php +1 -2
- package/server/migrations/2023_04_27_053459_add_foreign_keys_to_zones_table.php +1 -2
- package/server/migrations/2023_09_14_074512_update_vehicles_table.php +1 -2
- package/server/migrations/2023_09_14_074619_create_vehicle_devices_table.php +35 -36
- package/server/migrations/2023_09_26_071205_add_online_column_to_vehicles_table.php +1 -2
- package/server/migrations/2023_09_26_083957_create_fleet_vehicles_table.php +1 -2
- package/server/migrations/2023_09_27_023757_add_column_to_fleets_table.php +1 -2
- package/server/migrations/2023_10_05_074811_update_vehicle.php +1 -2
- package/server/migrations/2023_10_25_093014_create_vehicle_device_events_table.php +1 -2
- package/server/migrations/2023_11_03_072503_refactor_issues_table_columns.php +1 -2
- package/server/migrations/2023_11_06_040645_refactor_fuel_reports_table.php +1 -2
- package/server/migrations/2023_11_09_041807_add_status_column_to_fuel_reports_table.php +1 -2
- package/server/migrations/2023_11_15_062814_add_comments_column_and_resolved_at_column_to_vehicle_device_events_table.php +1 -2
- package/server/migrations/2023_11_17_053001_add_category_uuid_to_entities_table.php +1 -2
- package/server/migrations/2023_11_28_074244_add_supplier_uuid_column_to_entities_table.php +1 -2
- package/server/migrations/2023_12_14_100209_add_meta_column_on_driver_table copy.php +1 -2
- package/server/migrations/2024_02_18_100209_add_avatar_url_columns_table.php +3 -4
- package/server/migrations/2024_02_27_093648_create_order_configs_table.php +43 -0
- package/server/migrations/2024_03_07_075508_add_order_config_uuid_column_to_orders_table.php +28 -0
- package/server/migrations/2024_03_12_033527_add_public_id_column_to_order_configs_table.php +34 -0
- package/server/seeders/OrderConfigSeeder.php +23 -0
- package/server/src/Casts/OrderConfigEntities.php +53 -0
- package/server/src/Console/Commands/FixLegacyOrderConfigs.php +66 -0
- package/server/src/Events/DriverLocationChanged.php +1 -1
- package/server/src/Events/DriverSimulatedLocationChanged.php +1 -1
- package/server/src/Flow/Activity.php +232 -6
- package/server/src/Flow/Condition.php +84 -0
- package/server/src/Flow/Event.php +88 -0
- package/server/src/Flow/Flow.php +50 -0
- package/server/src/Flow/FlowResource.php +143 -0
- package/server/src/Flow/Logic.php +57 -1
- package/server/src/Http/Controllers/Api/v1/DriverController.php +2 -2
- package/server/src/Http/Controllers/Api/v1/IssueController.php +132 -0
- package/server/src/Http/Controllers/Api/v1/OrderController.php +152 -57
- package/server/src/Http/Controllers/Api/v1/OrganizationController.php +27 -0
- package/server/src/Http/Controllers/Api/v1/PlaceController.php +2 -3
- package/server/src/Http/Controllers/Controller.php +9 -0
- package/server/src/Http/Controllers/FleetOpsController.php +7 -0
- package/server/src/Http/Controllers/Internal/v1/OrderConfigController.php +40 -233
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +58 -28
- package/server/src/Http/Controllers/Internal/v1/SettingController.php +20 -0
- package/server/src/Http/Filter/OrderConfigFilter.php +13 -0
- package/server/src/Http/Requests/CreateIssueRequest.php +19 -0
- package/server/src/Http/Requests/Internal/CreateOrderConfigRequest.php +40 -0
- package/server/src/Http/Requests/Internal/CreateOrderRequest.php +66 -0
- package/server/src/Http/Requests/Internal/DeleteOrderConfigRequest.php +0 -0
- package/server/src/Http/Requests/UpdateIssueRequest.php +7 -0
- package/server/src/Http/Resources/v1/Order.php +3 -0
- package/server/src/Listeners/HandleOrderCanceled.php +8 -4
- package/server/src/Listeners/HandleOrderDispatched.php +14 -12
- package/server/src/Models/Order.php +527 -31
- package/server/src/Models/OrderConfig.php +467 -0
- package/server/src/Models/Payload.php +6 -7
- package/server/src/Notifications/OrderAssigned.php +1 -1
- package/server/src/Notifications/OrderCanceled.php +1 -1
- package/server/src/Notifications/OrderDispatchFailed.php +1 -1
- package/server/src/Notifications/OrderDispatched.php +1 -1
- package/server/src/Notifications/OrderPing.php +1 -1
- package/server/src/Observers/CompanyObserver.php +20 -0
- package/server/src/Providers/FleetOpsServiceProvider.php +4 -1
- package/server/src/Providers/NotificationServiceProvider.php +2 -1
- package/server/src/Support/FleetOps.php +137 -0
- package/server/src/Support/Utils.php +17 -0
- package/server/src/Traits/HasTrackingNumber.php +9 -9
- package/server/src/routes.php +19 -11
- package/translations/en-us.yaml +137 -0
- package/server/src/Flow/Config.php +0 -7
- package/server/src/Support/Flow.php +0 -653
|
@@ -0,0 +1,129 @@
|
|
|
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 { dasherize } from '@ember/string';
|
|
6
|
+
import contextComponentCallback from '../utils/context-component-callback';
|
|
7
|
+
import applyContextComponentArguments from '../utils/apply-context-component-arguments';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Component class for custom entity form panel.
|
|
11
|
+
* This component handles the creation and editing of custom entities,
|
|
12
|
+
* including file uploads and type settings.
|
|
13
|
+
*
|
|
14
|
+
* @extends Component
|
|
15
|
+
*/
|
|
16
|
+
export default class CustomEntityFormPanelComponent extends Component {
|
|
17
|
+
/**
|
|
18
|
+
* Service for displaying notifications.
|
|
19
|
+
* @service
|
|
20
|
+
*/
|
|
21
|
+
@service notifications;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Service for performing fetch operations.
|
|
25
|
+
* @service
|
|
26
|
+
*/
|
|
27
|
+
@service fetch;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Tracked property for the custom entity being edited or created.
|
|
31
|
+
* @tracked
|
|
32
|
+
*/
|
|
33
|
+
@tracked customEntity;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Tracked property for configuration settings of the custom entity.
|
|
37
|
+
* @tracked
|
|
38
|
+
*/
|
|
39
|
+
@tracked config;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Constructor for CustomEntityFormPanelComponent.
|
|
43
|
+
* Applies context component arguments upon instantiation.
|
|
44
|
+
*/
|
|
45
|
+
constructor() {
|
|
46
|
+
super(...arguments);
|
|
47
|
+
applyContextComponentArguments(this);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Action method to save the custom entity. It triggers an optional onSave callback
|
|
52
|
+
* with the current state of the custom entity.
|
|
53
|
+
* @action
|
|
54
|
+
*/
|
|
55
|
+
@action save() {
|
|
56
|
+
contextComponentCallback(this, 'onSave', this.customEntity);
|
|
57
|
+
if (typeof this.onSave === 'function') {
|
|
58
|
+
this.onSave(this.customEntity);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Action method called when a file is added. It uploads the file
|
|
64
|
+
* and updates the custom entity's photo information.
|
|
65
|
+
* @param {File} file - The file that was added.
|
|
66
|
+
* @action
|
|
67
|
+
*/
|
|
68
|
+
@action onFileAdded(file) {
|
|
69
|
+
this.fetch.uploadFile.perform(
|
|
70
|
+
file,
|
|
71
|
+
{
|
|
72
|
+
path: `uploads/${this.config.id}/entity/${this.simpleHash(this.customEntity.get('name') + '+' + this.customEntity.get('description'))}`,
|
|
73
|
+
subject_uuid: this.config.id,
|
|
74
|
+
subject_type: 'fleet-ops:order-config',
|
|
75
|
+
type: 'custom_entity_image',
|
|
76
|
+
},
|
|
77
|
+
(uploadedFile) => {
|
|
78
|
+
this.customEntity.setProperties({
|
|
79
|
+
photo_uuid: uploadedFile.id,
|
|
80
|
+
photo_url: uploadedFile.url,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Action method to set the type of the custom entity. Converts the type to a dasherized string.
|
|
88
|
+
* @param {Event} event - The event object containing the selected type.
|
|
89
|
+
* @action
|
|
90
|
+
*/
|
|
91
|
+
@action setCustomEntityType(event) {
|
|
92
|
+
const value = event.target.value;
|
|
93
|
+
this.customEntity.set('type', dasherize(value));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Action method to update the unit of dimensions of the custom entity.
|
|
98
|
+
* @param {string} unit - The unit for the dimensions.
|
|
99
|
+
* @action
|
|
100
|
+
*/
|
|
101
|
+
@action updateCustomEntityDimensionsUnit(unit) {
|
|
102
|
+
this.customEntity.set('dimensions_unit', unit);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Action method to update the weight unit of the custom entity.
|
|
107
|
+
* @param {string} unit - The unit for the weight.
|
|
108
|
+
* @action
|
|
109
|
+
*/
|
|
110
|
+
@action updateCustomEntityWeightUnit(unit) {
|
|
111
|
+
this.customEntity.set('weight_unit', unit);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* A utility method to generate a simple hash from a string.
|
|
116
|
+
* Used for creating unique identifiers.
|
|
117
|
+
* @param {string} str - The input string.
|
|
118
|
+
* @returns {number} The generated hash value.
|
|
119
|
+
*/
|
|
120
|
+
simpleHash(str) {
|
|
121
|
+
let hash = 0;
|
|
122
|
+
for (let i = 0; i < str.length; i++) {
|
|
123
|
+
const char = str.charCodeAt(i);
|
|
124
|
+
hash = (hash << 5) - hash + char;
|
|
125
|
+
hash |= 0;
|
|
126
|
+
}
|
|
127
|
+
return hash;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<div class="rounded-lg border border-gray-200 dark:border-gray-700" ...attributes>
|
|
2
|
+
<div class="flex flex-row items-center justify-between px-4 py-2">
|
|
3
|
+
<div class="mr-2 text-sm">{{t "fleet-ops.component.custom-field-form-panel.field-options"}}</div>
|
|
4
|
+
<Button @type="magic" @icon="plus" @text="Add new option" @size="xs" @onClick={{this.addOption}} />
|
|
5
|
+
</div>
|
|
6
|
+
{{#each-in this.options as |index option|}}
|
|
7
|
+
<div class="border-t border-gray-200 dark:border-gray-700 flex flex-row items-center pr-2 py-1">
|
|
8
|
+
<input value={{option}} {{on "input" (fn this.updateOptionValue index)}} {{on "blur" this.updateOptions}} class="w-full bg-white dark:bg-gray-900 text-sm leading-4 text-black dark:text-gray-200 p-2" />
|
|
9
|
+
<Button @type="danger" @icon="times" @onClick={{fn this.removeOption index}} @size="xs" />
|
|
10
|
+
</div>
|
|
11
|
+
{{/each-in}}
|
|
12
|
+
</div>
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import { tracked } from '@glimmer/tracking';
|
|
3
|
+
import { action } from '@ember/object';
|
|
4
|
+
import { isArray } from '@ember/array';
|
|
5
|
+
import isObject from '@fleetbase/ember-core/utils/is-object';
|
|
6
|
+
|
|
7
|
+
export default class CustomFieldFormPanelOptionsInputComponent extends Component {
|
|
8
|
+
/**
|
|
9
|
+
* Represents the custom field being manipulated.
|
|
10
|
+
* @type {Object}
|
|
11
|
+
*/
|
|
12
|
+
@tracked customField;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The object holding the current state of options, indexed by unique keys.
|
|
16
|
+
* @type {Object}
|
|
17
|
+
*/
|
|
18
|
+
@tracked options = {};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A temporary object used to manage updates to options before finalizing changes.
|
|
22
|
+
* @type {Object}
|
|
23
|
+
*/
|
|
24
|
+
@tracked _options = {};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Constructs a new CustomFieldFormPanelOptionsInputComponent instance, initializing the custom field and options tracking.
|
|
28
|
+
* @param {Object} owner - The owner of the component.
|
|
29
|
+
* @param {Object} customField - The custom field object to be managed.
|
|
30
|
+
*/
|
|
31
|
+
constructor(owner, { customField }) {
|
|
32
|
+
super(...arguments);
|
|
33
|
+
this.customField = customField;
|
|
34
|
+
this.trackOptions(this.createOptionsObjectFromArray(customField.options));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Converts an array of options into an object format for easier tracking and manipulation.
|
|
39
|
+
* @param {Array} options - The array of options to be converted.
|
|
40
|
+
* @returns {Object} The options object.
|
|
41
|
+
*/
|
|
42
|
+
createOptionsObjectFromArray(options = []) {
|
|
43
|
+
const optionsObject = {};
|
|
44
|
+
if (isArray(options)) {
|
|
45
|
+
for (let i = 0; i < options.length; i++) {
|
|
46
|
+
const option = options[i];
|
|
47
|
+
optionsObject[i] = option;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return optionsObject;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Tracks the given options object, setting both the primary and temporary options states.
|
|
56
|
+
* @param {Object} options - The options object to track.
|
|
57
|
+
*/
|
|
58
|
+
trackOptions(options = {}) {
|
|
59
|
+
this.options = options;
|
|
60
|
+
this._options = options;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Adds a new option to the options object.
|
|
65
|
+
*/
|
|
66
|
+
@action addOption() {
|
|
67
|
+
const index = Object.keys(this.options).length + 1;
|
|
68
|
+
this.trackOptions({
|
|
69
|
+
...this.options,
|
|
70
|
+
[index]: '',
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Updates the value of an option at the specified index.
|
|
76
|
+
* @param {number} index - The index of the option to update.
|
|
77
|
+
* @param {Event} event - The input event containing the new value.
|
|
78
|
+
*/
|
|
79
|
+
@action updateOptionValue(index, event) {
|
|
80
|
+
let value = event.target.value;
|
|
81
|
+
this._options = {
|
|
82
|
+
...this.options,
|
|
83
|
+
[index]: value,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Removes an option at the specified index.
|
|
89
|
+
* @param {number} index - The index of the option to remove.
|
|
90
|
+
*/
|
|
91
|
+
@action removeOption(index) {
|
|
92
|
+
const options = { ...this.options };
|
|
93
|
+
delete options[index];
|
|
94
|
+
this.trackOptions(options);
|
|
95
|
+
this.onOptionsChanges();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Updates the primary options object with changes made to the temporary options object.
|
|
100
|
+
*/
|
|
101
|
+
@action updateOptions() {
|
|
102
|
+
this.options = {
|
|
103
|
+
...this._options,
|
|
104
|
+
};
|
|
105
|
+
this.onOptionsChanges();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Handles changes to the options, updating the customField and calling the onChange callback if provided.
|
|
110
|
+
*/
|
|
111
|
+
@action onOptionsChanges() {
|
|
112
|
+
const options = Object.values(this.options);
|
|
113
|
+
this.customField.set('options', options);
|
|
114
|
+
if (typeof this.args.onChange === 'function') {
|
|
115
|
+
this.args.onChange(options, this.customField);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Adds or updates a meta option with the given key and value.
|
|
121
|
+
* @param {string} key - The key of the meta option to add or update.
|
|
122
|
+
* @param {string} value - The value of the meta option.
|
|
123
|
+
*/
|
|
124
|
+
@action addMetaOption(key, value) {
|
|
125
|
+
if (!isObject(this.customField.meta)) {
|
|
126
|
+
this.customField.set('meta', {});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const meta = {
|
|
130
|
+
...this.customField.meta,
|
|
131
|
+
[key]: value,
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
this.customField.meta = meta;
|
|
135
|
+
if (typeof this.args.onMetaChanged === 'function') {
|
|
136
|
+
this.args.onMetaChanged(meta, this.customField);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<Overlay @onLoad={{this.setOverlayContext}} @onOpen={{this.onOpen}} @onClose={{this.onClose}} @onToggle={{this.onToggle}} @position="right" @noBackdrop={{true}} @fullHeight={{true}} @isResizable={{or this.isResizable @isResizable}} @width={{or this.width @width "570px"}}>
|
|
2
|
+
<Overlay::Header @title={{if this.customField.label (concat (t "fleet-ops.component.custom-field-form-panel.custom-field-title-concat") this.customField.label) (t "fleet-ops.component.custom-field-form-panel.new-custom-field") }} @hideStatusDot={{true}} @titleWrapperClass="leading-5">
|
|
3
|
+
<div class="flex flex-1 justify-end">
|
|
4
|
+
<Button @icon={{if this.customField.id "save" "check"}} @type="primary" @text={{if this.customField.id (t "fleet-ops.component.custom-field-form-panel.save-custom-field")(t "fleet-ops.component.custom-field-form-panel.create-custom-field") }} @onClick={{perform this.save}} @isLoading={{not this.save.isIdle}} @wrapperClass="mr-2" />
|
|
5
|
+
<Button @type="default" @icon="times" @helpText={{if this.customField.id (t "fleet-ops.component.custom-field-form-panel.cancel-edit-custom-field")(t "fleet-ops.component.custom-field-form-panel.close-new-custom-field") }} @onClick={{this.onPressCancel}} />
|
|
6
|
+
</div>
|
|
7
|
+
</Overlay::Header>
|
|
8
|
+
|
|
9
|
+
<Overlay::Body @wrapperClass="px-4 pt-4">
|
|
10
|
+
<InputGroup @name={{t "fleet-ops.component.custom-field-form-panel.field-label"}} @value={{this.customField.label}} {{on "input" this.setCustomFieldName}} />
|
|
11
|
+
<InputGroup @name={{t "fleet-ops.component.custom-field-form-panel.field-description"}} @value={{this.customField.description}} />
|
|
12
|
+
<InputGroup @name={{t "fleet-ops.component.custom-field-form-panel.field-help-text"}} @value={{this.customField.help_text}} />
|
|
13
|
+
<InputGroup>
|
|
14
|
+
<Toggle @isToggled={{this.customField.required}} @onToggle={{fn (mut this.customField.required)}}>
|
|
15
|
+
<span class="dark:text-gray-100 text-sm ml-2">{{t "fleet-ops.component.custom-field-form-panel.field-is-required"}}</span>
|
|
16
|
+
</Toggle>
|
|
17
|
+
</InputGroup>
|
|
18
|
+
<InputGroup>
|
|
19
|
+
<Toggle @isToggled={{this.customField.editable}} @onToggle={{fn (mut this.customField.editable)}}>
|
|
20
|
+
<span class="dark:text-gray-100 text-sm ml-2">{{t "fleet-ops.component.custom-field-form-panel.field-is-editable"}}</span>
|
|
21
|
+
</Toggle>
|
|
22
|
+
</InputGroup>
|
|
23
|
+
<InputGroup @name={{t "fleet-ops.component.custom-field-form-panel.field-type"}}>
|
|
24
|
+
<select class="form-select w-full has--placeholder" {{on "change" this.onSelectCustomFieldType}}>
|
|
25
|
+
<option selected disabled>
|
|
26
|
+
{{t "fleet-ops.component.custom-field-form-panel.select-field-type"}}
|
|
27
|
+
</option>
|
|
28
|
+
{{#each-in this.customFieldTypeMap as |key|}}
|
|
29
|
+
<option value={{dasherize key}} selected={{eq this.customField.type (dasherize key)}}>
|
|
30
|
+
{{smart-humanize key}}
|
|
31
|
+
</option>
|
|
32
|
+
{{/each-in}}
|
|
33
|
+
</select>
|
|
34
|
+
</InputGroup>
|
|
35
|
+
{{#if this.currentFieldMap.hasOptions}}
|
|
36
|
+
<CustomFieldFormPanel::OptionsInput @customField={{this.customField}} @fieldMap={{this.currentFieldMap}} class="mb-4" />
|
|
37
|
+
{{/if}}
|
|
38
|
+
{{#if this.currentFieldMap.allowedModels}}
|
|
39
|
+
<InputGroup @name={{t "fleet-ops.component.custom-field-form-panel.field-model-type"}}>
|
|
40
|
+
<select class="form-select w-full has--placeholder" {{on "change" this.onSelectModelType}}>
|
|
41
|
+
<option selected disabled>
|
|
42
|
+
{{t "fleet-ops.component.custom-field-form-panel.field-select-model-type"}}
|
|
43
|
+
</option>
|
|
44
|
+
{{#each this.currentFieldMap.allowedModels as |modelName|}}
|
|
45
|
+
<option value={{dasherize modelName}} selected={{eq this.customField.meta.modelName (dasherize modelName)}}>
|
|
46
|
+
{{smart-humanize modelName}}
|
|
47
|
+
</option>
|
|
48
|
+
{{/each}}
|
|
49
|
+
</select>
|
|
50
|
+
</InputGroup>
|
|
51
|
+
{{/if}}
|
|
52
|
+
<InputGroup @name={{t "fleet-ops.component.custom-field-form-panel.meta-col-span"}}>
|
|
53
|
+
<DropdownButton @text={{concat (t "fleet-ops.component.custom-field-form-panel.col-span-size") ": " (n-a this.customField.meta.colSpan)}} @textClass="text-sm mr-2" @buttonClass="flex-row-reverse w-64 justify-between" @icon="caret-down" @iconClass="mr-0i" @size="sm" @iconPrefix="fas" @triggerClass="hidden md:flex" as |dd|>
|
|
54
|
+
<div class="next-dd-menu mt-1 mx-0" aria-labelledby="user-menu">
|
|
55
|
+
<div class="p-1">
|
|
56
|
+
{{#each this.colSpanSizeOptions as |size|}}
|
|
57
|
+
<a href="javascript:;" class="next-dd-item" {{on "click" (dropdown-fn dd this.setCustomFieldMetaProperty "colSpan" size)}}>
|
|
58
|
+
<div class="flex-1 flex flex-row items-center">
|
|
59
|
+
<div class="w-6">
|
|
60
|
+
<FaIcon @icon="grip" />
|
|
61
|
+
</div>
|
|
62
|
+
<span>{{size}}</span>
|
|
63
|
+
</div>
|
|
64
|
+
<div>
|
|
65
|
+
{{#if (eq size this.customField.meta.colSpan)}}
|
|
66
|
+
<FaIcon @icon="check" class="text-green-500" />
|
|
67
|
+
{{/if}}
|
|
68
|
+
</div>
|
|
69
|
+
</a>
|
|
70
|
+
{{/each}}
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
</DropdownButton>
|
|
74
|
+
</InputGroup>
|
|
75
|
+
<Spacer @height="300px" />
|
|
76
|
+
</Overlay::Body>
|
|
77
|
+
</Overlay>
|
|
@@ -0,0 +1,144 @@
|
|
|
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 { dasherize, camelize } from '@ember/string';
|
|
6
|
+
import { task } from 'ember-concurrency-decorators';
|
|
7
|
+
import isObject from '@fleetbase/ember-core/utils/is-object';
|
|
8
|
+
import contextComponentCallback from '../utils/context-component-callback';
|
|
9
|
+
import applyContextComponentArguments from '../utils/apply-context-component-arguments';
|
|
10
|
+
import getCustomFieldTypeMap from '../utils/get-custom-field-type-map';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Component class for managing custom fields within forms.
|
|
14
|
+
* This component facilitates the creation and editing of custom fields,
|
|
15
|
+
* offering a variety of field types including inputs, selects, and file uploads.
|
|
16
|
+
*
|
|
17
|
+
* @extends Component
|
|
18
|
+
*/
|
|
19
|
+
export default class CustomFieldFormPanelComponent extends Component {
|
|
20
|
+
/**
|
|
21
|
+
* Service for displaying notifications.
|
|
22
|
+
* @service
|
|
23
|
+
*/
|
|
24
|
+
@service notifications;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Tracked property for the custom field being edited or created.
|
|
28
|
+
* @tracked
|
|
29
|
+
*/
|
|
30
|
+
@tracked customField;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Tracked property representing the current mapping for the selected field type.
|
|
34
|
+
* @tracked
|
|
35
|
+
*/
|
|
36
|
+
@tracked currentFieldMap;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* A map defining the available custom field types and their corresponding components.
|
|
40
|
+
*/
|
|
41
|
+
customFieldTypeMap = getCustomFieldTypeMap();
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Tracked array of col span size options for the custom field groups.
|
|
45
|
+
* @tracked
|
|
46
|
+
*/
|
|
47
|
+
@tracked colSpanSizeOptions = [1, 2, 3];
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Constructor for CustomFieldFormPanelComponent.
|
|
51
|
+
* Applies context component arguments and selects the appropriate field map
|
|
52
|
+
* based on the custom field type.
|
|
53
|
+
*/
|
|
54
|
+
constructor() {
|
|
55
|
+
super(...arguments);
|
|
56
|
+
applyContextComponentArguments(this);
|
|
57
|
+
this.selectFieldMap(this.customField.type);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* A task for saving the custom field. It handles the save operation asynchronously,
|
|
62
|
+
* manages callbacks on success, and shows notifications on error.
|
|
63
|
+
* @task
|
|
64
|
+
*/
|
|
65
|
+
@task *save() {
|
|
66
|
+
yield this.customField
|
|
67
|
+
.save()
|
|
68
|
+
.then((customField) => {
|
|
69
|
+
if (typeof this.onCustomFieldSaved === 'function') {
|
|
70
|
+
this.onCustomFieldSaved(customField);
|
|
71
|
+
}
|
|
72
|
+
contextComponentCallback(this, 'onCustomFieldSaved', customField);
|
|
73
|
+
})
|
|
74
|
+
.catch((error) => {
|
|
75
|
+
this.notifications.serverError(error);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Action method to set the name of the custom field. Converts the name to a dasherized string.
|
|
81
|
+
* @param {Event} event - The event object containing the new field name.
|
|
82
|
+
* @action
|
|
83
|
+
*/
|
|
84
|
+
@action setCustomFieldName(event) {
|
|
85
|
+
const value = event.target.value;
|
|
86
|
+
this.customField.name = dasherize(value);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Action method for selecting the custom field type. It updates the field type
|
|
91
|
+
* and selects the corresponding field map.
|
|
92
|
+
* @param {Event} event - The event object containing the selected field type.
|
|
93
|
+
* @action
|
|
94
|
+
*/
|
|
95
|
+
@action onSelectCustomFieldType(event) {
|
|
96
|
+
const value = event.target.value;
|
|
97
|
+
const type = dasherize(value);
|
|
98
|
+
this.customField.type = type;
|
|
99
|
+
this.selectFieldMap(type);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Action method for selecting a model type for the custom field.
|
|
104
|
+
* @param {Event} event - The event object containing the selected model type.
|
|
105
|
+
* @action
|
|
106
|
+
*/
|
|
107
|
+
@action onSelectModelType(event) {
|
|
108
|
+
const value = event.target.value;
|
|
109
|
+
const modelName = dasherize(value);
|
|
110
|
+
this.setCustomFieldMetaProperty('modelName', modelName);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Action method to set a metadata property for the custom field.
|
|
115
|
+
* Initializes the metadata object if it doesn't exist.
|
|
116
|
+
* @param {string} key - The key of the metadata property.
|
|
117
|
+
* @param {*} value - The value to set for the property.
|
|
118
|
+
* @action
|
|
119
|
+
*/
|
|
120
|
+
@action setCustomFieldMetaProperty(key, value) {
|
|
121
|
+
if (!isObject(this.customField.meta)) {
|
|
122
|
+
this.customField.set('meta', {});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
this.customField.meta[key] = value;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Selects the field map based on the given field type.
|
|
130
|
+
* Updates the current field map and the component for the custom field.
|
|
131
|
+
* @param {string} type - The type of the custom field.
|
|
132
|
+
*/
|
|
133
|
+
selectFieldMap(type) {
|
|
134
|
+
if (!type) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const fieldKey = camelize(type);
|
|
138
|
+
const fieldMap = this.customFieldTypeMap[fieldKey];
|
|
139
|
+
if (fieldMap) {
|
|
140
|
+
this.currentFieldMap = fieldMap;
|
|
141
|
+
this.customField.component = fieldMap.component;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
@@ -1,42 +1,64 @@
|
|
|
1
|
-
|
|
2
|
-
{{
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
1
|
+
{{#if this.customFieldComponent}}
|
|
2
|
+
<div class="{{if this.customField.meta.colSpan (concat "col-span-" this.customField.meta.colSpan) ''}}">
|
|
3
|
+
{{#if (eq this.customFieldComponent "input")}}
|
|
4
|
+
<InputGroup @name={{this.customField.label}} @value={{this.value}} @required={{this.customField.required}} @helpText={{this.customField.help_text}} {{on "input" this.onChangeHandler}} />
|
|
5
|
+
{{else if (eq this.customFieldComponent "select")}}
|
|
6
|
+
<InputGroup @name={{this.customField.label}} @required={{this.customField.required}} @helpText={{this.customField.help_text}}>
|
|
7
|
+
<select class="form-select w-full has--placeholder" {{on "change" this.onChangeHandler}}>
|
|
8
|
+
<option selected disabled>
|
|
9
|
+
{{this.customField.label}}
|
|
10
|
+
</option>
|
|
11
|
+
{{#each this.customField.options as |selectOption|}}
|
|
12
|
+
<option value={{selectOption}} selected={{eq this.value selectOption}}>
|
|
13
|
+
{{selectOption}}
|
|
14
|
+
</option>
|
|
15
|
+
{{/each}}
|
|
16
|
+
</select>
|
|
17
|
+
</InputGroup>
|
|
18
|
+
{{else if (eq this.customFieldComponent "phone-input")}}
|
|
19
|
+
<InputGroup @name={{this.customField.label}} @required={{this.customField.required}} @helpText={{this.customField.help_text}}>
|
|
20
|
+
<PhoneInput @value={{this.value}} @onInput={{this.onChangeHandler}} class="form-input w-full" />
|
|
21
|
+
</InputGroup>
|
|
22
|
+
{{else if (eq this.customFieldComponent "money-input")}}
|
|
23
|
+
<InputGroup @name={{this.customField.label}} @required={{this.customField.required}} @helpText={{this.customField.help_text}}>
|
|
24
|
+
<MoneyInput class="w-full" @wrapperClass="x-fleetops-input-height shadow-md" @value={{this.value}} @canSelectCurrency={{true}} @onChange={{this.onChangeHandler}} />
|
|
25
|
+
</InputGroup>
|
|
26
|
+
{{else if (eq this.customFieldComponent "date-time-input")}}
|
|
27
|
+
<InputGroup @name={{this.customField.label}} @required={{this.customField.required}} @helpText={{this.customField.help_text}}>
|
|
28
|
+
<DateTimeInput class="form-input" @value={{this.value}} @minDate={{format-date (now) "yyyy-MM-d" }} @minTime={{format-date (now) "HH:mm" }} @onUpdate={{this.onChangeHandler}} />
|
|
29
|
+
</InputGroup>
|
|
30
|
+
{{else if (eq this.customFieldComponent "radio-button-select")}}
|
|
31
|
+
<InputGroup @name={{this.customField.label}} @required={{this.customField.required}} @helpText={{this.customField.help_text}}>
|
|
32
|
+
<div class="mt-2 flex items-center space-x-2">
|
|
33
|
+
{{#each this.customField.options as |radioOption index|}}
|
|
34
|
+
<div class="radio-group-item shadow-sm {{if (eq this.value radioOption) 'is-checked'}}">
|
|
35
|
+
<div class="flex items-center">
|
|
36
|
+
<RadioButton @radioClass="focus:ring-blue-500" @radioId={{concat this.customField.name "-radio-option-" index}} @value={{radioOption}} @groupValue={{this.value}} @name={{radioOption}} @changed={{this.onChangeHandler}} />
|
|
37
|
+
<div class="ml-2 text-sm dark:text-gray-100 text-gray-900 truncate">{{radioOption}}</div>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
{{/each}}
|
|
29
41
|
</div>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
</InputGroup>
|
|
43
|
+
{{else if (eq this.customFieldComponent "file-upload")}}
|
|
44
|
+
<InputGroup @name={{this.customField.label}} @required={{this.customField.required}} @helpText={{this.customField.help_text}}>
|
|
45
|
+
<div class="flex items-center">
|
|
46
|
+
<FileUpload @name={{this.customField.name}} @for={{this.customField.name}} @accept={{join "," this.acceptedFileTypes}} @multiple={{false}} @onFileAdded={{this.onFileAddedHandler}}>
|
|
47
|
+
<a tabindex={{0}} class="btn btn-default btn-xs cursor-pointer">
|
|
48
|
+
<FaIcon @icon="upload" @size="sm" class="mr-2" />{{t "common.select-file"}}
|
|
49
|
+
</a>
|
|
50
|
+
</FileUpload>
|
|
51
|
+
{{#if this.file}}
|
|
52
|
+
<div class="ml-2 flex items-center text-sm">
|
|
53
|
+
<Spinner class="dark:text-blue-400 text-blue-900" />
|
|
54
|
+
<span class="ml-2 text-xs dark:text-blue-400 text-blue-900">{{round this.file.progress}}%</span>
|
|
55
|
+
</div>
|
|
56
|
+
{{/if}}
|
|
57
|
+
</div>
|
|
58
|
+
{{#if this.uploadedFile}}
|
|
59
|
+
<File @file={{this.uploadedFile}} @onDelete={{this.removeFile}} class="custom-field-file" />
|
|
60
|
+
{{/if}}
|
|
61
|
+
</InputGroup>
|
|
62
|
+
{{/if}}
|
|
63
|
+
</div>
|
|
64
|
+
{{/if}}
|