auth/wyatt_arch_migration #25
| @ -32,3 +32,4 @@ export 'input_validators/name.dart'; | ||||
| export 'input_validators/password.dart'; | ||||
| export 'input_validators/phone.dart'; | ||||
| export 'input_validators/text_string.dart'; | ||||
| export 'repositories/form_repository_impl.dart'; | ||||
|  | ||||
| @ -30,6 +30,7 @@ class WyattFormImpl extends WyattForm { | ||||
|       FormInput<dynamic, FormInputValidator<dynamic, ValidationError>, | ||||
|           dynamic>> _inputs; | ||||
|   final FormValidator _validator; | ||||
|   final String _name; | ||||
| 
 | ||||
|   late List< | ||||
|       FormInput<dynamic, FormInputValidator<dynamic, ValidationError>, | ||||
| @ -37,8 +38,10 @@ class WyattFormImpl extends WyattForm { | ||||
| 
 | ||||
|   WyattFormImpl( | ||||
|     this._inputs, { | ||||
|     required String name, | ||||
|     FormValidator validationStrategy = const EveryInputValidator(), | ||||
|   }) : _validator = validationStrategy { | ||||
|   })  : _name = name, | ||||
|         _validator = validationStrategy { | ||||
|     _inputsInitial = _inputs.map((input) => input.clone()).toList(); | ||||
|   } | ||||
| 
 | ||||
| @ -50,6 +53,9 @@ class WyattFormImpl extends WyattForm { | ||||
|   @override | ||||
|   FormValidator get formValidationStrategy => _validator; | ||||
| 
 | ||||
|   @override | ||||
|   String get name => _name; | ||||
| 
 | ||||
|   @override | ||||
|   bool containsKey(String key) => inputs.any((input) => input.key == key); | ||||
| 
 | ||||
| @ -94,22 +100,24 @@ class WyattFormImpl extends WyattForm { | ||||
|   FormStatus validate() => formValidationStrategy.validate(this); | ||||
| 
 | ||||
|   @override | ||||
|   WyattForm clone() => WyattFormImpl( | ||||
|         _inputs.map((input) => input.clone()).toList(), | ||||
|         validationStrategy: formValidationStrategy, | ||||
|       ); | ||||
|   WyattForm clone() { | ||||
|     final clone = WyattFormImpl( | ||||
|       _inputs.map((input) => input.clone()).toList(), | ||||
|       name: _name, | ||||
|       validationStrategy: formValidationStrategy, | ||||
|     ).._inputsInitial = _inputsInitial; | ||||
|     return clone; | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   WyattForm reset() => WyattFormImpl( | ||||
|         _inputsInitial, | ||||
|         validationStrategy: formValidationStrategy, | ||||
|       ); | ||||
| 
 | ||||
|   @override | ||||
|   bool? get stringify => true; | ||||
| 
 | ||||
|   @override | ||||
|   List<Object?> get props => _inputs; | ||||
|   WyattForm reset() { | ||||
|     final newForm = WyattFormImpl( | ||||
|       _inputsInitial, | ||||
|       name: _name, | ||||
|       validationStrategy: formValidationStrategy, | ||||
|     ).._inputsInitial = _inputsInitial; | ||||
|     return newForm; | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   void updateMetadata<Extra>(String key, FormInputMetadata<Extra> metadata) { | ||||
| @ -133,4 +141,11 @@ class WyattFormImpl extends WyattForm { | ||||
|   @override | ||||
|   WyattForm operationWith(FormOperation operation, WyattForm other) => | ||||
|       operation.call(this, other); | ||||
| 
 | ||||
|   @override | ||||
|   List<Object?> get props => [_inputs, _name, _validator]; | ||||
| 
 | ||||
|   @override | ||||
|   String toString() => | ||||
|       'WyattForm(name: $name, validation: ${_validator.runtimeType}, inputs: $inputs)'; | ||||
| } | ||||
|  | ||||
| @ -44,6 +44,7 @@ class FormDifference extends FormOperation { | ||||
| 
 | ||||
|     return WyattFormImpl( | ||||
|       inputs, | ||||
|       name: a.name, | ||||
|       validationStrategy: a.formValidationStrategy, | ||||
|     ); | ||||
|   } | ||||
|  | ||||
| @ -38,6 +38,7 @@ class FormIntersection extends FormOperation { | ||||
| 
 | ||||
|     return WyattFormImpl( | ||||
|       inputs, | ||||
|       name: a.name, | ||||
|       validationStrategy: a.formValidationStrategy, | ||||
|     ); | ||||
|   } | ||||
|  | ||||
| @ -42,6 +42,7 @@ class FormUnion extends FormOperation { | ||||
| 
 | ||||
|     return WyattFormImpl( | ||||
|       inputs, | ||||
|       name: a.name, | ||||
|       validationStrategy: a.formValidationStrategy, | ||||
|     ); | ||||
|   } | ||||
|  | ||||
| @ -0,0 +1,60 @@ | ||||
| // Copyright (C) 2022 WYATT GROUP | ||||
| // Please see the AUTHORS file for details. | ||||
| // | ||||
| // This program is free software: you can redistribute it and/or modify | ||||
| // it under the terms of the GNU General Public License as published by | ||||
| // the Free Software Foundation, either version 3 of the License, or | ||||
| // any later version. | ||||
| // | ||||
| // This program is distributed in the hope that it will be useful, | ||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
| // GNU General Public License for more details. | ||||
| // | ||||
| // You should have received a copy of the GNU General Public License | ||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import 'package:wyatt_architecture/wyatt_architecture.dart'; | ||||
| import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart'; | ||||
| import 'package:wyatt_form_bloc/src/domain/repositories/form_repository.dart'; | ||||
| 
 | ||||
| class FormRepositoryImpl extends FormRepository { | ||||
|   final Map<String, WyattForm> _runtimeForms = {}; | ||||
| 
 | ||||
|   @override | ||||
|   Map<String, WyattForm> get runtimeForms => _runtimeForms; | ||||
| 
 | ||||
|   @override | ||||
|   WyattForm accessForm(String formName) { | ||||
|     if (_runtimeForms.containsKey(formName)) { | ||||
|       return _runtimeForms[formName]!; | ||||
|     } else { | ||||
|       throw ClientException( | ||||
|         'Form $formName is not registered. Just use ' | ||||
|         '`FormRepository.register(yourForm);` before any operation on it.', | ||||
|       ); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   void registerForm(WyattForm form) { | ||||
|     _runtimeForms[form.name] = form; | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   void updateForm(WyattForm form) { | ||||
|     if (_runtimeForms.containsKey(form.name)) { | ||||
|       _runtimeForms[form.name] = form; | ||||
|     } else { | ||||
|       throw ClientException( | ||||
|         'Form ${form.name} is not registered. Just use ' | ||||
|         '`FormRepository.register(yourForm);` before any operation on it.', | ||||
|       ); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   void unregisterForm(String formName) { | ||||
|     _runtimeForms.remove(formName); | ||||
|   } | ||||
| } | ||||
| @ -21,3 +21,4 @@ export 'form_encoders/form_encoder.dart'; | ||||
| export 'form_operations/form_operation.dart'; | ||||
| export 'form_validators/form_validator.dart'; | ||||
| export 'input_validators/form_input_validator.dart'; | ||||
| export 'repositories/form_repository.dart'; | ||||
|  | ||||
| @ -59,8 +59,9 @@ class FormInput< | ||||
|       ); | ||||
| 
 | ||||
|   @override | ||||
|   bool? get stringify => true; | ||||
|   List<Object?> get props => [key, validator, metadata]; | ||||
| 
 | ||||
|   @override | ||||
|   List<Object?> get props => [key, validator, metadata]; | ||||
|   String toString() => | ||||
|       'FormInput(name: $name, value: ${validator.value}, status: ${validator.status.name}'; | ||||
| } | ||||
|  | ||||
| @ -28,6 +28,7 @@ import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator | ||||
| abstract class WyattForm extends Equatable { | ||||
|   List<FormInput> get inputs; | ||||
|   FormValidator get formValidationStrategy; | ||||
|   String get name; | ||||
| 
 | ||||
|   bool containsKey(String key); | ||||
| 
 | ||||
|  | ||||
| @ -19,5 +19,6 @@ import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart'; | ||||
| // ignore: one_member_abstracts | ||||
| abstract class FormOperation { | ||||
|   const FormOperation(); | ||||
|   // TODO(hpcl): handle operation on `initialInputs` | ||||
|   WyattForm call(WyattForm a, WyattForm b); | ||||
| } | ||||
|  | ||||
| @ -18,11 +18,11 @@ import 'package:equatable/equatable.dart'; | ||||
| import 'package:wyatt_form_bloc/src/core/enums/form_input_status.dart'; | ||||
| import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart'; | ||||
| 
 | ||||
| part 'any_validator.dart'; | ||||
| part 'equality_validator.dart'; | ||||
| part 'nullable_validator.dart'; | ||||
| part 'regex_validator.dart'; | ||||
| part 'text_validator.dart'; | ||||
| part 'nullable_validator.dart'; | ||||
| part 'equality_validator.dart'; | ||||
| part 'any_validator.dart'; | ||||
| 
 | ||||
| /// {@template form_input_validator} | ||||
| /// A [FormInputValidator] represents the value of a single form input field. | ||||
|  | ||||
| @ -0,0 +1,27 @@ | ||||
| // Copyright (C) 2022 WYATT GROUP | ||||
| // Please see the AUTHORS file for details. | ||||
| // | ||||
| // This program is free software: you can redistribute it and/or modify | ||||
| // it under the terms of the GNU General Public License as published by | ||||
| // the Free Software Foundation, either version 3 of the License, or | ||||
| // any later version. | ||||
| // | ||||
| // This program is distributed in the hope that it will be useful, | ||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
| // GNU General Public License for more details. | ||||
| // | ||||
| // You should have received a copy of the GNU General Public License | ||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import 'package:wyatt_architecture/wyatt_architecture.dart'; | ||||
| import 'package:wyatt_form_bloc/wyatt_form_bloc.dart'; | ||||
| 
 | ||||
| abstract class FormRepository extends BaseRepository { | ||||
|   Map<String, WyattForm> get runtimeForms; | ||||
| 
 | ||||
|   void registerForm(WyattForm form); | ||||
|   void updateForm(WyattForm form); | ||||
|   WyattForm accessForm(String formName); | ||||
|   void unregisterForm(String formName); | ||||
| } | ||||
| @ -29,6 +29,8 @@ part 'form_data_state.dart'; | ||||
| abstract class FormDataCubit<State extends FormDataState> extends Cubit<State> { | ||||
|   FormDataCubit(super.initialState) : super(); | ||||
| 
 | ||||
|   String get formName; | ||||
| 
 | ||||
|   FutureOr<void> dataChanged<Value>( | ||||
|     String key, | ||||
|     FormInputValidator<Value, ValidationError> dirtyValue, | ||||
|  | ||||
| @ -21,22 +21,31 @@ import 'package:wyatt_form_bloc/src/core/enums/set_operations.dart'; | ||||
| import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart'; | ||||
| import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart'; | ||||
| import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart'; | ||||
| import 'package:wyatt_form_bloc/src/domain/repositories/form_repository.dart'; | ||||
| import 'package:wyatt_form_bloc/src/presentation/features/form_data/form_data_cubit.dart'; | ||||
| 
 | ||||
| part 'form_data_state_impl.dart'; | ||||
| 
 | ||||
| abstract class FormDataCubitImpl extends FormDataCubit<FormDataStateImpl> { | ||||
|   FormDataCubitImpl(WyattForm form) : super(FormDataStateImpl(form: form)); | ||||
|   final FormRepository _formRepository; | ||||
|   final String _formName; | ||||
| 
 | ||||
|   FormDataCubitImpl(this._formRepository, this._formName) | ||||
|       : super(FormDataStateImpl(form: _formRepository.accessForm(_formName))); | ||||
| 
 | ||||
|   @override | ||||
|   String get formName => _formName; | ||||
| 
 | ||||
|   @override | ||||
|   FutureOr<void> dataChanged<Value>( | ||||
|     String key, | ||||
|     FormInputValidator<Value, ValidationError> dirtyValue, | ||||
|   ) { | ||||
|     final form = state.form.clone(); | ||||
|     final form = _formRepository.accessForm(_formName).clone(); | ||||
| 
 | ||||
|     try { | ||||
|       form.updateValidator(key, dirtyValue); | ||||
|       _formRepository.updateForm(form); | ||||
|     } catch (e) { | ||||
|       rethrow; | ||||
|     } | ||||
| @ -54,7 +63,9 @@ abstract class FormDataCubitImpl extends FormDataCubit<FormDataStateImpl> { | ||||
|     WyattForm form, { | ||||
|     SetOperation operation = SetOperation.replace, | ||||
|   }) { | ||||
|     final WyattForm newForm = operation.operation.call(state.form, form); | ||||
|     final WyattForm current = _formRepository.accessForm(_formName).clone(); | ||||
|     final WyattForm newForm = operation.operation.call(current, form); | ||||
|     _formRepository.updateForm(newForm); | ||||
| 
 | ||||
|     emit( | ||||
|       state.copyWith( | ||||
| @ -67,6 +78,7 @@ abstract class FormDataCubitImpl extends FormDataCubit<FormDataStateImpl> { | ||||
|   @override | ||||
|   FutureOr<void> reset() { | ||||
|     final form = state.form.reset(); | ||||
|     _formRepository.updateForm(form); | ||||
|     emit( | ||||
|       state.copyWith( | ||||
|         form: form, | ||||
|  | ||||
| @ -35,8 +35,9 @@ class FormDataStateImpl extends FormDataState { | ||||
|       ); | ||||
| 
 | ||||
|   @override | ||||
|   bool? get stringify => true; | ||||
|   List<Object?> get props => [status, form, errorMessage]; | ||||
| 
 | ||||
|   @override | ||||
|   List<Object?> get props => [status, form, errorMessage]; | ||||
|   String toString() => | ||||
|       'FormDataSate(status: ${status.name} ${(errorMessage != null) ? " [$errorMessage]" : ""}, $form'; | ||||
| } | ||||
|  | ||||
| @ -35,7 +35,7 @@ class InputBuilder<Cubit extends FormDataCubit> extends StatelessWidget { | ||||
|   Widget build(BuildContext context) => | ||||
|       BlocBuilder<Cubit, FormDataState>( | ||||
|         builder: (context, state) { | ||||
|           final cubit = context.read<Cubit>(); | ||||
|           final cubit = context.watch<Cubit>(); | ||||
|           final inputValid = state.form.validatorOf(field).valid; | ||||
|           return builder.call(context, cubit, state, field, inputValid); | ||||
|         }, | ||||
|  | ||||
| @ -0,0 +1,75 @@ | ||||
| // Copyright (C) 2022 WYATT GROUP | ||||
| // Please see the AUTHORS file for details. | ||||
| // | ||||
| // This program is free software: you can redistribute it and/or modify | ||||
| // it under the terms of the GNU General Public License as published by | ||||
| // the Free Software Foundation, either version 3 of the License, or | ||||
| // any later version. | ||||
| // | ||||
| // This program is distributed in the hope that it will be useful, | ||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
| // GNU General Public License for more details. | ||||
| // | ||||
| // You should have received a copy of the GNU General Public License | ||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:flutter_bloc/flutter_bloc.dart'; | ||||
| import 'package:wyatt_form_bloc/src/domain/entities/form_input_metadata.dart'; | ||||
| import 'package:wyatt_form_bloc/src/domain/repositories/form_repository.dart'; | ||||
| import 'package:wyatt_form_bloc/src/presentation/features/form_data/form_data_cubit.dart'; | ||||
| 
 | ||||
| class InputBuilderTextController<Cubit extends FormDataCubit, S extends String?, | ||||
|     Extra> extends StatelessWidget { | ||||
|   InputBuilderTextController({ | ||||
|     required this.field, | ||||
|     required this.builder, | ||||
|     super.key, | ||||
|   }); | ||||
| 
 | ||||
|   final String field; | ||||
| 
 | ||||
|   final Widget Function( | ||||
|     BuildContext context, | ||||
|     Cubit cubit, | ||||
|     FormDataState state, | ||||
|     String field, | ||||
|     bool inputValid, | ||||
|     TextEditingController textEditingController, | ||||
|     FormInputMetadata<Extra>? metadata, | ||||
|   ) builder; | ||||
| 
 | ||||
|   final TextEditingController _controller = TextEditingController(); | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     final formName = context.watch<Cubit>().formName; | ||||
|     final value = | ||||
|         context.read<FormRepository>().accessForm(formName).valueOf<S>(field); | ||||
|     _controller | ||||
|       ..text = value ?? '' | ||||
|       ..selection = TextSelection.fromPosition( | ||||
|         TextPosition( | ||||
|           offset: _controller.text.length, | ||||
|         ), | ||||
|       ); | ||||
| 
 | ||||
|     return BlocBuilder<Cubit, FormDataState>( | ||||
|       builder: (context, state) { | ||||
|         final cubit = context.read<Cubit>(); | ||||
|         final inputValid = state.form.validatorOf(field).valid; | ||||
|         final metadata = state.form.metadataOf<Extra>(field); | ||||
|         return builder.call( | ||||
|           context, | ||||
|           cubit, | ||||
|           state, | ||||
|           field, | ||||
|           inputValid, | ||||
|           _controller, | ||||
|           metadata, | ||||
|         ); | ||||
|       }, | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| @ -18,4 +18,5 @@ export 'features/form_data/form_data_cubit.dart'; | ||||
| export 'features/form_data_impl/form_data_cubit_impl.dart'; | ||||
| export 'features/widgets/input_builder.dart'; | ||||
| export 'features/widgets/input_builder_metadata.dart'; | ||||
| export 'features/widgets/input_builder_text_controller.dart'; | ||||
| export 'features/widgets/submit_builder.dart'; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user