Feature/Fix-Invalid-TimeProgress-Name (#3)

Throw Exception when creating time progress with empty or null name.
Handle Exception when user creates new time progress or changes name.

Signed-off-by Andreas Fahrecker <AndreasFahrecker@gmail.com>
This commit is contained in:
Andreas Fahrecker 2020-11-21 19:57:47 +01:00 committed by GitHub
parent f43edc1ea7
commit 7cbd2eff40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 64 additions and 17 deletions

View File

@ -0,0 +1,7 @@
class TimeProgressInvalidNameException implements Exception {
final invalidName;
TimeProgressInvalidNameException(this.invalidName);
String errMsg() => "The name of a TimeProgress can't be: $invalidName";
}

View File

@ -1,4 +1,5 @@
import 'package:meta/meta.dart';
import 'package:time_progress_tracker/models/app_exceptions.dart';
import 'package:time_progress_tracker/persistence/time_progress_entity.dart';
import 'package:time_progress_tracker/uuid.dart';
@ -10,11 +11,15 @@ class TimeProgress {
final DateTime endTime;
TimeProgress(this.name, this.startTime, this.endTime, {String id})
: id = id ?? Uuid().generateV4();
: id = id ?? Uuid().generateV4() {
if (this.name == null || this.name == "") {
throw new TimeProgressInvalidNameException(this.name);
}
}
factory TimeProgress.initialDefault() {
int thisYear = DateTime.now().year;
return TimeProgress("", DateTime(thisYear - 1), DateTime(thisYear + 1));
return TimeProgress("Initial Name", DateTime(thisYear - 1), DateTime(thisYear + 1));
}
TimeProgress copyWith(

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:time_progress_tracker/actions/actions.dart';
import 'package:time_progress_tracker/models/app_exceptions.dart';
import 'package:time_progress_tracker/models/app_state.dart';
import 'package:time_progress_tracker/models/time_progress.dart';
import 'package:time_progress_tracker/screens/progress_dashboard_screen.dart';
@ -22,6 +23,8 @@ class _ProgressCreationScreenState extends State<ProgressCreationScreen> {
DateTime pickedEndTime = DateTime(
DateTime.now().year + 1, DateTime.now().month, DateTime.now().day);
bool _validName = true;
Future<DateTime> _selectDate(
BuildContext context, DateTime initialDate) async {
return await showDatePicker(
@ -32,10 +35,17 @@ class _ProgressCreationScreenState extends State<ProgressCreationScreen> {
}
void _createTimeProgress(BuildContext context) {
StoreProvider.of<AppState>(context).dispatch(AddTimeProgressAction(
TimeProgress(_nameController.text, pickedStartTime, pickedEndTime),
));
try {
TimeProgress tpToCreate =
TimeProgress(_nameController.text, pickedStartTime, pickedEndTime);
StoreProvider.of<AppState>(context)
.dispatch(AddTimeProgressAction(tpToCreate));
Navigator.pushNamed(context, ProgressDashboardScreen.routeName);
} on TimeProgressInvalidNameException catch (e) {
setState(() {
_validName = false;
});
}
}
@override
@ -60,7 +70,12 @@ class _ProgressCreationScreenState extends State<ProgressCreationScreen> {
child: TextField(
controller: _nameController,
decoration: InputDecoration(
border: OutlineInputBorder(), labelText: "Progress Name"),
border: OutlineInputBorder(),
labelText: "Progress Name",
errorText: _validName
? null
: "The Name of the Time Progress has to be set.",
),
),
),
Expanded(

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:redux/redux.dart';
import 'package:time_progress_tracker/actions/actions.dart';
import 'package:time_progress_tracker/models/app_exceptions.dart';
import 'package:time_progress_tracker/models/app_state.dart';
import 'package:time_progress_tracker/models/time_progress.dart';
import 'package:time_progress_tracker/screens/progress_dashboard_screen.dart';
@ -30,10 +31,13 @@ class ProgressDetailScreen extends StatefulWidget {
}
class _ProgressDetailScreenState extends State<ProgressDetailScreen> {
final TextEditingController _nameController = TextEditingController();
bool _isBeingEdited = false;
final TextEditingController _nameController = TextEditingController();
TimeProgress _editedProgress = TimeProgress.initialDefault();
bool _validName = true;
void _onStartDateChanged(DateTime picked) {
if (picked != null) {
setState(() {
@ -118,10 +122,18 @@ class _ProgressDetailScreenState extends State<ProgressDetailScreen> {
void initState() {
super.initState();
_nameController.addListener(() {
this.setState(() {
this._editedProgress =
this._editedProgress.copyWith(name: _nameController.text);
try {
TimeProgress editedProgress =
_editedProgress.copyWith(name: _nameController.text);
setState(() {
_editedProgress = editedProgress;
_validName = true;
});
} on TimeProgressInvalidNameException catch (e) {
setState(() {
_validName = false;
});
}
});
}
@ -152,7 +164,11 @@ class _ProgressDetailScreenState extends State<ProgressDetailScreen> {
controller: _nameController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: "Progress Name"),
labelText: "Progress Name",
errorText: _validName
? null
: "The Name of the Time Progress has to be set.",
),
)
: FittedBox(
fit: BoxFit.fitWidth,
@ -205,7 +221,8 @@ class _ProgressDetailScreenState extends State<ProgressDetailScreen> {
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: _isBeingEdited
? ProgressDetailFabEditingRow(
onSave: () => _onSaveTimeProgress(store, args.id),
onSave: () =>
_validName ? _onSaveTimeProgress(store, args.id) : null,
onCancelEdit: () =>
_showCancelEditTimeProgressDialog(store.state, args.id),
)

View File

@ -4,5 +4,8 @@ import 'package:time_progress_tracker/models/time_progress.dart';
List<TimeProgress> timeProgressListSelector(AppState state) =>
state.timeProgressList;
TimeProgress timeProgressByIdSelector(AppState state, String id) =>
state.timeProgressList.firstWhere((timeProgress) => timeProgress.id == id);
TimeProgress timeProgressByIdSelector(AppState state, String id) {
if (state.timeProgressList.length < 1) return null;
return state.timeProgressList
.firstWhere((timeProgress) => timeProgress.id == id);
}