Artur Mukhamadiev 1a8c220ca3 frontend: time-based playful status line while a query runs
The running view showed one fixed line for up to 15 minutes, which reads as a
hang. js/running-status.js maps elapsed run time to a line, starting neutral
("Searching Confluence…") and getting more playful at 20 s, 1, 2, 4, 7 and 11
minutes, in the same register as the Exit queue button. app.js re-evaluates
the line every 5 s from wall-clock time (correct after background-tab
throttling), restarts the clock when the running state is entered after a
queue wait, and stops the ticker when the view leaves the running state. The
backend streams no progress, so no line claims a specific activity.
2026-09-15 14:06:39 +03:00

169 lines
8.2 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Confluence Research</title>
<link rel="icon" type="image/svg+xml" href="assets/book.svg">
<link rel="stylesheet" href="css/style.css">
<script src="vendor/marked.min.js"></script>
<script src="vendor/purify.min.js"></script>
<script type="module" src="js/app.js"></script>
</head>
<body>
<!-- Top Navigation Header -->
<header class="app-header">
<div id="app-brand" class="app-brand">
<span id="brand-logo" class="book" aria-hidden="true">
<span class="book-page"></span>
<span class="book-edge"></span>
<span class="book-cover"><span class="book-label"></span></span>
</span>
<span>Confluence Research</span>
</div>
<button id="key-btn" class="key-btn" type="button" aria-label="Configure Confluence Credentials" title="Configure Confluence Credentials">
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<path d="M 6.5625 5.0136719 C 2.4595703 5.2668613 -0.68726562 9.0536406 0.13085938 13.369141 C 0.65285938 16.124141 2.8748594 18.347141 5.6308594 18.869141 C 9.378008 19.579519 12.720128 17.298793 13.703125 14 L 18 14 L 18 15 C 18 16.105 18.895 17 20 17 C 21.105 17 22 16.105 22 15 L 22 14 C 23.105 14 24 13.105 24 12 C 24 10.895 23.105 10 22 10 L 13.699219 10 C 12.979424 7.5432523 10.909496 5.6120152 8.3691406 5.1308594 C 7.7527656 5.0139844 7.1486328 4.977502 6.5625 5.0136719 z M 7 9 C 8.657 9 10 10.343 10 12 C 10 13.657 8.657 15 7 15 C 5.343 15 4 13.657 4 12 C 4 10.343 5.343 9 7 9 z"></path>
</svg>
<span id="cred-indicator" class="cred-indicator" aria-hidden="true"></span>
<span id="cred-status-sr" class="sr-only">Credentials not set</span>
</button>
</header>
<!-- Main View Container -->
<main class="app-main">
<!-- State 1: Prompt View -->
<section id="view-prompt" class="view-prompt" aria-label="Research prompt view">
<div class="prompt-wrapper">
<h1 class="prompt-title">What would you like to research?</h1>
<div id="prompt-error" class="alert-box error-box hidden" role="alert"></div>
<div class="prompt-box">
<textarea
id="prompt-input"
class="prompt-input"
placeholder="Search or ask about Confluence documentation..."
rows="3"
aria-label="Research prompt"
></textarea>
<div class="prompt-footer">
<span class="prompt-helper">Press Enter ↵ to send · Shift + Enter for new line</span>
<button id="submit-btn" class="submit-btn" type="button" aria-label="Send query">
<span>Send</span>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<line x1="22" y1="2" x2="11" y2="13"></line>
<polygon points="22 2 15 22 11 13 2 9 22 2"></polygon>
</svg>
</button>
</div>
</div>
</div>
</section>
<!-- State 3: Loading View -->
<section id="view-loading" class="view-loading hidden" aria-label="Loading execution view">
<div class="spinner-wrapper">
<canvas id="thinking-orb" class="thinking-orb" width="64" height="64" aria-hidden="true"></canvas>
</div>
<p id="loading-status" class="loading-status" aria-live="polite">Searching Confluence…</p>
<button id="cancel-btn" class="cancel-btn" type="button">Cancel</button>
<button id="exit-queue-btn" class="cancel-btn exit-queue-btn hidden" type="button" aria-label="Leave the queue">I will try next time</button>
</section>
<!-- State 4: Result View -->
<section id="view-result" class="view-result hidden" aria-label="Research result view">
<div class="action-bar">
<button id="back-btn" class="action-btn back-btn" type="button">← Back to prompt</button>
<button id="export-btn" class="action-btn export-btn" type="button">Export to MD</button>
</div>
<div id="result-warnings" class="warnings-container hidden" role="region" aria-label="Result warnings"></div>
<div id="section-nav" class="section-nav hidden"></div>
<div id="output-content" class="output-content"></div>
<!-- Artifacts Section -->
<div id="artifacts-section" class="artifacts-section hidden" role="region" aria-label="Generated artifacts">
<h2 class="artifacts-heading">Generated Artifacts</h2>
<div id="artifacts-error" class="alert-box error-box hidden" role="alert"></div>
<ul id="artifacts-list" class="artifacts-list"></ul>
</div>
<!-- Sources & Request History Section -->
<div id="history-section" class="history-section" role="region" aria-label="Sources and request history">
<button id="history-toggle-btn" class="history-toggle-btn" type="button" aria-expanded="false" aria-controls="history-content">
<span id="history-toggle-title">Sources &amp; Request History (0 pages accessed)</span>
<span class="toggle-icon"></span>
</button>
<div id="history-content" class="history-content hidden">
<h3 class="history-subheading">Pages Read</h3>
<div id="pages-accessed-list" class="pages-list"></div>
<h3 class="history-subheading">Tool Operations</h3>
<div id="tool-history-list" class="tool-list"></div>
</div>
</div>
</section>
</main>
<!-- State 2: Credentials Configuration Modal -->
<div id="modal-backdrop" class="modal-backdrop hidden" tabindex="-1">
<div id="modal-dialog" class="modal-dialog" role="dialog" aria-modal="true" aria-labelledby="modal-title">
<div class="modal-header">
<h2 id="modal-title" class="modal-title">Confluence Credentials</h2>
<button id="modal-close-btn" class="modal-close-btn" type="button" aria-label="Close credentials dialog">&times;</button>
</div>
<form id="credentials-form" novalidate>
<div class="form-group">
<label for="cred-url" class="form-label">Confluence Base URL</label>
<input
type="url"
id="cred-url"
class="modal-input"
placeholder="https://confluence.example.com"
autocomplete="off"
spellcheck="false"
required
>
<span class="field-hint">Must be a valid HTTP or HTTPS URL (max 8 KiB)</span>
</div>
<div class="form-group">
<label for="cred-pat" class="form-label">Personal Access Token (PAT)</label>
<div class="password-input-wrapper">
<input
type="password"
id="cred-pat"
class="modal-input"
placeholder="Personal Access Token"
autocomplete="off"
spellcheck="false"
required
>
<button type="button" id="toggle-pat-btn" class="toggle-password-btn" aria-label="Show token">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
<circle cx="12" cy="12" r="3"></circle>
</svg>
</button>
</div>
<span class="field-hint">Token is kept strictly in browser memory (max 8 KiB)</span>
</div>
<div id="modal-feedback" class="modal-feedback hidden" role="status" aria-live="polite"></div>
<div class="modal-actions">
<div class="modal-actions-left">
<button type="button" id="btn-clear-cred" class="btn-secondary danger">Clear credentials</button>
</div>
<div class="modal-actions-right">
<button type="button" id="btn-test-cred" class="btn-secondary">Test Connection</button>
<button type="button" id="btn-cancel-cred" class="btn-secondary">Cancel</button>
<button type="submit" id="btn-save-cred" class="btn-primary">Save &amp; Close</button>
</div>
</div>
</form>
</div>
</div>
</body>
</html>