feat: menu contextuel — sous-menu 'Add existing tag' + 'New tag' pliables
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped

- 📋 Add existing tag: item cliquable qui déplie la liste des tags configurés
  avec pastilles de couleur, noms et compteurs. Clic sur un tag → ajout + repli
- ➕ New tag: item cliquable qui déplie palette couleurs + input texte
- Chevrons ▸/▾ indiquent l'état ouvert/fermé
- ctxTagExistingOpen state réinitialisé à chaque ouverture du menu
- Les tags déjà assignés restent visibles en haut avec ✕ pour retirer
This commit is contained in:
2026-07-12 15:44:37 -04:00
parent 97eda84cd1
commit 1f31e33b69
+14 -8
View File
@@ -784,21 +784,25 @@
</div> </div>
</template> </template>
<div x-show="(ctxMenu.tags||[]).length === 0" style="padding:2px 14px;font-size:11px;color:var(--text-dim);">No tags</div> <div x-show="(ctxMenu.tags||[]).length === 0" style="padding:2px 14px;font-size:11px;color:var(--text-dim);">No tags</div>
<div class="ctx-sep" x-show="ctxAvailTags.length > 0"></div> <div class="ctx-sep"></div>
<!-- Available tags to add --> <!-- Add existing tag → sub-menu -->
<div x-show="ctxAvailTags.length > 0" style="padding:0 0 4px;"> <div class="ctx-item ctx-has-sub" @click.stop="ctxTagExistingOpen=!ctxTagExistingOpen" x-show="ctxAvailTags.length > 0">
<div style="padding:2px 14px;font-size:11px;color:var(--text-dim);">Add tag:</div> <span style="flex:1;">📋 Add existing tag</span>
<span x-text="ctxTagExistingOpen ? '▾' : '▸'"></span>
</div>
<div x-show="ctxTagExistingOpen && ctxAvailTags.length > 0" style="padding:0 0 4px;background:var(--bg-tertiary);border-radius:6px;margin:2px 6px;">
<template x-for="t in ctxAvailTags" :key="'ctx-avail'+t.id"> <template x-for="t in ctxAvailTags" :key="'ctx-avail'+t.id">
<div class="ctx-item ctx-add-tag-item" @click.stop="ctxAddExistingTag(t)"> <div class="ctx-item ctx-add-tag-item" @click.stop="ctxAddExistingTag(t); ctxTagExistingOpen=false">
<span class="ctx-tag-color" :style="{background: t.color}"></span> <span class="ctx-tag-color" :style="{background: t.color}"></span>
<span style="flex:1;font-size:13px;" x-text="t.name"></span> <span style="flex:1;font-size:13px;" x-text="t.name"></span>
<span style="font-size:10px;color:var(--text-dim);" x-text="t.count||''"></span> <span style="font-size:10px;color:var(--text-dim);" x-text="t.count||''"></span>
</div> </div>
</template> </template>
</div> </div>
<div class="ctx-tag-add" x-show="!ctxTagAdding" @click.stop="ctxTagAdding=true"> <!-- Create new tag -->
<span class="ctx-tag-color" style="background:var(--bg-tertiary);border:1px dashed var(--border);"></span> <div class="ctx-item ctx-has-sub" @click.stop="ctxTagAdding=!ctxTagAdding">
+ New tag <span style="flex:1;">➕ New tag</span>
<span x-text="ctxTagAdding ? '▾' : '▸'"></span>
</div> </div>
<div x-show="ctxTagAdding" style="display:flex;align-items:center;gap:4px;padding:4px 14px;"> <div x-show="ctxTagAdding" style="display:flex;align-items:center;gap:4px;padding:4px 14px;">
<template x-for="c in ctxTagColors" :key="c"> <template x-for="c in ctxTagColors" :key="c">
@@ -899,6 +903,7 @@ document.addEventListener('alpine:init', function() {
// Context menu // Context menu
ctxMenu: {visible:false,x:0,y:0,node:null,tags:[]}, ctxMenu: {visible:false,x:0,y:0,node:null,tags:[]},
ctxTagAdding: false, ctxTagAdding: false,
ctxTagExistingOpen: false,
ctxAvailTags: [], ctxAvailTags: [],
ctxNewTagColor: '#787774', ctxNewTagColor: '#787774',
ctxTagColors: ['#787774','#E03E3E','#D9730D','#DFAB01','#0F7B6C','#0B6E99','#6940A5','#AD1A72','#E16259','#D4A72C','#448361','#337EA9','#9065B0','#C94D8B'], ctxTagColors: ['#787774','#E03E3E','#D9730D','#DFAB01','#0F7B6C','#0B6E99','#6940A5','#AD1A72','#E16259','#D4A72C','#448361','#337EA9','#9065B0','#C94D8B'],
@@ -1263,6 +1268,7 @@ document.addEventListener('alpine:init', function() {
tags: [...(node.tags||[])] tags: [...(node.tags||[])]
}; };
this.ctxTagAdding = false; this.ctxTagAdding = false;
this.ctxTagExistingOpen = false;
this.ctxNewTagColor = '#787774'; this.ctxNewTagColor = '#787774';
// Load available tags (not already on the item) // Load available tags (not already on the item)
this.ctxAvailTags = (this.workspaceTags || []).filter(function(t) { this.ctxAvailTags = (this.workspaceTags || []).filter(function(t) {