v22: экспорт/импорт всех данных — сохранение и восстановление
This commit is contained in:
parent
15180b11b9
commit
df44758cdb
33
index.html
33
index.html
@ -217,7 +217,10 @@ function renderDashboard(){
|
||||
h+='<button class="btn btn-sm" onclick="downloadReport()">Скачать CSV</button>';
|
||||
h+='<button class="btn btn-sm btn-outline" onclick="downloadHTML()" style="margin-left:8px">Скачать HTML</button>';
|
||||
h+='<div style="margin-top:12px;font-size:12px;color:var(--gray-500)">Хранилище: '+fmtStorage()+'</div>';
|
||||
h+='<button class="btn btn-sm" style="margin-top:6px;background:var(--red);color:#fff" onclick="clearAllFiles()">🗑 Очистить все файлы</button></div></div>';
|
||||
h+='<button class="btn btn-sm" style="margin-top:6px;background:var(--green);color:#fff" onclick="exportAll()">💾 Сохранить все данные</button>';
|
||||
h+='<button class="btn btn-sm btn-outline" style="margin-top:6px;margin-left:4px" onclick="document.getElementById(\'impF\').click()">📥 Загрузить данные</button>';
|
||||
h+='<input type="file" id="impF" accept=".json" style="display:none" onchange="importAll(this)">';
|
||||
h+='<button class="btn btn-sm" style="margin-top:6px;margin-left:4px;background:var(--red);color:#fff" onclick="clearAllFiles()">🗑 Очистить файлы</button></div></div>';
|
||||
|
||||
document.getElementById("tab-dashboard").innerHTML=h;
|
||||
}
|
||||
@ -448,6 +451,34 @@ function storageUsed(){var t=0;for(var i=0;i<localStorage.length;i++){var k=loca
|
||||
function fmtStorage(){var b=storageUsed();return b>1048576?(b/1048576).toFixed(1)+' МБ':(b/1024).toFixed(0)+' КБ'}
|
||||
function clearAllFiles(){if(!confirm('Удалить ВСЕ загруженные файлы и отчёты? Это нельзя отменить.'))return;var keys=[];for(var i=0;i<localStorage.length;i++){var k=localStorage.key(i);if(k.indexOf('sf_')===0||k.indexOf('ss_')===0)keys.push(k)}keys.forEach(function(k){localStorage.removeItem(k)});alert('Файлы очищены. Хранилище: '+fmtStorage());renderDashboard()}
|
||||
|
||||
function exportAll(){
|
||||
var data={events:events,user:curUser,date:new Date().toISOString(),files:{},subChecks:{}};
|
||||
for(var i=0;i<localStorage.length;i++){var k=localStorage.key(i);if(k.indexOf('sf_')===0)data.files[k]=localStorage.getItem(k);if(k.indexOf('ss_')===0)data.subChecks[k]=localStorage.getItem(k)}
|
||||
var blob=new Blob([JSON.stringify(data)],{type:"application/json"}),a=document.createElement("a");
|
||||
a.href=URL.createObjectURL(blob);a.download="backup_pb_"+new Date().toISOString().slice(0,10)+".json";a.click();
|
||||
alert("✅ Данные сохранены. Файл backup_pb_....json скачан. Его можно загрузить обратно кнопкой «Загрузить данные».")
|
||||
}
|
||||
|
||||
function importAll(input){
|
||||
if(!input.files.length)return;
|
||||
var reader=new FileReader();
|
||||
reader.onload=function(ev){
|
||||
try{
|
||||
var data=JSON.parse(ev.target.result);
|
||||
if(!data.events||!data.files){alert("❌ Неверный формат файла");return}
|
||||
if(!confirm("Загрузить данные из бекапа? Текущие данные будут заменены."))return;
|
||||
// Save events
|
||||
events=data.events;saveEvents();
|
||||
// Save files and sub-checks
|
||||
for(var k in data.files){if(data.files.hasOwnProperty(k))localStorage.setItem(k,data.files[k])}
|
||||
for(var k in data.subChecks){if(data.subChecks.hasOwnProperty(k))localStorage.setItem(k,data.subChecks[k])}
|
||||
alert("✅ Данные восстановлены. Обновите страницу.");
|
||||
location.reload();
|
||||
}catch(e){alert("❌ Ошибка чтения файла")}
|
||||
};
|
||||
reader.readAsText(input.files[0]);
|
||||
}
|
||||
|
||||
function countFiles(id){
|
||||
var total=0,main=getMD(id);
|
||||
for(var k in main){if(main.hasOwnProperty(k))total+=(main[k].files||[]).length}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user