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: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/persistence/time_progress_entity.dart';
|
||||||
import 'package:time_progress_tracker/uuid.dart';
|
import 'package:time_progress_tracker/uuid.dart';
|
||||||
|
|
||||||
@ -10,11 +11,15 @@ class TimeProgress {
|
|||||||
final DateTime endTime;
|
final DateTime endTime;
|
||||||
|
|
||||||
TimeProgress(this.name, this.startTime, this.endTime, {String id})
|
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() {
|
factory TimeProgress.initialDefault() {
|
||||||
int thisYear = DateTime.now().year;
|
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(
|
TimeProgress copyWith(
|
||||||
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter_redux/flutter_redux.dart';
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
import 'package:time_progress_tracker/actions/actions.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/app_state.dart';
|
||||||
import 'package:time_progress_tracker/models/time_progress.dart';
|
import 'package:time_progress_tracker/models/time_progress.dart';
|
||||||
import 'package:time_progress_tracker/screens/progress_dashboard_screen.dart';
|
import 'package:time_progress_tracker/screens/progress_dashboard_screen.dart';
|
||||||
@ -22,6 +23,8 @@ class _ProgressCreationScreenState extends State<ProgressCreationScreen> {
|
|||||||
DateTime pickedEndTime = DateTime(
|
DateTime pickedEndTime = DateTime(
|
||||||
DateTime.now().year + 1, DateTime.now().month, DateTime.now().day);
|
DateTime.now().year + 1, DateTime.now().month, DateTime.now().day);
|
||||||
|
|
||||||
|
bool _validName = true;
|
||||||
|
|
||||||
Future<DateTime> _selectDate(
|
Future<DateTime> _selectDate(
|
||||||
BuildContext context, DateTime initialDate) async {
|
BuildContext context, DateTime initialDate) async {
|
||||||
return await showDatePicker(
|
return await showDatePicker(
|
||||||
@ -32,10 +35,17 @@ class _ProgressCreationScreenState extends State<ProgressCreationScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _createTimeProgress(BuildContext context) {
|
void _createTimeProgress(BuildContext context) {
|
||||||
StoreProvider.of<AppState>(context).dispatch(AddTimeProgressAction(
|
try {
|
||||||
TimeProgress(_nameController.text, pickedStartTime, pickedEndTime),
|
TimeProgress tpToCreate =
|
||||||
));
|
TimeProgress(_nameController.text, pickedStartTime, pickedEndTime);
|
||||||
Navigator.pushNamed(context, ProgressDashboardScreen.routeName);
|
StoreProvider.of<AppState>(context)
|
||||||
|
.dispatch(AddTimeProgressAction(tpToCreate));
|
||||||
|
Navigator.pushNamed(context, ProgressDashboardScreen.routeName);
|
||||||
|
} on TimeProgressInvalidNameException catch (e) {
|
||||||
|
setState(() {
|
||||||
|
_validName = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -60,7 +70,12 @@ class _ProgressCreationScreenState extends State<ProgressCreationScreen> {
|
|||||||
child: TextField(
|
child: TextField(
|
||||||
controller: _nameController,
|
controller: _nameController,
|
||||||
decoration: InputDecoration(
|
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(
|
Expanded(
|
||||||
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_redux/flutter_redux.dart';
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
import 'package:redux/redux.dart';
|
import 'package:redux/redux.dart';
|
||||||
import 'package:time_progress_tracker/actions/actions.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/app_state.dart';
|
||||||
import 'package:time_progress_tracker/models/time_progress.dart';
|
import 'package:time_progress_tracker/models/time_progress.dart';
|
||||||
import 'package:time_progress_tracker/screens/progress_dashboard_screen.dart';
|
import 'package:time_progress_tracker/screens/progress_dashboard_screen.dart';
|
||||||
@ -30,10 +31,13 @@ class ProgressDetailScreen extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _ProgressDetailScreenState extends State<ProgressDetailScreen> {
|
class _ProgressDetailScreenState extends State<ProgressDetailScreen> {
|
||||||
final TextEditingController _nameController = TextEditingController();
|
|
||||||
bool _isBeingEdited = false;
|
bool _isBeingEdited = false;
|
||||||
|
final TextEditingController _nameController = TextEditingController();
|
||||||
|
|
||||||
TimeProgress _editedProgress = TimeProgress.initialDefault();
|
TimeProgress _editedProgress = TimeProgress.initialDefault();
|
||||||
|
|
||||||
|
bool _validName = true;
|
||||||
|
|
||||||
void _onStartDateChanged(DateTime picked) {
|
void _onStartDateChanged(DateTime picked) {
|
||||||
if (picked != null) {
|
if (picked != null) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -118,10 +122,18 @@ class _ProgressDetailScreenState extends State<ProgressDetailScreen> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_nameController.addListener(() {
|
_nameController.addListener(() {
|
||||||
this.setState(() {
|
try {
|
||||||
this._editedProgress =
|
TimeProgress editedProgress =
|
||||||
this._editedProgress.copyWith(name: _nameController.text);
|
_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(
|
? TextField(
|
||||||
controller: _nameController,
|
controller: _nameController,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
border: OutlineInputBorder(),
|
border: OutlineInputBorder(),
|
||||||
labelText: "Progress Name"),
|
labelText: "Progress Name",
|
||||||
|
errorText: _validName
|
||||||
|
? null
|
||||||
|
: "The Name of the Time Progress has to be set.",
|
||||||
|
),
|
||||||
)
|
)
|
||||||
: FittedBox(
|
: FittedBox(
|
||||||
fit: BoxFit.fitWidth,
|
fit: BoxFit.fitWidth,
|
||||||
@ -205,7 +221,8 @@ class _ProgressDetailScreenState extends State<ProgressDetailScreen> {
|
|||||||
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
|
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
|
||||||
floatingActionButton: _isBeingEdited
|
floatingActionButton: _isBeingEdited
|
||||||
? ProgressDetailFabEditingRow(
|
? ProgressDetailFabEditingRow(
|
||||||
onSave: () => _onSaveTimeProgress(store, args.id),
|
onSave: () =>
|
||||||
|
_validName ? _onSaveTimeProgress(store, args.id) : null,
|
||||||
onCancelEdit: () =>
|
onCancelEdit: () =>
|
||||||
_showCancelEditTimeProgressDialog(store.state, args.id),
|
_showCancelEditTimeProgressDialog(store.state, args.id),
|
||||||
)
|
)
|
||||||
|
@ -4,5 +4,8 @@ import 'package:time_progress_tracker/models/time_progress.dart';
|
|||||||
List<TimeProgress> timeProgressListSelector(AppState state) =>
|
List<TimeProgress> timeProgressListSelector(AppState state) =>
|
||||||
state.timeProgressList;
|
state.timeProgressList;
|
||||||
|
|
||||||
TimeProgress timeProgressByIdSelector(AppState state, String id) =>
|
TimeProgress timeProgressByIdSelector(AppState state, String id) {
|
||||||
state.timeProgressList.firstWhere((timeProgress) => timeProgress.id == 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