Skip to content

Commit 011cec4

Browse files
sarg3ntclaude
andcommitted
fix: load SortableJS locally via UseLocalAssets pattern
SortableJS was loaded as an ES module from CDN via sortable-loader.js, which was blocked by CSP in local asset mode. This caused "Sortable not loaded!" errors preventing sidebar nav reordering and dashboard editing. - Add SortableJS UMD build to base.templ UseLocalAssets conditional - Remove sortable-loader.js module script from base.templ and dashboard_editor.templ - Simplify editor.js Sortable check (no longer needs async event listener) - Add SortableJS to Makefile dev-assets download target Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 9f943d5 commit 011cec4

4 files changed

Lines changed: 7 additions & 12 deletions

File tree

gearbox/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ dev-assets: ## Download CDN assets locally for secure development (CSP-compliant
103103
@curl -fsSL https://cdn.jsdelivr.net/npm/chartjs-plugin-zoom@2.0.1/dist/chartjs-plugin-zoom.min.js -o static/js/vendor/chartjs-plugin-zoom.min.js
104104
@echo " → D3.js..."
105105
@curl -fsSL https://d3js.org/d3.v7.min.js -o static/js/vendor/d3.v7.min.js
106+
@echo " → SortableJS..."
107+
@curl -fsSL https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.js -o static/js/vendor/sortable.min.js
106108
@echo " → Tabulator CSS..."
107109
@curl -fsSL https://unpkg.com/tabulator-tables@6.3.0/dist/css/tabulator.min.css -o static/css/vendor/tabulator.min.css
108110
@echo " → Tabulator JS..."

gearbox/internal/framework/templates/layouts/base.templ

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ templ Base(title string, user *models.User, currentPath ...string) {
8686
<script src="/static/js/vendor/chartjs-plugin-zoom.min.js"></script>
8787
<link rel="stylesheet" href="/static/css/vendor/tabulator.min.css"/>
8888
<script src="/static/js/vendor/tabulator.min.js"></script>
89+
<script src="/static/js/vendor/sortable.min.js"></script>
8990
} else {
9091
<!-- CDN JavaScript libraries -->
9192
<script src="https://unpkg.com/htmx.org@1.9.10/dist/htmx.min.js"></script>
@@ -95,6 +96,7 @@ templ Base(title string, user *models.User, currentPath ...string) {
9596
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-zoom@2.0.1/dist/chartjs-plugin-zoom.min.js"></script>
9697
<link rel="stylesheet" href="https://unpkg.com/tabulator-tables@6.3.0/dist/css/tabulator.min.css"/>
9798
<script src="https://unpkg.com/tabulator-tables@6.3.0/dist/js/tabulator.min.js"></script>
99+
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.js"></script>
98100
}
99101
<style>
100102
/* Base styles */
@@ -810,8 +812,6 @@ templ Base(title string, user *models.User, currentPath ...string) {
810812
<script src="/static/js/utils/api.js" defer></script>
811813
<script src="/static/js/common/page-header.js" defer></script>
812814
<script src="/static/js/common/box-selector.js" defer></script>
813-
<!-- Sortable.js for sidebar nav reordering -->
814-
<script type="module" src="/static/js/dashboard/sortable-loader.js"></script>
815815
</head>
816816
<body class="h-full bg-gray-100 dark:bg-slate-900">
817817
@ui.CollapsibleRestoreScript()

gearbox/internal/framework/templates/pages/dashboard_editor.templ

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -384,8 +384,6 @@ templ WidgetConfigModal() {
384384

385385
// DashboardEditorScript provides the editor JavaScript
386386
templ DashboardEditorScript(dash *dashboard.Dashboard) {
387-
<!-- Load Sortable.js module -->
388-
<script type="module" src="/static/js/dashboard/sortable-loader.js"></script>
389387
<!-- Load widget palette logic -->
390388
<script src="/static/js/dashboard/palette.js" defer></script>
391389
<!-- Load dashboard editor logic -->

gearbox/static/js/dashboard/editor.js

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,11 @@ document.addEventListener('DOMContentLoaded', function() {
2727
}
2828
}
2929

30-
// Wait for Sortable module to load before injecting controls
31-
if (window.sortableReady) {
32-
console.log('Sortable already loaded, initializing controls');
30+
// Initialize controls — Sortable is loaded globally via base.templ
31+
if (typeof window.Sortable !== 'undefined') {
3332
injectEditControls();
3433
} else {
35-
console.log('Waiting for Sortable to load...');
36-
window.addEventListener('sortable-loaded', function() {
37-
console.log('Sortable loaded event received, initializing controls');
38-
injectEditControls();
39-
});
34+
console.error('Sortable not loaded! Dashboard editor drag-and-drop will not work.');
4035
}
4136
});
4237

0 commit comments

Comments
 (0)