Commit Graph

1497 Commits

Author SHA1 Message Date
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
kolaente 23c82bd5fa feat(frontend): expose isAdmin on current user and add config feature check 2026-04-20 18:55:06 +00:00
kolaente c9b3d4775c feat(admin): add typed models for admin users and overview 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
MidoriKurage 44122bfe6b fix(frontend/oidc): Prefix frontend base to redirect URL 2026-04-20 14:28:23 +00:00
MidoriKurage 7710e2549e fix(frontend): Fix hard-coded API base in checkAndSetApiUrl.ts 2026-04-20 14:28:23 +00:00
MidoriKurage e31c45c44e fix(frontend): Make sw.ts respect to frontend base URL 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
Frederick [Bot] 56aef03697 chore(i18n): update translations via Crowdin 2026-04-19 01:46:56 +00:00
Frederick [Bot] 9b46ad8ecc chore(i18n): update translations via Crowdin 2026-04-18 01:23:08 +00:00
kolaente 89af0a6c14 refactor(frontend): use FormCheckbox for remember-me on Login 2026-04-17 12:54:17 +00:00
kolaente b9f6eabe2c refactor(frontend): use form primitives in WebhookManager 2026-04-17 12:54:17 +00:00
kolaente cab970b59b refactor(frontend): use form primitives in user settings General view 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
kolaente 10e5fa915a refactor(frontend): drop Bulma components/navbar import
.navbar and .navbar-end are only used in AppHeader.vue. Ports the
relevant rules (z-index 30 and min-block-size: $navbar-height) into
its scoped <style> block and drops the partial import.
2026-04-17 07:43:35 +00:00
Tink 95ec3325c2
refactor(frontend): migrate .box to Card and drop Bulma elements/box (#2640) 2026-04-16 14:14:36 +02:00
Tink 19ee7f26ee
refactor(frontend): drop Bulma components/card import (#2639) 2026-04-16 14:12:36 +02:00
Frederick [Bot] 3120c2b12c chore(i18n): update translations via Crowdin 2026-04-16 01:46:56 +00:00
kolaente 50465818ae refactor(frontend): drop Bulma components/media import
The .media / .media-left / .media-content classes are only used in
Comments.vue. Ports the relevant rules into its scoped <style> block
and drops the partial import.
2026-04-15 20:15:42 +00:00
kolaente 3c3b1820a1 refactor(frontend): port is-pulled-right locally and drop Bulma float helper
Only .is-pulled-right is used (3 callsites); .is-pulled-left and
.is-clearfix from Bulma's helpers/float partial have zero usage. Ports the
one needed rule into theme/helpers.scss so the Bulma import can go.
2026-04-15 20:12:45 +00:00
kolaente d09ef36bd4 fix(frontend): guard Object.keys against null in refactored helpers
typeof null === 'object', so null slipped past the type guards in
objectToCamelCase/objectToSnakeCase/prepareParams. The original
for...in loops silently iterated nothing on null; Object.keys(null)
throws. Also guard saveCollapsedBucketState where state[projectId]
may be undefined.
2026-04-15 11:44:47 +00:00
kolaente dd83e0d42b refactor(frontend): replace reverse-index splice loops with findIndex/filter
Single-match removals use findIndex + splice; the reminder-null cleanup
uses filter since model.reminders is on a local shallow clone.
2026-04-15 11:44:47 +00:00
kolaente 2c6029eac4 refactor(frontend): replace for...in usages and forbid via lint rule
Replaces 33 for...in loops across 18 files with for...of + Object.keys/entries
or indexed for loops. for...in iterates enumerable string keys including
inherited ones, which is especially risky on reactive arrays (tasks, labels,
assignees, etc.) where polyfilled properties may appear.

Loops that mutate via splice during iteration now iterate backwards to avoid
index-shift bugs. Adds a no-restricted-syntax ESLint rule forbidding
ForInStatement to prevent regressions.

Closes #513
2026-04-15 11:44:47 +00:00
kolaente 95180a341d refactor(frontend): drop unused Bulma form/file partial import
Every file input in the codebase is hidden (via class="is-hidden" or
scoped display:none) and triggered programmatically by a custom XButton.
None of Bulma's .file / .file-label / .file-cta / .file-input / .file-name /
.file-icon classes are used anywhere in .vue files, so the partial is dead
code.
2026-04-15 11:06:11 +00:00
kolaente 39c804f460 refactor(frontend): drop unused Bulma modal partial import
Vikunja's Modal.vue uses a native <dialog> element with its own locally-
scoped classes (modal-dialog, modal-container, modal-content, modal-header).
None of Bulma's modal classes (.modal, .modal-background, .modal-card*) are
used anywhere in the app. The two CSS variables this partial provided
(--modal-card-head-padding, --modal-content-spacing-tablet) were inlined in
the two callers in the previous commits, so the whole partial is now dead
code.

Modal.vue already had several 'reset bulma' overrides fighting the default
rules Bulma applied to .modal-content; those can be cleaned up in a
follow-up.
2026-04-15 10:56:48 +00:00
kolaente d05fd4dbb2 refactor(frontend): inline modal-content-spacing-tablet in PDF preview
The --modal-content-spacing-tablet CSS variable is provided by Bulma's
components/modal partial. Inlining Bulma's default (40px) lets us drop that
partial.
2026-04-15 10:56:48 +00:00
kolaente 0b2f625f06 refactor(frontend): inline modal-card-head-padding in Card footer
The --modal-card-head-padding CSS variable is provided by Bulma's
components/modal partial. Inlining Bulma's default (20px) lets us drop that
partial without needing a local redeclaration.
2026-04-15 10:56:48 +00:00
kolaente 9899979ca7 docs(frontend): document styles architecture and token system 2026-04-15 10:02:39 +00:00
kolaente 21609127a1 fix(frontend): guard caldav and totp settings routes when disabled 2026-04-15 09:57:17 +00:00
kolaente 91d5cfb1c0 fix(frontend): render editor popups inside modal dialog top-layer
Native <dialog> elements opened with showModal() render in the browser's
top-layer. Popups appended to document.body end up behind the dialog
regardless of z-index, which broke the slash-command menu and the user
mention suggestion inside the task detail modal.

Append the popups to the nearest open <dialog> ancestor of the editor
(falling back to document.body) so they join the same top-layer stacking
context.
2026-04-15 08:39:24 +00:00
kolaente c0f05b6277 feat(editor): register emoji autocomplete extension 2026-04-14 13:48:49 +00:00
kolaente 7ab2804129 feat(editor): add emoji TipTap extension 2026-04-14 13:48:49 +00:00
kolaente 02d4dd1631 feat(editor): add emoji suggestion handler 2026-04-14 13:48:49 +00:00
kolaente 88136ed45e feat(editor): add EmojiList popup component 2026-04-14 13:48:49 +00:00
kolaente 542cab5ef6 feat(editor): add lazy emoji data loader and filter 2026-04-14 13:48:49 +00:00
kolaente d389408618 test(kanban): cover moveTaskToBucket 2026-04-14 11:32:14 +00:00
kolaente 13c4aec461 fix(frontend/kanban): honor server bucket redirect on drag (#2618) 2026-04-14 11:32:14 +00:00
Frederick [Bot] 8bde434676 chore(i18n): update translations via Crowdin 2026-04-14 01:29:51 +00:00
Frederick [Bot] 5ef01965e5 chore(i18n): update translations via Crowdin 2026-04-13 01:48:06 +00:00
kolaente 5afd066a13 feat(tasks): apply default reminders to quick-add tasks with due date
When a user has configured default reminders in their frontend settings,
those are cloned onto every task created via quick-add magic that has a
parsed due date. Tasks without a due date are silently skipped.

The buildDefaultRemindersForQuickAdd helper is exported as a pure
function so it can be unit-tested without stubbing the Pinia store.
2026-04-11 21:51:41 +00:00
kolaente 338d4d8b76 feat(settings): surface quick add default reminders in user settings
Adds the settings field next to the quick add magic mode select, hidden
when that mode is set to Disabled. Uses Reminders.vue directly with
allow-absolute=false and default-relative-to pinned to due date.
2026-04-11 21:51:41 +00:00
kolaente 6c9753328b feat(i18n): add strings for quick add default reminders 2026-04-11 21:51:41 +00:00
kolaente dc4b7a5510 refactor(reminders): make Reminders.vue take ITaskReminder[] directly
Reminders.vue only read three task fields (dueDate/startDate/endDate)
and wrote one back (reminders). The ITask coupling was accidental.

Flip the prop to ITaskReminder[] and pass defaultRelativeTo / allowAbsolute
as plain props. TaskDetailView now owns the due/start/end priority
computation and binds v-model="task.reminders" directly. This also lets
the settings page reuse Reminders.vue for configuring default reminders.
2026-04-11 21:51:41 +00:00
kolaente b61ad9d46a feat(reminders): add allowAbsolute prop to ReminderDetail
Adds an allowAbsolute prop to ReminderDetail that hides the 'Date and
time' option when set to false, and a lockRelativeTo prop on
ReminderPeriod that hides the relativeTo select and forces the chosen
value. ReminderDetail threads them together so that when absolute
reminders are disallowed, the Custom form can only produce reminders
that anchor to defaultRelativeTo.
2026-04-11 21:51:41 +00:00