Skip to content

Improve progress bar with per-step success/failure tracking, marquee animation, and tooltips - #56

Merged
maxi07 merged 20 commits into
mainfrom
copilot/utilize-progress-bar-on-card
Jul 2, 2026
Merged

maxi07 merged 20 commits into
mainfrom
copilot/utilize-progress-bar-on-card

Conversation

Copilot AI commented May 24, 2026 •

Copy link
Copy Markdown
Contributor

Progress bar segments now visually distinguish between completed, in-progress, and pending steps. Current step shows a blue marquee animation, completed steps turn green, and individual failed steps turn red. Each segment has a hover tooltip showing step name and status. Per-step success/failure is determined using ocr_status, file_naming_status, and file_status data.

CSS (dashboard.css)

  • Replace .active class with .completed (green #198754) and .current (animated blue gradient)
  • Add @keyframes marquee for the shimmer effect on the active segment
  • Add ::after pseudo-element tooltip on hover
  • Change .progress-bar-wrapper to overflow: visible so tooltips render above the bar

Backend (main.py, dashboard.py)

  • Add ocr_status and file_naming_status to the SSE payload for live updates
  • Join ocr_jobs and file_naming_jobs tables in the dashboard query to include per-step status in static page data

JS (dashboard.js)

  • New getStepStatuses() helper determines each step's visual state using per-step status data:
    • Step 0 (File Detection): red if file_status is "Invalid File"
    • Step 1 (Reading Metadata): red if generic failure at step ≤1
    • Step 2 (OCR): red if ocr_status indicates failure (FAILED, UNSUPPORTED, DPI_ERROR, INPUT_ERROR, OUTPUT_ERROR)
    • Step 3 (File Naming): red if file_naming_status indicates failure (FAILED, NO_OCR_FILE, NO_PDF_TEXT, NO_SERVER_CONNECTION, etc.)
    • Step 4 (Upload): red if file_status is "Sync Failed"
  • Individual steps can show red even when overall status is "Completed" (e.g., OCR failed but process continued)
  • Deleted files show all segments red
  • Both addPdfCard() and updateProgressBar() use getStepStatuses() for consistent rendering
  • Each segment gets a data-tooltip + aria-label tooltip/status label (e.g. "OCR – Failed", "File Naming – Completed")

Step labels map to the five processing stages: File Detection → Reading Metadata → OCR → File Naming → Upload

Tests (tests/test_homepage.py)

  • Added UI coverage for segmented progress bar rendering to validate per-step class/state and tooltip text for all five stages.
  • Added corner-case scenarios for different failure reasons:
    • Invalid file
    • OCR failure (INPUT_ERROR)
    • File naming failure (NO_SERVER_CONNECTION)
    • Upload failure (Sync Failed)
    • Deleted files (all failed)
    • Completed files with step-level failure (OCR UNSUPPORTED)

Copilot AI linked an issue May 24, 2026 that may be closed by this pull request
- Current step shows blue marquee animation
- Completed steps turn green
- Failed/deleted files show all segments red
- Mouse-over tooltips show step name and status
- Five steps: File Detection, Reading Metadata, OCR, File Naming, Upload

Agent-Logs-Url: https://github.com/maxi07/ScanSync/sessions/bd124723-e8f5-41b8-87b4-706c4b54a319

Co-authored-by: maxi07 <7480270+maxi07@users.noreply.github.com>
Copilot AI changed the title [WIP] Improve progress bar representation on scan cards Improve progress bar with step-aware colors, marquee animation, and tooltips May 24, 2026
Copilot finished work on behalf of maxi07 May 24, 2026 08:59
Copilot AI requested a review from maxi07 May 24, 2026 08:59
@maxi07
maxi07 changed the base branch from main to dev May 24, 2026 21:20
@maxi07

maxi07 commented May 24, 2026

Copy link
Copy Markdown
Owner

@copilot the web interface actually needs to reflect the success of each individual failure. meaning, we need to read from js variables such as ocr_status from pdfdata. This currently only exists for OCR, we will need to send live and static data about the other states if successful or not. Each step needs a "was this step successful".

- Add ocr_status and file_naming_status to SSE payload (main.py)
- Join ocr_jobs and file_naming_jobs in dashboard query for static data
- Add getStepStatuses() to determine individual step success/failure
- Completed steps show green, failed individual steps show red
- Detection/metadata/upload failure derived from file_status
- OCR and file naming failure derived from their specific status fields

Agent-Logs-Url: https://github.com/maxi07/ScanSync/sessions/5266926b-1101-4d90-9c4f-018674b32880

Co-authored-by: maxi07 <7480270+maxi07@users.noreply.github.com>

Copilot AI commented May 24, 2026

Copy link
Copy Markdown
Contributor Author

@copilot the web interface actually needs to reflect the success of each individual failure. meaning, we need to read from js variables such as ocr_status from pdfdata. This currently only exists ...

Implemented per-step success/failure tracking in commit 9b28e15:

Backend changes:

  • main.py: SSE payload now includes ocr_status and file_naming_status from the ProcessItem
  • dashboard.py: Dashboard query joins with ocr_jobs and file_naming_jobs tables to include per-step status in static page data

Frontend changes:

  • New getStepStatuses() function determines each step's visual state:
    • Step 0 (File Detection): fails red if file_status is "Invalid File"
    • Step 1 (Reading Metadata): fails red if generic "Failed" at step ≤1
    • Step 2 (OCR): uses ocr_status — shows red for FAILED, UNSUPPORTED, DPI_ERROR, INPUT_ERROR, OUTPUT_ERROR
    • Step 3 (File Naming): uses file_naming_status — shows red for FAILED, NO_OCR_FILE, NO_PDF_TEXT, NO_SERVER_CONNECTION, MODEL_NOT_FOUND, etc.
    • Step 4 (Upload): fails red if file_status is "Sync Failed"
  • Individual steps can show red even when overall status is "Completed" (e.g., OCR failed but process continued)
  • Deleted files show all segments red

Copilot AI changed the title Improve progress bar with step-aware colors, marquee animation, and tooltips Improve progress bar with per-step success/failure tracking, marquee animation, and tooltips May 24, 2026
Copilot finished work on behalf of maxi07 May 24, 2026 21:34
@maxi07
maxi07 requested a review from Copilot May 24, 2026 21:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances the web dashboard’s segmented progress bar to reflect per-step outcomes (completed/current/pending/failed), adds an animated “current step” marquee effect, and surfaces step/status tooltips using OCR and file-naming job status data from live SSE updates and the dashboard query.

Changes:

  • Updated dashboard.js to compute per-step visual states (completed/current/pending/failed) using file_status, ocr_status, and file_naming_status, and to apply new segment classes and tooltips.
  • Updated dashboard.css to add .completed (green) and .current (animated gradient) styling plus hover tooltip rendering.
  • Updated the dashboard backend to include ocr_status / file_naming_status in both initial page data (SQL joins) and live SSE payloads.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
web_service/src/static/js/dashboard.js Adds per-step status computation and updates progress bar rendering/classes/tooltips for initial cards and SSE updates.
web_service/src/static/css/dashboard.css Adds new segment styles (completed/current animation) and hover tooltip styling; allows overflow for tooltip display.
web_service/src/routes/dashboard.py Extends dashboard query to include latest OCR and file-naming job status values per scanned item.
web_service/src/main.py Adds ocr_status and file_naming_status fields to SSE payloads for live updates.

Comment thread web_service/src/static/js/dashboard.js Outdated
@@ -452,19 +452,28 @@ function addPdfCard(pdfData) {
progressContainer.id = pdfData.id + '_progress_bar';

const progressStep = pdfData.status_progressbar || 1;
Comment thread web_service/src/routes/dashboard.py Outdated
Comment on lines +69 to +73
LEFT JOIN (
SELECT scanneddata_id, ocr_status
FROM ocr_jobs
WHERE id IN (SELECT MAX(id) FROM ocr_jobs GROUP BY scanneddata_id)
) ocr ON d.id = ocr.scanneddata_id
Comment on lines 80 to 94
.progress-segment[title]:hover::after {
content: attr(title);
position: absolute;
bottom: calc(100% + 6px);
left: 50%;
transform: translateX(-50%);
background-color: rgba(0, 0, 0, 0.85);
color: #fff;
padding: 4px 8px;
border-radius: 4px;
font-size: 0.7rem;
white-space: nowrap;
z-index: 10;
pointer-events: none;
}
@maxi07

maxi07 commented Jun 30, 2026

Copy link
Copy Markdown
Owner

@copilot add ui tests that validate the changed from this pr description have actually been implemented. please use the playwright browser to test the new behavior, also making sure that every step is represented correctly. also add corner cases with different failure reasons

Copilot AI commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

@copilot add ui tests that validate the changed from this pr description have actually been implemented. please use the playwright browser to test the new behavior, also making sure that every step is...

Implemented in 38c4276: added UI test coverage in tests/test_homepage.py for the segmented progress bar with per-step assertions (class + tooltip/aria label) across all stages and corner-case failure reasons (Invalid File, OCR INPUT_ERROR, File Naming NO_SERVER_CONNECTION, Sync Failed, Deleted, and Completed with OCR failure).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.

Comment thread tests/test_homepage.py Outdated
Comment on lines +18 to +24
return Array.from(
document.querySelectorAll(`#${pdfData.id}_progress_bar .progress-segment`)
).map((segment) => ({
classes: Array.from(segment.classList),
tooltip: segment.getAttribute('data-tooltip'),
ariaLabel: segment.getAttribute('aria-label'),
}));
Comment thread web_service/src/static/js/dashboard.js Outdated
Comment on lines 454 to 458
const parsedProgressStep = Number(pdfData.status_progressbar);
const progressStep = Number.isFinite(parsedProgressStep) ? parsedProgressStep : 1;
const isDeleted = pdfData.file_status?.toLowerCase().includes("deleted");
const isFailed = pdfData.file_status?.toLowerCase().includes("failed") || isDeleted || pdfData.status_progressbar === -1;
const isCompleted = pdfData.file_status?.toLowerCase().includes("completed");
Comment thread web_service/src/main.py
Comment on lines +96 to +97
ocr_status=item.ocr_status.name if getattr(item, "ocr_status", None) else None,
file_naming_status=item.file_naming_status.name if getattr(item, "file_naming_status", None) else None,
Comment thread web_service/src/static/js/dashboard.js
Comment thread web_service/src/static/js/dashboard.js
Comment thread web_service/src/static/js/dashboard.js Outdated
Comment on lines 651 to 652
segment.classList.remove('active', 'failed', 'completed', 'current');

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (1)

file_naming_service/main.py:93

  • The generic exception handler can raise a new exception when item is None or not a ProcessItem (e.g., if pickle.loads(body) fails). Referencing item.filename (and unconditionally updating file_naming_jobs using item.file_naming_db_id) will crash the callback and prevent the RabbitMQ message from being acked.
    except Exception as e:
        logger.exception(f"Failed processing {item.filename}.")
        execute_query("UPDATE file_naming_jobs SET file_naming_status = ?, error_description = ?, finished = DATETIME('now', 'localtime') WHERE id = ?", (FileNamingStatus.FAILED.name, str(e), item.file_naming_db_id))

Comment thread web_service/src/routes/dashboard.py Outdated
Comment on lines +69 to +73
LEFT JOIN (
SELECT scanneddata_id, ocr_status
FROM ocr_jobs
WHERE id IN (SELECT MAX(id) FROM ocr_jobs GROUP BY scanneddata_id)
) ocr ON d.id = ocr.scanneddata_id
Comment thread web_service/src/routes/dashboard.py Outdated
Comment thread tests/test_ocr_job_tracking.py
Comment thread tests/test_file_naming_status.py
maxi07 and others added 5 commits June 30, 2026 19:29
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Comment on lines 52 to 56
.progress-segment {
flex: 1;
background-color: #dee2e6;
transition: background-color 0.3s;
border-radius: 2px;
Comment on lines 71 to +75
.progress-segment.failed {
background-color: #dc3545; /* Bootstrap-Rot */
background-color: #dc3545;
}

.progress-segment.completed {
background-color: green; /* Bootstrap-Rot */
.progress-segment.pending {
@maxi07

maxi07 commented Jul 1, 2026

Copy link
Copy Markdown
Owner

@copilot resolve the merge conflicts in this pull request

Copilot AI commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

@copilot resolve the merge conflicts in this pull request

Merge conflicts resolved in the merge commit ea891b9. The four conflicting files were resolved as follows:

  • docker-compose.test.yml: kept the file_naming_service volume mount (required by our new tests)
  • ocr_service/main.py: merged both import sets (execute_query + extract_text), adopted dev's result variable name and OCR text-verification logic while keeping the execute_query DB persistence calls
  • web_service/src/main.py: kept file_naming_status in the SSE payload
  • web_service/src/static/js/dashboard.js: kept the full getStepStatuses() / getCurrentStepIndex() implementation; discarded dev's partial getOcrStatusText() stub that would have broken the per-step progress bar

Copilot finished work on behalf of maxi07 July 1, 2026 22:22
@maxi07
maxi07 changed the base branch from dev to main July 1, 2026 22:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 15 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

file_naming_service/main.py:93

  • The generic except Exception handler assumes item is a valid ProcessItem and accesses item.filename / item.file_naming_db_id. If deserialization fails (or any exception happens before item is assigned), this handler will raise a secondary AttributeError, masking the original error and potentially crashing the consumer loop.
    except Exception as e:
        logger.exception(f"Failed processing {item.filename}.")
        execute_query("UPDATE file_naming_jobs SET file_naming_status = ?, error_description = ?, finished = DATETIME('now', 'localtime') WHERE id = ?", (FileNamingStatus.FAILED.name, str(e), item.file_naming_db_id))

Comment thread web_service/src/static/js/dashboard.js
Comment on lines +68 to +73
LEFT JOIN file_naming_jobs fn
ON fn.id = (
SELECT MAX(id)
FROM file_naming_jobs
WHERE scanneddata_id = d.id
)
Comment thread package.json
Comment on lines 10 to 13
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "echo \"Error: no test specified\" && exit 1",
"test:js": "node --test \"tests/js/**/*.test.mjs\""
},
maxi07 and others added 2 commits July 2, 2026 09:47
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@maxi07
maxi07 merged commit 6dfa60e into main Jul 2, 2026
4 checks passed
@maxi07
maxi07 deleted the copilot/utilize-progress-bar-on-card branch July 2, 2026 08:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Utilize progress bar on card better

3 participants