This commit is contained in:
Mateusz Gruszczyński
2026-09-16 22:22:09 +02:00
parent c7d47db64e
commit bb39ab9dfa
27 changed files with 523 additions and 319 deletions
+38 -4
View File
@@ -272,17 +272,31 @@ function persistSavedCharts() {
localStorage.setItem('gree_controller_saved_charts', JSON.stringify(app.savedCharts.slice(0, 30)));
}
function savedChartRangeLabel(hours) {
const value = Number(hours || 24);
if (value === 168) return tr('history.range7d');
if (value === 720) return tr('history.range30d');
if (value === 2160) return tr('history.range90d');
if (value === 8760) return tr('history.range1y');
return `${value} h`;
}
function renderCustomBuilder() {
const host = $('#historyCustomBuilder'); if (!host) return;
if (app.historyTab !== 'custom') { host.innerHTML = ''; host.classList.remove('active'); return; }
host.classList.add('active');
const options = customSeriesOptions();
const selected = app.customChartSeries.map((key, index) => customSeriesDefinition(key, index)).filter(Boolean);
const editing = app.savedCharts.find(item => item.id === app.customChartEditingId) || null;
const draftName = app.customChartNameDraft !== null ? app.customChartNameDraft : (editing?.name || '');
const editNote = editing ? `<span class="custom-chart-edit-note">${esc(tr('history.editingChart'))}: <strong>${esc(editing.name)}</strong></span>` : '';
const cancelEdit = editing ? `<button class="secondary" data-history-action="cancel-chart-edit">${esc(tr('actions.cancel'))}</button>` : '';
host.innerHTML = `<div class="panel custom-chart-panel"><div class="chart-title-row"><div><h3>${esc(tr('history.customTitle'))}</h3><p>${esc(tr('history.customDescription'))}</p></div></div>
<div class="custom-chart-add"><select id="customSeriesSelect">${options.map(([value, label]) => `<option value="${esc(value)}">${esc(label)}</option>`).join('')}</select><button class="secondary" data-history-action="add-series">${esc(tr('history.addSeries'))}</button></div>
<div class="custom-series-list">${selected.length ? selected.map((item, index) => `<span class="custom-series-chip"><i style="--chip-color:${esc(item.color)}"></i>${esc(item.label)}<button data-history-action="remove-series" data-index="${index}" aria-label="${esc(tr('actions.remove'))}">${uiIcon('close')}</button></span>`).join('') : `<span class="field-note">${esc(tr('history.noCustomSeries'))}</span>`}</div>
<div class="custom-chart-save"><input id="customChartName" placeholder="${esc(tr('history.chartName'))}"><button class="secondary" data-history-action="save-chart">${esc(tr('actions.save'))}</button><button class="primary" data-history-action="copy-chart-link">${esc(tr('history.copyLink'))}</button></div>
<div class="saved-chart-list">${app.savedCharts.length ? app.savedCharts.map(item => `<div class="saved-chart-row"><button data-history-action="load-chart" data-id="${esc(item.id)}"><strong>${esc(item.name)}</strong><small>${esc(item.series.length)} ${esc(tr('history.series'))}</small></button><button class="danger" data-history-action="delete-chart" data-id="${esc(item.id)}">${uiIcon('close')}</button></div>`).join('') : `<span class="field-note">${esc(tr('history.noSavedCharts'))}</span>`}</div>
${editNote}
<div class="custom-chart-save"><input id="customChartName" value="${esc(draftName)}" placeholder="${esc(tr('history.chartName'))}"><button class="secondary" data-history-action="save-chart">${esc(editing ? tr('history.saveChanges') : tr('actions.save'))}</button>${cancelEdit}<button class="primary" data-history-action="copy-chart-link">${esc(tr('history.copyLink'))}</button></div>
<div class="saved-chart-section"><div class="saved-chart-heading"><strong>${esc(tr('history.savedCharts'))}</strong><small>${app.savedCharts.length}</small></div><div class="saved-chart-list">${app.savedCharts.length ? app.savedCharts.map(item => `<div class="saved-chart-row${item.id === app.customChartEditingId ? ' is-editing' : ''}"><button class="saved-chart-open" data-history-action="load-chart" data-id="${esc(item.id)}"><strong>${esc(item.name)}</strong><small>${esc(item.series.length)} ${esc(tr('history.series'))} · ${esc(savedChartRangeLabel(item.hours))}</small></button><div class="saved-chart-actions"><button class="secondary" data-history-action="edit-chart" data-id="${esc(item.id)}" title="${esc(tr('actions.edit'))}" aria-label="${esc(tr('actions.edit'))}">${uiIcon('edit')}</button><button class="danger" data-history-action="delete-chart" data-id="${esc(item.id)}" title="${esc(tr('actions.delete'))}" aria-label="${esc(tr('actions.delete'))}">${uiIcon('close')}</button></div></div>`).join('') : `<span class="field-note">${esc(tr('history.noSavedCharts'))}</span>`}</div></div>
</div>`;
}
@@ -327,26 +341,46 @@ function publicCustomChartUrl(path) {
async function handleHistoryAction(button) {
const action = button.dataset.historyAction;
if (action === 'add-series') {
if ($('#customChartName')) app.customChartNameDraft = $('#customChartName').value;
const value = $('#customSeriesSelect')?.value;
if (value && !app.customChartSeries.includes(value)) app.customChartSeries.push(value);
renderCustomHistory(); updateBrowserUrl(currentHistoryPath(), true); return;
}
if (action === 'remove-series') {
if ($('#customChartName')) app.customChartNameDraft = $('#customChartName').value;
app.customChartSeries.splice(Number(button.dataset.index), 1);
renderCustomHistory(); updateBrowserUrl(currentHistoryPath(), true); return;
}
if (action === 'save-chart') {
if (!app.customChartSeries.length) return toast(tr('history.noCustomSeries'), true);
const name = $('#customChartName')?.value.trim() || tr('history.customChart');
const item = { id: `chart-${Date.now()}`, name, series: [...app.customChartSeries], hours: $('#historyHours')?.value || '24' };
app.savedCharts.unshift(item); persistSavedCharts(); renderCustomHistory(); toast(tr('history.chartSaved')); return;
const hours = $('#historyHours')?.value || '24';
const editingIndex = app.savedCharts.findIndex(entry => entry.id === app.customChartEditingId);
if (editingIndex >= 0) {
app.savedCharts[editingIndex] = { ...app.savedCharts[editingIndex], name, series: [...app.customChartSeries], hours };
app.customChartEditingId = null; app.customChartNameDraft = null;
persistSavedCharts(); renderCustomHistory(); toast(tr('history.chartUpdated')); return;
}
const item = { id: `chart-${Date.now()}`, name, series: [...app.customChartSeries], hours };
app.savedCharts.unshift(item); app.customChartNameDraft = null; persistSavedCharts(); renderCustomHistory(); toast(tr('history.chartSaved')); return;
}
if (action === 'load-chart') {
const item = app.savedCharts.find(entry => entry.id === button.dataset.id); if (!item) return;
app.customChartEditingId = null; app.customChartNameDraft = item.name || '';
app.customChartSeries = [...item.series]; if ($('#historyHours') && item.hours) $('#historyHours').value = String(item.hours);
renderCustomHistory(); updateBrowserUrl(currentHistoryPath()); return;
}
if (action === 'edit-chart') {
const item = app.savedCharts.find(entry => entry.id === button.dataset.id); if (!item) return;
app.customChartEditingId = item.id; app.customChartNameDraft = item.name || ''; app.customChartSeries = [...item.series];
if ($('#historyHours') && item.hours) $('#historyHours').value = String(item.hours);
renderCustomHistory(); updateBrowserUrl(currentHistoryPath()); $('#customChartName')?.focus(); return;
}
if (action === 'cancel-chart-edit') {
app.customChartEditingId = null; app.customChartNameDraft = null; renderCustomHistory(); return;
}
if (action === 'delete-chart') {
if (app.customChartEditingId === button.dataset.id) { app.customChartEditingId = null; app.customChartNameDraft = null; }
app.savedCharts = app.savedCharts.filter(entry => entry.id !== button.dataset.id); persistSavedCharts(); renderCustomHistory(); return;
}
if (action === 'copy-chart-link') {