ui: custom project switcher dropdown — no native select

This commit is contained in:
James 2026-03-12 02:37:04 -04:00
parent a2fc510065
commit a9d40a31b5
2 changed files with 26 additions and 43 deletions

View File

@ -216,28 +216,6 @@ input:focus, textarea:focus, select:focus { border-color: var(--ds-ac) !importan
/* ===== TREE TABLE ===== */
#reqTree { border-collapse: collapse; width: 100%; font-size: 13px; }
/* ===== PROJECT SWITCHER ===== */
#projectSwitcher {
appearance: none;
-webkit-appearance: none;
background: transparent;
border: none;
outline: none;
color: var(--ds-tx);
font-size: 1.25rem;
font-weight: 600;
cursor: pointer;
padding: 0;
margin: 0;
max-width: 320px;
}
#projectSwitcher option {
background: var(--ds-sf);
color: var(--ds-tx);
font-size: 13px;
font-weight: 400;
}
/* ===== TYPE HIERARCHY ===== */
/* Level 1 — Logo / Page title : 2xl (19.5px) — set inline */
/* Level 2 — Project name in header : xl (16.25px) — set inline */

View File

@ -2,10 +2,14 @@
<div class="flex items-center gap-3">
<a href="/app/projects" class="text-2xl font-bold text-white tracking-tight"><span class="text-[#c9a84c]">Deal</span>space</a>
<span class="text-white/20 text-lg">/</span>
<select id="projectSwitcher" onchange="switchProject(this.value)"
class="bg-transparent border-none outline-none text-xl font-semibold text-white cursor-pointer focus:outline-none">
<option id="projectName" value="">Loading...</option>
</select>
<div id="projectSwitcher" class="relative">
<button id="projectSwitcherBtn" onclick="toggleProjectMenu()" class="flex items-center gap-1.5 text-xl font-semibold text-white hover:text-white/80 transition focus:outline-none">
<span id="projectName">Loading...</span>
<span style="font-size:10px;opacity:.5;margin-top:2px"></span>
</button>
<div id="projectMenu" class="hidden absolute left-0 top-full mt-2 min-w-[220px] rounded-lg border shadow-xl z-50" style="background:var(--ds-sf);border-color:var(--ds-bd)">
</div>
</div>
</div>
{{end}}
@ -331,25 +335,18 @@
const d = parseData(p.data_text);
const name = d.name || p.summary_text || p.summary || 'Untitled';
document.title = name + ' — Dealspace';
// Populate project switcher
const sel = document.getElementById('projectSwitcher');
const opt = document.getElementById('projectName');
opt.value = projectID;
opt.textContent = name;
// Load all projects for switcher
document.getElementById('projectName').textContent = name;
fetchAPI('/api/projects').then(r=>r.json()).then(projects=>{
sel.innerHTML = '';
(projects||[]).forEach(p=>{
const o = document.createElement('option');
o.value = p.entry_id;
const menu = document.getElementById('projectMenu');
menu.innerHTML = (projects||[]).map(p=>{
const d = p.data_text ? (()=>{try{return JSON.parse(p.data_text)}catch{return{}}})() : {};
o.textContent = d.name || p.search_key || p.entry_id;
if(p.entry_id === projectID) o.selected = true;
sel.appendChild(o);
});
}).catch(()=>{
sel.innerHTML = `<option value="${projectID}">${name}</option>`;
});
const pname = d.name || p.search_key || p.entry_id;
const active = p.entry_id === projectID;
return `<div onclick="switchProject('${p.entry_id}')" class="px-4 py-2.5 cursor-pointer transition text-sm" style="color:${active?'var(--ds-ac)':'var(--ds-tx)'};background:${active?'rgba(255,255,255,.04)':'transparent'}" onmouseover="this.style.background='rgba(255,255,255,.06)'" onmouseout="this.style.background='${active?'rgba(255,255,255,.04)':'transparent'}'">
${escHtml(pname)}
</div>`;
}).join('');
}).catch(()=>{});
// projectTitle removed — name shown in header breadcrumb only
document.getElementById('projectDesc').textContent = d.description || '';
const status = d.status || 'active';
@ -898,8 +895,16 @@
}
function switchProject(pid) {
document.getElementById('projectMenu').classList.add('hidden');
if (pid && pid !== projectID) window.location.href = '/app/projects/' + pid;
}
function toggleProjectMenu() {
document.getElementById('projectMenu').classList.toggle('hidden');
}
document.addEventListener('click', e => {
if (!document.getElementById('projectSwitcher')?.contains(e.target))
document.getElementById('projectMenu')?.classList.add('hidden');
});
function closeAddOrgModal() {
document.getElementById('addOrgModal').classList.add('hidden');