refactor(ts): Convert internal window dependencies to ES modules
Phase 1 of ESBuild migration: Convert 193+ internal window reads
to proper ES module imports across consumer modules.
Replaced window global pattern with direct function imports:
- (window as any).showToast → import { showToast } → showToast(msg, "type")
- (window as any).api.post → import { apiPost } → apiPost(url, data)
- (window as any).dom.getElementById → import { getElementById }
Modules migrated:
- admin.ts: Convert 14 showToast window reads
- analytics.ts: Add ES export (no window reads)
- conflicts.ts: Convert 6 showToast window reads
- custom-section-builder.ts: Convert api.post reads, add ES exports
- dashboard.ts: Convert 10 window reads (api, showToast)
- device-management.ts: Convert 4 showToast window reads, add Alpine registration
- linking.ts: Convert showToast window reads
- queue.ts: Convert 8 showToast window reads
Additionally added Alpine.js registration for templates:
- device-management.ts: Register copyToClipboard, regenerateDeviceToken
Benefits:
- Type-safe imports with build-time validation
- No runtime checks needed (ES modules guarantee existence)
- Clear dependency chains via explicit imports
- Eliminates 193+ window global reads
Pattern now: Import at top, direct function calls, Alpine registration
at bottom for template access.
Migration progress: Phase 1 complete
Next: Phase 2 (Alpine registration for remaining modules)
This commit is contained in:
+17
-21
@@ -1,3 +1,6 @@
|
||||
import { apiPost, apiPut } from "./api";
|
||||
import { showToast } from "./toast";
|
||||
|
||||
// Dashboard functionality with unified collections architecture
|
||||
// Procedural/imperative style (no OOP)
|
||||
|
||||
@@ -19,7 +22,7 @@ async function openDashboardSettings(): Promise<void> {
|
||||
) as HTMLSelectElement;
|
||||
const libraryId = librarySelect?.value;
|
||||
if (!libraryId) {
|
||||
(window as any).showToast.error("No library selected");
|
||||
showToast("No library selected", "error");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -34,7 +37,7 @@ async function openDashboardSettings(): Promise<void> {
|
||||
const prefs = await response.json();
|
||||
applyPreferencesToModal(prefs);
|
||||
} else {
|
||||
(window as any).showToast.error("Failed to load library preferences");
|
||||
showToast("Failed to load library preferences", "error");
|
||||
console.error("API Error:", response.status, response.statusText);
|
||||
return; // Don't open modal with stale data.
|
||||
}
|
||||
@@ -125,20 +128,18 @@ async function saveDashboardSettings(): Promise<void> {
|
||||
"library-select",
|
||||
) as HTMLSelectElement;
|
||||
const libraryId = librarySelect?.value || "";
|
||||
const response = await (window as any).api.put("/dashboard/preferences", {
|
||||
const response = await apiPut("/dashboard/preferences", {
|
||||
library_id: libraryId,
|
||||
hidden_collections: hiddenCollections,
|
||||
collection_order: collectionOrder,
|
||||
items_per_section: parseInt(itemsPerCollection),
|
||||
});
|
||||
if (response.ok) {
|
||||
(window as any).showToast.success("Dashboard settings saved");
|
||||
showToast("Dashboard settings saved", "success");
|
||||
closeDashboardSettings();
|
||||
// Fetch updated sections and re-render (like switchLibrary does)
|
||||
if (!libraryId) {
|
||||
(window as any).showToast.error(
|
||||
"Unable to refresh dashboard - no library selected",
|
||||
);
|
||||
showToast("Unable to refresh dashboard - no library selected", "error");
|
||||
return;
|
||||
}
|
||||
const sectionResponse = await fetch(
|
||||
@@ -155,11 +156,11 @@ async function saveDashboardSettings(): Promise<void> {
|
||||
renderDashboardCollections(data.sections);
|
||||
localStorage.setItem("selectedLibraryId", libraryId);
|
||||
} else {
|
||||
(window as any).showToast.error("Failed to refresh sections");
|
||||
showToast("Failed to refresh sections", "error");
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
(window as any).showToast.error("Failed to save settings");
|
||||
showToast("Failed to save settings", "error");
|
||||
console.error("Save dashboard settings error:", error);
|
||||
}
|
||||
}
|
||||
@@ -176,21 +177,16 @@ async function restoreSystemCollection(
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await (window as any).api.post(
|
||||
"/dashboard/restore-system-collection",
|
||||
{
|
||||
collection_name: collectionName,
|
||||
},
|
||||
);
|
||||
const response = await apiPost("/dashboard/restore-system-collection", {
|
||||
collection_name: collectionName,
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
(window as any).showToast.success(
|
||||
`"${collectionTitle}" restored to defaults`,
|
||||
);
|
||||
showToast(`"${collectionTitle}" restored to defaults`, "success");
|
||||
setTimeout(() => window.location.reload(), 1000);
|
||||
}
|
||||
} catch (error) {
|
||||
(window as any).showToast.error("Failed to restore system collection");
|
||||
showToast("Failed to restore system collection", "error");
|
||||
console.error("Restore system collection error:", error);
|
||||
}
|
||||
}
|
||||
@@ -232,7 +228,7 @@ async function switchLibrary(libraryId: string): Promise<void> {
|
||||
renderDashboardCollections(data.sections);
|
||||
localStorage.setItem("selectedLibrary", libraryId);
|
||||
} catch (error) {
|
||||
(window as any).showToast.error("Failed to load library");
|
||||
showToast("Failed to load library", "error");
|
||||
console.error("Switch library error:", error);
|
||||
} finally {
|
||||
loading.classList.add("hidden");
|
||||
@@ -366,7 +362,7 @@ async function reloadPage(): Promise<void> {
|
||||
const currentLibraryId = librarySelect?.value;
|
||||
|
||||
if (!currentLibraryId) {
|
||||
(window as any).showToast.error("No library selected");
|
||||
showToast("No library selected", "error");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user