feat(notes): titlen er første linje, og # foreslår projektet
Release / Build and publish image (push) Failing after 9m59s

Titlen var udledt én gang og derefter ladt i fred, så den gik i stå i det øjeblik
nogen skrev begyndelsen om — en note med overskriften "Ny note" stod i listen som
"fdgfgfgh", hvilket var, hvad dens første linje havde været nogle rettelser
tidligere. Den udledes nu ved hver gemning, og ingen kan sætte den ved siden af
teksten: kolonnen er en kopi af kroppen, ikke et felt derudover. Feltet er væk fra
både HTTP-fladen og MCP-værktøjerne, for et felt, serveren ignorerer, er et løfte,
den ikke kan holde.

Skriver man #Kaf, foreslås #Kaffebaren. Ordet læses fra den tekstknude, markøren
står i, og ikke fra hele dokumentet — en note kan nævne tyve projekter, og kun det
under markøren er ved at blive skrevet. Listen ejer piletasterne og retur, mens
den er åben, som enhver anden fuldførelse.

Og under feltet står nu, hvad teksten forstår: # projekt, [[en anden note]], ⌘B,
⌘U. Samme idé som linjen under hurtig tilføjelse — en note er det andet sted i
programmet, hvor det, man skriver, bliver læst for betydning.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kristian Wind
2026-08-19 18:36:31 +02:00
co-authored by Claude Opus 5
parent 3223989a9d
commit 5e670119db
9 changed files with 286 additions and 28 deletions
+48
View File
@@ -2129,3 +2129,51 @@ test('en ny note begynder som titel, og linjen efter er brødtekst', async ({ pa
expect(trouble).toEqual([]);
});
test('# foreslår et projekt, og titlen følger den første linje', 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('Forslagsprojektet');
await sidebar.getByLabel('Projektnavn').press('Enter');
await expect(sidebar.getByRole('link', { name: 'Forslagsprojektet' })).toBeVisible();
await sidebar.getByRole('link', { name: 'Noter', exact: true }).click();
await page.getByRole('button', { name: 'Ny note' }).click();
const ed = page.getByRole('textbox', { name: 'Notens tekst' });
await ed.click();
await page.keyboard.type('Første udkast');
await page.keyboard.press('Enter');
// Half a tag is enough. The name is long and nobody should have to spell it.
await page.keyboard.type('Handler om #Forslags');
const option = page.getByRole('option', { name: /Forslagsprojektet/ }).first();
await expect(option).toBeVisible();
// Return takes the highlighted one — the list owns the key while it is open.
await page.keyboard.press('Enter');
await expect(ed).toContainText('#Forslagsprojektet');
await expect(option).toBeHidden();
// And the syntax is spelled out under the field, where it is being typed.
await expect(page.getByText('projekt', { exact: false }).first()).toBeVisible();
// The title is the first line. It used to be derived once and then left alone,
// so rewriting the opening left the list calling the note by an old name.
await page.keyboard.press('Enter');
await ed.blur();
await expect(page.getByRole('button', { name: /Første udkast/ })).toBeVisible();
// Rewrite the first line; the list has to follow.
await ed.click();
await page.keyboard.press('ControlOrMeta+Home');
for (let i = 0; i < 13; i++) await page.keyboard.press('Shift+ArrowRight');
await page.keyboard.type('Andet udkast');
await ed.blur();
await expect(page.getByRole('button', { name: /Andet udkast/ })).toBeVisible();
expect(trouble).toEqual([]);
});