eight-hourr/frontend/settings.html

246 lines
12 KiB
HTML
Raw Permalink Normal View History

2026-07-17 06:55:36 +00:00
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>設定 · 吉八小</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link rel="preconnect" href="https://font.emtech.cc" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
<link href="https://font.emtech.cc/css/TaipeiSansTC.css" rel="stylesheet" />
<script>
(function () {
var p = localStorage.getItem("pts_theme") || "system";
var dark = window.matchMedia("(prefers-color-scheme: dark)").matches;
var t = p === "light" || p === "dark" ? p : dark ? "dark" : "light";
document.documentElement.setAttribute("data-theme", t);
document.documentElement.classList.toggle("dark", t === "dark");
})();
</script>
<link rel="stylesheet" href="/static/style.css" />
</head>
<body>
<div class="container">
<header class="topbar">
<div>
<h1>設定</h1>
<p class="subtitle">吉八小 · 帳號連線與系統參數</p>
</div>
<div class="topbar-actions">
<div class="theme-toggle" title="外觀">
<button type="button" class="theme-btn" data-theme-option="light">淺色</button>
<button type="button" class="theme-btn" data-theme-option="dark">深色</button>
<button type="button" class="theme-btn" data-theme-option="system">系統</button>
</div>
<nav class="nav">
<a href="/" class="nav-link">填工時</a>
<a href="/compbase" class="nav-link">刷卡補填</a>
<a href="/settings" class="nav-link active">設定</a>
</nav>
</div>
</header>
<section class="card">
<h2>帳號連線</h2>
<p class="hint">輸入帳密登入。能打 API 就直接打;需 MFA 時才開瀏覽器。密碼加密存本機。</p>
<div class="auth-grid">
<div class="auth-panel">
<div class="panel-head">
<h3>PTS</h3>
<div id="ptsAuthStatus" class="badge warn">檢查中…</div>
</div>
<div class="settings-grid">
<label>帳號<input type="text" id="ptsUsername" placeholder="DOMAIN\user" autocomplete="username" /></label>
<label>密碼<input type="password" id="ptsPassword" placeholder="密碼" autocomplete="current-password" /></label>
</div>
<div class="actions">
<button type="button" id="ptsLoginBtn" class="btn primary">登入</button>
<button type="button" id="ptsLogoutBtn" class="btn secondary">清除 Session</button>
</div>
<p id="ptsLoginMsg" class="settings-status"></p>
</div>
<div class="auth-panel">
<div class="panel-head">
<h3>Teams 行事曆</h3>
<div id="teamsAuthStatus" class="badge">選配</div>
</div>
<div class="settings-grid">
<label class="checkbox-row"><input type="checkbox" id="teamsEnabled" /> 啟用會議併入工時</label>
<label>Microsoft 帳號<input type="text" id="teamsUsername" placeholder="you@company.com" autocomplete="username" /></label>
<label>密碼<input type="password" id="teamsPassword" placeholder="密碼" autocomplete="current-password" /></label>
</div>
<div class="actions">
<button type="button" id="teamsLoginBtn" class="btn primary">登入</button>
<button type="button" id="teamsLogoutBtn" class="btn secondary">中斷</button>
</div>
<p id="teamsLoginMsg" class="settings-status"></p>
<p class="hint small">Docker登入會開虛擬 Chrome可用互動畫面完成 MFA最多約 10 分鐘,不會中途關掉)。</p>
</div>
</div>
</section>
<!-- Teams MFAnoVNC 互動 + 截圖預覽 -->
<div id="teamsMfaModal" class="modal hidden" role="dialog" aria-modal="true" aria-labelledby="teamsMfaTitle">
<div class="modal-card modal-wide">
<div class="modal-head">
<h2 id="teamsMfaTitle">Teams 驗證MFA</h2>
<button type="button" id="teamsMfaClose" class="btn secondary btn-sm">關閉預覽</button>
</div>
<p class="hint" id="teamsMfaHint">
帳密送出後,請在下方<strong>互動畫面</strong>完成驗證(可點數字、輸入驗證碼)。
瀏覽器會保持開啟直到登入成功或逾時,請勿急著關掉。
</p>
<p class="settings-status" id="teamsMfaStatus">準備中…</p>
<div class="mfa-grid">
<div class="mfa-panel">
<div class="mfa-panel-head">
<strong>互動畫面</strong>
<a id="teamsVncLink" class="linkish" href="#" target="_blank" rel="noopener">新分頁開啟</a>
</div>
<iframe id="teamsVncFrame" class="mfa-frame" title="Teams 瀏覽器互動畫面" allow="clipboard-read; clipboard-write"></iframe>
<p class="hint small">若 iframe 空白,請用「新分頁開啟」。埠預設 6080。</p>
</div>
<div class="mfa-panel">
<div class="mfa-panel-head">
<strong>即時截圖</strong>
<span class="muted-inline" id="teamsMfaShotMeta"></span>
</div>
<img id="teamsMfaShot" class="mfa-shot" alt="MFA 截圖預覽" />
<p class="hint small">約每 1.5 秒更新,方便對號/看驗證畫面。</p>
</div>
</div>
</div>
</div>
<section class="card">
<h2>測試Teams 抓會議</h2>
<p class="hint">只測行事曆爬蟲(不走 Graph API。先「登入 Teams」完成 MFA再選日期測試。不寫 PTS、不碰 GitLab。</p>
<div class="form-row">
<label>
開始
<input type="date" id="teamsTestStart" />
</label>
<label>
結束
<input type="date" id="teamsTestEnd" />
</label>
<label class="checkbox dry-run-row">
<input type="checkbox" id="teamsTestSkipHolidays" checked />
跳過假日
</label>
</div>
<div class="actions">
<button type="button" id="teamsTestBtn" class="btn primary">測試抓會議</button>
<button type="button" id="teamsStatusBtn" class="btn secondary">連線狀態</button>
</div>
<p id="teamsTestMsg" class="settings-status"></p>
<div id="teamsTestSummary" class="meetings-summary"></div>
<div id="teamsTestList" class="meetings-list"></div>
<pre id="teamsTestDebug" class="preview">尚無測試結果</pre>
</section>
<section class="card">
<h2>系統參數</h2>
<form id="settingsForm" class="settings-form">
<fieldset>
<legend>GitLab</legend>
<div class="settings-grid">
<label>URL<input type="url" name="gitlab_url" /></label>
<label>GitLab Personal Access Token
<input type="password" name="gitlab_token" placeholder="貼上 token" autocomplete="off" />
</label>
<p id="gitlabTokenHint" class="hint small full-span"></p>
<label>Project Path<input type="text" name="gitlab_project_path" /></label>
<label>Board ID<input type="number" name="gitlab_board_id" min="1" /></label>
<label>Board Labels<input type="text" name="gitlab_board_labels" /></label>
<label>Milestone<input type="text" name="gitlab_milestone_title" placeholder="留空自動" /></label>
</div>
</fieldset>
<fieldset>
<legend>工時填寫</legend>
<div class="settings-grid">
<label>PTS URL<input type="url" name="pts_url" /></label>
<label>Project Name<input type="text" name="pts_project_name" /></label>
<label>Task Type<input type="text" name="pts_default_task_name" /></label>
<label>Max Hours / Day<input type="number" name="max_hours_per_day" min="0.5" max="24" step="0.5" /></label>
<label>Hour Step<input type="number" name="hour_step" min="0.5" max="8" step="0.5" /></label>
<label>時區<input type="text" name="teams_calendar_timezone" /></label>
<label>會議 Task 預設<input type="text" name="teams_meeting_task_name" /></label>
<label class="full-span">排除加入 PTS 的會議關鍵字(逗號分隔,符合的會議仍會顯示在下方列表,但不會寫入 PTS
<input type="text" name="teams_meeting_exclude_keywords" placeholder="例如:貼心的提醒,請記得下班刷退" />
</label>
</div>
</fieldset>
<fieldset>
<legend>CompBase 刷卡補填(選填)</legend>
<p class="hint small full-span">預設沿用上方 PTS 帳密做 NTLM。僅在帳號不同時才填這裡。</p>
<div class="settings-grid">
<label>List URL<input type="url" name="compbase_list_url" /></label>
<label>Fill URL<input type="url" name="compbase_fill_url" /></label>
<label>帳號<input type="text" name="compbase_username" placeholder="留空=用工時帳號" autocomplete="username" /></label>
<label>密碼<input type="password" name="compbase_password" placeholder="留空不變更/用工時密碼" autocomplete="new-password" /></label>
<label>預設近 N 天<input type="number" name="compbase_default_days" min="1" max="62" /></label>
<label>刷退模式
<select name="compbase_out_time_mode">
<option value="expected">expected正常工時</option>
<option value="latest_option">latest_option</option>
</select>
</label>
</div>
</fieldset>
<fieldset>
<legend>Grok LLM</legend>
<div class="settings-grid">
<label class="checkbox-row"><input type="checkbox" name="use_llm" /> 啟用 Grok</label>
<label class="checkbox-row"><input type="checkbox" name="use_description_variation" /> 描述變化</label>
<label>API Key<input type="password" name="xai_api_key" placeholder="留空不變更" autocomplete="off" /></label>
<label>Base URL<input type="url" name="xai_base_url" /></label>
<label>Model<input type="text" name="grok_model" /></label>
</div>
</fieldset>
<fieldset>
<legend>自動排程</legend>
<div class="settings-grid">
<label class="checkbox-row"><input type="checkbox" name="auto_fill_enabled" /> 每日自動填寫</label>
<label>Hour<input type="number" name="auto_fill_hour" min="0" max="23" /></label>
<label>Minute<input type="number" name="auto_fill_minute" min="0" max="59" /></label>
</div>
</fieldset>
<fieldset>
<legend>補寫日期 (dates.txt)</legend>
<textarea id="datesFileContent" name="dates_file_content" class="date-list" rows="6" placeholder="一行一個日期"></textarea>
</fieldset>
<div class="actions">
<button type="submit" class="btn primary">儲存設定</button>
<a href="/" class="btn secondary">回主頁</a>
<span id="settingsStatus" class="settings-status"></span>
</div>
</form>
</section>
<section class="card muted-card">
<h2>備援:瀏覽器擴充功能</h2>
<p class="hint">帳密登入不可用時,可用擴充功能同步工時系統登入憑證。</p>
<div class="actions">
<a href="/api/extension/download" class="btn secondary" download="jibaxiao-sync.zip">下載擴充功能</a>
</div>
<ol class="install-steps">
<li>解壓後於 <code>chrome://extensions</code> 載入未封裝項目</li>
<li>登入工時系統網頁 → 重新整理 → 擴充功能同步憑證</li>
</ol>
</section>
</div>
<script src="/static/common.js"></script>
<script src="/static/settings.js"></script>
</body>
</html>