From 687b929170ce7fa54615f78af1adaf464037915c Mon Sep 17 00:00:00 2001 From: Niek Rabelink Date: Tue, 15 Sep 2026 18:40:16 +0200 Subject: [PATCH] Jira22 --- jira.php | 116 +++++++++++++++++++++++++++++++--------------------- planner.php | 8 ++-- 2 files changed, 73 insertions(+), 51 deletions(-) diff --git a/jira.php b/jira.php index 03cf8e4..b1b0bc3 100644 --- a/jira.php +++ b/jira.php @@ -984,6 +984,17 @@ function getDeduplicatedIssues() { return list; } +// Hulpfunctie voor het betrouwbaar achterhalen van de projectcode van een issue +function getIssueProjectKey(iss) { + if (!iss) return ''; + let k = (iss.project_key || '').toUpperCase().trim(); + if (!k && iss.key) { + const m = iss.key.match(/^([A-Z0-9]+)-/i); + if (m) k = m[1].toUpperCase().trim(); + } + return k; +} + function isDoneStatus(st) { const s = (st || '').toLowerCase().trim(); return s.includes('done') || s.includes('gesloten') || s.includes('afgerond') || s.includes('gereed') || s.includes('closed') || s.includes('resolved'); @@ -1085,16 +1096,13 @@ function getTotalStatusCount() { // Hulpfunctie: Bepaal of de status van een ticket geselecteerd is (ondersteunt compound keys en statusnamen) function isIssueStatusSelected(iss) { const total = getTotalStatusCount(); - if (selectedStatuses.size === 0) return false; + if (total === 0) return true; + if (selectedStatuses.size === 0) return true; if (selectedStatuses.size >= total) return true; - let issPKey = (iss.project_key || '').toUpperCase().trim(); - if (!issPKey && iss.key) { - const m = iss.key.match(/^([A-Z0-9]+)-/i); - if (m) issPKey = m[1].toUpperCase(); - } + const issPKey = getIssueProjectKey(iss).toLowerCase(); const issStatus = (iss.status || '').toLowerCase().trim(); - const compound = issPKey ? `${issPKey.toLowerCase()}::${issStatus}` : ''; + const compound = issPKey ? `${issPKey}::${issStatus}` : ''; if (compound && selectedStatuses.has(compound)) return true; if (selectedStatuses.has(issStatus)) return true; @@ -1219,13 +1227,10 @@ function updateStatusCounts() { (projectStatusesData || []).forEach(proj => { const pKey = (proj.key || '').toUpperCase().trim(); let projIssues = all.filter(iss => { - let k = (iss.project_key || '').toUpperCase().trim(); - if (!k && iss.key) { - const parts = iss.key.split('-'); - if (parts.length > 1) k = parts[0].toUpperCase().trim(); - } + const k = getIssueProjectKey(iss); const pn = (iss.project || '').toUpperCase().trim(); - return k === pKey || pn.includes(pKey); + if (k) return k === pKey; + return pn.includes(pKey); }); // Wachtrij filter meenemen indien actief @@ -1394,16 +1399,16 @@ function initStatusSelection() { let validSaved = false; if (Array.isArray(saved) && saved.length > 0) { - const hasCompound = saved.some(s => String(s).includes('::')); - if (hasCompound) { - saved.forEach(s => { - if (s) selectedStatuses.add(String(s).toLowerCase().trim()); - }); + saved.forEach(s => { + if (s) selectedStatuses.add(String(s).toLowerCase().trim()); + }); + if (selectedStatuses.size > 0) { validSaved = true; } } - if (!validSaved) { + if (!validSaved || selectedStatuses.size === 0) { + selectedStatuses.clear(); // Standaard alle actieve statussen selecteren, gesloten uit conform gebruikerswens (projectStatusesData || []).forEach(proj => { const pKeyLower = (proj.key || '').toLowerCase().trim(); @@ -1425,6 +1430,16 @@ function initStatusSelection() { }); }); } + if (selectedStatuses.size === 0) { + const all = getDeduplicatedIssues(); + all.forEach(iss => { + const pk = getIssueProjectKey(iss).toLowerCase(); + const st = (iss.status || '').toLowerCase().trim(); + if (st && !isDoneStatus(st)) { + selectedStatuses.add(pk ? `${pk}::${st}` : st); + } + }); + } } renderStatusCheckboxes(); @@ -1505,7 +1520,9 @@ function matchJqlClause(iss, jql) { const projEqMatch = cond.match(/^project\s*=\s*["']?([A-Z0-9_-]+)["']?$/i); if (projEqMatch) { const req = projEqMatch[1].toUpperCase().trim(); - if (issPKey !== req && !issPName.includes(req.toLowerCase())) { + if (issPKey) { + if (issPKey !== req) return false; + } else if (!issPName.includes(req.toLowerCase()) && !(req === 'SD' && issPName.includes('servicedesk'))) { return false; } continue; @@ -1515,7 +1532,9 @@ function matchJqlClause(iss, jql) { const projNeqMatch = cond.match(/^project\s*!=\s*["']?([A-Z0-9_-]+)["']?$/i); if (projNeqMatch) { const notReq = projNeqMatch[1].toUpperCase().trim(); - if (issPKey === notReq || issPName.includes(notReq.toLowerCase())) { + if (issPKey) { + if (issPKey === notReq) return false; + } else if (issPName.includes(notReq.toLowerCase()) || (notReq === 'SD' && issPName.includes('servicedesk'))) { return false; } continue; @@ -1525,7 +1544,9 @@ function matchJqlClause(iss, jql) { const projInMatch = cond.match(/^project\s+in\s*\(([^)]+)\)$/i); if (projInMatch) { const allowed = projInMatch[1].split(',').map(s => s.replace(/["']/g, '').toUpperCase().trim()); - if (!allowed.includes(issPKey) && !allowed.some(p => issPName.includes(p.toLowerCase()))) { + if (issPKey) { + if (!allowed.includes(issPKey)) return false; + } else if (!allowed.some(p => issPName.includes(p.toLowerCase()) || (p === 'SD' && issPName.includes('servicedesk')))) { return false; } continue; @@ -1535,7 +1556,9 @@ function matchJqlClause(iss, jql) { const projNotInMatch = cond.match(/^project\s+not\s+in\s*\(([^)]+)\)$/i); if (projNotInMatch) { const disallowed = projNotInMatch[1].split(',').map(s => s.replace(/["']/g, '').toUpperCase().trim()); - if (disallowed.includes(issPKey) || disallowed.some(p => issPName.includes(p.toLowerCase()))) { + if (issPKey) { + if (disallowed.includes(issPKey)) return false; + } else if (disallowed.some(p => issPName.includes(p.toLowerCase()) || (p === 'SD' && issPName.includes('servicedesk')))) { return false; } continue; @@ -1674,7 +1697,9 @@ function isIssueInQueue(iss, qCode) { // Project key validatie indien expliciet in filter ingesteld if (fObj.project_key) { const filterPKey = fObj.project_key.toUpperCase().trim(); - if (pKey !== filterPKey && !pName.includes(filterPKey.toLowerCase())) { + if (pKey) { + if (pKey !== filterPKey) return false; + } else if (!pName.includes(filterPKey.toLowerCase())) { return false; } } @@ -1685,32 +1710,32 @@ function isIssueInQueue(iss, qCode) { // Als er alleen een project_key was zonder nadere jql_clause: if (fObj.project_key) { const filterPKey = fObj.project_key.toUpperCase().trim(); - return pKey === filterPKey || pName.includes(filterPKey.toLowerCase()); + return pKey ? (pKey === filterPKey) : pName.includes(filterPKey.toLowerCase()); } } // 2. Fallbacks voor standaard wachtrijen (als er geen filter in de database staat) if (code === 'DX') { - const isSd = (pKey === 'SD' || pName.includes('servicedesk')); + const isSd = pKey ? (pKey === 'SD') : pName.includes('servicedesk'); if (!isSd) return false; const dxTerms = ['koppeling', 'sso', 'endpoint', 'rest', 'datadump', 'uwv', 'migratie']; return dxTerms.some(t => ol.includes(t) || sum.includes(t)); } if (code === 'SD') { - return (pKey === 'SD' || pName.includes('servicedesk')); + return pKey ? (pKey === 'SD') : pName.includes('servicedesk'); } if (code === 'IN') { - return (pKey === 'IN' || pName.includes('interface')); + return pKey ? (pKey === 'IN') : pName.includes('interface'); } if (code === 'AAN') { - return (pKey === 'AAN' || pName.includes('aanvraag')); + return pKey ? (pKey === 'AAN') : pName.includes('aanvraag'); } if (code === 'GEN') { - return (pKey === 'GEN' || pName.includes('general') || pName.includes('algemeen')); + return pKey ? (pKey === 'GEN') : (pName.includes('general') || pName.includes('algemeen')); } return true; @@ -1742,8 +1767,6 @@ function updateProjectCounts() { if (selectedStatuses.size > 0 && selectedStatuses.size < total) { currentList = currentList.filter(iss => isIssueStatusSelected(iss)); - } else if (selectedStatuses.size === 0) { - currentList = []; } const elAll = document.getElementById('projCount_all'); @@ -1755,7 +1778,7 @@ function updateProjectCounts() { const cnt = currentList.filter(iss => { const pk = getIssueProjectKey(iss); const pn = (iss.project || '').toLowerCase().trim(); - if (pk === key) return true; + if (pk) return pk === key; if (key === 'SD' && pn.includes('servicedesk')) return true; if (key === 'IN' && pn.includes('interface')) return true; if (key === 'AAN' && pn.includes('aanvraag')) return true; @@ -1774,8 +1797,6 @@ function updateQueueCounts() { if (selectedStatuses.size > 0 && selectedStatuses.size < total) { currentList = currentList.filter(iss => isIssueStatusSelected(iss)); - } else if (selectedStatuses.size === 0) { - currentList = []; } if (currentProject) { @@ -1783,7 +1804,8 @@ function updateQueueCounts() { currentList = currentList.filter(iss => { const pk = getIssueProjectKey(iss); const pn = (iss.project || '').trim().toLowerCase(); - return pk === pNorm || pn.includes(pNorm.toLowerCase()); + if (pk) return pk === pNorm; + return pn.includes(pNorm.toLowerCase()); }); } @@ -1890,21 +1912,21 @@ function applyFilters() { if (!isIssueStatusSelected(iss)) { return false; } - } else if (selectedStatuses.size === 0) { - return false; } // 2. Project Filter (SD, IN, AAN, GEN of ander) if (projectVal) { - let matchesProj = (issPKey === projectVal); - if (!matchesProj) { + if (issPKey) { + if (issPKey !== projectVal) return false; + } else { + let matchesProj = false; if (projectVal === 'SD' && issPName.includes('servicedesk')) matchesProj = true; else if (projectVal === 'IN' && issPName.includes('interface')) matchesProj = true; else if (projectVal === 'AAN' && issPName.includes('aanvraag')) matchesProj = true; else if (projectVal === 'GEN' && (issPName.includes('general') || issPName.includes('algemeen'))) matchesProj = true; else if (issPName === projectVal.toLowerCase()) matchesProj = true; + if (!matchesProj) return false; } - if (!matchesProj) return false; } // 3. Wachtrijfilter (MY_QUEUES, SD, IN, AAN, GEN, DX) @@ -2042,21 +2064,21 @@ function renderTickets(tickets) { } // Project badge styling (SD, IN, AAN, GEN) - const pKey = (ticket.project_key || '').toUpperCase().trim(); + const pKey = getIssueProjectKey(ticket); const pName = (ticket.project || '').toLowerCase().trim(); let projBadgeClass = 'bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-300 border border-slate-200/80 dark:border-slate-700/80'; let projLabel = escapeHtml(ticket.project || 'Project'); - if (pKey === 'SD' || pName.includes('servicedesk')) { + if (pKey === 'SD' || (!pKey && pName.includes('servicedesk'))) { projBadgeClass = 'bg-sky-50 dark:bg-sky-950/40 text-sky-700 dark:text-sky-300 border border-sky-300 dark:border-sky-800/80'; projLabel = 'SD • Servicedesk'; - } else if (pKey === 'IN' || pName.includes('interface')) { + } else if (pKey === 'IN' || (!pKey && pName.includes('interface'))) { projBadgeClass = 'bg-amber-50 dark:bg-amber-950/40 text-amber-700 dark:text-amber-300 border border-amber-300 dark:border-amber-800/80'; projLabel = 'IN • Interfaces'; - } else if (pKey === 'AAN' || pName.includes('aanvraag')) { + } else if (pKey === 'AAN' || (!pKey && pName.includes('aanvraag'))) { projBadgeClass = 'bg-emerald-50 dark:bg-emerald-950/40 text-emerald-700 dark:text-emerald-300 border border-emerald-300 dark:border-emerald-800/80'; projLabel = 'AAN • Aanvragen'; - } else if (pKey === 'GEN' || pName.includes('general') || pName.includes('algemeen')) { + } else if (pKey === 'GEN' || (!pKey && (pName.includes('general') || pName.includes('algemeen')))) { projBadgeClass = 'bg-indigo-50 dark:bg-indigo-950/40 text-indigo-700 dark:text-indigo-300 border border-indigo-300 dark:border-indigo-800/80'; projLabel = 'GEN • General'; } @@ -2802,8 +2824,8 @@ document.addEventListener('DOMContentLoaded', () => { toggleJiraFiltersDrawer(true); } - calculateKpis(); initStatusSelection(); + calculateKpis(); updateProjectPills(); updateQueueCounts(); if (currentQueue) { diff --git a/planner.php b/planner.php index 0d28023..088d860 100644 --- a/planner.php +++ b/planner.php @@ -4678,7 +4678,7 @@ function isIssueInQueue(iss, qCode) { if (parts.length > 0) pKey = parts[0].toUpperCase().trim(); } const pName = (iss.project || '').toLowerCase().trim(); - const isSd = (pKey === 'SD' || pName.includes('servicedesk') || !pKey); + const isSd = pKey ? (pKey === 'SD') : pName.includes('servicedesk'); const ol = (iss.onderwerp_logging || '').toLowerCase().trim(); const sum = (iss.summary || '').toLowerCase(); @@ -4688,9 +4688,9 @@ function isIssueInQueue(iss, qCode) { if (code === 'DX') return matchesDx; if (code === 'SD') return isSd && !matchesDx; - if (code === 'IN') return (pKey === 'IN' || pName.includes('interface')); - if (code === 'AAN') return (pKey === 'AAN' || pName.includes('aanvraag')); - if (code === 'GEN') return (pKey === 'GEN' || pName.includes('general') || pName.includes('algemeen')); + if (code === 'IN') return pKey ? (pKey === 'IN') : pName.includes('interface'); + if (code === 'AAN') return pKey ? (pKey === 'AAN') : pName.includes('aanvraag'); + if (code === 'GEN') return pKey ? (pKey === 'GEN') : (pName.includes('general') || pName.includes('algemeen')); return true; } -- 2.52.0