feat: admin logging + search
This commit is contained in:
		| @@ -5,29 +5,86 @@ | ||||
|       .subheading.grey--text Configure the system logger(s) | ||||
|     v-tabs(:color='$vuetify.dark ? "primary" : "grey lighten-4"', fixed-tabs, :slider-color='$vuetify.dark ? "white" : "primary"', show-arrows) | ||||
|       v-tab(key='settings'): v-icon settings | ||||
|       v-tab(v-for='svc in activeServices', :key='svc.key') {{ svc.title }} | ||||
|       v-tab(v-for='logger in activeLoggers', :key='logger.key') {{ logger.title }} | ||||
|  | ||||
|       v-tab-item(key='settings', :transition='false', :reverse-transition='false') | ||||
|         v-card.pa-3(flat, tile) | ||||
|           .body-2.pb-2 Select which logging service to enable: | ||||
|           .body-2.grey--text.text--darken-1 Select which logging service to enable: | ||||
|           .caption.grey--text.pb-2 Some loggers require additional configuration in their dedicated tab (when selected). | ||||
|           v-form | ||||
|             v-checkbox( | ||||
|               v-for='(svc, n) in services', | ||||
|               v-model='selectedServices', | ||||
|               :key='svc.key', | ||||
|               :label='svc.title', | ||||
|               :value='svc.key', | ||||
|               color='primary', | ||||
|               :disabled='svc.key === `console`' | ||||
|             v-checkbox.my-1( | ||||
|               v-for='(logger, n) in loggers' | ||||
|               v-model='logger.isEnabled' | ||||
|               :key='logger.key' | ||||
|               :label='logger.title' | ||||
|               color='primary' | ||||
|               hide-details | ||||
|             ) | ||||
|  | ||||
|       v-tab-item(v-for='(svc, n) in activeServices', :key='svc.key', :transition='false', :reverse-transition='false') | ||||
|       v-tab-item(v-for='(logger, n) in activeLoggers', :key='logger.key', :transition='false', :reverse-transition='false') | ||||
|         v-card.pa-3(flat, tile) | ||||
|           v-form | ||||
|             v-subheader Service Configuration | ||||
|             .body-1(v-if='!svc.props || svc.props.length < 1') This logging service has no configuration options you can modify. | ||||
|             v-text-field(v-else, v-for='prop in svc.props', :key='prop', :label='prop', prepend-icon='mode_edit') | ||||
|             .loggerlogo | ||||
|               img(:src='logger.logo', :alt='logger.title') | ||||
|             v-subheader.pl-0 {{logger.title}} | ||||
|             .caption {{logger.description}} | ||||
|             .caption: a(:href='logger.website') {{logger.website}} | ||||
|             v-divider.mt-3 | ||||
|             v-subheader.pl-0 Logger Configuration | ||||
|             .body-1.ml-3(v-if='!logger.config || logger.config.length < 1') This logger has no configuration options you can modify. | ||||
|             template(v-else, v-for='cfg in logger.config') | ||||
|               v-select( | ||||
|                 v-if='cfg.value.type === "string" && cfg.value.enum' | ||||
|                 outline | ||||
|                 background-color='grey lighten-2' | ||||
|                 :items='cfg.value.enum' | ||||
|                 :key='cfg.key' | ||||
|                 :label='cfg.value.title' | ||||
|                 v-model='cfg.value.value' | ||||
|                 prepend-icon='settings_applications' | ||||
|                 :hint='cfg.value.hint ? cfg.value.hint : ""' | ||||
|                 persistent-hint | ||||
|                 :class='cfg.value.hint ? "mb-2" : ""' | ||||
|               ) | ||||
|               v-switch( | ||||
|                 v-else-if='cfg.value.type === "boolean"' | ||||
|                 :key='cfg.key' | ||||
|                 :label='cfg.value.title' | ||||
|                 v-model='cfg.value.value' | ||||
|                 color='primary' | ||||
|                 prepend-icon='settings_applications' | ||||
|                 :hint='cfg.value.hint ? cfg.value.hint : ""' | ||||
|                 persistent-hint | ||||
|                 ) | ||||
|               v-text-field( | ||||
|                 v-else | ||||
|                 outline | ||||
|                 background-color='grey lighten-2' | ||||
|                 :key='cfg.key' | ||||
|                 :label='cfg.value.title' | ||||
|                 v-model='cfg.value.value' | ||||
|                 prepend-icon='settings_applications' | ||||
|                 :hint='cfg.value.hint ? cfg.value.hint : ""' | ||||
|                 persistent-hint | ||||
|                 :class='cfg.value.hint ? "mb-2" : ""' | ||||
|                 ) | ||||
|             v-divider.mt-3 | ||||
|             v-subheader.pl-0 Log Level | ||||
|             .body-1.ml-3 Select the minimum error level that will be reported to this logger. | ||||
|             v-layout(row) | ||||
|               v-flex(xs12, md6, lg4) | ||||
|                 .pt-3 | ||||
|                   v-select( | ||||
|                     single-line | ||||
|                     outline | ||||
|                     background-color='grey lighten-2' | ||||
|                     :items='levels' | ||||
|                     label='Level' | ||||
|                     v-model='logger.level' | ||||
|                     prepend-icon='graphic_eq' | ||||
|                     hint='Default: warn' | ||||
|                     persistent-hint | ||||
|                   ) | ||||
|  | ||||
|     v-card-chin | ||||
|       v-btn(color='primary', @click='save') | ||||
| @@ -51,6 +108,9 @@ import _ from 'lodash' | ||||
|  | ||||
| import LoggingConsole from './admin-logging-console.vue' | ||||
|  | ||||
| import loggersQuery from 'gql/admin/logging/logging-query-loggers.gql' | ||||
| import loggersSaveMutation from 'gql/admin/logging/logging-mutation-save-loggers.gql' | ||||
|  | ||||
| export default { | ||||
|   components: { | ||||
|     LoggingConsole | ||||
| @@ -58,34 +118,72 @@ export default { | ||||
|   data() { | ||||
|     return { | ||||
|       showConsole: false, | ||||
|       services: [], | ||||
|       selectedServices: ['console'], | ||||
|       refreshCompleted: false | ||||
|       loggers: [], | ||||
|       levels: ['error', 'warn', 'info', 'debug', 'verbose'] | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     activeServices() { | ||||
|       return _.filter(this.services, 'isEnabled') | ||||
|     activeLoggers() { | ||||
|       return _.filter(this.loggers, 'isEnabled') | ||||
|     } | ||||
|   }, | ||||
|   // apollo: { | ||||
|   //   services: { | ||||
|   //     query: CONSTANTS.GRAPH.AUTHENTICATION.QUERY_PROVIDERS, | ||||
|   //     update: (data) => data.authentication.providers | ||||
|   //   } | ||||
|   // }, | ||||
|   methods: { | ||||
|     async refresh() { | ||||
|       await this.$apollo.queries.services.refetch() | ||||
|       this.refreshCompleted = true | ||||
|       await this.$apollo.queries.loggers.refetch() | ||||
|       this.$store.commit('showNotification', { | ||||
|         message: 'List of loggers has been refreshed.', | ||||
|         style: 'success', | ||||
|         icon: 'cached' | ||||
|       }) | ||||
|     }, | ||||
|     toggleConsole () { | ||||
|       this.showConsole = !this.showConsole | ||||
|     async save() { | ||||
|       this.$store.commit(`loadingStart`, 'admin-logging-saveloggers') | ||||
|       await this.$apollo.mutate({ | ||||
|         mutation: loggersSaveMutation, | ||||
|         variables: { | ||||
|           loggers: this.loggers.map(tgt => _.pick(tgt, [ | ||||
|             'isEnabled', | ||||
|             'key', | ||||
|             'config', | ||||
|             'level' | ||||
|           ])).map(str => ({...str, config: str.config.map(cfg => ({...cfg, value: cfg.value.value}))})) | ||||
|         } | ||||
|       }) | ||||
|       this.$store.commit('showNotification', { | ||||
|         message: 'Logging configuration saved successfully.', | ||||
|         style: 'success', | ||||
|         icon: 'check' | ||||
|       }) | ||||
|       this.$store.commit(`loadingStop`, 'admin-logging-saveloggers') | ||||
|     } | ||||
|   }, | ||||
|   apollo: { | ||||
|     loggers: { | ||||
|       query: loggersQuery, | ||||
|       fetchPolicy: 'network-only', | ||||
|       update: (data) => _.cloneDeep(data.logging.loggers).map(str => ({...str, config: str.config.map(cfg => ({...cfg, value: JSON.parse(cfg.value)}))})), | ||||
|       watchLoading (isLoading) { | ||||
|         this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-logging-refresh') | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang='scss'> | ||||
| <style lang='scss' scoped> | ||||
|  | ||||
| .loggerlogo { | ||||
|   width: 250px; | ||||
|   height: 85px; | ||||
|   float:right; | ||||
|   display: flex; | ||||
|   justify-content: flex-end; | ||||
|   align-items: center; | ||||
|  | ||||
|   img { | ||||
|     max-width: 100%; | ||||
|     max-height: 50px; | ||||
|   } | ||||
| } | ||||
|  | ||||
| </style> | ||||
|   | ||||
| @@ -5,26 +5,70 @@ | ||||
|       .subheading.grey--text Configure the search capabilities of your wiki | ||||
|     v-tabs(:color='$vuetify.dark ? "primary" : "grey lighten-4"', fixed-tabs, :slider-color='$vuetify.dark ? "white" : "primary"', show-arrows) | ||||
|       v-tab(key='settings'): v-icon settings | ||||
|       v-tab(key='db') Database | ||||
|       v-tab(key='algolia') Algolia | ||||
|       v-tab(key='elasticsearch') Elasticsearch | ||||
|       v-tab(key='solr') Solr | ||||
|       v-tab(v-for='engine in activeEngines', :key='engine.key') {{ engine.title }} | ||||
|  | ||||
|       v-tab-item(key='settings') | ||||
|       v-tab-item(key='settings', :transition='false', :reverse-transition='false') | ||||
|         v-card.pa-3(flat, tile) | ||||
|           .body-2.grey--text.text--darken-1 Select which search engine to enable: | ||||
|           .caption.grey--text.pb-2 Some search engines require additional configuration in their dedicated tab (when selected). | ||||
|           v-form | ||||
|             v-radio-group(v-model='selectedEngine') | ||||
|               v-radio.my-1( | ||||
|                 v-for='(engine, n) in engines' | ||||
|                 :key='engine.key' | ||||
|                 :label='engine.title' | ||||
|                 :value='engine.key' | ||||
|                 color='primary' | ||||
|                 hide-details | ||||
|               ) | ||||
|  | ||||
|       v-tab-item(v-for='(engine, n) in activeEngines', :key='engine.key', :transition='false', :reverse-transition='false') | ||||
|         v-card.pa-3(flat, tile) | ||||
|           v-form | ||||
|             .body-2.grey--text.text--darken-1 Select the search engine to use: | ||||
|             .caption.grey--text.pb-2 Some engines require additional configuration in their dedicated tab (when selected). | ||||
|             v-radio-group(v-model='selectedEngine') | ||||
|               v-radio(v-for='(engine, n) in engines', :key='n', :label='engine.text', :value='engine.value', color='primary') | ||||
|       v-tab-item(key='db') | ||||
|         v-card.pa-3 TODO | ||||
|       v-tab-item(key='algolia') | ||||
|         v-card.pa-3 TODO | ||||
|       v-tab-item(key='elasticsearch') | ||||
|         v-card.pa-3 TODO | ||||
|       v-tab-item(key='solr') | ||||
|         v-card.pa-3 TODO | ||||
|             .enginelogo | ||||
|               img(:src='engine.logo', :alt='engine.title') | ||||
|             v-subheader.pl-0 {{engine.title}} | ||||
|             .caption {{engine.description}} | ||||
|             .caption: a(:href='engine.website') {{engine.website}} | ||||
|             v-divider.mt-3 | ||||
|             v-subheader.pl-0 Engine Configuration | ||||
|             .body-1.ml-3(v-if='!engine.config || engine.config.length < 1') This engine has no configuration options you can modify. | ||||
|             template(v-else, v-for='cfg in logger.config') | ||||
|               v-select( | ||||
|                 v-if='cfg.value.type === "string" && cfg.value.enum' | ||||
|                 outline | ||||
|                 background-color='grey lighten-2' | ||||
|                 :items='cfg.value.enum' | ||||
|                 :key='cfg.key' | ||||
|                 :label='cfg.value.title' | ||||
|                 v-model='cfg.value.value' | ||||
|                 prepend-icon='settings_applications' | ||||
|                 :hint='cfg.value.hint ? cfg.value.hint : ""' | ||||
|                 persistent-hint | ||||
|                 :class='cfg.value.hint ? "mb-2" : ""' | ||||
|               ) | ||||
|               v-switch( | ||||
|                 v-else-if='cfg.value.type === "boolean"' | ||||
|                 :key='cfg.key' | ||||
|                 :label='cfg.value.title' | ||||
|                 v-model='cfg.value.value' | ||||
|                 color='primary' | ||||
|                 prepend-icon='settings_applications' | ||||
|                 :hint='cfg.value.hint ? cfg.value.hint : ""' | ||||
|                 persistent-hint | ||||
|                 ) | ||||
|               v-text-field( | ||||
|                 v-else | ||||
|                 outline | ||||
|                 background-color='grey lighten-2' | ||||
|                 :key='cfg.key' | ||||
|                 :label='cfg.value.title' | ||||
|                 v-model='cfg.value.value' | ||||
|                 prepend-icon='settings_applications' | ||||
|                 :hint='cfg.value.hint ? cfg.value.hint : ""' | ||||
|                 persistent-hint | ||||
|                 :class='cfg.value.hint ? "mb-2" : ""' | ||||
|                 ) | ||||
|  | ||||
|     v-card-chin | ||||
|       v-btn(color='primary', @click='save') | ||||
| @@ -40,23 +84,90 @@ | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import _ from 'lodash' | ||||
|  | ||||
| import enginesQuery from 'gql/admin/search/search-query-engines.gql' | ||||
| import enginesSaveMutation from 'gql/admin/search/search-mutation-save-engines.gql' | ||||
|  | ||||
| export default { | ||||
|   data() { | ||||
|     return { | ||||
|       engines: [ | ||||
|         { text: 'Disabled', value: 'disabled' }, | ||||
|         { text: 'Database (built-in)', value: 'db' }, | ||||
|         { text: 'Algolia', value: 'algolia' }, | ||||
|         { text: 'Elasticsearch', value: 'elasticsearch' }, | ||||
|         { text: 'Solr', value: 'solr' } | ||||
|       ], | ||||
|       selectedEngine: 'db', | ||||
|       darkMode: false | ||||
|       engines: [], | ||||
|       selectedEngine: 'db' | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     activeEngines() { | ||||
|       return _.filter(this.engines, 'isEnabled') | ||||
|     } | ||||
|   }, | ||||
|   watch: { | ||||
|     selectedEngine(newValue, oldValue) { | ||||
|       this.engines.forEach(engine => { | ||||
|         if (engine.key === newValue) { | ||||
|           engine.isEnabled = true | ||||
|         } else { | ||||
|           engine.isEnabled = false | ||||
|         } | ||||
|       }) | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     async refresh() { | ||||
|       await this.$apollo.queries.engines.refetch() | ||||
|       this.$store.commit('showNotification', { | ||||
|         message: 'List of search engines has been refreshed.', | ||||
|         style: 'success', | ||||
|         icon: 'cached' | ||||
|       }) | ||||
|     }, | ||||
|     async save() { | ||||
|       this.$store.commit(`loadingStart`, 'admin-search-saveengines') | ||||
|       await this.$apollo.mutate({ | ||||
|         mutation: enginesSaveMutation, | ||||
|         variables: { | ||||
|           engines: this.engines.map(tgt => _.pick(tgt, [ | ||||
|             'isEnabled', | ||||
|             'key', | ||||
|             'config' | ||||
|           ])).map(str => ({...str, config: str.config.map(cfg => ({...cfg, value: cfg.value.value}))})) | ||||
|         } | ||||
|       }) | ||||
|       this.$store.commit('showNotification', { | ||||
|         message: 'Logging configuration saved successfully.', | ||||
|         style: 'success', | ||||
|         icon: 'check' | ||||
|       }) | ||||
|       this.$store.commit(`loadingStop`, 'admin-search-saveengines') | ||||
|     } | ||||
|   }, | ||||
|   apollo: { | ||||
|     engines: { | ||||
|       query: enginesQuery, | ||||
|       fetchPolicy: 'network-only', | ||||
|       update: (data) => _.cloneDeep(data.search.searchEngines).map(str => ({...str, config: str.config.map(cfg => ({...cfg, value: JSON.parse(cfg.value)}))})), | ||||
|       watchLoading (isLoading) { | ||||
|         this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-search-refresh') | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang='scss'> | ||||
| <style lang='scss' scoped> | ||||
|  | ||||
| .enginelogo { | ||||
|   width: 250px; | ||||
|   height: 85px; | ||||
|   float:right; | ||||
|   display: flex; | ||||
|   justify-content: flex-end; | ||||
|   align-items: center; | ||||
|  | ||||
|   img { | ||||
|     max-width: 100%; | ||||
|     max-height: 50px; | ||||
|   } | ||||
| } | ||||
|  | ||||
| </style> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user