mirror of
https://github.com/frappe/books.git
synced 2025-02-09 07:29:07 +00:00
Report Actions
This commit is contained in:
parent
5eae951c92
commit
e1266c4f69
@ -30,6 +30,7 @@
|
|||||||
"electron-debug": "^2.0.0",
|
"electron-debug": "^2.0.0",
|
||||||
"electron-devtools-installer": "^2.2.4",
|
"electron-devtools-installer": "^2.2.4",
|
||||||
"express": "^4.16.2",
|
"express": "^4.16.2",
|
||||||
|
"file-saver": "^2.0.2",
|
||||||
"feather-icons": "^4.7.3",
|
"feather-icons": "^4.7.3",
|
||||||
"file-loader": "^1.1.11",
|
"file-loader": "^1.1.11",
|
||||||
"flatpickr": "^4.3.2",
|
"flatpickr": "^4.3.2",
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<form :class="['frappe-form-layout', { 'was-validated': invalid }]">
|
<form :class="['frappe-form-layout', { 'was-validated': invalid }]">
|
||||||
<div class="form-row" v-if="layoutConfig"
|
<div
|
||||||
v-for="(section, i) in layoutConfig.sections" :key="i"
|
class="form-row"
|
||||||
|
v-if="layoutConfig"
|
||||||
|
v-for="(section, i) in layoutConfig.sections"
|
||||||
|
:key="i"
|
||||||
v-show="showSection(i)"
|
v-show="showSection(i)"
|
||||||
>
|
>
|
||||||
<div class="col" v-for="(column, j) in section.columns" :key="j">
|
<div class="col" v-for="(column, j) in section.columns" :key="j">
|
||||||
@ -84,15 +87,17 @@ export default {
|
|||||||
|
|
||||||
if (!layout) {
|
if (!layout) {
|
||||||
const fields = this.fields.map(df => df.fieldname);
|
const fields = this.fields.map(df => df.fieldname);
|
||||||
layout = [{
|
layout = [
|
||||||
columns: [{ fields }]
|
{
|
||||||
}];
|
columns: [{ fields }]
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Array.isArray(layout)) {
|
if (Array.isArray(layout)) {
|
||||||
layout = {
|
layout = {
|
||||||
sections: layout
|
sections: layout
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,12 @@
|
|||||||
:disabled="isDisabled"
|
:disabled="isDisabled"
|
||||||
:autofocus="autofocus"
|
:autofocus="autofocus"
|
||||||
:doc="doc"
|
:doc="doc"
|
||||||
|
:config="dateConfig"
|
||||||
@change="$emit('change', $event)"
|
@change="$emit('change', $event)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
import frappe from 'frappejs';
|
||||||
import Base from './Base';
|
import Base from './Base';
|
||||||
import Autocomplete from './Autocomplete';
|
import Autocomplete from './Autocomplete';
|
||||||
import Check from './Check';
|
import Check from './Check';
|
||||||
@ -62,6 +64,32 @@ export default {
|
|||||||
Time
|
Time
|
||||||
}[this.docfield.fieldtype];
|
}[this.docfield.fieldtype];
|
||||||
},
|
},
|
||||||
|
dateConfig() {
|
||||||
|
if (this.docfield.fieldtype === 'Date') {
|
||||||
|
if (frappe.SystemSettings) {
|
||||||
|
let systemDateFormat = frappe.SystemSettings.dateFormat;
|
||||||
|
let divider = systemDateFormat.indexOf('/') != -1 ? '/' : '-';
|
||||||
|
let flatPickrFormat = '';
|
||||||
|
for (let char of systemDateFormat) {
|
||||||
|
if (
|
||||||
|
!flatPickrFormat.includes(char.toLowerCase()) &&
|
||||||
|
!flatPickrFormat.includes(char.toUpperCase())
|
||||||
|
) {
|
||||||
|
if (char.toLowerCase() !== 'y')
|
||||||
|
flatPickrFormat += char.toLowerCase() + divider;
|
||||||
|
else flatPickrFormat += char.toUpperCase() + divider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
dateFormat: flatPickrFormat.slice(0, -1)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
dateFormat: 'Y/m/d'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
isDisabled() {
|
isDisabled() {
|
||||||
let disabled = this.docfield.disabled;
|
let disabled = this.docfield.disabled;
|
||||||
|
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="row pb-4">
|
<div class="row pb-4">
|
||||||
<frappe-control class="col-4"
|
<frappe-control
|
||||||
v-for="docfield in filters"
|
class="col-3"
|
||||||
:key="docfield.fieldname"
|
v-for="docfield in filters"
|
||||||
:docfield="docfield"
|
:key="docfield.fieldname"
|
||||||
:value="$data.filterValues[docfield.fieldname]"
|
:docfield="docfield"
|
||||||
:doc="$data.filterValues"
|
:value="$data.filterValues[docfield.fieldname]"
|
||||||
@change="updateValue(docfield.fieldname, $event)"/>
|
:doc="$data.filterValues"
|
||||||
</div>
|
@change="updateValue(docfield.fieldname, $event)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import FrappeControl from 'frappejs/ui/components/controls/FrappeControl';
|
import FrappeControl from 'frappejs/ui/components/controls/FrappeControl';
|
||||||
|
16
ui/pages/Report/ReportLinks.vue
Normal file
16
ui/pages/Report/ReportLinks.vue
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<template>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 text-right" v-for="link of links" :key="link.label">
|
||||||
|
<f-button primary @click="link.handler">{{ link.label }}</f-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: ['links']
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
@ -1,17 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
<h4 class="pb-2">{{ reportConfig.title }}</h4>
|
<h4 class="pb-2">{{ reportConfig.title }}</h4>
|
||||||
<report-filters v-if="filtersExists" :filters="reportConfig.filterFields" :filterDefaults="filters" @change="getReportData"></report-filters>
|
<div class="row pb-4">
|
||||||
<div class="pt-2" ref="datatable" v-once></div>
|
<report-filters
|
||||||
</div>
|
:class="linksExists ? 'col-10' : 'col-12'"
|
||||||
<not-found v-if="!reportConfig" />
|
v-if="filtersExists"
|
||||||
|
:filters="reportConfig.filterFields"
|
||||||
|
:filterDefaults="filters"
|
||||||
|
@change="getReportData"
|
||||||
|
></report-filters>
|
||||||
|
<report-links class="col-2" v-if="linksExists" :links="links"></report-links>
|
||||||
|
</div>
|
||||||
|
<div class="pt-2" ref="datatable" v-once></div>
|
||||||
</div>
|
</div>
|
||||||
|
<not-found v-if="!reportConfig" />
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import DataTable from 'frappe-datatable';
|
import DataTable from 'frappe-datatable';
|
||||||
import frappe from 'frappejs';
|
import frappe from 'frappejs';
|
||||||
import ReportFilters from './ReportFilters';
|
import ReportFilters from './ReportFilters';
|
||||||
|
import ReportLinks from './ReportLinks';
|
||||||
import utils from 'frappejs/client/ui/utils';
|
import utils from 'frappejs/client/ui/utils';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -20,13 +30,25 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
filtersExists() {
|
filtersExists() {
|
||||||
return (this.reportConfig.filterFields || []).length;
|
return (this.reportConfig.filterFields || []).length;
|
||||||
|
},
|
||||||
|
linksExists() {
|
||||||
|
return (this.reportConfig.linkFields || []).length;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
links: []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
async created() {
|
||||||
|
this.setLinks();
|
||||||
|
// this.doc.on('change', this.setLinks);
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async getReportData(filters) {
|
async getReportData(filters) {
|
||||||
let data = await frappe.call({
|
let data = await frappe.call({
|
||||||
method: this.reportConfig.method,
|
method: this.reportConfig.method,
|
||||||
args: filters
|
args: filters
|
||||||
});
|
});
|
||||||
|
|
||||||
let rows, columns;
|
let rows, columns;
|
||||||
@ -48,8 +70,8 @@ export default {
|
|||||||
columns = this.getColumns();
|
columns = this.getColumns();
|
||||||
}
|
}
|
||||||
|
|
||||||
for(let column of columns) {
|
for (let column of columns) {
|
||||||
column.editable = false;
|
column.editable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.datatable) {
|
if (this.datatable) {
|
||||||
@ -60,6 +82,21 @@ export default {
|
|||||||
data: rows
|
data: rows
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
return [rows, columns];
|
||||||
|
},
|
||||||
|
setLinks() {
|
||||||
|
if (this.linksExists) {
|
||||||
|
let links = [];
|
||||||
|
for (let link of this.reportConfig.linkFields) {
|
||||||
|
links.push({
|
||||||
|
label: link.label,
|
||||||
|
handler: () => {
|
||||||
|
link.action(this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.links = links;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
getColumns(data) {
|
getColumns(data) {
|
||||||
const columns = this.reportConfig.getColumns(data);
|
const columns = this.reportConfig.getColumns(data);
|
||||||
@ -67,7 +104,8 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
ReportFilters
|
ReportFilters,
|
||||||
|
ReportLinks
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -4,34 +4,34 @@ const luxon = require('luxon');
|
|||||||
const frappe = require('frappejs');
|
const frappe = require('frappejs');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
format(value, field) {
|
format(value, field) {
|
||||||
if (typeof field === 'string') {
|
if (typeof field === 'string') {
|
||||||
field = { fieldtype: field };
|
field = { fieldtype: field };
|
||||||
}
|
|
||||||
|
|
||||||
if (field.fieldtype === 'Currency') {
|
|
||||||
value = numberFormat.formatNumber(value);
|
|
||||||
|
|
||||||
} else if (field.fieldtype === 'Text') {
|
|
||||||
// value = markdown.makeHtml(value || '');
|
|
||||||
|
|
||||||
} else if (field.fieldtype === 'Date') {
|
|
||||||
let dateFormat;
|
|
||||||
if (!frappe.SystemSettings) {
|
|
||||||
dateFormat = 'yyyy-MM-dd';
|
|
||||||
} else {
|
|
||||||
dateFormat = frappe.SystemSettings.dateFormat;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = luxon.DateTime.fromISO(value).toFormat(dateFormat);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (value === null || value === undefined) {
|
|
||||||
value = '';
|
|
||||||
} else {
|
|
||||||
value = value + '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (field.fieldtype === 'Currency') {
|
||||||
|
value = numberFormat.formatNumber(value);
|
||||||
|
} else if (field.fieldtype === 'Text') {
|
||||||
|
// value = markdown.makeHtml(value || '');
|
||||||
|
} else if (field.fieldtype === 'Date') {
|
||||||
|
let dateFormat;
|
||||||
|
if (!frappe.SystemSettings) {
|
||||||
|
dateFormat = 'yyyy-MM-dd';
|
||||||
|
} else {
|
||||||
|
dateFormat = frappe.SystemSettings.dateFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = luxon.DateTime.fromISO(value).toFormat(dateFormat);
|
||||||
|
if (value === 'Invalid DateTime') {
|
||||||
|
value = '';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (value === null || value === undefined) {
|
||||||
|
value = '';
|
||||||
|
} else {
|
||||||
|
value = value + '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user