feat: editor props scripts + styles code editor

pull/2097/head
NGPixel 5 years ago
parent 0a16929a57
commit 718c14dd74

@ -203,7 +203,7 @@ export default {
this.checkoutDateActive = this.checkoutDate
if (this.effectivePermissions) {
this.$store.set('page/effectivePermissions',JSON.parse(Buffer.from(this.effectivePermissions, 'base64').toString()))
this.$store.set('page/effectivePermissions', JSON.parse(Buffer.from(this.effectivePermissions, 'base64').toString()))
}
},
mounted() {

@ -936,86 +936,6 @@ $editor-height-mobile: calc(100vh - 112px - 16px);
.CodeMirror-selection-highlight-scrollbar {
background-color: mc('green', '600');
}
.cm-s-wikijs-dark.CodeMirror {
background: darken(mc('grey','900'), 3%);
color: #e0e0e0;
}
.cm-s-wikijs-dark div.CodeMirror-selected {
background: mc('blue','800');
}
.cm-s-wikijs-dark .cm-matchhighlight {
background: mc('blue','800');
}
.cm-s-wikijs-dark .CodeMirror-line::selection, .cm-s-wikijs-dark .CodeMirror-line > span::selection, .cm-s-wikijs-dark .CodeMirror-line > span > span::selection {
background: mc('amber', '500');
}
.cm-s-wikijs-dark .CodeMirror-line::-moz-selection, .cm-s-wikijs-dark .CodeMirror-line > span::-moz-selection, .cm-s-wikijs-dark .CodeMirror-line > span > span::-moz-selection {
background: mc('amber', '500');
}
.cm-s-wikijs-dark .CodeMirror-gutters {
background: darken(mc('grey','900'), 6%);
border-right: 1px solid mc('grey','900');
}
.cm-s-wikijs-dark .CodeMirror-guttermarker {
color: #ac4142;
}
.cm-s-wikijs-dark .CodeMirror-guttermarker-subtle {
color: #505050;
}
.cm-s-wikijs-dark .CodeMirror-linenumber {
color: mc('grey','800');
}
.cm-s-wikijs-dark .CodeMirror-cursor {
border-left: 1px solid #b0b0b0;
}
.cm-s-wikijs-dark span.cm-comment {
color: mc('orange','800');
}
.cm-s-wikijs-dark span.cm-atom {
color: #aa759f;
}
.cm-s-wikijs-dark span.cm-number {
color: #aa759f;
}
.cm-s-wikijs-dark span.cm-property, .cm-s-wikijs-dark span.cm-attribute {
color: #90a959;
}
.cm-s-wikijs-dark span.cm-keyword {
color: #ac4142;
}
.cm-s-wikijs-dark span.cm-string {
color: #f4bf75;
}
.cm-s-wikijs-dark span.cm-variable {
color: #90a959;
}
.cm-s-wikijs-dark span.cm-variable-2 {
color: #6a9fb5;
}
.cm-s-wikijs-dark span.cm-def {
color: #d28445;
}
.cm-s-wikijs-dark span.cm-bracket {
color: #e0e0e0;
}
.cm-s-wikijs-dark span.cm-tag {
color: #ac4142;
}
.cm-s-wikijs-dark span.cm-link {
color: #aa759f;
}
.cm-s-wikijs-dark span.cm-error {
background: #ac4142;
color: #b0b0b0;
}
.cm-s-wikijs-dark .CodeMirror-activeline-background {
background: mc('grey','900');
}
.cm-s-wikijs-dark .CodeMirror-matchingbracket {
text-decoration: underline;
color: white !important;
}
}
// HINT DROPDOWN

@ -17,12 +17,13 @@
v-icon(left) mdi-check
span {{ $t('common:actions.ok') }}
v-card(tile)
v-tabs(color='white', background-color='blue darken-1', dark, centered)
v-tabs(color='white', background-color='blue darken-1', dark, centered, v-model='currentTab')
v-tab {{$t('editor:props.info')}}
v-tab {{$t('editor:props.scheduling')}}
v-tab(disabled) {{$t('editor:props.scripts')}}
v-tab(:disabled='!hasScriptPermission') {{$t('editor:props.scripts')}}
v-tab {{$t('editor:props.social')}}
v-tab-item
v-tab(:disabled='!hasStylePermission') {{$t('editor:props.styles')}}
v-tab-item(transition='fade-transition', reverse-transition='fade-transition')
v-card-text.pt-5
.overline.pb-5 {{$t('editor:props.pageInfo')}}
v-text-field(
@ -88,16 +89,15 @@
hide-no-data
:search-input.sync='newTagSearch'
)
v-tab-item
v-tab-item(transition='fade-transition', reverse-transition='fade-transition')
v-card-text
.overline.pb-5 {{$t('editor:props.publishState')}} #[v-chip.ml-3(label, color='grey', small, outlined).white--text coming soon]
.overline {{$t('editor:props.publishState')}}
v-switch(
:label='$t(`editor:props.publishToggle`)'
v-model='isPublished'
color='primary'
:hint='$t(`editor:props.publishToggleHint`)'
persistent-hint
disabled
inset
)
v-divider
@ -111,7 +111,7 @@
v-model='isPublishStartShown'
:return-value.sync='publishStartDate'
width='460px'
:disabled='!isPublished || true'
:disabled='!isPublished'
)
template(v-slot:activator='{ on }')
v-text-field(
@ -124,7 +124,7 @@
clearable
:hint='$t(`editor:props.publishStartHint`)'
persistent-hint
:disabled='!isPublished || true'
:disabled='!isPublished'
)
v-date-picker(
v-model='publishStartDate'
@ -152,7 +152,7 @@
v-model='isPublishEndShown'
:return-value.sync='publishEndDate'
width='460px'
:disabled='!isPublished || true'
:disabled='!isPublished'
)
template(v-slot:activator='{ on }')
v-text-field(
@ -165,7 +165,7 @@
clearable
:hint='$t(`editor:props.publishEndHint`)'
persistent-hint
:disabled='!isPublished || true'
:disabled='!isPublished'
)
v-date-picker(
v-model='publishEndDate'
@ -187,35 +187,21 @@
@click='$refs.menuPublishEnd.save(publishEndDate)'
) {{$t('common:actions.ok')}}
v-tab-item
v-card-text
.overline.pb-3 {{$t('editor:props.js')}}
v-textarea(
outlined
rows='5'
:hint='$t(`editor:props.jsHint`)'
persistent-hint
)
v-divider
v-card-text.grey.pt-5(:class='$vuetify.theme.dark ? `darken-3-d3` : `lighten-5`')
.overline.pb-3 {{$t('editor:props.css')}}
v-textarea(
outlined
rows='5'
:hint='$t(`editor:props.cssHint`)'
persistent-hint
)
v-tab-item(:transition='false', :reverse-transition='false')
.editor-props-codeeditor
textarea(ref='codejs')
.editor-props-codeeditor-hint
.caption {{$t('editor:props.jsHint')}}
v-tab-item
v-tab-item(transition='fade-transition', reverse-transition='fade-transition')
v-card-text
.overline.pb-5 {{$t('editor:props.socialFeatures')}} #[v-chip.ml-3(label, color='grey', small, outlined).white--text coming soon]
.overline {{$t('editor:props.socialFeatures')}}
v-switch(
:label='$t(`editor:props.allowComments`)'
v-model='isPublished'
color='primary'
:hint='$t(`editor:props.allowCommentsHint`)'
persistent-hint
disabled
inset
)
v-switch(
@ -233,7 +219,6 @@
color='primary'
:hint='$t(`editor:props.displayAuthorHint`)'
persistent-hint
disabled
inset
)
v-switch(
@ -242,10 +227,15 @@
color='primary'
:hint='$t(`editor:props.displaySharingBarHint`)'
persistent-hint
disabled
inset
)
v-tab-item(:transition='false', :reverse-transition='false')
.editor-props-codeeditor
textarea(ref='codecss')
.editor-props-codeeditor-hint
.caption {{$t('editor:props.cssHint')}}
page-selector(:mode='pageSelectorMode', v-model='pageSelectorShown', :path='path', :locale='locale', :open-handler='setPath')
</template>
@ -254,6 +244,11 @@ import _ from 'lodash'
import { sync, get } from 'vuex-pathify'
import gql from 'graphql-tag'
import CodeMirror from 'codemirror'
import 'codemirror/lib/codemirror.css'
import 'codemirror/mode/javascript/javascript.js'
import 'codemirror/mode/css/css.js'
/* global siteLangs, siteConfig */
export default {
@ -263,7 +258,7 @@ export default {
default: false
}
},
data() {
data () {
return {
isPublishStartShown: false,
isPublishEndShown: false,
@ -271,7 +266,9 @@ export default {
namespaces: siteLangs.length ? siteLangs.map(ns => ns.code) : [siteConfig.lang],
newTag: '',
newTagSuggestions: [],
newTagSearch: ''
newTagSearch: '',
currentTab: 0,
cm: null
}
},
computed: {
@ -288,20 +285,23 @@ export default {
isPublished: sync('page/isPublished'),
publishStartDate: sync('page/publishStartDate'),
publishEndDate: sync('page/publishEndDate'),
scriptJs: sync('page/scriptJs'),
scriptCss: sync('page/scriptCss'),
hasScriptPermission: get('page/effectivePermissions@pages.script'),
hasStylePermission: get('page/effectivePermissions@pages.style'),
pageSelectorMode () {
return (this.mode === 'create') ? 'create' : 'move'
}
},
watch: {
value(newValue, oldValue) {
value (newValue, oldValue) {
if (newValue) {
_.delay(() => {
this.$refs.iptTitle.focus()
// this.$tours['editorPropertiesTour'].start()
}, 500)
}
},
newTag(newValue, oldValue) {
newTag (newValue, oldValue) {
const tagClean = _.trim(newValue || '').toLowerCase()
if (tagClean && tagClean.length > 0) {
if (!_.includes(this.tags, tagClean)) {
@ -311,6 +311,24 @@ export default {
this.newTag = null
})
}
},
currentTab (newValue, oldValue) {
if (this.cm) {
this.cm.toTextArea()
}
if (newValue === 2) {
this.$nextTick(() => {
setTimeout(() => {
this.loadEditor(this.$refs.codejs, 'javascript')
}, 100)
})
} else if (newValue === 4) {
this.$nextTick(() => {
setTimeout(() => {
this.loadEditor(this.$refs.codecss, 'css')
}, 100)
})
}
}
},
methods: {
@ -326,6 +344,42 @@ export default {
setPath({ path, locale }) {
this.locale = locale
this.path = path
},
loadEditor(ref, mode) {
this.cm = CodeMirror.fromTextArea(ref, {
tabSize: 2,
mode: `text/${mode}`,
theme: 'wikijs-dark',
lineNumbers: true,
lineWrapping: true,
line: true,
styleActiveLine: true,
viewportMargin: 50,
inputStyle: 'contenteditable',
direction: 'ltr'
})
switch (mode) {
case 'javascript':
this.cm.setValue(this.scriptJs)
this.cm.on('change', c => {
this.scriptJs = c.getValue()
})
break
case 'css':
this.cm.setValue(this.scriptCss)
this.cm.on('change', c => {
this.scriptCss = c.getValue()
})
break
default:
console.warn('Invalid Editor Mode')
break
}
this.cm.setSize(null, '500px')
this.$nextTick(() => {
this.cm.refresh()
this.cm.focus()
})
}
},
apollo: {
@ -355,4 +409,20 @@ export default {
<style lang='scss'>
.editor-props-codeeditor {
background-color: mc('grey', '900');
min-height: 500px;
> textarea {
visibility: hidden;
}
&-hint {
background-color: mc('grey', '900');
border-top: 1px solid lighten(mc('grey', '900'), 5%);
color: mc('grey', '500');
padding: 5px 10px;
}
}
</style>

@ -8,6 +8,7 @@
@import '~katex/dist/katex.min.css';
@import '~diff2html/bundles/css/diff2html.min.css';
@import 'components/codemirror';
@import 'components/katex';
@import 'components/v-btn';
@import 'components/v-data-table';

@ -0,0 +1,79 @@
.cm-s-wikijs-dark.CodeMirror {
background: darken(mc('grey','900'), 3%);
color: #e0e0e0;
}
.cm-s-wikijs-dark div.CodeMirror-selected {
background: mc('blue','800');
}
.cm-s-wikijs-dark .cm-matchhighlight {
background: mc('blue','800');
}
.cm-s-wikijs-dark .CodeMirror-line::selection, .cm-s-wikijs-dark .CodeMirror-line > span::selection, .cm-s-wikijs-dark .CodeMirror-line > span > span::selection {
background: mc('amber', '500');
}
.cm-s-wikijs-dark .CodeMirror-line::-moz-selection, .cm-s-wikijs-dark .CodeMirror-line > span::-moz-selection, .cm-s-wikijs-dark .CodeMirror-line > span > span::-moz-selection {
background: mc('amber', '500');
}
.cm-s-wikijs-dark .CodeMirror-gutters {
background: darken(mc('grey','900'), 6%);
border-right: 1px solid mc('grey','900');
}
.cm-s-wikijs-dark .CodeMirror-guttermarker {
color: #ac4142;
}
.cm-s-wikijs-dark .CodeMirror-guttermarker-subtle {
color: #505050;
}
.cm-s-wikijs-dark .CodeMirror-linenumber {
color: mc('grey','800');
}
.cm-s-wikijs-dark .CodeMirror-cursor {
border-left: 1px solid #b0b0b0;
}
.cm-s-wikijs-dark span.cm-comment {
color: mc('orange','800');
}
.cm-s-wikijs-dark span.cm-atom {
color: #aa759f;
}
.cm-s-wikijs-dark span.cm-number {
color: #aa759f;
}
.cm-s-wikijs-dark span.cm-property, .cm-s-wikijs-dark span.cm-attribute {
color: #90a959;
}
.cm-s-wikijs-dark span.cm-keyword {
color: #ac4142;
}
.cm-s-wikijs-dark span.cm-string {
color: #f4bf75;
}
.cm-s-wikijs-dark span.cm-variable {
color: #90a959;
}
.cm-s-wikijs-dark span.cm-variable-2 {
color: #6a9fb5;
}
.cm-s-wikijs-dark span.cm-def {
color: #d28445;
}
.cm-s-wikijs-dark span.cm-bracket {
color: #e0e0e0;
}
.cm-s-wikijs-dark span.cm-tag {
color: #ac4142;
}
.cm-s-wikijs-dark span.cm-link {
color: #aa759f;
}
.cm-s-wikijs-dark span.cm-error {
background: #ac4142;
color: #b0b0b0;
}
.cm-s-wikijs-dark .CodeMirror-activeline-background {
background: mc('grey','900');
}
.cm-s-wikijs-dark .CodeMirror-matchingbracket {
text-decoration: underline;
color: white !important;
}

@ -15,6 +15,8 @@ const state = {
title: '',
updatedAt: '',
mode: '',
scriptJs: '',
scriptCss: '',
effectivePermissions: {
comments: {
read: false,
@ -30,7 +32,9 @@ const state = {
pages: {
write: false,
manage: false,
delete: false
delete: false,
script: false,
style: false
},
system: {
manage: false

@ -23,7 +23,9 @@ const getPageEffectivePermissions = (req, page) => {
pages: {
write: WIKI.auth.checkAccess(req.user, ['write:pages'], page),
manage: WIKI.auth.checkAccess(req.user, ['manage:pages'], page),
delete: WIKI.auth.checkAccess(req.user, ['delete:pages'], page)
delete: WIKI.auth.checkAccess(req.user, ['delete:pages'], page),
script: WIKI.auth.checkAccess(req.user, ['write:scripts'], page),
style: WIKI.auth.checkAccess(req.user, ['write:styles'], page)
},
system: {
manage: WIKI.auth.checkAccess(req.user, ['manage:system'], page)

Loading…
Cancel
Save