3
0

Improve record selector resolution in blocks

This commit is contained in:
Jože Fortun
2023-05-17 14:16:44 +02:00
parent 2d9310fee3
commit f4dd6eda0b
16 changed files with 375 additions and 161 deletions

View File

@@ -215,6 +215,7 @@ export default {
...mapGetters({
getModuleByID: 'module/getByID',
findUserByID: 'user/findByID',
findRecordsByIDs: 'record/findByIDs',
}),
options () {
@@ -292,7 +293,9 @@ export default {
methods: {
...mapActions({
findModuleByID: 'module/findByID',
resolveUsers: 'user/fetchUsers',
resolveUsers: 'user/resolveUsers',
resolveRecords: 'record/resolveRecords',
updateRecords: 'record/updateRecords',
}),
getRecord (index = undefined) {
@@ -403,6 +406,8 @@ export default {
this.filter.nextPage = filter.nextPage
this.filter.prevPage = filter.prevPage
this.updateRecords(set)
return this.formatRecordValues(set.map(({ recordID }) => recordID)).then(() => {
this.records = set.map(r => new compose.Record(this.module, r))
})
@@ -416,67 +421,67 @@ export default {
return [this.field.options.labelField].filter(f => !!f).join(', ')
},
async formatRecordValues (value) {
value = Array.isArray(value) ? value : [value].filter(v => v) || []
async formatRecordValues (recordIDs) {
recordIDs = Array.isArray(recordIDs) ? recordIDs : [recordIDs].filter(v => v) || []
const { namespaceID = NoID } = this.namespace
const { moduleID = NoID, labelField, recordLabelField } = this.field.options
if (!value.length || [moduleID, namespaceID].includes(NoID) || !labelField) {
if (!recordIDs.length || [moduleID, namespaceID].includes(NoID) || !labelField) {
return
}
this.processing = true
return this.findModuleByID({ namespace: this.namespace, moduleID }).then(async module => {
const relatedField = module.fields.find(({ name }) => name === labelField)
const records = this.findRecordsByIDs(recordIDs).map(r => new compose.Record(module, r))
const mappedIDs = {}
// Get configured module/field
return this.findModuleByID({ namespace: this.namespace, moduleID }).then(module => {
let relatedField = module.fields.find(({ name }) => name === labelField)
const query = value.map(recordID => `recordID = ${recordID}`).join(' OR ')
if (relatedField.kind === 'Record' && recordLabelField) {
this.processing = true
return this.$ComposeAPI.recordList({ namespaceID, moduleID, query, deleted: 1 }).then(async ({ set = [] }) => {
if (recordLabelField) {
set = await this.findModuleByID({ namespaceID, moduleID: relatedField.options.moduleID }).then(relatedModule => {
const mappedIDs = {}
const queryIDs = []
const relatedModule = await this.findModuleByID({ namespaceID, moduleID: relatedField.options.moduleID })
const relatedRecordIDs = new Set()
set.forEach(r => {
r = new compose.Record(module, r)
mappedIDs[r.values[labelField]] = r.recordID
queryIDs.push(`recordID = ${r.values[labelField]}`)
})
records.forEach(r => {
const recordValue = relatedField.isMulti ? r.values[relatedField.name] : [r.values[relatedField.name]]
recordValue.forEach(rID => relatedRecordIDs.add(rID))
})
await this.resolveRecords({ namespaceID, moduleID: relatedModule.moduleID, recordIDs: [...relatedRecordIDs] })
return this.$ComposeAPI.recordList({ namespaceID, moduleID: relatedField.options.moduleID, query: queryIDs.join(' OR '), deleted: 1 }).then(({ set: resolvedSet = [] }) => {
relatedField = relatedModule.fields.find(({ name }) => name === this.field.options.recordLabelField)
resolvedSet.forEach(r => {
mappedIDs[r.recordID] = r
})
const relatedLabelField = relatedModule.fields.find(({ name }) => name === recordLabelField)
return set.map(r => {
r = new compose.Record(module, r)
const relatedRecord = mappedIDs[r.values[labelField]]
relatedRecord.recordID = r.recordID
return new compose.Record(relatedModule, relatedRecord)
})
})
})
} else {
set = set.map(r => new compose.Record(module, r))
}
for (let r of await this.findRecordsByIDs([...relatedRecordIDs])) {
r = new compose.Record(relatedModule, r)
let relatedRecordValue = relatedLabelField.isMulti ? r.values[relatedLabelField.name] : [r.values[relatedLabelField.name]]
for (const record of set) {
let recordValue = relatedField.isMulti ? record.values[relatedField.name] : [record.values[relatedField.name]]
if (recordValue.length && relatedField.kind === 'User') {
recordValue = await Promise.all(recordValue.map(async v => {
if (!this.findUserByID(v)) {
await this.resolveUsers(v)
}
return relatedField.formatter(this.findUserByID(v))
}))
if (relatedLabelField.kind === 'User') {
await this.resolveUsers(relatedRecordValue)
relatedRecordValue = relatedRecordValue.map(v => relatedLabelField.formatter(this.findUserByID(v)))
}
this.$set(this.recordValues, record.recordID, recordValue.join(relatedField.options.multiDelimiter))
mappedIDs[r.recordID] = relatedRecordValue.join(relatedLabelField.options.multiDelimiter)
}
} else if (relatedField.kind === 'User') {
this.processing = true
const relatedUserIDs = new Set()
records.forEach(r => {
const recordValue = relatedField.isMulti ? r.values[relatedField.name] : [r.values[relatedField.name]]
recordValue.forEach(uID => relatedUserIDs.add(uID))
})
await this.resolveUsers([...relatedUserIDs])
}
records.forEach(record => {
let recordValue = relatedField.isMulti ? record.values[relatedField.name] : [record.values[relatedField.name]]
if (relatedField.kind === 'User') {
recordValue = recordValue.map(v => relatedField.formatter(this.findUserByID(v)))
} else if (relatedField.kind === 'Record' && recordLabelField) {
recordValue = recordValue.map(v => mappedIDs[v])
}
this.$set(this.recordValues, record.recordID, recordValue.join(relatedField.options.multiDelimiter))
})
}).finally(() => {
setTimeout(() => {

View File

@@ -55,6 +55,7 @@ export default {
...mapGetters({
pages: 'page/set',
findUserByID: 'user/findByID',
findRecordsByIDs: 'record/findByIDs',
}),
formattedValue () {
@@ -84,7 +85,8 @@ export default {
methods: {
...mapActions({
findModuleByID: 'module/findByID',
resolveUsers: 'user/fetchUsers',
resolveUsers: 'user/resolveUsers',
resolveRecords: 'record/resolveRecords',
}),
linkToRecord (recordID) {
@@ -101,61 +103,67 @@ export default {
}
},
async formatRecordValues (value) {
value = Array.isArray(value) ? value : [value].filter(v => v) || []
async formatRecordValues (recordIDs) {
recordIDs = Array.isArray(recordIDs) ? recordIDs : [recordIDs].filter(v => v) || []
const { namespaceID = NoID } = this.namespace
const { moduleID = NoID, labelField, recordLabelField } = this.field.options
if (!value.length || [moduleID, namespaceID].includes(NoID) || !labelField) {
if (!recordIDs.length || [moduleID, namespaceID].includes(NoID) || !labelField) {
return
}
this.processing = true
return this.findModuleByID({ namespace: this.namespace, moduleID }).then(async module => {
const relatedField = module.fields.find(({ name }) => name === labelField)
const records = this.findRecordsByIDs(recordIDs).map(r => new compose.Record(module, r))
const mappedIDs = {}
// Get configured module/field
return this.findModuleByID({ namespace: this.namespace, moduleID }).then(module => {
let relatedField = module.fields.find(({ name }) => name === labelField)
const query = value.map(recordID => `recordID = ${recordID}`).join(' OR ')
if (relatedField.kind === 'Record' && recordLabelField) {
this.processing = true
return this.$ComposeAPI.recordList({ namespaceID, moduleID, query, deleted: 1 }).then(async ({ set = [] }) => {
if (recordLabelField) {
set = await this.findModuleByID({ namespaceID, moduleID: relatedField.options.moduleID }).then(relatedModule => {
const mappedIDs = {}
const queryIDs = []
const relatedModule = await this.findModuleByID({ namespaceID, moduleID: relatedField.options.moduleID })
const relatedRecordIDs = new Set()
set.forEach(r => {
r = new compose.Record(module, r)
mappedIDs[r.values[labelField]] = r.recordID
queryIDs.push(`recordID = ${r.values[labelField]}`)
})
records.forEach(r => {
const recordValue = relatedField.isMulti ? r.values[relatedField.name] : [r.values[relatedField.name]]
recordValue.forEach(rID => relatedRecordIDs.add(rID))
})
await this.resolveRecords({ namespaceID, moduleID: relatedModule.moduleID, recordIDs: [...relatedRecordIDs] })
return this.$ComposeAPI.recordList({ namespaceID, moduleID: relatedField.options.moduleID, query: queryIDs.join(' OR '), deleted: 1 }).then(({ set = [] }) => {
relatedField = relatedModule.fields.find(({ name }) => name === this.field.options.recordLabelField)
return set.map(r => {
r.recordID = mappedIDs[r.recordID]
return new compose.Record(relatedModule, r)
})
})
})
} else {
set = set.map(r => new compose.Record(module, r))
}
const relatedLabelField = relatedModule.fields.find(({ name }) => name === recordLabelField)
for (const record of set) {
let recordValue = relatedField.isMulti ? record.values[relatedField.name] : [record.values[relatedField.name]]
for (let r of await this.findRecordsByIDs([...relatedRecordIDs])) {
r = new compose.Record(relatedModule, r)
let relatedRecordValue = relatedLabelField.isMulti ? r.values[relatedLabelField.name] : [r.values[relatedLabelField.name]]
if (recordValue.length && relatedField.kind === 'User') {
recordValue = await Promise.all(recordValue.map(async v => {
if (!this.findUserByID(v)) {
await this.resolveUsers(v)
}
return relatedField.formatter(this.findUserByID(v))
}))
if (relatedLabelField.kind === 'User') {
await this.resolveUsers(relatedRecordValue)
relatedRecordValue = relatedRecordValue.map(v => relatedLabelField.formatter(this.findUserByID(v)))
}
this.$set(this.recordValues, record.recordID, recordValue.join(relatedField.options.multiDelimiter))
mappedIDs[r.recordID] = relatedRecordValue.join(relatedLabelField.options.multiDelimiter)
}
} else if (relatedField.kind === 'User') {
this.processing = true
const relatedUserIDs = new Set()
records.forEach(r => {
const recordValue = relatedField.isMulti ? r.values[relatedField.name] : [r.values[relatedField.name]]
recordValue.forEach(uID => relatedUserIDs.add(uID))
})
await this.resolveUsers([...relatedUserIDs])
}
records.forEach(record => {
let recordValue = relatedField.isMulti ? record.values[relatedField.name] : [record.values[relatedField.name]]
if (relatedField.kind === 'User') {
recordValue = recordValue.map(v => relatedField.formatter(this.findUserByID(v)))
} else if (relatedField.kind === 'Record' && recordLabelField) {
recordValue = recordValue.map(v => mappedIDs[v])
}
this.$set(this.recordValues, record.recordID, recordValue.join(relatedField.options.multiDelimiter))
})
}).finally(() => {
setTimeout(() => {

View File

@@ -67,6 +67,7 @@ import base from './base'
import FieldViewer from 'corteza-webapp-compose/src/components/ModuleFields/Viewer'
import Hint from 'corteza-webapp-compose/src/components/Common/Hint.vue'
import users from 'corteza-webapp-compose/src/mixins/users'
import records from 'corteza-webapp-compose/src/mixins/records'
import conditionalFields from 'corteza-webapp-compose/src/mixins/conditionalFields'
export default {
@@ -83,6 +84,7 @@ export default {
mixins: [
users,
records,
conditionalFields,
],
@@ -131,17 +133,24 @@ export default {
handler (recordID) {
if (!recordID) return
this.evaluating = true
this.evaluateExpressions()
.finally(() => {
this.evaluating = false
})
let resolutions = []
if (recordID !== NoID) {
this.fetchUsers(this.fields, [this.record])
resolutions = [
this.fetchUsers(this.fields, [this.record]),
this.fetchRecords(this.namespace.namespaceID, this.fields, [this.record]),
]
}
this.evaluating = true
Promise.all([
...resolutions,
this.evaluateExpressions(),
]).finally(() => {
this.evaluating = false
})
if (this.options.referenceModuleID) {
this.fetchReferenceModule(this.options.referenceModuleID)
}

View File

@@ -78,6 +78,7 @@
import { validator, NoID } from '@cortezaproject/corteza-js'
import base from './base'
import users from 'corteza-webapp-compose/src/mixins/users'
import records from 'corteza-webapp-compose/src/mixins/records'
import FieldEditor from 'corteza-webapp-compose/src/components/ModuleFields/Editor'
import FieldViewer from 'corteza-webapp-compose/src/components/ModuleFields/Viewer'
import Hint from 'corteza-webapp-compose/src/components/Common/Hint.vue'
@@ -99,6 +100,7 @@ export default {
mixins: [
users,
records,
conditionalFields,
],
@@ -145,16 +147,23 @@ export default {
handler (recordID) {
if (!recordID) return
this.evaluating = true
this.evaluateExpressions()
.finally(() => {
this.evaluating = false
})
let resolutions = []
if (recordID !== NoID) {
this.fetchUsers(this.fields, [this.record])
resolutions = [
this.fetchUsers(this.fields, [this.record]),
this.fetchRecords(this.namespace.namespaceID, this.fields, [this.record]),
]
}
this.evaluating = true
Promise.all([
...resolutions,
this.evaluateExpressions(),
]).finally(() => {
this.evaluating = false
})
},
},
},

View File

@@ -627,7 +627,7 @@
<div class="text-truncate">
<div
v-if="options.showTotalCount"
class="ml-2 text-nowrap"
class="ml-2 text-nowrap my-1"
>
<span
v-if="pagination.count > options.perPage"
@@ -732,6 +732,7 @@ import ImporterModal from 'corteza-webapp-compose/src/components/Public/Record/I
import AutomationButtons from './Shared/AutomationButtons'
import { compose, validator, NoID } from '@cortezaproject/corteza-js'
import users from 'corteza-webapp-compose/src/mixins/users'
import records from 'corteza-webapp-compose/src/mixins/records'
import { evaluatePrefilter, queryToFilter } from 'corteza-webapp-compose/src/lib/record-filter'
import { getItem, setItem, removeItem } from 'corteza-webapp-compose/src/lib/local-storage'
import { components, url } from '@cortezaproject/corteza-vue'
@@ -764,6 +765,7 @@ export default {
mixins: [
users,
records,
],
props: {
@@ -1576,9 +1578,13 @@ export default {
// Extract user IDs from record values and load all users
const fields = this.fields.filter(f => f.moduleField).map(f => f.moduleField)
this.fetchUsers(fields, records)
this.items = records.map(r => this.wrapRecord(r))
return Promise.all([
this.fetchUsers(fields, records),
this.fetchRecords(namespaceID, fields, records),
]).then(() => {
this.items = records.map(r => this.wrapRecord(r))
})
})
.catch(this.toastErrorHandler(this.$t('notification:record.listLoadFailed')))
.finally(() => {

View File

@@ -36,7 +36,6 @@
md="6"
>
<b-form-group
v-if="recordListModule"
:label="$t('recordList.record.inlineEditorAllow')"
label-class="text-primary"
>

View File

@@ -35,55 +35,50 @@
{{ $t('recordOrganizer.noRecords') }}
</div>
</template>
<router-link
<b-card
v-for="record in records"
:key="`${record.recordID}`"
tag="div"
class="record-item mb-2"
:class="{ 'pointer': roRecordPage }"
:to="{ name: 'page.record', params: { pageID: (roRecordPage || {}).pageID, recordID: record.recordID }, query: null }"
body-class="px-2 py-1"
class="record-item border border-light rounded mb-2 grab"
@click="handleRecordClick(record)"
>
<b-card
body-class="px-2 py-1"
class="border rounded"
<div
v-if="labelField"
class="d-flex mb-1"
>
<b-card-title
v-if="labelField"
title-tag="div"
class="mb-1"
<field-viewer
v-if="labelField.canReadRecordValue"
:field="labelField"
:record="record"
:namespace="namespace"
value-only
/>
<i
v-else
class="text-secondary"
>{{ $t('field.noPermission') }}</i>
</div>
<b-card-text
v-if="descriptionField"
class="d-flex small"
>
<field-viewer
v-if="descriptionField.canReadRecordValue"
:field="descriptionField"
:record="record"
:namespace="namespace"
value-only
/>
<i
v-else
class="text-secondary"
>
<field-viewer
v-if="labelField.canReadRecordValue"
:field="labelField"
:record="record"
:namespace="namespace"
value-only
/>
<i
v-else
class="text-secondary"
>{{ $t('field.noPermission') }}</i>
</b-card-title>
<b-card-text
v-if="descriptionField"
class="small"
>
<field-viewer
v-if="descriptionField.canReadRecordValue"
:field="descriptionField"
:record="record"
:namespace="namespace"
value-only
/>
<i
v-else
class="text-secondary"
>
{{ $t('field.noPermission') }}
</i>
</b-card-text>
</b-card>
</router-link>
{{ $t('field.noPermission') }}
</i>
</b-card-text>
</b-card>
</draggable>
<div
v-else
@@ -118,6 +113,7 @@ import base from './base'
import draggable from 'vuedraggable'
import FieldViewer from 'corteza-webapp-compose/src/components/ModuleFields/Viewer'
import users from 'corteza-webapp-compose/src/mixins/users'
import records from 'corteza-webapp-compose/src/mixins/records'
import { evaluatePrefilter, getFieldFilter } from 'corteza-webapp-compose/src/lib/record-filter'
import { compose, NoID } from '@cortezaproject/corteza-js'
@@ -135,6 +131,7 @@ export default {
mixins: [
users,
records,
],
data () {
@@ -412,7 +409,7 @@ export default {
args: Object.keys(args).map(name => ({ name, value: String(args[name]) })),
}
return this.$ComposeAPI.recordExec(params).then(this.fetchRecords)
return this.$ComposeAPI.recordExec(params).then(this.pullRecords)
},
/**
@@ -422,7 +419,7 @@ export default {
* @param {String} query Filter records
* @returns {Promise<Record[]>}
*/
async fetchRecords () {
async pullRecords () {
if (!this.roModule) {
return
}
@@ -432,17 +429,21 @@ export default {
}
const query = this.expandFilter()
const { labelField, descriptionField, positionField } = this.options
const { positionField } = this.options
const { moduleID, namespaceID } = this.roModule
const sort = positionField || `updatedAt, ${labelField || descriptionField}`
const sort = positionField || 'updatedAt'
this.processing = true
return this.$ComposeAPI.recordList({ namespaceID, moduleID, query, sort })
.then(({ set }) => {
this.records = set.map(r => Object.freeze(new compose.Record(this.roModule, r)))
const fields = [this.labelField, this.descriptionField].filter(f => !!f)
this.fetchUsers(fields, this.records)
this.records = set.map(r => Object.freeze(new compose.Record(this.roModule, r)))
return Promise.all([
this.fetchUsers(fields, this.records),
this.fetchRecords(namespaceID, fields, this.records),
])
}).catch(e => {
console.error(e)
}).finally(() => {
@@ -450,8 +451,23 @@ export default {
})
},
handleRecordClick (record) {
if (!this.roRecordPage) return
const route = {
name: 'page.record',
params: {
pageID: (this.roRecordPage || {}).pageID,
recordID: record.recordID,
},
query: null,
}
this.$router.push(route)
},
refresh () {
this.fetchRecords()
this.pullRecords()
},
},
}

View File

@@ -0,0 +1,39 @@
export default {
methods: {
fetchRecords (namespaceID, fields = [], records = []) {
if (records.length === 0 || fields.length === 0) {
return
}
const moduleRecords = {}
fields.filter(c => c.kind === 'Record').forEach(f => {
const { moduleID } = f.options || {}
if (!moduleRecords[moduleID]) {
moduleRecords[moduleID] = new Set()
}
records.forEach(r => {
let recordIDs = []
if (f.isSystem) {
recordIDs = [r[f.name]]
} else {
recordIDs = f.isMulti ? r.values[f.name] : [r.values[f.name]]
}
recordIDs.forEach(recordID => {
if (!recordID) return
moduleRecords[moduleID].add(recordID)
})
})
})
// Dispatch resolution per module
return Promise.all(Object.entries(moduleRecords).map(([moduleID, recordIDs]) => {
recordIDs = [...recordIDs]
return this.$store.dispatch('record/resolveRecords', { namespaceID, moduleID, recordIDs })
}))
},
},
}

View File

@@ -17,7 +17,7 @@ export default {
})
}).flat(Infinity))
return this.$store.dispatch('user/fetchUsers', [...list])
return this.$store.dispatch('user/resolveUsers', [...list])
},
},
}

View File

@@ -6,6 +6,7 @@ import module from './module'
import page from './page'
import pageLayout from './page-layout'
import chart from './chart'
import record from './record'
import user from './user'
import languages from './languages'
import ui from './ui'
@@ -22,6 +23,7 @@ export default new Vuex.Store({
page: page(Vue.prototype.$ComposeAPI),
pageLayout: pageLayout(Vue.prototype.$ComposeAPI),
chart: chart(Vue.prototype.$ComposeAPI),
record: record(Vue.prototype.$ComposeAPI),
user: user(Vue.prototype.$SystemAPI),
languages: languages(Vue.prototype.$SystemAPI),
ui: ui(Vue.prototype.$ComposeAPI),

View File

@@ -0,0 +1,113 @@
// Records in this store not classes, but raw objects instead
const types = {
pending: 'pending',
completed: 'completed',
updateSet: 'updateSet',
clearSet: 'clearSet',
}
export default function (ComposeAPI) {
return {
namespaced: true,
state: {
pending: false,
set: [],
},
getters: {
pending: (state) => state.pending,
findByID (state) {
return (ID) => state.set.find(({ recordID }) => ID === recordID)
},
findByIDs (state) {
return (IDs) => {
IDs = IDs.flat()
return state.set.filter(({ recordID }) => IDs.includes(recordID))
}
},
set (state) {
return state.set
},
},
actions: {
/**
* Similar to fetchRecords but it only fetches unknown (not in set) ids
*/
async resolveRecords ({ commit, getters }, { namespaceID, moduleID, recordIDs }) {
if (recordIDs.length === 0) {
// save ourselves some work
return
}
// exclude existing & make unique
const existing = new Set(getters.set.map(({ recordID }) => recordID))
recordIDs = [...new Set(recordIDs.filter(recordID => !existing.has(recordID)))]
if (recordIDs.length === 0) {
// Check for values again
return
}
const query = recordIDs.map(recordID => `recordID = ${recordID}`).join(' OR ')
return ComposeAPI.recordList({ namespaceID, moduleID, query, deleted: 1 }).then(({ set }) => {
commit(types.updateSet, set)
}).finally(() => {
commit(types.completed)
})
},
updateRecords ({ commit }, records) {
commit(types.updateSet, records)
},
push ({ commit }, record) {
commit(types.updateSet, record)
},
clearSet ({ commit }) {
commit(types.clearSet)
},
},
mutations: {
[types.pending] (state) {
state.pending = true
},
[types.completed] (state) {
state.pending = false
},
[types.updateSet] (state, set) {
set = (Array.isArray(set) ? set : [set]).filter(r => !!r)
if (state.set.length === 0) {
state.set = set
return
}
const existing = new Set(state.set.map(({ recordID }) => recordID))
set.forEach(newItem => {
const oldIndex = !existing.has(newItem.recordID) ? state.set.findIndex(({ recordID }) => recordID === newItem.recordID) : -1
if (oldIndex > -1) {
state.set.splice(oldIndex, 1, newItem)
} else {
state.set.push(newItem)
}
})
},
[types.clearSet] (state) {
state.pending = false
state.set.splice(0)
},
},
}
}

View File

@@ -32,9 +32,9 @@ export default function (SystemAPI) {
},
actions: {
async load ({ commit }) {
async load ({ commit }, filter) {
commit(types.pending)
return SystemAPI.userList().then(({ set }) => {
return SystemAPI.userList(filter).then(({ set }) => {
commit(types.updateSet, set)
}).finally(() => {
commit(types.completed)

View File

@@ -240,7 +240,6 @@ export default {
.recordRead({ namespaceID, moduleID, recordID })
.then(record => {
this.record = new compose.Record(module, record)
this.fetchUsers(this.module.fields, [this.record])
})
.catch(this.toastErrorHandler(this.$t('notification:record.loadFailed')))
}

View File

@@ -60,6 +60,9 @@ export default {
},
created () {
// Preload first 500 users
this.$store.dispatch('user/load', { limit: 500 })
this.$store.dispatch('namespace/load', { force: true }).then(namespaces => {
this.namespaces = namespaces
this.loaded = true

View File

@@ -274,6 +274,7 @@ export default {
methods: {
...mapActions({
popPreviousPages: 'ui/popPreviousPages',
clearRecordSet: 'record/clearSet',
}),
async loadRecord () {
@@ -403,6 +404,8 @@ export default {
},
async determineLayout (pageLayoutID) {
// Clear stored records so they can be refetched with latest values
this.clearRecordSet()
let expressions = {}
// Only evaluate if one of the layouts has an expressions variable

View File

@@ -230,6 +230,7 @@ export default {
clearRecordIDs: 'ui/clearRecordIDs',
setPreviousPages: 'ui/setPreviousPages',
pushPreviousPages: 'ui/pushPreviousPages',
clearRecordSet: 'record/clearSet',
}),
evaluateLayoutExpressions () {
@@ -265,6 +266,8 @@ export default {
},
async determineLayout () {
// Clear stored records so they can be refetched with latest values
this.clearRecordSet()
this.layouts = this.getPageLayouts(this.page.pageID)
let expressions = {}