style: consistent back button and some translations
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
91cf7cca6a
commit
0f12befd11
26 changed files with 747 additions and 710 deletions
|
|
@ -61,7 +61,7 @@ We are building a membership management system (Mila) using the following techno
|
|||
8. [Accessibility Guidelines](#8-accessibility-guidelines)
|
||||
|
||||
**Related documents:**
|
||||
- **UI / UX:** [`DESIGN_DUIDELINES.md`](../DESIGN_DUIDELINES.md) defines visual and interaction consistency: use of CoreComponents (no raw DaisyUI in views), page skeleton (`<.header>`, `mt-6 space-y-6`), typography, buttons, forms, tables, flash/toast, and microcopy (e.g. German "du" and glossary). Follow "components first" and semantic variants instead of hard-coded colors.
|
||||
- **UI / UX:** [`DESIGN_DUIDELINES.md`](../DESIGN_DUIDELINES.md) defines visual and interaction consistency: use of CoreComponents (no raw DaisyUI in views), page skeleton (`<.header>`, `mt-6 space-y-6`), **Back button left in header for edit/new forms** (§2.2), typography, buttons, forms, tables, flash/toast, and microcopy (e.g. German "du" and glossary). Follow "components first" and semantic variants instead of hard-coded colors.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -46,19 +46,35 @@ Every authenticated page should follow the same structure:
|
|||
**MUST:** Use `<.header>` on every page (except login/public pages).
|
||||
**SHOULD:** Put short explanations into `<:subtitle>` rather than sprinkling random text blocks.
|
||||
|
||||
**Template:**
|
||||
### 2.2 Edit/New form header: Back button left (mandatory)
|
||||
|
||||
For LiveViews that render an edit or new form (e.g. member, group, role, user, custom field, membership fee type):
|
||||
|
||||
- **MUST:** Provide a **Back** button on the **left** side of the header using the `<:leading>` slot (same as data fields: Back left, title next, primary action on the right).
|
||||
- **MUST:** Use the same pattern everywhere: Back button with `variant="neutral"`, arrow-left icon, and label “Back”. It navigates to the previous context (e.g. detail page or index) via a `return_path`-style helper.
|
||||
- **SHOULD:** Place the primary action (e.g. “Save”) in `<:actions>` on the right.
|
||||
- **Rationale:** Users expect a consistent way to leave the form without submitting; Back left matches the data fields edit view and keeps primary actions on the right.
|
||||
|
||||
**Template for form pages:**
|
||||
```heex
|
||||
<.header>
|
||||
Title
|
||||
<:subtitle>Short explanation of what the page is for.</:subtitle>
|
||||
<:leading>
|
||||
<.button navigate={return_path(@return_to, @resource)} variant="neutral">
|
||||
<.icon name="hero-arrow-left" class="size-4" />
|
||||
{gettext("Back")}
|
||||
</.button>
|
||||
</:leading>
|
||||
Page title (e.g. “Edit Member” or “New User”)
|
||||
<:subtitle>Short explanation.</:subtitle>
|
||||
<:actions>
|
||||
<.button variant="primary" navigate={...}>Primary action</.button>
|
||||
<.button phx-disable-with={gettext("Saving...")} variant="primary" type="submit">
|
||||
{gettext("Save")}
|
||||
</.button>
|
||||
</:actions>
|
||||
</.header>
|
||||
```
|
||||
|
||||
<div class="mt-6 space-y-6">
|
||||
<!-- Sections / Cards / Tables -->
|
||||
</div>
|
||||
If the `<.header>` is outside the `<.form>`, the submit button must reference the form via the `form` attribute (e.g. `form="user-form"`).
|
||||
|
||||
## 3) Typography (system)
|
||||
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ defmodule MvWeb.CoreComponents do
|
|||
<.button variant="ghost" size="sm">Edit</.button>
|
||||
<.button disabled={true}>Disabled</.button>
|
||||
"""
|
||||
attr :rest, :global, include: ~w(href navigate patch method data-testid)
|
||||
attr :rest, :global, include: ~w(href navigate patch method data-testid form)
|
||||
|
||||
attr :variant, :string,
|
||||
values: ~w(primary secondary neutral ghost outline danger link icon),
|
||||
|
|
@ -633,17 +633,24 @@ defmodule MvWeb.CoreComponents do
|
|||
|
||||
@doc """
|
||||
Renders a header with title.
|
||||
|
||||
Use the `:leading` slot for the Back button (left side, consistent with data fields).
|
||||
Use the `:actions` slot for primary actions (e.g. Save) on the right.
|
||||
"""
|
||||
attr :class, :string, default: nil
|
||||
|
||||
slot :leading, doc: "Content on the left (e.g. Back button)"
|
||||
slot :inner_block, required: true
|
||||
slot :subtitle
|
||||
slot :actions
|
||||
|
||||
def header(assigns) do
|
||||
~H"""
|
||||
<header class={[@actions != [] && "flex items-center justify-between gap-6", "pb-4", @class]}>
|
||||
<div>
|
||||
<header class={["flex items-center gap-6 pb-4", @class]}>
|
||||
<div :if={@leading != []} class="shrink-0">
|
||||
{render_slot(@leading)}
|
||||
</div>
|
||||
<div class="min-w-0 flex-1">
|
||||
<h1 class="text-xl font-semibold leading-8">
|
||||
{render_slot(@inner_block)}
|
||||
</h1>
|
||||
|
|
@ -651,7 +658,9 @@ defmodule MvWeb.CoreComponents do
|
|||
{render_slot(@subtitle)}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-4 justify-end">{render_slot(@actions)}</div>
|
||||
<div :if={@actions != []} class="shrink-0 flex gap-4 justify-end">
|
||||
{render_slot(@actions)}
|
||||
</div>
|
||||
</header>
|
||||
"""
|
||||
end
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ defmodule MvWeb.Components.FieldVisibilityDropdownComponent do
|
|||
|
||||
defp find_custom_field_name(id, _field_string, custom_fields) do
|
||||
case Enum.find(custom_fields, fn cf -> to_string(cf.id) == id end) do
|
||||
nil -> gettext("Custom Field %{id}", id: id)
|
||||
nil -> gettext("Datafield %{id}", id: id)
|
||||
custom_field -> custom_field.name
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@ defmodule MvWeb.Components.MemberFilterComponent do
|
|||
<!-- Custom Fields Group -->
|
||||
<div :if={length(@boolean_custom_fields) > 0} class="mb-2">
|
||||
<div class="text-xs font-semibold opacity-70 mb-2 uppercase tracking-wider">
|
||||
{gettext("Custom Fields")}
|
||||
{gettext("Individual datafields")}
|
||||
</div>
|
||||
<div class="max-h-60 overflow-y-auto pr-2">
|
||||
<fieldset
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ defmodule MvWeb.CustomFieldLive.FormComponent do
|
|||
<div class="border border-base-300 rounded-lg p-4 bg-base-100">
|
||||
<p class="text-base-content/70 mb-4">
|
||||
{gettext(
|
||||
"Deleting this data field cannot be undone. All custom field values for this field will be permanently removed."
|
||||
"Deleting this data field cannot be undone. All datafield values for this field will be permanently removed."
|
||||
)}
|
||||
</p>
|
||||
<.button
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ defmodule MvWeb.CustomFieldLive.IndexComponent do
|
|||
phx-target={@myself}
|
||||
disabled={@slug_confirmation != @custom_field_to_delete.slug}
|
||||
>
|
||||
{gettext("Delete Custom Field and All Values")}
|
||||
{gettext("Delete Datafields and All Values")}
|
||||
</.button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ defmodule MvWeb.GlobalSettingsLive do
|
|||
</div>
|
||||
|
||||
<.button phx-disable-with={gettext("Saving...")} variant="primary">
|
||||
{gettext("Save Settings")}
|
||||
{gettext("Save Name")}
|
||||
</.button>
|
||||
</.form>
|
||||
</.form_section>
|
||||
|
|
|
|||
|
|
@ -79,12 +79,14 @@ defmodule MvWeb.GroupLive.Form do
|
|||
<Layouts.app flash={@flash} current_user={@current_user}>
|
||||
<.form for={@form} id="group-form" phx-change="validate" phx-submit="save">
|
||||
<.header>
|
||||
{@page_title}
|
||||
<:actions>
|
||||
<:leading>
|
||||
<.button navigate={return_path(@return_to, @group)} variant="neutral">
|
||||
<.icon name="hero-arrow-left" class="size-4" />
|
||||
{gettext("Back")}
|
||||
</.button>
|
||||
</:leading>
|
||||
{@page_title}
|
||||
<:actions>
|
||||
<.button phx-disable-with={gettext("Saving...")} variant="primary" type="submit">
|
||||
{gettext("Save")}
|
||||
</.button>
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ defmodule MvWeb.GroupLive.Show do
|
|||
end
|
||||
end
|
||||
|
||||
defp load_group_by_slug(socket, slug, actor, params \\ %{}) do
|
||||
defp load_group_by_slug(socket, slug, actor, params) do
|
||||
# Load group with members and member_count
|
||||
# Using explicit load ensures efficient preloading of members relationship
|
||||
require Ash.Query
|
||||
|
|
@ -92,8 +92,7 @@ defmodule MvWeb.GroupLive.Show do
|
|||
~H"""
|
||||
<Layouts.app flash={@flash} current_user={@current_user}>
|
||||
<.header>
|
||||
{@group.name}
|
||||
<:actions>
|
||||
<:leading>
|
||||
<.button
|
||||
navigate={~p"/groups"}
|
||||
variant="neutral"
|
||||
|
|
@ -102,13 +101,16 @@ defmodule MvWeb.GroupLive.Show do
|
|||
<.icon name="hero-arrow-left" class="size-4" />
|
||||
{gettext("Back")}
|
||||
</.button>
|
||||
</:leading>
|
||||
{@group.name}
|
||||
<:actions>
|
||||
<%= if can?(@current_user, :update, @group) do %>
|
||||
<.button
|
||||
variant="primary"
|
||||
navigate={~p"/groups/#{@group.slug}/edit"}
|
||||
data-testid="group-show-edit-btn"
|
||||
>
|
||||
{gettext("Edit group")}
|
||||
<.icon name="hero-pencil-square" /> {gettext("Edit group")}
|
||||
</.button>
|
||||
<% end %>
|
||||
</:actions>
|
||||
|
|
|
|||
|
|
@ -39,16 +39,18 @@ defmodule MvWeb.MemberLive.Form do
|
|||
<Layouts.app flash={@flash} current_user={@current_user}>
|
||||
<.form for={@form} id="member-form" phx-change="validate" phx-submit="save">
|
||||
<.header>
|
||||
<:leading>
|
||||
<.button navigate={return_path(@return_to, @member)} variant="neutral">
|
||||
<.icon name="hero-arrow-left" class="size-4" />
|
||||
{gettext("Back")}
|
||||
</.button>
|
||||
</:leading>
|
||||
<%= if @member do %>
|
||||
{MvWeb.Helpers.MemberHelpers.display_name(@member)}
|
||||
<% else %>
|
||||
{gettext("New Member")}
|
||||
<% end %>
|
||||
<:actions>
|
||||
<.button navigate={return_path(@return_to, @member)} variant="neutral">
|
||||
<.icon name="hero-arrow-left" class="size-4" />
|
||||
{gettext("Back")}
|
||||
</.button>
|
||||
<.button phx-disable-with={gettext("Saving...")} variant="primary" type="submit">
|
||||
{gettext("Save")}
|
||||
</.button>
|
||||
|
|
@ -408,32 +410,33 @@ defmodule MvWeb.MemberLive.Form do
|
|||
member = socket.assigns.member
|
||||
actor = current_actor(socket)
|
||||
|
||||
if is_nil(member) do
|
||||
{:noreply, put_flash(socket, :error, gettext("Member not found"))}
|
||||
else
|
||||
if to_string(id) != to_string(member.id) do
|
||||
cond do
|
||||
is_nil(member) ->
|
||||
{:noreply, put_flash(socket, :error, gettext("Member not found"))}
|
||||
else
|
||||
case Ash.destroy(member, actor: actor) do
|
||||
:ok ->
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:success, gettext("Member deleted successfully"))
|
||||
|> push_navigate(to: ~p"/members")}
|
||||
|
||||
{:error, %Ash.Error.Forbidden{}} ->
|
||||
{:noreply,
|
||||
put_flash(
|
||||
socket,
|
||||
:error,
|
||||
gettext("You do not have permission to delete this member")
|
||||
)}
|
||||
to_string(id) != to_string(member.id) ->
|
||||
{:noreply, put_flash(socket, :error, gettext("Member not found"))}
|
||||
|
||||
{:error, error} ->
|
||||
Logger.warning("Member delete failed: member_id=#{member.id} error=#{inspect(error)}")
|
||||
{:noreply, put_flash(socket, :error, format_destroy_error(error))}
|
||||
end
|
||||
end
|
||||
true ->
|
||||
handle_member_delete_destroy(socket, member, actor)
|
||||
end
|
||||
end
|
||||
|
||||
defp handle_member_delete_destroy(socket, member, actor) do
|
||||
case Ash.destroy(member, actor: actor) do
|
||||
:ok ->
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:success, gettext("Member deleted successfully"))
|
||||
|> push_navigate(to: ~p"/members")}
|
||||
|
||||
{:error, %Ash.Error.Forbidden{}} ->
|
||||
{:noreply,
|
||||
put_flash(socket, :error, gettext("You do not have permission to delete this member"))}
|
||||
|
||||
{:error, error} ->
|
||||
Logger.warning("Member delete failed: member_id=#{member.id} error=#{inspect(error)}")
|
||||
{:noreply, put_flash(socket, :error, format_destroy_error(error))}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -31,8 +31,7 @@ defmodule MvWeb.MemberLive.Show do
|
|||
~H"""
|
||||
<Layouts.app flash={@flash} current_user={@current_user}>
|
||||
<.header>
|
||||
{MvWeb.Helpers.MemberHelpers.display_name(@member)}
|
||||
<:actions>
|
||||
<:leading>
|
||||
<.button
|
||||
navigate={~p"/members?highlight=#{@member.id}"}
|
||||
variant="neutral"
|
||||
|
|
@ -41,13 +40,16 @@ defmodule MvWeb.MemberLive.Show do
|
|||
<.icon name="hero-arrow-left" class="size-4" />
|
||||
{gettext("Back")}
|
||||
</.button>
|
||||
</:leading>
|
||||
{MvWeb.Helpers.MemberHelpers.display_name(@member)}
|
||||
<:actions>
|
||||
<%= if can?(@current_user, :update, @member) do %>
|
||||
<.button
|
||||
variant="primary"
|
||||
navigate={~p"/members/#{@member}/edit?return_to=show"}
|
||||
data-testid="member-edit"
|
||||
>
|
||||
{gettext("Edit member")}
|
||||
<.icon name="hero-pencil-square" /> {gettext("Edit member")}
|
||||
</.button>
|
||||
<% end %>
|
||||
</:actions>
|
||||
|
|
|
|||
|
|
@ -27,10 +27,26 @@ defmodule MvWeb.MembershipFeeTypeLive.Form do
|
|||
~H"""
|
||||
<Layouts.app flash={@flash} current_user={@current_user}>
|
||||
<.header>
|
||||
<:leading>
|
||||
<.button navigate={return_path(@return_to, @membership_fee_type)} variant="neutral">
|
||||
<.icon name="hero-arrow-left" class="size-4" />
|
||||
{gettext("Back")}
|
||||
</.button>
|
||||
</:leading>
|
||||
{@page_title}
|
||||
<:subtitle>
|
||||
{gettext("Use this form to manage membership fee types in your database.")}
|
||||
</:subtitle>
|
||||
<:actions>
|
||||
<.button
|
||||
form="membership-fee-type-form"
|
||||
phx-disable-with={gettext("Saving...")}
|
||||
variant="primary"
|
||||
type="submit"
|
||||
>
|
||||
{gettext("Save")}
|
||||
</.button>
|
||||
</:actions>
|
||||
</.header>
|
||||
|
||||
<.form
|
||||
|
|
|
|||
|
|
@ -23,13 +23,15 @@ defmodule MvWeb.RoleLive.Form do
|
|||
<Layouts.app flash={@flash} current_user={@current_user}>
|
||||
<.form class="max-w-xl" for={@form} id="role-form" phx-change="validate" phx-submit="save">
|
||||
<.header>
|
||||
{@page_title}
|
||||
<:subtitle>{gettext("Use this form to manage roles in your database.")}</:subtitle>
|
||||
<:actions>
|
||||
<:leading>
|
||||
<.button navigate={return_path(@return_to, @role)} variant="neutral">
|
||||
<.icon name="hero-arrow-left" class="size-4" />
|
||||
{gettext("Back")}
|
||||
</.button>
|
||||
</:leading>
|
||||
{@page_title}
|
||||
<:subtitle>{gettext("Use this form to manage roles in your database.")}</:subtitle>
|
||||
<:actions>
|
||||
<.button phx-disable-with={gettext("Saving...")} variant="primary" type="submit">
|
||||
{gettext("Save")}
|
||||
</.button>
|
||||
|
|
|
|||
|
|
@ -161,10 +161,7 @@ defmodule MvWeb.RoleLive.Show do
|
|||
~H"""
|
||||
<Layouts.app flash={@flash} current_user={@current_user}>
|
||||
<.header>
|
||||
{gettext("Role")} {@role.name}
|
||||
<:subtitle>{gettext("Role details and permissions.")}</:subtitle>
|
||||
|
||||
<:actions>
|
||||
<:leading>
|
||||
<.button
|
||||
navigate={~p"/admin/roles"}
|
||||
variant="neutral"
|
||||
|
|
@ -173,13 +170,18 @@ defmodule MvWeb.RoleLive.Show do
|
|||
<.icon name="hero-arrow-left" class="size-4" />
|
||||
{gettext("Back")}
|
||||
</.button>
|
||||
</:leading>
|
||||
{gettext("Role")} {@role.name}
|
||||
<:subtitle>{gettext("Role details and permissions.")}</:subtitle>
|
||||
|
||||
<:actions>
|
||||
<%= if can?(@current_user, :update, Mv.Authorization.Role) do %>
|
||||
<.button
|
||||
variant="primary"
|
||||
navigate={~p"/admin/roles/#{@role}/edit"}
|
||||
data-testid="role-show-edit-btn"
|
||||
>
|
||||
{gettext("Edit role")}
|
||||
<.icon name="hero-pencil-square" /> {gettext("Edit role")}
|
||||
</.button>
|
||||
<% end %>
|
||||
</:actions>
|
||||
|
|
|
|||
|
|
@ -46,8 +46,24 @@ defmodule MvWeb.UserLive.Form do
|
|||
~H"""
|
||||
<Layouts.app flash={@flash} current_user={@current_user}>
|
||||
<.header>
|
||||
<:leading>
|
||||
<.button navigate={return_path(@return_to, @user)} variant="neutral">
|
||||
<.icon name="hero-arrow-left" class="size-4" />
|
||||
{gettext("Back")}
|
||||
</.button>
|
||||
</:leading>
|
||||
{@page_title}
|
||||
<:subtitle>{gettext("Use this form to manage user records in your database.")}</:subtitle>
|
||||
<:actions>
|
||||
<.button
|
||||
form="user-form"
|
||||
phx-disable-with={gettext("Saving...")}
|
||||
variant="primary"
|
||||
type="submit"
|
||||
>
|
||||
{gettext("Save User")}
|
||||
</.button>
|
||||
</:actions>
|
||||
</.header>
|
||||
|
||||
<.form class="max-w-xl" for={@form} id="user-form" phx-change="validate" phx-submit="save">
|
||||
|
|
@ -300,7 +316,8 @@ defmodule MvWeb.UserLive.Form do
|
|||
phx-click="delete"
|
||||
phx-value-id={@user.id}
|
||||
data-confirm={
|
||||
gettext("Are you sure you want to delete the user %{email}? This action cannot be undone.",
|
||||
gettext(
|
||||
"Are you sure you want to delete the user %{email}? This action cannot be undone.",
|
||||
email: @user.email
|
||||
)
|
||||
}
|
||||
|
|
@ -442,36 +459,18 @@ defmodule MvWeb.UserLive.Form do
|
|||
user = socket.assigns.user
|
||||
actor = current_actor(socket)
|
||||
|
||||
if is_nil(user) do
|
||||
{:noreply, put_flash(socket, :error, gettext("User not found"))}
|
||||
else
|
||||
if to_string(id) != to_string(user.id) do
|
||||
cond do
|
||||
is_nil(user) ->
|
||||
{:noreply, put_flash(socket, :error, gettext("User not found"))}
|
||||
else
|
||||
if Mv.Helpers.SystemActor.system_user?(user) do
|
||||
{:noreply,
|
||||
put_flash(socket, :error, gettext("System user cannot be deleted."))}
|
||||
else
|
||||
case Ash.destroy(user, domain: Mv.Accounts, actor: actor) do
|
||||
:ok ->
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:success, gettext("User deleted successfully"))
|
||||
|> push_navigate(to: ~p"/users")}
|
||||
|
||||
{:error, %Ash.Error.Forbidden{}} ->
|
||||
{:noreply,
|
||||
put_flash(
|
||||
socket,
|
||||
:error,
|
||||
gettext("You do not have permission to delete this user")
|
||||
)}
|
||||
to_string(id) != to_string(user.id) ->
|
||||
{:noreply, put_flash(socket, :error, gettext("User not found"))}
|
||||
|
||||
{:error, error} ->
|
||||
{:noreply, put_flash(socket, :error, format_ash_error(error))}
|
||||
end
|
||||
end
|
||||
end
|
||||
Mv.Helpers.SystemActor.system_user?(user) ->
|
||||
{:noreply, put_flash(socket, :error, gettext("System user cannot be deleted."))}
|
||||
|
||||
true ->
|
||||
handle_user_delete_destroy(socket, user, actor)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -585,6 +584,23 @@ defmodule MvWeb.UserLive.Form do
|
|||
{:noreply, socket}
|
||||
end
|
||||
|
||||
defp handle_user_delete_destroy(socket, user, actor) do
|
||||
case Ash.destroy(user, domain: Mv.Accounts, actor: actor) do
|
||||
:ok ->
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:success, gettext("User deleted successfully"))
|
||||
|> push_navigate(to: ~p"/users")}
|
||||
|
||||
{:error, %Ash.Error.Forbidden{}} ->
|
||||
{:noreply,
|
||||
put_flash(socket, :error, gettext("You do not have permission to delete this user"))}
|
||||
|
||||
{:error, error} ->
|
||||
{:noreply, put_flash(socket, :error, format_ash_error(error))}
|
||||
end
|
||||
end
|
||||
|
||||
defp handle_member_linking(socket, user, actor) do
|
||||
result = perform_member_link_action(socket, user, actor)
|
||||
|
||||
|
|
|
|||
|
|
@ -7,15 +7,10 @@ defmodule MvWeb.UserLive.Index do
|
|||
- Sort users by email (default)
|
||||
- Navigate to user details (row click) and edit from details header
|
||||
- Delete only via Danger zone on user show/edit
|
||||
- Bulk selection for future batch operations
|
||||
|
||||
## Relationships
|
||||
Displays linked member information when a user is connected to a member account.
|
||||
|
||||
## Events
|
||||
- `select_user` - Toggle individual user selection
|
||||
- `select_all` - Toggle selection of all visible users
|
||||
|
||||
## Security
|
||||
User deletion requires admin permissions (enforced by Ash policies).
|
||||
"""
|
||||
|
|
@ -42,24 +37,7 @@ defmodule MvWeb.UserLive.Index do
|
|||
|> assign(:page_title, gettext("Listing Users"))
|
||||
|> assign(:sort_field, :email)
|
||||
|> assign(:sort_order, :asc)
|
||||
|> assign(:users, sorted)
|
||||
|> assign(:selected_users, [])}
|
||||
end
|
||||
|
||||
# Selects one user in the list of users
|
||||
@impl true
|
||||
def handle_event("select_user", %{"id" => id}, socket) do
|
||||
# Normalize ID to string for consistent comparison
|
||||
id_str = to_string(id)
|
||||
|
||||
selected =
|
||||
if id_str in socket.assigns.selected_users do
|
||||
List.delete(socket.assigns.selected_users, id_str)
|
||||
else
|
||||
[id_str | socket.assigns.selected_users]
|
||||
end
|
||||
|
||||
{:noreply, assign(socket, :selected_users, selected)}
|
||||
|> assign(:users, sorted)}
|
||||
end
|
||||
|
||||
# Sorts the list of users according to a field, when you click on the column header
|
||||
|
|
@ -86,24 +64,6 @@ defmodule MvWeb.UserLive.Index do
|
|||
|> assign(:users, sorted_users)}
|
||||
end
|
||||
|
||||
# Selects all users in the list of users
|
||||
@impl true
|
||||
def handle_event("select_all", _params, socket) do
|
||||
users = socket.assigns.users
|
||||
|
||||
# Normalize IDs to strings for consistent comparison
|
||||
all_ids = Enum.map(users, &to_string(&1.id))
|
||||
|
||||
selected =
|
||||
if Enum.sort(socket.assigns.selected_users) == Enum.sort(all_ids) do
|
||||
[]
|
||||
else
|
||||
all_ids
|
||||
end
|
||||
|
||||
{:noreply, assign(socket, :selected_users, selected)}
|
||||
end
|
||||
|
||||
defp toggle_order(:asc), do: :desc
|
||||
defp toggle_order(:desc), do: :asc
|
||||
defp sort_fun(:asc), do: &<=/2
|
||||
|
|
|
|||
|
|
@ -19,33 +19,6 @@
|
|||
sort_field={@sort_field}
|
||||
sort_order={@sort_order}
|
||||
>
|
||||
<:col
|
||||
:let={user}
|
||||
label={
|
||||
~H"""
|
||||
<.input
|
||||
type="checkbox"
|
||||
name="select_all"
|
||||
phx-click="select_all"
|
||||
checked={Enum.sort(@selected_users) == Enum.map(@users, &to_string(&1.id)) |> Enum.sort()}
|
||||
aria-label={gettext("Select all users")}
|
||||
role="checkbox"
|
||||
/>
|
||||
"""
|
||||
}
|
||||
>
|
||||
<.input
|
||||
type="checkbox"
|
||||
name={to_string(user.id)}
|
||||
phx-click="select_user"
|
||||
phx-value-id={to_string(user.id)}
|
||||
checked={to_string(user.id) in @selected_users}
|
||||
phx-capture-click
|
||||
phx-stop-propagation
|
||||
aria-label={gettext("Select user")}
|
||||
role="checkbox"
|
||||
/>
|
||||
</:col>
|
||||
<:col
|
||||
:let={user}
|
||||
sort_field={:email}
|
||||
|
|
|
|||
|
|
@ -34,14 +34,20 @@ defmodule MvWeb.UserLive.Show do
|
|||
~H"""
|
||||
<Layouts.app flash={@flash} current_user={@current_user}>
|
||||
<.header>
|
||||
<:leading>
|
||||
<.button
|
||||
navigate={~p"/users"}
|
||||
variant="neutral"
|
||||
aria-label={gettext("Back to users list")}
|
||||
>
|
||||
<.icon name="hero-arrow-left" class="size-4" />
|
||||
{gettext("Back")}
|
||||
</.button>
|
||||
</:leading>
|
||||
{gettext("User")} {@user.email}
|
||||
<:subtitle>{gettext("This is a user record from your database.")}</:subtitle>
|
||||
|
||||
<:actions>
|
||||
<.button navigate={~p"/users"} variant="neutral" aria-label={gettext("Back to users list")}>
|
||||
<.icon name="hero-arrow-left" />
|
||||
<span class="sr-only">{gettext("Back to users list")}</span>
|
||||
</.button>
|
||||
<%= if can?(@current_user, :update, @user) do %>
|
||||
<.button
|
||||
variant="primary"
|
||||
|
|
@ -99,7 +105,8 @@ defmodule MvWeb.UserLive.Show do
|
|||
phx-click="delete"
|
||||
phx-value-id={@user.id}
|
||||
data-confirm={
|
||||
gettext("Are you sure you want to delete the user %{email}? This action cannot be undone.",
|
||||
gettext(
|
||||
"Are you sure you want to delete the user %{email}? This action cannot be undone.",
|
||||
email: @user.email
|
||||
)
|
||||
}
|
||||
|
|
@ -141,33 +148,32 @@ defmodule MvWeb.UserLive.Show do
|
|||
user = socket.assigns.user
|
||||
actor = current_actor(socket)
|
||||
|
||||
if to_string(id) != to_string(user.id) do
|
||||
{:noreply, put_flash(socket, :error, gettext("User not found"))}
|
||||
else
|
||||
if Mv.Helpers.SystemActor.system_user?(user) do
|
||||
cond do
|
||||
to_string(id) != to_string(user.id) ->
|
||||
{:noreply, put_flash(socket, :error, gettext("User not found"))}
|
||||
|
||||
Mv.Helpers.SystemActor.system_user?(user) ->
|
||||
{:noreply, put_flash(socket, :error, gettext("System user cannot be deleted."))}
|
||||
|
||||
true ->
|
||||
handle_user_delete_destroy(socket, user, actor)
|
||||
end
|
||||
end
|
||||
|
||||
defp handle_user_delete_destroy(socket, user, actor) do
|
||||
case Ash.destroy(user, domain: Mv.Accounts, actor: actor) do
|
||||
:ok ->
|
||||
{:noreply,
|
||||
put_flash(socket, :error, gettext("System user cannot be deleted."))}
|
||||
else
|
||||
case Ash.destroy(user, domain: Mv.Accounts, actor: actor) do
|
||||
:ok ->
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:success, gettext("User deleted successfully"))
|
||||
|> push_navigate(to: ~p"/users")}
|
||||
socket
|
||||
|> put_flash(:success, gettext("User deleted successfully"))
|
||||
|> push_navigate(to: ~p"/users")}
|
||||
|
||||
{:error, %Ash.Error.Forbidden{}} ->
|
||||
{:noreply,
|
||||
put_flash(
|
||||
socket,
|
||||
:error,
|
||||
gettext("You do not have permission to delete this user")
|
||||
)}
|
||||
{:error, %Ash.Error.Forbidden{}} ->
|
||||
{:noreply,
|
||||
put_flash(socket, :error, gettext("You do not have permission to delete this user"))}
|
||||
|
||||
{:error, error} ->
|
||||
{:noreply,
|
||||
put_flash(socket, :error, format_ash_error(error))}
|
||||
end
|
||||
end
|
||||
{:error, error} ->
|
||||
{:noreply, put_flash(socket, :error, format_ash_error(error))}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -18,9 +18,6 @@ msgstr "Aktionen"
|
|||
|
||||
#: lib/mv_web/live/membership_fee_settings_live.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/show.ex
|
||||
#: lib/mv_web/live/user_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Are you sure?"
|
||||
msgstr "Bist du sicher?"
|
||||
|
|
@ -38,11 +35,8 @@ msgstr "Verbindung wird wiederhergestellt"
|
|||
msgid "City"
|
||||
msgstr "Stadt"
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#: lib/mv_web/live/group_live/show.ex
|
||||
#: lib/mv_web/live/member_live/show/membership_fees_component.ex
|
||||
#: lib/mv_web/live/role_live/index.html.heex
|
||||
#: lib/mv_web/live/user_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete"
|
||||
msgstr "Löschen"
|
||||
|
|
@ -100,8 +94,6 @@ msgid "New Member"
|
|||
msgstr "Neues Mitglied"
|
||||
|
||||
#: lib/mv_web/live/member_live/index.html.heex
|
||||
#: lib/mv_web/live/role_live/index.html.heex
|
||||
#: lib/mv_web/live/user_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Show"
|
||||
msgstr "Anzeigen"
|
||||
|
|
@ -480,16 +472,6 @@ msgstr "Passwort"
|
|||
msgid "Password requirements"
|
||||
msgstr "Passwort-Anforderungen"
|
||||
|
||||
#: lib/mv_web/live/user_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Select all users"
|
||||
msgstr "Alle Benutzer*innen auswählen"
|
||||
|
||||
#: lib/mv_web/live/user_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Select user"
|
||||
msgstr "Benutzer*in auswählen"
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Set Password"
|
||||
|
|
@ -605,7 +587,6 @@ msgstr "E-Mail kann nicht aktualisiert werden: Diese E-Mail-Adresse ist bereits
|
|||
msgid "This email is already linked to a different OIDC account. Cannot link multiple OIDC providers to the same account."
|
||||
msgstr "Diese E-Mail-Adresse ist bereits mit einem anderen OIDC-Konto verknüpft. Es können nicht mehrere OIDC-Provider mit demselben Konto verknüpft werden."
|
||||
|
||||
#: lib/mv_web/live/components/member_filter_component.ex
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
|
|
@ -624,11 +605,6 @@ msgstr[1] "%{count} Mitglieder haben Werte für dieses benutzerdefinierte Feld z
|
|||
msgid "All custom field values will be permanently deleted when you delete this custom field."
|
||||
msgstr "Alle benutzerdefinierten Feldwerte werden beim Löschen dieses benutzerdefinierten Feldes dauerhaft gelöscht."
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete Custom Field and All Values"
|
||||
msgstr "Benutzerdefiniertes Feld und alle Werte löschen"
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Enter the text above to confirm"
|
||||
|
|
@ -662,7 +638,6 @@ msgstr "Vereinsdaten"
|
|||
msgid "Manage global settings for the association."
|
||||
msgstr "Passe übergreifende Einstellungen für den Verein an."
|
||||
|
||||
#: lib/mv_web/live/global_settings_live.ex
|
||||
#: lib/mv_web/live/membership_fee_settings_live.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Save Settings"
|
||||
|
|
@ -785,8 +760,11 @@ msgstr "Adresse"
|
|||
#: lib/mv_web/live/member_field_live/form_component.ex
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#: lib/mv_web/live/membership_fee_type_live/form.ex
|
||||
#: lib/mv_web/live/role_live/form.ex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Back"
|
||||
msgstr "Zurück"
|
||||
|
|
@ -821,6 +799,7 @@ msgstr "Persönliche Daten"
|
|||
#: lib/mv_web/live/group_live/form.ex
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show/membership_fees_component.ex
|
||||
#: lib/mv_web/live/membership_fee_type_live/form.ex
|
||||
#: lib/mv_web/live/role_live/form.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Save"
|
||||
|
|
@ -964,11 +943,6 @@ msgstr "Unbezahlt"
|
|||
msgid "Yearly"
|
||||
msgstr "jährlich"
|
||||
|
||||
#: lib/mv_web/live/components/field_visibility_dropdown_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Custom Field %{id}"
|
||||
msgstr "Benutzerdefiniertes Feld %{id}"
|
||||
|
||||
#: lib/mv_web/live/member_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Last name"
|
||||
|
|
@ -1604,17 +1578,11 @@ msgstr "Datenfeld speichern"
|
|||
msgid "Back to roles list"
|
||||
msgstr "Zurück zur Rollen-Liste"
|
||||
|
||||
#: lib/mv_web/live/role_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Cannot delete system role"
|
||||
msgstr "System-Rolle kann nicht gelöscht werden"
|
||||
|
||||
#: lib/mv_web/live/role_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Custom"
|
||||
msgstr "Benutzerdefiniert"
|
||||
|
||||
#: lib/mv_web/live/role_live/index.ex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Failed to delete role: %{error}"
|
||||
|
|
@ -1631,7 +1599,6 @@ msgstr "Rollen auflisten"
|
|||
msgid "Manage user roles and their permission sets."
|
||||
msgstr "Verwalte Benutzer*innen-Rollen und ihre Berechtigungssätze."
|
||||
|
||||
#: lib/mv_web/live/role_live/index.ex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Cannot delete role. %{count} user(s) are still assigned to this role. Please assign them to another role first."
|
||||
|
|
@ -1642,11 +1609,6 @@ msgstr "Rolle kann nicht gelöscht werden. %{count} Benutzer*in(nen) sind dieser
|
|||
msgid "Close sidebar"
|
||||
msgstr "Sidebar schließen"
|
||||
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete Role"
|
||||
msgstr "Rolle löschen"
|
||||
|
||||
#: lib/mv_web/components/layouts/sidebar.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Main navigation"
|
||||
|
|
@ -1690,7 +1652,6 @@ msgstr "Profil"
|
|||
msgid "Role"
|
||||
msgstr "Rolle"
|
||||
|
||||
#: lib/mv_web/live/role_live/index.ex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Role deleted successfully."
|
||||
|
|
@ -1702,7 +1663,6 @@ msgid "Role details and permissions."
|
|||
msgstr "Rollen-Details und Berechtigungen."
|
||||
|
||||
#: lib/mv_web/live/role_live/form.ex
|
||||
#: lib/mv_web/live/role_live/index.ex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Role not found."
|
||||
|
|
@ -1734,12 +1694,6 @@ msgstr "System"
|
|||
msgid "System Role"
|
||||
msgstr "System-Rolle"
|
||||
|
||||
#: lib/mv_web/live/role_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "System roles cannot be deleted"
|
||||
msgstr "System-Rollen können nicht gelöscht werden"
|
||||
|
||||
#: lib/mv_web/live/role_live/index.ex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "System roles cannot be deleted."
|
||||
|
|
@ -1816,12 +1770,14 @@ msgstr "Mitgliedsbeitragsart nicht gefunden"
|
|||
msgid "User %{action} successfully"
|
||||
msgstr "Benutzer*in wurde erfolgreich %{action}"
|
||||
|
||||
#: lib/mv_web/live/user_live/index.ex
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "User deleted successfully"
|
||||
msgstr "Benutzer*in erfolgreich gelöscht"
|
||||
|
||||
#: lib/mv_web/live/user_live/index.ex
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "User not found"
|
||||
msgstr "Benutzer*in nicht gefunden"
|
||||
|
|
@ -1832,18 +1788,14 @@ msgstr "Benutzer*in nicht gefunden"
|
|||
msgid "You do not have permission to access this membership fee type"
|
||||
msgstr "Du hast keine Berechtigung, auf diese Mitgliedsbeitragsart zuzugreifen"
|
||||
|
||||
#: lib/mv_web/live/user_live/index.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You do not have permission to access this user"
|
||||
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
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You do not have permission to delete this membership fee type"
|
||||
msgstr "Du hast keine Berechtigung, diese Mitgliedsbeitragsart zu löschen"
|
||||
|
||||
#: lib/mv_web/live/user_live/index.ex
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You do not have permission to delete this user"
|
||||
msgstr "Du hast keine Berechtigung, diese*n Benutzer*in zu löschen"
|
||||
|
|
@ -1864,16 +1816,19 @@ msgstr "aktualisiert"
|
|||
msgid "Unknown error"
|
||||
msgstr "Unbekannter Fehler"
|
||||
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Member deleted successfully"
|
||||
msgstr "Mitglied wurde erfolgreich gelöscht"
|
||||
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Member not found"
|
||||
msgstr "Mitglied nicht gefunden"
|
||||
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You do not have permission to delete this member"
|
||||
|
|
@ -2130,6 +2085,7 @@ msgstr "Gruppe erstellen"
|
|||
msgid "Delete Group"
|
||||
msgstr "Gruppe löschen"
|
||||
|
||||
#: lib/mv_web/live/group_live/form.ex
|
||||
#: lib/mv_web/live/group_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Delete group"
|
||||
|
|
@ -2210,11 +2166,6 @@ msgstr[1] "Diese Gruppe hat %{count} Mitglieder. Alle Mitglied-Gruppen-Zuordnung
|
|||
msgid "To confirm deletion, please enter the group name:"
|
||||
msgstr "Um die Löschung zu bestätigen, gib bitte den Gruppennamen ein:"
|
||||
|
||||
#: lib/mv_web/live/group_live/index.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "View"
|
||||
msgstr "Anzeigen"
|
||||
|
||||
#: lib/mv_web/live/group_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Total: %{count} member"
|
||||
|
|
@ -3073,38 +3024,42 @@ msgstr "Filter zurücksetzen“"
|
|||
msgid "Apply filters"
|
||||
msgstr "Filter auswählen"
|
||||
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Are you sure you want to delete %{name}? This action cannot be undone."
|
||||
msgstr "Möchtest du diese Gruppe wirklich löschen? Die Aktion kann nicht rückgängig gemacht werden."
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/form_component.ex
|
||||
#: lib/mv_web/live/group_live/form.ex
|
||||
#: lib/mv_web/live/group_live/show.ex
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Danger zone"
|
||||
msgstr "Gefahrenzone"
|
||||
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Delete member"
|
||||
msgstr "Mitglied löschen"
|
||||
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete member %{name}"
|
||||
msgstr "Mitglied %{name} löschen"
|
||||
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Deleting this member cannot be undone. All related data (e.g. membership fee cycles) will be removed."
|
||||
msgstr "Das Löschen des Mitglieds kann nicht rückgängig gemacht werden. Alle dazugehörigen Daten (z.B. Mitgliedsbeitragszylen) werden gelöscht."
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#: lib/mv_web/live/member_field_live/index_component.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Edit datafield"
|
||||
msgstr "Datenfeld bearbeiten"
|
||||
|
||||
#: lib/mv_web/live/group_live/index.ex
|
||||
#: lib/mv_web/live/group_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Edit group"
|
||||
|
|
@ -3115,22 +3070,11 @@ msgstr "Gruppe bearbeiten"
|
|||
msgid "Edit member"
|
||||
msgstr "Mitglied bearbeiten"
|
||||
|
||||
#: lib/mv_web/live/role_live/index.html.heex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Edit role"
|
||||
msgstr "Rolle bearbeiten"
|
||||
|
||||
#: lib/mv_web/live/user_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Edit user"
|
||||
msgstr "Benutzer*in bearbeiten"
|
||||
|
||||
#: lib/mv_web/live/member_field_live/index_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Click for datafield details"
|
||||
msgstr "Klicke für Datenfeld-Details"
|
||||
|
||||
#: lib/mv_web/live/group_live/index.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Click for group details"
|
||||
|
|
@ -3151,31 +3095,155 @@ msgstr "Klicke für Rollen-Details"
|
|||
msgid "Click for user details"
|
||||
msgstr "Klicke für Benutzer*innen-Details"
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Click for dataield details"
|
||||
msgstr "Klicke für Datenfeld-Details"
|
||||
|
||||
#: lib/mv_web/live/member_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Members table"
|
||||
msgstr "Mitglieder"
|
||||
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Are you sure you want to delete the role %{name}? This action cannot be undone."
|
||||
msgstr "Möchtest du diese Gruppe wirklich löschen? Die Aktion kann nicht rückgängig gemacht werden."
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Are you sure you want to delete the user %{email}? This action cannot be undone."
|
||||
msgstr "Möchtest du diese Gruppe wirklich löschen? Die Aktion kann nicht rückgängig gemacht werden."
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#: lib/mv_web/live/member_field_live/index_component.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Click to edit datafield"
|
||||
msgstr "Klicke für Datenfeld-Details"
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/form_component.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Delete data field"
|
||||
msgstr "Datenfeld löschen"
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/form_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete data field %{name}"
|
||||
msgstr "Datenfeld %{name} löschen"
|
||||
|
||||
#: lib/mv_web/live/group_live/form.ex
|
||||
#: lib/mv_web/live/group_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Delete group %{name}"
|
||||
msgstr "Gruppe %{name} löschen"
|
||||
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Delete role"
|
||||
msgstr "Rolle löschen"
|
||||
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Delete role %{name}"
|
||||
msgstr "Mitglied %{name} löschen"
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Delete user"
|
||||
msgstr "Löschen"
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete user %{email}"
|
||||
msgstr "Benutzer*in %{email} löschen"
|
||||
|
||||
#: lib/mv_web/live/group_live/form.ex
|
||||
#: lib/mv_web/live/group_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Deleting this group cannot be undone. All member-group associations will be permanently removed."
|
||||
msgstr "Das Löschen der Gruppe kann nicht rückgängig gemacht werden. Alle Mitglieds-Gruppen Zugehörigkeiten werden gelöscht."
|
||||
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Deleting this role cannot be undone. Users assigned to this role must be reassigned first."
|
||||
msgstr "Das Löschen dieser Rolle kann nicht rückgängig gemacht werden. Benutzer*inen die dieser Rolle zugewiesen wurden, müssen zuerst einer anderen Rolle zugewiesen werden."
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Deleting this user cannot be undone. The user account and any linked member association will be affected."
|
||||
msgstr "Das Löschen kann nicht rückgängig gemacht werden. Der Account und Verlinkungen zu Mitgliedern werden entfernt."
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "System user cannot be deleted."
|
||||
msgstr "System-Rollen können nicht gelöscht werden."
|
||||
|
||||
#: lib/mv_web/live/global_settings_live.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Save Name"
|
||||
msgstr "Speichern"
|
||||
|
||||
#: lib/mv_web/live/components/field_visibility_dropdown_component.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Datafield %{id}"
|
||||
msgstr "Datenfelder"
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Delete Datafields and All Values"
|
||||
msgstr "Benutzerdefiniertes Feld und alle Werte löschen"
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/form_component.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Deleting this data field cannot be undone. All datafield values for this field will be permanently removed."
|
||||
msgstr "Das Löschen dieses Datenfeldes kann nicht rückgängig gemacht werden. Alle "
|
||||
|
||||
#: lib/mv_web/live/components/member_filter_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Individual datafields"
|
||||
msgstr "Individuelle Datenfelder"
|
||||
|
||||
#~ #: lib/mv_web/live/member_field_live/form_component.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Back to Settings"
|
||||
#~ msgstr "Zurück zu den Einstellungen"
|
||||
|
||||
#~ #: lib/mv_web/live/role_live/index.html.heex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Cannot delete system role"
|
||||
#~ msgstr "System-Rolle kann nicht gelöscht werden"
|
||||
|
||||
#~ #: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Click for custom field details"
|
||||
#~ msgstr "Klicke für Datenfeld-Details"
|
||||
|
||||
#~ #: lib/mv_web/live/member_field_live/index_component.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Click for datafield details"
|
||||
#~ msgstr "Klicke für Datenfeld-Details"
|
||||
|
||||
#~ #: lib/mv_web/live/member_live/form.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Coming soon"
|
||||
#~ msgstr "Demnächst verfügbar"
|
||||
|
||||
#~ #: lib/mv_web/live/components/field_visibility_dropdown_component.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Custom Field %{id}"
|
||||
#~ msgstr "Benutzerdefiniertes Feld %{id}"
|
||||
|
||||
#~ #: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#~ #: lib/mv_web/live/member_field_live/index_component.ex
|
||||
#~ #, elixir-autogen, elixir-format, fuzzy
|
||||
#~ msgid "Edit datafield"
|
||||
#~ msgstr "Datenfeld bearbeiten"
|
||||
|
||||
#~ #: lib/mv_web/live/user_live/index.html.heex
|
||||
#~ #, elixir-autogen, elixir-format, fuzzy
|
||||
#~ msgid "Edit user"
|
||||
#~ msgstr "Benutzer*in bearbeiten"
|
||||
|
||||
#~ #: lib/mv_web/live/components/member_filter_component.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Reset"
|
||||
|
|
@ -3191,7 +3259,32 @@ msgstr "Mitglieder"
|
|||
#~ msgid "Save Role"
|
||||
#~ msgstr "Rolle speichern"
|
||||
|
||||
#~ #: lib/mv_web/live/user_live/index.html.heex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Select all users"
|
||||
#~ msgstr "Alle Benutzer*innen auswählen"
|
||||
|
||||
#~ #: lib/mv_web/live/user_live/index.html.heex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Select user"
|
||||
#~ msgstr "Benutzer*in auswählen"
|
||||
|
||||
#~ #: lib/mv_web/live/role_live/index.html.heex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "System roles cannot be deleted"
|
||||
#~ msgstr "System-Rollen können nicht gelöscht werden"
|
||||
|
||||
#~ #: lib/mv_web/live/group_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "View"
|
||||
#~ msgstr "Anzeigen"
|
||||
|
||||
#~ #: lib/mv_web/live/member_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "You do not have permission to access this member"
|
||||
#~ msgstr "Du hast keine Berechtigung, auf dieses Mitglied zuzugreifen"
|
||||
|
||||
#~ #: lib/mv_web/live/user_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "You do not have permission to access this user"
|
||||
#~ msgstr "Du hast keine Berechtigung, auf diese*n Benutzer*in zuzugreifen"
|
||||
|
|
|
|||
|
|
@ -19,9 +19,6 @@ msgstr ""
|
|||
|
||||
#: lib/mv_web/live/membership_fee_settings_live.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/show.ex
|
||||
#: lib/mv_web/live/user_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Are you sure?"
|
||||
msgstr ""
|
||||
|
|
@ -39,11 +36,8 @@ msgstr ""
|
|||
msgid "City"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#: lib/mv_web/live/group_live/show.ex
|
||||
#: lib/mv_web/live/member_live/show/membership_fees_component.ex
|
||||
#: lib/mv_web/live/role_live/index.html.heex
|
||||
#: lib/mv_web/live/user_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete"
|
||||
msgstr ""
|
||||
|
|
@ -101,8 +95,6 @@ msgid "New Member"
|
|||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/member_live/index.html.heex
|
||||
#: lib/mv_web/live/role_live/index.html.heex
|
||||
#: lib/mv_web/live/user_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Show"
|
||||
msgstr ""
|
||||
|
|
@ -481,16 +473,6 @@ msgstr ""
|
|||
msgid "Password requirements"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Select all users"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Select user"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Set Password"
|
||||
|
|
@ -606,7 +588,6 @@ msgstr ""
|
|||
msgid "This email is already linked to a different OIDC account. Cannot link multiple OIDC providers to the same account."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/components/member_filter_component.ex
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
|
|
@ -625,11 +606,6 @@ msgstr[1] ""
|
|||
msgid "All custom field values will be permanently deleted when you delete this custom field."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete Custom Field and All Values"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Enter the text above to confirm"
|
||||
|
|
@ -663,7 +639,6 @@ msgstr ""
|
|||
msgid "Manage global settings for the association."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/global_settings_live.ex
|
||||
#: lib/mv_web/live/membership_fee_settings_live.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Save Settings"
|
||||
|
|
@ -786,8 +761,11 @@ msgstr ""
|
|||
#: lib/mv_web/live/member_field_live/form_component.ex
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#: lib/mv_web/live/membership_fee_type_live/form.ex
|
||||
#: lib/mv_web/live/role_live/form.ex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Back"
|
||||
msgstr ""
|
||||
|
|
@ -822,6 +800,7 @@ msgstr ""
|
|||
#: lib/mv_web/live/group_live/form.ex
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show/membership_fees_component.ex
|
||||
#: lib/mv_web/live/membership_fee_type_live/form.ex
|
||||
#: lib/mv_web/live/role_live/form.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Save"
|
||||
|
|
@ -965,11 +944,6 @@ msgstr ""
|
|||
msgid "Yearly"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/components/field_visibility_dropdown_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Custom Field %{id}"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/member_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Last name"
|
||||
|
|
@ -1605,17 +1579,11 @@ msgstr ""
|
|||
msgid "Back to roles list"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Cannot delete system role"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Custom"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/index.ex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Failed to delete role: %{error}"
|
||||
|
|
@ -1632,7 +1600,6 @@ msgstr ""
|
|||
msgid "Manage user roles and their permission sets."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/index.ex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Cannot delete role. %{count} user(s) are still assigned to this role. Please assign them to another role first."
|
||||
|
|
@ -1643,11 +1610,6 @@ msgstr ""
|
|||
msgid "Close sidebar"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete Role"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/components/layouts/sidebar.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Main navigation"
|
||||
|
|
@ -1691,7 +1653,6 @@ msgstr ""
|
|||
msgid "Role"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/index.ex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Role deleted successfully."
|
||||
|
|
@ -1703,7 +1664,6 @@ msgid "Role details and permissions."
|
|||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/form.ex
|
||||
#: lib/mv_web/live/role_live/index.ex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Role not found."
|
||||
|
|
@ -1735,12 +1695,6 @@ msgstr ""
|
|||
msgid "System Role"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "System roles cannot be deleted"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/index.ex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "System roles cannot be deleted."
|
||||
|
|
@ -1817,12 +1771,14 @@ msgstr ""
|
|||
msgid "User %{action} successfully"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/index.ex
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "User deleted successfully"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/index.ex
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "User not found"
|
||||
msgstr ""
|
||||
|
|
@ -1833,18 +1789,14 @@ msgstr ""
|
|||
msgid "You do not have permission to access this membership fee type"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/index.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You do not have permission to access this user"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/membership_fee_settings_live.ex
|
||||
#: lib/mv_web/live/membership_fee_type_live/index.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You do not have permission to delete this membership fee type"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/index.ex
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You do not have permission to delete this user"
|
||||
msgstr ""
|
||||
|
|
@ -1865,16 +1817,19 @@ msgstr ""
|
|||
msgid "Unknown error"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Member deleted successfully"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Member not found"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You do not have permission to delete this member"
|
||||
|
|
@ -2131,6 +2086,7 @@ msgstr ""
|
|||
msgid "Delete Group"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/group_live/form.ex
|
||||
#: lib/mv_web/live/group_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete group"
|
||||
|
|
@ -2211,11 +2167,6 @@ msgstr[1] ""
|
|||
msgid "To confirm deletion, please enter the group name:"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/group_live/index.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/group_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Total: %{count} member"
|
||||
|
|
@ -3073,38 +3024,42 @@ msgstr ""
|
|||
msgid "Apply filters"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Are you sure you want to delete %{name}? This action cannot be undone."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/form_component.ex
|
||||
#: lib/mv_web/live/group_live/form.ex
|
||||
#: lib/mv_web/live/group_live/show.ex
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Danger zone"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete member"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete member %{name}"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Deleting this member cannot be undone. All related data (e.g. membership fee cycles) will be removed."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#: lib/mv_web/live/member_field_live/index_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Edit datafield"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/group_live/index.ex
|
||||
#: lib/mv_web/live/group_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Edit group"
|
||||
|
|
@ -3115,22 +3070,11 @@ msgstr ""
|
|||
msgid "Edit member"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/index.html.heex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Edit role"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Edit user"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/member_field_live/index_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Click for datafield details"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/group_live/index.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Click for group details"
|
||||
|
|
@ -3151,12 +3095,110 @@ msgstr ""
|
|||
msgid "Click for user details"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Click for dataield details"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/member_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Members table"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Are you sure you want to delete the role %{name}? This action cannot be undone."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Are you sure you want to delete the user %{email}? This action cannot be undone."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#: lib/mv_web/live/member_field_live/index_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Click to edit datafield"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/form_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete data field"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/form_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete data field %{name}"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/group_live/form.ex
|
||||
#: lib/mv_web/live/group_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete group %{name}"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete role"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete role %{name}"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete user"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete user %{email}"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/group_live/form.ex
|
||||
#: lib/mv_web/live/group_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Deleting this group cannot be undone. All member-group associations will be permanently removed."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Deleting this role cannot be undone. Users assigned to this role must be reassigned first."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Deleting this user cannot be undone. The user account and any linked member association will be affected."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "System user cannot be deleted."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/global_settings_live.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Save Name"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/components/field_visibility_dropdown_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Datafield %{id}"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete Datafields and All Values"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/form_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Deleting this data field cannot be undone. All datafield values for this field will be permanently removed."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/components/member_filter_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Individual datafields"
|
||||
msgstr ""
|
||||
|
|
|
|||
|
|
@ -19,9 +19,6 @@ msgstr ""
|
|||
|
||||
#: lib/mv_web/live/membership_fee_settings_live.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/show.ex
|
||||
#: lib/mv_web/live/user_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Are you sure?"
|
||||
msgstr ""
|
||||
|
|
@ -39,11 +36,8 @@ msgstr ""
|
|||
msgid "City"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#: lib/mv_web/live/group_live/show.ex
|
||||
#: lib/mv_web/live/member_live/show/membership_fees_component.ex
|
||||
#: lib/mv_web/live/role_live/index.html.heex
|
||||
#: lib/mv_web/live/user_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete"
|
||||
msgstr ""
|
||||
|
|
@ -101,8 +95,6 @@ msgid "New Member"
|
|||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/member_live/index.html.heex
|
||||
#: lib/mv_web/live/role_live/index.html.heex
|
||||
#: lib/mv_web/live/user_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Show"
|
||||
msgstr ""
|
||||
|
|
@ -481,16 +473,6 @@ msgstr ""
|
|||
msgid "Password requirements"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Select all users"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Select user"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Set Password"
|
||||
|
|
@ -606,7 +588,6 @@ msgstr ""
|
|||
msgid "This email is already linked to a different OIDC account. Cannot link multiple OIDC providers to the same account."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/components/member_filter_component.ex
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
|
|
@ -625,11 +606,6 @@ msgstr[1] ""
|
|||
msgid "All custom field values will be permanently deleted when you delete this custom field."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete Custom Field and All Values"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Enter the text above to confirm"
|
||||
|
|
@ -663,7 +639,6 @@ msgstr ""
|
|||
msgid "Manage global settings for the association."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/global_settings_live.ex
|
||||
#: lib/mv_web/live/membership_fee_settings_live.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Save Settings"
|
||||
|
|
@ -786,8 +761,11 @@ msgstr ""
|
|||
#: lib/mv_web/live/member_field_live/form_component.ex
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#: lib/mv_web/live/membership_fee_type_live/form.ex
|
||||
#: lib/mv_web/live/role_live/form.ex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Back"
|
||||
msgstr ""
|
||||
|
|
@ -822,6 +800,7 @@ msgstr ""
|
|||
#: lib/mv_web/live/group_live/form.ex
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show/membership_fees_component.ex
|
||||
#: lib/mv_web/live/membership_fee_type_live/form.ex
|
||||
#: lib/mv_web/live/role_live/form.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Save"
|
||||
|
|
@ -965,11 +944,6 @@ msgstr ""
|
|||
msgid "Yearly"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/components/field_visibility_dropdown_component.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Custom Field %{id}"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/member_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Last name"
|
||||
|
|
@ -1605,17 +1579,11 @@ msgstr ""
|
|||
msgid "Back to roles list"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Cannot delete system role"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Custom"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/index.ex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Failed to delete role: %{error}"
|
||||
|
|
@ -1632,7 +1600,6 @@ msgstr ""
|
|||
msgid "Manage user roles and their permission sets."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/index.ex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Cannot delete role. %{count} user(s) are still assigned to this role. Please assign them to another role first."
|
||||
|
|
@ -1643,11 +1610,6 @@ msgstr ""
|
|||
msgid "Close sidebar"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Delete Role"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/components/layouts/sidebar.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Main navigation"
|
||||
|
|
@ -1691,7 +1653,6 @@ msgstr ""
|
|||
msgid "Role"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/index.ex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Role deleted successfully."
|
||||
|
|
@ -1703,7 +1664,6 @@ msgid "Role details and permissions."
|
|||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/form.ex
|
||||
#: lib/mv_web/live/role_live/index.ex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Role not found."
|
||||
|
|
@ -1735,12 +1695,6 @@ msgstr ""
|
|||
msgid "System Role"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "System roles cannot be deleted"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/index.ex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "System roles cannot be deleted."
|
||||
|
|
@ -1817,12 +1771,14 @@ msgstr ""
|
|||
msgid "User %{action} successfully"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/index.ex
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "User deleted successfully"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/index.ex
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "User not found"
|
||||
msgstr ""
|
||||
|
|
@ -1833,18 +1789,14 @@ msgstr ""
|
|||
msgid "You do not have permission to access this membership fee type"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/index.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "You do not have permission to access this user"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/membership_fee_settings_live.ex
|
||||
#: lib/mv_web/live/membership_fee_type_live/index.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "You do not have permission to delete this membership fee type"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/index.ex
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "You do not have permission to delete this user"
|
||||
msgstr ""
|
||||
|
|
@ -1865,16 +1817,19 @@ msgstr ""
|
|||
msgid "Unknown error"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Member deleted successfully"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Member not found"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You do not have permission to delete this member"
|
||||
|
|
@ -2131,6 +2086,7 @@ msgstr ""
|
|||
msgid "Delete Group"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/group_live/form.ex
|
||||
#: lib/mv_web/live/group_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Delete group"
|
||||
|
|
@ -2211,11 +2167,6 @@ msgstr[1] ""
|
|||
msgid "To confirm deletion, please enter the group name:"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/group_live/index.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/group_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Total: %{count} member"
|
||||
|
|
@ -3073,38 +3024,42 @@ msgstr ""
|
|||
msgid "Apply filters"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Are you sure you want to delete %{name}? This action cannot be undone."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/form_component.ex
|
||||
#: lib/mv_web/live/group_live/form.ex
|
||||
#: lib/mv_web/live/group_live/show.ex
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Danger zone"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Delete member"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete member %{name}"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/member_live/form.ex
|
||||
#: lib/mv_web/live/member_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Deleting this member cannot be undone. All related data (e.g. membership fee cycles) will be removed."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#: lib/mv_web/live/member_field_live/index_component.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Edit datafield"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/group_live/index.ex
|
||||
#: lib/mv_web/live/group_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Edit group"
|
||||
|
|
@ -3115,22 +3070,11 @@ msgstr ""
|
|||
msgid "Edit member"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/index.html.heex
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Edit role"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Edit user"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/member_field_live/index_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Click for datafield details"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/group_live/index.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Click for group details"
|
||||
|
|
@ -3151,31 +3095,155 @@ msgstr ""
|
|||
msgid "Click for user details"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Click for dataield details"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/member_live/index.html.heex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Members table"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Are you sure you want to delete the role %{name}? This action cannot be undone."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Are you sure you want to delete the user %{email}? This action cannot be undone."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#: lib/mv_web/live/member_field_live/index_component.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Click to edit datafield"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/form_component.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Delete data field"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/form_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete data field %{name}"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/group_live/form.ex
|
||||
#: lib/mv_web/live/group_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Delete group %{name}"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Delete role"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Delete role %{name}"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Delete user"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Delete user %{email}"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/group_live/form.ex
|
||||
#: lib/mv_web/live/group_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Deleting this group cannot be undone. All member-group associations will be permanently removed."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/role_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Deleting this role cannot be undone. Users assigned to this role must be reassigned first."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Deleting this user cannot be undone. The user account and any linked member association will be affected."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex
|
||||
#: lib/mv_web/live/user_live/show.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "System user cannot be deleted."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/global_settings_live.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Save Name"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/components/field_visibility_dropdown_component.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Datafield %{id}"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Delete Datafields and All Values"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/custom_field_live/form_component.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Deleting this data field cannot be undone. All datafield values for this field will be permanently removed."
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv_web/live/components/member_filter_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Individual datafields"
|
||||
msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/member_field_live/form_component.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Back to Settings"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/role_live/index.html.heex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Cannot delete system role"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Click for custom field details"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/member_field_live/index_component.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Click for datafield details"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/member_live/form.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Coming soon"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/components/field_visibility_dropdown_component.ex
|
||||
#~ #, elixir-autogen, elixir-format, fuzzy
|
||||
#~ msgid "Custom Field %{id}"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/custom_field_live/index_component.ex
|
||||
#~ #: lib/mv_web/live/member_field_live/index_component.ex
|
||||
#~ #, elixir-autogen, elixir-format, fuzzy
|
||||
#~ msgid "Edit datafield"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/user_live/index.html.heex
|
||||
#~ #, elixir-autogen, elixir-format, fuzzy
|
||||
#~ msgid "Edit user"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/components/member_filter_component.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Reset"
|
||||
|
|
@ -3191,7 +3259,32 @@ msgstr ""
|
|||
#~ msgid "Save Role"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/user_live/index.html.heex
|
||||
#~ #, elixir-autogen, elixir-format, fuzzy
|
||||
#~ msgid "Select all users"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/user_live/index.html.heex
|
||||
#~ #, elixir-autogen, elixir-format, fuzzy
|
||||
#~ msgid "Select user"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/role_live/index.html.heex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "System roles cannot be deleted"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/group_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "View"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/member_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "You do not have permission to access this member"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/user_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format, fuzzy
|
||||
#~ msgid "You do not have permission to access this user"
|
||||
#~ msgstr ""
|
||||
|
|
|
|||
|
|
@ -46,6 +46,17 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
|
|||
%{conn: conn, user: user_with_role}
|
||||
end
|
||||
|
||||
# Delete is in the edit form (FormComponent); open form by clicking the name cell (unique td with phx-click)
|
||||
defp open_delete_modal(view, custom_field) do
|
||||
view
|
||||
|> element("tr#custom_fields-#{custom_field.id} td", custom_field.name)
|
||||
|> render_click()
|
||||
|
||||
view
|
||||
|> element("[data-testid=custom-field-delete]")
|
||||
|> render_click()
|
||||
end
|
||||
|
||||
describe "delete button and modal" do
|
||||
test "opens modal with correct member count when delete is clicked", %{conn: conn} do
|
||||
{:ok, member} = create_member()
|
||||
|
|
@ -55,11 +66,7 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
|
|||
create_custom_field_value(member, custom_field, "test")
|
||||
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/datafields")
|
||||
|
||||
# Click delete button - find the delete link within the component
|
||||
view
|
||||
|> element("#custom-fields-component a", "Delete")
|
||||
|> render_click()
|
||||
open_delete_modal(view, custom_field)
|
||||
|
||||
# Modal should be visible
|
||||
assert has_element?(view, "#delete-custom-field-modal")
|
||||
|
|
@ -81,23 +88,17 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
|
|||
create_custom_field_value(member2, custom_field, "test2")
|
||||
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/datafields")
|
||||
|
||||
view
|
||||
|> element("#custom-fields-component a", "Delete")
|
||||
|> render_click()
|
||||
open_delete_modal(view, custom_field)
|
||||
|
||||
# Should show plural form
|
||||
assert render(view) =~ "2 members have values assigned for this custom field"
|
||||
end
|
||||
|
||||
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"/admin/datafields")
|
||||
|
||||
view
|
||||
|> element("#custom-fields-component a", "Delete")
|
||||
|> render_click()
|
||||
open_delete_modal(view, custom_field)
|
||||
|
||||
# Should show 0 members
|
||||
assert render(view) =~ "0 members have values assigned for this custom field"
|
||||
|
|
@ -109,10 +110,7 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
|
|||
{:ok, custom_field} = create_custom_field("test_field", :string)
|
||||
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/datafields")
|
||||
|
||||
view
|
||||
|> element("#custom-fields-component a", "Delete")
|
||||
|> render_click()
|
||||
open_delete_modal(view, custom_field)
|
||||
|
||||
# Type in slug input - use element to find the form with phx-target
|
||||
view
|
||||
|
|
@ -124,13 +122,10 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
|
|||
end
|
||||
|
||||
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"/admin/datafields")
|
||||
|
||||
view
|
||||
|> element("#custom-fields-component a", "Delete")
|
||||
|> render_click()
|
||||
open_delete_modal(view, custom_field)
|
||||
|
||||
# Type wrong slug - use element to find the form with phx-target
|
||||
view
|
||||
|
|
@ -149,11 +144,7 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
|
|||
{:ok, custom_field_value} = create_custom_field_value(member, custom_field, "test")
|
||||
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/datafields")
|
||||
|
||||
# Open modal
|
||||
view
|
||||
|> element("#custom-fields-component a", "Delete")
|
||||
|> render_click()
|
||||
open_delete_modal(view, custom_field)
|
||||
|
||||
# Enter correct slug - use element to find the form with phx-target
|
||||
view
|
||||
|
|
@ -162,7 +153,7 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
|
|||
|
||||
# Click confirm
|
||||
view
|
||||
|> element("#delete-custom-field-modal button", "Delete Custom Field and All Values")
|
||||
|> element("#delete-custom-field-modal button", "Delete Datafields and All Values")
|
||||
|> render_click()
|
||||
|
||||
# Should show success message
|
||||
|
|
@ -186,10 +177,7 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
|
|||
{:ok, custom_field} = create_custom_field("test_field", :string)
|
||||
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/datafields")
|
||||
|
||||
view
|
||||
|> element("#custom-fields-component a", "Delete")
|
||||
|> render_click()
|
||||
open_delete_modal(view, custom_field)
|
||||
|
||||
# Enter wrong slug - use element to find the form with phx-target
|
||||
view
|
||||
|
|
@ -210,10 +198,7 @@ defmodule MvWeb.CustomFieldLive.DeletionTest do
|
|||
{:ok, custom_field} = create_custom_field("test_field", :string)
|
||||
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/datafields")
|
||||
|
||||
view
|
||||
|> element("#custom-fields-component a", "Delete")
|
||||
|> render_click()
|
||||
open_delete_modal(view, custom_field)
|
||||
|
||||
# Modal should be visible
|
||||
assert has_element?(view, "#delete-custom-field-modal")
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ defmodule MvWeb.RoleLiveTest do
|
|||
assert html =~ "System Role" || html =~ "system"
|
||||
end
|
||||
|
||||
test "delete button disabled for system roles", %{conn: conn, actor: actor} do
|
||||
test "delete button not shown for system roles", %{conn: conn, actor: actor} do
|
||||
system_role =
|
||||
Role
|
||||
|> Ash.Changeset.for_create(:create_role, %{
|
||||
|
|
@ -148,28 +148,19 @@ defmodule MvWeb.RoleLiveTest do
|
|||
|> Ash.Changeset.force_change_attribute(:is_system_role, true)
|
||||
|> Ash.create!(actor: actor)
|
||||
|
||||
{:ok, view, _html} = live(conn, "/admin/roles")
|
||||
{:ok, view, _html} = live(conn, "/admin/roles/#{system_role.id}")
|
||||
|
||||
assert has_element?(
|
||||
view,
|
||||
"button[phx-click='delete'][phx-value-id='#{system_role.id}'][disabled]"
|
||||
) ||
|
||||
not has_element?(
|
||||
view,
|
||||
"button[phx-click='delete'][phx-value-id='#{system_role.id}']"
|
||||
)
|
||||
# Danger zone (and delete button) is not rendered for system roles
|
||||
refute has_element?(view, "[data-testid=role-delete]")
|
||||
end
|
||||
|
||||
test "delete button enabled for non-system roles", %{conn: conn} do
|
||||
role = create_role()
|
||||
|
||||
{:ok, view, html} = live(conn, "/admin/roles")
|
||||
{:ok, view, _html} = live(conn, "/admin/roles/#{role.id}")
|
||||
|
||||
# Delete is a link with phx-click containing delete event
|
||||
# Check if delete link exists in HTML (phx-click contains delete and role id)
|
||||
assert (html =~ "phx-click" && html =~ "delete" && html =~ role.id) ||
|
||||
has_element?(view, "a[phx-click*='delete'][phx-value-id='#{role.id}']") ||
|
||||
has_element?(view, "a[aria-label='Delete role']")
|
||||
# Delete is on show page (Danger zone)
|
||||
assert has_element?(view, "[data-testid=role-delete]")
|
||||
end
|
||||
|
||||
test "new role button navigates to form", %{conn: conn} do
|
||||
|
|
@ -393,21 +384,21 @@ defmodule MvWeb.RoleLiveTest do
|
|||
test "deletes non-system role", %{conn: conn, actor: actor} do
|
||||
role = create_role()
|
||||
|
||||
{:ok, view, html} = live(conn, "/admin/roles")
|
||||
{:ok, view, _html} = live(conn, "/admin/roles/#{role.id}")
|
||||
|
||||
# Delete is a link - JS.push creates phx-click with value containing id
|
||||
# Verify the role id is in the HTML (in phx-click value)
|
||||
assert html =~ role.id
|
||||
# Delete from Danger zone on show page
|
||||
view
|
||||
|> element("[data-testid=role-delete]")
|
||||
|> render_click()
|
||||
|
||||
# Send delete event directly to avoid selector issues with multiple delete buttons
|
||||
render_click(view, "delete", %{"id" => role.id})
|
||||
assert_redirect(view, "/admin/roles")
|
||||
|
||||
# Verify deletion by checking database
|
||||
assert {:error, %Ash.Error.Invalid{errors: [%Ash.Error.Query.NotFound{}]}} =
|
||||
Authorization.get_role(role.id, actor: actor)
|
||||
end
|
||||
|
||||
test "fails to delete system role with error message", %{conn: conn, actor: actor} do
|
||||
test "system role has no delete button and cannot be deleted", %{conn: conn, actor: actor} do
|
||||
system_role =
|
||||
Role
|
||||
|> Ash.Changeset.for_create(:create_role, %{
|
||||
|
|
@ -417,19 +408,12 @@ defmodule MvWeb.RoleLiveTest do
|
|||
|> Ash.Changeset.force_change_attribute(:is_system_role, true)
|
||||
|> Ash.create!(actor: actor)
|
||||
|
||||
{:ok, view, html} = live(conn, "/admin/roles")
|
||||
{:ok, view, _html} = live(conn, "/admin/roles/#{system_role.id}")
|
||||
|
||||
# System role delete button should be disabled
|
||||
assert html =~ "disabled" || html =~ "cursor-not-allowed" ||
|
||||
html =~ "System roles cannot be deleted"
|
||||
# Danger zone is not rendered for system roles (no delete button)
|
||||
refute has_element?(view, "[data-testid=role-delete]")
|
||||
|
||||
# Try to delete via event (backend check)
|
||||
render_click(view, "delete", %{"id" => system_role.id})
|
||||
|
||||
# Should show error message
|
||||
assert render(view) =~ "System roles cannot be deleted"
|
||||
|
||||
# Role should still exist
|
||||
# Role still exists
|
||||
{:ok, _role} = Authorization.get_role(system_role.id, actor: actor)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,14 +10,16 @@ defmodule MvWeb.UserLiveAuthorizationTest do
|
|||
|
||||
describe "User Index - Admin" do
|
||||
@tag role: :admin
|
||||
test "sees New User, Edit and Delete buttons", %{conn: conn} do
|
||||
test "sees New User button; Edit and Delete are on show page", %{conn: conn} do
|
||||
user = Fixtures.user_with_role_fixture("admin")
|
||||
|
||||
{:ok, view, _html} = live(conn, "/users")
|
||||
{:ok, index_view, _html} = live(conn, "/users")
|
||||
assert has_element?(index_view, "[data-testid=user-new]")
|
||||
|
||||
assert has_element?(view, "[data-testid=user-new]")
|
||||
assert has_element?(view, "#row-#{user.id} [data-testid=user-edit]")
|
||||
assert has_element?(view, "#row-#{user.id} [data-testid=user-delete]")
|
||||
# Edit and Delete are on user show page (Danger zone), not on index
|
||||
{:ok, show_view, _html} = live(conn, "/users/#{user.id}")
|
||||
assert has_element?(show_view, "[data-testid=user-edit]")
|
||||
assert has_element?(show_view, "[data-testid=user-delete]")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -16,11 +16,10 @@ defmodule MvWeb.UserLive.IndexTest do
|
|||
assert html =~ "alice@example.com"
|
||||
assert html =~ "bob@example.com"
|
||||
|
||||
# UI elements: New User button, action links
|
||||
# UI elements: New User button; row click navigates to show (no Edit/Delete on index)
|
||||
assert html =~ "New User"
|
||||
assert html =~ "Edit"
|
||||
assert html =~ "Delete"
|
||||
assert html =~ ~r/href="[^"]*\/users\/#{user1.id}\/edit"/
|
||||
# Row or navigation contains user id (e.g. row id or phx-click navigate)
|
||||
assert html =~ "row-#{user1.id}" or html =~ to_string(user1.id)
|
||||
end
|
||||
|
||||
@tag :ui
|
||||
|
|
@ -116,177 +115,29 @@ defmodule MvWeb.UserLive.IndexTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "checkbox selection functionality" do
|
||||
setup do
|
||||
user1 = create_test_user(%{email: "user1@example.com", oidc_id: "user1"})
|
||||
user2 = create_test_user(%{email: "user2@example.com", oidc_id: "user2"})
|
||||
%{users: [user1, user2]}
|
||||
end
|
||||
|
||||
@tag :ui
|
||||
test "shows checkbox UI elements", %{conn: conn, users: [user1, user2]} do
|
||||
conn = conn_with_oidc_user(conn)
|
||||
{:ok, _view, html} = live(conn, "/users")
|
||||
|
||||
# Check select all checkbox exists
|
||||
assert html =~ ~s(name="select_all")
|
||||
assert html =~ ~s(phx-click="select_all")
|
||||
|
||||
# Check individual user checkboxes exist
|
||||
assert html =~ ~s(name="#{user1.id}")
|
||||
assert html =~ ~s(name="#{user2.id}")
|
||||
assert html =~ ~s(phx-click="select_user")
|
||||
end
|
||||
|
||||
@tag :ui
|
||||
test "can select and deselect individual users", %{conn: conn, users: [user1, user2]} do
|
||||
conn = conn_with_oidc_user(conn)
|
||||
{:ok, view, _html} = live(conn, "/users")
|
||||
|
||||
# Initially, individual checkboxes should exist but not be checked
|
||||
assert view |> element("input[type='checkbox'][name='#{user1.id}']") |> has_element?()
|
||||
assert view |> element("input[type='checkbox'][name='#{user2.id}']") |> has_element?()
|
||||
|
||||
refute view
|
||||
|> element("input[type='checkbox'][name='select_all'][checked]")
|
||||
|> has_element?()
|
||||
|
||||
# Select first user checkbox
|
||||
html = view |> element("input[type='checkbox'][name='#{user1.id}']") |> render_click()
|
||||
assert html =~ "Email"
|
||||
assert html =~ to_string(user1.email)
|
||||
|
||||
# The select_all checkbox should still not be checked (not all users selected)
|
||||
refute view
|
||||
|> element("input[type='checkbox'][name='select_all'][checked]")
|
||||
|> has_element?()
|
||||
|
||||
# Deselect user
|
||||
html = view |> element("input[type='checkbox'][name='#{user1.id}']") |> render_click()
|
||||
assert html =~ "Email"
|
||||
|
||||
refute view
|
||||
|> element("input[type='checkbox'][name='select_all'][checked]")
|
||||
|> has_element?()
|
||||
end
|
||||
|
||||
@tag :ui
|
||||
test "select all and deselect all functionality", %{conn: conn, users: [user1, user2]} do
|
||||
conn = conn_with_oidc_user(conn)
|
||||
{:ok, view, _html} = live(conn, "/users")
|
||||
|
||||
# Initially no checkboxes should be checked
|
||||
refute view
|
||||
|> element("input[type='checkbox'][name='select_all'][checked]")
|
||||
|> has_element?()
|
||||
|
||||
refute view
|
||||
|> element("input[type='checkbox'][name='#{user1.id}'][checked]")
|
||||
|> has_element?()
|
||||
|
||||
refute view
|
||||
|> element("input[type='checkbox'][name='#{user2.id}'][checked]")
|
||||
|> has_element?()
|
||||
|
||||
# Click select all
|
||||
html = view |> element("input[type='checkbox'][name='select_all']") |> render_click()
|
||||
|
||||
# After selecting all, the select_all checkbox should be checked
|
||||
assert view
|
||||
|> element("input[type='checkbox'][name='select_all'][checked]")
|
||||
|> has_element?()
|
||||
|
||||
assert html =~ "Email"
|
||||
assert html =~ to_string(user1.email)
|
||||
assert html =~ to_string(user2.email)
|
||||
|
||||
# Then deselect all
|
||||
html = view |> element("input[type='checkbox'][name='select_all']") |> render_click()
|
||||
|
||||
# After deselecting all, no checkboxes should be checked
|
||||
refute view
|
||||
|> element("input[type='checkbox'][name='select_all'][checked]")
|
||||
|> has_element?()
|
||||
|
||||
refute view
|
||||
|> element("input[type='checkbox'][name='#{user1.id}'][checked]")
|
||||
|> has_element?()
|
||||
|
||||
refute view
|
||||
|> element("input[type='checkbox'][name='#{user2.id}'][checked]")
|
||||
|> has_element?()
|
||||
|
||||
assert html =~ "Email"
|
||||
end
|
||||
|
||||
@tag :slow
|
||||
test "select all automatically checks when all individual users are selected", %{
|
||||
conn: conn,
|
||||
users: [_user1, _user2]
|
||||
} do
|
||||
conn = conn_with_oidc_user(conn)
|
||||
{:ok, view, html} = live(conn, "/users")
|
||||
|
||||
# Get all user IDs from the rendered HTML by finding all checkboxes with phx-click="select_user"
|
||||
# Extract user IDs from the HTML (they appear as name attributes on checkboxes)
|
||||
user_ids =
|
||||
html
|
||||
|> String.split("phx-click=\"select_user\"")
|
||||
|> Enum.flat_map(fn part ->
|
||||
case Regex.run(~r/name="([^"]+)"[^>]*phx-value-id/, part) do
|
||||
[_, user_id] -> [user_id]
|
||||
_ -> []
|
||||
end
|
||||
end)
|
||||
|> Enum.uniq()
|
||||
|
||||
# Skip if no users found (shouldn't happen, but be safe)
|
||||
if user_ids != [] do
|
||||
# Initially nothing should be checked
|
||||
refute view
|
||||
|> element("input[type='checkbox'][name='select_all'][checked]")
|
||||
|> has_element?()
|
||||
|
||||
# Select all users one by one
|
||||
Enum.each(user_ids, fn user_id ->
|
||||
view |> element("input[type='checkbox'][name='#{user_id}']") |> render_click()
|
||||
end)
|
||||
|
||||
# Now select all should be automatically checked (all individual users are selected)
|
||||
assert view
|
||||
|> element("input[type='checkbox'][name='select_all'][checked]")
|
||||
|> has_element?()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete functionality" do
|
||||
test "can delete a user", %{conn: conn} do
|
||||
_user = create_test_user(%{email: "delete-me@example.com"})
|
||||
# Delete is only on user show page (Danger zone), not on index (per CODE_GUIDELINES: at most one UI smoke test for delete)
|
||||
test "can delete a user from show page", %{conn: conn} do
|
||||
user = create_test_user(%{email: "delete-me@example.com"})
|
||||
conn = conn_with_oidc_user(conn)
|
||||
{:ok, view, _html} = live(conn, "/users")
|
||||
{:ok, index_view, _html} = live(conn, "/users")
|
||||
assert render(index_view) =~ "delete-me@example.com"
|
||||
|
||||
# Confirm user is displayed
|
||||
assert render(view) =~ "delete-me@example.com"
|
||||
# Navigate to user show and trigger delete from Danger zone
|
||||
{:ok, show_view, _html} = live(conn, "/users/#{user.id}")
|
||||
|
||||
# Click the delete button (phx-click="delete" event)
|
||||
view |> element("tbody tr:first-child a[data-confirm]") |> render_click()
|
||||
show_view
|
||||
|> element("[data-testid=user-delete]")
|
||||
|> render_click()
|
||||
|
||||
# Verify user was actually deleted (should not appear in HTML anymore)
|
||||
html = render(view)
|
||||
# Should redirect to index
|
||||
assert_redirect(show_view, "/users")
|
||||
|
||||
# Reload index with same session; user should be gone
|
||||
{:ok, _view_after, html} = live(conn, "/users")
|
||||
refute html =~ "delete-me@example.com"
|
||||
# Table header should still be there
|
||||
assert html =~ "Email"
|
||||
end
|
||||
|
||||
test "shows delete confirmation", %{conn: conn} do
|
||||
_user = create_test_user(%{email: "confirm-delete@example.com"})
|
||||
conn = conn_with_oidc_user(conn)
|
||||
{:ok, _view, html} = live(conn, "/users")
|
||||
|
||||
# Check that delete link has confirmation attribute
|
||||
assert html =~ ~s(data-confirm="Are you sure?")
|
||||
end
|
||||
end
|
||||
|
||||
describe "navigation" do
|
||||
|
|
@ -296,36 +147,14 @@ defmodule MvWeb.UserLive.IndexTest do
|
|||
conn = conn_with_oidc_user(conn)
|
||||
{:ok, _view, html} = live(conn, "/users")
|
||||
|
||||
# Check that user row contains link to show page
|
||||
# Row click navigates to show page (edit is on show page)
|
||||
assert html =~ ~s(/users/#{user.id})
|
||||
|
||||
# Check edit link points to correct edit page
|
||||
assert html =~ ~s(/users/#{user.id}/edit)
|
||||
|
||||
# Check new user button points to correct new page
|
||||
assert html =~ ~s(/users/new)
|
||||
end
|
||||
end
|
||||
|
||||
describe "translations" do
|
||||
@tag :ui
|
||||
test "shows translations for selection in different locales", %{conn: conn} do
|
||||
conn = conn_with_oidc_user(conn)
|
||||
|
||||
# Test German translations
|
||||
conn = Plug.Test.init_test_session(conn, locale: "de")
|
||||
{:ok, _view, html_de} = live(conn, "/users")
|
||||
assert html_de =~ "Alle Benutzer*innen auswählen"
|
||||
assert html_de =~ "Benutzer*in auswählen"
|
||||
|
||||
# Test English translations
|
||||
Gettext.put_locale(MvWeb.Gettext, "en")
|
||||
{:ok, _view, html_en} = live(conn, "/users")
|
||||
# Check that aria-label attributes exist (structure is there)
|
||||
assert html_en =~ ~s(aria-label=)
|
||||
end
|
||||
end
|
||||
|
||||
describe "edge cases" do
|
||||
test "handles empty user list gracefully", %{conn: conn} do
|
||||
# Don't create any users besides the authenticated one
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue