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.

756 lines
30KB

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