feat: Add story points support and AI daily briefing feature
- Enhanced JIRA integration to fetch story points from multiple custom fields. - Updated task display to show story points and their estimated duration. - Introduced AI daily briefing banner with dynamic content loading. - Implemented subtasks functionality with add, toggle, and delete capabilities. - Improved task management UI with better accessibility and interaction.
This commit is contained in:
@@ -494,10 +494,15 @@ $boardsJson = json_encode($boards, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT
|
||||
<div class="flex items-center space-x-2">
|
||||
<span id="planTicketKeyBadge" class="font-mono text-xs font-bold text-indigo-600 dark:text-indigo-400">FOC-101</span>
|
||||
<span id="planTicketProject" class="text-[11px] text-slate-400">• Fociz Platform</span>
|
||||
<span id="planSpBadge" class="hidden ml-auto text-[10px] font-bold px-2 py-0.5 rounded-full bg-violet-50 dark:bg-violet-500/10 text-violet-700 dark:text-violet-300 border border-violet-200 dark:border-violet-500/20"></span>
|
||||
</div>
|
||||
<div id="planTicketSummaryText" class="text-xs font-semibold text-slate-800 dark:text-slate-200 mt-1 line-clamp-2">
|
||||
Tweestapsverificatie implementeren
|
||||
</div>
|
||||
<div id="planSpHint" class="hidden mt-1.5 text-[11px] text-violet-600 dark:text-violet-400 flex items-center space-x-1">
|
||||
<i data-lucide="zap" class="w-3 h-3"></i>
|
||||
<span id="planSpHintText"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Datum Kiezer -->
|
||||
@@ -1408,6 +1413,31 @@ function openPlanModal(item) {
|
||||
document.getElementById('planTicketProject').innerText = '• ' + (ticket.project || 'Project');
|
||||
document.getElementById('planTicketSummaryText').innerText = ticket.summary;
|
||||
|
||||
// Story Points → Duur conversie (1 SP = 30 minuten, configurabel)
|
||||
const spBadge = document.getElementById('planSpBadge');
|
||||
const spHint = document.getElementById('planSpHint');
|
||||
const spHintText = document.getElementById('planSpHintText');
|
||||
const sp = parseFloat(ticket.story_points);
|
||||
if (!isNaN(sp) && sp > 0) {
|
||||
const spMinutes = Math.round(sp * 30); // 1 SP = 30 minuten
|
||||
const closestDuration = [30, 45, 60, 90, 120].reduce((prev, curr) =>
|
||||
Math.abs(curr - spMinutes) < Math.abs(prev - spMinutes) ? curr : prev
|
||||
);
|
||||
const durationSelect = document.getElementById('planDurationInput');
|
||||
if (durationSelect) {
|
||||
const opt = durationSelect.querySelector(`option[value="${closestDuration}"]`);
|
||||
if (opt) opt.selected = true;
|
||||
}
|
||||
spBadge.textContent = `${sp} SP`;
|
||||
spBadge.classList.remove('hidden');
|
||||
spHintText.textContent = `${sp} story ${sp === 1 ? 'point' : 'points'} ≈ ${spMinutes} min → automatisch ${closestDuration} min ingesteld`;
|
||||
spHint.classList.remove('hidden');
|
||||
spHint.style.display = 'flex';
|
||||
} else {
|
||||
spBadge.classList.add('hidden');
|
||||
spHint.classList.add('hidden');
|
||||
}
|
||||
|
||||
// Suggesteer prioriteit op basis van Jira prio
|
||||
let focizPrio = 'P2';
|
||||
const jp = (ticket.priority || '').toLowerCase();
|
||||
@@ -1422,6 +1452,7 @@ function openPlanModal(item) {
|
||||
const modal = document.getElementById('planTaskModal');
|
||||
modal.classList.remove('hidden');
|
||||
modal.classList.add('flex');
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
}
|
||||
|
||||
function closePlanModal() {
|
||||
|
||||
Reference in New Issue
Block a user