143 lines
8.1 KiB
Cheetah
143 lines
8.1 KiB
Cheetah
{{define "upload_it"}}
|
||
<style>
|
||
.upload-area { border: 2px dashed var(--border); border-radius: 8px; padding: 40px; text-align: center; cursor: pointer; transition: all 0.15s; background: var(--bg-card); }
|
||
.upload-area:hover, .upload-area.dragover { border-color: var(--accent); background: var(--accent-light); }
|
||
.upload-icon { color: var(--accent); margin-bottom: 12px; }
|
||
.upload-text { font-size: 1rem; font-weight: 500; color: var(--text); margin-bottom: 4px; }
|
||
.upload-hint { font-size: 1rem; color: var(--text-muted); }
|
||
.progress-overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.5); align-items: center; justify-content: center; z-index: 1000; }
|
||
.progress-modal { background: var(--bg-card); padding: 32px 48px; border-radius: 12px; text-align: center; width: 600px; box-shadow: 0 20px 25px -5px rgba(0,0,0,0.15); }
|
||
.progress-bar-wrap, .progress-track { background: var(--border); border-radius: 4px; height: 6px; overflow: hidden; margin-top: 16px; }
|
||
.progress-bar { background: var(--accent); height: 100%; width: 0%; transition: width 0.2s; }
|
||
.progress-label { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); margin-bottom: 8px; }
|
||
#upload-text, #process-text { font-size: 1.25rem; font-weight: 500; }
|
||
.progress-detail { margin-top: 12px; font-size: 1rem; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.file-table { background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
|
||
.file-row { display: flex; justify-content: space-between; align-items: center; padding: 10px 16px; border-bottom: 1px solid var(--border); font-size: 0.9rem; }
|
||
.file-row:last-child { border-bottom: none; }
|
||
.file-row.file-deleted { opacity: 0.5; }
|
||
.file-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
|
||
.file-name { font-weight: 500; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.file-deleted .file-name { text-decoration: line-through; }
|
||
.file-meta { font-size: 0.85rem; color: var(--text-muted); }
|
||
.file-status { display: flex; align-items: center; gap: 8px; white-space: nowrap; flex-shrink: 0; }
|
||
.status-expires { color: var(--text-muted); font-size: 0.85rem; }
|
||
.status-deleted { color: var(--danger); font-size: 0.85rem; }
|
||
.status-badge { font-size: 0.7rem; padding: 2px 6px; background: var(--accent-light); color: var(--accent); border-radius: 4px; text-transform: uppercase; letter-spacing: 0.02em; min-width: 60px; text-align: center; display: inline-block; }
|
||
.status-badge-failed { background: var(--danger-light); color: var(--danger); }
|
||
.btn-icon { padding: 4px 8px; background: transparent; color: var(--text-muted); border: none; font-size: 1rem; line-height: 1; border-radius: 4px; cursor: pointer; }
|
||
.btn-icon:hover { color: var(--danger); background: var(--danger-light); }
|
||
.paste-section { display: flex; flex-direction: column; align-items: flex-end; }
|
||
.form-textarea { width: 100%; box-sizing: border-box; padding: 10px 12px; font-size: 0.85rem; font-family: monospace; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-card); color: var(--text); resize: vertical; }
|
||
.form-textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-light); }
|
||
</style>
|
||
|
||
<div class="page-container" style="max-width: 800px;">
|
||
|
||
<div class="page-card">
|
||
<div style="display: flex; justify-content: space-between; align-items: baseline;">
|
||
<div>
|
||
<h1>{{.T.upload_files}}</h1>
|
||
<p class="intro">{{printf .T.upload_files_intro .TargetDossier.Name}}</p>
|
||
</div>
|
||
<a href="/dossier/{{.TargetDossier.DossierID}}" class="btn btn-secondary btn-small">{{.T.back}}</a>
|
||
</div>
|
||
|
||
<div class="upload-area" id="upload-area">
|
||
<div class="upload-icon">
|
||
<svg width="40" height="40" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5"/>
|
||
</svg>
|
||
</div>
|
||
<p class="upload-text">{{.T.upload_drop}}</p>
|
||
<p class="upload-hint">{{.T.upload_hint_broad}}</p>
|
||
</div>
|
||
<input type="file" id="file-input" multiple webkitdirectory style="display:none">
|
||
<input type="file" id="file-input-files" multiple style="display:none">
|
||
|
||
<p style="color: var(--text-muted); font-size: 0.9rem; margin: 24px 0 8px;">{{.T.upload_paste_hint}}</p>
|
||
<div class="paste-section">
|
||
<textarea id="paste-input" class="form-textarea" rows="5" placeholder="{{.T.upload_paste_placeholder}}"></textarea>
|
||
<button type="button" class="btn btn-small" style="margin-top: 8px;" id="paste-submit" onclick="submitPaste()">{{.T.upload_paste_submit}}</button>
|
||
</div>
|
||
</div>
|
||
|
||
{{if .UploadList}}
|
||
<div class="page-card">
|
||
<h2>{{.T.upload_recent}}</h2>
|
||
<div class="file-table">
|
||
{{range .UploadList}}
|
||
<div class="file-row {{if .Deleted}}file-deleted{{end}}">
|
||
<div class="file-info">
|
||
<span class="file-name">{{.FileName}}</span>
|
||
<span class="file-meta">{{.SizeHuman}} · {{.UploadedAt}}</span>
|
||
</div>
|
||
<div class="file-status">
|
||
{{if .Deleted}}
|
||
<span class="status-deleted">{{.DeletedReason}}</span>
|
||
{{else}}
|
||
{{if ne .Status "uploaded"}}<span class="status-badge{{if eq .Status "failed"}} status-badge-failed{{end}}">{{.Status}}</span>{{end}}
|
||
{{if .CanReprocess}}<button type="button" class="btn-icon" title="Reprocess" onclick="reprocessFile({{.ID}})">↻</button>{{else if .CanUndo}}<button type="button" class="btn-icon" title="{{$.T.upload_undo_title}}" onclick="undoImport({{.ID}})">↩</button>{{end}}
|
||
<span class="status-expires">{{$.T.upload_expires}} {{.ExpiresAt}}</span>
|
||
<button type="button" class="btn-icon" title="{{$.T.op_delete}}" onclick="deleteFile({{.ID}})">×</button>
|
||
{{end}}
|
||
</div>
|
||
</div>
|
||
{{end}}
|
||
</div>
|
||
</div>
|
||
{{else}}
|
||
<div class="page-card" style="text-align: center; color: var(--text-muted);">
|
||
{{.T.upload_no_files}}
|
||
</div>
|
||
{{end}}
|
||
|
||
<p style="color: var(--text-muted); font-size: 0.85rem;">{{.T.upload_auto_delete}}</p>
|
||
|
||
{{template "footer"}}
|
||
</div>
|
||
|
||
<div class="progress-overlay" id="progress-overlay">
|
||
<div class="progress-modal">
|
||
<p class="progress-label">{{.T.upload_importing_label}}</p>
|
||
<p id="upload-text"></p>
|
||
<div class="progress-bar-wrap">
|
||
<div class="progress-bar" id="upload-bar"></div>
|
||
</div>
|
||
<p class="progress-detail" id="upload-detail"></p>
|
||
<p class="progress-label" id="process-label" style="margin-top:16px;display:none">{{.T.upload_processing_label}}</p>
|
||
<div class="progress-track" id="process-track" style="display:none">
|
||
<div class="progress-bar" id="process-bar"></div>
|
||
</div>
|
||
<p id="process-text"></p>
|
||
<p class="progress-detail" id="process-detail"></p>
|
||
</div>
|
||
</div>
|
||
|
||
<script id="upload-i18n" type="application/json">
|
||
{
|
||
"dossier": {{js .TargetDossier.DossierID}},
|
||
"reading_files": {{js .T.upload_reading_files}},
|
||
"processing_genetics": {{js .T.upload_processing_genetics}},
|
||
"analyzing_variants": {{js .T.upload_analyzing_variants}},
|
||
"processing_documents": {{js .T.upload_processing_documents}},
|
||
"extracting_data": {{js .T.upload_extracting_data}},
|
||
"processing_complete": {{js .T.upload_processing_complete}},
|
||
"processing_failed": {{js .T.upload_processing_failed}},
|
||
"processing_timeout": {{js .T.upload_processing_timeout}},
|
||
"confirm_delete": {{js .T.upload_confirm_delete}},
|
||
"confirm_undo": {{js .T.upload_confirm_undo}},
|
||
"import_undone": {{js .T.upload_import_undone}},
|
||
"undo_failed": {{js .T.upload_undo_failed}},
|
||
"preparing": {{js .T.upload_preparing}},
|
||
"importing": {{js .T.upload_importing}},
|
||
"analyzing": {{js .T.upload_analyzing}},
|
||
"extracting_labs": {{js .T.upload_extracting_labs}},
|
||
"normalizing": {{js .T.upload_normalizing}},
|
||
"mapping_loinc": {{js .T.upload_mapping_loinc}},
|
||
"import_error": {{js .T.upload_import_error}},
|
||
"imported": {{js .T.upload_imported}}
|
||
}
|
||
</script>
|
||
<script src="/static/upload.js"></script>
|
||
{{end}} |