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.

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