Show overlapping times

This commit is contained in:
Hillel Coren 2022-03-01 16:45:14 +02:00
parent 80f942fd1e
commit d98fa17c91
6 changed files with 62 additions and 12 deletions

View File

@ -352,6 +352,35 @@ abstract class TaskEntity extends Object
return isValid && countRunning <= 1;
}
List get getInvalidTimeIndices {
final times = getTaskTimes();
DateTime lastDateTime = DateTime(2000);
final indices = <int>[];
int counter = 0;
times.forEach((time) {
final startDate = time.startDate;
final endDate = time.endDate;
if (time.isRunning) {
//
} else {
if (startDate.isBefore(lastDateTime) || startDate.isAfter(endDate)) {
indices.add(counter);
}
if (endDate.isBefore(startDate) || endDate.isBefore(lastDateTime)) {
indices.add(counter);
}
lastDateTime = lastDateTime.isAfter(endDate) ? lastDateTime : endDate;
}
counter++;
});
return indices;
}
bool get isRunning {
final taskTimes = getTaskTimes();

View File

@ -123,10 +123,12 @@ class _TaskEditDesktopState extends State<TaskEditDesktop> {
final client = state.clientState.get(task.clientId);
final showEndDate = company.showTaskEndDate;
final taskTimes = task.getTaskTimes(sort: false);
if (!taskTimes.any((taskTime) => taskTime.isEmpty)) {
taskTimes.add(TaskTime().rebuild((b) => b..startDate = null));
}
final overlapping = task.getInvalidTimeIndices;
final rateLabel = localization.rate +
'' +
formatNumber(
@ -413,8 +415,13 @@ class _TaskEditDesktopState extends State<TaskEditDesktop> {
Padding(
padding: const EdgeInsets.only(top: 4),
child: IconButton(
icon: Icon(Icons.clear),
tooltip: localization.remove,
icon: Icon(
Icons.clear,
color: overlapping.contains(index) ? Colors.red : null,
),
tooltip: overlapping.contains(index)
? localization.invalidTime
: localization.remove,
onPressed: taskTimes[index].isEmpty
? null
: () {

View File

@ -52,6 +52,7 @@ class _TaskEditTimesState extends State<TaskEditTimes> {
final viewModel = widget.viewModel;
final task = viewModel.task;
final taskTimes = task.getTaskTimes();
final invalidTimes = task.getInvalidTimeIndices;
final taskTime = viewModel.taskTimeIndex != null &&
taskTimes.length > viewModel.taskTimeIndex
? taskTimes[viewModel.taskTimeIndex]
@ -68,15 +69,18 @@ class _TaskEditTimesState extends State<TaskEditTimes> {
return HelpText(localization.clickPlusToAddTime);
}
final taskTimeWidgets = task
.getTaskTimes()
.toList()
.reversed
.map<Widget>((taskTime) => TaskTimeListTile(
task: task,
taskTime: taskTime,
onTap: (context) => _showTaskTimeEditor(taskTime, context),
));
final sortedTaskTimes = task.getTaskTimes().toList().reversed.toList();
final taskTimeWidgets = <Widget>[];
for (var i = 0; i < sortedTaskTimes.length; i++) {
final taskTime = sortedTaskTimes[i];
taskTimeWidgets.add(TaskTimeListTile(
task: task,
taskTime: taskTime,
onTap: (context) => _showTaskTimeEditor(taskTime, context),
isValid: !invalidTimes.contains(sortedTaskTimes.length - i - 1),
));
}
return ScrollableListView(
children: taskTimeWidgets.toList(),

View File

@ -18,11 +18,13 @@ class TaskTimeListTile extends StatelessWidget {
@required this.task,
@required this.taskTime,
@required this.onTap,
@required this.isValid,
});
final Function(BuildContext context) onTap;
final TaskEntity task;
final TaskTime taskTime;
final bool isValid;
@override
Widget build(BuildContext context) {
@ -51,7 +53,9 @@ class TaskTimeListTile extends StatelessWidget {
],
),
subtitle: Text(subtitle),
trailing: onTap != null ? Icon(Icons.navigate_next) : null,
trailing: onTap != null
? Icon(isValid ? Icons.navigate_next : Icons.error)
: null,
),
Divider(
height: 1.0,

View File

@ -200,6 +200,7 @@ class _TaskOverviewState extends State<TaskOverview> {
TaskTimeListTile(
task: task,
taskTime: taskTime,
isValid: true,
onTap: (BuildContext context) =>
viewModel.state.userCompany.canEditEntity(task)
? viewModel.onEditPressed(context, taskTime)

View File

@ -16,6 +16,7 @@ mixin LocalizationsProvider on LocaleCodeAware {
static final Map<String, Map<String, String>> _localizedValues = {
'en': {
// STARTER: lang key - do not remove comment
'invalid_time': 'Invalid Time',
'client_shipping_state': 'Client Shipping State',
'client_shipping_city': 'Client Shipping City',
'client_shipping_postal_code': 'Client Shipping Postal Code',
@ -74125,6 +74126,10 @@ mixin LocalizationsProvider on LocaleCodeAware {
_localizedValues[localeCode]['client_shipping_country'] ??
_localizedValues['en']['client_shipping_country'];
String get invalidTime =>
_localizedValues[localeCode]['invalid_time'] ??
_localizedValues['en']['invalid_time'];
// STARTER: lang field - do not remove comment
String lookup(String key) {