Files
Meeting-Mixer/js/history.js

149 lines
4.9 KiB
JavaScript

import { state } from './app.js';
import { loadFromJSON, saveToJSON, removeHistoryEntry } from './data.js';
import { downloadBlob } from './excel.js';
export function renderDataTab() {
const container = document.getElementById('tab-data');
container.replaceChildren();
const title = document.createElement('h2');
title.className = 'section-title';
title.textContent = 'Daten';
container.appendChild(title);
const grid = document.createElement('div');
grid.style.cssText = 'display:grid;grid-template-columns:1fr 1fr;gap:32px';
// Left: save/load
const saveLoadCol = document.createElement('div');
const saveTitle = document.createElement('h3');
saveTitle.style.cssText = 'margin-bottom:12px;font-size:15px';
saveTitle.textContent = 'Speichern / Laden';
saveLoadCol.appendChild(saveTitle);
const saveRow = document.createElement('div');
saveRow.className = 'row';
const saveBtn = document.createElement('button');
saveBtn.type = 'button';
saveBtn.className = 'primary';
saveBtn.textContent = 'Daten speichern (.json)';
saveRow.appendChild(saveBtn);
saveLoadCol.appendChild(saveRow);
const loadRow = document.createElement('div');
loadRow.className = 'row';
const loadBtn = document.createElement('button');
loadBtn.type = 'button';
loadBtn.textContent = 'Daten laden (.json)';
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.accept = '.json';
fileInput.style.display = 'none';
loadRow.append(loadBtn, fileInput);
saveLoadCol.appendChild(loadRow);
const hint = document.createElement('p');
hint.style.cssText = 'color:#6b7280;font-size:12px;margin-top:8px';
hint.textContent = 'Speichert Mitarbeiterliste, Einschränkungen und Verlauf. Beim nächsten Mal diese Datei laden.';
saveLoadCol.appendChild(hint);
// Right: history
const historyCol = document.createElement('div');
const historyTitle = document.createElement('h3');
historyTitle.style.cssText = 'margin-bottom:12px;font-size:15px';
historyTitle.textContent = 'Verlauf';
historyCol.appendChild(historyTitle);
const historyTable = document.createElement('div');
historyTable.id = 'history-table';
historyCol.appendChild(historyTable);
grid.append(saveLoadCol, historyCol);
container.appendChild(grid);
renderHistoryTable();
saveBtn.addEventListener('click', () => {
const blob = new Blob([saveToJSON(state)], { type: 'application/json' });
downloadBlob(blob, 'morning-planner-daten.json');
});
loadBtn.addEventListener('click', () => fileInput.click());
fileInput.addEventListener('change', async e => {
const file = e.target.files[0];
if (!file) return;
try {
const loaded = loadFromJSON(await file.text());
state.employees = loaded.employees;
state.calendar = loaded.calendar;
state.history = loaded.history;
alert('Daten erfolgreich geladen.');
renderDataTab();
} catch (err) {
alert('Fehler beim Laden: ' + err.message);
}
e.target.value = '';
});
}
function renderHistoryTable() {
const el = document.getElementById('history-table');
el.replaceChildren();
if (state.history.length === 0) {
const msg = document.createElement('p');
msg.style.cssText = 'color:#9ca3af;font-size:13px';
msg.textContent = 'Noch keine Einträge im Verlauf.';
el.appendChild(msg);
return;
}
const nameById = Object.fromEntries(state.employees.map(e => [e.id, e.name]));
const sorted = [...state.history].sort((a, b) => b.date.localeCompare(a.date));
const table = document.createElement('table');
const thead = document.createElement('thead');
const headRow = document.createElement('tr');
['Datum','Mitarbeiter','Typ',''].forEach(txt => {
const th = document.createElement('th');
th.textContent = txt;
headRow.appendChild(th);
});
thead.appendChild(headRow);
table.appendChild(thead);
const tbody = document.createElement('tbody');
for (const h of sorted) {
const [y, m, d] = h.date.split('-');
const tr = document.createElement('tr');
const dateTd = document.createElement('td');
dateTd.textContent = d + '.' + m + '.' + y;
const nameTd = document.createElement('td');
nameTd.textContent = nameById[h.employeeId] ?? '(unbekannt)'; // textContent: safe
const typeTd = document.createElement('td');
typeTd.style.color = '#6b7280';
typeTd.textContent = h.manual ? 'Manuell' : 'Auto';
const actionTd = document.createElement('td');
const delBtn = document.createElement('button');
delBtn.type = 'button';
delBtn.textContent = '✕';
delBtn.style.cssText = 'font-size:11px;padding:2px 6px';
delBtn.addEventListener('click', () => {
removeHistoryEntry(state, h.date);
renderHistoryTable();
});
actionTd.appendChild(delBtn);
tr.append(dateTd, nameTd, typeTd, actionTd);
tbody.appendChild(tr);
}
table.appendChild(tbody);
el.appendChild(table);
}