fix: corretto tempo di visualizzazione che non considerava la variabile. style: aggiunto pulsante per eliminare precedenti env.
This commit is contained in:
1 parent
cf500aabb3
commit
ec1fb25d4e
5 files changed
+101
-4
No files matched your search
+11
-1
@@ -508,7 +508,13 @@ const App = {
|
|||||||
|
|
||||||
/** Ensure lookup data is loaded (cached) */
|
/** Ensure lookup data is loaded (cached) */
|
||||||
async ensureLookups(forceRefresh = false) {
|
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
|
// Check localStorage cache first if not forcing refresh
|
||||||
if (!forceRefresh) {
|
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) {
|
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)');
|
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;
|
this.lookupsLoaded = true;
|
||||||
return;
|
return;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -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; justify-content:space-between; margin-bottom:4px;">
|
||||||
<div style="display:flex; align-items:center; gap:6px;">
|
<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>
|
<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>` : ''}
|
${isCurrentVersion ? `<span class="badge" style="background:rgba(16,185,129,0.2); color:#10b981; font-weight:600; font-size:0.7rem;">Attuale</span>` : ''}
|
||||||
</div>
|
</div>
|
||||||
<span style="font-size:0.75rem; color:var(--text-tertiary); font-family:monospace;">${formattedDate}</span>
|
<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.currentContent = content;
|
||||||
this.history = res.history || [];
|
this.history = res.history || [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
await App.ensureLookups(true);
|
||||||
|
App.updateDailyTimer();
|
||||||
|
} catch (_) {}
|
||||||
|
|
||||||
// Re-render history panel
|
// Re-render history panel
|
||||||
const historyListDiv = document.getElementById('env-history-list');
|
const historyListDiv = document.getElementById('env-history-list');
|
||||||
if (historyListDiv) {
|
if (historyListDiv) {
|
||||||
@@ -237,6 +245,11 @@ const EnvConfigView = {
|
|||||||
this.currentContent = res.content || record.content;
|
this.currentContent = res.content || record.content;
|
||||||
this.history = res.history || [];
|
this.history = res.history || [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
await App.ensureLookups(true);
|
||||||
|
App.updateDailyTimer();
|
||||||
|
} catch (_) {}
|
||||||
|
|
||||||
const editorTextarea = document.getElementById('env-editor-content');
|
const editorTextarea = document.getElementById('env-editor-content');
|
||||||
if (editorTextarea) {
|
if (editorTextarea) {
|
||||||
editorTextarea.value = this.currentContent;
|
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) {
|
showPreviewModal(record) {
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ router.post('/env', async (req, res) => {
|
|||||||
|
|
||||||
// Write updated content to disk
|
// Write updated content to disk
|
||||||
fs.writeFileSync(envPath, content, 'utf8');
|
fs.writeFileSync(envPath, content, 'utf8');
|
||||||
|
try { require('dotenv').config({ path: envPath, override: true }); } catch (_) {}
|
||||||
|
|
||||||
// Save snapshot in history table
|
// Save snapshot in history table
|
||||||
const info = db.prepare(`
|
const info = db.prepare(`
|
||||||
@@ -112,6 +113,7 @@ router.post('/env/restore/:history_id', async (req, res) => {
|
|||||||
|
|
||||||
// Write snapshot content to disk
|
// Write snapshot content to disk
|
||||||
fs.writeFileSync(envPath, record.content, 'utf8');
|
fs.writeFileSync(envPath, record.content, 'utf8');
|
||||||
|
try { require('dotenv').config({ path: envPath, override: true }); } catch (_) {}
|
||||||
|
|
||||||
// Insert new history record documenting the restore operation
|
// Insert new history record documenting the restore operation
|
||||||
const restoreNote = `Ripristinato alla versione #${record.id} del ${record.created_at}`;
|
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;
|
module.exports = router;
|
||||||
+1
-1
@@ -147,7 +147,7 @@ router.get('/config', async (req, res) => {
|
|||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
defaultAgentLogin: process.env.OTRS_API_USER || '',
|
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,
|
phraseThreshold: parseInt(process.env.PHRASE_THRESHOLD, 10) || 70,
|
||||||
autoTimeMinHour: process.env.AUTO_TIME_MIN_HOUR || '18:00',
|
autoTimeMinHour: process.env.AUTO_TIME_MIN_HOUR || '18:00',
|
||||||
helpdeskEmail: process.env.OTRS_MAIL_BCC || '',
|
helpdeskEmail: process.env.OTRS_MAIL_BCC || '',
|
||||||
|
|||||||
+2
-2
@@ -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 workDaysRaw = process.env.WORK_DAYS || '1,2,3,4,5';
|
||||||
const workDays = workDaysRaw.split(',').map(x => parseInt(x.trim(), 10)).filter(x => !isNaN(x));
|
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');
|
await client.query('BEGIN');
|
||||||
|
|
||||||
// 1. Calculate remaining time
|
// 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(
|
const timeTodayRes = await client.query(
|
||||||
`SELECT COALESCE(SUM(time_unit), 0) AS total_today
|
`SELECT COALESCE(SUM(time_unit), 0) AS total_today
|
||||||
FROM time_accounting
|
FROM time_accounting
|
||||||
|
|||||||
Reference in new issue
Block a user