Jira22 #87

Merged
NiekRabelink merged 1 commits from dev into main 2026-09-15 16:40:44 +00:00
2 changed files with 73 additions and 51 deletions
+66 -44
View File
@@ -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());
});
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,22 +1912,22 @@ 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;
}
}
// 3. Wachtrijfilter (MY_QUEUES, SD, IN, AAN, GEN, DX)
if (currentQueue) {
@@ -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) {
+4 -4
View File
@@ -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;
}