Commit graph

591 commits

Author SHA1 Message Date
77fc11a0b0 refactor(member-live): modularize the overview and drop the superseded in-memory paths
Extract the cookie parser, export-payload builder and fee-status helper
into their own modules and remove the filter/sort/load helpers the
database pushdown made dead, so the overview LiveView stays a thin
coordinator over focused units.
2026-07-06 11:00:29 +02:00
c2cb3edab8 feat(member): bring the overview table up to WCAG 2.2 AA 2026-07-06 11:00:29 +02:00
0c375234c8 feat(member): make overview columns sortable through accessible sort headers 2026-07-06 10:48:28 +02:00
dfc616257d feat(member): let members tailor overview density and visible columns
The View dropdown drives row density and whether the Member and Address
fields render as composite cells or split into their underlying columns;
the column manager toggles visibility and resets to the curated default.
All choices persist per browser through the URL/session/cookie/global
chain, so a saved layout survives reloads without a per-account store.
2026-07-06 10:45:53 +02:00
af2cc2e0d4 feat(member): condense the overview into composite name and address cells 2026-07-03 11:35:46 +02:00
b79d7ac9ea feat(member): stream the overview with keyset infinite scroll instead of loading every member 2026-07-03 11:31:44 +02:00
b09cdf7f3a feat(member): resolve custom-field filters and sorting in PostgreSQL
Push the boolean and date custom-field predicates and custom-field
sorting down to JSONB expressions so the overview stops classifying
custom-field values in memory. A GIN index on custom_field_values.value
keeps the boolean membership predicates index-served.
2026-07-03 11:19:59 +02:00
e64f55c36a feat(member): back the overview with a keyset-paginated :overview read action 2026-07-03 11:12:38 +02:00
fe534319ee style: order module directives per StrictModuleLayout 2026-06-16 15:51:07 +02:00
3f073d4365 refactor(membership-fees): share fee-type delete handling between LiveViews 2026-06-16 15:51:07 +02:00
18bf4dab2b refactor(web): use canonical DateFormatter for all date display 2026-06-16 15:51:07 +02:00
e66fb5d3d9 refactor(email): share build/deliver skeleton across join emails 2026-06-16 15:51:07 +02:00
1adf6aa664 refactor(web): extract shared current_actor controller helper 2026-06-16 15:51:07 +02:00
561779e704 refactor(web): share member-dropdown keyboard navigation between LiveViews 2026-06-16 15:51:07 +02:00
2a3a152b13 perf(member): drop per-render timing log on the member-list hot path 2026-06-16 15:51:07 +02:00
2eda661e37 fix(export): order member export chronologically by custom :date fields 2026-06-15 16:18:13 +02:00
6d4629ef5b fix(member): order member list chronologically by custom :date fields 2026-06-15 16:14:14 +02:00
856ea4279c refactor(member): share Ash error formatting across member-show components 2026-06-15 15:10:44 +02:00
24f67bea80 feat(member): keep text selection in the overview table from opening the member 2026-06-15 15:10:44 +02:00
be57dcfce8 fix(web): prevent sortable-header tooltips from being clipped by the sticky header 2026-06-15 15:10:44 +02:00
035edae522 feat(web): add tooltips to icon-only action buttons 2026-06-15 15:10:44 +02:00
bec49f0771 feat(settings): explain that OIDC enables single sign-on 2026-06-15 15:10:44 +02:00
3dc3a2b8ef feat(member): deactivate and reactivate members via an exit-date dialog 2026-06-15 15:10:44 +02:00
9b7368d0a3
fix: width of bulk action
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/promote/production Build is passing
2026-06-08 11:44:26 +02:00
6a6099659b Merge branch 'main' into issue/mitgliederverwaltung-420
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/promote/production Build is passing
Integrate current main (CSV import, GDPR join-form description, dependency and
tooling bumps) into the bulk-actions-dropdown feature. Gettext catalogs were
reconciled with mix gettext.extract --merge; the CHANGELOG Unreleased entries
of both sides were combined.
2026-06-04 16:56:27 +02:00
c983c8d5bb feat(member): collect member-overview bulk actions into a single dropdown
The growing row of bulk-action buttons above the member overview is replaced
by one "Aktionen" dropdown holding all four actions (open in email program,
copy addresses, export CSV, export PDF). With no selection the actions operate
on all — or the currently filtered — members; the email-program action is
disabled past a recipient cap, because the browser cannot reliably hand a very
long mailto over to the mail client. The trigger shows the active scope as a
badge: an emphasized count when members are selected, a muted "alle"/"gefiltert"
otherwise.
2026-06-04 16:44:13 +02:00
8e5dd7e4c6 feat(web): add chevron affordance and scope-badge slot to dropdown triggers
Dropdown openers were visually indistinguishable from ordinary buttons. A
trailing chevron now marks every dropdown trigger — both the shared
dropdown_menu component and the bespoke member-filter trigger — and an
optional badge slot lets a trigger show a status indicator beside its label.
2026-06-04 16:40:05 +02:00
6500dead95
Merge remote-tracking branch 'origin/main' into issue/mitgliederverwaltung-508
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/promote/production Build is passing
2026-06-04 09:53:27 +02:00
404d524ee1 feat(custom-field): let admins set join_description with a link-syntax hint 2026-06-03 12:28:23 +02:00
df271055a8 feat(member): show join_description as a tooltip on custom-field labels 2026-06-03 12:22:58 +02:00
ee5ccbf7e9 feat(join): highlight auto-linked join-form links 2026-06-03 12:16:53 +02:00
aced57d0fd feat(join): use join_description as the join-form field label 2026-06-03 12:11:39 +02:00
cb5cb68483 feat(join): render join_description with auto-linked URLs and Markdown links 2026-06-03 12:06:48 +02:00
118b9f8d57 perf(import): reuse auto-created groups across import chunks 2026-06-03 02:32:15 +02:00
68a1a9530a feat(import): confirm column mapping in a preview before importing members 2026-06-03 02:25:50 +02:00
a93dd9d535 feat(import): serve dynamic CSV import templates reflecting current custom fields 2026-06-03 02:21:36 +02:00
a7ad608051 fix(auth): redirect a live-view socket in the user-required guard
LiveSession.assign_new_resources/2 is typed to return a Phoenix.Socket, which made the on_mount redirect type-incompatible. The authenticated-routes live_session already assigns current_user, so the guard reads it from socket.assigns directly. Also assign the locale into the socket actually used by the no-user redirect instead of discarding it.
2026-06-02 12:19:21 +02:00
6a4a99f638 refactor(types): drop guards and clauses that can never succeed 2026-06-02 12:11:59 +02:00
ec6422d450 fix(membership-fees): show error for unparseable cycle date instead of crashing
Date.from_iso8601/1 returns {:error, reason}, so the with else clause matching a bare :error never fired and an invalid date raised a WithClauseError. Match the real date/calendar error reasons so the user sees the validation message.
2026-06-02 12:08:19 +02:00
05f66ccf74 refactor(types): remove dead catch-all clauses unreachable per success typing 2026-06-02 11:56:44 +02:00
d9a5a081df refactor(import): drop unreachable CSV error-formatting path
consume_and_read_csv/2 and MemberCSV.prepare/2 only ever return {:error, binary()}, so the non-binary error branch and the format_error_message/* helpers it called were unreachable. Removed them and bound the remaining discarded locale/dispatch results.
2026-06-02 11:50:43 +02:00
c0395f16e8 fix(types): resolve unknown type references in member and authorization specs 2026-06-02 11:46:54 +02:00
848f0cd013 refactor(types): bind intentionally discarded side-effecting results 2026-06-02 11:42:57 +02:00
04ab05f556 fix(member-export): forbid request without actor instead of falling through
The nil-actor guard used a one-armed if and continued into the export path regardless. The CheckPagePermission plug already halts unauthenticated requests before this controller runs, so the corrected early return preserves observable behavior while removing the dead fall-through. The export action is split into per-payload clauses so the guard reads as a flat early return.
2026-06-02 11:39:04 +02:00
fd8e6ac178 refactor(types): reconcile @specs with their success typings 2026-06-02 11:25:03 +02:00
a27425b5fb fix(auth): replace sign-out page with accessible custom LiveView
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/promote/production Build is passing
2026-06-01 20:06:32 +02:00
ba66bc15db fix(auth): trigger RP-initiated logout at OIDC provider 2026-06-01 19:59:52 +02:00
d6671daf1a feat(member-filter): add date filter sections with active-count badge and reset support
Some checks failed
continuous-integration/drone/push Build is failing
2026-05-20 16:32:29 +02:00
e3295ab4b5 feat(member-live): wire date filters into LiveView lifecycle 2026-05-20 16:28:17 +02:00
ddd4a9a878 feat(date-filter): introduce DateFilter module with URL codec and Ash query expressions 2026-05-20 16:24:08 +02:00