83 lines
2.9 KiB
JavaScript
83 lines
2.9 KiB
JavaScript
// Generated, do not edit. sha256:9856275bb06c64defb28cac958ae6f3ea1416a635a680ca0739edd9bad0379ee
|
||||
|
|
import * as dialog from './dialog.js';
|
|||
|
|
import { esc } from './escape.js';
|
|||
|
|
|
|||
|
|
let _seq = 0;
|
|||
|
|
|
|||
|
|
export function labelComboMarkup(fieldKey, currentId) {
|
|||
|
|
const id = currentId == null ? '' : currentId;
|
|||
|
|
const dl = `lc-dl-${++_seq}`;
|
|||
|
|
return `<span class="label-combo" data-field="${esc(fieldKey)}" data-label-combo>
|
|||
|
|
<input type="hidden" data-label-id value="${esc(id)}">
|
|||
|
|
<input class="input label-combo-input" data-label-input list="${dl}" placeholder="label…" autocomplete="off">
|
|||
|
|
<datalist id="${dl}"></datalist>
|
|||
|
|
<button type="button" class="label-combo-btn" data-label-add title="Label maken/koppelen">+</button>
|
|||
|
|
<button type="button" class="label-combo-btn" data-label-del title="Label ontkoppelen">−</button>
|
|||
|
|
</span>`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export function labelComboRead(host) {
|
|||
|
|
if (!host) return null;
|
|||
|
|
const v = host.querySelector('[data-label-id]').value;
|
|||
|
|
return v === '' ? null : Number(v);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export function labelComboMount(host, labelApi, onChange) {
|
|||
|
|
const hidden = host.querySelector('[data-label-id]');
|
|||
|
|
const input = host.querySelector('[data-label-input]');
|
|||
|
|
const datalist = host.querySelector('datalist');
|
|||
|
|
const addBtn = host.querySelector('[data-label-add]');
|
|||
|
|
const delBtn = host.querySelector('[data-label-del]');
|
|||
|
|
|
|||
|
|
let cache = [];
|
|||
|
|
const byName = name => {
|
|||
|
|
const n = name.trim().toLowerCase();
|
|||
|
|
return cache.find(l => l.name.toLowerCase() === n) || null;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function refreshList() {
|
|||
|
|
datalist.innerHTML = cache.map(l => `<option value="${esc(l.name)}"></option>`).join('');
|
|||
|
|
}
|
|||
|
|
function setId(id) {
|
|||
|
|
hidden.value = id == null ? '' : id;
|
|||
|
|
const cur = cache.find(l => String(l.id) === String(id));
|
|||
|
|
input.value = cur ? cur.name : '';
|
|||
|
|
delBtn.disabled = !cur;
|
|||
|
|
}
|
|||
|
|
async function load() {
|
|||
|
|
cache = (await labelApi.listLabels()) || [];
|
|||
|
|
refreshList();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
input.onfocus = () => { input.value = ''; load(); };
|
|||
|
|
input.onblur = () => setTimeout(() => {
|
|||
|
|
if (document.activeElement === input) return;
|
|||
|
|
if (!input.value.trim()) {
|
|||
|
|
const cur = cache.find(l => String(l.id) === String(hidden.value));
|
|||
|
|
input.value = cur ? cur.name : '';
|
|||
|
|
}
|
|||
|
|
}, 150);
|
|||
|
|
|
|||
|
|
input.onchange = () => {
|
|||
|
|
const name = input.value.trim();
|
|||
|
|
if (!name) { setId(''); onChange?.(null); return; }
|
|||
|
|
const m = byName(name);
|
|||
|
|
if (m) { setId(m.id); onChange?.(m.id); }
|
|||
|
|
else { hidden.value = ''; delBtn.disabled = true; }
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
addBtn.onclick = async () => {
|
|||
|
|
const name = input.value.trim();
|
|||
|
|
if (!name) { input.focus(); return; }
|
|||
|
|
const m = byName(name);
|
|||
|
|
if (m) { setId(m.id); onChange?.(m.id); return; }
|
|||
|
|
try {
|
|||
|
|
const id = await labelApi.createLabel({ name });
|
|||
|
|
await load(); setId(id); onChange?.(id);
|
|||
|
|
} catch (e) { dialog.alert({ message: e.message }); }
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
delBtn.onclick = () => { setId(''); onChange?.(null); };
|
|||
|
|
|
|||
|
|
return load().then(() => setId(hidden.value || ''));
|
|||
|
|
}
|