inou/portal/templates/upload_nl.tmpl

143 lines
8.1 KiB
Cheetah
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{{define "upload_nl"}}
<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}}