fix: corretto tempo di visualizzazione che non considerava la variabile. style: aggiunto pulsante per eliminare precedenti env.

This commit is contained in:
Gabriele Cimaschi committed 2026-09-09 11:21:58 +02:00
1 parent cf500aabb3
commit ec1fb25d4e
5 files changed
+101 -4

No files matched your search

+11 -1
View File
@@ -508,7 +508,13 @@ const App = {
/** Ensure lookup data is loaded (cached) */
async ensureLookups(forceRefresh = false) {
if (this.lookupsLoaded && !forceRefresh) return;
if (this.lookupsLoaded && !forceRefresh) {
const freshConfig = await this.api('/api/config').catch(() => null);
if (freshConfig && this.lookups) {
this.lookups.config = freshConfig;
}
return;
}
// Check localStorage cache first if not forcing refresh
if (!forceRefresh) {
@@ -519,6 +525,10 @@ const App = {
if (!this.lookups.config || this.lookups.config.autoTimeMinHour === undefined || !this.lookups.customerUsers || !this.lookups.customer_users_version_1) {
throw new Error('Outdated config cache (missing autoTimeMinHour or customerUsers)');
}
const freshConfig = await this.api('/api/config').catch(() => null);
if (freshConfig) {
this.lookups.config = freshConfig;
}
this.lookupsLoaded = true;
return;
} catch (e) {
+48
View File
@@ -125,6 +125,9 @@ const EnvConfigView = {
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:4px;">
<div style="display:flex; align-items:center; gap:6px;">
<span class="badge" style="background:var(--bg-secondary); border:1px solid var(--border-subtle); font-weight:700; font-size:0.75rem; color:var(--text-primary);">#${h.id}</span>
<button class="env-history-delete-btn" data-id="${h.id}" style="background:var(--bg-tertiary); border:1px solid var(--border-subtle); border-radius:var(--radius-sm); cursor:pointer; padding:2px 5px; display:inline-flex; align-items:center; justify-content:center; color:var(--danger); transition:all 0.15s ease;" title="Elimina questa versione dallo storico">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:13px; height:13px;"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/></svg>
</button>
${isCurrentVersion ? `<span class="badge" style="background:rgba(16,185,129,0.2); color:#10b981; font-weight:600; font-size:0.7rem;">Attuale</span>` : ''}
</div>
<span style="font-size:0.75rem; color:var(--text-tertiary); font-family:monospace;">${formattedDate}</span>
@@ -176,6 +179,11 @@ const EnvConfigView = {
this.currentContent = content;
this.history = res.history || [];
try {
await App.ensureLookups(true);
App.updateDailyTimer();
} catch (_) {}
// Re-render history panel
const historyListDiv = document.getElementById('env-history-list');
if (historyListDiv) {
@@ -237,6 +245,11 @@ const EnvConfigView = {
this.currentContent = res.content || record.content;
this.history = res.history || [];
try {
await App.ensureLookups(true);
App.updateDailyTimer();
} catch (_) {}
const editorTextarea = document.getElementById('env-editor-content');
if (editorTextarea) {
editorTextarea.value = this.currentContent;
@@ -254,6 +267,41 @@ const EnvConfigView = {
}
});
});
// Delete buttons
document.querySelectorAll('.env-history-delete-btn').forEach(btn => {
btn.addEventListener('click', async () => {
const id = parseInt(btn.dataset.id, 10);
const record = this.history.find(h => h.id === id);
if (!record) return;
const confirmed = await App.confirm(
`Eliminazione Versione #${record.id}`,
`Sei sicuro di voler eliminare permanentemente la versione #${record.id} dallo storico?`
);
if (!confirmed) return;
try {
btn.disabled = true;
const res = await App.api(`/api/config/env/history/${id}`, {
method: 'DELETE'
});
Toast.success(res.message || `Versione #${id} eliminata dallo storico!`);
this.history = res.history || [];
const historyListDiv = document.getElementById('env-history-list');
if (historyListDiv) {
historyListDiv.innerHTML = this.renderHistoryList();
this.bindHistoryEvents();
}
} catch (err) {
Toast.error('Errore durante l\'eliminazione dello storico: ' + err.message);
btn.disabled = false;
}
});
});
},
showPreviewModal(record) {
+39
View File
@@ -67,6 +67,7 @@ router.post('/env', async (req, res) => {
// Write updated content to disk
fs.writeFileSync(envPath, content, 'utf8');
try { require('dotenv').config({ path: envPath, override: true }); } catch (_) {}
// Save snapshot in history table
const info = db.prepare(`
@@ -112,6 +113,7 @@ router.post('/env/restore/:history_id', async (req, res) => {
// Write snapshot content to disk
fs.writeFileSync(envPath, record.content, 'utf8');
try { require('dotenv').config({ path: envPath, override: true }); } catch (_) {}
// Insert new history record documenting the restore operation
const restoreNote = `Ripristinato alla versione #${record.id} del ${record.created_at}`;
@@ -144,4 +146,41 @@ router.post('/env/restore/:history_id', async (req, res) => {
}
});
// DELETE /api/config/env/history/:id — Delete a specific .env history entry
router.delete('/env/history/:id', async (req, res) => {
try {
const { id } = req.params;
const operatorId = parseInt(req.headers['x-agent-id'] || '1', 10);
const agentName = await resolveAgentName(operatorId);
const record = db.prepare('SELECT * FROM env_history WHERE id = ?').get(id);
if (!record) {
return res.status(404).json({ error: 'Versione di storico non trovata' });
}
db.prepare('DELETE FROM env_history WHERE id = ?').run(id);
logAttivita({
agente_id: operatorId,
agente_nome: agentName,
titolo_azione: 'Eliminazione Storico .env',
azione: { deleted_history_id: id },
esito: 'successo',
});
const history = db.prepare(`
SELECT * FROM env_history ORDER BY id DESC LIMIT 100
`).all();
res.json({
success: true,
message: `Versione #${id} dello storico eliminata con successo!`,
history,
});
} catch (err) {
console.error('Error deleting .env history entry:', err);
res.status(500).json({ error: 'Errore durante l\'eliminazione della versione dello storico', message: err.message });
}
});
module.exports = router;
+1 -1
View File
@@ -147,7 +147,7 @@ router.get('/config', async (req, res) => {
res.json({
defaultAgentLogin: process.env.OTRS_API_USER || '',
dailyTargetTime: parseInt(process.env.DAILY_TARGET_TIME, 10) || 480,
dailyTargetTime: parseInt(process.env.DAILY_TARGET_TIME || process.env.daily_target_time || process.env.Daily_Target_Time, 10) || 480,
phraseThreshold: parseInt(process.env.PHRASE_THRESHOLD, 10) || 70,
autoTimeMinHour: process.env.AUTO_TIME_MIN_HOUR || '18:00',
helpdeskEmail: process.env.OTRS_MAIL_BCC || '',
+2 -2
View File
@@ -2140,7 +2140,7 @@ router.get('/time-accounting/summary', async (req, res) => {
}
});
const targetMinutes = parseInt(process.env.DAILY_TARGET_TIME, 10) || 480;
const targetMinutes = parseInt(process.env.DAILY_TARGET_TIME || process.env.daily_target_time || process.env.Daily_Target_Time, 10) || 480;
const workDaysRaw = process.env.WORK_DAYS || '1,2,3,4,5';
const workDays = workDaysRaw.split(',').map(x => parseInt(x.trim(), 10)).filter(x => !isNaN(x));
@@ -2265,7 +2265,7 @@ router.post('/auto-time', async (req, res) => {
await client.query('BEGIN');
// 1. Calculate remaining time
const targetTime = parseInt(process.env.DAILY_TARGET_TIME, 10) || 480;
const targetTime = parseInt(process.env.DAILY_TARGET_TIME || process.env.daily_target_time || process.env.Daily_Target_Time, 10) || 480;
const timeTodayRes = await client.query(
`SELECT COALESCE(SUM(time_unit), 0) AS total_today
FROM time_accounting