refactor(form): all package structure/documentation
This commit is contained in:
+9
-9
@@ -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(),
|
||||
),
|
||||
);
|
||||
}
|
||||
+7
-7
@@ -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)';
|
||||
}
|
||||
}
|
||||
+4
-1
@@ -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';
|
||||
+15
-16
@@ -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)';
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
|
||||
Reference in New Issue
Block a user