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.

358 lines
12 KiB

6 years ago
5 years ago
5 years ago
6 years ago
  1. <template lang='pug'>
  2. v-dialog(
  3. v-model='isShown'
  4. persistent
  5. width='1000'
  6. :fullscreen='$vuetify.breakpoint.smAndDown'
  7. )
  8. .dialog-header
  9. v-icon(color='white') mdi-tag-text-outline
  10. .subtitle-1.white--text.ml-3 {{$t('editor:props.pageProperties')}}
  11. v-spacer
  12. v-btn.mx-0(
  13. outlined
  14. dark
  15. @click.native='close'
  16. )
  17. v-icon(left) mdi-check
  18. span {{ $t('common:actions.ok') }}
  19. v-card(tile)
  20. v-tabs(color='white', background-color='blue darken-1', dark, centered)
  21. v-tab {{$t('editor:props.info')}}
  22. v-tab {{$t('editor:props.scheduling')}}
  23. v-tab(disabled) {{$t('editor:props.scripts')}}
  24. v-tab {{$t('editor:props.social')}}
  25. v-tab-item
  26. v-card-text.pt-5
  27. .overline.pb-5 {{$t('editor:props.pageInfo')}}
  28. v-text-field(
  29. ref='iptTitle'
  30. outlined
  31. :label='$t(`editor:props.title`)'
  32. counter='255'
  33. v-model='title'
  34. )
  35. v-text-field(
  36. outlined
  37. :label='$t(`editor:props.shortDescription`)'
  38. counter='255'
  39. v-model='description'
  40. persistent-hint
  41. :hint='$t(`editor:props.shortDescriptionHint`)'
  42. )
  43. v-divider
  44. v-card-text.grey.pt-5(:class='$vuetify.theme.dark ? `darken-3-d3` : `lighten-5`')
  45. .overline.pb-5 {{$t('editor:props.path')}}
  46. v-container.pa-0(fluid, grid-list-lg)
  47. v-layout(row, wrap)
  48. v-flex(xs12, md2)
  49. v-select(
  50. outlined
  51. :label='$t(`editor:props.locale`)'
  52. suffix='/'
  53. :items='namespaces'
  54. v-model='locale'
  55. hide-details
  56. )
  57. v-flex(xs12, md10)
  58. v-text-field(
  59. outlined
  60. :label='$t(`editor:props.path`)'
  61. append-icon='mdi-folder-search'
  62. v-model='path'
  63. :hint='$t(`editor:props.pathHint`)'
  64. persistent-hint
  65. @click:append='showPathSelector'
  66. )
  67. v-divider
  68. v-card-text.grey.pt-5(:class='$vuetify.theme.dark ? `darken-3-d5` : `lighten-4`')
  69. .overline.pb-5 {{$t('editor:props.categorization')}}
  70. v-chip-group.radius-5.mb-5(column, v-if='tags && tags.length > 0')
  71. v-chip(
  72. v-for='tag of tags'
  73. :key='`tag-` + tag'
  74. close
  75. label
  76. color='teal'
  77. text-color='teal lighten-5'
  78. @click:close='removeTag(tag)'
  79. ) {{tag}}
  80. v-combobox(
  81. :label='$t(`editor:props.tags`)'
  82. outlined
  83. v-model='newTag'
  84. :hint='$t(`editor:props.tagsHint`)'
  85. :items='newTagSuggestions'
  86. :loading='$apollo.queries.newTagSuggestions.loading'
  87. persistent-hint
  88. hide-no-data
  89. :search-input.sync='newTagSearch'
  90. )
  91. v-tab-item
  92. v-card-text
  93. .overline.pb-5 {{$t('editor:props.publishState')}} #[v-chip.ml-3(label, color='grey', small, outlined).white--text coming soon]
  94. v-switch(
  95. :label='$t(`editor:props.publishToggle`)'
  96. v-model='isPublished'
  97. color='primary'
  98. :hint='$t(`editor:props.publishToggleHint`)'
  99. persistent-hint
  100. disabled
  101. inset
  102. )
  103. v-divider
  104. v-card-text.grey.pt-5(:class='$vuetify.theme.dark ? `darken-3-d3` : `lighten-5`')
  105. v-container.pa-0(fluid, grid-list-lg)
  106. v-row
  107. v-col(cols='6')
  108. v-dialog(
  109. ref='menuPublishStart'
  110. :close-on-content-click='false'
  111. v-model='isPublishStartShown'
  112. :return-value.sync='publishStartDate'
  113. width='460px'
  114. :disabled='!isPublished || true'
  115. )
  116. template(v-slot:activator='{ on }')
  117. v-text-field(
  118. v-on='on'
  119. :label='$t(`editor:props.publishStart`)'
  120. v-model='publishStartDate'
  121. prepend-icon='mdi-calendar-check'
  122. readonly
  123. outlined
  124. clearable
  125. :hint='$t(`editor:props.publishStartHint`)'
  126. persistent-hint
  127. :disabled='!isPublished || true'
  128. )
  129. v-date-picker(
  130. v-model='publishStartDate'
  131. :min='(new Date()).toISOString().substring(0, 10)'
  132. color='primary'
  133. reactive
  134. scrollable
  135. landscape
  136. )
  137. v-spacer
  138. v-btn(
  139. flat=''
  140. color='primary'
  141. @click='isPublishStartShown = false'
  142. ) {{$t('common:actions.cancel')}}
  143. v-btn(
  144. flat=''
  145. color='primary'
  146. @click='$refs.menuPublishStart.save(publishStartDate)'
  147. ) {{$t('common:actions.ok')}}
  148. v-col(cols='6')
  149. v-dialog(
  150. ref='menuPublishEnd'
  151. :close-on-content-click='false'
  152. v-model='isPublishEndShown'
  153. :return-value.sync='publishEndDate'
  154. width='460px'
  155. :disabled='!isPublished || true'
  156. )
  157. template(v-slot:activator='{ on }')
  158. v-text-field(
  159. v-on='on'
  160. :label='$t(`editor:props.publishEnd`)'
  161. v-model='publishEndDate'
  162. prepend-icon='mdi-calendar-remove'
  163. readonly
  164. outlined
  165. clearable
  166. :hint='$t(`editor:props.publishEndHint`)'
  167. persistent-hint
  168. :disabled='!isPublished || true'
  169. )
  170. v-date-picker(
  171. v-model='publishEndDate'
  172. :min='(new Date()).toISOString().substring(0, 10)'
  173. color='primary'
  174. reactive
  175. scrollable
  176. landscape
  177. )
  178. v-spacer
  179. v-btn(
  180. flat=''
  181. color='primary'
  182. @click='isPublishEndShown = false'
  183. ) {{$t('common:actions.cancel')}}
  184. v-btn(
  185. flat=''
  186. color='primary'
  187. @click='$refs.menuPublishEnd.save(publishEndDate)'
  188. ) {{$t('common:actions.ok')}}
  189. v-tab-item
  190. v-card-text
  191. .overline.pb-3 {{$t('editor:props.js')}}
  192. v-textarea(
  193. outlined
  194. rows='5'
  195. :hint='$t(`editor:props.jsHint`)'
  196. persistent-hint
  197. )
  198. v-divider
  199. v-card-text.grey.pt-5(:class='$vuetify.theme.dark ? `darken-3-d3` : `lighten-5`')
  200. .overline.pb-3 {{$t('editor:props.css')}}
  201. v-textarea(
  202. outlined
  203. rows='5'
  204. :hint='$t(`editor:props.cssHint`)'
  205. persistent-hint
  206. )
  207. v-tab-item
  208. v-card-text
  209. .overline.pb-5 {{$t('editor:props.socialFeatures')}} #[v-chip.ml-3(label, color='grey', small, outlined).white--text coming soon]
  210. v-switch(
  211. :label='$t(`editor:props.allowComments`)'
  212. v-model='isPublished'
  213. color='primary'
  214. :hint='$t(`editor:props.allowCommentsHint`)'
  215. persistent-hint
  216. disabled
  217. inset
  218. )
  219. v-switch(
  220. :label='$t(`editor:props.allowRatings`)'
  221. v-model='isPublished'
  222. color='primary'
  223. :hint='$t(`editor:props.allowRatingsHint`)'
  224. persistent-hint
  225. disabled
  226. inset
  227. )
  228. v-switch(
  229. :label='$t(`editor:props.displayAuthor`)'
  230. v-model='isPublished'
  231. color='primary'
  232. :hint='$t(`editor:props.displayAuthorHint`)'
  233. persistent-hint
  234. disabled
  235. inset
  236. )
  237. v-switch(
  238. :label='$t(`editor:props.displaySharingBar`)'
  239. v-model='isPublished'
  240. color='primary'
  241. :hint='$t(`editor:props.displaySharingBarHint`)'
  242. persistent-hint
  243. disabled
  244. inset
  245. )
  246. page-selector(:mode='pageSelectorMode', v-model='pageSelectorShown', :path='path', :locale='locale', :open-handler='setPath')
  247. </template>
  248. <script>
  249. import _ from 'lodash'
  250. import { sync, get } from 'vuex-pathify'
  251. import gql from 'graphql-tag'
  252. /* global siteLangs, siteConfig */
  253. export default {
  254. props: {
  255. value: {
  256. type: Boolean,
  257. default: false
  258. }
  259. },
  260. data() {
  261. return {
  262. isPublishStartShown: false,
  263. isPublishEndShown: false,
  264. pageSelectorShown: false,
  265. namespaces: siteLangs.length ? siteLangs.map(ns => ns.code) : [siteConfig.lang],
  266. newTag: '',
  267. newTagSuggestions: [],
  268. newTagSearch: ''
  269. }
  270. },
  271. computed: {
  272. isShown: {
  273. get() { return this.value },
  274. set(val) { this.$emit('input', val) }
  275. },
  276. mode: get('editor/mode'),
  277. title: sync('page/title'),
  278. description: sync('page/description'),
  279. locale: sync('page/locale'),
  280. tags: sync('page/tags'),
  281. path: sync('page/path'),
  282. isPublished: sync('page/isPublished'),
  283. publishStartDate: sync('page/publishStartDate'),
  284. publishEndDate: sync('page/publishEndDate'),
  285. pageSelectorMode () {
  286. return (this.mode === 'create') ? 'create' : 'move'
  287. }
  288. },
  289. watch: {
  290. value(newValue, oldValue) {
  291. if (newValue) {
  292. _.delay(() => {
  293. this.$refs.iptTitle.focus()
  294. // this.$tours['editorPropertiesTour'].start()
  295. }, 500)
  296. }
  297. },
  298. newTag(newValue, oldValue) {
  299. const tagClean = _.trim(newValue || '').toLowerCase()
  300. if (tagClean && tagClean.length > 0) {
  301. if (!_.includes(this.tags, tagClean)) {
  302. this.tags = [...this.tags, tagClean]
  303. }
  304. this.$nextTick(() => {
  305. this.newTag = null
  306. })
  307. }
  308. }
  309. },
  310. methods: {
  311. removeTag (tag) {
  312. this.tags = _.without(this.tags, tag)
  313. },
  314. close() {
  315. this.isShown = false
  316. },
  317. showPathSelector() {
  318. this.pageSelectorShown = true
  319. },
  320. setPath({ path, locale }) {
  321. this.locale = locale
  322. this.path = path
  323. }
  324. },
  325. apollo: {
  326. newTagSuggestions: {
  327. query: gql`
  328. query ($query: String!) {
  329. pages {
  330. searchTags (query: $query)
  331. }
  332. }
  333. `,
  334. variables () {
  335. return {
  336. query: this.newTagSearch
  337. }
  338. },
  339. fetchPolicy: 'cache-first',
  340. update: (data) => _.get(data, 'pages.searchTags', []),
  341. skip () {
  342. return !this.value || _.isEmpty(this.newTagSearch)
  343. },
  344. throttle: 500
  345. }
  346. }
  347. }
  348. </script>
  349. <style lang='scss'>
  350. </style>