feat(ui): persist library selection across page navigation
Save the selected library to localStorage when the user changes the dropdown on the bookshelf page, and restore it on every page load via a new restoreLibrarySelection() call in the header Alpine component. This ensures that when a user navigates between dashboard, bookshelf, collections, etc., their last-chosen library filter is automatically re-applied rather than resetting to the default. Changes: - web/src/bookshelf.ts: listen for change events on #library-select and persist the value to localStorage - web/src/header.ts: add restoreLibrarySelection() which checks localStorage and sets the matching dropdown option on page load - templates/header.templ: call restoreLibrarySelection() in x-init - templates/header_templ.go: regenerated from templ source
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
package templates
|
package templates
|
||||||
|
|
||||||
templ Header(user User, currentPath string) {
|
templ Header(user User, currentPath string) {
|
||||||
<nav x-data="header" x-init="initializeSearch(); initializeTheme(); loadWoodPaneling(); updateWoodPanelingIndicators()" class="border-b header-nav" style="border-color: var(--border); background-color: var(--bg-secondary);">
|
<nav x-data="header" x-init="initializeSearch(); initializeTheme(); loadWoodPaneling(); updateWoodPanelingIndicators(); restoreLibrarySelection()" class="border-b header-nav" style="border-color: var(--border); background-color: var(--bg-secondary);">
|
||||||
<div x-data="{}" x-init="console.log('Alpine is working!', $el)"></div>
|
<div x-data="{}" x-init="console.log('Alpine is working!', $el)"></div>
|
||||||
<div class="w-full px-4 sm:px-6 lg:px-8">
|
<div class="w-full px-4 sm:px-6 lg:px-8">
|
||||||
<div class="flex justify-between items-center h-16">
|
<div class="flex justify-between items-center h-16">
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -415,6 +415,9 @@ function initBookshelf(): void {
|
|||||||
const librarySelect = document.getElementById(
|
const librarySelect = document.getElementById(
|
||||||
"library-select",
|
"library-select",
|
||||||
) as HTMLSelectElement;
|
) as HTMLSelectElement;
|
||||||
|
librarySelect?.addEventListener("change", () => {
|
||||||
|
localStorage.setItem("selectedLibrary", librarySelect.value);
|
||||||
|
});
|
||||||
if (librarySelect && librarySelect.value) {
|
if (librarySelect && librarySelect.value) {
|
||||||
const filterForm = document.getElementById(
|
const filterForm = document.getElementById(
|
||||||
"filter-form",
|
"filter-form",
|
||||||
|
|||||||
+30
-1
@@ -9,6 +9,7 @@ import {
|
|||||||
loadWoodPaneling,
|
loadWoodPaneling,
|
||||||
updateWoodPanelingIndicators,
|
updateWoodPanelingIndicators,
|
||||||
} from "./theme";
|
} from "./theme";
|
||||||
|
import { getSelectedLibrary } from "./storage";
|
||||||
|
|
||||||
const logout = (): void => {
|
const logout = (): void => {
|
||||||
localStorage.removeItem("token");
|
localStorage.removeItem("token");
|
||||||
@@ -16,7 +17,34 @@ const logout = (): void => {
|
|||||||
window.location.href = "/";
|
window.location.href = "/";
|
||||||
};
|
};
|
||||||
|
|
||||||
export { logout };
|
// Looks for saved library in localStorage and selects it in current page's dropdown
|
||||||
|
const restoreLibrarySelection = (): void => {
|
||||||
|
const savedLibrary = getSelectedLibrary();
|
||||||
|
if (!savedLibrary) return;
|
||||||
|
|
||||||
|
// Common library dropdown IDs across pages
|
||||||
|
const dropdownSelectors = [
|
||||||
|
"#library-select", // dashboard, bookshelf
|
||||||
|
"#selected-library", // alternate naming
|
||||||
|
"#library_id", // form field
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const selector of dropdownSelectors) {
|
||||||
|
const dropdown = document.querySelector(selector) as HTMLSelectElement;
|
||||||
|
if (dropdown) {
|
||||||
|
const option = dropdown.querySelector(`option[value="${savedLibrary}"]`);
|
||||||
|
if (option) {
|
||||||
|
dropdown.value = savedLibrary;
|
||||||
|
// Trigger any htmx/change handlers
|
||||||
|
dropdown.dispatchEvent(new Event("change", { bubbles: true }));
|
||||||
|
console.log("Restored library selection:", savedLibrary);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export { logout, restoreLibrarySelection };
|
||||||
|
|
||||||
Alpine.data("header", () => ({
|
Alpine.data("header", () => ({
|
||||||
logout,
|
logout,
|
||||||
@@ -26,4 +54,5 @@ Alpine.data("header", () => ({
|
|||||||
changeWoodPaneling,
|
changeWoodPaneling,
|
||||||
loadWoodPaneling,
|
loadWoodPaneling,
|
||||||
updateWoodPanelingIndicators,
|
updateWoodPanelingIndicators,
|
||||||
|
restoreLibrarySelection,
|
||||||
}));
|
}));
|
||||||
|
|||||||
Reference in New Issue
Block a user