feat(admin): invitations management tab#4217
Conversation
|
Warning Review limit reached
More reviews will be available in 46 minutes and 12 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (3)
WalkthroughThis PR adds a complete invitations management feature to the admin section. It includes store actions to fetch, create, and revoke signup invitations; a new Vue component with a data table, create dialog, and revoke confirmation; router configuration for the ChangesAdmin invitations management
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #4217 +/- ##
=======================================
Coverage 99.56% 99.57%
=======================================
Files 31 31
Lines 1159 1182 +23
Branches 330 330
=======================================
+ Hits 1154 1177 +23
Misses 5 5 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
…ov patch) Add missing tests to reach 100% line/statement/function coverage on the new admin.invitations.view.vue and the new invitation store actions: - openCreate() reset, openRevoke() populate, rules.required/mail validators - submitInvite error path (catch+finally), confirmRevoke error path (finally) - getUser error path (sets error + resets user via resetUser) - Slot-rendering coreDataTableComponent stub to cover #status/#invitedBy/#actions - Event-triggering stubs (v-dialog, v-form, v-text-field, coreConfirmDialog) to cover compiled v-model onUpdate handlers and cancel-button click handler
There was a problem hiding this comment.
Pull request overview
Adds an Invitations management tab to the Admin area, providing UI + store support for listing, creating, and revoking signup invitations via the existing admin API.
Changes:
- Added a new Admin child route (
/admin/invitations) and a corresponding built-in Admin tab entry. - Implemented
AdminInvitationsview with a datatable, create-invite dialog, and revoke confirmation flow. - Extended the admin Pinia store with invitations state + actions and added unit tests covering routing, layout tabs, store actions, and view behavior.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/modules/admin/views/admin.layout.vue | Adds the Invitations tab to the built-in Admin tab list. |
| src/modules/admin/views/admin.invitations.view.vue | New Invitations tab UI: list + status chip + create/revoke dialogs. |
| src/modules/admin/router/admin.router.js | Registers the /admin/invitations child route with CASL meta. |
| src/modules/admin/stores/admin.store.js | Adds invitations state plus list/create/revoke actions hitting /auth/invitations. |
| src/modules/admin/tests/admin.store.unit.tests.js | Adds store tests for invitations CRUD actions. |
| src/modules/admin/tests/admin.router.unit.tests.js | Adds coverage that the invitations child route is registered. |
| src/modules/admin/tests/admin.layout.unit.tests.js | Updates expectations for the new built-in tab count and presence. |
| src/modules/admin/tests/admin.invitations.view.unit.tests.js | Adds view-level tests for status derivation and create/revoke wiring. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/modules/admin/tests/admin.invitations.view.unit.tests.js`:
- Around line 180-192: The test uses a no-op assertion
(expect(wrapper.vm).toBeDefined()) after triggering button clicks; replace that
with assertions that verify the actual observable state changes: after
simulating the Cancel button click in the "cancel button in create-dialog" test
assert that wrapper.vm.createDialog.show === false, and in the related submit
test assert that the v-form submit sets wrapper.vm.createDialog.valid === true
(or whatever concrete flag your component uses). Locate the tests in
admin.invitations.view.unit.tests.js that manipulate createDialog.show and the
form submit handler and update their expect statements to check those specific
properties (createDialog.show and createDialog.valid) instead of merely
asserting wrapper.vm is defined.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: bd139481-a69b-467d-8dab-2f1b2e8d114a
📒 Files selected for processing (8)
src/modules/admin/router/admin.router.jssrc/modules/admin/stores/admin.store.jssrc/modules/admin/tests/admin.invitations.view.unit.tests.jssrc/modules/admin/tests/admin.layout.unit.tests.jssrc/modules/admin/tests/admin.router.unit.tests.jssrc/modules/admin/tests/admin.store.unit.tests.jssrc/modules/admin/views/admin.invitations.view.vuesrc/modules/admin/views/admin.layout.vue
… real behavior in binding tests
# [2.1.0](v2.0.0...v2.1.0) (2026-06-01) ### Bug Fixes * **billing:** 4 pricing page bugs (signed-in features, hero bg, truncation, guest CTA) ([#4123](#4123)) ([bd399bd](bd399bd)) * **billing:** add aria-expanded + touch support to BillingComputeGauge components ([#4181](#4181)) ([7e7fa97](7e7fa97)) * **billing:** billing UX hardening — 5 reliability fixes ([#4079](#4079)) ([dd62b3d](dd62b3d)), closes [#4078](#4078) * **billing:** canonical FA6 icons + meterError lifecycle + reject URL credentials ([#4082](#4082)) ([be16045](be16045)), closes [#4081](#4081) * **billing:** clear intentId on Stripe cancel-redirect ([#4085](#4085)) ([11be9ab](11be9ab)) * **billing:** drop empty overage aria-live div + add fr overDetail key ([#4142](#4142)) ([10e5d81](10e5d81)) * **billing:** i18n migration + Intl.NumberFormat USD (audit Codex P1) ([#4069](#4069)) ([3d3a4f6](3d3a4f6)) * **billing:** mega vue hardening v3 — UX + design + a11y + V4 ([#4063](#4063)) ([802cbc4](802cbc4)) * **billing:** send {} body on portal POST to satisfy Zod PortalRequest schema ([#4137](#4137)) ([bf6b9c8](bf6b9c8)) * **billing:** send intentId UUID to close extras double-charge window ([#4084](#4084)) ([3e27c4c](3e27c4c)) * **billing:** subscription state safety + webhook lag polling (audit Codex P1) ([#4068](#4068)) ([328700b](328700b)) * **billing:** surface meterError + remove dead 409 dialog from subscriptions ([#4081](#4081)) ([61f5d53](61f5d53)) * **billing:** V5 polish — F5 polling recovery + visibility refetch + i18n residual + locale null-guard ([#4070](#4070)) ([4908adb](4908adb)) * **billing:** V6 polish — sessionStorage guard + locale BCP47 + i18n plural + NaN guard ([#4076](#4076)) ([2ad018c](2ad018c)) * **build:** drop ARG defaults for analytics_* + filter empty env vars ([#4112](#4112)) ([afd336e](afd336e)), closes [Vue#4110](https://github.com/Vue/issues/4110) [#4110](#4110) * **build:** restore Layer 5 empty-string env override (revert [#4112](#4112) part 2) ([c9aa9e6](c9aa9e6)), closes [Vue#4110](https://github.com/Vue/issues/4110) [comes-io/trawl_vue#880](https://github.com/comes-io/trawl_vue/issues/880) [Vue#4110](https://github.com/Vue/issues/4110) * **core:** pin CorePageHeader to content size in flex-column contexts ([#4210](#4210)) ([e182512](e182512)), closes [#4202](#4202) * **layout:** route /pricing outside app shell — no drawer offset on signed-in ([#4124](#4124)) ([d862fbb](d862fbb)) * **legal:** cookie banner UA-detection + appName fallback to app.title ([#4113](#4113)) ([04cc70a](04cc70a)), closes [trawl_vue#876](https://github.com/trawl_vue/issues/876) [#4109](#4109) * **legal:** cookie consent + footer polish (5 QA bugs) ([#4098](#4098)) ([a9bf0a3](a9bf0a3)) * **legal:** gate cookie banner on isMounted to prevent prerender hydration double-render ([#4109](#4109)) ([3198e48](3198e48)), closes [#app](https://github.com/pierreb-devkit/Vue/issues/app) * **router:** redirect authenticated users to config.sign.route instead of hardcoded '/' ([#4088](#4088)) ([ca9094e](ca9094e)), closes [#4083](#4083) * **tasks:** propagate store errors so views gate navigation on success ([#4221](#4221)) ([b029d39](b029d39)), closes [#4218](#4218) * **ui:** chrome convergence — restore section title + surface backgrounds + homogeneous gutter ([#4188](#4188)) ([1e5fdf1](1e5fdf1)) * **users:** re-apply route tab when serverConfig.billing arrives async ([#4138](#4138)) ([87cc7b2](87cc7b2)) * **users:** refetch billing subscription on auth state change ([#4125](#4125)) ([5a3425a](5a3425a)) ### Features * **admin:** invitations management tab ([#4217](#4217)) ([61ad86c](61ad86c)), closes [invitedBy/#actions](https://github.com/pierreb-devkit/Vue/issues/actions) * **analytics:** add identify and reset helpers, wire auth store ([#4104](#4104)) ([c4d8b87](c4d8b87)) * **auth:** invite-gated signup UI ([#4212](#4212)) ([d17a841](d17a841)) * **billing:** add 'Manage subscription' footer link in meterDrawer ([#4056](#4056)) ([#4057](#4057)) ([7d494af](7d494af)) * **billing:** align packs.component on BillingCardComponent (V4 unified schema) ([#4147](#4147)) ([7f5dd41](7f5dd41)) * **billing:** combined pool gauge + linear breakdown bars + alerts cleanup ([f5034b1](f5034b1)) * **billing:** config-driven static-content resolver (no file replace) ([e95d944](e95d944)) * **billing:** expose netRemainingRaw + overage in useMeter for negative quota display ([#4061](#4061)) ([111e64b](111e64b)), closes [#4060](#4060) * **billing:** meter gauges display % primary, compute units in overflow tooltip ([#4139](#4139)) ([50498ba](50498ba)) * **billing:** meter UX refonte — drop drawer + subscriptions tab ([#4059](#4059)) ([891b5ae](891b5ae)), closes [#subscriptions](https://github.com/pierreb-devkit/Vue/issues/subscriptions) [#1](#1) [#2](#2) [#3](#3) [#4](#4) * **billing:** post-grant upgrade prompt variant for depleted signupGrant ([#4128](#4128)) ([0ae8558](0ae8558)) * **billing:** pricing page redesign — multi-mode + auto-savings + sectioned features + FAQ ([#4102](#4102)) ([2c83ab6](2c83ab6)) * **billing:** pricingCard Free CTA — 'Sign up' for guests, route to /signup ([#4106](#4106)) ([cc92ac8](cc92ac8)) * **billing:** redesign Subscriptions view to match user-tabs aesthetic ([#4127](#4127)) ([15fd466](15fd466)) * **billing:** relocate billing under Organization settings ([#4175](#4175)) ([1f36137](1f36137)) * **billing:** sidenav compute gauge above sign-out row (meter mode) ([#4126](#4126)) ([fe1497f](fe1497f)) * **billing:** sidenav compute gauge redesign — button-shape above sign-out row ([#4140](#4140)) ([9d3a090](9d3a090)) * **billing:** sidenav compute gauge revamp — v-progress-circular + v-tooltip ([#4144](#4144)) ([5d60f1b](5d60f1b)), closes [#prepend](https://github.com/pierreb-devkit/Vue/issues/prepend) * **billing:** subscriptions view 2-col layout — drop dup bar, CTA to /pricing#units ([#4141](#4141)) ([b7ef516](b7ef516)), closes [pricing#units](https://github.com/pricing/issues/units) * **billing:** unified BillingCardComponent + annual toggle disabled state ([#4146](#4146)) ([474bb11](474bb11)) * **billing:** unified BillingCardComponent + annual toggle disabled state ([#4149](#4149)) ([d1403ff](d1403ff)) * **billing:** v4 hardening + Phase 3 polish — equivalences chips + UX gaps + a11y ([#4066](#4066)) ([dd40b2a](dd40b2a)) * **billing:** wire netRemainingRaw + overage into devkit components ([#4062](#4062)) ([61d6897](61d6897)), closes [#4061](#4061) * **core:** reusable PageTabs component + Account view refactor ([#4183](#4183)) ([dc2504a](dc2504a)) * **core:** unified logo+title lockup in header and sidenav ([#4086](#4086)) ([ec457db](ec457db)), closes [#4083](#4083) * **feature:** read ERRORS.md in Phase 0 before coding ([#4089](#4089)) ([ddf8f60](ddf8f60)) * **legal:** Add legal module + cookie consent (RGPD) ([#4097](#4097)) ([595e6c4](595e6c4)), closes [#3204116570](https://github.com/pierreb-devkit/Vue/issues/3204116570) [#3204116650](https://github.com/pierreb-devkit/Vue/issues/3204116650) [#1](#1) [#19](#19) [#18](#18) [#13](#13) [#11](#11) [#18](#18) [#3](#3) [#10](#10) [#12](#12) [#14](#14) [#15](#15) [#17](#17) [#20](#20) [#4](#4) [#5](#5) [#6](#6) [#7](#7) [#8](#8) [#9](#9) [#16](#16) [#3](#3) [#16](#16) [#22](#22) * **legal:** liquid glass cookie banner — Vuetify-only with friendlier copy ([#4115](#4115)) ([3d74789](3d74789)), closes [#4114](#4114) * **monitoring:** single-source PostHog Error Tracking (drop Sentry) ([#4118](#4118)) ([82dfca6](82dfca6)) * **organizations:** add Organization tab + rename General route to tab-addressable ([#4184](#4184)) ([fdfbf0b](fdfbf0b)) * **organizations:** soft suggestedJoin onboarding banner + recovery-screen copy ([#4176](#4176)) ([25a3ceb](25a3ceb)) * **seo:** enrich seoInjectPlugin — multi-schemas + rich SoftwareApplication + themeColor ([#4092](#4092)) ([#4111](#4111)) ([7f8bd09](7f8bd09)) * **skill/feature:** add Phase 0.0 issue claim-on-start ([#4117](#4117)) ([a582430](a582430)), closes [pierreb-projects/infra#28](https://github.com/pierreb-projects/infra/issues/28) * **skills/update-stack:** block on undeclared drift vs upstream ([#4228](#4228)) ([ab8ee68](ab8ee68)), closes [#4227](#4227) * **users:** subs full-width + delete account danger zone + halo full-bleed fix ([#4143](#4143)) ([981f073](981f073))
Summary
src/modules/admin).coreDataTableComponentlists signup invitations with a per-row status chip (Pending / Accepted / Expired, derived fromusedAt/expiresAt), an Invite button opening an email dialog (createInvitation), and a per-row revoke action (coreConfirmDialog→deleteInvitation)./api/auth/invitationsadmin API (list/create/revoke). Tab gated by the same CASL meta as the Users tab (action: manage, subject: UserAdmin).Why
Admins need a self-service UI to manage signup invitations without direct API or DB access.
Scope
src/modules/admin(new view + route + tab entry)nonelowCloses #4216
Validation
npm run lintnpm run test:unitnpm run buildGuardrails check
.env*,secrets/**, keys, tokens)Notes for reviewers
{ action: manage, subject: UserAdmin }— same guard as the Users tab./update-projectonce merged.Test plan
Full Vue unit suite green (1934 tests) + lint clean. New tests cover:
usedAt/expiresAtlogic)[doc-sync ack]clean (no deleted files, no stale comments).Summary by CodeRabbit
Release Notes
New Features
Tests