1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import { loadManifest } from "./board-refs.js";
var boardRefManifest = null;
export function getBoardRefManifest() {
return boardRefManifest;
}
export function refreshBoardRefManifest() {
var ctx = getBoardContext();
if (!ctx.project) return Promise.resolve(null);
return loadManifest(ctx.project, ctx.board)
.then(function (manifest) {
boardRefManifest = manifest;
return manifest;
})
.catch(function () {
boardRefManifest = { commits: [], refs: [] };
return boardRefManifest;
});
}
export function taskDisplayId(ref) {
if (!ref) return '';
var slug = ref.replace(/^refs\/tags\/tasks\//, '');
if (slug.indexOf('task_') === 0) return slug.slice(5);
return slug;
}
export function taskDisplayIdShort(fullId) {
if (!fullId) return '';
return fullId.length <= 4 ? fullId : fullId.slice(-4);
}
export function syncCardTitleLineTooltip(card) {
var titleLine = card.querySelector('.board-card-title-line');
if (!titleLine) return;
var titleEl = card.querySelector('.board-card-title');
var titleText = ((titleEl && titleEl.textContent) || '').trim() || 'Untitled';
var fullId = card.dataset.taskRef ? taskDisplayId(card.dataset.taskRef) : '';
titleLine.title = fullId ? (fullId + ': ' + titleText) : titleText;
}
export function setCardTaskRefDisplay(card, ref, id) {
var fullId = id || taskDisplayId(ref);
var idEl = card.querySelector('.board-card-task-id');
if (idEl) idEl.textContent = taskDisplayIdShort(fullId);
var refEl = card.querySelector('.board-card-task-ref');
if (refEl) refEl.textContent = ref || '';
syncCardTitleLineTooltip(card);
}
export function getBoardContext() {
var boardColumns = document.querySelector('.board-columns');
var project = boardColumns && boardColumns.dataset.project;
var board = boardColumns && boardColumns.dataset.board;
if (!project && location.pathname) {
var m = location.pathname.match(/^\/project\/(.+?)\/board\/?$/);
if (m) project = m[1];
}
if (!board) board = (new URLSearchParams(location.search)).get('b') || 'Tasks';
return { project: project || '', board: board || 'Tasks' };
}
export function findBoardCardByTaskRef(taskRef) {
if (!taskRef) return null;
var cards = document.querySelectorAll('.board-card');
for (var i = 0; i < cards.length; i++) {
if (cards[i].dataset.taskRef === taskRef) return cards[i];
}
return null;
}
export function showBoardError(message) {
var boardColumns = document.querySelector('.board-columns');
var anchor = boardColumns && boardColumns.parentNode;
if (!anchor) return;
var existing = document.querySelector('.board-task-error-hint');
if (existing) existing.remove();
var el = document.createElement('div');
el.className = 'alert board-task-error-hint py-2 px-3 mb-2';
el.setAttribute('role', 'alert');
el.textContent = message;
anchor.insertBefore(el, boardColumns);
window.setTimeout(function() {
if (el.parentNode) el.remove();
}, 8000);
}
export function updateColumnBadge(column) {
var cardsContainer = column && column.querySelector('.board-column-cards');
var countBadge = column && column.querySelector('.board-column-task-count');
var pointsBadge = column && column.querySelector('.board-column-points-total');
if (!cardsContainer) return;
var cards = cardsContainer.querySelectorAll('.board-card');
if (countBadge) countBadge.textContent = cards.length;
if (pointsBadge) {
var total = 0;
cards.forEach(function(c) {
var v = c.dataset.taskPoints;
if (v) total += parseInt(v, 10) || 0;
});
pointsBadge.textContent = total + ' pts';
}
}
export function pushTaskFieldUpdate(card, fields) {
var taskRef = card && card.dataset.taskRef;
if (!taskRef) return Promise.resolve({ ok: false, status: 0 });
var ctx = getBoardContext();
if (!ctx.project) return Promise.resolve({ ok: false, status: 0 });
return fetch('/tasks/update?' + new URLSearchParams({ project: ctx.project, board: ctx.board, task: taskRef }).toString(), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(fields)
}).then(function(res) {
return { ok: res.ok, status: res.status };
}).catch(function() {
return { ok: false, status: 0 };
});
}