diff --git a/content.js b/content.js index 42dfbf6..68d8057 100644 --- a/content.js +++ b/content.js @@ -244,6 +244,11 @@ function createApplicantsIndexHtml() { min-height: 100vh; } + button, + input { + font: inherit; + } + .layout { display: flex; min-height: 100vh; @@ -281,6 +286,25 @@ function createApplicantsIndexHtml() { color: #475569; } + .controls { + display: grid; + gap: 0.75rem; + margin-bottom: 1rem; + padding: 1rem; + border: 1px solid #e2e8f0; + border-radius: 0.75rem; + background: #f8fafc; + } + + .controls p { + margin: 0; + color: #475569; + } + + .controls input[type="file"] { + width: 100%; + } + .viewer { flex: 1; width: 100%; @@ -288,16 +312,6 @@ function createApplicantsIndexHtml() { background: #e2e8f0; } - .placeholder { - display: flex; - align-items: center; - justify-content: center; - height: 100%; - padding: 2rem; - color: #475569; - text-align: center; - } - .applicant-card { margin-bottom: 1rem; padding: 1rem; @@ -343,6 +357,15 @@ function createApplicantsIndexHtml() { text-decoration: underline; } + .viewer-download { + color: #0f6cbd; + text-decoration: none; + } + + .viewer-download:hover { + text-decoration: underline; + } + .file-list-title { margin: 1rem 0 0.5rem; font-size: 0.95rem; @@ -378,18 +401,33 @@ function createApplicantsIndexHtml() {

Applicant archive

-

Select a file on the left to preview it here.

+

Select the ZIP file, then choose a file on the left to preview it here.

+
+ ` } +async function getArchiveViewerJsZipSource() { + const candidates = [ + "lib/jszip.min.js", + "lib/jszip.js" + ] + + for (const candidate of candidates) { + const response = await fetch(chrome.runtime.getURL(candidate)) + + if (response.ok) { + return response.text() + } + } + + throw new Error("Failed to load archive viewer dependency") +} + function downloadBlob(blob, fileName) { const url = URL.createObjectURL(blob) const link = document.createElement("a") @@ -650,7 +781,7 @@ function createProgressDialog() { dialog.classList.add("ripper-progress-dialog") title.textContent = "EPAS Ripper" status.classList.add("ripper-progress-status") - status.textContent = "Retrieving applicants list (will take some time)..." + status.textContent = "Retrieving applicants list (will take several minutes)..." list.classList.add("ripper-progress-list") summary.classList.add("ripper-progress-summary") elapsed.classList.add("ripper-progress-elapsed") @@ -759,7 +890,7 @@ function rip(event) { btn.disabled = true; getApplicants() .then(async ({ aid, applicants, token }) => { - progressDialog.setStatus("Downloading applicant files...") + progressDialog.setStatus("Downloading applicant files (will take a lot of time)...") applicants.forEach((applicant) => { progressDialog.initializeApplicant(applicant) }) @@ -776,7 +907,8 @@ function rip(event) { } })) - progressDialog.setStatus("Creating zip archive...") + console.log("Preparing zip archive...") + progressDialog.setStatus("Preparing zip archive...") const zip = new JSZip() const successfulApplicants = [] @@ -798,9 +930,20 @@ function rip(event) { }) }) + console.log("Creating applicants.csv") zip.file("applicants.csv", createApplicantsCsv(successfulApplicants)) + + console.log("Creating index.html") zip.file("index.html", createApplicantsIndexHtml()) + + console.log("Adding viewer Javascript to archive") + zip.file("jszip.min.js", await getArchiveViewerJsZipSource()) + + + console.log("Generating zip archive...") const zipBlob = await zip.generateAsync({ type: "blob" }) + + console.log("Zip archive is ready.") progressDialog.setStatus("Download ready.") downloadBlob(zipBlob, `applications_${aid}.zip`) btn.textContent = "done" @@ -822,7 +965,7 @@ function rip(event) { function install() { const titleTag = document.querySelector("scrm-module-title") - if (titleTag != null) { + if (titleTag != null && window.location.hash.startsWith("#/job-procedures/record")) { if (titleTag.querySelector(".ripper-btn") != null) { return } diff --git a/manifest.json b/manifest.json index 10b484e..dd98771 100644 --- a/manifest.json +++ b/manifest.json @@ -19,5 +19,16 @@ "style.css" ] } + ], + "web_accessible_resources": [ + { + "resources": [ + "lib/jszip.js", + "lib/jszip.min.js" + ], + "matches": [ + "https://personal.uni-graz.at/*" + ] + } ] }