Commit 8aba5305 authored by NGPixel's avatar NGPixel Committed by Nicolas Giard

feat: sidebar item permissions + admin nav edit

parent 9a93ac28
...@@ -215,6 +215,7 @@ let bootstrap = () => { ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -386,6 +410,8 @@ export default {
icon icon
targetType targetType
target target
visibilityMode
visibilityGroups
} }
} }
} }
......
<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 @@ ...@@ -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' ...@@ -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 { ...@@ -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 { ...@@ -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()
} }
} }
} }
......
...@@ -37,7 +37,7 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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({ ...@@ -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) => { ...@@ -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 = { ...@@ -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) {
......
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') ...@@ -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 = { ...@@ -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 = { ...@@ -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 = { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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)
} }
} }
if (bypassAuth) {
return locale === 'all' ? navTree.config : WIKI.cache.get(`nav:sidebar:${locale}`) return locale === 'all' ? navTree.config : WIKI.cache.get(`nav:sidebar:${locale}`)
} else { } else {
return locale === 'all' ? WIKI.models.navigation.getAuthorizedItems(navTree.config, groups) : WIKI.models.navigation.getAuthorizedItems(WIKI.cache.get(`nav:sidebar:${locale}`), groups)
}
} 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,6 +315,9 @@ module.exports = () => { ...@@ -315,6 +315,9 @@ module.exports = () => {
key: 'site', key: 'site',
config: [ config: [
{ {
locale: 'en',
items: [
{
id: uuid(), id: uuid(),
icon: 'mdi-home', icon: 'mdi-home',
kind: 'link', kind: 'link',
...@@ -323,6 +326,8 @@ module.exports = () => { ...@@ -323,6 +326,8 @@ module.exports = () => {
targetType: 'home' targetType: 'home'
} }
] ]
}
]
}) })
WIKI.logger.info('Setup is complete!') WIKI.logger.info('Setup is complete!')
......
This diff was suppressed by a .gitattributes entry.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment