From 30806d3c8da51ab07d6bcea8bc50f93512ff7166 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Sun, 16 Sep 2018 18:36:15 -0400 Subject: [PATCH] feat: editor - existing content --- client/app.js | 8 ++-- client/components/editor.vue | 50 ++++++++++++++++++-- client/components/editor/editor-markdown.vue | 2 +- dev/webpack/webpack.dev.js | 6 ++- dev/webpack/webpack.prod.js | 16 ++++++- server/controllers/common.js | 26 ++++++++-- server/helpers/page.js | 5 +- server/models/pages.js | 4 +- server/views/editor.pug | 12 ++++- server/views/new.pug | 2 +- server/views/page.pug | 2 +- 11 files changed, 113 insertions(+), 20 deletions(-) diff --git a/client/app.js b/client/app.js index af359669..8b461372 100644 --- a/client/app.js +++ b/client/app.js @@ -110,13 +110,13 @@ Vue.prototype.Velocity = Velocity // ==================================== Vue.component('admin', () => import(/* webpackChunkName: "admin" */ './components/admin.vue')) -Vue.component('editor', () => import(/* webpackChunkName: "editor" */ './components/editor.vue')) -Vue.component('login', () => import(/* webpackMode: "eager" */ './components/login.vue')) +Vue.component('editor', () => import(/* webpackPrefetch: -100, webpackChunkName: "editor" */ './components/editor.vue')) +Vue.component('login', () => import(/* webpackPrefetch: true, webpackChunkName: "login" */ './components/login.vue')) Vue.component('nav-footer', () => import(/* webpackMode: "eager" */ './components/common/nav-footer.vue')) -Vue.component('nav-header', () => import(/* webpackMode: "eager" */ './components/common/nav-header.vue')) +Vue.component('nav-header', () => import(/* webpackMode: "lazy" */ './components/common/nav-header.vue')) Vue.component('profile', () => import(/* webpackChunkName: "profile" */ './components/profile.vue')) Vue.component('setup', () => import(/* webpackChunkName: "setup" */ './components/setup.vue')) -Vue.component('v-card-chin', () => import(/* webpackMode: "eager" */ './components/common/v-card-chin.vue')) +Vue.component('v-card-chin', () => import(/* webpackPrefetch: true, webpackChunkName: "ui-extra" */ './components/common/v-card-chin.vue')) Vue.component('page', () => import(/* webpackChunkName: "theme-page" */ './themes/' + process.env.CURRENT_THEME + '/components/app.vue')) let bootstrap = () => { diff --git a/client/components/editor.vue b/client/components/editor.vue index 8dd24532..00d66ab9 100644 --- a/client/components/editor.vue +++ b/client/components/editor.vue @@ -101,10 +101,48 @@ WIKI.$store.registerModule('editor', editorStore) export default { components: { AtomSpinner, - editorCode: () => import(/* webpackChunkName: "editor-code" */ './editor/editor-code.vue'), - editorMarkdown: () => import(/* webpackChunkName: "editor-markdown" */ './editor/editor-markdown.vue'), - editorWysiwyg: () => import(/* webpackChunkName: "editor-wysiwyg" */ './editor/editor-wysiwyg.vue'), - editorModalProperties: () => import(/* webpackChunkName: "editor" */ './editor/editor-modal-properties.vue') + editorCode: () => import(/* webpackChunkName: "editor-code", webpackMode: "lazy" */ './editor/editor-code.vue'), + editorMarkdown: () => import(/* webpackChunkName: "editor-markdown", webpackMode: "lazy" */ './editor/editor-markdown.vue'), + editorWysiwyg: () => import(/* webpackChunkName: "editor-wysiwyg", webpackMode: "lazy" */ './editor/editor-wysiwyg.vue'), + editorModalProperties: () => import(/* webpackChunkName: "editor", webpackMode: "eager" */ './editor/editor-modal-properties.vue') + }, + props: { + locale: { + type: String, + default: 'en' + }, + path: { + type: String, + default: 'home' + }, + title: { + type: String, + default: 'Untitled Page' + }, + description: { + type: String, + default: '' + }, + tags: { + type: Array, + default: () => ([]) + }, + isPublished: { + type: Boolean, + default: false + }, + initEditor: { + type: String, + default: null + }, + initMode: { + type: String, + default: 'create' + }, + initContent: { + type: String, + default: null + } }, data() { return { @@ -120,10 +158,14 @@ export default { notificationState: sync('notification@isActive') }, mounted() { + this.$store.set('editor/mode', this.initMode || 'create') + this.$store.set('editor/content', this.initContent ? window.atob(this.initContent) : '# Header\n\nYour content here') if (this.mode === 'create') { _.delay(() => { this.dialogEditorSelector = true }, 500) + } else { + this.selectEditor(this.initEditor || 'markdown') } }, methods: { diff --git a/client/components/editor/editor-markdown.vue b/client/components/editor/editor-markdown.vue index 68d9241e..214eb3e1 100644 --- a/client/components/editor/editor-markdown.vue +++ b/client/components/editor/editor-markdown.vue @@ -165,7 +165,7 @@ export default { data() { return { fabInsertMenu: false, - code: '# Header 1\n\nSample **Text**\nhttp://wiki.js.org\n:rocket: :) :( :| :P\n\n## Header 2\nSample Text\n\n```javascript\nvar test = require("test");\n\n// some comment\nconst foo = bar(\'param\') + 1.234;\n```\n\n### Header 3\nLorem *ipsum* ~~text~~', + code: this.$store.get('editor/content'), cmOptions: { tabSize: 2, mode: 'text/markdown', diff --git a/dev/webpack/webpack.dev.js b/dev/webpack/webpack.dev.js index 4656268a..70a0e128 100644 --- a/dev/webpack/webpack.dev.js +++ b/dev/webpack/webpack.dev.js @@ -137,8 +137,7 @@ module.exports = { { test: /\.svg$/, include: [ - path.join(process.cwd(), 'client/svg'), - path.join(process.cwd(), 'node_modules/grapesjs/src/styles/fonts/main-fonts.svg') + path.join(process.cwd(), 'client/svg') ], use: [ { @@ -156,6 +155,9 @@ module.exports = { }, { test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/, + exclude: [ + path.join(process.cwd(), 'client') + ], use: [{ loader: 'file-loader', options: { diff --git a/dev/webpack/webpack.prod.js b/dev/webpack/webpack.prod.js index 3fdc8d52..f49de224 100644 --- a/dev/webpack/webpack.prod.js +++ b/dev/webpack/webpack.prod.js @@ -126,7 +126,8 @@ module.exports = { { test: /\.svg$/, exclude: [ - path.join(process.cwd(), 'client/svg') + path.join(process.cwd(), 'client/svg'), + path.join(process.cwd(), 'node_modules/grapesjs') ], use: [ { @@ -157,6 +158,19 @@ module.exports = { { loader: 'graphql-tag/loader' } ] }, + { + test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/, + exclude: [ + path.join(process.cwd(), 'client') + ], + use: [{ + loader: 'file-loader', + options: { + name: '[name].[ext]', + outputPath: 'fonts/' + } + }] + }, { test: /.jsx$/, loader: 'babel-loader', diff --git a/server/controllers/common.js b/server/controllers/common.js index 3e505fbf..e9f7f879 100644 --- a/server/controllers/common.js +++ b/server/controllers/common.js @@ -7,8 +7,28 @@ const pageHelper = require('../helpers/page') /** * Create/Edit document */ -router.get(['/e', '/e/*'], (req, res, next) => { - res.render('editor') +router.get(['/e', '/e/*'], async (req, res, next) => { + const pageArgs = pageHelper.parsePath(req.path) + let page = await WIKI.models.pages.getPageFromDb({ + path: pageArgs.path, + locale: pageArgs.locale, + userId: req.user.id, + isPrivate: false + }) + if (page) { + page.mode = 'update' + page.isPublished = (page.isPublished === true || page.isPublished === 1) ? 'true' : 'false' + page.content = Buffer.from(page.content).toString('base64') + } else { + page = { + path: pageArgs.path, + localeCode: pageArgs.locale, + editorKey: null, + mode: 'create', + content: null + } + } + res.render('editor', { page }) }) /** @@ -41,7 +61,7 @@ router.get('/*', async (req, res, next) => { } else if (pageArgs.path === 'home') { res.render('welcome') } else { - res.render('new') + res.render('new', { pagePath: req.path }) } }) diff --git a/server/helpers/page.js b/server/helpers/page.js index fdbcf538..8d3adb1e 100644 --- a/server/helpers/page.js +++ b/server/helpers/page.js @@ -21,8 +21,11 @@ module.exports = { // Extract Info let pathParts = _.filter(_.split(rawPath, '/'), p => !_.isEmpty(p)) + if (pathParts[0].length === 1) { + pathParts.shift() + } if (pathParts[0].length === 2) { - pathObj = pathParts[0] + pathObj.locale = pathParts[0] pathParts.shift() } pathObj.path = _.join(pathParts, '/') diff --git a/server/models/pages.js b/server/models/pages.js index e933ea62..5e0abdbe 100644 --- a/server/models/pages.js +++ b/server/models/pages.js @@ -187,7 +187,9 @@ module.exports = class Page extends Model { let page = await WIKI.models.pages.getPageFromCache(opts) if (!page) { page = await WIKI.models.pages.getPageFromDb(opts) - await WIKI.models.pages.savePageToCache(page) + if (page) { + await WIKI.models.pages.savePageToCache(page) + } } return page } diff --git a/server/views/editor.pug b/server/views/editor.pug index 4c7937f2..7cf1c5fd 100644 --- a/server/views/editor.pug +++ b/server/views/editor.pug @@ -3,4 +3,14 @@ extends master.pug block body #root v-app - editor + editor( + locale=page.localeCode + path=page.path + title=page.title + description=page.description + tags=page.tags + :is-published=page.isPublished + init-mode=page.mode + init-editor=page.editorKey + init-content=page.content + ) diff --git a/server/views/new.pug b/server/views/new.pug index a12c9701..25e5ed3b 100644 --- a/server/views/new.pug +++ b/server/views/new.pug @@ -8,7 +8,7 @@ block body img.animated.fadeIn(src='/svg/henry-thinking.svg', alt='Henry') .headline= t('newpage.title') .subheading.mt-3= t('newpage.subtitle') - v-btn.mt-5(href='/e/home', large) + v-btn.mt-5(href='/e' + pagePath, large) v-icon(left) add span= t('newpage.create') v-btn.mt-2(color='blue lighten-4', href='javascript:window.history.go(-1);', large, outline) diff --git a/server/views/page.pug b/server/views/page.pug index 828bda14..ee32eeed 100644 --- a/server/views/page.pug +++ b/server/views/page.pug @@ -13,7 +13,7 @@ block body created-at=page.createdAt updated-at=page.updatedAt author-name=page.authorName - author-id=page.authorId + :author-id=page.authorId is-published=page.isPublished ) template(slot='contents')!= page.render