mirror of
https://github.com/itflow-org/itflow
synced 2026-11-11 07:01:16 +00:00
138 lines
4.5 KiB
JavaScript
138 lines
4.5 KiB
JavaScript
/*
|
|
* ITFlow - client switcher.
|
|
*
|
|
* The client card at the top of the client side nav opens a dropdown listing
|
|
* the agent's clients, most recently opened first, with a box to filter them.
|
|
* The list comes from ajax.php?get_active_clients the first time it opens and
|
|
* is filtered here as you type. Picking a client goes to the same page for
|
|
* that client - the side nav works out which page that is (data-switch-url).
|
|
*
|
|
* Keys: type to filter, Down to move into the list, Enter to open the first
|
|
* match, Esc to close.
|
|
*/
|
|
(function () {
|
|
'use strict';
|
|
|
|
const root = document.querySelector('[data-client-switcher]');
|
|
if (!root) {
|
|
return;
|
|
}
|
|
|
|
const input = root.querySelector('[data-client-switcher-search]');
|
|
const list = root.querySelector('[data-client-switcher-list]');
|
|
const currentId = parseInt(root.dataset.clientId, 10);
|
|
const switchUrl = root.dataset.switchUrl;
|
|
const tones = ['primary', 'success', 'info', 'warning', 'secondary'];
|
|
const limit = 50;
|
|
|
|
let clients = null;
|
|
let loading = null;
|
|
|
|
function message(text) {
|
|
list.textContent = '';
|
|
const div = document.createElement('div');
|
|
div.className = 'itflow-client-switcher-empty';
|
|
div.textContent = text;
|
|
list.appendChild(div);
|
|
}
|
|
|
|
function item(c) {
|
|
const id = parseInt(c.client_id, 10);
|
|
const link = document.createElement('a');
|
|
link.className = 'dropdown-item itflow-client-switcher-item';
|
|
link.href = switchUrl + id;
|
|
if (id === currentId) {
|
|
link.classList.add('active');
|
|
link.setAttribute('aria-current', 'true');
|
|
}
|
|
|
|
const tile = document.createElement('span');
|
|
const tone = tones.indexOf(c.client_tone) !== -1 ? c.client_tone : 'secondary';
|
|
tile.className = 'itflow-client-avatar itflow-client-avatar-xs text-bg-' + tone;
|
|
tile.setAttribute('aria-hidden', 'true');
|
|
tile.textContent = c.client_initials;
|
|
|
|
const name = document.createElement('span');
|
|
name.className = 'text-truncate';
|
|
name.textContent = c.client_name;
|
|
|
|
link.append(tile, name);
|
|
return link;
|
|
}
|
|
|
|
function render() {
|
|
if (clients === null) {
|
|
message('Loading clients...');
|
|
return;
|
|
}
|
|
|
|
const typed = input.value.trim();
|
|
const term = typed.toLowerCase();
|
|
const matches = clients.filter(function (c) {
|
|
return !term || c.client_name.toLowerCase().indexOf(term) !== -1 || c.client_initials.toLowerCase() === term;
|
|
});
|
|
|
|
if (!matches.length) {
|
|
message(term ? 'No clients match "' + typed + '"' : 'No clients');
|
|
return;
|
|
}
|
|
|
|
list.textContent = '';
|
|
matches.slice(0, limit).forEach(function (c) {
|
|
list.appendChild(item(c));
|
|
});
|
|
if (matches.length > limit) {
|
|
const more = document.createElement('div');
|
|
more.className = 'itflow-client-switcher-empty';
|
|
more.textContent = 'Keep typing to narrow down ' + (matches.length - limit) + ' more';
|
|
list.appendChild(more);
|
|
}
|
|
}
|
|
|
|
function load() {
|
|
if (clients !== null || loading) {
|
|
return;
|
|
}
|
|
loading = fetch('/agent/ajax.php?get_active_clients', { credentials: 'same-origin', headers: { Accept: 'application/json' } })
|
|
.then(function (response) {
|
|
if (!response.ok) {
|
|
throw new Error(response.status);
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(function (data) {
|
|
clients = (data && Array.isArray(data.clients)) ? data.clients : [];
|
|
render();
|
|
})
|
|
.catch(function () {
|
|
loading = null;
|
|
message('Could not load clients - close and try again');
|
|
});
|
|
}
|
|
|
|
root.addEventListener('show.bs.dropdown', function () {
|
|
input.value = '';
|
|
render();
|
|
load();
|
|
});
|
|
|
|
root.addEventListener('shown.bs.dropdown', function () {
|
|
input.focus();
|
|
});
|
|
|
|
input.addEventListener('input', render);
|
|
|
|
input.addEventListener('keydown', function (event) {
|
|
const first = list.querySelector('.itflow-client-switcher-item');
|
|
if (event.key === 'Enter') {
|
|
event.preventDefault();
|
|
if (first) {
|
|
window.location.href = first.href;
|
|
}
|
|
} else if (event.key === 'ArrowDown' && first) {
|
|
event.preventDefault();
|
|
first.focus();
|
|
}
|
|
});
|
|
})();
|