Ajoute un sélecteur de tags existants dans la modale fiche idée

This commit is contained in:
Etienne Delvarre
2026-06-22 18:12:17 +02:00
parent 16f8bf578c
commit 04b436a9c7
3 changed files with 43 additions and 3 deletions
+36 -1
View File
@@ -428,6 +428,7 @@ function openNew() {
document.getElementById('modal-label').textContent = 'Nouvelle idee';
document.getElementById('f-title').value = '';
renderModalTags(['À étudier']);
updateTagSuggestions();
document.getElementById('f-tags-input').value = '';
document.getElementById('f-acte').value = 'En attente';
document.getElementById('f-resume').value = '';
@@ -452,6 +453,7 @@ function openEdit(id) {
document.getElementById('modal-label').textContent = 'Modifier';
document.getElementById('f-title').value = r.Title || '';
renderModalTags((r.Tags || '').split(',').map(s => s.trim()).filter(Boolean));
updateTagSuggestions();
document.getElementById('f-tags-input').value = '';
document.getElementById('f-acte').value = r.Acte || '';
document.getElementById('f-resume').value = r['Résumé'] || '';
@@ -579,6 +581,38 @@ function getModalTags() {
return [...document.querySelectorAll('#f-tags .tag-chip')].map(c => c.dataset.tag);
}
function collectExistingTags() {
const tagSet = new Set();
records.forEach(r => {
if (r.Tags) r.Tags.split(',').forEach(t => { const trimmed = t.trim(); if (trimmed) tagSet.add(trimmed); });
});
return [...tagSet].sort((a, b) => a.localeCompare(b, 'fr'));
}
function updateTagSuggestions() {
const select = document.getElementById('f-tags-select');
const current = getModalTags();
const existing = collectExistingTags().filter(t => !current.includes(t));
select.innerHTML = '<option value="">Tags existants...</option>';
existing.forEach(t => {
const opt = document.createElement('option');
opt.value = t; opt.textContent = t;
select.appendChild(opt);
});
}
function addExistingTag() {
const select = document.getElementById('f-tags-select');
const val = select.value;
if (!val) return;
const current = getModalTags();
if (!current.includes(val)) {
renderModalTags([...current, val]);
}
select.value = '';
updateTagSuggestions();
}
function renderModalTags(tags) {
const container = document.getElementById('f-tags');
container.querySelectorAll('.tag-chip').forEach(c => c.remove());
@@ -587,7 +621,7 @@ function renderModalTags(tags) {
const chip = document.createElement('span');
chip.className = 'tag-chip';
chip.dataset.tag = tag;
chip.innerHTML = `${esc(tag)}<span class="tag-chip-remove" onclick="this.parentElement.remove()">&times;</span>`;
chip.innerHTML = `${esc(tag)}<span class="tag-chip-remove" onclick="this.parentElement.remove(); updateTagSuggestions();">&times;</span>`;
container.insertBefore(chip, input);
});
}
@@ -601,6 +635,7 @@ function addTag() {
renderModalTags([...current, val]);
}
input.value = '';
updateTagSuggestions();
}
document.getElementById('modal').addEventListener('click', e => {
+4 -1
View File
@@ -256,7 +256,10 @@ window.dispatchEvent(new Event('tiptap-loaded'));
<div class="field">
<label>Tags</label>
<div class="tags-input-container" id="f-tags">
<input type="text" class="tags-input" id="f-tags-input" placeholder="Ajouter un tag..." onkeydown="if(event.key==='Enter'){event.preventDefault();addTag()}">
<input type="text" class="tags-input" id="f-tags-input" placeholder="Ajouter un tag..." onkeydown="if(event.key==='Enter'){event.preventDefault();addTag()}" oninput="updateTagSuggestions()" onfocus="updateTagSuggestions()">
<select class="tags-existing-select" id="f-tags-select" onchange="addExistingTag()">
<option value="">Tags existants...</option>
</select>
</div>
</div>
<div class="field-row">
+3 -1
View File
@@ -196,7 +196,9 @@
.tags-input-container { display: flex; flex-wrap: wrap; gap: 6px; padding: 6px 8px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-input); align-items: center; min-height: 36px; }
.tags-input-container:focus-within { border-color: var(--accent); }
.tags-input { border: none; outline: none; font-size: 13px; font-family: 'Lora', serif; color: var(--text); background: transparent; flex: 1; min-width: 80px; padding: 2px 0; }
.tag-chip { display: inline-flex; align-items: center; gap: 4px; padding: 3px 8px; background: #ede8e0; color: #6b5a4a; border-radius: 6px; font-size: 12px; font-family: 'Lora', serif; }
.tags-existing-select { border: none; outline: none; font-size: 12px; font-family: 'Lora', serif; color: var(--text-muted); background: transparent; cursor: pointer; padding: 2px 8px; border-left: 1px dashed var(--border); }
.tags-existing-select:focus { color: var(--text); }
.tags-input-container .tag-chip { display: inline-flex; align-items: center; gap: 4px; padding: 3px 8px; background: #ede8e0; color: #6b5a4a; border-radius: 6px; font-size: 12px; font-family: 'Lora', serif; }
.dark .tag-chip { background: #3a3020; color: #c4a870; }
.tag-chip-remove { cursor: pointer; font-size: 14px; line-height: 1; opacity: 0.6; }
.tag-chip-remove:hover { opacity: 1; }