2019-10-13 21:56:20 +00:00
|
|
|
<template>
|
2019-11-08 10:49:06 +00:00
|
|
|
<div class="flex flex-col max-w-full">
|
2019-10-13 21:56:20 +00:00
|
|
|
<PageHeader>
|
2019-11-19 19:14:15 +00:00
|
|
|
<h1 slot="title" class="text-2xl font-bold">{{ report.title }}</h1>
|
2019-10-13 21:56:20 +00:00
|
|
|
<template slot="actions">
|
|
|
|
<SearchBar class="ml-2" />
|
|
|
|
</template>
|
|
|
|
</PageHeader>
|
2019-11-19 19:14:15 +00:00
|
|
|
<div class="mt-6 flex text-base px-8" v-if="report.filterFields">
|
|
|
|
<div class="ml-3 first:ml-0 w-32" v-for="df in report.filterFields">
|
|
|
|
<FormControl
|
|
|
|
size="small"
|
2019-11-21 19:07:27 +00:00
|
|
|
:background="true"
|
2019-11-19 19:14:15 +00:00
|
|
|
:df="df"
|
|
|
|
:value="filters[df.fieldname]"
|
|
|
|
@change="value => onFilterChange(df, value)"
|
|
|
|
:target="
|
|
|
|
df.fieldtype === 'DynamicLink' ? filters[df.references] : null
|
|
|
|
"
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
2019-11-08 10:49:06 +00:00
|
|
|
<div class="px-8 mt-4">
|
2019-11-19 19:14:15 +00:00
|
|
|
<div class="overflow-auto" :style="{ height: 'calc(100vh - 8rem)' }">
|
|
|
|
<Row
|
|
|
|
:columnCount="columns.length"
|
|
|
|
gap="1rem"
|
|
|
|
column-width="minmax(200px, 1fr)"
|
|
|
|
>
|
2019-10-13 21:56:20 +00:00
|
|
|
<div
|
2019-11-19 19:14:15 +00:00
|
|
|
class="text-gray-600 text-base truncate py-4"
|
2019-10-13 21:56:20 +00:00
|
|
|
v-for="column in columns"
|
|
|
|
:key="column.label"
|
2019-11-19 19:14:15 +00:00
|
|
|
>
|
|
|
|
{{ column.label }}
|
|
|
|
</div>
|
2019-10-13 21:56:20 +00:00
|
|
|
</Row>
|
2019-11-08 10:49:06 +00:00
|
|
|
<div class="flex-1">
|
|
|
|
<Row
|
|
|
|
v-for="(row, i) in rows"
|
|
|
|
:columnCount="columns.length"
|
|
|
|
gap="1rem"
|
|
|
|
:key="i"
|
|
|
|
column-width="minmax(200px, 1fr)"
|
|
|
|
>
|
|
|
|
<div
|
2019-11-19 19:14:15 +00:00
|
|
|
class="text-gray-900 text-base truncate py-4"
|
2019-11-08 10:49:06 +00:00
|
|
|
v-for="column in columns"
|
|
|
|
:key="column.label"
|
2019-11-19 19:14:15 +00:00
|
|
|
>
|
|
|
|
<component
|
|
|
|
v-if="typeof row[column.fieldname] === 'object'"
|
|
|
|
:is="row[column.fieldname]"
|
|
|
|
/>
|
|
|
|
<template v-else>
|
|
|
|
{{ frappe.format(row[column.fieldname], column) }}
|
|
|
|
</template>
|
|
|
|
</div>
|
2019-11-08 10:49:06 +00:00
|
|
|
</Row>
|
|
|
|
</div>
|
2019-10-13 21:56:20 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
<script>
|
|
|
|
import frappe from 'frappejs';
|
|
|
|
import PageHeader from '@/components/PageHeader';
|
|
|
|
import Button from '@/components/Button';
|
|
|
|
import SearchBar from '@/components/SearchBar';
|
|
|
|
import Row from '@/components/Row';
|
2019-11-19 19:14:15 +00:00
|
|
|
import FormControl from '@/components/Controls/FormControl';
|
2019-10-13 21:56:20 +00:00
|
|
|
import reportViewConfig from '@/../reports/view';
|
2019-11-19 19:14:15 +00:00
|
|
|
import throttle from 'lodash/throttle';
|
2019-10-13 21:56:20 +00:00
|
|
|
|
|
|
|
export default {
|
|
|
|
name: 'Report',
|
|
|
|
props: ['reportName'],
|
|
|
|
components: {
|
|
|
|
PageHeader,
|
|
|
|
Button,
|
|
|
|
SearchBar,
|
2019-11-19 19:14:15 +00:00
|
|
|
Row,
|
|
|
|
FormControl
|
|
|
|
},
|
|
|
|
provide() {
|
|
|
|
return {
|
|
|
|
doc: this.filters
|
|
|
|
}
|
2019-10-13 21:56:20 +00:00
|
|
|
},
|
|
|
|
data() {
|
2019-11-19 19:14:15 +00:00
|
|
|
let filters = {};
|
|
|
|
for (let df of reportViewConfig[this.reportName].filterFields) {
|
|
|
|
filters[df.fieldname] = null;
|
|
|
|
}
|
|
|
|
|
2019-10-13 21:56:20 +00:00
|
|
|
return {
|
2019-11-19 19:14:15 +00:00
|
|
|
filters,
|
2019-10-13 21:56:20 +00:00
|
|
|
rows: [],
|
|
|
|
columns: []
|
|
|
|
};
|
|
|
|
},
|
2019-11-19 19:14:15 +00:00
|
|
|
async mounted() {
|
2019-10-13 21:56:20 +00:00
|
|
|
this.columns = this.report.getColumns();
|
2019-11-19 19:14:15 +00:00
|
|
|
await this.setDefaultFilters();
|
|
|
|
await this.fetchReportData();
|
2019-10-13 21:56:20 +00:00
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
async fetchReportData() {
|
|
|
|
let data = await frappe.call({
|
|
|
|
method: this.report.method,
|
2019-11-19 19:14:15 +00:00
|
|
|
args: this.filters
|
2019-10-13 21:56:20 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
let rows, columns;
|
|
|
|
if (data.rows) {
|
|
|
|
rows = data.rows;
|
|
|
|
} else {
|
|
|
|
rows = data;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data.columns) {
|
|
|
|
this.columns = this.report.getColumns(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!rows) {
|
|
|
|
rows = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
this.rows = rows;
|
2019-11-19 19:14:15 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
onFilterChange(df, value) {
|
|
|
|
this.filters[df.fieldname] = value;
|
|
|
|
this.fetchReportData();
|
|
|
|
},
|
|
|
|
|
|
|
|
async setDefaultFilters() {
|
|
|
|
for (let df of this.report.filterFields) {
|
|
|
|
let defaultValue = null;
|
|
|
|
if (df.default) {
|
|
|
|
if (typeof df.default === 'function') {
|
|
|
|
defaultValue = await df.default();
|
|
|
|
} else {
|
|
|
|
defaultValue = df.default;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.filters[df.fieldname] = defaultValue;
|
|
|
|
}
|
2019-10-13 21:56:20 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
computed: {
|
|
|
|
report() {
|
|
|
|
return reportViewConfig[this.reportName];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
</script>
|