big refactoring
This commit is contained in:
+2
-2
@@ -11,8 +11,8 @@ REPORTS_DIR = Path(__file__).resolve().parent.parent
|
||||
load_dotenv(REPORTS_DIR / '.env')
|
||||
|
||||
TMPL_DIR = REPORTS_DIR / "templates"
|
||||
CSS_PATH = REPORTS_DIR / "static" / "style.css"
|
||||
PAGES_CSS_DIR = REPORTS_DIR / "static" / "pages"
|
||||
CSS_PATH = REPORTS_DIR / "static" / "css" / "style.css"
|
||||
PAGES_CSS_DIR = REPORTS_DIR / "static" / "css"
|
||||
JS_DIR = REPORTS_DIR / "static" / "js"
|
||||
|
||||
class DbType(StrEnum):
|
||||
|
||||
@@ -20,6 +20,7 @@ def get_iscrizioni(db_path: str) -> list:
|
||||
i.updated_at
|
||||
FROM rpa_intra_api_iscrizione i
|
||||
LEFT JOIN rpa_mapping_aziende m ON m.id = i.azienda_sorgente_id
|
||||
WHERE date(i.created_at) >= date('now', '-10 days')
|
||||
ORDER BY i.id DESC
|
||||
LIMIT 500
|
||||
""")
|
||||
|
||||
@@ -20,6 +20,11 @@ def count(db_path: str, sql: str) -> int:
|
||||
return rows[0]['n'] if rows else 0
|
||||
|
||||
|
||||
def count_q(db_path: str, sql: str, params: tuple = ()) -> int:
|
||||
rows = query(db_path, sql, params)
|
||||
return rows[0]['n'] if rows else 0
|
||||
|
||||
|
||||
# ------------------------------------------------------------------ HTML utils
|
||||
|
||||
def e(v) -> str:
|
||||
|
||||
+13
-6
@@ -1,6 +1,6 @@
|
||||
"""queries/email.py — rpa_intra_email_queue (Intraz)"""
|
||||
|
||||
from .db import query, count, e, dt, badge
|
||||
from .db import query, count, count_q, e, dt, badge
|
||||
|
||||
|
||||
def get_email(db_path: str) -> list:
|
||||
@@ -8,16 +8,23 @@ def get_email(db_path: str) -> list:
|
||||
"SELECT id, iscrizione_id, recipient, subject, attachment_path, "
|
||||
"inviata, inviata_at, errore, created_at "
|
||||
"FROM rpa_intra_email_queue "
|
||||
"WHERE date(created_at) >= date('now', '-10 days') "
|
||||
"ORDER BY created_at DESC LIMIT 200"
|
||||
)
|
||||
|
||||
|
||||
def get_stats(db_path: str) -> dict:
|
||||
def get_stats(db_path: str, date_from: str = None, date_to: str = None) -> dict:
|
||||
conds, params = [], []
|
||||
if date_from: conds.append("date(created_at) >= ?"); params.append(date_from)
|
||||
if date_to: conds.append("date(created_at) <= ?"); params.append(date_to)
|
||||
where = (" WHERE " + " AND ".join(conds)) if conds else ""
|
||||
and_pfx = (" AND" if conds else " WHERE")
|
||||
t = tuple(params)
|
||||
return {
|
||||
'email_total': count(db_path, "SELECT COUNT(*) as n FROM rpa_intra_email_queue"),
|
||||
'email_inviata': count(db_path, "SELECT COUNT(*) as n FROM rpa_intra_email_queue WHERE inviata=1"),
|
||||
'email_errore': count(db_path, "SELECT COUNT(*) as n FROM rpa_intra_email_queue WHERE inviata=0 AND errore IS NOT NULL"),
|
||||
'email_pending': count(db_path, "SELECT COUNT(*) as n FROM rpa_intra_email_queue WHERE inviata=0 AND errore IS NULL"),
|
||||
'email_total': count_q(db_path, f"SELECT COUNT(*) as n FROM rpa_intra_email_queue{where}", t),
|
||||
'email_inviata': count_q(db_path, f"SELECT COUNT(*) as n FROM rpa_intra_email_queue{where}{and_pfx} inviata=1", t),
|
||||
'email_errore': count_q(db_path, f"SELECT COUNT(*) as n FROM rpa_intra_email_queue{where}{and_pfx} inviata=0 AND errore IS NOT NULL", t),
|
||||
'email_pending': count_q(db_path, f"SELECT COUNT(*) as n FROM rpa_intra_email_queue{where}{and_pfx} inviata=0 AND errore IS NULL", t),
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ def get_corsi(db_path: str) -> list:
|
||||
LEFT JOIN rpa_mapping_aziende m ON m.company_code = f.company_code
|
||||
LEFT JOIN rpa_intra_steps_status s ON s.rpa_intra_ftp_json_id = f.id
|
||||
LEFT JOIN rpa_intra_bc_check bc ON bc.rpa_intra_ftp_json_id = f.id
|
||||
WHERE date(f.created_at) >= date('now', '-10 days')
|
||||
ORDER BY f.id DESC
|
||||
""")
|
||||
|
||||
@@ -67,8 +68,18 @@ def _step_cell(step_val, err_val) -> str:
|
||||
return badge_html
|
||||
|
||||
|
||||
def get_stats(db_path: str) -> dict:
|
||||
rows = get_corsi(db_path)
|
||||
def get_stats(db_path: str, date_from: str = None, date_to: str = None) -> dict:
|
||||
conds, params = [], []
|
||||
if date_from: conds.append("date(f.created_at) >= ?"); params.append(date_from)
|
||||
if date_to: conds.append("date(f.created_at) <= ?"); params.append(date_to)
|
||||
where = (" WHERE " + " AND ".join(conds)) if conds else ""
|
||||
rows = query(db_path, f"""
|
||||
SELECT s.step_ftp, s.step_bc, s.step_iscrizione, s.step_odv,
|
||||
s.step_sharepoint, s.step_report, s.step_email
|
||||
FROM rpa_intra_ftp_json f
|
||||
LEFT JOIN rpa_intra_steps_status s ON s.rpa_intra_ftp_json_id = f.id
|
||||
{where}
|
||||
""", tuple(params))
|
||||
return {
|
||||
'isc_total': len(rows),
|
||||
'isc_ok': sum(1 for r in rows if all(r.get(s) in ('done', 'skipped') for s in _ALL_STEPS)),
|
||||
|
||||
+12
-4
@@ -1,6 +1,6 @@
|
||||
"""queries/logs.py — rpa_logs"""
|
||||
|
||||
from .db import query, count, e, dt, badge
|
||||
from .db import query, count, count_q, e, dt, badge
|
||||
|
||||
|
||||
def get_logs(db_path: str) -> list:
|
||||
@@ -8,6 +8,7 @@ def get_logs(db_path: str) -> list:
|
||||
"SELECT l.*, COALESCE(p.process_name, 'unknown') AS process_name "
|
||||
"FROM rpa_logs l "
|
||||
"LEFT JOIN rpa_process p ON p.id = l.rpa_process_id "
|
||||
"WHERE date(l.date_log) >= date('now', '-10 days') "
|
||||
"ORDER BY l.date_log DESC LIMIT 500")
|
||||
|
||||
|
||||
@@ -19,6 +20,7 @@ def get_last_run_ids(db_path: str, n: int = 20) -> list:
|
||||
"FROM rpa_logs l "
|
||||
"LEFT JOIN rpa_process p ON p.id = l.rpa_process_id "
|
||||
"WHERE l.rpa_process_id IS NOT NULL "
|
||||
"AND date(l.date_log) >= date('now', '-10 days') "
|
||||
"GROUP BY l.rpa_process_id ORDER BY l.rpa_process_id DESC LIMIT ?", (n,))
|
||||
|
||||
|
||||
@@ -30,10 +32,16 @@ def get_logs_by_run(db_path: str, run_id: int) -> list:
|
||||
"WHERE l.rpa_process_id=? ORDER BY l.date_log DESC", (run_id,))
|
||||
|
||||
|
||||
def get_stats(db_path: str) -> dict:
|
||||
def get_stats(db_path: str, date_from: str = None, date_to: str = None) -> dict:
|
||||
conds, params = [], []
|
||||
if date_from: conds.append("date(date_log) >= ?"); params.append(date_from)
|
||||
if date_to: conds.append("date(date_log) <= ?"); params.append(date_to)
|
||||
where = (" WHERE " + " AND ".join(conds)) if conds else ""
|
||||
and_pfx = (" AND" if conds else " WHERE")
|
||||
t = tuple(params)
|
||||
return {
|
||||
'log_errors': count(db_path, "SELECT COUNT(*) as n FROM rpa_logs WHERE type='error'"),
|
||||
'log_warnings': count(db_path, "SELECT COUNT(*) as n FROM rpa_logs WHERE type='warning'"),
|
||||
'log_errors': count_q(db_path, f"SELECT COUNT(*) as n FROM rpa_logs{where}{and_pfx} type='error'", t),
|
||||
'log_warnings': count_q(db_path, f"SELECT COUNT(*) as n FROM rpa_logs{where}{and_pfx} type='warning'", t),
|
||||
}
|
||||
|
||||
|
||||
|
||||
+13
-7
@@ -1,6 +1,6 @@
|
||||
"""queries/pec.py — pec_comunicazioni"""
|
||||
|
||||
from .db import query, count, e, dt, badge
|
||||
from .db import query, count, count_q, e, dt, badge
|
||||
|
||||
_PEC_JOIN = """
|
||||
SELECT
|
||||
@@ -16,15 +16,21 @@ _PEC_JOIN = """
|
||||
|
||||
|
||||
def get_pec(db_path: str) -> list:
|
||||
return query(db_path, _PEC_JOIN + "ORDER BY p.created_at DESC LIMIT 200")
|
||||
return query(db_path, _PEC_JOIN + "WHERE date(p.created_at) >= date('now', '-10 days') ORDER BY p.created_at DESC LIMIT 200")
|
||||
|
||||
|
||||
def get_stats(db_path: str) -> dict:
|
||||
def get_stats(db_path: str, date_from: str = None, date_to: str = None) -> dict:
|
||||
conds, params = [], []
|
||||
if date_from: conds.append("date(created_at) >= ?"); params.append(date_from)
|
||||
if date_to: conds.append("date(created_at) <= ?"); params.append(date_to)
|
||||
where = (" WHERE " + " AND ".join(conds)) if conds else ""
|
||||
and_pfx = (" AND" if conds else " WHERE")
|
||||
t = tuple(params)
|
||||
return {
|
||||
'total_pec': count(db_path, "SELECT COUNT(*) as n FROM pec_comunicazioni"),
|
||||
'pec_inviato': count(db_path, "SELECT COUNT(*) as n FROM pec_comunicazioni WHERE stato_invio='inviata'"),
|
||||
'pec_errore': count(db_path, "SELECT COUNT(*) as n FROM pec_comunicazioni WHERE stato_invio='errore'"),
|
||||
'pec_pending': count(db_path, "SELECT COUNT(*) as n FROM pec_comunicazioni WHERE stato_invio='pending'"),
|
||||
'total_pec': count_q(db_path, f"SELECT COUNT(*) as n FROM pec_comunicazioni{where}", t),
|
||||
'pec_inviato': count_q(db_path, f"SELECT COUNT(*) as n FROM pec_comunicazioni{where}{and_pfx} stato_invio='inviata'", t),
|
||||
'pec_errore': count_q(db_path, f"SELECT COUNT(*) as n FROM pec_comunicazioni{where}{and_pfx} stato_invio='errore'", t),
|
||||
'pec_pending': count_q(db_path, f"SELECT COUNT(*) as n FROM pec_comunicazioni{where}{and_pfx} stato_invio='pending'", t),
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,18 +1,27 @@
|
||||
"""queries/processes.py — rpa_process"""
|
||||
|
||||
from .db import query, count, e, dt, dur, badge
|
||||
from .db import query, count, count_q, e, dt, dur, badge
|
||||
|
||||
|
||||
def get_processes(db_path: str) -> list:
|
||||
return query(db_path, "SELECT id, process_name, note, completed, start_run, finish_run FROM rpa_process ORDER BY id DESC LIMIT 50")
|
||||
return query(db_path,
|
||||
"SELECT id, process_name, note, completed, start_run, finish_run FROM rpa_process "
|
||||
"WHERE date(start_run) >= date('now', '-10 days') "
|
||||
"ORDER BY id DESC LIMIT 50")
|
||||
|
||||
|
||||
def get_stats(db_path: str) -> dict:
|
||||
total = count(db_path, "SELECT COUNT(*) as n FROM rpa_process")
|
||||
completed = count(db_path, "SELECT COUNT(*) as n FROM rpa_process WHERE completed = 1")
|
||||
def get_stats(db_path: str, date_from: str = None, date_to: str = None) -> dict:
|
||||
conds, params = [], []
|
||||
if date_from: conds.append("date(start_run) >= ?"); params.append(date_from)
|
||||
if date_to: conds.append("date(start_run) <= ?"); params.append(date_to)
|
||||
where = (" WHERE " + " AND ".join(conds)) if conds else ""
|
||||
and_pfx = (" AND" if conds else " WHERE")
|
||||
t = tuple(params)
|
||||
total = count_q(db_path, f"SELECT COUNT(*) as n FROM rpa_process{where}", t)
|
||||
completed = count_q(db_path, f"SELECT COUNT(*) as n FROM rpa_process{where}{and_pfx} completed=1", t)
|
||||
return {
|
||||
'total_runs': total,
|
||||
'completed_runs': completed,
|
||||
'total_runs': total,
|
||||
'completed_runs': completed,
|
||||
'incomplete_runs': total - completed,
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,9 @@ def get_report(db_path: str, da_data: str = None, a_data: str = None) -> list:
|
||||
where.append("sc.rilevato_at <= ?")
|
||||
params.append(a_data + " 23:59:59")
|
||||
|
||||
where_sql = ("WHERE " + " AND ".join(where)) if where else ""
|
||||
if not where:
|
||||
where.append("date(sc.rilevato_at) >= date('now', '-10 days')")
|
||||
where_sql = "WHERE " + " AND ".join(where)
|
||||
|
||||
sql = f"""
|
||||
SELECT
|
||||
|
||||
@@ -14,6 +14,7 @@ def get_sharepoint(db_path: str) -> list:
|
||||
json_extract(f.azienda, '$.ragione_sociale') AS azienda_nome
|
||||
FROM rpa_intra_sharepoint sp
|
||||
LEFT JOIN rpa_intra_ftp_json f ON f.id = sp.rpa_intra_ftp_json_id
|
||||
WHERE date(sp.created_at) >= date('now', '-10 days')
|
||||
ORDER BY sp.id DESC
|
||||
LIMIT 500
|
||||
""")
|
||||
|
||||
+21
-13
@@ -10,29 +10,37 @@ def _css() -> str:
|
||||
return CSS_PATH.read_text(encoding='utf-8')
|
||||
|
||||
|
||||
def _page_subdirs(base: Path) -> list:
|
||||
"""Return direct subdirectories of base, excluding 'shared'."""
|
||||
return [d for d in sorted(base.iterdir()) if d.is_dir() and d.name != 'shared']
|
||||
|
||||
|
||||
def _page_css(name: str) -> str:
|
||||
parts = []
|
||||
shared = PAGES_CSS_DIR / 'filters.css'
|
||||
if shared.exists():
|
||||
parts.append(shared.read_text(encoding='utf-8'))
|
||||
main = PAGES_CSS_DIR / f'{name}.css'
|
||||
if main.exists():
|
||||
parts.append(main.read_text(encoding='utf-8'))
|
||||
for f in sorted(PAGES_CSS_DIR.glob(f'{name}_*.css')):
|
||||
parts.append(f.read_text(encoding='utf-8'))
|
||||
for search_dir in [PAGES_CSS_DIR] + _page_subdirs(PAGES_CSS_DIR):
|
||||
main = search_dir / f'{name}.css'
|
||||
if main.exists():
|
||||
parts.append(main.read_text(encoding='utf-8'))
|
||||
for f in sorted(search_dir.glob(f'{name}_*.css')):
|
||||
parts.append(f.read_text(encoding='utf-8'))
|
||||
return '\n'.join(parts)
|
||||
|
||||
|
||||
def _page_js(name: str) -> str:
|
||||
parts = []
|
||||
shared = JS_DIR / 'filters.js'
|
||||
if shared.exists():
|
||||
parts.append(shared.read_text(encoding='utf-8'))
|
||||
main = JS_DIR / f'{name}.js'
|
||||
if main.exists():
|
||||
parts.append(main.read_text(encoding='utf-8'))
|
||||
for f in sorted(JS_DIR.glob(f'{name}_*.js')):
|
||||
parts.append(f.read_text(encoding='utf-8'))
|
||||
shared_dir = JS_DIR / 'shared'
|
||||
if shared_dir.exists():
|
||||
for f in sorted(shared_dir.glob('*.js')):
|
||||
parts.append(f.read_text(encoding='utf-8'))
|
||||
for search_dir in [JS_DIR] + _page_subdirs(JS_DIR):
|
||||
main = search_dir / f'page_{name}.js'
|
||||
if main.exists():
|
||||
parts.append(main.read_text(encoding='utf-8'))
|
||||
for f in sorted(search_dir.glob(f'page_{name}_*.js')):
|
||||
parts.append(f.read_text(encoding='utf-8'))
|
||||
return '\n'.join(parts)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
/* dashboard.css — stili specifici per la pagina Dashboard */
|
||||
.sec-link{color:inherit;text-decoration:none}
|
||||
.sec-link:hover{text-decoration:underline;text-underline-offset:3px}
|
||||
|
||||
/* Section collapse toggle */
|
||||
.sec-toggle-btn{background:none;border:none;cursor:pointer;padding:0 0 0 .5rem;vertical-align:middle;color:inherit;opacity:.6;line-height:1}
|
||||
.sec-toggle-btn:hover{opacity:1}
|
||||
.sec-toggle-arrow{width:1.1em;height:1.1em;display:inline-block;transition:transform .22s ease;transform:rotate(-90deg)}
|
||||
.sec-toggle-arrow.open{transform:rotate(0deg)}
|
||||
.dash-grid-hidden{display:none}
|
||||
@@ -13,7 +13,7 @@
|
||||
}
|
||||
|
||||
var COLS = ['sorgente', 'azienda', 'sessione', 'corso', 'data',
|
||||
'ftp', 'bc', 'iscrizione', 'odv', 'sharepoint', 'report', 'email'];
|
||||
'ftp', 'bc', 'iscrizione', 'odv_number', 'odv', 'sharepoint', 'report', 'email'];
|
||||
var STEP_COLS = ['ftp', 'bc', 'iscrizione', 'odv', 'sharepoint', 'report', 'email'];
|
||||
var BADGE_CLS = { done: 'ok', processing: 'proc', pending: 'warn', error: 'err', skipped: 'info' };
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
(function () {
|
||||
// ── Section collapse (visible by default) ────────────────────────────────
|
||||
document.querySelectorAll('section:not(.page-header)').forEach(function (sec, idx) {
|
||||
var grid = sec.querySelector('.grid');
|
||||
if (!grid) return;
|
||||
var h2 = sec.querySelector('h2');
|
||||
if (!h2) return;
|
||||
|
||||
var key = 'dash_sec_' + idx;
|
||||
var isOpen = (sessionStorage.getItem(key) !== 'closed');
|
||||
|
||||
grid.classList.toggle('dash-grid-hidden', !isOpen);
|
||||
|
||||
var btn = document.createElement('button');
|
||||
btn.className = 'sec-toggle-btn';
|
||||
btn.title = 'Espandi / Comprimi';
|
||||
btn.innerHTML = (
|
||||
'<svg class="sec-toggle-arrow' + (isOpen ? ' open' : '') + '"'
|
||||
+ ' viewBox="0 0 24 24" fill="none" stroke="currentColor"'
|
||||
+ ' stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">'
|
||||
+ '<polyline points="6 9 12 15 18 9"/></svg>'
|
||||
);
|
||||
h2.appendChild(btn);
|
||||
|
||||
btn.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var hidden = grid.classList.toggle('dash-grid-hidden');
|
||||
var arrow = btn.querySelector('.sec-toggle-arrow');
|
||||
if (arrow) arrow.classList.toggle('open', !hidden);
|
||||
try { sessionStorage.setItem(key, hidden ? 'closed' : 'open'); } catch(e2) {}
|
||||
});
|
||||
});
|
||||
})();
|
||||
@@ -5,42 +5,29 @@
|
||||
var pgSelect = document.getElementById('pg-run-select');
|
||||
var dateFrom = document.getElementById('filter-date-from');
|
||||
var dateTo = document.getElementById('filter-date-to');
|
||||
var filterBtn = document.getElementById('filter-date-btn');
|
||||
|
||||
var STORAGE_KEY = 'logs_pn_filter';
|
||||
var STORAGE_KEY_DATE = 'logs_date_filter';
|
||||
var STORAGE_KEY_ACTIVE = 'logs_date_active';
|
||||
|
||||
function toIsoDate(d) { return d.toISOString().slice(0, 10); }
|
||||
|
||||
// ── Restore / default date range ──────────────────────────────────────────
|
||||
function loadSavedDates() {
|
||||
try { return JSON.parse(sessionStorage.getItem(STORAGE_KEY_DATE) || 'null'); } catch(e) { return null; }
|
||||
}
|
||||
function saveDates() {
|
||||
try {
|
||||
sessionStorage.setItem(STORAGE_KEY_DATE, JSON.stringify({
|
||||
from: dateFrom ? dateFrom.value : '',
|
||||
to: dateTo ? dateTo.value : '',
|
||||
}));
|
||||
sessionStorage.setItem(STORAGE_KEY_ACTIVE, '1');
|
||||
} catch(e) {}
|
||||
}
|
||||
|
||||
var dateActive = (function() {
|
||||
try { return sessionStorage.getItem(STORAGE_KEY_ACTIVE) === '1'; } catch(e) { return false; }
|
||||
})();
|
||||
|
||||
var savedDates = loadSavedDates();
|
||||
if (savedDates) {
|
||||
if (dateFrom) dateFrom.value = savedDates.from || '';
|
||||
if (dateTo) dateTo.value = savedDates.to || '';
|
||||
} else {
|
||||
var today = new Date();
|
||||
var twoWeeksAgo = new Date(today); twoWeeksAgo.setDate(today.getDate() - 14);
|
||||
if (dateFrom) dateFrom.value = toIsoDate(twoWeeksAgo);
|
||||
if (dateTo) dateTo.value = toIsoDate(today);
|
||||
}
|
||||
// ── Date range filter (client-side DOM filtering) ─────────────────────────
|
||||
window.initDateRangeFilter({
|
||||
storageKey: 'logs_date_filter',
|
||||
readUrlParams: false,
|
||||
defaultFrom: function () {
|
||||
var d = new Date(); d.setDate(d.getDate() - 14); return d.toISOString().slice(0, 10);
|
||||
},
|
||||
defaultTo: function () { return new Date().toISOString().slice(0, 10); },
|
||||
onFilter: function () {
|
||||
console.log('[logs] filtra clicked — from:', dateFrom && dateFrom.value, 'to:', dateTo && dateTo.value);
|
||||
dateActive = true;
|
||||
try { sessionStorage.setItem(STORAGE_KEY_ACTIVE, '1'); } catch(e) {}
|
||||
applyFilter();
|
||||
filterSelect();
|
||||
},
|
||||
});
|
||||
|
||||
// ── Process-name checkboxes (built from pagination select options) ─────────
|
||||
var names = [];
|
||||
@@ -53,12 +40,12 @@
|
||||
}
|
||||
|
||||
function loadSaved() {
|
||||
try { return JSON.parse(sessionStorage.getItem(STORAGE_KEY) || '{}'); } catch(e) { return {}; }
|
||||
try { return JSON.parse(sessionStorage.getItem('logs_pn_filter') || '{}'); } catch(e) { return {}; }
|
||||
}
|
||||
function saveState() {
|
||||
var state = {};
|
||||
Object.keys(pnChecks).forEach(function(n){ state[n] = pnChecks[n].checked; });
|
||||
try { sessionStorage.setItem(STORAGE_KEY, JSON.stringify(state)); } catch(e) {}
|
||||
try { sessionStorage.setItem('logs_pn_filter', JSON.stringify(state)); } catch(e) {}
|
||||
}
|
||||
|
||||
var pnChecks = {};
|
||||
@@ -124,17 +111,6 @@
|
||||
});
|
||||
}
|
||||
|
||||
// ── Filter button — saves dates then applies both filters ─────────────────
|
||||
if (filterBtn) {
|
||||
filterBtn.addEventListener('click', function() {
|
||||
console.log('[logs] filtra clicked — from:', dateFrom && dateFrom.value, 'to:', dateTo && dateTo.value);
|
||||
dateActive = true;
|
||||
saveDates();
|
||||
applyFilter();
|
||||
filterSelect();
|
||||
});
|
||||
}
|
||||
|
||||
if (search) search.addEventListener('input', function() {
|
||||
console.log('[logs] search input:', search.value);
|
||||
applyFilter();
|
||||
@@ -0,0 +1,92 @@
|
||||
// filters/generic_filters.js — shared date-range filter initialiser
|
||||
//
|
||||
// Usage:
|
||||
// var df = window.initDateRangeFilter({
|
||||
// storageKey: 'my_page_date_filter', // sessionStorage key
|
||||
// defaultFrom: function() { return '2025-01-01'; },
|
||||
// defaultTo: function() { return '2025-01-02'; },
|
||||
// readUrlParams: true, // sync from/to URL params on load (for server-side pages)
|
||||
// onFilter: function(from, to) { ... },
|
||||
// onReset: function() { ... }, // optional
|
||||
// });
|
||||
// // df.getDates() → { from, to }
|
||||
|
||||
window.initDateRangeFilter = function (opts) {
|
||||
var dateFrom = document.getElementById('filter-date-from');
|
||||
var dateTo = document.getElementById('filter-date-to');
|
||||
var filterBtn = document.getElementById('filter-date-btn');
|
||||
var resetBtn = document.getElementById('filter-date-reset');
|
||||
|
||||
function toIsoDate(d) { return d.toISOString().slice(0, 10); }
|
||||
|
||||
function getUrlParam(name) {
|
||||
try { return new URLSearchParams(window.location.search).get(name); } catch(e) { return null; }
|
||||
}
|
||||
|
||||
function loadSaved() {
|
||||
try { return JSON.parse(sessionStorage.getItem(opts.storageKey) || 'null'); } catch(e) { return null; }
|
||||
}
|
||||
|
||||
function saveDates(from, to) {
|
||||
try { sessionStorage.setItem(opts.storageKey, JSON.stringify({ from: from, to: to })); } catch(e) {}
|
||||
}
|
||||
|
||||
function clearSaved() {
|
||||
try { sessionStorage.removeItem(opts.storageKey); } catch(e) {}
|
||||
}
|
||||
|
||||
// ── Initialise input values ───────────────────────────────────────────────
|
||||
var initFrom = '', initTo = '';
|
||||
|
||||
if (opts.readUrlParams) {
|
||||
var urlFrom = getUrlParam('from');
|
||||
var urlTo = getUrlParam('to');
|
||||
if (urlFrom || urlTo) {
|
||||
initFrom = urlFrom || '';
|
||||
initTo = urlTo || '';
|
||||
saveDates(initFrom, initTo);
|
||||
}
|
||||
}
|
||||
|
||||
if (!initFrom && !initTo) {
|
||||
var saved = loadSaved();
|
||||
if (saved) {
|
||||
initFrom = saved.from || '';
|
||||
initTo = saved.to || '';
|
||||
} else {
|
||||
initFrom = opts.defaultFrom ? opts.defaultFrom() : '';
|
||||
initTo = opts.defaultTo ? opts.defaultTo() : '';
|
||||
}
|
||||
}
|
||||
|
||||
if (dateFrom) dateFrom.value = initFrom;
|
||||
if (dateTo) dateTo.value = initTo;
|
||||
|
||||
// ── Wire buttons ─────────────────────────────────────────────────────────
|
||||
if (filterBtn) {
|
||||
filterBtn.addEventListener('click', function () {
|
||||
var from = dateFrom ? dateFrom.value : '';
|
||||
var to = dateTo ? dateTo.value : '';
|
||||
saveDates(from, to);
|
||||
if (opts.onFilter) opts.onFilter(from, to);
|
||||
});
|
||||
}
|
||||
|
||||
if (resetBtn && opts.onReset) {
|
||||
resetBtn.addEventListener('click', function () {
|
||||
clearSaved();
|
||||
opts.onReset();
|
||||
});
|
||||
}
|
||||
|
||||
// ── Public API ────────────────────────────────────────────────────────────
|
||||
return {
|
||||
getDates: function () {
|
||||
return {
|
||||
from: dateFrom ? dateFrom.value : '',
|
||||
to: dateTo ? dateTo.value : '',
|
||||
};
|
||||
},
|
||||
toIsoDate: toIsoDate,
|
||||
};
|
||||
};
|
||||
@@ -1,3 +0,0 @@
|
||||
/* dashboard.css — stili specifici per la pagina Dashboard */
|
||||
.sec-link{color:inherit;text-decoration:none}
|
||||
.sec-link:hover{text-decoration:underline;text-underline-offset:3px}
|
||||
Reference in New Issue
Block a user