sync: auto-sync from HOWARD-HOME at 2026-07-17 20:22:53
Author: Howard Enos Machine: HOWARD-HOME Timestamp: 2026-07-17 20:22:53
This commit is contained in:
@@ -203,18 +203,8 @@ const SECTIONS = [
|
||||
{ id: 'ct-projects', label: 'Projects', repos: ['claudetools'], filter: i => (getType(i)==='project' || getType(i)==='feature') && !isClientProject(i) },
|
||||
];
|
||||
// Client project sections — built dynamically from labels
|
||||
const CLIENT_SECTIONS = [
|
||||
{ id: 'cp-all', label: 'All Client Projects', client: null },
|
||||
{ id: 'cp-cascades', label: 'Cascades', client: 'client:cascades' },
|
||||
{ id: 'cp-glaztech', label: 'GlazTech', client: 'client:glaztech' },
|
||||
{ id: 'cp-sif', label: 'SIF / Oidak', client: 'client:sif-oidak' },
|
||||
{ id: 'cp-goldstein', label: 'Goldstein', client: 'client:goldstein' },
|
||||
{ id: 'cp-prairie', label: 'Prairie Schooner', client: 'client:prairie-schooner' },
|
||||
{ id: 'cp-cryoweave', label: 'CryoWeave', client: 'client:cryoweave' },
|
||||
{ id: 'cp-tedards', label: 'Tedards Law', client: 'client:tedards' },
|
||||
{ id: 'cp-vwp', label: 'Valley Water Pumps', client: 'client:vwp' },
|
||||
{ id: 'cp-acg', label: 'ACG Internal', client: 'client:acg' },
|
||||
];
|
||||
// Client sections are built dynamically from labels — only clients with issues appear in sidebar
|
||||
const CLIENT_SECTIONS = [];
|
||||
const ALL_REPOS = ['gururmm','guru-rmm','guru-connect','claudetools'];
|
||||
const REPO_NAMES = { 'gururmm':'GuruRMM', 'guru-rmm':'GuruRMM', 'guru-connect':'GuruConnect', 'claudetools':'ClaudeTools' };
|
||||
|
||||
@@ -329,11 +319,11 @@ function tagStyle(l) { return `background:#${l.color}20;color:#${l.color};`; }
|
||||
function getFiltered() {
|
||||
let items = allIssues;
|
||||
if (currentSection.startsWith('cp-')) {
|
||||
// Client project section
|
||||
const cs = CLIENT_SECTIONS.find(s=>s.id===currentSection);
|
||||
if (cs) {
|
||||
items = items.filter(i => isClientProject(i));
|
||||
if (cs.client) items = items.filter(i => i.labels.some(l => l.name === cs.client));
|
||||
// Client project section — dynamic
|
||||
items = items.filter(i => isClientProject(i));
|
||||
if (currentSection !== 'cp-all') {
|
||||
const clientTag = 'client:' + currentSection.slice(3);
|
||||
items = items.filter(i => i.labels.some(l => l.name === clientTag));
|
||||
}
|
||||
} else if (currentSection === 'all') {
|
||||
// Exclude client projects from "all issues"
|
||||
@@ -388,24 +378,24 @@ function renderSidebar() {
|
||||
</div>`;
|
||||
}
|
||||
|
||||
// Client projects section
|
||||
const cpCount = (cs) => {
|
||||
let items = allIssues.filter(i => i.state !== 'closed' && isClientProject(i));
|
||||
if (cs && cs.client) items = items.filter(i => i.labels.some(l => l.name === cs.client));
|
||||
return items.length;
|
||||
};
|
||||
const totalCp = cpCount(null);
|
||||
// Client projects section — built dynamically from issue labels
|
||||
const cpItems = allIssues.filter(i => i.state !== 'closed' && isClientProject(i));
|
||||
const clientCounts = {};
|
||||
for (const i of cpItems) {
|
||||
const cl = getClient(i);
|
||||
if (cl) clientCounts[cl] = (clientCounts[cl] || 0) + 1;
|
||||
}
|
||||
const totalCp = cpItems.length;
|
||||
html += `<div class="sidebar-divider"></div><div class="sidebar-section">Client Projects</div>`;
|
||||
html += `<div class="sidebar-item ${currentSection==='cp-all'?'active':''}" onclick="setSection('cp-all')">
|
||||
All Clients <span class="cnt">${totalCp}</span>
|
||||
</div>`;
|
||||
for (const cs of CLIENT_SECTIONS.filter(s=>s.client)) {
|
||||
const cnt = cpCount(cs);
|
||||
if (cnt > 0) {
|
||||
html += `<div class="sidebar-item ${currentSection===cs.id?'active':''}" onclick="setSection('${cs.id}')">
|
||||
${cs.label} <span class="cnt">${cnt}</span>
|
||||
</div>`;
|
||||
}
|
||||
for (const [cl, cnt] of Object.entries(clientCounts).sort((a,b)=>b[1]-a[1])) {
|
||||
const sid = 'cp-' + cl.replace('client:','');
|
||||
const displayName = cl.split(':')[1].replace(/-/g,' ').replace(/\b\w/g,c=>c.toUpperCase());
|
||||
html += `<div class="sidebar-item ${currentSection===sid?'active':''}" onclick="setSection('${sid}')">
|
||||
${displayName} <span class="cnt">${cnt}</span>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
sb.innerHTML = html;
|
||||
@@ -669,20 +659,6 @@ function showNewIssue() {
|
||||
<div class="frow" id="ni-client-row" style="display:none">
|
||||
<div class="fg"><label>Client</label><select id="ni-client">
|
||||
<option value="">(select client)</option>
|
||||
<option value="client:cascades">Cascades of Tucson</option>
|
||||
<option value="client:glaztech">GlazTech</option>
|
||||
<option value="client:sif-oidak">SIF / Oidak</option>
|
||||
<option value="client:goldstein">Goldstein</option>
|
||||
<option value="client:prairie-schooner">Prairie Schooner</option>
|
||||
<option value="client:cryoweave">CryoWeave</option>
|
||||
<option value="client:tedards">Tedards Law</option>
|
||||
<option value="client:vwp">Valley Water Pumps</option>
|
||||
<option value="client:acg">ACG Internal</option>
|
||||
<option value="client:attrebesch">Attrebesch</option>
|
||||
<option value="client:birth-biologic">Birth Biologic</option>
|
||||
<option value="client:desert-rv">Desert RV Center</option>
|
||||
<option value="client:deere-park">Deere Park</option>
|
||||
<option value="client:mineralogical">Mineralogical Record</option>
|
||||
</select></div>
|
||||
<div class="fg"><label>Assigned To</label><select id="ni-assign">
|
||||
<option value="">(unassigned)</option>
|
||||
@@ -703,14 +679,25 @@ function showNewIssue() {
|
||||
// Show/hide client fields based on type
|
||||
const typeEl = document.getElementById('ni-type');
|
||||
const clientRow = document.getElementById('ni-client-row');
|
||||
// Populate client dropdown from labelCache
|
||||
const clientSel = document.getElementById('ni-client');
|
||||
clientSel.innerHTML = '<option value="">(select client)</option>';
|
||||
const lc = labelCache['claudetools'] || {};
|
||||
const clientLabels = Object.keys(lc).filter(k => k.startsWith('client:') && k !== 'client-project').sort();
|
||||
for (const cl of clientLabels) {
|
||||
const name = cl.split(':')[1].replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
|
||||
clientSel.innerHTML += `<option value="${cl}">${name}</option>`;
|
||||
}
|
||||
const toggleClient = () => { clientRow.style.display = typeEl.value === 'client-project' ? 'flex' : 'none'; };
|
||||
typeEl.onchange = toggleClient;
|
||||
// Pre-select client-project if we're in a client section
|
||||
if (currentSection.startsWith('cp-')) {
|
||||
typeEl.value = 'client-project';
|
||||
toggleClient();
|
||||
const cs = CLIENT_SECTIONS.find(s=>s.id===currentSection);
|
||||
if (cs && cs.client) document.getElementById('ni-client').value = cs.client;
|
||||
if (currentSection !== 'cp-all') {
|
||||
const clientTag = 'client:' + currentSection.slice(3);
|
||||
document.getElementById('ni-client').value = clientTag;
|
||||
}
|
||||
}
|
||||
setTimeout(()=>document.getElementById('ni-title').focus(), 100);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user