Commit graph

17 commits

Author SHA1 Message Date
ryan-crabbe-berri
74ff8d0ff9
fix(ui): navigate to /ui/login/ with trailing slash via hard navigation (#33561)
* fix(ui): navigate to /ui/login/ with trailing slash via hard navigation

Logged-out redirects targeted /ui/login without the trailing slash, so
Starlette's StaticFiles(html=True) mount answered with a 307 whose
absolute Location is built from the scheme the container sees. Behind a
TLS-terminating reverse proxy uvicorn does not trust X-Forwarded-Proto
by default, so the redirect downgraded https to http and stranded users
on an unreachable URL (#33454). The auth guard also used the Next client
router for this navigation, which first requests an RSC payload that the
static export cannot serve, producing 404s before falling back to a full
page load.

Centralize the login URL in getLoginUrl(), which always emits the
trailing slash so no server redirect fires, and use
window.location.replace for the login redirects so no RSC fetch is
attempted.

* test(ui): expect trailing slash in expired-token login redirect
2026-07-16 12:18:55 -07:00
ryan-crabbe-berri
b6dbda48f9
refactor(ui): colocate the mcp-servers view, keeping the shared mcp_tools surface (#32968)
* refactor(ui): colocate the usage view, keeping the shared usage components

Split for the usage (UsagePage) segment. Most of the folder is the usage page's
own view, but four pieces are reused elsewhere and stay in @/components/UsagePage:
TopKeyView (old-usage), KeyModelUsageView and value_formatters (activity_metrics),
and the shared types (activity_metrics, chartUtils). The other 21 files move into
usage/_components, preserving the folder structure.

The external consumers import only the retained files, so they are untouched. The
moved files' imports of the retained files become @/components/UsagePage paths,
other escaping relative imports are absolutized, and lint suppressions are re-keyed
for moved files only. No behavior change.

* refactor(ui): colocate the mcp-servers view, keeping the shared mcp_tools surface
2026-07-11 18:01:41 -07:00
ryan-crabbe-berri
77a30a120c
refactor(ui): colocate agents and guardrails views, keeping shared selectors and types (#32728)
* refactor(ui): colocate agents and guardrails views, keeping shared selectors and types

The last two group-1 colocation splits. Both are file-plus-folder combos: the
page view is a top-level file (agents.tsx / guardrails.tsx) sitting beside a
supporting folder of the same name, and part of that folder is shared.

agents: agents/types (imported by the agents hook) stays in @/components/agents;
agents.tsx and the rest of the agents/ folder move into agents/_components (the
view file becomes _components/index.tsx).

guardrails: GuardrailSelector (imported by the Playground, the key edit view,
and the agents add-guardrail form) and types stay in @/components/guardrails;
guardrails.tsx and the other 47 folder files (including the tool_permission,
custom_code, content_filter, and llm_judge subfolders) move into
guardrails/_components.

Moved files' imports of the retained shared files become @/components paths,
other escaping relative imports are absolutized against @/, and moved test
files have their from/vi.mock/vi.importActual paths rewritten to match. Lint
suppressions are re-keyed for moved files only (the staying selector/types keep
their src/components keys). The shared selectors did not move, so their external
consumers are untouched. No behavior change.

* fix(ui): move the orphaned agents/guardrails view tests and drop dead GuardrailItem

Greptile follow-ups on the agents/guardrails colocation:

- agents.tsx and guardrails.tsx moved to their _components/index.tsx, but their
  sibling test files (src/components/agents.test.tsx, guardrails.test.tsx) were
  left behind still importing ./agents and ./guardrails, which broke a full
  vitest run. Move them to the matching _components/index.test.tsx and rewrite
  their view import to ./index, folder mocks to local ./ siblings, and
  networking to @/components/networking.
- Remove the unused GuardrailItem interface and its GuardrailDefinitionLocation
  import from the guardrails view (dead code carried over from before the move;
  state is typed as Guardrail[]).
2026-07-10 10:57:12 -07:00
ryan-crabbe-berri
3d5d5e1295
refactor(ui): colocate tag-management and vector-stores views, keeping the shared selectors (#32719)
Two of the group-1 colocation splits. Each of these folders lived in the shared
src/components dump but is only partly shared: the page's management view is
segment-owned, while a selector widget is reused by other features. So this
splits them rather than moving wholesale.

tag-management: TagSelector (used by playground) and its types stay in
@/components/tag_management; the management view (index, tag_info, TagTable,
CreateTagModal) moves to tag-management/_components.

vector-stores: VectorStoreSelector (used by organizations and playground) and
its types stay in @/components/vector_store_management; the rest of the
management UI moves to vector-stores/_components.

The moved files' imports of the retained shared files are rewritten to absolute
@/components paths, escaping relative imports are absolutized, and moved test
files have both their `from` imports and `vi.mock` paths rewritten to match.
Grandfathered lint suppressions for moved files are re-keyed. The external
consumers of the selectors are untouched (the selectors did not move). No
behavior change.
2026-07-09 22:19:11 -07:00
ryan-crabbe-berri
65d90fd5cf
refactor(ui): colocate 11 route segments' components into _components/ (#32704)
Colocation follow-up to the App Router migration: move each page's owned
components out of the shared src/components dump and into its route segment's
_components/ folder, draining the shared bucket. Convention: a component used
by exactly one segment goes in that segment's _components/ (private, matching
Next's _ route-exclusion); a component shared by 2+ segments stays in
@/components. No new _shared/ folder.

Rename-in-place (segment already had a local components/ folder):
- api-reference (also relocates the shared CodeBlock, used by playground and
  cost-tracking, to @/components/CodeBlock)
- memory, budgets, access-groups
- caching, projects, guardrails-monitor

Extract from src/components (page view lived in the shared dump):
- AdminPanel -> admin-panel, organizations -> organizations,
  general_settings -> router-settings, usage -> old-usage

Each folder/view was verified to have no importer other than its own page
(cross-checked across src, tests, and e2e_tests). Relative imports inside moved
single files are rewritten to absolute @/components/*; colocated tests move with
their subject and have their vi.mock paths rewritten to match. Grandfathered
lint suppressions (tremor, react-hooks, and similar, all pre-existing) are
re-keyed to the new paths with counts unchanged. No behavior change.
2026-07-09 17:43:33 -07:00
ryan-crabbe-berri
3d644e1f9d
refactor(ui): colocate users page into route-level _components (#31897)
Moves the user-management component tree (view_users plus BulkEditUsers, edit_user, DefaultUserSettings, user_edit_view, and the view_users table/columns/info-view) out of the shared src/components dump into the users route segment under _components, now that the app router owns the route. The page imports from a trimmed ./_components barrel

UserInfo moves into networking.tsx beside UserListResponse, its real owner: networking defines the user API response shapes that embed it, and previously reached up into a view folder (components/view_users/types) to import the type. Defining it in networking removes that backwards data-layer-to-view dependency and drains the view_users/ folder entirely. CreateUserButton and onboarding_link stay in components/ since the create-key flow also consumes them

Relative imports in the moved files are rewritten to @/components/* absolute paths, and the eight pre-existing eslint-suppressions entries are re-keyed to the new paths so the move stays behavior and lint neutral

Verified: the moved suites pass with the same 75 assertions as before the move, tsc and eslint are clean, and next build compiles the /users route
2026-07-01 20:14:07 -07:00
ryan-crabbe-berri
4def6916da
refactor(ui): consolidate dashboard to one shell in the (dashboard) layout (#30166)
* refactor(ui): consolidate dashboard to one shell in the (dashboard) layout

Moves the legacy ?page= switch page into the (dashboard) route group and
hoists Navbar, sidebar, ThemeProvider, and DebugWarningBanner into the
shared layout with real props, deleting the degraded duplicate shell that
wrapped migrated routes. The active page key now derives from the URL at
render time, so navigating between legacy and migrated pages no longer
remounts the shell.

useProxySettings becomes a React Query hook taking accessToken, shared by
the navbar, the AdminPanel arm, and migrated pages; this replaces the
lifted proxySettings state and the Navbar setProxySettings prop drilling.
The invitation onboarding flow (?invitation_id=) keeps rendering without
chrome via a layout escape hatch. Dead dark mode state and the no-op antd
ConfigProvider are removed.

* fix(ui): include accessToken in useProxySettings query key

The queryFn closes over accessToken, so the key must include it for the
cache to be honest about its inputs. Settings are instance-global today,
which made the omission harmless, but a token change while mounted would
have served the cached entry without refetching.

* test(ui): point CreateKeyPage test at the moved page

The page moved into the (dashboard) route group and no longer renders
the navbar (the layout owns chrome now), so the valid-token test asserts
the default page content (UserDashboard stub) instead.
2026-06-10 18:37:44 -07:00
ryan-crabbe-berri
248176112e
feat(ui): add admin flag to disable in-product UI nudges for everyone (#29796)
* feat(ui): add admin flag to disable in-product UI nudges for everyone

Admins can now suppress the survey and Claude Code feedback popups for
all users via a single disable_ui_nudges UI setting, instead of relying
on each user dismissing them individually.

* fix(ui): suppress nudges while ui settings are loading

Gate nudgesDisabled on the ui-settings loading state so an admin with
disable_ui_nudges on doesn't see the survey prompt flash, and the
getInProductNudgesCall fetch doesn't fire, on a cold page load before
the flag resolves. Falls back to showing nudges if the fetch errors.

* test(ui): wrap CreateKeyPage test in QueryClientProvider

page.tsx now calls useUISettings (react-query), which needs a
QueryClient that layout.tsx supplies in production but the test did
not. Add the provider and mock getUiSettings so the query resolves.
2026-06-09 17:45:42 -07:00
ryan-crabbe-berri
7edf3a9cb5
style(ui): run prettier --write across the dashboard (#29622)
Formatting-only pass; no logic changes. Brings the UI into compliance
with .prettierrc so the new format-check CI job passes
2026-06-04 11:37:54 -07:00
ryan-crabbe-berri
73e9071311
refactor(ui): extract auth state into AuthContext (#28910)
Some checks are pending
Unit Tests: Proxy DB Operations / assert-shard-coverage (push) Waiting to run
Unit Tests: Proxy DB Operations / auth-checks (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / budgets (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / custom-logging (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / db-and-spend (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / endpoints-and-responses (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / guardrails-hooks (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / jwt-and-keys (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / key-generation (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / logging-misc (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / proxy-runtime (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / proxy-server-core (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / schema-migration (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / proxy-utils (push) Blocked by required conditions
Unit Tests: Security / security (push) Waiting to run
* refactor(ui): extract auth state into AuthContext

Move auth state (token, userID, userRole, accessToken, premiumUser, userEmail,
disabledPersonalKeyCreation, showSSOBanner) out of src/app/page.tsx into a
new AuthProvider at src/contexts/AuthContext.tsx. Wrapped at the root layout
so login/onboarding/dashboard routes all have access via useAuth().

Day 1 foundation for the App Router migration: migrated (dashboard)/X/page.tsx
route entry points won't have a parent passing props, so shared auth state
must live in a context they can read from.

Sub-components are unchanged — they still receive accessToken/userID/userRole
as props from page.tsx (which now reads them from useAuth()). Only the
page.tsx → top-level-page-component handoff is de-drilled; deeper prop
drilling is left for the per-page migration to address.

Net change: -86 lines from page.tsx (state + two effects moved), +5 in
layout.tsx (provider wrap), new AuthContext.tsx (~140 lines), test update
to wrap CreateKeyPage in AuthProvider.

Fixes LIT-3366
Part of LIT-3128

* fix(ui): await getUiConfig before clearing authLoading

The AuthContext refactor flipped authLoading to false synchronously on mount
while letting getUiConfig() run fire-and-forget. On SERVER_ROOT_PATH deployments
this races the unauthenticated login-redirect effect: the redirect fires with
proxyBaseUrl still at its module-init value, sending users to /ui/login instead
of {SERVER_ROOT_PATH}/ui/login.

Restores the original sequencing inside AuthProvider's mount effect and adds a
Playwright spec wired into the existing SERVER_ROOT_PATH workflow matrix. The
spec delays the config endpoint via page.route() to make the race deterministic
across CI runners.
2026-05-26 17:53:03 -07:00
yuneng-jiang
0cd4a68157 [Fix] Add missing networking mocks to CreateKeyPage test
The test's partial vi.mock of @/components/networking was missing the daily
activity call exports now imported by EntityUsage via ENTITY_FETCH_FNS.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 09:47:56 -07:00
Dibyo Mukherjee
518cd3ef60 feat(ui): add key creation deep-links with SSO return URL support
Enables deep-linking directly to the key creation modal with prefilled
form data via URL parameters, including support for preserving these
deep-links through SSO authentication flows.

Key Creation Deep-links:
- Auto-open key creation modal via ?create=true parameter
- Prefill form fields from URL parameters (team_id, key_alias, models, etc.)
- Role-based access control for auto-open (requires write access)
- Race condition protection for redirect handling

Example: /ui?create=true&team_id=abc&key_alias=my-key&models=gpt-4,claude-3

SSO Return URL Preservation:
- Cookie-based return URL storage (works across ports for SSO flows)
- URL validation to prevent open redirect attacks
- Support for both dev and production environments

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 15:41:54 -05:00
yuneng-jiang
5496e622c1 Unit tests 2025-12-03 23:46:09 -08:00
Achintya Rajan
b4444ead0d rebased, removed unused imports 2025-10-10 10:25:48 -07:00
Achintya Rajan
87b0ff6ab0 Update CreateKeyPage.expiredToken.test.tsx 2025-10-09 13:58:34 -07:00
Achintya Rajan
fe2d4addfa Update CreateKeyPage.expiredToken.test.tsx 2025-10-08 14:10:09 -07:00
Achintya Rajan
d6852b11ae Create CreateKeyPage.expiredToken.test.tsx 2025-10-08 13:41:00 -07:00