Repository navigation
[Customer Portal][FE][Web] Enhance Update Levels Report Parsing, Bug Fix Display, and PDF Download Experience - #621
Conversation
Add parsing utilities for update descriptions and bug fixes (parseDescriptionSections, parseBugFixes) and use them in both the modal UI and PDF generator. The modal now renders structured sections (General Description, Implementation Details, Impact), formats bug-fix URLs as links, and preserves instructions/security advisories layout. PDF generation was updated to consume the parsed sections and bug-fix list. Also add a download state with a CircularProgress icon and disabled Download button while the PDF is being generated.
Only destructure the setUrlParams setter from useSearchParams in AllUpdatesTab.tsx (replacing `const [urlParams, setUrlParams]` with `const [, setUrlParams]`). This removes an unused variable and avoids linter warnings, clarifying that only the setter is needed.
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 41 minutes and 21 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe pull request refactors update description rendering in the customer portal by introducing structured parsing of description sections and bug fixes, removes an unused variable in search parameter handling, and adds loading state feedback during PDF generation. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
apps/customer-portal/webapp/src/features/updates/utils/updateLevelsReportPdf.ts (2)
75-75: Nit: redundant[Dd]under theiflag.The case-insensitive flag already matches
Dandd, so[Dd]etails?simplifies to[Dd]etails?→Details?. Functionally equivalent; kept for consistency only if intentional.♻️ Proposed simplification
- const headerRe = /(?:^|\n)\s*(General\s+Description|Implementation\s+[Dd]etails?|Impact)\s*:/gi; + const headerRe = /(?:^|\n)\s*(General\s+Description|Implementation\s+Details?|Impact)\s*:/gi;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/customer-portal/webapp/src/features/updates/utils/updateLevelsReportPdf.ts` at line 75, The regex assigned to headerRe redundantly uses a character class `[Dd]` despite the /i flag; update the pattern used in headerRe (const headerRe) to replace `Implementation\s+[Dd]etails?` with `Implementation\s+Details?` so the case-insensitive flag handles casing, keeping the rest of the regex unchanged.
107-121: Consider filtering to safehttp(s)URLs inparseBugFixes.
UpdateLevelsReportModal.tsxpasses these strings straight into<a href={url}>without scheme validation (see related comment on that file). Filtering here would harden every consumer at the source — including the PDF wherebugFixUrls.join("\n")could otherwise displayjavascript:/data:strings as if they were proper URLs.♻️ Proposed change
export function parseBugFixes(raw: string | null | undefined): string[] { if (!raw?.trim()) return []; + const isSafe = (s: string): boolean => { + try { + const { protocol } = new URL(s); + return protocol === "http:" || protocol === "https:"; + } catch { + return false; + } + }; try { const parsed = JSON.parse(raw); if (Array.isArray(parsed)) { return parsed .map((item) => String(item).trim()) - .filter((item) => item && item.toLowerCase() !== "n/a"); + .filter((item) => item && item.toLowerCase() !== "n/a" && isSafe(item)); } } catch { // not JSON } const t = raw.trim(); - return t && t.toLowerCase() !== "n/a" ? [t] : []; + return t && t.toLowerCase() !== "n/a" && isSafe(t) ? [t] : []; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/customer-portal/webapp/src/features/updates/utils/updateLevelsReportPdf.ts` around lines 107 - 121, The parseBugFixes function should exclude non-http(s) schemes to prevent unsafe links; update parseBugFixes to, after parsing and trimming items (and for the single-string fallback), validate each candidate by constructing a URL (or otherwise parsing) and only return items whose protocol is "http:" or "https:" and are non-empty and not "n/a". Apply this filtering both in the Array.isArray(parsed) branch (filter the mapped items) and in the single-value fallback before returning [t], referencing the parseBugFixes function name so consumers like UpdateLevelsReportModal.tsx/PDFs receive only safe http(s) URLs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@apps/customer-portal/webapp/src/features/updates/components/all-updates/UpdateLevelsReportModal.tsx`:
- Around line 89-96: The handler handleDownloadPdf currently sets isDownloading
true then calls generateUpdateLevelsReportPdf inside a setTimeout but never
resets isDownloading if that call throws; wrap the generateUpdateLevelsReportPdf
invocation inside a try/finally (inside the existing setTimeout callback) so
setIsDownloading(false) always runs, keeping the early return when !reportData
and preserving the setIsDownloading(true) timing and useCallback signature;
reference handleDownloadPdf, generateUpdateLevelsReportPdf, setIsDownloading and
useCallback when making the change.
- Around line 61-71: The bug-fix URLs are rendered directly from bugFixUrls
(produced by parseBugFixes) and can contain unsafe schemes like "javascript:";
update the rendering in UpdateLevelsReportModal to validate each url's scheme
(only allow http:// or https://) before rendering an <a> tag: if the scheme is
invalid, render the URL as plain text or skip it. Apply the same guard to the
Update Details rendering where bugFixUrls are used (the block at lines
~353-357). Preferably, also add this scheme check inside parseBugFixes so both
call sites get sanitized URLs by default (use a clear helper name like
isSafeHttpUrl when locating the code).
---
Nitpick comments:
In
`@apps/customer-portal/webapp/src/features/updates/utils/updateLevelsReportPdf.ts`:
- Line 75: The regex assigned to headerRe redundantly uses a character class
`[Dd]` despite the /i flag; update the pattern used in headerRe (const headerRe)
to replace `Implementation\s+[Dd]etails?` with `Implementation\s+Details?` so
the case-insensitive flag handles casing, keeping the rest of the regex
unchanged.
- Around line 107-121: The parseBugFixes function should exclude non-http(s)
schemes to prevent unsafe links; update parseBugFixes to, after parsing and
trimming items (and for the single-string fallback), validate each candidate by
constructing a URL (or otherwise parsing) and only return items whose protocol
is "http:" or "https:" and are non-empty and not "n/a". Apply this filtering
both in the Array.isArray(parsed) branch (filter the mapped items) and in the
single-value fallback before returning [t], referencing the parseBugFixes
function name so consumers like UpdateLevelsReportModal.tsx/PDFs receive only
safe http(s) URLs.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 2435d30a-fde3-4e65-80fd-095eb39117c2
📒 Files selected for processing (3)
apps/customer-portal/webapp/src/features/updates/components/all-updates/AllUpdatesTab.tsxapps/customer-portal/webapp/src/features/updates/components/all-updates/UpdateLevelsReportModal.tsxapps/customer-portal/webapp/src/features/updates/utils/updateLevelsReportPdf.ts
Add URL safety checks and improve error handling for update-levels report generation. Introduces isSafeHttpUrl() and updates parseBugFixes to only include http(s) links, and tweaks description header regex. In the UI, unsafe URLs are no longer rendered as <a> anchors (shown as plain text instead), and the PDF generation call is wrapped in a try/finally so the downloading state is always cleared. Changes span the report PDF util and the UpdateLevelsReportModal component to prevent unsafe schemes and ensure the spinner is reset on errors.
Description
This pull request enhances the
UpdateLevelsReportModalin the customer portal by improving how update descriptions and bug fixes are parsed and displayed, both in the UI and in generated PDF reports. The changes introduce structured parsing of description fields, better handling and display of bug fix URLs, and a more user-friendly download experience.Improvements to parsing and displaying update details:
parseDescriptionSectionsandparseBugFixesutilities to extract and structure description sections (General Description, Implementation Details, Impact) and to robustly parse bug fix URLs from both JSON arrays and plain strings.User experience improvements:
Code maintenance:
Summary by CodeRabbit