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{font-size:13px;color:var(--gray-500)}
|
||||||
.modal .meta-row .fld strong{display:block;font-size:14px;color:var(--ink);margin-top:2px}
|
.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{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}
|
.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{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:hover{border-color:var(--cyan);color:var(--cyan)}
|
||||||
.file-upload .icon{font-size:28px;display:block;margin-bottom:4px}
|
.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
|
// Generate file list from saved file metadata
|
||||||
const savedFiles = JSON.parse(localStorage.getItem('samruk_files_'+e.id) || '[]')
|
const savedFiles = JSON.parse(localStorage.getItem('samruk_files_'+e.id) || '[]')
|
||||||
const fileList = savedFiles.map((f,i) => `
|
const fileList = savedFiles.map((f,i) => `
|
||||||
<span class="doc-chip">📄 ${f.name} (${(f.size/1024).toFixed(0)} КБ)
|
<span class="doc-chip" onclick="downloadFile(${e.id},${i})" title="Скачать ${f.name}" style="cursor:pointer">
|
||||||
<button onclick="removeFile(${e.id},${i})" title="Удалить">×</button></span>`).join('')
|
📄 ${f.name} (${(f.size/1024).toFixed(0)} КБ)
|
||||||
|
<button onclick="event.stopPropagation();removeFile(${e.id},${i})" title="Удалить">×</button></span>`).join('')
|
||||||
|
|
||||||
document.getElementById('editModalContent').innerHTML = `
|
document.getElementById('editModalContent').innerHTML = `
|
||||||
<button class="close" onclick="closeEditModal()">×</button>
|
<button class="close" onclick="closeEditModal()">×</button>
|
||||||
@ -660,30 +662,67 @@ function saveEdit(id){
|
|||||||
const newProgress = parseInt(document.getElementById('editProgress').value)
|
const newProgress = parseInt(document.getElementById('editProgress').value)
|
||||||
const comment = document.getElementById('editComment').value.trim()
|
const comment = document.getElementById('editComment').value.trim()
|
||||||
|
|
||||||
// Save files from input
|
// Save files as data URLs
|
||||||
const fileInput = document.getElementById('editFileInput')
|
const fileInput = document.getElementById('editFileInput')
|
||||||
if(fileInput.files.length > 0){
|
const MAX_SIZE = 4 * 1024 * 1024 // 4 MB limit per file for localStorage
|
||||||
const existing = JSON.parse(localStorage.getItem('samruk_files_'+id) || '[]')
|
|
||||||
for(const f of fileInput.files){
|
function finalizeSave(){
|
||||||
existing.push({name: f.name, size: f.size, type: f.type, date: new Date().toLocaleDateString()})
|
const now = new Date().toLocaleDateString()
|
||||||
}
|
e.h.push(`${now} — ${currentUser.name}: статус ${statusMap[newStatus]}, прогресс ${newProgress}%${comment?' — комм.: '+comment:''}`)
|
||||||
localStorage.setItem('samruk_files_'+id, JSON.stringify(existing))
|
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
|
if(fileInput.files.length > 0){
|
||||||
const now = new Date().toLocaleDateString()
|
const existing = JSON.parse(localStorage.getItem('samruk_files_'+id) || '[]')
|
||||||
e.h.push(`${now} — ${currentUser.name}: статус ${statusMap[newStatus]}, прогресс ${newProgress}%${comment?' — комм.: '+comment:''}`)
|
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
|
function downloadFile(eventId, fileIdx){
|
||||||
e.p = newProgress
|
const files = JSON.parse(localStorage.getItem('samruk_files_'+eventId) || '[]')
|
||||||
if(newStatus === 'done' && e.done === '—') e.done = now
|
const f = files[fileIdx]
|
||||||
|
if(!f || !f.data) return
|
||||||
// Save edits
|
const a = document.createElement('a')
|
||||||
localStorage.setItem('samruk_edits_'+id, JSON.stringify({comment, editedBy: currentUser.name, editedAt: now}))
|
a.href = f.data
|
||||||
saveState()
|
a.download = f.name
|
||||||
closeEditModal()
|
document.body.appendChild(a)
|
||||||
renderAll()
|
a.click()
|
||||||
renderNotifs()
|
document.body.removeChild(a)
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeFile(eventId, fileIdx){
|
function removeFile(eventId, fileIdx){
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user