The CSV handler imported echo/v4 instead of echo/v5 (which the project
uses), used value receiver echo.Context instead of pointer
*echo.Context, and called a non-existent handler.HandleHTTPError
function. Update to match existing handler patterns.
resetToUpload() cleared state but not the file input's value, so
re-selecting the same file after cancel would not trigger a change
event in the browser.
The error Message was only rendered inside the upload step div, so
preview/import failures during the mapping step were invisible to
users. Move it above the step-conditional sections and remove dead
preview-errors template code.
ErrorCount and Errors fields were never populated by PreviewImport,
making the API contract misleading. Remove them from both the Go
struct and the TypeScript interface.
Previously all parseCSV errors were mapped to ErrNotACSVFile, hiding
the actual cause. Now ErrFileIsEmpty is propagated correctly instead
of being misreported as an invalid CSV file.
parseCSV previously ignored the quoteChar parameter (named _). Since
Go's csv.Reader only supports double-quote, we now pre-process the
data to replace alternative quote characters before parsing.
The migration list linked all migrators to the 'migrate.service' route
by name, which loads MigrationHandler.vue. For the CSV migrator this
would result in a 400 error since it requires the multi-step
MigrationCSV.vue flow with config. Now CSV migrators link to
'migrate.csv' instead.
Remove labels from service structs and move them to the component.
The service now exports simple arrays of values, while the component
handles translation through mapping functions.
Add a new CSV migration module that allows users to import tasks from
any CSV file with custom column mapping and parsing options.
Backend changes:
- New CSV migrator module with detection, preview, and import endpoints
- Auto-detection of delimiter, quote character, and date format
- Suggested column mappings based on column name patterns
- Transactional import using InsertFromStructure
Frontend changes:
- New CSV migration UI with two-step flow (upload -> mapping -> import)
- Column mapping selectors for all task attributes
- Live preview showing first 5 tasks with current mapping
- Parsing option controls for delimiter and date format
The CSV migrator creates a parent "Imported from CSV" project with
child projects based on the project column if provided, or a default
"Tasks" project for tasks without a specified project.
Use a separate error variable for the user lookup in
UpdateTaskInSavedFilterViews so that ErrUserDoesNotExist does not
pollute the named return `err`. The `:=` inside the for loop shadowed
the outer `err`, leaving it set to the stale user-not-found error,
which caused the handler to be poisoned.
Closes#2359
The ListUsers function now references team_members and teams tables
via a subquery for external team discoverability. The pkg/user test
environment only syncs user tables, so these tests need to run in
pkg/models which has the full schema and all fixtures.
Also adds new tests for the external team discoverability bypass
directly in the models package alongside the moved tests.
Track old-to-new attachment ID mapping during duplication and
re-set CoverImageAttachmentID on the new task if the original
had a cover image configured.
Save the source file handle before calling NewAttachment (which
overwrites attachment.File) and use defer to ensure it gets closed.
This prevents file descriptor leaks on both success and error paths.
Previously WipeEverything used x.DBMetas() which returns all tables
in the database, including those owned by PostgreSQL extensions like
PostGIS. This caused restore to fail with 'cannot drop table
spatial_ref_sys because extension postgis requires it'.
Now uses the registered table list instead.
Fixesgo-vikunja/vikunja#2219
When a task bucket is updated without changing buckets (early return in
updateTaskBucket), b.Task remains nil. The TaskUpdatedEvent was then
dispatched with a nil Task, causing a nil pointer dereference in
HandleTaskUpdatedMentions when accessing event.Task.Description.
This adds:
- A nil guard in TaskBucket.Update to skip event dispatch when b.Task is nil
- Nil checks in HandleTaskUpdatedMentions, HandleTaskCreateMentions,
HandleTaskCommentEditMentions, and UpdateTaskInSavedFilterViews
- Tests verifying the handlers gracefully handle nil task events
Closes#2351
Add a github-script step to the preview workflow that creates or updates
a comment with preview URLs (pr-number and per-commit SHA) and Docker
image tags. Past SHA URLs are preserved across pushes so reviewers can
access any previously built version.
The back button was removed from modal mode in the previous commit.
On mobile kanban, tasks open as modals, so the test now uses the
close button from the Heading component instead.
When viewing a task in modal mode on mobile, both a back button and a close button were displayed, causing confusion. The back button condition `!isModal || isMobile` meant it would show on mobile even in modal mode.
This fix changes the back button to only display when not in modal mode (`!isModal`), ensuring only the close button appears when viewing tasks in a modal on mobile devices.
Also removed the now-unused `isMobile` variable and its import.