You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

203 lines
7.5 KiB

  1. <template lang='pug'>
  2. v-container(fluid, grid-list-lg)
  3. v-layout(row, wrap)
  4. v-flex(xs12)
  5. .admin-header
  6. img.animated.fadeInUp(src='/svg/icon-search.svg', alt='Search Engine', style='width: 80px;')
  7. .admin-header-title
  8. .headline.primary--text.animated.fadeInLeft Search Engine
  9. .subheading.grey--text.animated.fadeInLeft.wait-p2s Configure the search capabilities of your wiki
  10. v-spacer
  11. v-btn.animated.fadeInDown.wait-p2s(outline, color='grey', @click='refresh', large)
  12. v-icon refresh
  13. v-btn.animated.fadeInDown.wait-p1s(color='black', dark, large, depressed, @click='rebuild')
  14. v-icon(left) cached
  15. span Rebuild Index
  16. v-btn.animated.fadeInDown(color='success', @click='save', depressed, large)
  17. v-icon(left) check
  18. span {{$t('common:actions.apply')}}
  19. v-flex(lg3, xs12)
  20. v-card.animated.fadeInUp
  21. v-toolbar(flat, color='primary', dark, dense)
  22. .subheading Search Engine
  23. v-list.py-0(two-line, dense)
  24. template(v-for='(eng, idx) in engines')
  25. v-list-tile(:key='eng.key', @click='selectedEngine = eng.key', :disabled='!eng.isAvailable')
  26. v-list-tile-avatar
  27. v-icon(color='grey', v-if='!eng.isAvailable') cancel
  28. v-icon(color='primary', v-else-if='eng.key === selectedEngine') radio_button_checked
  29. v-icon(color='grey', v-else) radio_button_unchecked
  30. v-list-tile-content
  31. v-list-tile-title.body-2(:class='!eng.isAvailable ? `grey--text` : (selectedEngine === eng.key ? `primary--text` : ``)') {{ eng.title }}
  32. v-list-tile-sub-title.caption(:class='!eng.isAvailable ? `grey--text text--lighten-1` : (selectedEngine === eng.key ? `blue--text ` : ``)') {{ eng.description }}
  33. v-list-tile-avatar(v-if='selectedEngine === eng.key')
  34. v-icon.animated.fadeInLeft(color='primary') arrow_forward_ios
  35. v-divider(v-if='idx < engines.length - 1')
  36. v-flex(lg9, xs12)
  37. v-card.wiki-form.animated.fadeInUp.wait-p2s
  38. v-toolbar(color='primary', dense, flat, dark)
  39. .subheading {{engine.title}}
  40. v-card-text
  41. .enginelogo
  42. img(:src='engine.logo', :alt='engine.title')
  43. .caption.pt-3 {{engine.description}}
  44. .caption.pb-3: a(:href='engine.website') {{engine.website}}
  45. v-divider.mt-3
  46. v-subheader.pl-0 Engine Configuration
  47. .body-1.ml-3(v-if='!engine.config || engine.config.length < 1') This engine has no configuration options you can modify.
  48. template(v-else, v-for='cfg in engine.config')
  49. v-select(
  50. v-if='cfg.value.type === "string" && cfg.value.enum'
  51. outline
  52. background-color='grey lighten-2'
  53. :items='cfg.value.enum'
  54. :key='cfg.key'
  55. :label='cfg.value.title'
  56. v-model='cfg.value.value'
  57. prepend-icon='settings_applications'
  58. :hint='cfg.value.hint ? cfg.value.hint : ""'
  59. persistent-hint
  60. :class='cfg.value.hint ? "mb-2" : ""'
  61. )
  62. v-switch.mb-3(
  63. v-else-if='cfg.value.type === "boolean"'
  64. :key='cfg.key'
  65. :label='cfg.value.title'
  66. v-model='cfg.value.value'
  67. color='primary'
  68. prepend-icon='settings_applications'
  69. :hint='cfg.value.hint ? cfg.value.hint : ""'
  70. persistent-hint
  71. )
  72. v-text-field(
  73. v-else
  74. outline
  75. background-color='grey lighten-2'
  76. :key='cfg.key'
  77. :label='cfg.value.title'
  78. v-model='cfg.value.value'
  79. prepend-icon='settings_applications'
  80. :hint='cfg.value.hint ? cfg.value.hint : ""'
  81. persistent-hint
  82. :class='cfg.value.hint ? "mb-2" : ""'
  83. )
  84. </template>
  85. <script>
  86. import _ from 'lodash'
  87. import enginesQuery from 'gql/admin/search/search-query-engines.gql'
  88. import enginesSaveMutation from 'gql/admin/search/search-mutation-save-engines.gql'
  89. import enginesRebuildMutation from 'gql/admin/search/search-mutation-rebuild-index.gql'
  90. export default {
  91. data() {
  92. return {
  93. engines: [],
  94. selectedEngine: '',
  95. engine: {}
  96. }
  97. },
  98. watch: {
  99. selectedEngine(newValue, oldValue) {
  100. this.engine = _.find(this.engines, ['key', newValue]) || {}
  101. },
  102. engines(newValue, oldValue) {
  103. this.selectedEngine = _.get(_.find(this.engines, 'isEnabled'), 'key', 'db')
  104. }
  105. },
  106. methods: {
  107. async refresh() {
  108. await this.$apollo.queries.engines.refetch()
  109. this.$store.commit('showNotification', {
  110. message: 'List of search engines has been refreshed.',
  111. style: 'success',
  112. icon: 'cached'
  113. })
  114. },
  115. async save() {
  116. this.$store.commit(`loadingStart`, 'admin-search-saveengines')
  117. try {
  118. const resp = await this.$apollo.mutate({
  119. mutation: enginesSaveMutation,
  120. variables: {
  121. engines: this.engines.map(tgt => ({
  122. isEnabled: tgt.key === this.selectedEngine,
  123. key: tgt.key,
  124. config: tgt.config.map(cfg => ({...cfg, value: JSON.stringify({ v: cfg.value.value })}))
  125. }))
  126. }
  127. })
  128. if (_.get(resp, 'data.search.updateSearchEngines.responseResult.succeeded', false)) {
  129. this.$store.commit('showNotification', {
  130. message: 'Search engine configuration saved successfully.',
  131. style: 'success',
  132. icon: 'check'
  133. })
  134. } else {
  135. throw new Error(_.get(resp, 'data.search.updateSearchEngines.responseResult.message', 'An unexpected error occured'))
  136. }
  137. } catch (err) {
  138. this.$store.commit('pushGraphError', err)
  139. }
  140. this.$store.commit(`loadingStop`, 'admin-search-saveengines')
  141. },
  142. async rebuild () {
  143. this.$store.commit(`loadingStart`, 'admin-search-rebuildindex')
  144. try {
  145. const resp = await this.$apollo.mutate({
  146. mutation: enginesRebuildMutation
  147. })
  148. if (_.get(resp, 'data.search.rebuildIndex.responseResult.succeeded', false)) {
  149. this.$store.commit('showNotification', {
  150. message: 'Index rebuilt successfully.',
  151. style: 'success',
  152. icon: 'check'
  153. })
  154. } else {
  155. throw new Error(_.get(resp, 'data.search.rebuildIndex.responseResult.message', 'An unexpected error occured'))
  156. }
  157. } catch (err) {
  158. this.$store.commit('pushGraphError', err)
  159. }
  160. this.$store.commit(`loadingStop`, 'admin-search-rebuildindex')
  161. }
  162. },
  163. apollo: {
  164. engines: {
  165. query: enginesQuery,
  166. fetchPolicy: 'network-only',
  167. update: (data) => _.cloneDeep(data.search.searchEngines).map(str => ({
  168. ...str,
  169. config: _.sortBy(str.config.map(cfg => ({
  170. ...cfg,
  171. value: JSON.parse(cfg.value)
  172. })), [t => t.value.order])
  173. })),
  174. watchLoading (isLoading) {
  175. this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-search-refresh')
  176. }
  177. }
  178. }
  179. }
  180. </script>
  181. <style lang='scss' scoped>
  182. .enginelogo {
  183. width: 250px;
  184. height: 85px;
  185. float:right;
  186. display: flex;
  187. justify-content: flex-end;
  188. align-items: center;
  189. img {
  190. max-width: 100%;
  191. max-height: 50px;
  192. }
  193. }
  194. </style>