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); // Verzamel unieke projecten en types voor filter dropdowns en project switcher // 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']; } } // 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; } } // Ook eventuele andere gebruikte projecten toevoegen die tickets hebben in $allIssues foreach ($usedProjectKeys as $uKey => $val) { $activeProjectKeys[$uKey] = true; } // Fallback als er nog geen tickets geladen zijn (bijv. lege sync), toon minimaal de 4 core projecten if (empty($activeProjectKeys)) { $activeProjectKeys = array_fill_keys(['SD', 'IN', 'AAN', 'GEN'], true); } // Haal projectstatussen op uit jiraData $rawProjectStatuses = $jiraData['project_statuses'] ?? []; // Bouw gestructureerde lijst van statussen gegroepeerd per project $projectStatusesData = []; $allStatusesMap = []; foreach (array_keys($activeProjectKeys) as $pKey) { $pName = $coreProjects[$pKey]['name'] ?? ($allProjects[$pKey]['name'] ?? $pKey); $pColor = $coreProjects[$pKey]['color'] ?? 'slate'; $pStatuses = []; // 1. Statussen uit Jira API voor dit project if (!empty($rawProjectStatuses[$pKey])) { foreach ($rawProjectStatuses[$pKey] 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) { $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]); } if ($issPKey === $pKey && !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); $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); $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); ?>
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.
Direct filteren op projectcode
Er zijn geen Jira tickets die overeenkomen met de geselecteerde tab of zoekfilters.