diff --git a/src/popup/popup.css b/src/popup/popup.css
index 083c9ff..6f0c39e 100644
--- a/src/popup/popup.css
+++ b/src/popup/popup.css
@@ -93,6 +93,30 @@ body {
outline-offset: 2px;
}
+.icon-btn svg {
+ display: block;
+}
+
+.icon-btn.refreshing svg {
+ animation: spin 1s linear infinite;
+}
+
+@keyframes spin {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+/* Header actions */
+.header-actions {
+ display: flex;
+ gap: var(--spacing-sm);
+ align-items: center;
+}
+
/* Views */
.view {
flex: 1;
diff --git a/src/popup/popup.html b/src/popup/popup.html
index 84ffd17..e20321c 100644
--- a/src/popup/popup.html
+++ b/src/popup/popup.html
@@ -10,7 +10,16 @@
diff --git a/src/popup/popup.ts b/src/popup/popup.ts
index a7adbf3..0fa30c5 100644
--- a/src/popup/popup.ts
+++ b/src/popup/popup.ts
@@ -25,6 +25,7 @@ const loginBtn = document.getElementById('loginBtn') as HTMLButtonElement;
const authError = document.getElementById('authError')!;
const logoutBtn = document.getElementById('logoutBtn')!;
+const refreshBtn = document.getElementById('refreshBtn')!;
const helpBtn = document.getElementById('helpBtn')!;
const togglePasswordBtn = document.getElementById('togglePassword') as HTMLButtonElement;
const eyeIcon = document.getElementById('eyeIcon')!;
@@ -75,6 +76,7 @@ async function init() {
function setupEventListeners() {
loginForm.addEventListener('submit', handleLogin);
logoutBtn.addEventListener('click', handleLogout);
+ refreshBtn.addEventListener('click', handleRefreshAll);
helpBtn.addEventListener('click', handleHelp);
togglePasswordBtn.addEventListener('click', handleTogglePassword);
}
@@ -336,9 +338,8 @@ function renderPDFItem(pdf: PDFQueueEntry, section: 'pending' | 'basket' | 'prod
`;
break;
case 'production':
- actionsHtml = `
-
- `;
+ // No individual actions - use global refresh button in header
+ actionsHtml = '';
break;
case 'completed':
actionsHtml = `
@@ -386,14 +387,6 @@ function setupPDFListEventListeners() {
});
});
- // Refresh buttons
- pdfList.querySelectorAll('.btn-refresh-item').forEach(btn => {
- btn.addEventListener('click', (e) => {
- const id = (e.target as HTMLElement).dataset.id;
- if (id) handleRefreshStatus(id);
- });
- });
-
// Dismiss/Cancel/Remove buttons
pdfList.querySelectorAll('.btn-dismiss').forEach(btn => {
btn.addEventListener('click', (e) => {
@@ -685,6 +678,53 @@ async function handleOrderPDF(id: string) {
}
}
+/**
+ * Handle refresh all documents that have been uploaded to server
+ */
+async function handleRefreshAll() {
+ if (!currentCredentials) {
+ return;
+ }
+
+ // Find all documents that have been uploaded and are still visible
+ const uploadedDocs = pdfQueue.filter(p =>
+ p.binectDocumentId &&
+ (p.status === 'in_basket' || p.status === 'in_production')
+ );
+
+ if (uploadedDocs.length === 0) {
+ showStatus('No documents to refresh', 'success');
+ setTimeout(() => hideStatus(), 2000);
+ return;
+ }
+
+ // Disable refresh button during refresh
+ refreshBtn.classList.add('refreshing');
+ showStatus(`Refreshing ${uploadedDocs.length} document${uploadedDocs.length > 1 ? 's' : ''}...`, 'uploading');
+
+ let successCount = 0;
+ let errorCount = 0;
+
+ for (const pdf of uploadedDocs) {
+ try {
+ await handleRefreshStatus(pdf.id);
+ successCount++;
+ } catch {
+ errorCount++;
+ }
+ }
+
+ refreshBtn.classList.remove('refreshing');
+
+ if (errorCount === 0) {
+ showStatus(`Refreshed ${successCount} document${successCount > 1 ? 's' : ''}`, 'success');
+ } else {
+ showStatus(`Refreshed ${successCount}, ${errorCount} failed`, 'error');
+ }
+
+ setTimeout(() => hideStatus(), 3000);
+}
+
/**
* Handle refresh document status
*/