From c30d07797d2adf1213925e2a00a2fc3658d2dac7 Mon Sep 17 00:00:00 2001 From: Emmy Leke Date: Wed, 17 Jan 2024 14:04:47 +0100 Subject: [PATCH] Add ability to configure columns in metric and chart blocks --- .../Admin/Module/Records/ColumnPicker.vue | 32 ++++++-- .../src/components/PageBlocks/ChartBase.vue | 2 + .../PageBlocks/ChartConfigurator.vue | 78 +++++++++++++++---- .../src/components/PageBlocks/MetricBase.vue | 2 + .../PageBlocks/MetricConfigurator/index.vue | 62 +++++++++++---- lib/js/src/compose/types/page-block/chart.ts | 18 ++++- lib/js/src/compose/types/page-block/metric.ts | 9 ++- .../compose/types/page-block/record-list.ts | 2 +- locale/en/corteza-webapp-compose/block.yaml | 6 +- 9 files changed, 164 insertions(+), 47 deletions(-) diff --git a/client/web/compose/src/components/Admin/Module/Records/ColumnPicker.vue b/client/web/compose/src/components/Admin/Module/Records/ColumnPicker.vue index 95b967e56..111d4932b 100644 --- a/client/web/compose/src/components/Admin/Module/Records/ColumnPicker.vue +++ b/client/web/compose/src/components/Admin/Module/Records/ColumnPicker.vue @@ -1,12 +1,15 @@ @@ -64,6 +81,7 @@ import base from './base' import { mapGetters } from 'vuex' import { NoID } from '@cortezaproject/corteza-js' +import ColumnPicker from 'corteza-webapp-compose/src/components/Admin/Module/Records/ColumnPicker' export default { i18nOptions: { @@ -72,11 +90,16 @@ export default { name: 'Chart', + components: { + ColumnPicker, + }, + extends: base, computed: { ...mapGetters({ charts: 'chart/set', + getModuleByID: 'module/getByID', }), selectedChart () { @@ -87,6 +110,14 @@ export default { return this.charts.find(({ chartID }) => chartID === this.options.chartID) }, + chartExternalLink () { + return !this.selectedChart ? 'admin.charts' : 'admin.charts.edit' + }, + + chartSelectorTooltip () { + return !this.selectedChart ? 'chart.openChartList' : 'chart.openInBuilder' + }, + selectedChartModuleID () { if (!this.selectedChart) return @@ -95,6 +126,18 @@ export default { return moduleID }, + selectedChartModule () { + if (!this.selectedChartModuleID) return + + return this.getModuleByID(this.selectedChartModuleID) + }, + + selectedDrilldownFields () { + if (!this.selectedChart) return [] + + return this.options.drillDown.recordListOptions.fields + }, + isDrillDownAvailable () { if (!this.selectedChart) return @@ -110,15 +153,16 @@ export default { methods: { chartSelected () { - this.options.drillDown = { - enabled: false, - blockID: '', - } + this.block.resetDrillDown() }, getOptionKey ({ chartID }) { return chartID }, + + onUpdateFields (fields) { + this.options.drillDown.recordListOptions.fields = fields.map(({ fieldID }) => fieldID) + }, }, } diff --git a/client/web/compose/src/components/PageBlocks/MetricBase.vue b/client/web/compose/src/components/PageBlocks/MetricBase.vue index 7bf915a6f..332bccd6d 100644 --- a/client/web/compose/src/components/PageBlocks/MetricBase.vue +++ b/client/web/compose/src/components/PageBlocks/MetricBase.vue @@ -222,12 +222,14 @@ export default { } else { // Open in modal const metricID = `${this.block.blockID}-${name.replace(/\s+/g, '-').toLowerCase()}-${moduleID}-${metricIndex}` + const { fields = [] } = this.options.metrics[metricIndex].drillDown.recordListOptions || {} const block = new compose.PageBlockRecordList({ title: name || this.$t('metric.metricDrillDown'), blockID: `drillDown-${metricID}`, options: { moduleID, + fields, prefilter: filter, presort: 'createdAt DESC', hideRecordReminderButton: true, diff --git a/client/web/compose/src/components/PageBlocks/MetricConfigurator/index.vue b/client/web/compose/src/components/PageBlocks/MetricConfigurator/index.vue index 31ad12dc3..6b9abc417 100644 --- a/client/web/compose/src/components/PageBlocks/MetricConfigurator/index.vue +++ b/client/web/compose/src/components/PageBlocks/MetricConfigurator/index.vue @@ -166,7 +166,7 @@ -
+
{{ $t('metric.edit.metricLabel') }}
@@ -263,23 +263,39 @@ > - + + + + + + + + +
@@ -333,6 +349,7 @@ import base from '../base' import MStyle from './MStyle' import { mapGetters } from 'vuex' import MetricBase from '../MetricBase' +import ColumnPicker from 'corteza-webapp-compose/src/components/Admin/Module/Records/ColumnPicker' import { compose, NoID } from '@cortezaproject/corteza-js' export default { @@ -344,6 +361,7 @@ export default { components: { MStyle, MetricBase, + ColumnPicker, }, extends: base, @@ -375,7 +393,7 @@ export default { computed: { ...mapGetters({ modules: 'module/set', - moduleByID: 'module/getByID', + getModuleByID: 'module/getByID', }), fields () { @@ -383,7 +401,13 @@ export default { return [] } - return this.moduleByID(this.edit.moduleID).fields + return this.getModuleByID(this.edit.moduleID).fields + }, + + selectedDrilldownFields () { + if (!this.edit || !this.edit.drillDown.recordListOptions.fields) return [] + + return this.edit.drillDown.recordListOptions.fields }, metricFields () { @@ -406,6 +430,12 @@ export default { drillDownOptions () { return this.page.blocks.filter(({ blockID, kind, options = {} }) => kind === 'RecordList' && blockID !== NoID && options.moduleID === this.edit.moduleID) }, + + selectedMetricModule () { + if (!this.edit.moduleID) return undefined + + return this.getModuleByID(this.edit.moduleID) + }, }, watch: { @@ -471,6 +501,10 @@ export default { } }, + onUpdateFields (fields) { + this.edit.drillDown.recordListOptions.fields = fields + }, + setDefaultValues () { this.edit = undefined this.dimensionModifiers = [] diff --git a/lib/js/src/compose/types/page-block/chart.ts b/lib/js/src/compose/types/page-block/chart.ts index b4bf24f88..c0d6716b9 100644 --- a/lib/js/src/compose/types/page-block/chart.ts +++ b/lib/js/src/compose/types/page-block/chart.ts @@ -1,11 +1,14 @@ import { PageBlock, PageBlockInput, Registry } from './base' -import { Apply, CortezaID, NoID } from '../../../cast' +import { Apply,NoID } from '../../../cast' +import { Options as PageBlockRecordListOptions } from './record-list' +import { cloneDeep, merge } from 'lodash' const kind = 'Chart' interface DrillDown { enabled: boolean; - blockID?: string; + blockID: string; + recordListOptions: Partial; } interface Options { @@ -24,7 +27,10 @@ const defaults: Readonly = Object.freeze({ drillDown: { enabled: false, blockID: '', - }, + recordListOptions: { + fields: [], + }, + } }) export class PageBlockChart extends PageBlock { @@ -47,9 +53,13 @@ export class PageBlockChart extends PageBlock { Apply(this.options, o, Boolean, 'showRefresh') if (o.drillDown) { - this.options.drillDown = o.drillDown + this.options.drillDown = merge({}, defaults.drillDown, o.drillDown) } } + + resetDrillDown(): void { + this.options.drillDown = cloneDeep(defaults.drillDown) + } } Registry.set(kind, PageBlockChart) diff --git a/lib/js/src/compose/types/page-block/metric.ts b/lib/js/src/compose/types/page-block/metric.ts index e3bc496ec..0b15dd0ec 100644 --- a/lib/js/src/compose/types/page-block/metric.ts +++ b/lib/js/src/compose/types/page-block/metric.ts @@ -1,14 +1,15 @@ import { PageBlock, PageBlockInput, Registry } from './base' import { merge } from 'lodash' import { Apply } from '../../../cast' - +import { Options as PageBlockRecordListOptions } from './record-list' const kind = 'Metric' type Reporter = (p: ReporterParams) => Promise interface DrillDown { enabled: boolean; - blockID?: string; + blockID: string; + recordListOptions: Partial; } interface ReporterParams { @@ -62,9 +63,13 @@ const defaultMetric: Readonly = Object.freeze({ color: '#000000', fontSize: undefined, }, + drillDown: { enabled: false, blockID: '', + recordListOptions: { + fields: [], + }, }, }) diff --git a/lib/js/src/compose/types/page-block/record-list.ts b/lib/js/src/compose/types/page-block/record-list.ts index 57e8ce7fa..037c22c69 100644 --- a/lib/js/src/compose/types/page-block/record-list.ts +++ b/lib/js/src/compose/types/page-block/record-list.ts @@ -12,7 +12,7 @@ interface FilterPreset { roles: string[]; } -interface Options { +export interface Options { moduleID: string; prefilter: string; presort: string; diff --git a/locale/en/corteza-webapp-compose/block.yaml b/locale/en/corteza-webapp-compose/block.yaml index a15f18266..c80d29d5a 100644 --- a/locale/en/corteza-webapp-compose/block.yaml +++ b/locale/en/corteza-webapp-compose/block.yaml @@ -98,8 +98,9 @@ chart: display: Chart to display inside this block drillDown: label: Drill down - description: If a record list is selected, it will be used to display the drill down data. If no record list is selected the drill down data will be shown in a modal. + description: If a record list is selected, it will be used to display the drill down data. If no record list is selected, the drill down data will be shown in a modal. openInModal: Open in modal + configureColumns: Choose the default fields edit: label: Edit chart dimension: @@ -119,6 +120,7 @@ chart: chartId: Chart preview (ID {{0}}) searchPlaceholder: Type here to search all charts in this namespace openInBuilder: Open in chart builder + openChartList: Open chart list content: ok: Ok label: Content @@ -201,7 +203,7 @@ metric: defaultMetricLabel: Unnamed metric drillDown: label: Drill down - description: If a record list is selected, it will be used to display the drill down data. If no record list is selected the drill down data will be shown in a modal. + description: If a record list is selected, it will be used to display the drill down data. If no record list is selected, the drill down data will be shown in a modal. openInModal: Open in modal edit: bucketLabel: Bucket size