Merge pull request 'Adds Global Settings closes #211' (#219) from feature/211_globalsettings into main
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
Reviewed-on: #219 Reviewed-by: moritz <moritz@noreply.git.local-it.org>
This commit is contained in:
commit
e803dbdf8b
17 changed files with 822 additions and 103 deletions
|
|
@ -8,6 +8,9 @@ TOKEN_SIGNING_SECRET=changeme-run-mix-phx.gen.secret
|
||||||
# Required: Hostname for URL generation
|
# Required: Hostname for URL generation
|
||||||
PHX_HOST=localhost
|
PHX_HOST=localhost
|
||||||
|
|
||||||
|
# Recommended: Association settings
|
||||||
|
ASSOCIATION_NAME="Sportsclub XYZ"
|
||||||
|
|
||||||
# Optional: OIDC Configuration
|
# Optional: OIDC Configuration
|
||||||
# These have defaults in docker-compose.prod.yml, only override if needed
|
# These have defaults in docker-compose.prod.yml, only override if needed
|
||||||
# OIDC_CLIENT_ID=mv
|
# OIDC_CLIENT_ID=mv
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,14 @@ defmodule Mv.Membership do
|
||||||
- `Member` - Club members with personal information and custom field values
|
- `Member` - Club members with personal information and custom field values
|
||||||
- `CustomFieldValue` - Dynamic custom field values attached to members
|
- `CustomFieldValue` - Dynamic custom field values attached to members
|
||||||
- `CustomField` - Schema definitions for custom fields
|
- `CustomField` - Schema definitions for custom fields
|
||||||
|
- `Setting` - Global application settings (singleton)
|
||||||
|
|
||||||
## Public API
|
## Public API
|
||||||
The domain exposes these main actions:
|
The domain exposes these main actions:
|
||||||
- Member CRUD: `create_member/1`, `list_members/0`, `update_member/2`, `destroy_member/1`
|
- Member CRUD: `create_member/1`, `list_members/0`, `update_member/2`, `destroy_member/1`
|
||||||
- Custom field value management: `create_custom_field_value/1`, `list_custom_field_values/0`, etc.
|
- Custom field value management: `create_custom_field_value/1`, `list_custom_field_values/0`, etc.
|
||||||
- Custom field management: `create_custom_field/1`, `list_custom_fields/0`, etc.
|
- Custom field management: `create_custom_field/1`, `list_custom_fields/0`, etc.
|
||||||
|
- Settings management: `get_settings/0`, `update_settings/2`
|
||||||
|
|
||||||
## Admin Interface
|
## Admin Interface
|
||||||
The domain is configured with AshAdmin for management UI.
|
The domain is configured with AshAdmin for management UI.
|
||||||
|
|
@ -45,5 +47,80 @@ defmodule Mv.Membership do
|
||||||
define :destroy_custom_field, action: :destroy_with_values
|
define :destroy_custom_field, action: :destroy_with_values
|
||||||
define :prepare_custom_field_deletion, action: :prepare_deletion, args: [:id]
|
define :prepare_custom_field_deletion, action: :prepare_deletion, args: [:id]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
resource Mv.Membership.Setting do
|
||||||
|
# Note: create action exists but is not exposed via code interface
|
||||||
|
# It's only used internally as fallback in get_settings/0
|
||||||
|
# Settings should be created via seed script
|
||||||
|
define :update_settings, action: :update
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Singleton pattern: Get the single settings record
|
||||||
|
@doc """
|
||||||
|
Gets the global settings.
|
||||||
|
|
||||||
|
Settings should normally be created via the seed script (`priv/repo/seeds.exs`).
|
||||||
|
If no settings exist, this function will create them as a fallback using the
|
||||||
|
`ASSOCIATION_NAME` environment variable or "Club Name" as default.
|
||||||
|
|
||||||
|
## Returns
|
||||||
|
|
||||||
|
- `{:ok, settings}` - The settings record
|
||||||
|
- `{:ok, nil}` - No settings exist (should not happen if seeds were run)
|
||||||
|
- `{:error, error}` - Error reading settings
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> {:ok, settings} = Mv.Membership.get_settings()
|
||||||
|
iex> settings.club_name
|
||||||
|
"My Club"
|
||||||
|
|
||||||
|
"""
|
||||||
|
def get_settings do
|
||||||
|
# Try to get the first (and only) settings record
|
||||||
|
case Ash.read_one(Mv.Membership.Setting, domain: __MODULE__) do
|
||||||
|
{:ok, nil} ->
|
||||||
|
# No settings exist - create as fallback (should normally be created via seed script)
|
||||||
|
default_club_name = System.get_env("ASSOCIATION_NAME") || "Club Name"
|
||||||
|
|
||||||
|
Mv.Membership.Setting
|
||||||
|
|> Ash.Changeset.for_create(:create, %{club_name: default_club_name})
|
||||||
|
|> Ash.create!(domain: __MODULE__)
|
||||||
|
|> then(fn settings -> {:ok, settings} end)
|
||||||
|
|
||||||
|
{:ok, settings} ->
|
||||||
|
{:ok, settings}
|
||||||
|
|
||||||
|
{:error, error} ->
|
||||||
|
{:error, error}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Updates the global settings.
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
- `settings` - The settings record to update
|
||||||
|
- `attrs` - A map of attributes to update (e.g., `%{club_name: "New Name"}`)
|
||||||
|
|
||||||
|
## Returns
|
||||||
|
|
||||||
|
- `{:ok, updated_settings}` - Successfully updated settings
|
||||||
|
- `{:error, error}` - Validation or update error
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> {:ok, settings} = Mv.Membership.get_settings()
|
||||||
|
iex> {:ok, updated} = Mv.Membership.update_settings(settings, %{club_name: "New Club"})
|
||||||
|
iex> updated.club_name
|
||||||
|
"New Club"
|
||||||
|
|
||||||
|
"""
|
||||||
|
def update_settings(settings, attrs) do
|
||||||
|
settings
|
||||||
|
|> Ash.Changeset.for_update(:update, attrs)
|
||||||
|
|> Ash.update(domain: __MODULE__)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
80
lib/membership/setting.ex
Normal file
80
lib/membership/setting.ex
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
defmodule Mv.Membership.Setting do
|
||||||
|
@moduledoc """
|
||||||
|
Ash resource representing global application settings.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
Settings is a singleton resource that stores global configuration for the association,
|
||||||
|
such as the club name and branding information. There should only ever be one settings
|
||||||
|
record in the database.
|
||||||
|
|
||||||
|
## Attributes
|
||||||
|
- `club_name` - The name of the association/club (required, cannot be empty)
|
||||||
|
|
||||||
|
## Singleton Pattern
|
||||||
|
This resource uses a singleton pattern - there should only be one settings record.
|
||||||
|
The resource is designed to be read and updated, but not created or destroyed
|
||||||
|
through normal CRUD operations. Initial settings should be seeded.
|
||||||
|
|
||||||
|
## Environment Variable Support
|
||||||
|
The `club_name` can be set via the `ASSOCIATION_NAME` environment variable.
|
||||||
|
If set, the environment variable value is used as a fallback when no database
|
||||||
|
value exists. Database values always take precedence over environment variables.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
# Get current settings
|
||||||
|
{:ok, settings} = Mv.Membership.get_settings()
|
||||||
|
settings.club_name # => "My Club"
|
||||||
|
|
||||||
|
# Update club name
|
||||||
|
{:ok, updated} = Mv.Membership.update_settings(settings, %{club_name: "New Name"})
|
||||||
|
"""
|
||||||
|
use Ash.Resource,
|
||||||
|
domain: Mv.Membership,
|
||||||
|
data_layer: AshPostgres.DataLayer
|
||||||
|
|
||||||
|
postgres do
|
||||||
|
table "settings"
|
||||||
|
repo Mv.Repo
|
||||||
|
end
|
||||||
|
|
||||||
|
resource do
|
||||||
|
description "Global application settings (singleton resource)"
|
||||||
|
end
|
||||||
|
|
||||||
|
actions do
|
||||||
|
defaults [:read]
|
||||||
|
|
||||||
|
# Internal create action - not exposed via code interface
|
||||||
|
# Used only as fallback in get_settings/0 if settings don't exist
|
||||||
|
# Settings should normally be created via seed script
|
||||||
|
create :create do
|
||||||
|
accept [:club_name]
|
||||||
|
end
|
||||||
|
|
||||||
|
update :update do
|
||||||
|
primary? true
|
||||||
|
accept [:club_name]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
validations do
|
||||||
|
validate present(:club_name), on: [:create, :update]
|
||||||
|
validate string_length(:club_name, min: 1), on: [:create, :update]
|
||||||
|
end
|
||||||
|
|
||||||
|
attributes do
|
||||||
|
uuid_primary_key :id
|
||||||
|
|
||||||
|
attribute :club_name, :string,
|
||||||
|
allow_nil?: false,
|
||||||
|
public?: true,
|
||||||
|
description: "The name of the association/club",
|
||||||
|
constraints: [
|
||||||
|
trim?: true,
|
||||||
|
min_length: 1
|
||||||
|
]
|
||||||
|
|
||||||
|
timestamps()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -6,15 +6,21 @@ defmodule MvWeb.Layouts.Navbar do
|
||||||
use Gettext, backend: MvWeb.Gettext
|
use Gettext, backend: MvWeb.Gettext
|
||||||
use MvWeb, :verified_routes
|
use MvWeb, :verified_routes
|
||||||
|
|
||||||
|
alias Mv.Membership
|
||||||
|
|
||||||
attr :current_user, :map,
|
attr :current_user, :map,
|
||||||
required: true,
|
required: true,
|
||||||
doc: "The current user - navbar is only shown when user is present"
|
doc: "The current user - navbar is only shown when user is present"
|
||||||
|
|
||||||
def navbar(assigns) do
|
def navbar(assigns) do
|
||||||
|
club_name = get_club_name()
|
||||||
|
|
||||||
|
assigns = assign(assigns, :club_name, club_name)
|
||||||
|
|
||||||
~H"""
|
~H"""
|
||||||
<header class="navbar bg-base-100 shadow-sm">
|
<header class="navbar bg-base-100 shadow-sm">
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<a class="btn btn-ghost text-xl">Mitgliederverwaltung</a>
|
<a class="btn btn-ghost text-xl">{@club_name}</a>
|
||||||
<ul class="menu menu-horizontal bg-base-200">
|
<ul class="menu menu-horizontal bg-base-200">
|
||||||
<li><.link navigate="/members">{gettext("Members")}</.link></li>
|
<li><.link navigate="/members">{gettext("Members")}</.link></li>
|
||||||
<li><.link navigate="/custom_fields">{gettext("Custom Fields")}</.link></li>
|
<li><.link navigate="/custom_fields">{gettext("Custom Fields")}</.link></li>
|
||||||
|
|
@ -89,7 +95,9 @@ defmodule MvWeb.Layouts.Navbar do
|
||||||
{gettext("Profil")}
|
{gettext("Profil")}
|
||||||
</.link>
|
</.link>
|
||||||
</li>
|
</li>
|
||||||
<li><a>{gettext("Settings")}</a></li>
|
<li>
|
||||||
|
<.link navigate={~p"/settings"}>{gettext("Settings")}</.link>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<.link href={~p"/sign-out"}>{gettext("Logout")}</.link>
|
<.link href={~p"/sign-out"}>{gettext("Logout")}</.link>
|
||||||
</li>
|
</li>
|
||||||
|
|
@ -99,4 +107,13 @@ defmodule MvWeb.Layouts.Navbar do
|
||||||
</header>
|
</header>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Helper function to get club name from settings
|
||||||
|
# Falls back to "Mitgliederverwaltung" if settings can't be loaded
|
||||||
|
defp get_club_name do
|
||||||
|
case Membership.get_settings() do
|
||||||
|
{:ok, settings} -> settings.club_name
|
||||||
|
_ -> "Mitgliederverwaltung"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
97
lib/mv_web/live/global_settings_live.ex
Normal file
97
lib/mv_web/live/global_settings_live.ex
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
defmodule MvWeb.GlobalSettingsLive do
|
||||||
|
@moduledoc """
|
||||||
|
LiveView for managing global application settings (Vereinsdaten).
|
||||||
|
|
||||||
|
## Features
|
||||||
|
- Edit the association/club name
|
||||||
|
- Real-time form validation
|
||||||
|
- Success/error feedback
|
||||||
|
|
||||||
|
## Settings
|
||||||
|
- `club_name` - The name of the association/club (required)
|
||||||
|
|
||||||
|
## Events
|
||||||
|
- `validate` - Real-time form validation
|
||||||
|
- `save` - Save settings changes
|
||||||
|
|
||||||
|
## Note
|
||||||
|
Settings is a singleton resource - there is only one settings record.
|
||||||
|
The club_name can also be set via the `ASSOCIATION_NAME` environment variable.
|
||||||
|
"""
|
||||||
|
use MvWeb, :live_view
|
||||||
|
|
||||||
|
alias Mv.Membership
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def mount(_params, _session, socket) do
|
||||||
|
{:ok, settings} = Membership.get_settings()
|
||||||
|
|
||||||
|
{:ok,
|
||||||
|
socket
|
||||||
|
|> assign(:page_title, gettext("Club Settings"))
|
||||||
|
|> assign(:settings, settings)
|
||||||
|
|> assign_form()}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def render(assigns) do
|
||||||
|
~H"""
|
||||||
|
<Layouts.app flash={@flash} current_user={@current_user}>
|
||||||
|
<.header>
|
||||||
|
{gettext("Club Settings")}
|
||||||
|
<:subtitle>
|
||||||
|
{gettext("Manage global settings for the association.")}
|
||||||
|
</:subtitle>
|
||||||
|
</.header>
|
||||||
|
|
||||||
|
<.form for={@form} id="settings-form" phx-change="validate" phx-submit="save">
|
||||||
|
<.input
|
||||||
|
field={@form[:club_name]}
|
||||||
|
type="text"
|
||||||
|
label={gettext("Association Name")}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
|
||||||
|
<.button phx-disable-with={gettext("Saving...")} variant="primary">
|
||||||
|
{gettext("Save Settings")}
|
||||||
|
</.button>
|
||||||
|
</.form>
|
||||||
|
</Layouts.app>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_event("validate", %{"setting" => setting_params}, socket) do
|
||||||
|
{:noreply,
|
||||||
|
assign(socket, form: AshPhoenix.Form.validate(socket.assigns.form, setting_params))}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event("save", %{"setting" => setting_params}, socket) do
|
||||||
|
case AshPhoenix.Form.submit(socket.assigns.form, params: setting_params) do
|
||||||
|
{:ok, updated_settings} ->
|
||||||
|
socket =
|
||||||
|
socket
|
||||||
|
|> assign(:settings, updated_settings)
|
||||||
|
|> put_flash(:info, gettext("Settings updated successfully"))
|
||||||
|
|> assign_form()
|
||||||
|
|
||||||
|
{:noreply, socket}
|
||||||
|
|
||||||
|
{:error, form} ->
|
||||||
|
{:noreply, assign(socket, form: form)}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp assign_form(%{assigns: %{settings: settings}} = socket) do
|
||||||
|
form =
|
||||||
|
AshPhoenix.Form.for_update(
|
||||||
|
settings,
|
||||||
|
:update,
|
||||||
|
api: Membership,
|
||||||
|
as: "setting",
|
||||||
|
forms: [auto?: true]
|
||||||
|
)
|
||||||
|
|
||||||
|
assign(socket, form: to_form(form))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -73,6 +73,8 @@ defmodule MvWeb.Router do
|
||||||
live "/users/:id", UserLive.Show, :show
|
live "/users/:id", UserLive.Show, :show
|
||||||
live "/users/:id/show/edit", UserLive.Show, :edit
|
live "/users/:id/show/edit", UserLive.Show, :edit
|
||||||
|
|
||||||
|
live "/settings", GlobalSettingsLive
|
||||||
|
|
||||||
post "/set_locale", LocaleController, :set_locale
|
post "/set_locale", LocaleController, :set_locale
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ msgid "Actions"
|
||||||
msgstr "Aktionen"
|
msgstr "Aktionen"
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/index.html.heex:202
|
#: lib/mv_web/live/member_live/index.html.heex:202
|
||||||
#: lib/mv_web/live/user_live/index.html.heex:65
|
#: lib/mv_web/live/user_live/index.html.heex:72
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Are you sure?"
|
msgid "Are you sure?"
|
||||||
msgstr "Bist du sicher?"
|
msgstr "Bist du sicher?"
|
||||||
|
|
@ -35,14 +35,14 @@ msgid "City"
|
||||||
msgstr "Stadt"
|
msgstr "Stadt"
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/index.html.heex:204
|
#: lib/mv_web/live/member_live/index.html.heex:204
|
||||||
#: lib/mv_web/live/user_live/index.html.heex:67
|
#: lib/mv_web/live/user_live/index.html.heex:74
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Löschen"
|
msgstr "Löschen"
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/index.html.heex:196
|
#: lib/mv_web/live/member_live/index.html.heex:196
|
||||||
#: lib/mv_web/live/user_live/form.ex:141
|
#: lib/mv_web/live/user_live/form.ex:265
|
||||||
#: lib/mv_web/live/user_live/index.html.heex:59
|
#: lib/mv_web/live/user_live/index.html.heex:66
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Edit"
|
msgid "Edit"
|
||||||
msgstr "Bearbeite"
|
msgstr "Bearbeite"
|
||||||
|
|
@ -88,7 +88,7 @@ msgid "New Member"
|
||||||
msgstr "Neues Mitglied"
|
msgstr "Neues Mitglied"
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/index.html.heex:193
|
#: lib/mv_web/live/member_live/index.html.heex:193
|
||||||
#: lib/mv_web/live/user_live/index.html.heex:56
|
#: lib/mv_web/live/user_live/index.html.heex:63
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Show"
|
msgid "Show"
|
||||||
msgstr "Anzeigen"
|
msgstr "Anzeigen"
|
||||||
|
|
@ -160,8 +160,9 @@ msgstr "Mitglied speichern"
|
||||||
|
|
||||||
#: lib/mv_web/live/custom_field_live/form.ex:66
|
#: lib/mv_web/live/custom_field_live/form.ex:66
|
||||||
#: lib/mv_web/live/custom_field_value_live/form.ex:74
|
#: lib/mv_web/live/custom_field_value_live/form.ex:74
|
||||||
|
#: lib/mv_web/live/global_settings_live.ex:55
|
||||||
#: lib/mv_web/live/member_live/form.ex:79
|
#: lib/mv_web/live/member_live/form.ex:79
|
||||||
#: lib/mv_web/live/user_live/form.ex:234
|
#: lib/mv_web/live/user_live/form.ex:248
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Saving..."
|
msgid "Saving..."
|
||||||
msgstr "Speichern..."
|
msgstr "Speichern..."
|
||||||
|
|
@ -183,7 +184,7 @@ msgstr "Dieses Formular dient zur Verwaltung von Mitgliedern und deren Eigenscha
|
||||||
msgid "Id"
|
msgid "Id"
|
||||||
msgstr "ID"
|
msgstr "ID"
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/index/formatter.ex:65
|
#: lib/mv_web/live/member_live/index/formatter.ex:61
|
||||||
#: lib/mv_web/live/member_live/show.ex:53
|
#: lib/mv_web/live/member_live/show.ex:53
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "No"
|
msgid "No"
|
||||||
|
|
@ -199,7 +200,7 @@ msgstr "Mitglied anzeigen"
|
||||||
msgid "This is a member record from your database."
|
msgid "This is a member record from your database."
|
||||||
msgstr "Dies ist ein Mitglied aus deiner Datenbank."
|
msgstr "Dies ist ein Mitglied aus deiner Datenbank."
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/index/formatter.ex:64
|
#: lib/mv_web/live/member_live/index/formatter.ex:60
|
||||||
#: lib/mv_web/live/member_live/show.ex:53
|
#: lib/mv_web/live/member_live/show.ex:53
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Yes"
|
msgid "Yes"
|
||||||
|
|
@ -258,7 +259,7 @@ msgstr "Ihr Passwort wurde erfolgreich zurückgesetzt"
|
||||||
#: lib/mv_web/live/custom_field_live/index.ex:120
|
#: lib/mv_web/live/custom_field_live/index.ex:120
|
||||||
#: lib/mv_web/live/custom_field_value_live/form.ex:77
|
#: lib/mv_web/live/custom_field_value_live/form.ex:77
|
||||||
#: lib/mv_web/live/member_live/form.ex:82
|
#: lib/mv_web/live/member_live/form.ex:82
|
||||||
#: lib/mv_web/live/user_live/form.ex:237
|
#: lib/mv_web/live/user_live/form.ex:251
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Abbrechen"
|
msgstr "Abbrechen"
|
||||||
|
|
@ -293,7 +294,7 @@ msgstr "ID"
|
||||||
msgid "Immutable"
|
msgid "Immutable"
|
||||||
msgstr "Unveränderlich"
|
msgstr "Unveränderlich"
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:94
|
#: lib/mv_web/components/layouts/navbar.ex:102
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Logout"
|
msgid "Logout"
|
||||||
msgstr "Abmelden"
|
msgstr "Abmelden"
|
||||||
|
|
@ -309,7 +310,7 @@ msgstr "Benutzer*innen auflisten"
|
||||||
msgid "Member"
|
msgid "Member"
|
||||||
msgstr "Mitglied"
|
msgstr "Mitglied"
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:19
|
#: lib/mv_web/components/layouts/navbar.ex:25
|
||||||
#: lib/mv_web/live/member_live/index.ex:57
|
#: lib/mv_web/live/member_live/index.ex:57
|
||||||
#: lib/mv_web/live/member_live/index.html.heex:3
|
#: lib/mv_web/live/member_live/index.html.heex:3
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -338,7 +339,7 @@ msgstr "Nicht gesetzt"
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:107
|
#: lib/mv_web/live/user_live/form.ex:107
|
||||||
#: lib/mv_web/live/user_live/form.ex:115
|
#: lib/mv_web/live/user_live/form.ex:115
|
||||||
#: lib/mv_web/live/user_live/form.ex:210
|
#: lib/mv_web/live/user_live/form.ex:224
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
msgstr "Hinweis"
|
msgstr "Hinweis"
|
||||||
|
|
@ -354,7 +355,7 @@ msgstr "OIDC ID"
|
||||||
msgid "Password Authentication"
|
msgid "Password Authentication"
|
||||||
msgstr "Passwort-Authentifizierung"
|
msgstr "Passwort-Authentifizierung"
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:89
|
#: lib/mv_web/components/layouts/navbar.ex:95
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Profil"
|
msgid "Profil"
|
||||||
msgstr "Profil"
|
msgstr "Profil"
|
||||||
|
|
@ -374,12 +375,12 @@ msgstr "Alle Mitglieder auswählen"
|
||||||
msgid "Select member"
|
msgid "Select member"
|
||||||
msgstr "Mitglied auswählen"
|
msgstr "Mitglied auswählen"
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:92
|
#: lib/mv_web/components/layouts/navbar.ex:99
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Einstellungen"
|
msgstr "Einstellungen"
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:235
|
#: lib/mv_web/live/user_live/form.ex:249
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Save User"
|
msgid "Save User"
|
||||||
msgstr "Benutzer*in speichern"
|
msgstr "Benutzer*in speichern"
|
||||||
|
|
@ -404,7 +405,7 @@ msgstr "Nicht unterstützter Wertetyp: %{type}"
|
||||||
msgid "Use this form to manage user records in your database."
|
msgid "Use this form to manage user records in your database."
|
||||||
msgstr "Verwenden Sie dieses Formular, um Benutzer*innen-Datensätze zu verwalten."
|
msgstr "Verwenden Sie dieses Formular, um Benutzer*innen-Datensätze zu verwalten."
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:252
|
#: lib/mv_web/live/user_live/form.ex:266
|
||||||
#: lib/mv_web/live/user_live/show.ex:34
|
#: lib/mv_web/live/user_live/show.ex:34
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "User"
|
msgid "User"
|
||||||
|
|
@ -432,7 +433,7 @@ msgstr "aufsteigend"
|
||||||
msgid "descending"
|
msgid "descending"
|
||||||
msgstr "absteigend"
|
msgstr "absteigend"
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:251
|
#: lib/mv_web/live/user_live/form.ex:265
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "New"
|
msgid "New"
|
||||||
msgstr "Neue*r"
|
msgstr "Neue*r"
|
||||||
|
|
@ -542,14 +543,14 @@ msgstr "Zurück zur Mitgliederliste"
|
||||||
msgid "Back to users list"
|
msgid "Back to users list"
|
||||||
msgstr "Zurück zur Benutzer*innen-Liste"
|
msgstr "Zurück zur Benutzer*innen-Liste"
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:27
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:33
|
#: lib/mv_web/components/layouts/navbar.ex:33
|
||||||
|
#: lib/mv_web/components/layouts/navbar.ex:39
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Select language"
|
msgid "Select language"
|
||||||
msgstr "Sprache auswählen"
|
msgstr "Sprache auswählen"
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:40
|
#: lib/mv_web/components/layouts/navbar.ex:46
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:60
|
#: lib/mv_web/components/layouts/navbar.ex:66
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Toggle dark mode"
|
msgid "Toggle dark mode"
|
||||||
msgstr "Dunklen Modus umschalten"
|
msgstr "Dunklen Modus umschalten"
|
||||||
|
|
@ -560,7 +561,7 @@ msgstr "Dunklen Modus umschalten"
|
||||||
msgid "Search..."
|
msgid "Search..."
|
||||||
msgstr "Suchen..."
|
msgstr "Suchen..."
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:21
|
#: lib/mv_web/components/layouts/navbar.ex:27
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Users"
|
msgid "Users"
|
||||||
msgstr "Benutzer*innen"
|
msgstr "Benutzer*innen"
|
||||||
|
|
@ -653,7 +654,7 @@ msgstr "Benutzerdefinierten Feldwert speichern"
|
||||||
msgid "Use this form to manage custom_field records in your database."
|
msgid "Use this form to manage custom_field records in your database."
|
||||||
msgstr "Verwende dieses Formular, um Benutzerdefinierte Felder in deiner Datenbank zu verwalten."
|
msgstr "Verwende dieses Formular, um Benutzerdefinierte Felder in deiner Datenbank zu verwalten."
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:20
|
#: lib/mv_web/components/layouts/navbar.ex:26
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Custom Fields"
|
msgid "Custom Fields"
|
||||||
msgstr "Benutzerdefinierte Felder"
|
msgstr "Benutzerdefinierte Felder"
|
||||||
|
|
@ -700,37 +701,73 @@ msgstr "Obigen Text zur Bestätigung eingeben"
|
||||||
msgid "To confirm deletion, please enter this text:"
|
msgid "To confirm deletion, please enter this text:"
|
||||||
msgstr "Um die Löschung zu bestätigen, gib bitte folgenden Text ein:"
|
msgstr "Um die Löschung zu bestätigen, gib bitte folgenden Text ein:"
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:210
|
#: lib/mv_web/live/custom_field_live/form.ex:64
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Show in overview"
|
||||||
|
msgstr "In der Mitglieder-Übersicht anzeigen"
|
||||||
|
|
||||||
|
#: lib/mv_web/live/global_settings_live.ex:51
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Association Name"
|
||||||
|
msgstr "Vereinsname"
|
||||||
|
|
||||||
|
#: lib/mv_web/live/global_settings_live.ex:31
|
||||||
|
#: lib/mv_web/live/global_settings_live.ex:41
|
||||||
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
msgid "Club Settings"
|
||||||
|
msgstr "Vereinsdaten"
|
||||||
|
|
||||||
|
#: lib/mv_web/live/global_settings_live.ex:43
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Manage global settings for the association."
|
||||||
|
msgstr "Passe übergreifende Einstellungen für den Verein an."
|
||||||
|
|
||||||
|
#: lib/mv_web/live/global_settings_live.ex:56
|
||||||
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
msgid "Save Settings"
|
||||||
|
msgstr "Einstellungen speichern"
|
||||||
|
|
||||||
|
#: lib/mv_web/live/global_settings_live.ex:75
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Settings updated successfully"
|
||||||
|
msgstr "Einstellungen erfolgreich gespeichert"
|
||||||
|
|
||||||
|
#: lib/mv_web/live/user_live/form.ex:224
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "A member with this email already exists. To link with a different member, please change one of the email addresses first."
|
msgid "A member with this email already exists. To link with a different member, please change one of the email addresses first."
|
||||||
msgstr "Ein Mitglied mit dieser E-Mail-Adresse existiert bereits. Um mit einem anderen Mitglied zu verknüpfen, ändern Sie bitte zuerst eine der E-Mail-Adressen."
|
msgstr "Ein Mitglied mit dieser E-Mail-Adresse existiert bereits. Um mit einem anderen Mitglied zu verknüpfen, ändern Sie bitte zuerst eine der E-Mail-Adressen."
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:185
|
#: lib/mv_web/live/user_live/form.ex:192
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Available members"
|
msgid "Available members"
|
||||||
msgstr "Verfügbare Mitglieder"
|
msgstr "Verfügbare Mitglieder"
|
||||||
|
|
||||||
|
#: lib/mv_web/live/user_live/form.ex:357
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Failed to link member: %{error}"
|
||||||
|
msgstr "Fehler beim Verlinken des Mitglieds: %{error}"
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:152
|
#: lib/mv_web/live/user_live/form.ex:152
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Member will be unlinked when you save. Cannot select new member until saved."
|
msgid "Member will be unlinked when you save. Cannot select new member until saved."
|
||||||
msgstr "Mitglied wird beim Speichern entverknüpft. Neues Mitglied kann erst nach dem Speichern ausgewählt werden."
|
msgstr "Mitglied wird beim Speichern entverknüpft. Neues Mitglied kann erst nach dem Speichern ausgewählt werden."
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:226
|
#: lib/mv_web/live/user_live/form.ex:240
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Save to confirm linking."
|
msgid "Save to confirm linking."
|
||||||
msgstr "Speichern, um die Verknüpfung zu bestätigen."
|
msgstr "Speichern, um die Verknüpfung zu bestätigen."
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:169
|
#: lib/mv_web/live/user_live/form.ex:171
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Search for a member to link..."
|
msgid "Search for a member to link..."
|
||||||
msgstr "Nach einem Mitglied zum Verknüpfen suchen..."
|
msgstr "Nach einem Mitglied zum Verknüpfen suchen..."
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:173
|
#: lib/mv_web/live/user_live/form.ex:175
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Search for member to link"
|
msgid "Search for member to link"
|
||||||
msgstr "Nach Mitglied zum Verknüpfen suchen"
|
msgstr "Nach Mitglied zum Verknüpfen suchen"
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:223
|
#: lib/mv_web/live/user_live/form.ex:237
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Selected"
|
msgid "Selected"
|
||||||
msgstr "Ausgewählt"
|
msgstr "Ausgewählt"
|
||||||
|
|
@ -745,15 +782,6 @@ msgstr "Mitglied entverknüpfen"
|
||||||
msgid "Unlinking scheduled"
|
msgid "Unlinking scheduled"
|
||||||
msgstr "Entverknüpfung geplant"
|
msgstr "Entverknüpfung geplant"
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:342
|
|
||||||
#, elixir-autogen, elixir-format
|
|
||||||
msgid "Failed to link member: %{error}"
|
|
||||||
msgstr ""
|
|
||||||
#: lib/mv_web/live/custom_field_live/form.ex:64
|
|
||||||
#, elixir-autogen, elixir-format
|
|
||||||
msgid "Show in overview"
|
|
||||||
msgstr "In der Mitglieder-Übersicht anzeigen"
|
|
||||||
|
|
||||||
#~ #: lib/mv_web/live/custom_field_live/index.ex:97
|
#~ #: lib/mv_web/live/custom_field_live/index.ex:97
|
||||||
#~ #, elixir-autogen, elixir-format
|
#~ #, elixir-autogen, elixir-format
|
||||||
#~ msgid "To confirm deletion, please enter the custom field slug:"
|
#~ msgid "To confirm deletion, please enter the custom field slug:"
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ msgid "Actions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/index.html.heex:202
|
#: lib/mv_web/live/member_live/index.html.heex:202
|
||||||
#: lib/mv_web/live/user_live/index.html.heex:65
|
#: lib/mv_web/live/user_live/index.html.heex:72
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Are you sure?"
|
msgid "Are you sure?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -36,14 +36,14 @@ msgid "City"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/index.html.heex:204
|
#: lib/mv_web/live/member_live/index.html.heex:204
|
||||||
#: lib/mv_web/live/user_live/index.html.heex:67
|
#: lib/mv_web/live/user_live/index.html.heex:74
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/index.html.heex:196
|
#: lib/mv_web/live/member_live/index.html.heex:196
|
||||||
#: lib/mv_web/live/user_live/form.ex:141
|
#: lib/mv_web/live/user_live/form.ex:265
|
||||||
#: lib/mv_web/live/user_live/index.html.heex:59
|
#: lib/mv_web/live/user_live/index.html.heex:66
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Edit"
|
msgid "Edit"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -89,7 +89,7 @@ msgid "New Member"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/index.html.heex:193
|
#: lib/mv_web/live/member_live/index.html.heex:193
|
||||||
#: lib/mv_web/live/user_live/index.html.heex:56
|
#: lib/mv_web/live/user_live/index.html.heex:63
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Show"
|
msgid "Show"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -161,8 +161,9 @@ msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/custom_field_live/form.ex:66
|
#: lib/mv_web/live/custom_field_live/form.ex:66
|
||||||
#: lib/mv_web/live/custom_field_value_live/form.ex:74
|
#: lib/mv_web/live/custom_field_value_live/form.ex:74
|
||||||
|
#: lib/mv_web/live/global_settings_live.ex:55
|
||||||
#: lib/mv_web/live/member_live/form.ex:79
|
#: lib/mv_web/live/member_live/form.ex:79
|
||||||
#: lib/mv_web/live/user_live/form.ex:234
|
#: lib/mv_web/live/user_live/form.ex:248
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Saving..."
|
msgid "Saving..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -184,7 +185,7 @@ msgstr ""
|
||||||
msgid "Id"
|
msgid "Id"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/index/formatter.ex:65
|
#: lib/mv_web/live/member_live/index/formatter.ex:61
|
||||||
#: lib/mv_web/live/member_live/show.ex:53
|
#: lib/mv_web/live/member_live/show.ex:53
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "No"
|
msgid "No"
|
||||||
|
|
@ -200,7 +201,7 @@ msgstr ""
|
||||||
msgid "This is a member record from your database."
|
msgid "This is a member record from your database."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/index/formatter.ex:64
|
#: lib/mv_web/live/member_live/index/formatter.ex:60
|
||||||
#: lib/mv_web/live/member_live/show.ex:53
|
#: lib/mv_web/live/member_live/show.ex:53
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Yes"
|
msgid "Yes"
|
||||||
|
|
@ -259,7 +260,7 @@ msgstr ""
|
||||||
#: lib/mv_web/live/custom_field_live/index.ex:120
|
#: lib/mv_web/live/custom_field_live/index.ex:120
|
||||||
#: lib/mv_web/live/custom_field_value_live/form.ex:77
|
#: lib/mv_web/live/custom_field_value_live/form.ex:77
|
||||||
#: lib/mv_web/live/member_live/form.ex:82
|
#: lib/mv_web/live/member_live/form.ex:82
|
||||||
#: lib/mv_web/live/user_live/form.ex:237
|
#: lib/mv_web/live/user_live/form.ex:251
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -294,7 +295,7 @@ msgstr ""
|
||||||
msgid "Immutable"
|
msgid "Immutable"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:94
|
#: lib/mv_web/components/layouts/navbar.ex:102
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Logout"
|
msgid "Logout"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -310,7 +311,7 @@ msgstr ""
|
||||||
msgid "Member"
|
msgid "Member"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:19
|
#: lib/mv_web/components/layouts/navbar.ex:25
|
||||||
#: lib/mv_web/live/member_live/index.ex:57
|
#: lib/mv_web/live/member_live/index.ex:57
|
||||||
#: lib/mv_web/live/member_live/index.html.heex:3
|
#: lib/mv_web/live/member_live/index.html.heex:3
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -339,7 +340,7 @@ msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:107
|
#: lib/mv_web/live/user_live/form.ex:107
|
||||||
#: lib/mv_web/live/user_live/form.ex:115
|
#: lib/mv_web/live/user_live/form.ex:115
|
||||||
#: lib/mv_web/live/user_live/form.ex:210
|
#: lib/mv_web/live/user_live/form.ex:224
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -355,7 +356,7 @@ msgstr ""
|
||||||
msgid "Password Authentication"
|
msgid "Password Authentication"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:89
|
#: lib/mv_web/components/layouts/navbar.ex:95
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Profil"
|
msgid "Profil"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -375,12 +376,12 @@ msgstr ""
|
||||||
msgid "Select member"
|
msgid "Select member"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:92
|
#: lib/mv_web/components/layouts/navbar.ex:99
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:235
|
#: lib/mv_web/live/user_live/form.ex:249
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Save User"
|
msgid "Save User"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -405,7 +406,7 @@ msgstr ""
|
||||||
msgid "Use this form to manage user records in your database."
|
msgid "Use this form to manage user records in your database."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:252
|
#: lib/mv_web/live/user_live/form.ex:266
|
||||||
#: lib/mv_web/live/user_live/show.ex:34
|
#: lib/mv_web/live/user_live/show.ex:34
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "User"
|
msgid "User"
|
||||||
|
|
@ -433,7 +434,7 @@ msgstr ""
|
||||||
msgid "descending"
|
msgid "descending"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:251
|
#: lib/mv_web/live/user_live/form.ex:265
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "New"
|
msgid "New"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -543,14 +544,14 @@ msgstr ""
|
||||||
msgid "Back to users list"
|
msgid "Back to users list"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:27
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:33
|
#: lib/mv_web/components/layouts/navbar.ex:33
|
||||||
|
#: lib/mv_web/components/layouts/navbar.ex:39
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Select language"
|
msgid "Select language"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:40
|
#: lib/mv_web/components/layouts/navbar.ex:46
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:60
|
#: lib/mv_web/components/layouts/navbar.ex:66
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Toggle dark mode"
|
msgid "Toggle dark mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -561,7 +562,7 @@ msgstr ""
|
||||||
msgid "Search..."
|
msgid "Search..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:21
|
#: lib/mv_web/components/layouts/navbar.ex:27
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Users"
|
msgid "Users"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -654,7 +655,7 @@ msgstr ""
|
||||||
msgid "Use this form to manage custom_field records in your database."
|
msgid "Use this form to manage custom_field records in your database."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:20
|
#: lib/mv_web/components/layouts/navbar.ex:26
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Custom Fields"
|
msgid "Custom Fields"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -705,3 +706,79 @@ msgstr ""
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Show in overview"
|
msgid "Show in overview"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/global_settings_live.ex:51
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Association Name"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/global_settings_live.ex:31
|
||||||
|
#: lib/mv_web/live/global_settings_live.ex:41
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Club Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/global_settings_live.ex:43
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Manage global settings for the association."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/global_settings_live.ex:56
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Save Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/global_settings_live.ex:75
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Settings updated successfully"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/user_live/form.ex:224
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "A member with this email already exists. To link with a different member, please change one of the email addresses first."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/user_live/form.ex:192
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Available members"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/user_live/form.ex:357
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Failed to link member: %{error}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/user_live/form.ex:152
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Member will be unlinked when you save. Cannot select new member until saved."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/user_live/form.ex:240
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Save to confirm linking."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/user_live/form.ex:171
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Search for a member to link..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/user_live/form.ex:175
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Search for member to link"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/user_live/form.ex:237
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Selected"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/user_live/form.ex:143
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Unlink Member"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/user_live/form.ex:152
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Unlinking scheduled"
|
||||||
|
msgstr ""
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ msgid "Actions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/index.html.heex:202
|
#: lib/mv_web/live/member_live/index.html.heex:202
|
||||||
#: lib/mv_web/live/user_live/index.html.heex:65
|
#: lib/mv_web/live/user_live/index.html.heex:72
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Are you sure?"
|
msgid "Are you sure?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -36,14 +36,14 @@ msgid "City"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/index.html.heex:204
|
#: lib/mv_web/live/member_live/index.html.heex:204
|
||||||
#: lib/mv_web/live/user_live/index.html.heex:67
|
#: lib/mv_web/live/user_live/index.html.heex:74
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/index.html.heex:196
|
#: lib/mv_web/live/member_live/index.html.heex:196
|
||||||
#: lib/mv_web/live/user_live/form.ex:141
|
#: lib/mv_web/live/user_live/form.ex:265
|
||||||
#: lib/mv_web/live/user_live/index.html.heex:59
|
#: lib/mv_web/live/user_live/index.html.heex:66
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Edit"
|
msgid "Edit"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -89,7 +89,7 @@ msgid "New Member"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/index.html.heex:193
|
#: lib/mv_web/live/member_live/index.html.heex:193
|
||||||
#: lib/mv_web/live/user_live/index.html.heex:56
|
#: lib/mv_web/live/user_live/index.html.heex:63
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Show"
|
msgid "Show"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -161,8 +161,9 @@ msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/custom_field_live/form.ex:66
|
#: lib/mv_web/live/custom_field_live/form.ex:66
|
||||||
#: lib/mv_web/live/custom_field_value_live/form.ex:74
|
#: lib/mv_web/live/custom_field_value_live/form.ex:74
|
||||||
|
#: lib/mv_web/live/global_settings_live.ex:55
|
||||||
#: lib/mv_web/live/member_live/form.ex:79
|
#: lib/mv_web/live/member_live/form.ex:79
|
||||||
#: lib/mv_web/live/user_live/form.ex:234
|
#: lib/mv_web/live/user_live/form.ex:248
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Saving..."
|
msgid "Saving..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -184,7 +185,7 @@ msgstr ""
|
||||||
msgid "Id"
|
msgid "Id"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/index/formatter.ex:65
|
#: lib/mv_web/live/member_live/index/formatter.ex:61
|
||||||
#: lib/mv_web/live/member_live/show.ex:53
|
#: lib/mv_web/live/member_live/show.ex:53
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "No"
|
msgid "No"
|
||||||
|
|
@ -200,7 +201,7 @@ msgstr ""
|
||||||
msgid "This is a member record from your database."
|
msgid "This is a member record from your database."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/index/formatter.ex:64
|
#: lib/mv_web/live/member_live/index/formatter.ex:60
|
||||||
#: lib/mv_web/live/member_live/show.ex:53
|
#: lib/mv_web/live/member_live/show.ex:53
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Yes"
|
msgid "Yes"
|
||||||
|
|
@ -259,7 +260,7 @@ msgstr ""
|
||||||
#: lib/mv_web/live/custom_field_live/index.ex:120
|
#: lib/mv_web/live/custom_field_live/index.ex:120
|
||||||
#: lib/mv_web/live/custom_field_value_live/form.ex:77
|
#: lib/mv_web/live/custom_field_value_live/form.ex:77
|
||||||
#: lib/mv_web/live/member_live/form.ex:82
|
#: lib/mv_web/live/member_live/form.ex:82
|
||||||
#: lib/mv_web/live/user_live/form.ex:237
|
#: lib/mv_web/live/user_live/form.ex:251
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -294,7 +295,7 @@ msgstr ""
|
||||||
msgid "Immutable"
|
msgid "Immutable"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:94
|
#: lib/mv_web/components/layouts/navbar.ex:102
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Logout"
|
msgid "Logout"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -310,7 +311,7 @@ msgstr ""
|
||||||
msgid "Member"
|
msgid "Member"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:19
|
#: lib/mv_web/components/layouts/navbar.ex:25
|
||||||
#: lib/mv_web/live/member_live/index.ex:57
|
#: lib/mv_web/live/member_live/index.ex:57
|
||||||
#: lib/mv_web/live/member_live/index.html.heex:3
|
#: lib/mv_web/live/member_live/index.html.heex:3
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -339,7 +340,7 @@ msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:107
|
#: lib/mv_web/live/user_live/form.ex:107
|
||||||
#: lib/mv_web/live/user_live/form.ex:115
|
#: lib/mv_web/live/user_live/form.ex:115
|
||||||
#: lib/mv_web/live/user_live/form.ex:210
|
#: lib/mv_web/live/user_live/form.ex:224
|
||||||
#, elixir-autogen, elixir-format, fuzzy
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -355,7 +356,7 @@ msgstr ""
|
||||||
msgid "Password Authentication"
|
msgid "Password Authentication"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:89
|
#: lib/mv_web/components/layouts/navbar.ex:95
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Profil"
|
msgid "Profil"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -375,12 +376,12 @@ msgstr ""
|
||||||
msgid "Select member"
|
msgid "Select member"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:92
|
#: lib/mv_web/components/layouts/navbar.ex:99
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:235
|
#: lib/mv_web/live/user_live/form.ex:249
|
||||||
#, elixir-autogen, elixir-format, fuzzy
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
msgid "Save User"
|
msgid "Save User"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -405,7 +406,7 @@ msgstr ""
|
||||||
msgid "Use this form to manage user records in your database."
|
msgid "Use this form to manage user records in your database."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:252
|
#: lib/mv_web/live/user_live/form.ex:266
|
||||||
#: lib/mv_web/live/user_live/show.ex:34
|
#: lib/mv_web/live/user_live/show.ex:34
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "User"
|
msgid "User"
|
||||||
|
|
@ -433,7 +434,7 @@ msgstr ""
|
||||||
msgid "descending"
|
msgid "descending"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:251
|
#: lib/mv_web/live/user_live/form.ex:265
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "New"
|
msgid "New"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -543,14 +544,14 @@ msgstr ""
|
||||||
msgid "Back to users list"
|
msgid "Back to users list"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:27
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:33
|
#: lib/mv_web/components/layouts/navbar.ex:33
|
||||||
|
#: lib/mv_web/components/layouts/navbar.ex:39
|
||||||
#, elixir-autogen, elixir-format, fuzzy
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
msgid "Select language"
|
msgid "Select language"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:40
|
#: lib/mv_web/components/layouts/navbar.ex:46
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:60
|
#: lib/mv_web/components/layouts/navbar.ex:66
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Toggle dark mode"
|
msgid "Toggle dark mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -561,7 +562,7 @@ msgstr ""
|
||||||
msgid "Search..."
|
msgid "Search..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:21
|
#: lib/mv_web/components/layouts/navbar.ex:27
|
||||||
#, elixir-autogen, elixir-format, fuzzy
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
msgid "Users"
|
msgid "Users"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -654,7 +655,7 @@ msgstr ""
|
||||||
msgid "Use this form to manage custom_field records in your database."
|
msgid "Use this form to manage custom_field records in your database."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/components/layouts/navbar.ex:20
|
#: lib/mv_web/components/layouts/navbar.ex:26
|
||||||
#, elixir-autogen, elixir-format, fuzzy
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
msgid "Custom Fields"
|
msgid "Custom Fields"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -701,37 +702,73 @@ msgstr ""
|
||||||
msgid "To confirm deletion, please enter this text:"
|
msgid "To confirm deletion, please enter this text:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:210
|
#: lib/mv_web/live/custom_field_live/form.ex:64
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Show in overview"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/global_settings_live.ex:51
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Association Name"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/global_settings_live.ex:31
|
||||||
|
#: lib/mv_web/live/global_settings_live.ex:41
|
||||||
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
msgid "Club Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/global_settings_live.ex:43
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Manage global settings for the association."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/global_settings_live.ex:56
|
||||||
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
msgid "Save Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/global_settings_live.ex:75
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Settings updated successfully"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/user_live/form.ex:224
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "A member with this email already exists. To link with a different member, please change one of the email addresses first."
|
msgid "A member with this email already exists. To link with a different member, please change one of the email addresses first."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:185
|
#: lib/mv_web/live/user_live/form.ex:192
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Available members"
|
msgid "Available members"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/user_live/form.ex:357
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Failed to link member: %{error}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:152
|
#: lib/mv_web/live/user_live/form.ex:152
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Member will be unlinked when you save. Cannot select new member until saved."
|
msgid "Member will be unlinked when you save. Cannot select new member until saved."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:226
|
#: lib/mv_web/live/user_live/form.ex:240
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Save to confirm linking."
|
msgid "Save to confirm linking."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:169
|
#: lib/mv_web/live/user_live/form.ex:171
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Search for a member to link..."
|
msgid "Search for a member to link..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:173
|
#: lib/mv_web/live/user_live/form.ex:175
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Search for member to link"
|
msgid "Search for member to link"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:223
|
#: lib/mv_web/live/user_live/form.ex:237
|
||||||
#, elixir-autogen, elixir-format, fuzzy
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
msgid "Selected"
|
msgid "Selected"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -746,15 +783,6 @@ msgstr ""
|
||||||
msgid "Unlinking scheduled"
|
msgid "Unlinking scheduled"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/user_live/form.ex:342
|
|
||||||
#, elixir-autogen, elixir-format
|
|
||||||
msgid "Failed to link member: %{error}"
|
|
||||||
msgstr ""
|
|
||||||
#: lib/mv_web/live/custom_field_live/form.ex:64
|
|
||||||
#, elixir-autogen, elixir-format
|
|
||||||
msgid "Show in overview"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#~ #: lib/mv_web/live/custom_field_live/index.ex:97
|
#~ #: lib/mv_web/live/custom_field_live/index.ex:97
|
||||||
#~ #, elixir-autogen, elixir-format
|
#~ #, elixir-autogen, elixir-format
|
||||||
#~ msgid "To confirm deletion, please enter the custom field slug:"
|
#~ msgid "To confirm deletion, please enter the custom field slug:"
|
||||||
|
|
|
||||||
31
priv/repo/migrations/20251127134451_add_settings_table.exs
Normal file
31
priv/repo/migrations/20251127134451_add_settings_table.exs
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
defmodule Mv.Repo.Migrations.AddSettingsTable do
|
||||||
|
@moduledoc """
|
||||||
|
Updates resources based on their most recent snapshots.
|
||||||
|
|
||||||
|
This file was autogenerated with `mix ash_postgres.generate_migrations`
|
||||||
|
"""
|
||||||
|
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def up do
|
||||||
|
create table(:settings, primary_key: false) do
|
||||||
|
add :id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true
|
||||||
|
add :club_name, :text, null: false
|
||||||
|
|
||||||
|
add :inserted_at, :utc_datetime_usec,
|
||||||
|
null: false,
|
||||||
|
default: fragment("(now() AT TIME ZONE 'utc')")
|
||||||
|
|
||||||
|
add :updated_at, :utc_datetime_usec,
|
||||||
|
null: false,
|
||||||
|
default: fragment("(now() AT TIME ZONE 'utc')")
|
||||||
|
end
|
||||||
|
|
||||||
|
# Note: Singleton pattern is enforced at application level via get_settings/0
|
||||||
|
# which creates the record if it doesn't exist and only allows updates
|
||||||
|
end
|
||||||
|
|
||||||
|
def down do
|
||||||
|
drop table(:settings)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -323,8 +323,21 @@ if friedrich = find_member.("friedrich.wagner@example.de") do
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Create or update global settings (singleton)
|
||||||
|
default_club_name = System.get_env("ASSOCIATION_NAME") || "Club Name"
|
||||||
|
|
||||||
|
case Membership.get_settings() do
|
||||||
|
{:ok, existing_settings} ->
|
||||||
|
# Settings exist, update if club_name is different from env var
|
||||||
|
if existing_settings.club_name != default_club_name do
|
||||||
|
{:ok, _updated} =
|
||||||
|
Membership.update_settings(existing_settings, %{club_name: default_club_name})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
IO.puts("✅ Seeds completed successfully!")
|
IO.puts("✅ Seeds completed successfully!")
|
||||||
IO.puts("📝 Created sample data:")
|
IO.puts("📝 Created sample data:")
|
||||||
|
IO.puts(" - Global settings: club_name = #{default_club_name}")
|
||||||
IO.puts(" - Custom fields: 12 fields (String, Date, Boolean, Email, + 8 realistic fields)")
|
IO.puts(" - Custom fields: 12 fields (String, Date, Boolean, Email, + 8 realistic fields)")
|
||||||
IO.puts(" - Admin user: admin@mv.local (password: testpassword)")
|
IO.puts(" - Admin user: admin@mv.local (password: testpassword)")
|
||||||
IO.puts(" - Sample members: Hans, Greta, Friedrich")
|
IO.puts(" - Sample members: Hans, Greta, Friedrich")
|
||||||
|
|
|
||||||
67
priv/resource_snapshots/repo/settings/20251127134451.json
Normal file
67
priv/resource_snapshots/repo/settings/20251127134451.json
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
{
|
||||||
|
"attributes": [
|
||||||
|
{
|
||||||
|
"allow_nil?": false,
|
||||||
|
"default": "fragment(\"gen_random_uuid()\")",
|
||||||
|
"generated?": false,
|
||||||
|
"precision": null,
|
||||||
|
"primary_key?": true,
|
||||||
|
"references": null,
|
||||||
|
"scale": null,
|
||||||
|
"size": null,
|
||||||
|
"source": "id",
|
||||||
|
"type": "uuid"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_nil?": false,
|
||||||
|
"default": "nil",
|
||||||
|
"generated?": false,
|
||||||
|
"precision": null,
|
||||||
|
"primary_key?": false,
|
||||||
|
"references": null,
|
||||||
|
"scale": null,
|
||||||
|
"size": null,
|
||||||
|
"source": "club_name",
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_nil?": false,
|
||||||
|
"default": "fragment(\"(now() AT TIME ZONE 'utc')\")",
|
||||||
|
"generated?": false,
|
||||||
|
"precision": null,
|
||||||
|
"primary_key?": false,
|
||||||
|
"references": null,
|
||||||
|
"scale": null,
|
||||||
|
"size": null,
|
||||||
|
"source": "inserted_at",
|
||||||
|
"type": "utc_datetime_usec"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_nil?": false,
|
||||||
|
"default": "fragment(\"(now() AT TIME ZONE 'utc')\")",
|
||||||
|
"generated?": false,
|
||||||
|
"precision": null,
|
||||||
|
"primary_key?": false,
|
||||||
|
"references": null,
|
||||||
|
"scale": null,
|
||||||
|
"size": null,
|
||||||
|
"source": "updated_at",
|
||||||
|
"type": "utc_datetime_usec"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"base_filter": null,
|
||||||
|
"check_constraints": [],
|
||||||
|
"custom_indexes": [],
|
||||||
|
"custom_statements": [],
|
||||||
|
"has_create_action": true,
|
||||||
|
"hash": "353EB39F18B97C596A77A78A060FB9DE075AAD731F74F64AB62D357CBCDEC914",
|
||||||
|
"identities": [],
|
||||||
|
"multitenancy": {
|
||||||
|
"attribute": null,
|
||||||
|
"global": null,
|
||||||
|
"strategy": null
|
||||||
|
},
|
||||||
|
"repo": "Elixir.Mv.Repo",
|
||||||
|
"schema": null,
|
||||||
|
"table": "settings"
|
||||||
|
}
|
||||||
61
test/membership/setting_env_test.exs
Normal file
61
test/membership/setting_env_test.exs
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
defmodule Mv.Membership.SettingEnvTest do
|
||||||
|
use Mv.DataCase, async: false
|
||||||
|
alias Mv.Membership
|
||||||
|
|
||||||
|
describe "Settings with environment variable" do
|
||||||
|
test "club_name can be set via ASSOCIATION_NAME environment variable" do
|
||||||
|
# Set environment variable
|
||||||
|
System.put_env("ASSOCIATION_NAME", "Test Association from Env")
|
||||||
|
|
||||||
|
try do
|
||||||
|
# Get settings - should use environment variable if no DB value exists
|
||||||
|
{:ok, settings} = Membership.get_settings()
|
||||||
|
|
||||||
|
# If settings don't have a club_name in DB, it should use the env var
|
||||||
|
# This depends on implementation - we'll check that the env var is respected
|
||||||
|
assert settings.club_name != nil
|
||||||
|
after
|
||||||
|
# Clean up
|
||||||
|
System.delete_env("ASSOCIATION_NAME")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "database value takes precedence over environment variable" do
|
||||||
|
# Set environment variable
|
||||||
|
System.put_env("ASSOCIATION_NAME", "Env Value")
|
||||||
|
|
||||||
|
try do
|
||||||
|
# Set a value in the database
|
||||||
|
{:ok, settings} = Membership.get_settings()
|
||||||
|
{:ok, _updated} = Membership.update_settings(settings, %{club_name: "DB Value"})
|
||||||
|
|
||||||
|
# Get settings again - should use DB value, not env var
|
||||||
|
{:ok, settings_after} = Membership.get_settings()
|
||||||
|
assert settings_after.club_name == "DB Value"
|
||||||
|
after
|
||||||
|
# Clean up
|
||||||
|
System.delete_env("ASSOCIATION_NAME")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "uses environment variable when database value is not set" do
|
||||||
|
# Set environment variable
|
||||||
|
System.put_env("ASSOCIATION_NAME", "Default from Env")
|
||||||
|
|
||||||
|
try do
|
||||||
|
# Clear database value (if possible) or check that env var is used
|
||||||
|
{:ok, settings} = Membership.get_settings()
|
||||||
|
|
||||||
|
# If club_name is nil or empty in DB, should use env var
|
||||||
|
# This test depends on implementation details
|
||||||
|
# We're testing that the env var fallback works
|
||||||
|
club_name = settings.club_name || System.get_env("ASSOCIATION_NAME")
|
||||||
|
assert club_name != nil
|
||||||
|
assert club_name != ""
|
||||||
|
after
|
||||||
|
# Clean up
|
||||||
|
System.delete_env("ASSOCIATION_NAME")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
51
test/membership/setting_test.exs
Normal file
51
test/membership/setting_test.exs
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
defmodule Mv.Membership.SettingTest do
|
||||||
|
use Mv.DataCase, async: false
|
||||||
|
alias Mv.Membership
|
||||||
|
|
||||||
|
describe "Settings Resource" do
|
||||||
|
test "can read settings" do
|
||||||
|
# Settings should be a singleton resource
|
||||||
|
assert {:ok, _settings} = Membership.get_settings()
|
||||||
|
end
|
||||||
|
|
||||||
|
test "settings have club_name attribute" do
|
||||||
|
{:ok, settings} = Membership.get_settings()
|
||||||
|
assert Map.has_key?(settings, :club_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "can update club_name" do
|
||||||
|
{:ok, settings} = Membership.get_settings()
|
||||||
|
|
||||||
|
assert {:ok, updated_settings} =
|
||||||
|
Membership.update_settings(settings, %{club_name: "New Club Name"})
|
||||||
|
|
||||||
|
assert updated_settings.club_name == "New Club Name"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "club_name is required" do
|
||||||
|
{:ok, settings} = Membership.get_settings()
|
||||||
|
|
||||||
|
assert {:error, %Ash.Error.Invalid{errors: errors}} =
|
||||||
|
Membership.update_settings(settings, %{club_name: nil})
|
||||||
|
|
||||||
|
assert error_message(errors, :club_name) =~ "must be present"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "club_name cannot be empty" do
|
||||||
|
{:ok, settings} = Membership.get_settings()
|
||||||
|
|
||||||
|
assert {:error, %Ash.Error.Invalid{errors: errors}} =
|
||||||
|
Membership.update_settings(settings, %{club_name: ""})
|
||||||
|
|
||||||
|
assert error_message(errors, :club_name) =~ "must be present"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Helper function to extract error messages
|
||||||
|
defp error_message(errors, field) do
|
||||||
|
errors
|
||||||
|
|> Enum.filter(fn err -> Map.get(err, :field) == field end)
|
||||||
|
|> Enum.map(&Map.get(&1, :message, ""))
|
||||||
|
|> List.first() || ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -84,5 +84,23 @@ defmodule MvWeb.Layouts.NavbarTest do
|
||||||
# Check for correct logout path
|
# Check for correct logout path
|
||||||
assert html =~ ~s(href="/sign-out")
|
assert html =~ ~s(href="/sign-out")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "Settings link navigates to global settings page", %{conn: conn} do
|
||||||
|
user = create_test_user(%{email: "test@example.com"})
|
||||||
|
conn = conn_with_oidc_user(conn, user)
|
||||||
|
|
||||||
|
html =
|
||||||
|
render_component(&MvWeb.Layouts.Navbar.navbar/1, %{
|
||||||
|
current_user: user
|
||||||
|
})
|
||||||
|
|
||||||
|
# Check that Settings link exists and points to /settings
|
||||||
|
assert html =~ "Settings"
|
||||||
|
assert html =~ ~s(href="/settings") || html =~ ~s(navigate="/settings")
|
||||||
|
|
||||||
|
# Verify the link actually works by navigating to it
|
||||||
|
{:ok, _view, settings_html} = live(conn, ~p"/settings")
|
||||||
|
assert settings_html =~ "Club Settings"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
defmodule MvWeb.PageControllerTest do
|
defmodule MvWeb.PageControllerTest do
|
||||||
use MvWeb.ConnCase
|
use MvWeb.ConnCase, async: true
|
||||||
|
|
||||||
test "GET /", %{conn: conn} do
|
test "renders home template successfully with authenticated user", %{conn: conn} do
|
||||||
conn = conn_with_oidc_user(conn)
|
user = create_test_user(%{email: "test@example.com"})
|
||||||
|
conn = conn_with_oidc_user(conn, user)
|
||||||
|
conn = get(conn, "/")
|
||||||
|
|
||||||
conn = get(conn, ~p"/")
|
assert html_response(conn, 200)
|
||||||
assert html_response(conn, 200) =~ "Mitgliederverwaltung"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
68
test/mv_web/live/global_settings_live_test.exs
Normal file
68
test/mv_web/live/global_settings_live_test.exs
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
defmodule MvWeb.GlobalSettingsLiveTest do
|
||||||
|
use MvWeb.ConnCase, async: true
|
||||||
|
import Phoenix.LiveViewTest
|
||||||
|
alias Mv.Membership
|
||||||
|
|
||||||
|
describe "Global Settings LiveView" do
|
||||||
|
setup %{conn: conn} do
|
||||||
|
user = create_test_user(%{email: "admin@example.com"})
|
||||||
|
conn = conn_with_oidc_user(conn, user)
|
||||||
|
{:ok, conn: conn, user: user}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "renders the global settings page", %{conn: conn} do
|
||||||
|
{:ok, _view, html} = live(conn, ~p"/settings")
|
||||||
|
|
||||||
|
assert html =~ "Club Settings"
|
||||||
|
assert html =~ "Settings"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "displays current club name", %{conn: conn} do
|
||||||
|
# Set initial club name
|
||||||
|
{:ok, settings} = Membership.get_settings()
|
||||||
|
{:ok, _updated} = Membership.update_settings(settings, %{club_name: "Test Club"})
|
||||||
|
|
||||||
|
{:ok, _view, html} = live(conn, ~p"/settings")
|
||||||
|
|
||||||
|
assert html =~ "Test Club"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "can update club name via form", %{conn: conn} do
|
||||||
|
{:ok, view, _html} = live(conn, ~p"/settings")
|
||||||
|
|
||||||
|
# Submit form with new club name
|
||||||
|
assert view
|
||||||
|
|> form("#settings-form", %{setting: %{club_name: "Updated Club Name"}})
|
||||||
|
|> render_submit()
|
||||||
|
|
||||||
|
# Check for success message
|
||||||
|
assert render(view) =~ "Settings updated successfully"
|
||||||
|
assert render(view) =~ "Updated Club Name"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "shows error when club_name is empty", %{conn: conn} do
|
||||||
|
{:ok, view, _html} = live(conn, ~p"/settings")
|
||||||
|
|
||||||
|
# Submit form with empty club name
|
||||||
|
html =
|
||||||
|
view
|
||||||
|
|> form("#settings-form", %{setting: %{club_name: ""}})
|
||||||
|
|> render_submit()
|
||||||
|
|
||||||
|
assert html =~ "must be present"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "shows error when club_name is missing", %{conn: conn} do
|
||||||
|
{:ok, view, _html} = live(conn, ~p"/settings")
|
||||||
|
|
||||||
|
# Submit form with club_name explicitly set to empty string
|
||||||
|
# (Phoenix forms will keep existing value if field is omitted)
|
||||||
|
html =
|
||||||
|
view
|
||||||
|
|> form("#settings-form", %{setting: %{club_name: ""}})
|
||||||
|
|> render_submit()
|
||||||
|
|
||||||
|
assert html =~ "must be present"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Add table
Add a link
Reference in a new issue