Merge pull request 'Fixes empty custom fields while turning back in settings closes #413' (#425) from bug/413_turn_back_custom into main
All checks were successful
continuous-integration/drone/push Build is passing

Reviewed-on: #425
This commit is contained in:
carla 2026-02-17 19:30:11 +01:00
commit e99dbdfb82
11 changed files with 165 additions and 198 deletions

View file

@ -1,7 +1,7 @@
defmodule Mv.Membership.Import.ImportRunner do
@moduledoc """
Orchestrates CSV member import: file reading, progress tracking, chunk processing,
and error formatting. Used by `MvWeb.ImportExportLive` to keep LiveView thin.
and error formatting. Used by `MvWeb.ImportLive` to keep LiveView thin.
This module does not depend on Phoenix or LiveView. It provides pure functions for
progress/merge and side-effectful helpers (read_file_entry, process_chunk) that

View file

@ -118,7 +118,7 @@ defmodule MvWeb.Layouts.Sidebar do
/>
<% end %>
<%= if can_access_page?(@current_user, PagePaths.settings()) do %>
<.menu_subitem href={~p"/admin/import-export"} label={gettext("Import/Export")} />
<.menu_subitem href={~p"/admin/import"} label={gettext("Import")} />
<.menu_subitem href={~p"/settings"} label={gettext("Settings")} />
<% end %>
</.menu_group>

View file

@ -219,6 +219,9 @@ defmodule MvWeb.CustomFieldLive.IndexComponent do
send(self(), {:editing_section_changed, nil})
end
# Get actor from assigns or fall back to socket assigns
actor = Map.get(assigns, :actor, socket.assigns[:actor])
{:ok,
socket
|> assign(assigns)
@ -228,7 +231,7 @@ defmodule MvWeb.CustomFieldLive.IndexComponent do
|> assign_new(:show_delete_modal, fn -> false end)
|> assign_new(:custom_field_to_delete, fn -> nil end)
|> assign_new(:slug_confirmation, fn -> "" end)
|> stream(:custom_fields, stream_custom_fields(assigns[:actor], self()), reset: true)}
|> stream(:custom_fields, stream_custom_fields(actor, self()), reset: true)}
end
@impl true

View file

@ -1,6 +1,6 @@
defmodule MvWeb.ImportExportLive do
defmodule MvWeb.ImportLive do
@moduledoc """
LiveView for importing and exporting members via CSV.
LiveView for importing members via CSV.
## Features
- CSV member import (admin only)
@ -38,7 +38,7 @@ defmodule MvWeb.ImportExportLive do
alias Mv.Membership.Import.ImportRunner
alias Mv.Membership.Import.MemberCSV
alias MvWeb.Authorization
alias MvWeb.ImportExportLive.Components
alias MvWeb.ImportLive.Components
on_mount {MvWeb.LiveHelpers, :ensure_user_role_loaded}
@ -65,7 +65,7 @@ defmodule MvWeb.ImportExportLive do
socket =
socket
|> assign(:page_title, gettext("Import/Export"))
|> assign(:page_title, gettext("Import"))
|> assign(:club_name, club_name)
|> assign(:import_state, nil)
|> assign(:import_progress, nil)
@ -90,13 +90,6 @@ defmodule MvWeb.ImportExportLive do
def render(assigns) do
~H"""
<Layouts.app flash={@flash} current_user={@current_user} club_name={@club_name}>
<.header>
{gettext("Import/Export")}
<:subtitle>
{gettext("Import members from CSV files or export member data.")}
</:subtitle>
</.header>
<%= if Authorization.can?(@current_user, :create, Mv.Membership.Member) do %>
<%!-- CSV Import Section --%>
<.form_section title={gettext("Import Members (CSV)")}>
@ -107,18 +100,6 @@ defmodule MvWeb.ImportExportLive do
<Components.import_progress {assigns} />
<% end %>
</.form_section>
<%!-- Export Section (Placeholder) --%>
<.form_section title={gettext("Export Members (CSV)")}>
<div role="note" class="alert alert-info">
<.icon name="hero-information-circle" class="size-5" aria-hidden="true" />
<div>
<p class="text-sm">
{gettext("Export functionality will be available in a future release.")}
</p>
</div>
</div>
</.form_section>
<% else %>
<div role="alert" class="alert alert-error">
<.icon name="hero-exclamation-circle" class="size-5" aria-hidden="true" />

View file

@ -1,6 +1,6 @@
defmodule MvWeb.ImportExportLive.Components do
defmodule MvWeb.ImportLive.Components do
@moduledoc """
Function components for the Import/Export LiveView: import form, progress, results,
Function components for the Import LiveView: import form, progress, results,
custom fields notice, and template links. Keeps the main LiveView focused on
mount/handle_event/handle_info and glue code.
"""

View file

@ -91,8 +91,8 @@ defmodule MvWeb.Router do
live "/admin/roles/:id", RoleLive.Show, :show
live "/admin/roles/:id/edit", RoleLive.Form, :edit
# Import/Export (Admin only)
live "/admin/import-export", ImportExportLive
# Import (Admin only)
live "/admin/import", ImportLive
post "/members/export.csv", MemberExportController, :export
post "/members/export.pdf", MemberPdfExportController, :export

View file

@ -1861,7 +1861,7 @@ msgstr "erstellt"
msgid "updated"
msgstr "aktualisiert"
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#: lib/mv_web/live/user_live/form.ex
#, elixir-autogen, elixir-format
msgid "Unknown error"
@ -1982,37 +1982,37 @@ msgstr "Bezahlstatus"
msgid "Reset"
msgstr "Zurücksetzen"
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid " (Field: %{field})"
msgstr " (Datenfeld: %{field})"
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "CSV File"
msgstr "CSV Datei"
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Download CSV templates:"
msgstr "CSV Vorlagen herunterladen:"
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "English Template"
msgstr "Englische Vorlage"
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Error list truncated to %{count} entries"
msgstr "Liste der Fehler auf %{count} Einträge reduziert"
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Errors"
msgstr "Fehler"
#: lib/mv_web/live/import_export_live.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format
msgid "Failed to prepare CSV import: %{reason}"
msgstr "Das Vorbereiten des CSV Imports ist gescheitert: %{reason}"
@ -2027,27 +2027,27 @@ msgstr "Das Importieren von %{idx} ist gescheitert: %{reason}"
msgid "Failed to read file: %{reason}"
msgstr "Fehler beim Lesen der Datei: %{reason}"
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Failed: %{count} row(s)"
msgstr "Fehlgeschlagen: %{count} Zeile(n)"
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "German Template"
msgstr "Deutsche Vorlage"
#: lib/mv_web/live/import_export_live.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format
msgid "Import Members (CSV)"
msgstr "Mitglieder importieren (CSV)"
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Import Results"
msgstr "Import-Ergebnisse"
#: lib/mv_web/live/import_export_live.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format
msgid "Import is already running. Please wait for it to complete."
msgstr "Import läuft bereits. Bitte warte, bis er abgeschlossen ist."
@ -2062,7 +2062,7 @@ msgstr "Import-Status fehlt. Chunk %{idx} kann nicht verarbeitet werden."
msgid "Invalid chunk index: %{idx}"
msgstr "Ungültiger Chunk-Index: %{idx}"
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Line %{line}: %{message}"
msgstr "Zeile %{line}: %{message}"
@ -2072,47 +2072,47 @@ msgstr "Zeile %{line}: %{message}"
msgid "No file was uploaded"
msgstr "Es wurde keine Datei hochgeladen"
#: lib/mv_web/live/import_export_live.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format
msgid "Only administrators can import members from CSV files."
msgstr "Nur Administrator*innen können Mitglieder aus CSV-Dateien importieren."
#: lib/mv_web/live/import_export_live.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format
msgid "Please select a CSV file to import."
msgstr "Bitte wähle eine CSV-Datei zum Importieren."
#: lib/mv_web/live/import_export_live.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format
msgid "Please wait for the file upload to complete before starting the import."
msgstr "Bitte warte, bis der Datei-Upload abgeschlossen ist, bevor du den Import startest."
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Processing chunk %{current} of %{total}..."
msgstr "Verarbeite Chunk %{current} von %{total}..."
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Start Import"
msgstr "Import starten"
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Starting import..."
msgstr "Import wird gestartet..."
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Successfully inserted: %{count} member(s)"
msgstr "Erfolgreich eingefügt: %{count} Mitglied(er)"
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Summary"
msgstr "Zusammenfassung"
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Warnings"
msgstr "Warnungen"
@ -2329,7 +2329,7 @@ msgstr "%{name} entfernen"
msgid "Some members could not be added: %{errors}"
msgstr "Einige Mitglieder konnten nicht hinzugefügt werden: %{errors}"
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "CSV files only, maximum %{size} MB"
msgstr "Nur CSV Dateien, maximal %{size} MB"
@ -2359,43 +2359,22 @@ msgstr "Datenfeld: %{name} erwartet %{type}, erhalten: %{value}"
msgid "Unknown column '%{header}' will be ignored. If this is a custom field, create it in Mila before importing."
msgstr "Unbekannte Spalte '%{header}' wird ignoriert. Falls dies ein Datenfeld ist, erstelle es in Mila vor dem Import."
#: lib/mv_web/live/import_export_live.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Export Members (CSV)"
msgstr "Mitglieder importieren (CSV)"
#: lib/mv_web/live/import_export_live.ex
#, elixir-autogen, elixir-format
msgid "Export functionality will be available in a future release."
msgstr "Export-Funktionalität ist im nächsten release verfügbar."
#: lib/mv/membership/import/import_runner.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Failed to read uploaded file: unexpected format"
msgstr "Fehler beim Lesen der hochgeladenen Datei"
#: lib/mv_web/live/import_export_live.ex
#, elixir-autogen, elixir-format
msgid "Import members from CSV files or export member data."
msgstr "Importiere Mitglieder aus CSV-Dateien oder exportiere Mitgliederdaten."
#: lib/mv_web/components/layouts/sidebar.ex
#: lib/mv_web/live/import_export_live.ex
#, elixir-autogen, elixir-format
msgid "Import/Export"
msgstr "Import/Export"
#: lib/mv_web/live/import_export_live.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "You do not have permission to access this page."
msgstr "Du hast keine Berechtigung, auf diese Seite zuzugreifen."
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Manage Member Data"
msgstr "Mitgliederdaten verwalten"
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Use the data field name as the CSV column header in your file. Data fields must exist in Mila before importing, so they must be listed in the list of member data (like e-mail or first name). Unknown data field columns will be ignored with a warning."
msgstr "Verwende die Namen der Datenfelder als Spaltennamen in der CSV Datei. Datenfelder müssen in Mila bereits angelegt sein, damit sie importiert werden können. sie müssen in der Liste der Mitgliederdaten als Datenfeld enthalten sein (z.B. E-Mail). Spalten mit unbekannten Spaltenüberschriften werden mit einer Warnung ignoriert."
@ -2457,7 +2436,7 @@ msgstr "SSO / OIDC Nutzer*in"
msgid "This user is linked via SSO (Single Sign-On). A password set or changed here only affects login with email and password in this application. It does not change the password in your identity provider (e.g. Authentik). To change the SSO password, use the identity provider or your organization's IT."
msgstr "Diese*r Nutzer*in ist über SSO (Single Sign-On) verbunden. Ein hier festgelegtes oder geändertes Passwort wirkt sich nur auf die Anmeldung mit E-Mail-Adresse und Passwort in dieser Anwendung aus. Es ändert nicht das Passwort in Eurem Identitätsanbieter (z. B. Authentik). Um das SSO-Passwort zu ändern, wende dich an den Identitätsanbieter oder die IT-Abteilung Ihrer Organisation."
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Import aborted"
msgstr "Import abgebrochen"
@ -2618,3 +2597,24 @@ msgstr "Anzahl Mitglieder:"
#, elixir-autogen, elixir-format
msgid "PDF"
msgstr "PDF"
#: lib/mv_web/components/layouts/sidebar.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Import"
msgstr "Import"
#~ #: lib/mv_web/live/import_export_live.ex
#~ #, elixir-autogen, elixir-format, fuzzy
#~ msgid "Export Members (CSV)"
#~ msgstr "Mitglieder exportieren (CSV)"
#~ #: lib/mv_web/live/import_export_live.ex
#~ #, elixir-autogen, elixir-format
#~ msgid "Export functionality will be available in a future release."
#~ msgstr "Export-Funktionalität ist im nächsten release verfügbar."
#~ #: lib/mv_web/live/import_export_live.ex
#~ #, elixir-autogen, elixir-format
#~ msgid "Import members from CSV files or export member data."
#~ msgstr "Importiere Mitglieder aus CSV-Dateien oder exportiere Mitgliederdaten."

View file

@ -1862,7 +1862,7 @@ msgstr ""
msgid "updated"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#: lib/mv_web/live/user_live/form.ex
#, elixir-autogen, elixir-format
msgid "Unknown error"
@ -1983,37 +1983,37 @@ msgstr ""
msgid "Reset"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid " (Field: %{field})"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "CSV File"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Download CSV templates:"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "English Template"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Error list truncated to %{count} entries"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Errors"
msgstr ""
#: lib/mv_web/live/import_export_live.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format
msgid "Failed to prepare CSV import: %{reason}"
msgstr ""
@ -2028,27 +2028,27 @@ msgstr ""
msgid "Failed to read file: %{reason}"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Failed: %{count} row(s)"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "German Template"
msgstr ""
#: lib/mv_web/live/import_export_live.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format
msgid "Import Members (CSV)"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Import Results"
msgstr ""
#: lib/mv_web/live/import_export_live.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format
msgid "Import is already running. Please wait for it to complete."
msgstr ""
@ -2063,7 +2063,7 @@ msgstr ""
msgid "Invalid chunk index: %{idx}"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Line %{line}: %{message}"
msgstr ""
@ -2073,47 +2073,47 @@ msgstr ""
msgid "No file was uploaded"
msgstr ""
#: lib/mv_web/live/import_export_live.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format
msgid "Only administrators can import members from CSV files."
msgstr ""
#: lib/mv_web/live/import_export_live.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format
msgid "Please select a CSV file to import."
msgstr ""
#: lib/mv_web/live/import_export_live.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format
msgid "Please wait for the file upload to complete before starting the import."
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Processing chunk %{current} of %{total}..."
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Start Import"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Starting import..."
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Successfully inserted: %{count} member(s)"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Summary"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Warnings"
msgstr ""
@ -2330,7 +2330,7 @@ msgstr ""
msgid "Some members could not be added: %{errors}"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "CSV files only, maximum %{size} MB"
msgstr ""
@ -2360,43 +2360,22 @@ msgstr ""
msgid "Unknown column '%{header}' will be ignored. If this is a custom field, create it in Mila before importing."
msgstr ""
#: lib/mv_web/live/import_export_live.ex
#, elixir-autogen, elixir-format
msgid "Export Members (CSV)"
msgstr ""
#: lib/mv_web/live/import_export_live.ex
#, elixir-autogen, elixir-format
msgid "Export functionality will be available in a future release."
msgstr ""
#: lib/mv/membership/import/import_runner.ex
#, elixir-autogen, elixir-format
msgid "Failed to read uploaded file: unexpected format"
msgstr ""
#: lib/mv_web/live/import_export_live.ex
#, elixir-autogen, elixir-format
msgid "Import members from CSV files or export member data."
msgstr ""
#: lib/mv_web/components/layouts/sidebar.ex
#: lib/mv_web/live/import_export_live.ex
#, elixir-autogen, elixir-format
msgid "Import/Export"
msgstr ""
#: lib/mv_web/live/import_export_live.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format
msgid "You do not have permission to access this page."
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Manage Member Data"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Use the data field name as the CSV column header in your file. Data fields must exist in Mila before importing, so they must be listed in the list of member data (like e-mail or first name). Unknown data field columns will be ignored with a warning."
msgstr ""
@ -2458,7 +2437,7 @@ msgstr ""
msgid "This user is linked via SSO (Single Sign-On). A password set or changed here only affects login with email and password in this application. It does not change the password in your identity provider (e.g. Authentik). To change the SSO password, use the identity provider or your organization's IT."
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Import aborted"
msgstr ""
@ -2619,3 +2598,9 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "PDF"
msgstr ""
#: lib/mv_web/components/layouts/sidebar.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format
msgid "Import"
msgstr ""

View file

@ -1862,7 +1862,7 @@ msgstr ""
msgid "updated"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#: lib/mv_web/live/user_live/form.ex
#, elixir-autogen, elixir-format
msgid "Unknown error"
@ -1983,37 +1983,37 @@ msgstr ""
msgid "Reset"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid " (Field: %{field})"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "CSV File"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Download CSV templates:"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "English Template"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Error list truncated to %{count} entries"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Errors"
msgstr ""
#: lib/mv_web/live/import_export_live.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format
msgid "Failed to prepare CSV import: %{reason}"
msgstr ""
@ -2028,27 +2028,27 @@ msgstr ""
msgid "Failed to read file: %{reason}"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Failed: %{count} row(s)"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "German Template"
msgstr ""
#: lib/mv_web/live/import_export_live.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format
msgid "Import Members (CSV)"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Import Results"
msgstr ""
#: lib/mv_web/live/import_export_live.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format
msgid "Import is already running. Please wait for it to complete."
msgstr ""
@ -2063,7 +2063,7 @@ msgstr ""
msgid "Invalid chunk index: %{idx}"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Line %{line}: %{message}"
msgstr ""
@ -2073,47 +2073,47 @@ msgstr ""
msgid "No file was uploaded"
msgstr ""
#: lib/mv_web/live/import_export_live.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format
msgid "Only administrators can import members from CSV files."
msgstr ""
#: lib/mv_web/live/import_export_live.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Please select a CSV file to import."
msgstr ""
#: lib/mv_web/live/import_export_live.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format
msgid "Please wait for the file upload to complete before starting the import."
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Processing chunk %{current} of %{total}..."
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Start Import"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Starting import..."
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Successfully inserted: %{count} member(s)"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Summary"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Warnings"
msgstr ""
@ -2330,7 +2330,7 @@ msgstr ""
msgid "Some members could not be added: %{errors}"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "CSV files only, maximum %{size} MB"
msgstr ""
@ -2360,43 +2360,22 @@ msgstr ""
msgid "Unknown column '%{header}' will be ignored. If this is a custom field, create it in Mila before importing."
msgstr "Unknown column '%{header}' will be ignored. If this is a custom field, create it in Mila before importing."
#: lib/mv_web/live/import_export_live.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Export Members (CSV)"
msgstr ""
#: lib/mv_web/live/import_export_live.ex
#, elixir-autogen, elixir-format
msgid "Export functionality will be available in a future release."
msgstr ""
#: lib/mv/membership/import/import_runner.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Failed to read uploaded file: unexpected format"
msgstr ""
#: lib/mv_web/live/import_export_live.ex
#, elixir-autogen, elixir-format
msgid "Import members from CSV files or export member data."
msgstr ""
#: lib/mv_web/components/layouts/sidebar.ex
#: lib/mv_web/live/import_export_live.ex
#, elixir-autogen, elixir-format
msgid "Import/Export"
msgstr ""
#: lib/mv_web/live/import_export_live.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "You do not have permission to access this page."
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Manage Member Data"
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Use the data field name as the CSV column header in your file. Data fields must exist in Mila before importing, so they must be listed in the list of member data (like e-mail or first name). Unknown data field columns will be ignored with a warning."
msgstr ""
@ -2458,7 +2437,7 @@ msgstr ""
msgid "This user is linked via SSO (Single Sign-On). A password set or changed here only affects login with email and password in this application. It does not change the password in your identity provider (e.g. Authentik). To change the SSO password, use the identity provider or your organization's IT."
msgstr ""
#: lib/mv_web/live/import_export_live/components.ex
#: lib/mv_web/live/import_live/components.ex
#, elixir-autogen, elixir-format
msgid "Import aborted"
msgstr ""
@ -2619,3 +2598,24 @@ msgstr "Member count:"
#, elixir-autogen, elixir-format
msgid "PDF"
msgstr ""
#: lib/mv_web/components/layouts/sidebar.ex
#: lib/mv_web/live/import_live.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Import"
msgstr ""
#~ #: lib/mv_web/live/import_export_live.ex
#~ #, elixir-autogen, elixir-format, fuzzy
#~ msgid "Export Members (CSV)"
#~ msgstr ""
#~ #: lib/mv_web/live/import_export_live.ex
#~ #, elixir-autogen, elixir-format
#~ msgid "Export functionality will be available in a future release."
#~ msgstr ""
#~ #: lib/mv_web/live/import_export_live.ex
#~ #, elixir-autogen, elixir-format
#~ msgid "Import members from CSV files or export member data."
#~ msgstr ""

View file

@ -42,7 +42,7 @@ defmodule MvWeb.GlobalSettingsLiveConfigTest do
# Arrange: Set custom row limit to 500
Application.put_env(:mv, :csv_import, max_rows: 500)
{:ok, view, _html} = live(conn, ~p"/admin/import-export")
{:ok, view, _html} = live(conn, ~p"/admin/import")
# Generate CSV with 501 rows (exceeding custom limit of 500)
header = "first_name;last_name;email;street;postal_code;city\n"

View file

@ -1,6 +1,6 @@
defmodule MvWeb.ImportExportLiveTest do
defmodule MvWeb.ImportLiveTest do
@moduledoc """
Tests for Import/Export LiveView: authorization (business rule), CSV import integration,
Tests for Import LiveView: authorization (business rule), CSV import integration,
and minimal UI smoke tests. CSV parsing/validation logic is covered by
Mv.Membership.Import.MemberCSVTest; here we verify access control and end-to-end outcomes.
"""
@ -31,7 +31,7 @@ defmodule MvWeb.ImportExportLiveTest do
# ---------- Business logic: Authorization ----------
describe "Authorization" do
test "non-admin user cannot access import/export page and sees permission error", %{
test "non-admin user cannot access import page and sees permission error", %{
conn: conn
} do
member_user = Mv.Fixtures.user_with_role_fixture("own_data")
@ -42,7 +42,7 @@ defmodule MvWeb.ImportExportLiveTest do
|> put_locale_en()
assert {:error, {:redirect, %{to: redirect_path, flash: %{"error" => msg}}}} =
live(conn, ~p"/admin/import-export")
live(conn, ~p"/admin/import")
assert redirect_path =~ "/users/"
assert msg =~ "don't have permission"
@ -55,7 +55,7 @@ defmodule MvWeb.ImportExportLiveTest do
Path.join([__DIR__, "..", "..", "fixtures", "valid_member_import.csv"])
|> File.read!()
{:ok, view, _html} = live(conn, ~p"/admin/import-export")
{:ok, view, _html} = live(conn, ~p"/admin/import")
upload_csv_file(view, csv_content)
submit_import(view)
wait_for_import_completion()
@ -109,7 +109,7 @@ defmodule MvWeb.ImportExportLiveTest do
end
test "invalid CSV shows user-friendly prepare error", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/import-export")
{:ok, view, _html} = live(conn, ~p"/admin/import")
upload_csv_file(view, "invalid_header\nincomplete_row", "invalid.csv")
submit_import(view)
html = render(view)
@ -120,7 +120,7 @@ defmodule MvWeb.ImportExportLiveTest do
conn: conn,
invalid_csv: csv_content
} do
{:ok, view, _html} = live(conn, ~p"/admin/import-export")
{:ok, view, _html} = live(conn, ~p"/admin/import")
upload_csv_file(view, csv_content, "invalid_import.csv")
submit_import(view)
wait_for_import_completion()
@ -135,7 +135,7 @@ defmodule MvWeb.ImportExportLiveTest do
end
test "error list is capped and truncation message is shown", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/import-export")
{:ok, view, _html} = live(conn, ~p"/admin/import")
header = "first_name;last_name;email;street;postal_code;city\n"
invalid_rows =
@ -153,7 +153,7 @@ defmodule MvWeb.ImportExportLiveTest do
end
test "row limit is enforced (1001 rows rejected)", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/import-export")
{:ok, view, _html} = live(conn, ~p"/admin/import")
header = "first_name;last_name;email;street;postal_code;city\n"
rows =
@ -168,7 +168,7 @@ defmodule MvWeb.ImportExportLiveTest do
end
test "BOM and semicolon delimiter are accepted", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/import-export")
{:ok, view, _html} = live(conn, ~p"/admin/import")
csv_content =
Path.join([__DIR__, "..", "..", "fixtures", "csv_with_bom_semicolon.csv"])
@ -187,7 +187,7 @@ defmodule MvWeb.ImportExportLiveTest do
test "physical line numbers in errors (empty line does not shift numbering)", %{
conn: conn
} do
{:ok, view, _html} = live(conn, ~p"/admin/import-export")
{:ok, view, _html} = live(conn, ~p"/admin/import")
csv_content =
Path.join([__DIR__, "..", "..", "fixtures", "csv_with_empty_lines.csv"])
@ -207,7 +207,7 @@ defmodule MvWeb.ImportExportLiveTest do
conn: conn,
unknown_custom_field_csv: csv_content
} do
{:ok, view, _html} = live(conn, ~p"/admin/import-export")
{:ok, view, _html} = live(conn, ~p"/admin/import")
upload_csv_file(view, csv_content, "unknown_custom.csv")
submit_import(view)
wait_for_import_completion()
@ -220,7 +220,7 @@ defmodule MvWeb.ImportExportLiveTest do
end
# ---------- UI (smoke / framework): tagged for exclusion from fast CI ----------
describe "Import/Export page UI" do
describe "Import page UI" do
@describetag :ui
setup %{conn: conn} do
admin_user = Mv.Fixtures.user_with_role_fixture("admin")
@ -233,19 +233,17 @@ defmodule MvWeb.ImportExportLiveTest do
{:ok, conn: conn}
end
test "page loads and shows import form and export placeholder", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/import-export")
test "page loads and shows import form", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/import")
assert has_element?(view, "[data-testid='csv-upload-form']")
assert has_element?(view, "[data-testid='start-import-button']")
assert has_element?(view, "[data-testid='custom-fields-link']")
html = render(view)
assert html =~ "Import Members (CSV)"
assert html =~ "Export Members (CSV)"
assert html =~ "Export functionality will be available"
end
test "template links and file input are present", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/import-export")
{:ok, view, _html} = live(conn, ~p"/admin/import")
assert has_element?(view, "a[href*='/templates/member_import_en.csv']")
assert has_element?(view, "a[href*='/templates/member_import_de.csv']")
assert has_element?(view, "label[for='csv_file']")
@ -258,7 +256,7 @@ defmodule MvWeb.ImportExportLiveTest do
Path.join([__DIR__, "..", "..", "fixtures", "valid_member_import.csv"])
|> File.read!()
{:ok, view, _html} = live(conn, ~p"/admin/import-export")
{:ok, view, _html} = live(conn, ~p"/admin/import")
upload_csv_file(view, csv_content)
submit_import(view)
wait_for_import_completion()
@ -273,7 +271,7 @@ defmodule MvWeb.ImportExportLiveTest do
@tag :skip
test "empty CSV shows error", %{conn: conn} do
conn = put_locale_en(conn)
{:ok, view, _html} = live(conn, ~p"/admin/import-export")
{:ok, view, _html} = live(conn, ~p"/admin/import")
upload_csv_file(view, " ", "empty.csv")
submit_import(view)
html = render(view)