v9: скачивание загруженных файлов

This commit is contained in:
Dauren777 2026-06-04 11:27:26 +00:00
parent 8ca93f6275
commit 239c51a0a3

View File

@ -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()">&times;</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){