Преглед изворни кода

setup wizard intro + syscheck

NGPixel пре 8 година
родитељ
комит
d8fa6ecc27

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
assets/css/app.css


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
assets/css/configure.css


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
assets/css/error.css


+ 1 - 0
assets/js/configure.js

@@ -0,0 +1 @@
+"use strict";jQuery(document).ready(function(e){new Vue({el:"main",data:{loading:!1,state:"welcome",syscheck:{ok:!1,error:""},conf:{title:"Wiki",host:""}},methods:{proceedToSyscheck:function(e){var t=this;this.state="syscheck",this.loading=!0,_.delay(function(){axios.post("/syscheck").then(function(e){e.data.ok===!0?t.syscheck.ok=!0:(t.syscheck.ok=!1,t.syscheck.error=e.data.error),t.loading=!1}).catch(function(e){window.alert(e.message)})},1e3)},proceedToGeneral:function(e){this.state="general",this.loading=!0}}})});

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
assets/js/libs.js


+ 46 - 0
client/js/configure.js

@@ -0,0 +1,46 @@
+'use strict'
+
+/* global jQuery, _, Vue, axios */
+
+jQuery(document).ready(function ($) {
+  new Vue({ // eslint-disable-line no-new
+    el: 'main',
+    data: {
+      loading: false,
+      state: 'welcome',
+      syscheck: {
+        ok: false,
+        error: ''
+      },
+      conf: {
+        title: 'Wiki',
+        host: ''
+      }
+    },
+    methods: {
+      proceedToSyscheck: function (ev) {
+        let self = this
+        this.state = 'syscheck'
+        this.loading = true
+
+        _.delay(() => {
+          axios.post('/syscheck').then(resp => {
+            if (resp.data.ok === true) {
+              self.syscheck.ok = true
+            } else {
+              self.syscheck.ok = false
+              self.syscheck.error = resp.data.error
+            }
+            self.loading = false
+          }).catch(err => {
+            window.alert(err.message)
+          })
+        }, 1000)
+      },
+      proceedToGeneral: function (ev) {
+        this.state = 'general'
+        this.loading = true
+      }
+    }
+  })
+})

+ 25 - 0
client/scss/configure.scss

@@ -25,3 +25,28 @@ $primary: 'indigo';
 	}
 	}
 
 
 }
 }
+
+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')
+}
+
+.tst-welcome-leave-active {
+  transition: all .5s;
+  overflow-y: hidden;
+}
+.tst-welcome-leave {
+  opacity: 1;
+  max-height: 200px;
+}
+.tst-welcome-leave-to {
+  opacity: 0;
+  max-height: 0;
+  padding-top: 0;
+}

+ 56 - 0
configure.js

@@ -14,6 +14,8 @@ module.exports = (port, spinner) => {
   const favicon = require('serve-favicon')
   const favicon = require('serve-favicon')
   const http = require('http')
   const http = require('http')
   const path = require('path')
   const path = require('path')
+  const Promise = require('bluebird')
+  const _ = require('lodash')
 
 
   // ----------------------------------------
   // ----------------------------------------
   // Define Express App
   // Define Express App
@@ -49,6 +51,60 @@ module.exports = (port, spinner) => {
     res.render('configure/index')
     res.render('configure/index')
   })
   })
 
 
+  app.post('/syscheck', (req, res) => {
+    Promise.mapSeries([
+      () => {
+        const semver = require('semver')
+        if (!semver.satisfies(semver.clean(process.version), '>=4.6.0')) {
+          throw new Error('Node.js version is too old. Minimum is 4.6.0.')
+        }
+        return true
+      },
+      () => {
+        const os = require('os')
+        if (os.totalmem() < 1024 * 1024 * 512) {
+          throw new Error('Not enough memory. Minimum is 512 MB.')
+        }
+        return true
+      },
+      () => {
+        return Promise.try(() => {
+          require('crypto')
+        }).catch(err => { // eslint-disable-line handle-callback-err
+          throw new Error('Crypto Node.js module is not available.')
+        }).return(true)
+      },
+      () => {
+        const exec = require('child_process').exec
+        const semver = require('semver')
+        return new Promise((resolve, reject) => {
+          exec('git --version', (err, stdout, stderr) => {
+            if (err || stdout.length < 3) {
+              reject(new Error('Git is not installed or not reachable from PATH.'))
+            }
+            let gitver = _.chain(stdout.replace(/[^\d.]/g, '')).split('.').take(3).join('.').value()
+            if (!semver.satisfies(semver.clean(gitver), '>=2.11.0')) {
+              reject(new Error('Git version is too old. Minimum is 2.11.0.'))
+            }
+            resolve(true)
+          })
+        })
+      },
+      () => {
+        let fs = require('fs')
+        return Promise.try(() => {
+          fs.accessSync(path.join(ROOTPATH, 'config.yml'), (fs.constants || fs).W_OK)
+        }).catch(err => { // eslint-disable-line handle-callback-err
+          throw new Error('config.yml file is not writable by Node.js process or was not created properly.')
+        }).return(true)
+      }
+    ], test => { return test() }).then(results => {
+      res.json({ ok: true })
+    }).catch(err => {
+      res.json({ ok: false, error: err.message })
+    })
+  })
+
   // ----------------------------------------
   // ----------------------------------------
   // Error handling
   // Error handling
   // ----------------------------------------
   // ----------------------------------------

+ 1 - 0
gulpfile.js

@@ -27,6 +27,7 @@ const paths = {
       './node_modules/socket.io-client/dist/socket.io.min.js',
       './node_modules/socket.io-client/dist/socket.io.min.js',
       './node_modules/jquery/dist/jquery.min.js',
       './node_modules/jquery/dist/jquery.min.js',
       './node_modules/vue/dist/vue.min.js',
       './node_modules/vue/dist/vue.min.js',
+      './node_modules/axios/dist/axios.min.js',
       './node_modules/jquery-smooth-scroll/jquery.smooth-scroll.min.js',
       './node_modules/jquery-smooth-scroll/jquery.smooth-scroll.min.js',
       './node_modules/jquery-simple-upload/simpleUpload.min.js',
       './node_modules/jquery-simple-upload/simpleUpload.min.js',
       './node_modules/jquery-contextmenu/dist/jquery.contextMenu.min.js',
       './node_modules/jquery-contextmenu/dist/jquery.contextMenu.min.js',

+ 1 - 0
package.json

@@ -97,6 +97,7 @@
     "request": "^2.79.0",
     "request": "^2.79.0",
     "search-index-adder": "github:NGPixel/search-index-adder",
     "search-index-adder": "github:NGPixel/search-index-adder",
     "search-index-searcher": "github:NGPixel/search-index-searcher",
     "search-index-searcher": "github:NGPixel/search-index-searcher",
+    "semver": "^5.3.0",
     "serve-favicon": "^2.4.1",
     "serve-favicon": "^2.4.1",
     "simplemde": "^1.11.2",
     "simplemde": "^1.11.2",
     "socket.io": "^1.7.3",
     "socket.io": "^1.7.3",

+ 46 - 22
views/configure/index.pug

@@ -15,7 +15,7 @@ html
 
 
     // JS
     // JS
     script(type='text/javascript', src='/js/libs.js')
     script(type='text/javascript', src='/js/libs.js')
-    //script(type='text/javascript', src='/js/app.js')
+    script(type='text/javascript', src='/js/configure.js')
 
 
     block head
     block head
 
 
@@ -24,32 +24,56 @@ html
       #header-container
       #header-container
         nav.nav#header
         nav.nav#header
           .nav-left
           .nav-left
-            a.nav-item(href='/')
+            a.nav-item
               h1
               h1
                 i.icon-layers
                 i.icon-layers
                 | Wiki.js
                 | Wiki.js
       main
       main
         .container
         .container
-          .welcome(style={'padding-bottom': '5px'})
-            img(src='/favicons/android-icon-96x96.png', alt='Wiki.js')
-            h1 Welcome to Wiki.js!
-            h2(style={'margin-bottom': 0}) Fill in the fields below to get up and running.
-          .content
-            .panel
-              h2.panel-title
-                span General
-                i(v-if='loading')
-              .panel-content.form-sections
-                section
-                  p.control.is-fullwidth
-                    label.label Site Title
-                    input(type='text', placeholder='e.g. Wiki', v-model='title')
-                section
-                  p.control.is-fullwidth
-                    label.label Host
-                    input(type='text', placeholder='http://', v-model='host')
-              .panel-footer
-                button.button.is-indigo(v-on:click='add', v-bind:disabled='loading') Continue
+          transition(name='tst-welcome')
+            .welcome(style={'padding-bottom': '5px'}, v-if='state === "welcome"')
+              img(src='/favicons/android-icon-96x96.png', alt='Wiki.js')
+              h1 Welcome to Wiki.js!
+              h2(style={'margin-bottom': 0}) A modern, lightweight and powerful wiki app built on NodeJS, Git and Markdown
+          .content(v-cloak)
+            template(v-if='state === "welcome"')
+              .panel
+                h2.panel-title.is-featured
+                  span Introduction
+                  i(v-if='loading')
+                .panel-content.is-text
+                  p This installation wizard will guide you through the steps needed to get your wiki up and running in no time!
+                  p Detailed information about installation and usage can be found on the #[a(href='https://docs.wiki.requarks.io/') official documentation site]. #[br] Should you have any question or would like to report something that doesn't look right, feel free to create a new issue on the #[a(href='https://github.com/Requarks/wiki/issues') GitHub project].
+                .panel-footer
+                  button.button.is-indigo(v-on:click='proceedToSyscheck', v-bind:disabled='loading') Start
+            template(v-else-if='state === "syscheck"')
+              .panel
+                h2.panel-title.is-featured
+                  span System Check
+                  i(v-if='loading')
+                .panel-content.is-text
+                  p(v-if='loading') #[i.icon-loader.animated.rotateIn.infinite] Checking your system for compatibility...
+                  p(v-if='!loading && syscheck.ok') #[i.icon-check] Looks great! No issues so far.
+                  p(v-if='!loading && !syscheck.ok') #[i.icon-square-cross] Error: {{ syscheck.error }}
+                .panel-footer
+                  button.button.is-teal(v-on:click='proceedToSyscheck', v-if='!loading && !syscheck.ok') Check Again
+                  button.button.is-indigo(v-on:click='proceedToGeneral', v-if='loading || syscheck.ok', v-bind:disabled='loading') Continue
+            template(v-else-if='state === "general"')
+              .panel
+                h2.panel-title.is-featured
+                  span General
+                  i(v-if='loading')
+                .panel-content.form-sections
+                  section
+                    p.control.is-fullwidth
+                      label.label Site Title
+                      input(type='text', placeholder='e.g. Wiki', v-model='conf.title')
+                  section
+                    p.control.is-fullwidth
+                      label.label Host
+                      input(type='text', placeholder='http://', v-model='conf.host')
+                .panel-footer
+                  button.button.is-indigo(v-on:click='proceedToSyscheck', v-bind:disabled='loading') Continue
       footer.footer
       footer.footer
         span
         span
           | Powered by 
           | Powered by 

Неке датотеке нису приказане због велике количине промена