diff --git a/static/app.js b/static/app.js index e8cbfea..6bd8d5e 100644 --- a/static/app.js +++ b/static/app.js @@ -1,26 +1,13 @@ // app.js — 入口文件(加载模块 + 初始化) -// 所有业务逻辑已拆分到 modules/ 目录: -// utils.js — 共享状态、工具函数、API 封装 -// home.js — 首页 + 财务趋势图 -// projects.js — 重点工作与台账(项目+任务+拖拽) -// proposals.js — 业务方案 + 文件管理 -// products.js — 产品迭代 -// finance.js — 经营管理(财务) -// drawer.js — 详情抽屉 + 评论 + 转移 - -// Tab 点击委托 -document.querySelector("#tabs").addEventListener("click", (event) => { - const button = event.target.closest("button[data-tab]"); - if (button) switchTab(button.dataset.tab); -}); // 恢复上次的工作台和标签页 const savedTenant = localStorage.getItem("opc-active-tenant"); if (savedTenant) { state.tenant = savedTenant; - document.querySelectorAll(".workspace-nav-item").forEach(el => el.classList.toggle("active", el.dataset.tenant === savedTenant)); const label = savedTenant.replace("·无界", ""); document.querySelector("#workspaceTitle").textContent = label + " OPC 工作台"; + const tLabel = document.querySelector("#currentTenantLabel"); + if (tLabel) { tLabel.textContent = label || "工作台"; tLabel.title = savedTenant; } } const savedTab = localStorage.getItem("opc-active-tab"); diff --git a/static/modules/projects.js b/static/modules/projects.js index 0f3ed4a..0ecafc6 100644 --- a/static/modules/projects.js +++ b/static/modules/projects.js @@ -13,13 +13,57 @@ function applyUserTenants() { e.stopPropagation(); toggleUserMenu(user); }); - const allowedTenants = data.tenants || []; - document.querySelectorAll(".workspace-nav-item").forEach(el => { - el.style.display = allowedTenants.includes(el.dataset.tenant) ? "" : "none"; - }); + // 缓存可用工作台列表,供下拉菜单使用 + state.allowedTenants = data.tenants || []; + updateTenantLabel(); }); } +window.toggleTenantMenu = (event) => { + event.stopPropagation(); + let menu = document.getElementById("tenantMenu"); + if (menu) { menu.remove(); return; } + const btn = event.currentTarget; + const rect = btn.getBoundingClientRect(); + const tenants = state.allowedTenants || []; + menu = document.createElement("div"); + menu.id = "tenantMenu"; + menu.className = "fixed bg-white rounded-lg shadow-xl border border-slate-200 py-1 min-w-[160px] z-[9999]"; + menu.style.left = Math.min(rect.left - 8, window.innerWidth - 180) + "px"; + menu.style.top = rect.bottom + 6 + "px"; + menu.innerHTML = ` +
+

切换工作台

+
+ ${tenants.map(t => ` + + `).join('')}`; + document.body.appendChild(menu); + if (window.lucide) lucide.createIcons(); + setTimeout(() => { + document.addEventListener("click", function closeMenu() { + menu.remove(); + document.removeEventListener("click", closeMenu); + }, { once: true }); + }, 10); +}; + +window.switchTenantFromMenu = (tenant) => { + document.getElementById("tenantMenu")?.remove(); + switchTenant(tenant); +}; + +function updateTenantLabel() { + const label = document.querySelector("#currentTenantLabel"); + if (label) { + label.textContent = state.tenant.replace("·无界", "") || "工作台"; + label.title = state.tenant; + } +} + window.toggleUserMenu = (user) => { let menu = document.getElementById("userMenu"); if (menu) { menu.remove(); return; } diff --git a/static/modules/utils.js b/static/modules/utils.js index 74b495e..031df3c 100644 --- a/static/modules/utils.js +++ b/static/modules/utils.js @@ -123,7 +123,7 @@ async function load() { function switchTab(tab) { state.active = tab; localStorage.setItem("opc-active-tab", tab); - document.querySelectorAll("#tabs button").forEach((btn) => btn.classList.toggle("active", btn.dataset.tab === tab)); + document.querySelectorAll(".sidebar-tab").forEach((btn) => btn.classList.toggle("active", btn.dataset.tab === tab)); document.querySelectorAll(".panel").forEach((panel) => panel.classList.toggle("active", panel.id === tab)); render(); } @@ -179,7 +179,8 @@ window.switchTenant = (tenant) => { state.selectedProject = null; localStorage.setItem("opc-active-tenant", tenant); document.querySelector("#workspaceTitle").textContent = tenant.replace("·无界", "") + " OPC 工作台"; - document.querySelectorAll(".workspace-nav-item").forEach((el) => el.classList.toggle("active", el.dataset.tenant === tenant)); + const label = document.querySelector("#currentTenantLabel"); + if (label) { label.textContent = tenant.replace("·无界", "") || "工作台"; label.title = tenant; } load(); }; window.doLogout = async () => { diff --git a/static/styles.css b/static/styles.css index f81bb49..c136d74 100644 --- a/static/styles.css +++ b/static/styles.css @@ -32,25 +32,30 @@ body { background: rgba(96,165,250,0.15); } -.tabs { +.sidebar-tab { display: flex; - gap: 4px; -} - -.tabs button { + flex-direction: column; align-items: center; - border-bottom: 2px solid transparent; - color: #64748b; - display: inline-flex; - font-size: 14px; - font-weight: 600; - gap: 8px; - padding: 14px 16px; + padding: 8px 4px; + border-radius: 8px; + cursor: pointer; + color: #94a3b8; + transition: all 0.15s ease; + width: 100%; } -.tabs button.active { - border-bottom-color: #1d4ed8; - color: #1d4ed8; +.sidebar-tab:hover { + background: #1e293b; + color: #cbd5e1; +} + +.sidebar-tab.active { + background: #1e293b; + color: #60a5fa; +} + +.sidebar-tab.active i { + color: #60a5fa; } .panel { diff --git a/templates/index.html b/templates/index.html index 27d608f..7e078e7 100644 --- a/templates/index.html +++ b/templates/index.html @@ -29,29 +29,42 @@
@@ -67,14 +80,6 @@
- -