diff --git a/activityDb.js b/activityDb.js index 0bcac8d..5b008e9 100644 --- a/activityDb.js +++ b/activityDb.js @@ -90,17 +90,18 @@ db.exec(` db.exec(` CREATE TABLE IF NOT EXISTS dashboard_chart_lines ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - name TEXT NOT NULL, - statuses TEXT NOT NULL, - types TEXT NOT NULL, - queues TEXT NOT NULL, - owners TEXT NOT NULL, - responsibles TEXT NOT NULL, - color TEXT, - is_visible INTEGER NOT NULL DEFAULT 1, - is_default INTEGER NOT NULL DEFAULT 0, - created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')) + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + statuses TEXT NOT NULL, + types TEXT NOT NULL, + queues TEXT NOT NULL, + owners TEXT NOT NULL, + responsibles TEXT NOT NULL, + color TEXT, + is_visible INTEGER NOT NULL DEFAULT 1, + is_default INTEGER NOT NULL DEFAULT 0, + bypass_state_filter INTEGER NOT NULL DEFAULT 0, + created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')) ) `); @@ -116,22 +117,31 @@ try { // Already exists } +try { + db.exec(`ALTER TABLE dashboard_chart_lines ADD COLUMN bypass_state_filter INTEGER NOT NULL DEFAULT 0`); +} catch (e) { + // Already exists +} + try { const countRow = db.prepare("SELECT COUNT(*) AS count FROM dashboard_chart_lines").get(); if (countRow && countRow.count === 0) { db.prepare(` - INSERT INTO dashboard_chart_lines (name, statuses, types, queues, owners, responsibles, color, is_visible, is_default) - VALUES (?, ?, ?, ?, ?, ?, ?, 1, 1) + INSERT INTO dashboard_chart_lines (name, statuses, types, queues, owners, responsibles, color, is_visible, is_default, bypass_state_filter) + VALUES (?, ?, ?, ?, ?, ?, ?, 1, 1, 1) `).run('Ticket aperti', JSON.stringify([1, 4, 6, 7, 8]), '[]', '[]', '[]', '[]', '#4f46e5'); db.prepare(` - INSERT INTO dashboard_chart_lines (name, statuses, types, queues, owners, responsibles, color, is_visible, is_default) - VALUES (?, ?, ?, ?, ?, ?, ?, 1, 1) + INSERT INTO dashboard_chart_lines (name, statuses, types, queues, owners, responsibles, color, is_visible, is_default, bypass_state_filter) + VALUES (?, ?, ?, ?, ?, ?, ?, 1, 1, 0) `).run('Ticket chiusi', JSON.stringify([2, 3, 10]), '[]', '[]', '[]', '[]', '#10b981'); } else { // Update default ones color if not set yet db.prepare(`UPDATE dashboard_chart_lines SET color = '#4f46e5' WHERE name = 'Ticket aperti' AND color IS NULL`).run(); db.prepare(`UPDATE dashboard_chart_lines SET color = '#10b981' WHERE name = 'Ticket chiusi' AND color IS NULL`).run(); + + // Set default Ticket aperti to bypass state filter + db.prepare(`UPDATE dashboard_chart_lines SET bypass_state_filter = 1 WHERE name = 'Ticket aperti'`).run(); } } catch (e) { console.error("Error seeding default chart lines:", e.message); diff --git a/public/js/views/dashboard.js b/public/js/views/dashboard.js index 4906055..0478e37 100644 --- a/public/js/views/dashboard.js +++ b/public/js/views/dashboard.js @@ -311,6 +311,14 @@ const DashboardView = {
+
+ + +
+
@@ -413,6 +421,7 @@ const DashboardView = { const queues = this.getSelectedIds('form-select-queues'); const owners = this.getSelectedIds('form-select-owners'); const responsibles = this.getSelectedIds('form-select-responsibles'); + const bypass_state_filter = document.getElementById('form-series-bypass-state').checked ? 1 : 0; // Preserve current visibility if editing let is_visible = 1; @@ -421,7 +430,7 @@ const DashboardView = { if (existing) is_visible = existing.is_visible; } - const payload = { name, statuses, types, queues, owners, responsibles, color, is_visible }; + const payload = { name, statuses, types, queues, owners, responsibles, color, is_visible, bypass_state_filter }; try { if (seriesId) { @@ -726,6 +735,7 @@ const DashboardView = { idInput.value = line ? line.id : ''; nameInput.value = line ? line.name : ''; colorInput.value = line ? line.color : '#4f46e5'; + document.getElementById('form-series-bypass-state').checked = line ? !!line.bypass_state_filter : false; this.renderMultiselect('form-select-statuses', App.lookups.states || [], statuses); this.renderMultiselect('form-select-types', App.lookups.types || [], types); diff --git a/routes/dashboard.js b/routes/dashboard.js index 437e6c7..c5a06c7 100644 --- a/routes/dashboard.js +++ b/routes/dashboard.js @@ -257,13 +257,13 @@ router.get('/chart-lines', (req, res) => { // POST /api/dashboard/chart-lines router.post('/chart-lines', (req, res) => { - const { name, statuses, types, queues, owners, responsibles, color, is_visible } = req.body; + const { name, statuses, types, queues, owners, responsibles, color, is_visible, bypass_state_filter } = req.body; if (!name) return res.status(400).json({ error: 'Name is required' }); try { const info = db.prepare(` - INSERT INTO dashboard_chart_lines (name, statuses, types, queues, owners, responsibles, color, is_visible, is_default) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0) + INSERT INTO dashboard_chart_lines (name, statuses, types, queues, owners, responsibles, color, is_visible, is_default, bypass_state_filter) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0, ?) `).run( name, JSON.stringify(statuses || []), @@ -272,7 +272,8 @@ router.post('/chart-lines', (req, res) => { JSON.stringify(owners || []), JSON.stringify(responsibles || []), color || '#4f46e5', - is_visible !== undefined ? parseInt(is_visible, 10) : 1 + is_visible !== undefined ? parseInt(is_visible, 10) : 1, + bypass_state_filter !== undefined ? parseInt(bypass_state_filter, 10) : 0 ); res.json({ success: true, id: info.lastInsertRowid }); } catch (err) { @@ -284,13 +285,13 @@ router.post('/chart-lines', (req, res) => { // PUT /api/dashboard/chart-lines/:id router.put('/chart-lines/:id', (req, res) => { const { id } = req.params; - const { name, statuses, types, queues, owners, responsibles, color, is_visible } = req.body; + const { name, statuses, types, queues, owners, responsibles, color, is_visible, bypass_state_filter } = req.body; if (!name) return res.status(400).json({ error: 'Name is required' }); try { const info = db.prepare(` UPDATE dashboard_chart_lines - SET name = ?, statuses = ?, types = ?, queues = ?, owners = ?, responsibles = ?, color = ?, is_visible = ? + SET name = ?, statuses = ?, types = ?, queues = ?, owners = ?, responsibles = ?, color = ?, is_visible = ?, bypass_state_filter = ? WHERE id = ? `).run( name, @@ -301,6 +302,7 @@ router.put('/chart-lines/:id', (req, res) => { JSON.stringify(responsibles || []), color || '#4f46e5', is_visible !== undefined ? parseInt(is_visible, 10) : 1, + bypass_state_filter !== undefined ? parseInt(bypass_state_filter, 10) : 0, id ); if (info.changes === 0) return res.status(404).json({ error: 'Line not found' }); @@ -362,7 +364,7 @@ router.get('/chart-data', async (req, res) => { params.push(end_date + ' 23:59:59'); const statuses = JSON.parse(line.statuses || '[]'); - if (statuses.length > 0) { + if (statuses.length > 0 && !line.bypass_state_filter) { const placeholders = statuses.map(() => `$${paramIdx++}`).join(', '); conditions.push(`t.ticket_state_id IN (${placeholders})`); params.push(...statuses.map(id => parseInt(id))); @@ -473,7 +475,7 @@ router.get('/export-excel', async (req, res) => { params.push(end_date + ' 23:59:59'); const statuses = JSON.parse(line.statuses || '[]'); - if (statuses.length > 0) { + if (statuses.length > 0 && !line.bypass_state_filter) { const placeholders = statuses.map(() => `$${paramIdx++}`).join(', '); conditions.push(`t.ticket_state_id IN (${placeholders})`); params.push(...statuses.map(id => parseInt(id)));