feat(library): tags + tag filtering, monochrome icons; fix live tag updates

- library: expose page tags (batch), render tag chips per row and add a tag
  filter bar; register tag create/associate/remove in the shared context menu
  exactly like local-workspace
- library: restore monochrome SVG icons (folder/edit/image/file) matching
  local-workspace, with optional custom page_icon
- workspace: refresh tag chips/filter live on tag add/remove (reassign arrays
  + tagsVersion) instead of requiring a page reload
- ctxmenu: measure the rendered menu and clamp it to the viewport on open
This commit is contained in:
2026-09-11 22:33:37 -04:00
parent c36082be6a
commit 881c3e3e0a
4 changed files with 198 additions and 32 deletions
+17 -10
View File
@@ -532,6 +532,7 @@ window._wsInitData = (function() {
workspaceTags: [],
tagFilter: '',
tagInputId: null,
tagsVersion: 0,
// Preview panel
previewItem: null,
@@ -1158,11 +1159,13 @@ window._wsInitData = (function() {
});
if (r.ok) {
var d = await r.json();
if (!node.tags) node.tags = [];
if (!node.tags.some(function(t) { return t.id === d.tag.id; })) node.tags.push(d.tag);
var cur = node.tags || [];
if (!cur.some(function(t) { return t.id === d.tag.id; })) node.tags = cur.concat([d.tag]);
this._updateNodeTags(this.tree, node.id, d.tag, 'add');
this.displayTree = [...this.tree];
this.loadWorkspaceTags();
this.tagsVersion++;
await this.loadWorkspaceTags();
this._computeFilteredTableItems();
this._ctxRefreshAvail();
}
} catch(e) {}
@@ -2241,7 +2244,9 @@ window._wsInitData = (function() {
// Update node tags in tree
this._updateNodeTags(this.tree, itemId, d.tag, 'add');
this.displayTree = [...this.tree];
this.loadWorkspaceTags();
this.tagsVersion++;
await this.loadWorkspaceTags();
this._computeFilteredTableItems();
}
} catch(e) {}
this.tagInputId = null;
@@ -2255,7 +2260,9 @@ window._wsInitData = (function() {
if (r.ok) {
this._updateNodeTags(this.tree, itemId, null, 'remove', tagId);
this.displayTree = [...this.tree];
this.loadWorkspaceTags();
this.tagsVersion++;
await this.loadWorkspaceTags();
this._computeFilteredTableItems();
}
} catch(e) {}
},
@@ -2264,10 +2271,10 @@ window._wsInitData = (function() {
for (var i=0; i<nodes.length; i++) {
if (nodes[i].id === itemId) {
if (action === 'add') {
if (!nodes[i].tags) nodes[i].tags = [];
// Avoid duplicates
if (!nodes[i].tags.some(function(t) { return t.id === tag.id; })) {
nodes[i].tags.push(tag);
// Réassigne un nouveau tableau → déclenche la réactivité Alpine
var cur = nodes[i].tags || [];
if (!cur.some(function(t) { return t.id === tag.id; })) {
nodes[i].tags = cur.concat([tag]);
}
} else if (action === 'remove') {
nodes[i].tags = (nodes[i].tags || []).filter(function(t) { return t.id !== removeTagId; });
@@ -2682,7 +2689,7 @@ console.log('FLOWDECK v2.4.6 — IIFE done, _wsInitData keys:', Object.keys(wind
</div>
<!-- Children -->
<ul class="ws-tree" x-show="expanded[node.id]" x-transition
x-html="renderChildren(node.children, (node.depth||0)+1)">
x-html="renderChildren(node.children, (node.depth||0)+1, tagsVersion)">
</ul>
</li>
</template>