-
-
Notifications
You must be signed in to change notification settings - Fork 29
fix(acms): Updates logic to support PDF uploads from new modal #423
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
When a user clicks a document link on the ACMS docket page, ACMS opens a download confirmation modal. The modal does not render the docket entry ID or document name in its HTML, making it impossible to determine which docket entry was clicked from the DOM alone. This commit adds getDocumentDataFromDownloadModal, which injects a script into the page context to access the DownloadConfirmation instance via window.showDocPageInitializer.modalManager.currentComponent and extracts the docketEntryId and docketEntryDocuments. The data is stored in sessionStorage as a bridge between the page context and the extension's content script.
Refactor handleAcmsDownloadPage to support intercepting PDF downloads from the ACMS download confirmation modal and sending them to the RECAP archive. This refactor breaks the code into focused helper methods: - `isDownloadConfirmationModal`: checks if the modal is a billable download page - `resolveDocumentData`: centralizes logic for looking up the docket entry and specific document from sessionStorage - `replaceAcceptChargesButton`: swaps the default button with one that intercepts the download so we can fetch the PDF as a blob for RECAP upload - `startUploadProcess`: fetches the PDF via the merge API and hands the blob to handleDocFormResponse for upload. - `insertRecapBannerIfAvailable`: queries the RECAP archive and displays a centered download banner if a copy exists
fd64738 to
9f162ec
Compare
albertisfu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @ERosendo this looks good. I only found a potential issue and some code suggestions.
| (entry) => entry.docketEntryId == downloadData.docketEntryId | ||
| ); | ||
|
|
||
| if (!docketEntryData.docketEntryDocuments.length) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible for docketEntryData and docketEntryDocuments to be null? In that case, the .length condition would fail.
| if (!docketEntryData.docketEntryDocuments.length) { | |
| if (!docketEntryData?.docketEntryDocuments?.length) { |
| // For entries with multiple attachments, match on the specific document | ||
| // that was clicked. For single-document entries, use the only document. | ||
| let documentData; | ||
| if (docketEntryData.docketEntryDocuments.length > 1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar suggestion:
| if (docketEntryData.docketEntryDocuments.length > 1) { | |
| if (docketEntryData?.docketEntryDocuments?.length > 1) { |
| return { docketEntryData, documentData }; | ||
| }; | ||
|
|
||
| insertRecapBannerIfAvailable = async (docketEntryData, documentData) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing const?
| insertRecapBannerIfAvailable = async (docketEntryData, documentData) => { | |
| const insertRecapBannerIfAvailable = async (docketEntryData, documentData) => { |
| (obj) => obj.acms_document_guid == documentData.docketDocumentDetailsId | ||
| ); | ||
| } else { | ||
| result = recapLinks.results[0]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed an issue that occurs under the following conditions:
- The entry contains attachments.
- One of the attachments is available.
In that case, the RECAP banner on the download confirmation page is shown for both documents, but it points to the same available document.
I think the problem is on this line.
If only one document is available but there are multiple documents in the entry, the same document banner is injected into all of them. We may need to verify that the document returned is the same one being displayed on the download confirmation page.
|
|
||
| // Insert the banner inside the centered wrapper | ||
| insertAvailableDocBanner(result.filepath_local, wrapper); | ||
| };; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| };; | |
| }; |
| (entry) => entry.docketEntryId == downloadData.docketEntryId | ||
| ); | ||
|
|
||
| if (!docketEntryData.docketEntryDocuments.length) return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if (!docketEntryData.docketEntryDocuments.length) return; | |
| if (!docketEntryData?.docketEntryDocuments?.length) return; |
| let mainDiv = modal.querySelector('.modal-body'); | ||
| mainDiv.innerHTML = ''; | ||
| loadingTextMessage = APPELLATE.createsLoadingMessage(downloadData); | ||
| loadingTextMessage = APPELLATE.createsLoadingMessage(caseNumber); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing var defintion:
| loadingTextMessage = APPELLATE.createsLoadingMessage(caseNumber); | |
| let loadingTextMessage = APPELLATE.createsLoadingMessage(caseNumber); |
|
|
||
| newButton.addEventListener( | ||
| 'click', | ||
| startUploadProcess.bind(this, modal, docketEntryData, documentData) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are passing parameters to startUploadProcess, but the method does not receive them. They appear to be unused.
| 'recapDownloadDocumentData', | ||
| JSON.stringify({ | ||
| docketEntryId: null, | ||
| documentName: null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn’t find documentName being used anywhere else. Should it be?
| documentName: null, | |
| docketEntryDocuments: null, |
What does this PR do?
Adds support to intercept PDF downloads from the new ACMS download confirmation modal and upload them to the RECAP Archive.
The new version of ACMS renders a download confirmation modal when a user clicks a document link on the docket page. The modal does not include the docket entry ID or document name in its HTML, so there’s no way to tell which document was clicked using the DOM alone.
On top of that, the modal always displays "Document 1" regardless of which docket entry is actually selected. If the extension relied on parsing this HTML to identify the document, it would incorrectly associate all downloads with docket entry 1, mixing up PDFs from different entries and causing data integrity issues (see freelawproject/recap#401 (comment))
To solve this, this PR introduces a background script function (
getDocumentDataFromDownloadModal) that injects a script into the page context to access theDownloadConfirmationinstance viawindow.showDocPageInitializer.modalManager.currentComponentand extracts thedocketEntryIdanddocketEntryDocuments. The data is stored in sessionStorage as a bridge between the page context and the extension's content script.Changes
getDocumentDataFromDownloadModal()to extract document data from the page context via script injectionhandleAcmsDownloadPageinto focused helper methods:isDownloadConfirmationModal: checks if the modal is a billable download pageresolveDocumentData: consolidates duplicated logic for looking up the docket entry and document from sessionStoragereplaceAcceptChargesButton: swaps the default button with one that intercepts the download for RECAP upload (the original PDF URL is one-time-use)startUploadProcess: fetches the PDF via the merge API and hands the blob tohandleDocFormResponsefor uploadinsertRecapBannerIfAvailable: queries the RECAP archive and displays a centered download banner if a cached copy exists