Commit Graph

14441 Commits

Author SHA1 Message Date
renovate[bot] c72cfdf50d chore(deps): update dev-dependencies 2026-06-28 12:46:39 +00:00
renovate[bot] c6b3c7cddc fix(deps): update module github.com/arran4/golang-ical to v0.3.5 2026-06-28 12:10:52 +00:00
renovate[bot] 12952516cf fix(deps): update dependency ufo to v1.6.4 2026-06-28 12:10:14 +00:00
renovate[bot] 9946ca9031 fix(deps): update dependency nanoid to v5.1.16 2026-06-28 12:10:03 +00:00
renovate[bot] a73761f4c5 fix(deps): update dependency sortablejs to v1.15.7 2026-06-28 09:08:08 +00:00
renovate[bot] ac9811826e fix(deps): update dependency marked to v17.0.6 2026-06-28 09:07:29 +00:00
renovate[bot] 0369b61001 fix(deps): update dependency dayjs to v1.11.21 2026-06-28 09:07:12 +00:00
renovate[bot] 59da1d9514 fix(deps): update dependency @floating-ui/dom to v1.7.6 2026-06-28 09:06:49 +00:00
renovate[bot] d374c8e6f9 chore(deps): update actions/checkout action to v7 2026-06-28 09:06:15 +00:00
renovate[bot] aa8c5974ae chore(deps): update node.js to cd6fb7e 2026-06-28 09:05:56 +00:00
Frederick [Bot] 0dba563a03 chore(i18n): update translations via Crowdin 2026-06-28 00:29:43 +00:00
renovate[bot] dab2ac473f chore(deps): update postgres:18 docker digest to 4aabea7 2026-06-27 19:40:01 +00:00
renovate[bot] 57b6d530f3 chore(deps): update ghcr.io/techknowlogick/xgo:go-1.25.x docker digest to 57c6285 2026-06-27 19:39:40 +00:00
renovate[bot] ba5c09f962 chore(deps): update actions/cache action to v6 2026-06-27 19:39:18 +00:00
renovate[bot] eed762097a fix(deps): update tiptap to v3.27.1 2026-06-27 19:39:07 +00:00
renovate[bot] f6baa7d472 chore(deps): update docker/dockerfile:1 docker digest to 87999aa 2026-06-27 19:38:32 +00:00
renovate[bot] 07d39b4290 chore(deps): pin dependencies 2026-06-27 18:01:23 +00:00
karl Einziger 0efae572cd fix(auth): use binddn as group sync dn instead of userbind 2026-06-27 15:12:10 +00:00
kolaente 9e880e98a5 fix(api): export api-token permission groups in snake_case
The api-token permission group key is derived from the route slug. Every
group is snake_case except "time-entries", whose URL slug carries a hyphen.
The frontend snake_cases request payloads, rewriting that group key to
"time_entries", which the backend then rejected — so a token granted the
Time Entries scope could not be saved.

Canonicalise group and path-segment names to snake_case where they are
derived, and normalise the group key on token validation and authorisation
so any token stored under the old hyphenated key keeps resolving. No data
migration is needed: the v2 time-entries resource has never shipped in a
release.
2026-06-27 15:01:54 +00:00
kolaente e25ca7ab9a fix: don't re-login after logout when OIDC auto-redirect is enabled
Set the just-logged-out flag before navigating, and skip the intermediate
router.push to login when redirecting to the IdP — otherwise Login.vue's
onBeforeMount consumed the flag before the logout round-trip landed, so the
single-provider auto-redirect fired and logged the user straight back in.

redirectToProviderOnLogout now reports whether it navigated, so logout can fall through to the login page when there's no static logout URL.
2026-06-27 14:20:05 +00:00
kolaente 18ee92f227 feat: auto-redirect to OIDC provider on login when it's the only option 2026-06-27 14:20:05 +00:00
kolaente 96452f0b71 fix(desktop): set the main window icon on Linux
On X11/XWayland (Electron's default on Wayland sessions) the window had no
icon, so KDE Plasma showed the generic placeholder. Point BrowserWindow at
the packaged icon.png so the compositor has an icon to render.
2026-06-27 14:12:10 +00:00
kolaente 3f8ce93636 fix(desktop): show hidden window when relaunched from tray
When the app is hidden in the tray, closing then relaunching it triggered
the single-instance second-instance handler, which only called focus() — a
hidden window stays hidden on focus(), so the app appeared not to start
(notably on KDE Plasma Wayland where the tray icon may also be unreachable).
Call show() to surface it, and recreate the window if it no longer exists.
2026-06-27 14:12:10 +00:00
kolaente 626e1e267e fix(desktop): quit on SIGTERM and SIGINT
The desktop app ignored termination signals because the tray and embedded
express server keep the Electron event loop alive, forcing users to kill -9
on logout/shutdown. Add SIGINT/SIGTERM handlers that set isQuitting before
app.quit() so the hide-to-tray close handler doesn't swallow the quit.
2026-06-27 14:12:10 +00:00
BlackFuffey f18813f3ff feat(projects): make gantt chart zoom in if there are space available 2026-06-27 13:44:03 +00:00
gabe f7ac69d01a feat(filters): translate My Open Tasks title in frontend 2026-06-27 13:35:50 +00:00
gabe 98b3613247 feat(filters): generate open task saved filter on user creation 2026-06-27 13:35:50 +00:00
kolaente 18a0df505b
fix(deps): bump desktop undici to patched versions
node-gyp's undici 6.26.0 -> 6.27.0 and @electron/get's 7.27.2 -> 7.28.0,
each pinned within its major via overrides so only the security patch is
taken (an open >= range would jump across majors, e.g. to undici 8).

Resolves the 9 open desktop undici Dependabot alerts.
2026-06-27 14:34:20 +02:00
kolaente 7b5b8ecad2
chore(dev): remove leftover .envrc
Now handled directly by devenv
2026-06-27 14:26:28 +02:00
kolaente 4b18d08993
chore(dev): move devcontainer config to .devcontainer/ directory
Newer devenv generates the devcontainer config at .devcontainer/devcontainer.json
instead of the legacy root-level .devcontainer.json, which left an untracked
duplicate. Track the new path so regeneration is a no-op.
2026-06-27 14:25:45 +02:00
kolaente 7c9b9e3352
chore(deps): update devenv 2026-06-27 14:25:44 +02:00
kolaente 08890895de fix(task): don't drop the list-view done save during the check animation
Marking a task done via the list-view checkbox deferred the entire update
— including the network request — by 300ms to play the check animation. If
the page was torn down within that window (a refresh, tab close, or leaving
the app), the request was never sent and the save was silently lost. For
repeating tasks this is especially confusing: the due date never advances,
yet the checkbox un-checks itself anyway, so the failure looks identical to
success.

Fire the request immediately with the intended done value snapshotted, and
defer only the animation-coupled follow-up (result swap, pop sound, toast).
The optimistic v-model state already drives the check animation during the
300ms, so nothing visual is lost.
2026-06-27 12:01:51 +00:00
kolaente 330b94c3c4 feat(migration): import recurring tasks from todoist 2026-06-26 13:32:08 +00:00
kolaente 7691f282cf fix(veans): preserve unsent task fields on update via PATCH (#2962)
The v1 update was a whole-object POST /tasks/{id}: omitted scalars were
zeroed, so a status-only `veans update` silently wiped a task's
description and priority. The v1->v2 migration replaced that with
PATCH /tasks/{id} carrying a JSON Merge Patch built from only the
changed fields (client.TaskPatch, all-pointer + omitempty), which fixes
this by construction — absent fields are left untouched server-side.

Pin it with the acceptance tests from the issue: a title-only and a
status-only update must send only the field(s) they change, so the
stored description and priority survive.
2026-06-26 11:23:14 +00:00
kolaente 6cee626383 refactor(veans): migrate API client from v1 to v2
veans is unreleased and targets bleeding-edge Vikunja, so the CLI now
speaks the Huma-backed /api/v2 exclusively (v1 is frozen and the kanban
bucket CRUD veans relies on only exists on v2).

- Transport: base path /api/v1 -> /api/v2 in Do/DoRaw; add a
  content-type-aware path (DoMerge for application/merge-patch+json).
- Pagination: drop the x-pagination-total-pages header reader; every v2
  list returns the {items,total,page,per_page,total_pages} envelope.
  Decode it with a generic Paginated[T]/doList[T] and page until
  page >= total_pages. Previously-single-GET lists (views, buckets,
  comments, bots) are enveloped too — unwrap .items.
- Verbs: creates flip PUT -> POST (projects, labels, tokens, bot users,
  shares, task create, comments, relations, assignees, label-attach,
  bucket create); the bucket-task move flips POST -> PUT with a bare
  {"task_id":N} body (URL owns project/view/bucket); task update moves
  to PATCH merge-patch with a partial body.
- Errors: parse the RFC 9457 problem+json body (detail/title/code)
  instead of v1's {code,message}; the status -> output.Code mapping is
  unchanged.
- Discovery probes /api/v2/info, which doubles as the "new enough" check.
- Label search param s -> q; add views_buckets_tasks_put to the bot's
  projects scope so the move is authorized regardless of route-init order.

Tests and the veans agent guide are updated for the new paths, verbs and
envelope. Verified end-to-end against a local v2 server: init, create,
show, list, claim, update and prime all work.
2026-06-26 11:23:14 +00:00
kolaente 0d043e80e4 feat(api/v2): add kanban bucket CRUD endpoints
Port the standalone bucket list/create/update/delete from v1 to the
Huma-backed /api/v2, under /projects/{project}/views/{view}/buckets,
using v2 verb conventions (POST creates, PUT updates). The handlers
reuse the generic handler.Do* functions, so permissions are enforced
by the Bucket model's existing Can* methods.

Mirrors v1: no read-one route (the model has no ReadOne/CanRead), so
AutoPatch synthesises no PATCH. No model changes.
2026-06-26 08:56:15 +00:00
Frederick [Bot] 9390199ce0 chore(i18n): update translations via Crowdin 2026-06-26 00:32:25 +00:00
Bradley Erickson f8eacca7c8 fix(auth): allow api tokens to access global v2 task list endpoint
The tasks.read_all special case in CanDoAPIRoute only covered v1 paths.
Both GET /api/v2/tasks and GET /api/v2/projects/:project/tasks normalize
to the same tasks.read_all map key, but only one RouteDetail survives —
the project-scoped path overwrites the global one. The exact path
comparison then rejects the global endpoint with 401.

Extend the special case to include the v2 paths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-24 17:49:02 +00:00
renovate[bot] 7a182817ee chore(deps): update dev-dependencies 2026-06-24 17:37:15 +00:00
Frederick [Bot] aaa2428f6c chore(i18n): update translations via Crowdin 2026-06-24 00:26:43 +00:00
renovate[bot] 0f3a8a7e39 chore(deps): update dev-dependencies 2026-06-22 12:33:44 +00:00
Tink f4bbe80144
fix(auth): dedupe and retry token refresh to prevent spurious logouts (#2948) 2026-06-21 18:22:30 +02:00
Frederick [Bot] 02d46944ac chore(i18n): update translations via Crowdin 2026-06-21 00:33:22 +00:00
kolaente 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
kolaente 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
Tink 82dae774f1
fix(views): persist list/table sort across sidebar navigation (#2778) 2026-06-19 22:08:06 +02:00
kolaente 63b7f32379 fix(editor): render floating popups inside the task dialog (Kanban popup)
The Kanban task detail opens as a native <dialog> via showModal(), which
paints in the browser top-layer. Floating UI appended to document.body
(or teleported to <body>) then renders behind the dialog regardless of
z-index, matching the bug class of #2940 / #1746 / #1899 / #1929.

- Emoji autocomplete popup: append to getPopupContainer(editor) (the open
  dialog ancestor, else body), the same helper the slash menu and mentions
  already use. Also switch its unmount to popupElement.remove() so it works
  no matter which container it was appended to.
- Attachment dropzone overlay: teleport into the topmost open
  dialog.modal-dialog instead of always <body>, mirroring Notification.vue,
  so the drag-and-drop hint is visible while a task detail dialog is open.
2026-06-19 19:03:20 +00:00
Tink 81791fd346
fix(auth): link OIDC username fallback on preferred_username, not just sub (#2945) 2026-06-19 20:47:05 +02:00
Tink b6af132845
fix(auth): preserve desktop authorize URL when not signed in (#2944) 2026-06-19 19:50:47 +02:00
renovate[bot] ab927aa772 chore(deps): update dev-dependencies to v4.62.2 2026-06-19 17:32:00 +00:00