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)));