Dev #76
+89
-18
@@ -1550,8 +1550,11 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
||||
|
||||
<?php $isJiraPlanned = !empty($plannedExternalIds[$issue['key']]); ?>
|
||||
<button
|
||||
onclick="quickImportJiraByKey(this, '<?= htmlspecialchars($issue['key'] ?? '') ?>')"
|
||||
onclick="quickImportJiraByKey(this, '<?= htmlspecialchars($issue['key'] ?? '') ?>', event)"
|
||||
data-jira-key="<?= htmlspecialchars($issue['key'] ?? '') ?>"
|
||||
data-jira-summary="<?= htmlspecialchars($issue['summary'] ?? '') ?>"
|
||||
data-jira-status="<?= htmlspecialchars($issue['status'] ?? 'To Do') ?>"
|
||||
data-jira-priority="<?= htmlspecialchars($issue['priority'] ?? 'Medium') ?>"
|
||||
class="plan-btn-jira flex items-center space-x-1 text-[11px] <?= $isJiraPlanned ? 'font-bold text-white bg-emerald-600 hover:bg-emerald-500 border border-emerald-600 shadow-xs' : 'font-semibold text-indigo-600 dark:text-indigo-400 hover:text-indigo-700 dark:hover:text-indigo-300 bg-indigo-50 dark:bg-indigo-500/10 hover:bg-indigo-100 dark:hover:bg-indigo-500/20 border border-indigo-200 dark:border-indigo-500/20' ?> px-2.5 py-1 rounded-lg transition flex-shrink-0 cursor-pointer"
|
||||
title="<?= $isJiraPlanned ? 'Dit ticket is al ingepland als dagtaak (klik om status te bekijken of te herplannen)' : 'Plan in als dagtaak' ?>"
|
||||
>
|
||||
@@ -4638,17 +4641,22 @@ document.addEventListener('click', (e) => {
|
||||
});
|
||||
|
||||
// --- Jira Queue & Tickets Widget Engine (v2.0) ---
|
||||
const plannerJiraAssigned = <?= json_encode($jiraAssignedIssues, JSON_UNESCAPED_UNICODE) ?>;
|
||||
const plannerJiraAll = <?= json_encode($jiraAllIssues, JSON_UNESCAPED_UNICODE) ?>;
|
||||
const plannerJiraAssigned = <?= json_encode($jiraAssignedIssues, JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) ?>;
|
||||
const plannerJiraAll = <?= json_encode($jiraAllIssues, JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) ?>;
|
||||
const plannerTicketStore = new Map();
|
||||
plannerJiraAll.forEach(iss => {
|
||||
if (iss && iss.key) plannerTicketStore.set(iss.key, iss);
|
||||
(Array.isArray(plannerJiraAll) ? plannerJiraAll : []).forEach(iss => {
|
||||
if (iss && iss.key) plannerTicketStore.set(String(iss.key).trim().toUpperCase(), iss);
|
||||
});
|
||||
plannerJiraAssigned.forEach(iss => {
|
||||
if (iss && iss.key && !plannerTicketStore.has(iss.key)) plannerTicketStore.set(iss.key, iss);
|
||||
(Array.isArray(plannerJiraAssigned) ? plannerJiraAssigned : []).forEach(iss => {
|
||||
if (iss && iss.key) {
|
||||
const normKey = String(iss.key).trim().toUpperCase();
|
||||
if (!plannerTicketStore.has(normKey)) {
|
||||
plannerTicketStore.set(normKey, iss);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const plannedExternalTasksMap = <?= json_encode($plannedExternalIds, JSON_UNESCAPED_UNICODE) ?> || {};
|
||||
const plannedExternalTasksMap = <?= json_encode($plannedExternalIds, JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) ?> || {};
|
||||
const plannedExternalIdsSet = new Set(Object.keys(plannedExternalTasksMap));
|
||||
let activePlannerJiraQueue = ''; // '': Alle, 'my': Mijn, 'DX': DX Queue, 'SD': SD Queue
|
||||
|
||||
@@ -4754,8 +4762,11 @@ function filterPlannerJira() {
|
||||
const isPlanned = plannedExternalIdsSet.has(issue.key);
|
||||
const planBtn = isPlanned
|
||||
? `<button
|
||||
onclick="quickImportJiraByKey(this, '${keyEsc}')"
|
||||
onclick="quickImportJiraByKey(this, '${keyEsc}', event)"
|
||||
data-jira-key="${keyEsc}"
|
||||
data-jira-summary="${summaryEsc}"
|
||||
data-jira-status="${statusEsc}"
|
||||
data-jira-priority="${priorityEsc}"
|
||||
class="plan-btn-jira flex items-center space-x-1 text-[11px] font-bold text-white bg-emerald-600 hover:bg-emerald-500 border border-emerald-600 shadow-xs px-2.5 py-1 rounded-lg transition flex-shrink-0 cursor-pointer"
|
||||
title="Dit ticket is al ingepland als dagtaak (klik om status te bekijken of te herplannen)"
|
||||
>
|
||||
@@ -4763,8 +4774,11 @@ function filterPlannerJira() {
|
||||
<span>Ingepland</span>
|
||||
</button>`
|
||||
: `<button
|
||||
onclick="quickImportJiraByKey(this, '${keyEsc}')"
|
||||
onclick="quickImportJiraByKey(this, '${keyEsc}', event)"
|
||||
data-jira-key="${keyEsc}"
|
||||
data-jira-summary="${summaryEsc}"
|
||||
data-jira-status="${statusEsc}"
|
||||
data-jira-priority="${priorityEsc}"
|
||||
class="plan-btn-jira flex items-center space-x-1 text-[11px] font-semibold text-indigo-600 dark:text-indigo-400 hover:text-indigo-700 dark:hover:text-indigo-300 bg-indigo-50 dark:bg-indigo-500/10 hover:bg-indigo-100 dark:hover:bg-indigo-500/20 border border-indigo-200 dark:border-indigo-500/20 px-2.5 py-1 rounded-lg transition flex-shrink-0 cursor-pointer"
|
||||
title="Plan in als dagtaak"
|
||||
>
|
||||
@@ -4803,8 +4817,27 @@ function filterPlannerJira() {
|
||||
let _jiraDetailCurrentIssue = null;
|
||||
|
||||
function openJiraTicketDetail(issueKey) {
|
||||
const issue = plannerTicketStore.get(issueKey);
|
||||
if (!issue) return;
|
||||
const rawKey = String(issueKey || '').trim();
|
||||
const normKey = rawKey.toUpperCase();
|
||||
let issue = plannerTicketStore.get(normKey) || plannerTicketStore.get(rawKey);
|
||||
|
||||
if (!issue) {
|
||||
// Fallback: probeer element op te halen uit de lijst
|
||||
const cardBtn = document.querySelector(`[data-jira-key="${rawKey}"]`);
|
||||
const summary = cardBtn?.getAttribute('data-jira-summary') || '';
|
||||
const status = cardBtn?.getAttribute('data-jira-status') || 'To Do';
|
||||
const priority = cardBtn?.getAttribute('data-jira-priority') || 'Medium';
|
||||
|
||||
issue = {
|
||||
key: rawKey,
|
||||
summary: summary || `Jira item ${rawKey}`,
|
||||
status: status,
|
||||
priority: priority,
|
||||
description: '',
|
||||
url: ''
|
||||
};
|
||||
plannerTicketStore.set(normKey, issue);
|
||||
}
|
||||
_jiraDetailCurrentIssue = issue;
|
||||
|
||||
// Vul header
|
||||
@@ -4930,9 +4963,30 @@ function toggleJiraPlanDescription() {
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
}
|
||||
|
||||
function openJiraPlanModal(issueKey) {
|
||||
const issue = plannerTicketStore.get(issueKey);
|
||||
if (!issue) return;
|
||||
function openJiraPlanModal(issueKey, fallbackData = null) {
|
||||
const rawKey = String(issueKey || '').trim();
|
||||
const normKey = rawKey.toUpperCase();
|
||||
let issue = plannerTicketStore.get(normKey) || plannerTicketStore.get(rawKey);
|
||||
|
||||
if (!issue) {
|
||||
// Zoek fallback gegevens op de plan-knop in de DOM
|
||||
const btn = document.querySelector(`[data-jira-key="${rawKey}"]`) || document.querySelector(`[data-jira-key="${normKey}"]`);
|
||||
const summary = fallbackData?.summary || btn?.getAttribute('data-jira-summary') || '';
|
||||
const status = fallbackData?.status || btn?.getAttribute('data-jira-status') || 'To Do';
|
||||
const priority = fallbackData?.priority || btn?.getAttribute('data-jira-priority') || 'Medium';
|
||||
|
||||
issue = {
|
||||
key: rawKey || 'JIRA-ITEM',
|
||||
summary: summary || (rawKey ? `Oppakken Jira item ${rawKey}` : 'Jira taak'),
|
||||
status: status,
|
||||
priority: priority,
|
||||
description: fallbackData?.description || '',
|
||||
url: fallbackData?.url || ''
|
||||
};
|
||||
if (rawKey) {
|
||||
plannerTicketStore.set(normKey, issue);
|
||||
}
|
||||
}
|
||||
_jiraPlanCurrentIssue = issue;
|
||||
|
||||
// Vul header
|
||||
@@ -5350,9 +5404,26 @@ async function submitJiraPlanModal() {
|
||||
}
|
||||
}
|
||||
|
||||
async function quickImportJiraByKey(btn, issueKey) {
|
||||
// Plan knop → open de plan modal (niet direct importeren)
|
||||
openJiraPlanModal(issueKey);
|
||||
async function quickImportJiraByKey(btn, issueKey, event = null) {
|
||||
if (event) {
|
||||
try {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
const rawKey = String(issueKey || '').trim();
|
||||
let fallbackData = null;
|
||||
|
||||
if (btn) {
|
||||
fallbackData = {
|
||||
summary: btn.getAttribute('data-jira-summary') || '',
|
||||
status: btn.getAttribute('data-jira-status') || 'To Do',
|
||||
priority: btn.getAttribute('data-jira-priority') || 'Medium'
|
||||
};
|
||||
}
|
||||
|
||||
openJiraPlanModal(rawKey, fallbackData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user