forked from eva/focus-flow
86 lines
2.3 KiB
Dart
86 lines
2.3 KiB
Dart
import 'models.dart';
|
|
import 'scheduling_engine.dart';
|
|
|
|
/// Quick actions available from a flexible task card.
|
|
enum FlexibleTaskQuickAction {
|
|
done,
|
|
push,
|
|
backlog,
|
|
breakUp,
|
|
}
|
|
|
|
/// Explicit push destinations shown after choosing the push quick action.
|
|
enum PushDestination {
|
|
nextAvailableSlot,
|
|
tomorrowTopOfQueue,
|
|
backlog,
|
|
}
|
|
|
|
/// Domain result for a flexible task quick action.
|
|
class FlexibleTaskActionResult {
|
|
const FlexibleTaskActionResult({
|
|
required this.action,
|
|
required this.task,
|
|
this.pushDestinations = const <PushDestination>[],
|
|
this.startsChildTaskFlow = false,
|
|
});
|
|
|
|
final FlexibleTaskQuickAction action;
|
|
final Task task;
|
|
final List<PushDestination> pushDestinations;
|
|
final bool startsChildTaskFlow;
|
|
|
|
bool get changedTask => !startsChildTaskFlow && pushDestinations.isEmpty;
|
|
}
|
|
|
|
/// Applies low-friction quick actions for flexible task cards.
|
|
class FlexibleTaskActionService {
|
|
const FlexibleTaskActionService({
|
|
this.schedulingEngine = const SchedulingEngine(),
|
|
});
|
|
|
|
final SchedulingEngine schedulingEngine;
|
|
|
|
FlexibleTaskActionResult apply({
|
|
required Task task,
|
|
required FlexibleTaskQuickAction action,
|
|
DateTime? updatedAt,
|
|
}) {
|
|
if (!task.isFlexible) {
|
|
throw ArgumentError.value(
|
|
task.type, 'task.type', 'Task must be flexible.');
|
|
}
|
|
|
|
switch (action) {
|
|
case FlexibleTaskQuickAction.done:
|
|
return FlexibleTaskActionResult(
|
|
action: action,
|
|
task: task.copyWith(
|
|
status: TaskStatus.completed,
|
|
updatedAt: updatedAt ?? DateTime.now(),
|
|
),
|
|
);
|
|
case FlexibleTaskQuickAction.push:
|
|
return FlexibleTaskActionResult(
|
|
action: action,
|
|
task: task,
|
|
pushDestinations: const [
|
|
PushDestination.nextAvailableSlot,
|
|
PushDestination.tomorrowTopOfQueue,
|
|
PushDestination.backlog,
|
|
],
|
|
);
|
|
case FlexibleTaskQuickAction.backlog:
|
|
return FlexibleTaskActionResult(
|
|
action: action,
|
|
task: schedulingEngine.moveToBacklog(task, updatedAt: updatedAt),
|
|
);
|
|
case FlexibleTaskQuickAction.breakUp:
|
|
return FlexibleTaskActionResult(
|
|
action: action,
|
|
task: task,
|
|
startsChildTaskFlow: true,
|
|
);
|
|
}
|
|
}
|
|
}
|