- Add search.ts - header search with keyboard navigation - Debounced search with 300ms delay - Arrow key navigation through results - Escape to close, Enter to select - Library type icons and highlighting - Add collections.ts - collection and rule management - Rule CRUD operations (create, update, delete) - Rule testing functionality - Bulk collection operations - Add bookshelf.ts - book display and navigation - Library selection state management - Book viewing interactions - Pagination logic - Add linking.ts - book matching and manual linking - Search and match functionality - Manual link modal - Bulk auto-link and suggestions - Add api-explorer.ts - API testing interface - Request/response display - cURL command generation - History tracking - Add admin.ts - admin dashboard actions - Library scan triggers - System statistics display - Profile management - Add analytics.ts - analytics data loading - Chart.js integration - Daily reading minutes chart - Device usage and popular books display - Add queue.ts - sync queue management - Process pending items - Clear failed/all items - Filter by status, type, device - Add conflicts.ts - conflict resolution - Individual and bulk resolve operations - Winner device selection - Manual override inputs - Add docs.ts - documentation search - Lunr.js search integration - Sidebar toggle for mobile
87 lines
2.9 KiB
TypeScript
87 lines
2.9 KiB
TypeScript
function toggleSidebar(): void {
|
|
const sidebar = document.getElementById('docs-sidebar');
|
|
const overlay = document.getElementById('docs-overlay');
|
|
|
|
if (sidebar && overlay) {
|
|
sidebar.classList.toggle('translate-x-0');
|
|
sidebar.classList.toggle('-translate-x-full');
|
|
overlay.classList.toggle('hidden');
|
|
}
|
|
}
|
|
|
|
function initializeDocsSearch(): void {
|
|
const searchInput = document.getElementById('docs-search') as HTMLInputElement;
|
|
const searchResults = document.getElementById('docs-search-results');
|
|
|
|
if (!searchInput || !searchResults) return;
|
|
|
|
let searchTimeout: ReturnType<typeof setTimeout> | null = null;
|
|
|
|
searchInput.addEventListener('input', () => {
|
|
const query = searchInput.value.trim();
|
|
|
|
if (searchTimeout) {
|
|
clearTimeout(searchTimeout);
|
|
}
|
|
|
|
if (query.length < 2) {
|
|
searchResults.innerHTML = '';
|
|
searchResults.classList.add('hidden');
|
|
return;
|
|
}
|
|
|
|
searchTimeout = setTimeout(() => {
|
|
performDocsSearch(query);
|
|
}, 300);
|
|
});
|
|
}
|
|
|
|
function performDocsSearch(query: string): void {
|
|
const searchResults = document.getElementById('docs-search-results');
|
|
if (!searchResults) return;
|
|
|
|
if (!(window as any).lunr) {
|
|
console.warn('Lunr.js not loaded');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const idx = (window as any).lunrIndex;
|
|
if (!idx) {
|
|
searchResults.innerHTML = '<p class="p-2 text-sm" style="color: var(--text-secondary)">Search index not loaded</p>';
|
|
searchResults.classList.remove('hidden');
|
|
return;
|
|
}
|
|
|
|
const results = idx.search(query);
|
|
|
|
if (results.length === 0) {
|
|
searchResults.innerHTML = '<p class="p-2 text-sm" style="color: var(--text-secondary)">No results found</p>';
|
|
} else {
|
|
searchResults.innerHTML = results.slice(0, 10).map((result: { ref: string }) => {
|
|
const doc = (window as any).docsData?.[result.ref];
|
|
if (!doc) return '';
|
|
|
|
return `
|
|
<a href="${result.ref}" class="block p-2 hover:bg-opacity-50 transition-colors" style="background-color: var(--bg-secondary)">
|
|
<p class="font-medium text-sm" style="color: var(--text-primary)">${doc.title || result.ref}</p>
|
|
${doc.section ? `<p class="text-xs" style="color: var(--text-secondary)">${doc.section}</p>` : ''}
|
|
</a>
|
|
`;
|
|
}).join('');
|
|
}
|
|
|
|
searchResults.classList.remove('hidden');
|
|
} catch (error) {
|
|
console.error('Search error:', error);
|
|
searchResults.innerHTML = '<p class="p-2 text-sm" style="color: var(--text-secondary)">Search error</p>';
|
|
searchResults.classList.remove('hidden');
|
|
}
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
initializeDocsSearch();
|
|
});
|
|
|
|
(window as any).toggleSidebar = toggleSidebar;
|