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.

387 lines
14 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='/_assets/svg/icon-categorize.svg', alt='General', style='width: 80px;')
  7. .admin-header-title
  8. .headline.primary--text.animated.fadeInLeft {{ $t('admin:general.title') }}
  9. .subtitle-1.grey--text.animated.fadeInLeft {{ $t('admin:general.subtitle') }}
  10. v-spacer
  11. v-btn.animated.fadeInDown(color='success', depressed, @click='save', large)
  12. v-icon(left) mdi-check
  13. span {{$t('common:actions.apply')}}
  14. v-form.pt-3
  15. v-layout(row wrap)
  16. v-flex(lg6 xs12)
  17. v-form
  18. v-card.animated.fadeInUp
  19. v-toolbar(color='primary', dark, dense, flat)
  20. v-toolbar-title.subtitle-1 {{ $t('admin:general.siteInfo') }}
  21. .overline.grey--text.pa-4 {{$t('admin:general.general')}}
  22. .px-3.pb-3
  23. v-text-field(
  24. outlined
  25. :label='$t(`admin:general.siteUrl`)'
  26. required
  27. :counter='255'
  28. v-model='config.host'
  29. prepend-icon='mdi-label-variant-outline'
  30. :hint='$t(`admin:general.siteUrlHint`)'
  31. persistent-hint
  32. )
  33. v-text-field.mt-3(
  34. outlined
  35. :label='$t(`admin:general.siteTitle`)'
  36. required
  37. :counter='50'
  38. v-model='config.title'
  39. prepend-icon='mdi-earth'
  40. :hint='$t(`admin:general.siteTitleHint`)'
  41. persistent-hint
  42. )
  43. v-divider
  44. .overline.grey--text.pa-4 {{$t('admin:general.logo')}}
  45. .pt-2.pb-7.pl-10.pr-3
  46. .d-flex.align-center
  47. v-avatar(size='100', tile)
  48. v-img(
  49. :src='config.logoUrl'
  50. lazy-src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNcWQ8AAdcBKrJda2oAAAAASUVORK5CYII='
  51. aspect-ratio='1'
  52. )
  53. .ml-4(style='flex: 1 1 auto;')
  54. v-text-field(
  55. outlined
  56. :label='$t(`admin:general.logoUrl`)'
  57. v-model='config.logoUrl'
  58. :hint='$t(`admin:general.logoUrlHint`)'
  59. persistent-hint
  60. append-icon='mdi-folder-image'
  61. @click:append='browseLogo'
  62. @keyup.enter='refreshLogo'
  63. )
  64. v-divider
  65. .overline.grey--text.pa-4 {{$t('admin:general.footerCopyright')}}
  66. .px-3.pb-3
  67. v-text-field(
  68. outlined
  69. :label='$t(`admin:general.companyName`)'
  70. v-model='config.company'
  71. :counter='255'
  72. prepend-icon='mdi-domain'
  73. persistent-hint
  74. :hint='$t(`admin:general.companyNameHint`)'
  75. )
  76. v-select.mt-3(
  77. outlined
  78. :label='$t(`admin:general.contentLicense`)'
  79. :items='contentLicenses'
  80. v-model='config.contentLicense'
  81. prepend-icon='mdi-creative-commons'
  82. :return-object='false'
  83. :hint='$t(`admin:general.contentLicenseHint`)'
  84. persistent-hint
  85. )
  86. v-divider
  87. .overline.grey--text.pa-4 SEO
  88. .px-3.pb-3
  89. v-text-field(
  90. outlined
  91. :label='$t(`admin:general.siteDescription`)'
  92. :counter='255'
  93. v-model='config.description'
  94. prepend-icon='mdi-compass'
  95. :hint='$t(`admin:general.siteDescriptionHint`)'
  96. persistent-hint
  97. )
  98. v-select.mt-3(
  99. outlined
  100. :label='$t(`admin:general.metaRobots`)'
  101. multiple
  102. :items='metaRobots'
  103. v-model='config.robots'
  104. prepend-icon='mdi-compass'
  105. :return-object='false'
  106. :hint='$t(`admin:general.metaRobotsHint`)'
  107. persistent-hint
  108. )
  109. v-flex(lg6 xs12)
  110. v-card.animated.fadeInUp.wait-p4s
  111. v-toolbar(color='indigo', dark, dense, flat)
  112. v-toolbar-title.subtitle-1 Features
  113. v-card-text
  114. //- v-switch(
  115. //- inset
  116. //- label='Asset Image Optimization'
  117. //- color='indigo'
  118. //- v-model='config.featureTinyPNG'
  119. //- persistent-hint
  120. //- hint='Image optimization tool to reduce filesize and bandwidth costs.'
  121. //- disabled
  122. //- )
  123. //- v-text-field.mt-3(
  124. //- outlined
  125. //- label='TinyPNG API Key'
  126. //- :counter='255'
  127. //- v-model='config.description'
  128. //- prepend-icon='mdi-subdirectory-arrow-right'
  129. //- hint='Get your API key at https://tinypng.com/developers'
  130. //- persistent-hint
  131. //- disabled
  132. //- )
  133. //- v-divider.mt-3
  134. //- v-switch(
  135. //- inset
  136. //- label='Page Ratings'
  137. //- color='indigo'
  138. //- v-model='config.featurePageRatings'
  139. //- persistent-hint
  140. //- hint='Allow users to rate pages.'
  141. //- disabled
  142. //- )
  143. //- v-divider.mt-3
  144. v-switch(
  145. inset
  146. label='Comments'
  147. color='indigo'
  148. v-model='config.featurePageComments'
  149. persistent-hint
  150. hint='Allow users to leave comments on pages.'
  151. )
  152. //- v-divider.mt-3
  153. //- v-switch(
  154. //- inset
  155. //- label='Personal Wikis'
  156. //- color='indigo'
  157. //- v-model='config.featurePersonalWikis'
  158. //- persistent-hint
  159. //- hint='Allow users to have their own personal wiki.'
  160. //- disabled
  161. //- )
  162. v-card.mt-5.animated.fadeInUp.wait-p6s
  163. v-toolbar(color='primary', dark, dense, flat)
  164. v-toolbar-title.subtitle-1 URL Handling
  165. v-card-text
  166. v-text-field(
  167. outlined
  168. :label='$t(`admin:general.pageExtensions`)'
  169. v-model='config.pageExtensions'
  170. prepend-icon='mdi-format-text-wrapping-overflow'
  171. :hint='$t(`admin:general.pageExtensionsHint`)'
  172. persistent-hint
  173. )
  174. component(:is='activeModal')
  175. </template>
  176. <script>
  177. import _ from 'lodash'
  178. import { sync } from 'vuex-pathify'
  179. import gql from 'graphql-tag'
  180. import editorStore from '../../store/editor'
  181. /* global WIKI */
  182. const titleRegex = /[<>"]/i
  183. WIKI.$store.registerModule('editor', editorStore)
  184. export default {
  185. i18nOptions: { namespaces: 'editor' },
  186. components: {
  187. editorModalMedia: () => import(/* webpackChunkName: "editor", webpackMode: "lazy" */ '../editor/editor-modal-media.vue')
  188. },
  189. data() {
  190. return {
  191. config: {
  192. host: '',
  193. title: '',
  194. description: '',
  195. robots: [],
  196. analyticsService: '',
  197. analyticsId: '',
  198. company: '',
  199. contentLicense: '',
  200. logoUrl: '',
  201. featureAnalytics: false,
  202. featurePageRatings: false,
  203. featurePageComments: false,
  204. featurePersonalWikis: false,
  205. featureTinyPNG: false,
  206. pageExtensions: ''
  207. },
  208. metaRobots: [
  209. { text: 'Index', value: 'index' },
  210. { text: 'Follow', value: 'follow' },
  211. { text: 'No Index', value: 'noindex' },
  212. { text: 'No Follow', value: 'nofollow' }
  213. ]
  214. }
  215. },
  216. computed: {
  217. siteTitle: sync('site/title'),
  218. logoUrl: sync('site/logoUrl'),
  219. company: sync('site/company'),
  220. contentLicense: sync('site/contentLicense'),
  221. activeModal: sync('editor/activeModal'),
  222. contentLicenses () {
  223. return [
  224. { value: '', text: this.$t('common:license.none') },
  225. { value: 'alr', text: this.$t('common:license.alr') },
  226. { value: 'cc0', text: this.$t('common:license.cc0') },
  227. { value: 'ccby', text: this.$t('common:license.ccby') },
  228. { value: 'ccbysa', text: this.$t('common:license.ccbysa') },
  229. { value: 'ccbynd', text: this.$t('common:license.ccbynd') },
  230. { value: 'ccbync', text: this.$t('common:license.ccbync') },
  231. { value: 'ccbyncsa', text: this.$t('common:license.ccbyncsa') },
  232. { value: 'ccbyncnd', text: this.$t('common:license.ccbyncnd') }
  233. ]
  234. }
  235. },
  236. methods: {
  237. async save () {
  238. const title = _.get(this.config, 'title', '')
  239. if (titleRegex.test(title)) {
  240. this.$store.commit('showNotification', {
  241. style: 'error',
  242. message: this.$t('admin:general.siteTitleInvalidChars'),
  243. icon: 'alert'
  244. })
  245. return
  246. }
  247. try {
  248. await this.$apollo.mutate({
  249. mutation: gql`
  250. mutation (
  251. $host: String
  252. $title: String
  253. $description: String
  254. $robots: [String]
  255. $analyticsService: String
  256. $analyticsId: String
  257. $company: String
  258. $contentLicense: String
  259. $logoUrl: String
  260. $pageExtensions: String
  261. $featurePageRatings: Boolean
  262. $featurePageComments: Boolean
  263. $featurePersonalWikis: Boolean
  264. ) {
  265. site {
  266. updateConfig(
  267. host: $host
  268. title: $title
  269. description: $description
  270. robots: $robots
  271. analyticsService: $analyticsService
  272. analyticsId: $analyticsId
  273. company: $company
  274. contentLicense: $contentLicense
  275. logoUrl: $logoUrl
  276. pageExtensions: $pageExtensions
  277. featurePageRatings: $featurePageRatings
  278. featurePageComments: $featurePageComments
  279. featurePersonalWikis: $featurePersonalWikis
  280. ) {
  281. responseResult {
  282. succeeded
  283. errorCode
  284. slug
  285. message
  286. }
  287. }
  288. }
  289. }
  290. `,
  291. variables: {
  292. host: _.get(this.config, 'host', ''),
  293. title: _.get(this.config, 'title', ''),
  294. description: _.get(this.config, 'description', ''),
  295. robots: _.get(this.config, 'robots', []),
  296. analyticsService: _.get(this.config, 'analyticsService', ''),
  297. analyticsId: _.get(this.config, 'analyticsId', ''),
  298. company: _.get(this.config, 'company', ''),
  299. contentLicense: _.get(this.config, 'contentLicense', ''),
  300. logoUrl: _.get(this.config, 'logoUrl', ''),
  301. pageExtensions: _.get(this.config, 'pageExtensions', ''),
  302. featurePageRatings: _.get(this.config, 'featurePageRatings', false),
  303. featurePageComments: _.get(this.config, 'featurePageComments', false),
  304. featurePersonalWikis: _.get(this.config, 'featurePersonalWikis', false)
  305. },
  306. watchLoading (isLoading) {
  307. this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-site-update')
  308. }
  309. })
  310. this.$store.commit('showNotification', {
  311. style: 'success',
  312. message: this.$t('admin:general.saveSuccess'),
  313. icon: 'check'
  314. })
  315. this.siteTitle = this.config.title
  316. this.company = this.config.company
  317. this.contentLicense = this.config.contentLicense
  318. this.logoUrl = this.config.logoUrl
  319. } catch (err) {
  320. this.$store.commit('pushGraphError', err)
  321. }
  322. },
  323. browseLogo () {
  324. this.$store.set('editor/editorKey', 'common')
  325. this.activeModal = 'editorModalMedia'
  326. },
  327. refreshLogo () {
  328. this.$forceUpdate()
  329. }
  330. },
  331. mounted () {
  332. this.$root.$on('editorInsert', opts => {
  333. this.config.logoUrl = opts.path
  334. })
  335. },
  336. beforeDestroy() {
  337. this.$root.$off('editorInsert')
  338. },
  339. apollo: {
  340. config: {
  341. query: gql`
  342. {
  343. site {
  344. config {
  345. host
  346. title
  347. description
  348. robots
  349. analyticsService
  350. analyticsId
  351. company
  352. contentLicense
  353. logoUrl
  354. pageExtensions
  355. featurePageRatings
  356. featurePageComments
  357. featurePersonalWikis
  358. }
  359. }
  360. }
  361. `,
  362. fetchPolicy: 'network-only',
  363. update: (data) => _.cloneDeep(data.site.config),
  364. watchLoading (isLoading) {
  365. this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-site-refresh')
  366. }
  367. }
  368. }
  369. }
  370. </script>
  371. <style lang='scss'>
  372. </style>