Commit fe0c4ce0 authored by NGPixel's avatar NGPixel

Fuse-box client scripts integration + deps update

parent f6c519c5
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -8,8 +8,6 @@ switch (logic) { ...@@ -8,8 +8,6 @@ switch (logic) {
require('./js/login.js') require('./js/login.js')
break break
default: default:
require('./node_modules/highlight.js/styles/tomorrow.css')
require('./node_modules/simplemde/dist/simplemde.min.css')
require('./scss/app.scss') require('./scss/app.scss')
require('./js/app.js') require('./js/app.js')
break break
......
...@@ -2,14 +2,14 @@ ...@@ -2,14 +2,14 @@
/* global alertsData */ /* global alertsData */
import jQuery from 'jquery' import $ from 'jquery'
import _ from 'lodash' import _ from 'lodash'
import Sticky from 'sticky-js'
import io from 'socket.io-client' import io from 'socket.io-client'
import Alerts from './components/alerts.js' import Alerts from './components/alerts.js'
/* eslint-disable spaced-comment */ import 'jquery-smooth-scroll'
import Sticky from 'sticky-js'
jQuery(document).ready(function ($) { $(() => {
// ==================================== // ====================================
// Scroll // Scroll
// ==================================== // ====================================
...@@ -45,24 +45,17 @@ jQuery(document).ready(function ($) { ...@@ -45,24 +45,17 @@ jQuery(document).ready(function ($) {
// Establish WebSocket connection // Establish WebSocket connection
// ==================================== // ====================================
var socket = io(window.location.origin) // eslint-disable-line no-unused-vars var socket = io(window.location.origin)
//=include components/search.js require('./components/search.js')(socket)
// ==================================== // ====================================
// Pages logic // Pages logic
// ==================================== // ====================================
//=include pages/view.js require('./pages/view.js')(alerts)
//=include pages/create.js // require('./pages/create.js')
//=include pages/edit.js require('./pages/edit.js')(alerts, socket)
//=include pages/source.js require('./pages/source.js')(alerts)
//=include pages/admin.js require('./pages/admin.js')(alerts)
}) })
//=include helpers/form.js
//=include helpers/pages.js
//=include components/alerts.js
/* eslint-enable spaced-comment */
/* global $, Vue, ace, mde, _ */ 'use strict'
import $ from 'jquery'
import Vue from 'vue'
import _ from 'lodash'
import * as ace from 'brace'
import 'brace/theme/tomorrow_night'
import 'brace/mode/markdown'
let modelist = ace.require('ace/ext/modelist')
let codeEditor = null let codeEditor = null
// ACE - Mode Loader // ACE - Mode Loader
...@@ -24,52 +30,56 @@ let loadAceMode = (m) => { ...@@ -24,52 +30,56 @@ let loadAceMode = (m) => {
// Vue Code Block instance // Vue Code Block instance
let vueCodeBlock = new Vue({ module.exports = (mde, mdeModalOpenState) => {
el: '#modal-editor-codeblock', let modelist = {} // ace.require('ace/ext/modelist')
data: { let vueCodeBlock = new Vue({
modes: modelist.modesByName, el: '#modal-editor-codeblock',
modeSelected: 'text', data: {
initContent: '' modes: modelist.modesByName,
}, modeSelected: 'text',
watch: { initContent: ''
modeSelected: (val, oldVal) => { },
loadAceMode(val).done(() => { watch: {
ace.require('ace/mode/' + val) modeSelected: (val, oldVal) => {
codeEditor.getSession().setMode('ace/mode/' + val) loadAceMode(val).done(() => {
}) ace.require('ace/mode/' + val)
} codeEditor.getSession().setMode('ace/mode/' + val)
}, })
methods: { }
open: (ev) => { },
$('#modal-editor-codeblock').addClass('is-active') methods: {
open: (ev) => {
$('#modal-editor-codeblock').addClass('is-active')
_.delay(() => { _.delay(() => {
codeEditor = ace.edit('codeblock-editor') codeEditor = ace.edit('codeblock-editor')
codeEditor.setTheme('ace/theme/tomorrow_night') codeEditor.setTheme('ace/theme/tomorrow_night')
codeEditor.getSession().setMode('ace/mode/' + vueCodeBlock.modeSelected) codeEditor.getSession().setMode('ace/mode/' + vueCodeBlock.modeSelected)
codeEditor.setOption('fontSize', '14px') codeEditor.setOption('fontSize', '14px')
codeEditor.setOption('hScrollBarAlwaysVisible', false) codeEditor.setOption('hScrollBarAlwaysVisible', false)
codeEditor.setOption('wrap', true) codeEditor.setOption('wrap', true)
codeEditor.setValue(vueCodeBlock.initContent) codeEditor.setValue(vueCodeBlock.initContent)
codeEditor.focus() codeEditor.focus()
codeEditor.renderer.updateFull() codeEditor.renderer.updateFull()
}, 300) }, 300)
}, },
cancel: (ev) => { cancel: (ev) => {
mdeModalOpenState = false // eslint-disable-line no-undef mdeModalOpenState = false // eslint-disable-line no-undef
$('#modal-editor-codeblock').removeClass('is-active') $('#modal-editor-codeblock').removeClass('is-active')
vueCodeBlock.initContent = '' vueCodeBlock.initContent = ''
}, },
insertCode: (ev) => { insertCode: (ev) => {
if (mde.codemirror.doc.somethingSelected()) { if (mde.codemirror.doc.somethingSelected()) {
mde.codemirror.execCommand('singleSelection') mde.codemirror.execCommand('singleSelection')
} }
let codeBlockText = '\n```' + vueCodeBlock.modeSelected + '\n' + codeEditor.getValue() + '\n```\n' let codeBlockText = '\n```' + vueCodeBlock.modeSelected + '\n' + codeEditor.getValue() + '\n```\n'
mde.codemirror.doc.replaceSelection(codeBlockText) mde.codemirror.doc.replaceSelection(codeBlockText)
vueCodeBlock.cancel() vueCodeBlock.cancel()
}
} }
} })
}) return vueCodeBlock
}
/* global $, Vue, mde, _ */ 'use strict'
import $ from 'jquery'
import Vue from 'vue'
import _ from 'lodash'
const videoRules = { const videoRules = {
'youtube': new RegExp(/(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/)|(?:(?:watch)?\?v(?:i)?=|&v(?:i)?=))([^#&?]*).*/, 'i'), 'youtube': new RegExp(/(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/)|(?:(?:watch)?\?v(?:i)?=|&v(?:i)?=))([^#&?]*).*/, 'i'),
...@@ -6,43 +10,46 @@ const videoRules = { ...@@ -6,43 +10,46 @@ const videoRules = {
'dailymotion': new RegExp(/(?:dailymotion\.com(?:\/embed)?(?:\/video|\/hub)|dai\.ly)\/([0-9a-z]+)(?:[-_0-9a-zA-Z]+(?:#video=)?([a-z0-9]+)?)?/, 'i') 'dailymotion': new RegExp(/(?:dailymotion\.com(?:\/embed)?(?:\/video|\/hub)|dai\.ly)\/([0-9a-z]+)(?:[-_0-9a-zA-Z]+(?:#video=)?([a-z0-9]+)?)?/, 'i')
} }
// Vue Video instance module.exports = (mde, mdeModalOpenState) => {
// Vue Video instance
let vueVideo = new Vue({
el: '#modal-editor-video',
data: {
link: ''
},
methods: {
open: (ev) => {
$('#modal-editor-video').addClass('is-active')
$('#modal-editor-video input').focus()
},
cancel: (ev) => {
mdeModalOpenState = false // eslint-disable-line no-undef
$('#modal-editor-video').removeClass('is-active')
vueVideo.link = ''
},
insertVideo: (ev) => {
if (mde.codemirror.doc.somethingSelected()) {
mde.codemirror.execCommand('singleSelection')
}
// Guess video type
let videoType = _.findKey(videoRules, (vr) => { let vueVideo = new Vue({
return vr.test(vueVideo.link) el: '#modal-editor-video',
}) data: {
if (_.isNil(videoType)) { link: ''
videoType = 'video' },
methods: {
open: (ev) => {
$('#modal-editor-video').addClass('is-active')
$('#modal-editor-video input').focus()
},
cancel: (ev) => {
mdeModalOpenState = false // eslint-disable-line no-undef
$('#modal-editor-video').removeClass('is-active')
vueVideo.link = ''
},
insertVideo: (ev) => {
if (mde.codemirror.doc.somethingSelected()) {
mde.codemirror.execCommand('singleSelection')
}
// Guess video type
let videoType = _.findKey(videoRules, (vr) => {
return vr.test(vueVideo.link)
})
if (_.isNil(videoType)) {
videoType = 'video'
}
// Insert video tag
let videoText = '[video](' + vueVideo.link + '){.' + videoType + '}\n'
mde.codemirror.doc.replaceSelection(videoText)
vueVideo.cancel()
} }
// Insert video tag
let videoText = '[video](' + vueVideo.link + '){.' + videoType + '}\n'
mde.codemirror.doc.replaceSelection(videoText)
vueVideo.cancel()
} }
} })
}) return vueVideo
}
'use strict' 'use strict'
/* global $, Vue, _, socket */ import $ from 'jquery'
import _ from 'lodash'
import Vue from 'vue'
if ($('#search-input').length) { module.exports = (socket) => {
$('#search-input').focus() if ($('#search-input').length) {
$('#search-input').focus()
$('.searchresults').css('display', 'block') $('.searchresults').css('display', 'block')
var vueHeader = new Vue({ var vueHeader = new Vue({
el: '#header-container', el: '#header-container',
data: { data: {
searchq: '', searchq: '',
searchres: [], searchres: [],
searchsuggest: [], searchsuggest: [],
searchload: 0, searchload: 0,
searchactive: false, searchactive: false,
searchmoveidx: 0, searchmoveidx: 0,
searchmovekey: '', searchmovekey: '',
searchmovearr: [] searchmovearr: []
},
watch: {
searchq: (val, oldVal) => {
vueHeader.searchmoveidx = 0
if (val.length >= 3) {
vueHeader.searchactive = true
vueHeader.searchload++
socket.emit('search', { terms: val }, (data) => {
vueHeader.searchres = data.match
vueHeader.searchsuggest = data.suggest
vueHeader.searchmovearr = _.concat([], vueHeader.searchres, vueHeader.searchsuggest)
if (vueHeader.searchload > 0) { vueHeader.searchload-- }
})
} else {
vueHeader.searchactive = false
vueHeader.searchres = []
vueHeader.searchsuggest = []
vueHeader.searchmovearr = []
vueHeader.searchload = 0
}
}, },
searchmoveidx: (val, oldVal) => { watch: {
if (val > 0) { searchq: (val, oldVal) => {
vueHeader.searchmovekey = (vueHeader.searchmovearr[val - 1]) vueHeader.searchmoveidx = 0
? 'res.' + vueHeader.searchmovearr[val - 1].entryPath if (val.length >= 3) {
: 'sug.' + vueHeader.searchmovearr[val - 1] vueHeader.searchactive = true
} else { vueHeader.searchload++
vueHeader.searchmovekey = '' socket.emit('search', { terms: val }, (data) => {
vueHeader.searchres = data.match
vueHeader.searchsuggest = data.suggest
vueHeader.searchmovearr = _.concat([], vueHeader.searchres, vueHeader.searchsuggest)
if (vueHeader.searchload > 0) { vueHeader.searchload-- }
})
} else {
vueHeader.searchactive = false
vueHeader.searchres = []
vueHeader.searchsuggest = []
vueHeader.searchmovearr = []
vueHeader.searchload = 0
}
},
searchmoveidx: (val, oldVal) => {
if (val > 0) {
vueHeader.searchmovekey = (vueHeader.searchmovearr[val - 1])
? 'res.' + vueHeader.searchmovearr[val - 1].entryPath
: 'sug.' + vueHeader.searchmovearr[val - 1]
} else {
vueHeader.searchmovekey = ''
}
} }
}
},
methods: {
useSuggestion: (sug) => {
vueHeader.searchq = sug
}, },
closeSearch: () => { methods: {
vueHeader.searchq = '' useSuggestion: (sug) => {
}, vueHeader.searchq = sug
moveSelectSearch: () => { },
if (vueHeader.searchmoveidx < 1) { return } closeSearch: () => {
let i = vueHeader.searchmoveidx - 1 vueHeader.searchq = ''
},
moveSelectSearch: () => {
if (vueHeader.searchmoveidx < 1) { return }
let i = vueHeader.searchmoveidx - 1
if (vueHeader.searchmovearr[i]) { if (vueHeader.searchmovearr[i]) {
window.location.assign('/' + vueHeader.searchmovearr[i].entryPath) window.location.assign('/' + vueHeader.searchmovearr[i].entryPath)
} else { } else {
vueHeader.searchq = vueHeader.searchmovearr[i] vueHeader.searchq = vueHeader.searchmovearr[i]
} }
}, },
moveDownSearch: () => { moveDownSearch: () => {
if (vueHeader.searchmoveidx < vueHeader.searchmovearr.length) { if (vueHeader.searchmoveidx < vueHeader.searchmovearr.length) {
vueHeader.searchmoveidx++ vueHeader.searchmoveidx++
} }
}, },
moveUpSearch: () => { moveUpSearch: () => {
if (vueHeader.searchmoveidx > 0) { if (vueHeader.searchmoveidx > 0) {
vueHeader.searchmoveidx-- vueHeader.searchmoveidx--
}
} }
} }
} })
})
$('main').on('click', vueHeader.closeSearch) $('main').on('click', vueHeader.closeSearch)
}
} }
/* eslint-disable no-unused-vars */ 'use strict'
function setInputSelection (input, startPos, endPos) { module.exports = {
input.focus() /**
if (typeof input.selectionStart !== 'undefined') { * Set Input Selection
input.selectionStart = startPos * @param {DOMElement} input The input element
input.selectionEnd = endPos * @param {number} startPos The starting position
} else if (document.selection && document.selection.createRange) { * @param {nunber} endPos The ending position
// IE branch */
input.select() setInputSelection: (input, startPos, endPos) => {
var range = document.selection.createRange() input.focus()
range.collapse(true) if (typeof input.selectionStart !== 'undefined') {
range.moveEnd('character', endPos) input.selectionStart = startPos
range.moveStart('character', startPos) input.selectionEnd = endPos
range.select() } else if (document.selection && document.selection.createRange) {
// IE branch
input.select()
var range = document.selection.createRange()
range.collapse(true)
range.moveEnd('character', endPos)
range.moveStart('character', startPos)
range.select()
}
} }
} }
/* eslint-enable no-unused-vars */
/* global _ */ 'use strict'
/* eslint-disable no-unused-vars */
function makeSafePath (rawPath) { import _ from 'lodash'
let rawParts = _.split(_.trim(rawPath), '/')
rawParts = _.map(rawParts, (r) => {
return _.kebabCase(_.deburr(_.trim(r)))
})
return _.join(_.filter(rawParts, (r) => { return !_.isEmpty(r) }), '/') module.exports = {
} /**
* Convert raw path to safe path
* @param {string} rawPath Raw path
* @returns {string} Safe path
*/
makeSafePath: (rawPath) => {
let rawParts = _.split(_.trim(rawPath), '/')
rawParts = _.map(rawParts, (r) => {
return _.kebabCase(_.deburr(_.trim(r)))
})
/* eslint-enable no-unused-vars */ return _.join(_.filter(rawParts, (r) => { return !_.isEmpty(r) }), '/')
}
}
/* global $, Vue, alerts */ 'use strict'
import $ from 'jquery'
import Vue from 'vue'
// Vue Create User instance // Vue Create User instance
let vueCreateUser = new Vue({ module.exports = (alerts) => {
el: '#modal-admin-users-create', let vueCreateUser = new Vue({
data: { el: '#modal-admin-users-create',
email: '', data: {
provider: 'local', email: '',
password: '', provider: 'local',
name: '', password: '',
loading: false name: '',
}, loading: false
methods: {
open: (ev) => {
$('#modal-admin-users-create').addClass('is-active')
$('#modal-admin-users-create input').first().focus()
},
cancel: (ev) => {
$('#modal-admin-users-create').removeClass('is-active')
vueCreateUser.email = ''
vueCreateUser.provider = 'local'
}, },
create: (ev) => { methods: {
vueCreateUser.loading = true open: (ev) => {
$.ajax('/admin/users/create', { $('#modal-admin-users-create').addClass('is-active')
data: { $('#modal-admin-users-create input').first().focus()
email: vueCreateUser.email, },
provider: vueCreateUser.provider, cancel: (ev) => {
password: vueCreateUser.password, $('#modal-admin-users-create').removeClass('is-active')
name: vueCreateUser.name vueCreateUser.email = ''
}, vueCreateUser.provider = 'local'
dataType: 'json', },
method: 'POST' create: (ev) => {
}).then((rData, rStatus, rXHR) => { vueCreateUser.loading = true
vueCreateUser.loading = false $.ajax('/admin/users/create', {
if (rData.ok) { data: {
vueCreateUser.cancel() email: vueCreateUser.email,
window.location.reload(true) provider: vueCreateUser.provider,
} else { password: vueCreateUser.password,
alerts.pushError('Something went wrong', rData.msg) name: vueCreateUser.name
} },
}, (rXHR, rStatus, err) => { dataType: 'json',
vueCreateUser.loading = false method: 'POST'
alerts.pushError('Error', rXHR.responseJSON.msg) }).then((rData, rStatus, rXHR) => {
}) vueCreateUser.loading = false
if (rData.ok) {
vueCreateUser.cancel()
window.location.reload(true)
} else {
alerts.pushError('Something went wrong', rData.msg)
}
}, (rXHR, rStatus, err) => {
vueCreateUser.loading = false
alerts.pushError('Error', rXHR.responseJSON.msg)
})
}
} }
} })
})
$('.btn-create-prompt').on('click', vueCreateUser.open) $('.btn-create-prompt').on('click', vueCreateUser.open)
}
/* global $, Vue, usrData, alerts */ 'use strict'
/* global usrData */
'use strict'
import $ from 'jquery'
import Vue from 'vue'
// Vue Delete User instance // Vue Delete User instance
let vueDeleteUser = new Vue({ module.exports = (alerts) => {
el: '#modal-admin-users-delete', let vueDeleteUser = new Vue({
data: { el: '#modal-admin-users-delete',
loading: false data: {
}, loading: false
methods: {
open: (ev) => {
$('#modal-admin-users-delete').addClass('is-active')
},
cancel: (ev) => {
$('#modal-admin-users-delete').removeClass('is-active')
}, },
deleteUser: (ev) => { methods: {
vueDeleteUser.loading = true open: (ev) => {
$.ajax('/admin/users/' + usrData._id, { $('#modal-admin-users-delete').addClass('is-active')
dataType: 'json', },
method: 'DELETE' cancel: (ev) => {
}).then((rData, rStatus, rXHR) => { $('#modal-admin-users-delete').removeClass('is-active')
vueDeleteUser.loading = false },
vueDeleteUser.cancel() deleteUser: (ev) => {
window.location.assign('/admin/users') vueDeleteUser.loading = true
}, (rXHR, rStatus, err) => { $.ajax('/admin/users/' + usrData._id, {
vueDeleteUser.loading = false dataType: 'json',
alerts.pushError('Error', rXHR.responseJSON.msg) method: 'DELETE'
}) }).then((rData, rStatus, rXHR) => {
vueDeleteUser.loading = false
vueDeleteUser.cancel()
window.location.assign('/admin/users')
}, (rXHR, rStatus, err) => {
vueDeleteUser.loading = false
alerts.pushError('Error', rXHR.responseJSON.msg)
})
}
} }
} })
})
$('.btn-deluser-prompt').on('click', vueDeleteUser.open) $('.btn-deluser-prompt').on('click', vueDeleteUser.open)
}
/* global $, _, currentBasePath */ 'use strict'
import $ from 'jquery'
import _ from 'lodash'
import { setInputSelection } from '../helpers/form'
import { makeSafePath } from '../helpers/pages'
// -> Create New Document // -> Create New Document
let suggestedCreatePath = currentBasePath + '/new-page' module.exports = (currentBasePath) => {
let suggestedCreatePath = currentBasePath + '/new-page'
$('.btn-create-prompt').on('click', (ev) => { $('.btn-create-prompt').on('click', (ev) => {
$('#txt-create-prompt').val(suggestedCreatePath) $('#txt-create-prompt').val(suggestedCreatePath)
$('#modal-create-prompt').toggleClass('is-active') $('#modal-create-prompt').toggleClass('is-active')
setInputSelection($('#txt-create-prompt').get(0), currentBasePath.length + 1, suggestedCreatePath.length) // eslint-disable-line no-undef setInputSelection($('#txt-create-prompt').get(0), currentBasePath.length + 1, suggestedCreatePath.length)
$('#txt-create-prompt').removeClass('is-danger').next().addClass('is-hidden') $('#txt-create-prompt').removeClass('is-danger').next().addClass('is-hidden')
}) })
$('#txt-create-prompt').on('keypress', (ev) => { $('#txt-create-prompt').on('keypress', (ev) => {
if (ev.which === 13) { if (ev.which === 13) {
$('.btn-create-go').trigger('click') $('.btn-create-go').trigger('click')
} }
}) })
$('.btn-create-go').on('click', (ev) => { $('.btn-create-go').on('click', (ev) => {
let newDocPath = makeSafePath($('#txt-create-prompt').val()) // eslint-disable-line no-undef let newDocPath = makeSafePath($('#txt-create-prompt').val())
if (_.isEmpty(newDocPath)) { if (_.isEmpty(newDocPath)) {
$('#txt-create-prompt').addClass('is-danger').next().removeClass('is-hidden') $('#txt-create-prompt').addClass('is-danger').next().removeClass('is-hidden')
} else { } else {
$('#txt-create-prompt').parent().addClass('is-loading') $('#txt-create-prompt').parent().addClass('is-loading')
window.location.assign('/create/' + newDocPath) window.location.assign('/create/' + newDocPath)
} }
}) })
}
/* global $, _, alerts, currentBasePath */ 'use strict'
import $ from 'jquery'
import _ from 'lodash'
import { makeSafePath } from '../helpers/form'
import { setInputSelection } from '../helpers/pages'
// -> Move Existing Document // -> Move Existing Document
if (currentBasePath !== '') { module.exports = (currentBasePath, alerts) => {
$('.btn-move-prompt').removeClass('is-hidden') if (currentBasePath !== '') {
} $('.btn-move-prompt').removeClass('is-hidden')
}
let moveInitialDocument = _.lastIndexOf(currentBasePath, '/') + 1 let moveInitialDocument = _.lastIndexOf(currentBasePath, '/') + 1
$('.btn-move-prompt').on('click', (ev) => { $('.btn-move-prompt').on('click', (ev) => {
$('#txt-move-prompt').val(currentBasePath) $('#txt-move-prompt').val(currentBasePath)
$('#modal-move-prompt').toggleClass('is-active') $('#modal-move-prompt').toggleClass('is-active')
setInputSelection($('#txt-move-prompt').get(0), moveInitialDocument, currentBasePath.length) // eslint-disable-line no-undef setInputSelection($('#txt-move-prompt').get(0), moveInitialDocument, currentBasePath.length)
$('#txt-move-prompt').removeClass('is-danger').next().addClass('is-hidden') $('#txt-move-prompt').removeClass('is-danger').next().addClass('is-hidden')
}) })
$('#txt-move-prompt').on('keypress', (ev) => { $('#txt-move-prompt').on('keypress', (ev) => {
if (ev.which === 13) { if (ev.which === 13) {
$('.btn-move-go').trigger('click') $('.btn-move-go').trigger('click')
} }
}) })
$('.btn-move-go').on('click', (ev) => { $('.btn-move-go').on('click', (ev) => {
let newDocPath = makeSafePath($('#txt-move-prompt').val()) // eslint-disable-line no-undef let newDocPath = makeSafePath($('#txt-move-prompt').val())
if (_.isEmpty(newDocPath) || newDocPath === currentBasePath || newDocPath === 'home') { if (_.isEmpty(newDocPath) || newDocPath === currentBasePath || newDocPath === 'home') {
$('#txt-move-prompt').addClass('is-danger').next().removeClass('is-hidden') $('#txt-move-prompt').addClass('is-danger').next().removeClass('is-hidden')
} else { } else {
$('#txt-move-prompt').parent().addClass('is-loading') $('#txt-move-prompt').parent().addClass('is-loading')
$.ajax(window.location.href, { $.ajax(window.location.href, {
data: { data: {
move: newDocPath move: newDocPath
}, },
dataType: 'json', dataType: 'json',
method: 'PUT' method: 'PUT'
}).then((rData, rStatus, rXHR) => { }).then((rData, rStatus, rXHR) => {
if (rData.ok) { if (rData.ok) {
window.location.assign('/' + newDocPath) window.location.assign('/' + newDocPath)
} else { } else {
alerts.pushError('Something went wrong', rData.error) alerts.pushError('Something went wrong', rData.error)
} }
}, (rXHR, rStatus, err) => { }, (rXHR, rStatus, err) => {
alerts.pushError('Something went wrong', 'Save operation failed.') alerts.pushError('Something went wrong', 'Save operation failed.')
}) })
} }
}) })
}
/* global $, Vue, alerts, _, usrData, usrDataName */ 'use strict'
if ($('#page-type-admin-profile').length) { /* global usrData, usrDataName */
let vueProfile = new Vue({
el: '#page-type-admin-profile',
data: {
password: '********',
passwordVerify: '********',
name: ''
},
methods: {
saveUser: (ev) => {
if (vueProfile.password !== vueProfile.passwordVerify) {
alerts.pushError('Error', "Passwords don't match!")
return
}
$.post(window.location.href, {
password: vueProfile.password,
name: vueProfile.name
}).done((resp) => {
alerts.pushSuccess('Saved successfully', 'Changes have been applied.')
}).fail((jqXHR, txtStatus, resp) => {
alerts.pushError('Error', resp)
})
}
},
created: function () {
this.name = usrDataName
}
})
} else if ($('#page-type-admin-users').length) {
/* eslint-disable spaced-comment */ import $ from 'jquery'
//=include ../modals/admin-users-create.js import _ from 'lodash'
/* eslint-enable spaced-comment */ import Vue from 'vue'
} else if ($('#page-type-admin-users-edit').length) { module.exports = (alerts) => {
let vueEditUser = new Vue({ if ($('#page-type-admin-profile').length) {
el: '#page-type-admin-users-edit', let vueProfile = new Vue({
data: { el: '#page-type-admin-profile',
id: '', data: {
email: '', password: '********',
password: '********', passwordVerify: '********',
name: '', name: ''
rights: [],
roleoverride: 'none'
},
methods: {
addRightsRow: (ev) => {
vueEditUser.rights.push({
role: 'write',
path: '/',
exact: false,
deny: false
})
},
removeRightsRow: (idx) => {
_.pullAt(vueEditUser.rights, idx)
vueEditUser.$forceUpdate()
}, },
saveUser: (ev) => { methods: {
let formattedRights = _.cloneDeep(vueEditUser.rights) saveUser: (ev) => {
switch (vueEditUser.roleoverride) { if (vueProfile.password !== vueProfile.passwordVerify) {
case 'admin': alerts.pushError('Error', "Passwords don't match!")
formattedRights.push({ return
role: 'admin', }
path: '/', $.post(window.location.href, {
exact: false, password: vueProfile.password,
deny: false name: vueProfile.name
}) }).done((resp) => {
break alerts.pushSuccess('Saved successfully', 'Changes have been applied.')
}).fail((jqXHR, txtStatus, resp) => {
alerts.pushError('Error', resp)
})
} }
$.post(window.location.href, {
password: vueEditUser.password,
name: vueEditUser.name,
rights: JSON.stringify(formattedRights)
}).done((resp) => {
alerts.pushSuccess('Saved successfully', 'Changes have been applied.')
}).fail((jqXHR, txtStatus, resp) => {
alerts.pushError('Error', resp)
})
}
},
created: function () {
this.id = usrData._id
this.email = usrData.email
this.name = usrData.name
if (_.find(usrData.rights, { role: 'admin' })) {
this.rights = _.reject(usrData.rights, ['role', 'admin'])
this.roleoverride = 'admin'
} else {
this.rights = usrData.rights
}
}
})
/* eslint-disable spaced-comment */
//=include ../modals/admin-users-delete.js
/* eslint-enable spaced-comment */
} else if ($('#page-type-admin-settings').length) {
let vueSettings = new Vue({ // eslint-disable-line no-unused-vars
el: '#page-type-admin-settings',
data: {
upgradeModal: {
state: false,
step: 'confirm',
mode: 'upgrade',
error: 'Something went wrong.'
}
},
methods: {
upgrade: (ev) => {
vueSettings.upgradeModal.mode = 'upgrade'
vueSettings.upgradeModal.step = 'confirm'
vueSettings.upgradeModal.state = true
},
reinstall: (ev) => {
vueSettings.upgradeModal.mode = 're-install'
vueSettings.upgradeModal.step = 'confirm'
vueSettings.upgradeModal.state = true
}, },
upgradeCancel: (ev) => { created: function () {
vueSettings.upgradeModal.state = false this.name = usrDataName
}, }
upgradeStart: (ev) => { })
vueSettings.upgradeModal.step = 'running' } else if ($('#page-type-admin-users').length) {
$.post('/admin/settings/install', { require('../modals/admin-users-create.js')(alerts)
mode: vueSettings.upgradeModal.mode } else if ($('#page-type-admin-users-edit').length) {
}).done((resp) => { let vueEditUser = new Vue({
// todo el: '#page-type-admin-users-edit',
}).fail((jqXHR, txtStatus, resp) => { data: {
vueSettings.upgradeModal.step = 'error' id: '',
vueSettings.upgradeModal.error = jqXHR.responseText email: '',
}) password: '********',
name: '',
rights: [],
roleoverride: 'none'
}, },
flushcache: (ev) => { methods: {
window.alert('Coming soon!') addRightsRow: (ev) => {
vueEditUser.rights.push({
role: 'write',
path: '/',
exact: false,
deny: false
})
},
removeRightsRow: (idx) => {
_.pullAt(vueEditUser.rights, idx)
vueEditUser.$forceUpdate()
},
saveUser: (ev) => {
let formattedRights = _.cloneDeep(vueEditUser.rights)
switch (vueEditUser.roleoverride) {
case 'admin':
formattedRights.push({
role: 'admin',
path: '/',
exact: false,
deny: false
})
break
}
$.post(window.location.href, {
password: vueEditUser.password,
name: vueEditUser.name,
rights: JSON.stringify(formattedRights)
}).done((resp) => {
alerts.pushSuccess('Saved successfully', 'Changes have been applied.')
}).fail((jqXHR, txtStatus, resp) => {
alerts.pushError('Error', resp)
})
}
}, },
resetaccounts: (ev) => { created: function () {
window.alert('Coming soon!') this.id = usrData._id
this.email = usrData.email
this.name = usrData.name
if (_.find(usrData.rights, { role: 'admin' })) {
this.rights = _.reject(usrData.rights, ['role', 'admin'])
this.roleoverride = 'admin'
} else {
this.rights = usrData.rights
}
}
})
require('../modals/admin-users-delete.js')(alerts)
} else if ($('#page-type-admin-settings').length) {
let vueSettings = new Vue({ // eslint-disable-line no-unused-vars
el: '#page-type-admin-settings',
data: {
upgradeModal: {
state: false,
step: 'confirm',
mode: 'upgrade',
error: 'Something went wrong.'
}
}, },
flushsessions: (ev) => { methods: {
window.alert('Coming soon!') upgrade: (ev) => {
vueSettings.upgradeModal.mode = 'upgrade'
vueSettings.upgradeModal.step = 'confirm'
vueSettings.upgradeModal.state = true
},
reinstall: (ev) => {
vueSettings.upgradeModal.mode = 're-install'
vueSettings.upgradeModal.step = 'confirm'
vueSettings.upgradeModal.state = true
},
upgradeCancel: (ev) => {
vueSettings.upgradeModal.state = false
},
upgradeStart: (ev) => {
vueSettings.upgradeModal.step = 'running'
$.post('/admin/settings/install', {
mode: vueSettings.upgradeModal.mode
}).done((resp) => {
// todo
}).fail((jqXHR, txtStatus, resp) => {
vueSettings.upgradeModal.step = 'error'
vueSettings.upgradeModal.error = jqXHR.responseText
})
},
flushcache: (ev) => {
window.alert('Coming soon!')
},
resetaccounts: (ev) => {
window.alert('Coming soon!')
},
flushsessions: (ev) => {
window.alert('Coming soon!')
}
} }
} })
}) }
} }
/* global $ */ 'use strict'
if ($('#page-type-edit').length) { import $ from 'jquery'
let pageEntryPath = $('#page-type-edit').data('entrypath') // eslint-disable-line no-unused-vars
// let pageCleanExit = false
// -> Discard module.exports = (alerts, socket) => {
if ($('#page-type-edit').length) {
let pageEntryPath = $('#page-type-edit').data('entrypath')
// let pageCleanExit = false
$('.btn-edit-discard').on('click', (ev) => { // -> Discard
$('#modal-edit-discard').toggleClass('is-active')
})
// window.onbeforeunload = function () { $('.btn-edit-discard').on('click', (ev) => {
// return (pageCleanExit) ? true : 'Unsaved modifications will be lost. Are you sure you want to navigate away from this page?' $('#modal-edit-discard').toggleClass('is-active')
// } })
/* eslint-disable spaced-comment */ // window.onbeforeunload = function () {
//=include ../components/editor.js // return (pageCleanExit) ? true : 'Unsaved modifications will be lost. Are you sure you want to navigate away from this page?'
/* eslint-enable spaced-comment */ // }
require('../components/editor.js')(alerts, pageEntryPath, socket)
}
} }
/* global $, ace */ 'use strict'
if ($('#page-type-source').length) { import $ from 'jquery'
var scEditor = ace.edit('source-display') import * as ace from 'brace'
scEditor.setTheme('ace/theme/tomorrow_night') import 'brace/theme/tomorrow_night'
scEditor.getSession().setMode('ace/mode/markdown') import 'brace/mode/markdown'
scEditor.setOption('fontSize', '14px')
scEditor.setOption('hScrollBarAlwaysVisible', false)
scEditor.setOption('wrap', true)
scEditor.setReadOnly(true)
scEditor.renderer.updateFull()
let currentBasePath = ($('#page-type-source').data('entrypath') !== 'home') ? $('#page-type-source').data('entrypath') : '' // eslint-disable-line no-unused-vars module.exports = (alerts) => {
if ($('#page-type-source').length) {
var scEditor = ace.edit('source-display')
scEditor.setTheme('ace/theme/tomorrow_night')
scEditor.getSession().setMode('ace/mode/markdown')
scEditor.setOption('fontSize', '14px')
scEditor.setOption('hScrollBarAlwaysVisible', false)
scEditor.setOption('wrap', true)
scEditor.setReadOnly(true)
scEditor.renderer.updateFull()
/* eslint-disable spaced-comment */ let currentBasePath = ($('#page-type-source').data('entrypath') !== 'home') ? $('#page-type-source').data('entrypath') : ''
//=include ../modals/create.js
//=include ../modals/move.js require('../modals/create.js')(currentBasePath)
/* eslint-enable spaced-comment */ require('../modals/move.js')(currentBasePath, alerts)
}
} }
/* global $ */ 'use strict'
if ($('#page-type-view').length) { import $ from 'jquery'
let currentBasePath = ($('#page-type-view').data('entrypath') !== 'home') ? $('#page-type-view').data('entrypath') : '' // eslint-disable-line no-unused-vars
/* eslint-disable spaced-comment */ module.exports = (alerts) => {
//=include ../modals/create.js if ($('#page-type-view').length) {
//=include ../modals/move.js let currentBasePath = ($('#page-type-view').data('entrypath') !== 'home') ? $('#page-type-view').data('entrypath') : ''
/* eslint-enable spaced-comment */
require('../modals/create.js')(currentBasePath)
require('../modals/move.js')(currentBasePath, alerts)
}
} }
...@@ -19,6 +19,8 @@ $primary: 'indigo'; ...@@ -19,6 +19,8 @@ $primary: 'indigo';
@import './libs/twemoji-awesome'; @import './libs/twemoji-awesome';
@import './libs/jquery-contextmenu'; @import './libs/jquery-contextmenu';
@import 'node_modules/highlight.js/styles/tomorrow';
@import 'node_modules/simplemde/dist/simplemde.min';
@import './components/_editor'; @import './components/_editor';
......
...@@ -27,6 +27,21 @@ const args = require('yargs') ...@@ -27,6 +27,21 @@ const args = require('yargs')
.alias('h', 'help') .alias('h', 'help')
.argv .argv
// Define aliases
const ALIASES = {
'ace': 'ace-builds/src-min-noconflict/ace.js',
'simplemde': 'simplemde/dist/simplemde.min.js',
'socket.io-client': 'socket.io-client/dist/socket.io.min.js',
'vue': 'vue/dist/vue.js'
}
const SHIMS = {
jquery: {
source: 'node_modules/jquery/dist/jquery.js',
exports: '$'
}
}
if (args.d) { if (args.d) {
// ============================================= // =============================================
// DEVELOPER MODE // DEVELOPER MODE
...@@ -41,9 +56,8 @@ if (args.d) { ...@@ -41,9 +56,8 @@ if (args.d) {
const fuse = fsbx.FuseBox.init({ const fuse = fsbx.FuseBox.init({
homeDir: './client', homeDir: './client',
outFile: './assets/js/bundle.min.js', outFile: './assets/js/bundle.min.js',
alias: { alias: ALIASES,
vue: 'vue/dist/vue.js' shim: SHIMS,
},
plugins: [ plugins: [
[ fsbx.SassPlugin({ includePaths: ['../core'] }), fsbx.CSSPlugin() ], [ fsbx.SassPlugin({ includePaths: ['../core'] }), fsbx.CSSPlugin() ],
fsbx.BabelPlugin({ comments: false, presets: ['es2015'] }), fsbx.BabelPlugin({ comments: false, presets: ['es2015'] }),
...@@ -55,7 +69,8 @@ if (args.d) { ...@@ -55,7 +69,8 @@ if (args.d) {
fuse.devServer('>index.js', { fuse.devServer('>index.js', {
port: 4444, port: 4444,
httpServer: false httpServer: false,
hmr: false
}) })
// Server // Server
...@@ -80,7 +95,7 @@ if (args.d) { ...@@ -80,7 +95,7 @@ if (args.d) {
}, 1000) }, 1000)
} else if (args.c) { } else if (args.c) {
// ============================================= // =============================================
// DEVELOPER MODE // CONFIGURE - DEVELOPER MODE
// ============================================= // =============================================
console.info(colors.bgWhite.black(' Starting Fuse in CONFIGURE DEVELOPER mode... ')) console.info(colors.bgWhite.black(' Starting Fuse in CONFIGURE DEVELOPER mode... '))
...@@ -92,9 +107,8 @@ if (args.d) { ...@@ -92,9 +107,8 @@ if (args.d) {
const fuse = fsbx.FuseBox.init({ const fuse = fsbx.FuseBox.init({
homeDir: './client', homeDir: './client',
outFile: './assets/js/configure.min.js', outFile: './assets/js/configure.min.js',
alias: { alias: ALIASES,
vue: 'vue/dist/vue.js' shim: SHIMS,
},
plugins: [ plugins: [
[ fsbx.SassPlugin({ includePaths: ['../core'] }), fsbx.CSSPlugin() ], [ fsbx.SassPlugin({ includePaths: ['../core'] }), fsbx.CSSPlugin() ],
fsbx.BabelPlugin({ comments: false, presets: ['es2015'] }), fsbx.BabelPlugin({ comments: false, presets: ['es2015'] }),
...@@ -131,9 +145,8 @@ if (args.d) { ...@@ -131,9 +145,8 @@ if (args.d) {
const fuse = fsbx.FuseBox.init({ const fuse = fsbx.FuseBox.init({
homeDir: './client', homeDir: './client',
alias: { alias: ALIASES,
vue: 'vue/dist/vue.js' shim: SHIMS,
},
plugins: [ plugins: [
[ fsbx.SassPlugin({ outputStyle: 'compressed', includePaths: ['./node_modules/requarks-core'] }), fsbx.CSSPlugin() ], [ fsbx.SassPlugin({ outputStyle: 'compressed', includePaths: ['./node_modules/requarks-core'] }), fsbx.CSSPlugin() ],
fsbx.BabelPlugin({ fsbx.BabelPlugin({
......
...@@ -43,13 +43,13 @@ ...@@ -43,13 +43,13 @@
}, },
"dependencies": { "dependencies": {
"auto-load": "^2.1.0", "auto-load": "^2.1.0",
"axios": "^0.15.3", "axios": "^0.16.0",
"bcryptjs-then": "^1.0.1", "bcryptjs-then": "^1.0.1",
"bluebird": "^3.4.7", "bluebird": "^3.4.7",
"body-parser": "^1.17.1", "body-parser": "^1.17.1",
"bunyan": "^1.8.9", "bunyan": "^1.8.9",
"cheerio": "^0.22.0", "cheerio": "^0.22.0",
"child-process-promise": "^2.2.0", "child-process-promise": "^2.2.1",
"chokidar": "^1.6.0", "chokidar": "^1.6.0",
"commander": "^2.9.0", "commander": "^2.9.0",
"compression": "^1.6.2", "compression": "^1.6.2",
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
"express": "^4.15.2", "express": "^4.15.2",
"express-brute": "^1.0.0", "express-brute": "^1.0.0",
"express-brute-mongoose": "0.0.7", "express-brute-mongoose": "0.0.7",
"express-session": "^1.15.1", "express-session": "^1.15.2",
"file-type": "^4.0.0", "file-type": "^4.0.0",
"filesize.js": "^1.0.2", "filesize.js": "^1.0.2",
"follow-redirects": "^1.2.3", "follow-redirects": "^1.2.3",
...@@ -85,19 +85,19 @@ ...@@ -85,19 +85,19 @@
"markdown-it-expand-tabs": "^1.0.11", "markdown-it-expand-tabs": "^1.0.11",
"markdown-it-external-links": "0.0.6", "markdown-it-external-links": "0.0.6",
"markdown-it-footnote": "^3.0.1", "markdown-it-footnote": "^3.0.1",
"markdown-it-task-lists": "^1.4.1", "markdown-it-task-lists": "^2.0.0",
"memdown": "^1.2.4", "memdown": "^1.2.4",
"mime-types": "^2.1.15", "mime-types": "^2.1.15",
"moment": "^2.18.1", "moment": "^2.18.1",
"moment-timezone": "^0.5.11", "moment-timezone": "^0.5.11",
"mongodb": "^2.2.25", "mongodb": "^2.2.25",
"mongoose": "^4.9.1", "mongoose": "^4.9.2",
"multer": "^1.2.1", "multer": "^1.2.1",
"ora": "^1.2.0", "ora": "^1.2.0",
"passport": "^0.3.2", "passport": "^0.3.2",
"passport-local": "^1.0.0", "passport-local": "^1.0.0",
"passport.socketio": "^3.7.0", "passport.socketio": "^3.7.0",
"pm2": "^2.4.2", "pm2": "^2.4.3",
"pug": "^2.0.0-beta11", "pug": "^2.0.0-beta11",
"read-chunk": "^2.0.0", "read-chunk": "^2.0.0",
"remove-markdown": "^0.1.0", "remove-markdown": "^0.1.0",
...@@ -119,33 +119,33 @@ ...@@ -119,33 +119,33 @@
"winston": "^2.3.0" "winston": "^2.3.0"
}, },
"devDependencies": { "devDependencies": {
"ace-builds": "^1.2.6",
"babel-cli": "^6.24.0", "babel-cli": "^6.24.0",
"babel-jest": "^19.0.0", "babel-jest": "^19.0.0",
"babel-preset-es2015": "^6.24.0", "babel-preset-es2015": "^6.24.0",
"brace": "^0.10.0",
"colors": "^1.1.2", "colors": "^1.1.2",
"eslint": "^3.18.0", "eslint": "^3.19.0",
"eslint-config-standard": "^7.1.0", "eslint-config-standard": "^7.1.0",
"eslint-plugin-import": "^2.2.0", "eslint-plugin-import": "^2.2.0",
"eslint-plugin-node": "^4.2.1", "eslint-plugin-node": "^4.2.2",
"eslint-plugin-promise": "^3.5.0", "eslint-plugin-promise": "^3.5.0",
"eslint-plugin-standard": "^2.1.1", "eslint-plugin-standard": "^2.1.1",
"fuse-box": "^1.3.128", "fuse-box": "^1.3.129",
"jest": "^19.0.2", "jest": "^19.0.2",
"jquery": "^3.2.1", "jquery": "^3.2.1",
"jquery-contextmenu": "^2.4.4", "jquery-contextmenu": "^2.4.4",
"jquery-simple-upload": "^1.0.0", "jquery-simple-upload": "^1.0.0",
"jquery-smooth-scroll": "^2.0.0", "jquery-smooth-scroll": "^2.0.0",
"node-sass": "^4.5.1", "node-sass": "^4.5.2",
"nodemon": "^1.11.0", "nodemon": "^1.11.0",
"pre-commit": "^1.2.2", "pre-commit": "^1.2.2",
"pug-lint": "^2.4.0", "pug-lint": "^2.4.0",
"snyk": "^1.25.1", "snyk": "^1.26.1",
"standard": "^9.0.2", "standard": "^9.0.2",
"sticky-js": "^1.1.9", "sticky-js": "^1.1.9",
"twemoji-awesome": "^1.0.4", "twemoji-awesome": "^1.0.4",
"vee-validate": "^2.0.0-beta.25", "vee-validate": "^2.0.0-beta.25",
"vue": "^2.2.5" "vue": "^2.2.6"
}, },
"standard": { "standard": {
"globals": [ "globals": [
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment