Commit Graph

887 Commits

Author SHA1 Message Date
kolaente 46dbeb5784 feat(editor): preserve comment-id on blockquotes
Extend the default Blockquote with a `commentId` attribute that
round-trips through HTML as `data-comment-id`. This single attribute
is the canonical record of a reply: it survives TipTap serialize /
parse so the backend listener and the in-app renderer can both find
the parent comment without a separate schema field.
2026-05-20 21:02:14 +00:00
kolaente 4351ebf411
fix(print): hide reaction create button 2026-05-20 17:58:58 +02:00
kolaente 995aad3d53
fix(print): hide description editor when no description is present 2026-05-20 17:58:13 +02:00
kolaente bc7c2059aa
fix(print): hide bucket select icon 2026-05-20 17:54:15 +02:00
kolaente 612628a657
fix(modal): print full content of modal dialogs
A <dialog> opened via showModal() lives in the browser's top layer, which
renders only on the first page during print — top-layer elements are
viewport-anchored and don't paginate. CSS overrides like position: static
have no effect since top-layer membership is browser-managed.

Swap to a non-modal dialog on beforeprint (removes it from the top layer
so content flows in normal document order) and back to modal on
afterprint. The accompanying @media print rules reset the dialog's fixed
positioning and overflow so the non-modal dialog can paginate freely.
2026-05-20 17:53:01 +02:00
kolaente 44db02ab56
fix(task): print styles 2026-05-20 17:39:11 +02:00
Tink bot 3c048223c3 feat(filters): add Tomorrow option to date range dropdown
Closes #2734
2026-05-19 09:01:46 +00:00
Tink bot a79517a79a fix(frontend): prevent avatar layout shift while loading
The .avatar img in User.vue relied solely on the width/height HTML
attributes for sizing. Those are presentational hints with zero CSS
specificity, so Bulma's global reset (img { height: auto; max-width: 100% })
overrode them. While avatarSrc was still resolving (initial src=""),
the browser had no intrinsic dimensions to compute the auto height from
and fell back to the broken-image box (~96px in Chrome), then snapped
to the real size once the blob URL loaded.

Set inline-size/block-size explicitly via a CSS custom property bound
to the avatarSize prop so the rendered size is locked regardless of
load state or the Bulma reset.
2026-05-18 19:13:36 +00:00
kolaente dbccbd64ef
fix(relations): correctly position quick add magic hint (#2766) 2026-05-18 13:23:43 +02:00
bradmartin333 4a16df8af1 fix(frontend): ensure text color inherits in filter autocomplete component 2026-05-17 15:03:50 +00:00
kolaente b9e3bb95fa
feat(frontend): add Atom feed settings page and notifications discovery (#2760) 2026-05-15 19:28:29 +02:00
Tink bot 2ad7efb669 fix(kanban): prevent task taps from leaking through the sticky add-task footer on touch devices
The sticky bucket footer had no z-index, so the absolutely positioned
`.handle` overlays on each task (z-index: 1, used to capture taps on
touch devices) stacked above the Add Task button. Tapping the button
where a task scrolled behind it would open that task instead of opening
the new-task input.
2026-05-15 10:27:38 +00:00
Tink bot 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
kolaente 3d594db725 fix(frontend): scope checkbox hit-area pseudo to the task row
The pseudo-element that extends the checkbox hit target also covered
label text content, which broke Playwright actionability checks for
clicks on text inside wider FancyCheckbox labels (e.g. the "Show
Archived" toggle on the projects list page).

Move the rule out of BaseCheckbox and into SingleTaskInProject's deep
override, where the label slot is already hidden via display: none, so
no neighboring content can be intercepted.
2026-05-05 15:42:10 +00:00
kolaente 9bea92bb6f fix(frontend): skip task detail on label and checkbox clicks
Defense in depth for the list-view row click handler: a click that
lands on a label or checkbox input no longer bubbles up to open the
task detail.
2026-05-05 15:42:10 +00:00
kolaente 1ea5675e1b fix(frontend): extend checkbox hit target to 44x44
A pseudo-element on the label provides a 44x44 minimum hit area
centered on the visible icon. Visible size and surrounding layout
are unchanged. Addresses misclicks on the task list view checkbox
where ~50% of taps would open the task detail instead of toggling
done.
2026-05-05 15:42:10 +00:00
kolaente 469ee8f364 fix(frontend): respect user's 12h/24h time format in date pickers
The flatpickr time inputs hardcoded `time_24hr: true`, so users who
selected the 12-hour format in their settings still got a 24-hour
picker — even though the displayed dates respected the preference.

Bind `time_24hr` to the existing `useTimeFormat` composable in:
- DatepickerInline (start/end/due dates and absolute reminders)
- DeferTask (defer due date)
- ApiTokenForm (API token expiry)

Reported at https://community.vikunja.io/t/4492.
2026-05-05 14:47:24 +00:00
kolaente 459dbe71ca
Improve modal responsive sizing with inline-size constraints (#2716) 2026-05-04 15:33:59 +02:00
kolaente d467a06e72 feat(frontend): add bot settings page and services 2026-05-01 14:44:10 +00:00
kolaente c4e5f55b6d feat(frontend): add bot user model support and badge 2026-05-01 14:44:10 +00:00
Claude 01fff665c6 fix(frontend): focus quick actions input after modal opens
The Modal mounts the <dialog> via v-if and calls showModal() in a
follow-up flush, so v-focus runs while the dialog is still closed and
its focus() call is dropped. The existing rAF retry was gated on
quick-add mode, leaving Ctrl+K in the regular app with no focused
input. Run the retry whenever the quick actions become active and keep
the command pre-selection scoped to quick-add mode.
2026-04-30 14:06:07 +00:00
Timh e97b629d6c feat: support filter_include_nulls in project view configuration 2026-04-28 14:16:51 +00:00
Cristian Ivascu 67ad31c9c8
fix(webhook): use same casing for basic auth fields (#2688) 2026-04-24 11:20:07 +02:00
Claude 6bf586e928 fix(tasks): disable task glance tooltip on touch devices
Mouse event emulation from taps on touch devices caused the glance
tooltip to appear unexpectedly with no reliable way to dismiss it.
Gate the tooltip behind a `(hover: hover) and (pointer: fine)` media
query so it only activates on devices with a real pointer.
2026-04-24 08:52:44 +00:00
kolaente 2829a851df feat(a11y): associate errors with inputs in FormInput and FormSelect
Wire aria-invalid, aria-describedby and role=alert on the form
primitive components so errors raised directly on FormInput or
FormSelect are announced by assistive tech and programmatically
linked to the control.
2026-04-21 11:44:36 +00:00
kolaente fd1a329f5d feat(a11y): add descriptive labels to task checkboxes
Adds aria-label='Mark {task} as done' to task checkboxes so
screen readers can distinguish between them. Passes ariaLabel
prop through FancyCheckbox → BaseCheckbox → input.

Fixes WCAG 2.4.6 (Headings and Labels).
2026-04-21 11:44:36 +00:00
kolaente 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
kolaente c1f74ae9dc feat(a11y): add labels to color picker and sort select
Adds aria-label to the color input and sort select elements
so screen readers announce their purpose.

Fixes WCAG 3.3.2 (Labels or Instructions).
2026-04-21 11:44:36 +00:00
kolaente 4618f3491b feat(a11y): associate form errors with input fields
Adds aria-invalid, aria-describedby, and role='alert' to error
messages in FormField and Password components so screen readers
announce validation errors.

Fixes WCAG 3.3.1 (Error Identification).
2026-04-21 11:44:36 +00:00
kolaente a0d0379e95 feat(a11y): fix logo link accessible name to include 'Vikunja'
Changes aria-label from 'Overview' to 'Vikunja home' so the
accessible name includes the visible text.

Fixes WCAG 2.5.3 (Label in Name).
2026-04-21 11:44:36 +00:00
kolaente a34c247611 feat(a11y): use autocomplete='new-password' on register form
Adds autocomplete prop to Password component (defaults to
'current-password'). Register page passes 'new-password' so
password managers offer to generate a strong password.

Fixes WCAG 1.3.5 (Identify Input Purpose).
2026-04-21 11:44:36 +00:00
kolaente 21b7ae3f9f feat(a11y): add accessible names to modal dialogs
Passes aria-label to the <dialog> element via attribute inheritance
so screen readers announce the dialog's purpose.

Fixes WCAG 4.1.2 (Name, Role, Value).
2026-04-21 11:44:36 +00:00
kolaente 40ff558540 feat(a11y): add aria-live region to toast notifications
Adds role='status' and aria-live='polite' to the notification
container so screen readers announce status messages.

Fixes WCAG 4.1.3 (Status Messages).
2026-04-21 11:44:36 +00:00
kolaente 11ffb530be feat(a11y): add accessible names to icon-only buttons
Adds aria-label to sidebar toggle, mobile overlay, banner close,
modal close, quick actions close, task detail close, and dropdown
trigger buttons. Adds triggerLabel prop to Dropdown component.

Fixes WCAG 4.1.2 (Name, Role, Value).
2026-04-21 11:44:36 +00:00
kolaente 732b65ba7c feat(a11y): add skip navigation link and main landmark on auth pages
Adds a visually-hidden skip-to-content link as the first focusable
element. Adds id='main-content' to the <main> element. Changes
<section> to <main> on auth pages for proper landmark navigation.

Fixes WCAG 2.4.1 (Bypass Blocks).
2026-04-21 11:44:36 +00:00
kolaente f7dc50faf7 refactor(frontend): port checkbox-radio rules into FormCheckbox and drop Bulma import
The Bulma form/checkbox-radio partial only defined two selectors: .checkbox
(consumed exclusively by FormCheckbox.vue) and .radio (consumed by
ViewEditForm.vue and user/settings/Avatar.vue). Ports the %checkbox-radio
placeholder rules (cursor, line-height, position, hover/disabled states,
and the input cursor override) into FormCheckbox's scoped style for the
.checkbox side, and into scoped style blocks on the two remaining .radio
call-sites for the .radio side (including the 0.5em sibling margin via
margin-inline-start). Drops the now-unused @import. Pixel-perfect verified
on /login, /user/settings/general, and /user/settings/avatar: every
measured label/input getBoundingClientRect and computed style matches the
baseline exactly (0px deltas across all 5 sampled checkboxes and all 5
avatar radios).
2026-04-20 19:55:14 +00:00
kolaente db3f5d2daf feat(project): add before-delete slot to ProjectSettingsDropdown 2026-04-20 18:55:06 +00:00
kolaente c7b088ac18 feat(frontend): introduce TimeDisplay component 2026-04-20 18:55:06 +00:00
kolaente 7e4bf83fa0 refactor(frontend): extract SideNavShell for admin and user settings 2026-04-20 18:55:06 +00:00
kolaente 4e805d182a test(frontend): update form primitive tests for admin input usage 2026-04-20 18:55:06 +00:00
kolaente 7df5f127ca feat(admin): add frontend admin shell, views, services, and routes 2026-04-20 18:55:06 +00:00
MidoriKurage 2d2dbf67a0 fix(tasks): Let getCommentUrl handle frontendUrl including sub-path 2026-04-20 14:28:23 +00:00
kolaente b241c293d0 fix(frontend): restore tablet pagination layout (space-between + flex order)
The Bulma partial applied justify-content: space-between on .pagination and
flex-order 1/2/3 on prev/list/next inside a tablet media query under
.is-centered — the port missed both. Pixel-diff against main is now zero.
2026-04-20 10:38:08 +00:00
kolaente 8f64836999 refactor(frontend): extract PaginationItem to own pagination-link styling
BasePagination was reaching across slot boundaries with :deep() to style
.pagination-previous / -next / -link — markup it doesn't actually render.
Move that markup and the related scoped rules into a new PaginationItem
component that polymorphically renders RouterLink (when `to` is given)
or BaseButton (emit-based). BasePagination keeps only the scaffold it
actually owns: .pagination, .pagination-list, .pagination-ellipsis.

Pagination.vue and PaginationEmit.vue become thin wrappers around
BasePagination + PaginationItem; no more raw pagination-* class usage or
BaseButton imports in the emit wrapper.

The .app-container.has-background / .link-share-container.has-background
theme override moves with the .pagination-link rules into PaginationItem
as its own unscoped <style> block.

Result: 0 remaining :deep(.pagination-*) selectors (was 14).
2026-04-20 10:38:08 +00:00
kolaente 5ea7853dd6 refactor(frontend): port pagination rules into BasePagination and drop Bulma import
The Bulma components/pagination partial is only used by BasePagination
and its two wrappers (Pagination.vue, PaginationEmit.vue); no other
component renders raw .pagination-* markup. Ports the rules we actually
use (base layout, item sizing, hover/focus/disabled states, is-current
styling, mobile/tablet breakpoints) into BasePagination's scoped styles,
using :deep() to reach slotted children. The theme override for
.pagination-link on .has-background containers moves into an unscoped
style block on the same component. Drops the now-unused @import.
2026-04-20 10:38:08 +00:00
kolaente b9f6eabe2c refactor(frontend): use form primitives in WebhookManager 2026-04-17 12:54:17 +00:00
kolaente a6811a922a refactor(frontend): support two-col layout on FormField 2026-04-17 12:54:17 +00:00
kolaente 59e7c9bce3 feat(frontend): add FormCheckbox primitive component 2026-04-17 12:54:17 +00:00
kolaente 740546ee5a feat(frontend): add FormSelect primitive component 2026-04-17 12:54:17 +00:00
kolaente 875f685caf feat(frontend): add FormInput primitive component 2026-04-17 12:54:17 +00:00