diff --git a/client/js/app.js b/client/js/app.js index bbbcfeb2..743b5c5a 100644 --- a/client/js/app.js +++ b/client/js/app.js @@ -12,6 +12,8 @@ import io from 'socket-io-client' import i18next from 'i18next' import i18nextXHR from 'i18next-xhr-backend' import VueI18Next from '@panter/vue-i18next' +import 'jquery-contextmenu' +import 'jquery-simple-upload' import 'jquery-smooth-scroll' import 'jquery-sticky' @@ -19,8 +21,8 @@ import 'jquery-sticky' // Load minimal lodash // ==================================== -import concat from 'lodash/concat' import cloneDeep from 'lodash/cloneDeep' +import concat from 'lodash/concat' import debounce from 'lodash/debounce' import deburr from 'lodash/deburr' import delay from 'lodash/delay' @@ -29,6 +31,7 @@ import find from 'lodash/find' import findKey from 'lodash/findKey' import forEach from 'lodash/forEach' import includes from 'lodash/includes' +import isBoolean from 'lodash/isBoolean' import isEmpty from 'lodash/isEmpty' import isNil from 'lodash/isNil' import join from 'lodash/join' @@ -39,8 +42,10 @@ import pullAt from 'lodash/pullAt' import reject from 'lodash/reject' import slice from 'lodash/slice' import split from 'lodash/split' -import trim from 'lodash/trim' +import startCase from 'lodash/startCase' +import toString from 'lodash/toString' import toUpper from 'lodash/toUpper' +import trim from 'lodash/trim' // ==================================== // Load Helpers @@ -56,6 +61,7 @@ import alertComponent from './components/alert.vue' import anchorComponent from './components/anchor.vue' import colorPickerComponent from './components/color-picker.vue' import editorCodeblockComponent from './components/editor-codeblock.vue' +import editorFileComponent from './components/editor-file.vue' import editorVideoComponent from './components/editor-video.vue' import loadingSpinnerComponent from './components/loading-spinner.vue' import modalCreatePageComponent from './components/modal-create-page.vue' @@ -88,6 +94,7 @@ const _ = { findKey, forEach, includes, + isBoolean, isEmpty, isNil, join, @@ -98,6 +105,8 @@ const _ = { reject, slice, split, + startCase, + toString, toUpper, trim } @@ -159,6 +168,7 @@ $(() => { contentView: contentViewComponent, editor: editorComponent, editorCodeblock: editorCodeblockComponent, + editorFile: editorFileComponent, editorVideo: editorVideoComponent, loadingSpinner: loadingSpinnerComponent, modalCreatePage: modalCreatePageComponent, diff --git a/client/js/components/editor-file.vue b/client/js/components/editor-file.vue new file mode 100644 index 00000000..d995ab2b --- /dev/null +++ b/client/js/components/editor-file.vue @@ -0,0 +1,413 @@ + + + diff --git a/client/js/components/editor.component.js b/client/js/components/editor.component.js index 1ffea4ad..b5db8c71 100644 --- a/client/js/components/editor.component.js +++ b/client/js/components/editor.component.js @@ -1,6 +1,5 @@ 'use strict' -import filesize from 'filesize.js' import $ from 'jquery' let mde @@ -8,11 +7,6 @@ let mde export default { name: 'editor', props: ['currentPath'], - filters: { - filesize(v) { - return this._.toUpper(filesize(v)) - } - }, data() { return {} }, @@ -124,11 +118,8 @@ export default { { name: 'link', action: (editor) => { - /* if(!mdeModalOpenState) { - mdeModalOpenState = true; - $('#modal-editor-link').slideToggle(); - } */ window.alert('Coming soon!') + // todo }, className: 'icon-link2', title: 'Insert Link' @@ -136,9 +127,7 @@ export default { { name: 'image', action: (editor) => { - // if (!mdeModalOpenState) { - // vueImage.open() - // } + self.$store.dispatch('editorImage/open') }, className: 'icon-image', title: 'Insert Image' @@ -146,9 +135,7 @@ export default { { name: 'file', action: (editor) => { - // if (!mdeModalOpenState) { - // vueFile.open() - // } + self.$store.dispatch('editorFile/open') }, className: 'icon-paper', title: 'Insert File' diff --git a/client/js/helpers/common.js b/client/js/helpers/common.js new file mode 100644 index 00000000..bfbeabc5 --- /dev/null +++ b/client/js/helpers/common.js @@ -0,0 +1,15 @@ +'use strict' + +import filesize from 'filesize.js' +import toUpper from 'lodash/toUpper' + +module.exports = { + /** + * Convert bytes to humanized form + * @param {number} rawSize Size in bytes + * @returns {string} Humanized file size + */ + filesize(rawSize) { + return toUpper(filesize(rawSize)) + } +} diff --git a/client/js/helpers/index.js b/client/js/helpers/index.js index bd94a1e8..6f802e8b 100644 --- a/client/js/helpers/index.js +++ b/client/js/helpers/index.js @@ -1,6 +1,7 @@ 'use strict' const helpers = { + common: require('./common'), form: require('./form'), pages: require('./pages') } diff --git a/client/js/store/index.js b/client/js/store/index.js index a4708e00..a9829deb 100644 --- a/client/js/store/index.js +++ b/client/js/store/index.js @@ -5,6 +5,7 @@ import alert from './modules/alert' import anchor from './modules/anchor' import editor from './modules/editor' import editorCodeblock from './modules/editor-codeblock' +import editorFile from './modules/editor-file' import editorVideo from './modules/editor-video' import modalCreatePage from './modules/modal-create-page' import modalCreateUser from './modules/modal-create-user' @@ -32,6 +33,7 @@ export default new Vuex.Store({ anchor, editor, editorCodeblock, + editorFile, editorVideo, modalCreatePage, modalCreateUser, diff --git a/client/js/store/modules/editor-file.js b/client/js/store/modules/editor-file.js new file mode 100644 index 00000000..ded21980 --- /dev/null +++ b/client/js/store/modules/editor-file.js @@ -0,0 +1,19 @@ +'use strict' + +export default { + namespaced: true, + state: { + shown: false + }, + getters: {}, + mutations: { + shownChange: (state, shownState) => { state.shown = shownState } + }, + actions: { + open({ commit }, opts) { + commit('shownChange', true) + wikijs.$emit('editorFile/init') + }, + close({ commit }) { commit('shownChange', false) } + } +} diff --git a/package.json b/package.json index 900091ea..d756e7d5 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ }, "dependencies": { "auto-load": "^2.1.0", - "axios": "0.16.1", + "axios": "^0.16.2", "bcryptjs-then": "^1.0.1", "bluebird": "^3.5.0", "body-parser": "^1.17.2", @@ -89,7 +89,7 @@ "mime-types": "^2.1.15", "moment": "^2.18.1", "moment-timezone": "^0.5.13", - "mongodb": "^2.2.27", + "mongodb": "^2.2.28", "mongoose": "^4.10.4", "multer": "^1.3.0", "node-graceful": "^0.2.3", @@ -105,7 +105,7 @@ "passport-windowslive": "^1.0.2", "passport.socketio": "^3.7.0", "pm2": "2.4.6", - "pug": "^2.0.0-rc.1", + "pug": "^2.0.0-rc.2", "read-chunk": "^2.0.0", "remove-markdown": "^0.1.0", "request": "^2.81.0", @@ -117,7 +117,7 @@ "socket.io": "^2.0.2", "stopword": "^0.1.1", "stream-to-promise": "^2.2.0", - "tar": "^3.1.3", + "tar": "^3.1.5", "through2": "^2.0.3", "validator": "^7.0.0", "validator-as-promised": "^1.0.2", @@ -136,7 +136,7 @@ "eslint": "^3.19.0", "eslint-config-standard": "^10.2.1", "eslint-plugin-import": "^2.3.0", - "eslint-plugin-node": "^4.2.2", + "eslint-plugin-node": "^5.0.0", "eslint-plugin-promise": "^3.5.0", "eslint-plugin-standard": "^3.0.1", "fuse-box": "2.1.0-beta.10", diff --git a/server/locales/en/browser.json b/server/locales/en/browser.json index 4c951ca9..d0f87357 100644 --- a/server/locales/en/browser.json +++ b/server/locales/en/browser.json @@ -1,53 +1,86 @@ { "editor": { - "discard": "Discard", - "codeblocktitle": "Insert Code Block", "codeblockinsert": "Insert Code Block", "codeblocklanguage": "Language", "codeblockloading": "Loading code syntax for {{name}}", "codeblockloadingerror": "Error: Unable to load language syntax.", "codeblocksuccess": "Your code block has been inserted.", - "videotitle": "Insert Video", - "videolinktitle": "Enter the link to the video to be embedded:", - "videoinsert": "Insert Video", - "videonotsupported": "This URL is invalid or not supported!", - "videosupportedtitle": "The following are supported:", + "codeblocktitle": "Insert Code Block", + "discard": "Discard", + "filedeleteaction": "Delete", + "filedeleteloading": "Deleting file...", + "filedeletedefault": "this file", + "fileerror": "Unable to fetch updated listing.", + "filefolderempty": "This folder is empty.", + "fileinsert": "Insert Link to File", + "fileloading": "Fetching files...", + "filemoveaction": "Move to...", + "filemoveerror": "Move error: {{err}}", + "filemoveloading": "Moving file...", + "fileprocessing": "Processing...", + "filerenameaction": "Rename", + "filesuccess": "File link has been inserted.", + "filetitle": "Insert File", + "fileupload": "Upload File", + "folders": "Folders", + "foldersloading": "Fetching folders list...", + "newfolder": "New Folder", "videoanymp4file": "Any standard MP4 file", - "videosuccess": "The video code has been inserted." + "videoinsert": "Insert Video", + "videolinktitle": "Enter the link to the video to be embedded:", + "videonotsupported": "This URL is invalid or not supported!", + "videosuccess": "The video code has been inserted.", + "videosupportedtitle": "The following are supported:", + "videotitle": "Insert Video" }, "modal": { "abort": "Abort", - "anchortitle": "Copy link to this section", - "anchorsuccess": "The URL has been copied to your clipboard.", "anchorerror": "Clipboard copy failed. Copy the URL manually.", + "anchorsuccess": "The URL has been copied to your clipboard.", + "anchortitle": "Copy link to this section", "copyclipboard": "Copy to Clipboard", "create": "Create", - "createpagetitle": "Create New Page", - "createpagepath": "Enter the new page path:", "createpageinvalid": "This page path is invalid!", - "createusertitle": "Create / Authorize User", - "createuseremail": "Email address:", - "createuseremailplaceholder": "e.g. john.doe@company.com", - "createuserprovider": "Provider:", - "createuserpassword": "Password:", - "createusername": "Full Name:", - "createusernameplaceholder": "e.g. John Doe", + "createpagepath": "Enter the new page path:", + "createpagetitle": "Create New Page", "createuser": "Create User", "createuserauthorize": "Authorize User", - "discard": "Discard", - "discardpagestay": "Stay on page", - "discardpagetitle": "Discard?", - "discardpagecreate": "Are you sure you want to leave this page and loose anything you wrote so far?", - "discardpageedit": "Are you sure you want to leave this page and loose any modifications?", + "createuseremail": "Email address:", + "createuseremailplaceholder": "e.g. john.doe@company.com", + "createusername": "Full Name:", + "createusernameplaceholder": "e.g. John Doe", + "createuserpassword": "Password:", + "createuserprovider": "Provider:", + "createusertitle": "Create / Authorize User", "delete": "Delete", + "deletefiletitle": "Delete?", + "deletefilewarn": "Are you sure you want to delete", "deleteusertitle": "Delete User Account?", "deleteuserwarning": "Are you sure you want to delete this user account? This action cannot be undone!", + "discard": "Discard", + "discardpagecreate": "Are you sure you want to leave this page and loose anything you wrote so far?", + "discardpageedit": "Are you sure you want to leave this page and loose any modifications?", + "discardpagestay": "Stay on page", + "discardpagetitle": "Discard?", "move": "Move", - "movepagetitle": "Move Page", - "movepagepath": "Enter the new page path:", "movepageinvalid": "This page path is invalid or not allowed!", + "movepagepath": "Enter the new page path:", + "movepageplaceholder": "page-name", + "movepagetitle": "Move Page", "movepagewarning": "Note that moving or renaming pages can lead to broken links. Make sure to edit any page that links to this page afterwards!", - "movepageplaceholder": "page-name" + "newfolderinvalid": "This folder name is invalid!", + "newfolderloading": "Creating new folder...", + "newfoldername": "Enter the new folder name:", + "newfoldernameplaceholder": "folder name", + "newfoldersuccess": "New folder {{name}} created.", + "newfoldertitle": "New Folder", + "renamefile": "Rename", + "renamefileerror": "Rename error: {{err}}", + "renamefileinvalid": "This filename is invalid!", + "renamefileloading": "Renaming file...", + "renamefilename": "Enter the new filename (without the extension) of the file:", + "renamefilenameplaceholder": "filename", + "renamefiletitle": "Rename File" }, "nav": { "home": "Home" @@ -61,9 +94,9 @@ "savechanges": "Save Changes" }, "search": { - "placeholder": "Search...", - "results": "Search Results", + "didyoumean": "Did you mean...?", "nomatch": "No results matching your query", - "didyoumean": "Did you mean...?" + "placeholder": "Search...", + "results": "Search Results" } -} \ No newline at end of file +} diff --git a/server/views/pages/edit.pug b/server/views/pages/edit.pug index 4d851c23..7373e967 100644 --- a/server/views/pages/edit.pug +++ b/server/views/pages/edit.pug @@ -18,6 +18,7 @@ block content .editor-area textarea(ref='editorTextArea', v-pre)= pageData.markdown + editor-file editor-video editor-codeblock modal-discard-page(mode='edit', current-path=pageData.meta.path) diff --git a/server/views/pages/source.pug b/server/views/pages/source.pug index c15fe4d6..271acc22 100644 --- a/server/views/pages/source.pug +++ b/server/views/pages/source.pug @@ -25,7 +25,7 @@ block content source-view(inline-template, entrypath=pageData.meta.path, v-cloak) .ace-container - #source-display= pageData.markdown + #source-display(v-pre)= pageData.markdown modal-create-page(basepath=pageData.meta.path) modal-move-page(current-path=pageData.meta.path) diff --git a/yarn.lock b/yarn.lock index f3061aef..879b6cec 100644 Binary files a/yarn.lock and b/yarn.lock differ