Browse Source

feat: config-manager component

pull/621/head
NGPixel 7 years ago
parent
commit
c94e2d5700
24 changed files with 461 additions and 155 deletions
  1. 4
      client/configure.js
  2. 2
      client/js/app.js
  3. 304
      client/js/components/config-manager.component.js
  4. 6
      client/js/components/editor-video.vue
  5. 1
      client/scss/app.scss
  6. 6
      client/scss/components/button.scss
  7. 61
      client/scss/components/config-manager.scss
  8. 11
      server/app/data.yml
  9. 83
      server/configure.js
  10. 2
      server/models/_relations.js
  11. 2
      server/models/comment.js
  12. 2
      server/models/document.js
  13. 2
      server/models/file.js
  14. 2
      server/models/folder.js
  15. 2
      server/models/group.js
  16. 2
      server/models/right.js
  17. 2
      server/models/setting.js
  18. 2
      server/models/tag.js
  19. 2
      server/models/user.js
  20. 2
      server/modules/auth.js
  21. 6
      server/modules/config.js
  22. 2
      server/modules/db.js
  23. 106
      server/views/configure/index.pug
  24. 2
      server/views/master.pug

4
client/configure.js

@ -1,4 +0,0 @@
'use strict'
require('./scss/configure.scss')
require('./js/configure.js')

2
client/js/app.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

@ -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)
}
}
}

6
client/js/components/editor-video.vue

@ -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 {

1
client/scss/app.scss

@ -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';

6
client/scss/components/button.scss

@ -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

@ -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;
}
}
}

11
server/app/data.yml

@ -24,6 +24,17 @@ defaults:
ha:
nodeuid: primary
readonly: false
site:
path: ''
title: Wiki.js
configNamespaces:
- auth
- features
- git
- logging
- site
- theme
- uploads
queues:
- gitSync
- uplClearTemp

83
server/configure.js

@ -1,12 +1,8 @@
'use strict'
const path = require('path')
module.exports = (port, spinner) => {
const path = require('path')
const ROOTPATH = process.cwd()
const SERVERPATH = path.join(ROOTPATH, 'server')
const IS_DEBUG = process.env.NODE_ENV === 'development'
/* global wiki */
module.exports = () => {
// ----------------------------------------
// Load modules
// ----------------------------------------
@ -26,28 +22,30 @@ module.exports = (port, spinner) => {
// Define Express App
// ----------------------------------------
var app = express()
let app = express()
app.use(compression())
var server
let server
// ----------------------------------------
// Public Assets
// ----------------------------------------
app.use(favicon(path.join(ROOTPATH, 'assets', 'favicon.ico')))
app.use(express.static(path.join(ROOTPATH, 'assets')))
app.use(favicon(path.join(wiki.ROOTPATH, 'assets', 'favicon.ico')))
app.use(express.static(path.join(wiki.ROOTPATH, 'assets')))
// ----------------------------------------
// View Engine Setup
// ----------------------------------------
app.set('views', path.join(SERVERPATH, 'views'))
app.set('views', path.join(wiki.SERVERPATH, 'views'))
app.set('view engine', 'pug')
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false }))
app.locals.config = wiki.config
app.locals.data = wiki.data
app.locals._ = require('lodash')
// ----------------------------------------
@ -55,22 +53,7 @@ module.exports = (port, spinner) => {
// ----------------------------------------
app.get('*', (req, res) => {
let langs = []
let conf = {}
try {
langs = yaml.safeLoad(fs.readFileSync(path.join(SERVERPATH, 'app/data.yml'), 'utf8')).langs
conf = yaml.safeLoad(fs.readFileSync(path.join(ROOTPATH, 'config.yml'), 'utf8'))
} catch (err) {
console.error(err)
}
res.render('configure/index', {
langs,
conf,
runmode: {
staticPort: (process.env.WIKI_JS_HEROKU || process.env.WIKI_JS_DOCKER),
staticMongo: (!_.isNil(process.env.WIKI_JS_HEROKU))
}
})
res.render('configure/index')
})
/**
@ -81,14 +64,14 @@ module.exports = (port, spinner) => {
() => {
const semver = require('semver')
if (!semver.satisfies(semver.clean(process.version), '>=6.9.0')) {
throw new Error('Node.js version is too old. Minimum is v6.11.1.')
throw new Error('Node.js version is too old. Minimum is 6.11.1.')
}
return 'Node.js ' + process.version + ' detected.'
return 'Node.js ' + process.version + ' detected. Minimum is 6.11.1.'
},
() => {
return Promise.try(() => {
require('crypto')
}).catch(err => { // eslint-disable-line handle-callback-err
}).catch(err => {
throw new Error('Crypto Node.js module is not available.')
}).return('Node.js Crypto module is available.')
},
@ -102,9 +85,9 @@ module.exports = (port, spinner) => {
}
let gitver = _.head(stdout.match(/[\d]+\.[\d]+(\.[\d]+)?/gi))
if (!gitver || !semver.satisfies(semver.clean(gitver), '>=2.7.4')) {
reject(new Error('Git version is too old. Minimum is v2.7.4.'))
reject(new Error('Git version is too old. Minimum is 2.7.4.'))
}
resolve('Git v' + gitver + ' detected. Minimum is v2.7.4.')
resolve('Git ' + gitver + ' detected. Minimum is 2.7.4.')
})
})
},
@ -118,8 +101,8 @@ module.exports = (port, spinner) => {
() => {
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
fs.accessSync(path.join(wiki.ROOTPATH, 'config.yml'), (fs.constants || fs).W_OK)
}).catch(err => {
throw new Error('config.yml file is not writable by Node.js process or was not created properly.')
}).return('config.yml is writable by the setup process.')
}
@ -174,8 +157,8 @@ module.exports = (port, spinner) => {
const exec = require('execa')
const url = require('url')
const dataDir = path.resolve(ROOTPATH, cfgHelper.parseConfigValue(req.body.pathData))
const gitDir = path.resolve(ROOTPATH, cfgHelper.parseConfigValue(req.body.pathRepo))
const dataDir = path.resolve(wiki.ROOTPATH, cfgHelper.parseConfigValue(req.body.pathData))
const gitDir = path.resolve(wiki.ROOTPATH, cfgHelper.parseConfigValue(req.body.pathRepo))
let gitRemoteUrl = ''
@ -315,7 +298,7 @@ module.exports = (port, spinner) => {
}
})
}),
fs.readFileAsync(path.join(ROOTPATH, 'config.yml'), 'utf8').then(confRaw => {
fs.readFileAsync(path.join(wiki.ROOTPATH, 'config.yml'), 'utf8').then(confRaw => {
let conf = yaml.safeLoad(confRaw)
conf.title = req.body.title
conf.host = req.body.host
@ -356,12 +339,12 @@ module.exports = (port, spinner) => {
return crypto.randomBytesAsync(32).then(buf => {
conf.sessionSecret = buf.toString('hex')
confRaw = yaml.safeDump(conf)
return fs.writeFileAsync(path.join(ROOTPATH, 'config.yml'), confRaw)
return fs.writeFileAsync(path.join(wiki.ROOTPATH, 'config.yml'), confRaw)
})
})
).then(() => {
if (process.env.IS_HEROKU) {
return fs.outputJsonAsync(path.join(SERVERPATH, 'app/heroku.json'), { configured: true })
return fs.outputJsonAsync(path.join(wiki.SERVERPATH, 'app/heroku.json'), { configured: true })
} else {
return true
}
@ -377,7 +360,7 @@ module.exports = (port, spinner) => {
*/
app.post('/restart', (req, res) => {
res.status(204).end()
server.destroy(() => {
/* server.destroy(() => {
spinner.text = 'Setup wizard terminated. Restarting in normal mode...'
_.delay(() => {
const exec = require('execa')
@ -386,7 +369,7 @@ module.exports = (port, spinner) => {
process.exit(0)
})
}, 1000)
})
}) */
})
// ----------------------------------------
@ -403,9 +386,9 @@ module.exports = (port, spinner) => {
res.status(err.status || 500)
res.send({
message: err.message,
error: IS_DEBUG ? err : {}
error: wiki.IS_DEBUG ? err : {}
})
spinner.fail(err.message)
wiki.logger.error(err.message)
process.exit(1)
})
@ -413,11 +396,11 @@ module.exports = (port, spinner) => {
// Start HTTP server
// ----------------------------------------
spinner.text = 'Starting HTTP server...'
wiki.logger.info(`HTTP Server on port: ${wiki.config.port}`)
app.set('port', port)
app.set('port', wiki.config.port)
server = http.createServer(app)
server.listen(port)
server.listen(wiki.config.port)
var openConnections = []
@ -443,10 +426,10 @@ module.exports = (port, spinner) => {
switch (error.code) {
case 'EACCES':
spinner.fail('Listening on port ' + port + ' requires elevated privileges!')
wiki.logger.error('Listening on port ' + wiki.config.port + ' requires elevated privileges!')
return process.exit(1)
case 'EADDRINUSE':
spinner.fail('Port ' + port + ' is already in use!')
wiki.logger.error('Port ' + wiki.config.port + ' is already in use!')
return process.exit(1)
default:
throw error
@ -454,6 +437,6 @@ module.exports = (port, spinner) => {
})
server.on('listening', () => {
spinner.text = 'Browse to http://localhost:' + port + ' to configure Wiki.js!'
wiki.logger.info('HTTP Server: RUNNING')
})
}

2
server/models/_relations.js

@ -1,5 +1,3 @@
'use strict'
/**
* Associate DB Model relations
*/

2
server/models/comment.js

@ -1,5 +1,3 @@
'use strict'
/**
* Comment schema
*/

2
server/models/document.js

@ -1,5 +1,3 @@
'use strict'
/**
* Document schema
*/

2
server/models/file.js

@ -1,5 +1,3 @@
'use strict'
/**
* File schema
*/

2
server/models/folder.js

@ -1,5 +1,3 @@
'use strict'
/**
* Folder schema
*/

2
server/models/group.js

@ -1,5 +1,3 @@
'use strict'
/**
* Group schema
*/

2
server/models/right.js

@ -1,5 +1,3 @@
'use strict'
/**
* Right schema
*/

2
server/models/setting.js

@ -1,5 +1,3 @@
'use strict'
/**
* Settings schema
*/

2
server/models/tag.js

@ -1,5 +1,3 @@
'use strict'
/**
* Tags schema
*/

2
server/models/user.js

@ -1,5 +1,3 @@
'use strict'
/* global wiki */
const Promise = require('bluebird')

2
server/modules/auth.js

@ -1,5 +1,3 @@
'use strict'
/* global wiki */
const _ = require('lodash')

6
server/modules/config.js

@ -1,5 +1,3 @@
'use strict'
/* global wiki */
const fs = require('fs')
@ -9,8 +7,6 @@ const path = require('path')
const cfgHelper = require('../helpers/config')
module.exports = {
SUBSETS: ['auth', 'features', 'git', 'logging', 'site', 'theme', 'uploads'],
/**
* Load root config from disk
*/
@ -64,7 +60,7 @@ module.exports = {
*/
loadFromDb(subsets) {
if (!_.isArray(subsets) || subsets.length === 0) {
subsets = this.SUBSETS
subsets = wiki.data.configNamespaces
}
return wiki.db.Setting.findAll({

2
server/modules/db.js

@ -110,7 +110,7 @@ module.exports = {
// -> Sync DB Schemas
syncSchemas() {
return self.inst.sync({
force: true,
force: false,
logging: log => { wiki.logger.log('verbose', log) }
})
},

106
server/views/configure/index.pug

@ -1,31 +1,9 @@
doctype html
html(data-logic='configure')
head
meta(http-equiv='X-UA-Compatible', content='IE=edge')
meta(charset='UTF-8')
title Wiki.js | Configure
// Favicon
each favsize in [32, 96, 16]
link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize, href='/favicons/favicon-' + favsize + 'x' + favsize + '.png')
// JS / CSS
script(type='text/javascript').
var appconfig = !{JSON.stringify(conf)};
var runmode = !{JSON.stringify(runmode)};
script(type='text/javascript', src='/js/vendor.js')
script(type='text/javascript', src='/js/configure.js')
extends ../master.pug
block body
body
#root
#header-container
nav.nav#header
.nav-left
a.nav-item
h1
i.icon-layers
| Wiki.js
main
#app.config-manager
config-manager(inline-template)
.container
transition(name='tst-welcome')
.welcome(v-if='state === "welcome" || state === "restart"')
@ -47,7 +25,7 @@ html(data-logic='configure')
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
.progress-bar: div(v-bind:style='{width: currentProgress}')
button.button.is-light-blue(v-on:click='proceedToSyscheck', v-bind:disabled='loading') Start
button.button.is-small.is-light-blue(v-on:click='proceedToSyscheck', v-bind:disabled='loading') Start
//- ==============================================
//- SYSTEM CHECK
@ -69,9 +47,9 @@ html(data-logic='configure')
p(v-if='!loading && !syscheck.ok') #[i.icon-square-cross] Error: {{ syscheck.error }}
.panel-footer
.progress-bar: div(v-bind:style='{width: currentProgress}')
button.button.is-light-blue.is-outlined(v-on:click='proceedToWelcome', v-bind:disabled='loading') Back
button.button.is-teal(v-on:click='proceedToSyscheck', v-if='!loading && !syscheck.ok') Check Again
button.button.is-light-blue(v-on:click='proceedToGeneral', v-if='loading || syscheck.ok', v-bind:disabled='loading') Continue
button.button.is-small.is-light-blue.is-outlined(v-on:click='proceedToWelcome', v-bind:disabled='loading') Back
button.button.is-small.is-teal(v-on:click='proceedToSyscheck', v-if='!loading && !syscheck.ok') Check Again
button.button.is-small.is-light-blue(v-on:click='proceedToGeneral', v-if='loading || syscheck.ok', v-bind:disabled='loading') Continue
//- ==============================================
//- GENERAL
@ -93,17 +71,16 @@ html(data-logic='configure')
label.label Host
input(type='text', placeholder='http://', v-model='conf.host', data-vv-scope='general', name='ipt-host', v-validate='{ required: true, min: 4 }')
span.desc The full URL to your wiki, without the trailing slash. E.g.: http://wiki.domain.com. Note that sub-folders are #[u not supported].
if !runmode.staticPort
section
p.control
label.label Port
input(type='text', placeholder='e.g. 80', v-model.number='conf.port', data-vv-scope='general', name='ipt-port', v-validate='{ required: true }')
span.desc The port on which Wiki.js will listen to. Usually port 80 if connecting directly, or a random port (e.g. 3000) if using a web server in front of it.<br>Set <strong>$(PORT)</strong> to use PORT environment variable.
section
p.control
label.label Port
input(type='text', placeholder='e.g. 80', v-model.number='conf.port', data-vv-scope='general', name='ipt-port', v-validate='{ required: true }')
span.desc The port on which Wiki.js will listen to. Usually port 80 if connecting directly, or a random port (e.g. 3000) if using a web server in front of it.<br>Set <strong>$(PORT)</strong> to use PORT environment variable.
section
p.control
label.label Site UI Language
select(v-model='conf.lang')
each lg in langs
select(v-model='conf.site.lang')
each lg in data.langs
option(value=lg.id)= lg.name
span.desc The language in which navigation, help and other UI elements will be displayed.
section
@ -113,8 +90,8 @@ html(data-logic='configure')
span.desc Should the site be accessible (read only) without login.
.panel-footer
.progress-bar: div(v-bind:style='{width: currentProgress}')
button.button.is-light-blue.is-outlined(v-on:click='proceedToSyscheck', v-bind:disabled='loading') Back
button.button.is-light-blue(v-on:click='proceedToConsiderations', v-bind:disabled='loading || errors.any("general")') Continue
button.button.is-small.is-light-blue.is-outlined(v-on:click='proceedToSyscheck', v-bind:disabled='loading') Back
button.button.is-small.is-light-blue(v-on:click='proceedToConsiderations', v-bind:disabled='loading || errors.any("general")') Continue
//- ==============================================
//- CONSIDERATIONS
@ -144,8 +121,8 @@ html(data-logic='configure')
p The host URL you specified is localhost. Unless you are a developer running Wiki.js locally on your machine, this is not recommended!
.panel-footer
.progress-bar: div(v-bind:style='{width: currentProgress}')
button.button.is-light-blue.is-outlined(v-on:click='proceedToGeneral', v-bind:disabled='loading') Back
button.button.is-light-blue(v-on:click='proceedToDb', v-bind:disabled='loading') Continue
button.button.is-small.is-light-blue.is-outlined(v-on:click='proceedToGeneral', v-bind:disabled='loading') Back
button.button.is-small.is-light-blue(v-on:click='proceedToDb', v-bind:disabled='loading') Continue
//- ==============================================
//- DATABASE
@ -166,8 +143,8 @@ html(data-logic='configure')
span.desc The connection string to your MongoDB server. Leave the default localhost value if MongoDB is installed on the same server.<br />You can also specify an environment variable as the connection string, e.g. $(MONGO_URI).
.panel-footer
.progress-bar: div(v-bind:style='{width: currentProgress}')
button.button.is-light-blue.is-outlined(v-on:click='proceedToConsiderations', v-bind:disabled='loading') Back
button.button.is-light-blue(v-on:click='proceedToDbcheck', v-bind:disabled='loading || errors.any("db")') Connect
button.button.is-small.is-light-blue.is-outlined(v-on:click='proceedToConsiderations', v-bind:disabled='loading') Back
button.button.is-small.is-light-blue(v-on:click='proceedToDbcheck', v-bind:disabled='loading || errors.any("db")') Connect
//- ==============================================
//- DATABASE CHECK
@ -186,9 +163,9 @@ html(data-logic='configure')
p(v-if='!loading && !dbcheck.ok') #[i.icon-square-cross] Error: {{ dbcheck.error }}
.panel-footer
.progress-bar: div(v-bind:style='{width: currentProgress}')
button.button.is-light-blue.is-outlined(v-on:click='proceedToDb', v-bind:disabled='loading') Back
button.button.is-teal(v-on:click='proceedToDbcheck', v-if='!loading && !dbcheck.ok') Try Again
button.button.is-light-blue(v-on:click='proceedToPaths', v-if='loading || dbcheck.ok', v-bind:disabled='loading') Continue
button.button.is-small.is-light-blue.is-outlined(v-on:click='proceedToDb', v-bind:disabled='loading') Back
button.button.is-small.is-teal(v-on:click='proceedToDbcheck', v-if='!loading && !dbcheck.ok') Try Again
button.button.is-small.is-light-blue(v-on:click='proceedToPaths', v-if='loading || dbcheck.ok', v-bind:disabled='loading') Continue
//- ==============================================
//- PATHS
@ -214,8 +191,8 @@ html(data-logic='configure')
span.desc The path where the local git repository will be created, used to store content in markdown files and uploads.
.panel-footer
.progress-bar: div(v-bind:style='{width: currentProgress}')
button.button.is-light-blue.is-outlined(v-on:click='proceedToDb', v-bind:disabled='loading') Back
button.button.is-light-blue(v-on:click='proceedToGit', v-bind:disabled='loading || errors.any("paths")') Continue
button.button.is-small.is-light-blue.is-outlined(v-on:click='proceedToDb', v-bind:disabled='loading') Back
button.button.is-small.is-light-blue(v-on:click='proceedToGit', v-bind:disabled='loading || errors.any("paths")') Continue
//- ==============================================
//- GIT
@ -279,9 +256,9 @@ html(data-logic='configure')
span.desc The default/fallback email to use when creating commits to the git repository.
.panel-footer
.progress-bar: div(v-bind:style='{width: currentProgress}')
button.button.is-light-blue.is-outlined(v-on:click='proceedToPaths', v-bind:disabled='loading') Back
button.button.is-light-blue.is-outlined(v-on:click='conf.gitUseRemote = false; proceedToGitCheck()', v-bind:disabled='loading') Skip this step
button.button.is-light-blue(v-on:click='conf.gitUseRemote = true; proceedToGitCheck()', v-bind:disabled='loading || errors.any("git")') Continue
button.button.is-small.is-light-blue.is-outlined(v-on:click='proceedToPaths', v-bind:disabled='loading') Back
button.button.is-small.is-light-blue.is-outlined(v-on:click='conf.gitUseRemote = false; proceedToGitCheck()', v-bind:disabled='loading') Skip this step
button.button.is-small.is-light-blue(v-on:click='conf.gitUseRemote = true; proceedToGitCheck()', v-bind:disabled='loading || errors.any("git")') Continue
//- ==============================================
//- GIT CHECK
@ -303,9 +280,9 @@ html(data-logic='configure')
p(v-if='!loading && !gitcheck.ok') #[i.icon-square-cross] Error: {{ gitcheck.error }}
.panel-footer
.progress-bar: div(v-bind:style='{width: currentProgress}')
button.button.is-light-blue.is-outlined(v-on:click='proceedToGit', v-bind:disabled='loading') Back
button.button.is-teal(v-on:click='proceedToGitCheck', v-if='!loading && !gitcheck.ok') Try Again
button.button.is-light-blue(v-on:click='proceedToAdmin', v-if='loading || gitcheck.ok', v-bind:disabled='loading') Continue
button.button.is-small.is-light-blue.is-outlined(v-on:click='proceedToGit', v-bind:disabled='loading') Back
button.button.is-small.is-teal(v-on:click='proceedToGitCheck', v-if='!loading && !gitcheck.ok') Try Again
button.button.is-small.is-light-blue(v-on:click='proceedToAdmin', v-if='loading || gitcheck.ok', v-bind:disabled='loading') Continue
//- ==============================================
//- ADMINISTRATOR ACCOUNT
@ -337,8 +314,8 @@ html(data-logic='configure')
span.desc Verify your password again.
.panel-footer
.progress-bar: div(v-bind:style='{width: currentProgress}')
button.button.is-light-blue.is-outlined(v-on:click='proceedToGit', v-bind:disabled='loading') Back
button.button.is-light-blue(v-on:click='proceedToFinal', v-bind:disabled='loading || errors.any("admin")') Continue
button.button.is-small.is-light-blue.is-outlined(v-on:click='proceedToGit', v-bind:disabled='loading') Back
button.button.is-small.is-light-blue(v-on:click='proceedToFinal', v-bind:disabled='loading || errors.any("admin")') Continue
//- ==============================================
//- FINAL
@ -359,9 +336,9 @@ html(data-logic='configure')
p(v-if='!loading && !final.ok') #[i.icon-square-cross] Error: {{ final.error }}
.panel-footer
.progress-bar: div(v-bind:style='{width: currentProgress}')
button.button.is-light-blue.is-outlined(v-on:click='proceedToAdmin', v-bind:disabled='loading') Back
button.button.is-teal(v-on:click='proceedToFinal', v-if='!loading && !final.ok') Try Again
button.button.is-green(v-on:click='finish', v-if='loading || final.ok', v-bind:disabled='loading') Start
button.button.is-small.is-light-blue.is-outlined(v-on:click='proceedToAdmin', v-bind:disabled='loading') Back
button.button.is-small.is-teal(v-on:click='proceedToFinal', v-if='!loading && !final.ok') Try Again
button.button.is-small.is-green(v-on:click='finish', v-if='loading || final.ok', v-bind:disabled='loading') Start
//- ==============================================
//- RESTART
@ -376,11 +353,4 @@ html(data-logic='configure')
p #[i.icon-loader.animated.rotateIn.infinite] Restarting Wiki.js in normal mode...
p You'll automatically be redirected to the homepage when ready. This usually takes about 30 seconds.
.panel-footer
button.button.is-green(disabled='disabled') Start
footer.footer
span
| Powered by
a(href='https://github.com/Requarks/wiki') Wiki.js
| .
block outside
button.button.is-small.is-green(disabled='disabled') Start

2
server/views/master.pug

@ -7,7 +7,7 @@ html
meta(name='theme-color', content='#009688')
meta(name='msapplication-TileColor', content='#009688')
meta(name='msapplication-TileImage', content=config.site.path + '/favicons/ms-icon-144x144.png')
title= config.title
title= config.site.title
//- Favicon
each favsize in [57, 60, 72, 76, 114, 120, 144, 152, 180]

Loading…
Cancel
Save