(file)
| 15611 | const model = await window.electron.getModel(filePath); |
| 15612 | return model && model.tags ? (Array.isArray(model.tags) ? model.tags : []) : []; |
| 15613 | } catch (error) { |
| 15614 | console.error(`Error loading tags for ${filePath}:`, error); |
| 15615 | return []; |
| 15616 | } |
| 15617 | }); |
| 15618 | |
| 15619 | const allTagsArrays = await Promise.all(tagPromises); |
| 15620 | |
| 15621 | // Collect unique tags across all selected files |
| 15622 | const uniqueTags = new Set(); |
| 15623 | allTagsArrays.forEach(tags => { |
| 15624 | if (Array.isArray(tags)) { |
| 15625 | tags.forEach(tag => { |
| 15626 | if (tag && typeof tag === 'string') { |
| 15627 | const normalizedTag = tag.trim(); |
| 15628 | if (normalizedTag) { |
| 15629 | uniqueTags.add(normalizedTag); |
| 15630 | } |
| 15631 | } |
| 15632 | }); |
| 15633 | } |
| 15634 | }); |
| 15635 | |
| 15636 | // Sort tags alphabetically |
| 15637 | const sortedTags = Array.from(uniqueTags).sort((a, b) => a.localeCompare(b)); |
| 15638 | |
| 15639 | // Display tags in the container with remove functionality |
| 15640 | sortedTags.forEach(tagName => { |
| 15641 | // Check if tag already exists visually |
| 15642 | const existingTag = Array.from(multiTagsContainer.children) |
| 15643 | .find(tag => tag.getAttribute('data-tag-name') === tagName); |
| 15644 | |
| 15645 | if (!existingTag) { |
| 15646 | // Create tag element with remove functionality |
| 15647 | const tag = document.createElement('div'); |
| 15648 | tag.className = 'tag'; |
| 15649 | tag.setAttribute('data-tag-name', tagName); |
| 15650 | tag.setAttribute('title', tagName); |
| 15651 | tag.innerHTML = ` |
| 15652 | <span class="tag-text">${tagName}</span> |
| 15653 | <span class="tag-remove">×</span> |
| 15654 | `; |
| 15655 | |
| 15656 | // Add remove handler with auto-save |
| 15657 | tag.querySelector('.tag-remove')?.addEventListener('click', async () => { |
| 15658 | tag.remove(); |
| 15659 | // Auto-save the updated tags after REMOVAL |
| 15660 | const currentTags = Array.from(multiTagsContainer.querySelectorAll('.tag')) |
| 15661 | .map(t => t.getAttribute('data-tag-name')); |
| 15662 | |
| 15663 | // Use replaceTags: true to replace tags instead of merging |
| 15664 | await autoSaveMultipleModels('tags', currentTags, { replaceTags: true }); |
| 15665 | |
| 15666 | // Refresh the remove tag dropdown after removal |
| 15667 | await populateRemoveTagSelect(); |
| 15668 | }); |
| 15669 | |
| 15670 | multiTagsContainer.appendChild(tag); |
no test coverage detected