diff --git a/src/AnnotationControl/annotationPanel.js b/src/AnnotationControl/annotationPanel.js index 1ccd379..3d47f8e 100644 --- a/src/AnnotationControl/annotationPanel.js +++ b/src/AnnotationControl/annotationPanel.js @@ -68,6 +68,41 @@ export function initAnnotationsPanel(viewer) { if (v.x != null && v.y != null && v.z != null) return [v.x, v.y, v.z] return null } + // Monotonic numbering: assign an increasing number to each UUID and never reuse numbers. + // Stored in-memory for the session; later we can persist to a file. + const _uuidToIndex = new Map() + let _nextIndex = 1 + + function _ensureIndexForUUID(uuid) { + if (!uuid) return null + if (!_uuidToIndex.has(uuid)) { + _uuidToIndex.set(uuid, _nextIndex++) + } + return _uuidToIndex.get(uuid) + } + + function _renameJSTreeNode(nodeId, text) { + try { + if (window.$ && $.jstree) { + if ($.jstree.reference) { + const ref = $.jstree.reference(nodeId) + if (ref && typeof ref.rename_node === 'function') { + ref.rename_node(nodeId, text) + return + } + } + // fallback to global selector + if ($('#jstree_scene') && $('#jstree_scene').jstree) { + try { + $('#jstree_scene').jstree('rename_node', nodeId, text) + return + } catch (e) {} + } + } + } catch (e) { + // ignore rename failures + } + } function updateAnnotationsList() { // Implementation for listing annotations targetContainer.innerHTML = '' @@ -86,12 +121,33 @@ export function initAnnotationsPanel(viewer) { targetContainer.appendChild(empty) return } + // Assign monotonic indices for any node UUIDs encountered and rename unlabeled nodes + try { + const items = (annotationsRoot.children || []).map((n) => ({ data: n.data || {}, node: n })) + for (const it of items) { + const uuid = (it.data && it.data.uuid) || null + if (!uuid) continue + const idx = _ensureIndexForUUID(uuid) + const text = (it.node && it.node.text) || '' + const shouldRename = !text || text.trim() === '' || text === 'Unnamed' || text === 'Annotation Title' + if (shouldRename && idx != null) { + const newName = `Annotation #${idx}` + _renameJSTreeNode(it.node.id, newName) + it.node.text = newName + } + } + } catch (e) { + // ignore failures; we just won't rename nodes in that case + } + + // Build list entries for each annotation node annotationsRoot.children.forEach((node) => { + const row = document.createElement('div') row.className = 'annotation-row' - const label = document.createElement('span') - label.textContent = node.text || 'Unnamed' + const label = document.createElement('span') + label.textContent = node.text || 'Unnamed' label.className = 'annotation-label' // Jump button