From ea3d04d9ae0a8d49ed5f85fff574da6514840d50 Mon Sep 17 00:00:00 2001 From: chfhtw Date: Fri, 11 Sep 2026 11:29:58 +0200 Subject: [PATCH] Handle calculated values if they need user interaction --- .../components/DashboardWidget/Report/Kpi.js | 63 ++++++++++++++++++- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/public/js/components/DashboardWidget/Report/Kpi.js b/public/js/components/DashboardWidget/Report/Kpi.js index 9111013bf..9a883caaa 100644 --- a/public/js/components/DashboardWidget/Report/Kpi.js +++ b/public/js/components/DashboardWidget/Report/Kpi.js @@ -76,6 +76,55 @@ export default { let vars = {}; for (var key in this.config.vars) { vars[key] = await this.getValueForVar(this.config.vars[key]); + + if (this.config.vars[key].type == 'user') { + if (!this.config.uservars || !this.config.uservars[key]) + delete vars[key]; + else + vars[key] = this.config.uservars[key].value; + } else if (this.config.vars[key].type.substr(0, 5) == 'calc:') { + const requiresArray = this.config.vars[key].detail.multiple ? true : false; + const isArray = Array.isArray(vars[key]); + + if (requiresArray && !isArray) { + vars[key] = [ vars[key] ]; + } else if (!requiresArray && isArray) { + const isSelect = this.config.vars[key].detail.type == 'select'; + + let val = undefined; + + if (this.config.uservars) + val = this.config.uservars[key]?.value; + + if (val && !vars[key].some(v1 => v1 == val)) { + val = undefined; + delete this.config.uservars[key].value; + } + if (isSelect && val && !this.config.vars[key].detail.options.some(option => option.value == val)) { + val = undefined; + delete this.config.uservars[key].value; + } + + if (!val) + val = vars[key].find(Boolean); // get first element + + let detail = { ...this.config.vars[key].detail, type: 'select' }; + + if (this.config.vars[key].detail.type == 'select') { + detail.options = this.config.vars[key].detail.options + .filter(option => vars[key].some(v => v == option.value)); + } else { + detail.options = vars[key].map(value => ({ label: value, value })); + } + + const sharedData = this.sharedData || {}; + sharedData[key] = detail; + this.$emit('update:sharedData', sharedData); + this.$emit('setConfig', Vue.markRaw(ConfigKpi)); + + vars[key] = val; + } + } } try { @@ -85,10 +134,20 @@ export default { ); this.data = result.data; } catch(error) { - if (this.activeAggregator === undefined) return this.hasErrors = true; - if (Object.values(this.config.vars).some(v => v.type == 'user' && v.value === undefined)) + + const hasEmptyUserValues = Object.entries(this.config.vars) + .some(([v, key]) => { + if (v.type != 'user') + return false; + if (!this.config.uservars) + return true; + if (!this.config.uservars[key]) + return true; + return false; + }); + if (hasEmptyUserValues) return this.hasErrors = true; if (error.response.data.errors)