diff --git a/application/controllers/api/frontend/v1/Report.php b/application/controllers/api/frontend/v1/Report.php index b79026a8e..6313a393c 100644 --- a/application/controllers/api/frontend/v1/Report.php +++ b/application/controllers/api/frontend/v1/Report.php @@ -154,6 +154,7 @@ class Report extends FHCAPI_Controller return [ 'value' => $value, 'label' => $label, + 'original' => $option, ]; }, $options); diff --git a/public/js/components/DashboardWidget/Report/Graph.js b/public/js/components/DashboardWidget/Report/Graph.js index 76f577cf5..4760cdb19 100644 --- a/public/js/components/DashboardWidget/Report/Graph.js +++ b/public/js/components/DashboardWidget/Report/Graph.js @@ -7,6 +7,8 @@ import { useCalculatedVars } from '../../../composables/DashboardWidget/Report/C import ApiReport from '../../../api/factory/report.js'; +import { compileLabel } from '../../../helpers/DashboardWidget/Report.js'; + export default { name: "WidgetsReportGraph", components: { @@ -38,19 +40,10 @@ export default { if (!this.data) return null; - const title = (this.config.title || '').replace( - /\{\s*([^\}]+)\s*\}/g, - (match, key) => { - if (this.calledVars[key] === undefined) - return match; - if (this.config.vars[key].detail?.options) { - const options = this.config.vars[key].detail.options; - const res = options.find(opt => opt.value == this.calledVars[key]); - if (res?.label) - return res.label; - } - return this.calledVars[key]; - } + const title = compileLabel( + this.config.title || '', + this.calledVars, + this.config.vars ); let result = { diff --git a/public/js/components/DashboardWidget/Report/Kpi.js b/public/js/components/DashboardWidget/Report/Kpi.js index ced697015..b862cb942 100644 --- a/public/js/components/DashboardWidget/Report/Kpi.js +++ b/public/js/components/DashboardWidget/Report/Kpi.js @@ -6,6 +6,8 @@ import { useCalculatedVars } from '../../../composables/DashboardWidget/Report/C import ApiReport from '../../../api/factory/report.js'; +import { compileLabel } from '../../../helpers/DashboardWidget/Report.js'; + export default { name: "WidgetsReportKpi", components: { @@ -31,19 +33,10 @@ export default { if (!this.activeAggregator.label) return ''; - return this.activeAggregator.label.replace( - /\{\s*([^\}]+)\s*\}/g, - (match, key) => { - if (this.calledVars[key] === undefined) - return match; - if (this.config.vars[key].detail?.options) { - const options = this.config.vars[key].detail.options; - const res = options.find(opt => opt.value == this.calledVars[key]); - if (res?.label) - return res.label; - } - return this.calledVars[key]; - } + return compileLabel( + this.activeAggregator.label, + this.calledVars, + this.config.vars ); }, activeAggregator() { diff --git a/public/js/helpers/DashboardWidget/Report.js b/public/js/helpers/DashboardWidget/Report.js new file mode 100644 index 000000000..93764c20b --- /dev/null +++ b/public/js/helpers/DashboardWidget/Report.js @@ -0,0 +1,45 @@ +/** + * Compile variable values into label. + * + * Usage: + * { filtername } or { filtername:sqlfield } + * + * The sqlfield in the first option defaults to either 'name' or the first field + * not named 'value' in the query. If a field is not found 'value' is displayed. + * + * @param string string + * @param object values + * @param object details + * @return string + */ +function compileLabel(string, values, details) { + return string.replace( + /\{\s*([^\}]+)\s*\}/g, + (match, key) => { + const [ name, field ] = key.split(':'); + if (values[name] === undefined) + return match; + + const options = details[name].detail?.options; + if (options && field != 'value') { + const option = options.find(opt => opt.value == values[name]); + if (!field) { + if (option?.label !== undefined) + return option.label; + } else { + if (option?.original && option?.original[field] !== undefined) + return option.original[field]; + } + } + return values[name]; + } + ); +} + +export { + compileLabel, +}; + +export default { + compileLabel, +};