console 頁面 profile 裁剪:CONSOLE_PROFILE=rag 企業產品樣(搜尋落地),未設=full mira 零影響 (#48)

This commit was merged in pull request #48.
This commit is contained in:
Leo
2026-07-13 11:15:00 +00:00
parent 2e1005ea67
commit cbebb36c01
3 changed files with 42 additions and 14 deletions
@@ -814,4 +814,9 @@ function renderDashboardHtml(brand: string): string {
// GET /console/dashboard — 駕駛艙頁(無需登入;純渲染 dashboard-data,無互動、無說明文字)
// 品牌字樣(Arcrun#21):引擎預設 Arcrun,實例可用 CONSOLE_BRAND 覆蓋(如 "Arcrun RAG"
consoleDashboardRouter.get('/console/dashboard', (c) => c.html(renderDashboardHtml(c.env.CONSOLE_BRAND || 'Arcrun')));
// CONSOLE_PROFILE=ragconsole-profile-trim):駕駛艙不屬企業版頁面 → 302 回 /console。
// 選 302 不選 404:舊書籤/外鏈直接落回產品頁,不給死路(只裁 UI 頁面,資料端點行為不動)。
consoleDashboardRouter.get('/console/dashboard', (c) => {
if ((c.env.CONSOLE_PROFILE || 'full') === 'rag') return c.redirect('/console', 302);
return c.html(renderDashboardHtml(c.env.CONSOLE_BRAND || 'Arcrun'));
});
+30 -13
View File
@@ -63,7 +63,18 @@ import { TAIPEI_CLIENT_JS } from '../lib/taipei-time';
export const consoleRouter = new Hono<{ Bindings: Bindings }>();
function renderConsoleHtml(registryBase: string, brand: string): string {
function renderConsoleHtml(registryBase: string, brand: string, profile: string): string {
// Console profileconfig 裁剪,非 auth——#24/#25 多人 Portal 是另一回事):
// full(未設即此)=全套,Mira 實例現行為一字不變。
// rag=企業產品樣:只留 總庫搜尋/工作流/設定(card 是搜尋的詳頁,跟著留),落地=搜尋頁。
// 隱藏頁的 view div 仍在 DOMdisplay:none、路由 guard 導回,永遠點不進)——
// 因 creds/inbox 有 top-level addEventListener 綁定,抽掉 div 會讓整包 JS 啟動即炸,
// 純渲染層裁剪以「導不進去」為準,不為了抽 DOM 把 null-guard 灑滿全檔。
const rag = profile === 'rag';
const views = rag
? ['search', 'card', 'workflows', 'settings']
: ['cockpit', 'search', 'card', 'workflows', 'creds', 'inbox', 'settings'];
const home = rag ? 'search' : 'cockpit';
return `<!doctype html>
<html lang="zh-Hant">
<head>
@@ -302,7 +313,7 @@ function renderConsoleHtml(registryBase: string, brand: string): string {
<div id="login-status" class="err" style="font-size:14px;min-height:1.2em"></div>
</div>
<div style="font-size:13.5px;color:rgba(var(--ink-rgb),.4);line-height:1.7">這是一個人的智慧總部。<br>若你不是擁有者,這裡沒有你要找的東西。</div>
<a href="/console/dashboard" style="font-size:13.5px;color:rgba(var(--amber-rgb),.7)">免登入看駕駛艙 </a>
${rag ? '' : '<a href="/console/dashboard" style="font-size:13.5px;color:rgba(var(--amber-rgb),.7)">免登入看駕駛艙 </a>'}
<button class="btn3 themelabel" data-themetoggle style="align-self:center;padding:8px 16px;font-size:13.5px;border-radius:999px">☾ 切深色</button>
</div>
</div>
@@ -330,11 +341,11 @@ function renderConsoleHtml(registryBase: string, brand: string): string {
<div id="shell">
<div id="sidenav">
<div class="logo">${brand}</div>
<div class="nav" data-nav="cockpit">駕駛艙</div>
${rag ? '' : '<div class="nav" data-nav="cockpit">駕駛艙</div>'}
<div class="nav" data-nav="search">總庫搜尋</div>
<div class="nav" data-nav="workflows">工作流</div>
<div class="nav" data-nav="creds">憑證管理</div>
<div class="nav" data-nav="inbox">分流台</div>
${rag ? '' : `<div class="nav" data-nav="creds">憑證管理</div>
<div class="nav" data-nav="inbox">分流台</div>`}
<div class="nav" data-nav="settings">設定</div>
<div class="nav themelabel" data-themetoggle style="margin-top:8px;font-size:14.5px">☾ 切深色</div>
<div class="foot" id="side-foot"></div>
@@ -498,13 +509,13 @@ function renderConsoleHtml(registryBase: string, brand: string): string {
<div id="st-pw-status" style="font-size:14px;min-height:1.2em"></div>
</div>
</div>
<div class="panel" style="display:flex;align-items:center;gap:12px;cursor:pointer" data-nav="creds">
${rag ? '' : `<div class="panel" style="display:flex;align-items:center;gap:12px;cursor:pointer" data-nav="creds">
<div>
<div style="font-size:17px;font-weight:600">憑證管理</div>
<div style="margin-top:4px;font-size:14px;color:rgba(var(--ink-rgb),.55)">只保存目錄與加密值,不可回看</div>
</div>
<span style="margin-left:auto;color:rgba(var(--amber-rgb),.6);font-size:18px"></span>
</div>
</div>`}
<div class="panel">
<div style="font-size:17px;font-weight:600;margin-bottom:12px">系統資訊</div>
<div id="st-info"><div class="muted">載入中…</div></div>
@@ -518,10 +529,10 @@ function renderConsoleHtml(registryBase: string, brand: string): string {
<!-- 手機底部導覽 -->
<div id="tabbar">
<div class="tab" data-nav="cockpit">駕駛艙</div>
${rag ? '' : '<div class="tab" data-nav="cockpit">駕駛艙</div>'}
<div class="tab" data-nav="search">搜尋</div>
<div class="tab" data-nav="workflows">工作流</div>
<div class="tab" data-nav="inbox">分流台</div>
${rag ? '' : '<div class="tab" data-nav="inbox">分流台</div>'}
<div class="tab" data-nav="settings">設定</div>
</div>
@@ -646,11 +657,14 @@ function renderConsoleHtml(registryBase: string, brand: string): string {
}
// ── 路由 ──
var VIEWS = ['cockpit', 'search', 'card', 'workflows', 'creds', 'inbox', 'settings'];
// VIEWS / HOME 由 server 依 CONSOLE_PROFILE 注入(full=全套 7 頁落地駕駛艙;rag=4 頁落地搜尋)。
// 不在 VIEWS 裡的 hash(含被 profile 裁掉的頁)一律導回 HOME——手打 #/cockpit 也進不去。
var VIEWS = ${JSON.stringify(views)};
var HOME = ${JSON.stringify(home)};
function currentRoute() {
var h = location.hash.replace(/^#\\/?/, '');
var seg = h.split('/');
return { view: VIEWS.indexOf(seg[0]) >= 0 ? seg[0] : 'cockpit', arg: seg.slice(1).join('/') };
return { raw: seg[0] || '', view: VIEWS.indexOf(seg[0]) >= 0 ? seg[0] : HOME, arg: seg.slice(1).join('/') };
}
function nav(view, arg) {
location.hash = '#/' + view + (arg ? '/' + encodeURIComponent(arg) : '');
@@ -666,6 +680,8 @@ function renderConsoleHtml(registryBase: string, brand: string): string {
var LOADERS = { cockpit: loadCockpit, search: initSearchOnce, card: loadCard, workflows: loadWorkflows, creds: loadCreds, inbox: loadTriage, settings: loadSettings };
function route() {
var r = currentRoute();
// 隱藏頁/不存在頁 guardhash 不在 VIEWS → 改寫成 HOMEhashchange 會再進來一次正常渲染)
if (r.raw && r.raw !== r.view) { location.hash = '#/' + r.view; return; }
if (r.view === 'card' && r.arg) S.cardId = decodeURIComponent(r.arg);
showView(r.view);
if (LOADERS[r.view]) LOADERS[r.view]();
@@ -689,7 +705,7 @@ function renderConsoleHtml(registryBase: string, brand: string): string {
$('shell').classList.add('on');
$('tabbar').classList.add('on');
$('side-foot').innerHTML = '租戶 ' + esc(S.tenant) + '<br>' + esc(location.host);
if (!location.hash) location.hash = '#/cockpit';
if (!location.hash) location.hash = '#/' + HOME;
route();
}
function init() {
@@ -1476,5 +1492,6 @@ consoleRouter.get('/console', (c) => {
? `https://arcrun-registry.${subdomain}.workers.dev`
: 'https://registry.arcrun.dev';
// 品牌字樣(Arcrun#21):引擎預設 Arcrun,實例可用 CONSOLE_BRAND 覆蓋(如 "Arcrun RAG"
return c.html(renderConsoleHtml(registryBase, c.env.CONSOLE_BRAND || 'Arcrun'));
// 頁面組成(console-profile-trim):CONSOLE_PROFILE 未設=full 全套;"rag"=企業產品樣(搜尋落地)
return c.html(renderConsoleHtml(registryBase, c.env.CONSOLE_BRAND || 'Arcrun', c.env.CONSOLE_PROFILE || 'full'));
});
+6
View File
@@ -82,6 +82,12 @@ export type Bindings = {
// 不影響任何行為。未設 → "Arcrun"console 是引擎共用件,不寫死產品名)。
// 實例可覆蓋,例:arcrun-rag demo 可設 --var CONSOLE_BRAND:"Arcrun RAG"。
CONSOLE_BRAND?: string;
// Console 頁面組成 profileconsole-profile-trim,非機密)。只影響 UI 組成與落地頁,
// 不動任何 API/資料行為。未設或 "full" → 全套(Mira 實例現行為,一字不變)。
// "rag" → 企業產品樣:側欄只留 總庫搜尋/工作流/設定(含卡片詳頁),落地=搜尋頁;
// 駕駛艙/分流台/憑證管理隱藏且路由導回搜尋;/console/dashboard 302 回 /console。
// 例:arcrun-rag demo 可設 --var CONSOLE_PROFILE:rag。
CONSOLE_PROFILE?: string;
// ── console 駕駛艙「等你的事」活資料源(fix/console-dashboard-live-data2026-07-07)──
// 等 leo 的事真相源=InkStoneCo sprint 檔「## 等 leo 清單」(progress-guard 每日維護),
// 不是沒人維護的 KBDB dash_wait。cypher 進程內 fetch Gitea API(自架 Gitea,非 GitHub