]> acesimba.cloud Git - StationBuilder.git/commitdiff
feat: 重构扩展页面菜单(仪表板/报表子页/基础组件库/功能组件库/筛选器/数据源),各页空白占位
authorroot <root@localhost.localdomain>
Wed, 9 Sep 2026 06:46:08 +0000 (14:46 +0800)
committerroot <root@localhost.localdomain>
Wed, 9 Sep 2026 06:46:08 +0000 (14:46 +0800)
app/globals.css
app/page.tsx
data/db/StationBuilder.sqlite
scripts/verify-extmenu.mjs [new file with mode: 0644]

index 11133dd95c28f3265fc0ec4ca88ceaafd0d94bbd..b82632351408a18f916d30fd2ae81b97284ec585 100644 (file)
@@ -297,6 +297,9 @@ html,body{font-family:Roboto,"Noto Sans SC","Microsoft YaHei",Arial,sans-serif;f
 .menu-section-items button:hover{background:#dcecf5;color:var(--company-primary)}
 .menu-section-items button.active{background:#c3e4f6;color:var(--company-primary);font-weight:500}
 .extension-menu-items{padding-bottom:2px}.extension-menu-item{height:50px;padding:0 20px 0 40px;display:flex;align-items:center;font-size:17px;line-height:50px;color:#323233;font-weight:500;cursor:default}.extension-submenu-title{justify-content:space-between;cursor:pointer}.extension-submenu-title>.anticon{font-size:11px;margin-right:1px}.extension-third-menu>div{height:50px;padding:0 20px 0 60px;display:flex;align-items:center;color:#323233;font-size:17px;line-height:50px;font-weight:500;cursor:default}.extension-menu-section .extension-menu-item:hover,.extension-menu-section .extension-third-menu>div:hover{background:transparent;color:inherit}
+.extension-third-menu>button{height:50px;padding:0 20px 0 60px;display:flex;align-items:center;color:#323233;font-size:17px;line-height:50px;font-weight:500;cursor:pointer;border:0;background:transparent;width:100%;text-align:left;font-family:inherit}
+.extension-menu-section .extension-third-menu>button.clickable:hover{background:#e8f4fb;color:var(--company-primary)}
+.extension-menu-section .extension-third-menu>button.clickable.active{background:#d7eef9;color:var(--company-primary);font-weight:500}
 .company-side-footer{position:relative;margin:auto 16px 16px;padding:14px 4px 0;border-top:1px solid #ddd;display:flex;flex-direction:column;gap:8px;font-size:11px}
 .company-side-footer>b{color:#515a6e}.company-side-footer>button{height:26px;padding:0;border:0;background:transparent;display:flex;align-items:center;justify-content:space-between;color:#89898a;text-align:left}
 .company-model-menu{position:absolute;left:0;right:0;bottom:30px;padding:6px;background:#fff;border:1px solid #d9d9d9;box-shadow:0 4px 12px #00000018}
index f8f80cf702963cad162e595958ddd08ed0f38dba..5cb53cd8e01a2ac35082acd0484f7da301f8064b 100644 (file)
@@ -4,7 +4,7 @@ import { useEffect, useMemo, useRef, useState, type PointerEvent as ReactPointer
 import { Button as AntButton, Drawer, Dropdown, QRCode, Tag } from "antd";
 import { AimOutlined, ApartmentOutlined, BarsOutlined, BlockOutlined, CaretDownOutlined, CaretRightOutlined, ControlOutlined, CopyOutlined, DeleteOutlined, DownloadOutlined, EditOutlined, EllipsisOutlined, EyeOutlined, LinkOutlined, PlusOutlined, PlusSquareOutlined, RobotOutlined, SearchOutlined, SnippetsOutlined, UploadOutlined, ZoomInOutlined, ZoomOutOutlined } from "@ant-design/icons";
 
-type PageKey = "login" | "projects" | "siteEdit" | "basic" | "assets" | "pageConfig" | "functions" | "generate" | "result" | "preview" | "domains" | "domainDetail" | "styleLibrary" | "deviceTemplates" | "toolSettings" | "domainSettings" | "dashboard";
+type PageKey = "login" | "projects" | "siteEdit" | "basic" | "assets" | "pageConfig" | "functions" | "generate" | "result" | "preview" | "domains" | "domainDetail" | "styleLibrary" | "deviceTemplates" | "toolSettings" | "domainSettings" | "dashboard" | "report-dashboard" | "report-doc" | "basic-components" | "func-components" | "filters" | "datasource";
 type ModalKey = "" | "feedback" | "download" | "history" | "prompt" | "completePrompt";
 
 const meta: Record<PageKey, { label: string; icon: string; subtitle: string }> = {
@@ -24,7 +24,13 @@ const meta: Record<PageKey, { label: string; icon: string; subtitle: string }> =
   styleLibrary:{label:"页面样式",icon:"❖",subtitle:"管理可复用的 Cube 页面视觉样式与预览资源"},
   toolSettings:{label:"内部工具配置",icon:"",subtitle:"配置 StationBuilder 使用的内部能力、AI 服务和默认模型"},
   domainSettings:{label:"领域配置",icon:"",subtitle:"维护领域分类,供领域方案与站点项目统一使用"},
-  dashboard:{label:"仪表盘",icon:"◈",subtitle:"仅展示仪表盘示意图片"},
+  dashboard:{label:"仪表板",icon:"◈",subtitle:"仅展示仪表盘示意图片"},
+  "report-dashboard":{label:"仪表板报表",icon:"",subtitle:""},
+  "report-doc":{label:"文档报表",icon:"",subtitle:""},
+  "basic-components":{label:"基础组件库",icon:"",subtitle:""},
+  "func-components":{label:"功能组件库",icon:"",subtitle:""},
+  filters:{label:"筛选器",icon:"",subtitle:""},
+  datasource:{label:"数据源",icon:"",subtitle:""},
 };
 
 
@@ -533,7 +539,7 @@ export default function Home(){
   const projectArea = (["projects","siteEdit","basic","assets","pageConfig","functions","generate","result","preview"] as PageKey[]).includes(page);
   const resourceArea = (["domains","domainDetail","deviceTemplates","styleLibrary"] as PageKey[]).includes(page);
   const systemArea = (["toolSettings","domainSettings"] as PageKey[]).includes(page);
-  const extensionArea = (["dashboard"] as PageKey[]).includes(page);
+  const extensionArea = (["dashboard","report-dashboard","report-doc","basic-components","func-components","filters","datasource"] as PageKey[]).includes(page);
   const siteEditMeta = meta[siteEditSection];
   const manualAssetActive = assetConfigMode==="manual" && (page==="assets" || (page==="siteEdit"&&siteEditSection==="assets"));
 
@@ -569,16 +575,18 @@ export default function Home(){
         <section className={extensionArea?"menu-section extension-menu-section current":"menu-section extension-menu-section"} aria-label="扩展页面菜单">
           <button className="menu-section-title" aria-expanded={extensionNavOpen} onClick={()=>setExtensionNavOpen(v=>!v)}><span>扩展页面</span>{extensionNavOpen?<CaretDownOutlined/>:<CaretRightOutlined/>}</button>
           {extensionNavOpen&&<div className="menu-section-items extension-menu-items">
-            <button className={page==="dashboard"?"extension-menu-item clickable active":"extension-menu-item clickable"} onClick={()=>go("dashboard")}>仪表盘</button>
-            <div className="extension-menu-item">数据源</div>
+            <button className={page==="dashboard"?"extension-menu-item clickable active":"extension-menu-item clickable"} onClick={()=>go("dashboard")}>仪表板</button>
             <div className="extension-submenu">
               <button className="extension-menu-item extension-submenu-title" aria-expanded={reportNavOpen} onClick={()=>setReportNavOpen(v=>!v)}><span>报表</span>{reportNavOpen?<CaretDownOutlined/>:<CaretRightOutlined/>}</button>
               {reportNavOpen&&<div className="extension-third-menu">
-                <div>仪表盘报表</div>
-                <div>文档报表</div>
+                <button className={page==="report-dashboard"?"extension-third-menu-item clickable active":"extension-third-menu-item clickable"} onClick={()=>go("report-dashboard")}>仪表板报表</button>
+                <button className={page==="report-doc"?"extension-third-menu-item clickable active":"extension-third-menu-item clickable"} onClick={()=>go("report-doc")}>文档报表</button>
               </div>}
             </div>
-            <div className="extension-menu-item">数据源</div>
+            <button className={page==="basic-components"?"extension-menu-item clickable active":"extension-menu-item clickable"} onClick={()=>go("basic-components")}>基础组件库</button>
+            <button className={page==="func-components"?"extension-menu-item clickable active":"extension-menu-item clickable"} onClick={()=>go("func-components")}>功能组件库</button>
+            <button className={page==="filters"?"extension-menu-item clickable active":"extension-menu-item clickable"} onClick={()=>go("filters")}>筛选器</button>
+            <button className={page==="datasource"?"extension-menu-item clickable active":"extension-menu-item clickable"} onClick={()=>go("datasource")}>数据源</button>
           </div>}
         </section>
         <section className={resourceArea?"menu-section current":"menu-section"}>
index 0d8130d093faeae991940835bd9f9bac6e9086b8..70c7efabc6b5c220932d2f33da6b7d7950e8827b 100644 (file)
Binary files a/data/db/StationBuilder.sqlite and b/data/db/StationBuilder.sqlite differ
diff --git a/scripts/verify-extmenu.mjs b/scripts/verify-extmenu.mjs
new file mode 100644 (file)
index 0000000..c9787a1
--- /dev/null
@@ -0,0 +1,22 @@
+import { chromium } from 'playwright';
+const BASE='https://aidemo.istation.cloud/t/stationbuilder';
+const b=await chromium.launch();
+const p=await b.newPage({viewport:{width:1440,height:900}});
+const errs=[];
+p.on('console',m=>{if(m.type()==='error')errs.push(m.text());});
+await p.goto(`${BASE}/?page=projects`,{waitUntil:'networkidle'});
+await p.waitForSelector('.company-side-nav',{timeout:15000});
+// collect menu text
+const menuText = await p.evaluate(()=>{
+  const sec=[...document.querySelectorAll('.extension-menu-section')][0];
+  return sec? sec.innerText.replace(/\n+/g,' | ') : 'NO SECTION';
+});
+console.log('MENU:', menuText);
+for (const key of ['dashboard','report-dashboard','report-doc','basic-components','func-components','filters','datasource']) {
+  await p.goto(`${BASE}/?page=${key}`,{waitUntil:'networkidle'});
+  await p.waitForSelector('.page-heading h1',{timeout:10000}).catch(()=>{});
+  const title = await p.evaluate(()=>document.querySelector('.page-heading h1')?.textContent||'(none)');
+  console.log('PAGE', key, '=>', title);
+}
+console.log('ERRORS', errs.slice(0,8));
+await b.close();