generated from coulomb/repo-seed
UI improvements: filename display, local tag, auto-refresh, password toggle
- Show only filename in list with full path as tooltip on hover - Add "local" tag for documents not yet uploaded to server - Auto-refresh after user interactions (upload/order) with Fibonacci-like sequence: 10, 20, 30, 50, 80, 130, 210 seconds - Fix password toggle button (add pointer-events: none to SVG icons) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -234,6 +234,7 @@ body {
|
|||||||
|
|
||||||
.password-toggle svg {
|
.password-toggle svg {
|
||||||
display: block;
|
display: block;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Buttons */
|
/* Buttons */
|
||||||
@@ -464,6 +465,21 @@ body {
|
|||||||
color: var(--binect-blue-deep);
|
color: var(--binect-blue-deep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Local tag */
|
||||||
|
.tag-local {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 6px;
|
||||||
|
padding: 1px 5px;
|
||||||
|
font-size: 9px;
|
||||||
|
font-weight: 500;
|
||||||
|
text-transform: uppercase;
|
||||||
|
background: var(--light-bg);
|
||||||
|
color: var(--text-light);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 3px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
/* Recipient address */
|
/* Recipient address */
|
||||||
.pdf-item-recipient {
|
.pdf-item-recipient {
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
|
|||||||
@@ -40,6 +40,11 @@ let pdfQueue: DocumentProxy[] = [];
|
|||||||
let currentCredentials: { username: string; password: string } | null = null;
|
let currentCredentials: { username: string; password: string } | null = null;
|
||||||
let showingArchive = false; // false = live view, true = archive view
|
let showingArchive = false; // false = live view, true = archive view
|
||||||
|
|
||||||
|
// Auto-refresh state
|
||||||
|
const REFRESH_INTERVALS = [10, 20, 30, 50, 80, 130, 210]; // seconds
|
||||||
|
let refreshTimeouts: ReturnType<typeof setTimeout>[] = [];
|
||||||
|
let refreshIndex = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize popup
|
* Initialize popup
|
||||||
*/
|
*/
|
||||||
@@ -110,6 +115,54 @@ async function handleToggleArchiveView() {
|
|||||||
await loadPDFQueue();
|
await loadPDFQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start auto-refresh sequence after user interaction
|
||||||
|
*/
|
||||||
|
function startAutoRefresh() {
|
||||||
|
// Clear any existing refresh timeouts
|
||||||
|
cancelAutoRefresh();
|
||||||
|
refreshIndex = 0;
|
||||||
|
scheduleNextRefresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedule the next refresh in the sequence
|
||||||
|
*/
|
||||||
|
function scheduleNextRefresh() {
|
||||||
|
if (refreshIndex >= REFRESH_INTERVALS.length) {
|
||||||
|
return; // Sequence complete
|
||||||
|
}
|
||||||
|
|
||||||
|
const delay = REFRESH_INTERVALS[refreshIndex] * 1000;
|
||||||
|
const timeout = setTimeout(async () => {
|
||||||
|
console.log(`[Popup] Auto-refresh #${refreshIndex + 1} after ${REFRESH_INTERVALS[refreshIndex]}s`);
|
||||||
|
await handleRefreshAll();
|
||||||
|
refreshIndex++;
|
||||||
|
scheduleNextRefresh();
|
||||||
|
}, delay);
|
||||||
|
|
||||||
|
refreshTimeouts.push(timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel all pending auto-refresh timeouts
|
||||||
|
*/
|
||||||
|
function cancelAutoRefresh() {
|
||||||
|
for (const timeout of refreshTimeouts) {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
}
|
||||||
|
refreshTimeouts = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract just the filename from a full path
|
||||||
|
*/
|
||||||
|
function extractFilename(fullPath: string): string {
|
||||||
|
// Handle both forward and back slashes
|
||||||
|
const parts = fullPath.split(/[/\\]/);
|
||||||
|
return parts[parts.length - 1] || fullPath;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle password visibility toggle
|
* Handle password visibility toggle
|
||||||
*/
|
*/
|
||||||
@@ -364,6 +417,8 @@ function renderPDFItem(pdf: DocumentProxy, section: 'pending' | 'basket' | 'prod
|
|||||||
const statusClass = getStatusClass(pdf.binectStatus);
|
const statusClass = getStatusClass(pdf.binectStatus);
|
||||||
const statusText = getStatusText(pdf);
|
const statusText = getStatusText(pdf);
|
||||||
const priceText = pdf.price ? `${(pdf.price / 100).toFixed(2)} €` : '';
|
const priceText = pdf.price ? `${(pdf.price / 100).toFixed(2)} €` : '';
|
||||||
|
const displayFilename = extractFilename(pdf.filename);
|
||||||
|
const isLocalOnly = !pdf.binectDocumentId;
|
||||||
|
|
||||||
let actionsHtml = '';
|
let actionsHtml = '';
|
||||||
|
|
||||||
@@ -407,7 +462,10 @@ function renderPDFItem(pdf: DocumentProxy, section: 'pending' | 'basket' | 'prod
|
|||||||
<div class="pdf-list-item ${statusClass}" data-id="${escapeHtml(pdf.id)}">
|
<div class="pdf-list-item ${statusClass}" data-id="${escapeHtml(pdf.id)}">
|
||||||
<div class="pdf-item-icon">${getStatusIcon(pdf.binectStatus)}</div>
|
<div class="pdf-item-icon">${getStatusIcon(pdf.binectStatus)}</div>
|
||||||
<div class="pdf-item-details">
|
<div class="pdf-item-details">
|
||||||
<div class="pdf-item-filename" title="${escapeHtml(pdf.filename)}">${escapeHtml(pdf.filename)}</div>
|
<div class="pdf-item-filename" title="${escapeHtml(pdf.filename)}">
|
||||||
|
${escapeHtml(displayFilename)}
|
||||||
|
${isLocalOnly ? '<span class="tag-local">local</span>' : ''}
|
||||||
|
</div>
|
||||||
<div class="pdf-item-meta">
|
<div class="pdf-item-meta">
|
||||||
${formatFileSize(pdf.size)} · ${escapeHtml(pdf.sourceDomain)}
|
${formatFileSize(pdf.size)} · ${escapeHtml(pdf.sourceDomain)}
|
||||||
${priceText ? ` · <span class="pdf-price">${priceText}</span>` : ''}
|
${priceText ? ` · <span class="pdf-price">${priceText}</span>` : ''}
|
||||||
@@ -626,6 +684,9 @@ async function handleSendPDF(id: string) {
|
|||||||
|
|
||||||
showStatus(`Uploaded! Ready to order (${(pdf.price || 0) / 100} €)`, 'success');
|
showStatus(`Uploaded! Ready to order (${(pdf.price || 0) / 100} €)`, 'success');
|
||||||
|
|
||||||
|
// Start auto-refresh sequence
|
||||||
|
startAutoRefresh();
|
||||||
|
|
||||||
// Hide status after 3 seconds
|
// Hide status after 3 seconds
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
hideStatus();
|
hideStatus();
|
||||||
@@ -729,6 +790,9 @@ async function handleOrderPDF(id: string) {
|
|||||||
|
|
||||||
showStatus('Order placed! Document is in production.', 'success');
|
showStatus('Order placed! Document is in production.', 'success');
|
||||||
|
|
||||||
|
// Start auto-refresh sequence
|
||||||
|
startAutoRefresh();
|
||||||
|
|
||||||
// Hide status after 3 seconds
|
// Hide status after 3 seconds
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
hideStatus();
|
hideStatus();
|
||||||
|
|||||||
Reference in New Issue
Block a user