feat: config-manager component
This commit is contained in:
		@@ -1,4 +0,0 @@
 | 
			
		||||
'use strict'
 | 
			
		||||
 | 
			
		||||
require('./scss/configure.scss')
 | 
			
		||||
require('./js/configure.js')
 | 
			
		||||
@@ -52,6 +52,7 @@ import adminEditUserComponent from './pages/admin-edit-user.component.js'
 | 
			
		||||
import adminProfileComponent from './pages/admin-profile.component.js'
 | 
			
		||||
import adminSettingsComponent from './pages/admin-settings.component.js'
 | 
			
		||||
import adminThemeComponent from './pages/admin-theme.component.js'
 | 
			
		||||
import configManagerComponent from './components/config-manager.component.js'
 | 
			
		||||
import contentViewComponent from './pages/content-view.component.js'
 | 
			
		||||
import editorComponent from './components/editor.component.js'
 | 
			
		||||
import sourceViewComponent from './pages/source-view.component.js'
 | 
			
		||||
@@ -94,6 +95,7 @@ Vue.component('adminSettings', adminSettingsComponent)
 | 
			
		||||
Vue.component('adminTheme', adminThemeComponent)
 | 
			
		||||
Vue.component('anchor', anchorComponent)
 | 
			
		||||
Vue.component('colorPicker', colorPickerComponent)
 | 
			
		||||
Vue.component('configManager', configManagerComponent)
 | 
			
		||||
Vue.component('contentView', contentViewComponent)
 | 
			
		||||
Vue.component('editor', editorComponent)
 | 
			
		||||
Vue.component('editorCodeblock', editorCodeblockComponent)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										304
									
								
								client/js/components/config-manager.component.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										304
									
								
								client/js/components/config-manager.component.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,304 @@
 | 
			
		||||
'use strict'
 | 
			
		||||
 | 
			
		||||
/* global siteConfig */
 | 
			
		||||
 | 
			
		||||
import VeeValidate from 'vee-validate'
 | 
			
		||||
import axios from 'axios'
 | 
			
		||||
 | 
			
		||||
Vue.use(VeeValidate, {
 | 
			
		||||
  enableAutoClasses: true,
 | 
			
		||||
  classNames: {
 | 
			
		||||
    touched: 'is-touched', // the control has been blurred
 | 
			
		||||
    untouched: 'is-untouched', // the control hasn't been blurred
 | 
			
		||||
    valid: 'is-valid', // model is valid
 | 
			
		||||
    invalid: 'is-invalid', // model is invalid
 | 
			
		||||
    pristine: 'is-pristine', // control has not been interacted with
 | 
			
		||||
    dirty: 'is-dirty' // control has been interacted with
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'configManager',
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      loading: false,
 | 
			
		||||
      state: 'welcome',
 | 
			
		||||
      syscheck: {
 | 
			
		||||
        ok: false,
 | 
			
		||||
        error: '',
 | 
			
		||||
        results: []
 | 
			
		||||
      },
 | 
			
		||||
      dbcheck: {
 | 
			
		||||
        ok: false,
 | 
			
		||||
        error: ''
 | 
			
		||||
      },
 | 
			
		||||
      gitcheck: {
 | 
			
		||||
        ok: false,
 | 
			
		||||
        error: ''
 | 
			
		||||
      },
 | 
			
		||||
      final: {
 | 
			
		||||
        ok: false,
 | 
			
		||||
        error: '',
 | 
			
		||||
        results: []
 | 
			
		||||
      },
 | 
			
		||||
      conf: {
 | 
			
		||||
        title: siteConfig.title || 'Wiki',
 | 
			
		||||
        host: siteConfig.host || 'http://',
 | 
			
		||||
        port: siteConfig.port || 80,
 | 
			
		||||
        lang: siteConfig.lang || 'en',
 | 
			
		||||
        public: (siteConfig.public === true),
 | 
			
		||||
        db: siteConfig.db || 'mongodb://localhost:27017/wiki',
 | 
			
		||||
        pathData: './data',
 | 
			
		||||
        pathRepo: './repo',
 | 
			
		||||
        gitUseRemote: (siteConfig.git !== false),
 | 
			
		||||
        gitUrl: '',
 | 
			
		||||
        gitBranch: 'master',
 | 
			
		||||
        gitAuthType: 'ssh',
 | 
			
		||||
        gitAuthSSHKey: '',
 | 
			
		||||
        gitAuthUser: '',
 | 
			
		||||
        gitAuthPass: '',
 | 
			
		||||
        gitAuthSSL: true,
 | 
			
		||||
        gitShowUserEmail: true,
 | 
			
		||||
        gitServerEmail: '',
 | 
			
		||||
        adminEmail: '',
 | 
			
		||||
        adminPassword: '',
 | 
			
		||||
        adminPasswordConfirm: ''
 | 
			
		||||
      },
 | 
			
		||||
      considerations: {
 | 
			
		||||
        https: false,
 | 
			
		||||
        port: false,
 | 
			
		||||
        localhost: false
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    currentProgress: function () {
 | 
			
		||||
      let perc = '0%'
 | 
			
		||||
      switch (this.state) {
 | 
			
		||||
        case 'welcome':
 | 
			
		||||
          perc = '0%'
 | 
			
		||||
          break
 | 
			
		||||
        case 'syscheck':
 | 
			
		||||
          perc = (this.syscheck.ok) ? '15%' : '5%'
 | 
			
		||||
          break
 | 
			
		||||
        case 'general':
 | 
			
		||||
          perc = '20%'
 | 
			
		||||
          break
 | 
			
		||||
        case 'considerations':
 | 
			
		||||
          perc = '30%'
 | 
			
		||||
          break
 | 
			
		||||
        case 'db':
 | 
			
		||||
          perc = '35%'
 | 
			
		||||
          break
 | 
			
		||||
        case 'dbcheck':
 | 
			
		||||
          perc = (this.dbcheck.ok) ? '50%' : '40%'
 | 
			
		||||
          break
 | 
			
		||||
        case 'paths':
 | 
			
		||||
          perc = '55%'
 | 
			
		||||
          break
 | 
			
		||||
        case 'git':
 | 
			
		||||
          perc = '60%'
 | 
			
		||||
          break
 | 
			
		||||
        case 'gitcheck':
 | 
			
		||||
          perc = (this.gitcheck.ok) ? '75%' : '65%'
 | 
			
		||||
          break
 | 
			
		||||
        case 'admin':
 | 
			
		||||
          perc = '80%'
 | 
			
		||||
          break
 | 
			
		||||
      }
 | 
			
		||||
      return perc
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  mounted: function () {
 | 
			
		||||
    /* if (appconfig.paths) {
 | 
			
		||||
      this.conf.pathData = appconfig.paths.data || './data'
 | 
			
		||||
      this.conf.pathRepo = appconfig.paths.repo || './repo'
 | 
			
		||||
    }
 | 
			
		||||
    if (appconfig.git !== false && _.isPlainObject(appconfig.git)) {
 | 
			
		||||
      this.conf.gitUrl = appconfig.git.url || ''
 | 
			
		||||
      this.conf.gitBranch = appconfig.git.branch || 'master'
 | 
			
		||||
      this.conf.gitShowUserEmail = (appconfig.git.showUserEmail !== false)
 | 
			
		||||
      this.conf.gitServerEmail = appconfig.git.serverEmail || ''
 | 
			
		||||
      if (_.isPlainObject(appconfig.git.auth)) {
 | 
			
		||||
        this.conf.gitAuthType = appconfig.git.auth.type || 'ssh'
 | 
			
		||||
        this.conf.gitAuthSSHKey = appconfig.git.auth.privateKey || ''
 | 
			
		||||
        this.conf.gitAuthUser = appconfig.git.auth.username || ''
 | 
			
		||||
        this.conf.gitAuthPass = appconfig.git.auth.password || ''
 | 
			
		||||
        this.conf.gitAuthSSL = (appconfig.git.auth.sslVerify !== false)
 | 
			
		||||
      }
 | 
			
		||||
    } */
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    proceedToWelcome: function (ev) {
 | 
			
		||||
      this.state = 'welcome'
 | 
			
		||||
      this.loading = false
 | 
			
		||||
    },
 | 
			
		||||
    proceedToSyscheck: function (ev) {
 | 
			
		||||
      let self = this
 | 
			
		||||
      this.state = 'syscheck'
 | 
			
		||||
      this.loading = true
 | 
			
		||||
      self.syscheck = {
 | 
			
		||||
        ok: false,
 | 
			
		||||
        error: '',
 | 
			
		||||
        results: []
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.$helpers._.delay(() => {
 | 
			
		||||
        axios.post('/syscheck').then(resp => {
 | 
			
		||||
          if (resp.data.ok === true) {
 | 
			
		||||
            self.syscheck.ok = true
 | 
			
		||||
            self.syscheck.results = resp.data.results
 | 
			
		||||
          } else {
 | 
			
		||||
            self.syscheck.ok = false
 | 
			
		||||
            self.syscheck.error = resp.data.error
 | 
			
		||||
          }
 | 
			
		||||
          self.loading = false
 | 
			
		||||
          self.$nextTick()
 | 
			
		||||
        }).catch(err => {
 | 
			
		||||
          window.alert(err.message)
 | 
			
		||||
        })
 | 
			
		||||
      }, 1000)
 | 
			
		||||
    },
 | 
			
		||||
    proceedToGeneral: function (ev) {
 | 
			
		||||
      let self = this
 | 
			
		||||
      self.state = 'general'
 | 
			
		||||
      self.loading = false
 | 
			
		||||
      self.$nextTick(() => {
 | 
			
		||||
        self.$validator.validateAll('general')
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    proceedToConsiderations: function (ev) {
 | 
			
		||||
      this.considerations = {
 | 
			
		||||
        https: !this.$helpers._.startsWith(this.conf.host, 'https'),
 | 
			
		||||
        port: false, // TODO
 | 
			
		||||
        localhost: this.$helpers._.includes(this.conf.host, 'localhost')
 | 
			
		||||
      }
 | 
			
		||||
      this.state = 'considerations'
 | 
			
		||||
      this.loading = false
 | 
			
		||||
    },
 | 
			
		||||
    proceedToDb: function (ev) {
 | 
			
		||||
      let self = this
 | 
			
		||||
      self.state = 'db'
 | 
			
		||||
      self.loading = false
 | 
			
		||||
      self.$nextTick(() => {
 | 
			
		||||
        self.$validator.validateAll('db')
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    proceedToDbcheck: function (ev) {
 | 
			
		||||
      let self = this
 | 
			
		||||
      this.state = 'dbcheck'
 | 
			
		||||
      this.loading = true
 | 
			
		||||
      self.dbcheck = {
 | 
			
		||||
        ok: false,
 | 
			
		||||
        error: ''
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.$helpers._.delay(() => {
 | 
			
		||||
        axios.post('/dbcheck', {
 | 
			
		||||
          db: self.conf.db
 | 
			
		||||
        }).then(resp => {
 | 
			
		||||
          if (resp.data.ok === true) {
 | 
			
		||||
            self.dbcheck.ok = true
 | 
			
		||||
          } else {
 | 
			
		||||
            self.dbcheck.ok = false
 | 
			
		||||
            self.dbcheck.error = resp.data.error
 | 
			
		||||
          }
 | 
			
		||||
          self.loading = false
 | 
			
		||||
          self.$nextTick()
 | 
			
		||||
        }).catch(err => {
 | 
			
		||||
          window.alert(err.message)
 | 
			
		||||
        })
 | 
			
		||||
      }, 1000)
 | 
			
		||||
    },
 | 
			
		||||
    proceedToPaths: function (ev) {
 | 
			
		||||
      let self = this
 | 
			
		||||
      self.state = 'paths'
 | 
			
		||||
      self.loading = false
 | 
			
		||||
      self.$nextTick(() => {
 | 
			
		||||
        self.$validator.validateAll('paths')
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    proceedToGit: function (ev) {
 | 
			
		||||
      let self = this
 | 
			
		||||
      self.state = 'git'
 | 
			
		||||
      self.loading = false
 | 
			
		||||
      self.$nextTick(() => {
 | 
			
		||||
        self.$validator.validateAll('git')
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    proceedToGitCheck: function (ev) {
 | 
			
		||||
      let self = this
 | 
			
		||||
      this.state = 'gitcheck'
 | 
			
		||||
      this.loading = true
 | 
			
		||||
      self.gitcheck = {
 | 
			
		||||
        ok: false,
 | 
			
		||||
        results: [],
 | 
			
		||||
        error: ''
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.$helpers._.delay(() => {
 | 
			
		||||
        axios.post('/gitcheck', self.conf).then(resp => {
 | 
			
		||||
          if (resp.data.ok === true) {
 | 
			
		||||
            self.gitcheck.ok = true
 | 
			
		||||
            self.gitcheck.results = resp.data.results
 | 
			
		||||
          } else {
 | 
			
		||||
            self.gitcheck.ok = false
 | 
			
		||||
            self.gitcheck.error = resp.data.error
 | 
			
		||||
          }
 | 
			
		||||
          self.loading = false
 | 
			
		||||
          self.$nextTick()
 | 
			
		||||
        }).catch(err => {
 | 
			
		||||
          window.alert(err.message)
 | 
			
		||||
        })
 | 
			
		||||
      }, 1000)
 | 
			
		||||
    },
 | 
			
		||||
    proceedToAdmin: function (ev) {
 | 
			
		||||
      let self = this
 | 
			
		||||
      self.state = 'admin'
 | 
			
		||||
      self.loading = false
 | 
			
		||||
      self.$nextTick(() => {
 | 
			
		||||
        self.$validator.validateAll('admin')
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    proceedToFinal: function (ev) {
 | 
			
		||||
      let self = this
 | 
			
		||||
      self.state = 'final'
 | 
			
		||||
      self.loading = true
 | 
			
		||||
      self.final = {
 | 
			
		||||
        ok: false,
 | 
			
		||||
        error: '',
 | 
			
		||||
        results: []
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.$helpers._.delay(() => {
 | 
			
		||||
        axios.post('/finalize', self.conf).then(resp => {
 | 
			
		||||
          if (resp.data.ok === true) {
 | 
			
		||||
            self.final.ok = true
 | 
			
		||||
            self.final.results = resp.data.results
 | 
			
		||||
          } else {
 | 
			
		||||
            self.final.ok = false
 | 
			
		||||
            self.final.error = resp.data.error
 | 
			
		||||
          }
 | 
			
		||||
          self.loading = false
 | 
			
		||||
          self.$nextTick()
 | 
			
		||||
        }).catch(err => {
 | 
			
		||||
          window.alert(err.message)
 | 
			
		||||
        })
 | 
			
		||||
      }, 1000)
 | 
			
		||||
    },
 | 
			
		||||
    finish: function (ev) {
 | 
			
		||||
      let self = this
 | 
			
		||||
      self.state = 'restart'
 | 
			
		||||
 | 
			
		||||
      this.$helpers._.delay(() => {
 | 
			
		||||
        axios.post('/restart', {}).then(resp => {
 | 
			
		||||
          this.$helpers._.delay(() => {
 | 
			
		||||
            window.location.assign(self.conf.host)
 | 
			
		||||
          }, 30000)
 | 
			
		||||
        }).catch(err => {
 | 
			
		||||
          window.alert(err.message)
 | 
			
		||||
        })
 | 
			
		||||
      }, 1000)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -34,9 +34,9 @@
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
  const videoRules = {
 | 
			
		||||
    'youtube': new RegExp(/(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/)|(?:(?:watch)?\?v(?:i)?=|&v(?:i)?=))([^#&?]*).*/, 'i'),
 | 
			
		||||
    'vimeo': new RegExp(/vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/(?:[^/]*)\/videos\/|album\/(?:\d+)\/video\/|)(\d+)(?:$|\/|\?)/, 'i'),
 | 
			
		||||
    'dailymotion': new RegExp(/(?:dailymotion\.com(?:\/embed)?(?:\/video|\/hub)|dai\.ly)\/([0-9a-z]+)(?:[-_0-9a-zA-Z]+(?:#video=)?([a-z0-9]+)?)?/, 'i')
 | 
			
		||||
    'youtube': new RegExp('/(?:(?:youtu\\.be\\/|v\\/|vi\\/|u\\/\\w\\/|embed\\/)|(?:(?:watch)?\\?v(?:i)?=|&v(?:i)?=))([^#&?]*).*/', 'i'),
 | 
			
		||||
    'vimeo': new RegExp('/vimeo.com\\/(?:channels\\/(?:\\w+\\/)?|groups\\/(?:[^/]*)\\/videos\\/|album\\/(?:\\d+)\\/video\\/|)(\\d+)(?:$|\\/|\\?)/', 'i'),
 | 
			
		||||
    'dailymotion': new RegExp('/(?:dailymotion\\.com(?:\\/embed)?(?:\\/video|\\/hub)|dai\\.ly)\\/([0-9a-z]+)(?:[-_0-9a-zA-Z]+(?:#video=)?([a-z0-9]+)?)?/', 'i')
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  export default {
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,7 @@ $primary: 'indigo';
 | 
			
		||||
@import 'components/button';
 | 
			
		||||
@import 'components/collapsable-nav';
 | 
			
		||||
@import 'components/color-picker';
 | 
			
		||||
@import 'components/config-manager';
 | 
			
		||||
@import 'components/footer';
 | 
			
		||||
@import 'components/form';
 | 
			
		||||
@import 'components/grid';
 | 
			
		||||
 
 | 
			
		||||
@@ -97,7 +97,11 @@
 | 
			
		||||
      background-color: mc('grey', '300') !important;
 | 
			
		||||
      color: mc('grey', '500') !important;
 | 
			
		||||
    }
 | 
			
		||||
	}
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  &.is-small {
 | 
			
		||||
    height: 30px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										61
									
								
								client/scss/components/config-manager.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								client/scss/components/config-manager.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
.config-manager {
 | 
			
		||||
  .welcome {
 | 
			
		||||
    text-align: center;
 | 
			
		||||
    padding: 50px 0 15px 0;
 | 
			
		||||
    color: mc('grey', '700');
 | 
			
		||||
 | 
			
		||||
    h2 {
 | 
			
		||||
      margin: 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  i.icon-loader {
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
    color: mc('indigo', '500')
 | 
			
		||||
  }
 | 
			
		||||
  i.icon-check {
 | 
			
		||||
    color: mc('green', '500')
 | 
			
		||||
  }
 | 
			
		||||
  i.icon-square-cross {
 | 
			
		||||
    color: mc('red', '500')
 | 
			
		||||
  }
 | 
			
		||||
  i.icon-warning-outline {
 | 
			
		||||
    color: mc('orange', '500')
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .tst-welcome-leave-active, .tst-welcome-enter-active {
 | 
			
		||||
    transition: all .5s;
 | 
			
		||||
    overflow-y: hidden;
 | 
			
		||||
  }
 | 
			
		||||
  .tst-welcome-leave, .tst-welcome-enter-to {
 | 
			
		||||
    opacity: 1;
 | 
			
		||||
    max-height: 200px;
 | 
			
		||||
  }
 | 
			
		||||
  .tst-welcome-leave-to, .tst-welcome-enter {
 | 
			
		||||
    opacity: 0;
 | 
			
		||||
    max-height: 0;
 | 
			
		||||
    padding-top: 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .progress-bar {
 | 
			
		||||
    width: 150px;
 | 
			
		||||
    height: 10px;
 | 
			
		||||
    background-color: mc('indigo', '50');
 | 
			
		||||
    border:1px solid mc('indigo', '100');
 | 
			
		||||
    border-radius: 3px;
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    left: 15px;
 | 
			
		||||
    top: 21px;
 | 
			
		||||
    padding: 1px;
 | 
			
		||||
 | 
			
		||||
    > div {
 | 
			
		||||
      width: 5px;
 | 
			
		||||
      height: 6px;
 | 
			
		||||
      background-color: mc('indigo', '200');
 | 
			
		||||
      border-radius: 2px;
 | 
			
		||||
      transition: all 1s ease;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user