v9: скачивание загруженных файлов
This commit is contained in:
parent
8ca93f6275
commit
239c51a0a3
85
index.html
85
index.html
@ -90,8 +90,9 @@ tr:hover td{background:var(--cyan-50)}
|
||||
.modal .meta-row .fld{font-size:13px;color:var(--gray-500)}
|
||||
.modal .meta-row .fld strong{display:block;font-size:14px;color:var(--ink);margin-top:2px}
|
||||
.modal .docs{display:flex;gap:8px;flex-wrap:wrap;margin:8px 0}
|
||||
.modal .docs .doc-chip{background:var(--gray-100);padding:6px 12px;border-radius:6px;font-size:13px;display:flex;align-items:center;gap:6px}
|
||||
.modal .docs .doc-chip{background:var(--gray-100);padding:6px 12px;border-radius:6px;font-size:13px;display:flex;align-items:center;gap:6px;border:1px solid transparent;transition:.15s}
|
||||
.modal .docs .doc-chip button{background:none;border:none;cursor:pointer;color:var(--red);font-size:14px;line-height:1}
|
||||
.doc-chip:hover{background:var(--cyan-50);color:var(--ink);border-color:var(--cyan)}
|
||||
.file-upload{border:2px dashed var(--gray-200);border-radius:8px;padding:20px;text-align:center;color:var(--gray-500);cursor:pointer;margin-bottom:12px;font-size:14px;transition:.15s}
|
||||
.file-upload:hover{border-color:var(--cyan);color:var(--cyan)}
|
||||
.file-upload .icon{font-size:28px;display:block;margin-bottom:4px}
|
||||
@ -592,8 +593,9 @@ function openEdit(id){
|
||||
// Generate file list from saved file metadata
|
||||
const savedFiles = JSON.parse(localStorage.getItem('samruk_files_'+e.id) || '[]')
|
||||
const fileList = savedFiles.map((f,i) => `
|
||||
<span class="doc-chip">📄 ${f.name} (${(f.size/1024).toFixed(0)} КБ)
|
||||
<button onclick="removeFile(${e.id},${i})" title="Удалить">×</button></span>`).join('')
|
||||
<span class="doc-chip" onclick="downloadFile(${e.id},${i})" title="Скачать ${f.name}" style="cursor:pointer">
|
||||
📄 ${f.name} (${(f.size/1024).toFixed(0)} КБ)
|
||||
<button onclick="event.stopPropagation();removeFile(${e.id},${i})" title="Удалить">×</button></span>`).join('')
|
||||
|
||||
document.getElementById('editModalContent').innerHTML = `
|
||||
<button class="close" onclick="closeEditModal()">×</button>
|
||||
@ -660,30 +662,67 @@ function saveEdit(id){
|
||||
const newProgress = parseInt(document.getElementById('editProgress').value)
|
||||
const comment = document.getElementById('editComment').value.trim()
|
||||
|
||||
// Save files from input
|
||||
// Save files as data URLs
|
||||
const fileInput = document.getElementById('editFileInput')
|
||||
if(fileInput.files.length > 0){
|
||||
const existing = JSON.parse(localStorage.getItem('samruk_files_'+id) || '[]')
|
||||
for(const f of fileInput.files){
|
||||
existing.push({name: f.name, size: f.size, type: f.type, date: new Date().toLocaleDateString()})
|
||||
}
|
||||
localStorage.setItem('samruk_files_'+id, JSON.stringify(existing))
|
||||
const MAX_SIZE = 4 * 1024 * 1024 // 4 MB limit per file for localStorage
|
||||
|
||||
function finalizeSave(){
|
||||
const now = new Date().toLocaleDateString()
|
||||
e.h.push(`${now} — ${currentUser.name}: статус ${statusMap[newStatus]}, прогресс ${newProgress}%${comment?' — комм.: '+comment:''}`)
|
||||
e.s = newStatus
|
||||
e.p = newProgress
|
||||
if(newStatus === 'done' && e.done === '—') e.done = now
|
||||
localStorage.setItem('samruk_edits_'+id, JSON.stringify({comment, editedBy: currentUser.name, editedAt: now}))
|
||||
saveState()
|
||||
closeEditModal()
|
||||
renderAll()
|
||||
renderNotifs()
|
||||
}
|
||||
|
||||
// Add history entry
|
||||
const now = new Date().toLocaleDateString()
|
||||
e.h.push(`${now} — ${currentUser.name}: статус ${statusMap[newStatus]}, прогресс ${newProgress}%${comment?' — комм.: '+comment:''}`)
|
||||
if(fileInput.files.length > 0){
|
||||
const existing = JSON.parse(localStorage.getItem('samruk_files_'+id) || '[]')
|
||||
let processed = 0
|
||||
let skipped = 0
|
||||
for(const f of fileInput.files){
|
||||
if(f.size > MAX_SIZE){
|
||||
skipped++
|
||||
if(++processed === fileInput.files.length){
|
||||
if(skipped) alert(`⚠️ ${skipped} файл(ов) > 4 МБ пропущены — слишком велики для локального хранения.`)
|
||||
finalizeSave()
|
||||
}
|
||||
continue
|
||||
}
|
||||
const reader = new FileReader()
|
||||
reader.onload = function(ev){
|
||||
existing.push({name: f.name, size: f.size, type: f.type, date: new Date().toLocaleDateString(), data: ev.target.result})
|
||||
processed++
|
||||
if(processed === fileInput.files.length){
|
||||
try {
|
||||
localStorage.setItem('samruk_files_'+id, JSON.stringify(existing))
|
||||
} catch(e) {
|
||||
alert('⚠️ Хранилище браузера переполнено. Удалите старые файлы.')
|
||||
}
|
||||
if(skipped) alert(`⚠️ ${skipped} файл(ов) > 4 МБ пропущены.`)
|
||||
finalizeSave()
|
||||
}
|
||||
}
|
||||
reader.readAsDataURL(f)
|
||||
}
|
||||
} else {
|
||||
finalizeSave()
|
||||
}
|
||||
}
|
||||
|
||||
e.s = newStatus
|
||||
e.p = newProgress
|
||||
if(newStatus === 'done' && e.done === '—') e.done = now
|
||||
|
||||
// Save edits
|
||||
localStorage.setItem('samruk_edits_'+id, JSON.stringify({comment, editedBy: currentUser.name, editedAt: now}))
|
||||
saveState()
|
||||
closeEditModal()
|
||||
renderAll()
|
||||
renderNotifs()
|
||||
function downloadFile(eventId, fileIdx){
|
||||
const files = JSON.parse(localStorage.getItem('samruk_files_'+eventId) || '[]')
|
||||
const f = files[fileIdx]
|
||||
if(!f || !f.data) return
|
||||
const a = document.createElement('a')
|
||||
a.href = f.data
|
||||
a.download = f.name
|
||||
document.body.appendChild(a)
|
||||
a.click()
|
||||
document.body.removeChild(a)
|
||||
}
|
||||
|
||||
function removeFile(eventId, fileIdx){
|
||||
|
||||
Loading…
Reference in New Issue
Block a user