Skip to content

Render the PDF report's row links for an administrator alone#13130

Open
shervElmi wants to merge 13 commits into
developfrom
enhancement/12958-pdf-view-only-links
Open

Render the PDF report's row links for an administrator alone#13130
shervElmi wants to merge 13 commits into
developfrom
enhancement/12958-pdf-view-only-links

Conversation

@shervElmi

@shervElmi shervElmi commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Summary

Addresses issue:

Relevant technical choices

  • shared-react-pdf-components/PDFLink.tsx
    • Renders plain text when href is empty, so a widget passes its URL straight through and never branches. The IB gave each widget that conditional, which repeated the same markup across the report.
  • AudienceTilesWidget/getPDFData.ts and buildPDFAudienceCard.ts
    • The loader passes a link resolver, not a resolved map. Only the card builder reads the top content rows, so only it knows each row's page path.
  • DashboardAllTrafficWidgetGA4/getPDFData.ts, DashboardPageSpeedWidget/getPDFData.ts, and SearchFunnelWidgetGA4/getPDFData.ts
    • Each declares its own params interface instead of importing the shared GetPDFDataParams, so each needed viewOnly to typecheck. A comment marks that the loader doesn't read it.
  • AudienceTilesWidget/PDFYourVisitorGroupsTile.tsx
    • The top content rows use a bottom margin, not a vertical one, to match the design's 6px row gap.

PR Author Checklist

  • My code is tested and passes existing unit tests.
  • My code has an appropriate set of unit tests which all pass.
  • My code is backward-compatible with WordPress 5.2 and PHP 7.4.
  • My code follows the WordPress coding standards.
  • My code has proper inline documentation.
  • I have added a QA Brief on the issue linked above.
  • I have signed the Contributor License Agreement (see https://cla.developers.google.com/).

Do not alter or remove anything below. The following sections will be managed by moderators only.

Code Reviewer Checklist

  • Run the code.
  • Ensure the acceptance criteria are satisfied.
  • Reassess the implementation with the IB.
  • Ensure no unrelated changes are included.
  • Ensure CI checks pass.
  • Check Storybook where applicable.
  • Ensure there is a QA Brief.
  • Ensure there are no unexpected significant changes to file sizes.

Merge Reviewer Checklist

  • Ensure the PR has the correct target branch.
  • Double-check that the PR is okay to be merged.
  • Ensure the corresponding issue has a ZenHub release assigned.
  • Add a changelog message to the issue.

Add a required viewOnly flag to the shared PDF getData params, and
pass the value the orchestrator already reads from useViewOnly into
every widget's getData call. The per-widget commits that follow read
the flag to decide whether to resolve a link.
With an empty href, PDFLink renders its text in the default color with
no annotation. A widget then passes a row's link straight through, and
a view-only export's empty link reads as plain text without the widget
branching on its own.
Resolve the Search Console report link for each query only when the
export is not view-only, and render the query through PDFLink. A
view-only export leaves the link empty, so the query reads as plain
text, matching the dashboard widget.
Link each title to the same All pages and screens report the dashboard
widget opens for an administrator. The loader built the entity
dashboard URL before. Keep the public URL on the URL line, and resolve
neither link on a view-only export.
Build the Analytics report link for each page only when the export is
not view-only, and render the title through PDFLink. A view-only export
leaves the link empty, so the title reads as plain text.
Pass the loader a link resolver, which the card builder calls for each
top content page path, since only the builder reads those rows. The
resolver returns an empty link on a view-only export, so the tile
renders the title as plain text.
These widgets render no row links, so their loaders take the new flag
and leave it unread. The three that declare their own params interface
add the field there. Each holds a comment saying the loader ignores it,
so the shared pipeline typechecks.
@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown

🤖 This comment is automatically updated by CI workflows. Each section is managed independently.

🎭 Playwright reports for a71e4c0:

📚 Storybook for a71e4c0:

📦 Build files for a71e4c0:

@shervElmi
shervElmi marked this pull request as ready for review July 16, 2026 17:21

@zutigrm zutigrm left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks @shervElmi Nice work.

There are just few things we should polish and fix, before it is ready.

We also need to align with AC point "The links present in a generated PDF match those the same user sees on their dashboard." which current implementation misses in one case for view only users:

Image

You can see above, view only users can click top content pages, and see them in entity dashboard, but in PDF they can't which is not matching the dashboard behaviour hence mismatch with the pointed AC. This is the PDF:

Image

There is also a conflict with develop we should resolve

* @since n.e.x.t Added the `viewContext` parameter.
*
* @param viewContext The dashboard view context to render under.
* @return The render result for the orchestrator.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Param and return should include {type}, you can check this for example:

/**
* Sends a tracking event to Analytics via gtag.
*
* @since 1.18.0
*
* @param {string} action Event action / event name.
* @param {Record< string, unknown >|null} metadata Additional event metadata to send, or `null`.
* @return {void}
*/

@shervElmi shervElmi Jul 21, 2026

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.

Thanks @zutigrm! I don't think we add parameter types to JSDoc in TypeScript files.

CC @eugene-manuilov @tofumatt

@zutigrm zutigrm Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We still include them in TypeScript files as well, as stated in our doc:

In TypeScript files, define an `interface` (or `type`) for the shape instead of a `\@typedef`, and annotate the function with it — see `docs/context/js/component-conventions.md`. The JSDoc block stays (description, `\@since`, `\@param`, `\@return`), and `\@param`/`\@return` still carry their `{type}` annotations as in JS — only `\@typedef`/`\@property` are dropped in favour of the TypeScript type.

The JSDoc block stays (description, \@since, \@param, \@return), and \@param/\@return still carry their {type} annotations as in JS — only \@typedef/\@property are dropped in favour of the TypeScript type.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

For clarification: the TS Types should be the “Source of truth” and the ones we’ll use going forward.

Eventually we’ll remove this ESLint rule from TypeScript files, but I just haven’t got around to it yet. 😅

For now: yes, we tend to "redundantly" document them twice, but treat the TS types as the main place for documentation, etc. 🙂

Comment thread assets/js/googlesitekit/widgets/types.ts Outdated
Updated the PDF data loader interfaces to use a unified parameter
structure, improving clarity and maintainability. Introduced
`PDFDataLoaderParams` and adjusted related functions accordingly.
New tests added for the `getAllPagesReportURL` utility to ensure
correct functionality.

@zutigrm zutigrm left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks @shervElmi , looks good now. Just one more merge conflict to be resolved, and left you one reply

* @since n.e.x.t Added the `viewContext` parameter.
*
* @param viewContext The dashboard view context to render under.
* @return The render result for the orchestrator.

@zutigrm zutigrm Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We still include them in TypeScript files as well, as stated in our doc:

In TypeScript files, define an `interface` (or `type`) for the shape instead of a `\@typedef`, and annotate the function with it — see `docs/context/js/component-conventions.md`. The JSDoc block stays (description, `\@since`, `\@param`, `\@return`), and `\@param`/`\@return` still carry their `{type}` annotations as in JS — only `\@typedef`/`\@property` are dropped in favour of the TypeScript type.

The JSDoc block stays (description, \@since, \@param, \@return), and \@param/\@return still carry their {type} annotations as in JS — only \@typedef/\@property are dropped in favour of the TypeScript type.

Updated parameter types and return types in various functions to improve
documentation accuracy. This change ensures better understanding of the
codebase for future developers and maintains consistency in JSDoc
formatting.
Updated the parameter types in the getPageLinkMap and getPopularPageLinkMap
functions to use a more concise Pick type for better readability and
maintainability.

@zutigrm zutigrm left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM

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.

3 participants