setup wizard intro + syscheck
This commit is contained in:
parent
48e7ea2e30
commit
d8fa6ecc27
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
assets/js/configure.js
Normal file
1
assets/js/configure.js
Normal file
@ -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}}})});
|
File diff suppressed because one or more lines are too long
46
client/js/configure.js
Normal file
46
client/js/configure.js
Normal file
@ -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,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
configure.js
56
configure.js
@ -14,6 +14,8 @@ module.exports = (port, spinner) => {
|
||||
const favicon = require('serve-favicon')
|
||||
const http = require('http')
|
||||
const path = require('path')
|
||||
const Promise = require('bluebird')
|
||||
const _ = require('lodash')
|
||||
|
||||
// ----------------------------------------
|
||||
// Define Express App
|
||||
@ -49,6 +51,60 @@ module.exports = (port, spinner) => {
|
||||
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
|
||||
// ----------------------------------------
|
||||
|
@ -27,6 +27,7 @@ const paths = {
|
||||
'./node_modules/socket.io-client/dist/socket.io.min.js',
|
||||
'./node_modules/jquery/dist/jquery.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-simple-upload/simpleUpload.min.js',
|
||||
'./node_modules/jquery-contextmenu/dist/jquery.contextMenu.min.js',
|
||||
|
@ -97,6 +97,7 @@
|
||||
"request": "^2.79.0",
|
||||
"search-index-adder": "github:NGPixel/search-index-adder",
|
||||
"search-index-searcher": "github:NGPixel/search-index-searcher",
|
||||
"semver": "^5.3.0",
|
||||
"serve-favicon": "^2.4.1",
|
||||
"simplemde": "^1.11.2",
|
||||
"socket.io": "^1.7.3",
|
||||
|
@ -15,7 +15,7 @@ html
|
||||
|
||||
// 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
|
||||
|
||||
@ -24,32 +24,56 @@ html
|
||||
#header-container
|
||||
nav.nav#header
|
||||
.nav-left
|
||||
a.nav-item(href='/')
|
||||
a.nav-item
|
||||
h1
|
||||
i.icon-layers
|
||||
| Wiki.js
|
||||
main
|
||||
.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
|
||||
span
|
||||
| Powered by
|
||||
|
Loading…
Reference in New Issue
Block a user