Files
myworkspace/LinkSyncExtension/popup.html
DavidSaylor 09d30427f4 Complete LinkSyncServer and LinkSyncExtension implementation
LinkSyncServer:
- Fix app.py imports, add CORS middleware, lifespan events
- Create api/routes.py router aggregator
- Create config/settings.py for centralized configuration
- Rewrite models/base.py with proper relationships and serialization
- Rewrite all API endpoints with real DB integration (auth, links, collections, sync, queries, tags)
- Add admin endpoints (user management, stats, audit log)
- Complete query parser with recursive descent and proper precedence
- Complete query executor with set operations and field filters
- Set up Alembic migrations with initial schema
- Create web interface (templates, CSS, JS)
- Add 42 passing tests (auth, links, collections, queries)
- Add deploy.ps1 and deploy.sh scripts
- Update README with deployment workflow

LinkSyncExtension:
- Create utils/api.js (REST client with retries, auth, error handling)
- Create utils/sync.js (3 sync modes + conflict detection)
- Create utils/collection.js (collection management)
- Create utils/query-engine.js (client-side query parser)
- Rewrite background.js (sync loop, bookmark events, message routing)
- Rewrite popup.js (tabs, settings modal, notifications, CRUD)
- Update popup.html (tabbed interface, query builder, modal)
- Update popup.css (full redesign)
- Create content/content.js (page metadata extraction)
- Create options.html/js (dedicated settings page)
- Generate icons (48x48, 96x96)
- Update manifest.json (host permissions, content scripts, options)
- Create AGENTS.md
2026-05-19 13:21:26 -05:00

159 lines
6.2 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>LinkSync</title>
<link rel="stylesheet" href="popup.css">
</head>
<body>
<header>
<h1>LinkSync</h1>
<div id="sync-status">
<span id="sync-indicator"></span>
<span id="last-sync">Not synced yet</span>
</div>
</header>
<div id="notification-container"></div>
<!-- Tabs -->
<nav id="tabs">
<button class="tab active" data-tab="bookmarks">Bookmarks</button>
<button class="tab" data-tab="collections">Collections</button>
<button class="tab" data-tab="query">Query</button>
</nav>
<!-- Bookmarks Tab -->
<section id="tab-bookmarks" class="tab-content active">
<section id="bookmark-form">
<h2>Add Bookmark</h2>
<form id="add-bookmark-form">
<div class="form-group">
<label for="url">URL</label>
<input type="url" id="url" placeholder="https://example.com" required>
</div>
<div class="form-group">
<label for="title">Title</label>
<input type="text" id="title" placeholder="Page title">
</div>
<div class="form-group">
<label for="description">Description</label>
<textarea id="description" rows="2" placeholder="Page description"></textarea>
</div>
<div class="form-group">
<label for="notes">Notes</label>
<textarea id="notes" rows="2" placeholder="Your notes"></textarea>
</div>
<div class="form-group">
<label for="tags">Tags</label>
<input type="text" id="tags" placeholder="work, personal, dev">
</div>
<div class="form-group">
<label for="folder">Folder</label>
<input type="text" id="folder" placeholder="path/to/folder">
</div>
<button type="submit" id="submit-btn">Add Bookmark</button>
</form>
</section>
<section id="bookmark-list">
<div id="search-filter">
<input type="text" id="search" placeholder="Search bookmarks...">
</div>
<div id="bookmarks-container">
<p class="empty-state">Loading bookmarks...</p>
</div>
</section>
</section>
<!-- Collections Tab -->
<section id="tab-collections" class="tab-content">
<section id="collections-panel">
<h2>Collections</h2>
<div id="collections-container">
<p class="empty-state">Loading collections...</p>
</div>
</section>
</section>
<!-- Query Tab -->
<section id="tab-query" class="tab-content">
<section id="query-panel">
<h2>Query Builder</h2>
<div class="form-group">
<label for="query-input">Expression</label>
<input type="text" id="query-input" placeholder="('work', 'dev') OR tag:work">
</div>
<div class="query-actions">
<button id="parse-btn" class="btn-small">Parse</button>
<button id="execute-btn" class="btn-small btn-primary">Execute</button>
</div>
<div id="query-result"></div>
<div class="query-help">
<p>Syntax: <code>('term1', 'term2') OR tag:work AND url:example.com</code></p>
<p>Precedence: <code>()</code> &gt; XOR &gt; AND &gt; OR</p>
</div>
</section>
</section>
<footer>
<button id="sync-btn">Sync Now</button>
<button id="settings-btn">Settings</button>
</footer>
<!-- Settings Modal -->
<div id="settings-modal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h2>Settings</h2>
<button id="close-settings" class="close-btn">&times;</button>
</div>
<form id="settings-form">
<div class="form-group">
<label for="server-url">Server URL</label>
<input type="url" id="server-url" placeholder="http://localhost:5000" required>
</div>
<div class="form-group">
<label for="api-key">API Key</label>
<div class="input-with-toggle">
<input type="password" id="api-key" placeholder="Your API key">
<button type="button" id="toggle-key" class="toggle-btn">Show</button>
</div>
</div>
<div class="form-group">
<label for="sync-mode">Sync Mode</label>
<select id="sync-mode">
<option value="bi-directional">Bi-directional</option>
<option value="browser-authoritative">Browser Authoritative</option>
<option value="server-authoritative">Server Authoritative</option>
</select>
</div>
<div class="form-group checkbox-group">
<label>
<input type="checkbox" id="deletions">
Enable deletions
</label>
</div>
<div class="form-group checkbox-group">
<label>
<input type="checkbox" id="auto-sync">
Auto-sync every 5 minutes
</label>
</div>
<div class="settings-actions">
<button type="button" id="test-connection" class="btn-small">Test Connection</button>
<button type="submit" class="btn-primary">Save</button>
</div>
</form>
</div>
</div>
<script src="utils/api.js"></script>
<script src="utils/sync.js"></script>
<script src="utils/collection.js"></script>
<script src="utils/query-engine.js"></script>
<script src="utils/bookmark.js"></script>
<script src="popup.js"></script>
</body>
</html>