eight-hourr/frontend/settings.html

246 lines
12 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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>