+
@@ -901,22 +873,6 @@ let selectedStatuses = new Set();
let activeUrgentOnly = false;
let expandedKeys = new Set();
const ticketStore = new Map();
-const allJiraStatuses = = $statusesJson ?>;
-
-// Hulpfunctie voor deduplicatie van tickets (assigned + team)
-function getDeduplicatedIssues() {
- const assigned = jiraData.assigned_issues || [];
- const team = jiraData.team_issues || [];
- const seen = new Set();
- const list = [];
- [...assigned, ...team].forEach(iss => {
- if (iss && iss.key && !seen.has(iss.key)) {
- seen.add(iss.key);
- list.push(iss);
- }
- });
- return list;
-}
function isDoneStatus(st) {
const s = (st || '').toLowerCase().trim();
@@ -983,7 +939,7 @@ function toggleJiraFiltersDrawer(forceOpen) {
}
}
-// Bepaal aantal actieve filters voor badge
+// Bepaal aantal actieve filters voor de badge in de rechter onderhoek
function updateActiveFilterBadge() {
const badge = document.getElementById('activeFilterBadge');
if (!badge) return;
@@ -993,7 +949,8 @@ function updateActiveFilterBadge() {
if (currentQueue && currentQueue !== 'MY_QUEUES') activeCount++;
if (document.getElementById('filterType')?.value) activeCount++;
if (document.getElementById('filterPriority')?.value) activeCount++;
- if (selectedStatuses.size > 0 && selectedStatuses.size < allJiraStatuses.length) activeCount++;
+ if (document.getElementById('filterStatus')?.value) activeCount++;
+ if (onlyInProgress) activeCount++;
if (activeCount > 0) {
badge.innerText = activeCount;
@@ -1003,236 +960,73 @@ function updateActiveFilterBadge() {
}
}
-// ==========================================
-// STATUS MULTI-SELECT CHECKBOX DROPDOWN LOGICA
-// ==========================================
+// Wissel tussen tabs
+function switchTab(tab) {
+ currentTab = tab;
+ activeUrgentOnly = false;
-function renderStatusCheckboxes() {
- const container = document.getElementById('statusCheckboxList');
- if (!container) return;
-
- if (!allJiraStatuses || allJiraStatuses.length === 0) {
- container.innerHTML = '
Geen Jira statussen gevonden
';
- return;
- }
-
- let html = '';
- allJiraStatuses.forEach((st, idx) => {
- const sNorm = (st.name || '').toLowerCase().trim();
- const isChecked = selectedStatuses.has(sNorm);
- const cat = (st.status_category || '').toLowerCase().trim();
-
- let dotColor = 'bg-blue-500';
- if (cat === 'new' || sNorm.includes('to do') || sNorm.includes('open') || sNorm.includes('nieuw')) {
- dotColor = 'bg-slate-400';
- } else if (cat === 'done' || isDoneStatus(sNorm)) {
- dotColor = 'bg-emerald-500';
- } else if (sNorm.includes('wacht') || sNorm.includes('klant') || sNorm.includes('pending')) {
- dotColor = 'bg-amber-500';
- }
-
- const safeId = 'chkStatus_' + idx;
-
- html += `
-
-
-
-
- ${escapeHtml(st.name)}
-
- 0
-
- `;
- });
-
- container.innerHTML = html;
- updateStatusCounts();
-}
-
-function updateStatusCounts() {
- const all = getDeduplicatedIssues();
- allJiraStatuses.forEach((st, idx) => {
- const sNorm = (st.name || '').toLowerCase().trim();
- const el = document.getElementById(`statusCount_${idx}`);
- if (el) {
- let currentList = all;
- if (currentProject) {
- const pNorm = currentProject.trim().toUpperCase();
- currentList = currentList.filter(iss => {
- const pk = (iss.project_key || '').trim().toUpperCase();
- const pn = (iss.project || '').trim().toLowerCase();
- return pk === pNorm || pn.includes(pNorm.toLowerCase());
- });
- }
- if (currentQueue) {
- currentList = currentList.filter(iss => isIssueInQueue(iss, currentQueue));
- }
- const cnt = currentList.filter(iss => (iss.status || '').toLowerCase().trim() === sNorm).length;
- el.innerText = cnt;
+ // Update tab knoppen styling
+ const tabs = ['assigned', 'team', 'in_progress', 'done'];
+ tabs.forEach(t => {
+ const btn = document.getElementById(`tabBtn_${t}`);
+ if (!btn) return;
+ if (t === tab) {
+ btn.className = "flex items-center space-x-1.5 px-3 py-1.5 text-xs font-bold rounded-xl transition cursor-pointer bg-indigo-50 dark:bg-indigo-950/50 text-indigo-600 dark:text-indigo-400 border border-indigo-200 dark:border-indigo-800/60 flex-shrink-0";
+ } else {
+ btn.className = "flex items-center space-x-1.5 px-3 py-1.5 text-xs font-bold rounded-xl transition cursor-pointer text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white hover:bg-slate-100 dark:hover:bg-slate-800/60 border border-transparent flex-shrink-0";
}
});
-}
-function toggleStatusDropdown(force) {
- const menu = document.getElementById('statusDropdownMenu');
- const chevron = document.getElementById('statusDropdownChevron');
- const btn = document.getElementById('statusDropdownBtn');
- if (!menu) return;
-
- const willOpen = (typeof force === 'boolean') ? force : menu.classList.contains('hidden');
- if (willOpen) {
- menu.classList.remove('hidden');
- if (chevron) chevron.classList.add('rotate-180');
- if (btn) btn.setAttribute('aria-expanded', 'true');
- updateStatusCounts();
- } else {
- menu.classList.add('hidden');
- if (chevron) chevron.classList.remove('rotate-180');
- if (btn) btn.setAttribute('aria-expanded', 'false');
- }
-}
-
-document.addEventListener('click', (e) => {
- const wrapper = document.getElementById('statusDropdownWrapper');
- if (wrapper && !wrapper.contains(e.target)) {
- toggleStatusDropdown(false);
- }
-});
-
-function onStatusCheckboxChange() {
- selectedStatuses.clear();
- const checked = document.querySelectorAll('.status-checkbox:checked');
- checked.forEach(chk => {
- if (chk.value) selectedStatuses.add(chk.value.toLowerCase().trim());
- });
-
- try {
- localStorage.setItem('fociz_jira_selected_statuses', JSON.stringify([...selectedStatuses]));
- } catch (e) {}
-
- updateStatusDropdownLabel();
applyFilters();
}
-function selectAllStatuses(selectAll) {
- selectedStatuses.clear();
- const chks = document.querySelectorAll('.status-checkbox');
- chks.forEach(chk => {
- chk.checked = !!selectAll;
- if (selectAll && chk.value) {
- selectedStatuses.add(chk.value.toLowerCase().trim());
- }
- });
-
- try {
- localStorage.setItem('fociz_jira_selected_statuses', JSON.stringify([...selectedStatuses]));
- } catch (e) {}
-
- updateStatusDropdownLabel();
+// Toggle: Verberg Gesloten
+function toggleHideClosed() {
+ hideClosed = !hideClosed;
+ updateHideClosedButton();
applyFilters();
}
-function selectActiveStatusesOnly() {
- selectedStatuses.clear();
- const chks = document.querySelectorAll('.status-checkbox');
- chks.forEach(chk => {
- const val = (chk.value || '').toLowerCase().trim();
- const isDone = isDoneStatus(val);
- chk.checked = !isDone;
- if (!isDone) {
- selectedStatuses.add(val);
- }
- });
+function updateHideClosedButton() {
+ const btn = document.getElementById('btnHideClosed');
+ if (!btn) return;
+ if (hideClosed) {
+ btn.className = "flex items-center space-x-1.5 px-2.5 py-1.5 rounded-xl text-xs font-bold transition cursor-pointer bg-emerald-50 dark:bg-emerald-950/40 text-emerald-700 dark:text-emerald-300 border border-emerald-300 dark:border-emerald-800/80 shadow-2xs";
+ btn.innerHTML = `
Verberg Gesloten `;
+ } else {
+ btn.className = "flex items-center space-x-1.5 px-2.5 py-1.5 rounded-xl text-xs font-semibold transition cursor-pointer bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-400 hover:bg-slate-200 dark:hover:bg-slate-700 border border-slate-200 dark:border-slate-700";
+ btn.innerHTML = `
Toon Ook Gesloten `;
+ }
+ if (typeof lucide !== 'undefined') lucide.createIcons();
+}
- try {
- localStorage.setItem('fociz_jira_selected_statuses', JSON.stringify([...selectedStatuses]));
- } catch (e) {}
-
- updateStatusDropdownLabel();
+// Toggle: Snelfilter Alleen In Behandeling
+function toggleOnlyInProgress() {
+ onlyInProgress = !onlyInProgress;
+ updateOnlyInProgressButton();
applyFilters();
}
-function updateStatusDropdownLabel() {
- const labelEl = document.getElementById('statusDropdownLabel');
- const badgeEl = document.getElementById('statusDropdownBadge');
- if (!labelEl) return;
-
- const total = allJiraStatuses.length;
- const selected = selectedStatuses.size;
-
- if (selected === total || (total === 0 && selected === 0)) {
- labelEl.innerText = "Alle statussen";
- if (badgeEl) badgeEl.classList.add('hidden');
- } else if (selected === 0) {
- labelEl.innerText = "Geen geselecteerd";
- if (badgeEl) {
- badgeEl.innerText = "0";
- badgeEl.classList.remove('hidden');
- badgeEl.className = "px-1.5 py-0.5 rounded-full text-[10px] font-bold bg-rose-100 dark:bg-rose-950/60 text-rose-700 dark:text-rose-300";
- }
- } else if (selected === 1) {
- const singleNorm = [...selectedStatuses][0];
- const match = allJiraStatuses.find(st => (st.name || '').toLowerCase().trim() === singleNorm);
- labelEl.innerText = match ? match.name : singleNorm;
- if (badgeEl) {
- badgeEl.innerText = "1";
- badgeEl.classList.remove('hidden');
- badgeEl.className = "px-1.5 py-0.5 rounded-full text-[10px] font-bold bg-indigo-100 dark:bg-indigo-950/60 text-indigo-700 dark:text-indigo-300";
- }
+function updateOnlyInProgressButton() {
+ const btn = document.getElementById('btnOnlyInProgress');
+ if (!btn) return;
+ if (onlyInProgress) {
+ btn.className = "flex items-center space-x-1.5 px-2.5 py-1.5 rounded-xl text-xs font-bold transition cursor-pointer bg-blue-600 text-white shadow-xs";
+ btn.innerHTML = `
In behandeling (Actief) `;
} else {
- labelEl.innerText = `${selected} statussen`;
- if (badgeEl) {
- badgeEl.innerText = `${selected}/${total}`;
- badgeEl.classList.remove('hidden');
- badgeEl.className = "px-1.5 py-0.5 rounded-full text-[10px] font-bold bg-indigo-100 dark:bg-indigo-950/60 text-indigo-700 dark:text-indigo-300";
- }
- }
-
- const btnReset = document.getElementById('btnResetFiltersInline');
- if (btnReset) {
- const isCustom = selected < total || currentProject !== '' || (currentQueue !== '' && currentQueue !== 'MY_QUEUES') || document.getElementById('jiraSearchInput')?.value;
- if (isCustom) btnReset.classList.remove('hidden');
- else btnReset.classList.add('hidden');
+ btn.className = "flex items-center space-x-1.5 px-2.5 py-1.5 rounded-xl text-xs font-semibold transition cursor-pointer bg-slate-100 dark:bg-slate-800 text-slate-700 dark:text-slate-300 hover:bg-slate-200 dark:hover:bg-slate-700 border border-slate-200 dark:border-slate-700";
+ btn.innerHTML = `
In behandeling `;
}
+ if (typeof lucide !== 'undefined') lucide.createIcons();
}
-function initStatusSelection() {
- selectedStatuses = new Set();
- let saved = null;
- try {
- const raw = localStorage.getItem('fociz_jira_selected_statuses');
- if (raw) saved = JSON.parse(raw);
- } catch (e) {}
-
- if (Array.isArray(saved) && saved.length > 0) {
- saved.forEach(s => {
- if (s) selectedStatuses.add(String(s).toLowerCase().trim());
- });
- } else {
- // Standaard alle actieve statussen selecteren, gesloten uit conform gebruikerswens
- allJiraStatuses.forEach(st => {
- const sNorm = (st.name || '').toLowerCase().trim();
- const cat = (st.status_category || '').toLowerCase().trim();
- if (cat !== 'done' && !isDoneStatus(sNorm)) {
- selectedStatuses.add(sNorm);
- }
- });
- if (selectedStatuses.size === 0) {
- allJiraStatuses.forEach(st => {
- selectedStatuses.add((st.name || '').toLowerCase().trim());
- });
- }
+// Status dropdown verandering
+function onStatusSelectChange(val) {
+ if (val && isDoneStatus(val)) {
+ hideClosed = false;
+ updateHideClosedButton();
}
-
- renderStatusCheckboxes();
- updateStatusDropdownLabel();
+ applyFilters();
}
// Project selectie via pill tabs
@@ -1348,13 +1142,21 @@ function updateQueuePills() {
}
function updateProjectCounts() {
- const all = getDeduplicatedIssues();
- let currentList = all;
+ const assigned = jiraData.assigned_issues || [];
+ const team = jiraData.team_issues || [];
+ const all = [...assigned, ...team];
- if (selectedStatuses.size > 0 && selectedStatuses.size < allJiraStatuses.length) {
- currentList = currentList.filter(iss => selectedStatuses.has((iss.status || '').toLowerCase().trim()));
- } else if (selectedStatuses.size === 0) {
- currentList = [];
+ let currentList = all;
+ if (currentTab === 'assigned') currentList = assigned;
+ else if (currentTab === 'team') currentList = team;
+ else if (currentTab === 'in_progress') {
+ currentList = all.filter(iss => isInProgressStatus(iss.status, iss.status_category));
+ } else if (currentTab === 'done') {
+ currentList = all.filter(iss => isDoneStatus(iss.status) || (iss.status_category || '').toLowerCase() === 'done');
+ }
+
+ if (hideClosed && currentTab !== 'done') {
+ currentList = currentList.filter(iss => !isDoneStatus(iss.status) && (iss.status_category || '').toLowerCase() !== 'done');
}
const elAll = document.getElementById('projCount_all');
@@ -1379,13 +1181,21 @@ function updateProjectCounts() {
}
function updateQueueCounts() {
- const all = getDeduplicatedIssues();
- let currentList = all;
+ const assigned = jiraData.assigned_issues || [];
+ const team = jiraData.team_issues || [];
+ const all = [...assigned, ...team];
- if (selectedStatuses.size > 0 && selectedStatuses.size < allJiraStatuses.length) {
- currentList = currentList.filter(iss => selectedStatuses.has((iss.status || '').toLowerCase().trim()));
- } else if (selectedStatuses.size === 0) {
- currentList = [];
+ let currentList = all;
+ if (currentTab === 'assigned') currentList = assigned;
+ else if (currentTab === 'team') currentList = team;
+ else if (currentTab === 'in_progress') {
+ currentList = all.filter(iss => isInProgressStatus(iss.status, iss.status_category));
+ } else if (currentTab === 'done') {
+ currentList = all.filter(iss => isDoneStatus(iss.status) || (iss.status_category || '').toLowerCase() === 'done');
+ }
+
+ if (hideClosed && currentTab !== 'done') {
+ currentList = currentList.filter(iss => !isDoneStatus(iss.status) && (iss.status_category || '').toLowerCase() !== 'done');
}
if (currentProject) {
@@ -1494,10 +1304,11 @@ function applyFilters() {
const issPKey = (iss.project_key || '').toUpperCase().trim();
const issPName = (iss.project || '').toLowerCase().trim();
const issStatus = (iss.status || '').toLowerCase().trim();
+ const issCat = (iss.status_category || '').toLowerCase().trim();
- // 1. Status Filter via Checkboxes
- if (selectedStatuses.size > 0 && selectedStatuses.size < allJiraStatuses.length) {
- if (!selectedStatuses.has(issStatus)) {
+ // 1. Verberg Gesloten filter (als tab niet 'done' is en er niet expliciet een gesloten status gekozen is)
+ if (currentTab !== 'done' && hideClosed && !isDoneStatus(statusVal)) {
+ if (issCat === 'done' || isDoneStatus(issStatus)) {
return false;
}
} else if (selectedStatuses.size === 0) {
diff --git a/profile.php b/profile.php
index 7ab2eeb..cc39f99 100644
--- a/profile.php
+++ b/profile.php
@@ -1284,7 +1284,7 @@ require_once __DIR__ . '/includes/header.php';
- Centraal overzicht van alle actieve inlogapparaten conform ISO 27001 en SOC 2 richtlijnen.
+ Centraal overzicht van alle actieve inlogapparaten conform ISO 27001 en SOC 2 richtlijnen (maximaal 20 actieve sessies).