Migrate profile email-preferences tab to Vue + /api/v2/users/me/preferences (Group 2.2 1/5)#868
Open
edwh wants to merge 7 commits into
Open
Migrate profile email-preferences tab to Vue + /api/v2/users/me/preferences (Group 2.2 1/5)#868edwh wants to merge 7 commits into
edwh wants to merge 7 commits into
Conversation
…Group 2.2 partial 1/5)
The profile-edit page is a tabbed shell with 5 partials (profile, account,
email-preferences, calendars, repair-directory). This commit migrates the
email-preferences partial — the simplest — as the first slice.
- GET/PATCH /api/v2/users/me/preferences (auth:api, OpenAPI annotated)
returning {data: {invites: bool}}
- tests/Feature/Users/APIv2UserPreferencesTest: 7 cases covering auth,
shape, validation, and persistence in both directions
- resources/js/components/EmailPreferencesTab.vue: small Vue component
rendering the existing UI and POSTing via the new endpoint
- resources/views/user/profile/email-preferences.blade.php now mounts
the Vue component; the existing /profile/edit-preferences POST handler
is unchanged and remains a fallback
- lang/{en,fr,fr-BE}/general.php: error_occurred key for the toast
Follow-ups: migrate profile/account/calendars/repair-directory tabs
incrementally on the same branch.
edwh
added a commit
that referenced
this pull request
May 30, 2026
…oup 2.2 2/5) - GET /api/v2/users/me/calendars (auth:api) returns user + per-group + admin all-events + group-area calendar URLs with OpenAPI - tests/Feature/Users/APIv2UserCalendarsTest: 3 cases (auth, host shape, admin flag/url) - CalendarsTab.vue: lists subscription URLs, copy buttons, area select; uses clipboard API instead of the old jQuery btn-copy-input-text - calendars.blade.php now mounts the Vue component
…ir-directory-* (Group 2.2 3/5)
- GET /api/v2/users/{id}/repair-directory-options: per-option `selected`
+ `disabled` flags computed against existing UserPolicy::changeRepairDirRole.
- PATCH /api/v2/users/{id}/repair-directory-role: policy-gated save.
- APIv2RepairDirectoryTest: 7 cases (auth/404/super-admin enabled/non-admin
disabled/forbidden update/persistence/validation enum).
- RepairDirectoryTab.vue: replicates the existing select with disabled
options and submit button.
…up 2.2 4/5 partial) The account tab contains 4 sub-forms (password, language, admin matrix, soft-delete). This commit migrates the language sub-form only — non-sensitive and isolated. Password change, admin matrix, and soft-delete remain on existing CSRF-protected POST routes pending adversarial review of those security boundaries. - GET /api/v2/users/me/language returns current language + supported locales - PATCH /api/v2/users/me/language validates against supported list, fires UserLanguageUpdated event, persists to user - APIv2UserLanguageTest: 5 cases (get auth/shape, update auth/validation/persist) - LanguageTab.vue: select + save, reloads after save to apply translations
…ed key
The PR's new v2 endpoint tests exposed three real issues:
1. Unauthenticated auth:api requests returned 500 instead of 401. The custom
JSON exception handler mapped any exception without getStatusCode() to 500,
and Laravel's AuthenticationException has none. Added an explicit
AuthenticationException -> 401 branch. This is correct API behaviour and was
simply never asserted before (these are the suite's first 401 tests), so it
fixed every *RequiresAuth test across preferences/calendars/language/
repair-directory at once.
2. getMyCalendarsv2 read the admin all-events hash via env('CALENDAR_HASH')
directly, which returns null under config:cache in production (a latent bug)
and can't be overridden in tests. Moved it to config('restarters.calendar_hash')
and updated the test to set it via config() instead of putenv() (which
Laravel's env() does not read).
3. email_alerts_pref1 ('monthly newsletter') was only ever referenced inside a
commented-out block in the old blade, so translations:check passed on the
stray string. Migrating that tab to Vue removed the last textual reference,
orphaning the key. The newsletter checkbox has long been disabled (handled by
the community platform), so removed the dead key from en/fr/fr-BE.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PHPUnit is green after the previous commit; the only failure was tests/Integration/event.test.js "Invite volunteers modal opens from Event Actions dropdown" timing out clicking the dropdown item. That test is untouched by this PR, the branch is level with develop, and the test has a long history of timeout/hang flake-fixes (Google Maps hang in Docker noted in its own comments). Empty commit to re-run the suite. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The event Playwright suite failed deterministically today (last day of May) on "Invite volunteers modal opens from Event Actions dropdown". Root cause is in the shared createEvent() helper, not the test or this PR's code: createEvent(past=false) selected the last day of the *current* month at 13:00-14:00. On the last day of a month that date is "today"; when CI runs after 14:00 local the event has already finished, so the API reports upcoming=false and EventActions correctly hides the "Invite Volunteers" item (gated on isAttending && upcoming && approved). The test then times out waiting for an item that will never appear. develop passed only because its run happened earlier in the day. Fix: for future events, advance to the next month before selecting the day (mirroring the past branch's "Previous month"), so the event is always comfortably upcoming regardless of when the suite runs. Only the two past=false callers in event.test.js are affected; device.test.js uses past. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
First slice of plans/active/blade-to-vue-migration.md Group 2.2.
The
user/profile-editpage is a tabbed shell with 5 partials. This PRmigrates the simplest tab (
email-preferences.blade.php) so the APIshape and Vue-component pattern can be reviewed before the heavier tabs
(profile, account, calendars, repair-directory) follow on the same branch.
GET/PATCH /api/v2/users/me/preferenceswith OpenAPI + 7 PHPUnit testsEmailPreferencesTab.vue/profile/edit-preferencesPOST handler is unchanged soany other consumers stay green.
Test plan
APIv2UserPreferencesTestpasses on CI