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.
Tooltips on relative dates (and other content) were invisible when a task
was opened in the modal. The modal uses <dialog> opened via showModal(),
which places it in the browser's top layer. floating-vue teleports
tooltips to <body> by default, so they were rendered *below* the dialog
backdrop and hidden behind it.
Wrap the v-tooltip directive to detect the nearest <dialog> ancestor of
the target and use it as the tooltip's container, keeping the tooltip in
the same top-layer context as the modal it belongs to. Tooltips outside
any dialog still teleport to <body> as before.
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.
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.
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.
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.
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.
Removes the `service.enablebotusers` config flag, the matching
`bot_users_enabled` field on /info, and the now-unused
`ErrBotUsersDisabled` error. Bot user routes and the frontend
settings tab are now always available.
https://claude.ai/code/session_01VhAR6xnoCdG1fpX52bzaCC
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.
Stylelint 17.9.0 resolves customSyntax modules relative to the
stylelint package, so the transitive postcss-html pulled in via
stylelint-config-recommended-vue is no longer reachable and lint
fails with "Could not find postcss-html".
During E2E testing with Playwright (via `mage test:e2e`), the frontend is built using Vite with `--mode development`. However, Vite hardcodes `process.env.NODE_ENV` to `production` during the build step, which causes `import.meta.env.DEV` to statically evaluate to `false`.
Because the `v-cy` custom testing directive relied on the `DEV` flag, it silently evaluated to false and failed to render the `data-cy` attributes into the DOM during the test build. This caused test failures because Playwright could not locate the elements.
Changing the check to explicitly evaluate `import.meta.env.MODE === 'development'` successfully bypasses the Vite build behavior, ensuring that `data-cy` testing attributes are consistently rendered during E2E tests.
For more context on Vite's build behavior regarding `DEV` and development mode, see:
https://github.com/vitejs/vite/discussions/14083
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.
Remove 47 keys from frontend/src/i18n/lang/en.json that are not
referenced by any $t / t / i18n.t / i18n.global.t / tc / <i18n-t>
call site, nor by any stored-as-literal dynamic lookup pattern.
The keys fall into a few broad groups: leftover attribute labels on
filter and label models, dropped editor toolbar entries, unused
password/password-confirmation copy, and a handful of stale admin and
migration strings. The sibling translation files will be reconciled on
the next Crowdin sync.