Skip to content
This repository has been archived by the owner on Nov 22, 2022. It is now read-only.

Commit

Permalink
Add compose reporter page block
Browse files Browse the repository at this point in the history
  • Loading branch information
Fajfa committed Feb 17, 2022
1 parent c3c2d5d commit 89664b8
Show file tree
Hide file tree
Showing 8 changed files with 360 additions and 43 deletions.
Binary file added src/assets/PageBlocks/Report.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/assets/PageBlocks/index.js
Expand Up @@ -10,3 +10,4 @@ export const RecordOrganizer = require('./RecordOrganizer.png')
export const IFrame = require('./IFrame.png')
export const Metric = require('./Metric.png')
export const Comment = require('./Comment.png')
export const Report = require('./Report.png')
86 changes: 43 additions & 43 deletions src/components/Admin/Page/Builder/Selector.vue
Expand Up @@ -32,7 +32,13 @@
<b-row
class="border-top mt-2"
>
<b-col>{{ $t('selectBlockFootnote') }}.</b-col>
<b-col>
<div
class="mt-2"
>
{{ $t('selectBlockFootnote') }}
</div>
</b-col>
</b-row>
</b-container>
</template>
Expand All @@ -57,76 +63,70 @@ export default {
current: undefined,
types: [
{
label: this.$t('content.label'),
recordPageOnly: false,
block: new compose.PageBlockContent(),
image: images.Content,
label: this.$t('automation.label'),
block: new compose.PageBlockAutomation(),
image: images.Automation,
},
{
label: this.$t('metric.label'),
recordPageOnly: false,
block: new compose.PageBlockMetric(),
image: images.Metric,
label: this.$t('calendar.label'),
block: new compose.PageBlockCalendar(),
image: images.Calendar,
},
{
label: this.$t('chart.label'),
recordPageOnly: false,
block: new compose.PageBlockChart(),
image: images.Chart,
},
{
label: this.$t('socialFeed.label'),
recordPageOnly: false,
block: new compose.PageBlockSocialFeed(),
image: images.SocialFeed,
label: this.$t('content.label'),
block: new compose.PageBlockContent(),
image: images.Content,
},
{
label: this.$t('record.label'),
recordPageOnly: true,
block: new compose.PageBlockRecord(),
image: images.Record,
label: this.$t('comment.label'),
block: new compose.PageBlockComment(),
image: images.Comment,
},
{
label: this.$t('recordList.label'),
recordPageOnly: false,
block: new compose.PageBlockRecordList(),
image: images.RecordList,
label: this.$t('file.label'),
block: new compose.PageBlockFile(),
image: images.File,
},
{
label: this.$t('automation.label'),
recordPageOnly: false,
block: new compose.PageBlockAutomation(),
image: images.Automation,
label: this.$t('iframe.label'),
block: new compose.PageBlockIFrame(),
image: images.IFrame,
},
{
label: this.$t('calendar.label'),
recordPageOnly: false,
block: new compose.PageBlockCalendar(),
image: images.Calendar,
label: this.$t('metric.label'),
block: new compose.PageBlockMetric(),
image: images.Metric,
},
{
label: this.$t('file.label'),
recordPageOnly: false,
block: new compose.PageBlockFile(),
image: images.File,
label: this.$t('record.label'),
block: new compose.PageBlockRecord(),
image: images.Record,
recordPageOnly: true,
},
{
label: this.$t('recordList.label'),
block: new compose.PageBlockRecordList(),
image: images.RecordList,
},
{
label: this.$t('recordOrganizer.label'),
recordPageOnly: false,
block: new compose.PageBlockRecordOrganizer(),
image: images.RecordOrganizer,
},
{
label: this.$t('iframe.label'),
recordPageOnly: false,
block: new compose.PageBlockIFrame(),
image: images.IFrame,
label: this.$t('report.label'),
block: new compose.PageBlockReport(),
image: images.Report,
},
{
label: this.$t('comment.label'),
recordPageOnly: false,
block: new compose.PageBlockComment(),
image: images.Comment,
label: this.$t('socialFeed.label'),
block: new compose.PageBlockSocialFeed(),
image: images.SocialFeed,
},
],
}
Expand Down
134 changes: 134 additions & 0 deletions src/components/PageBlocks/Report/Base.vue
@@ -0,0 +1,134 @@
<template>
<wrap
v-bind="$props"
v-on="$listeners"
>
<div
v-if="processing"
class="d-flex align-items-center justify-content-center h-100"
>
<b-spinner />
</div>

<display-element
v-else-if="displayElement"
:display-element="displayElement"
:labels="{
previous: $t('recordList.pagination.prev'),
next: $t('recordList.pagination.next'),
}"
@update="getDataframes"
/>
</wrap>
</template>
<script>
import base from '../base'
import { system, reporter, NoID } from '@cortezaproject/corteza-js'
import DisplayElement from './DisplayElements'
export default {
name: 'ReportBase',
components: {
DisplayElement,
},
extends: base,
data () {
return {
processing: false,
report: undefined,
displayElement: undefined,
}
},
watch: {
options: {
deep: true,
immediate: true,
handler ({ reportID = NoID }) {
if (reportID !== NoID) {
this.fetchReport(reportID)
}
},
},
},
methods: {
fetchReport (reportID) {
this.processing = true
this.$SystemAPI.reportRead({ reportID })
.then(report => {
this.report = new system.Report(report)
this.getDataframes()
}).catch(this.toastErrorHandler(this.$t('notification:report.fetchFailed')))
.finally(() => {
this.processing = false
})
},
getDataframes (definition = {}) {
const { elementID } = this.options
this.displayElement = undefined
if (elementID) {
const block = this.report.blocks.find(({ elements }) => {
return elements.some(e => e.elementID === elementID)
})
let element = (block.elements || []).find(e => e.elementID === elementID)
if (element && element.kind !== 'Text') {
element = reporter.DisplayElementMaker(element)
const scenarioDefinition = this.getScenarioDefinition(element)
Object.entries(definition).forEach(([key, value]) => {
definition[key] = { ...value, ...scenarioDefinition[key] }
})
const { dataframes: frames = [] } = element.reportDefinitions({ ...definition, ...scenarioDefinition })
if (frames.length) {
this.$SystemAPI.reportRun({ frames, reportID: this.options.reportID })
.then(({ frames: dataframes = [] }) => {
this.displayElement = {
...element,
dataframes,
}
}).catch((e) => {
this.toastErrorHandler(this.$t('notification:report.run-failed'))(e)
})
}
} else {
this.displayElement = element
}
}
},
getScenarioDefinition (element) {
const scenarioDefinition = {}
const { scenarioID } = this.options
const scenario = this.report.scenarios.find(({ label }) => scenarioID === label)
// Generate filter for each load datasource
if (scenario && scenario.filters) {
element.options.datasources.forEach(({ name }) => {
scenarioDefinition[name] = {
ref: name,
filter: scenario.filters[name] || {},
}
})
}
return scenarioDefinition
},
},
}
</script>
126 changes: 126 additions & 0 deletions src/components/PageBlocks/Report/Configurator.vue
@@ -0,0 +1,126 @@
<template>
<b-tab :title="$t('report.label')">
<b-row>
<b-col>
<b-form-group
:label="$t('report.label')"
>
<b-form-select
v-model="options.reportID"
:options="reportOptions"
text-field="handle"
value-field="reportID"
/>
</b-form-group>
</b-col>
<b-col
v-if="selectedReport && scenarioOptions.length > 1"
>
<b-form-group
:label="$t('report.scenario.label')"
>
<b-form-select
v-model="options.scenarioID"
:options="scenarioOptions"
text-field="label"
value-field="scenarioID"
/>
</b-form-group>
</b-col>
</b-row>

<b-form-group
v-if="selectedReport"
:label="$t('report.element.label')"
:description="$t('report.element.description')"
>
<b-form-select
v-model="options.elementID"
:options="elementOptions"
text-field="name"
value-field="elementID"
/>
</b-form-group>
</b-tab>
</template>
<script>
import base from '../base'
import { NoID } from '@cortezaproject/corteza-js'
export default {
i18nOptions: {
namespaces: 'block',
},
extends: base,
data () {
return {
reports: [],
}
},
computed: {
reportOptions () {
return [
{ reportID: NoID, handle: this.$t('general:label.none') },
...this.reports,
]
},
selectedReport () {
const { reportID = NoID } = this.options
if (reportID !== NoID) {
return this.reports.find(r => r.reportID === reportID)
}
return undefined
},
scenarioOptions () {
const { scenarios = [] } = this.selectedReport || {}
return [
{ scenarioID: NoID, label: this.$t('general:label.none') },
...scenarios,
]
},
elementOptions () {
const elements = [{ elementID: NoID, name: this.$t('general:label.none') }]
if (this.selectedReport) {
this.selectedReport.blocks.forEach(b => {
elements.push({
label: b.title || b.key,
options: b.elements.map(({ elementID, name, kind }) => ({ elementID, name: name || kind })),
})
})
}
return elements
},
},
watch: {
'options.blockID' () {
this.options.elementID = NoID
},
},
created () {
this.fetchReports()
},
methods: {
fetchReports () {
this.$SystemAPI.reportList()
.then(({ set = [] }) => {
this.reports = set
})
.catch(this.toastErrorHandler(this.$t('notification:report.listFetchFailed')))
},
},
}
</script>

0 comments on commit 89664b8

Please sign in to comment.