refactor(form): all package structure/documentation

This commit is contained in:
2022-04-20 00:01:12 +02:00
parent aa2b51f3da
commit ae731f5877
27 changed files with 938 additions and 115 deletions
@@ -18,19 +18,19 @@ import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:meta/meta.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/utils/set_operations.dart';
part 'form_state.dart';
part 'form_data_state.dart';
class FormCubit extends Cubit<FormState> {
final Future<bool> Function(FormState state)? _onSubmit;
class FormDataCubit extends Cubit<FormDataState> {
final Future<bool> Function(FormDataState state)? _onSubmit;
FormCubit({
FormDataCubit({
required FormData entries,
Future<bool> Function(FormState state)? onSubmit,
Future<bool> Function(FormDataState state)? onSubmit,
}) : _onSubmit = onSubmit,
super(FormState(data: entries));
super(FormDataState(data: entries));
void dataChanged<T>(String field, FormInput dirtyValue) {
final _form = state.data.clone();
@@ -44,7 +44,7 @@ class FormCubit extends Cubit<FormState> {
emit(
state.copyWith(
data: _form,
status: FormValidator.validate(_form.inputs<dynamic>()),
status: _form.validate(),
),
);
}
@@ -73,7 +73,7 @@ class FormCubit extends Cubit<FormState> {
emit(
state.copyWith(
data: _form,
status: FormValidator.validate(_form.inputs<dynamic>()),
status: _form.validate(),
),
);
}
@@ -14,26 +14,26 @@
// 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_cubit.dart';
part of 'form_data_cubit.dart';
@immutable
class FormState {
class FormDataState {
final FormStatus status;
final FormData data;
final String? errorMessage;
const FormState({
const FormDataState({
required this.data,
this.status = FormStatus.pure,
this.errorMessage,
});
FormState copyWith({
FormDataState copyWith({
FormStatus? status,
FormData? data,
String? errorMessage,
}) {
return FormState(
return FormDataState(
status: status ?? this.status,
data: data ?? this.data,
errorMessage: errorMessage ?? this.errorMessage,
@@ -44,7 +44,7 @@ class FormState {
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is FormState &&
return other is FormDataState &&
other.status == status &&
other.data == data &&
other.errorMessage == errorMessage;
@@ -57,7 +57,7 @@ class FormState {
@override
String toString() {
return 'FormState(status: $status, data: $data, '
return 'FormDataState(status: $status, data: $data, '
'errorMessage: $errorMessage)';
}
}
@@ -14,4 +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/>.
enum SetOperation { replace, intersection, difference, union }
export 'form_input_status.dart';
export 'form_status.dart';
export 'set_operations.dart';
export 'validation_error.dart';
@@ -1,30 +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/form/form.dart';
/// Class which contains methods that help manipulate and manage
/// [FormStatus] and [FormInputStatus] instances.
class FormValidator {
/// Returns a [FormStatus] given a list of [FormInput].
static FormStatus validate(List<FormInput> inputs) {
return inputs.every((FormInput element) => element.pure)
? FormStatus.pure
: inputs.any((FormInput input) => input.valid == false)
? FormStatus.invalid
: FormStatus.valid;
}
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
}
@@ -17,6 +17,3 @@
export 'form_data.dart';
export 'form_entry.dart';
export 'form_input.dart';
export 'form_input_status.dart';
export 'form_status.dart';
export 'form_validator.dart';
@@ -15,6 +15,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:meta/meta.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/utils/list_equals.dart';
import 'package:wyatt_form_bloc/src/validators/validators.dart';
@@ -35,25 +36,34 @@ class FormData {
.toList();
}
FormInput<T, ValidationError> input<T>(String field) {
if (contains(field)) {
return _entries
.firstWhere((FormEntry entry) => entry.field == field)
.input as FormInput<T, ValidationError>;
FormStatus validate() {
final List<FormInput> inputs = this.inputs<dynamic>();
return inputs.every((FormInput element) => element.pure)
? FormStatus.pure
: inputs.any((FormInput input) => input.valid == false)
? FormStatus.invalid
: FormStatus.valid;
}
FormInput<T, ValidationError> input<T>(String key) {
if (contains(key)) {
return _entries.firstWhere((FormEntry entry) => entry.key == key).input
as FormInput<T, ValidationError>;
} else {
throw Exception('Field $field does not exist in form');
throw Exception('FormInput with key `$key` does not exist in form');
}
}
bool contains(String field) {
return _entries.any((FormEntry entry) => entry.field == field);
bool contains(String key) {
return _entries.any((FormEntry entry) => entry.key == key);
}
FormData intersection(FormData other) {
final List<FormEntry> entries = <FormEntry>[];
for (final FormEntry entry in _entries) {
if (other.contains(entry.field)) {
if (other.contains(entry.key)) {
entries.add(entry);
}
}
@@ -65,13 +75,13 @@ class FormData {
final List<FormEntry> entries = <FormEntry>[];
for (final FormEntry otherEntry in other._entries) {
if (!contains(otherEntry.field)) {
if (!contains(otherEntry.key)) {
entries.add(otherEntry);
}
}
for (final FormEntry entry in _entries) {
if (!other.contains(entry.field)) {
if (!other.contains(entry.key)) {
entries.add(entry);
}
}
@@ -87,7 +97,7 @@ class FormData {
}
for (final FormEntry otherEntry in other._entries) {
if (!contains(otherEntry.field)) {
if (!contains(otherEntry.key)) {
entries.add(otherEntry);
}
}
@@ -95,10 +105,10 @@ class FormData {
return FormData(entries);
}
void update(String field, FormInput input) {
if (contains(field)) {
void update(String key, FormInput input) {
if (contains(key)) {
final index = _entries.indexOf(
_entries.firstWhere((FormEntry entry) => entry.field == field),
_entries.firstWhere((FormEntry entry) => entry.key == key),
);
_entries[index] = _entries[index].copyWith(input: input);
}
@@ -106,9 +116,7 @@ class FormData {
FormData clone() {
return FormData(
_entries
.map((FormEntry entry) => entry.clone())
.toList(),
_entries.map((FormEntry entry) => entry.clone()).toList(),
);
}
@@ -116,7 +124,7 @@ class FormData {
final map = <String, dynamic>{};
for (final entry in _entries) {
if (entry.export) {
map[entry.fieldName ?? entry.field] = entry.input.value;
map[entry.name] = entry.input.value;
}
}
return map;
@@ -19,33 +19,36 @@ import 'package:wyatt_form_bloc/src/form/form.dart';
@immutable
class FormEntry {
const FormEntry(this.field, this.input, {this.export = true, this.fieldName});
const FormEntry(this.key, this.input, {this.export = true, String? name})
: _field = name ?? key;
final String field;
final String key;
final FormInput input;
final bool export;
final String? fieldName;
final String _field;
String get name => _field;
FormEntry copyWith({
String? field,
String? key,
FormInput? input,
bool? export,
String? fieldName,
String? name,
}) {
return FormEntry(
field ?? this.field,
key ?? this.key,
input ?? this.input,
export: export ?? this.export,
fieldName: fieldName ?? this.fieldName,
name: name,
);
}
FormEntry clone() {
return FormEntry(
field,
key,
input,
export: export,
fieldName: fieldName,
name: name,
);
}
@@ -54,23 +57,23 @@ class FormEntry {
if (identical(this, other)) return true;
return other is FormEntry &&
other.field == field &&
other.key == key &&
other.input == input &&
other.export == export &&
other.fieldName == fieldName;
other.name == name;
}
@override
int get hashCode {
return field.hashCode ^
return key.hashCode ^
input.hashCode ^
export.hashCode ^
fieldName.hashCode;
name.hashCode;
}
@override
String toString() {
return 'FormEntry(field: $field, input: $input, '
'export: $export, fieldName: $fieldName)';
return 'FormEntry(key: $key, input: $input, '
'export: $export, name: $name)';
}
}
@@ -15,7 +15,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:meta/meta.dart';
import 'package:wyatt_form_bloc/src/form/form.dart';
import 'package:wyatt_form_bloc/src/enums/enums.dart';
/// {@template form_input}
/// A [FormInput] represents the value of a single form input field.
@@ -107,5 +107,5 @@ abstract class FormInput<T, E> {
}
@override
String toString() => '$runtimeType($value, $pure)';
String toString() => 'FormInput<$runtimeType>(value: $value, pure: $pure)';
}
+2 -1
View File
@@ -14,6 +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 'utils/set_operations.dart';
export 'validators/validators.dart';
@@ -14,8 +14,8 @@
// 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/validators/validators.dart';
/// {@template boolean}
/// Form input for a bool input
@@ -14,8 +14,8 @@
// 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/validators/validators.dart';
/// {@template confirmed_password}
/// Form input for a confirmed password input.
@@ -14,8 +14,8 @@
// 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/validators/validators.dart';
/// {@template email}
/// Form input for an email input.
@@ -33,8 +33,6 @@ class Email extends FormInput<String, ValidationError> {
@override
ValidationError? validator(String? value) {
return _emailRegExp.hasMatch(value ?? '')
? null
: ValidationError.invalid;
return _emailRegExp.hasMatch(value ?? '') ? null : ValidationError.invalid;
}
}
@@ -14,8 +14,8 @@
// 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/validators/validators.dart';
/// {@template iban}
/// Form input for an IBAN input.
@@ -14,8 +14,8 @@
// 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/validators/validators.dart';
/// {@template name}
/// Form input for a name input.
@@ -14,8 +14,8 @@
// 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/validators/validators.dart';
/// {@template password}
/// Form input for a password input.
@@ -14,8 +14,8 @@
// 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/validators/validators.dart';
/// {@template phone}
/// Form input for a phone input.
@@ -14,8 +14,8 @@
// 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/validators/validators.dart';
/// {@template siren}
/// Form input for a SIREN input.
@@ -14,8 +14,8 @@
// 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/validators/validators.dart';
/// {@template text_string}
/// Form input for a text input
@@ -29,8 +29,6 @@ class TextString extends FormInput<String, ValidationError> {
@override
ValidationError? validator(String? value) {
return (value?.isNotEmpty ?? false)
? null
: ValidationError.invalid;
return (value?.isNotEmpty ?? false) ? null : ValidationError.invalid;
}
}
@@ -23,4 +23,3 @@ export 'password.dart';
export 'phone.dart';
export 'siren.dart';
export 'text_string.dart';
export 'validation_error.dart';