feat(tasks): snooze — park a task at the bottom until a time
Snooze puts a task out of the way without finishing it or filing it: it sinks to
the bottom of its list and greys, and comes back on its own when its time passes.
No job wakes it — "snoozed" is just snoozed_until being still in the future, read
against the clock each time the list is ordered.
- `snoozed_until` on tasks (migration 0031); the list order sinks a still-snoozed
task below everything, and it rejoins its place the moment the time passes.
- POST /tasks/{id}/snooze {until} — an RFC3339 time to snooze to, or empty to wake.
Nothing else about the task moves; a snooze is about when you want to see it, not
when it is due.
- The task drawer gains quick picks (this evening / tomorrow / next week) and a
custom time, and a Wake now once it is snoozed. The row dims and carries a
"snoozed until X" mark, and the list keeps snoozed tasks at the foot — the client
sorts the same way the server does, so a drag-sorted list does not jump on reload.
Tests: snooze sinks a task below one made after it and waking returns it (Go); and
from the drawer the row greys, shows the mark, and un-greys on wake (e2e). Full
suites green.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
fa816b2e41
commit
9e3f20b050
@@ -127,6 +127,32 @@ test('hvert link i sidebjælken fører et sted hen', async ({ page }) => {
|
||||
expect(trouble).toEqual([]);
|
||||
});
|
||||
|
||||
test('en opgave kan slumres og hentes frem igen', async ({ page }) => {
|
||||
const trouble = watchForTrouble(page);
|
||||
await page.goto('/');
|
||||
|
||||
// "i dag" is parsed as the due date, so the task is named "Alfa" and shows here.
|
||||
const box = page.getByLabel('Ny opgave');
|
||||
await box.fill('Alfa i dag');
|
||||
await box.press('Enter');
|
||||
|
||||
// Snooze it to tomorrow from its drawer.
|
||||
await page.getByText('Alfa', { exact: true }).click();
|
||||
const drawer = page.getByRole('complementary', { name: 'Opgave' });
|
||||
await drawer.getByRole('button', { name: 'I morgen' }).click();
|
||||
|
||||
// The row greys — it carries the snoozed class and a "slumret til" mark.
|
||||
const alfa = page.locator('.row', { hasText: 'Alfa' });
|
||||
await expect(alfa).toHaveClass(/snoozed/);
|
||||
await expect(alfa.locator('.snooze-mark')).toBeVisible();
|
||||
|
||||
// The drawer now offers to wake it, and waking takes the grey off.
|
||||
await drawer.getByRole('button', { name: 'Væk nu' }).click();
|
||||
await expect(alfa).not.toHaveClass(/snoozed/);
|
||||
|
||||
expect(trouble).toEqual([]);
|
||||
});
|
||||
|
||||
test('en opgave kan åbnes og redigeres', async ({ page }) => {
|
||||
const trouble = watchForTrouble(page);
|
||||
await page.goto('/');
|
||||
|
||||
Reference in New Issue
Block a user