Procházet zdrojové kódy

feat: editor page properties

NGPixel před 6 roky
rodič
revize
760939f808

+ 4 - 7
client/components/admin/admin-theme.vue

@@ -49,6 +49,7 @@
 
 <script>
 import _ from 'lodash'
+import { sync } from 'vuex-pathify'
 
 import themeSaveMutation from 'gql/admin/theme/theme-mutation-save.gql'
 
@@ -60,21 +61,17 @@ export default {
         { text: 'Default', author: 'requarks.io', value: 'default' }
       ],
       selectedTheme: 'default',
-      darkMode: false,
       darkModeInitial: false
     }
   },
-  watch: {
-    darkMode(newValue, oldValue) {
-      this.$store.commit('admin/setThemeDarkMode', newValue)
-    }
+  computed: {
+    darkMode: sync('admin/theme@dark')
   },
   mounted() {
-    this.darkMode = this.$store.state.admin.theme.dark
     this.darkModeInitial = this.darkMode
   },
   beforeDestroy() {
-    this.$store.commit('admin/setThemeDarkMode', this.darkModeInitial)
+    this.darkMode = this.darkModeInitial
   },
   methods: {
     async save () {

+ 26 - 4
client/components/editor.vue

@@ -7,25 +7,37 @@
           span.white--text Save
         v-btn(icon): v-icon(color='red') close
         v-btn(icon, @click.native.stop='openModal(`properties`)'): v-icon(color='white') sort_by_alpha
-        v-btn(icon, @click.native.stop='openModal(`access`)'): v-icon(color='white') vpn_lock
     v-content
       editor-code
       component(:is='currentModal')
       v-dialog(v-model='dialogProgress', persistent, max-width='350')
         v-card(color='blue darken-3', dark)
           v-card-text.text-xs-center.py-4
-            v-progress-circular(indeterminate, color='white', :width='1')
+            atom-spinner.is-inline(
+              :animation-duration='1000'
+              :size='60'
+              color='#FFF'
+              )
             .subheading Processing
             .caption.blue--text.text--lighten-3 Please wait...
 </template>
 
 <script>
 import _ from 'lodash'
+import { AtomSpinner } from 'epic-spinners'
+
+import savePageMutation from 'gql/editor/save.gql'
+
+import editorStore from '@/store/editor'
+
+/* global WIKI */
+
+WIKI.$store.registerModule('editor', editorStore)
 
 export default {
   components: {
+    AtomSpinner,
     editorCode: () => import(/* webpackChunkName: "editor-code" */ './editor/editor-code.vue'),
-    editorModalAccess: () => import(/* webpackChunkName: "editor" */ './editor/editor-modal-access.vue'),
     editorModalProperties: () => import(/* webpackChunkName: "editor" */ './editor/editor-modal-properties.vue')
   },
   data() {
@@ -49,8 +61,14 @@ export default {
     hideProgressDialog() {
       this.dialogProgress = false
     },
-    save() {
+    async save() {
       this.showProgressDialog('saving')
+      // const resp = await this.$apollo.mutate({
+      //   mutation: savePageMutation,
+      //   variables: {
+
+      //   }
+      // })
     }
   }
 }
@@ -58,4 +76,8 @@ export default {
 
 <style lang='scss'>
 
+  .atom-spinner.is-inline {
+    display: inline-block;
+  }
+
 </style>

+ 1 - 1
client/components/editor/editor-code.vue

@@ -1,6 +1,6 @@
 <template lang='pug'>
   .editor-code
-    v-toolbar.editor-code-toolbar.px-3(dense, color='primary', dark)
+    v-toolbar.editor-code-toolbar(dense, color='primary', dark)
       v-btn(icon).mx-0
         svg.icons.is-18(role='img')
           title Bold

+ 0 - 60
client/components/editor/editor-modal-access.vue

@@ -1,60 +0,0 @@
-<template lang='pug'>
-  v-bottom-sheet(v-model='isShown', inset, persistent)
-    v-toolbar(color='orange', flat)
-      v-icon(color='white') vpn_lock
-      v-toolbar-title.white--text Page Access
-      v-spacer
-      v-btn(icon, dark, @click.native='close')
-        v-icon close
-    v-card.pa-3(tile)
-      v-form
-        v-container(fluid)
-          v-layout(row, wrap)
-            v-flex(xs12)
-              v-switch(label='Published', v-model='isPublished', color='primary')
-            v-flex(xs6)
-              v-menu(ref='menuPublishStart', lazy='', :close-on-content-click='false', v-model='isPublishStartShown', transition='scale-transition', offset-y='', full-width='', :nudge-right='40', min-width='290px', :return-value.sync='publishStartDate')
-                v-text-field(slot='activator', label='Publish starting on...', v-model='publishStartDate', prepend-icon='event', readonly)
-                v-date-picker(v-model='publishStartDate', :min='(new Date()).toISOString().substring(0, 10)', reactive)
-                  v-spacer
-                  v-btn(flat='', color='primary', @click='isPublishStartShown = false') Cancel
-                  v-btn(flat='', color='primary', @click='$refs.menuPublishStart.save(date)') OK
-            v-flex(xs6)
-              v-menu(ref='menuPublishEnd', lazy='', :close-on-content-click='false', v-model='isPublishEndShown', transition='scale-transition', offset-y='', full-width='', :nudge-right='40', min-width='290px', :return-value.sync='publishEndDate')
-                v-text-field(slot='activator', label='Publish ending on...', v-model='publishEndDate', prepend-icon='event', readonly)
-                v-date-picker(v-model='publishEndDate', :min='(new Date()).toISOString().substring(0, 10)', reactive)
-                  v-spacer
-                  v-btn(flat='', color='primary', @click='isPublishEndShown = false') Cancel
-                  v-btn(flat='', color='primary', @click='$refs.menuPublishEnd.save(date)') OK
-      v-card-actions
-        v-btn(color='green', dark) Save
-        v-btn(@click.native='close') Cancel
-</template>
-
-<script>
-export default {
-  data() {
-    return {
-      isShown: false,
-      isPublished: true,
-      isPublishStartShown: false,
-      isPublishEndShown: false,
-      publishStartDate: '',
-      publishEndDate: ''
-    }
-  },
-  mounted() {
-    this.isShown = true
-  },
-  methods: {
-    close() {
-      this.isShown = false
-      this.$parent.$parent.closeModal()
-    }
-  }
-}
-</script>
-
-<style lang='scss'>
-
-</style>

+ 147 - 15
client/components/editor/editor-modal-properties.vue

@@ -1,30 +1,162 @@
 <template lang='pug'>
-  v-bottom-sheet(v-model='isShown', inset, persistent)
-    v-toolbar(color='blue-grey', flat)
+  v-bottom-sheet(
+    v-model='isShown'
+    inset
+    persistent
+    )
+    .dialog-header
       v-icon(color='white') sort_by_alpha
-      v-toolbar-title.white--text Page Properties
+      .subheading.white--text.ml-2 Page Properties
       v-spacer
-      v-btn(icon, dark, @click.native='close')
-        v-icon close
-    v-card.pa-3(tile)
+      v-btn(
+        outline
+        dark
+        @click.native='close'
+        )
+        v-icon(left) close
+        span Close
+    v-card(tile)
       v-card-text
-        v-form
-          v-text-field(label='Title', counter='255')
-          v-text-field(label='Short Description', counter='255')
-          v-select(label='Tags', chips, tags, deletable-chips)
-          v-text-field(label='Path', prefix='/', append-icon='folder')
-      v-card-actions
-        v-btn(color='green', dark) Save
-        v-btn(@click.native='close') Cancel
+        v-subheader.pl-0 Page Info
+        v-text-field(
+          outline
+          background-color='grey lighten-2'
+          label='Title'
+          counter='255'
+          v-model='title'
+          )
+        v-text-field(
+          outline
+          background-color='grey lighten-2'
+          label='Short Description'
+          counter='255'
+          v-model='description'
+          )
+        v-text-field(
+          outline
+          background-color='grey lighten-2'
+          label='Path'
+          prefix='/'
+          append-icon='folder'
+          v-model='path'
+          )
+      v-divider
+      v-card-text
+        v-subheader.pl-0 Tags
+        v-select(
+          background-color='grey lighten-2'
+          chips
+          deletable-chips
+          hide-details
+          label='Tags'
+          outline
+          tags
+          v-model='tags'
+          single-line
+          )
+      v-divider
+      v-card-text
+        v-subheader.pl-0 Publishing State
+        v-layout(row, wrap)
+          v-flex(xs4)
+            v-switch(
+              label='Published'
+              v-model='isPublished'
+              color='primary'
+              )
+          v-flex(xs4)
+            v-menu(
+              ref='menuPublishStart'
+              lazy=''
+              :close-on-content-click='false'
+              v-model='isPublishStartShown'
+              transition='scale-transition'
+              offset-y=''
+              full-width=''
+              :nudge-right='40'
+              min-width='290px'
+              :return-value.sync='publishStartDate'
+              )
+              v-text-field(
+                slot='activator'
+                label='Publish starting on...'
+                v-model='publishStartDate'
+                prepend-icon='event'
+                readonly)
+              v-date-picker(
+                v-model='publishStartDate'
+                :min='(new Date()).toISOString().substring(0, 10)'
+                reactive
+                )
+                v-spacer
+                v-btn(
+                  flat=''
+                  color='primary'
+                  @click='isPublishStartShown = false'
+                  ) Cancel
+                v-btn(
+                  flat=''
+                  color='primary'
+                  @click='$refs.menuPublishStart.save(date)'
+                  ) OK
+          v-flex(xs4)
+            v-menu(
+              ref='menuPublishEnd'
+              lazy=''
+              :close-on-content-click='false'
+              v-model='isPublishEndShown'
+              transition='scale-transition'
+              offset-y=''
+              full-width=''
+              :nudge-right='40'
+              min-width='290px'
+              :return-value.sync='publishEndDate'
+              )
+              v-text-field(
+                slot='activator'
+                label='Publish ending on...'
+                v-model='publishEndDate'
+                prepend-icon='event'
+                readonly
+                )
+              v-date-picker(
+                v-model='publishEndDate'
+                :min='(new Date()).toISOString().substring(0, 10)'
+                reactive
+                )
+                v-spacer
+                v-btn(
+                  flat=''
+                  color='primary'
+                  @click='isPublishEndShown = false'
+                  ) Cancel
+                v-btn(
+                  flat=''
+                  color='primary'
+                  @click='$refs.menuPublishEnd.save(date)'
+                  ) OK
 </template>
 
 <script>
+import { sync } from 'vuex-pathify'
+
 export default {
   data() {
     return {
-      isShown: false
+      isShown: false,
+      isPublishStartShown: false,
+      isPublishEndShown: false
     }
   },
+  computed: {
+    title: sync('editor/title'),
+    description: sync('editor/description'),
+    tags: sync('editor/tags'),
+    path: sync('editor/path'),
+    isPublished: sync('editor/isPublished'),
+    publishStartDate: sync('editor/publishStartDate'),
+    publishEndDate: sync('editor/publishEndDate')
+  },
   mounted() {
     this.isShown = true
   },

+ 7 - 0
client/graph/editor/save.gql

@@ -0,0 +1,7 @@
+mutation {
+  page {
+    create {
+      page
+    }
+  }
+}

+ 10 - 10
client/store/admin.js

@@ -1,13 +1,13 @@
+import { make } from 'vuex-pathify'
+
+const state = {
+  theme: {
+    dark: false
+  }
+}
+
 export default {
   namespaced: true,
-  state: {
-    theme: {
-      dark: false
-    }
-  },
-  mutations: {
-    setThemeDarkMode(state, payload) {
-      state.theme.dark = payload
-    }
-  }
+  state,
+  mutations: make.mutations(state)
 }

+ 18 - 0
client/store/editor.js

@@ -0,0 +1,18 @@
+import { make } from 'vuex-pathify'
+
+const state = {
+  title: '',
+  description: '',
+  tags: [],
+  path: '',
+  isPublished: true,
+  publishEtartDate: '',
+  publishEndDate: '',
+  locale: 'en'
+}
+
+export default {
+  namespaced: true,
+  state,
+  mutations: make.mutations(state)
+}

+ 4 - 0
client/store/index.js

@@ -1,11 +1,15 @@
 import _ from 'lodash'
 import Vue from 'vue'
 import Vuex from 'vuex'
+import pathify from 'vuex-pathify'
 
 Vue.use(Vuex)
 
 export default new Vuex.Store({
   strict: process.env.NODE_ENV !== 'production',
+  plugins: [
+    pathify.plugin
+  ],
   state: {
     loadingStack: [],
     notification: {

+ 2 - 0
package.json

@@ -173,6 +173,7 @@
     "css-loader": "0.28.11",
     "cssnano": "4.0.0-rc.2",
     "duplicate-package-checker-webpack-plugin": "3.0.0",
+    "epic-spinners": "1.0.3",
     "eslint": "5.0.1",
     "eslint-config-requarks": "1.0.7",
     "eslint-config-standard": "11.0.0",
@@ -238,6 +239,7 @@
     "vuedraggable": "2.16.0",
     "vuetify": "1.1.1",
     "vuex": "3.0.1",
+    "vuex-pathify": "1.1.0",
     "vuex-persistedstate": "2.5.4",
     "webpack": "4.14.0",
     "webpack-bundle-analyzer": "2.13.1",

+ 12 - 0
yarn.lock

@@ -4259,6 +4259,12 @@ env-variable@0.0.x:
   version "0.0.4"
   resolved "https://registry.yarnpkg.com/env-variable/-/env-variable-0.0.4.tgz#0d6280cf507d84242befe35a512b5ae4be77c54e"
 
+epic-spinners@1.0.3:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/epic-spinners/-/epic-spinners-1.0.3.tgz#f8ec3c59a4132de74acfe4edc0a8e1ce8b0c8312"
+  dependencies:
+    vue "2.5.16"
+
 errno@^0.1.3, errno@~0.1.7:
   version "0.1.7"
   resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618"
@@ -12857,6 +12863,12 @@ vuetify@1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/vuetify/-/vuetify-1.1.1.tgz#8d8f64306a45aaf862487addae8decf082dac0a3"
 
+vuex-pathify@1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/vuex-pathify/-/vuex-pathify-1.1.0.tgz#a908d5c9cd85ac42212332182f5ba9f060948fec"
+  dependencies:
+    lodash.clonedeep "^4.5.0"
+
 vuex-persistedstate@2.5.4:
   version "2.5.4"
   resolved "https://registry.yarnpkg.com/vuex-persistedstate/-/vuex-persistedstate-2.5.4.tgz#a19710ad7f9a08cea4e65fc585924d9fdac7384a"