// ============================================================
// PAGERS & EXTENSIONS — personal directory with async search + soft delete
// ============================================================
(function () {
var _inited = false;
var _items = [];
var _mode = 'active'; // 'active' | 'trash'
var _editId = null; // null = creating, non-null = editing
var _searchDebounce = null;
document.addEventListener('tabChanged', function (e) {
if (e.detail.tab !== 'extensions' || _inited) return;
_inited = true;
init();
});
function init() {
document.getElementById('ext-add-btn').addEventListener('click', onAddClick);
document.getElementById('ext-cancel-btn').addEventListener('click', hideForm);
document.getElementById('ext-save-btn').addEventListener('click', saveItem);
document.getElementById('ext-trash-btn').addEventListener('click', toggleTrashMode);
document.getElementById('ext-back-active').addEventListener('click', function () { _mode = 'active'; updateModeBanner(); load(); });
var searchInp = document.getElementById('ext-search');
searchInp.addEventListener('input', function () {
clearTimeout(_searchDebounce);
_searchDebounce = setTimeout(load, 200);
});
// Keyboard: Esc cancels form
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape' && !document.getElementById('ext-form-wrap').classList.contains('hidden')) {
hideForm();
}
});
load();
loadTrashCount();
}
function loadTrashCount() {
fetch('/api/extensions?trash=1', { headers: getAuthHeaders() })
.then(function (r) { return r.json(); })
.then(function (d) {
if (d.success) {
var n = (d.items || []).length;
document.getElementById('ext-trash-count').textContent = n ? '(' + n + ')' : '';
}
})
.catch(function () {});
}
function load() {
var q = document.getElementById('ext-search').value.trim();
var url = '/api/extensions?' + (_mode === 'trash' ? 'trash=1&' : '') + (q ? 'q=' + encodeURIComponent(q) : '');
var listEl = document.getElementById('ext-list');
listEl.innerHTML = '
Loading...
';
fetch(url, { headers: getAuthHeaders() })
.then(function (r) { return r.json(); })
.then(function (d) {
if (!d.success) { listEl.innerHTML = '' + esc(d.error || 'Load failed') + '
'; return; }
_items = d.items || [];
render();
refreshLocationList();
})
.catch(function (err) {
listEl.innerHTML = 'Load failed: ' + esc(err.message) + '
';
});
}
function refreshLocationList() {
// Populate datalist with existing unique locations for autocomplete
var dl = document.getElementById('ext-location-list');
if (!dl) return;
var seen = {};
var opts = [];
_items.forEach(function (x) {
if (!seen[x.location]) { seen[x.location] = true; opts.push(x.location); }
});
dl.innerHTML = opts.map(function (l) { return '