OIDC-only sign-in, Vereinfacht connection test, locale defaults, and settings/docs cleanup #445

Merged
moritz merged 17 commits from feature/settings into main 2026-02-24 15:51:51 +01:00
18 changed files with 886 additions and 251 deletions
Showing only changes of commit 62b37b9aa2 - Show all commits

View file

@ -80,11 +80,11 @@ defmodule MvWeb.Layouts.Sidebar do
/> />
<% end %> <% end %>
<%= if can_access_page?(@current_user, PagePaths.membership_fee_types()) do %> <%= if can_access_page?(@current_user, PagePaths.groups()) do %>
<.menu_item <.menu_item
href={~p"/membership_fee_types"} href={~p"/groups"}
icon="hero-currency-euro" icon="hero-user-group"
label={gettext("Fee Types")} label={gettext("Groups")}
/> />
<% end %> <% end %>
@ -102,24 +102,26 @@ defmodule MvWeb.Layouts.Sidebar do
label={gettext("Administration")} label={gettext("Administration")}
testid="sidebar-administration" testid="sidebar-administration"
> >
<%= if can_access_page?(@current_user, PagePaths.users()) do %> <%= if can_access_page?(@current_user, PagePaths.settings()) do %>
<.menu_subitem href={~p"/users"} label={gettext("Users")} /> <.menu_subitem href={~p"/settings"} label={gettext("Basic settings")} />
<% end %> <% end %>
<%= if can_access_page?(@current_user, PagePaths.groups()) do %> <%= if can_access_page?(@current_user, PagePaths.admin_datafields()) do %>
<.menu_subitem href={~p"/groups"} label={gettext("Groups")} /> <.menu_subitem href={~p"/admin/datafields"} label={gettext("Datafields")} />
<% end %>
<%= if can_access_page?(@current_user, PagePaths.admin_roles()) do %>
<.menu_subitem href={~p"/admin/roles"} label={gettext("Roles")} />
<% end %> <% end %>
<%= if can_access_page?(@current_user, PagePaths.membership_fee_settings()) do %> <%= if can_access_page?(@current_user, PagePaths.membership_fee_settings()) do %>
<.menu_subitem <.menu_subitem
href={~p"/membership_fee_settings"} href={~p"/membership_fee_settings"}
label={gettext("Fee Settings")} label={gettext("Membership fee settings")}
/> />
<% end %> <% end %>
<%= if can_access_page?(@current_user, PagePaths.settings()) do %> <%= if can_access_page?(@current_user, PagePaths.admin_import()) do %>
<.menu_subitem href={~p"/admin/import"} label={gettext("Import")} /> <.menu_subitem href={~p"/admin/import"} label={gettext("Import")} />
<.menu_subitem href={~p"/settings"} label={gettext("Settings")} /> <% end %>
<%= if can_access_page?(@current_user, PagePaths.users()) do %>
<.menu_subitem href={~p"/users"} label={gettext("Users")} />
<% end %>
<%= if can_access_page?(@current_user, PagePaths.admin_roles()) do %>
<.menu_subitem href={~p"/admin/roles"} label={gettext("Roles")} />
<% end %> <% end %>
</.menu_group> </.menu_group>
<% end %> <% end %>

View file

@ -0,0 +1,132 @@
defmodule MvWeb.DatafieldsLive do
@moduledoc """
LiveView for managing member field visibility/required and custom fields (datafields).
Renders MemberFieldLive.IndexComponent and CustomFieldLive.IndexComponent.
Moved from GlobalSettingsLive (Memberdata section) to a dedicated page.
"""
use MvWeb, :live_view
alias Mv.Membership
on_mount {MvWeb.LiveHelpers, :ensure_user_role_loaded}
@impl true
def mount(_params, _session, socket) do
{:ok, settings} = Membership.get_settings()
{:ok,
socket
|> assign(:page_title, gettext("Datafields"))
|> assign(:settings, settings)
|> assign(:active_editing_section, nil)}
end
@impl true
def render(assigns) do
~H"""
<Layouts.app flash={@flash} current_user={@current_user} club_name={@settings.club_name}>
<.header>
{gettext("Datafields")}
<:subtitle>
{gettext("Configure member fields and custom data fields.")}
</:subtitle>
</.header>
<.form_section title={gettext("Member fields")}>
<.live_component
:if={@active_editing_section != :custom_fields}
module={MvWeb.MemberFieldLive.IndexComponent}
id="member-fields-component"
settings={@settings}
/>
</.form_section>
<.form_section title={gettext("Custom fields")}>
<.live_component
:if={@active_editing_section != :member_fields}
module={MvWeb.CustomFieldLive.IndexComponent}
id="custom-fields-component"
actor={@current_user}
/>
</.form_section>
</Layouts.app>
"""
end
@impl true
def handle_info({:custom_field_saved, _custom_field, action}, socket) do
send_update(MvWeb.CustomFieldLive.IndexComponent,
id: "custom-fields-component",
show_form: false
)
{:noreply,
socket
|> assign(:active_editing_section, nil)
|> put_flash(:info, gettext("Data field %{action} successfully", action: action))}
end
@impl true
def handle_info({:custom_field_deleted, _custom_field}, socket) do
{:noreply, put_flash(socket, :info, gettext("Data field deleted successfully"))}
end
@impl true
def handle_info({:custom_field_delete_error, error}, socket) do
{:noreply,
put_flash(
socket,
:error,
gettext("Failed to delete data field: %{error}", error: inspect(error))
)}
end
@impl true
def handle_info(:custom_field_slug_mismatch, socket) do
{:noreply, put_flash(socket, :error, gettext("Slug does not match. Deletion cancelled."))}
end
def handle_info({:custom_fields_load_error, _error}, socket) do
{:noreply,
put_flash(
socket,
:error,
gettext("Could not load data fields. Please check your permissions.")
)}
end
@impl true
def handle_info({:editing_section_changed, section}, socket) do
{:noreply, assign(socket, :active_editing_section, section)}
end
@impl true
def handle_info({:member_field_saved, _member_field, action}, socket) do
{:ok, updated_settings} = Membership.get_settings()
send_update(MvWeb.MemberFieldLive.IndexComponent,
id: "member-fields-component",
show_form: false,
settings: updated_settings
)
{:noreply,
socket
|> assign(:settings, updated_settings)
|> assign(:active_editing_section, nil)
|> put_flash(:info, gettext("Member field %{action} successfully", action: action))}
end
@impl true
def handle_info({:member_field_visibility_updated}, socket) do
{:ok, updated_settings} = Membership.get_settings()
send_update(MvWeb.MemberFieldLive.IndexComponent,
id: "member-fields-component",
settings: updated_settings
)
{:noreply, assign(socket, :settings, updated_settings)}
end
end

View file

@ -1,17 +1,23 @@
defmodule MvWeb.MembershipFeeSettingsLive do defmodule MvWeb.MembershipFeeSettingsLive do
@moduledoc """ @moduledoc """
LiveView for managing membership fee settings (Admin). LiveView for membership fee settings and fee types (Admin).
Allows administrators to configure: Combines:
- Default membership fee type for new members - Global settings (default fee type, include joining cycle)
- Whether to include the joining cycle in membership fee generation - Membership fee types table (CRUD links to new/edit routes; delete inline)
Examples and info are collapsible to save space.
""" """
use MvWeb, :live_view use MvWeb, :live_view
require Ash.Query
import MvWeb.LiveHelpers, only: [current_actor: 1] import MvWeb.LiveHelpers, only: [current_actor: 1]
alias Mv.Membership alias Mv.Membership
alias Mv.Membership.Member
alias Mv.MembershipFees
alias Mv.MembershipFees.MembershipFeeType alias Mv.MembershipFees.MembershipFeeType
alias MvWeb.Helpers.MembershipFeeHelpers
@impl true @impl true
def mount(_params, _session, socket) do def mount(_params, _session, socket) do
@ -23,11 +29,14 @@ defmodule MvWeb.MembershipFeeSettingsLive do
|> Ash.Query.sort(name: :asc) |> Ash.Query.sort(name: :asc)
|> Ash.read!(domain: Mv.MembershipFees, actor: actor) |> Ash.read!(domain: Mv.MembershipFees, actor: actor)
member_counts = load_member_counts(membership_fee_types, actor)
{:ok, {:ok,
socket socket
|> assign(:page_title, gettext("Membership Fee Settings")) |> assign(:page_title, gettext("Membership Fee Settings"))
|> assign(:settings, settings) |> assign(:settings, settings)
|> assign(:membership_fee_types, membership_fee_types) |> assign(:membership_fee_types, membership_fee_types)
|> assign(:member_counts, member_counts)
|> assign_form()} |> assign_form()}
end end
@ -81,6 +90,51 @@ defmodule MvWeb.MembershipFeeSettingsLive do
end end
end end
@impl true
def handle_event("delete", %{"id" => id}, socket) do
actor = current_actor(socket)
case Ash.get(MembershipFeeType, id, domain: MembershipFees, actor: actor) do
{:ok, fee_type} ->
case Ash.destroy(fee_type, domain: MembershipFees, actor: actor) do
:ok ->
updated_types = Enum.reject(socket.assigns.membership_fee_types, &(&1.id == id))
updated_counts = Map.delete(socket.assigns.member_counts, id)
{:noreply,
socket
|> assign(:membership_fee_types, updated_types)
|> assign(:member_counts, updated_counts)
|> put_flash(:info, gettext("Membership fee type deleted"))}
{:error, %Ash.Error.Forbidden{}} ->
{:noreply,
put_flash(
socket,
:error,
gettext("You do not have permission to delete this membership fee type")
)}
{:error, error} ->
{:noreply, put_flash(socket, :error, format_error(error))}
end
{:error, %Ash.Error.Query.NotFound{}} ->
{:noreply, put_flash(socket, :error, gettext("Membership fee type not found"))}
{:error, %Ash.Error.Forbidden{}} ->
{:noreply,
put_flash(
socket,
:error,
gettext("You do not have permission to access this membership fee type")
)}
{:error, error} ->
{:noreply, put_flash(socket, :error, format_error(error))}
end
end
@impl true @impl true
def render(assigns) do def render(assigns) do
~H""" ~H"""
@ -88,8 +142,13 @@ defmodule MvWeb.MembershipFeeSettingsLive do
<.header> <.header>
{gettext("Membership Fee Settings")} {gettext("Membership Fee Settings")}
<:subtitle> <:subtitle>
{gettext("Configure global settings for membership fees.")} {gettext("Configure global settings and fee types for membership fees.")}
</:subtitle> </:subtitle>
<:actions>
<.button variant="primary" navigate={~p"/membership_fee_settings/new_fee_type"}>
<.icon name="hero-plus" /> {gettext("New Membership Fee Type")}
</.button>
</:actions>
</.header> </.header>
<div class="grid gap-6 lg:grid-cols-2"> <div class="grid gap-6 lg:grid-cols-2">
@ -188,58 +247,169 @@ defmodule MvWeb.MembershipFeeSettingsLive do
</div> </div>
</div> </div>
<%!-- Examples Card --%> <%!-- Examples Card (collapsible) --%>
<div class="card bg-base-200"> <div class="card bg-base-200">
<div class="card-body"> <div class="card-body">
<h2 class="card-title"> <details class="group">
<.icon name="hero-light-bulb" class="size-5" /> <summary class="card-title cursor-pointer list-none flex items-center gap-2">
{gettext("Examples")} <.icon name="hero-chevron-right" class="size-5 transition group-open:rotate-90" />
</h2> <.icon name="hero-light-bulb" class="size-5" />
{gettext("Examples")}
</summary>
<.example_section <div class="pt-4 space-y-4">
title={gettext("Yearly Interval - Joining Cycle Included")} <.example_section
joining_date="15.03.2023" title={gettext("Yearly Interval - Joining Cycle Included")}
include_joining={true} joining_date="15.03.2023"
start_date="01.01.2023" include_joining={true}
periods={["2023", "2024", "2025"]} start_date="01.01.2023"
note={gettext("Member pays for the year they joined")} periods={["2023", "2024", "2025"]}
/> note={gettext("Member pays for the year they joined")}
/>
<div class="divider"></div> <div class="divider"></div>
<.example_section <.example_section
title={gettext("Yearly Interval - Joining Cycle Excluded")} title={gettext("Yearly Interval - Joining Cycle Excluded")}
joining_date="15.03.2023" joining_date="15.03.2023"
include_joining={false} include_joining={false}
start_date="01.01.2024" start_date="01.01.2024"
periods={["2024", "2025"]} periods={["2024", "2025"]}
note={gettext("Member pays from the next full year")} note={gettext("Member pays from the next full year")}
/> />
<div class="divider"></div> <div class="divider"></div>
<.example_section <.example_section
title={gettext("Quarterly Interval - Joining Cycle Excluded")} title={gettext("Quarterly Interval - Joining Cycle Excluded")}
joining_date="15.05.2024" joining_date="15.05.2024"
include_joining={false} include_joining={false}
start_date="01.07.2024" start_date="01.07.2024"
periods={["Q3/2024", "Q4/2024", "Q1/2025"]} periods={["Q3/2024", "Q4/2024", "Q1/2025"]}
note={gettext("Member pays from the next full quarter")} note={gettext("Member pays from the next full quarter")}
/> />
<div class="divider"></div> <div class="divider"></div>
<.example_section <.example_section
title={gettext("Monthly Interval - Joining Cycle Included")} title={gettext("Monthly Interval - Joining Cycle Included")}
joining_date="15.03.2024" joining_date="15.03.2024"
include_joining={true} include_joining={true}
start_date="01.03.2024" start_date="01.03.2024"
periods={["03/2024", "04/2024", "05/2024", "..."]} periods={["03/2024", "04/2024", "05/2024", "..."]}
note={gettext("Member pays from the joining month")} note={gettext("Member pays from the joining month")}
/> />
</div>
</details>
</div> </div>
</div> </div>
</div> </div>
<%!-- Fee Types Table --%>
<div class="mt-8">
<h2 class="text-lg font-semibold mb-4">{gettext("Membership Fee Types")}</h2>
<.table
id="membership_fee_types"
rows={@membership_fee_types}
row_id={fn mft -> "mft-#{mft.id}" end}
>
<:col :let={mft} label={gettext("Name")}>
<span class="font-medium">{mft.name}</span>
<p :if={mft.description} class="text-sm text-base-content/70">{mft.description}</p>
</:col>
<:col :let={mft} label={gettext("Amount")}>
<span class="font-mono">{MembershipFeeHelpers.format_currency(mft.amount)}</span>
</:col>
<:col :let={mft} label={gettext("Interval")}>
<span class="badge badge-outline">
{MembershipFeeHelpers.format_interval(mft.interval)}
</span>
</:col>
<:col :let={mft} label={gettext("Members")}>
<span class="badge badge-ghost">{get_member_count(mft, @member_counts)}</span>
</:col>
<:action :let={mft}>
<.link
navigate={~p"/membership_fee_settings/#{mft.id}/edit_fee_type"}
class="btn btn-ghost btn-xs"
aria-label={gettext("Edit membership fee type")}
>
<.icon name="hero-pencil" class="size-4" />
</.link>
</:action>
<:action :let={mft}>
<div
:if={get_member_count(mft, @member_counts) > 0}
class="tooltip tooltip-left"
data-tip={
gettext("Cannot delete - %{count} member(s) assigned",
count: get_member_count(mft, @member_counts)
)
}
>
<button
phx-click="delete"
phx-value-id={mft.id}
data-confirm={gettext("Are you sure?")}
class="btn btn-ghost btn-xs text-error opacity-50 cursor-not-allowed"
aria-label={
gettext("Cannot delete - %{count} member(s) assigned",
count: get_member_count(mft, @member_counts)
)
}
disabled={true}
>
<.icon name="hero-trash" class="size-4" />
</button>
</div>
<button
:if={get_member_count(mft, @member_counts) == 0}
phx-click="delete"
phx-value-id={mft.id}
data-confirm={gettext("Are you sure?")}
class="btn btn-ghost btn-xs text-error"
aria-label={gettext("Delete Membership Fee Type")}
>
<.icon name="hero-trash" class="size-4" />
</button>
</:action>
</.table>
<details class="mt-6 card bg-base-200">
<summary class="card-body cursor-pointer list-none card-title">
<.icon name="hero-information-circle" class="size-5" />
{gettext("About Membership Fee Types")}
</summary>
<div class="card-body pt-0 prose prose-sm max-w-none">
<p>
{gettext(
"Membership fee types define different membership fee structures. Each type has a fixed interval (monthly, quarterly, half-yearly, yearly) that cannot be changed after creation."
)}
</p>
<ul>
<li>
<strong>{gettext("Name & Amount")}</strong>
- {gettext("Can be changed at any time. Amount changes affect future periods only.")}
</li>
<li>
<strong>{gettext("Interval")}</strong>
- {gettext(
"Fixed after creation. Members can only switch between types with the same interval."
)}
</li>
<li>
<strong>{gettext("Deletion")}</strong>
- {gettext("Only possible if no members are assigned to this type.")}
</li>
</ul>
</div>
</details>
</div>
</Layouts.app> </Layouts.app>
""" """
end end
@ -286,6 +456,32 @@ defmodule MvWeb.MembershipFeeSettingsLive do
defp format_interval(:half_yearly), do: gettext("Half-yearly") defp format_interval(:half_yearly), do: gettext("Half-yearly")
defp format_interval(:yearly), do: gettext("Yearly") defp format_interval(:yearly), do: gettext("Yearly")
defp load_member_counts(fee_types, actor) do
fee_type_ids = Enum.map(fee_types, & &1.id)
members =
Member
|> Ash.Query.filter(membership_fee_type_id in ^fee_type_ids)
|> Ash.Query.select([:membership_fee_type_id])
|> Ash.read!(domain: Membership, actor: actor)
members
|> Enum.group_by(& &1.membership_fee_type_id)
|> Enum.map(fn {fee_type_id, members_list} -> {fee_type_id, length(members_list)} end)
|> Map.new()
end
defp get_member_count(fee_type, member_counts) do
Map.get(member_counts, fee_type.id, 0)
end
defp format_error(%Ash.Error.Invalid{} = error) do
Enum.map_join(error.errors, ", ", fn e -> e.message end)
end
defp format_error(error) when is_binary(error), do: error
defp format_error(_error), do: gettext("An error occurred")
defp assign_form(%{assigns: %{settings: settings}} = socket) do defp assign_form(%{assigns: %{settings: settings}} = socket) do
form = form =
AshPhoenix.Form.for_update( AshPhoenix.Form.for_update(

View file

@ -384,7 +384,8 @@ defmodule MvWeb.MembershipFeeTypeLive.Form do
defp format_interval_value(value), do: to_string(value) defp format_interval_value(value), do: to_string(value)
@spec return_path(String.t(), MembershipFeeType.t() | nil) :: String.t() @spec return_path(String.t(), MembershipFeeType.t() | nil) :: String.t()
defp return_path("index", _membership_fee_type), do: ~p"/membership_fee_types" defp return_path("index", _membership_fee_type), do: ~p"/membership_fee_settings"
defp return_path(_, _), do: ~p"/membership_fee_settings"
@spec get_affected_member_count(String.t(), Mv.Accounts.User.t() | nil) :: non_neg_integer() @spec get_affected_member_count(String.t(), Mv.Accounts.User.t() | nil) :: non_neg_integer()
# Checks if amount changed and updates socket assigns accordingly # Checks if amount changed and updates socket assigns accordingly

View file

@ -47,7 +47,7 @@ defmodule MvWeb.MembershipFeeTypeLive.Index do
{gettext("Manage membership fee types for membership fees.")} {gettext("Manage membership fee types for membership fees.")}
</:subtitle> </:subtitle>
<:actions> <:actions>
<.button variant="primary" navigate={~p"/membership_fee_types/new"}> <.button variant="primary" navigate={~p"/membership_fee_settings/new_fee_type"}>
<.icon name="hero-plus" /> {gettext("New Membership Fee Type")} <.icon name="hero-plus" /> {gettext("New Membership Fee Type")}
</.button> </.button>
</:actions> </:actions>
@ -79,7 +79,7 @@ defmodule MvWeb.MembershipFeeTypeLive.Index do
<:action :let={mft}> <:action :let={mft}>
<.link <.link
navigate={~p"/membership_fee_types/#{mft.id}/edit"} navigate={~p"/membership_fee_settings/#{mft.id}/edit_fee_type"}
class="btn btn-ghost btn-xs" class="btn btn-ghost btn-xs"
aria-label={gettext("Edit membership fee type")} aria-label={gettext("Edit membership fee type")}
> >

View file

@ -8,30 +8,30 @@ defmodule MvWeb.PagePaths do
# Sidebar top-level menu paths # Sidebar top-level menu paths
@members "/members" @members "/members"
@membership_fee_types "/membership_fee_types"
@statistics "/statistics" @statistics "/statistics"
# Administration submenu paths (all must match router) # Administration submenu paths (all must match router)
@users "/users" @users "/users"
@groups "/groups" @groups "/groups"
@admin_roles "/admin/roles" @admin_roles "/admin/roles"
@admin_datafields "/admin/datafields"
@membership_fee_settings "/membership_fee_settings" @membership_fee_settings "/membership_fee_settings"
@admin_import "/admin/import"
@settings "/settings" @settings "/settings"
@admin_page_paths [ @admin_page_paths [
@users, @users,
@groups, @groups,
@admin_roles, @admin_roles,
@admin_datafields,
@membership_fee_settings, @membership_fee_settings,
@admin_import,
@settings @settings
] ]
@doc "Path for Members index (sidebar and page permission check)." @doc "Path for Members index (sidebar and page permission check)."
def members, do: @members def members, do: @members
@doc "Path for Membership Fee Types index (sidebar and page permission check)."
def membership_fee_types, do: @membership_fee_types
@doc "Path for Statistics page (sidebar and page permission check)." @doc "Path for Statistics page (sidebar and page permission check)."
def statistics, do: @statistics def statistics, do: @statistics
@ -41,6 +41,8 @@ defmodule MvWeb.PagePaths do
def users, do: @users def users, do: @users
def groups, do: @groups def groups, do: @groups
def admin_roles, do: @admin_roles def admin_roles, do: @admin_roles
def admin_datafields, do: @admin_datafields
def membership_fee_settings, do: @membership_fee_settings def membership_fee_settings, do: @membership_fee_settings
def admin_import, do: @admin_import
def settings, do: @settings def settings, do: @settings
end end

View file

@ -68,16 +68,13 @@ defmodule MvWeb.Router do
live "/settings", GlobalSettingsLive live "/settings", GlobalSettingsLive
# Membership Fee Settings # Membership Fee Settings (includes fee types list; new/edit under sub-routes)
live "/membership_fee_settings", MembershipFeeSettingsLive live "/membership_fee_settings", MembershipFeeSettingsLive
live "/membership_fee_settings/new_fee_type", MembershipFeeTypeLive.Form, :new
# Membership Fee Types Management live "/membership_fee_settings/:id/edit_fee_type", MembershipFeeTypeLive.Form, :edit
live "/membership_fee_types", MembershipFeeTypeLive.Index, :index
# Statistics # Statistics
live "/statistics", StatisticsLive, :index live "/statistics", StatisticsLive, :index
live "/membership_fee_types/new", MembershipFeeTypeLive.Form, :new
live "/membership_fee_types/:id/edit", MembershipFeeTypeLive.Form, :edit
# Groups Management # Groups Management
live "/groups", GroupLive.Index, :index live "/groups", GroupLive.Index, :index
@ -91,6 +88,9 @@ defmodule MvWeb.Router do
live "/admin/roles/:id", RoleLive.Show, :show live "/admin/roles/:id", RoleLive.Show, :show
live "/admin/roles/:id/edit", RoleLive.Form, :edit live "/admin/roles/:id/edit", RoleLive.Form, :edit
# Datafields (member fields + custom fields)
live "/admin/datafields", DatafieldsLive
# Import (Admin only) # Import (Admin only)
live "/admin/import", ImportLive live "/admin/import", ImportLive

View file

@ -18,6 +18,7 @@ msgid "Actions"
msgstr "Aktionen" msgstr "Aktionen"
#: lib/mv_web/live/member_live/index.html.heex #: lib/mv_web/live/member_live/index.html.heex
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#: lib/mv_web/live/role_live/index.html.heex #: lib/mv_web/live/role_live/index.html.heex
#: lib/mv_web/live/role_live/show.ex #: lib/mv_web/live/role_live/show.ex
@ -322,6 +323,7 @@ msgstr "Benutzer*innen auflisten"
#: lib/mv_web/live/group_live/show.ex #: lib/mv_web/live/group_live/show.ex
#: lib/mv_web/live/member_live/index.ex #: lib/mv_web/live/member_live/index.ex
#: lib/mv_web/live/member_live/index.html.heex #: lib/mv_web/live/member_live/index.html.heex
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#: lib/mv_web/live/statistics_live.ex #: lib/mv_web/live/statistics_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -335,6 +337,7 @@ msgstr "Mitglieder"
#: lib/mv_web/live/group_live/show.ex #: lib/mv_web/live/group_live/show.ex
#: lib/mv_web/live/member_field_live/form_component.ex #: lib/mv_web/live/member_field_live/form_component.ex
#: lib/mv_web/live/member_field_live/index_component.ex #: lib/mv_web/live/member_field_live/index_component.ex
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/form.ex #: lib/mv_web/live/membership_fee_type_live/form.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#: lib/mv_web/live/role_live/form.ex #: lib/mv_web/live/role_live/form.ex
@ -382,7 +385,6 @@ msgstr "Alle Mitglieder auswählen"
msgid "Select member" msgid "Select member"
msgstr "Mitglied auswählen" msgstr "Mitglied auswählen"
#: lib/mv_web/components/layouts/sidebar.ex
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Settings" msgid "Settings"
@ -842,6 +844,7 @@ msgid "Create Member"
msgstr "Mitglied erstellen" msgstr "Mitglied erstellen"
#: lib/mv_web/live/member_live/show/membership_fees_component.ex #: lib/mv_web/live/member_live/show/membership_fees_component.ex
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/form.ex #: lib/mv_web/live/membership_fee_type_live/form.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -853,11 +856,13 @@ msgstr "Betrag"
msgid "Back to Settings" msgid "Back to Settings"
msgstr "Zurück zu den Einstellungen" msgstr "Zurück zu den Einstellungen"
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Can be changed at any time. Amount changes affect future periods only." msgid "Can be changed at any time. Amount changes affect future periods only."
msgstr "Kann jederzeit geändert werden. Änderungen des Betrags betreffen nur zukünftige Zyklen." msgstr "Kann jederzeit geändert werden. Änderungen des Betrags betreffen nur zukünftige Zyklen."
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "Deletion" msgid "Deletion"
@ -868,6 +873,7 @@ msgstr "Löschen"
msgid "Examples" msgid "Examples"
msgstr "Beispiele" msgstr "Beispiele"
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Fixed after creation. Members can only switch between types with the same interval." msgid "Fixed after creation. Members can only switch between types with the same interval."
@ -886,6 +892,7 @@ msgid "Half-yearly"
msgstr "Halbjährlich" msgstr "Halbjährlich"
#: lib/mv_web/live/member_live/show/membership_fees_component.ex #: lib/mv_web/live/member_live/show/membership_fees_component.ex
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/form.ex #: lib/mv_web/live/membership_fee_type_live/form.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -924,11 +931,13 @@ msgstr "Mitglied zahlt ab dem nächsten vollständigen Jahr"
msgid "Monthly" msgid "Monthly"
msgstr "Monatlich" msgstr "Monatlich"
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Name & Amount" msgid "Name & Amount"
msgstr "Name & Betrag" msgstr "Name & Betrag"
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Only possible if no members are assigned to this type." msgid "Only possible if no members are assigned to this type."
@ -1002,7 +1011,7 @@ msgstr "Alle auswählen"
msgid "Select none" msgid "Select none"
msgstr "Keine auswählen" msgstr "Keine auswählen"
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Slug does not match. Deletion cancelled." msgid "Slug does not match. Deletion cancelled."
msgstr "Eingegebener Text war nicht korrekt. Vorgang abgebrochen." msgstr "Eingegebener Text war nicht korrekt. Vorgang abgebrochen."
@ -1044,11 +1053,6 @@ msgstr "Textfeld"
msgid "Yes/No-Selection" msgid "Yes/No-Selection"
msgstr "Ja/Nein-Auswahl" msgstr "Ja/Nein-Auswahl"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Memberdata"
msgstr "Mitgliederdaten"
#: lib/mv_web/live/custom_field_live/index_component.ex #: lib/mv_web/live/custom_field_live/index_component.ex
#: lib/mv_web/live/member_field_live/index_component.ex #: lib/mv_web/live/member_field_live/index_component.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -1060,7 +1064,7 @@ msgstr "Optional"
msgid "These fields are neccessary for MILA to handle member identification and payment calculations in the future. Thus you cannot delete these fields but hide them in the member overview." msgid "These fields are neccessary for MILA to handle member identification and payment calculations in the future. Thus you cannot delete these fields but hide them in the member overview."
msgstr "Diese Datenfelder sind für MILA notwendig um Mitglieder zu identifizieren und zukünftig Beitragszahlungen zu berechnen. Aus diesem Grund können sie nicht gelöscht, aber in der Übersicht ausgeblendet werden." msgstr "Diese Datenfelder sind für MILA notwendig um Mitglieder zu identifizieren und zukünftig Beitragszahlungen zu berechnen. Aus diesem Grund können sie nicht gelöscht, aber in der Übersicht ausgeblendet werden."
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Member field %{action} successfully" msgid "Member field %{action} successfully"
msgstr "Mitgliedsfeld wurde erfolgreich %{action}" msgstr "Mitgliedsfeld wurde erfolgreich %{action}"
@ -1070,6 +1074,7 @@ msgstr "Mitgliedsfeld wurde erfolgreich %{action}"
msgid "A cycle for this period already exists" msgid "A cycle for this period already exists"
msgstr "Ein Zyklus für diesen Zeitraum existiert bereits" msgstr "Ein Zyklus für diesen Zeitraum existiert bereits"
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "About Membership Fee Types" msgid "About Membership Fee Types"
@ -1086,6 +1091,7 @@ msgid "Already paid cycles will remain with the old amount."
msgstr "Bereits bezahlte Zyklen bleiben mit dem alten Betrag." msgstr "Bereits bezahlte Zyklen bleiben mit dem alten Betrag."
#: lib/mv_web/live/member_live/show/membership_fees_component.ex #: lib/mv_web/live/member_live/show/membership_fees_component.ex
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#: lib/mv_web/live/role_live/helpers.ex #: lib/mv_web/live/role_live/helpers.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -1097,6 +1103,7 @@ msgstr "Ein Fehler ist aufgetreten"
msgid "Are you sure you want to delete this cycle?" msgid "Are you sure you want to delete this cycle?"
msgstr "Möchtest du diesen Zyklus wirklich löschen?" msgstr "Möchtest du diesen Zyklus wirklich löschen?"
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Cannot delete - %{count} member(s) assigned" msgid "Cannot delete - %{count} member(s) assigned"
@ -1117,11 +1124,6 @@ msgstr "Die Änderung des Betrags betrifft %{count} Mitglied(er)."
msgid "Click to edit amount" msgid "Click to edit amount"
msgstr "Klicke, um den Betrag zu bearbeiten" msgstr "Klicke, um den Betrag zu bearbeiten"
#: lib/mv_web/live/membership_fee_settings_live.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Configure global settings for membership fees."
msgstr "Globale Einstellungen für Mitgliedsbeiträge konfigurieren."
#: lib/mv_web/live/membership_fee_type_live/form.ex #: lib/mv_web/live/membership_fee_type_live/form.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Confirm Change" msgid "Confirm Change"
@ -1232,6 +1234,7 @@ msgstr "Feld bearbeiten: %{field}"
msgid "Edit Membership Fee Type" msgid "Edit Membership Fee Type"
msgstr "Mitgliedsbeitragsart bearbeiten" msgstr "Mitgliedsbeitragsart bearbeiten"
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "Edit membership fee type" msgid "Edit membership fee type"
@ -1330,6 +1333,7 @@ msgstr "Mitgliedsbeitragsstatus"
msgid "Membership Fee Type" msgid "Membership Fee Type"
msgstr "Mitgliedsbeitragsart" msgstr "Mitgliedsbeitragsart"
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Membership Fee Types" msgid "Membership Fee Types"
@ -1346,6 +1350,7 @@ msgstr "Mitgliedsbeiträge"
msgid "Membership fee start" msgid "Membership fee start"
msgstr "Beitragsbeginn" msgstr "Beitragsbeginn"
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Membership fee type deleted" msgid "Membership fee type deleted"
@ -1366,6 +1371,7 @@ msgstr "Mitgliedsbeitragsart erfolgreich gespeichert"
msgid "Membership fee type updated. Cycles regenerated." msgid "Membership fee type updated. Cycles regenerated."
msgstr "Mitgliedsbeitragsart aktualisiert. Zyklen regeneriert." msgstr "Mitgliedsbeitragsart aktualisiert. Zyklen regeneriert."
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "Membership fee types define different membership fee structures. Each type has a fixed interval (monthly, quarterly, half-yearly, yearly) that cannot be changed after creation." msgid "Membership fee types define different membership fee structures. Each type has a fixed interval (monthly, quarterly, half-yearly, yearly) that cannot be changed after creation."
@ -1376,6 +1382,7 @@ msgstr "Mitgliedsbeitragsarten definieren verschiedene Mitgliedsbeitragsstruktur
msgid "Monthly Interval - Joining Cycle Included" msgid "Monthly Interval - Joining Cycle Included"
msgstr "Monatliches Intervall Beitrittszeitraum einbezogen" msgstr "Monatliches Intervall Beitrittszeitraum einbezogen"
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/form.ex #: lib/mv_web/live/membership_fee_type_live/form.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -1550,6 +1557,7 @@ msgstr "Jährliches Intervall Beitrittszeitraum einbezogen"
msgid "You are about to delete all %{count} cycles for this member." msgid "You are about to delete all %{count} cycles for this member."
msgstr "Du bist dabei alle %{count} Zyklen für dieses Mitglied zu löschen." msgstr "Du bist dabei alle %{count} Zyklen für dieses Mitglied zu löschen."
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "Delete Membership Fee Type" msgid "Delete Membership Fee Type"
@ -1571,12 +1579,12 @@ msgstr "Spalten ein-/ausblenden"
msgid "Back to settings" msgid "Back to settings"
msgstr "Zurück zu den Einstellungen" msgstr "Zurück zu den Einstellungen"
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "Data field %{action} successfully" msgid "Data field %{action} successfully"
msgstr "Datenfeld erfolgreich %{action}" msgstr "Datenfeld erfolgreich %{action}"
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "Data field deleted successfully" msgid "Data field deleted successfully"
msgstr "Datenfeld erfolgreich gelöscht" msgstr "Datenfeld erfolgreich gelöscht"
@ -1591,7 +1599,7 @@ msgstr "Datenfeld löschen"
msgid "Edit Data Field" msgid "Edit Data Field"
msgstr "Datenfeld bearbeiten" msgstr "Datenfeld bearbeiten"
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "Failed to delete data field: %{error}" msgid "Failed to delete data field: %{error}"
msgstr "Konnte Datenfeld nicht löschen: %{error}" msgstr "Konnte Datenfeld nicht löschen: %{error}"
@ -1823,6 +1831,7 @@ msgstr "Zyklus löschen"
msgid "The cycle period will be calculated based on this date and the interval." msgid "The cycle period will be calculated based on this date and the interval."
msgstr "Der Zyklus wird basierend auf diesem Datum und dem Intervall berechnet." msgstr "Der Zyklus wird basierend auf diesem Datum und dem Intervall berechnet."
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Membership fee type not found" msgid "Membership fee type not found"
@ -1843,6 +1852,7 @@ msgstr "Benutzer*in erfolgreich gelöscht"
msgid "User not found" msgid "User not found"
msgstr "Benutzer*in nicht gefunden" msgstr "Benutzer*in nicht gefunden"
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "You do not have permission to access this membership fee type" msgid "You do not have permission to access this membership fee type"
@ -1853,6 +1863,7 @@ msgstr "Du hast keine Berechtigung, auf diese Mitgliedsbeitragsart zuzugreifen"
msgid "You do not have permission to access this user" msgid "You do not have permission to access this user"
msgstr "Du hast keine Berechtigung, auf diese*n Benutzer*in zuzugreifen" msgstr "Du hast keine Berechtigung, auf diese*n Benutzer*in zuzugreifen"
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "You do not have permission to delete this membership fee type" msgid "You do not have permission to delete this membership fee type"
@ -1924,16 +1935,6 @@ msgstr "E-Mail ist erforderlich."
msgid "Roles" msgid "Roles"
msgstr "Rollen" msgstr "Rollen"
#: lib/mv_web/components/layouts/sidebar.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Fee Settings"
msgstr "Beitragseinstellungen"
#: lib/mv_web/components/layouts/sidebar.ex
#, elixir-autogen, elixir-format
msgid "Fee Types"
msgstr "Beitragstypen"
#: lib/mv_web/components/layouts/sidebar.ex #: lib/mv_web/components/layouts/sidebar.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Administration" msgid "Administration"
@ -2272,7 +2273,7 @@ msgstr "Dieser Benutzer kann nicht angezeigt werden."
msgid "Not authorized." msgid "Not authorized."
msgstr "Nicht berechtigt." msgstr "Nicht berechtigt."
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Could not load data fields. Please check your permissions." msgid "Could not load data fields. Please check your permissions."
msgstr "Datenfelder konnten nicht geladen werden. Bitte überprüfe deine Berechtigungen." msgstr "Datenfelder konnten nicht geladen werden. Bitte überprüfe deine Berechtigungen."
@ -2423,6 +2424,7 @@ msgstr "Beitragsart auswählen"
msgid "Linked" msgid "Linked"
msgstr "Verknüpft" msgstr "Verknüpft"
#: lib/mv_web/live/global_settings_live.ex
#: lib/mv_web/live/user_live/index.html.heex #: lib/mv_web/live/user_live/index.html.heex
#: lib/mv_web/live/user_live/show.ex #: lib/mv_web/live/user_live/show.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -2975,3 +2977,109 @@ msgstr "Für die Vereinfacht-Integration erforderlich und kann nicht deaktiviert
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Fee Type" msgid "Fee Type"
msgstr "Beitragsart" msgstr "Beitragsart"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Admin group name"
msgstr "Admin-Gruppenname"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Base URL"
msgstr "Basis-URL"
#: lib/mv_web/components/layouts/sidebar.ex
#, elixir-autogen, elixir-format
msgid "Basic settings"
msgstr "Grundeinstellungen"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Client ID"
msgstr "Client-ID"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Client Secret"
msgstr "Client-Geheimnis"
#: lib/mv_web/live/membership_fee_settings_live.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Configure global settings and fee types for membership fees."
msgstr "Globale Einstellungen für Mitgliedsbeiträge konfigurieren."
#: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format
msgid "Configure member fields and custom data fields."
msgstr "Mitgliedsfelder und benutzerdefinierte Datenfelder konfigurieren."
#: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Custom fields"
msgstr "Benutzerdefinierte Felder"
#: lib/mv_web/components/layouts/sidebar.ex
#: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format
msgid "Datafields"
msgstr "Datenfelder"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "From OIDC_ADMIN_GROUP_NAME"
msgstr "Aus OIDC_ADMIN_GROUP_NAME"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "From OIDC_BASE_URL"
msgstr "Aus OIDC_BASE_URL"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "From OIDC_CLIENT_ID"
msgstr "Aus OIDC_CLIENT_ID"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "From OIDC_CLIENT_SECRET"
msgstr "Aus OIDC_CLIENT_SECRET"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "From OIDC_GROUPS_CLAIM"
msgstr "Aus OIDC_GROUPS_CLAIM"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "From OIDC_REDIRECT_URI"
msgstr "Aus OIDC_REDIRECT_URI"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Groups claim"
msgstr "Gruppen"
#: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Member fields"
msgstr "Mitgliedsfilter"
#: lib/mv_web/components/layouts/sidebar.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Membership fee settings"
msgstr "Beitragseinstellungen"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Redirect URI"
msgstr "Weiterleitungs-URI"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Save OIDC Settings"
msgstr "Einstellungen speichern"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "e.g. admin"
msgstr "z. B. admin"

View file

@ -19,6 +19,7 @@ msgid "Actions"
msgstr "" msgstr ""
#: lib/mv_web/live/member_live/index.html.heex #: lib/mv_web/live/member_live/index.html.heex
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#: lib/mv_web/live/role_live/index.html.heex #: lib/mv_web/live/role_live/index.html.heex
#: lib/mv_web/live/role_live/show.ex #: lib/mv_web/live/role_live/show.ex
@ -323,6 +324,7 @@ msgstr ""
#: lib/mv_web/live/group_live/show.ex #: lib/mv_web/live/group_live/show.ex
#: lib/mv_web/live/member_live/index.ex #: lib/mv_web/live/member_live/index.ex
#: lib/mv_web/live/member_live/index.html.heex #: lib/mv_web/live/member_live/index.html.heex
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#: lib/mv_web/live/statistics_live.ex #: lib/mv_web/live/statistics_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -336,6 +338,7 @@ msgstr ""
#: lib/mv_web/live/group_live/show.ex #: lib/mv_web/live/group_live/show.ex
#: lib/mv_web/live/member_field_live/form_component.ex #: lib/mv_web/live/member_field_live/form_component.ex
#: lib/mv_web/live/member_field_live/index_component.ex #: lib/mv_web/live/member_field_live/index_component.ex
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/form.ex #: lib/mv_web/live/membership_fee_type_live/form.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#: lib/mv_web/live/role_live/form.ex #: lib/mv_web/live/role_live/form.ex
@ -383,7 +386,6 @@ msgstr ""
msgid "Select member" msgid "Select member"
msgstr "" msgstr ""
#: lib/mv_web/components/layouts/sidebar.ex
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Settings" msgid "Settings"
@ -843,6 +845,7 @@ msgid "Create Member"
msgstr "" msgstr ""
#: lib/mv_web/live/member_live/show/membership_fees_component.ex #: lib/mv_web/live/member_live/show/membership_fees_component.ex
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/form.ex #: lib/mv_web/live/membership_fee_type_live/form.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -854,11 +857,13 @@ msgstr ""
msgid "Back to Settings" msgid "Back to Settings"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Can be changed at any time. Amount changes affect future periods only." msgid "Can be changed at any time. Amount changes affect future periods only."
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Deletion" msgid "Deletion"
@ -869,6 +874,7 @@ msgstr ""
msgid "Examples" msgid "Examples"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Fixed after creation. Members can only switch between types with the same interval." msgid "Fixed after creation. Members can only switch between types with the same interval."
@ -887,6 +893,7 @@ msgid "Half-yearly"
msgstr "" msgstr ""
#: lib/mv_web/live/member_live/show/membership_fees_component.ex #: lib/mv_web/live/member_live/show/membership_fees_component.ex
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/form.ex #: lib/mv_web/live/membership_fee_type_live/form.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -925,11 +932,13 @@ msgstr ""
msgid "Monthly" msgid "Monthly"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Name & Amount" msgid "Name & Amount"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Only possible if no members are assigned to this type." msgid "Only possible if no members are assigned to this type."
@ -1003,7 +1012,7 @@ msgstr ""
msgid "Select none" msgid "Select none"
msgstr "" msgstr ""
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Slug does not match. Deletion cancelled." msgid "Slug does not match. Deletion cancelled."
msgstr "" msgstr ""
@ -1045,11 +1054,6 @@ msgstr ""
msgid "Yes/No-Selection" msgid "Yes/No-Selection"
msgstr "" msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Memberdata"
msgstr ""
#: lib/mv_web/live/custom_field_live/index_component.ex #: lib/mv_web/live/custom_field_live/index_component.ex
#: lib/mv_web/live/member_field_live/index_component.ex #: lib/mv_web/live/member_field_live/index_component.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -1061,7 +1065,7 @@ msgstr ""
msgid "These fields are neccessary for MILA to handle member identification and payment calculations in the future. Thus you cannot delete these fields but hide them in the member overview." msgid "These fields are neccessary for MILA to handle member identification and payment calculations in the future. Thus you cannot delete these fields but hide them in the member overview."
msgstr "" msgstr ""
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Member field %{action} successfully" msgid "Member field %{action} successfully"
msgstr "" msgstr ""
@ -1071,6 +1075,7 @@ msgstr ""
msgid "A cycle for this period already exists" msgid "A cycle for this period already exists"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "About Membership Fee Types" msgid "About Membership Fee Types"
@ -1087,6 +1092,7 @@ msgid "Already paid cycles will remain with the old amount."
msgstr "" msgstr ""
#: lib/mv_web/live/member_live/show/membership_fees_component.ex #: lib/mv_web/live/member_live/show/membership_fees_component.ex
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#: lib/mv_web/live/role_live/helpers.ex #: lib/mv_web/live/role_live/helpers.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -1098,6 +1104,7 @@ msgstr ""
msgid "Are you sure you want to delete this cycle?" msgid "Are you sure you want to delete this cycle?"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Cannot delete - %{count} member(s) assigned" msgid "Cannot delete - %{count} member(s) assigned"
@ -1118,11 +1125,6 @@ msgstr ""
msgid "Click to edit amount" msgid "Click to edit amount"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Configure global settings for membership fees."
msgstr ""
#: lib/mv_web/live/membership_fee_type_live/form.ex #: lib/mv_web/live/membership_fee_type_live/form.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Confirm Change" msgid "Confirm Change"
@ -1233,6 +1235,7 @@ msgstr ""
msgid "Edit Membership Fee Type" msgid "Edit Membership Fee Type"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Edit membership fee type" msgid "Edit membership fee type"
@ -1331,6 +1334,7 @@ msgstr ""
msgid "Membership Fee Type" msgid "Membership Fee Type"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Membership Fee Types" msgid "Membership Fee Types"
@ -1347,6 +1351,7 @@ msgstr ""
msgid "Membership fee start" msgid "Membership fee start"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Membership fee type deleted" msgid "Membership fee type deleted"
@ -1367,6 +1372,7 @@ msgstr ""
msgid "Membership fee type updated. Cycles regenerated." msgid "Membership fee type updated. Cycles regenerated."
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Membership fee types define different membership fee structures. Each type has a fixed interval (monthly, quarterly, half-yearly, yearly) that cannot be changed after creation." msgid "Membership fee types define different membership fee structures. Each type has a fixed interval (monthly, quarterly, half-yearly, yearly) that cannot be changed after creation."
@ -1377,6 +1383,7 @@ msgstr ""
msgid "Monthly Interval - Joining Cycle Included" msgid "Monthly Interval - Joining Cycle Included"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/form.ex #: lib/mv_web/live/membership_fee_type_live/form.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -1551,6 +1558,7 @@ msgstr ""
msgid "You are about to delete all %{count} cycles for this member." msgid "You are about to delete all %{count} cycles for this member."
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Delete Membership Fee Type" msgid "Delete Membership Fee Type"
@ -1572,12 +1580,12 @@ msgstr ""
msgid "Back to settings" msgid "Back to settings"
msgstr "" msgstr ""
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Data field %{action} successfully" msgid "Data field %{action} successfully"
msgstr "" msgstr ""
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Data field deleted successfully" msgid "Data field deleted successfully"
msgstr "" msgstr ""
@ -1592,7 +1600,7 @@ msgstr ""
msgid "Edit Data Field" msgid "Edit Data Field"
msgstr "" msgstr ""
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Failed to delete data field: %{error}" msgid "Failed to delete data field: %{error}"
msgstr "" msgstr ""
@ -1824,6 +1832,7 @@ msgstr ""
msgid "The cycle period will be calculated based on this date and the interval." msgid "The cycle period will be calculated based on this date and the interval."
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Membership fee type not found" msgid "Membership fee type not found"
@ -1844,6 +1853,7 @@ msgstr ""
msgid "User not found" msgid "User not found"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "You do not have permission to access this membership fee type" msgid "You do not have permission to access this membership fee type"
@ -1854,6 +1864,7 @@ msgstr ""
msgid "You do not have permission to access this user" msgid "You do not have permission to access this user"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "You do not have permission to delete this membership fee type" msgid "You do not have permission to delete this membership fee type"
@ -1925,16 +1936,6 @@ msgstr ""
msgid "Roles" msgid "Roles"
msgstr "" msgstr ""
#: lib/mv_web/components/layouts/sidebar.ex
#, elixir-autogen, elixir-format
msgid "Fee Settings"
msgstr ""
#: lib/mv_web/components/layouts/sidebar.ex
#, elixir-autogen, elixir-format
msgid "Fee Types"
msgstr ""
#: lib/mv_web/components/layouts/sidebar.ex #: lib/mv_web/components/layouts/sidebar.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Administration" msgid "Administration"
@ -2273,7 +2274,7 @@ msgstr ""
msgid "Not authorized." msgid "Not authorized."
msgstr "" msgstr ""
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Could not load data fields. Please check your permissions." msgid "Could not load data fields. Please check your permissions."
msgstr "" msgstr ""
@ -2424,6 +2425,7 @@ msgstr ""
msgid "Linked" msgid "Linked"
msgstr "" msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#: lib/mv_web/live/user_live/index.html.heex #: lib/mv_web/live/user_live/index.html.heex
#: lib/mv_web/live/user_live/show.ex #: lib/mv_web/live/user_live/show.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -2975,3 +2977,109 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Fee Type" msgid "Fee Type"
msgstr "" msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Admin group name"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Base URL"
msgstr ""
#: lib/mv_web/components/layouts/sidebar.ex
#, elixir-autogen, elixir-format
msgid "Basic settings"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Client ID"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Client Secret"
msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Configure global settings and fee types for membership fees."
msgstr ""
#: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format
msgid "Configure member fields and custom data fields."
msgstr ""
#: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format
msgid "Custom fields"
msgstr ""
#: lib/mv_web/components/layouts/sidebar.ex
#: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format
msgid "Datafields"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "From OIDC_ADMIN_GROUP_NAME"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "From OIDC_BASE_URL"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "From OIDC_CLIENT_ID"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "From OIDC_CLIENT_SECRET"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "From OIDC_GROUPS_CLAIM"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "From OIDC_REDIRECT_URI"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Groups claim"
msgstr ""
#: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format
msgid "Member fields"
msgstr ""
#: lib/mv_web/components/layouts/sidebar.ex
#, elixir-autogen, elixir-format
msgid "Membership fee settings"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Redirect URI"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Save OIDC Settings"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "e.g. admin"
msgstr ""

View file

@ -19,6 +19,7 @@ msgid "Actions"
msgstr "" msgstr ""
#: lib/mv_web/live/member_live/index.html.heex #: lib/mv_web/live/member_live/index.html.heex
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#: lib/mv_web/live/role_live/index.html.heex #: lib/mv_web/live/role_live/index.html.heex
#: lib/mv_web/live/role_live/show.ex #: lib/mv_web/live/role_live/show.ex
@ -323,6 +324,7 @@ msgstr ""
#: lib/mv_web/live/group_live/show.ex #: lib/mv_web/live/group_live/show.ex
#: lib/mv_web/live/member_live/index.ex #: lib/mv_web/live/member_live/index.ex
#: lib/mv_web/live/member_live/index.html.heex #: lib/mv_web/live/member_live/index.html.heex
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#: lib/mv_web/live/statistics_live.ex #: lib/mv_web/live/statistics_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -336,6 +338,7 @@ msgstr ""
#: lib/mv_web/live/group_live/show.ex #: lib/mv_web/live/group_live/show.ex
#: lib/mv_web/live/member_field_live/form_component.ex #: lib/mv_web/live/member_field_live/form_component.ex
#: lib/mv_web/live/member_field_live/index_component.ex #: lib/mv_web/live/member_field_live/index_component.ex
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/form.ex #: lib/mv_web/live/membership_fee_type_live/form.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#: lib/mv_web/live/role_live/form.ex #: lib/mv_web/live/role_live/form.ex
@ -383,7 +386,6 @@ msgstr ""
msgid "Select member" msgid "Select member"
msgstr "" msgstr ""
#: lib/mv_web/components/layouts/sidebar.ex
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Settings" msgid "Settings"
@ -843,6 +845,7 @@ msgid "Create Member"
msgstr "" msgstr ""
#: lib/mv_web/live/member_live/show/membership_fees_component.ex #: lib/mv_web/live/member_live/show/membership_fees_component.ex
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/form.ex #: lib/mv_web/live/membership_fee_type_live/form.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -854,11 +857,13 @@ msgstr ""
msgid "Back to Settings" msgid "Back to Settings"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Can be changed at any time. Amount changes affect future periods only." msgid "Can be changed at any time. Amount changes affect future periods only."
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "Deletion" msgid "Deletion"
@ -869,6 +874,7 @@ msgstr ""
msgid "Examples" msgid "Examples"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Fixed after creation. Members can only switch between types with the same interval." msgid "Fixed after creation. Members can only switch between types with the same interval."
@ -887,6 +893,7 @@ msgid "Half-yearly"
msgstr "" msgstr ""
#: lib/mv_web/live/member_live/show/membership_fees_component.ex #: lib/mv_web/live/member_live/show/membership_fees_component.ex
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/form.ex #: lib/mv_web/live/membership_fee_type_live/form.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -925,11 +932,13 @@ msgstr ""
msgid "Monthly" msgid "Monthly"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Name & Amount" msgid "Name & Amount"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Only possible if no members are assigned to this type." msgid "Only possible if no members are assigned to this type."
@ -1003,7 +1012,7 @@ msgstr ""
msgid "Select none" msgid "Select none"
msgstr "" msgstr ""
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Slug does not match. Deletion cancelled." msgid "Slug does not match. Deletion cancelled."
msgstr "" msgstr ""
@ -1045,11 +1054,6 @@ msgstr ""
msgid "Yes/No-Selection" msgid "Yes/No-Selection"
msgstr "" msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Memberdata"
msgstr ""
#: lib/mv_web/live/custom_field_live/index_component.ex #: lib/mv_web/live/custom_field_live/index_component.ex
#: lib/mv_web/live/member_field_live/index_component.ex #: lib/mv_web/live/member_field_live/index_component.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
@ -1061,7 +1065,7 @@ msgstr ""
msgid "These fields are neccessary for MILA to handle member identification and payment calculations in the future. Thus you cannot delete these fields but hide them in the member overview." msgid "These fields are neccessary for MILA to handle member identification and payment calculations in the future. Thus you cannot delete these fields but hide them in the member overview."
msgstr "" msgstr ""
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "Member field %{action} successfully" msgid "Member field %{action} successfully"
msgstr "" msgstr ""
@ -1071,6 +1075,7 @@ msgstr ""
msgid "A cycle for this period already exists" msgid "A cycle for this period already exists"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "About Membership Fee Types" msgid "About Membership Fee Types"
@ -1087,6 +1092,7 @@ msgid "Already paid cycles will remain with the old amount."
msgstr "" msgstr ""
#: lib/mv_web/live/member_live/show/membership_fees_component.ex #: lib/mv_web/live/member_live/show/membership_fees_component.ex
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#: lib/mv_web/live/role_live/helpers.ex #: lib/mv_web/live/role_live/helpers.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -1098,6 +1104,7 @@ msgstr ""
msgid "Are you sure you want to delete this cycle?" msgid "Are you sure you want to delete this cycle?"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "Cannot delete - %{count} member(s) assigned" msgid "Cannot delete - %{count} member(s) assigned"
@ -1118,11 +1125,6 @@ msgstr ""
msgid "Click to edit amount" msgid "Click to edit amount"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Configure global settings for membership fees."
msgstr ""
#: lib/mv_web/live/membership_fee_type_live/form.ex #: lib/mv_web/live/membership_fee_type_live/form.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Confirm Change" msgid "Confirm Change"
@ -1233,6 +1235,7 @@ msgstr ""
msgid "Edit Membership Fee Type" msgid "Edit Membership Fee Type"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "Edit membership fee type" msgid "Edit membership fee type"
@ -1331,6 +1334,7 @@ msgstr ""
msgid "Membership Fee Type" msgid "Membership Fee Type"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "Membership Fee Types" msgid "Membership Fee Types"
@ -1347,6 +1351,7 @@ msgstr ""
msgid "Membership fee start" msgid "Membership fee start"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "Membership fee type deleted" msgid "Membership fee type deleted"
@ -1367,6 +1372,7 @@ msgstr ""
msgid "Membership fee type updated. Cycles regenerated." msgid "Membership fee type updated. Cycles regenerated."
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "Membership fee types define different membership fee structures. Each type has a fixed interval (monthly, quarterly, half-yearly, yearly) that cannot be changed after creation." msgid "Membership fee types define different membership fee structures. Each type has a fixed interval (monthly, quarterly, half-yearly, yearly) that cannot be changed after creation."
@ -1377,6 +1383,7 @@ msgstr ""
msgid "Monthly Interval - Joining Cycle Included" msgid "Monthly Interval - Joining Cycle Included"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/form.ex #: lib/mv_web/live/membership_fee_type_live/form.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
@ -1551,6 +1558,7 @@ msgstr ""
msgid "You are about to delete all %{count} cycles for this member." msgid "You are about to delete all %{count} cycles for this member."
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "Delete Membership Fee Type" msgid "Delete Membership Fee Type"
@ -1572,12 +1580,12 @@ msgstr ""
msgid "Back to settings" msgid "Back to settings"
msgstr "" msgstr ""
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "Data field %{action} successfully" msgid "Data field %{action} successfully"
msgstr "" msgstr ""
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "Data field deleted successfully" msgid "Data field deleted successfully"
msgstr "" msgstr ""
@ -1592,7 +1600,7 @@ msgstr ""
msgid "Edit Data Field" msgid "Edit Data Field"
msgstr "" msgstr ""
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "Failed to delete data field: %{error}" msgid "Failed to delete data field: %{error}"
msgstr "" msgstr ""
@ -1824,6 +1832,7 @@ msgstr ""
msgid "The cycle period will be calculated based on this date and the interval." msgid "The cycle period will be calculated based on this date and the interval."
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "Membership fee type not found" msgid "Membership fee type not found"
@ -1844,6 +1853,7 @@ msgstr ""
msgid "User not found" msgid "User not found"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "You do not have permission to access this membership fee type" msgid "You do not have permission to access this membership fee type"
@ -1854,6 +1864,7 @@ msgstr ""
msgid "You do not have permission to access this user" msgid "You do not have permission to access this user"
msgstr "" msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#: lib/mv_web/live/membership_fee_type_live/index.ex #: lib/mv_web/live/membership_fee_type_live/index.ex
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "You do not have permission to delete this membership fee type" msgid "You do not have permission to delete this membership fee type"
@ -1925,16 +1936,6 @@ msgstr ""
msgid "Roles" msgid "Roles"
msgstr "" msgstr ""
#: lib/mv_web/components/layouts/sidebar.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Fee Settings"
msgstr ""
#: lib/mv_web/components/layouts/sidebar.ex
#, elixir-autogen, elixir-format
msgid "Fee Types"
msgstr ""
#: lib/mv_web/components/layouts/sidebar.ex #: lib/mv_web/components/layouts/sidebar.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Administration" msgid "Administration"
@ -2273,7 +2274,7 @@ msgstr ""
msgid "Not authorized." msgid "Not authorized."
msgstr "" msgstr ""
#: lib/mv_web/live/global_settings_live.ex #: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Could not load data fields. Please check your permissions." msgid "Could not load data fields. Please check your permissions."
msgstr "" msgstr ""
@ -2424,6 +2425,7 @@ msgstr ""
msgid "Linked" msgid "Linked"
msgstr "" msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#: lib/mv_web/live/user_live/index.html.heex #: lib/mv_web/live/user_live/index.html.heex
#: lib/mv_web/live/user_live/show.ex #: lib/mv_web/live/user_live/show.ex
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -2975,3 +2977,109 @@ msgstr "Required for Vereinfacht integration and cannot be disabled."
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Fee Type" msgid "Fee Type"
msgstr "Fee Type" msgstr "Fee Type"
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Admin group name"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Base URL"
msgstr ""
#: lib/mv_web/components/layouts/sidebar.ex
#, elixir-autogen, elixir-format
msgid "Basic settings"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Client ID"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Client Secret"
msgstr ""
#: lib/mv_web/live/membership_fee_settings_live.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Configure global settings and fee types for membership fees."
msgstr ""
#: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format
msgid "Configure member fields and custom data fields."
msgstr ""
#: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Custom fields"
msgstr ""
#: lib/mv_web/components/layouts/sidebar.ex
#: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format
msgid "Datafields"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "From OIDC_ADMIN_GROUP_NAME"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "From OIDC_BASE_URL"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "From OIDC_CLIENT_ID"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "From OIDC_CLIENT_SECRET"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "From OIDC_GROUPS_CLAIM"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "From OIDC_REDIRECT_URI"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Groups claim"
msgstr ""
#: lib/mv_web/live/datafields_live.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Member fields"
msgstr ""
#: lib/mv_web/components/layouts/sidebar.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Membership fee settings"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "Redirect URI"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format, fuzzy
msgid "Save OIDC Settings"
msgstr ""
#: lib/mv_web/live/global_settings_live.ex
#, elixir-autogen, elixir-format
msgid "e.g. admin"
msgstr ""

View file

@ -12,14 +12,14 @@ defmodule Mv.OidcRoleSyncTest do
setup do setup do
ensure_roles_exist() ensure_roles_exist()
restore_config = put_oidc_config(admin_group_name: "mila-admin", groups_claim: "groups") restore_config = put_oidc_env(admin_group_name: "mila-admin", groups_claim: "groups")
on_exit(restore_config) on_exit(restore_config)
:ok :ok
end end
describe "apply_admin_role_from_user_info/2" do describe "apply_admin_role_from_user_info/2" do
test "when OIDC_ADMIN_GROUP_NAME not configured: does not change user (Mitglied stays)" do test "when OIDC_ADMIN_GROUP_NAME not configured: does not change user (Mitglied stays)" do
restore = put_oidc_config(admin_group_name: nil, groups_claim: "groups") restore = put_oidc_env(admin_group_name: nil, groups_claim: "groups")
on_exit(restore) on_exit(restore)
email = "sync-no-config-#{System.unique_integer([:positive])}@test.example.com" email = "sync-no-config-#{System.unique_integer([:positive])}@test.example.com"
@ -58,7 +58,7 @@ defmodule Mv.OidcRoleSyncTest do
end end
test "when OIDC_GROUPS_CLAIM is different: reads groups from that claim" do test "when OIDC_GROUPS_CLAIM is different: reads groups from that claim" do
restore = put_oidc_config(admin_group_name: "mila-admin", groups_claim: "ak_groups") restore = put_oidc_env(admin_group_name: "mila-admin", groups_claim: "ak_groups")
on_exit(restore) on_exit(restore)
email = "sync-claim-#{System.unique_integer([:positive])}@test.example.com" email = "sync-claim-#{System.unique_integer([:positive])}@test.example.com"
@ -131,13 +131,30 @@ defmodule Mv.OidcRoleSyncTest do
end end
end end
defp put_oidc_config(opts) do defp put_oidc_env(opts) do
current = Application.get_env(:mv, :oidc_role_sync, []) prev_admin = System.get_env("OIDC_ADMIN_GROUP_NAME")
merged = Keyword.merge(current, opts) prev_claim = System.get_env("OIDC_GROUPS_CLAIM")
Application.put_env(:mv, :oidc_role_sync, merged)
if opts[:admin_group_name] != nil do
System.put_env("OIDC_ADMIN_GROUP_NAME", to_string(opts[:admin_group_name]))
else
System.delete_env("OIDC_ADMIN_GROUP_NAME")
end
if opts[:groups_claim] != nil do
System.put_env("OIDC_GROUPS_CLAIM", to_string(opts[:groups_claim]))
else
System.delete_env("OIDC_GROUPS_CLAIM")
end
fn -> fn ->
Application.put_env(:mv, :oidc_role_sync, current) if prev_admin,
do: System.put_env("OIDC_ADMIN_GROUP_NAME", prev_admin),
else: System.delete_env("OIDC_ADMIN_GROUP_NAME")
if prev_claim,
do: System.put_env("OIDC_GROUPS_CLAIM", prev_claim),
else: System.delete_env("OIDC_GROUPS_CLAIM")
end end
end end

View file

@ -30,7 +30,7 @@ defmodule MvWeb.SidebarAuthorizationTest do
html = render_sidebar(sidebar_assigns(user)) html = render_sidebar(sidebar_assigns(user))
assert html =~ ~s(href="/members") assert html =~ ~s(href="/members")
assert html =~ ~s(href="/membership_fee_types") assert html =~ ~s(href="/membership_fee_settings")
assert html =~ ~s(href="/statistics") assert html =~ ~s(href="/statistics")
assert html =~ ~s(data-testid="sidebar-administration") assert html =~ ~s(data-testid="sidebar-administration")
assert html =~ ~s(href="/users") assert html =~ ~s(href="/users")
@ -55,7 +55,7 @@ defmodule MvWeb.SidebarAuthorizationTest do
user = Fixtures.user_with_role_fixture("read_only") user = Fixtures.user_with_role_fixture("read_only")
html = render_sidebar(sidebar_assigns(user)) html = render_sidebar(sidebar_assigns(user))
refute html =~ ~s(href="/membership_fee_types") refute html =~ ~s(href="/membership_fee_settings")
refute html =~ ~s(href="/users") refute html =~ ~s(href="/users")
refute html =~ ~s(href="/admin/roles") refute html =~ ~s(href="/admin/roles")
refute html =~ ~s(href="/settings") refute html =~ ~s(href="/settings")
@ -76,7 +76,7 @@ defmodule MvWeb.SidebarAuthorizationTest do
user = Fixtures.user_with_role_fixture("normal_user") user = Fixtures.user_with_role_fixture("normal_user")
html = render_sidebar(sidebar_assigns(user)) html = render_sidebar(sidebar_assigns(user))
refute html =~ ~s(href="/membership_fee_types") refute html =~ ~s(href="/membership_fee_settings")
refute html =~ ~s(href="/users") refute html =~ ~s(href="/users")
refute html =~ ~s(href="/admin/roles") refute html =~ ~s(href="/admin/roles")
refute html =~ ~s(href="/settings") refute html =~ ~s(href="/settings")
@ -96,7 +96,7 @@ defmodule MvWeb.SidebarAuthorizationTest do
html = render_sidebar(sidebar_assigns(user)) html = render_sidebar(sidebar_assigns(user))
refute html =~ ~s(href="/statistics") refute html =~ ~s(href="/statistics")
refute html =~ ~s(href="/membership_fee_types") refute html =~ ~s(href="/membership_fee_settings")
refute html =~ ~s(href="/users") refute html =~ ~s(href="/users")
refute html =~ ~s(data-testid="sidebar-administration") refute html =~ ~s(data-testid="sidebar-administration")
end end
@ -117,7 +117,7 @@ defmodule MvWeb.SidebarAuthorizationTest do
html = render_sidebar(sidebar_assigns(user)) html = render_sidebar(sidebar_assigns(user))
refute html =~ ~s(href="/members") refute html =~ ~s(href="/members")
refute html =~ ~s(href="/membership_fee_types") refute html =~ ~s(href="/membership_fee_settings")
refute html =~ ~s(href="/users") refute html =~ ~s(href="/users")
end end
end end

View file

@ -54,7 +54,7 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
# Create custom field value # Create custom field value
create_custom_field_value(member, custom_field, "test") create_custom_field_value(member, custom_field, "test")
{:ok, view, _html} = live(conn, ~p"/settings") {:ok, view, _html} = live(conn, ~p"/admin/datafields")
# Click delete button - find the delete link within the component # Click delete button - find the delete link within the component
view view
@ -80,7 +80,7 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
create_custom_field_value(member1, custom_field, "test1") create_custom_field_value(member1, custom_field, "test1")
create_custom_field_value(member2, custom_field, "test2") create_custom_field_value(member2, custom_field, "test2")
{:ok, view, _html} = live(conn, ~p"/settings") {:ok, view, _html} = live(conn, ~p"/admin/datafields")
view view
|> element("#custom-fields-component a", "Delete") |> element("#custom-fields-component a", "Delete")
@ -93,7 +93,7 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
test "shows 0 members for custom field without values", %{conn: conn} do test "shows 0 members for custom field without values", %{conn: conn} do
{:ok, _custom_field} = create_custom_field("test_field", :string) {:ok, _custom_field} = create_custom_field("test_field", :string)
{:ok, view, _html} = live(conn, ~p"/settings") {:ok, view, _html} = live(conn, ~p"/admin/datafields")
view view
|> element("#custom-fields-component a", "Delete") |> element("#custom-fields-component a", "Delete")
@ -108,7 +108,7 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
test "updates confirmation state when typing", %{conn: conn} do test "updates confirmation state when typing", %{conn: conn} do
{:ok, custom_field} = create_custom_field("test_field", :string) {:ok, custom_field} = create_custom_field("test_field", :string)
{:ok, view, _html} = live(conn, ~p"/settings") {:ok, view, _html} = live(conn, ~p"/admin/datafields")
view view
|> element("#custom-fields-component a", "Delete") |> element("#custom-fields-component a", "Delete")
@ -126,7 +126,7 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
test "delete button is disabled when slug doesn't match", %{conn: conn} do test "delete button is disabled when slug doesn't match", %{conn: conn} do
{:ok, _custom_field} = create_custom_field("test_field", :string) {:ok, _custom_field} = create_custom_field("test_field", :string)
{:ok, view, _html} = live(conn, ~p"/settings") {:ok, view, _html} = live(conn, ~p"/admin/datafields")
view view
|> element("#custom-fields-component a", "Delete") |> element("#custom-fields-component a", "Delete")
@ -148,7 +148,7 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
{:ok, custom_field} = create_custom_field("test_field", :string) {:ok, custom_field} = create_custom_field("test_field", :string)
{:ok, custom_field_value} = create_custom_field_value(member, custom_field, "test") {:ok, custom_field_value} = create_custom_field_value(member, custom_field, "test")
{:ok, view, _html} = live(conn, ~p"/settings") {:ok, view, _html} = live(conn, ~p"/admin/datafields")
# Open modal # Open modal
view view
@ -185,7 +185,7 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
} do } do
{:ok, custom_field} = create_custom_field("test_field", :string) {:ok, custom_field} = create_custom_field("test_field", :string)
{:ok, view, _html} = live(conn, ~p"/settings") {:ok, view, _html} = live(conn, ~p"/admin/datafields")
view view
|> element("#custom-fields-component a", "Delete") |> element("#custom-fields-component a", "Delete")
@ -209,7 +209,7 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
test "closes modal without deleting", %{conn: conn} do test "closes modal without deleting", %{conn: conn} do
{:ok, custom_field} = create_custom_field("test_field", :string) {:ok, custom_field} = create_custom_field("test_field", :string)
{:ok, view, _html} = live(conn, ~p"/settings") {:ok, view, _html} = live(conn, ~p"/admin/datafields")
view view
|> element("#custom-fields-component a", "Delete") |> element("#custom-fields-component a", "Delete")
@ -234,7 +234,7 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
describe "create custom field" do describe "create custom field" do
test "submitting new data field form creates custom field and shows success", %{conn: conn} do test "submitting new data field form creates custom field and shows success", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/settings") {:ok, view, _html} = live(conn, ~p"/admin/datafields")
# Open "New Data Field" form # Open "New Data Field" form
view view

View file

@ -64,21 +64,5 @@ defmodule MvWeb.GlobalSettingsLiveTest do
assert html =~ "must be present" assert html =~ "must be present"
end end
test "displays Memberdata section", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/settings")
assert html =~ "Memberdata" or html =~ "Member Data"
end
test "displays flash message after member field visibility update", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/settings")
# Simulate member field visibility update
send(view.pid, {:member_field_visibility_updated})
# Check for flash message
assert render(view) =~ "updated" or render(view) =~ "success"
end
end end
end end

View file

@ -23,7 +23,7 @@ defmodule MvWeb.MemberFieldLive.IndexComponentTest do
describe "rendering" do describe "rendering" do
test "renders all member fields from Constants", %{conn: conn} do test "renders all member fields from Constants", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/settings") {:ok, _view, html} = live(conn, ~p"/admin/datafields")
# Check that all member fields are displayed # Check that all member fields are displayed
member_fields = Mv.Constants.member_fields() member_fields = Mv.Constants.member_fields()
@ -36,7 +36,7 @@ defmodule MvWeb.MemberFieldLive.IndexComponentTest do
end end
test "displays show_in_overview status as badge", %{conn: conn} do test "displays show_in_overview status as badge", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/settings") {:ok, _view, html} = live(conn, ~p"/admin/datafields")
# Should have "Show in overview" column header # Should have "Show in overview" column header
assert html =~ "Show in overview" or html =~ "Show in Overview" assert html =~ "Show in overview" or html =~ "Show in Overview"
@ -46,7 +46,7 @@ defmodule MvWeb.MemberFieldLive.IndexComponentTest do
end end
test "displays required status column", %{conn: conn} do test "displays required status column", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/settings") {:ok, _view, html} = live(conn, ~p"/admin/datafields")
# Should have "Required" column; email is always required # Should have "Required" column; email is always required
assert html =~ "Required" or html =~ "required" assert html =~ "Required" or html =~ "required"
@ -59,7 +59,7 @@ defmodule MvWeb.MemberFieldLive.IndexComponentTest do
{:ok, _updated} = {:ok, _updated} =
Membership.update_settings(settings, %{member_field_visibility: %{}}) Membership.update_settings(settings, %{member_field_visibility: %{}})
{:ok, _view, html} = live(conn, ~p"/settings") {:ok, _view, html} = live(conn, ~p"/admin/datafields")
# All fields should show as visible (Yes) by default # All fields should show as visible (Yes) by default
# Check for "Yes" badge or similar indicator # Check for "Yes" badge or similar indicator
@ -74,7 +74,7 @@ defmodule MvWeb.MemberFieldLive.IndexComponentTest do
{:ok, _updated} = {:ok, _updated} =
Membership.update_member_field_visibility(settings, visibility_config) Membership.update_member_field_visibility(settings, visibility_config)
{:ok, _view, html} = live(conn, ~p"/settings") {:ok, _view, html} = live(conn, ~p"/admin/datafields")
# Street and house_number should show as hidden (No) # Street and house_number should show as hidden (No)
# Other fields should show as visible (Yes) # Other fields should show as visible (Yes)
@ -102,7 +102,7 @@ defmodule MvWeb.MemberFieldLive.IndexComponentTest do
end end
test "marks email as required (always from settings)", %{conn: conn} do test "marks email as required (always from settings)", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/settings") {:ok, _view, html} = live(conn, ~p"/admin/datafields")
# Email is always required # Email is always required
assert html =~ "email" or html =~ "Email" assert html =~ "email" or html =~ "Email"
@ -119,7 +119,7 @@ defmodule MvWeb.MemberFieldLive.IndexComponentTest do
required: true required: true
) )
{:ok, _view, html} = live(conn, ~p"/settings") {:ok, _view, html} = live(conn, ~p"/admin/datafields")
# First name row should show Required (and Optional for others) # First name row should show Required (and Optional for others)
assert html =~ "First name" or html =~ "first_name" assert html =~ "First name" or html =~ "first_name"
@ -127,7 +127,7 @@ defmodule MvWeb.MemberFieldLive.IndexComponentTest do
end end
test "optional fields show Optional when not required in settings", %{conn: conn} do test "optional fields show Optional when not required in settings", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/settings") {:ok, _view, html} = live(conn, ~p"/admin/datafields")
# Email is required; other fields default to optional # Email is required; other fields default to optional
assert html =~ "Optional" assert html =~ "Optional"

View file

@ -11,7 +11,7 @@ defmodule MvWeb.MembershipFeeTypeLive.FormTest do
require Ash.Query require Ash.Query
setup %{conn: conn} do setup %{conn: conn} do
# User must have admin role (or normal_user) to access /membership_fee_types pages # User must have admin role (or normal_user) to access /membership_fee_settings pages
user = Mv.Fixtures.user_with_role_fixture("admin") user = Mv.Fixtures.user_with_role_fixture("admin")
authenticated_conn = conn_with_password_user(conn, user) authenticated_conn = conn_with_password_user(conn, user)
%{conn: authenticated_conn, user: user} %{conn: authenticated_conn, user: user}
@ -51,7 +51,7 @@ defmodule MvWeb.MembershipFeeTypeLive.FormTest do
describe "create form" do describe "create form" do
test "creates new membership fee type", %{conn: conn, user: user} do test "creates new membership fee type", %{conn: conn, user: user} do
{:ok, view, _html} = live(conn, "/membership_fee_types/new") {:ok, view, _html} = live(conn, "/membership_fee_settings/new_fee_type")
form_data = %{ form_data = %{
"membership_fee_type[name]" => "New Type", "membership_fee_type[name]" => "New Type",
@ -65,7 +65,7 @@ defmodule MvWeb.MembershipFeeTypeLive.FormTest do
|> form("#membership-fee-type-form", form_data) |> form("#membership-fee-type-form", form_data)
|> render_submit() |> render_submit()
assert to == "/membership_fee_types" assert to == "/membership_fee_settings"
# Verify type was created (use actor so read is authorized) # Verify type was created (use actor so read is authorized)
type = type =
@ -79,7 +79,7 @@ defmodule MvWeb.MembershipFeeTypeLive.FormTest do
end end
test "interval field is editable on create", %{conn: conn} do test "interval field is editable on create", %{conn: conn} do
{:ok, _view, html} = live(conn, "/membership_fee_types/new") {:ok, _view, html} = live(conn, "/membership_fee_settings/new_fee_type")
# Interval field should be editable (not disabled) # Interval field should be editable (not disabled)
refute html =~ "disabled" || html =~ "readonly" refute html =~ "disabled" || html =~ "readonly"
@ -90,7 +90,7 @@ defmodule MvWeb.MembershipFeeTypeLive.FormTest do
test "loads existing type data", %{conn: conn} do test "loads existing type data", %{conn: conn} do
fee_type = create_fee_type(%{name: "Existing Type", amount: Decimal.new("60.00")}) fee_type = create_fee_type(%{name: "Existing Type", amount: Decimal.new("60.00")})
{:ok, _view, html} = live(conn, "/membership_fee_types/#{fee_type.id}/edit") {:ok, _view, html} = live(conn, "/membership_fee_settings/#{fee_type.id}/edit_fee_type")
assert html =~ "Existing Type" assert html =~ "Existing Type"
assert html =~ "60" || html =~ "60,00" assert html =~ "60" || html =~ "60,00"
@ -99,7 +99,7 @@ defmodule MvWeb.MembershipFeeTypeLive.FormTest do
test "interval field is grayed out on edit", %{conn: conn} do test "interval field is grayed out on edit", %{conn: conn} do
fee_type = create_fee_type(%{interval: :yearly}) fee_type = create_fee_type(%{interval: :yearly})
{:ok, _view, html} = live(conn, "/membership_fee_types/#{fee_type.id}/edit") {:ok, _view, html} = live(conn, "/membership_fee_settings/#{fee_type.id}/edit_fee_type")
# Interval field should be disabled # Interval field should be disabled
assert html =~ "disabled" || html =~ "readonly" assert html =~ "disabled" || html =~ "readonly"
@ -109,7 +109,7 @@ defmodule MvWeb.MembershipFeeTypeLive.FormTest do
fee_type = create_fee_type(%{amount: Decimal.new("50.00")}) fee_type = create_fee_type(%{amount: Decimal.new("50.00")})
create_member(%{membership_fee_type_id: fee_type.id}) create_member(%{membership_fee_type_id: fee_type.id})
{:ok, view, _html} = live(conn, "/membership_fee_types/#{fee_type.id}/edit") {:ok, view, _html} = live(conn, "/membership_fee_settings/#{fee_type.id}/edit_fee_type")
# Change amount # Change amount
view view
@ -129,7 +129,7 @@ defmodule MvWeb.MembershipFeeTypeLive.FormTest do
create_member(%{membership_fee_type_id: fee_type.id}) create_member(%{membership_fee_type_id: fee_type.id})
end) end)
{:ok, view, _html} = live(conn, "/membership_fee_types/#{fee_type.id}/edit") {:ok, view, _html} = live(conn, "/membership_fee_settings/#{fee_type.id}/edit_fee_type")
# Change amount # Change amount
html = html =
@ -144,7 +144,7 @@ defmodule MvWeb.MembershipFeeTypeLive.FormTest do
test "amount change can be confirmed", %{conn: conn, user: user} do test "amount change can be confirmed", %{conn: conn, user: user} do
fee_type = create_fee_type(%{amount: Decimal.new("50.00")}) fee_type = create_fee_type(%{amount: Decimal.new("50.00")})
{:ok, view, _html} = live(conn, "/membership_fee_types/#{fee_type.id}/edit") {:ok, view, _html} = live(conn, "/membership_fee_settings/#{fee_type.id}/edit_fee_type")
# Change amount and confirm # Change amount and confirm
view view
@ -173,7 +173,7 @@ defmodule MvWeb.MembershipFeeTypeLive.FormTest do
test "amount change can be cancelled", %{conn: conn, user: user} do test "amount change can be cancelled", %{conn: conn, user: user} do
fee_type = create_fee_type(%{amount: Decimal.new("50.00")}) fee_type = create_fee_type(%{amount: Decimal.new("50.00")})
{:ok, view, _html} = live(conn, "/membership_fee_types/#{fee_type.id}/edit") {:ok, view, _html} = live(conn, "/membership_fee_settings/#{fee_type.id}/edit_fee_type")
# Change amount and cancel # Change amount and cancel
view view
@ -195,7 +195,7 @@ defmodule MvWeb.MembershipFeeTypeLive.FormTest do
end end
test "validation errors display correctly", %{conn: conn} do test "validation errors display correctly", %{conn: conn} do
{:ok, view, _html} = live(conn, "/membership_fee_types/new") {:ok, view, _html} = live(conn, "/membership_fee_settings/new_fee_type")
# Submit with invalid data # Submit with invalid data
html = html =
@ -214,7 +214,7 @@ defmodule MvWeb.MembershipFeeTypeLive.FormTest do
describe "permissions" do describe "permissions" do
test "only admin can access", %{conn: conn} do test "only admin can access", %{conn: conn} do
# This test assumes non-admin users cannot access # This test assumes non-admin users cannot access
{:ok, _view, html} = live(conn, "/membership_fee_types/new") {:ok, _view, html} = live(conn, "/membership_fee_settings/new_fee_type")
# Should show the form (admin user in setup) # Should show the form (admin user in setup)
assert html =~ "Membership Fee Type" || html =~ "Beitragsart" assert html =~ "Membership Fee Type" || html =~ "Beitragsart"

View file

@ -60,7 +60,7 @@ defmodule MvWeb.MembershipFeeTypeLive.IndexTest do
admin_user admin_user
) )
{:ok, _view, html} = live(conn, "/membership_fee_types") {:ok, _view, html} = live(conn, "/membership_fee_settings")
assert html =~ "Regular" assert html =~ "Regular"
assert html =~ "Reduced" assert html =~ "Reduced"
@ -77,33 +77,33 @@ defmodule MvWeb.MembershipFeeTypeLive.IndexTest do
create_member(%{membership_fee_type_id: fee_type.id}, admin_user) create_member(%{membership_fee_type_id: fee_type.id}, admin_user)
end) end)
{:ok, _view, html} = live(conn, "/membership_fee_types") {:ok, _view, html} = live(conn, "/membership_fee_settings")
assert html =~ "3" || html =~ "Members" || html =~ "Mitglieder" assert html =~ "3" || html =~ "Members" || html =~ "Mitglieder"
end end
test "create button navigates to form", %{conn: conn} do test "create button navigates to form", %{conn: conn} do
{:ok, view, _html} = live(conn, "/membership_fee_types") {:ok, view, _html} = live(conn, "/membership_fee_settings")
{:error, {:live_redirect, %{to: to}}} = {:error, {:live_redirect, %{to: to}}} =
view view
|> element("a[href='/membership_fee_types/new']") |> element("a[href='/membership_fee_settings/new_fee_type']")
|> render_click() |> render_click()
assert to == "/membership_fee_types/new" assert to == "/membership_fee_settings/new_fee_type"
end end
test "edit button per row navigates to edit form", %{conn: conn, current_user: admin_user} do test "edit button per row navigates to edit form", %{conn: conn, current_user: admin_user} do
fee_type = create_fee_type(%{interval: :yearly}, admin_user) fee_type = create_fee_type(%{interval: :yearly}, admin_user)
{:ok, view, _html} = live(conn, "/membership_fee_types") {:ok, view, _html} = live(conn, "/membership_fee_settings")
{:error, {:live_redirect, %{to: to}}} = {:error, {:live_redirect, %{to: to}}} =
view view
|> element("a[href='/membership_fee_types/#{fee_type.id}/edit']") |> element("a[href='/membership_fee_settings/#{fee_type.id}/edit_fee_type']")
|> render_click() |> render_click()
assert to == "/membership_fee_types/#{fee_type.id}/edit" assert to == "/membership_fee_settings/#{fee_type.id}/edit_fee_type"
end end
end end
@ -112,7 +112,7 @@ defmodule MvWeb.MembershipFeeTypeLive.IndexTest do
fee_type = create_fee_type(%{interval: :yearly}, admin_user) fee_type = create_fee_type(%{interval: :yearly}, admin_user)
create_member(%{membership_fee_type_id: fee_type.id}, admin_user) create_member(%{membership_fee_type_id: fee_type.id}, admin_user)
{:ok, _view, html} = live(conn, "/membership_fee_types") {:ok, _view, html} = live(conn, "/membership_fee_settings")
# Delete button should be disabled # Delete button should be disabled
assert html =~ "disabled" || html =~ "cursor-not-allowed" assert html =~ "disabled" || html =~ "cursor-not-allowed"
@ -122,7 +122,7 @@ defmodule MvWeb.MembershipFeeTypeLive.IndexTest do
fee_type = create_fee_type(%{interval: :yearly}, admin_user) fee_type = create_fee_type(%{interval: :yearly}, admin_user)
# No members assigned # No members assigned
{:ok, view, _html} = live(conn, "/membership_fee_types") {:ok, view, _html} = live(conn, "/membership_fee_settings")
# Delete button should be enabled # Delete button should be enabled
view view
@ -142,10 +142,11 @@ defmodule MvWeb.MembershipFeeTypeLive.IndexTest do
test "only admin can access", %{conn: conn} do test "only admin can access", %{conn: conn} do
# This test assumes non-admin users cannot access # This test assumes non-admin users cannot access
# Adjust based on actual permission implementation # Adjust based on actual permission implementation
{:ok, _view, html} = live(conn, "/membership_fee_types") {:ok, _view, html} = live(conn, "/membership_fee_settings")
# Should show the page (admin user in setup) # Should show the page (admin user in setup)
assert html =~ "Membership Fee Types" || html =~ "Beitragsarten" assert html =~ "Membership Fee Settings" || html =~ "Beitragseinstellungen" ||
html =~ "Membership Fee Types"
end end
end end
end end

View file

@ -279,17 +279,11 @@ defmodule MvWeb.Plugs.CheckPagePermissionTest do
end end
@tag role: :member @tag role: :member
test "GET /membership_fee_types redirects to user profile", %{conn: conn, current_user: user} do test "GET /membership_fee_settings/new_fee_type redirects to user profile", %{
conn = get(conn, "/membership_fee_types")
assert redirected_to(conn) == "/users/#{user.id}"
end
@tag role: :member
test "GET /membership_fee_types/new redirects to user profile", %{
conn: conn, conn: conn,
current_user: user current_user: user
} do } do
conn = get(conn, "/membership_fee_types/new") conn = get(conn, "/membership_fee_settings/new_fee_type")
assert redirected_to(conn) == "/users/#{user.id}" assert redirected_to(conn) == "/users/#{user.id}"
end end
@ -385,7 +379,7 @@ defmodule MvWeb.Plugs.CheckPagePermissionTest do
end end
@tag role: :member @tag role: :member
test "GET /membership_fee_types/:id/edit redirects to user profile", %{ test "GET /membership_fee_settings/:id/edit_fee_type redirects to user profile", %{
conn: conn, conn: conn,
current_user: user current_user: user
} do } do
@ -396,7 +390,7 @@ defmodule MvWeb.Plugs.CheckPagePermissionTest do
|> List.first() |> List.first()
if type do if type do
conn = get(conn, "/membership_fee_types/#{type.id}/edit") conn = get(conn, "/membership_fee_settings/#{type.id}/edit_fee_type")
assert redirected_to(conn) == "/users/#{user.id}" assert redirected_to(conn) == "/users/#{user.id}"
end end
end end
@ -680,15 +674,6 @@ defmodule MvWeb.Plugs.CheckPagePermissionTest do
assert redirected_to(conn) == "/users/#{user.id}" assert redirected_to(conn) == "/users/#{user.id}"
end end
@tag role: :read_only
test "GET /membership_fee_types redirects to user profile", %{
conn: conn,
current_user: user
} do
conn = get(conn, "/membership_fee_types")
assert redirected_to(conn) == "/users/#{user.id}"
end
@tag role: :read_only @tag role: :read_only
test "GET /groups/new redirects to user profile", %{conn: conn, current_user: user} do test "GET /groups/new redirects to user profile", %{conn: conn, current_user: user} do
conn = get(conn, "/groups/new") conn = get(conn, "/groups/new")
@ -864,15 +849,6 @@ defmodule MvWeb.Plugs.CheckPagePermissionTest do
assert redirected_to(conn) == "/users/#{user.id}" assert redirected_to(conn) == "/users/#{user.id}"
end end
@tag role: :normal_user
test "GET /membership_fee_types redirects to user profile", %{
conn: conn,
current_user: user
} do
conn = get(conn, "/membership_fee_types")
assert redirected_to(conn) == "/users/#{user.id}"
end
@tag role: :normal_user @tag role: :normal_user
test "GET /admin/roles redirects to user profile", %{conn: conn, current_user: user} do test "GET /admin/roles redirects to user profile", %{conn: conn, current_user: user} do
conn = get(conn, "/admin/roles") conn = get(conn, "/admin/roles")