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.

191 lines
6.6 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-paint-palette.svg', alt='Theme', style='width: 80px;')
  7. .admin-header-title
  8. .headline.primary--text.animated.fadeInLeft {{$t('admin:theme.title')}}
  9. .subheading.grey--text.animated.fadeInLeft.wait-p2s {{$t('admin:theme.subtitle')}}
  10. v-spacer
  11. v-btn.animated.fadeInRight(color='success', depressed, @click='save', large, :loading='loading')
  12. v-icon(left) check
  13. span {{$t('common:actions.apply')}}
  14. v-form.pt-3
  15. v-layout(row wrap)
  16. v-flex(lg6 xs12)
  17. v-card.wiki-form.animated.fadeInUp
  18. v-toolbar(color='primary', dark, dense, flat)
  19. v-toolbar-title
  20. .subheading {{$t('admin:theme.title')}}
  21. v-card-text
  22. v-select(
  23. :items='themes'
  24. outline
  25. background-color='grey lighten-2'
  26. prepend-icon='palette'
  27. v-model='config.theme'
  28. :label='$t(`admin:theme.siteTheme`)'
  29. persistent-hint
  30. :hint='$t(`admin:theme.siteThemeHint`)'
  31. )
  32. template(slot='item', slot-scope='data')
  33. v-list-tile-avatar
  34. v-icon.blue--text(dark) filter_frames
  35. v-list-tile-content
  36. v-list-tile-title(v-html='data.item.text')
  37. v-list-tile-sub-title(v-html='data.item.author')
  38. v-select.mt-3(
  39. :items='iconsets'
  40. outline
  41. background-color='grey lighten-2'
  42. prepend-icon='pets'
  43. v-model='config.iconset'
  44. :label='$t(`admin:theme.iconset`)'
  45. persistent-hint
  46. :hint='$t(`admin:theme.iconsetHint`)'
  47. )
  48. v-divider.mt-3
  49. v-switch(
  50. v-model='darkMode'
  51. :label='$t(`admin:theme.darkMode`)'
  52. color='primary'
  53. persistent-hint
  54. :hint='$t(`admin:theme.darkModeHint`)'
  55. )
  56. v-card.wiki-form.mt-3.animated.fadeInUp.wait-p2s
  57. v-toolbar(color='primary', dark, dense, flat)
  58. v-toolbar-title
  59. .subheading {{$t(`admin:theme.codeInjection`)}}
  60. v-card-text
  61. v-textarea(
  62. v-model='config.injectCSS'
  63. :label='$t(`admin:theme.cssOverride`)'
  64. outline
  65. background-color='grey lighten-1'
  66. color='primary'
  67. persistent-hint
  68. :hint='$t(`admin:theme.cssOverrideHint`)'
  69. auto-grow
  70. )
  71. v-textarea.mt-2(
  72. v-model='config.injectHead'
  73. :label='$t(`admin:theme.headHtmlInjection`)'
  74. outline
  75. background-color='grey lighten-1'
  76. color='primary'
  77. persistent-hint
  78. :hint='$t(`admin:theme.headHtmlInjectionHint`)'
  79. auto-grow
  80. )
  81. v-textarea.mt-2(
  82. v-model='config.injectBody'
  83. :label='$t(`admin:theme.bodyHtmlInjection`)'
  84. outline
  85. background-color='grey lighten-1'
  86. color='primary'
  87. persistent-hint
  88. :hint='$t(`admin:theme.bodyHtmlInjectionHint`)'
  89. auto-grow
  90. )
  91. v-flex(lg6 xs12)
  92. v-card.animated.fadeInUp.wait-p2s
  93. v-toolbar(color='teal', dark, dense, flat)
  94. v-toolbar-title
  95. .subheading {{$t('admin:theme.downloadThemes')}}
  96. v-spacer
  97. v-chip(label, color='white', small).teal--text coming soon
  98. v-card-text.caption -- Coming soon --
  99. </template>
  100. <script>
  101. import _ from 'lodash'
  102. import { sync } from 'vuex-pathify'
  103. import themeConfigQuery from 'gql/admin/theme/theme-query-config.gql'
  104. import themeSaveMutation from 'gql/admin/theme/theme-mutation-save.gql'
  105. export default {
  106. data() {
  107. return {
  108. loading: false,
  109. themes: [
  110. { text: 'Default', author: 'requarks.io', value: 'default' }
  111. ],
  112. iconsets: [
  113. { text: 'Material Icons (default)', value: 'md' },
  114. { text: 'Material Design Icons', value: 'mdi' },
  115. { text: 'Font Awesome 5', value: 'fa' },
  116. { text: 'Font Awesome 4', value: 'fa4' },
  117. ],
  118. config: {
  119. theme: 'default',
  120. darkMode: false,
  121. iconset: '',
  122. injectCSS: '',
  123. injectHead: '',
  124. injectBody: ''
  125. },
  126. darkModeInitial: false
  127. }
  128. },
  129. computed: {
  130. darkMode: sync('site/dark')
  131. },
  132. mounted() {
  133. this.darkModeInitial = this.darkMode
  134. },
  135. beforeDestroy() {
  136. this.darkMode = this.darkModeInitial
  137. },
  138. methods: {
  139. async save () {
  140. this.loading = true
  141. this.$store.commit(`loadingStart`, 'admin-theme-save')
  142. try {
  143. const respRaw = await this.$apollo.mutate({
  144. mutation: themeSaveMutation,
  145. variables: {
  146. theme: this.config.theme,
  147. iconset: this.config.iconset,
  148. darkMode: this.darkMode,
  149. injectCSS: this.config.injectCSS,
  150. injectHead: this.config.injectHead,
  151. injectBody: this.config.injectBody
  152. }
  153. })
  154. const resp = _.get(respRaw, 'data.theming.setConfig.responseResult', {})
  155. if (resp.succeeded) {
  156. this.darkModeInitial = this.darkMode
  157. this.$store.commit('showNotification', {
  158. message: 'Theme settings updated successfully.',
  159. style: 'success',
  160. icon: 'check'
  161. })
  162. } else {
  163. throw new Error(resp.message)
  164. }
  165. } catch (err) {
  166. this.$store.commit('pushGraphError', err)
  167. }
  168. this.$store.commit(`loadingStop`, 'admin-theme-save')
  169. this.loading = false
  170. }
  171. },
  172. apollo: {
  173. config: {
  174. query: themeConfigQuery,
  175. fetchPolicy: 'network-only',
  176. update: (data) => data.theming.config,
  177. watchLoading (isLoading) {
  178. this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-theme-refresh')
  179. }
  180. }
  181. }
  182. }
  183. </script>
  184. <style lang='scss'>
  185. </style>