feat: links to user, proposal, FAP from Experiments and Proposals table#1593
feat: links to user, proposal, FAP from Experiments and Proposals table#1593shivoomiess wants to merge 11 commits into
Conversation
Add a generic RoleBasedLink wrapper that resolves its destination from the current user's role. Use it in the experiments table so a user officer's proposal-id link opens the officer proposal modal, carrying a `from` param so closing the modal returns to the originating page. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a generic RoleBasedLink wrapper that resolves its destination from the current user's role. Use it in the experiments table so a user officer's proposal-id link opens the officer proposal modal, carrying a `from` param so closing the modal returns to the originating page. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
e70b01c to
c8d3b9a
Compare
…ffice-core into SWAP-5403-links
| key: instrument.id, | ||
| label: instrument.name, | ||
| roleRoutes: { | ||
| [UserRole.USER_OFFICER]: `/Instruments?search=${instrument.name}`, |
There was a problem hiding this comment.
suggestion: maybe we could encodeURIComponent the same as callShortCode. This way in case someone has fancy instrument name it still works.
There was a problem hiding this comment.
could you elaborate? I'm not sure I follow
There was a problem hiding this comment.
i mean something like /Instruments?search=${encodeURIComponent(instrument.name)}
does that makes sense?
| key: instrument.id, | ||
| label: instrument.name, | ||
| roleRoutes: { | ||
| [UserRole.USER_OFFICER]: `/Instruments?search=${instrument.name}`, |
There was a problem hiding this comment.
Pull request overview
Adds role-aware deep links from table cells (Experiments and Proposals views) to improve navigation to related entities (proposal modal, PI user page, Calls/Instruments lists, FAP page), while keeping access control aligned with the currently selected role.
Changes:
- Introduces a reusable
RoleBasedLinkcomponent to conditionally render router links based on the active role. - Updates Experiments and Proposals officer tables to render linked values (proposal id, PI, call, instruments, FAPs).
- Extends proposals GraphQL query to include PI
idneeded for People-page navigation.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/frontend/src/utils/fromArrayToCommaSeparatedLinks.tsx | New helper to render comma-separated lists as role-based links. |
| apps/frontend/src/graphql/proposal/getProposalsCore.graphql | Fetches PI id to support People-page links. |
| apps/frontend/src/components/proposal/ProposalTableOfficer.tsx | Adds links for PI/Call/Instruments/FAP and adds “return-to-origin” behavior when closing proposal modal. |
| apps/frontend/src/components/experiment/ExperimentsTable.tsx | Renders Proposal ID as a role-based link into the proposal review modal and carries from for navigation back. |
| apps/frontend/src/components/common/RoleBasedLink.tsx | New role-aware link component combining MUI Link styling with react-router navigation. |
| export function fromArrayToCommaSeparatedLinks( | ||
| links: CommaSeparatedLink[] | null | undefined | ||
| ) { | ||
| return ( | ||
| <> | ||
| {links?.map((link, index) => ( | ||
| <React.Fragment key={link.key}> | ||
| {index > 0 && ', '} | ||
| <RoleBasedLink roleRoutes={link.roleRoutes}> | ||
| {link.label} | ||
| </RoleBasedLink> | ||
| </React.Fragment> | ||
| ))} | ||
| </> | ||
| ); | ||
| } |
| roleRoutes: { | ||
| [UserRole.USER_OFFICER]: `/Instruments?search=${instrument.name}`, | ||
| }, |
| if (from) { | ||
| // Return to the page that opened the modal (e.g. Experiments), | ||
| // restoring its filters, instead of staying on /Proposals. | ||
| navigate(decodeURIComponent(from), { replace: true }); | ||
|
|
||
| return; | ||
| } |
| { | ||
| title: 'Proposal ID', | ||
| field: 'proposal.proposalId', | ||
| render: (rowData: Experiment) => ( | ||
| <RoleBasedLink | ||
| roleRoutes={{ | ||
| [UserRole.USER_OFFICER]: `/Proposals?reviewModal=${rowData.proposal.primaryKey}&from=${from}`, | ||
| [UserRole.INSTRUMENT_SCIENTIST]: `/Proposals?reviewModal=${rowData.proposal.primaryKey}&from=${from}`, | ||
| }} | ||
| > | ||
| {rowData.proposal.proposalId} | ||
| </RoleBasedLink> | ||
| ), |
Description
Introduces links to user, proposal, and FAP from the Experiments and Proposals tables.
Motivation and Context
This modification is required to enhance navigation and user experience by allowing users to navigate directly to related pages (user, proposal, FAP) from the Experiments and Proposals tables.
Changes
RoleBasedLinkthat renders links based on user roles.ExperimentsTable.tsx, added links to the proposal ID.ProposalTableOfficer.tsx, added links to Principal Investigator, Call, Instrument, and FAP fields.How Has This Been Tested?
Fixes Jira Issue
https://jira.ess.eu//browse/SWAP-5403
Depends On
Tests included/Docs Updated?