Commit graph

190 commits

Author SHA1 Message Date
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
05f66ccf74 refactor(types): remove dead catch-all clauses unreachable per success typing 2026-06-02 11:56:44 +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
a12888de2f Improve member view table behavior+style, fix config settings (#493)
All checks were successful
continuous-integration/drone/push Build is passing
## Description of the implemented changes
The changes were:
- [x] Bugfixing
- [x] New Feature
- [ ] Breaking Change
- [x] Refactoring

This PR standardizes interactive table behavior and improves settings robustness.
It makes the new hover/focus-visible row highlight the default for clickable tables, keeps sticky first-column behavior configurable (and optimized for member selection UX), and tightens SMTP source-of-truth handling so ENV-based and UI-based configuration do not conflict.

## What has been changed?
- Refactored `CoreComponents.table` to expose interaction state via `data-row-interactive` and moved default row hover/focus styling to CSS.
- Made the new row highlight behavior (`hover` + `:has(:focus-visible)`) the default for clickable zebra tables.
- Kept sticky-first-column as an explicit table option and preserved sticky-specific selection accent behavior.
- Updated member overview table usage to the sticky-first-column mode and refined scrolling behavior (table scrollbar within container, not page-coupled).
- Adjusted table-related tests to validate the new interaction contract (attribute/CSS-driven behavior instead of legacy ring classes).
- Improved SMTP config handling:
  - clearer ENV-vs-Settings behavior (ENV-only mode when host env is set),
  - read-only and warning behavior in global settings UI when required env keys are missing,
  - updated related config/tests/docs.
- Updated docs and changelog (`CHANGELOG.md`, `DESIGN_GUIDELINES.md`, `CODE_GUIDELINES.md`, SMTP concept docs).
- Updated gettext catalogs (`default.pot`, `en`, `de`) for new/changed UI strings.

## Definition of Done
### Code Quality
- [x] No new technical depths
- [x] Linting passed
- [x] Documentation is added were needed

### Accessibility
- [x] New elements are properly defined with html-tags
- [x] Colour contrast follows WCAG criteria
- [x] Aria labels are added when needed
- [x] Everything is accessible by keyboard
- [x] Tab-Order is comprehensible
- [x] All interactive elements have a visible focus

### Testing
- [x] Tests for new code are written
- [x] All tests pass
- [ ] axe-core dev tools show no critical or major issues

## Additional Notes
- Branch includes 4 commits:
  - `fix: make sure smtp can be set either via env or ui`
  - `fix: make horizontal scrollbars sticky to bottom`
  - `docs: update changelog`
  - `feat: make checkbox column in member view sticky`
- Full fast suite passed (`mix test --exclude slow --exclude ui`): 2017 tests, 0 failures (plus expected non-failing warning logs in test output).
- Reviewer focus areas:
  1. **Cross-table UX consistency** after moving row interaction styling to component/CSS contract.
  2. **Sticky table behavior** (selection accent stripe, zebra background, keyboard focus visibility).
  3. **SMTP precedence and UI constraints** in global settings when ENV mode is active.
  4. **Regression risk in tests** that previously asserted ring-based row classes.
- No breaking API changes expected; behavior change is primarily visual/interaction-level and intentional.

Reviewed-on: #493
Co-authored-by: Simon <s.thiessen@local-it.org>
Co-committed-by: Simon <s.thiessen@local-it.org>
2026-05-08 15:04:53 +02:00
2bb01bd201 Improve UX of join requests and fix minor bugs (#492)
All checks were successful
continuous-integration/drone/push Build is passing
## Description of the implemented changes
The changes were:
- [x] Bugfixing
- [x] New Feature
- [ ] Breaking Change
- [ ] Refactoring

This PR improves the join-request flow and presentation quality, fixes several data-display issues in join/join-request screens, and adds a usability improvement in global settings (directly opening the join link). It also includes dependency updates and changelog maintenance.

## What has been changed?
- Join form (`JoinLive`) now renders inputs based on actual field types (including checkbox/date/number/email behavior instead of generic text-only handling).
- Join form custom-field labels are resolved from configured custom fields (fallback remains safe if lookup fails).
- Join-request details page (`JoinRequestLive.Show`) now:
  - resolves and shows custom field names instead of raw IDs,
  - formats boolean-like values (`on/true/1`, `off/false/0`) as localized `Yes/No`,
  - formats ISO date strings for better readability,
  - keeps legacy field handling while improving output consistency.
- Join-request detail layout was improved semantically and visually (`dl/dt/dd` structure for label/value rows).
- Global settings page now includes an **Open** button for the join URL (`target="_blank"`, `rel="noopener noreferrer"`, ARIA label).
- Added/updated tests around:
  - join field type rendering,
  - custom field labels in join-request views,
  - related auth/global-settings behavior.
- Updated translations (`default.pot`, `en`, `de`) for new UI strings.
- Updated dependencies/tooling (`mix.lock`, `mix.exs`, CI/renovate-related updates).
- Updated `CHANGELOG.md` entries for unreleased changes.

## Definition of Done
### Code Quality
- [x] No new technical depths
- [x] Linting passed
- [x] Documentation is added were needed

### Accessibility
- [x] New elements are properly defined with html-tags
- [x] Colour contrast follows WCAG criteria
- [x] Aria labels are added when needed
- [x] Everything is accessible by keyboard
- [x] Tab-Order is comprehensible
- [x] All interactive elements have a visible focus

### Testing
- [x] Tests for new code are written
- [ ] All tests pass
- [ ] axe-core dev tools show no critical or major issues

## Additional Notes
- Reviewer focus areas:
  - `lib/mv_web/live/join_live.ex`: input type derivation and custom field lookup strategy (`authorize?: false` read path used intentionally for field metadata).
  - `lib/mv_web/live/join_request_live/show.ex`: value-formatting logic (especially backward compatibility for legacy `form_data` payloads).
  - `lib/mv_web/live/global_settings_live.ex`: external-link behavior and accessibility attributes.
- The branch also contains dependency update commits; please review lockfile and CI-related changes separately from functional join/join-request changes.

Reviewed-on: #492
Co-authored-by: Simon <s.thiessen@local-it.org>
Co-committed-by: Simon <s.thiessen@local-it.org>
2026-05-06 14:34:42 +02:00
c381b86b5e Improve oidc only mode (#474)
All checks were successful
continuous-integration/drone/push Build is passing
## Description of the implemented changes
The changes were:
- [x] Bugfixing
- [x] New Feature
- [ ] Breaking Change
- [x] Refactoring

**OIDC-only mode improvements and UX tweaks (success toasts, unauthenticated redirect).**

## What has been changed?

### OIDC-only mode (new feature)
- **Admin settings:** "Only OIDC sign-in" is an immediate toggle at the top of the OIDC section (no save button). Enabling it also turns off "Allow direct registration". When OIDC-only is on, the registration checkbox is disabled and shows a tooltip (DaisyUI `<.tooltip>`).
- **Backend:** Password sign-in is forbidden via Ash policy (`OidcOnlyActive` check). Password registration is blocked via validation `OidcOnlyBlocksPasswordRegistration`. New plug `OidcOnlySignInRedirect`: when OIDC-only and OIDC are configured, GET `/sign-in` redirects to the OIDC flow; GET `/auth/user/password/sign_in_with_token` is rejected with redirect + flash. `AuthController.success/4` also rejects password sign-in when OIDC-only.
- **Tests:** GlobalSettingsLive (OIDC-only UI), AuthController (redirect and password sign-in rejection), User authentication (register_with_password blocked when OIDC-only).

### UX / behaviour (no new feature flag)
- **Success toasts:** Success flash messages auto-dismiss after 5 seconds via JS hook `FlashAutoDismiss` and optional `auto_clear_ms` on `<.flash>` (used for success in root layout and `flash_group`).
- **Unauthenticated users:** Redirect to sign-in without the "You don't have permission to access this page" flash; that message is only shown to logged-in users who lack access. Logic in `LiveHelpers` and `CheckPagePermission` plug; test updated accordingly.

### Other
- Layouts: comment about unprocessed join-request count no longer uses "TODO" (Credo).
- Gettext: German translation for "Home" (Startseite); POT/PO kept in sync.
- CHANGELOG: Unreleased section updated with the above.

## Definition of Done
### Code Quality
- [x] No new technical depths
- [x] Linting passed
- [x] Documentation is added where needed (module docs, comments where non-obvious)

### Accessibility
- [x] New elements are properly defined with html-tags (labels, aria-label on checkboxes)
- [x] Colour contrast follows WCAG criteria (unchanged)
- [x] Aria labels are added when needed (e.g. oidc-only and registration checkboxes)
- [x] Everything is accessible by keyboard (toggles and buttons unchanged)
- [x] Tab-Order is comprehensible
- [x] All interactive elements have a visible focus (existing patterns)

### Testing
- [x] Tests for new code are written (OIDC-only UI, auth controller, user auth; SMTP config builder and mailer)
- [x] All tests pass
- [ ] axe-core dev tools show no critical or major issues (not re-run for this PR; suggest spot-check on settings and sign-in)

## Additional Notes
- **OIDC-only:** When the `OIDC_ONLY` env var is set, the toggle is read-only and shows "(From OIDC_ONLY)". When OIDC is not configured, the toggle is disabled.
- **Invalidation:** Enabling OIDC-only sets `registration_enabled: false` in one update; disabling OIDC-only only updates `oidc_only` (registration left as-is).
- **Review focus:** Plug order in router (OidcOnlySignInRedirect), policy/validation order in User, and that all OIDC-only paths (form, plug, controller) stay consistent.

Reviewed-on: #474
Co-authored-by: Simon <s.thiessen@local-it.org>
Co-committed-by: Simon <s.thiessen@local-it.org>
2026-03-16 19:09:07 +01:00
c933144920
feat: unify page titles
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/production Build is failing
2026-03-13 19:01:50 +01:00
e8ec620d57
feat: add timezone handling
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/production Build is failing
2026-03-13 18:22:12 +01:00
349cee0ce6
refactor: review remarks
Some checks failed
continuous-integration/drone/push Build is failing
2026-03-13 17:55:17 +01:00
5e39fffce2
i18n: update gettext
Some checks failed
continuous-integration/drone/push Build is failing
2026-03-13 16:47:16 +01:00
09e4b64663
feat: allow disabling registration
Some checks failed
continuous-integration/drone/push Build is failing
2026-03-13 16:40:39 +01:00
eb18209669
feat: rearrange smtp settings
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-13 15:56:02 +01:00
99a8d64344
fix: translation of login page
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-13 14:11:54 +01:00
086ecdcb1b
feat: prevent join requests with equal mail
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-13 11:18:34 +01:00
40a4461d23
fix: join confirmation mail configuration
Some checks failed
continuous-integration/drone/push Build is failing
2026-03-13 09:34:56 +01:00
a7481f6ab1
feat: improve field order for approvals and add seeds
Some checks failed
continuous-integration/drone/push Build is failing
2026-03-12 16:15:57 +01:00
4af80a8305
Merge remote-tracking branch 'origin/main' into feature/308-web-form
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/production Build is failing
2026-03-12 13:52:33 +01:00
a4f3aa5d6f
feat: add smtp settings
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-12 13:39:48 +01:00
762402adf9 fix translations
Some checks failed
continuous-integration/drone/push Build is failing
2026-03-11 11:30:26 +01:00
45c2f3e2b3 i18n: fix translations
Some checks failed
continuous-integration/drone/push Build is failing
2026-03-11 11:13:21 +01:00
f53a3ce3cc
refactor: integrate approval ui review changes
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/production Build is failing
2026-03-11 02:20:29 +01:00
86d9242d83
feat: add approval ui for join requests
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-11 02:04:03 +01:00
021b709e6a
refactor: address review comments for join view
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/production Build is passing
2026-03-10 22:54:41 +01:00
f1d0526209
feat: add join form
Some checks failed
continuous-integration/drone/push Build is failing
2026-03-10 18:25:17 +01:00
05e2a298fe
feat: add accessible drag&drop table component
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-10 15:40:28 +01:00
fa738aae88
feat: add join form settings
Some checks failed
continuous-integration/drone/push Build is failing
2026-03-10 14:29:49 +01:00
0614592674
Merge remote-tracking branch 'origin/main' into feature/308-web-form
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-09 18:18:16 +01:00
6385fbc831
feat: add join confirmation and mail templating
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-09 18:15:12 +01:00
f601550526 fix translations
Some checks reported errors
continuous-integration/drone/push Build was killed
2026-03-09 16:45:14 +01:00
8da22b3d88 Apply review feedback and fix Credo in fee type filter
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/promote/production Build is passing
- Index: use FilterParams and constants; fix parse recursion; validate fee type/group
  IDs; OR semantics for :in; build_query_params/reset_all_filters map-based API;
  alias order (Credo); Map.take list deprecation fix
- MemberFilterComponent: use FilterParams and constants; fee_type_filter_part
  helper (Credo nesting); in_not_in_filter_label_class; reset_all_filters map;
  button label for :not_in and combined filter count; fieldset borders
- Gettext: Fee types, filter count plural, 'without %{name}' (en/de)
2026-03-09 14:33:58 +01:00
3af52f2829 Update gettext: extract and merge after fee type filter strings 2026-03-09 14:33:58 +01:00
0ac39c646f
Remove Vereinfacht-required logic from settings and member validation
- Member field settings: required only from email + settings (no API override)
- Member resource validation: required fields from settings only
- Gettext: remove obsolete 'Required for Vereinfacht integration' string
2026-03-04 20:21:51 +01:00
8025858060
Gettext: add translations for member index and membership fee settings 2026-03-04 16:21:17 +01:00
4ac56958b4 feat: keep empty cells consistent empty
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-26 13:37:35 +01:00
faf80bfb4b refactor: consistend subheadings
Some checks failed
continuous-integration/drone/push Build is failing
2026-02-26 12:10:42 +01:00
88831685fc i18n: update translations
Some checks failed
continuous-integration/drone/push Build is failing
2026-02-26 11:56:24 +01:00
c7c082b867 Merge branch 'main' into feat/447_concistency
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/promote/production Build is passing
2026-02-25 16:52:59 +01:00
0f12befd11 style: consistent back button and some translations
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-25 16:25:13 +01:00
e5a6003ace feat: sticky memberstable header
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-25 14:16:43 +01:00
49fd2181a7 style: highlight selected table and add tooltip
Some checks failed
continuous-integration/drone/push Build is failing
2026-02-25 13:16:27 +01:00
bfc078d5aa Merge branch 'main' into feat/299_plz
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/promote/production Build is passing
2026-02-24 16:02:56 +01:00
6417958ccc i18n: Update translations 2026-02-24 15:38:20 +01:00
7af65d997b
Gettext: add DE/EN for OIDC-only labels and auth divider (or/oder) 2026-02-24 15:13:21 +01:00
62b37b9aa2
feat: Datafields page, merge fee types into membership_fee_settings, sidebar
- Add /admin/datafields (DatafieldsLive) for member and custom field config
- Remove Memberdata block from GlobalSettingsLive
- Router: drop /membership_fee_types, add new_fee_type and edit_fee_type under membership_fee_settings
- MembershipFeeSettingsLive: fee types table, collapsible examples; Index links updated
- PagePaths: admin_datafields, admin_import; remove membership_fee_types
- Sidebar: order and labels (Basic settings, Datafields, Membership fee settings, Import, Users, Roles)
- Gettext: German translations for sidebar and OIDC
- Tests: datafields and fee routes, permission and form tests updated
2026-02-24 13:58:38 +01:00
f29bbb02a2
feat: add Vereinfacht connection test button to settings 2026-02-24 13:09:34 +01:00
9a7608f9a1 Merge branch 'main' into feat/299_plz
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-24 11:44:19 +01:00
63040afee7 Merge branch 'main' into feat/299_plz
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-24 10:40:26 +01:00
3891c33204 i18n: update translation 2026-02-24 09:36:24 +01:00
b7ef69813b
feat(members): add Fee Type label and gettext strings
MemberFields.label(:membership_fee_type), DE: Beitragsart.
2026-02-23 23:54:59 +01:00
8933ad9d14
Member field settings: required checkbox, line break, toggle fix
Index/Form use member_field_required; Required disabled for email and
Vereinfacht-required fields with tooltip. Rebuild form with to_form
on validate to fix checkbox toggle. Add mt-4 block before Required.
2026-02-23 22:13:31 +01:00