feat: sidebar item permissions + admin nav edit
This commit is contained in:
@@ -215,6 +215,7 @@ let bootstrap = () => {
|
|||||||
// Load theme-specific code
|
// Load theme-specific code
|
||||||
// ====================================
|
// ====================================
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-unused-expressions
|
||||||
import(/* webpackChunkName: "theme-page" */ './themes/' + process.env.CURRENT_THEME + '/js/app.js')
|
import(/* webpackChunkName: "theme-page" */ './themes/' + process.env.CURRENT_THEME + '/js/app.js')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -118,6 +118,8 @@
|
|||||||
:items='locales'
|
:items='locales'
|
||||||
v-model='rule.locales'
|
v-model='rule.locales'
|
||||||
placeholder='Any Locale'
|
placeholder='Any Locale'
|
||||||
|
item-value='code'
|
||||||
|
item-text='name'
|
||||||
multiple
|
multiple
|
||||||
hide-details
|
hide-details
|
||||||
height='48px'
|
height='48px'
|
||||||
@@ -126,7 +128,7 @@
|
|||||||
style='flex: 0 1 150px;'
|
style='flex: 0 1 150px;'
|
||||||
)
|
)
|
||||||
template(slot='selection', slot-scope='{ item, index }')
|
template(slot='selection', slot-scope='{ item, index }')
|
||||||
v-chip.white--text.ml-0(v-if='rule.locales.length === 1', small, label, :color='rule.deny ? `red` : `green`').caption {{ item.value.toUpperCase() }}
|
v-chip.white--text.ml-0(v-if='rule.locales.length === 1', small, label, :color='rule.deny ? `red` : `green`').caption {{ item.code.toUpperCase() }}
|
||||||
v-chip.white--text.ml-0(v-else-if='index === 0', small, label, :color='rule.deny ? `red` : `green`').caption {{ rule.locales.length }} locales
|
v-chip.white--text.ml-0(v-else-if='index === 0', small, label, :color='rule.deny ? `red` : `green`').caption {{ rule.locales.length }} locales
|
||||||
v-list-item(slot='prepend-item', @click='rule.locales = []')
|
v-list-item(slot='prepend-item', @click='rule.locales = []')
|
||||||
v-list-item-action(style='min-width: 30px;')
|
v-list-item-action(style='min-width: 30px;')
|
||||||
@@ -149,8 +151,8 @@
|
|||||||
)
|
)
|
||||||
v-icon.mr-2(:color='rule.deny ? `red` : `green`') mdi-web
|
v-icon.mr-2(:color='rule.deny ? `red` : `green`') mdi-web
|
||||||
v-list-item-content
|
v-list-item-content
|
||||||
v-list-item-title.body-2 {{props.item.text}}
|
v-list-item-title.body-2 {{props.item.name}}
|
||||||
v-chip.mr-2.grey--text(label, small, :color='$vuetify.theme.dark ? `grey darken-4` : `grey lighten-4`').caption {{props.item.value.toUpperCase()}}
|
v-chip.mr-2.grey--text(label, small, :color='$vuetify.theme.dark ? `grey darken-4` : `grey lighten-4`').caption {{props.item.code.toUpperCase()}}
|
||||||
|
|
||||||
//- Path
|
//- Path
|
||||||
v-text-field(
|
v-text-field(
|
||||||
@@ -197,6 +199,8 @@
|
|||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import { customAlphabet } from 'nanoid/non-secure'
|
import { customAlphabet } from 'nanoid/non-secure'
|
||||||
|
|
||||||
|
/* global siteLangs */
|
||||||
|
|
||||||
const nanoid = customAlphabet('1234567890abcdef', 10)
|
const nanoid = customAlphabet('1234567890abcdef', 10)
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -209,10 +213,10 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
roles: [
|
roles: [
|
||||||
{ text: 'Read Pages', value: 'read:pages', icon: 'mdi-file-document-box-search-outline' },
|
{ text: 'Read Pages', value: 'read:pages', icon: 'mdi-file-eye-outline' },
|
||||||
{ text: 'Create Pages', value: 'write:pages', icon: 'mdi-file-document-box-plus-outline' },
|
{ text: 'Create Pages', value: 'write:pages', icon: 'mdi-file-plus-outline' },
|
||||||
{ text: 'Edit + Move Pages', value: 'manage:pages', icon: 'mdi-file-document-edit-outline' },
|
{ text: 'Edit + Move Pages', value: 'manage:pages', icon: 'mdi-file-document-edit-outline' },
|
||||||
{ text: 'Delete Pages', value: 'delete:pages', icon: 'mdi-file-document-box-remove-outline' },
|
{ text: 'Delete Pages', value: 'delete:pages', icon: 'mdi-file-remove-outline' },
|
||||||
{ text: 'View Pages Source', value: 'read:source', icon: 'mdi-code-tags' },
|
{ text: 'View Pages Source', value: 'read:source', icon: 'mdi-code-tags' },
|
||||||
{ text: 'View Pages History', value: 'read:history', icon: 'mdi-history' },
|
{ text: 'View Pages History', value: 'read:history', icon: 'mdi-history' },
|
||||||
{ text: 'Read / Use Assets', value: 'read:assets', icon: 'mdi-image-search-outline' },
|
{ text: 'Read / Use Assets', value: 'read:assets', icon: 'mdi-image-search-outline' },
|
||||||
@@ -228,9 +232,6 @@ export default {
|
|||||||
{ text: 'Path Ends With...', value: 'END', icon: '.../' },
|
{ text: 'Path Ends With...', value: 'END', icon: '.../' },
|
||||||
{ text: 'Path Matches Regex...', value: 'REGEX', icon: '$.*' },
|
{ text: 'Path Matches Regex...', value: 'REGEX', icon: '$.*' },
|
||||||
{ text: 'Tag Matches...', value: 'TAG', icon: 'T' }
|
{ text: 'Tag Matches...', value: 'TAG', icon: 'T' }
|
||||||
],
|
|
||||||
locales: [
|
|
||||||
{ text: 'English', value: 'en' }
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -238,7 +239,8 @@ export default {
|
|||||||
group: {
|
group: {
|
||||||
get() { return this.value },
|
get() { return this.value },
|
||||||
set(val) { this.$set('input', val) }
|
set(val) { this.$set('input', val) }
|
||||||
}
|
},
|
||||||
|
locales() { return siteLangs }
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
addRule(group) {
|
addRule(group) {
|
||||||
|
|||||||
@@ -69,12 +69,12 @@
|
|||||||
item-value='code'
|
item-value='code'
|
||||||
)
|
)
|
||||||
v-list.py-2(dense, nav, dark, class='blue darken-2', style='border-radius: 0;')
|
v-list.py-2(dense, nav, dark, class='blue darken-2', style='border-radius: 0;')
|
||||||
v-list-item(v-if='navTree.length < 1')
|
v-list-item(v-if='currentTree.length < 1')
|
||||||
v-list-item-avatar(size='24'): v-icon(color='blue lighten-3') mdi-alert
|
v-list-item-avatar(size='24'): v-icon(color='blue lighten-3') mdi-alert
|
||||||
v-list-item-content
|
v-list-item-content
|
||||||
em.caption.blue--text.text--lighten-4 {{$t('navigation.emptyList')}}
|
em.caption.blue--text.text--lighten-4 {{$t('navigation.emptyList')}}
|
||||||
draggable(v-model='navTree')
|
draggable(v-model='currentTree')
|
||||||
template(v-for='navItem in navTree')
|
template(v-for='navItem in currentTree')
|
||||||
v-list-item(
|
v-list-item(
|
||||||
v-if='navItem.kind === "link"'
|
v-if='navItem.kind === "link"'
|
||||||
:key='navItem.id'
|
:key='navItem.id'
|
||||||
@@ -223,7 +223,7 @@
|
|||||||
)
|
)
|
||||||
template(v-else)
|
template(v-else)
|
||||||
v-toolbar(height='56', color='teal lighten-1', flat, dark)
|
v-toolbar(height='56', color='teal lighten-1', flat, dark)
|
||||||
v-card-text.grey--text(v-if='navTree.length > 0') {{$t('navigation.noSelectionText')}}
|
v-card-text.grey--text(v-if='currentTree.length > 0') {{$t('navigation.noSelectionText')}}
|
||||||
v-card-text.grey--text(v-else) {{$t('navigation.noItemsText')}}
|
v-card-text.grey--text(v-else) {{$t('navigation.noItemsText')}}
|
||||||
|
|
||||||
page-selector(mode='select', v-model='selectPageModal', :open-handler='selectPageHandle', path='home', :locale='currentLang')
|
page-selector(mode='select', v-model='selectPageModal', :open-handler='selectPageHandle', path='home', :locale='currentLang')
|
||||||
@@ -247,9 +247,9 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
selectPageModal: false,
|
selectPageModal: false,
|
||||||
navTree: [],
|
trees: [],
|
||||||
current: {},
|
current: {},
|
||||||
currentLang: 'en',
|
currentLang: siteConfig.lang,
|
||||||
groups: [],
|
groups: [],
|
||||||
config: {
|
config: {
|
||||||
mode: 'NONE'
|
mode: 'NONE'
|
||||||
@@ -267,6 +267,33 @@ export default {
|
|||||||
},
|
},
|
||||||
locales () {
|
locales () {
|
||||||
return siteLangs
|
return siteLangs
|
||||||
|
},
|
||||||
|
currentTree: {
|
||||||
|
get () {
|
||||||
|
return _.get(_.find(this.trees, ['locale', this.currentLang]), 'items', null) || []
|
||||||
|
},
|
||||||
|
set (val) {
|
||||||
|
const tree = _.find(this.trees, ['locale', this.currentLang])
|
||||||
|
if (tree) {
|
||||||
|
tree.items = val
|
||||||
|
} else {
|
||||||
|
this.trees = [...this.trees, {
|
||||||
|
locale: this.currentLang,
|
||||||
|
items: val
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
currentLang (newValue, oldValue) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.currentTree.length > 0) {
|
||||||
|
this.current = this.currentTree[0]
|
||||||
|
} else {
|
||||||
|
this.current = {}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -291,11 +318,11 @@ export default {
|
|||||||
newItem.label = this.$t('navigation.untitled', { kind: this.$t(`navigation.header`) })
|
newItem.label = this.$t('navigation.untitled', { kind: this.$t(`navigation.header`) })
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
this.navTree.push(newItem)
|
this.currentTree = [...this.currentTree, newItem]
|
||||||
this.current = newItem
|
this.current = newItem
|
||||||
},
|
},
|
||||||
deleteItem(item) {
|
deleteItem(item) {
|
||||||
this.navTree = _.pull(this.navTree, item)
|
this.currentTree = _.pull(this.currentTree, item)
|
||||||
this.current = {}
|
this.current = {}
|
||||||
},
|
},
|
||||||
selectItem(item) {
|
selectItem(item) {
|
||||||
@@ -326,7 +353,7 @@ export default {
|
|||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
tree: this.navTree
|
tree: this.trees
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (_.get(resp, 'data.navigation.updateTree.responseResult.succeeded', false)) {
|
if (_.get(resp, 'data.navigation.updateTree.responseResult.succeeded', false)) {
|
||||||
@@ -344,7 +371,7 @@ export default {
|
|||||||
this.$store.commit(`loadingStop`, 'admin-navigation-save')
|
this.$store.commit(`loadingStop`, 'admin-navigation-save')
|
||||||
},
|
},
|
||||||
async refresh() {
|
async refresh() {
|
||||||
await this.$apollo.queries.navTree.refetch()
|
await this.$apollo.queries.trees.refetch()
|
||||||
this.current = {}
|
this.current = {}
|
||||||
this.$store.commit('showNotification', {
|
this.$store.commit('showNotification', {
|
||||||
message: 'Navigation has been refreshed.',
|
message: 'Navigation has been refreshed.',
|
||||||
@@ -353,9 +380,6 @@ export default {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
|
||||||
this.currentLang = siteConfig.lang
|
|
||||||
},
|
|
||||||
apollo: {
|
apollo: {
|
||||||
config: {
|
config: {
|
||||||
query: gql`
|
query: gql`
|
||||||
@@ -373,7 +397,7 @@ export default {
|
|||||||
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-navigation-config')
|
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-navigation-config')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
navTree: {
|
trees: {
|
||||||
query: gql`
|
query: gql`
|
||||||
{
|
{
|
||||||
navigation {
|
navigation {
|
||||||
@@ -386,6 +410,8 @@ export default {
|
|||||||
icon
|
icon
|
||||||
targetType
|
targetType
|
||||||
target
|
target
|
||||||
|
visibilityMode
|
||||||
|
visibilityGroups
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
<template lang="pug">
|
<template lang="pug">
|
||||||
div
|
div
|
||||||
.blue.darken-3.pa-3.d-flex(v-if='navMode === `MIXED`')
|
.blue.darken-3.pa-3.d-flex(v-if='navMode === `MIXED`')
|
||||||
v-btn(depressed, color='blue darken-2', style='min-width:0;', href='/')
|
v-btn(depressed, color='blue darken-2', style='min-width:0;', @click='goHome')
|
||||||
v-icon(size='20') mdi-home
|
v-icon(size='20') mdi-home
|
||||||
v-btn.ml-3(v-if='currentMode === `custom`', depressed, color='blue darken-2', style='flex: 1 1 100%;', @click='switchMode(`browse`)')
|
v-btn.ml-3(v-if='currentMode === `custom`', depressed, color='blue darken-2', style='flex: 1 1 100%;', @click='switchMode(`browse`)')
|
||||||
v-icon(left) mdi-file-tree
|
v-icon(left) mdi-file-tree
|
||||||
.body-2.text-none Browse
|
.body-2.text-none {{$t('common:sidebar.browse')}}
|
||||||
v-btn.ml-3(v-else-if='currentMode === `browse`', depressed, color='blue darken-2', style='flex: 1 1 100%;', @click='switchMode(`custom`)')
|
v-btn.ml-3(v-else-if='currentMode === `browse`', depressed, color='blue darken-2', style='flex: 1 1 100%;', @click='switchMode(`custom`)')
|
||||||
v-icon(left) mdi-navigation
|
v-icon(left) mdi-navigation
|
||||||
.body-2.text-none Main Menu
|
.body-2.text-none {{$t('common:sidebar.mainMenu')}}
|
||||||
v-divider
|
v-divider
|
||||||
//-> Custom Navigation
|
//-> Custom Navigation
|
||||||
v-list.py-2(v-if='currentMode === `custom`', dense, :class='color', :dark='dark')
|
v-list.py-2(v-if='currentMode === `custom`', dense, :class='color', :dark='dark')
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
v-icon(small) mdi-folder-open
|
v-icon(small) mdi-folder-open
|
||||||
v-list-item-title {{ item.title }}
|
v-list-item-title {{ item.title }}
|
||||||
v-divider.mt-2
|
v-divider.mt-2
|
||||||
v-subheader.pl-4 Current Directory
|
v-subheader.pl-4 {{$t('common:sidebar.currentDirectory')}}
|
||||||
template(v-for='item of currentItems')
|
template(v-for='item of currentItems')
|
||||||
v-list-item(v-if='item.isFolder', :key='`childfolder-` + item.id', @click='fetchBrowseItems(item)')
|
v-list-item(v-if='item.isFolder', :key='`childfolder-` + item.id', @click='fetchBrowseItems(item)')
|
||||||
v-list-item-avatar(size='24')
|
v-list-item-avatar(size='24')
|
||||||
@@ -47,6 +47,8 @@ import _ from 'lodash'
|
|||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
import { get } from 'vuex-pathify'
|
import { get } from 'vuex-pathify'
|
||||||
|
|
||||||
|
/* global siteLangs */
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
color: {
|
color: {
|
||||||
@@ -85,6 +87,7 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
switchMode (mode) {
|
switchMode (mode) {
|
||||||
this.currentMode = mode
|
this.currentMode = mode
|
||||||
|
window.localStorage.setItem('navPref', mode)
|
||||||
if (mode === `browse` && this.loadedCache.length < 1) {
|
if (mode === `browse` && this.loadedCache.length < 1) {
|
||||||
this.loadFromCurrentPath()
|
this.loadFromCurrentPath()
|
||||||
}
|
}
|
||||||
@@ -186,14 +189,20 @@ export default {
|
|||||||
this.loadedCache = [curPage.parent]
|
this.loadedCache = [curPage.parent]
|
||||||
this.currentItems = _.filter(items, ['parent', curPage.parent])
|
this.currentItems = _.filter(items, ['parent', curPage.parent])
|
||||||
this.$store.commit(`loadingStop`, 'browse-load')
|
this.$store.commit(`loadingStop`, 'browse-load')
|
||||||
|
},
|
||||||
|
goHome () {
|
||||||
|
window.location.assign(siteLangs.length > 0 ? `/${this.locale}/home` : '/')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
this.currentParent.title = `/ ${this.$t('common:sidebar.root')}`
|
||||||
if (this.navMode === 'TREE') {
|
if (this.navMode === 'TREE') {
|
||||||
this.currentMode = 'browse'
|
this.currentMode = 'browse'
|
||||||
this.loadFromCurrentPath()
|
|
||||||
} else {
|
} else {
|
||||||
this.currentMode = 'custom'
|
this.currentMode = window.localStorage.getItem('navPref') || 'custom'
|
||||||
|
}
|
||||||
|
if (this.currentMode === 'browse') {
|
||||||
|
this.loadFromCurrentPath()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
package.json
28
package.json
@@ -37,7 +37,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aoberoi/passport-slack": "1.0.5",
|
"@aoberoi/passport-slack": "1.0.5",
|
||||||
"@azure/storage-blob": "12.1.1",
|
"@azure/storage-blob": "12.1.1",
|
||||||
"@bugsnag/js": "6.5.2",
|
"@bugsnag/js": "7.0.0",
|
||||||
"@exlinc/keycloak-passport": "1.0.2",
|
"@exlinc/keycloak-passport": "1.0.2",
|
||||||
"@root/csr": "0.8.1",
|
"@root/csr": "0.8.1",
|
||||||
"@root/keypairs": "0.9.0",
|
"@root/keypairs": "0.9.0",
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
"apollo-server": "2.12.0",
|
"apollo-server": "2.12.0",
|
||||||
"apollo-server-express": "2.12.0",
|
"apollo-server-express": "2.12.0",
|
||||||
"auto-load": "3.0.4",
|
"auto-load": "3.0.4",
|
||||||
"aws-sdk": "2.656.0",
|
"aws-sdk": "2.658.0",
|
||||||
"azure-search-client": "3.1.5",
|
"azure-search-client": "3.1.5",
|
||||||
"bcryptjs-then": "1.0.1",
|
"bcryptjs-then": "1.0.1",
|
||||||
"bluebird": "3.7.2",
|
"bluebird": "3.7.2",
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
"emoji-regex": "9.0.0",
|
"emoji-regex": "9.0.0",
|
||||||
"express": "4.17.1",
|
"express": "4.17.1",
|
||||||
"express-brute": "1.0.1",
|
"express-brute": "1.0.1",
|
||||||
"express-session": "1.17.0",
|
"express-session": "1.17.1",
|
||||||
"file-type": "14.1.4",
|
"file-type": "14.1.4",
|
||||||
"filesize": "6.1.0",
|
"filesize": "6.1.0",
|
||||||
"fs-extra": "9.0.0",
|
"fs-extra": "9.0.0",
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
"graphql-tools": "4.0.7",
|
"graphql-tools": "4.0.7",
|
||||||
"he": "1.2.0",
|
"he": "1.2.0",
|
||||||
"highlight.js": "9.18.1",
|
"highlight.js": "9.18.1",
|
||||||
"i18next": "19.4.1",
|
"i18next": "19.4.2",
|
||||||
"i18next-express-middleware": "1.9.1",
|
"i18next-express-middleware": "1.9.1",
|
||||||
"i18next-node-fs-backend": "2.1.3",
|
"i18next-node-fs-backend": "2.1.3",
|
||||||
"image-size": "0.8.3",
|
"image-size": "0.8.3",
|
||||||
@@ -94,7 +94,7 @@
|
|||||||
"jsonwebtoken": "8.5.1",
|
"jsonwebtoken": "8.5.1",
|
||||||
"katex": "0.11.1",
|
"katex": "0.11.1",
|
||||||
"klaw": "3.0.0",
|
"klaw": "3.0.0",
|
||||||
"knex": "0.20.13",
|
"knex": "0.20.15",
|
||||||
"lodash": "4.17.15",
|
"lodash": "4.17.15",
|
||||||
"markdown-it": "10.0.0",
|
"markdown-it": "10.0.0",
|
||||||
"markdown-it-abbr": "1.0.4",
|
"markdown-it-abbr": "1.0.4",
|
||||||
@@ -113,7 +113,7 @@
|
|||||||
"mime-types": "2.1.26",
|
"mime-types": "2.1.26",
|
||||||
"moment": "2.24.0",
|
"moment": "2.24.0",
|
||||||
"moment-timezone": "0.5.28",
|
"moment-timezone": "0.5.28",
|
||||||
"mongodb": "3.5.5",
|
"mongodb": "3.5.6",
|
||||||
"ms": "2.1.2",
|
"ms": "2.1.2",
|
||||||
"mssql": "6.2.0",
|
"mssql": "6.2.0",
|
||||||
"multer": "1.4.2",
|
"multer": "1.4.2",
|
||||||
@@ -157,7 +157,7 @@
|
|||||||
"safe-regex": "2.1.1",
|
"safe-regex": "2.1.1",
|
||||||
"sanitize-filename": "1.6.3",
|
"sanitize-filename": "1.6.3",
|
||||||
"scim-query-filter-parser": "2.0.4",
|
"scim-query-filter-parser": "2.0.4",
|
||||||
"semver": "7.2.2",
|
"semver": "7.3.2",
|
||||||
"serve-favicon": "2.5.0",
|
"serve-favicon": "2.5.0",
|
||||||
"simple-git": "1.132.0",
|
"simple-git": "1.132.0",
|
||||||
"solr-node": "1.2.1",
|
"solr-node": "1.2.1",
|
||||||
@@ -189,7 +189,7 @@
|
|||||||
"@babel/plugin-syntax-import-meta": "^7.8.3",
|
"@babel/plugin-syntax-import-meta": "^7.8.3",
|
||||||
"@babel/polyfill": "^7.8.7",
|
"@babel/polyfill": "^7.8.7",
|
||||||
"@babel/preset-env": "^7.9.5",
|
"@babel/preset-env": "^7.9.5",
|
||||||
"@mdi/font": "5.0.45",
|
"@mdi/font": "5.1.45",
|
||||||
"@panter/vue-i18next": "0.15.2",
|
"@panter/vue-i18next": "0.15.2",
|
||||||
"@requarks/ckeditor5": "12.4.0-wiki.16",
|
"@requarks/ckeditor5": "12.4.0-wiki.16",
|
||||||
"@vue/babel-preset-app": "4.3.1",
|
"@vue/babel-preset-app": "4.3.1",
|
||||||
@@ -234,7 +234,7 @@
|
|||||||
"eslint-plugin-vue": "6.2.2",
|
"eslint-plugin-vue": "6.2.2",
|
||||||
"fibers": "4.0.2",
|
"fibers": "4.0.2",
|
||||||
"file-loader": "6.0.0",
|
"file-loader": "6.0.0",
|
||||||
"filepond": "4.13.1",
|
"filepond": "4.13.4",
|
||||||
"filepond-plugin-file-validate-type": "1.2.5",
|
"filepond-plugin-file-validate-type": "1.2.5",
|
||||||
"filesize.js": "2.0.0",
|
"filesize.js": "2.0.0",
|
||||||
"graphql-persisted-document-loader": "2.0.0",
|
"graphql-persisted-document-loader": "2.0.0",
|
||||||
@@ -264,14 +264,14 @@
|
|||||||
"pug-lint": "2.6.0",
|
"pug-lint": "2.6.0",
|
||||||
"pug-loader": "2.4.0",
|
"pug-loader": "2.4.0",
|
||||||
"pug-plain-loader": "1.0.0",
|
"pug-plain-loader": "1.0.0",
|
||||||
"raw-loader": "4.0.0",
|
"raw-loader": "4.0.1",
|
||||||
"resolve-url-loader": "3.1.1",
|
"resolve-url-loader": "3.1.1",
|
||||||
"sass": "1.26.3",
|
"sass": "1.26.3",
|
||||||
"sass-loader": "8.0.2",
|
"sass-loader": "8.0.2",
|
||||||
"sass-resources-loader": "2.0.1",
|
"sass-resources-loader": "2.0.3",
|
||||||
"script-ext-html-webpack-plugin": "2.1.4",
|
"script-ext-html-webpack-plugin": "2.1.4",
|
||||||
"simple-progress-webpack-plugin": "1.1.2",
|
"simple-progress-webpack-plugin": "1.1.2",
|
||||||
"style-loader": "1.1.3",
|
"style-loader": "1.1.4",
|
||||||
"terser": "4.6.11",
|
"terser": "4.6.11",
|
||||||
"twemoji-awesome": "1.0.6",
|
"twemoji-awesome": "1.0.6",
|
||||||
"url-loader": "4.1.0",
|
"url-loader": "4.1.0",
|
||||||
@@ -291,13 +291,13 @@
|
|||||||
"vue2-animate": "2.1.3",
|
"vue2-animate": "2.1.3",
|
||||||
"vuedraggable": "2.23.2",
|
"vuedraggable": "2.23.2",
|
||||||
"vuescroll": "4.15.0",
|
"vuescroll": "4.15.0",
|
||||||
"vuetify": "2.2.21",
|
"vuetify": "2.2.22",
|
||||||
"vuetify-loader": "1.4.3",
|
"vuetify-loader": "1.4.3",
|
||||||
"vuex": "3.1.3",
|
"vuex": "3.1.3",
|
||||||
"vuex-pathify": "1.4.1",
|
"vuex-pathify": "1.4.1",
|
||||||
"vuex-persistedstate": "3.0.1",
|
"vuex-persistedstate": "3.0.1",
|
||||||
"webpack": "4.42.1",
|
"webpack": "4.42.1",
|
||||||
"webpack-bundle-analyzer": "3.6.1",
|
"webpack-bundle-analyzer": "3.7.0",
|
||||||
"webpack-cli": "3.3.11",
|
"webpack-cli": "3.3.11",
|
||||||
"webpack-dev-middleware": "3.7.2",
|
"webpack-dev-middleware": "3.7.2",
|
||||||
"webpack-hot-middleware": "2.25.0",
|
"webpack-hot-middleware": "2.25.0",
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ const bruteforce = new ExpressBrute(new BruteKnex({
|
|||||||
router.get('/login', async (req, res, next) => {
|
router.get('/login', async (req, res, next) => {
|
||||||
_.set(res.locals, 'pageMeta.title', 'Login')
|
_.set(res.locals, 'pageMeta.title', 'Login')
|
||||||
|
|
||||||
if (req.query.legacy || req.get('user-agent').indexOf('Trident') >= 0) {
|
if (req.query.legacy || (req.get('user-agent') && req.get('user-agent').indexOf('Trident') >= 0)) {
|
||||||
const { formStrategies, socialStrategies } = await WIKI.models.authentication.getStrategiesForLegacyClient()
|
const { formStrategies, socialStrategies } = await WIKI.models.authentication.getStrategiesForLegacyClient()
|
||||||
res.render('legacy/login', {
|
res.render('legacy/login', {
|
||||||
err: false,
|
err: false,
|
||||||
|
|||||||
@@ -395,7 +395,7 @@ router.get('/*', async (req, res, next) => {
|
|||||||
if (page) {
|
if (page) {
|
||||||
_.set(res.locals, 'pageMeta.title', page.title)
|
_.set(res.locals, 'pageMeta.title', page.title)
|
||||||
_.set(res.locals, 'pageMeta.description', page.description)
|
_.set(res.locals, 'pageMeta.description', page.description)
|
||||||
const sidebar = await WIKI.models.navigation.getTree({ cache: true, locale: pageArgs.locale })
|
const sidebar = await WIKI.models.navigation.getTree({ cache: true, locale: pageArgs.locale, groups: req.user.groups })
|
||||||
const injectCode = {
|
const injectCode = {
|
||||||
css: WIKI.config.theming.injectCSS,
|
css: WIKI.config.theming.injectCSS,
|
||||||
head: WIKI.config.theming.injectHead,
|
head: WIKI.config.theming.injectHead,
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ module.exports = {
|
|||||||
connection: dbConfig,
|
connection: dbConfig,
|
||||||
pool: {
|
pool: {
|
||||||
...WIKI.config.pool,
|
...WIKI.config.pool,
|
||||||
|
propagateCreateError: false,
|
||||||
async afterCreate(conn, done) {
|
async afterCreate(conn, done) {
|
||||||
// -> Set Connection App Name
|
// -> Set Connection App Name
|
||||||
switch (WIKI.config.db.type) {
|
switch (WIKI.config.db.type) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
const { createApolloFetch } = require('apollo-fetch')
|
const { createApolloFetch } = require('apollo-fetch')
|
||||||
const bugsnag = require('@bugsnag/node')
|
const Bugsnag = require('@bugsnag/js')
|
||||||
const { v4: uuid } = require('uuid')
|
const { v4: uuid } = require('uuid')
|
||||||
const os = require('os')
|
const os = require('os')
|
||||||
const fs = require('fs-extra')
|
const fs = require('fs-extra')
|
||||||
@@ -8,21 +8,20 @@ const fs = require('fs-extra')
|
|||||||
/* global WIKI */
|
/* global WIKI */
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
client: null,
|
|
||||||
enabled: false,
|
enabled: false,
|
||||||
init() {
|
init() {
|
||||||
this.client = bugsnag({
|
Bugsnag.start({
|
||||||
apiKey: WIKI.data.telemetry.BUGSNAG_ID,
|
apiKey: WIKI.data.telemetry.BUGSNAG_ID,
|
||||||
appType: 'server',
|
appType: 'server',
|
||||||
appVersion: WIKI.version,
|
appVersion: WIKI.version,
|
||||||
autoNotify: false,
|
autoDetectErrors: false,
|
||||||
collectUserIp: false,
|
autoTrackSessions: false,
|
||||||
hostname: _.get(WIKI.config, 'telemetry.clientId', uuid()),
|
hostname: _.get(WIKI.config, 'telemetry.clientId', uuid()),
|
||||||
notifyReleaseStages: ['production'],
|
enabledReleaseStages: ['production'],
|
||||||
releaseStage: WIKI.IS_DEBUG ? 'development' : 'production',
|
releaseStage: WIKI.IS_DEBUG ? 'development' : 'production',
|
||||||
projectRoot: WIKI.ROOTPATH,
|
projectRoot: WIKI.ROOTPATH,
|
||||||
logger: null,
|
logger: null,
|
||||||
beforeSend: (report) => {
|
onError: (report) => {
|
||||||
if (!WIKI.telemetry.enabled) { return false }
|
if (!WIKI.telemetry.enabled) { return false }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -34,7 +33,7 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
sendError(err) {
|
sendError(err) {
|
||||||
this.client.notify(err)
|
Bugsnag.notify(err)
|
||||||
},
|
},
|
||||||
sendEvent(eventCategory, eventAction, eventLabel) {
|
sendEvent(eventCategory, eventAction, eventLabel) {
|
||||||
// TODO
|
// TODO
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
NavigationQuery: {
|
NavigationQuery: {
|
||||||
async tree (obj, args, context, info) {
|
async tree (obj, args, context, info) {
|
||||||
return WIKI.models.navigation.getTree({ cache: false, locale: 'all' })
|
return WIKI.models.navigation.getTree({ cache: false, locale: 'all', bypassAuth: true })
|
||||||
},
|
},
|
||||||
config (obj, args, context, info) {
|
config (obj, args, context, info) {
|
||||||
return WIKI.config.nav
|
return WIKI.config.nav
|
||||||
@@ -23,7 +23,9 @@ module.exports = {
|
|||||||
await WIKI.models.navigation.query().patch({
|
await WIKI.models.navigation.query().patch({
|
||||||
config: args.tree
|
config: args.tree
|
||||||
}).where('key', 'site')
|
}).where('key', 'site')
|
||||||
await WIKI.cache.set('nav:sidebar', args.tree, 300)
|
for (const tree of args.tree) {
|
||||||
|
await WIKI.cache.set(`nav:sidebar:${tree.locale}`, tree.items, 300)
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
responseResult: graphHelper.generateSuccess('Navigation updated successfully')
|
responseResult: graphHelper.generateSuccess('Navigation updated successfully')
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ type NavigationItem {
|
|||||||
icon: String
|
icon: String
|
||||||
targetType: String
|
targetType: String
|
||||||
target: String
|
target: String
|
||||||
|
visibilityMode: String
|
||||||
|
visibilityGroups: [Int]
|
||||||
}
|
}
|
||||||
|
|
||||||
input NavigationItemInput {
|
input NavigationItemInput {
|
||||||
@@ -62,6 +64,8 @@ input NavigationItemInput {
|
|||||||
icon: String
|
icon: String
|
||||||
targetType: String
|
targetType: String
|
||||||
target: String
|
target: String
|
||||||
|
visibilityMode: String
|
||||||
|
visibilityGroups: [Int]
|
||||||
}
|
}
|
||||||
|
|
||||||
type NavigationConfig {
|
type NavigationConfig {
|
||||||
|
|||||||
@@ -22,20 +22,24 @@ module.exports = class Navigation extends Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async getTree({ cache = false, locale = 'en' } = {}) {
|
static async getTree({ cache = false, locale = 'en', groups = [], bypassAuth = false } = {}) {
|
||||||
if (cache) {
|
if (cache) {
|
||||||
const navTreeCached = await WIKI.cache.get(`nav:sidebar:${locale}`)
|
const navTreeCached = await WIKI.cache.get(`nav:sidebar:${locale}`)
|
||||||
if (navTreeCached) {
|
if (navTreeCached) {
|
||||||
return navTreeCached
|
return bypassAuth ? navTreeCached : WIKI.models.navigation.getAuthorizedItems(navTreeCached, groups)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const navTree = await WIKI.models.navigation.query().findOne('key', 'site')
|
const navTree = await WIKI.models.navigation.query().findOne('key', `site`)
|
||||||
if (navTree) {
|
if (navTree) {
|
||||||
// Check for pre-2.1 format
|
// Check for pre-2.3 format
|
||||||
if (_.has(navTree.config[0], 'kind')) {
|
if (_.has(navTree.config[0], 'kind')) {
|
||||||
navTree.config = [{
|
navTree.config = [{
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
items: navTree.config
|
items: navTree.config.map(item => ({
|
||||||
|
...item,
|
||||||
|
visibilityMode: 'all',
|
||||||
|
visibilityGroups: []
|
||||||
|
}))
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +48,20 @@ module.exports = class Navigation extends Model {
|
|||||||
await WIKI.cache.set(`nav:sidebar:${tree.locale}`, tree.items, 300)
|
await WIKI.cache.set(`nav:sidebar:${tree.locale}`, tree.items, 300)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return locale === 'all' ? navTree.config : WIKI.cache.get(`nav:sidebar:${locale}`)
|
if (bypassAuth) {
|
||||||
|
return locale === 'all' ? navTree.config : WIKI.cache.get(`nav:sidebar:${locale}`)
|
||||||
|
} else {
|
||||||
|
return locale === 'all' ? WIKI.models.navigation.getAuthorizedItems(navTree.config, groups) : WIKI.models.navigation.getAuthorizedItems(WIKI.cache.get(`nav:sidebar:${locale}`), groups)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
WIKI.logger.warn('Site Navigation is missing or corrupted.')
|
WIKI.logger.warn('Site Navigation is missing or corrupted.')
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getAuthorizedItems(tree = [], groups = []) {
|
||||||
|
return _.filter(tree, leaf => {
|
||||||
|
return leaf.visibilityMode === 'all' || _.intersection(leaf.visibilityGroups, groups).length > 0
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -315,12 +315,17 @@ module.exports = () => {
|
|||||||
key: 'site',
|
key: 'site',
|
||||||
config: [
|
config: [
|
||||||
{
|
{
|
||||||
id: uuid(),
|
locale: 'en',
|
||||||
icon: 'mdi-home',
|
items: [
|
||||||
kind: 'link',
|
{
|
||||||
label: 'Home',
|
id: uuid(),
|
||||||
target: '/',
|
icon: 'mdi-home',
|
||||||
targetType: 'home'
|
kind: 'link',
|
||||||
|
label: 'Home',
|
||||||
|
target: '/',
|
||||||
|
targetType: 'home'
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user