Brainstorm huge refactor

This commit is contained in:
2026-09-14 11:10:54 +02:00
parent 5a31f0948a
commit 24fbfb9d82
9 changed files with 747 additions and 41 deletions
+142 -2
View File
@@ -18,10 +18,13 @@ if ($isAjaxRequest) {
require_once __DIR__ . '/includes/settings.php';
require_once __DIR__ . '/includes/integrations/microsoft.php';
require_once __DIR__ . '/includes/integrations/jira.php';
require_once __DIR__ . '/includes/boards.php';
$db = get_db_connection();
$userId = (int)($currentUser['id'] ?? 0);
$isAdmin = (($currentUser['role'] ?? '') === 'ADMIN');
$today = date('Y-m-d');
$userBoards = fociz_get_user_boards_with_lanes($db, $userId, $isAdmin);
// Indien de datum van vandaag via de URL is meegegeven bij een normale pagina-aanroep, schoon de URL op naar zuiver 'planner.php'
if (!$isAjaxRequest && isset($_GET['date']) && $_GET['date'] === $today) {
@@ -2126,6 +2129,55 @@ if ($isAjaxRequest) {
<option value="P3" selected>P3 — Normaal</option>
</select>
</div>
<!-- Optie: Tevens toevoegen aan Bord & Tijdlijn -->
<div class="p-3 rounded-xl bg-slate-50 dark:bg-slate-900/40 border border-slate-200 dark:border-slate-800 space-y-2.5">
<label class="flex items-center space-x-2.5 cursor-pointer select-none">
<input type="checkbox" id="jiraPlanAddToBoard" onchange="toggleJiraBoardOptions(this.checked)" class="w-4 h-4 rounded text-indigo-600 focus:ring-indigo-500 border-slate-300 dark:border-slate-700 dark:bg-slate-900 cursor-pointer">
<span class="text-xs font-bold text-slate-800 dark:text-slate-200 flex items-center space-x-1.5">
<i data-lucide="layout-grid" class="w-3.5 h-3.5 text-indigo-600 dark:text-indigo-400"></i>
<span>Tevens toevoegen aan Bord &amp; Tijdlijn</span>
</span>
</label>
<div id="jiraBoardOptionsWrapper" class="hidden space-y-2.5 pt-2.5 border-t border-slate-200/70 dark:border-slate-800">
<?php if (empty($userBoards)): ?>
<p class="text-[11px] text-slate-500 dark:text-slate-400">Er zijn geen actieve borden gevonden.</p>
<?php else: ?>
<div class="grid grid-cols-2 gap-2">
<div>
<label for="jiraPlanBoardSelect" class="block text-[10px] font-bold text-slate-600 dark:text-slate-400 mb-1 uppercase tracking-wider">Bord</label>
<select id="jiraPlanBoardSelect" onchange="onJiraBoardSelectChange(this.value)" class="w-full bg-white dark:bg-[#0c0f17] border border-slate-200 dark:border-slate-800 rounded-xl px-2.5 py-1.5 text-xs text-slate-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-indigo-500">
<?php foreach ($userBoards as $b): ?>
<option value="<?= (int)$b['id'] ?>"><?= htmlspecialchars($b['title']) ?></option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="jiraPlanLaneSelect" class="block text-[10px] font-bold text-slate-600 dark:text-slate-400 mb-1 uppercase tracking-wider">Kolom</label>
<select id="jiraPlanLaneSelect" class="w-full bg-white dark:bg-[#0c0f17] border border-slate-200 dark:border-slate-800 rounded-xl px-2.5 py-1.5 text-xs text-slate-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-indigo-500">
<!-- Wordt gevuld via JS -->
</select>
</div>
</div>
<div class="pt-1">
<label class="flex items-center space-x-2 cursor-pointer select-none">
<input type="checkbox" id="jiraPlanScheduleOnTimeline" checked onchange="toggleJiraTimelineDates(this.checked)" class="w-3.5 h-3.5 rounded text-indigo-600 focus:ring-indigo-500 border-slate-300 dark:border-slate-700 dark:bg-slate-900 cursor-pointer">
<span class="text-xs font-medium text-slate-700 dark:text-slate-300">Inplannen op de Project Tijdlijn</span>
</label>
<div id="jiraTimelineDatesWrapper" class="grid grid-cols-2 gap-2 mt-2">
<div>
<label for="jiraTimelineStartDate" class="block text-[10px] font-bold text-slate-600 dark:text-slate-400 mb-1 uppercase tracking-wider">Startdatum</label>
<input type="date" id="jiraTimelineStartDate" class="w-full bg-white dark:bg-[#0c0f17] border border-slate-200 dark:border-slate-800 rounded-xl px-2.5 py-1.5 text-xs text-slate-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-indigo-500">
</div>
<div>
<label for="jiraTimelineEndDate" class="block text-[10px] font-bold text-slate-600 dark:text-slate-400 mb-1 uppercase tracking-wider">Einddatum</label>
<input type="date" id="jiraTimelineEndDate" class="w-full bg-white dark:bg-[#0c0f17] border border-slate-200 dark:border-slate-800 rounded-xl px-2.5 py-1.5 text-xs text-slate-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-indigo-500">
</div>
</div>
</div>
<?php endif; ?>
</div>
</div>
</div>
<div class="flex space-x-3 pt-2 border-t border-slate-100 dark:border-slate-800/80">
@@ -4976,6 +5028,59 @@ function toggleJiraPlanDescription() {
if (typeof lucide !== 'undefined') lucide.createIcons();
}
const availableUserBoards = <?= json_encode($userBoards, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP) ?> || [];
function toggleJiraBoardOptions(show) {
const wrapper = document.getElementById('jiraBoardOptionsWrapper');
if (wrapper) {
if (show) {
wrapper.classList.remove('hidden');
const boardSelect = document.getElementById('jiraPlanBoardSelect');
if (boardSelect && boardSelect.value) {
onJiraBoardSelectChange(boardSelect.value);
}
// Sync start en einddatum met de gekozen plandatum
const planDate = document.getElementById('jiraPlanDate')?.value || '';
const startInput = document.getElementById('jiraTimelineStartDate');
const endInput = document.getElementById('jiraTimelineEndDate');
if (startInput && !startInput.value) startInput.value = planDate;
if (endInput && !endInput.value) endInput.value = planDate;
} else {
wrapper.classList.add('hidden');
}
}
}
function onJiraBoardSelectChange(boardId) {
const laneSelect = document.getElementById('jiraPlanLaneSelect');
if (!laneSelect) return;
laneSelect.innerHTML = '';
const board = availableUserBoards.find(b => String(b.id) === String(boardId));
if (board && board.lanes && board.lanes.length > 0) {
board.lanes.forEach((lane, idx) => {
const opt = document.createElement('option');
opt.value = lane.id;
opt.textContent = lane.title;
if (idx === 0) opt.selected = true;
laneSelect.appendChild(opt);
});
} else {
const opt = document.createElement('option');
opt.value = '';
opt.textContent = 'Geen kolommen beschikbaar';
laneSelect.appendChild(opt);
}
}
function toggleJiraTimelineDates(show) {
const wrapper = document.getElementById('jiraTimelineDatesWrapper');
if (wrapper) {
if (show) wrapper.classList.remove('hidden');
else wrapper.classList.add('hidden');
}
}
function openJiraPlanModal(issueKey, fallbackData = null) {
const rawKey = String(issueKey || '').trim();
const normKey = rawKey.toUpperCase();
@@ -5111,6 +5216,22 @@ function openJiraPlanModal(issueKey, fallbackData = null) {
if (notice) notice.classList.add('hidden');
updateJiraPlanEndTimeDisplay();
// Reset board & timeline velden
const addToBoardCb = document.getElementById('jiraPlanAddToBoard');
if (addToBoardCb) {
addToBoardCb.checked = false;
toggleJiraBoardOptions(false);
}
const schedTimelineCb = document.getElementById('jiraPlanScheduleOnTimeline');
if (schedTimelineCb) {
schedTimelineCb.checked = true;
toggleJiraTimelineDates(true);
}
const tStart = document.getElementById('jiraTimelineStartDate');
const tEnd = document.getElementById('jiraTimelineEndDate');
if (tStart) tStart.value = targetDate;
if (tEnd) tEnd.value = targetDate;
// Reset submit button state
const submitBtn = document.getElementById('btnSubmitJiraPlan');
if (submitBtn) {
@@ -5328,6 +5449,23 @@ async function submitJiraPlanModal() {
finalEndTime = `${String(Math.floor(endMin / 60)).padStart(2,'0')}:${String(endMin % 60).padStart(2,'0')}`;
}
const addToBoard = document.getElementById('jiraPlanAddToBoard')?.checked || false;
const boardId = parseInt(document.getElementById('jiraPlanBoardSelect')?.value || '0', 10);
const laneId = parseInt(document.getElementById('jiraPlanLaneSelect')?.value || '0', 10);
const scheduleOnTimeline = document.getElementById('jiraPlanScheduleOnTimeline')?.checked || false;
const timelineStartDate = document.getElementById('jiraTimelineStartDate')?.value || planDate;
const timelineEndDate = document.getElementById('jiraTimelineEndDate')?.value || timelineStartDate;
const boardPayload = {
add_to_board: addToBoard,
board_id: boardId,
lane_id: laneId,
schedule_on_timeline: scheduleOnTimeline,
timeline_start_date: timelineStartDate,
timeline_end_date: timelineEndDate,
description: issue.summary ? `${issue.key}: ${issue.summary}` : ''
};
if (isUpdate) {
// Bestaande taak bijwerken / verplaatsen naar eventueel andere datum
res = await fetch('/api/planner.php?action=update_task', {
@@ -5340,7 +5478,8 @@ async function submitJiraPlanModal() {
duration_minutes: duration,
time_block_start: finalStartTime,
time_block_end: finalEndTime,
date: planDate
date: planDate,
...boardPayload
})
});
data = await res.json();
@@ -5353,7 +5492,8 @@ async function submitJiraPlanModal() {
external_id: issue.key,
external_url: issue.url || '',
duration_minutes: duration,
date: planDate
date: planDate,
...boardPayload
};
if (finalStartTime) {
payload.time_block_start = finalStartTime;