feat!(form): migrate to wyatt architecture
This commit is contained in:
+1
-14
@@ -14,17 +14,4 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
export 'form/every_input_validator.dart';
|
||||
export 'inputs/base/regex_validator.dart';
|
||||
export 'inputs/base/text_validator.dart';
|
||||
export 'inputs/boolean.dart';
|
||||
export 'inputs/confirmed_password.dart';
|
||||
export 'inputs/email.dart';
|
||||
export 'inputs/enum_validator.dart';
|
||||
export 'inputs/iban.dart';
|
||||
export 'inputs/list_option.dart';
|
||||
export 'inputs/name.dart';
|
||||
export 'inputs/password.dart';
|
||||
export 'inputs/phone.dart';
|
||||
export 'inputs/siren.dart';
|
||||
export 'inputs/text_string.dart';
|
||||
export 'enums/enums.dart';
|
||||
@@ -0,0 +1,39 @@
|
||||
// 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_form_bloc/src/data/form_operations/form_difference.dart';
|
||||
import 'package:wyatt_form_bloc/src/data/form_operations/form_intersection.dart';
|
||||
import 'package:wyatt_form_bloc/src/data/form_operations/form_replace.dart';
|
||||
import 'package:wyatt_form_bloc/src/data/form_operations/form_union.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/form_operations/form_operation.dart';
|
||||
|
||||
enum SetOperation {
|
||||
/// Replace entire set with new set.
|
||||
replace(FormReplace()),
|
||||
|
||||
/// Keep common elements between sets.
|
||||
intersection(FormIntersection()),
|
||||
|
||||
/// Remove common elements between sets.
|
||||
difference(FormDifference()),
|
||||
|
||||
/// Add new elements to set.
|
||||
union(FormUnion());
|
||||
|
||||
final FormOperation operation;
|
||||
|
||||
const SetOperation(this.operation);
|
||||
}
|
||||
+2
-1
@@ -23,5 +23,6 @@ abstract class ValidationError {}
|
||||
|
||||
enum ValidationStandardError implements ValidationError {
|
||||
invalid,
|
||||
empty
|
||||
empty,
|
||||
notEqual,
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
// 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 'dart:async';
|
||||
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:wyatt_form_bloc/src/enums/enums.dart';
|
||||
import 'package:wyatt_form_bloc/src/form/form.dart';
|
||||
import 'package:wyatt_form_bloc/src/validators/form/every_input_validator.dart';
|
||||
|
||||
part 'form_data_state.dart';
|
||||
|
||||
abstract class FormDataCubit extends Cubit<FormDataState> {
|
||||
FormValidator validationStrategy;
|
||||
FormData formCopy;
|
||||
|
||||
FormDataCubit({
|
||||
required FormData inputs,
|
||||
FormValidator validator = const EveryInputValidator(),
|
||||
}) : formCopy = inputs.clone(),
|
||||
validationStrategy = validator,
|
||||
super(FormDataState(data: inputs));
|
||||
|
||||
/// Change value of a field.
|
||||
///
|
||||
/// Inputs:
|
||||
/// - `field`: The key of the field to change.
|
||||
/// - `dirtyValue`: The new value of the field. (Wrapped in a dirty validator)
|
||||
void dataChanged<V>(
|
||||
String field,
|
||||
FormInputValidator<V, ValidationError> dirtyValue,
|
||||
) {
|
||||
final form = state.data.clone();
|
||||
|
||||
if (form.contains(field)) {
|
||||
form.updateValidator(field, dirtyValue);
|
||||
} else {
|
||||
throw Exception('Form field $field not found');
|
||||
}
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
data: form,
|
||||
status: validationStrategy.validate(form),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Just validate the form manually. (Useful if you just update the strategy)
|
||||
void validate() {
|
||||
final form = state.data;
|
||||
emit(state.copyWith(status: validationStrategy.validate(form)));
|
||||
}
|
||||
|
||||
/// Update entries list.
|
||||
///
|
||||
/// Inputs:
|
||||
/// - `data`: The new entries list.
|
||||
/// - `operation`: The operation to perform on the entries set.
|
||||
void updateFormData(
|
||||
FormData data, {
|
||||
SetOperation operation = SetOperation.replace,
|
||||
}) {
|
||||
FormData form = data;
|
||||
|
||||
switch (operation) {
|
||||
case SetOperation.replace:
|
||||
form = data;
|
||||
break;
|
||||
case SetOperation.difference:
|
||||
form = state.data.difference(data);
|
||||
break;
|
||||
case SetOperation.intersection:
|
||||
form = state.data.intersection(data);
|
||||
break;
|
||||
case SetOperation.union:
|
||||
form = state.data.union(data);
|
||||
break;
|
||||
}
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
data: form,
|
||||
status: validationStrategy.validate(form),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Reset all form inputs
|
||||
void resetForm() {
|
||||
emit(FormDataState(data: formCopy));
|
||||
}
|
||||
|
||||
/// Submit the form.
|
||||
Future<void> submitForm();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// 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/>.
|
||||
|
||||
export 'form/wyatt_form_impl.dart';
|
||||
export 'form_encoders/form_json_encoder.dart';
|
||||
export 'form_encoders/form_map_encoder.dart';
|
||||
export 'form_operations/form_difference.dart';
|
||||
export 'form_operations/form_intersection.dart';
|
||||
export 'form_operations/form_replace.dart';
|
||||
export 'form_operations/form_union.dart';
|
||||
export 'form_validators/every_input_validator.dart';
|
||||
export 'form_validators/only_required_input_validator.dart';
|
||||
export 'input_validators/boolean.dart';
|
||||
export 'input_validators/confirmed_password.dart';
|
||||
export 'input_validators/email.dart';
|
||||
export 'input_validators/enum_option.dart';
|
||||
export 'input_validators/list_option.dart';
|
||||
export 'input_validators/name.dart';
|
||||
export 'input_validators/password.dart';
|
||||
export 'input_validators/phone.dart';
|
||||
export 'input_validators/text_string.dart';
|
||||
@@ -0,0 +1,136 @@
|
||||
// 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_form_bloc/src/core/enums/form_status.dart';
|
||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
|
||||
import 'package:wyatt_form_bloc/src/data/form_validators/every_input_validator.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/entities/form_input.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/entities/form_input_metadata.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/form_operations/form_operation.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/form_validators/form_validator.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class WyattFormImpl extends WyattForm {
|
||||
final List<
|
||||
FormInput<dynamic, FormInputValidator<dynamic, ValidationError>,
|
||||
dynamic>> _inputs;
|
||||
final FormValidator _validator;
|
||||
|
||||
late List<
|
||||
FormInput<dynamic, FormInputValidator<dynamic, ValidationError>,
|
||||
dynamic>> _inputsInitial;
|
||||
|
||||
WyattFormImpl(
|
||||
this._inputs, {
|
||||
FormValidator validationStrategy = const EveryInputValidator(),
|
||||
}) : _validator = validationStrategy {
|
||||
_inputsInitial = _inputs.map((input) => input.clone()).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
List<
|
||||
FormInput<dynamic, FormInputValidator<dynamic, ValidationError>,
|
||||
dynamic>> get inputs => _inputs;
|
||||
|
||||
@override
|
||||
FormValidator get formValidationStrategy => _validator;
|
||||
|
||||
@override
|
||||
bool containsKey(String key) => inputs.any((input) => input.key == key);
|
||||
|
||||
@override
|
||||
List<FormInputValidator<Value, Error>>
|
||||
asValidatorList<Value, Error extends ValidationError>() => inputs
|
||||
.map<FormInputValidator<Value, Error>>(
|
||||
(input) => input.validator as FormInputValidator<Value, Error>,
|
||||
)
|
||||
.toList();
|
||||
|
||||
@override
|
||||
FormInput<dynamic, FormInputValidator<dynamic, ValidationError>, dynamic>
|
||||
inputOf(String key) {
|
||||
if (containsKey(key)) {
|
||||
return inputs.firstWhere((input) => input.key == key);
|
||||
} else {
|
||||
throw Exception('FormInput with key `$key` does not exist in form');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Error? errorOf<Error extends ValidationError>(String key) =>
|
||||
(inputOf(key).validator as FormInputValidator<dynamic, Error>).error;
|
||||
|
||||
@override
|
||||
FormInputMetadata<Extra> metadataOf<Extra>(String key) =>
|
||||
inputOf(key).metadata as FormInputMetadata<Extra>;
|
||||
|
||||
@override
|
||||
Validator validatorOf<
|
||||
Validator extends FormInputValidator<dynamic, ValidationError>>(
|
||||
String key,
|
||||
) =>
|
||||
inputOf(key).validator as Validator;
|
||||
|
||||
@override
|
||||
Value? valueOf<Value>(String key) =>
|
||||
(inputOf(key).validator as FormInputValidator<Value, dynamic>).value;
|
||||
|
||||
@override
|
||||
FormStatus validate() => formValidationStrategy.validate(this);
|
||||
|
||||
@override
|
||||
WyattForm clone() => WyattFormImpl(
|
||||
_inputs.map((input) => input.clone()).toList(),
|
||||
validationStrategy: formValidationStrategy,
|
||||
);
|
||||
|
||||
@override
|
||||
WyattForm reset() => WyattFormImpl(
|
||||
_inputsInitial,
|
||||
validationStrategy: formValidationStrategy,
|
||||
);
|
||||
|
||||
@override
|
||||
bool? get stringify => true;
|
||||
|
||||
@override
|
||||
List<Object?> get props => _inputs;
|
||||
|
||||
@override
|
||||
void updateMetadata<Extra>(String key, FormInputMetadata<Extra> metadata) {
|
||||
final index = _inputs.indexOf(
|
||||
inputOf(key),
|
||||
);
|
||||
_inputs[index] = _inputs[index].copyWith(metadata: metadata);
|
||||
}
|
||||
|
||||
@override
|
||||
void updateValidator<Value>(
|
||||
String key,
|
||||
FormInputValidator<Value?, ValidationError> dirtyValue,
|
||||
) {
|
||||
final index = _inputs.indexOf(
|
||||
inputOf(key),
|
||||
);
|
||||
_inputs[index] = _inputs[index].copyWith(validator: dirtyValue);
|
||||
}
|
||||
|
||||
@override
|
||||
WyattForm operationWith(FormOperation operation, WyattForm other) =>
|
||||
operation.call(this, other);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// 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 'dart:convert';
|
||||
|
||||
import 'package:wyatt_form_bloc/src/data/form_encoders/form_map_encoder.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/form_encoders/form_encoder.dart';
|
||||
|
||||
class FormJsonEncoder extends FormEncoder<String> {
|
||||
@override
|
||||
String encode(WyattForm form) {
|
||||
final mapEncoder = FormMapEncoder();
|
||||
final map = mapEncoder.encode(form);
|
||||
return jsonEncode(map);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// 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_form_bloc/src/domain/form/wyatt_form.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/form_encoders/form_encoder.dart';
|
||||
|
||||
class FormMapEncoder extends FormEncoder<Map<String, dynamic>> {
|
||||
@override
|
||||
Map<String, dynamic> encode(WyattForm form) {
|
||||
final inputs = form.inputs;
|
||||
final map = <String, dynamic>{};
|
||||
for (final input in inputs) {
|
||||
if (input.metadata.export) {
|
||||
map[input.name] = input.validator.value;
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// 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_form_bloc/src/core/enums/validation_error.dart';
|
||||
import 'package:wyatt_form_bloc/src/data/form/wyatt_form_impl.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/entities/form_input.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/form_operations/form_operation.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
|
||||
|
||||
class FormDifference extends FormOperation {
|
||||
const FormDifference();
|
||||
|
||||
@override
|
||||
WyattForm call(WyattForm a, WyattForm b) {
|
||||
final inputs = <
|
||||
FormInput<dynamic, FormInputValidator<dynamic, ValidationError>,
|
||||
dynamic>>[];
|
||||
|
||||
for (final i in b.inputs) {
|
||||
if (!a.containsKey(i.key)) {
|
||||
inputs.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
for (final i in a.inputs) {
|
||||
if (!b.containsKey(i.key)) {
|
||||
inputs.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
return WyattFormImpl(
|
||||
inputs,
|
||||
validationStrategy: a.formValidationStrategy,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// 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_form_bloc/src/core/enums/validation_error.dart';
|
||||
import 'package:wyatt_form_bloc/src/data/form/wyatt_form_impl.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/entities/form_input.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/form_operations/form_operation.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
|
||||
|
||||
class FormIntersection extends FormOperation {
|
||||
const FormIntersection();
|
||||
|
||||
@override
|
||||
WyattForm call(WyattForm a, WyattForm b) {
|
||||
final inputs = <
|
||||
FormInput<dynamic, FormInputValidator<dynamic, ValidationError>,
|
||||
dynamic>>[];
|
||||
|
||||
for (final i in a.inputs) {
|
||||
if (b.containsKey(i.key)) {
|
||||
inputs.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
return WyattFormImpl(
|
||||
inputs,
|
||||
validationStrategy: a.formValidationStrategy,
|
||||
);
|
||||
}
|
||||
}
|
||||
+7
-10
@@ -14,15 +14,12 @@
|
||||
// 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 'dart:convert';
|
||||
import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/form_operations/form_operation.dart';
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:wyatt_form_bloc/src/enums/form_input_status.dart';
|
||||
import 'package:wyatt_form_bloc/src/enums/form_status.dart';
|
||||
import 'package:wyatt_form_bloc/src/enums/validation_error.dart';
|
||||
class FormReplace extends FormOperation {
|
||||
const FormReplace();
|
||||
|
||||
part 'form_data.dart';
|
||||
part 'form_input.dart';
|
||||
part 'form_input_metadata.dart';
|
||||
part 'form_input_validator.dart';
|
||||
part 'form_validator.dart';
|
||||
@override
|
||||
WyattForm call(WyattForm a, WyattForm b) => b;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// 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_form_bloc/src/core/enums/validation_error.dart';
|
||||
import 'package:wyatt_form_bloc/src/data/form/wyatt_form_impl.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/entities/form_input.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/form_operations/form_operation.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
|
||||
|
||||
class FormUnion extends FormOperation {
|
||||
const FormUnion();
|
||||
|
||||
@override
|
||||
WyattForm call(WyattForm a, WyattForm b) {
|
||||
final inputs = <
|
||||
FormInput<dynamic, FormInputValidator<dynamic, ValidationError>,
|
||||
dynamic>>[];
|
||||
|
||||
for (final i in a.inputs) {
|
||||
inputs.add(i);
|
||||
}
|
||||
|
||||
for (final i in b.inputs) {
|
||||
if (!a.containsKey(i.key)) {
|
||||
inputs.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
return WyattFormImpl(
|
||||
inputs,
|
||||
validationStrategy: a.formValidationStrategy,
|
||||
);
|
||||
}
|
||||
}
|
||||
+6
-8
@@ -14,7 +14,10 @@
|
||||
// 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_form_bloc/wyatt_form_bloc.dart';
|
||||
import 'package:wyatt_form_bloc/src/core/enums/form_status.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/form_validators/form_validator.dart';
|
||||
|
||||
/// {@template every}
|
||||
/// Check and validate every input of a form
|
||||
@@ -24,18 +27,13 @@ class EveryInputValidator extends FormValidator {
|
||||
const EveryInputValidator() : super();
|
||||
|
||||
@override
|
||||
FormStatus validate(FormData form) {
|
||||
FormStatus validate(WyattForm form) {
|
||||
if (isPure(form)) {
|
||||
return FormStatus.pure;
|
||||
}
|
||||
|
||||
return rawValidate(form.validators<dynamic, ValidationError>());
|
||||
}
|
||||
final validators = form.asValidatorList<dynamic, ValidationError>();
|
||||
|
||||
@override
|
||||
FormStatus rawValidate(
|
||||
List<FormInputValidator<dynamic, ValidationError>> validators,
|
||||
) {
|
||||
if (validators.any((validator) => validator.valid == false)) {
|
||||
return FormStatus.invalid;
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// 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_form_bloc/src/core/enums/form_status.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/form_validators/form_validator.dart';
|
||||
|
||||
class OnlyRequiredInputValidator extends FormValidator {
|
||||
const OnlyRequiredInputValidator() : super();
|
||||
|
||||
@override
|
||||
FormStatus validate(WyattForm form) {
|
||||
// TODO(hpcl): use metadata to check if input is required or not.
|
||||
return FormStatus.valid;
|
||||
}
|
||||
}
|
||||
+8
-4
@@ -14,21 +14,25 @@
|
||||
// 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_form_bloc/src/enums/enums.dart';
|
||||
import 'package:wyatt_form_bloc/src/form/form.dart';
|
||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
|
||||
|
||||
/// {@template boolean}
|
||||
/// Form input for a bool input
|
||||
/// {@endtemplate}
|
||||
class Boolean extends FormInputValidator<bool, ValidationStandardError> {
|
||||
class Boolean extends NullableValidator<bool, ValidationStandardError> {
|
||||
/// {@macro boolean}
|
||||
const Boolean.pure({bool? defaultValue = false})
|
||||
: super.pure(defaultValue ?? false);
|
||||
|
||||
/// {@macro boolean}
|
||||
const Boolean.dirty({bool value = false}) : super.dirty(value);
|
||||
|
||||
@override
|
||||
ValidationStandardError get onNull => ValidationStandardError.invalid;
|
||||
|
||||
@override
|
||||
ValidationStandardError? validator(bool? value) =>
|
||||
value != null ? null : ValidationStandardError.invalid;
|
||||
value != null ? null : onNull;
|
||||
|
||||
}
|
||||
+13
-7
@@ -14,25 +14,31 @@
|
||||
// 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_form_bloc/src/enums/enums.dart';
|
||||
import 'package:wyatt_form_bloc/src/form/form.dart';
|
||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
|
||||
|
||||
/// {@template confirmed_password}
|
||||
/// Form input for a confirmed password input.
|
||||
/// {@endtemplate}
|
||||
class ConfirmedPassword
|
||||
extends FormInputValidator<String, ValidationStandardError> {
|
||||
extends EqualityValidator<String, ValidationStandardError> {
|
||||
/// {@macro confirmed_password}
|
||||
const ConfirmedPassword.pure({this.password = ''}) : super.pure('');
|
||||
const ConfirmedPassword.pure({this.password = '', String? defaultValue})
|
||||
: super.pure(defaultValue);
|
||||
|
||||
/// {@macro confirmed_password}
|
||||
const ConfirmedPassword.dirty({required this.password, String value = ''})
|
||||
const ConfirmedPassword.dirty({required this.password, String? value})
|
||||
: super.dirty(value);
|
||||
|
||||
/// The original password.
|
||||
final String password;
|
||||
|
||||
@override
|
||||
ValidationStandardError? validator(String? value) =>
|
||||
password == value ? null : ValidationStandardError.invalid;
|
||||
String get another => password;
|
||||
|
||||
@override
|
||||
ValidationStandardError get onNotEqual => ValidationStandardError.notEqual;
|
||||
|
||||
@override
|
||||
ValidationStandardError get onNull => ValidationStandardError.invalid;
|
||||
}
|
||||
+3
-3
@@ -14,15 +14,15 @@
|
||||
// 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_form_bloc/src/enums/enums.dart';
|
||||
import 'package:wyatt_form_bloc/src/validators/inputs/base/regex_validator.dart';
|
||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
|
||||
|
||||
/// {@template email}
|
||||
/// Form input for an email input.
|
||||
/// {@endtemplate}
|
||||
class Email extends RegexValidator<ValidationStandardError> {
|
||||
/// {@macro email}
|
||||
const Email.pure() : super.pure();
|
||||
const Email.pure([super.value]) : super.pure();
|
||||
|
||||
/// {@macro email}
|
||||
const Email.dirty([super.value = '']) : super.dirty();
|
||||
+17
-14
@@ -14,24 +14,27 @@
|
||||
// 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_form_bloc/src/enums/enums.dart';
|
||||
import 'package:wyatt_form_bloc/src/validators/inputs/base/regex_validator.dart';
|
||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
|
||||
|
||||
/// {@template siren}
|
||||
/// Form input for a SIREN input.
|
||||
/// {@endtemplate}
|
||||
class Siren extends RegexValidator<ValidationStandardError> {
|
||||
/// {@macro siren}
|
||||
const Siren.pure() : super.pure();
|
||||
class EnumOption<T> extends AnyValidator<T, List<T>, ValidationError> {
|
||||
const EnumOption.pure({this.enums = const [], T? defaultValue})
|
||||
: super.pure(defaultValue);
|
||||
|
||||
/// {@macro siren}
|
||||
const Siren.dirty([super.value = '']) : super.dirty();
|
||||
const EnumOption.dirty({required this.enums, T? value})
|
||||
: super.dirty(value);
|
||||
|
||||
final List<T> enums;
|
||||
|
||||
@override
|
||||
ValidationStandardError get onEmpty => ValidationStandardError.empty;
|
||||
@override
|
||||
ValidationStandardError get onError => ValidationStandardError.invalid;
|
||||
List<T> get allChoices => enums;
|
||||
|
||||
@override
|
||||
RegExp get regex => RegExp(r'(\d{9}|\d{3}[ ]\d{3}[ ]\d{3})$');
|
||||
ValidationError get onError => ValidationStandardError.invalid;
|
||||
|
||||
@override
|
||||
ValidationError get onNull => ValidationStandardError.invalid;
|
||||
|
||||
@override
|
||||
bool test(T? element, T value) => element == value;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// 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_form_bloc/src/core/enums/validation_error.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
|
||||
|
||||
class ListOption<T> extends AnyValidator<T, Iterable<T>, ValidationError> {
|
||||
const ListOption.pure({this.choices = const [], T? defaultValue})
|
||||
: super.pure(defaultValue);
|
||||
|
||||
const ListOption.dirty({required this.choices, T? value})
|
||||
: super.dirty(value);
|
||||
|
||||
final Iterable<T> choices;
|
||||
|
||||
@override
|
||||
Iterable<T> get allChoices => choices;
|
||||
|
||||
@override
|
||||
ValidationError get onError => ValidationStandardError.invalid;
|
||||
|
||||
@override
|
||||
ValidationError get onNull => ValidationStandardError.invalid;
|
||||
|
||||
@override
|
||||
bool test(T? element, T value) => element == value;
|
||||
}
|
||||
+3
-3
@@ -14,15 +14,15 @@
|
||||
// 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_form_bloc/src/enums/enums.dart';
|
||||
import 'package:wyatt_form_bloc/src/validators/inputs/base/regex_validator.dart';
|
||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
|
||||
|
||||
/// {@template name}
|
||||
/// Form input for a name input.
|
||||
/// {@endtemplate}
|
||||
class Name extends RegexValidator<ValidationStandardError> {
|
||||
/// {@macro name}
|
||||
const Name.pure() : super.pure();
|
||||
const Name.pure([super.value]) : super.pure();
|
||||
|
||||
/// {@macro name}
|
||||
const Name.dirty([super.value = '']) : super.dirty();
|
||||
+4
-4
@@ -14,18 +14,18 @@
|
||||
// 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_form_bloc/src/enums/enums.dart';
|
||||
import 'package:wyatt_form_bloc/src/validators/inputs/base/regex_validator.dart';
|
||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
|
||||
|
||||
/// {@template password}
|
||||
/// Form input for a password input.
|
||||
/// {@endtemplate}
|
||||
class Password extends RegexValidator<ValidationStandardError> {
|
||||
/// {@macro password}
|
||||
const Password.pure() : super.pure();
|
||||
const Password.pure([super.value]) : super.pure();
|
||||
|
||||
/// {@macro password}
|
||||
const Password.dirty([super.value = '']) : super.dirty();
|
||||
const Password.dirty([super.value]) : super.dirty();
|
||||
|
||||
@override
|
||||
ValidationStandardError get onEmpty => ValidationStandardError.empty;
|
||||
+3
-3
@@ -14,15 +14,15 @@
|
||||
// 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_form_bloc/src/enums/enums.dart';
|
||||
import 'package:wyatt_form_bloc/src/validators/inputs/base/regex_validator.dart';
|
||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
|
||||
|
||||
/// {@template phone}
|
||||
/// Form input for a phone input.
|
||||
/// {@endtemplate}
|
||||
class Phone extends RegexValidator<ValidationStandardError> {
|
||||
/// {@macro phone}
|
||||
const Phone.pure() : super.pure();
|
||||
const Phone.pure([super.value]) : super.pure();
|
||||
|
||||
/// {@macro phone}
|
||||
const Phone.dirty([super.value = '']) : super.dirty();
|
||||
+3
-3
@@ -14,15 +14,15 @@
|
||||
// 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_form_bloc/src/enums/enums.dart';
|
||||
import 'package:wyatt_form_bloc/src/validators/inputs/base/text_validator.dart';
|
||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
|
||||
|
||||
/// {@template text_string}
|
||||
/// Form input for a text input
|
||||
/// {@endtemplate}
|
||||
class TextString extends TextValidator<ValidationStandardError> {
|
||||
/// {@macro text_string}
|
||||
const TextString.pure() : super.pure();
|
||||
const TextString.pure([super.value]) : super.pure();
|
||||
|
||||
/// {@macro text_string}
|
||||
const TextString.dirty([super.value = '']) : super.dirty();
|
||||
@@ -0,0 +1,23 @@
|
||||
// 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/>.
|
||||
|
||||
export 'entities/form_input.dart';
|
||||
export 'entities/form_input_metadata.dart';
|
||||
export 'form/wyatt_form.dart';
|
||||
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';
|
||||
+21
-11
@@ -15,27 +15,36 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
part of 'form.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/entities/form_input_metadata.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
|
||||
|
||||
class FormInput<Validator extends FormInputValidator<dynamic, ValidationError>>
|
||||
extends Equatable {
|
||||
// ignore: must_be_immutable
|
||||
class FormInput<
|
||||
Value,
|
||||
Validator extends FormInputValidator<Value, ValidationError>,
|
||||
Extra> extends Equatable implements Entity {
|
||||
final String key;
|
||||
final Validator validator;
|
||||
final FormInputMetadata<dynamic> metadata;
|
||||
late FormInputMetadata<Extra> metadata;
|
||||
|
||||
String get name => metadata._name ?? key;
|
||||
String get name => metadata.name ?? key;
|
||||
|
||||
const FormInput(
|
||||
FormInput(
|
||||
this.key,
|
||||
this.validator, {
|
||||
// ignore: avoid_redundant_argument_values
|
||||
this.metadata = const FormInputMetadata<void>(export: true),
|
||||
});
|
||||
FormInputMetadata<Extra>? metadata,
|
||||
}) {
|
||||
this.metadata = metadata ?? FormInputMetadata<Extra>();
|
||||
}
|
||||
|
||||
FormInput copyWith({
|
||||
FormInput<Value, Validator, Extra> copyWith({
|
||||
String? key,
|
||||
Validator? validator,
|
||||
FormInputMetadata? metadata,
|
||||
FormInputMetadata<Extra>? metadata,
|
||||
}) =>
|
||||
FormInput(
|
||||
key ?? this.key,
|
||||
@@ -43,11 +52,12 @@ class FormInput<Validator extends FormInputValidator<dynamic, ValidationError>>
|
||||
metadata: metadata ?? this.metadata,
|
||||
);
|
||||
|
||||
FormInput clone() => copyWith(
|
||||
FormInput<Value, Validator, Extra> clone() => copyWith(
|
||||
key: key,
|
||||
validator: validator,
|
||||
metadata: metadata,
|
||||
);
|
||||
|
||||
@override
|
||||
bool? get stringify => true;
|
||||
|
||||
+15
-13
@@ -15,33 +15,35 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
part of 'form.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||
|
||||
class FormInputMetadata<T extends Object?> extends Equatable {
|
||||
class FormInputMetadata<Extra> extends Equatable
|
||||
implements Entity {
|
||||
final bool export;
|
||||
final String? _name;
|
||||
final T? extra;
|
||||
final String? name;
|
||||
final Extra? extra;
|
||||
|
||||
const FormInputMetadata({
|
||||
this.export = true,
|
||||
this.name,
|
||||
this.extra,
|
||||
String? name,
|
||||
}) : _name = name;
|
||||
});
|
||||
|
||||
FormInputMetadata<T> copyWith({
|
||||
FormInputMetadata<Extra> copyWith({
|
||||
bool? export,
|
||||
String? name,
|
||||
T? extra,
|
||||
Extra? extra,
|
||||
}) =>
|
||||
FormInputMetadata<T>(
|
||||
FormInputMetadata<Extra>(
|
||||
export: export ?? this.export,
|
||||
name: name ?? _name,
|
||||
name: name ?? this.name,
|
||||
extra: extra ?? this.extra,
|
||||
);
|
||||
|
||||
FormInputMetadata<T> clone() => copyWith(
|
||||
FormInputMetadata<Extra> clone() => copyWith(
|
||||
export: export,
|
||||
name: _name,
|
||||
name: name,
|
||||
extra: extra,
|
||||
);
|
||||
|
||||
@@ -49,5 +51,5 @@ class FormInputMetadata<T extends Object?> extends Equatable {
|
||||
bool? get stringify => true;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [export, _name, extra];
|
||||
List<Object?> get props => [export, name, extra];
|
||||
}
|
||||
@@ -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/>.
|
||||
|
||||
// ignore_for_file: strict_raw_type
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:wyatt_form_bloc/src/core/enums/form_status.dart';
|
||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/entities/form_input.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/entities/form_input_metadata.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/form_operations/form_operation.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/form_validators/form_validator.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator.dart';
|
||||
|
||||
abstract class WyattForm extends Equatable {
|
||||
List<FormInput> get inputs;
|
||||
FormValidator get formValidationStrategy;
|
||||
|
||||
bool containsKey(String key);
|
||||
|
||||
FormInput inputOf(String key);
|
||||
Validator validatorOf<
|
||||
Validator extends FormInputValidator<dynamic, ValidationError>>(
|
||||
String key,
|
||||
);
|
||||
Error? errorOf<Error extends ValidationError>(String key);
|
||||
Value? valueOf<Value>(String key);
|
||||
FormInputMetadata<Extra> metadataOf<Extra>(String key);
|
||||
|
||||
List<FormInputValidator<Value, Error>>
|
||||
asValidatorList<Value, Error extends ValidationError>();
|
||||
|
||||
void updateValidator<Value>(
|
||||
String key,
|
||||
FormInputValidator<Value?, ValidationError> dirtyValue,
|
||||
);
|
||||
|
||||
void updateMetadata<Extra>(
|
||||
String key,
|
||||
FormInputMetadata<Extra> metadata,
|
||||
);
|
||||
|
||||
FormStatus validate();
|
||||
WyattForm clone();
|
||||
WyattForm operationWith(FormOperation operation, WyattForm other);
|
||||
WyattForm reset();
|
||||
}
|
||||
+5
-12
@@ -14,16 +14,9 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
enum SetOperation {
|
||||
/// Replace entire set with new set.
|
||||
replace,
|
||||
|
||||
/// Keep common elements between sets.
|
||||
intersection,
|
||||
|
||||
/// Remove common elements between sets.
|
||||
difference,
|
||||
|
||||
/// Add new elements to set.
|
||||
union
|
||||
import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
|
||||
|
||||
// ignore: one_member_abstracts
|
||||
abstract class FormEncoder<Output> {
|
||||
Output encode(WyattForm form);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// 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_form_bloc/src/domain/form/wyatt_form.dart';
|
||||
|
||||
// ignore: one_member_abstracts
|
||||
abstract class FormOperation {
|
||||
const FormOperation();
|
||||
WyattForm call(WyattForm a, WyattForm b);
|
||||
}
|
||||
+6
-8
@@ -14,7 +14,9 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
part of 'form.dart';
|
||||
import 'package:wyatt_form_bloc/src/core/enums/form_status.dart';
|
||||
import 'package:wyatt_form_bloc/src/core/enums/validation_error.dart';
|
||||
import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
|
||||
|
||||
/// {@template form_validator}
|
||||
/// A [FormValidator] represents the global validaton state of a Form.
|
||||
@@ -23,13 +25,9 @@ abstract class FormValidator {
|
||||
/// {@macro form_validator}
|
||||
const FormValidator();
|
||||
|
||||
bool isPure(FormData form) => form
|
||||
.validators<dynamic, ValidationError>()
|
||||
bool isPure(WyattForm form) => form
|
||||
.asValidatorList<dynamic, ValidationError>()
|
||||
.every((validator) => validator.pure);
|
||||
|
||||
FormStatus validate(FormData form);
|
||||
|
||||
FormStatus rawValidate(
|
||||
List<FormInputValidator<dynamic, ValidationError>> validators,
|
||||
);
|
||||
FormStatus validate(WyattForm form);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// 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/>.
|
||||
|
||||
part of 'form_input_validator.dart';
|
||||
|
||||
abstract class AnyValidator<O, I extends Iterable<O?>,
|
||||
E extends ValidationError> extends FormInputValidator<O?, E> {
|
||||
const AnyValidator.pure(super.value) : super.pure();
|
||||
const AnyValidator.dirty(super.value) : super.dirty();
|
||||
|
||||
I get allChoices;
|
||||
|
||||
bool test(O? element, O value);
|
||||
|
||||
E get onError;
|
||||
|
||||
/// If value is null.
|
||||
E get onNull;
|
||||
|
||||
@override
|
||||
E? validator(O? value) {
|
||||
if (value == null) {
|
||||
return onNull;
|
||||
}
|
||||
if (allChoices.any(
|
||||
(element) => test(element, value),
|
||||
)) {
|
||||
return null;
|
||||
}
|
||||
return onError;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// 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/>.
|
||||
|
||||
part of 'form_input_validator.dart';
|
||||
|
||||
/// {@template equality_validator}
|
||||
/// Abstract equality validator validating a value when equals to another.
|
||||
/// {@endtemplate}
|
||||
abstract class EqualityValidator<O extends Object, E extends ValidationError>
|
||||
extends FormInputValidator<O?, E> {
|
||||
const EqualityValidator.pure(super.value) : super.pure();
|
||||
const EqualityValidator.dirty(super.value) : super.dirty();
|
||||
|
||||
O get another;
|
||||
|
||||
/// If values are different.
|
||||
E get onNotEqual;
|
||||
|
||||
/// If value is null.
|
||||
E get onNull;
|
||||
|
||||
@override
|
||||
E? validator(O? value) {
|
||||
if (value == null) {
|
||||
return onNull;
|
||||
}
|
||||
if (value != another) {
|
||||
return onNotEqual;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+15
-7
@@ -14,7 +14,15 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
part of 'form.dart';
|
||||
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 '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.
|
||||
@@ -39,21 +47,21 @@ part of 'form.dart';
|
||||
/// }
|
||||
/// ```
|
||||
/// {@endtemplate}
|
||||
abstract class FormInputValidator<V, E extends ValidationError>
|
||||
abstract class FormInputValidator<Value, Error extends ValidationError>
|
||||
extends Equatable {
|
||||
const FormInputValidator._(this.value, [this.pure = true]);
|
||||
|
||||
/// Constructor which create a `pure` [FormInputValidator] with a given value.
|
||||
const FormInputValidator.pure(V value) : this._(value);
|
||||
const FormInputValidator.pure(Value value) : this._(value);
|
||||
|
||||
/// Constructor which create a `dirty` [FormInputValidator] with a
|
||||
/// given value.
|
||||
const FormInputValidator.dirty(V value) : this._(value, false);
|
||||
const FormInputValidator.dirty(Value value) : this._(value, false);
|
||||
|
||||
/// The value of the given [FormInputValidator].
|
||||
/// For example, if you have a `FormInputValidator` for `FirstName`,
|
||||
/// the value could be 'Joe'.
|
||||
final V value;
|
||||
final Value? value;
|
||||
|
||||
/// If the [FormInputValidator] is pure (has been touched/modified).
|
||||
/// Typically when the `FormInputValidator` is initially created,
|
||||
@@ -80,7 +88,7 @@ abstract class FormInputValidator<V, E extends ValidationError>
|
||||
|
||||
/// Returns a validation error if the [FormInputValidator] is invalid.
|
||||
/// Returns `null` if the [FormInputValidator] is valid.
|
||||
E? get error => validator(value);
|
||||
Error? get error => validator(value);
|
||||
|
||||
/// Whether the [FormInputValidator] value is valid according to the
|
||||
/// overridden `validator`.
|
||||
@@ -96,7 +104,7 @@ abstract class FormInputValidator<V, E extends ValidationError>
|
||||
|
||||
/// A function that must return a validation error if the provided
|
||||
/// [value] is invalid and `null` otherwise.
|
||||
E? validator(V value);
|
||||
Error? validator(Value? value);
|
||||
|
||||
@override
|
||||
bool? get stringify => true;
|
||||
+16
-11
@@ -14,19 +14,24 @@
|
||||
// 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_form_bloc/src/enums/validation_error.dart';
|
||||
import 'package:wyatt_form_bloc/src/validators/inputs/base/text_validator.dart';
|
||||
part of 'form_input_validator.dart';
|
||||
|
||||
class EnumValidator<E> extends TextValidator<ValidationStandardError> {
|
||||
/// {@macro text_string}
|
||||
const EnumValidator.pure() : super.pure();
|
||||
/// {@template nullable_validator}
|
||||
/// Abstract nullable validator not validating null values.
|
||||
/// {@endtemplate}
|
||||
abstract class NullableValidator<O extends Object, E extends ValidationError>
|
||||
extends FormInputValidator<O?, E> {
|
||||
const NullableValidator.pure(super.value) : super.pure();
|
||||
const NullableValidator.dirty(super.value) : super.dirty();
|
||||
|
||||
/// {@macro text_string}
|
||||
EnumValidator.dirty(E value) : super.dirty(value.toString());
|
||||
/// If value is null.
|
||||
E get onNull;
|
||||
|
||||
@override
|
||||
ValidationStandardError get onEmpty => ValidationStandardError.empty;
|
||||
|
||||
@override
|
||||
ValidationStandardError get onNull => ValidationStandardError.invalid;
|
||||
E? validator(O? value) {
|
||||
if (value == null) {
|
||||
return onNull;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+6
-5
@@ -14,20 +14,21 @@
|
||||
// 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_form_bloc/src/enums/validation_error.dart';
|
||||
import 'package:wyatt_form_bloc/src/form/form.dart';
|
||||
part of 'form_input_validator.dart';
|
||||
|
||||
/// {@template regex_validator}
|
||||
/// Abstract regex validator for form input.
|
||||
/// {@endtemplate}
|
||||
abstract class RegexValidator<E extends ValidationError>
|
||||
extends FormInputValidator<String, E> {
|
||||
const RegexValidator.pure() : super.pure('');
|
||||
const RegexValidator.dirty([super.value = '']) : super.dirty();
|
||||
extends FormInputValidator<String?, E> {
|
||||
const RegexValidator.pure(super.value) : super.pure();
|
||||
const RegexValidator.dirty(super.value) : super.dirty();
|
||||
|
||||
RegExp get regex;
|
||||
|
||||
/// If the value is **not** null, but empty.
|
||||
E get onEmpty;
|
||||
|
||||
/// If value does not conform to regex.
|
||||
E get onError;
|
||||
|
||||
+4
-5
@@ -14,13 +14,12 @@
|
||||
// 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_form_bloc/src/enums/validation_error.dart';
|
||||
import 'package:wyatt_form_bloc/src/form/form.dart';
|
||||
part of 'form_input_validator.dart';
|
||||
|
||||
abstract class TextValidator<E extends ValidationError>
|
||||
extends FormInputValidator<String, E> {
|
||||
const TextValidator.pure() : super.pure('');
|
||||
const TextValidator.dirty([super.value = '']) : super.dirty();
|
||||
extends FormInputValidator<String?, E> {
|
||||
const TextValidator.pure(super.value) : super.pure();
|
||||
const TextValidator.dirty(super.value) : super.dirty();
|
||||
|
||||
/// If the value is **not** null, but empty.
|
||||
E get onEmpty;
|
||||
@@ -1,184 +0,0 @@
|
||||
// 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/>.
|
||||
|
||||
part of 'form.dart';
|
||||
|
||||
class FormData extends Equatable {
|
||||
final List<FormInput> _inputs;
|
||||
|
||||
const FormData(this._inputs);
|
||||
const FormData.empty() : this(const <FormInput>[]);
|
||||
|
||||
/// Returns all inputs as a list
|
||||
List<FormInput> inputs() => _inputs;
|
||||
|
||||
/// Returns the input for the associated key
|
||||
FormInput inputOf(String key) {
|
||||
if (contains(key)) {
|
||||
return _inputs.firstWhere((input) => input.key == key);
|
||||
} else {
|
||||
throw Exception('FormInput with key `$key` does not exist in form');
|
||||
}
|
||||
}
|
||||
|
||||
/// Updates a input (perform a replace at index).
|
||||
void updateInput(String key, FormInput input) {
|
||||
if (contains(key)) {
|
||||
final index = _inputs.indexOf(
|
||||
inputOf(key),
|
||||
);
|
||||
_inputs[index] = input;
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns all associated validators as a list
|
||||
List<FormInputValidator<V, E>> validators<V, E extends ValidationError>() =>
|
||||
_inputs
|
||||
.map<FormInputValidator<V, E>>(
|
||||
(input) => input.validator as FormInputValidator<V, E>,
|
||||
)
|
||||
.toList();
|
||||
|
||||
/// A [FormInputValidator] represents the value of a single form input field.
|
||||
/// It contains information about the [FormInputStatus], value, as well
|
||||
/// as validation status.
|
||||
T validatorOf<T>(String key) => inputOf(key).validator as T;
|
||||
|
||||
/// Updates validator of a given input. (perform copyWith)
|
||||
void updateValidator<V>(
|
||||
String key,
|
||||
FormInputValidator<V, ValidationError> dirtyValue,
|
||||
) {
|
||||
if (contains(key)) {
|
||||
final index = _inputs.indexOf(
|
||||
inputOf(key),
|
||||
);
|
||||
_inputs[index] = _inputs[index].copyWith(validator: dirtyValue);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a validation error if the [FormInputValidator] is invalid.
|
||||
/// Returns null if the [FormInputValidator] is valid.
|
||||
E? errorOf<E extends ValidationError>(String key) =>
|
||||
(inputOf(key).validator as FormInputValidator<dynamic, E>).error;
|
||||
|
||||
/// The value of the associated [FormInputValidator]. For example,
|
||||
/// if you have a FormInputValidator for FirstName, the value could be 'Joe'.
|
||||
V valueOf<V>(String key) =>
|
||||
(inputOf(key).validator as FormInputValidator<V, dynamic>).value;
|
||||
|
||||
/// Returns `true` if the [FormInputValidator] is not valid.
|
||||
/// Same as `E? errorOf<V, E>(String key) != null`
|
||||
bool isNotValid(String key) => !inputOf(key).validator.valid;
|
||||
|
||||
/// Returns all associated metadata as a list
|
||||
List<FormInputMetadata<M>> metadata<M>() => _inputs
|
||||
.map<FormInputMetadata<M>>(
|
||||
(input) => input.metadata as FormInputMetadata<M>,
|
||||
)
|
||||
.toList();
|
||||
|
||||
/// Returns the metadata associated. With `M` the type of extra data.
|
||||
FormInputMetadata<M> metadataOf<M>(String key) =>
|
||||
inputOf(key).metadata as FormInputMetadata<M>;
|
||||
|
||||
/// Updates metadata of a given input. (perform copyWith)
|
||||
void updateMetadata<M>(String key, FormInputMetadata<M> meta) {
|
||||
if (contains(key)) {
|
||||
final index = _inputs.indexOf(
|
||||
inputOf(key),
|
||||
);
|
||||
_inputs[index] = _inputs[index].copyWith(metadata: meta);
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if this contains an input with the given key.
|
||||
bool contains(String key) => _inputs.any((input) => input.key == key);
|
||||
|
||||
/// Makes an intersection set operation and returns newly created [FormData]
|
||||
FormData intersection(FormData other) {
|
||||
final List<FormInput> inputs = <FormInput>[];
|
||||
|
||||
for (final FormInput i in _inputs) {
|
||||
if (other.contains(i.key)) {
|
||||
inputs.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
return FormData(inputs);
|
||||
}
|
||||
|
||||
/// Makes a difference set operation and returns newly created [FormData]
|
||||
FormData difference(FormData other) {
|
||||
final List<FormInput> inputs = <FormInput>[];
|
||||
|
||||
for (final FormInput i in other._inputs) {
|
||||
if (!contains(i.key)) {
|
||||
inputs.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
for (final FormInput i in _inputs) {
|
||||
if (!other.contains(i.key)) {
|
||||
inputs.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
return FormData(inputs);
|
||||
}
|
||||
|
||||
/// Makes an union set operation and returns newly created [FormData]
|
||||
FormData union(FormData other) {
|
||||
final List<FormInput> inputs = <FormInput>[];
|
||||
|
||||
for (final FormInput i in _inputs) {
|
||||
inputs.add(i);
|
||||
}
|
||||
|
||||
for (final FormInput i in other._inputs) {
|
||||
if (!contains(i.key)) {
|
||||
inputs.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
return FormData(inputs);
|
||||
}
|
||||
|
||||
/// Deeply copy this.
|
||||
FormData clone() => FormData(
|
||||
_inputs.map((input) => input.clone()).toList(),
|
||||
);
|
||||
|
||||
/// Export this to [Map] format.
|
||||
Map<String, dynamic> toMap() {
|
||||
final map = <String, dynamic>{};
|
||||
for (final input in _inputs) {
|
||||
if (input.metadata.export) {
|
||||
map[input.name] = input.validator.value;
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/// Export this to [String] format.
|
||||
String toJson() => jsonEncode(toMap());
|
||||
|
||||
@override
|
||||
bool? get stringify => true;
|
||||
|
||||
@override
|
||||
List<Object?> get props => _inputs;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// 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 'dart:async';
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:wyatt_form_bloc/src/core/enums/form_status.dart';
|
||||
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';
|
||||
|
||||
part 'form_data_state.dart';
|
||||
|
||||
abstract class FormDataCubit<State extends FormDataState> extends Cubit<State> {
|
||||
FormDataCubit(super.initialState) : super();
|
||||
|
||||
FutureOr<void> dataChanged<Value>(
|
||||
String key,
|
||||
FormInputValidator<Value, ValidationError> dirtyValue,
|
||||
);
|
||||
|
||||
FutureOr<void> update(
|
||||
WyattForm form, {
|
||||
SetOperation operation = SetOperation.replace,
|
||||
});
|
||||
|
||||
FutureOr<void> validate();
|
||||
|
||||
FutureOr<void> reset();
|
||||
|
||||
FutureOr<void> submit();
|
||||
}
|
||||
+4
-20
@@ -16,35 +16,19 @@
|
||||
|
||||
part of 'form_data_cubit.dart';
|
||||
|
||||
class FormDataState extends Equatable {
|
||||
abstract class FormDataState extends Equatable {
|
||||
/// Global status of a form.
|
||||
final FormStatus status;
|
||||
|
||||
|
||||
/// FormData with all inputs, and associated metadata.
|
||||
final FormData data;
|
||||
final WyattForm form;
|
||||
|
||||
/// Optional error message.
|
||||
final String? errorMessage;
|
||||
|
||||
const FormDataState({
|
||||
required this.data,
|
||||
required this.form,
|
||||
this.status = FormStatus.pure,
|
||||
this.errorMessage,
|
||||
});
|
||||
|
||||
FormDataState copyWith({
|
||||
FormStatus? status,
|
||||
FormData? data,
|
||||
String? errorMessage,
|
||||
}) => FormDataState(
|
||||
status: status ?? this.status,
|
||||
data: data ?? this.data,
|
||||
errorMessage: errorMessage ?? this.errorMessage,
|
||||
);
|
||||
|
||||
@override
|
||||
bool? get stringify => true;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [status, data, errorMessage];
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
// 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 'dart:async';
|
||||
|
||||
import 'package:wyatt_form_bloc/src/core/enums/form_status.dart';
|
||||
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/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));
|
||||
|
||||
@override
|
||||
FutureOr<void> dataChanged<Value>(
|
||||
String key,
|
||||
FormInputValidator<Value, ValidationError> dirtyValue,
|
||||
) {
|
||||
final form = state.form.clone();
|
||||
|
||||
try {
|
||||
form.updateValidator(key, dirtyValue);
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
form: form,
|
||||
status: form.validate(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
FutureOr<void> update(
|
||||
WyattForm form, {
|
||||
SetOperation operation = SetOperation.replace,
|
||||
}) {
|
||||
final WyattForm newForm = operation.operation.call(state.form, form);
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
form: newForm,
|
||||
status: newForm.validate(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
FutureOr<void> reset() {
|
||||
final form = state.form.reset();
|
||||
emit(
|
||||
state.copyWith(
|
||||
form: form,
|
||||
status: form.validate(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
FutureOr<void> validate() {
|
||||
emit(
|
||||
state.copyWith(
|
||||
status: state.form.validate(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
// 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/>.
|
||||
|
||||
part of 'form_data_cubit_impl.dart';
|
||||
|
||||
class FormDataStateImpl extends FormDataState {
|
||||
const FormDataStateImpl({
|
||||
required super.form,
|
||||
super.status = FormStatus.pure,
|
||||
super.errorMessage,
|
||||
});
|
||||
|
||||
FormDataStateImpl copyWith({
|
||||
FormStatus? status,
|
||||
WyattForm? form,
|
||||
String? errorMessage,
|
||||
}) =>
|
||||
FormDataStateImpl(
|
||||
status: status ?? this.status,
|
||||
form: form ?? this.form,
|
||||
errorMessage: errorMessage ?? this.errorMessage,
|
||||
);
|
||||
|
||||
@override
|
||||
bool? get stringify => true;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [status, form, errorMessage];
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// 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/wyatt_form_bloc.dart';
|
||||
|
||||
class InputBuilder<Cubit extends FormDataCubit> extends StatelessWidget {
|
||||
const InputBuilder({required this.field, required this.builder, super.key});
|
||||
|
||||
final String field;
|
||||
|
||||
final Widget Function(
|
||||
BuildContext context,
|
||||
Cubit cubit,
|
||||
FormDataState state,
|
||||
String field,
|
||||
bool inputValid,
|
||||
) builder;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) =>
|
||||
BlocBuilder<Cubit, FormDataState>(
|
||||
builder: (context, state) {
|
||||
final cubit = context.read<Cubit>();
|
||||
final inputValid = state.form.validatorOf(field).valid;
|
||||
return builder.call(context, cubit, state, field, inputValid);
|
||||
},
|
||||
);
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
// 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/presentation/presentation.dart';
|
||||
|
||||
class InputBuilderMetadata<Cubit extends FormDataCubit, Extra>
|
||||
extends StatelessWidget {
|
||||
const InputBuilderMetadata({
|
||||
required this.field,
|
||||
required this.builder,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final String field;
|
||||
|
||||
final Widget Function(
|
||||
BuildContext context,
|
||||
Cubit cubit,
|
||||
FormDataState state,
|
||||
String field,
|
||||
bool inputValid,
|
||||
FormInputMetadata<Extra>? metadata,
|
||||
) builder;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => 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,
|
||||
metadata,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// 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/core/enums/form_status.dart';
|
||||
import 'package:wyatt_form_bloc/src/presentation/features/form_data/form_data_cubit.dart';
|
||||
|
||||
class SubmitBuilder<Cubit extends FormDataCubit> extends StatelessWidget {
|
||||
const SubmitBuilder({required this.builder, super.key});
|
||||
|
||||
final Widget Function(BuildContext context, Cubit cubit, FormStatus status)
|
||||
builder;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => BlocBuilder<Cubit, FormDataState>(
|
||||
buildWhen: (previous, current) => previous.status != current.status,
|
||||
builder: (context, state) => builder.call(
|
||||
context,
|
||||
context.read<Cubit>(),
|
||||
state.status,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// 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/>.
|
||||
|
||||
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/submit_builder.dart';
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
export 'cubit/form_data_cubit.dart';
|
||||
export 'enums/enums.dart';
|
||||
export 'form/form.dart';
|
||||
export 'validators/validators.dart';
|
||||
export 'core/core.dart';
|
||||
export 'data/data.dart';
|
||||
export 'domain/domain.dart';
|
||||
export 'presentation/presentation.dart';
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
// 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_form_bloc/src/enums/enums.dart';
|
||||
import 'package:wyatt_form_bloc/src/validators/inputs/base/regex_validator.dart';
|
||||
|
||||
/// {@template iban}
|
||||
/// Form input for an IBAN input.
|
||||
/// {@endtemplate}
|
||||
class Iban extends RegexValidator<ValidationStandardError> {
|
||||
/// {@macro iban}
|
||||
const Iban.pure() : super.pure();
|
||||
|
||||
/// {@macro iban}
|
||||
const Iban.dirty([super.value = '']) : super.dirty();
|
||||
|
||||
@override
|
||||
ValidationStandardError get onEmpty => ValidationStandardError.empty;
|
||||
@override
|
||||
ValidationStandardError get onError => ValidationStandardError.invalid;
|
||||
|
||||
@override
|
||||
RegExp get regex => RegExp(
|
||||
r'^(?:((?:IT|SM)\d{2}[A-Z]{1}\d{22})|(NL\d{2}[A-Z]{4}\d{10})|(LV\d{2}[A-Z]{4}\d{13})|((?:BG|GB|IE)\d{2}[A-Z]{4}\d{14})|(GI\d{2}[A-Z]{4}\d{15})|(RO\d{2}[A-Z]{4}\d{16})|(MT\d{2}[A-Z]{4}\d{23})|(NO\d{13})|((?:DK|FI)\d{16})|((?:SI)\d{17})|((?:AT|EE|LU|LT)\d{18})|((?:HR|LI|CH)\d{19})|((?:DE|VA)\d{20})|((?:AD|CZ|ES|MD|SK|SE)\d{22})|(PT\d{23})|((?:IS)\d{24})|((?:BE)\d{14})|((?:FR|MC|GR)\d{25})|((?:PL|HU|CY)\d{26}))$',
|
||||
);
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
// 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_form_bloc/src/enums/enums.dart';
|
||||
import 'package:wyatt_form_bloc/src/form/form.dart';
|
||||
|
||||
/// {@template list_option}
|
||||
/// Form input for a list input
|
||||
/// {@endtemplate}
|
||||
class ListOption<T>
|
||||
extends FormInputValidator<List<T>, ValidationStandardError> {
|
||||
/// {@macro list_option}
|
||||
const ListOption.pure({List<T>? defaultValue})
|
||||
: super.pure(defaultValue ?? const []);
|
||||
|
||||
/// {@macro list_option}
|
||||
const ListOption.dirty({List<T>? value}) : super.dirty(value ?? const []);
|
||||
|
||||
ListOption<T> select(T? v) {
|
||||
if (v == null) {
|
||||
return this;
|
||||
}
|
||||
if (value.contains(v)) {
|
||||
final List<T> newValue = List.from(value)..remove(v);
|
||||
return ListOption<T>.dirty(value: newValue);
|
||||
} else {
|
||||
final List<T> newValue = List.from(value)..add(v);
|
||||
return ListOption<T>.dirty(value: newValue);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
ValidationStandardError? validator(List<T>? value) =>
|
||||
value?.isNotEmpty ?? false == true
|
||||
? null
|
||||
: ValidationStandardError.invalid;
|
||||
}
|
||||
Reference in New Issue
Block a user