feat(todo): Today, Upcoming, Inbox, projects, quick add and the task sheet (ADR 0033, D8, D9)
The tabs hold the person's tasks: Today what is overdue (Reschedule moving it all to a day, times kept) and what is due today; Upcoming the overdue ones and the next four weeks day by day; Inbox and each project's screen from Browse the tasks above and in their sections, done ones on asking; Browse the projects with their open counts and the labels. A task's row shows its check in its priority's colour, its date in the colour of how near it is, its deadline, its sub-tasks done and its labels; quick add takes its title, date, priority, project, labels and description and stays for the next; its sheet edits all of it, adds sub-tasks and deletes it with them after asking. Colours are the palette's, cerise for overdue and P1 against the strawberry wash. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
bd3710ae58
commit
030c62ddde
1 changed files with 3647 additions and 121 deletions
|
|
@ -0,0 +1,109 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:halkyon_todo_flutter/src/feature/task/model/task.dart';
|
||||
import 'package:halkyon_todo_flutter/src/feature/task/model/task_views.dart';
|
||||
|
||||
/// What Todo's lists show of the person's tasks (ADR 0033, D8).
|
||||
void main() {
|
||||
const today = Day(2026, 11, 1);
|
||||
final done = DateTime(2026, 11, 1, 8);
|
||||
|
||||
OpenTask task(
|
||||
String id, {
|
||||
String project = 'inbox',
|
||||
String? section,
|
||||
String? parent,
|
||||
double position = 0,
|
||||
Day? day,
|
||||
int? time,
|
||||
Priority priority = Priority.none,
|
||||
bool completed = false,
|
||||
}) => (
|
||||
id: id,
|
||||
content: TaskContent(
|
||||
title: id,
|
||||
projectId: project,
|
||||
sectionId: section,
|
||||
parentId: parent,
|
||||
position: position,
|
||||
date: day == null ? null : TaskDate(day, time: time),
|
||||
priority: priority,
|
||||
completedAt: completed ? done : null,
|
||||
),
|
||||
);
|
||||
|
||||
test("a project's list: its own tasks above its sections or in one, no "
|
||||
'sub-tasks, done ones only when asked, in their order', () {
|
||||
final tasks = [
|
||||
task('b', position: 2),
|
||||
task('a', position: 1),
|
||||
task('sub', parent: 'a'),
|
||||
task('in section', section: 's'),
|
||||
task('done', completed: true),
|
||||
task('elsewhere', project: 'home'),
|
||||
];
|
||||
|
||||
expect(tasksIn(tasks, 'inbox').map((t) => t.id), ['a', 'b']);
|
||||
expect(
|
||||
tasksIn(tasks, 'inbox', completed: true).map((t) => t.id),
|
||||
['done', 'a', 'b'],
|
||||
);
|
||||
expect(tasksIn(tasks, 'inbox', sectionId: 's').map((t) => t.id), [
|
||||
'in section',
|
||||
]);
|
||||
expect(subTasksOf(tasks, 'a').map((t) => t.id), ['sub']);
|
||||
expect(openCountIn(tasks, 'inbox'), 4);
|
||||
});
|
||||
|
||||
test("Today: what is overdue, oldest first, never done ones; then today's, "
|
||||
'timed first by their time, then by priority', () {
|
||||
final tasks = [
|
||||
task('late', day: today.plus(-2)),
|
||||
task('later', day: today.plus(-1)),
|
||||
task('late but done', day: today.plus(-3), completed: true),
|
||||
task('any time', day: today),
|
||||
task('urgent', day: today, priority: Priority.p1),
|
||||
task('at 9', day: today, time: 9 * 60),
|
||||
task('at 7', day: today, time: 7 * 60),
|
||||
task('done today', day: today, completed: true),
|
||||
task('tomorrow', day: today.plus(1)),
|
||||
task('no date'),
|
||||
];
|
||||
|
||||
final (:overdue, :due) = todayOf(tasks, today);
|
||||
expect(overdue.map((t) => t.id), ['late', 'later']);
|
||||
expect(due.map((t) => t.id), ['at 7', 'at 9', 'urgent', 'any time']);
|
||||
expect(
|
||||
todayOf(tasks, today, completed: true).due.map((t) => t.id),
|
||||
contains('done today'),
|
||||
);
|
||||
});
|
||||
|
||||
test('Upcoming: the overdue ones, then every day from today on, empty '
|
||||
'days kept', () {
|
||||
final tasks = [
|
||||
task('late', day: today.plus(-1)),
|
||||
task('today', day: today),
|
||||
task('in three days', day: today.plus(3)),
|
||||
task('too far', day: today.plus(30)),
|
||||
];
|
||||
|
||||
final (:overdue, :days) = upcomingOf(tasks, today, days: 5);
|
||||
expect(overdue.map((t) => t.id), ['late']);
|
||||
expect(
|
||||
[for (final (day, _) in days) day],
|
||||
[
|
||||
for (var i = 0; i < 5; i++) today.plus(i),
|
||||
],
|
||||
);
|
||||
expect(
|
||||
[for (final (_, list) in days) list.map((t) => t.id).toList()],
|
||||
[
|
||||
['today'],
|
||||
<String>[],
|
||||
<String>[],
|
||||
['in three days'],
|
||||
<String>[],
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
Loading…
Reference in a new issue