Browse Source

fix: session knex connector + editor UI improvements

pull/835/head
Nick 5 years ago
parent
commit
6041b1697a
7 changed files with 122 additions and 97 deletions
  1. 12
      client/components/editor.vue
  2. 191
      client/components/editor/editor-markdown.vue
  3. 2
      client/scss/base/animation.scss
  4. 4
      client/themes/default/scss/app.scss
  5. 1
      package.json
  6. 6
      server/master.js
  7. 3
      server/models/editors.js

12
client/components/editor.vue

@ -6,25 +6,25 @@
.subheading.grey--text {{currentPageTitle}} .subheading.grey--text {{currentPageTitle}}
v-spacer v-spacer
template(slot='actions') template(slot='actions')
v-btn(
outline
v-btn.animated.fadeInDown(
flat
color='green' color='green'
@click.native.stop='save' @click.native.stop='save'
:class='{ "is-icon": $vuetify.breakpoint.mdAndDown }' :class='{ "is-icon": $vuetify.breakpoint.mdAndDown }'
) )
v-icon(color='green', :left='$vuetify.breakpoint.lgAndUp') check v-icon(color='green', :left='$vuetify.breakpoint.lgAndUp') check
span.white--text(v-if='$vuetify.breakpoint.lgAndUp') {{ mode === 'create' ? $t('common:actions.create') : $t('common:actions.save') }} span.white--text(v-if='$vuetify.breakpoint.lgAndUp') {{ mode === 'create' ? $t('common:actions.create') : $t('common:actions.save') }}
v-btn(
outline
v-btn.animated.fadeInDown.wait-p1s(
flat
color='blue' color='blue'
@click.native.stop='openPropsModal' @click.native.stop='openPropsModal'
:class='{ "is-icon": $vuetify.breakpoint.mdAndDown, "mx-0": !welcomeMode, "ml-0": welcomeMode }' :class='{ "is-icon": $vuetify.breakpoint.mdAndDown, "mx-0": !welcomeMode, "ml-0": welcomeMode }'
) )
v-icon(color='blue', :left='$vuetify.breakpoint.lgAndUp') sort_by_alpha v-icon(color='blue', :left='$vuetify.breakpoint.lgAndUp') sort_by_alpha
span.white--text(v-if='$vuetify.breakpoint.lgAndUp') {{ $t('editor:page') }} span.white--text(v-if='$vuetify.breakpoint.lgAndUp') {{ $t('editor:page') }}
v-btn(
v-btn.animated.fadeInDown.wait-p2s(
v-if='!welcomeMode' v-if='!welcomeMode'
outline
flat
color='red' color='red'
:class='{ "is-icon": $vuetify.breakpoint.mdAndDown }' :class='{ "is-icon": $vuetify.breakpoint.mdAndDown }'
@click.native.stop='exit' @click.native.stop='exit'

191
client/components/editor/editor-markdown.vue

@ -1,130 +1,134 @@
<template lang='pug'> <template lang='pug'>
.editor-markdown .editor-markdown
v-toolbar.editor-markdown-toolbar(dense, color='primary', dark, flat) v-toolbar.editor-markdown-toolbar(dense, color='primary', dark, flat)
v-tooltip(bottom, color='primary')
v-btn(icon, slot='activator', @click='toggleMarkup({ start: `**` })').mx-0
v-icon format_bold
span Bold
v-tooltip(bottom, color='primary')
v-btn(icon, slot='activator', @click='toggleMarkup({ start: `*` })').mx-0
v-icon format_italic
span Italic
v-tooltip(bottom, color='primary')
v-btn(icon, slot='activator', @click='toggleMarkup({ start: `~~` })').mx-0
v-icon format_strikethrough
span Strikethrough
v-menu(offset-y, open-on-hover)
v-btn(icon, slot='activator').mx-0
v-icon text_fields
v-list.py-0
template(v-for='(n, idx) in 6')
v-list-tile(@click='setHeaderLine(n)', :key='idx')
v-btn.animated.fadeInLeft(v-if='isModalShown', flat, @click='closeAllModal')
v-icon(left) chevron_left
span Back
template(v-else)
v-tooltip(bottom, color='primary')
v-btn.animated.fadeIn(icon, slot='activator', @click='toggleMarkup({ start: `**` })').mx-0
v-icon format_bold
span Bold
v-tooltip(bottom, color='primary')
v-btn.animated.fadeIn.wait-p1s(icon, slot='activator', @click='toggleMarkup({ start: `*` })').mx-0
v-icon format_italic
span Italic
v-tooltip(bottom, color='primary')
v-btn.animated.fadeIn.wait-p2s(icon, slot='activator', @click='toggleMarkup({ start: `~~` })').mx-0
v-icon format_strikethrough
span Strikethrough
v-menu(offset-y, open-on-hover)
v-btn.animated.fadeIn.wait-p3s(icon, slot='activator').mx-0
v-icon text_fields
v-list.py-0
template(v-for='(n, idx) in 6')
v-list-tile(@click='setHeaderLine(n)', :key='idx')
v-list-tile-action
v-icon(:size='24 - (idx - 1) * 2') title
v-list-tile-title Heading {{n}}
v-divider(v-if='idx < 5')
v-tooltip(bottom, color='primary')
v-btn.animated.fadeIn.wait-p4s(icon, slot='activator', @click='toggleMarkup({ start: `~` })').mx-0
v-icon vertical_align_bottom
span Subscript
v-tooltip(bottom, color='primary')
v-btn.animated.fadeIn.wait-p5s(icon, slot='activator', @click='toggleMarkup({ start: `^` })').mx-0
v-icon vertical_align_top
span Superscript
v-menu(offset-y, open-on-hover)
v-btn.animated.fadeIn.wait-p6s(icon, slot='activator').mx-0
v-icon format_quote
v-list.py-0
v-list-tile(@click='insertBeforeEachLine({ content: `> `})')
v-list-tile-action v-list-tile-action
v-icon(:size='24 - (idx - 1) * 2') title
v-list-tile-title Heading {{n}}
v-divider(v-if='idx < 5')
v-tooltip(bottom, color='primary')
v-btn(icon, slot='activator', @click='toggleMarkup({ start: `~` })').mx-0
v-icon vertical_align_bottom
span Subscript
v-tooltip(bottom, color='primary')
v-btn(icon, slot='activator', @click='toggleMarkup({ start: `^` })').mx-0
v-icon vertical_align_top
span Superscript
v-menu(offset-y, open-on-hover)
v-btn(icon, slot='activator').mx-0
v-icon format_quote
v-list.py-0
v-list-tile(@click='insertBeforeEachLine({ content: `> `})')
v-list-tile-action
v-icon format_quote
v-list-tile-title Blockquote
v-divider
v-list-tile(@click='insertBeforeEachLine({ content: `> `, after: `{.is-info}`})')
v-list-tile-action
v-icon(color='blue') format_quote
v-list-tile-title Info Blockquote
v-divider
v-list-tile(@click='insertBeforeEachLine({ content: `> `, after: `{.is-success}`})')
v-list-tile-action
v-icon(color='success') format_quote
v-list-tile-title Success Blockquote
v-divider
v-list-tile(@click='insertBeforeEachLine({ content: `> `, after: `{.is-warning}`})')
v-list-tile-action
v-icon(color='warning') format_quote
v-list-tile-title Warning Blockquote
v-divider
v-list-tile(@click='insertBeforeEachLine({ content: `> `, after: `{.is-error}`})')
v-list-tile-action
v-icon(color='error') format_quote
v-list-tile-title Error Blockquote
v-divider
v-tooltip(bottom, color='primary')
v-btn(icon, slot='activator', @click='insertBeforeEachLine({ content: `- `})').mx-0
v-icon format_list_bulleted
span Unordered List
v-tooltip(bottom, color='primary')
v-btn(icon, slot='activator', @click='insertBeforeEachLine({ content: `1. `})').mx-0
v-icon format_list_numbered
span Ordered List
v-tooltip(bottom, color='primary')
v-btn(icon, slot='activator', @click='toggleMarkup({ start: "`" })').mx-0
v-icon space_bar
span Inline Code
v-tooltip(bottom, color='primary')
v-btn(icon, slot='activator', @click='toggleMarkup({ start: `<kbd>`, end: `</kbd>` })').mx-0
v-icon font_download
span Keyboard Key
v-tooltip(bottom, color='primary')
v-btn(icon, slot='activator', @click='insertAfter({ content: `---`, newLine: true })').mx-0
v-icon remove
span Horizontal Bar
v-icon format_quote
v-list-tile-title Blockquote
v-divider
v-list-tile(@click='insertBeforeEachLine({ content: `> `, after: `{.is-info}`})')
v-list-tile-action
v-icon(color='blue') format_quote
v-list-tile-title Info Blockquote
v-divider
v-list-tile(@click='insertBeforeEachLine({ content: `> `, after: `{.is-success}`})')
v-list-tile-action
v-icon(color='success') format_quote
v-list-tile-title Success Blockquote
v-divider
v-list-tile(@click='insertBeforeEachLine({ content: `> `, after: `{.is-warning}`})')
v-list-tile-action
v-icon(color='warning') format_quote
v-list-tile-title Warning Blockquote
v-divider
v-list-tile(@click='insertBeforeEachLine({ content: `> `, after: `{.is-error}`})')
v-list-tile-action
v-icon(color='error') format_quote
v-list-tile-title Error Blockquote
v-divider
v-tooltip(bottom, color='primary')
v-btn.animated.fadeIn.wait-p7s(icon, slot='activator', @click='insertBeforeEachLine({ content: `- `})').mx-0
v-icon format_list_bulleted
span Unordered List
v-tooltip(bottom, color='primary')
v-btn.animated.fadeIn.wait-p8s(icon, slot='activator', @click='insertBeforeEachLine({ content: `1. `})').mx-0
v-icon format_list_numbered
span Ordered List
v-tooltip(bottom, color='primary')
v-btn.animated.fadeIn.wait-p9s(icon, slot='activator', @click='toggleMarkup({ start: "`" })').mx-0
v-icon space_bar
span Inline Code
v-tooltip(bottom, color='primary')
v-btn.animated.fadeIn.wait-p10s(icon, slot='activator', @click='toggleMarkup({ start: `<kbd>`, end: `</kbd>` })').mx-0
v-icon font_download
span Keyboard Key
v-tooltip(bottom, color='primary')
v-btn.animated.fadeIn.wait-p11s(icon, slot='activator', @click='insertAfter({ content: `---`, newLine: true })').mx-0
v-icon remove
span Horizontal Bar
.editor-markdown-main .editor-markdown-main
.editor-markdown-sidebar .editor-markdown-sidebar
v-tooltip(right, color='teal') v-tooltip(right, color='teal')
v-btn(icon, slot='activator', dark, disabled).mx-0
v-btn.animated.fadeInLeft(icon, slot='activator', dark, disabled).mx-0
v-icon link v-icon link
span Insert Link span Insert Link
v-tooltip(right, color='teal') v-tooltip(right, color='teal')
v-btn(icon, slot='activator', dark, @click='toggleModal(`editorModalMedia`)').mx-0
v-btn.animated.fadeInLeft.wait-p1s(icon, slot='activator', dark, @click='toggleModal(`editorModalMedia`)').mx-0
v-icon(:color='activeModal === `editorModalMedia` ? `teal` : ``') image v-icon(:color='activeModal === `editorModalMedia` ? `teal` : ``') image
span Insert Image span Insert Image
v-tooltip(right, color='teal') v-tooltip(right, color='teal')
v-btn(icon, slot='activator', dark, @click='toggleModal(`editorModalBlocks`)').mx-0
v-btn.animated.fadeInLeft.wait-p2s(icon, slot='activator', dark, @click='toggleModal(`editorModalBlocks`)').mx-0
v-icon(:color='activeModal === `editorModalBlocks` ? `teal` : ``') dashboard v-icon(:color='activeModal === `editorModalBlocks` ? `teal` : ``') dashboard
span Insert Block span Insert Block
v-tooltip(right, color='teal') v-tooltip(right, color='teal')
v-btn(icon, slot='activator', dark, disabled).mx-0
v-btn.animated.fadeInLeft.wait-p3s(icon, slot='activator', dark, disabled).mx-0
v-icon insert_drive_file v-icon insert_drive_file
span Insert File span Insert File
v-tooltip(right, color='teal') v-tooltip(right, color='teal')
v-btn(icon, slot='activator', dark, disabled).mx-0
v-btn.animated.fadeInLeft.wait-p4s(icon, slot='activator', dark, disabled).mx-0
v-icon code v-icon code
span Insert Code Block span Insert Code Block
v-tooltip(right, color='teal') v-tooltip(right, color='teal')
v-btn(icon, slot='activator', dark, disabled).mx-0
v-btn.animated.fadeInLeft.wait-p5s(icon, slot='activator', dark, disabled).mx-0
v-icon play_circle_outline v-icon play_circle_outline
span Insert Video / Audio span Insert Video / Audio
v-tooltip(right, color='teal') v-tooltip(right, color='teal')
v-btn(icon, slot='activator', dark, disabled).mx-0
v-btn.animated.fadeInLeft.wait-p6s(icon, slot='activator', dark, disabled).mx-0
v-icon multiline_chart v-icon multiline_chart
span Insert Diagram span Insert Diagram
v-tooltip(right, color='teal') v-tooltip(right, color='teal')
v-btn(icon, slot='activator', dark, disabled).mx-0
v-btn.animated.fadeInLeft.wait-p7s(icon, slot='activator', dark, disabled).mx-0
v-icon functions v-icon functions
span Insert Math Expression span Insert Math Expression
v-tooltip(right, color='teal') v-tooltip(right, color='teal')
v-btn(icon, slot='activator', dark, disabled).mx-0
v-btn.animated.fadeInLeft.wait-p8s(icon, slot='activator', dark, disabled).mx-0
v-icon border_outer v-icon border_outer
span Table Helper span Table Helper
v-spacer v-spacer
v-tooltip(right, color='teal') v-tooltip(right, color='teal')
v-btn(icon, slot='activator', dark, @click='toggleFullscreen').mx-0
v-btn.animated.fadeInLeft.wait-p9s(icon, slot='activator', dark, @click='toggleFullscreen').mx-0
v-icon crop_free v-icon crop_free
span Distraction Free Mode span Distraction Free Mode
v-tooltip(right, color='teal') v-tooltip(right, color='teal')
v-btn(icon, slot='activator', dark, @click='toggleHelp').mx-0
v-btn.animated.fadeInLeft.wait-p10s(icon, slot='activator', dark, @click='toggleHelp').mx-0
v-icon(:color='helpShown ? `teal` : ``') help v-icon(:color='helpShown ? `teal` : ``') help
span Markdown Formatting Help span Markdown Formatting Help
.editor-markdown-editor .editor-markdown-editor
@ -275,6 +279,9 @@ export default {
isMobile() { isMobile() {
return this.$vuetify.breakpoint.smAndDown return this.$vuetify.breakpoint.smAndDown
}, },
isModalShown() {
return this.helpShown || this.activeModal !== ''
},
locale: get('page/locale'), locale: get('page/locale'),
path: get('page/path'), path: get('page/path'),
activeModal: sync('editor/activeModal') activeModal: sync('editor/activeModal')
@ -282,6 +289,11 @@ export default {
methods: { methods: {
toggleModal(key) { toggleModal(key) {
this.activeModal = (this.activeModal === key) ? '' : key this.activeModal = (this.activeModal === key) ? '' : key
this.helpShown = false
},
closeAllModal() {
this.activeModal = ''
this.helpShown = false
}, },
onCmReady(cm) { onCmReady(cm) {
const keyBindings = { const keyBindings = {
@ -438,6 +450,7 @@ export default {
}, 500), }, 500),
toggleHelp () { toggleHelp () {
this.helpShown = !this.helpShown this.helpShown = !this.helpShown
this.activeModal = ''
}, },
toggleFullscreen () { toggleFullscreen () {
this.cm.setOption('fullScreen', true) this.cm.setOption('fullScreen', true)

2
client/scss/base/animation.scss

@ -5,7 +5,7 @@ $use-bounce: true;
@import "~animate-sass/animate"; @import "~animate-sass/animate";
@for $i from 1 to 9 {
@for $i from 1 to 12 {
.wait-p#{$i}s { .wait-p#{$i}s {
animation-delay: $i * .1s !important; animation-delay: $i * .1s !important;
} }

4
client/themes/default/scss/app.scss

@ -274,6 +274,10 @@
padding: 1rem 1rem 1rem 3rem; padding: 1rem 1rem 1rem 3rem;
margin: 1rem 24px; margin: 1rem 24px;
@at-root .theme--dark & {
background-color: darken(mc('grey', '900'), 5%);
}
> code { > code {
background-color: transparent; background-color: transparent;
padding: 0; padding: 0;

1
package.json

@ -57,6 +57,7 @@
"chokidar": "2.1.5", "chokidar": "2.1.5",
"clean-css": "4.2.1", "clean-css": "4.2.1",
"compression": "1.7.4", "compression": "1.7.4",
"connect-session-knex": "1.4.0",
"cookie-parser": "1.4.4", "cookie-parser": "1.4.4",
"cors": "2.8.5", "cors": "2.8.5",
"custom-error-instance": "2.1.1", "custom-error-instance": "2.1.1",

6
server/master.js

@ -5,6 +5,7 @@ const cookieParser = require('cookie-parser')
const cors = require('cors') const cors = require('cors')
const express = require('express') const express = require('express')
const session = require('express-session') const session = require('express-session')
const KnexSessionStore = require('connect-session-knex')(session)
const favicon = require('serve-favicon') const favicon = require('serve-favicon')
const fs = require('fs-extra') const fs = require('fs-extra')
const http = require('http') const http = require('http')
@ -69,7 +70,10 @@ module.exports = async () => {
app.use(session({ app.use(session({
secret: WIKI.config.sessionSecret, secret: WIKI.config.sessionSecret,
resave: false, resave: false,
saveUninitialized: false
saveUninitialized: false,
store: new KnexSessionStore({
knex: WIKI.models.knex
})
})) }))
app.use(WIKI.auth.passport.initialize()) app.use(WIKI.auth.passport.initialize())
app.use(WIKI.auth.authenticate) app.use(WIKI.auth.authenticate)

3
server/models/editors.js

@ -88,6 +88,9 @@ module.exports = class Editor extends Model {
} catch (err) { } catch (err) {
WIKI.logger.error(`Failed to scan or load new editors: [ FAILED ]`) WIKI.logger.error(`Failed to scan or load new editors: [ FAILED ]`)
WIKI.logger.error(err) WIKI.logger.error(err)
if (trx) {
trx.rollback()
}
} }
} }

Loading…
Cancel
Save