query("SELECT id, title FROM boards WHERE is_archived = 0 ORDER BY id ASC")->fetchAll(); } else { $stmt = $db->prepare(" SELECT b.id, b.title FROM boards b JOIN board_members bm ON b.id = bm.board_id WHERE bm.user_id = ? AND b.is_archived = 0 ORDER BY b.id ASC "); $stmt->execute([$userId]); $boards = $stmt->fetchAll(); } $boardIds = array_column($boards, 'id'); $lanesByBoard = []; if (!empty($boardIds)) { $inClause = implode(',', array_map('intval', $boardIds)); $lanes = $db->query("SELECT id, board_id, title, color FROM board_lanes WHERE board_id IN ({$inClause}) ORDER BY position ASC")->fetchAll(); foreach ($lanes as $lane) { $lanesByBoard[$lane['board_id']][] = $lane; } } foreach ($boards as &$b) { $b['lanes'] = $lanesByBoard[$b['id']] ?? []; } unset($b); // Ophalen van actieve wachtrijfilters en toewijzingen van de ingelogde gebruiker $queueFilters = $jiraData['queue_filters'] ?? jira_get_queue_filters(true); $defaultQueueFilter = $jiraData['default_queue_filter'] ?? jira_get_user_queue_preference($userId); $userQueueFilters = $jiraData['user_queue_filters'] ?? jira_get_user_queue_preferences($userId); $userQueueFilters = array_values(array_filter(array_map('strtoupper', array_map('trim', $userQueueFilters ?? [])))); $jiraData['user_queue_filters'] = $userQueueFilters; // Hulpfunctie om te controleren of een ticket behoort tot een wachtrij / project $issueMatchesQueue = function(array $iss, string $code) use ($queueFilters): bool { $code = strtoupper(trim($code)); if (empty($code)) return true; $pKey = strtoupper(trim($iss['project_key'] ?? '')); if (empty($pKey) && !empty($iss['key']) && preg_match('/^([A-Z0-9]+)-/i', $iss['key'], $m)) { $pKey = strtoupper($m[1]); } $pName = strtolower(trim($iss['project'] ?? '')); $ol = strtolower(trim($iss['onderwerp_logging'] ?? '')); $sum = strtolower(trim($iss['summary'] ?? '')); // 1. Zoek geconfigureerd filter in database foreach ($queueFilters as $qf) { if (strtoupper(trim($qf['filter_code'] ?? '')) === $code) { if (!empty($qf['project_key'])) { $filterPKey = strtoupper(trim($qf['project_key'])); if ($pKey) { if ($pKey !== $filterPKey) return false; } elseif (strpos($pName, strtolower($filterPKey)) === false) { return false; } } if (!empty($qf['jql_clause'])) { $jql = $qf['jql_clause']; if (preg_match('/onderwerp\s+logging.*?in\s*\(([^)]+)\)/i', $jql, $jm)) { $terms = array_map(function($t) { return trim($t, " '\"\t\n\r\0\x0B"); }, explode(',', strtolower($jm[1]))); $found = false; foreach ($terms as $t) { if ($t !== '' && (strpos($ol, $t) !== false || strpos($sum, $t) !== false)) { $found = true; break; } } if (!$found) return false; } } return true; } } // 2. Fallbacks voor standaard wachtrijen/projecten if ($code === 'DX') { $isSd = ($pKey === 'SD') || strpos($pName, 'servicedesk') !== false; if (!$isSd) return false; $dxTerms = ['koppeling', 'sso', 'endpoint', 'rest', 'datadump', 'uwv', 'migratie']; foreach ($dxTerms as $t) { if (strpos($ol, $t) !== false || strpos($sum, $t) !== false) return true; } return false; } if ($code === 'SD') { return ($pKey === 'SD') || strpos($pName, 'servicedesk') !== false; } if ($code === 'IN') { return ($pKey === 'IN') || strpos($pName, 'interface') !== false; } if ($code === 'AAN') { return ($pKey === 'AAN') || strpos($pName, 'aanvraag') !== false; } if ($code === 'GEN') { return ($pKey === 'GEN') || strpos($pName, 'general') !== false || strpos($pName, 'algemeen') !== false; } return ($pKey === $code); }; // Als er specifieke projecten aan de gebruiker zijn toegewezen: verberg tickets van niet-toegewezen projecten if (!empty($userQueueFilters)) { $filterByAssigned = function(array $issues) use ($userQueueFilters, $issueMatchesQueue): array { return array_values(array_filter($issues, function($iss) use ($userQueueFilters, $issueMatchesQueue) { foreach ($userQueueFilters as $qCode) { if ($issueMatchesQueue($iss, $qCode)) return true; } return false; })); }; $assignedIssues = $filterByAssigned($assignedIssues); $teamIssues = $filterByAssigned($teamIssues); $jiraData['assigned_issues'] = $assignedIssues; $jiraData['team_issues'] = $teamIssues; } // Verzamel unieke projecten en types voor filter dropdowns en project switcher $allIssues = array_merge($assignedIssues, $teamIssues); $allProjects = []; $allTypes = []; $allPriorities = ['Highest', 'High', 'Medium', 'Low']; $projectCounts = []; // Core projecten met styling en namen $coreProjects = [ 'SD' => ['key' => 'SD', 'name' => 'Servicedesk', 'color' => 'sky'], 'IN' => ['key' => 'IN', 'name' => 'Interfaces', 'color' => 'amber'], 'AAN' => ['key' => 'AAN', 'name' => 'Aanvragen', 'color' => 'emerald'], 'GEN' => ['key' => 'GEN', 'name' => 'General', 'color' => 'indigo'], ]; $usedProjectKeys = []; foreach ($allIssues as $iss) { $pKey = strtoupper(trim($iss['project_key'] ?? '')); if (empty($pKey) && !empty($iss['key']) && preg_match('/^([A-Z0-9]+)-/i', $iss['key'], $m)) { $pKey = strtoupper($m[1]); } if (!empty($pKey)) { $usedProjectKeys[$pKey] = true; } if (!empty($iss['project'])) { $p = $iss['project']; $allProjects[$p] = [ 'name' => $p, 'key' => $pKey ?: ($iss['project_key'] ?? ''), ]; $projectCounts[$p] = ($projectCounts[$p] ?? 0) + 1; } if (!empty($iss['issue_type'])) { $allTypes[$iss['issue_type']] = $iss['issue_type']; } if (!empty($iss['status'])) { $allStatuses[$iss['status']] = $iss['status']; } } // Bepaal welke projecten getoond worden: alleen projecten die tickets hebben, plus SD/IN/AAN/GEN // Geen statussen van projecten die niet gebruikt worden! $activeProjectKeys = []; foreach ($coreProjects as $cKey => $cMeta) { if (isset($usedProjectKeys[$cKey]) || !empty($projectCounts[$cMeta['name']]) || !empty($projectCounts[$cKey])) { $activeProjectKeys[$cKey] = true; } } foreach ($usedProjectKeys as $uKey => $val) { $activeProjectKeys[$uKey] = true; } if (empty($activeProjectKeys)) { $activeProjectKeys = array_fill_keys(['SD', 'IN', 'AAN', 'GEN'], true); } if (!empty($userQueueFilters)) { $filteredActiveKeys = []; foreach ($userQueueFilters as $code) { $clean = strtoupper(trim($code)); if ($clean === 'DX') { $filteredActiveKeys['SD'] = true; } elseif ($clean !== 'MY_QUEUES') { $filteredActiveKeys[$clean] = true; } } if (!empty($filteredActiveKeys)) { $activeProjectKeys = $filteredActiveKeys; } } // Haal projectstatussen op uit jiraData $rawProjectStatuses = $jiraData['project_statuses'] ?? []; // Bouw gestructureerde lijst van statussen gegroepeerd per project $projectStatusesData = []; $allStatusesMap = []; $allTargetKeys = array_keys($activeProjectKeys); if ($isCodeVisible('DX') && !in_array('DX', $allTargetKeys, true)) { $allTargetKeys[] = 'DX'; } if (!empty($queueFilters)) { foreach ($queueFilters as $qf) { $qCode = strtoupper(trim($qf['filter_code'] ?? '')); if (!empty($qCode) && $isCodeVisible($qCode) && !in_array($qCode, $allTargetKeys, true)) { $allTargetKeys[] = $qCode; } } } foreach ($allTargetKeys as $pKey) { if ($pKey === 'DX') { $pName = 'DX Koppelingen'; $pColor = 'amber'; } else { $pName = $coreProjects[$pKey]['name'] ?? ($allProjects[$pKey]['name'] ?? $pKey); $pColor = $coreProjects[$pKey]['color'] ?? 'slate'; if (!isset($coreProjects[$pKey]) && !empty($queueFilters)) { foreach ($queueFilters as $qf) { if (strtoupper(trim($qf['filter_code'] ?? '')) === $pKey && !empty($qf['filter_name'])) { $pName = $qf['filter_name']; break; } } } } $pStatuses = []; // 1. Statussen uit Jira API voor dit project $apiPKey = ($pKey === 'DX') ? 'SD' : $pKey; if (!empty($rawProjectStatuses[$apiPKey])) { foreach ($rawProjectStatuses[$apiPKey] as $st) { $sName = trim($st['name'] ?? ''); if (empty($sName)) continue; $sKey = strtolower($sName); $pStatuses[$sKey] = [ 'name' => $sName, 'status_category' => $st['status_category'] ?? 'indeterminate', 'category_name' => $st['category_name'] ?? '', ]; } } // 2. Statussen die op de tickets van dit project voorkomen toevoegen/mergen foreach ($allIssues as $iss) { $matches = false; if ($pKey === 'DX') { $matches = $issueMatchesQueue($iss, 'DX'); } else { $issPKey = strtoupper(trim($iss['project_key'] ?? '')); if (empty($issPKey) && !empty($iss['key']) && preg_match('/^([A-Z0-9]+)-/i', $iss['key'], $m)) { $issPKey = strtoupper($m[1]); } $matches = ($issPKey === $pKey); if (!$matches && !empty($queueFilters)) { foreach ($queueFilters as $qf) { if (strtoupper(trim($qf['filter_code'] ?? '')) === $pKey) { $matches = $issueMatchesQueue($iss, $pKey); break; } } } } if ($matches && !empty($iss['status'])) { $sName = trim($iss['status']); $sKey = strtolower($sName); if (!isset($pStatuses[$sKey])) { $pStatuses[$sKey] = [ 'name' => $sName, 'status_category' => $iss['status_category'] ?? 'indeterminate', 'category_name' => '', ]; } } } // Fallback als een project nog geen statussen heeft if (empty($pStatuses)) { $fallback = [ ['name' => 'To Do', 'status_category' => 'new'], ['name' => 'In behandeling', 'status_category' => 'indeterminate'], ['name' => 'Gesloten', 'status_category' => 'done'], ]; foreach ($fallback as $fb) { $pStatuses[strtolower($fb['name'])] = $fb; } } // Sorteren: To Do / Nieuw (1), In behandeling / Uitvoering (2), Gesloten / Gereed (3) uasort($pStatuses, function($a, $b) { $order = ['new' => 1, 'indeterminate' => 2, 'done' => 3]; $oa = $order[$a['status_category'] ?? 'indeterminate'] ?? 2; $ob = $order[$b['status_category'] ?? 'indeterminate'] ?? 2; if ($oa !== $ob) return $oa - $ob; return strcasecmp($a['name'], $b['name']); }); $statusList = array_values($pStatuses); foreach ($statusList as $st) { $allStatusesMap[strtolower($st['name'])] = $st; } $projectStatusesData[] = [ 'key' => $pKey, 'name' => $pName, 'color' => $pColor, 'statuses' => $statusList, ]; } $allStatusesList = array_values($allStatusesMap); ksort($allProjects); ksort($allTypes); $jiraDataJson = json_encode($jiraData, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP); $boardsJson = json_encode($boards, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP); $projectStatusesJson = json_encode($projectStatusesData, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP); $statusesJson = json_encode($allStatusesList, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP); $currentUserNameJson = json_encode($currentUserName, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP); $currentUserEmailJson = json_encode($currentUserEmail, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP); ?>

Atlassian Jira Hub

Live Verbonden Demomodus

Interactieve Voorbeeldweergave (Sandbox)

Je bekijkt momenteel demotickets. Koppel je Atlassian Jira Cloud instantie in je profiel om direct de live tickets van jouw organisatie in te laden.

Koppel Jira Cloud
Synchronisatiefout:
Controleer instellingen
Verbonden met als Demodataset actief met voorbeeldtickets
Projecten

Direct schakelen tussen projecten • Klik op het pijltje voor status instellingen & uitvoerder

Ticket succesvol verwerkt