diff --git a/client/web/compose/src/components/Chart/Report/ReportEdit.vue b/client/web/compose/src/components/Chart/Report/ReportEdit.vue index 1975651df7..d09b846501 100644 --- a/client/web/compose/src/components/Chart/Report/ReportEdit.vue +++ b/client/web/compose/src/components/Chart/Report/ReportEdit.vue @@ -544,7 +544,7 @@ export default { metricFields () { return [ - { value: 'count', text: 'Count' }, + { value: 'count', text: this.$t('general.label.count') }, ...this.module.fields.filter(f => f.kind === 'Number') .sort((a, b) => (a.label || a.name).localeCompare((b.label || b.name))) .map(({ label, name }) => ({ value: name, text: label || name })), diff --git a/client/web/compose/src/components/Chart/index.vue b/client/web/compose/src/components/Chart/index.vue index fb6fd59607..dc1fa3a46d 100644 --- a/client/web/compose/src/components/Chart/index.vue +++ b/client/web/compose/src/components/Chart/index.vue @@ -104,87 +104,104 @@ export default { const data = await chart.fetchReports({ reporter: this.reporter }) + const module = this.getModuleByID(report.moduleID) + const fields = [ + ...module.fields, + ...module.systemFields(), + ] + if (!!data.labels && Array.isArray(data.labels)) { // Get dimension field kind const [dimension = {}] = report.dimensions - let { field, meta = {} } = dimension - const module = this.getModuleByID(report.moduleID) - - if (module) { - field = [ - ...module.fields, - ...module.systemFields(), - ].find(({ name }) => name === field) - - if (meta.fields && field.kind === 'Select') { - data.labels = data.labels.map(value => { - const { text } = field.options.options.find(o => o.value === value) || {} - const label = text || value - this.valueMap[label] = value - - return label - }) - } - } - - if (field && ['User', 'Record'].includes(field.kind)) { - if (field.kind === 'User') { - // Fetch and map users to labels - await this.resolveUsers(data.labels) - data.labels = data.labels.map(userID => { - const label = field.formatter(this.getUserByID(userID)) || userID - this.valueMap[label] = userID - return label - }) - } else { - // Fetch and map records and their values to labels - const { namespaceID } = this.chart || {} - const recordModule = this.getModuleByID(field.options.moduleID) - if (recordModule && data.labels) { - const isValidRecordID = (recordID) => recordID !== dimension.default && recordID !== 'undefined' - await Promise.all(data.labels.map(recordID => { - if (isValidRecordID(recordID)) { - return this.$ComposeAPI.recordRead({ namespaceID, moduleID: recordModule.moduleID, recordID }).then(record => { - record = new compose.Record(recordModule, record) - - if (field.options.recordLabelField) { - // Get actual field - const relatedField = recordModule.fields.find(({ name }) => name === field.options.labelField) - - return this.$ComposeAPI.recordRead({ namespaceID, moduleID: relatedField.options.moduleID, recordID: record.values[field.options.labelField] }).then(labelRecord => { - record.values[field.options.labelField] = (labelRecord.values.find(({ name }) => name === this.field.options.recordLabelField) || {}).value - return record - }) - } else { + let { field } = dimension + + if (!module) return + + field = fields.find(({ name }) => name === field) + + if (!field) return + + if (field.kind === 'Bool') { + const { trueLabel, falseLabel } = field.options + + data.labels = data.labels.map(value => { + return value === '1' ? trueLabel || this.$t('general:label.yes') : falseLabel || this.$t('general:label.no') + }) + } else if (field.kind === 'Select') { + data.labels = data.labels.map(value => { + const { text } = field.options.options.find(o => o.value === value) || {} + const label = text || value + this.valueMap[label] = value + + return label + }) + } else if (field.kind === 'User') { + // Fetch and map users to labels + await this.resolveUsers(data.labels) + data.labels = data.labels.map(userID => { + const label = field.formatter(this.getUserByID(userID)) || userID + this.valueMap[label] = userID + return label + }) + } else if (field.kind === 'Record') { + // Fetch and map records and their values to labels + const { namespaceID } = this.chart || {} + const recordModule = this.getModuleByID(field.options.moduleID) + if (recordModule && data.labels) { + const isValidRecordID = (recordID) => recordID !== dimension.default && recordID !== 'undefined' + await Promise.all(data.labels.map(recordID => { + if (isValidRecordID(recordID)) { + return this.$ComposeAPI.recordRead({ namespaceID, moduleID: recordModule.moduleID, recordID }).then(record => { + record = new compose.Record(recordModule, record) + + if (field.options.recordLabelField) { + // Get actual field + const relatedField = recordModule.fields.find(({ name }) => name === field.options.labelField) + + return this.$ComposeAPI.recordRead({ namespaceID, moduleID: relatedField.options.moduleID, recordID: record.values[field.options.labelField] }).then(labelRecord => { + record.values[field.options.labelField] = (labelRecord.values.find(({ name }) => name === this.field.options.recordLabelField) || {}).value return record - } - }) - } else { - const record = { values: {} } - record.values[field.options.labelField] = recordID - return record - } - })).then(records => { - data.labels = records.map(record => { - const value = field.options.labelField ? record.values[field.options.labelField] : record.recordID - const label = Array.isArray(value) ? value.join(', ') : value - this.valueMap[label] = record.recordID - - return value + }) + } else { + return record + } }) + } else { + const record = { values: {} } + record.values[field.options.labelField] = recordID + return record + } + })).then(records => { + data.labels = records.map(record => { + const value = field.options.labelField ? record.values[field.options.labelField] : record.recordID + const label = Array.isArray(value) ? value.join(', ') : value + this.valueMap[label] = record.recordID + + return value }) - } + }) } } + } - data.labels = data.labels.map(l => l === 'undefined' ? this.$t('chart:undefined') : l) - data.customColorSchemes = this.$Settings.get('ui.charts.colorSchemes', []) - data.themeVariables = this.getThemeVariables() + data.datasets = data.datasets.map((dataset = {}, i) => { + const { label } = dataset - this.renderer = chart.makeOptions(data) - } else { - data.labels = [] - } + if (label === 'count') { + dataset.label = this.$t('chart:general.label.count') + } else { + const field = fields.find(({ name }) => name === label) || {} + dataset.label = field.label || label + } + + return dataset + }) + + data.labels = data.labels.map(l => l === 'undefined' ? this.$t('chart:undefined') : l) + data.customColorSchemes = this.$Settings.get('ui.charts.colorSchemes', []) + data.themeVariables = this.getThemeVariables() + + this.renderer = chart.makeOptions(data) } catch (e) { this.processing = false this.toastErrorHandler(this.$t('chart.optionsBuildFailed'))(e) diff --git a/locale/en/corteza-webapp-compose/chart.yaml b/locale/en/corteza-webapp-compose/chart.yaml index 9e05bf0a01..ec284b76b6 100644 --- a/locale/en/corteza-webapp-compose/chart.yaml +++ b/locale/en/corteza-webapp-compose/chart.yaml @@ -17,6 +17,7 @@ general: label: title: Label add: Add + count: Count value: Value placeholder: handle: handle (a - z, 0 - 9, underscore, dash)