fix: JS syntax error in renderCardDetail breaking all interactivity
CI / test (push) Failing after 4s
CI / lint (push) Failing after 3s

Root cause: operator precedence bug with stray ')' in:
  '...+(card.priority||"Medium")===p?"selected":"")+'>...
The ')+' created an unmatched parenthesis, causing SyntaxError
that stopped ALL JS event handlers (dblclick, drag-drop, buttons).

Fix: replaced string concatenation with template literals ('')
throughout renderCardDetail, eliminating escape/quoting issues.
This commit is contained in:
2026-07-08 10:53:32 -04:00
parent ae41937b03
commit 6ca376a675
+37 -19
View File
@@ -253,25 +253,43 @@
function renderCardDetail(owner, repo, data) {
const issue = data.issue || {}, comments = data.comments || [], checklists = data.checklists || [], card = data.card || {};
window._issueData = {owner, repo, issue, comments, checklists, card};
let h = '';
h += '<div class="detail-section"><span class="detail-state badge '+issue.state+'">'+issue.state+'</span> <strong>'+escHtml(issue.title||'')+'</strong></div>';
h += '<div class="detail-meta">';
(issue.labels||[]).forEach(l => h += '<span class="card-label" style="background:#'+(l.color||'666')+'33;color:#'+(l.color||'ccc')+'">'+escHtml(l.name)+'</span>');
if (issue.milestone) h += '<span>📅 '+escHtml(issue.milestone.title)+'</span>';
if (issue.assignee) h += '<span>👤 '+escHtml(issue.assignee.login)+'</span>';
h += '</div>';
h += '<div class="detail-editable"><label>Priorité: <select onchange="updateCardMeta(\''+owner+'\',\''+repo+'\','+issue.number+',this.value,\'\')" class="form-select-sm">';
['Low','Medium','High','Urgent'].forEach(p => h += '<option value="'+p+'" '+(card.priority||'Medium')===p?'selected':'')+'>'+p+'</option>');
h += '</select></label> <label>Échéance: <input type="date" value="'+(card.due_date||'')+'" onchange="updateCardMeta(\''+owner+'\',\''+repo+'\','+issue.number+',\'\',this.value)" class="form-input-sm"></label></div>';
h += '<div class="detail-section"><h4>Description</h4><div class="markdown-body">'+escHtml(issue.body||'')+'</div></div>';
h += renderChecklists(owner, repo, issue.number, checklists);
h += '<div class="detail-section"><h4>Commentaires ('+comments.length+')</h4>';
comments.forEach(c => h += '<div class="comment"><img src="'+(c.user?.avatar_url||'')+'" width="24" height="24" class="avatar"><strong>'+escHtml(c.user?.login||'')+'</strong><span class="comment-date">'+(c.created_at||'').substr(0,10)+'</span><div class="comment-body">'+escHtml(c.body||'')+'</div></div>');
h += '</div>';
h += '<div class="detail-actions"><a href="'+(issue.html_url||'')+'" target="_blank" class="btn btn-sm">🔗 Ouvrir dans Gitea</a>';
h += '<button onclick="showEditForm(\''+owner+'\',\''+repo+'\','+issue.number+')" class="btn btn-sm">✏️ Éditer</button>';
h += '<button onclick="closeModal()" class="btn btn-sm">Fermer</button></div>';
return h;
const labelsHtml = (issue.labels || []).map(l =>
`<span class="card-label" style="background:#${l.color||'666'}33;color:#${l.color||'ccc'}">${escHtml(l.name)}</span>`
).join('');
const prio = card.priority || 'Medium';
const prioOpts = ['Low','Medium','High','Urgent'].map(p =>
`<option value="${p}" ${prio===p?'selected':''}>${p}</option>`
).join('');
return `
<div class="detail-section"><span class="detail-state badge ${issue.state}">${issue.state}</span> <strong>${escHtml(issue.title||'')}</strong></div>
<div class="detail-meta">
${labelsHtml}
${issue.milestone ? '<span>📅 '+escHtml(issue.milestone.title)+'</span>' : ''}
${issue.assignee ? '<span>👤 '+escHtml(issue.assignee.login)+'</span>' : ''}
</div>
<div class="detail-editable">
<label>Priorité: <select onchange="updateCardMeta('${owner}','${repo}',${issue.number},this.value,'')" class="form-select-sm">${prioOpts}</select></label>
<label>Échéance: <input type="date" value="${card.due_date||''}" onchange="updateCardMeta('${owner}','${repo}',${issue.number},'',this.value)" class="form-input-sm"></label>
</div>
<div class="detail-section"><h4>Description</h4><div class="markdown-body">${escHtml(issue.body||'')}</div></div>
${renderChecklists(owner, repo, issue.number, checklists)}
<div class="detail-section"><h4>Commentaires (${comments.length})</h4>
${comments.map(c => `
<div class="comment">
<img src="${c.user?.avatar_url||''}" width="24" height="24" class="avatar">
<strong>${escHtml(c.user?.login||'')}</strong>
<span class="comment-date">${(c.created_at||'').substr(0,10)}</span>
<div class="comment-body">${escHtml(c.body||'')}</div>
</div>`).join('')}
</div>
<div class="detail-actions">
<a href="${issue.html_url||''}" target="_blank" class="btn btn-sm">🔗 Ouvrir dans Gitea</a>
<button onclick="showEditForm('${owner}','${repo}',${issue.number})" class="btn btn-sm">✏️ Éditer</button>
<button onclick="closeModal()" class="btn btn-sm">Fermer</button>
</div>`;
}
function renderChecklists(owner, repo, issueId, checklists) {