Skip to content

feat: links to user, proposal, FAP from Experiments and Proposals table#1593

Open
shivoomiess wants to merge 11 commits into
developfrom
SWAP-5403-links
Open

feat: links to user, proposal, FAP from Experiments and Proposals table#1593
shivoomiess wants to merge 11 commits into
developfrom
SWAP-5403-links

Conversation

@shivoomiess

@shivoomiess shivoomiess commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

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

  • Added a new component RoleBasedLink that renders links based on user roles.
  • In ExperimentsTable.tsx, added links to the proposal ID.
  • In 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?

  • I have added tests to cover my changes.
  • All relevant doc has been updated

shivoomiess and others added 4 commits June 17, 2026 11:27
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>
@shivoomiess shivoomiess requested a review from a team as a code owner June 22, 2026 08:18
@shivoomiess shivoomiess requested review from ellen-wright, jekabs-karklins and yoganandaness and removed request for a team and ellen-wright June 22, 2026 08:18
shivoomiess and others added 4 commits June 22, 2026 10:19
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>
key: instrument.id,
label: instrument.name,
roleRoutes: {
[UserRole.USER_OFFICER]: `/Instruments?search=${instrument.name}`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: maybe we could encodeURIComponent the same as callShortCode. This way in case someone has fancy instrument name it still works.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you elaborate? I'm not sure I follow

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i mean something like /Instruments?search=${encodeURIComponent(instrument.name)}
does that makes sense?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shivoomiess shivoomiess enabled auto-merge (squash) June 30, 2026 08:06
@shivoomiess shivoomiess disabled auto-merge June 30, 2026 08:07
@shivoomiess shivoomiess enabled auto-merge (squash) June 30, 2026 08:52
@shivoomiess shivoomiess disabled auto-merge June 30, 2026 08:52
@shivoomiess shivoomiess enabled auto-merge (squash) June 30, 2026 08:53
key: instrument.id,
label: instrument.name,
roleRoutes: {
[UserRole.USER_OFFICER]: `/Instruments?search=${instrument.name}`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 RoleBasedLink component 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 id needed 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.

Comment on lines +13 to +28
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>
))}
</>
);
}
Comment on lines +233 to +235
roleRoutes: {
[UserRole.USER_OFFICER]: `/Instruments?search=${instrument.name}`,
},
Comment on lines +1266 to +1272
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;
}
Comment on lines 176 to +188
{
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>
),
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.

4 participants