search.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. (function() {
  2. document.addEventListener('DOMContentLoaded', function(event) {
  3. var elem = document.querySelector('.js-search-input')
  4. KnowledgeBaseSearch.bindEvent(elem)
  5. });
  6. function KnowledgeBaseSearch() { }
  7. KnowledgeBaseSearch.lookup = function(query) {
  8. if(this.timeoutIdentifier) {
  9. clearTimeout(this.timeoutIdentifier)
  10. }
  11. this.clearContainer()
  12. var self = this
  13. this.timeoutIdentifier = setTimeout(function(e) { self.lookupAction(query) }, 300)
  14. }
  15. KnowledgeBaseSearch.lookupAction = function(query) {
  16. var params = {
  17. knowledge_base_id: document.documentElement.dataset.id,
  18. locale: document.documentElement.lang,
  19. query: query,
  20. flavor: 'public'
  21. }
  22. if(query === '') {
  23. return
  24. }
  25. var self = this
  26. fetch('/api/v1/knowledge_bases/search', {
  27. method: 'POST',
  28. headers: {'Content-Type': 'application/json'},
  29. body: JSON.stringify(params)
  30. })
  31. .then(function(resp) { return resp.json() })
  32. .then(function(json) {
  33. var newElems
  34. if(json.details.length === 0) {
  35. newElems = [new SearchResultMessage({ text: self.container().dataset.emptyPlaceholder })]
  36. } else {
  37. newElems = json.details.map(function(elem) { return new SearchResultElement(elem)})
  38. }
  39. newElems.forEach(function(elem) { self.container().appendChild(elem.el) } )
  40. }).catch( function(error) {
  41. var elem = new SearchResultMessage({ text: error.message })
  42. self.container().appendChild(elem.el)
  43. })
  44. }
  45. KnowledgeBaseSearch.container = function() {
  46. return document.querySelector('.js-search-results')
  47. }
  48. KnowledgeBaseSearch.clearContainer = function() {
  49. var container = this.container()
  50. while (container.firstChild !== null) container.removeChild(container.firstChild);
  51. }
  52. KnowledgeBaseSearch.bindEvent = function(field) {
  53. field.addEventListener('input', function(e) { KnowledgeBaseSearch.lookup(field.value)})
  54. }
  55. function SearchResultElement(data) {
  56. this.el = document.createElement('li')
  57. this.render = function() {
  58. this.el.classList.add('result')
  59. this.el.innerHTML = this.constructor.template
  60. this.setTitle(data.title, data.tags)
  61. this.setSubtitle(data.subtitle)
  62. this.setPreview(data.body)
  63. this.setURL(data.url)
  64. this.setIcon(data.icon, data.type)
  65. }
  66. this.setTitle = function(text, tags) {
  67. var title = text || ''
  68. this.el.querySelector('.result-title').innerHTML = title
  69. }
  70. this.setSubtitle = function(text) {
  71. this.el.querySelector('.result-category').innerHTML = text || ''
  72. }
  73. this.setPreview = function(text) {
  74. this.el.querySelector('.result-preview').innerHTML = text || ''
  75. }
  76. this.setURL = function(url) {
  77. this.el.querySelector('a').href = url || '#'
  78. }
  79. this.setIcon = function(iconName, type) {
  80. this.el.querySelector('.result-icon').innerHTML = this.generateIcon(iconName, type)
  81. }
  82. this.generateIcon = function(iconName, type) {
  83. switch(type) {
  84. case 'KnowledgeBase::Category::Translation':
  85. iconset = document.documentElement.dataset.iconset
  86. return Zammad.Util.generateIcon(iconName, iconset)
  87. default:
  88. return Zammad.Util.generateIcon(iconName)
  89. }
  90. }
  91. this.render()
  92. }
  93. SearchResultElement.template = '<a>' +
  94. ' <span class="result-icon"></span>' +
  95. ' <h3 class="result-title"></h3>' +
  96. ' <div class="result-subtitle">' +
  97. ' <span class="result-category"></span>' +
  98. ' <span class="result-preview"></span>' +
  99. ' </div>' +
  100. '</a>';
  101. function SearchResultMessage(data) {
  102. this.el = document.createElement('li')
  103. this.el.classList.add('search-message')
  104. this.el.textContent = data.text;
  105. }
  106. }())