108 Commits
Author SHA1 Message Date
kolaente e31ea2de50 test(e2e): seed hashed user tokens in TokenFactory (GHSA-r6w9-259g-gwrv)
Reset/confirm/deletion tokens (kinds 1-3) are now stored as a SHA-256 hash and
looked up by hash, so the e2e factory must seed the hash while returning the
plaintext to the test. Kind 4 (caldav/bcrypt) is seeded verbatim.
2026-07-19 18:59:34 +02:00
kolaenteandkolaente 37c35c64fb fix(a11y): make the editor toolbar a single tab stop with roving focus
role=toolbar with a roving tabindex: Arrow keys move between buttons,
one Tab stop, Tab leaves the toolbar, and the tab stop stays valid when
buttons become disabled. Covered by an e2e keyboard-navigation spec.

Also fixes the table-edit :disabled bindings, which referenced
editor.can().X as a property (always truthy) so those buttons never
actually disabled — surfaced by review while testing the roving focus.

Claude-Session: https://claude.ai/code/session_018prq5WqRL38EGhPNQKqZUP
2026-07-19 15:36:05 +00:00
kolaenteandkolaente 5495043861 feat(editor): prompt for alt text when inserting an image
Opens the existing alt-text prompt right after an image is inserted
(upload, paste and URL flows) so every new image gets a description.
Cancelling leaves the image without alt text, and the node is deselected
afterwards so the next insert appends instead of replacing.

Claude-Session: https://claude.ai/code/session_018prq5WqRL38EGhPNQKqZUP
2026-07-19 15:36:05 +00:00
kolaenteandkolaente 878d389587 fix(a11y): un-nest the attachment rows
Each attachment row was a button containing the download, copy-URL,
delete and set-cover buttons — interactive elements nested inside an
interactive element, which is invalid and confuses assistive-technology
focus (axe: nested-interactive). The row is now a non-interactive
container: the filename (and thumbnail) is the trigger that opens or
downloads the attachment, and the action buttons are its siblings.

Claude-Session: https://claude.ai/code/session_018prq5WqRL38EGhPNQKqZUP
2026-07-19 15:36:05 +00:00
TinkandGitHub 60a09f2088 fix(a11y): contrast tokens, empty-title feedback, structure and landmarks (#3234) 2026-07-19 15:15:10 +02:00
TinkandGitHub b5f34ff7da fix(labels): explain why link-share users can't create labels (#3233) 2026-07-19 14:45:37 +02:00
TinkandGitHub 5c2bb6bd2d fix(quick-add): don't abort task creation when a label can't be created (#3232) 2026-07-19 14:45:24 +02:00
TinkandGitHub 45fada10d6 feat(editor): allow setting image alt text (#3206) 2026-07-18 14:39:51 +02:00
TinkandGitHub 4425e0d146 fix(attachments): keep blob mime type so pdf previews open inline (#3157) 2026-07-11 18:53:09 +02:00
kolaenteandkolaente c689887fca chore(deps): update low-risk dev-dependency majors
Bumps independent dev-dependency majors split out of the bundled
renovate PR #3046:

- otplib 12.0.1 -> 13.4.1 (v13 is a rewrite: the `authenticator`
  singleton was removed in favour of the functional API; the only
  consumer is the TOTP e2e test, migrated to `await generate({secret})`)
- rollup-plugin-visualizer 6.0.11 -> 7.0.1
- stylelint-config-property-sort-order-smacss 10.0.0 -> 11.2.0
- @sentry/vite-plugin 3.6.1 -> 5.3.0 (no peer-dep coupling to vite)

Claude-Session: https://claude.ai/code/session_01AHD9BmNcUfgBZdPveZRa8z
2026-07-02 06:30:02 +00:00
kolaenteandkolaente 0e17556a16 fix(editor): make link prompt a sub-modal — Escape cancels it without closing the task dialog
Review point (#2950, comment 3444116036): when the surrounding task
<dialog> closed while the link prompt was open, the prompt was orphaned
and cleanup() never ran, leaking listeners and an unresolved promise.

Treat the prompt as a sub-modal of the task dialog: pressing Escape while
it is open now preventDefault()/stopPropagation()s the keydown so the
native modal <dialog> does not close on Escape, resolves the prompt with
'' (cancel) and runs cleanup() — only the prompt is dismissed, the task
dialog stays open. A one-shot 'cancel' listener on the enclosing dialog
backs this up in case the keydown handling is insufficient in some browser.

Tighten cleanup() so the prompt fully tears down regardless of how it
closes (Enter / Escape / click-outside): it now removes the scroll
listener, the document click listener and the dialog cancel listener, and
removes the element. handleClickOutside was hoisted so cleanup() can
remove it, closing the leaked-listener gap directly.

Adds an e2e asserting Escape cancels the prompt while the task dialog
stays open; the existing 'Enter creates the link' case still passes.
2026-06-19 20:14:19 +00:00
kolaenteandkolaente 84dc57c562 fix(editor): render link prompt inside the task dialog so it works in the Kanban popup (#2940)
The Kanban task popup renders the description editor inside a native
<dialog> opened via showModal(), which lives in the browser's top-layer.
inputPrompt appended its URL <input> to document.body, so it was painted
behind the top-layer dialog (z-index cannot beat the top-layer) and could
not be focused through the dialog's focus trap. As a result clicking "Link"
in the popup did nothing, while it worked on the full task page (no modal).

Thread the TipTap editor through inputPrompt and append the prompt to
getPopupContainer(editor) — the open dialog ancestor when present, falling
back to document.body otherwise, so non-modal usage is unchanged. This is
the same helper the slash menu and mentions already use to escape the
top-layer (#1746).

Fixes #2940
2026-06-19 20:14:19 +00:00
TinkandGitHub 82dae774f1 fix(views): persist list/table sort across sidebar navigation (#2778) 2026-06-19 22:08:06 +02:00
TinkandGitHub b6af132845 fix(auth): preserve desktop authorize URL when not signed in (#2944) 2026-06-19 19:50:47 +02:00
kolaenteandkolaente 4390af4773 test(time-tracking): add end-to-end coverage 2026-06-08 13:54:09 +00:00
kolaenteandkolaente d417a30802 test(e2e): cover comment replies end-to-end
Drives the reply flow through the browser: existing comment is
quoted via the Reply action, the prefilled blockquote round-trips
to the saved reply, the chevron jumps back to the original and
applies the brief highlight.
2026-05-20 21:02:14 +00:00
Tink botandkolaente f495a792b2 feat(frontend): apply quick add magic when creating related tasks
Route the create flow through taskStore.createNewTask so titles typed
into the related-task input get parsed for labels, priority, assignees,
due dates and cross-project targets - matching the main add-task input.
Also surface the quick-add-magic hint next to the field.
2026-05-11 21:21:11 +00:00
Xelaandkolaente 5cfb03a29e test(e2e): use ISOString for date seeding to prevent timezone parsing errors 2026-04-24 11:24:34 +02:00
Xelaandkolaente d2cac283c7 test(user): add tests for updating week start day and verifying date picker behavior 2026-04-24 11:24:34 +02:00
kolaenteandkolaente 6f85a7fb6b feat(a11y): fix heading hierarchy across pages
- Home: greeting H2 → H1 (page needs a top-level heading)
- Task detail: task ID H1 → span (only title should be H1)
- Task detail: H6 breadcrumb → nav element
- App header: project title H1 → span (avoids duplicate H1)

Fixes WCAG 1.3.1 (Info and Relationships) and 2.4.6 (Headings).
2026-04-21 11:44:36 +00:00
kolaenteandkolaente b90e67d7ca test(e2e): await DELETE in caldav token revoke test to avoid race 2026-04-21 10:50:09 +00:00
kolaenteandkolaente be28ec70d8 test(e2e): await DELETE in session revoke test to avoid race 2026-04-21 10:50:09 +00:00
kolaenteandkolaente c0101afb59 test(e2e): widen recurrence due-date tolerance to 5s
CI shard 4 hit a ~996ms skew between the JS-constructed originalDue and
the backend's advanced due date, enough to bust the <500ms precision
bound. Bump precision to -4 (<5s) — still tight enough to confirm the
regeneration advanced by ~1 day, loose enough to absorb sub-second
round-tripping through Date → ISO → Go time.Time → JSON.
2026-04-21 10:50:09 +00:00
kolaenteandkolaente c3b86b2102 test(e2e): cover link share permission tiers 2026-04-21 10:50:09 +00:00
kolaenteandkolaente 17e0dde7d3 test(e2e): cover link share password protection 2026-04-21 10:50:09 +00:00
kolaenteandkolaente 19d3b9c4bb test(e2e): cover team share revocation 2026-04-21 10:50:09 +00:00
kolaenteandkolaente f20267164f test(e2e): cover team READ_WRITE permission 2026-04-21 10:50:09 +00:00
kolaenteandkolaente be225fd4d3 test(e2e): cover team READ permission boundary 2026-04-21 10:50:09 +00:00
kolaenteandkolaente 01b71577d7 test(e2e): add TeamProjectFactory 2026-04-21 10:50:09 +00:00
kolaenteandkolaente 268c5daf8b test(e2e): drop unused authenticatedPage from recurrence beforeEach 2026-04-21 10:50:09 +00:00
kolaenteandkolaente 37d7f90acf test(e2e): cover monthly repeat mode UI 2026-04-21 10:50:09 +00:00
kolaenteandkolaente 637d810ff7 test(e2e): assert recurring task regenerates on complete 2026-04-21 10:50:09 +00:00
kolaenteandkolaente c93f644363 test(e2e): cover recurrence preset buttons 2026-04-21 10:50:09 +00:00
kolaenteandkolaente f2eee5d8a1 test(e2e): assert readers cannot delete attachments 2026-04-21 10:50:09 +00:00
kolaenteandkolaente 05432d3993 test(e2e): cover attachment deletion 2026-04-21 10:50:09 +00:00
kolaenteandkolaente db634093e0 test(e2e): drop unused authenticatedPage from webhooks beforeEach 2026-04-21 10:50:09 +00:00
kolaenteandkolaente 425889b879 test(e2e): create and delete a webhook 2026-04-21 10:50:09 +00:00
kolaenteandkolaente 5a93149849 test(e2e): require at least one webhook event 2026-04-21 10:50:09 +00:00
kolaenteandkolaente 2f2aafadfd test(e2e): validate webhook target url 2026-04-21 10:50:09 +00:00
kolaenteandkolaente 8bcdc314b1 test(e2e): cover data export request flow 2026-04-21 10:50:09 +00:00
kolaenteandkolaente a9f8fbaba8 test(e2e): cover scheduled deletion cancel flow 2026-04-21 10:50:09 +00:00
kolaenteandkolaente 2a5e4f2b84 test(e2e): cover account deletion request flow 2026-04-21 10:50:09 +00:00
kolaenteandkolaente 0902c009f6 test(e2e): assert current session has no delete control 2026-04-21 10:50:09 +00:00
kolaenteandkolaente 76055b622b test(e2e): assert session delete breaks refresh 2026-04-21 10:50:09 +00:00
kolaenteandkolaente cf9d0a26ab test(e2e): cover sessions list with current marker 2026-04-21 10:50:09 +00:00
kolaenteandkolaente 7145440fe6 test(e2e): assert wrong password blocks email change 2026-04-21 10:50:09 +00:00
kolaenteandkolaente 3dfbcae4d5 test(e2e): cover caldav token deletion 2026-04-21 10:50:09 +00:00
kolaenteandkolaente cd9d2a2245 test(e2e): cover caldav token creation end-to-end 2026-04-21 10:50:09 +00:00
kolaenteandkolaente 912d6a134f test(e2e): assert wrong TOTP passcode is rejected 2026-04-21 10:50:09 +00:00
kolaenteandkolaente 96685fdc5b test(e2e): cover TOTP disable flow 2026-04-21 10:50:09 +00:00