diff --git a/app/templates/local_workspace.html b/app/templates/local_workspace.html
index 26908ba..4de3b83 100644
--- a/app/templates/local_workspace.html
+++ b/app/templates/local_workspace.html
@@ -341,6 +341,7 @@
@dragleave="onDragLeave($event)"
@drop.prevent="onDrop($event)"
@keydown="onKeydown($event)"
+ @contextmenu.prevent="onContextMenu($event)"
tabindex="0"
x-ref="layout">
@@ -1026,41 +1027,6 @@ document.addEventListener('alpine:init', function() {
var self = this;
window.addEventListener('online', function() { self.online = true; });
window.addEventListener('offline', function() { self.online = false; });
- // Native context menu handler (bypasses Alpine scoping issues)
- self.$el.addEventListener('contextmenu', function(ev) {
- ev.preventDefault();
- var el = ev.target.closest('[data-ws-id]');
- if (!el) { self.ctxMenu.visible = false; return; }
- var id = parseInt(el.getAttribute('data-ws-id'));
- if (!id) { self.ctxMenu.visible = false; return; }
- var node = self._findNodeById(self.displayTree, id);
- if (!node) { self.ctxMenu.visible = false; return; }
- self.ctxMenu.visible = true;
- self.ctxMenu.x = ev.clientX;
- self.ctxMenu.y = ev.clientY;
- self.ctxMenu.node = node;
- self.ctxMenu.tags = [...(node.tags||[])];
- self.ctxTagAdding = false;
- self.ctxTagExistingOpen = false;
- self.ctxNewTagColor = '#787774';
- self.ctxAvailTags = (self.workspaceTags || []).filter(function(t) {
- return !(node.tags||[]).some(function(nt) { return nt.id === t.id; });
- });
- // Reposition after DOM update
- self.$nextTick(function() {
- var menu = self.$el.querySelector('.ctx-menu');
- if (!menu) return;
- var rect = menu.getBoundingClientRect();
- var mx = self.ctxMenu.x;
- var my = self.ctxMenu.y;
- if (mx + rect.width > window.innerWidth - 4) mx = window.innerWidth - rect.width - 4;
- if (my + rect.height > window.innerHeight - 4) my = window.innerHeight - rect.height - 4;
- if (mx < 4) mx = 4;
- if (my < 4) my = 4;
- self.ctxMenu.x = mx;
- self.ctxMenu.y = my;
- });
- });
// Load workspace tags
this.loadWorkspaceTags();
} catch(e) { console.error('Tree load error:', e); this.loaded = true; }
@@ -1293,25 +1259,30 @@ document.addEventListener('alpine:init', function() {
return {};
},
- // ── Context menu (fallback — native handler in init is primary) ──
+ // ── Context menu ──
onContextMenu(ev) {
+ console.log('onContextMenu fired', ev.clientX, ev.clientY);
var el = ev.target.closest('[data-ws-id]');
if (!el) { this.ctxMenu.visible = false; return; }
var id = parseInt(el.getAttribute('data-ws-id'));
if (!id) { this.ctxMenu.visible = false; return; }
var node = this._findNodeById(this.displayTree, id);
if (!node) { this.ctxMenu.visible = false; return; }
- this.ctxMenu.visible = true;
- this.ctxMenu.x = ev.clientX;
- this.ctxMenu.y = ev.clientY;
- this.ctxMenu.node = node;
- this.ctxMenu.tags = [...(node.tags||[])];
+ this.ctxMenu = {
+ visible: true,
+ x: ev.clientX,
+ y: ev.clientY,
+ node: node,
+ tags: [...(node.tags||[])]
+ };
this.ctxTagAdding = false;
this.ctxTagExistingOpen = false;
this.ctxNewTagColor = '#787774';
+ // Load available tags
this.ctxAvailTags = (this.workspaceTags || []).filter(function(t) {
return !(node.tags||[]).some(function(nt) { return nt.id === t.id; });
});
+ // Reposition after DOM update
var self = this;
self.$nextTick(function() {
var menu = self.$el.querySelector('.ctx-menu');