2022-03-31 12:20:31 +02:00
|
|
|
import './search.css'
|
2020-11-04 22:59:32 +01:00
|
|
|
import { TapiContact } from './tapi-contact'
|
|
|
|
|
import { debounce } from './debounce'
|
2024-10-14 10:59:19 +02:00
|
|
|
import { fireChangeEvents } from './utils'
|
2024-10-15 16:45:21 +02:00
|
|
|
import GM_fetch from '@trim21/gm-fetch'
|
2026-03-19 13:38:06 +01:00
|
|
|
import { Config } from './config'
|
2020-11-04 22:59:32 +01:00
|
|
|
|
2026-04-10 10:01:43 +02:00
|
|
|
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' },
|
|
|
|
|
]
|
|
|
|
|
|
2020-11-04 22:59:32 +01:00
|
|
|
export class Search {
|
|
|
|
|
private currentSearchText = ''
|
|
|
|
|
|
|
|
|
|
public createSearchWindow (element: HTMLElement) {
|
|
|
|
|
console.log('Create TAPI Search')
|
|
|
|
|
|
|
|
|
|
var form = document.createElement('form')
|
2026-04-10 10:01:43 +02:00
|
|
|
form.classList.add('tapi-form')
|
2020-11-04 22:59:32 +01:00
|
|
|
form.onsubmit = () => {
|
2023-06-27 17:23:37 +02:00
|
|
|
var items = document.getElementsByClassName('tapi-search-autocomplete-active')
|
2020-11-05 08:58:51 +01:00
|
|
|
if (items.length === 0) {
|
2023-06-27 17:23:37 +02:00
|
|
|
items = document.getElementsByClassName('tapi-search-autocomplete-item')
|
2020-11-05 08:58:51 +01:00
|
|
|
}
|
2020-11-04 22:59:32 +01:00
|
|
|
if (items.length > 0) {
|
|
|
|
|
this.dial((<HTMLElement>items[0]).dataset.tapiNumber)
|
2022-02-07 12:47:51 +01:00
|
|
|
} else {
|
|
|
|
|
this.dial((<HTMLInputElement>document.getElementById('tapiSearchInput')).value)
|
2020-11-04 22:59:32 +01:00
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-10 10:01:43 +02:00
|
|
|
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)
|
|
|
|
|
})
|
|
|
|
|
|
2020-11-04 22:59:32 +01:00
|
|
|
var searchBox = document.createElement('div')
|
2023-06-27 17:23:37 +02:00
|
|
|
searchBox.classList.add('tapi-search-autocomplete')
|
|
|
|
|
searchBox.style.width = '200px'
|
2020-11-04 22:59:32 +01:00
|
|
|
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 = () => {
|
2026-04-10 10:01:43 +02:00
|
|
|
setTimeout(() => { this.removeSearchResults() }, 250)
|
2020-11-04 22:59:32 +01:00
|
|
|
}
|
2023-06-27 17:23:37 +02:00
|
|
|
searchBox.appendChild(search)
|
2020-11-04 22:59:32 +01:00
|
|
|
|
2021-11-30 14:34:29 +01:00
|
|
|
element.parentElement.insertBefore(form, element)
|
2020-11-04 22:59:32 +01:00
|
|
|
}
|
|
|
|
|
|
2026-04-10 10:01:43 +02:00
|
|
|
private delay (ms: number): Promise<void> {
|
|
|
|
|
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()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-04 22:59:32 +01:00
|
|
|
private removeSearchResults () {
|
2023-06-27 17:23:37 +02:00
|
|
|
var resultList = document.getElementById('tapi-search-autocomplete-list')
|
2020-11-04 22:59:32 +01:00
|
|
|
if (resultList) {
|
|
|
|
|
resultList.parentNode.removeChild(resultList)
|
|
|
|
|
}
|
|
|
|
|
this.currentSearchText = ''
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private doSearchKeyDown (ev: KeyboardEvent) {
|
|
|
|
|
if (ev.key === 'ArrowUp') {
|
2023-06-27 17:23:37 +02:00
|
|
|
let items = document.getElementsByClassName('tapi-search-autocomplete-active')
|
2020-11-04 22:59:32 +01:00
|
|
|
if (items.length > 0) {
|
|
|
|
|
var prev = <Element>items[0].previousSibling
|
|
|
|
|
}
|
|
|
|
|
if (!prev) {
|
2023-06-27 17:23:37 +02:00
|
|
|
items = document.getElementsByClassName('tapi-search-autocomplete-item')
|
2020-11-04 22:59:32 +01:00
|
|
|
if (items.length > 0) {
|
|
|
|
|
prev = items[items.length - 1]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (prev) {
|
|
|
|
|
this.selectResult(prev)
|
|
|
|
|
prev.scrollIntoView(true)
|
|
|
|
|
}
|
|
|
|
|
} else if (ev.key === 'ArrowDown') {
|
2023-06-27 17:23:37 +02:00
|
|
|
let items = document.getElementsByClassName('tapi-search-autocomplete-active')
|
2020-11-04 22:59:32 +01:00
|
|
|
if (items.length > 0) {
|
|
|
|
|
var next = <Element>items[0].nextSibling
|
|
|
|
|
}
|
|
|
|
|
if (!next) {
|
2023-06-27 17:23:37 +02:00
|
|
|
items = document.getElementsByClassName('tapi-search-autocomplete-item')
|
2020-11-04 22:59:32 +01:00
|
|
|
if (items.length > 0) {
|
|
|
|
|
next = items[0]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (next) {
|
|
|
|
|
this.selectResult(next)
|
|
|
|
|
next.scrollIntoView(false)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
this.doSearch()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private doSearch = debounce(async () => {
|
|
|
|
|
var search = <HTMLInputElement>document.getElementById('tapiSearchInput')
|
|
|
|
|
var searchText = search.value.trim()
|
|
|
|
|
if (searchText === '') {
|
|
|
|
|
this.removeSearchResults()
|
|
|
|
|
return
|
|
|
|
|
} else if (searchText === this.currentSearchText) {
|
|
|
|
|
return
|
|
|
|
|
}
|
2026-03-19 13:38:06 +01:00
|
|
|
var response = await GM_fetch(Config.tapi_server_url + '/search?query=' + encodeURIComponent(searchText))
|
2024-10-14 10:59:19 +02:00
|
|
|
var contacts = await response.json() as TapiContact[]
|
2020-11-04 22:59:32 +01:00
|
|
|
this.removeSearchResults()
|
|
|
|
|
this.currentSearchText = searchText
|
|
|
|
|
|
2023-06-27 17:23:37 +02:00
|
|
|
var results = document.createElement('div');
|
|
|
|
|
results.setAttribute('id', 'tapi-search-autocomplete-list')
|
|
|
|
|
results.setAttribute('class', 'tapi-search-autocomplete-items')
|
|
|
|
|
document.getElementById('tapiSearchBox').appendChild(results)
|
2020-11-04 22:59:32 +01:00
|
|
|
|
|
|
|
|
contacts.forEach(contact => {
|
2023-06-27 17:23:37 +02:00
|
|
|
var item = document.createElement('div');
|
|
|
|
|
item.setAttribute('class', 'tapi-search-autocomplete-item')
|
2023-06-27 17:34:11 +02:00
|
|
|
var p = document.createElement('p')
|
|
|
|
|
p.innerHTML = contact.tD_NAME + '<br>' + contact.tD_MEDIUM + ': ' + contact.tD_NUMBER_TAPI
|
|
|
|
|
item.appendChild(p)
|
2023-06-27 17:23:37 +02:00
|
|
|
item.onclick = () => { this.dial(contact.tD_NUMBER_TAPI) }
|
|
|
|
|
item.onmouseover = () => { this.selectResult(item) }
|
|
|
|
|
item.dataset.tapiNumber = contact.tD_NUMBER_TAPI
|
|
|
|
|
results.appendChild(item);
|
2020-11-04 22:59:32 +01:00
|
|
|
})
|
|
|
|
|
}, 200)
|
|
|
|
|
|
2023-06-27 17:23:37 +02:00
|
|
|
private selectResult (item: Element) {
|
|
|
|
|
var items = document.getElementsByClassName('tapi-search-autocomplete-active')
|
|
|
|
|
for (var i of items) {
|
|
|
|
|
i.classList.remove('tapi-search-autocomplete-active')
|
2020-11-04 22:59:32 +01:00
|
|
|
}
|
2023-06-27 17:23:37 +02:00
|
|
|
item.classList.add('tapi-search-autocomplete-active')
|
2020-11-04 22:59:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private dial (number: string) {
|
2021-11-30 14:34:29 +01:00
|
|
|
var searchInput = document.getElementById('dialpad-input');
|
|
|
|
|
(<HTMLInputElement>searchInput).value = number;
|
|
|
|
|
(<HTMLInputElement>searchInput).focus;
|
|
|
|
|
fireChangeEvents(searchInput);
|
2020-11-04 22:59:32 +01:00
|
|
|
|
2021-11-30 14:34:29 +01:00
|
|
|
var toaster = document.querySelector('toaster-container');
|
|
|
|
|
if (window.getComputedStyle(toaster, null).display == 'none') {
|
|
|
|
|
document.getElementById('menuDialer').click();
|
2020-11-04 22:59:32 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|