feat(typescript): add feature modules for template conversion
- 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
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user