diff --git a/html/field.js b/html/field.js index d33182b..f81a7af 100644 --- a/html/field.js +++ b/html/field.js @@ -12,6 +12,16 @@ function esc(s) { return s == null ? '' : String(s).replace(/&/g, '&').repla function nsKey(id) { return 'wp_iwp_v1__' + id; } function stLabel(s) { return s === 'Issue' ? 'Issue (Hold)' : s; } function openCount(p) { return ((p && p.constraints) || []).filter(function (c) { return c.status === 'open'; }).length; } +// Predecessor packages that aren't Closed yet. A package waiting on upstream work +// is not release-ready either, so the field list must not call it Ready — the +// server would refuse to issue it (see enforce_release_gates). +function waitingCount(p, all) { + var preds = (p && p.predecessors) || []; + if (!preds.length) return 0; + var byId = {}; + (all || []).forEach(function (x) { byId[x.id] = x; }); + return preds.filter(function (id) { var q = byId[id]; return q && q.status !== 'Closed'; }).length; +} function fmtTs(s) { try { return wpFormatDateTime(s); } catch (e) { return s || ''; } } function me() { try { return (window.WP_USER && (window.WP_USER.full_name || window.WP_USER.username)) || ''; } catch (e) { return ''; } } function toast(m) { var t = document.getElementById('toast'); if (!t) return; t.textContent = m; t.classList.add('show'); clearTimeout(toast._t); toast._t = setTimeout(function () { t.classList.remove('show'); }, 2000); } @@ -57,8 +67,12 @@ function renderList() { if (!rows.length) { box.innerHTML = '