feat(projects): et projekts kalender kan vises som en uge

Ugen fandtes på Kommende og på Kalender, men ikke dér hvor et projekt bor — og det
er dér, "hvornår sker de her fire ting" oftest bliver spurgt.

Inde i kalendervisningen frem for som en fjerde `view_mode`. `view_mode` er
projektets og delt med alle, der kan se det, mens uge eller måned er et spørgsmål
om hvor bred skærmen er, foran hvilken der sidder én person — samme grund som
sidebjælkens bredde ligger i localStorage af. Og en fjerde værdi ville kræve en
tabelombygning: `CHECK (view_mode IN ('list','board','calendar'))` kan SQLite ikke
ændre på plads.

**Og så fandt den en fejl, der har ligget og ventet.** `cursor` blev sat med
`span === 'week' ? … : …`, hvilket læser `span` i det øjeblik komponenten bliver
til og fanger den værdi for altid. Byggeriet har advaret om det lige så længe. Så
længe hver visning havde sin egen komponent, gjorde det ingen forskel — og det
gjorde det i samme sekund, en vælger begyndte at skifte `span` på den samme.
Markøren stod på den 1. i måneden, og et skift til uge landede på ugen omkring den
1.: "27. jul.–2. aug." for en person, der kiggede på august.

Rettet, med den ene undtagelse skrevet ned: en månedsvisnings markør *er* den
første i måneden, så et skift til uge, mens man står i den indeværende måned,
skal lande på den uge, i dag ligger i — ikke på ugen omkring den 1.

Og en anden fælde, jeg selv gik i undervejs: en underklasses felter sættes *efter*
basens konstruktør er kørt. Nøglen til localStorage som et felt på en underklasse
betød, at valget blev gemt ét sted og læst et andet — en uge, man havde valgt, var
en måned igen efter en genindlæsning. Nøglen er et argument nu; et argument har
ingen rækkefølge at tage fejl af.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kristian Wind
2026-08-20 21:45:38 +02:00
co-authored by Claude Opus 5
parent dcb71f4c14
commit 868588de10
4 changed files with 146 additions and 8 deletions
+45
View File
@@ -3378,3 +3378,48 @@ test('notelisten grupperer favoritter og datoer, også i arkivet', async ({ page
expect(trouble).toEqual([]);
});
/**
* Et projekts kalender kan vises som en uge.
*
* Ugen fandtes på Kommende og på Kalender, men ikke dér, hvor et projekt bor — og
* det er dér, "hvornår sker de her fire ting" oftest bliver spurgt.
*
* Inde i kalendervisningen frem for som en fjerde `view_mode`. Den er projektets
* og delt med alle, der kan se det, mens uge eller måned er et spørgsmål om, hvor
* bred skærmen er, foran hvilken der sidder én person — og en fjerde værdi ville
* kræve en tabelombygning, fordi SQLite ikke kan ændre et CHECK på plads.
*/
test('et projekts kalender kan vises som en uge', async ({ page }) => {
const trouble = watchForTrouble(page);
await page.goto('/');
const sidebar = page.getByRole('navigation', { name: 'Hovedmenu' });
await sidebar.getByRole('button', { name: 'Nyt projekt' }).click();
await sidebar.getByLabel('Projektnavn').fill('Ugeprojekt');
await sidebar.getByLabel('Projektnavn').press('Enter');
await expect(page.getByRole('heading', { name: 'Ugeprojekt' })).toBeVisible();
const box = page.getByLabel('Ny opgave');
await box.fill('male døren i dag kl 10');
await box.press('Enter');
await expect(page.getByText('male døren')).toBeVisible();
await page.getByRole('button', { name: 'Kalender', exact: true }).click();
await page.getByRole('button', { name: 'Uge', exact: true }).click();
// Døgnet, ikke en rude: opgaven står på sit klokkeslæt.
const placed = page.locator('.tevent.task').filter({ hasText: 'male døren' });
await expect(placed, 'opgaven står ikke på døgnet').toBeVisible();
await expect(placed).toContainText('10:00');
// Valget huskes — i browseren, ikke på projektet: det er skærmens bredde, der
// afgør det, og projektet er delt med andre skærme.
await page.reload();
await expect(page.locator('.weekgrid'), 'ugen blev ikke husket').toBeVisible();
await page.getByRole('button', { name: 'Måned', exact: true }).click();
await expect(page.locator('.weekgrid')).toBeHidden();
expect(trouble).toEqual([]);
});