Merge branch 'main' into feature/209_hide_field_dropdown
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
Moritz 2025-12-03 17:37:01 +01:00
commit f5b67de870
Signed by: moritz
GPG key ID: 1020A035E5DD0824
12 changed files with 2012 additions and 1376 deletions

View file

@ -166,7 +166,7 @@ environment:
steps: steps:
- name: renovate - name: renovate
image: renovate/renovate:41.151 image: renovate/renovate:41.173
environment: environment:
RENOVATE_CONFIG_FILE: "renovate_backend_config.js" RENOVATE_CONFIG_FILE: "renovate_backend_config.js"
RENOVATE_TOKEN: RENOVATE_TOKEN:

View file

@ -1,3 +1,3 @@
elixir 1.18.3-otp-27 elixir 1.18.3-otp-27
erlang 27.3.4 erlang 27.3.4
just 1.43.0 just 1.43.1

View file

@ -5,80 +5,212 @@ defmodule MvWeb.MemberLive.Form do
## Features ## Features
- Create new members with personal information - Create new members with personal information
- Edit existing member details - Edit existing member details
- Manage custom properties (dynamic fields) - Grouped sections for better organization
- Tab navigation (Payments tab disabled, coming soon)
- Manage custom properties (dynamic fields, displayed sorted by name)
- Real-time validation with visual feedback - Real-time validation with visual feedback
- Link/unlink user accounts
## Form Fields ## Form Sections
**Required:** - Personal Data: Name, address, contact information, membership dates, notes
- first_name, last_name, email - Custom Fields: Dynamic fields in uniform grid layout (displayed sorted by name)
- Payment Data: Mockup section (not editable)
**Optional:**
- phone_number, address fields (city, street, house_number, postal_code)
- join_date, exit_date
- paid status
- notes
## Custom Field Values
Members can have dynamic custom field values defined by CustomFields.
The form dynamically renders inputs based on available CustomFields.
## Events ## Events
- `validate` - Real-time form validation - `validate` - Real-time form validation
- `save` - Submit form (create or update member) - `save` - Submit form (create or update member)
- Custom field value management events for adding/removing custom fields
""" """
use MvWeb, :live_view use MvWeb, :live_view
@impl true @impl true
def render(assigns) do def render(assigns) do
# Sort custom fields by name for display only
sorted_custom_fields = Enum.sort_by(assigns.custom_fields, & &1.name)
assigns = assign(assigns, :sorted_custom_fields, sorted_custom_fields)
~H""" ~H"""
<Layouts.app flash={@flash} current_user={@current_user}> <Layouts.app flash={@flash} current_user={@current_user}>
<.header>
{@page_title}
<:subtitle>
{gettext("Fields marked with an asterisk (*) cannot be empty.")}
</:subtitle>
</.header>
<.form for={@form} id="member-form" phx-change="validate" phx-submit="save"> <.form for={@form} id="member-form" phx-change="validate" phx-submit="save">
<.input field={@form[:first_name]} label={gettext("First Name")} required /> <%!-- Header with Back button, Name display, and Save button --%>
<.input field={@form[:last_name]} label={gettext("Last Name")} required /> <div class="flex items-center justify-between gap-4 pb-4">
<.input field={@form[:email]} label={gettext("Email")} required type="email" /> <.button navigate={return_path(@return_to, @member)} type="button">
<.input field={@form[:paid]} label={gettext("Paid")} type="checkbox" /> <.icon name="hero-arrow-left" class="size-4" />
<.input field={@form[:phone_number]} label={gettext("Phone Number")} /> {gettext("Back")}
<.input field={@form[:join_date]} label={gettext("Join Date")} type="date" /> </.button>
<.input field={@form[:exit_date]} label={gettext("Exit Date")} type="date" />
<.input field={@form[:notes]} label={gettext("Notes")} />
<.input field={@form[:city]} label={gettext("City")} />
<.input field={@form[:street]} label={gettext("Street")} />
<.input field={@form[:house_number]} label={gettext("House Number")} />
<.input field={@form[:postal_code]} label={gettext("Postal Code")} />
<h3 class="mt-8 mb-2 text-lg font-semibold">{gettext("Custom Field Values")}</h3> <h1 class="text-2xl font-bold text-center flex-1">
<.inputs_for :let={f_custom_field_value} field={@form[:custom_field_values]}> <%= if @member do %>
<% type = {@member.first_name} {@member.last_name}
Enum.find(@custom_fields, &(&1.id == f_custom_field_value[:custom_field_id].value)) %> <% else %>
<.inputs_for :let={value_form} field={f_custom_field_value[:value]}> {gettext("New Member")}
<% input_type = <% end %>
cond do </h1>
type && type.value_type == :boolean -> "checkbox"
type && type.value_type == :date -> :date <.button phx-disable-with={gettext("Saving...")} variant="primary" type="submit">
true -> :text {gettext("Save")}
end %> </.button>
<.input field={value_form[:value]} label={type && type.name} type={input_type} /> </div>
<%!-- Tab Navigation --%>
<div role="tablist" class="tabs tabs-bordered mb-6">
<button type="button" role="tab" class="tab tab-active" aria-selected="true">
<.icon name="hero-identification" class="size-4 mr-2" />
{gettext("Contact Data")}
</button>
<button
type="button"
role="tab"
class="tab"
disabled
aria-disabled="true"
title={gettext("Coming soon")}
>
<.icon name="hero-credit-card" class="size-4 mr-2" />
{gettext("Payments")}
</button>
</div>
<%!-- Personal Data and Custom Fields Row --%>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
<%!-- Personal Data Section --%>
<div>
<.form_section title={gettext("Personal Data")}>
<div class="space-y-4">
<%!-- Name Row --%>
<div class="flex gap-4">
<div class="w-48">
<.input field={@form[:first_name]} label={gettext("First Name")} required />
</div>
<div class="w-48">
<.input field={@form[:last_name]} label={gettext("Last Name")} required />
</div>
</div>
<%!-- Address Row --%>
<div class="flex gap-4">
<div class="flex-1">
<.input field={@form[:street]} label={gettext("Street")} />
</div>
<div class="w-16">
<.input field={@form[:house_number]} label={gettext("Nr.")} />
</div>
<div class="w-24">
<.input field={@form[:postal_code]} label={gettext("Postal Code")} />
</div>
<div class="w-32">
<.input field={@form[:city]} label={gettext("City")} />
</div>
</div>
<%!-- Email --%>
<div>
<.input field={@form[:email]} label={gettext("Email")} required type="email" />
</div>
<%!-- Phone --%>
<div>
<.input field={@form[:phone_number]} label={gettext("Phone")} type="tel" />
</div>
<%!-- Membership Dates Row --%>
<div class="flex gap-4">
<div class="w-36">
<.input field={@form[:join_date]} label={gettext("Join Date")} type="date" />
</div>
<div class="w-36">
<.input field={@form[:exit_date]} label={gettext("Exit Date")} type="date" />
</div>
</div>
<%!-- Notes --%>
<div>
<.input field={@form[:notes]} label={gettext("Notes")} type="textarea" />
</div>
</div>
</.form_section>
</div>
<%!-- Custom Fields Section --%>
<%= if Enum.any?(@custom_fields) do %>
<div>
<.form_section title={gettext("Custom Fields")}>
<div class="grid grid-cols-2 gap-4">
<%!-- Render in sorted order by finding the form for each sorted custom field --%>
<%= for cf <- @sorted_custom_fields do %>
<.inputs_for :let={f_cfv} field={@form[:custom_field_values]}>
<%= if f_cfv[:custom_field_id].value == cf.id do %>
<div class={if cf.value_type == :boolean, do: "flex items-end", else: ""}>
<.inputs_for :let={value_form} field={f_cfv[:value]}>
<.input
field={value_form[:value]}
label={cf.name}
type={custom_field_input_type(cf.value_type)}
/>
</.inputs_for> </.inputs_for>
<input <input
type="hidden" type="hidden"
name={f_custom_field_value[:custom_field_id].name} name={f_cfv[:custom_field_id].name}
value={f_custom_field_value[:custom_field_id].value} value={f_cfv[:custom_field_id].value}
/> />
</div>
<% end %>
</.inputs_for> </.inputs_for>
<% end %>
</div>
</.form_section>
</div>
<% end %>
</div>
<.button phx-disable-with={gettext("Saving...")} variant="primary"> <%!-- Payment Data Section (Mockup) --%>
<div class="max-w-xl">
<.form_section title={gettext("Payment Data")}>
<div role="alert" class="alert alert-info mb-4">
<.icon name="hero-information-circle" class="size-5" />
<span>{gettext("This data is for demonstration purposes only (mockup).")}</span>
</div>
<div class="flex gap-8">
<div class="w-24">
<label for="mock-contribution" class="label text-sm font-medium">
{gettext("Contribution")}
</label>
<input
type="text"
id="mock-contribution"
value="72 €"
disabled
class="input input-bordered w-full bg-base-200"
/>
</div>
<div class="w-40">
<label class="label text-sm font-medium">{gettext("Payment Cycle")}</label>
<div class="flex gap-3 mt-2">
<label class="flex items-center gap-1 cursor-not-allowed opacity-60">
<input type="radio" name="mock_cycle" checked disabled class="radio radio-sm" />
<span class="text-sm">{gettext("monthly")}</span>
</label>
<label class="flex items-center gap-1 cursor-not-allowed opacity-60">
<input type="radio" name="mock_cycle" disabled class="radio radio-sm" />
<span class="text-sm">{gettext("yearly")}</span>
</label>
</div>
</div>
<div class="w-24 flex items-end">
<.input field={@form[:paid]} label={gettext("Paid")} type="checkbox" />
</div>
</div>
</.form_section>
</div>
<%!-- Bottom Action Buttons --%>
<div class="flex justify-end gap-4 mt-6">
<.button navigate={return_path(@return_to, @member)} type="button">
{gettext("Cancel")}
</.button>
<.button phx-disable-with={gettext("Saving...")} variant="primary" type="submit">
{gettext("Save Member")} {gettext("Save Member")}
</.button> </.button>
<.button navigate={return_path(@return_to, @member)}>{gettext("Cancel")}</.button> </div>
</.form> </.form>
</Layouts.app> </Layouts.app>
""" """
@ -106,8 +238,8 @@ defmodule MvWeb.MemberLive.Form do
id -> Ash.get!(Mv.Membership.Member, id) id -> Ash.get!(Mv.Membership.Member, id)
end end
action = if is_nil(member), do: "New", else: "Edit" page_title =
page_title = action <> " " <> "Member" if is_nil(member), do: gettext("Create Member"), else: gettext("Edit Member")
{:ok, {:ok,
socket socket
@ -213,5 +345,37 @@ defmodule MvWeb.MemberLive.Form do
end end
defp return_path("index", _member), do: ~p"/members" defp return_path("index", _member), do: ~p"/members"
defp return_path("show", nil), do: ~p"/members"
defp return_path("show", member), do: ~p"/members/#{member.id}" defp return_path("show", member), do: ~p"/members/#{member.id}"
# -----------------------------------------------------------------
# Helper Components
# -----------------------------------------------------------------
# Renders a form section box with border and title.
attr :title, :string, required: true
slot :inner_block, required: true
defp form_section(assigns) do
~H"""
<section class="mb-6">
<h2 class="text-lg font-semibold mb-3">{@title}</h2>
<div class="border border-base-300 rounded-lg p-4 bg-base-100">
{render_slot(@inner_block)}
</div>
</section>
"""
end
# -----------------------------------------------------------------
# Helper Functions for Custom Fields
# -----------------------------------------------------------------
# Returns input type for custom field based on value type
defp custom_field_input_type(:string), do: "text"
defp custom_field_input_type(:integer), do: "number"
defp custom_field_input_type(:boolean), do: "checkbox"
defp custom_field_input_type(:date), do: "date"
defp custom_field_input_type(:email), do: "email"
defp custom_field_input_type(_), do: "text"
end end

View file

@ -3,19 +3,16 @@ defmodule MvWeb.MemberLive.Show do
LiveView for displaying a single member's details. LiveView for displaying a single member's details.
## Features ## Features
- Display all member information (personal, contact, address) - Display all member information in grouped sections
- Show linked user account (if exists) - Tab navigation for future features (Payments)
- Display custom field values - Show custom field values with type-based formatting
- Navigate to edit form - Navigate to edit form
- Return to member list - Return to member list
## Displayed Information ## Sections
- Basic: name, email, dates (join, exit) - Personal Data: Name, address, contact information, membership dates, notes
- Contact: phone number - Custom Fields: Dynamic fields in uniform grid layout (sorted by name)
- Address: street, house number, postal code, city - Payment Data: Mockup section with placeholder data
- Status: paid flag
- Relationships: linked user account
- Custom: dynamic custom field values from CustomFields
## Navigation ## Navigation
- Back to member list - Back to member list
@ -23,69 +20,155 @@ defmodule MvWeb.MemberLive.Show do
""" """
use MvWeb, :live_view use MvWeb, :live_view
import Ash.Query import Ash.Query
alias MvWeb.Helpers.DateFormatter
@impl true @impl true
def render(assigns) do def render(assigns) do
~H""" ~H"""
<Layouts.app flash={@flash} current_user={@current_user}> <Layouts.app flash={@flash} current_user={@current_user}>
<.header> <%!-- Header with Back button, Name, and Edit button --%>
{@member.first_name} {@member.last_name} <div class="flex items-center justify-between gap-4 pb-4">
<:subtitle>{gettext("This is a member record from your database.")}</:subtitle>
<:actions>
<.button navigate={~p"/members"} aria-label={gettext("Back to members list")}> <.button navigate={~p"/members"} aria-label={gettext("Back to members list")}>
<.icon name="hero-arrow-left" /> <.icon name="hero-arrow-left" class="size-4" />
<span class="sr-only">{gettext("Back to members list")}</span> {gettext("Back")}
</.button> </.button>
<.button variant="primary" navigate={~p"/members/#{@member}/edit?return_to=show"}>
<.icon name="hero-pencil-square" /> {gettext("Edit Member")}
</.button>
</:actions>
</.header>
<.list> <h1 class="text-2xl font-bold text-center flex-1">
<:item title={gettext("Id")}>{@member.id}</:item> {@member.first_name} {@member.last_name}
<:item title={gettext("First Name")}>{@member.first_name}</:item> </h1>
<:item title={gettext("Last Name")}>{@member.last_name}</:item>
<:item title={gettext("Email")}>{@member.email}</:item> <.button variant="primary" navigate={~p"/members/#{@member}/edit?return_to=show"}>
<:item title={gettext("Paid")}> {gettext("Edit Member")}
{if @member.paid, do: gettext("Yes"), else: gettext("No")} </.button>
</:item> </div>
<:item title={gettext("Phone Number")}>{@member.phone_number}</:item>
<:item title={gettext("Join Date")}>{DateFormatter.format_date(@member.join_date)}</:item> <%!-- Tab Navigation --%>
<:item title={gettext("Exit Date")}>{DateFormatter.format_date(@member.exit_date)}</:item> <div role="tablist" class="tabs tabs-bordered mb-6">
<:item title={gettext("Notes")}>{@member.notes}</:item> <button role="tab" class="tab tab-active" aria-selected="true">
<:item title={gettext("City")}>{@member.city}</:item> <.icon name="hero-identification" class="size-4 mr-2" />
<:item title={gettext("Street")}>{@member.street}</:item> {gettext("Contact Data")}
<:item title={gettext("House Number")}>{@member.house_number}</:item> </button>
<:item title={gettext("Postal Code")}>{@member.postal_code}</:item> <button role="tab" class="tab" disabled aria-disabled="true" title={gettext("Coming soon")}>
<:item title={gettext("Linked User")}> <.icon name="hero-credit-card" class="size-4 mr-2" />
{gettext("Payments")}
</button>
</div>
<%!-- Personal Data and Custom Fields Row --%>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
<%!-- Personal Data Section --%>
<div>
<.section_box title={gettext("Personal Data")}>
<div class="space-y-4">
<%!-- Name Row --%>
<div class="flex gap-6">
<.data_field label={gettext("First Name")} value={@member.first_name} class="w-48" />
<.data_field label={gettext("Last Name")} value={@member.last_name} class="w-48" />
</div>
<%!-- Address --%>
<div>
<.data_field label={gettext("Address")} value={format_address(@member)} />
</div>
<%!-- Email --%>
<div>
<.data_field label={gettext("Email")}>
<a
href={"mailto:#{MvWeb.MemberLive.Index.format_member_email(@member)}"}
class="text-blue-700 hover:text-blue-800 underline"
>
{@member.email}
</a>
</.data_field>
</div>
<%!-- Phone --%>
<div>
<.data_field label={gettext("Phone")} value={@member.phone_number} />
</div>
<%!-- Membership Dates Row --%>
<div class="flex gap-6">
<.data_field
label={gettext("Join Date")}
value={format_date(@member.join_date)}
class="w-28"
/>
<.data_field
label={gettext("Exit Date")}
value={format_date(@member.exit_date)}
class="w-28"
/>
</div>
<%!-- Linked User --%>
<div>
<.data_field label={gettext("Linked User")}>
<%= if @member.user do %> <%= if @member.user do %>
<.link <.link
navigate={~p"/users/#{@member.user}"} navigate={~p"/users/#{@member.user}"}
class="text-blue-600 hover:text-blue-800 underline" class="text-blue-700 hover:text-blue-800 underline inline-flex items-center gap-1"
> >
<.icon name="hero-user" class="h-4 w-4 inline mr-1" /> <.icon name="hero-user" class="size-4" />
{@member.user.email} {@member.user.email}
</.link> </.link>
<% else %> <% else %>
<span class="text-gray-500 italic">{gettext("No user linked")}</span> <span class="text-base-content/70 italic">{gettext("No user linked")}</span>
<% end %> <% end %>
</:item> </.data_field>
</.list> </div>
<h3 class="mt-8 mb-2 text-lg font-semibold">{gettext("Custom Field Values")}</h3> <%!-- Notes --%>
<.generic_list items={ <%= if @member.notes && String.trim(@member.notes) != "" do %>
Enum.map(@member.custom_field_values, fn cfv -> <div>
{ <.data_field label={gettext("Notes")}>
# name <p class="whitespace-pre-wrap text-base-content/80">{@member.notes}</p>
cfv.custom_field && cfv.custom_field.name, </.data_field>
# value </div>
format_custom_field_value(cfv) <% end %>
} </div>
end) </.section_box>
} /> </div>
<%!-- Custom Fields Section --%>
<%= if Enum.any?(@member.custom_field_values) do %>
<div>
<.section_box title={gettext("Custom Fields")}>
<div class="grid grid-cols-2 gap-4">
<%= for cfv <- sort_custom_field_values(@member.custom_field_values) do %>
<% custom_field = cfv.custom_field %>
<% value_type = custom_field && custom_field.value_type %>
<.data_field label={custom_field && custom_field.name}>
{format_custom_field_value(cfv.value, value_type)}
</.data_field>
<% end %>
</div>
</.section_box>
</div>
<% end %>
</div>
<%!-- Payment Data Section (Mockup) --%>
<div class="max-w-xl">
<.section_box title={gettext("Payment Data")}>
<div role="alert" class="alert alert-info mb-4">
<.icon name="hero-information-circle" class="size-5" />
<span>{gettext("This data is for demonstration purposes only (mockup).")}</span>
</div>
<div class="flex gap-6">
<.data_field label={gettext("Contribution")} value="72 €" class="w-24" />
<.data_field label={gettext("Payment Cycle")} value={gettext("monthly")} class="w-28" />
<.data_field label={gettext("Paid")} class="w-24">
<%= if @member.paid do %>
<span class="badge badge-success">{gettext("Paid")}</span>
<% else %>
<span class="badge badge-warning">{gettext("Pending")}</span>
<% end %>
</.data_field>
</div>
</.section_box>
</div>
</Layouts.app> </Layouts.app>
""" """
end end
@ -113,16 +196,119 @@ defmodule MvWeb.MemberLive.Show do
defp page_title(:show), do: gettext("Show Member") defp page_title(:show), do: gettext("Show Member")
defp page_title(:edit), do: gettext("Edit Member") defp page_title(:edit), do: gettext("Edit Member")
defp format_custom_field_value(cfv) do # -----------------------------------------------------------------
value = # Helper Components
case cfv.value do # -----------------------------------------------------------------
%{value: v} -> v
v -> v # Renders a section box with border and title.
attr :title, :string, required: true
slot :inner_block, required: true
defp section_box(assigns) do
~H"""
<section class="mb-6">
<h2 class="text-lg font-semibold mb-3">{@title}</h2>
<div class="border border-base-300 rounded-lg p-4 bg-base-100">
{render_slot(@inner_block)}
</div>
</section>
"""
end end
case value do # Renders a labeled data field.
%Date{} = date -> DateFormatter.format_date(date) attr :label, :string, required: true
other -> other attr :value, :string, default: nil
attr :class, :string, default: ""
slot :inner_block
defp data_field(assigns) do
~H"""
<dl class={@class}>
<dt class="text-sm font-medium text-base-content/70">{@label}</dt>
<dd class="mt-1 text-base-content">
<%= if @inner_block != [] do %>
{render_slot(@inner_block)}
<% else %>
{display_value(@value)}
<% end %>
</dd>
</dl>
"""
end
# -----------------------------------------------------------------
# Helper Functions
# -----------------------------------------------------------------
defp display_value(nil), do: ""
defp display_value(""), do: ""
defp display_value(value), do: value
defp format_address(member) do
street_part =
[member.street, member.house_number]
|> Enum.filter(&(&1 && &1 != ""))
|> Enum.join(" ")
city_part =
[member.postal_code, member.city]
|> Enum.filter(&(&1 && &1 != ""))
|> Enum.join(" ")
[street_part, city_part]
|> Enum.filter(&(&1 != ""))
|> Enum.join(", ")
|> case do
"" -> nil
address -> address
end end
end end
defp format_date(nil), do: nil
defp format_date(%Date{} = date) do
Calendar.strftime(date, "%d.%m.%Y")
end
defp format_date(date), do: to_string(date)
# Sorts custom field values by custom field name
defp sort_custom_field_values(custom_field_values) do
Enum.sort_by(custom_field_values, fn cfv ->
(cfv.custom_field && cfv.custom_field.name) || ""
end)
end
# Formats custom field value based on type
defp format_custom_field_value(%Ash.Union{value: value, type: type}, _expected_type) do
format_custom_field_value(value, type)
end
defp format_custom_field_value(nil, _type), do: ""
defp format_custom_field_value(value, :boolean) when is_boolean(value) do
if value, do: gettext("Yes"), else: gettext("No")
end
defp format_custom_field_value(%Date{} = date, :date) do
Calendar.strftime(date, "%d.%m.%Y")
end
defp format_custom_field_value(value, :email) when is_binary(value) do
assigns = %{email: value}
~H"""
<a href={"mailto:#{@email}"} class="text-blue-700 hover:text-blue-800 underline">{@email}</a>
"""
end
defp format_custom_field_value(value, :integer) when is_integer(value) do
Integer.to_string(value)
end
defp format_custom_field_value(value, _type) when is_binary(value) do
if String.trim(value) == "", do: "", else: value
end
defp format_custom_field_value(value, _type), do: to_string(value)
end end

View file

@ -12,7 +12,8 @@ defmodule Mv.MixProject do
compilers: [:phoenix_live_view] ++ Mix.compilers(), compilers: [:phoenix_live_view] ++ Mix.compilers(),
aliases: aliases(), aliases: aliases(),
deps: deps(), deps: deps(),
listeners: [Phoenix.CodeReloader] listeners: [Phoenix.CodeReloader],
gettext: [write_reference_line_numbers: false]
] ]
end end

View file

@ -36,7 +36,7 @@ msgstr ""
msgid "Need an account?" msgid "Need an account?"
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:268 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen #, elixir-autogen
msgid "Password" msgid "Password"
msgstr "" msgstr ""
@ -65,78 +65,77 @@ msgstr ""
msgid "Your password has successfully been reset" msgid "Your password has successfully been reset"
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:254 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "An account with email %{email} already exists. Please enter your password to link your OIDC account." msgid "An account with email %{email} already exists. Please enter your password to link your OIDC account."
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:289 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Cancel" msgid "Cancel"
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:163 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Incorrect password. Please try again." msgid "Incorrect password. Please try again."
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:37 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Invalid session. Please try again." msgid "Invalid session. Please try again."
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:281 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Link Account" msgid "Link Account"
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:252 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Link OIDC Account" msgid "Link OIDC Account"
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:280 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Linking..." msgid "Linking..."
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:40 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Session expired. Please try again." msgid "Session expired. Please try again."
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:209 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Your OIDC account has been successfully linked! Redirecting to complete sign-in..." msgid "Your OIDC account has been successfully linked! Redirecting to complete sign-in..."
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:76 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Account activated! Redirecting to complete sign-in..." msgid "Account activated! Redirecting to complete sign-in..."
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:119 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#: lib/mv_web/live/auth/link_oidc_account_live.ex:123
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Failed to link account. Please try again or contact support." msgid "Failed to link account. Please try again or contact support."
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:108 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "The email address from your OIDC provider is already registered to another account. Please change your email in the identity provider or contact support." msgid "The email address from your OIDC provider is already registered to another account. Please change your email in the identity provider or contact support."
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:98 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "This OIDC account is already linked to another user. Please contact support." msgid "This OIDC account is already linked to another user. Please contact support."
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:235 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Language selection" msgid "Language selection"
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:242 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Select language" msgid "Select language"
msgstr "" msgstr ""

View file

@ -35,7 +35,7 @@ msgstr "Falls diese*r Benutzer*in bekannt ist, wird jetzt eine Email mit einer A
msgid "Need an account?" msgid "Need an account?"
msgstr "Konto anlegen?" msgstr "Konto anlegen?"
#: lib/mv_web/live/auth/link_oidc_account_live.ex:268 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen #, elixir-autogen
msgid "Password" msgid "Password"
msgstr "Passwort" msgstr "Passwort"
@ -64,78 +64,77 @@ msgstr "Anmelden..."
msgid "Your password has successfully been reset" msgid "Your password has successfully been reset"
msgstr "Das Passwort wurde erfolgreich zurückgesetzt" msgstr "Das Passwort wurde erfolgreich zurückgesetzt"
#: lib/mv_web/live/auth/link_oidc_account_live.ex:254 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "An account with email %{email} already exists. Please enter your password to link your OIDC account." msgid "An account with email %{email} already exists. Please enter your password to link your OIDC account."
msgstr "Ein Konto mit der E-Mail %{email} existiert bereits. Bitte geben Sie Ihr Passwort ein, um Ihr OIDC-Konto zu verknüpfen." msgstr "Ein Konto mit der E-Mail %{email} existiert bereits. Bitte geben Sie Ihr Passwort ein, um Ihr OIDC-Konto zu verknüpfen."
#: lib/mv_web/live/auth/link_oidc_account_live.ex:289 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Cancel" msgid "Cancel"
msgstr "Abbrechen" msgstr "Abbrechen"
#: lib/mv_web/live/auth/link_oidc_account_live.ex:163 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Incorrect password. Please try again." msgid "Incorrect password. Please try again."
msgstr "Falsches Passwort. Bitte versuchen Sie es erneut." msgstr "Falsches Passwort. Bitte versuchen Sie es erneut."
#: lib/mv_web/live/auth/link_oidc_account_live.ex:37 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Invalid session. Please try again." msgid "Invalid session. Please try again."
msgstr "Ungültige Sitzung. Bitte versuchen Sie es erneut." msgstr "Ungültige Sitzung. Bitte versuchen Sie es erneut."
#: lib/mv_web/live/auth/link_oidc_account_live.ex:281 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Link Account" msgid "Link Account"
msgstr "Konto verknüpfen" msgstr "Konto verknüpfen"
#: lib/mv_web/live/auth/link_oidc_account_live.ex:252 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Link OIDC Account" msgid "Link OIDC Account"
msgstr "OIDC-Konto verknüpfen" msgstr "OIDC-Konto verknüpfen"
#: lib/mv_web/live/auth/link_oidc_account_live.ex:280 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Linking..." msgid "Linking..."
msgstr "Verknüpfen..." msgstr "Verknüpfen..."
#: lib/mv_web/live/auth/link_oidc_account_live.ex:40 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Session expired. Please try again." msgid "Session expired. Please try again."
msgstr "Sitzung abgelaufen. Bitte versuchen Sie es erneut." msgstr "Sitzung abgelaufen. Bitte versuchen Sie es erneut."
#: lib/mv_web/live/auth/link_oidc_account_live.ex:209 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Your OIDC account has been successfully linked! Redirecting to complete sign-in..." msgid "Your OIDC account has been successfully linked! Redirecting to complete sign-in..."
msgstr "Ihr OIDC-Konto wurde erfolgreich verknüpft! Sie werden zur Anmeldung weitergeleitet..." msgstr "Ihr OIDC-Konto wurde erfolgreich verknüpft! Sie werden zur Anmeldung weitergeleitet..."
#: lib/mv_web/live/auth/link_oidc_account_live.ex:76 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Account activated! Redirecting to complete sign-in..." msgid "Account activated! Redirecting to complete sign-in..."
msgstr "Konto aktiviert! Sie werden zur Anmeldung weitergeleitet..." msgstr "Konto aktiviert! Sie werden zur Anmeldung weitergeleitet..."
#: lib/mv_web/live/auth/link_oidc_account_live.ex:119 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#: lib/mv_web/live/auth/link_oidc_account_live.ex:123
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Failed to link account. Please try again or contact support." msgid "Failed to link account. Please try again or contact support."
msgstr "Verknüpfung des Kontos fehlgeschlagen. Bitte versuchen Sie es erneut oder kontaktieren Sie den Support." msgstr "Verknüpfung des Kontos fehlgeschlagen. Bitte versuchen Sie es erneut oder kontaktieren Sie den Support."
#: lib/mv_web/live/auth/link_oidc_account_live.ex:108 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "The email address from your OIDC provider is already registered to another account. Please change your email in the identity provider or contact support." msgid "The email address from your OIDC provider is already registered to another account. Please change your email in the identity provider or contact support."
msgstr "Die E-Mail-Adresse aus Ihrem OIDC-Provider ist bereits für ein anderes Konto registriert. Bitte ändern Sie Ihre E-Mail-Adresse im Identity-Provider oder kontaktieren Sie den Support." msgstr "Die E-Mail-Adresse aus Ihrem OIDC-Provider ist bereits für ein anderes Konto registriert. Bitte ändern Sie Ihre E-Mail-Adresse im Identity-Provider oder kontaktieren Sie den Support."
#: lib/mv_web/live/auth/link_oidc_account_live.ex:98 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "This OIDC account is already linked to another user. Please contact support." msgid "This OIDC account is already linked to another user. Please contact support."
msgstr "Dieses OIDC-Konto ist bereits mit einem anderen Benutzer verknüpft. Bitte kontaktieren Sie den Support." msgstr "Dieses OIDC-Konto ist bereits mit einem anderen Benutzer verknüpft. Bitte kontaktieren Sie den Support."
#: lib/mv_web/live/auth/link_oidc_account_live.ex:235 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Language selection" msgid "Language selection"
msgstr "Sprachauswahl" msgstr "Sprachauswahl"
#: lib/mv_web/live/auth/link_oidc_account_live.ex:242 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Select language" msgid "Select language"
msgstr "Sprache auswählen" msgstr "Sprache auswählen"

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -32,7 +32,7 @@ msgstr ""
msgid "Need an account?" msgid "Need an account?"
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:268 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen #, elixir-autogen
msgid "Password" msgid "Password"
msgstr "" msgstr ""
@ -61,78 +61,77 @@ msgstr ""
msgid "Your password has successfully been reset" msgid "Your password has successfully been reset"
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:254 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "An account with email %{email} already exists. Please enter your password to link your OIDC account." msgid "An account with email %{email} already exists. Please enter your password to link your OIDC account."
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:289 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Cancel" msgid "Cancel"
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:163 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Incorrect password. Please try again." msgid "Incorrect password. Please try again."
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:37 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Invalid session. Please try again." msgid "Invalid session. Please try again."
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:281 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Link Account" msgid "Link Account"
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:252 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Link OIDC Account" msgid "Link OIDC Account"
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:280 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Linking..." msgid "Linking..."
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:40 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Session expired. Please try again." msgid "Session expired. Please try again."
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:209 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Your OIDC account has been successfully linked! Redirecting to complete sign-in..." msgid "Your OIDC account has been successfully linked! Redirecting to complete sign-in..."
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:76 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Account activated! Redirecting to complete sign-in..." msgid "Account activated! Redirecting to complete sign-in..."
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:119 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#: lib/mv_web/live/auth/link_oidc_account_live.ex:123
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Failed to link account. Please try again or contact support." msgid "Failed to link account. Please try again or contact support."
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:108 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "The email address from your OIDC provider is already registered to another account. Please change your email in the identity provider or contact support." msgid "The email address from your OIDC provider is already registered to another account. Please change your email in the identity provider or contact support."
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:98 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "This OIDC account is already linked to another user. Please contact support." msgid "This OIDC account is already linked to another user. Please contact support."
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:235 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Language selection" msgid "Language selection"
msgstr "" msgstr ""
#: lib/mv_web/live/auth/link_oidc_account_live.ex:242 #: lib/mv_web/live/auth/link_oidc_account_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Select language" msgid "Select language"
msgstr "" msgstr ""

File diff suppressed because it is too large Load diff

View file

@ -16,8 +16,6 @@ defmodule MvWeb.Components.FieldVisibilityDropdownComponentTest do
assert has_element?(view, "button[phx-click='select_item'][phx-value-item='email']") assert has_element?(view, "button[phx-click='select_item'][phx-value-item='email']")
assert has_element?(view, "button[phx-click='select_all']") assert has_element?(view, "button[phx-click='select_all']")
assert has_element?(view, "button[phx-click='select_none']") assert has_element?(view, "button[phx-click='select_none']")
end end
end end
end end