import './search.css' import { TapiContact } from './tapi-contact' import { debounce } from './debounce' import { fireChangeEvents } from './utils' import GM_fetch from '@trim21/gm-fetch' import { Config } from './config' const iconArbeiten = require('./briefcase-regular-full.svg') const iconBesprechung = require('./screen-users-sharp-regular-full.svg') const iconFokus = require('./headphones-regular-full.svg') const iconMittag = require('./grill-hot-regular-full.svg') const iconFeierabend = require('./beer-mug-empty-regular-full.svg') const QUICK_BUTTONS = [ { icon: iconArbeiten, menuId: 'menuCustom1', message: '', css: 'tapi-btn-available', title: 'Arbeiten' }, { icon: iconBesprechung, menuId: 'menuOutofoffice', message: 'Besprechung', css: 'tapi-btn-dnd', title: 'Besprechung' }, { icon: iconFokus, menuId: 'menuOutofoffice', message: 'Fokus', css: 'tapi-btn-dnd', title: 'Fokus' }, { icon: iconMittag, menuId: 'menuAway', message: 'Mittag', css: 'tapi-btn-away', title: 'Mittag' }, { icon: iconFeierabend, menuId: 'menuAway', message: 'Feierabend', css: 'tapi-btn-away', title: 'Feierabend' }, ] export class Search { private currentSearchText = '' public createSearchWindow (element: HTMLElement) { console.log('Create TAPI Search') var form = document.createElement('form') form.classList.add('tapi-form') form.onsubmit = () => { var items = document.getElementsByClassName('tapi-search-autocomplete-active') if (items.length === 0) { items = document.getElementsByClassName('tapi-search-autocomplete-item') } if (items.length > 0) { this.dial((items[0]).dataset.tapiNumber) } else { this.dial((document.getElementById('tapiSearchInput')).value) } return false } QUICK_BUTTONS.forEach(btn => { var button = document.createElement('button') button.type = 'button' button.innerHTML = btn.icon button.classList.add('tapi-quick-btn') button.classList.add(btn.css) button.title = btn.title button.onclick = () => { this.setStatus(btn.menuId, btn.message) } form.appendChild(button) }) var searchBox = document.createElement('div') searchBox.classList.add('tapi-search-autocomplete') searchBox.style.width = '200px' searchBox.id = 'tapiSearchBox' form.appendChild(searchBox) var search = document.createElement('input') search.id = 'tapiSearchInput' search.autocomplete = 'off' search.placeholder = 'TAPI Suche' search.onfocus = () => { this.doSearch() } search.onkeydown = (ev) => { this.doSearchKeyDown(ev) } search.onblur = () => { setTimeout(() => { this.removeSearchResults() }, 250) } searchBox.appendChild(search) element.parentElement.insertBefore(form, element) } private delay (ms: number): Promise { return new Promise(resolve => setTimeout(resolve, ms)) } private async setStatus (menuId: string, message: string) { var accMenu = document.getElementsByTagName('wc-account-menu')[0] var avatar = accMenu.getElementsByTagName('app-avatar')[0] as HTMLAnchorElement avatar.click() await this.delay(1000) if (message !== '') { var pencilBtn = document.getElementById(menuId + 'SetStatus') as HTMLElement if (pencilBtn) { pencilBtn.click() await this.delay(500) var modalInput = document.querySelector('input[data-qa="input"][maxlength="128"]') as HTMLInputElement if (modalInput) { modalInput.value = message fireChangeEvents(modalInput) await this.delay(300) var okBtn = Array.from(document.querySelectorAll('button')).find(btn => btn.textContent && btn.textContent.trim() === 'OK' && btn.getBoundingClientRect().width > 0 ) as HTMLButtonElement if (okBtn) { okBtn.click() await this.delay(500) } } } } var statusItem = document.getElementById(menuId) as HTMLElement if (!statusItem || statusItem.getBoundingClientRect().width === 0) { avatar.click() await this.delay(1000) statusItem = document.getElementById(menuId) as HTMLElement } if (statusItem) { statusItem.click() } } private removeSearchResults () { var resultList = document.getElementById('tapi-search-autocomplete-list') if (resultList) { resultList.parentNode.removeChild(resultList) } this.currentSearchText = '' } private doSearchKeyDown (ev: KeyboardEvent) { if (ev.key === 'ArrowUp') { let items = document.getElementsByClassName('tapi-search-autocomplete-active') if (items.length > 0) { var prev = items[0].previousSibling } if (!prev) { items = document.getElementsByClassName('tapi-search-autocomplete-item') if (items.length > 0) { prev = items[items.length - 1] } } if (prev) { this.selectResult(prev) prev.scrollIntoView(true) } } else if (ev.key === 'ArrowDown') { let items = document.getElementsByClassName('tapi-search-autocomplete-active') if (items.length > 0) { var next = items[0].nextSibling } if (!next) { items = document.getElementsByClassName('tapi-search-autocomplete-item') if (items.length > 0) { next = items[0] } } if (next) { this.selectResult(next) next.scrollIntoView(false) } } else { this.doSearch() } } private doSearch = debounce(async () => { var search = document.getElementById('tapiSearchInput') var searchText = search.value.trim() if (searchText === '') { this.removeSearchResults() return } else if (searchText === this.currentSearchText) { return } var response = await GM_fetch(Config.tapi_server_url + '/search?query=' + encodeURIComponent(searchText)) var contacts = await response.json() as TapiContact[] this.removeSearchResults() this.currentSearchText = searchText var results = document.createElement('div'); results.setAttribute('id', 'tapi-search-autocomplete-list') results.setAttribute('class', 'tapi-search-autocomplete-items') document.getElementById('tapiSearchBox').appendChild(results) contacts.forEach(contact => { var item = document.createElement('div'); item.setAttribute('class', 'tapi-search-autocomplete-item') var p = document.createElement('p') p.innerHTML = contact.tD_NAME + '
' + contact.tD_MEDIUM + ': ' + contact.tD_NUMBER_TAPI item.appendChild(p) item.onclick = () => { this.dial(contact.tD_NUMBER_TAPI) } item.onmouseover = () => { this.selectResult(item) } item.dataset.tapiNumber = contact.tD_NUMBER_TAPI results.appendChild(item); }) }, 200) private selectResult (item: Element) { var items = document.getElementsByClassName('tapi-search-autocomplete-active') for (var i of items) { i.classList.remove('tapi-search-autocomplete-active') } item.classList.add('tapi-search-autocomplete-active') } private dial (number: string) { var searchInput = document.getElementById('dialpad-input'); (searchInput).value = number; (searchInput).focus; fireChangeEvents(searchInput); var toaster = document.querySelector('toaster-container'); if (window.getComputedStyle(toaster, null).display == 'none') { document.getElementById('menuDialer').click(); } } }