The origin check is an exact match including the context path, so users had to type "https://collab.lge.com/main" precisely. GET /api/v1/config now returns the approved origins in canonical form (non-secret: they are the only destinations the backend will talk to), and the UI swaps the URL text field for a select listing them, keeping the element id, focus handling and the Test connection flow unchanged. The text field remains the fallback when the fetch fails. Backend validation of the submitted URL is untouched. Mock server serves the endpoint; contract, API and e2e tests cover it.
169 lines
8.2 KiB
HTML
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 & 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">×</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 id="cred-url-hint" 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 & Close</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|