Control Tickets: improvement type badge/filter + download shared module

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Claude
2026-06-15 14:41:05 +10:00
parent e1ddcd201f
commit d71f72cd5a

View File

@@ -77,10 +77,13 @@ function statusPill(s) {
}
function typeBadge(t) {
const type = t === 'feature' ? 'feature' : 'bug';
const c = type === 'feature' ? '#7aa2e0' : '#e0b24b';
return el('span', { class: 'badge', style: { background: 'transparent', border: `1px solid ${c}`, color: c } },
type === 'feature' ? '✨ feature' : '🐞 bug');
const map = {
feature: { c: '#7aa2e0', label: '✨ feature' },
improvement: { c: '#5ec27a', label: '🛠 improvement' },
bug: { c: '#e0b24b', label: '🐞 bug' },
};
const m = map[t] || map.bug;
return el('span', { class: 'badge', style: { background: 'transparent', border: `1px solid ${m.c}`, color: m.c } }, m.label);
}
// ---- group cache (used by approve/instances dropdowns) ----------------------
@@ -311,7 +314,7 @@ async function renderTickets(panel) {
const statusSel = select([{ value: '', label: 'all' }, 'open', 'closed'], filter);
statusSel.onchange = () => { filter = statusSel.value; loadList(); };
const typeSel = select([{ value: '', label: 'all' }, { value: 'bug', label: '🐞 bug' }, { value: 'feature', label: '✨ feature' }], typeFilter);
const typeSel = select([{ value: '', label: 'all' }, { value: 'bug', label: '🐞 bug' }, { value: 'feature', label: '✨ feature' }, { value: 'improvement', label: '🛠 improvement' }], typeFilter);
typeSel.onchange = () => { typeFilter = typeSel.value; loadList(); };
async function loadList() {
@@ -357,6 +360,12 @@ async function renderTickets(panel) {
return el('a', { class: 'ghost', href: safeHref(`${A}/tickets/${id}/logs/${attId}`), target: '_blank', rel: 'noopener', style: { marginRight: '0.4rem' } },
'↗ ' + (att.name || `log ${attId}`));
});
const modules = (t.modules || []).map(att => {
const attId = att.id ?? att;
return el('a', { class: 'lk-url', href: safeHref(`${A}/tickets/${id}/modules/${attId}`), download: `module-${attId}.tar.gz`,
style: { color: 'var(--accent,#5ec27a)', marginRight: '0.5rem', fontSize: '0.8rem' } },
'⬇ download shared module');
});
mount(detail,
el('div', { class: 'card', style: { display: 'grid', gap: '0.6rem' } },
@@ -370,6 +379,7 @@ async function renderTickets(panel) {
el('div', { style: { whiteSpace: 'pre-wrap' } }, t.body || t.text || t.description || '(no text)'),
images.length ? el('div', { style: { display: 'flex', flexWrap: 'wrap', gap: '0.5rem' } }, images) : null,
logs.length ? el('div', {}, logs) : null,
modules.length ? el('div', {}, modules) : null,
field('Admin notes', notesInput),
el('div', { style: { display: 'flex', alignItems: 'center', gap: '0.6rem' } },
btn('Save notes', () => patch({ notes: notesInput.value }, 'notes saved'), 'primary'), msg)));