Skip to content

fix(v2): open profiles from inspector member actions - #1270

Open
lilyshen0722 wants to merge 3 commits into
mainfrom
fix/issue-1269-inspector-profile
Open

fix(v2): open profiles from inspector member actions#1270
lilyshen0722 wants to merge 3 commits into
mainfrom
fix/issue-1269-inspector-profile

Conversation

@lilyshen0722

Copy link
Copy Markdown
Contributor

Fixes #1269.

The inspector member-detail action now opens the selected agent’s V2 profile route instead of sending identity parameters to AgentsHub, which does not read them.

Tested:

  • ./node_modules/.bin/jest --watchAll=false --runTestsByPath src/v2/__tests__/V2PodInspectorMemberProfile.test.tsx
  • Targeted ESLint: no errors (existing JSX-extension warnings only).

@lilyshen0722

Copy link
Copy Markdown
Contributor Author

Gate at fc65db06, base e86a4a4a (merge-base is main's head — no staleness). The retarget itself is correct and the test fixture is well chosen. Two changes required, both about things the diff made true rather than things it broke.

1 — The button now says "Manage" and opens one agent's profile

V2PodInspector.tsx:1618 still renders t('inspector.members.manage'). Resolved:

  • i18n/locales/en.jsoninspector.members.manage = "Manage", and the sibling manageTitle = "Manage agents installed in this pod"
  • i18n/locales/zh-CN.json"管理" / "管理安装在此 Pod 的智能体"

@ux-lead's ruling on #1269 was explicitly "AgentsHub is manage-a-fleet, not look-at-one-agent" — the destination moved to look-at-one-agent and the label did not follow, in both locales. Prior art for the right string already exists: yourTeam.card.profile, used by the card button that navigates to this same route.

This is the failure mode the PR is fixing, one layer up. The old comment asserted a contract the route didn't satisfy; deleting the comment was right, and the visible label now asserts the same wrong thing to users instead of to readers.

2 — The identical defect survives at the sibling call site

inspector.members.manage has two render sites, and #1270 fixed one:

  • :1616 (member detail) — fixed by this PR ✓
  • :1408 (members-list header, gear icon, title={manageTitle}) — still navigate('/v2/agents?podId=' + pod._id)

/v2/agents renders V2YourTeamPage (V2App.tsx:266), which contains zero occurrences of useSearchParams / location.search / URLSearchParams at origin/main. So podId is discarded there exactly as agent and instanceId were. And this is the button that genuinely means manage-the-fleet, so by ux-lead's own reasoning it is the one that should point at /v2/agents/manage (V2App.tsx:285).

#1269 named the member-detail click because that is where Sam's bug report landed; the underlying defect is "this component navigates to /v2/agents with params nobody reads," and it has two instances. Fixing one and shipping is how a shared-mechanism bug comes back.

Verified

  • The diff is minimal and does exactly what it says: -4 +1, no behaviour touched beyond the URL.
  • The test fixture is genuinely discriminating. agentName: 'scout/ops' + instanceId: 'blue sky' asserting /v2/agent/scout%2Fops/blue%20sky pins encodeURIComponent on both segments — dropping either encoder fails it. That is a better fixture than the obvious agent-1/default and I'd have accepted the weaker one.
  • Route target matches shipped prior art: V2YourTeamPage.tsx:409 builds the same shape for its own card.
  • No CSS or invariant hunks; nothing to browser-check.

Not verified / non-blocking

  • CI is not settled — 10 checks, 4 pass, 5 pending (Analyze ×3, E2E Tests, Test & Coverage) at the time I read it. I did not run the frontend suite myself; react-scripts test does not run in a detached worktree in my environment. The gate is on the diff, not on a green board — re-check before pressing.
  • The empty-agentName edge is still unguarded and I am not asking for it here. useV2PodDetail.ts:306 normalizes agentName: a.agentName || a.name || '', so '' is reachable if a registry row carries neither field, and the expression then builds /v2/agent//default, which matches no route. This is pre-existing — the old line had the same || '' — so it is not fix(v2): open profiles from inspector member actions #1270's to fix, but it is now the only remaining way this button can go nowhere.
  • The test's selector is ambiguous by construction. getByRole('button', { name: 'inspector.members.manage' }) works only because the header button at :1408 does not render in view.kind === 'member'. Fixing item 1 dissolves this; leaving both sites on one key means a future layout change makes the test throw on multiple matches rather than fail on the assertion.
  • I did not check whether V2AgentProfile resolves an agentName containing a slash — the fixture exercises encoding at the router, not lookup at the page. V2YourTeamPage has shipped the same shape, so this is not a new risk.

Fix the label and take the sibling in the same PR and this is an approve.

@lilyshen0722

Copy link
Copy Markdown
Contributor Author

Re-gate at 95a6535b. Approve. Item 1 is fixed correctly and the guard I flagged as non-blocking was taken too. Item 2 was not taken and not mentioned — filing it separately rather than holding a correct PR on an adjacent button.

Verified

  • Label now t('yourTeam.card.profile') with aria-label={t('yourTeam.card.viewProfileAria', { name })}. Both keys resolve in both locales: en 'Profile' / "View {{name}}'s profile", zh-CN '资料页' / '查看 {{name}} 的资料页'. The {{name}} interpolation is satisfied — name is in scope at :1567 (agent.profile?.displayName || agent.displayName || agent.agentName).
  • The empty-agentName edge is closed twice over: disabled={!agent.agentName} plus an early return in the handler. Belt-and-braces is fine here; the disabled attribute is the one a user can observe.
  • The navigate expression no longer carries || '', so /v2/agent//default is unconstructible from this site.
  • The selector ambiguity I noted has dissolved on its own: inspector.members.manage now has exactly one render site (:1415), so the test's getByRole can no longer become ambiguous through a layout change.
  • CI 11/11 pass, including E2E Tests and Service Tests (Tier 1 — real DBs). Settled, unlike at my first read.

One note on the new test

expect(mockNavigate).not.toHaveBeenCalled() in the malformed-row case fires without a click, so it asserts that rendering doesn't navigate — true of any version of this code, guard or no guard. toBeDisabled() is doing all the work. Not worth a change; worth knowing which of the two assertions would actually go red.

Item 2 — still open, now filed as its own issue

:1408 remains navigate('/v2/agents?podId=' + pod._id) with title={t('inspector.members.manageTitle')}. V2YourTeamPage reads no query params, so podId is discarded exactly as agent and instanceId were at the site this PR fixed — and that button is the manage-the-fleet intent, so it is the one that should reach /v2/agents/manage.

I asked for both sites in one PR and got one. That is a defensible call — they are different buttons with different intents, and the second needs a UX decision this PR wasn't scoped for. What I'd rather not have is it going unmentioned, because a shared-mechanism bug fixed at one of two sites is how it comes back. Filed so it survives this PR closing.

Not verified

  • I did not run the frontend suite; react-scripts test won't run in a detached worktree in my environment. CI's Test & Coverage is green and that is the evidence I'm relying on.
  • Whether V2AgentProfile resolves an agentName containing a slash — the fixture pins encoding at the router, not lookup at the page. V2YourTeamPage has shipped the same shape, so not a new risk, but not a checked one either.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

V2PodInspector member click sends AgentsHub params to a route that reads none of them

1 participant