Compare commits
2 Commits
4163199d16
...
08307f5fe7
| Author | SHA1 | Date | |
|---|---|---|---|
| 08307f5fe7 | |||
| eda90dbba6 |
@@ -13,24 +13,20 @@ $isAdmin = ($userRole === 'ADMIN');
|
|||||||
?>
|
?>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
/* Volledige breedte benutting en soepele schermmaximalisatie */
|
/* Soepele overgang voor de lanes container bij maximaliseren */
|
||||||
#boardMainWrapper {
|
#lanesSectionWrapper {
|
||||||
width: 100% !important;
|
|
||||||
max-width: 100% !important;
|
|
||||||
transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
|
transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
|
||||||
}
|
}
|
||||||
#boardMainWrapper.is-maximized {
|
#lanesSectionWrapper.is-maximized {
|
||||||
padding-left: 0 !important;
|
max-width: 100% !important;
|
||||||
padding-right: 0 !important;
|
|
||||||
}
|
|
||||||
#boardMainWrapper #boardLanesContainer {
|
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div id="boardMainWrapper" class="space-y-4 w-full max-w-none">
|
<div id="boardPageContainer" class="space-y-4 w-full">
|
||||||
|
|
||||||
<!-- Bovenbalk: Bord Titel, Filters & Actieknoppen -->
|
<!-- Bovenbalk: Bord Titel, Filters & Actieknoppen (ALTIJD vaste standaard breedte) -->
|
||||||
|
<div class="max-w-7xl mx-auto w-full">
|
||||||
<div class="fociz-card p-4 sm:p-5">
|
<div class="fociz-card p-4 sm:p-5">
|
||||||
<div class="flex flex-col xl:flex-row xl:items-center justify-between gap-4">
|
<div class="flex flex-col xl:flex-row xl:items-center justify-between gap-4">
|
||||||
|
|
||||||
@@ -120,22 +116,26 @@ $isAdmin = ($userRole === 'ADMIN');
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Lanes Sectie: Wisselt tussen standaard gecentreerde breedte (max-w-7xl) en volledig scherm (max-w-none w-full) -->
|
||||||
|
<div id="lanesSectionWrapper" class="max-w-7xl mx-auto w-full transition-all duration-300">
|
||||||
|
|
||||||
<!-- Strook direct boven de lane blokken: klein maximaliseer-icoon rechts -->
|
<!-- Strook direct boven de lane blokken: klein maximaliseer-icoon rechts -->
|
||||||
<div class="flex items-center justify-between px-1 -mb-1">
|
<div class="flex items-center justify-between px-1 mb-2">
|
||||||
<div class="text-[11px] font-semibold text-slate-500 dark:text-slate-400" id="boardLanesSummary"></div>
|
<div class="text-[11px] font-semibold text-slate-500 dark:text-slate-400" id="boardLanesSummary"></div>
|
||||||
<button
|
<button
|
||||||
id="btnToggleMaximize"
|
id="btnToggleMaximize"
|
||||||
onclick="toggleBoardMaximize()"
|
onclick="toggleBoardMaximize()"
|
||||||
title="Bord maximaliseren naar volledige vensterbreedte"
|
title="Kolommen maximaliseren naar volledige vensterbreedte"
|
||||||
class="w-7 h-7 rounded-lg bg-white dark:bg-[#111624] hover:bg-slate-100 dark:hover:bg-slate-800 border border-slate-200 dark:border-slate-800 text-slate-600 dark:text-slate-300 flex items-center justify-center transition cursor-pointer shadow-2xs hover:scale-105 active:scale-95 ml-auto"
|
class="w-7 h-7 rounded-lg bg-white dark:bg-[#111624] hover:bg-slate-100 dark:hover:bg-slate-800 border border-slate-200 dark:border-slate-800 text-slate-600 dark:text-slate-300 flex items-center justify-center transition cursor-pointer shadow-2xs hover:scale-105 active:scale-95 ml-auto"
|
||||||
>
|
>
|
||||||
<i id="maximizeIcon" data-lucide="maximize-2" class="w-3.5 h-3.5"></i>
|
<i id="maximizeIcon" data-lucide="maximize-2" class="w-3.5 h-3.5"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Kanban Board Container (Horizontaal scrollbaar indien te smal, past automatisch in de breedte) -->
|
<!-- Kanban Board Container (past zich in standaardmodus soepel aan zonder scrollbalk) -->
|
||||||
<div id="boardLanesContainer" class="flex gap-4 overflow-x-auto pb-8 pt-1 min-h-[650px] items-start select-none w-full transition-all duration-300">
|
<div id="boardLanesContainer" class="flex gap-3 overflow-x-auto pb-2 pt-1 min-h-[440px] items-start select-none w-full transition-all duration-300">
|
||||||
<div class="flex items-center justify-center w-full py-20 text-slate-400 text-sm">
|
<div class="flex items-center justify-center w-full py-20 text-slate-400 text-sm">
|
||||||
<i data-lucide="loader-2" class="w-5 h-5 animate-spin mr-2"></i>
|
<i data-lucide="loader-2" class="w-5 h-5 animate-spin mr-2"></i>
|
||||||
<span>Bord laden...</span>
|
<span>Bord laden...</span>
|
||||||
@@ -144,6 +144,8 @@ $isAdmin = ($userRole === 'ADMIN');
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- MODAL 1: Taak (Post-it / Opdracht) Toevoegen of Bewerken -->
|
<!-- MODAL 1: Taak (Post-it / Opdracht) Toevoegen of Bewerken -->
|
||||||
<div id="cardModal" class="fixed inset-0 z-50 bg-slate-950/70 backdrop-blur-sm hidden items-center justify-center p-4 overflow-y-auto">
|
<div id="cardModal" class="fixed inset-0 z-50 bg-slate-950/70 backdrop-blur-sm hidden items-center justify-center p-4 overflow-y-auto">
|
||||||
<div class="fociz-card p-6 w-full max-w-xl shadow-2xl space-y-5 my-8">
|
<div class="fociz-card p-6 w-full max-w-xl shadow-2xl space-y-5 my-8">
|
||||||
@@ -635,9 +637,9 @@ function renderCards() {
|
|||||||
|
|
||||||
const dotColorClass = LANE_ACCENT_COLORS[lane.color] || 'bg-slate-500';
|
const dotColorClass = LANE_ACCENT_COLORS[lane.color] || 'bg-slate-500';
|
||||||
|
|
||||||
// Lane kolom HTML (past zich automatisch aan de schermbreedte aan)
|
// Lane kolom HTML: flex-1 en min-w-[160px] zodat 5+ lanes in standaardmodus binnen 1280px passen zonder scrollbalk
|
||||||
const laneEl = document.createElement('div');
|
const laneEl = document.createElement('div');
|
||||||
laneEl.className = 'flex-1 min-w-[260px] rounded-2xl bg-slate-100/70 dark:bg-[#0c0f17]/70 border border-slate-200/80 dark:border-slate-800/80 p-3.5 flex flex-col shadow-xs max-h-[82vh] transition-all duration-200';
|
laneEl.className = 'flex-1 min-w-0 sm:min-w-[160px] rounded-2xl bg-slate-100/70 dark:bg-[#0c0f17]/70 border border-slate-200/80 dark:border-slate-800/80 p-3 flex flex-col shadow-xs max-h-[calc(100vh-310px)] min-h-[440px] transition-all duration-200';
|
||||||
laneEl.setAttribute('data-lane-id', lane.id);
|
laneEl.setAttribute('data-lane-id', lane.id);
|
||||||
|
|
||||||
let cardsHtml = '';
|
let cardsHtml = '';
|
||||||
@@ -695,16 +697,16 @@ function renderCards() {
|
|||||||
ondragstart="onCardDragStart(event, ${card.id})"
|
ondragstart="onCardDragStart(event, ${card.id})"
|
||||||
ondragend="onCardDragEnd(event)"
|
ondragend="onCardDragEnd(event)"
|
||||||
onclick="onCardClick(event, ${card.id})"
|
onclick="onCardClick(event, ${card.id})"
|
||||||
class="group/card relative p-3.5 rounded-xl border ${colorClass} shadow-2xs hover:shadow-md hover:-translate-y-0.5 transition cursor-grab active:cursor-grabbing mb-2.5"
|
class="group/card relative p-3 rounded-xl border ${colorClass} shadow-2xs hover:shadow-md hover:-translate-y-0.5 transition cursor-grab active:cursor-grabbing mb-2.5"
|
||||||
>
|
>
|
||||||
<div class="flex items-start justify-between gap-2 mb-1.5">
|
<div class="flex items-start justify-between gap-1.5 mb-1.5">
|
||||||
<h4 class="text-xs font-bold leading-snug line-clamp-2">
|
<h4 class="text-xs font-bold leading-snug line-clamp-2 break-words">
|
||||||
${escapeHtml(card.title)}
|
${escapeHtml(card.title)}
|
||||||
</h4>
|
</h4>
|
||||||
${priorityBadge}
|
<div class="flex-shrink-0">${priorityBadge}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
${card.description ? `<p class="text-[11px] opacity-80 line-clamp-2 leading-relaxed mb-2.5">${escapeHtml(card.description)}</p>` : ''}
|
${card.description ? `<p class="text-[11px] opacity-80 line-clamp-2 leading-relaxed mb-2.5 break-words">${escapeHtml(card.description)}</p>` : ''}
|
||||||
|
|
||||||
<div class="flex items-center justify-between mt-auto">
|
<div class="flex items-center justify-between mt-auto">
|
||||||
${assigneeHtml}
|
${assigneeHtml}
|
||||||
@@ -725,14 +727,14 @@ function renderCards() {
|
|||||||
|
|
||||||
laneEl.innerHTML = `
|
laneEl.innerHTML = `
|
||||||
<!-- Lane Header -->
|
<!-- Lane Header -->
|
||||||
<div class="flex items-center justify-between pb-3 mb-3 border-b border-slate-200/80 dark:border-slate-800/80">
|
<div class="flex items-center justify-between pb-2.5 mb-2.5 border-b border-slate-200/80 dark:border-slate-800/80">
|
||||||
<div class="flex items-center space-x-2">
|
<div class="flex items-center space-x-2 min-w-0">
|
||||||
<span class="w-2.5 h-2.5 rounded-full ${dotColorClass}"></span>
|
<span class="w-2.5 h-2.5 rounded-full ${dotColorClass} flex-shrink-0"></span>
|
||||||
<h3 class="text-xs font-bold text-slate-800 dark:text-slate-200 uppercase tracking-wider">
|
<h3 class="text-xs font-bold text-slate-800 dark:text-slate-200 uppercase tracking-wider truncate">
|
||||||
${escapeHtml(lane.title)}
|
${escapeHtml(lane.title)}
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<span class="px-2 py-0.5 rounded-full text-[10px] font-bold bg-white dark:bg-slate-800 text-slate-600 dark:text-slate-400 border border-slate-200 dark:border-slate-700 shadow-2xs">
|
<span class="px-2 py-0.5 rounded-full text-[10px] font-bold bg-white dark:bg-slate-800 text-slate-600 dark:text-slate-400 border border-slate-200 dark:border-slate-700 shadow-2xs flex-shrink-0 ml-1">
|
||||||
${cards.length}
|
${cards.length}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -1206,40 +1208,39 @@ function escapeHtml(str) {
|
|||||||
.replace(/'/g, ''');
|
.replace(/'/g, ''');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 10. Bord Maximaliseren & Verkleinen (Soepele breedte-overgang)
|
// 10. Kolommen Maximaliseren & Verkleinen (Soepele breedte-overgang)
|
||||||
|
// De site-header blijft ALTIJD staan.
|
||||||
|
// De bovenbalk (Hoofdbord, filters, actieknoppen) behoudt altijd de vaste standaard breedte.
|
||||||
|
// ALLEEN de aparte lanes wisselen tussen standaard gecentreerde breedte en de volledige schermbreedte.
|
||||||
let isBoardMaximized = localStorage.getItem('fociz_board_maximized') === 'true';
|
let isBoardMaximized = localStorage.getItem('fociz_board_maximized') === 'true';
|
||||||
|
|
||||||
function applyMaximizeState(isMax) {
|
function applyMaximizeState(isMax) {
|
||||||
const wrapper = document.getElementById('boardMainWrapper');
|
const lanesWrapper = document.getElementById('lanesSectionWrapper');
|
||||||
const mainContainer = document.getElementById('focizMainContainer');
|
const mainContainer = document.getElementById('focizMainContainer');
|
||||||
const icon = document.getElementById('maximizeIcon');
|
const icon = document.getElementById('maximizeIcon');
|
||||||
const btn = document.getElementById('btnToggleMaximize');
|
const btn = document.getElementById('btnToggleMaximize');
|
||||||
|
|
||||||
if (!wrapper || !btn) return;
|
if (!lanesWrapper || !btn) return;
|
||||||
|
|
||||||
|
// Zorg dat header altijd zichtbaar blijft
|
||||||
|
document.querySelector('header')?.classList.remove('hidden');
|
||||||
|
if (mainContainer) {
|
||||||
|
mainContainer.style.maxWidth = '';
|
||||||
|
mainContainer.style.paddingLeft = '';
|
||||||
|
mainContainer.style.paddingRight = '';
|
||||||
|
}
|
||||||
|
|
||||||
if (isMax) {
|
if (isMax) {
|
||||||
wrapper.classList.add('is-maximized');
|
lanesWrapper.classList.remove('max-w-7xl', 'mx-auto');
|
||||||
if (mainContainer) {
|
lanesWrapper.classList.add('is-maximized', 'max-w-none', 'w-full', 'px-1', 'sm:px-3');
|
||||||
mainContainer.style.maxWidth = '100vw';
|
btn.setAttribute('title', 'Kolommen verkleinen naar standaard breedte (Escape)');
|
||||||
mainContainer.style.width = '100%';
|
|
||||||
mainContainer.style.paddingLeft = '0.5rem';
|
|
||||||
mainContainer.style.paddingRight = '0.5rem';
|
|
||||||
}
|
|
||||||
document.querySelector('header')?.classList.add('hidden');
|
|
||||||
btn.setAttribute('title', 'Bord verkleinen / navigatie tonen (Escape)');
|
|
||||||
if (icon) {
|
if (icon) {
|
||||||
icon.setAttribute('data-lucide', 'minimize-2');
|
icon.setAttribute('data-lucide', 'minimize-2');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
wrapper.classList.remove('is-maximized');
|
lanesWrapper.classList.remove('is-maximized', 'max-w-none', 'px-1', 'sm:px-3');
|
||||||
if (mainContainer) {
|
lanesWrapper.classList.add('max-w-7xl', 'mx-auto', 'w-full');
|
||||||
mainContainer.style.maxWidth = '';
|
btn.setAttribute('title', 'Kolommen maximaliseren naar volledige vensterbreedte');
|
||||||
mainContainer.style.width = '';
|
|
||||||
mainContainer.style.paddingLeft = '';
|
|
||||||
mainContainer.style.paddingRight = '';
|
|
||||||
}
|
|
||||||
document.querySelector('header')?.classList.remove('hidden');
|
|
||||||
btn.setAttribute('title', 'Bord maximaliseren (volledig venster)');
|
|
||||||
if (icon) {
|
if (icon) {
|
||||||
icon.setAttribute('data-lucide', 'maximize-2');
|
icon.setAttribute('data-lucide', 'maximize-2');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user