Add ability to configure columns in metric and chart blocks
This commit is contained in:
parent
03ec8d3930
commit
144eb912fb
@ -1,12 +1,15 @@
|
||||
<template>
|
||||
<div class="d-flex">
|
||||
<b-button
|
||||
size="lg"
|
||||
variant="light"
|
||||
:size="size"
|
||||
:variant="variant"
|
||||
class="flex-fill"
|
||||
:disabled="disabled"
|
||||
@click="showModal = true"
|
||||
>
|
||||
{{ $t('allRecords.columns.title') }}
|
||||
<slot>
|
||||
{{ $t('allRecords.columns.title') }}
|
||||
</slot>
|
||||
</b-button>
|
||||
|
||||
<b-modal
|
||||
@ -60,6 +63,21 @@ export default {
|
||||
required: true,
|
||||
default: () => [],
|
||||
},
|
||||
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
|
||||
size: {
|
||||
type: String,
|
||||
default: 'lg',
|
||||
},
|
||||
|
||||
variant: {
|
||||
type: String,
|
||||
default: 'light',
|
||||
},
|
||||
},
|
||||
|
||||
data () {
|
||||
@ -70,10 +88,10 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
this.filteredFields = this.fields.map(f => {
|
||||
return { ...f.moduleField }
|
||||
})
|
||||
watch: {
|
||||
fields (fields) {
|
||||
this.filteredFields = this.module.filterFields(fields)
|
||||
},
|
||||
},
|
||||
|
||||
beforeDestroy () {
|
||||
|
||||
@ -175,6 +175,7 @@ export default {
|
||||
this.$root.$emit(`drill-down-recordList:${recordListUniqueID}`, prefilter)
|
||||
} else {
|
||||
const { title } = this.block
|
||||
const { fields = [] } = this.options.drillDown.recordListOptions || {}
|
||||
|
||||
// Open in modal
|
||||
const block = new compose.PageBlockRecordList({
|
||||
@ -182,6 +183,7 @@ export default {
|
||||
blockID: `drillDown-${chartID}`,
|
||||
options: {
|
||||
moduleID,
|
||||
fields,
|
||||
prefilter,
|
||||
presort: 'createdAt DESC',
|
||||
hideRecordReminderButton: true,
|
||||
|
||||
@ -18,11 +18,11 @@
|
||||
|
||||
<b-input-group-append>
|
||||
<b-button
|
||||
v-b-tooltip.noninteractive.hover="{ title: $t('chart.openInBuilder'), container: '#body' }"
|
||||
:disabled="!selectedChart || (!selectedChart.canUpdateChart && !selectedChart.canDeleteChart)"
|
||||
v-b-tooltip.hover="{ title: $t(chartSelectorTooltip), container: '#body' }"
|
||||
:disabled="selectedChart && (!selectedChart.canUpdateChart && !selectedChart.canDeleteChart)"
|
||||
variant="extra-light"
|
||||
class="d-flex align-items-center"
|
||||
:to="{ name: 'admin.charts.edit', params: { chartID: (selectedChart || {}).chartID }, query: null }"
|
||||
:to="{ name: chartExternalLink, params: { chartID: (selectedChart || {}).chartID }, query: null }"
|
||||
>
|
||||
<font-awesome-icon :icon="['fas', 'external-link-alt']" />
|
||||
</b-button>
|
||||
@ -32,6 +32,7 @@
|
||||
|
||||
<template v-if="isDrillDownAvailable">
|
||||
<b-form-group
|
||||
:label="$t('chart.drillDown.label')"
|
||||
:description="$t('chart.drillDown.description')"
|
||||
label-class="d-flex align-items-center text-primary"
|
||||
class="mb-1"
|
||||
@ -46,16 +47,32 @@
|
||||
/>
|
||||
</template>
|
||||
|
||||
<c-input-select
|
||||
v-model="options.drillDown.blockID"
|
||||
:options="drillDownOptions"
|
||||
:get-option-key="getOptionKey"
|
||||
:disabled="!options.drillDown.enabled"
|
||||
:get-option-label="o => o.title || o.kind"
|
||||
:reduce="option => option.blockID"
|
||||
:clearable="true"
|
||||
:placeholder="$t('chart.drillDown.openInModal')"
|
||||
/>
|
||||
<b-input-group>
|
||||
<c-input-select
|
||||
v-model="options.drillDown.blockID"
|
||||
:options="drillDownOptions"
|
||||
:get-option-key="getOptionKey"
|
||||
:disabled="!options.drillDown.enabled"
|
||||
:get-option-label="o => o.title || o.kind"
|
||||
:reduce="option => option.blockID"
|
||||
:clearable="true"
|
||||
:placeholder="$t('chart.drillDown.openInModal')"
|
||||
/>
|
||||
|
||||
<b-input-group-append>
|
||||
<column-picker
|
||||
ref="columnPicker"
|
||||
:module="selectedChartModule"
|
||||
:fields="selectedDrilldownFields"
|
||||
:disabled="!!options.drillDown.blockID || !options.drillDown.enabled"
|
||||
variant="extra-light"
|
||||
size="md"
|
||||
@updateFields="onUpdateFields"
|
||||
>
|
||||
<font-awesome-icon :icon="['fas', 'wrench']" />
|
||||
</column-picker>
|
||||
</b-input-group-append>
|
||||
</b-input-group>
|
||||
</b-form-group>
|
||||
</template>
|
||||
</b-tab>
|
||||
@ -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)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -223,13 +223,16 @@ export default {
|
||||
} else {
|
||||
// Open in modal
|
||||
const metricID = `${this.block.blockID}-${name.replace(/\s+/g, '-').toLowerCase()}-${moduleID}-${metricIndex}`
|
||||
|
||||
const { title } = this.block
|
||||
const { fields = [] } = this.options.metrics[metricIndex].drillDown.recordListOptions || {}
|
||||
|
||||
const block = new compose.PageBlockRecordList({
|
||||
title: name || title || this.$t('metric.metricDrillDown'),
|
||||
blockID: `drillDown-${metricID}`,
|
||||
options: {
|
||||
moduleID,
|
||||
fields,
|
||||
prefilter: filter,
|
||||
presort: 'createdAt DESC',
|
||||
hideRecordReminderButton: true,
|
||||
|
||||
@ -166,7 +166,7 @@
|
||||
</b-form-group>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<fieldset v-if="selectedMetricModule">
|
||||
<h5>
|
||||
{{ $t('metric.edit.metricLabel') }}
|
||||
</h5>
|
||||
@ -263,23 +263,39 @@
|
||||
>
|
||||
<template #label>
|
||||
{{ $t('metric.drillDown.label') }}
|
||||
|
||||
<b-form-checkbox
|
||||
v-model="edit.drillDown.enabled"
|
||||
switch
|
||||
class="ml-1"
|
||||
class="ml-1 mb-1"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<c-input-select
|
||||
v-model="edit.drillDown.blockID"
|
||||
:options="drillDownOptions"
|
||||
:disabled="!edit.drillDown.enabled"
|
||||
:get-option-label="o => o.title || o.kind"
|
||||
:reduce="option => option.blockID"
|
||||
:clearable="true"
|
||||
:placeholder="$t('metric.drillDown.openInModal')"
|
||||
append-to-body
|
||||
/>
|
||||
<b-input-group>
|
||||
<c-input-select
|
||||
v-model="edit.drillDown.blockID"
|
||||
:options="drillDownOptions"
|
||||
:disabled="!edit.drillDown.enabled"
|
||||
:get-option-label="o => o.title || o.kind"
|
||||
:reduce="option => option.blockID"
|
||||
:clearable="true"
|
||||
:placeholder="$t('metric.drillDown.openInModal')"
|
||||
append-to-body
|
||||
/>
|
||||
|
||||
<b-input-group-append>
|
||||
<column-picker
|
||||
:module="selectedMetricModule"
|
||||
:disabled="!!edit.drillDown.blockID || !edit.drillDown.enabled"
|
||||
:fields="selectedDrilldownFields"
|
||||
variant="extra-light"
|
||||
size="md"
|
||||
@updateFields="onUpdateFields"
|
||||
>
|
||||
<font-awesome-icon :icon="['fas', 'wrench']" />
|
||||
</column-picker>
|
||||
</b-input-group-append>
|
||||
</b-input-group>
|
||||
</b-form-group>
|
||||
</fieldset>
|
||||
</b-card>
|
||||
@ -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 = []
|
||||
|
||||
@ -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<PageBlockRecordListOptions>;
|
||||
}
|
||||
|
||||
interface Options {
|
||||
@ -24,7 +27,10 @@ const defaults: Readonly<Options> = 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)
|
||||
|
||||
@ -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<any>
|
||||
|
||||
interface DrillDown {
|
||||
enabled: boolean;
|
||||
blockID?: string;
|
||||
blockID: string;
|
||||
recordListOptions: Partial<PageBlockRecordListOptions>;
|
||||
}
|
||||
|
||||
interface ReporterParams {
|
||||
@ -62,9 +63,13 @@ const defaultMetric: Readonly<Metric> = Object.freeze({
|
||||
color: '#000000',
|
||||
fontSize: undefined,
|
||||
},
|
||||
|
||||
drillDown: {
|
||||
enabled: false,
|
||||
blockID: '',
|
||||
recordListOptions: {
|
||||
fields: [],
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ interface FilterPreset {
|
||||
roles: string[];
|
||||
}
|
||||
|
||||
interface Options {
|
||||
export interface Options {
|
||||
moduleID: string;
|
||||
prefilter: string;
|
||||
presort: string;
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user