feat(organizations): add Organization tab + rename General route to tab-addressable#4184
Conversation
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, 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 have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughThis PR adds a new "Organization" tab to the organization detail view. The config defines the tab with route ChangesOrganization Tab Addition
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 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 |
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/organizations/tests/organizations.config.unit.tests.js`:
- Around line 55-58: The test currently only asserts that the 'billing' tab is
present when can() always returns true; update the assertions in the test (using
the result array produced in the test) to explicitly assert that both entries
with value 'organization' and 'billing' exist (e.g., check result.find(t =>
t.value === 'organization') and result.find(t => t.value === 'billing') are
defined), ensuring the test fails if either tab is missing.
🪄 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: 051f170a-bd71-4e67-b678-5669d70b23d6
📒 Files selected for processing (5)
src/modules/organizations/config/organizations.development.config.jssrc/modules/organizations/router/organizations.router.jssrc/modules/organizations/tests/organizations.config.unit.tests.jssrc/modules/organizations/tests/organizations.detail.layout.unit.tests.jssrc/modules/organizations/tests/organizations.router.unit.tests.js
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #4184 +/- ##
=======================================
Coverage 99.55% 99.55%
=======================================
Files 31 31
Lines 1136 1136
Branches 328 328
=======================================
Hits 1131 1131
Misses 5 5 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Adds an explicit Organization tab to the organization settings surface and makes the “General” child route tab-addressable (non-empty path) so it can be selected by SurfaceTabBar, while preserving backward compatibility via a redirect from the bare org settings URL.
Changes:
- Add
organizationtab descriptor toconfig.organizations.tabs(beforebilling). - Change the organization “General” child route from
path: ''topath: 'general', and add a'' -> generalredirect. - Extend/adjust unit tests to cover the new tab + routing behavior.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/modules/organizations/router/organizations.router.js | Adds default-child redirect and makes General a named, non-empty child path (general). |
| src/modules/organizations/config/organizations.development.config.js | Adds the missing organization tab descriptor ahead of billing. |
| src/modules/organizations/tests/organizations.router.unit.tests.js | New unit tests for the updated child path and redirect. |
| src/modules/organizations/tests/organizations.detail.layout.unit.tests.js | Updates layout tests to expect both Organization + Billing tabs and updated general child path. |
| src/modules/organizations/tests/organizations.config.unit.tests.js | Updates config tests for the new tab and CASL filtering behavior. |
| }); | ||
|
|
||
| test('Account Organization has a redirect from "" to General', () => { | ||
| const parent = routes.find((r) => r.name === 'Account Organization'); |
| it('resolveSurfaceTabs returns billing tab when can("manage","Organization") is true', () => { | ||
| const tabs = organizationsDefaultConfig.organizations.tabs; | ||
| const result = resolveSurfaceTabs(tabs, () => true); | ||
| expect(result).toHaveLength(1); | ||
| expect(result[0].value).toBe('billing'); | ||
| // Both organization (read) and billing (manage) are visible when can() always returns true | ||
| expect(result.length).toBeGreaterThanOrEqual(1); | ||
| expect(result.find((t) => t.value === 'billing')).toBeDefined(); | ||
| }); |
| // Default child: native org-settings sections (Details, Roles, Members, | ||
| // Invite, Pending Requests). Downstream child modules (e.g. billing) | ||
| // are injected via organizationChildModules in app.router.js. | ||
| children: [ | ||
| { | ||
| // Redirect bare /users/organizations/:id → :id/general so SurfaceTabBar | ||
| // descriptors with `route: 'general'` resolve correctly. |
…oth tabs (CR feedback)
Addressed in commit a63abc5 — tightened test assertion to toHaveLength(2) + explicit organization+billing find()
# [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))
Adds the missing 'Organization' tab descriptor in
config.organizations.tabs(was Billing-only post-#4175) and renames the General child route from''to'general'so it's addressable by SurfaceTabBar (which rejects empty-string routes viaisValidTab). A redirect from the bare path preserves backward compat for deep-links to/users/organizations/:id.Resolves user feedback item 3 (2026-05-20): 'onglet dans organization j'en vois toujours qu'un: Billing'.
Refs: docs/superpowers/plans/2026-05-20-trawl-ui-feedback-batch-v2.md PR Beta.
Summary by CodeRabbit