refactor(alpine): migrate remaining pages to x-init declarative initialization

- Remove DOMContentLoaded event listeners from analytics.ts and docs.ts
- Rely on x-init attribute in templates for page initialization
- Clean up unused exports from collections.ts Alpine data
- Add x-init calls to admin_library, analytics, and docs templates
- Normalize quote style in collections WebSocket script (single to double)
- Disable Add Books button in collection detail (pending implementation)
This commit is contained in:
2026-03-12 18:13:12 -04:00
parent 75c454b661
commit 06461a3202
11 changed files with 58 additions and 88 deletions
+36 -32
View File
@@ -18,69 +18,74 @@ templ Collection(user User, collections []CollectionData, errorMessage string) {
let libraryId = null;
function connectWebSocket() {
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const protocol =
window.location.protocol === "https:" ? "wss:" : "ws:";
const wsUrl = `${protocol}//${window.location.host}/ws/sync?token={ user.Token }`;
ws = new WebSocket(wsUrl);
ws.onopen = function() {
console.log('WebSocket connected');
ws.onopen = function () {
console.log("WebSocket connected");
};
ws.onmessage = function(event) {
ws.onmessage = function (event) {
try {
const message = JSON.parse(event.data);
if (message.type === 'collection_updated' && message.data.collection_id === collectionId) {
const actionText = message.data.action === 'books_added'
? `Added ${message.data.count || 0} book(s)`
: message.data.action === 'book_removed'
? 'Removed a book'
: message.data.action === 'books_bulk_removed'
? `Removed ${message.data.count || 0} book(s)`
: 'Collection updated';
if (
message.type === "collection_updated" &&
message.data.collection_id === collectionId
) {
const actionText =
message.data.action === "books_added"
? `Added ${message.data.count || 0} book(s)`
: message.data.action === "book_removed"
? "Removed a book"
: message.data.action === "books_bulk_removed"
? `Removed ${message.data.count || 0} book(s)`
: "Collection updated";
// Show toast notification
if (window.showToast) {
window.showToast(actionText, 'info');
window.showToast(actionText, "info");
}
// Check if user is actively typing
const activeElement = document.activeElement;
const isUserActive = activeElement && (
activeElement.tagName === 'INPUT' ||
activeElement.tagName === 'TEXTAREA' ||
activeElement.tagName === 'SELECT' ||
activeElement.getAttribute('contenteditable') === 'true'
);
const isUserActive =
activeElement &&
(activeElement.tagName === "INPUT" ||
activeElement.tagName === "TEXTAREA" ||
activeElement.tagName === "SELECT" ||
activeElement.getAttribute("contenteditable") === "true");
if (!isUserActive) {
setTimeout(function() {
setTimeout(function () {
location.reload();
}, 1000);
} else {
console.log('User actively typing - skipping auto-reload');
console.log("User actively typing - skipping auto-reload");
}
}
} catch (error) {
console.error('Failed to parse WebSocket message:', error);
console.error("Failed to parse WebSocket message:", error);
}
};
ws.onclose = function() {
console.log('WebSocket disconnected, reconnecting in 5s...');
ws.onclose = function () {
console.log("WebSocket disconnected, reconnecting in 5s...");
setTimeout(connectWebSocket, 5000);
};
ws.onerror = function(error) {
console.error('WebSocket error:', error);
ws.onerror = function (error) {
console.error("WebSocket error:", error);
};
}
document.addEventListener('DOMContentLoaded', function() {
document.addEventListener("DOMContentLoaded", function () {
// Get collection and library IDs from data attributes
const dataEl = document.getElementById('collection-data');
const dataEl = document.getElementById("collection-data");
if (dataEl) {
collectionId = dataEl.dataset.id || '';
libraryId = dataEl.dataset.libraryId || '';
collectionId = dataEl.dataset.id || "";
libraryId = dataEl.dataset.libraryId || "";
connectWebSocket();
}
});
@@ -220,13 +225,12 @@ templ CollectionDetail(user User, collection CollectionData, books []handlers.Bo
</div>
<button
id="bulk-remove-btn"
@click="removebooksToAdd"
disabled
class="btn-danger px-4 py-2 rounded-lg disabled:opacity-50 disabled:cursor-not-allowed"
>
🗑️ Remove Selected
</button>
<button @click="showAddBooksModal" class="btn-primary px-4 py-2 rounded-lg">
<button type="button" class="btn-primary px-4 py-2 rounded-lg" style="opacity: 0.5; cursor: not-allowed;" disabled>
Add Books
</button>
</div>