feat: admin component
This commit is contained in:
parent
a4f00e795c
commit
0ccdf10c9d
@ -5,6 +5,7 @@
|
||||
import CONSTANTS from './constants'
|
||||
|
||||
import Vue from 'vue'
|
||||
import VueRouter from 'vue-router'
|
||||
import VueClipboards from 'vue-clipboards'
|
||||
import VueSimpleBreakpoints from 'vue-simple-breakpoints'
|
||||
import VeeValidate from 'vee-validate'
|
||||
@ -79,6 +80,7 @@ window.graphQL = new ApolloClient({
|
||||
// Initialize Vue Modules
|
||||
// ====================================
|
||||
|
||||
Vue.use(VueRouter)
|
||||
Vue.use(VueClipboards)
|
||||
Vue.use(VueSimpleBreakpoints)
|
||||
Vue.use(localization.VueI18Next)
|
||||
@ -102,6 +104,7 @@ Vue.prototype.Velocity = Velocity
|
||||
// Register Vue Components
|
||||
// ====================================
|
||||
|
||||
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('navigator', () => import(/* webpackMode: "eager" */ './components/navigator.vue'))
|
||||
|
19
client/components/admin-dashboard.vue
Normal file
19
client/components/admin-dashboard.vue
Normal file
@ -0,0 +1,19 @@
|
||||
<template lang='pug'>
|
||||
v-container(fluid, fill-height)
|
||||
v-layout(row wrap)
|
||||
v-flex(xs12)
|
||||
.headline.blue--text.text--darken-2 Dashboard
|
||||
.subheading.grey--text Coming soon
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='scss'>
|
||||
|
||||
</style>
|
38
client/components/admin-general.vue
Normal file
38
client/components/admin-general.vue
Normal file
@ -0,0 +1,38 @@
|
||||
<template lang='pug'>
|
||||
v-container(fluid, fill-height, grid-list-lg)
|
||||
v-layout(row wrap)
|
||||
v-flex(xs12)
|
||||
.headline.blue--text.text--darken-2 General
|
||||
.subheading.grey--text Main settings of your wiki
|
||||
v-form.pt-3
|
||||
v-layout(row wrap)
|
||||
v-flex(lg6 xs12)
|
||||
v-card
|
||||
v-toolbar(color='blue', dark, dense, flat)
|
||||
v-toolbar-title
|
||||
.subheading Site Info
|
||||
v-card-text
|
||||
v-text-field(label='Site Title', required, :counter='50')
|
||||
v-text-field(label='Site Description', :counter='255')
|
||||
v-flex(lg6 xs12)
|
||||
v-card
|
||||
v-toolbar(color='blue', dark, dense, flat)
|
||||
v-toolbar-title
|
||||
.subheading Site Branding
|
||||
v-card-text
|
||||
v-text-field(label='Site Title', required, :counter='50')
|
||||
v-text-field(label='Site Description', :counter='255')
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='scss'>
|
||||
|
||||
</style>
|
115
client/components/admin.vue
Normal file
115
client/components/admin.vue
Normal file
@ -0,0 +1,115 @@
|
||||
<template lang='pug'>
|
||||
v-app.admin
|
||||
v-toolbar(color='black', dark, app, clipped-left, fixed, flat)
|
||||
v-toolbar-side-icon(@click.native='')
|
||||
v-toolbar-title
|
||||
span.subheading Wiki.js
|
||||
v-spacer
|
||||
v-btn(icon)
|
||||
v-icon(color='grey') search
|
||||
v-btn(icon, @click.native='darkTheme = !darkTheme')
|
||||
v-icon(color='grey') settings
|
||||
v-menu(offset-y, min-width='300')
|
||||
v-btn(icon, slot='activator')
|
||||
v-icon(color='grey') account_circle
|
||||
v-list.py-0
|
||||
v-list-tile.py-3(avatar)
|
||||
v-list-tile-avatar
|
||||
v-avatar.red(:size='40'): span.white--text.subheading JD
|
||||
v-list-tile-content
|
||||
v-list-tile-title John Doe
|
||||
v-list-tile-sub-title john.doe@example.com
|
||||
v-divider.my-0
|
||||
v-list-tile(@click='')
|
||||
v-list-tile-action: v-icon(color='red') exit_to_app
|
||||
v-list-tile-title Logout
|
||||
|
||||
v-navigation-drawer.pb-0(v-model='adminDrawerShown', app, fixed, clipped, left, permanent)
|
||||
v-list(dense)
|
||||
v-list-tile.pt-2(to='/dashboard')
|
||||
v-list-tile-action: v-icon dashboard
|
||||
v-list-tile-title Dashboard
|
||||
v-divider.my-2
|
||||
v-subheader Site
|
||||
v-list-tile(to='/general')
|
||||
v-list-tile-action: v-icon widgets
|
||||
v-list-tile-title General
|
||||
v-list-tile(to='/locale')
|
||||
v-list-tile-action: v-icon language
|
||||
v-list-tile-title Locale
|
||||
v-list-tile(to='/stats')
|
||||
v-list-tile-action: v-icon show_chart
|
||||
v-list-tile-title Statistics
|
||||
v-list-tile(to='/theme')
|
||||
v-list-tile-action: v-icon palette
|
||||
v-list-tile-title Theme
|
||||
v-divider.my-2
|
||||
v-subheader Users
|
||||
v-list-tile(to='/groups')
|
||||
v-list-tile-action: v-icon people
|
||||
v-list-tile-title Groups
|
||||
v-list-tile(to='/users')
|
||||
v-list-tile-action: v-icon perm_identity
|
||||
v-list-tile-title Users
|
||||
v-divider.my-2
|
||||
v-subheader Modules
|
||||
v-list-tile(to='/auth')
|
||||
v-list-tile-action: v-icon lock_outline
|
||||
v-list-tile-title Authentication
|
||||
v-list-tile(to='/rendering')
|
||||
v-list-tile-action: v-icon system_update_alt
|
||||
v-list-tile-title Content Rendering
|
||||
v-list-tile(to='/editor')
|
||||
v-list-tile-action: v-icon transform
|
||||
v-list-tile-title Editor
|
||||
v-list-tile(to='/logging')
|
||||
v-list-tile-action: v-icon graphic_eq
|
||||
v-list-tile-title Logging
|
||||
v-list-tile(to='/storage')
|
||||
v-list-tile-action: v-icon storage
|
||||
v-list-tile-title Storage
|
||||
v-divider.my-2
|
||||
v-subheader System
|
||||
v-list-tile(to='/system')
|
||||
v-list-tile-action: v-icon tune
|
||||
v-list-tile-title System Info
|
||||
v-list-tile(to='/utilities')
|
||||
v-list-tile-action: v-icon build
|
||||
v-list-tile-title Utilities
|
||||
v-list-tile(to='/dev')
|
||||
v-list-tile-action: v-icon weekend
|
||||
v-list-tile-title Developer Tools
|
||||
|
||||
v-content
|
||||
router-view
|
||||
|
||||
v-footer.py-2.justify-center(app, fixed, color='grey lighten-3', inset, height='auto')
|
||||
.caption.grey--text.text--darken-1 Powered by Wiki.js
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import VueRouter from 'vue-router'
|
||||
|
||||
const router = new VueRouter({
|
||||
mode: 'history',
|
||||
base: '/a',
|
||||
routes: [
|
||||
{ path: '/', redirect: '/dashboard' },
|
||||
{ path: '/dashboard', component: () => import(/* webpackChunkName: "admin" */ './admin-dashboard.vue') },
|
||||
{ path: '/general', component: () => import(/* webpackChunkName: "admin" */ './admin-general.vue') }
|
||||
]
|
||||
})
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
adminDrawerShown: true
|
||||
}
|
||||
},
|
||||
router
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='scss'>
|
||||
|
||||
</style>
|
@ -5,7 +5,7 @@
|
||||
v-toolbar-title.white--text Sample Page
|
||||
.editor-code-toolbar
|
||||
.editor-code-toolbar-group
|
||||
.editor-code-toolbar-item
|
||||
.editor-code-toolbar-item(@click='toggleAround("**", "**")')
|
||||
svg.icons.is-18(role='img')
|
||||
title Bold
|
||||
use(xlink:href='#fa-bold')
|
||||
@ -90,6 +90,11 @@
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
|
||||
// ========================================
|
||||
// IMPORTS
|
||||
// ========================================
|
||||
|
||||
// Code Mirror
|
||||
import { codemirror } from 'vue-codemirror'
|
||||
import 'codemirror/lib/codemirror.css'
|
||||
|
||||
@ -120,6 +125,14 @@ import mdImsize from 'markdown-it-imsize'
|
||||
// Prism (Syntax Highlighting)
|
||||
import Prism from '../libs/prism/prism.js'
|
||||
|
||||
// ========================================
|
||||
// INIT
|
||||
// ========================================
|
||||
|
||||
// Platform detection
|
||||
const CtrlKey = /Mac/.test(navigator.platform) ? 'Cmd' : 'Ctrl'
|
||||
|
||||
// Markdown Instance
|
||||
const md = new MarkdownIt({
|
||||
html: true,
|
||||
breaks: true,
|
||||
@ -138,6 +151,10 @@ const md = new MarkdownIt({
|
||||
.use(mdMark)
|
||||
.use(mdImsize)
|
||||
|
||||
// ========================================
|
||||
// HELPER FUNCTIONS
|
||||
// ========================================
|
||||
|
||||
// Inject line numbers for preview scroll sync
|
||||
let linesMap = []
|
||||
function injectLineNumbers (tokens, idx, options, env, slf) {
|
||||
@ -153,6 +170,10 @@ function injectLineNumbers (tokens, idx, options, env, slf) {
|
||||
md.renderer.rules.paragraph_open = injectLineNumbers
|
||||
md.renderer.rules.heading_open = injectLineNumbers
|
||||
|
||||
// ========================================
|
||||
// Vue Component
|
||||
// ========================================
|
||||
|
||||
export default {
|
||||
components: {
|
||||
codemirror
|
||||
@ -192,19 +213,24 @@ export default {
|
||||
methods: {
|
||||
onCmReady(cm) {
|
||||
let self = this
|
||||
cm.setSize(null, 'calc(100vh - 100px)')
|
||||
cm.setOption('extraKeys', {
|
||||
'F11'(cm) {
|
||||
const keyBindings = {
|
||||
'F11' (cm) {
|
||||
cm.setOption('fullScreen', !cm.getOption('fullScreen'))
|
||||
},
|
||||
'Esc'(cm) {
|
||||
'Esc' (cm) {
|
||||
if (cm.getOption('fullScreen')) cm.setOption('fullScreen', false)
|
||||
},
|
||||
'Ctrl-S'(cm) {
|
||||
self.$parent.save()
|
||||
}
|
||||
}
|
||||
_.set(keyBindings, `${CtrlKey}-S`, cm => {
|
||||
self.$parent.save()
|
||||
})
|
||||
|
||||
cm.setSize(null, 'calc(100vh - 100px)')
|
||||
cm.setOption('extraKeys', keyBindings)
|
||||
cm.on('cursorActivity', cm => {
|
||||
this.toolbarSync(cm)
|
||||
this.scrollSync(cm)
|
||||
})
|
||||
cm.on('cursorActivity', this.scrollSync)
|
||||
this.onCmInput(this.code)
|
||||
},
|
||||
onCmInput: _.debounce(function (newContent) {
|
||||
@ -215,6 +241,17 @@ export default {
|
||||
this.scrollSync(this.cm)
|
||||
})
|
||||
}, 500),
|
||||
/**
|
||||
* Update toolbar state
|
||||
*/
|
||||
toolbarSync(cm) {
|
||||
const pos = cm.getCursor('start')
|
||||
const token = cm.getTokenAt(pos)
|
||||
|
||||
if (!token.type) { return }
|
||||
|
||||
console.info(token)
|
||||
},
|
||||
/**
|
||||
* Update scroll sync
|
||||
*/
|
||||
@ -232,7 +269,10 @@ export default {
|
||||
this.Velocity(destElm, 'scroll', { offset: '-100', duration: 1000, container: this.$refs.editorPreview })
|
||||
}
|
||||
}
|
||||
}, 500)
|
||||
}, 500),
|
||||
toggleAround (before, after) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -16,8 +16,8 @@ import _ from 'lodash'
|
||||
export default {
|
||||
components: {
|
||||
editorCode: () => import(/* webpackChunkName: "editor-code" */ './editor-code.vue'),
|
||||
editorModalAccess: () => import(/* webpackChunkName: "editor-common" */ './editor-modal-access.vue'),
|
||||
editorModalProperties: () => import(/* webpackChunkName: "editor-common" */ './editor-modal-properties.vue')
|
||||
editorModalAccess: () => import(/* webpackChunkName: "editor" */ './editor-modal-access.vue'),
|
||||
editorModalProperties: () => import(/* webpackChunkName: "editor" */ './editor-modal-properties.vue')
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -20,28 +20,17 @@ html {
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: lighten(mc('blue-grey','50'), 5%);
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
main {
|
||||
background-color: mc('blue','500');
|
||||
background-image: linear-gradient(to bottom, mc('blue', '700') 0%, mc('blue', '500') 100%);
|
||||
padding: 50px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
a {
|
||||
color: mc('indigo', '600');
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: mc('indigo', '700');
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
// body {
|
||||
// background-color: lighten(mc('blue-grey','50'), 5%);
|
||||
// height: 100%;
|
||||
// }
|
||||
|
||||
// main {
|
||||
// background-color: mc('blue','500');
|
||||
// background-image: linear-gradient(to bottom, mc('blue', '700') 0%, mc('blue', '500') 100%);
|
||||
// padding: 50px;
|
||||
// min-height: 100vh;
|
||||
// }
|
||||
// Container
|
||||
|
||||
.container {
|
||||
|
@ -201,6 +201,7 @@
|
||||
"vue-codemirror": "4.0.3",
|
||||
"vue-hot-reload-api": "2.2.4",
|
||||
"vue-loader": "14.1.1",
|
||||
"vue-router": "3.0.1",
|
||||
"vue-simple-breakpoints": "1.0.3",
|
||||
"vue-template-compiler": "2.5.13",
|
||||
"vuetify": "1.0.1",
|
||||
|
@ -8,6 +8,13 @@ router.get('/e/*', (req, res, next) => {
|
||||
res.render('main/editor')
|
||||
})
|
||||
|
||||
/**
|
||||
* Administration
|
||||
*/
|
||||
router.get(['/a', '/a/*'], (req, res, next) => {
|
||||
res.render('main/admin')
|
||||
})
|
||||
|
||||
/**
|
||||
* View document
|
||||
*/
|
||||
|
6
server/views/main/admin.pug
Normal file
6
server/views/main/admin.pug
Normal file
@ -0,0 +1,6 @@
|
||||
extends ../master.pug
|
||||
|
||||
block body
|
||||
body
|
||||
#app
|
||||
admin
|
@ -10412,6 +10412,10 @@ vue-loader@14.1.1:
|
||||
vue-style-loader "^4.0.1"
|
||||
vue-template-es2015-compiler "^1.6.0"
|
||||
|
||||
vue-router@3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.0.1.tgz#d9b05ad9c7420ba0f626d6500d693e60092cc1e9"
|
||||
|
||||
vue-simple-breakpoints@1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/vue-simple-breakpoints/-/vue-simple-breakpoints-1.0.3.tgz#0ae5b77af4cdbd948b514d2f485686174dc5ff5d"
|
||||
|
Loading…
Reference in New Issue
Block a user