Browse Source

feat: theming resolvers + config fixes

NGPixel 7 years ago
parent
commit
197b6b4160

+ 12 - 9
client/components/admin.vue

@@ -7,7 +7,7 @@
           v-list-tile-avatar: v-icon dashboard
           v-list-tile-avatar: v-icon dashboard
           v-list-tile-title Dashboard
           v-list-tile-title Dashboard
         v-divider.my-2
         v-divider.my-2
-        v-subheader Site
+        v-subheader.pl-4 Site
         v-list-tile(to='/general')
         v-list-tile(to='/general')
           v-list-tile-avatar: v-icon widgets
           v-list-tile-avatar: v-icon widgets
           v-list-tile-title General
           v-list-tile-title General
@@ -21,7 +21,7 @@
           v-list-tile-avatar: v-icon palette
           v-list-tile-avatar: v-icon palette
           v-list-tile-title Theme
           v-list-tile-title Theme
         v-divider.my-2
         v-divider.my-2
-        v-subheader Users
+        v-subheader.pl-4 Users
         v-list-tile(to='/groups')
         v-list-tile(to='/groups')
           v-list-tile-avatar: v-icon people
           v-list-tile-avatar: v-icon people
           v-list-tile-title Groups
           v-list-tile-title Groups
@@ -33,19 +33,19 @@
               v-chip(small, disabled, color='grey lighten-4')
               v-chip(small, disabled, color='grey lighten-4')
                 .caption.grey--text 1
                 .caption.grey--text 1
         v-divider.my-2
         v-divider.my-2
-        v-subheader Modules
+        v-subheader.pl-4 Modules
         v-list-tile(to='/auth')
         v-list-tile(to='/auth')
           v-list-tile-avatar: v-icon lock_outline
           v-list-tile-avatar: v-icon lock_outline
           v-list-tile-title Authentication
           v-list-tile-title Authentication
-        v-list-tile(to='/rendering')
-          v-list-tile-avatar: v-icon system_update_alt
-          v-list-tile-title Content Rendering
         v-list-tile(to='/editor')
         v-list-tile(to='/editor')
           v-list-tile-avatar: v-icon transform
           v-list-tile-avatar: v-icon transform
           v-list-tile-title Editor
           v-list-tile-title Editor
         v-list-tile(to='/logging')
         v-list-tile(to='/logging')
           v-list-tile-avatar: v-icon graphic_eq
           v-list-tile-avatar: v-icon graphic_eq
           v-list-tile-title Logging
           v-list-tile-title Logging
+        v-list-tile(to='/rendering')
+          v-list-tile-avatar: v-icon system_update_alt
+          v-list-tile-title Rendering
         v-list-tile(to='/search')
         v-list-tile(to='/search')
           v-list-tile-avatar: v-icon search
           v-list-tile-avatar: v-icon search
           v-list-tile-title Search Engine
           v-list-tile-title Search Engine
@@ -53,7 +53,7 @@
           v-list-tile-avatar: v-icon storage
           v-list-tile-avatar: v-icon storage
           v-list-tile-title Storage
           v-list-tile-title Storage
         v-divider.my-2
         v-divider.my-2
-        v-subheader System
+        v-subheader.pl-4 System
         v-list-tile(to='/api')
         v-list-tile(to='/api')
           v-list-tile-avatar: v-icon call_split
           v-list-tile-avatar: v-icon call_split
           v-list-tile-title API Access
           v-list-tile-title API Access
@@ -96,7 +96,7 @@ import { mapState } from 'vuex'
 
 
 import adminStore from '@/store/admin'
 import adminStore from '@/store/admin'
 
 
-/* global WIKI */
+/* global WIKI, siteConfig */
 
 
 WIKI.$store.registerModule('admin', adminStore)
 WIKI.$store.registerModule('admin', adminStore)
 
 
@@ -143,7 +143,10 @@ export default {
       set(newState) { this.$store.commit('updateNotificationState', newState) }
       set(newState) { this.$store.commit('updateNotificationState', newState) }
     }
     }
   },
   },
-  router
+  router,
+  mounted() {
+    this.$store.commit('admin/setThemeDarkMode', siteConfig.darkMode)
+  }
 }
 }
 </script>
 </script>
 
 

+ 1 - 1
client/components/admin/admin-rendering.vue

@@ -2,7 +2,7 @@
   v-container(fluid, fill-height)
   v-container(fluid, fill-height)
     v-layout(row wrap)
     v-layout(row wrap)
       v-flex(xs12)
       v-flex(xs12)
-        .headline.primary--text Content Rendering
+        .headline.primary--text Rendering
         .subheading.grey--text Configure how content is rendered
         .subheading.grey--text Configure how content is rendered
 </template>
 </template>
 
 

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

@@ -12,7 +12,14 @@
                   v-toolbar-title
                   v-toolbar-title
                     .subheading Theme
                     .subheading Theme
                 v-card-text
                 v-card-text
-                  v-select(:items='themes', prepend-icon='palette', v-model='selectedTheme', label='Site Theme', persistent-hint, hint='Themes affect how content pages are displayed. Other site sections (such as the editor or admin area) are not affected.')
+                  v-select(
+                    :items='themes'
+                    prepend-icon='palette'
+                    v-model='selectedTheme'
+                    label='Site Theme'
+                    persistent-hint
+                    hint='Themes affect how content pages are displayed. Other site sections (such as the editor or admin area) are not affected.'
+                    )
                     template(slot='item', slot-scope='data')
                     template(slot='item', slot-scope='data')
                       v-list-tile-avatar
                       v-list-tile-avatar
                         v-icon.blue--text(dark) filter_frames
                         v-icon.blue--text(dark) filter_frames
@@ -20,7 +27,13 @@
                         v-list-tile-title(v-html='data.item.text')
                         v-list-tile-title(v-html='data.item.text')
                         v-list-tile-sub-title(v-html='data.item.author')
                         v-list-tile-sub-title(v-html='data.item.author')
                   v-divider
                   v-divider
-                  v-switch(v-model='darkMode', label='Dark Mode', color='primary', persistent-hint, hint='Not recommended for accessibility.')
+                  v-switch(
+                    v-model='darkMode'
+                    label='Dark Mode'
+                    color='primary'
+                    persistent-hint
+                    hint='Not recommended for accessibility. May not be supported by all themes.'
+                    )
                 v-card-chin
                 v-card-chin
                   v-spacer
                   v-spacer
                   v-btn(color='primary', :loading='loading', @click='save')
                   v-btn(color='primary', :loading='loading', @click='save')
@@ -35,20 +48,66 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import _ from 'lodash'
+
+import themeSaveMutation from 'gql/admin-theme-mutation-save.gql'
+
 export default {
 export default {
   data() {
   data() {
     return {
     return {
+      loading: false,
       themes: [
       themes: [
         { text: 'Default', author: 'requarks.io', value: 'default' }
         { text: 'Default', author: 'requarks.io', value: 'default' }
       ],
       ],
       selectedTheme: 'default',
       selectedTheme: 'default',
-      darkMode: false
+      darkMode: false,
+      darkModeInitial: false
     }
     }
   },
   },
   watch: {
   watch: {
     darkMode(newValue, oldValue) {
     darkMode(newValue, oldValue) {
       this.$store.commit('admin/setThemeDarkMode', newValue)
       this.$store.commit('admin/setThemeDarkMode', newValue)
-      console.info(this.$vuetify.dark)
+    }
+  },
+  mounted() {
+    this.darkMode = this.$store.state.admin.theme.dark
+    this.darkModeInitial = this.darkMode
+  },
+  beforeDestroy() {
+    this.$store.commit('admin/setThemeDarkMode', this.darkModeInitial)
+  },
+  methods: {
+    async save () {
+      this.loading = true
+      this.$store.commit(`loadingStart`, 'admin-theme-save')
+      try {
+        const respRaw = await this.$apollo.mutate({
+          mutation: themeSaveMutation,
+          variables: {
+            theme: this.selectedTheme,
+            darkMode: this.darkMode
+          }
+        })
+        const resp = _.get(respRaw, 'data.theming.setConfig.responseResult', {})
+        if (resp.succeeded) {
+          this.darkModeInitial = this.darkMode
+          this.$store.commit('showNotification', {
+            message: 'Theme settings updated successfully.',
+            style: 'success',
+            icon: 'check'
+          })
+        } else {
+          throw new Error(resp.message)
+        }
+      } catch (err) {
+        this.$store.commit('showNotification', {
+          message: `Error: ${err.message}`,
+          style: 'error',
+          icon: 'warning'
+        })
+      }
+      this.$store.commit(`loadingStop`, 'admin-theme-save')
+      this.loading = false
     }
     }
   }
   }
 }
 }

+ 3 - 3
client/components/common/user-search.vue

@@ -15,12 +15,13 @@
           v-show='searchLoading'
           v-show='searchLoading'
           )
           )
       v-card-text
       v-card-text
-        v-text-field.blue.lighten-5(
+        v-text-field(
           solo
           solo
           flat
           flat
           label='Search Users...'
           label='Search Users...'
           v-model='search'
           v-model='search'
           prepend-icon='search'
           prepend-icon='search'
+          :class='$vuetify.dark ? "grey darken-4" : "blue lighten-5"'
           color='primary'
           color='primary'
           ref='searchIpt'
           ref='searchIpt'
           )
           )
@@ -35,8 +36,7 @@
               v-list-tile-action
               v-list-tile-action
                 v-icon(color='primary') arrow_forward
                 v-icon(color='primary') arrow_forward
             v-divider.my-0(v-if='idx < items.length - 1')
             v-divider.my-0(v-if='idx < items.length - 1')
-      v-divider.my-0
-      v-card-actions.grey.lighten-4
+      v-card-chin
         v-spacer
         v-spacer
         v-btn(
         v-btn(
           flat
           flat

+ 5 - 2
client/components/nav-header.vue

@@ -33,7 +33,7 @@
           v-list-tile-avatar: v-icon(color='blue-grey') burst_mode
           v-list-tile-avatar: v-icon(color='blue-grey') burst_mode
           v-list-tile-content Images &amp; Files
           v-list-tile-content Images &amp; Files
     v-toolbar-title
     v-toolbar-title
-      span.subheading Wiki.js
+      span.subheading {{title}}
     v-spacer
     v-spacer
     transition(name='navHeaderSearch')
     transition(name='navHeaderSearch')
       v-text-field(
       v-text-field(
@@ -87,6 +87,8 @@
 <script>
 <script>
 import { mapGetters } from 'vuex'
 import { mapGetters } from 'vuex'
 
 
+/* global siteConfig */
+
 export default {
 export default {
   data() {
   data() {
     return {
     return {
@@ -97,7 +99,8 @@ export default {
     }
     }
   },
   },
   computed: {
   computed: {
-    ...mapGetters(['isLoading'])
+    ...mapGetters(['isLoading']),
+    title() { return siteConfig.title }
   },
   },
   methods: {
   methods: {
     searchToggle() {
     searchToggle() {

+ 12 - 0
client/graph/admin-theme-mutation-save.gql

@@ -0,0 +1,12 @@
+mutation($theme: String!, $darkMode: Boolean!) {
+  theming {
+    setConfig(theme: $theme, darkMode: $darkMode) {
+      responseResult {
+        succeeded
+        errorCode
+        slug
+        message
+      }
+    }
+  }
+}

+ 2 - 2
dev/templates/master.pug

@@ -7,7 +7,7 @@ html
     meta(name='theme-color', content='#333333')
     meta(name='theme-color', content='#333333')
     meta(name='msapplication-TileColor', content='#333333')
     meta(name='msapplication-TileColor', content='#333333')
     meta(name='msapplication-TileImage', content='/favicons/ms-icon-144x144.png')
     meta(name='msapplication-TileImage', content='/favicons/ms-icon-144x144.png')
-    title= config.site.title
+    title= config.title
 
 
     //- Favicon
     //- Favicon
     each favsize in [57, 60, 72, 76, 114, 120, 144, 152, 180]
     each favsize in [57, 60, 72, 76, 114, 120, 144, 152, 180]
@@ -19,7 +19,7 @@ html
 
 
     //- Site Lang
     //- Site Lang
     script.
     script.
-      var siteConfig = !{JSON.stringify(config.site)}
+      var siteConfig = !{JSON.stringify({ title: config.title, theme: config.theming.theme, darkMode: config.theming.darkMode, lang: config.lang.code })}
 
 
     //- CSS
     //- CSS
     link(type='text/css', rel='stylesheet', href='https://fonts.googleapis.com/icon?family=Roboto:400,500,700|Source+Code+Pro:400,700|Material+Icons')
     link(type='text/css', rel='stylesheet', href='https://fonts.googleapis.com/icon?family=Roboto:400,500,700|Source+Code+Pro:400,700|Material+Icons')

+ 15 - 15
server/app/data.yml

@@ -24,21 +24,21 @@ defaults:
       db: 0
       db: 0
       password: null
       password: null
     # DB defaults
     # DB defaults
-    auth:
-      public: false
-      strategies:
-        local:
-          isEnabled: true
-          allowSelfRegister: false
-    logging:
-      telemetry: false
-      loggers:
-        console:
-          enabled: true
-    site:
-      lang: en
-      rtl: false
-      title: Wiki.js
+    defaultEditor: 'markdown'
+    graphEndpoint: 'https://graph.requarks.io'
+    lang:
+      code: en
+      autoUpdate: true
+      namespaces: []
+      namespacing: false
+    public: false
+    telemetry:
+      clientId: ''
+      isEnabled: false
+    title: Wiki.js
+    theming:
+      theme: 'default'
+      darkMode: false
     # System defaults
     # System defaults
     setup: false
     setup: false
     cors:
     cors:

+ 2 - 1
server/core/auth.js

@@ -41,10 +41,11 @@ module.exports = {
 
 
       // Load enable strategies
       // Load enable strategies
       const enabledStrategies = await WIKI.db.authentication.getEnabledStrategies()
       const enabledStrategies = await WIKI.db.authentication.getEnabledStrategies()
+      console.info(enabledStrategies)
       for (let idx in enabledStrategies) {
       for (let idx in enabledStrategies) {
         const stg = enabledStrategies[idx]
         const stg = enabledStrategies[idx]
         const strategy = require(`../modules/authentication/${stg.key}`)
         const strategy = require(`../modules/authentication/${stg.key}`)
-        stg.config.callbackURL = `${WIKI.config.site.host}/login/${stg.key}/callback`
+        stg.config.callbackURL = `${WIKI.config.host}/login/${stg.key}/callback` // TODO: config.host
         strategy.init(passport, stg.config)
         strategy.init(passport, stg.config)
 
 
         fs.readFile(path.join(WIKI.ROOTPATH, `assets/svg/auth-icon-${strategy.key}.svg`), 'utf8').then(iconData => {
         fs.readFile(path.join(WIKI.ROOTPATH, `assets/svg/auth-icon-${strategy.key}.svg`), 'utf8').then(iconData => {

+ 12 - 6
server/core/logger.js

@@ -1,4 +1,4 @@
-const _ = require('lodash')
+// const _ = require('lodash')
 const winston = require('winston')
 const winston = require('winston')
 
 
 /* global WIKI */
 /* global WIKI */
@@ -16,11 +16,17 @@ module.exports = {
       )
       )
     })
     })
 
 
-    _.forOwn(_.omitBy(WIKI.config.logging.loggers, s => s.enabled === false), (loggerConfig, loggerKey) => {
-      let loggerModule = require(`../modules/logging/${loggerKey}`)
-      loggerModule.init(logger, loggerConfig)
-      this.loggers[logger.key] = loggerModule
-    })
+    // Init Console (default)
+
+    let loggerConsoleModule = require(`../modules/logging/console`)
+    loggerConsoleModule.init(logger)
+    this.loggers['console'] = loggerConsoleModule
+
+    // _.forOwn(_.omitBy(WIKI.config.logging.loggers, s => s.enabled === false), (loggerConfig, loggerKey) => {
+    //   let loggerModule = require(`../modules/logging/${loggerKey}`)
+    //   loggerModule.init(logger, loggerConfig)
+    //   this.loggers[logger.key] = loggerModule
+    // })
 
 
     return logger
     return logger
   }
   }

+ 42 - 0
server/graph/resolvers/theming.js

@@ -0,0 +1,42 @@
+const graphHelper = require('../../helpers/graph')
+
+/* global WIKI */
+
+module.exports = {
+  Query: {
+    async theming() { return {} }
+  },
+  Mutation: {
+    async theming() { return {} }
+  },
+  ThemingQuery: {
+    async themes(obj, args, context, info) {
+      return [{ // TODO
+        key: 'default',
+        title: 'Default',
+        author: 'requarks.io'
+      }]
+    },
+    async config(obj, args, context, info) {
+      return {
+        theme: WIKI.config.theming.theme,
+        darkMode: WIKI.config.theming.darkMode
+      }
+    }
+  },
+  ThemingMutation: {
+    async setConfig(obj, args, context, info) {
+      try {
+        WIKI.config.theming.theme = args.theme
+        WIKI.config.theming.darkMode = args.darkMode
+        await WIKI.configSvc.saveToDb(['theming'])
+
+        return {
+          responseResult: graphHelper.generateSuccess('Theme config updated')
+        }
+      } catch (err) {
+        return graphHelper.generateError(err)
+      }
+    }
+  }
+}

+ 46 - 0
server/graph/schemas/theming.graphql

@@ -0,0 +1,46 @@
+# ===============================================
+# THEMES
+# ===============================================
+
+extend type Query {
+  theming: ThemingQuery
+}
+
+extend type Mutation {
+  theming: ThemingMutation
+}
+
+# -----------------------------------------------
+# QUERIES
+# -----------------------------------------------
+
+type ThemingQuery {
+  themes: [ThemingTheme]
+  config: ThemingConfig
+}
+
+# -----------------------------------------------
+# MUTATIONS
+# -----------------------------------------------
+
+type ThemingMutation {
+  setConfig(
+    theme: String!
+    darkMode: Boolean!
+  ): DefaultResponse
+}
+
+# -----------------------------------------------
+# TYPES
+# -----------------------------------------------
+
+type ThemingConfig {
+  theme: String
+  darkMode: Boolean
+}
+
+type ThemingTheme {
+  key: String
+  title: String
+  author: String
+}

+ 1 - 1
server/master.js

@@ -111,7 +111,7 @@ module.exports = async () => {
   app.locals.basedir = WIKI.ROOTPATH
   app.locals.basedir = WIKI.ROOTPATH
   app.locals._ = require('lodash')
   app.locals._ = require('lodash')
   app.locals.moment = require('moment')
   app.locals.moment = require('moment')
-  app.locals.moment.locale(WIKI.config.site.lang)
+  app.locals.moment.locale(WIKI.config.lang.code)
   app.locals.config = WIKI.config
   app.locals.config = WIKI.config
 
 
   // ----------------------------------------
   // ----------------------------------------

+ 3 - 0
server/setup.js

@@ -284,6 +284,8 @@ module.exports = () => {
       _.set(WIKI.config, 'sessionSecret', (await crypto.randomBytesAsync(32)).toString('hex'))
       _.set(WIKI.config, 'sessionSecret', (await crypto.randomBytesAsync(32)).toString('hex'))
       _.set(WIKI.config, 'telemetry.isEnabled', req.body.telemetry === 'true')
       _.set(WIKI.config, 'telemetry.isEnabled', req.body.telemetry === 'true')
       _.set(WIKI.config, 'telemetry.clientId', WIKI.telemetry.cid)
       _.set(WIKI.config, 'telemetry.clientId', WIKI.telemetry.cid)
+      _.set(WIKI.config, 'theming.theme', 'default')
+      _.set(WIKI.config, 'theming.darkMode', false)
       _.set(WIKI.config, 'title', req.body.title)
       _.set(WIKI.config, 'title', req.body.title)
 
 
       // Save config to DB
       // Save config to DB
@@ -295,6 +297,7 @@ module.exports = () => {
         'public',
         'public',
         'sessionSecret',
         'sessionSecret',
         'telemetry',
         'telemetry',
+        'theming',
         'title'
         'title'
       ])
       ])
 
 

+ 2 - 2
server/views/master.pug

@@ -7,7 +7,7 @@ html
     meta(name='theme-color', content='#333333')
     meta(name='theme-color', content='#333333')
     meta(name='msapplication-TileColor', content='#333333')
     meta(name='msapplication-TileColor', content='#333333')
     meta(name='msapplication-TileImage', content='/favicons/ms-icon-144x144.png')
     meta(name='msapplication-TileImage', content='/favicons/ms-icon-144x144.png')
-    title= config.site.title
+    title= config.title
 
 
     //- Favicon
     //- Favicon
     each favsize in [57, 60, 72, 76, 114, 120, 144, 152, 180]
     each favsize in [57, 60, 72, 76, 114, 120, 144, 152, 180]
@@ -19,7 +19,7 @@ html
 
 
     //- Site Lang
     //- Site Lang
     script.
     script.
-      var siteConfig = !{JSON.stringify(config.site)}
+      var siteConfig = !{JSON.stringify({ title: config.title, theme: config.theming.theme, darkMode: config.theming.darkMode, lang: config.lang.code })}
 
 
     //- CSS
     //- CSS
     link(type='text/css', rel='stylesheet', href='https://fonts.googleapis.com/icon?family=Roboto:400,500,700|Source+Code+Pro:400,700|Material+Icons')
     link(type='text/css', rel='stylesheet', href='https://fonts.googleapis.com/icon?family=Roboto:400,500,700|Source+Code+Pro:400,700|Material+Icons')