diff --git a/cantaloupe_sync.py b/cantaloupe_sync.py
index f118777..f211203 100644
--- a/cantaloupe_sync.py
+++ b/cantaloupe_sync.py
@@ -386,7 +386,7 @@ async def run_sync(
file_path: Optional[str] = Query(None, description="Server-side path to Excel file"),
):
"""
- Run a full Cantaloupe sync from an Excel file.
+ Import an Excel file into a staged batch for review.
Accepts either:
- An uploaded Excel file (multipart form)
@@ -416,42 +416,10 @@ async def run_sync(
excel_path = str(p)
display_path = file_path
else:
- # Try subprocess call to cantaloupe export
- try:
- import subprocess
- import sys
- cantaloupe_dir = os.path.expanduser("~/projects/cantaloupe-downloader")
- result = subprocess.run(
- [sys.executable, "-m", "cantaloupe", "export", "--scheduled"],
- capture_output=True, text=True, timeout=120,
- cwd=cantaloupe_dir,
- )
- if result.returncode != 0:
- raise HTTPException(
- status_code=400,
- detail=f"Cantaloupe export failed: {result.stderr[:500]}"
- )
- # Parse output to find the exported file path
- for line in result.stdout.splitlines() + result.stderr.splitlines():
- line = line.strip()
- if line and Path(line).exists() and line.endswith((".xlsx", ".xls")):
- excel_path = line
- display_path = line
- break
- else:
- raise HTTPException(
- status_code=400,
- detail="Cantaloupe export ran but produced no recognizable file path. Provide file upload or file_path parameter."
- )
- except FileNotFoundError:
- raise HTTPException(
- status_code=400,
- detail="No file provided and cantaloupe module not found. Upload an Excel file or provide file_path."
- )
- except HTTPException:
- raise
- except Exception as e:
- raise HTTPException(status_code=500, detail=f"Cantaloupe export error: {e}")
+ raise HTTPException(
+ status_code=400,
+ detail="No file provided. Upload an Excel file to import asset data."
+ )
conn = _get_db()
try:
diff --git a/static/index.html b/static/index.html
index 30d39e8..5717b30 100644
--- a/static/index.html
+++ b/static/index.html
@@ -514,30 +514,51 @@
.hidden { display: none !important; }
.mono { font-family: 'Courier New', monospace; font-size: 12px; }
- /* Responsive: collapse sidebar on narrow screens */
+ /* ═══════════════════════════════════════════════════════════════════════
+ HAMBURGER BUTTON & SIDEBAR OVERLAY (mobile)
+ ═══════════════════════════════════════════════════════════════════════ */
+ .hamburger {
+ display: none;
+ background: none; border: none; color: var(--text); font-size: 24px;
+ cursor: pointer; padding: 6px; margin-right: 10px;
+ line-height: 1; flex-shrink: 0;
+ }
+ .hamburger:hover { color: var(--accent2); }
+ .sidebar-overlay {
+ display: none;
+ position: fixed; inset: 0; background: rgba(0,0,0,0.5);
+ z-index: 99; opacity: 0; transition: opacity 0.25s;
+ pointer-events: none;
+ }
+ .sidebar-overlay.open { opacity: 1; pointer-events: auto; }
+
+ /* Responsive: off-canvas sidebar on narrow screens */
@media (max-width: 768px) {
+ .hamburger { display: inline-flex; align-items: center; }
+ .sidebar-overlay { display: block; }
+
.sidebar {
- width: 56px;
- overflow: hidden;
+ transform: translateX(-100%);
+ transition: transform 0.25s ease;
+ z-index: 100;
}
- .sidebar .sidebar-header span,
- .sidebar .sidebar-user,
- .sidebar .nav-item span,
- .sidebar .nav-item .ni-badge,
- .sidebar .sidebar-footer span,
- .sidebar .sidebar-footer .logout-btn { display: none; }
- .sidebar .nav-item { justify-content: center; padding: 11px 0; }
- .sidebar .nav-item .ni-icon { font-size: 20px; width: auto; }
- .sidebar .sidebar-header { justify-content: center; }
- .sidebar .sidebar-header .sh-icon { font-size: 22px; }
- .main { margin-left: 56px; padding: 16px; max-width: calc(100vw - 56px); }
+ .sidebar.open { transform: translateX(0); }
+
+ .main {
+ margin-left: 0;
+ padding: 16px;
+ max-width: 100vw;
+ }
+
+ .page-title .pt-actions .btn .btn-label { display: none; }
+ .page-title .pt-actions .btn { min-width: 36px; justify-content: center; }
/* Stats grid: tighter cards */
.stats-grid { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 6px; }
.stat-card { padding: 10px; }
.stat-card .stat-value { font-size: 22px; }
- /* Cantaloupe Sync batch rows stack */
+ /* Import batch rows stack */
.cs-batch-row .csb-status { width: 60px; }
.cs-batch-row .csb-time { width: auto; font-size: 11px; }
.cs-batch-row .csb-rows { width: auto; text-align: left; margin-left: auto; }
@@ -567,7 +588,7 @@
.page-title .pt-actions { width: 100%; }
.page-title .pt-actions button { flex: 1; }
- /* Cantaloupe diff badges stack 2x2 */
+ /* Import diff badges stack 2x2 */
.cs-diff-summary { grid-template-columns: repeat(2, 1fr); }
.cs-diff-badge { padding: 8px; }
.cs-diff-badge .csd-val { font-size: 18px; }
@@ -586,7 +607,7 @@
}
/* ═══════════════════════════════════════════════════════════════════════
- CANTALOUPE SYNC
+ EXCEL IMPORT
═══════════════════════════════════════════════════════════════════════ */
.cs-diff-summary {
display: grid;
@@ -657,8 +678,11 @@
+
+
+
-