diff --git a/web/e2e/smoke.spec.js b/web/e2e/smoke.spec.js index b8c717a..ecc2ac5 100644 --- a/web/e2e/smoke.spec.js +++ b/web/e2e/smoke.spec.js @@ -86,6 +86,29 @@ test('hurtig tilføjelse opretter en opgave, og den kan lukkes', async ({ page } expect(trouble).toEqual([]); }); +test('en URL i en opgave bliver et klikbart link, og resten åbner opgaven', async ({ page }) => { + const trouble = watchForTrouble(page); + await page.goto('/'); + + const box = page.getByLabel('Ny opgave'); + // The URL is one token, so the parser leaves it in the title; "i dag" is what it + // takes. The link is made at display time — the stored title is still plain text. + await box.fill('læs https://example.com/artikel i dag'); + await box.press('Enter'); + + const row = page.locator('.row').filter({ hasText: 'læs' }); + const link = row.getByRole('link', { name: 'https://example.com/artikel' }); + await expect(link).toHaveAttribute('href', 'https://example.com/artikel'); + await expect(link).toHaveAttribute('rel', /noopener/); + + // Clicking anywhere but the link still opens the task — the open-overlay sits + // behind the text, the link above it. + await row.getByRole('button', { name: /læs https/ }).click(); + await expect(page.getByRole('complementary', { name: 'Opgave' })).toBeVisible(); + + expect(trouble).toEqual([]); +}); + test('hvert link i sidebjælken fører et sted hen', async ({ page }) => { const trouble = watchForTrouble(page); await page.goto('/'); diff --git a/web/src/lib/components/TaskRow.svelte b/web/src/lib/components/TaskRow.svelte index 10d1c52..04ba0cc 100644 --- a/web/src/lib/components/TaskRow.svelte +++ b/web/src/lib/components/TaskRow.svelte @@ -11,6 +11,7 @@ import { app } from '$lib/stores.svelte.js'; import { t, tag } from '$lib/i18n.svelte.js'; import { repeatLabel } from '$lib/when.js'; + import { linkify } from '$lib/linkify.js'; let { task, onedit } = $props(); @@ -99,13 +100,38 @@ - - + + {#each linkify(task.content) as run}{#if run.href}{run.text}{:else}{run.text}{/if}{/each} {#if task.description} - {task.description} + {#each linkify(task.description) as run}{#if run.href}{run.text}{:else}{run.text}{/if}{/each} {/if} {#if assignee || due || task.labels?.length || repeats || task.subtask_count || task.attachment_count} @@ -186,7 +212,7 @@ {/each} {/if} - +