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:
parent
f43edc1ea7
commit
7cbd2eff40
7
lib/models/app_exceptions.dart
Normal file
7
lib/models/app_exceptions.dart
Normal 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";
|
||||
}
|
@ -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(
|
||||
|
@ -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),
|
||||
));
|
||||
Navigator.pushNamed(context, ProgressDashboardScreen.routeName);
|
||||
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(
|
||||
|
@ -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;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -151,8 +163,12 @@ class _ProgressDetailScreenState extends State<ProgressDetailScreen> {
|
||||
? 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.",
|
||||
),
|
||||
)
|
||||
: 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),
|
||||
)
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user