You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

695 lines
28KB

  1. import 'dart:convert';
  2. import 'package:farm_tpf/custom_model/SuppliesUsing.dart';
  3. import 'package:farm_tpf/custom_model/action_form/ActionUIField.dart';
  4. import 'package:farm_tpf/custom_model/action_form/ActionUIForm.dart';
  5. import 'package:farm_tpf/custom_model/action_form/CommonData.dart';
  6. import 'package:farm_tpf/custom_model/action_form/RequestActivity.dart';
  7. import 'package:farm_tpf/data/api/app_exception.dart';
  8. import 'package:farm_tpf/data/repository/repository.dart';
  9. import 'package:farm_tpf/presentation/custom_widgets/app_bar_widget.dart';
  10. import 'package:farm_tpf/presentation/custom_widgets/bloc/media_helper_bloc.dart';
  11. import 'package:farm_tpf/presentation/custom_widgets/button_widget.dart';
  12. import 'package:farm_tpf/presentation/custom_widgets/dropdown_supply_widget.dart';
  13. import 'package:farm_tpf/presentation/custom_widgets/loading_list_page.dart';
  14. import 'package:farm_tpf/presentation/custom_widgets/widget_action_field_date.dart';
  15. import 'package:farm_tpf/presentation/custom_widgets/widget_field_time_picker.dart';
  16. import 'package:farm_tpf/presentation/custom_widgets/widget_loading.dart';
  17. import 'package:farm_tpf/presentation/custom_widgets/widget_media_picker.dart';
  18. import 'package:farm_tpf/presentation/custom_widgets/widget_radio_button.dart';
  19. import 'package:farm_tpf/presentation/custom_widgets/widget_text_field_area.dart';
  20. import 'package:farm_tpf/presentation/custom_widgets/widget_text_form_field.dart';
  21. import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart';
  22. import 'package:farm_tpf/presentation/screens/actions/cubit/action_ui_cubit.dart';
  23. import 'package:farm_tpf/utils/const_string.dart';
  24. import 'package:farm_tpf/utils/pref.dart';
  25. import 'package:farm_tpf/utils/validators.dart';
  26. import 'package:flutter/material.dart';
  27. import 'package:flutter/scheduler.dart';
  28. import 'package:flutter_bloc/flutter_bloc.dart';
  29. import 'package:get/get.dart';
  30. import 'package:keyboard_dismisser/keyboard_dismisser.dart';
  31. import 'package:farm_tpf/utils/formatter.dart';
  32. import '../../../utils/local_storage.dart';
  33. import 'controller/ChangeFieldInForm.dart';
  34. import 'controller/ChangeSupplyUsing.dart';
  35. import 'controller/ChangeWorker.dart';
  36. import 'dung/widget_dung_supply.dart';
  37. import 'nursery/widget_worker.dart';
  38. import 'plant/widget_plant_supply.dart';
  39. import 'spraying/widget_spraying_supply.dart';
  40. import 'state_management_helper/change_dropdown_controller.dart';
  41. import 'state_management_helper/change_file_controller.dart';
  42. import 'util_action.dart';
  43. class ActionScreen extends StatefulWidget {
  44. final bool isEdit;
  45. final int cropId;
  46. final int idAction;
  47. final String activityType;
  48. final String title;
  49. final int activityId;
  50. ActionScreen({
  51. required this.isEdit,
  52. required this.cropId,
  53. required this.idAction,
  54. required this.title,
  55. required this.activityType,
  56. required this.activityId,
  57. });
  58. @override
  59. _ActionScreenState createState() => _ActionScreenState();
  60. }
  61. class _ActionScreenState extends State<ActionScreen> {
  62. var _formKey = GlobalKey<FormState>();
  63. var pref = LocalPref();
  64. final _executeByController = TextEditingController();
  65. DateTime executeTime = DateTime.now();
  66. List<String> filePaths = <String>[];
  67. var controller = Get.put(ChangeDropdownController());
  68. var changeFileController = Get.put(ChangeFileController());
  69. Map<String, TextEditingController> textFieldControllers = {};
  70. Map<String, String> valueObjects = {};
  71. var _requestActivity = RequestActivity();
  72. final _repository = Repository();
  73. var _actionUIForm = ActionUIForm();
  74. var _nurseryDetails = <TbNurseryDetailsDTO>[];
  75. var _supplyUsings = <SuppliesUsing>[];
  76. var _previousGroupFieldName = '';
  77. var isValidated = false;
  78. Future<Null> getSharedPrefs() async {
  79. // var currentFullName = await pref.getString(DATA_CONST.CURRENT_FULL_NAME);
  80. var currentFullName = LocalStorage.getString(LocalStorageKey.full_name);
  81. _executeByController.text = currentFullName ?? "";
  82. }
  83. @override
  84. void initState() {
  85. super.initState();
  86. getSharedPrefs();
  87. changeFileController.initValue();
  88. }
  89. _submitForm() async {
  90. switch (widget.activityType) {
  91. case 'ACTIVE_TYPE_NURSERY':
  92. if (Get.find<ChangeFieldFormSupply>().isChanged ?? false) {
  93. Utils.showDialog(
  94. title: 'Thông tin người thực hiện chưa cập nhật',
  95. message: 'Bạn có muốn cập nhật',
  96. textConfirm: 'Tiếp tục',
  97. textCancel: 'Xem lại',
  98. onConfirm: () {
  99. Get.back();
  100. _validateInputs();
  101. });
  102. } else {
  103. _validateInputs();
  104. }
  105. break;
  106. case 'ACTIVE_TYPE_PLANTING':
  107. case 'ACTIVE_TYPE_FERTILIZE':
  108. case 'ACTIVE_TYPE_SPRAYING_PESTICIDES':
  109. if (Get.find<ChangeFieldFormSupply>().isChanged ?? false) {
  110. Utils.showDialogConfirmSupply(onConfirm: () {
  111. Get.back();
  112. _validateInputs();
  113. });
  114. } else {
  115. _validateInputs();
  116. }
  117. break;
  118. default:
  119. _validateInputs();
  120. break;
  121. }
  122. }
  123. _validateInputs() async {
  124. if (_formKey.currentState!.validate()) {
  125. _formKey.currentState!.save();
  126. try {
  127. LoadingDialog.showLoadingDialog(context);
  128. filePaths = Get.find<ChangeFileController>().newFiles ?? [];
  129. //Create request general model
  130. _requestActivity
  131. ..tbActivityTypeId = widget.idAction
  132. ..tbCropId = widget.cropId;
  133. if ((_actionUIForm.activityExtendTypeDTOList ?? []).isNotEmpty) {
  134. _requestActivity..externalTable = _actionUIForm?.activityExtendTypeDTOList?.first?.externalTable ?? '';
  135. }
  136. filePaths = Get.find<ChangeFileController>().newFiles ?? [];
  137. textFieldControllers.forEach((key, value) {
  138. valueObjects[key] = textFieldControllers[key]?.text ?? '';
  139. });
  140. //tbObjectUpdateDTOList
  141. var _objectPrameters = <TbObjectUpdateDTO>[];
  142. if (widget.isEdit) {
  143. // Edit
  144. if (_requestActivity.tbObjectUpdateDTOList != null) {
  145. _requestActivity.tbObjectUpdateDTOList?.forEach((element) {
  146. print(valueObjects[element.tbObjectParameterId.toString()]);
  147. var updateValue = '';
  148. if (Validators.stringNotNullOrEmpty(valueObjects[element.tbObjectParameterId.toString()] ?? '')) {
  149. updateValue = valueObjects[element.tbObjectParameterId.toString()] ?? '';
  150. } else {
  151. updateValue = element.index ?? '';
  152. }
  153. var objectUpdate = TbObjectUpdateDTO()
  154. ..id = element.id
  155. ..tbObjectParameterId = element.tbObjectParameterId
  156. ..index = updateValue;
  157. _objectPrameters.add(objectUpdate);
  158. });
  159. _requestActivity.tbObjectUpdateDTOList = _objectPrameters;
  160. }
  161. } else {
  162. //Add new
  163. valueObjects.forEach((key, value) {
  164. var objectUpdate = TbObjectUpdateDTO()
  165. ..tbObjectParameterId = int.tryParse(key)
  166. ..index = value;
  167. _objectPrameters.add(objectUpdate);
  168. });
  169. _requestActivity.tbObjectUpdateDTOList = _objectPrameters;
  170. }
  171. //CHECK NURSERY
  172. if (widget.activityType == 'ACTIVE_TYPE_NURSERY') {
  173. _requestActivity.tbNurseryDetailsDTOList = _nurseryDetails;
  174. } else if (widget.activityType == 'ACTIVE_TYPE_PLANTING' ||
  175. widget.activityType == 'ACTIVE_TYPE_FERTILIZE' ||
  176. widget.activityType == 'ACTIVE_TYPE_SPRAYING_PESTICIDES') {
  177. _requestActivity.tbSuppliesUsingDetailsDTOs = _supplyUsings;
  178. }
  179. //delete images
  180. _requestActivity.deletedImages = Get.find<ChangeFileController>().deleteFiles;
  181. //convert data to json
  182. var activityCommonData = jsonEncode(_requestActivity.toJson()).toString();
  183. print(activityCommonData);
  184. if (widget.activityId < 0) {
  185. //ADD New
  186. _repository.createActionCommon((data) {
  187. LoadingDialog.hideLoadingDialog(context);
  188. Get.back(result: 'ok');
  189. Utils.showSnackBarSuccess(message: label_add_success);
  190. }, (error) {
  191. LoadingDialog.hideLoadingDialog(context);
  192. Utils.showSnackBarError(message: AppException.handleError(error));
  193. }, activityType: widget.activityType, activityData: activityCommonData, filePaths: filePaths);
  194. } else {
  195. //UPDATE
  196. _repository.updateActionCommon((data) {
  197. LoadingDialog.hideLoadingDialog(context);
  198. Get.back(result: 'ok');
  199. Utils.showSnackBarSuccess(message: label_update_success);
  200. }, (error) {
  201. LoadingDialog.hideLoadingDialog(context);
  202. Utils.showSnackBarError(message: AppException.handleError(error));
  203. }, activityType: widget.activityType, activityData: activityCommonData, filePaths: filePaths);
  204. }
  205. //ADD NEW
  206. //Update
  207. } catch (e) {
  208. LoadingDialog.hideLoadingDialog(context);
  209. print(e.toString());
  210. }
  211. } else {
  212. //
  213. setState(() {
  214. isValidated = true;
  215. });
  216. }
  217. }
  218. Widget _btnExecuteTimePicker() {
  219. return WidgetFieldDateTimePicker(
  220. initDateTime: executeTime,
  221. onUpdateDateTime: (selectedDate) {
  222. _requestActivity.executeDate = selectedDate.convertLocalDateTimeToStringUtcDateTime();
  223. });
  224. }
  225. Widget _executeByField() {
  226. return TextFormField(
  227. keyboardType: TextInputType.text,
  228. decoration: InputDecoration(labelText: "Người thực hiện"),
  229. enabled: false,
  230. controller: _executeByController,
  231. onSaved: (newValue) {},
  232. );
  233. }
  234. //
  235. // GENERATE DYNAMIC FORM
  236. //
  237. Widget groupName(String name) {
  238. if (_previousGroupFieldName == name || !Validators.stringNotNullOrEmpty(name)) {
  239. return SizedBox();
  240. } else {
  241. _previousGroupFieldName = name ?? '';
  242. return Container(
  243. child: Row(
  244. children: [
  245. Container(
  246. width: 24,
  247. height: 0.5,
  248. color: Colors.green,
  249. ),
  250. Text(' ${name ?? ''} '),
  251. Expanded(
  252. child: Container(
  253. width: 5,
  254. height: 0.5,
  255. color: Colors.green,
  256. ),
  257. ),
  258. ],
  259. ),
  260. );
  261. }
  262. }
  263. Widget generateField(List<ActionUIField> fields) {
  264. return Wrap(
  265. children: [
  266. ListView.separated(
  267. shrinkWrap: true,
  268. physics: NeverScrollableScrollPhysics(),
  269. itemCount: fields.length,
  270. separatorBuilder: (context, index) {
  271. return SizedBox(
  272. height: 8,
  273. );
  274. },
  275. itemBuilder: (context, index) {
  276. var field = fields[index];
  277. if (field.tbControlTypeName == 'text') {
  278. return Column(
  279. children: [
  280. groupName(field.groupName ?? ''),
  281. TextFormField(
  282. keyboardType: TextInputType.text,
  283. decoration: InputDecoration(
  284. labelText: ((field.isMandatory ?? false) ?? false) ? '${field.description} *' : '${field.description}',
  285. hintText: field.description),
  286. controller: textFieldControllers[field.id.toString()],
  287. onSaved: (newValue) {},
  288. validator: ((field.isMandatory ?? false) ?? false)
  289. ? (String? value) {
  290. return Validators.validateNotNullOrEmpty(
  291. value ?? '',
  292. 'Vui lòng nhập ${field.description}',
  293. );
  294. }
  295. : null,
  296. ),
  297. ],
  298. );
  299. } else if (field.tbControlTypeName == 'number') {
  300. return Column(
  301. children: [
  302. groupName(field.groupName ?? ''),
  303. WidgetTextFormFieldNumber(
  304. hintValue: field.description ?? '',
  305. labelText: ((field.isMandatory ?? false) ?? false) ? '${field.description} *' : '${field.description}',
  306. textController: textFieldControllers[field.id.toString()] ?? TextEditingController(),
  307. onSaved: (newValue) {},
  308. validator: ((field.isMandatory ?? false) ?? false)
  309. ? (String? value) {
  310. return Validators.validNumberOrEmpty(
  311. value ?? '',
  312. 'Vui lòng nhập ${field.description}',
  313. );
  314. }
  315. : null,
  316. ),
  317. ],
  318. );
  319. } else if (field.tbControlTypeName == 'textarea') {
  320. return Column(
  321. children: [
  322. groupName(field.groupName ?? ''),
  323. TextFieldAreaWidget(
  324. hint: field.description ?? '',
  325. labelText: (field.isMandatory ?? false) ? '${field.description} *' : '${field.description}',
  326. controller: textFieldControllers[field.id.toString()] ?? TextEditingController(),
  327. onSaved: (newValue) {},
  328. validator: (field.isMandatory ?? false)
  329. ? (String? value) {
  330. return Validators.validateNotNullOrEmpty(
  331. value ?? '',
  332. 'Vui lòng nhập ${field.description}',
  333. );
  334. }
  335. : null,
  336. ),
  337. ],
  338. );
  339. } else if (field.tbControlTypeName == 'dropdown') {
  340. return Column(
  341. children: [
  342. groupName(field.groupName ?? ''),
  343. DropdownSupplyWidget(
  344. titleName: field.description ?? '',
  345. tbSupply: field.tbActivityExtendTypeExternalTable ?? '',
  346. tag: field.name ?? '',
  347. value: field.description,
  348. hint: '${field.description} ${(field.isMandatory ?? false) ? '*' : ''}',
  349. condition: field.tbActivityExtendTypeCondition ?? '',
  350. invalidMessage: '',
  351. onPressed: (commonData) {
  352. valueObjects[field.id.toString()] = commonData.id.toString();
  353. },
  354. ),
  355. ],
  356. );
  357. } else if (field.tbControlTypeName == 'radiobutton') {
  358. return Column(
  359. children: [
  360. groupName(field.groupName ?? ''),
  361. RadioButtonWidget(
  362. tag: field.name ?? '',
  363. condition: field.tbActivityExtendTypeCondition ?? '',
  364. supply: field.tbActivityExtendTypeExternalTable ?? '',
  365. onPressed: (commonData) {
  366. valueObjects[field.id.toString()] = commonData.id.toString();
  367. },
  368. ),
  369. ],
  370. );
  371. } else if (field.tbControlTypeName == 'date') {
  372. return Column(
  373. children: [
  374. groupName(field.groupName ?? ''),
  375. FieldDateWidget(
  376. tag: field.name ?? '',
  377. isValidated: isValidated,
  378. value: field.description,
  379. hint: '${field.description} ${(field.isMandatory ?? false) ? '*' : ''}',
  380. onPressed: (selectedDate) {
  381. valueObjects[field.id.toString()] = selectedDate.convertLocalDateTimeToStringUtcDateTime();
  382. },
  383. validator: (field.isMandatory ?? false)
  384. ? (String? value) {
  385. return Validators.validateNotNullOrEmpty(value ?? '', 'Vui lòng nhập ${field.description}');
  386. }
  387. : null,
  388. ),
  389. ],
  390. );
  391. } else {
  392. return Container();
  393. }
  394. })
  395. ],
  396. );
  397. }
  398. //
  399. // GENERATE SUPPLY
  400. //
  401. Widget generateSupply(String activityType) {
  402. switch (activityType) {
  403. case 'ACTIVE_TYPE_NURSERY':
  404. return WidgetWorker(onChangeWorkers: (nurseryDetails) {
  405. _nurseryDetails = nurseryDetails;
  406. });
  407. break;
  408. case 'ACTIVE_TYPE_PLANTING':
  409. return Column(
  410. children: [
  411. Container(
  412. width: double.infinity,
  413. height: 16,
  414. color: Colors.grey[200],
  415. ),
  416. WidgetPlantSupply(
  417. currentItems: [],
  418. onChangeSupplies: (value) {
  419. _supplyUsings = value;
  420. }),
  421. ],
  422. );
  423. break;
  424. case 'ACTIVE_TYPE_FERTILIZE':
  425. return Column(
  426. children: [
  427. Container(
  428. width: double.infinity,
  429. height: 16,
  430. color: Colors.grey[200],
  431. ),
  432. WidgetDungSupply(
  433. currentItems: [],
  434. onChangeSupplies: (value) {
  435. _supplyUsings = value;
  436. }),
  437. ],
  438. );
  439. break;
  440. case 'ACTIVE_TYPE_SPRAYING_PESTICIDES':
  441. return Column(
  442. children: [
  443. Container(
  444. width: double.infinity,
  445. height: 16,
  446. color: Colors.grey[200],
  447. ),
  448. WidgetSprayingSupply(
  449. currentItems: [],
  450. onChangeSupplies: (value) {
  451. _supplyUsings = value;
  452. }),
  453. ],
  454. );
  455. break;
  456. default:
  457. return Container();
  458. break;
  459. }
  460. }
  461. void showDataWhenEdit(BuildContext context) {
  462. //Show media
  463. try {
  464. if (Validators.stringNotNullOrEmpty(_requestActivity.media ?? '')) {
  465. BlocProvider.of<MediaHelperBloc>(context).add(
  466. ChangeListMedia(
  467. items: UtilAction.convertFilePathToMedia(
  468. _requestActivity.media ?? '',
  469. ),
  470. ),
  471. );
  472. }
  473. } catch (e) {
  474. print(e);
  475. }
  476. SchedulerBinding.instance.addPostFrameCallback((_) {
  477. if (widget.activityType == 'ACTIVE_TYPE_PLANTING' ||
  478. widget.activityType == 'ACTIVE_TYPE_FERTILIZE' ||
  479. widget.activityType == 'ACTIVE_TYPE_SPRAYING_PESTICIDES') {
  480. //list supply
  481. Get.find<ChangeSupplyUsing>().changeInitList(_requestActivity.tbSuppliesUsingDetailsDTOs ?? []);
  482. } else if (widget.activityType == 'ACTIVE_TYPE_NURSERY') {
  483. //list nursery
  484. Get.find<ChangeWorker>().changeInitList(_requestActivity.tbNurseryDetailsDTOList ?? []);
  485. }
  486. });
  487. //Show value textfield
  488. if (_requestActivity.tbObjectUpdateDTOList != null) {
  489. print(textFieldControllers.keys.toList());
  490. _requestActivity.tbObjectUpdateDTOList?.forEach((element) {
  491. if (element.tbObjectParameterDTO?.tbControlTypeName == 'text' || element.tbObjectParameterDTO?.tbControlTypeName == 'textarea') {
  492. SchedulerBinding.instance.addPostFrameCallback((_) {
  493. textFieldControllers[element.tbObjectParameterId.toString()]?.text = element.index ?? '';
  494. });
  495. } else if (element.tbObjectParameterDTO?.tbControlTypeName == 'number') {
  496. SchedulerBinding.instance.addPostFrameCallback((_) {
  497. textFieldControllers[element.tbObjectParameterId.toString()]?.text = element.index?.formatStringToStringDecimal() ?? '';
  498. });
  499. } else {
  500. SchedulerBinding.instance.addPostFrameCallback((_) {
  501. if (element.tbObjectParameterDTO?.tbControlTypeName == 'dropdown' ||
  502. element.tbObjectParameterDTO?.tbControlTypeName?.toLowerCase() == 'radiobutton') {
  503. var dropdownValueName = '';
  504. if ((element.tbObjectParameterDTO?.tbActivityExtendTypeDropDownDTOList ?? []).isNotEmpty ||
  505. element.tbObjectParameterDTO?.tbActivityExtendTypeDropDownDTOList != null) {
  506. element.tbObjectParameterDTO?.tbActivityExtendTypeDropDownDTOList?.forEach((dropdownData) {
  507. if (dropdownData.id == int.tryParse(element.index ?? '-1')) {
  508. dropdownValueName = dropdownData.name ?? '';
  509. }
  510. });
  511. }
  512. var commonData = CommonData()
  513. ..id = int.tryParse(element.index ?? '-1')
  514. ..name = dropdownValueName;
  515. Get.find<ChangeDropdownController>(tag: element.tbObjectParameterDTO?.name).change(commonData);
  516. } else if (element.tbObjectParameterDTO?.tbControlTypeName == 'date') {
  517. Get.find<ChangeDateTimePicker>(tag: element.tbObjectParameterDTO?.name).change(
  518. element.index?.convertStringServerDateTimeToLocalDateTime() ?? DateTime.now(),
  519. );
  520. }
  521. });
  522. }
  523. });
  524. } else {
  525. //
  526. }
  527. }
  528. @override
  529. Widget build(BuildContext context) => KeyboardDismisser(
  530. gestures: [
  531. GestureType.onTap,
  532. GestureType.onPanUpdateDownDirection,
  533. ],
  534. child: Scaffold(
  535. backgroundColor: Colors.white,
  536. appBar: AppBarWidget(
  537. isBack: true,
  538. action: InkWell(
  539. child: Text(
  540. 'Lưu',
  541. style: TextStyle(color: Colors.red, fontWeight: FontWeight.normal),
  542. ),
  543. onTap: () {
  544. FocusScopeNode currentFocus = FocusScope.of(context);
  545. if (!currentFocus.hasPrimaryFocus) {
  546. currentFocus.unfocus();
  547. }
  548. _submitForm();
  549. },
  550. ),
  551. ),
  552. body: MultiBlocProvider(
  553. providers: [
  554. BlocProvider<ActionUiCubit>(
  555. create: (context) => ActionUiCubit(repository: Repository())
  556. ..getActionUIForm(
  557. actionId: widget.idAction, actionType: widget.activityType, isEdit: widget.isEdit, activityId: widget.activityId)),
  558. BlocProvider<MediaHelperBloc>(
  559. create: (context) => MediaHelperBloc()..add(ChangeListMedia(items: [])),
  560. )
  561. ],
  562. child: Form(
  563. key: _formKey,
  564. child: SafeArea(
  565. child: BlocBuilder<ActionUiCubit, ActionUiState>(
  566. builder: (context, state) {
  567. if (state is ActionUiLoading) {
  568. print('loading...');
  569. return Center(
  570. child: LoadingListPage(),
  571. );
  572. } else if (state is ActionUiSuccess) {
  573. _actionUIForm = state.actionUIForm ?? ActionUIForm();
  574. _requestActivity = state.activityDetail ?? RequestActivity();
  575. //CREATE UI
  576. _actionUIForm.objectParameterDTOList?.forEach((element) {
  577. //generate controller
  578. if (element.tbControlTypeName == 'text' ||
  579. element.tbControlTypeName == 'number' ||
  580. element.tbControlTypeName == 'textarea') {
  581. var textEditingController = new TextEditingController();
  582. textFieldControllers.putIfAbsent(element.id.toString(), () => textEditingController);
  583. }
  584. // generate value each parameter
  585. valueObjects.putIfAbsent(element.id.toString(), () => '');
  586. });
  587. //SHOW EDIT DATA
  588. if (widget.isEdit) {
  589. showDataWhenEdit(context);
  590. }
  591. return SingleChildScrollView(
  592. child: Column(
  593. children: [
  594. Padding(
  595. padding: const EdgeInsets.all(8.0),
  596. child: Column(
  597. children: <Widget>[
  598. Container(
  599. width: double.infinity,
  600. child: Text(
  601. "Ngày thực hiện *",
  602. style: TextStyle(color: Colors.black54, fontSize: 13.0),
  603. ),
  604. ),
  605. _btnExecuteTimePicker(),
  606. SizedBox(
  607. height: 8.0,
  608. ),
  609. generateField(_actionUIForm.objectParameterDTOList ?? []),
  610. _executeByField(),
  611. SizedBox(
  612. height: 8.0,
  613. ),
  614. ],
  615. ),
  616. ),
  617. generateSupply(widget.activityType),
  618. Container(
  619. width: double.infinity,
  620. height: 16,
  621. color: Colors.grey[200],
  622. ),
  623. BlocBuilder<MediaHelperBloc, MediaHelperState>(builder: (context, state) {
  624. if (state is MediaHelperSuccess) {
  625. return WidgetMediaPicker(
  626. currentItems: state.items,
  627. onChangeFiles: (newPathFiles, deletePathFiles) async {
  628. Get.find<ChangeFileController>().change(newPathFiles, deletePathFiles);
  629. });
  630. } else {
  631. return Center(child: CircularProgressIndicator());
  632. }
  633. }),
  634. Padding(
  635. padding: const EdgeInsets.all(8.0),
  636. child: ButtonWidget(
  637. title: 'CẬP NHẬT',
  638. onPressed: () {
  639. FocusScopeNode currentFocus = FocusScope.of(context);
  640. if (!currentFocus.hasPrimaryFocus) {
  641. currentFocus.unfocus();
  642. }
  643. _submitForm();
  644. }),
  645. ),
  646. ],
  647. ),
  648. );
  649. } else if (state is ActionUiFailure) {
  650. return Center(child: Text(state.errorString));
  651. }
  652. return Container();
  653. },
  654. ),
  655. )),
  656. )));
  657. @override
  658. void dispose() {
  659. _executeByController.dispose();
  660. textFieldControllers.forEach((key, value) {
  661. textFieldControllers[key]?.dispose();
  662. });
  663. super.dispose();
  664. }
  665. }