Commit graph

152 commits

Author SHA1 Message Date
cdb8b03ce1 test(member): move the cycle-status test beside its OverviewQuery
Some checks failed
continuous-integration/drone/push Build is failing
2026-07-06 15:42:58 +02:00
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
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
e64f55c36a feat(member): back the overview with a keyset-paginated :overview read action 2026-07-03 11:12:38 +02:00
84e1cf1cb8 Merge branch 'main' into issue/mitgliederverwaltung-533
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/production Build is passing
# Conflicts:
#	test/mv_web/member_live/index_test.exs
2026-06-16 18:13:03 +02:00
cb54c2c46e test(member-live): build date-filter property bounds without a reject-filter
The bound-pair generator filtered out ~1/4 of generated values, so unlucky
seeds hit StreamData's FilterTooNarrowError under full property runs.
Construct an at-least-one-bound-set pair directly instead, preserving the
exact domain with no rejection.
2026-06-16 17:52:17 +02:00
655fd80524 test: wait on observable state instead of blind sleeps
Replace the fixed Process.sleep waits in the import, members-PDF and
field-visibility tests with event-based / bounded-poll waits on the
observable condition, removing a known flakiness vector.
2026-06-16 17:51:43 +02:00
18fb954f73 test(membership-fees): share create_fee_type and create_cycle fixtures
Replace the create_fee_type/create_cycle helpers duplicated across 18/8
membership-fee test files with a single shared definition in Mv.Fixtures,
reconciling the divergent local signatures (including the reversed
argument order) into one superset so behavior is unchanged.
2026-06-16 17:49:50 +02:00
fe534319ee style: order module directives per StrictModuleLayout 2026-06-16 15:51:07 +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
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
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
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
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
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
f353f1cbc0
fix: update smtp test
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/production Build is passing
2026-03-16 14:58:21 +01:00
1866c79461
fix: failing tests
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/production Build is passing
2026-03-13 20:36:13 +01:00
171a699326
fix: failing tests
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/production Build is failing
2026-03-13 19:59:59 +01:00
86c032004e
fix: failing tests
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/production Build is failing
2026-03-13 19:43:04 +01:00
a4239ce09b
fix: failing tests
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/production Build is failing
2026-03-13 19:25:23 +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
349cee0ce6
refactor: review remarks
Some checks failed
continuous-integration/drone/push Build is failing
2026-03-13 17:55:17 +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
a5ce7cb921
fix group performance test
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/production Build is passing
2026-03-12 15:46:52 +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
15d4c7d97f fix import test
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/production Build is failing
2026-03-11 11:50:24 +01:00
03d91d4029 fix tests
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/production Build is failing
2026-03-11 11:40:32 +01:00
c4135308e6
test: add tests for smtp mailer config 2026-03-11 09:18:37 +01:00
f79c9ac515 Merge pull request 'add public join form' (#466) from feature/308-web-form into main
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #466
2026-03-10 23:08:26 +01:00
f430762555
test: re-enable profile avatar test for first letter of email 2026-03-10 20:17:28 +01:00
b04d59e3c4
test: remove placeholder test for non-existent member IDs 2026-03-10 20:17:27 +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
eadf90b5fc
test: add tests for join request page 2026-03-10 17:18:14 +01:00
f9d6936274
Membership fee settings: row-click table, compact default layout 2026-03-04 16:21:17 +01:00
81ce204502
Fix Credo Readability (strict)
- Max line length, implicit try, alias order, zero-arity defs
- String sigils, long comments split; redundant blank lines fixed
2026-03-04 16:21:14 +01:00
7f15909cc6 fix tests
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/promote/production Build is passing
2026-02-26 17:14:47 +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
9751525a0c fix: datafield edit view was shown alongside othe relements
Some checks failed
continuous-integration/drone/push Build is failing
2026-02-26 12:37:52 +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