feat: delete button for all boards + custom confirm dialog
- Show × delete button for all boards (not just userCreated) - Custom confirm dialog "Wirklich löschen?" replaces browser confirm() - HIDDEN_BOARDS: deleted DEFAULTS boards persist via kanban_hidden in localStorage - loadHidden() called before loadState() so hidden boards are excluded on load Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
51
index.html
51
index.html
@@ -376,6 +376,10 @@ body { background:var(--bg); color:var(--text); font-family:-apple-system,BlinkM
|
|||||||
.promote-ok { flex:1; padding:7px; background:var(--accent); color:#fff; border:none; border-radius:5px; font-size:12px; font-weight:700; cursor:pointer; }
|
.promote-ok { flex:1; padding:7px; background:var(--accent); color:#fff; border:none; border-radius:5px; font-size:12px; font-weight:700; cursor:pointer; }
|
||||||
.promote-ok:hover { opacity:.85; }
|
.promote-ok:hover { opacity:.85; }
|
||||||
.promote-cancel { padding:7px 12px; background:var(--surface2); border:1px solid var(--border2); color:var(--text-muted); border-radius:5px; font-size:12px; cursor:pointer; }
|
.promote-cancel { padding:7px 12px; background:var(--surface2); border:1px solid var(--border2); color:var(--text-muted); border-radius:5px; font-size:12px; cursor:pointer; }
|
||||||
|
.confirm-box { background:var(--surface); border:1px solid var(--border2); border-radius:10px; padding:20px; width:260px; box-shadow:0 8px 32px rgba(0,0,0,.5); }
|
||||||
|
.confirm-msg { font-size:13px; color:var(--text); margin-bottom:14px; }
|
||||||
|
.confirm-ok { flex:1; padding:7px; background:var(--red); color:#fff; border:none; border-radius:5px; font-size:12px; font-weight:700; cursor:pointer; }
|
||||||
|
.confirm-ok:hover { opacity:.85; }
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -514,6 +518,16 @@ body { background:var(--bg); color:var(--text); font-family:-apple-system,BlinkM
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="confirm-overlay" style="display:none" class="promote-overlay" onclick="if(event.target===this)closeConfirm()">
|
||||||
|
<div class="confirm-box">
|
||||||
|
<div class="confirm-msg" id="confirm-msg"></div>
|
||||||
|
<div class="promote-btns">
|
||||||
|
<button class="confirm-ok" id="confirm-ok">Löschen</button>
|
||||||
|
<button class="promote-cancel" onclick="closeConfirm()">Abbrechen</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// ── BOARD DATA ────────────────────────────────────────────────────────────
|
// ── BOARD DATA ────────────────────────────────────────────────────────────
|
||||||
const TODAY = new Date('2026-05-19');
|
const TODAY = new Date('2026-05-19');
|
||||||
@@ -934,6 +948,9 @@ function getBoardsForGroup(g) {
|
|||||||
|
|
||||||
// ── STATE (localStorage) ──────────────────────────────────────────────────
|
// ── STATE (localStorage) ──────────────────────────────────────────────────
|
||||||
let BOARDS = {};
|
let BOARDS = {};
|
||||||
|
let HIDDEN_BOARDS = new Set();
|
||||||
|
function loadHidden() { try { HIDDEN_BOARDS = new Set(JSON.parse(localStorage.getItem('kanban_hidden') || '[]')); } catch {} }
|
||||||
|
function saveHidden() { localStorage.setItem('kanban_hidden', JSON.stringify([...HIDDEN_BOARDS])); }
|
||||||
|
|
||||||
function deepClone(o) { return JSON.parse(JSON.stringify(o)); }
|
function deepClone(o) { return JSON.parse(JSON.stringify(o)); }
|
||||||
|
|
||||||
@@ -956,6 +973,7 @@ function migrateCols(board) {
|
|||||||
|
|
||||||
function loadState() {
|
function loadState() {
|
||||||
BOARDS = deepClone(DEFAULTS);
|
BOARDS = deepClone(DEFAULTS);
|
||||||
|
HIDDEN_BOARDS.forEach(id => { delete BOARDS[id]; });
|
||||||
Object.keys(BOARDS).forEach(id => {
|
Object.keys(BOARDS).forEach(id => {
|
||||||
const m = BOARD_META[id] || {group:'Privat', color:'#7c6af7', ring:'?'};
|
const m = BOARD_META[id] || {group:'Privat', color:'#7c6af7', ring:'?'};
|
||||||
BOARDS[id].group = m.group;
|
BOARDS[id].group = m.group;
|
||||||
@@ -1069,28 +1087,31 @@ function saveBoardSetting(key, el, min, max) {
|
|||||||
if (curView === 'analytics') renderAnalytics(curId);
|
if (curView === 'analytics') renderAnalytics(curId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showConfirm(msg, onOk) {
|
||||||
|
document.getElementById('confirm-msg').textContent = msg;
|
||||||
|
document.getElementById('confirm-ok').onclick = () => { closeConfirm(); onOk(); };
|
||||||
|
document.getElementById('confirm-overlay').style.display = 'flex';
|
||||||
|
}
|
||||||
|
function closeConfirm() { document.getElementById('confirm-overlay').style.display = 'none'; }
|
||||||
|
|
||||||
function resetCurrentBoard() {
|
function resetCurrentBoard() {
|
||||||
const b = BOARDS[curId];
|
const b = BOARDS[curId];
|
||||||
if (b.userCreated) {
|
if (b.userCreated) { deleteBoard(curId); return; }
|
||||||
if (!confirm(`"${b.name}" löschen?`)) return;
|
showConfirm(`"${b.name}" auf Standardzustand zurücksetzen?`, () => {
|
||||||
deleteBoard(curId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!confirm(`"${b.name}" auf Standardzustand zurücksetzen?`)) return;
|
|
||||||
BOARDS[curId].cols = deepClone(DEFAULTS[curId].cols);
|
BOARDS[curId].cols = deepClone(DEFAULTS[curId].cols);
|
||||||
saveState();
|
saveState(); show(curId); renderSidebar();
|
||||||
show(curId);
|
});
|
||||||
renderSidebar();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteBoard(id, e) {
|
function deleteBoard(id, e) {
|
||||||
if (e) e.stopPropagation();
|
if (e) e.stopPropagation();
|
||||||
if (!confirm(`"${BOARDS[id].name}" löschen?`)) return;
|
showConfirm(`"${BOARDS[id]?.name}" wirklich löschen?`, () => {
|
||||||
|
if (!BOARDS[id].userCreated) { HIDDEN_BOARDS.add(id); saveHidden(); }
|
||||||
delete BOARDS[id];
|
delete BOARDS[id];
|
||||||
saveState();
|
saveState();
|
||||||
const firstId = Object.keys(BOARDS)[0];
|
const firstId = Object.keys(BOARDS)[0];
|
||||||
show(firstId);
|
show(firstId); renderSidebar();
|
||||||
renderSidebar();
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function addCard(boardId, colId, text) {
|
function addCard(boardId, colId, text) {
|
||||||
@@ -2157,8 +2178,7 @@ function renderSidebar() {
|
|||||||
const rem = remaining(b);
|
const rem = remaining(b);
|
||||||
const blk = hasBlocker(b);
|
const blk = hasBlocker(b);
|
||||||
const badgeCls = blk ? ' blk' : colCount(b,'wip') > 0 ? ' wip' : '';
|
const badgeCls = blk ? ' blk' : colCount(b,'wip') > 0 ? ' wip' : '';
|
||||||
const del = b.userCreated
|
const del = `<span class="nav-del" onclick="deleteBoard('${id}',event)">×</span>`;
|
||||||
? `<span class="nav-del" onclick="deleteBoard('${id}',event)">×</span>` : '';
|
|
||||||
const ring = b.ring || '?';
|
const ring = b.ring || '?';
|
||||||
const ringCls = ring === '?' ? 'r-q' : 'r-' + ring;
|
const ringCls = ring === '?' ? 'r-q' : 'r-' + ring;
|
||||||
const ringLbl = RING_LABELS[ring] || '?';
|
const ringLbl = RING_LABELS[ring] || '?';
|
||||||
@@ -2376,7 +2396,7 @@ function renderIdeas() {
|
|||||||
|
|
||||||
// ── EXPORT / IMPORT ──────────────────────────────────────────────────────────
|
// ── EXPORT / IMPORT ──────────────────────────────────────────────────────────
|
||||||
function exportState() {
|
function exportState() {
|
||||||
const keys = ['kanban_v2','kanban_groups','kanban_board_order','kanban_ideas','kanban_ideas_seeded','kanban_cards_seeded'];
|
const keys = ['kanban_v2','kanban_groups','kanban_board_order','kanban_ideas','kanban_ideas_seeded','kanban_hidden'];
|
||||||
const snap = {};
|
const snap = {};
|
||||||
keys.forEach(k => { const v = localStorage.getItem(k); if (v !== null) snap[k] = v; });
|
keys.forEach(k => { const v = localStorage.getItem(k); if (v !== null) snap[k] = v; });
|
||||||
const blob = new Blob([JSON.stringify(snap, null, 2)], {type:'application/json'});
|
const blob = new Blob([JSON.stringify(snap, null, 2)], {type:'application/json'});
|
||||||
@@ -2407,6 +2427,7 @@ if (window.location.protocol === 'file:') {
|
|||||||
}
|
}
|
||||||
loadGroups();
|
loadGroups();
|
||||||
loadBoardOrder();
|
loadBoardOrder();
|
||||||
|
loadHidden();
|
||||||
loadState();
|
loadState();
|
||||||
renderSidebar();
|
renderSidebar();
|
||||||
loadIdeas();
|
loadIdeas();
|
||||||
|
|||||||
Reference in New Issue
Block a user