Add expression evaluation to page layouts
This commit is contained in:
@@ -3,7 +3,9 @@ import Vue from 'vue'
|
||||
import toast from './toast'
|
||||
import resourceTranslations from './resource-translations'
|
||||
import vueSelectPosition from './vue-select-position'
|
||||
import uiHelpers from './uiHelpers'
|
||||
|
||||
Vue.mixin(toast)
|
||||
Vue.mixin(resourceTranslations)
|
||||
Vue.mixin(vueSelectPosition)
|
||||
Vue.mixin(uiHelpers)
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
export default {
|
||||
methods: {
|
||||
getBreakpoint () {
|
||||
let breakpoint
|
||||
const width = window.innerWidth
|
||||
|
||||
if (width < 576) {
|
||||
breakpoint = 'xs'
|
||||
} else if (width >= 576 && width < 768) {
|
||||
breakpoint = 'sm'
|
||||
} else if (width >= 768 && width < 992) {
|
||||
breakpoint = 'md'
|
||||
} else if (width >= 992 && width < 1200) {
|
||||
breakpoint = 'lg'
|
||||
} else if (width >= 1200 && width < 1400) {
|
||||
breakpoint = 'xl'
|
||||
} else {
|
||||
breakpoint = 'xxl'
|
||||
}
|
||||
|
||||
return breakpoint
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -133,8 +133,7 @@ export default {
|
||||
|
||||
layouts: [],
|
||||
layout: undefined,
|
||||
layoutButtons: {},
|
||||
|
||||
layoutButtons: new Set(),
|
||||
blocks: [],
|
||||
}
|
||||
},
|
||||
@@ -166,7 +165,7 @@ export default {
|
||||
recordToolbarLabels () {
|
||||
// Use an intermediate object so we can reflect all changes in one go;
|
||||
const aux = {}
|
||||
const { config = {} } = this.layout
|
||||
const { config = {} } = this.layout || {}
|
||||
const { buttons = {} } = config
|
||||
|
||||
Object.entries(buttons).forEach(([key, { label = '' }]) => {
|
||||
@@ -176,7 +175,7 @@ export default {
|
||||
},
|
||||
|
||||
layoutActions () {
|
||||
const { config = {} } = this.layout
|
||||
const { config = {} } = this.layout || {}
|
||||
const { actions = [] } = config
|
||||
|
||||
return actions
|
||||
@@ -208,6 +207,9 @@ export default {
|
||||
immediate: true,
|
||||
handler () {
|
||||
this.layouts = this.getPageLayouts(this.page.pageID)
|
||||
this.layout = undefined
|
||||
this.blocks = []
|
||||
|
||||
this.determineLayout()
|
||||
},
|
||||
},
|
||||
@@ -317,12 +319,43 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
determineLayout (pageLayoutID) {
|
||||
this.layout = this.layouts.find(l => {
|
||||
const { roles = [] } = l.config.visibility
|
||||
evaluateLayoutExpressions () {
|
||||
const expressions = {}
|
||||
const variables = {
|
||||
user: this.$auth.user,
|
||||
record: this.record || {},
|
||||
screen: {
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
userAgent: navigator.userAgent,
|
||||
breakpoint: this.getBreakpoint(), // This is from a global mixin uiHelpers
|
||||
},
|
||||
layout: this.layout || {},
|
||||
}
|
||||
|
||||
this.layouts.forEach(({ pageLayoutID, config }) => {
|
||||
if (!config.visibility.expression) return
|
||||
|
||||
expressions[pageLayoutID] = config.visibility.expression
|
||||
})
|
||||
|
||||
return this.$SystemAPI.expressionEvaluate({ variables, expressions }).catch(() => {
|
||||
Object.keys(expressions).forEach(key => (expressions[key] = false))
|
||||
return expressions
|
||||
})
|
||||
},
|
||||
|
||||
async determineLayout (pageLayoutID) {
|
||||
const expressions = await this.evaluateLayoutExpressions()
|
||||
|
||||
// Check layouts for expressions/roles and find the first one that fits
|
||||
this.layout = this.layouts.find(l => {
|
||||
if (pageLayoutID && l.pageLayoutID !== pageLayoutID) return
|
||||
|
||||
const { expression, roles = [] } = l.config.visibility
|
||||
|
||||
if (expression && !expressions[l.pageLayoutID]) return false
|
||||
|
||||
if (!roles.length) return true
|
||||
|
||||
return this.$auth.user.roles.some(roleID => roles.includes(roleID))
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
class="flex-grow-1 overflow-auto d-flex px-2 w-100"
|
||||
>
|
||||
<router-view
|
||||
v-if="recordID || isRecordCreatePage"
|
||||
v-if="isRecordPage"
|
||||
:namespace="namespace"
|
||||
:module="module"
|
||||
:page="page"
|
||||
@@ -117,7 +117,6 @@ export default {
|
||||
return {
|
||||
layouts: [],
|
||||
layout: undefined,
|
||||
|
||||
blocks: [],
|
||||
}
|
||||
},
|
||||
@@ -128,8 +127,8 @@ export default {
|
||||
getPageLayouts: 'pageLayout/getByPageID',
|
||||
}),
|
||||
|
||||
isRecordCreatePage () {
|
||||
return this.$route.name === 'page.record.create'
|
||||
isRecordPage () {
|
||||
return this.recordID || this.$route.name === 'page.record.create'
|
||||
},
|
||||
|
||||
module () {
|
||||
@@ -150,9 +149,9 @@ export default {
|
||||
},
|
||||
|
||||
pageTitle () {
|
||||
if (this.page.pageID !== NoID) {
|
||||
if (this.page.pageID !== NoID && this.layout) {
|
||||
const { title = '', handle = '' } = this.page
|
||||
const { meta = {} } = this.layout || {}
|
||||
const { meta = {} } = this.layout
|
||||
return meta.title || title || handle || this.$t('navigation:noPageTitle')
|
||||
}
|
||||
|
||||
@@ -169,16 +168,16 @@ export default {
|
||||
},
|
||||
|
||||
watch: {
|
||||
'page.title': {
|
||||
immediate: true,
|
||||
handler (title) {
|
||||
},
|
||||
},
|
||||
|
||||
'page.pageID': {
|
||||
immediate: true,
|
||||
handler () {
|
||||
this.determineLayout()
|
||||
this.layouts = []
|
||||
this.layout = undefined
|
||||
this.blocks = []
|
||||
|
||||
if (!this.isRecordPage) {
|
||||
this.determineLayout()
|
||||
}
|
||||
|
||||
// If the page changed we need to clear the record pagination since its not relevant anymore
|
||||
if (this.recordPaginationUsable) {
|
||||
@@ -208,10 +207,41 @@ export default {
|
||||
clearRecordIDs: 'ui/clearRecordIDs',
|
||||
}),
|
||||
|
||||
determineLayout () {
|
||||
evaluateLayoutExpressions () {
|
||||
const expressions = {}
|
||||
const variables = {
|
||||
screen: {
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
userAgent: navigator.userAgent,
|
||||
breakpoint: this.getBreakpoint(), // This is from a global mixin uiHelpers
|
||||
},
|
||||
user: this.$auth.user,
|
||||
layout: this.layout || {},
|
||||
}
|
||||
|
||||
this.layouts.forEach(({ pageLayoutID, config }) => {
|
||||
if (!config.visibility.expression) return
|
||||
|
||||
expressions[pageLayoutID] = config.visibility.expression
|
||||
})
|
||||
|
||||
return this.$SystemAPI.expressionEvaluate({ variables, expressions }).catch(() => {
|
||||
Object.keys(expressions).forEach(key => (expressions[key] = false))
|
||||
return expressions
|
||||
})
|
||||
},
|
||||
|
||||
async determineLayout () {
|
||||
this.layouts = this.getPageLayouts(this.page.pageID)
|
||||
this.layout = this.layouts.find(l => {
|
||||
const { roles = [] } = l.config.visibility
|
||||
|
||||
const expressions = await this.evaluateLayoutExpressions()
|
||||
|
||||
// Check layouts for expressions/roles and find the first one that fits
|
||||
this.layout = this.layouts.find(({ pageLayoutID, config = {} }) => {
|
||||
const { expression, roles = [] } = config.visibility
|
||||
|
||||
if (expression && !expressions[pageLayoutID]) return false
|
||||
|
||||
if (!roles.length) return true
|
||||
|
||||
|
||||
Reference in New Issue
Block a user