Jira aanpassingen #82

Merged
NiekRabelink merged 1 commits from dev into main 2026-09-14 14:24:42 +00:00
4 changed files with 1004 additions and 569 deletions
+49 -21
View File
@@ -171,15 +171,29 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
}
}
// 2d. Teamleden toewijzen aan Jira Wachtrijfilter
// 2d. Teamleden toewijzen aan Jira Wachtrijfilters (meervoudig)
elseif ($action === 'save_user_jira_assignments') {
$activeTab = 'jira';
$assignments = $_POST['user_filter'] ?? [];
if (is_array($assignments)) {
$upd = $db->prepare("UPDATE users SET default_jira_filter_code = ? WHERE id = ?");
foreach ($assignments as $uId => $fCode) {
$fCode = trim($fCode);
$upd->execute([$fCode !== '' ? $fCode : null, (int)$uId]);
$assignments = $_POST['user_filters'] ?? [];
$submittedUserIds = isset($_POST['user_ids']) && is_array($_POST['user_ids']) ? array_map('intval', $_POST['user_ids']) : [];
// Fallback als user_ids niet meegestuurd werd (bv. oude formulier submission met user_filter)
if (empty($submittedUserIds) && !empty($_POST['user_filter']) && is_array($_POST['user_filter'])) {
$submittedUserIds = array_map('intval', array_keys($_POST['user_filter']));
foreach ($_POST['user_filter'] as $uId => $sCode) {
$sCode = trim($sCode);
$assignments[$uId] = $sCode !== '' ? [$sCode] : [];
}
}
if (!empty($submittedUserIds)) {
$upd = $db->prepare("UPDATE users SET default_jira_filter_codes = ?, default_jira_filter_code = ? WHERE id = ?");
foreach ($submittedUserIds as $uId) {
$rawList = isset($assignments[$uId]) && is_array($assignments[$uId]) ? $assignments[$uId] : [];
$cleanCodes = array_values(array_unique(array_filter(array_map('trim', $rawList))));
$jsonVal = !empty($cleanCodes) ? json_encode($cleanCodes) : null;
$firstVal = !empty($cleanCodes) ? $cleanCodes[0] : null;
$upd->execute([$jsonVal, $firstVal, (int)$uId]);
}
fociz_log_audit($userId, 'SETTINGS_UPDATED', 'jira_assignments', null, [], 'SUCCESS', $adminUser['email']);
$message = "Standaard Jira wachtrijtoewijzingen voor het team zijn succesvol opgeslagen.";
@@ -511,7 +525,7 @@ try {
$allUsersForJira = [];
$allJiraFilters = [];
try {
$allUsersForJira = $db->query("SELECT id, name, email, role, avatar_url, default_jira_filter_code FROM users ORDER BY name ASC")->fetchAll() ?: [];
$allUsersForJira = $db->query("SELECT id, name, email, role, avatar_url, default_jira_filter_code, default_jira_filter_codes FROM users ORDER BY name ASC")->fetchAll() ?: [];
$allJiraFilters = $db->query("SELECT * FROM jira_queue_filters ORDER BY sort_order ASC, id ASC")->fetchAll() ?: [];
} catch (Throwable $e) {
error_log("Fout bij ophalen jira filters/users: " . $e->getMessage());
@@ -1373,10 +1387,10 @@ require_once __DIR__ . '/includes/header.php';
<div>
<h3 class="text-xs font-bold text-slate-900 dark:text-white uppercase tracking-wider flex items-center space-x-1.5">
<i data-lucide="users" class="w-3.5 h-3.5 text-indigo-500"></i>
<span>Team Wachtrijmatrix: Standaard Wachtrij per Collega</span>
<span>Team Wachtrijmatrix: Gekoppelde Wachtrijen per Collega</span>
</h3>
<p class="text-[11px] text-slate-500 dark:text-slate-400 mt-0.5">
Wijs collega's toe aan hun primaire wachtrij (bijv. DX of SD). Wanneer zij de Jira pagina openen, wordt deze wachtrij direct als standaard getoond.
Koppel collega's aan één of meerdere wachtrijfilters (bijv. SD, IN, AAN, GEN of DX). Collega's zien in de Jira Hub direct de tickets van hun gekoppelde wachtrijen.
</p>
</div>
</div>
@@ -1393,13 +1407,25 @@ require_once __DIR__ . '/includes/header.php';
<th class="py-3 px-4">Teamlid</th>
<th class="py-3 px-4">E-mailadres</th>
<th class="py-3 px-4">Rol</th>
<th class="py-3 px-4 w-72">Standaard Wachtrijfilter</th>
<th class="py-3 px-4">Gekoppelde Wachtrijen (Meervoudig)</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-100 dark:divide-slate-800/80 bg-white dark:bg-[#111622]">
<?php foreach ($allUsersForJira as $usr): ?>
<?php foreach ($allUsersForJira as $usr):
$userSelectedCodes = [];
if (!empty($usr['default_jira_filter_codes'])) {
$decoded = json_decode($usr['default_jira_filter_codes'], true);
if (is_array($decoded)) {
$userSelectedCodes = $decoded;
}
}
if (empty($userSelectedCodes) && !empty($usr['default_jira_filter_code'])) {
$userSelectedCodes = [$usr['default_jira_filter_code']];
}
?>
<tr class="hover:bg-slate-50/50 dark:hover:bg-slate-800/30 transition">
<td class="py-3 px-4">
<input type="hidden" name="user_ids[]" value="<?= (int)$usr['id'] ?>">
<div class="flex items-center space-x-2.5">
<?php if (!empty($usr['avatar_url'])): ?>
<img src="<?= htmlspecialchars($usr['avatar_url']) ?>" alt="Avatar" class="w-7 h-7 rounded-full object-cover border border-slate-200 dark:border-slate-700" onerror="this.classList.add('hidden'); if(this.nextElementSibling) this.nextElementSibling.classList.remove('hidden');">
@@ -1423,16 +1449,18 @@ require_once __DIR__ . '/includes/header.php';
</span>
</td>
<td class="py-3 px-4">
<select name="user_filter[<?= (int)$usr['id'] ?>]" class="w-full bg-slate-50 dark:bg-[#0c0f17] border border-slate-300 dark:border-slate-700 rounded-xl px-3 py-1.5 text-xs text-slate-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-indigo-500 cursor-pointer">
<option value="">Geen voorkeur (alles tonen)</option>
<?php foreach ($allJiraFilters as $f): ?>
<?php if ($f['is_active']): ?>
<option value="<?= htmlspecialchars($f['filter_code']) ?>" <?= ($usr['default_jira_filter_code'] === $f['filter_code']) ? 'selected' : '' ?>>
<?= htmlspecialchars($f['filter_code']) ?> — <?= htmlspecialchars($f['filter_name']) ?>
</option>
<?php endif; ?>
<div class="flex flex-wrap gap-1.5 items-center">
<?php foreach ($allJiraFilters as $f):
if (!$f['is_active']) continue;
$code = $f['filter_code'];
$isChecked = in_array($code, $userSelectedCodes, true);
?>
<label class="inline-flex items-center space-x-1.5 px-2.5 py-1 rounded-lg border text-xs font-semibold cursor-pointer transition select-none <?= $isChecked ? 'bg-indigo-50 border-indigo-300 text-indigo-700 dark:bg-indigo-950/60 dark:border-indigo-700 dark:text-indigo-300' : 'bg-slate-50 border-slate-200 text-slate-600 dark:bg-slate-900/40 dark:border-slate-800 dark:text-slate-400 hover:border-slate-300 dark:hover:border-slate-700' ?>">
<input type="checkbox" name="user_filters[<?= (int)$usr['id'] ?>][]" value="<?= htmlspecialchars($code) ?>" <?= $isChecked ? 'checked' : '' ?> class="w-3.5 h-3.5 rounded text-indigo-600 border-slate-300 dark:border-slate-700 focus:ring-indigo-500 cursor-pointer">
<span title="<?= htmlspecialchars($f['filter_name']) ?>"><?= htmlspecialchars($code) ?></span>
</label>
<?php endforeach; ?>
</select>
</div>
</td>
</tr>
<?php endforeach; ?>
+56 -23
View File
@@ -162,6 +162,8 @@ function ensure_tables_exist(PDO $pdo): void {
"ALTER TABLE board_card_schedules ADD UNIQUE KEY uk_sched_card (card_id)",
"CREATE TABLE IF NOT EXISTS `password_resets` (`id` INT AUTO_INCREMENT PRIMARY KEY, `email` VARCHAR(191) NOT NULL, `token` VARCHAR(64) NOT NULL UNIQUE, `expires_at` DATETIME NOT NULL, `used_at` DATETIME NULL, `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, INDEX (`email`), INDEX (`token`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
"CREATE TABLE IF NOT EXISTS `jira_queue_filters` (`id` INT AUTO_INCREMENT PRIMARY KEY, `filter_code` VARCHAR(50) NOT NULL UNIQUE, `filter_name` VARCHAR(120) NOT NULL, `project_key` VARCHAR(50) NULL, `jql_clause` TEXT NOT NULL, `description` VARCHAR(255) NULL, `is_active` TINYINT(1) NOT NULL DEFAULT 1, `sort_order` INT NOT NULL DEFAULT 0, `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
// Jira: Meerdere wachtrijfilters per teamlid
"ALTER TABLE users ADD COLUMN default_jira_filter_codes TEXT NULL AFTER default_jira_filter_code",
// V2.0: Subtaken & Checklists
"CREATE TABLE IF NOT EXISTS `task_subtasks` (`id` INT AUTO_INCREMENT PRIMARY KEY, `task_id` INT NOT NULL, `user_id` INT NOT NULL, `title` VARCHAR(255) NOT NULL, `is_completed` TINYINT(1) NOT NULL DEFAULT 0, `position` INT NOT NULL DEFAULT 0, `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX (`task_id`, `position`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
// Beveiliging: IP tracking & locatie-verificatie
@@ -191,30 +193,61 @@ function ensure_tables_exist(PDO $pdo): void {
}
}
// Zorg dat de standaard Jira Servicedesk wachtrijfilters (DX en SD) aanwezig zijn
// Zorg dat de standaard Jira wachtrijfilters (SD, IN, AAN, GEN, DX) aanwezig zijn
try {
$filterCount = (int)$pdo->query("SELECT COUNT(*) FROM jira_queue_filters")->fetchColumn();
if ($filterCount === 0) {
$insertFilterStmt = $pdo->prepare("
INSERT INTO jira_queue_filters (filter_code, filter_name, project_key, jql_clause, description, is_active, sort_order)
VALUES (?, ?, ?, ?, ?, 1, ?)
");
$insertFilterStmt->execute([
'DX',
'DX — Koppelingen, SSO & Migratie',
'SD',
'"Onderwerp logging[dropdown]" in (Koppelingen, SSO-koppeling, Rest-endpoints, Datadump, UWV-koppeling, Migratie)',
'Servicedesk tickets met betrekking tot koppelingen, endpoints en datamigraties.',
1
]);
$insertFilterStmt->execute([
'SD',
'SD — Regulier Servicedesk',
'SD',
'("Onderwerp logging[Dropdown]" = EMPTY OR "Onderwerp logging[Dropdown]" != Koppelingen AND "Onderwerp logging[Dropdown]" != Migratie AND "Onderwerp logging[Dropdown]" != SSO-koppeling AND "Onderwerp logging[Dropdown]" != UWV-koppeling AND "Onderwerp logging[Dropdown]" != Rest-endpoints AND "Onderwerp logging[Dropdown]" != Datadump)',
'Reguliere servicedesk incidenten, algemene meldingen en gebruikersvragen.',
2
]);
$existingCodes = $pdo->query("SELECT filter_code FROM jira_queue_filters")->fetchAll(PDO::FETCH_COLUMN) ?: [];
$defaultFilters = [
[
'code' => 'SD',
'name' => 'SD — Servicedesk',
'project' => 'SD',
'jql' => 'project = "SD"',
'desc' => 'Servicedesk supportvragen en operationele meldingen.',
'order' => 1
],
[
'code' => 'IN',
'name' => 'IN — Interfaces',
'project' => 'IN',
'jql' => 'project = "IN"',
'desc' => 'Interface-koppelingen, API-endpoints en data-uitwisselingen.',
'order' => 2
],
[
'code' => 'AAN',
'name' => 'AAN — Aanvragen',
'project' => 'AAN',
'jql' => 'project = "AAN"',
'desc' => 'Klant- en gebruikersaanvragen en wijzigingsverzoeken.',
'order' => 3
],
[
'code' => 'GEN',
'name' => 'GEN — General',
'project' => 'GEN',
'jql' => 'project = "GEN"',
'desc' => 'Algemene taken, organisatie en platformprojecten.',
'order' => 4
],
[
'code' => 'DX',
'name' => 'DX — Koppelingen & SSO',
'project' => 'SD',
'jql' => '"Onderwerp logging[dropdown]" in (Koppelingen, SSO-koppeling, Rest-endpoints, Datadump, UWV-koppeling, Migratie)',
'desc' => 'Servicedesk tickets specifiek voor koppelingen en migraties.',
'order' => 5
]
];
$insertFilterStmt = $pdo->prepare("
INSERT INTO jira_queue_filters (filter_code, filter_name, project_key, jql_clause, description, is_active, sort_order)
VALUES (?, ?, ?, ?, ?, 1, ?)
");
foreach ($defaultFilters as $df) {
if (!in_array($df['code'], $existingCodes)) {
$insertFilterStmt->execute([
$df['code'], $df['name'], $df['project'], $df['jql'], $df['desc'], $df['order']
]);
}
}
} catch (Throwable $e) {
// Stil negeren indien tabel nog in opbouw is
+368 -264
View File
@@ -226,20 +226,111 @@ function jira_get_queue_filters(bool $onlyActive = true): array {
}
/**
* Haalt de standaard wachtrijfilter voorkeur van een gebruiker op
* Haalt alle gekoppelde wachtrijfilter codes voor een gebruiker op (meervoudig)
*/
function jira_get_user_queue_preference(int $userId): ?string {
function jira_get_user_queue_preferences(int $userId): array {
try {
$db = get_db_connection();
$stmt = $db->prepare("SELECT default_jira_filter_code FROM users WHERE id = ?");
$stmt = $db->prepare("SELECT default_jira_filter_codes, default_jira_filter_code FROM users WHERE id = ?");
$stmt->execute([$userId]);
$res = $stmt->fetchColumn();
return $res ? (string)$res : null;
$row = $stmt->fetch();
if (!$row) return [];
if (!empty($row['default_jira_filter_codes'])) {
$decoded = json_decode($row['default_jira_filter_codes'], true);
if (is_array($decoded)) {
return array_values(array_filter(array_map('strtoupper', array_map('trim', $decoded))));
}
$parts = explode(',', $row['default_jira_filter_codes']);
return array_values(array_filter(array_map('strtoupper', array_map('trim', $parts))));
}
if (!empty($row['default_jira_filter_code'])) {
return [strtoupper(trim($row['default_jira_filter_code']))];
}
return [];
} catch (Throwable $e) {
return null;
return [];
}
}
/**
* Haalt de eerste standaard wachtrijfilter voorkeur van een gebruiker op (backwards compatibility)
*/
function jira_get_user_queue_preference(int $userId): ?string {
$prefs = jira_get_user_queue_preferences($userId);
return !empty($prefs) ? $prefs[0] : null;
}
/**
* Haalt alle officiële statussen op uit de Atlassian Jira Cloud instantie
*/
function jira_fetch_statuses(string $domain, string $email, string $apiToken): array {
$cleanDomain = jira_normalize_domain($domain);
if (empty($cleanDomain) || empty($email) || empty($apiToken)) {
return [];
}
$cacheKey = "jira_statuses_" . md5($cleanDomain);
$cached = fociz_cache_get($cacheKey);
if (is_array($cached) && !empty($cached)) {
return $cached;
}
$authHeader = jira_get_auth_header($email, $apiToken);
$url = $cleanDomain . '/rest/api/3/status';
$response = fociz_http_request($url, [
'method' => 'GET',
'headers' => [
'Authorization' => $authHeader,
'Accept' => 'application/json',
],
'timeout' => 10,
]);
if ($response['status'] === 404 || $response['status'] === 405) {
$urlV2 = $cleanDomain . '/rest/api/2/status';
$response = fociz_http_request($urlV2, [
'method' => 'GET',
'headers' => [
'Authorization' => $authHeader,
'Accept' => 'application/json',
],
'timeout' => 10,
]);
}
$statuses = [];
if ($response['status'] === 200 && is_array($response['json'])) {
foreach ($response['json'] as $st) {
$catKey = strtolower($st['statusCategory']['key'] ?? 'indeterminate');
$catName = $st['statusCategory']['name'] ?? 'In uitvoering';
$statuses[] = [
'id' => (string)($st['id'] ?? ''),
'name' => $st['name'] ?? '',
'description' => $st['description'] ?? '',
'status_category' => $catKey, // 'new', 'indeterminate', 'done'
'category_name' => $catName,
'color' => $st['statusCategory']['colorName'] ?? '',
];
}
// Sorteer: To Do eerst, dan In Progress, dan Done
usort($statuses, function($a, $b) {
$order = ['new' => 1, 'indeterminate' => 2, 'done' => 3];
$oa = $order[$a['status_category']] ?? 2;
$ob = $order[$b['status_category']] ?? 2;
if ($oa !== $ob) return $oa - $ob;
return strcasecmp($a['name'], $b['name']);
});
fociz_cache_set($cacheKey, $statuses, 3600);
}
return $statuses;
}
/**
* Haalt issues op via een flexibele JQL query via Atlassian REST API
*/
@@ -464,7 +555,7 @@ function jira_fetch_issues(string $domain, string $email, string $apiToken, stri
/**
* Haalt alle actieve issues op die zijn toegewezen aan de ingelogde Jira gebruiker
*/
function jira_fetch_assigned_issues(string $domain, string $email, string $apiToken, int $maxResults = 50): array {
function jira_fetch_assigned_issues(string $domain, string $email, string $apiToken, int $maxResults = 100): array {
$jql = 'assignee = currentUser() ORDER BY updated DESC';
return jira_fetch_issues($domain, $email, $apiToken, $jql, $maxResults);
}
@@ -472,7 +563,7 @@ function jira_fetch_assigned_issues(string $domain, string $email, string $apiTo
/**
* Haalt openstaande team issues op die horen bij de projecten van de gebruiker
*/
function jira_fetch_team_issues(string $domain, string $email, string $apiToken, int $maxResults = 50): array {
function jira_fetch_team_issues(string $domain, string $email, string $apiToken, int $maxResults = 100): array {
$jql = 'assignee != currentUser() AND statusCategory != Done ORDER BY updated DESC';
return jira_fetch_issues($domain, $email, $apiToken, $jql, $maxResults);
}
@@ -486,18 +577,29 @@ function jira_get_dashboard_data(int $userId, bool $forceRefresh = false): array
$stmt->execute([$userId]);
$integration = $stmt->fetch();
// Ophalen van actieve wachtrijfilters en voorkeur van gebruiker
// Ophalen van actieve wachtrijfilters en voorkeuren van gebruiker
$queueFilters = jira_get_queue_filters(true);
$userQueuePref = jira_get_user_queue_preference($userId);
$userQueuePrefs = jira_get_user_queue_preferences($userId);
// Sandbox / Demo dataset indien niet gekoppeld of expliciet in demomodus
if (!$integration || !empty($integration['is_demo_mode'])) {
$demoStatuses = [
['id' => '1', 'name' => 'To Do', 'status_category' => 'new', 'category_name' => 'Nieuw'],
['id' => '2', 'name' => 'Nieuw', 'status_category' => 'new', 'category_name' => 'Nieuw'],
['id' => '3', 'name' => 'In behandeling', 'status_category' => 'indeterminate', 'category_name' => 'In uitvoering'],
['id' => '4', 'name' => 'Wachten op klant', 'status_category' => 'indeterminate', 'category_name' => 'In uitvoering'],
['id' => '5', 'name' => 'In Review', 'status_category' => 'indeterminate', 'category_name' => 'In uitvoering'],
['id' => '6', 'name' => 'Gereed', 'status_category' => 'done', 'category_name' => 'Gereed'],
['id' => '7', 'name' => 'Gesloten', 'status_category' => 'done', 'category_name' => 'Gereed'],
];
$assigned = [
[
'key' => 'SD-401',
'summary' => 'AFAS Profit SSO-koppeling geeft 401 fout bij token refresh',
'description' => "Gebruikers die via AFAS SSO inloggen krijgen periodiek een HTTP 401 foutcode bij de geautomatiseerde token verversing.\n\nHet endpoint `/oauth/token` reageert met `invalid_grant` zodra de refresh token ouder is dan 24 uur. Er dient een retry-mechanisme met fallback authenticatie ingebouwd te worden.",
'status' => 'In Progress',
'description' => "Gebruikers die via AFAS SSO inloggen krijgen periodiek een HTTP 401 foutcode bij de geautomatiseerde token verversing.\n\nHet endpoint `/oauth/token` reageert met `invalid_grant` zodra de refresh token ouder is dan 24 uur.",
'status' => 'In behandeling',
'status_category' => 'indeterminate',
'priority' => 'Highest',
'issue_type' => 'Bug',
@@ -512,12 +614,13 @@ function jira_get_dashboard_data(int $userId, bool $forceRefresh = false): array
'created' => date('Y-m-d H:i:s', strtotime('-1 day')),
'updated' => date('Y-m-d H:i:s', strtotime('-45 minutes')),
'url' => 'https://jira.atlassian.net/browse/SD-401',
'story_points' => 3,
'source' => 'SANDBOX',
],
[
'key' => 'SD-405',
'summary' => 'REST-endpoints voor medewerker synchronisatie beveiligen met rate limiting',
'description' => "De openbare REST-endpoints voor medewerkerssynchronisatie dienen conform security richtlijnen te worden voorzien van rate limiting (max 120 calls per minuut per IP).\n\nBij overschrijding moet een duidelijke HTTP 429 Retry-After header worden geretourneerd.",
'description' => "De openbare REST-endpoints voor medewerkerssynchronisatie dienen conform security richtlijnen te worden voorzien van rate limiting.",
'status' => 'To Do',
'status_category' => 'new',
'priority' => 'High',
@@ -533,14 +636,147 @@ function jira_get_dashboard_data(int $userId, bool $forceRefresh = false): array
'created' => date('Y-m-d H:i:s', strtotime('-2 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-2 hours')),
'url' => 'https://jira.atlassian.net/browse/SD-405',
'story_points' => 5,
'source' => 'SANDBOX',
],
[
'key' => 'IN-201',
'summary' => 'Exact Online REST API webhook connectie configureren',
'description' => "Configuratie van de webhook triggers voor realtime debiteuren synchronisatie tussen Fociz en Exact Online.",
'status' => 'In behandeling',
'status_category' => 'indeterminate',
'priority' => 'High',
'issue_type' => 'Story',
'project' => 'Interfaces',
'project_key' => 'IN',
'assignee_name' => 'Mijzelf',
'assignee_avatar' => '',
'reporter_name' => 'Financieel Beheer',
'reporter_avatar' => '',
'onderwerp_logging' => 'Koppelingen',
'due_date' => date('Y-m-d', strtotime('+2 days')),
'created' => date('Y-m-d H:i:s', strtotime('-3 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-30 minutes')),
'url' => 'https://jira.atlassian.net/browse/IN-201',
'story_points' => 8,
'source' => 'SANDBOX',
],
[
'key' => 'IN-205',
'summary' => 'OAuth 2.0 PKCE handshake voor mobiele koppeling afronden',
'description' => "Migreer de verouderde implicit flow naar de PKCE authorisatie flow voor alle mobiele apparaten.",
'status' => 'To Do',
'status_category' => 'new',
'priority' => 'Medium',
'issue_type' => 'Task',
'project' => 'Interfaces',
'project_key' => 'IN',
'assignee_name' => 'Mijzelf',
'assignee_avatar' => '',
'reporter_name' => 'Tech Lead',
'reporter_avatar' => '',
'onderwerp_logging' => 'SSO-koppeling',
'due_date' => date('Y-m-d', strtotime('+4 days')),
'created' => date('Y-m-d H:i:s', strtotime('-4 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-1 day')),
'url' => 'https://jira.atlassian.net/browse/IN-205',
'story_points' => 5,
'source' => 'SANDBOX',
],
[
'key' => 'AAN-102',
'summary' => 'Aanvraag nieuwe laptop en ergonomische thuiswerkplek beeldschermen',
'description' => "Nieuwe onboarding developer heeft MacBook Pro 16 inch en 2x 4K schermen nodig conform standaardpakket.",
'status' => 'Wachten op klant',
'status_category' => 'indeterminate',
'priority' => 'Medium',
'issue_type' => 'Task',
'project' => 'Aanvragen',
'project_key' => 'AAN',
'assignee_name' => 'Mijzelf',
'assignee_avatar' => '',
'reporter_name' => 'HR Onboarding',
'reporter_avatar' => '',
'onderwerp_logging' => 'Hardware',
'due_date' => date('Y-m-d', strtotime('+5 days')),
'created' => date('Y-m-d H:i:s', strtotime('-2 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-3 hours')),
'url' => 'https://jira.atlassian.net/browse/AAN-102',
'story_points' => 2,
'source' => 'SANDBOX',
],
[
'key' => 'AAN-108',
'summary' => 'Autorisatieverzoek rechten AFAS financieel beheer teamleider',
'description' => "Goedkeuring benodigd voor toekennen van geautoriseerde rollen in AFAS Profit.",
'status' => 'In behandeling',
'status_category' => 'indeterminate',
'priority' => 'High',
'issue_type' => 'Task',
'project' => 'Aanvragen',
'project_key' => 'AAN',
'assignee_name' => 'Mijzelf',
'assignee_avatar' => '',
'reporter_name' => 'Teamleider Financiën',
'reporter_avatar' => '',
'onderwerp_logging' => 'Rechten',
'due_date' => date('Y-m-d'),
'created' => date('Y-m-d H:i:s', strtotime('-1 day')),
'updated' => date('Y-m-d H:i:s', strtotime('-1 hour')),
'url' => 'https://jira.atlassian.net/browse/AAN-108',
'story_points' => 1,
'source' => 'SANDBOX',
],
[
'key' => 'GEN-301',
'summary' => 'Jaarlijkse ISO-27001 interne security review voorbereiden',
'description' => "Samenstellen van security checklists, access reviews en back-up logs voor auditcommissie.",
'status' => 'In behandeling',
'status_category' => 'indeterminate',
'priority' => 'High',
'issue_type' => 'Task',
'project' => 'General',
'project_key' => 'GEN',
'assignee_name' => 'Mijzelf',
'assignee_avatar' => '',
'reporter_name' => 'CISO',
'reporter_avatar' => '',
'onderwerp_logging' => 'Beveiliging',
'due_date' => date('Y-m-d', strtotime('+6 days')),
'created' => date('Y-m-d H:i:s', strtotime('-5 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-4 hours')),
'url' => 'https://jira.atlassian.net/browse/GEN-301',
'story_points' => 13,
'source' => 'SANDBOX',
],
[
'key' => 'GEN-305',
'summary' => 'Kantoorruimte vergadertafel opstelling aanpassen voor hybride team',
'description' => "Herinrichting van de videovergaderruimte met Yealink meetingbar.",
'status' => 'Gesloten',
'status_category' => 'done',
'priority' => 'Low',
'issue_type' => 'Task',
'project' => 'General',
'project_key' => 'GEN',
'assignee_name' => 'Mijzelf',
'assignee_avatar' => '',
'reporter_name' => 'Facility Management',
'reporter_avatar' => '',
'onderwerp_logging' => 'Facilitair',
'due_date' => date('Y-m-d', strtotime('-2 days')),
'created' => date('Y-m-d H:i:s', strtotime('-8 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-1 day')),
'url' => 'https://jira.atlassian.net/browse/GEN-305',
'story_points' => 1,
'source' => 'SANDBOX',
],
[
'key' => 'SD-380',
'summary' => 'Wachtwoord reset e-mail komt niet aan bij nieuwe medewerker',
'description' => "Een nieuwe medewerker ontvangt geen welkomstmail en wachtwoord reset via het selfservice portaal.\n\nControleer de SMTP-verbinding van de mailserver mail.fociz.nl en controleer of het mailadres in de spamfilter is beland.",
'status' => 'In Progress',
'status_category' => 'indeterminate',
'description' => "Controleer de SMTP-verbinding van de mailserver mail.fociz.nl en controleer of het mailadres in de spamfilter is beland.",
'status' => 'Gesloten',
'status_category' => 'done',
'priority' => 'High',
'issue_type' => 'Task',
'project' => 'Servicedesk',
@@ -550,136 +786,11 @@ function jira_get_dashboard_data(int $userId, bool $forceRefresh = false): array
'reporter_name' => 'HR Servicedesk',
'reporter_avatar' => '',
'onderwerp_logging' => 'EMPTY',
'due_date' => date('Y-m-d'),
'created' => date('Y-m-d H:i:s', strtotime('-3 hours')),
'updated' => date('Y-m-d H:i:s', strtotime('-1 hour')),
'url' => 'https://jira.atlassian.net/browse/SD-380',
'source' => 'SANDBOX',
],
[
'key' => 'SD-385',
'summary' => 'Rechten aanpassen voor rol Projectleider in urenregistratie',
'description' => "Projectleiders hebben momenteel alleen leesrechten op ingediende urenstaten. Graag de rol uitbreiden zodat zij declaraties direct kunnen goedkeuren of afkeuren.",
'status' => 'To Do',
'status_category' => 'new',
'priority' => 'Medium',
'issue_type' => 'Task',
'project' => 'Servicedesk',
'project_key' => 'SD',
'assignee_name' => 'Mijzelf',
'assignee_avatar' => '',
'reporter_name' => 'Marianne Willems',
'reporter_avatar' => '',
'onderwerp_logging' => 'Algemeen',
'due_date' => date('Y-m-d', strtotime('+5 days')),
'created' => date('Y-m-d H:i:s', strtotime('-3 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-1 day')),
'url' => 'https://jira.atlassian.net/browse/SD-385',
'source' => 'SANDBOX',
],
[
'key' => 'FOC-101',
'summary' => 'Tweestapsverificatie (2FA TOTP) flow implementeren',
'description' => "Ontwikkeling van een complete Google Authenticator / Microsoft Authenticator TOTP verificatie flow inclusief 8 cijferige noodcodes en QR-code weergave in het gebruikersprofiel.",
'status' => 'In Progress',
'status_category' => 'indeterminate',
'priority' => 'High',
'issue_type' => 'Story',
'project' => 'Fociz Platform',
'project_key' => 'FOC',
'assignee_name' => 'Mijzelf',
'assignee_avatar' => '',
'reporter_name' => 'Product Owner',
'reporter_avatar' => '',
'onderwerp_logging' => 'Beveiliging',
'due_date' => date('Y-m-d', strtotime('+2 days')),
'created' => date('Y-m-d H:i:s', strtotime('-4 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-2 hours')),
'url' => 'https://jira.atlassian.net/browse/FOC-101',
'source' => 'SANDBOX',
],
[
'key' => 'FOC-102',
'summary' => 'Interactief whiteboard canvas voor brainstormsessies',
'description' => "Gebruikers moeten live post-its kunnen slepen, kleuren en stemmen tijdens kwartaal brainstormsessies.",
'status' => 'To Do',
'status_category' => 'new',
'priority' => 'High',
'issue_type' => 'Feature',
'project' => 'Fociz Platform',
'project_key' => 'FOC',
'assignee_name' => 'Mijzelf',
'assignee_avatar' => '',
'reporter_name' => 'Scrum Master',
'reporter_avatar' => '',
'onderwerp_logging' => '',
'due_date' => date('Y-m-d', strtotime('+4 days')),
'created' => date('Y-m-d H:i:s', strtotime('-5 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-1 day')),
'url' => 'https://jira.atlassian.net/browse/FOC-102',
'source' => 'SANDBOX',
],
[
'key' => 'FOC-103',
'summary' => 'Koppeling met Microsoft Outlook Calendar & Teams Graph API',
'description' => "Synchronisatie van dagplanning blokken naar Microsoft 365 Exchange Online agenda met real-time conflictcontrole.",
'status' => 'In Review',
'status_category' => 'indeterminate',
'priority' => 'Medium',
'issue_type' => 'Task',
'project' => 'Integrations Hub',
'project_key' => 'INT',
'assignee_name' => 'Mijzelf',
'assignee_avatar' => '',
'reporter_name' => 'Architect',
'reporter_avatar' => '',
'onderwerp_logging' => 'SSO-koppeling',
'due_date' => date('Y-m-d'),
'created' => date('Y-m-d H:i:s', strtotime('-6 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-4 hours')),
'url' => 'https://jira.atlassian.net/browse/FOC-103',
'source' => 'SANDBOX',
],
[
'key' => 'FOC-108',
'summary' => 'CSS scrollbar glitch oplossen in Kanban lane op Firefox',
'description' => "Op Windows Firefox versies 128+ verspringt de horizontale scrollbalk bij het slepen van kaarten tussen kolommen.",
'status' => 'In Progress',
'status_category' => 'indeterminate',
'priority' => 'Highest',
'issue_type' => 'Bug',
'project' => 'UI/UX Redesign',
'project_key' => 'UI',
'assignee_name' => 'Mijzelf',
'assignee_avatar' => '',
'reporter_name' => 'QA Lead',
'reporter_avatar' => '',
'onderwerp_logging' => '',
'due_date' => date('Y-m-d', strtotime('+1 day')),
'created' => date('Y-m-d H:i:s', strtotime('-2 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-30 minutes')),
'url' => 'https://jira.atlassian.net/browse/FOC-108',
'source' => 'SANDBOX',
],
[
'key' => 'FOC-112',
'summary' => 'Avatar upload beveiliging en compressie optimalisatie',
'description' => "Server-side image re-encoding en EXIF stripping voor geüploade gebruikersavatars.",
'status' => 'Done',
'status_category' => 'done',
'priority' => 'Medium',
'issue_type' => 'Task',
'project' => 'Security',
'project_key' => 'SEC',
'assignee_name' => 'Mijzelf',
'assignee_avatar' => '',
'reporter_name' => 'SecOps',
'reporter_avatar' => '',
'onderwerp_logging' => '',
'due_date' => date('Y-m-d', strtotime('-1 day')),
'created' => date('Y-m-d H:i:s', strtotime('-7 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-5 hours')),
'url' => 'https://jira.atlassian.net/browse/FOC-112',
'created' => date('Y-m-d H:i:s', strtotime('-3 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-6 hours')),
'url' => 'https://jira.atlassian.net/browse/SD-380',
'story_points' => 2,
'source' => 'SANDBOX',
],
];
@@ -688,8 +799,8 @@ function jira_get_dashboard_data(int $userId, bool $forceRefresh = false): array
[
'key' => 'SD-408',
'summary' => 'UWV-koppeling polisadministratie import loopt vast op datumformaat',
'description' => "De XML batch import vanuit het UWV portaal faalt op records met afwijkende geboortedatumnotatie.\n\nDe parser dient flexibel zowel ISO-8601 (YYYY-MM-DD) als traditioneel formaat (DD-MM-YYYY) te accepteren.",
'status' => 'In Progress',
'description' => "De XML batch import vanuit het UWV portaal faalt op records met afwijkende geboortedatumnotatie.",
'status' => 'In behandeling',
'status_category' => 'indeterminate',
'priority' => 'High',
'issue_type' => 'Bug',
@@ -704,6 +815,7 @@ function jira_get_dashboard_data(int $userId, bool $forceRefresh = false): array
'created' => date('Y-m-d H:i:s', strtotime('-2 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-1 hour')),
'url' => 'https://jira.atlassian.net/browse/SD-408',
'story_points' => 5,
'source' => 'SANDBOX',
],
[
@@ -725,39 +837,19 @@ function jira_get_dashboard_data(int $userId, bool $forceRefresh = false): array
'created' => date('Y-m-d H:i:s', strtotime('-3 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-4 hours')),
'url' => 'https://jira.atlassian.net/browse/SD-412',
'story_points' => 3,
'source' => 'SANDBOX',
],
[
'key' => 'SD-416',
'summary' => 'Migratie van oude klantportaal database naar MariaDB 11 cluster',
'description' => "Voorbereiden en uitvoeren van de dataschemamigratie van het oude portaal naar de nieuwe MariaDB 11 clusteromgeving inclusief regressietests.",
'status' => 'To Do',
'status_category' => 'new',
'priority' => 'High',
'issue_type' => 'Story',
'project' => 'Servicedesk',
'project_key' => 'SD',
'assignee_name' => 'Bram Meijer',
'assignee_avatar' => '',
'reporter_name' => 'Lead Engineer',
'reporter_avatar' => '',
'onderwerp_logging' => 'Migratie',
'due_date' => date('Y-m-d', strtotime('+8 days')),
'created' => date('Y-m-d H:i:s', strtotime('-4 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-6 hours')),
'url' => 'https://jira.atlassian.net/browse/SD-416',
'source' => 'SANDBOX',
],
[
'key' => 'SD-420',
'key' => 'IN-210',
'summary' => 'Koppelingen API webhook notificaties afleveren met retry-mechanisme',
'description' => "Webhooks die naar externe partnersystemen worden verzonden moeten bij een tijdelijke 5xx fout automatisch 3x opnieuw worden aangeboden (exponential backoff).",
'status' => 'In Review',
'description' => "Webhooks die naar externe partnersystemen worden verzonden moeten bij een tijdelijke 5xx fout automatisch 3x opnieuw worden aangeboden.",
'status' => 'In behandeling',
'status_category' => 'indeterminate',
'priority' => 'Medium',
'issue_type' => 'Task',
'project' => 'Servicedesk',
'project_key' => 'SD',
'project' => 'Interfaces',
'project_key' => 'IN',
'assignee_name' => 'Sophie de Vries',
'assignee_avatar' => '',
'reporter_name' => 'Integratie Specialist',
@@ -766,112 +858,118 @@ function jira_get_dashboard_data(int $userId, bool $forceRefresh = false): array
'due_date' => date('Y-m-d', strtotime('+4 days')),
'created' => date('Y-m-d H:i:s', strtotime('-5 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-3 hours')),
'url' => 'https://jira.atlassian.net/browse/SD-420',
'url' => 'https://jira.atlassian.net/browse/IN-210',
'story_points' => 5,
'source' => 'SANDBOX',
],
[
'key' => 'SD-392',
'summary' => 'Outlook Agenda synchronisatie toont dubbele afspraken op mobiel',
'description' => "Bij enkele gebruikers met de iOS Outlook app worden terugkerende agenda-afspraken tweemaal weergegeven na het synchroniseren.",
'status' => 'In Progress',
'key' => 'IN-215',
'summary' => 'Specificatie documentatie voor externe partner API opvragen',
'description' => "Opvragen van de actuele OpenAPI v3 JSON specificatie bij leverancier.",
'status' => 'Wachten op klant',
'status_category' => 'indeterminate',
'priority' => 'Medium',
'issue_type' => 'Bug',
'project' => 'Servicedesk',
'project_key' => 'SD',
'assignee_name' => 'Lisa Bakker',
'assignee_avatar' => '',
'reporter_name' => 'Servicedesk Support',
'reporter_avatar' => '',
'onderwerp_logging' => 'Incident',
'due_date' => date('Y-m-d', strtotime('+3 days')),
'created' => date('Y-m-d H:i:s', strtotime('-3 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-2 hours')),
'url' => 'https://jira.atlassian.net/browse/SD-392',
'source' => 'SANDBOX',
],
[
'key' => 'SD-399',
'summary' => 'Vraag over exportmogelijkheden naar Excel rapportage',
'description' => "Klant informeert of het mogelijk is om een wekelijkse CSV / Excel export van de urenstaten automatisch per mail te ontvangen.",
'status' => 'To Do',
'status_category' => 'new',
'priority' => 'Low',
'issue_type' => 'Task',
'project' => 'Servicedesk',
'project_key' => 'SD',
'project' => 'Interfaces',
'project_key' => 'IN',
'assignee_name' => 'Sophie de Vries',
'assignee_avatar' => '',
'reporter_name' => 'Partner Manager',
'reporter_avatar' => '',
'onderwerp_logging' => 'Koppelingen',
'due_date' => date('Y-m-d', strtotime('+7 days')),
'created' => date('Y-m-d H:i:s', strtotime('-4 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-2 hours')),
'url' => 'https://jira.atlassian.net/browse/IN-215',
'story_points' => 1,
'source' => 'SANDBOX',
],
[
'key' => 'AAN-110',
'summary' => 'Aanvraag extra Microsoft 365 E5 licenties voor marketing team',
'description' => "Bestelling en activering van 5 aanvullende E5 licenties voor het datateam.",
'status' => 'To Do',
'status_category' => 'new',
'priority' => 'Medium',
'issue_type' => 'Task',
'project' => 'Aanvragen',
'project_key' => 'AAN',
'assignee_name' => 'Thomas Jansen',
'assignee_avatar' => '',
'reporter_name' => 'Financieel Directeur',
'reporter_name' => 'Marketing Director',
'reporter_avatar' => '',
'onderwerp_logging' => 'Vraag',
'due_date' => date('Y-m-d', strtotime('+10 days')),
'created' => date('Y-m-d H:i:s', strtotime('-5 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-1 day')),
'url' => 'https://jira.atlassian.net/browse/SD-399',
'source' => 'SANDBOX',
],
[
'key' => 'FOC-95',
'summary' => 'Sessie timeout notificatie verschijnt niet tijdig bij inactieve tab',
'description' => "Wanneer een gebruiker de browser 2 uur niet aanraakt, vervalt de PHP sessie zonder dat het login-dialoogvenster netjes openspringt.",
'status' => 'In Progress',
'status_category' => 'indeterminate',
'priority' => 'Highest',
'issue_type' => 'Bug',
'project' => 'Fociz Platform',
'project_key' => 'FOC',
'assignee_name' => 'Lisa Bakker',
'assignee_avatar' => '',
'reporter_name' => 'Product QA',
'reporter_avatar' => '',
'onderwerp_logging' => '',
'due_date' => date('Y-m-d', strtotime('+1 day')),
'created' => date('Y-m-d H:i:s', strtotime('-2 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-1 hour')),
'url' => 'https://jira.atlassian.net/browse/FOC-95',
'source' => 'SANDBOX',
],
[
'key' => 'FOC-98',
'summary' => 'Automatische e-mail triggers voor taakdeadlines en uitnodigingen',
'description' => "Cronjob instellen die 24 uur voor de deadline van een taak een herinneringsmail stuurt via SMTP.",
'status' => 'To Do',
'status_category' => 'new',
'priority' => 'High',
'issue_type' => 'Story',
'project' => 'Notifications',
'project_key' => 'NOTIF',
'assignee_name' => 'Daan van Dijk',
'assignee_avatar' => '',
'reporter_name' => 'Operations',
'reporter_avatar' => '',
'onderwerp_logging' => '',
'onderwerp_logging' => 'Licenties',
'due_date' => date('Y-m-d', strtotime('+3 days')),
'created' => date('Y-m-d H:i:s', strtotime('-3 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-2 days')),
'url' => 'https://jira.atlassian.net/browse/FOC-98',
'created' => date('Y-m-d H:i:s', strtotime('-2 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-1 day')),
'url' => 'https://jira.atlassian.net/browse/AAN-110',
'story_points' => 2,
'source' => 'SANDBOX',
],
[
'key' => 'FOC-110',
'summary' => 'Real-time websocket synchronisatie voor gelijktijdig bewerken van borden',
'description' => "Voorkom overschrijfconflicten wanneer meerdere collega's gelijktijdig kaarten verplaatsen op hetzelfde Kanban bord.",
'status' => 'To Do',
'status_category' => 'new',
'key' => 'AAN-115',
'summary' => 'Aanvraag tijdelijke VPN toegang externe auditor KPMG',
'description' => "Toegang configureren met verloopdatum 30 september en MFA verplichting.",
'status' => 'Gesloten',
'status_category' => 'done',
'priority' => 'High',
'issue_type' => 'Story',
'project' => 'Realtime Engine',
'project_key' => 'RT',
'issue_type' => 'Task',
'project' => 'Aanvragen',
'project_key' => 'AAN',
'assignee_name' => 'Bram Meijer',
'assignee_avatar' => '',
'reporter_name' => 'Architect',
'reporter_name' => 'Security Officer',
'reporter_avatar' => '',
'onderwerp_logging' => '',
'due_date' => date('Y-m-d', strtotime('+6 days')),
'onderwerp_logging' => 'Rechten',
'due_date' => date('Y-m-d', strtotime('-3 days')),
'created' => date('Y-m-d H:i:s', strtotime('-7 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-2 days')),
'url' => 'https://jira.atlassian.net/browse/AAN-115',
'story_points' => 2,
'source' => 'SANDBOX',
],
[
'key' => 'GEN-310',
'summary' => 'Organisatiebeleid hybride werken 2026 actualiseren',
'description' => "Aanpassing van reiskostenvergoeding en thuiswerkvergoeding conform nieuwe cao-afspraken.",
'status' => 'In behandeling',
'status_category' => 'indeterminate',
'priority' => 'Medium',
'issue_type' => 'Story',
'project' => 'General',
'project_key' => 'GEN',
'assignee_name' => 'Lisa Bakker',
'assignee_avatar' => '',
'reporter_name' => 'Directie',
'reporter_avatar' => '',
'onderwerp_logging' => 'Algemeen',
'due_date' => date('Y-m-d', strtotime('+10 days')),
'created' => date('Y-m-d H:i:s', strtotime('-6 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-1 day')),
'url' => 'https://jira.atlassian.net/browse/GEN-310',
'story_points' => 5,
'source' => 'SANDBOX',
],
[
'key' => 'GEN-315',
'summary' => 'Kwartaalplanning en doelstellingen inventarisatie Q4',
'description' => "Verzamel OKR's van alle teams voor de centrale kwartaalpresentatie.",
'status' => 'To Do',
'status_category' => 'new',
'priority' => 'High',
'issue_type' => 'Story',
'project' => 'General',
'project_key' => 'GEN',
'assignee_name' => 'Bram Meijer',
'assignee_avatar' => '',
'reporter_name' => 'Operations Lead',
'reporter_avatar' => '',
'onderwerp_logging' => 'Algemeen',
'due_date' => date('Y-m-d', strtotime('+8 days')),
'created' => date('Y-m-d H:i:s', strtotime('-4 days')),
'updated' => date('Y-m-d H:i:s', strtotime('-6 hours')),
'url' => 'https://jira.atlassian.net/browse/FOC-110',
'updated' => date('Y-m-d H:i:s', strtotime('-5 hours')),
'url' => 'https://jira.atlassian.net/browse/GEN-315',
'story_points' => 8,
'source' => 'SANDBOX',
],
];
@@ -887,6 +985,8 @@ function jira_get_dashboard_data(int $userId, bool $forceRefresh = false): array
'team_issues' => $team,
'queue_filters' => $queueFilters,
'default_queue_filter' => $userQueuePref,
'user_queue_filters' => $userQueuePrefs,
'available_statuses' => $demoStatuses,
];
}
@@ -921,10 +1021,12 @@ function jira_get_dashboard_data(int $userId, bool $forceRefresh = false): array
}
}
// Ophalen van toegewezen taken
$assignedRes = jira_fetch_assigned_issues($domain, $email, $apiToken, 50);
// Ophalen van teamtaken
$teamRes = jira_fetch_team_issues($domain, $email, $apiToken, 50);
// Ophalen van toegewezen taken (max 100)
$assignedRes = jira_fetch_assigned_issues($domain, $email, $apiToken, 100);
// Ophalen van teamtaken (max 100)
$teamRes = jira_fetch_team_issues($domain, $email, $apiToken, 100);
// Ophalen van Jira statussen
$availableStatuses = jira_fetch_statuses($domain, $email, $apiToken);
if (!$assignedRes['success'] && !$teamRes['success']) {
return [
@@ -950,6 +1052,8 @@ function jira_get_dashboard_data(int $userId, bool $forceRefresh = false): array
'team_issues' => $teamIssues,
'queue_filters' => $queueFilters,
'default_queue_filter' => $userQueuePref,
'user_queue_filters' => $userQueuePrefs,
'available_statuses' => $availableStatuses,
];
fociz_cache_set($cacheKey, $data, 60);
+531 -261
View File
File diff suppressed because it is too large Load Diff