2
0
mirror of https://github.com/frappe/books.git synced 2024-11-10 07:40:55 +00:00

Render ListView based on listConfig

This commit is contained in:
Faris Ansari 2018-10-23 02:02:37 +05:30
parent 550c2708d2
commit bd3b266a69
14 changed files with 123 additions and 124 deletions

View File

@ -26,9 +26,8 @@ module.exports = {
fieldtype: 'Link',
target: 'Party',
required: 1,
getFilters: (query, control) => {
getFilters: (query) => {
return {
keywords: ['like', query],
customer: 1
};
}
@ -38,7 +37,7 @@ module.exports = {
label: 'Account',
fieldtype: 'Link',
target: 'Account',
formula: (doc) => doc.getFrom('Party', doc.customer , 'default_account'),
formula: (doc) => doc.getFrom('Party', doc.customer , 'defaultAccount'),
getFilters: (query, control) => {
return {
keywords: ['like', query],
@ -145,37 +144,5 @@ module.exports = {
await form.$formModal.open(payment);
}
}
],
listSettings: {
getFields(list) {
return ['name', 'customer', 'grandTotal', 'submitted'];
},
getRowHTML(list, data) {
return `<div class='col-3'>${list.getNameHTML(data)}</div>
<div class='col-4 text-muted'>${data.customer}</div>
<div class='col-4 text-muted text-right'>${frappe.format(data.grandTotal, 'Currency')}</div>`;
}
},
listView: {
columns: [
'customer',
{
label: 'Status',
getValue(doc) {
return doc.submitted ? 'Paid' : 'Pending';
}
},
'grandTotal',
'date',
{
label: 'INV #',
getValue(doc) {
return doc.name;
}
}
]
}
]
};

View File

@ -0,0 +1,23 @@
import { _ } from 'frappejs/utils';
export default {
doctype: 'Invoice',
title: _('Invoice'),
columns: [
'customer',
{
label: 'Status',
getValue(doc) {
return doc.submitted ? 'Paid' : 'Pending';
}
},
'grandTotal',
'date',
{
label: 'INV #',
getValue(doc) {
return doc.name;
}
}
]
}

View File

@ -80,11 +80,5 @@ module.exports = {
{ fields: ['tax'] }
]
}
],
listView: {
columns: [
'name',
'description'
]
}
]
};

View File

@ -0,0 +1,10 @@
import { _ } from 'frappejs/utils';
export default {
doctype: 'Item',
title: _('Item'),
columns: [
'name',
'description'
]
}

View File

@ -1,13 +1,12 @@
const BaseList = require('frappejs/client/view/list');
const frappe = require('frappejs');
import { _ } from 'frappejs/utils';
module.exports = class CustomerList extends BaseList {
constructor({doctype, parent, fields, page}) {
super({doctype: 'Party', parent: parent, fields: fields, page: page});
}
getFilters() {
let filters = super.getFilters();
filters.customer = 1;
return filters;
}
export default {
doctype: 'Party',
title: _('Customer'),
columns: [
'name'
],
filters: {
customer: 1
}
}

View File

@ -14,13 +14,12 @@ module.exports = {
"required": 1
},
{
fieldname: 'default_account',
fieldname: 'defaultAccount',
label: 'Default Account',
fieldtype: 'Link',
target: 'Account',
getFilters: (query, control) => {
return {
keywords: ['like', query],
isGroup: 0,
accountType: 'Receivable'
};
@ -48,12 +47,5 @@ module.exports = {
});
}
}
],
listView: {
columns: [
'name'
]
}
]
}

View File

@ -20,7 +20,7 @@ export default {
},
{
label: 'Customers',
route: '/list/Party'
route: '/list/Customer'
},
{
label: 'Items',

View File

@ -52,30 +52,33 @@ export default {
return frappe.getMeta(this.doctype);
}
},
async created() {
if (!this.name) return;
try {
this.doc = await frappe.getDoc(this.doctype, this.name);
if (this.doc._notInserted && this.meta.fields.map(df => df.fieldname).includes('name')) {
// For a user editable name field,
// it should be unset since it is autogenerated
this.doc.set('name', '');
}
if (this.defaultValues) {
for (let fieldname in this.defaultValues) {
const value = this.defaultValues[fieldname];
this.doc.set(fieldname, value);
}
}
} catch (e) {
this.notFound = true;
}
this.setLinks();
this.doc.on('change', this.setLinks);
created() {
this.loadDoc();
},
methods: {
async loadDoc() {
if (!this.name) return;
try {
this.doc = await frappe.getDoc(this.doctype, this.name);
if (this.doc._notInserted && this.meta.fields.map(df => df.fieldname).includes('name')) {
// For a user editable name field,
// it should be unset since it is autogenerated
this.doc.set('name', '');
}
if (this.defaultValues) {
for (let fieldname in this.defaultValues) {
const value = this.defaultValues[fieldname];
this.doc.set(fieldname, value);
}
}
} catch (e) {
this.notFound = true;
}
this.setLinks();
this.doc.on('change', this.setLinks);
},
async save() {
this.setValidity();
if (this.isFormInvalid) return;
@ -132,8 +135,3 @@ export default {
}
}
</script>
<style>
.form-container {
}
</style>

View File

@ -13,23 +13,24 @@
</div>
</template>
<script>
import frappe from 'frappejs';
import ListRow from './ListRow';
import ListCell from './ListCell';
export default {
name: 'List',
props: ['doctype'],
watch: {
doctype(oldValue, newValue) {
if (oldValue !== newValue) {
this.setupColumnsAndData();
}
}
},
props: ['listConfig'],
components: {
ListRow,
ListCell
},
watch: {
listConfig(oldValue, newValue) {
if (oldValue.doctype !== newValue.doctype) {
this.setupColumnsAndData();
}
}
},
data() {
return {
columns: [],
@ -42,6 +43,9 @@ export default {
},
methods: {
setupColumnsAndData() {
this.doctype = this.listConfig.doctype;
this.meta = frappe.getMeta(this.doctype);
this.prepareColumns();
this.updateData();
},
@ -49,11 +53,10 @@ export default {
this.$router.push(`/edit/${this.doctype}/${name}`);
},
async updateData(keywords) {
let filters = null;
let filters = this.listConfig.filters || null;
if (keywords) {
filters = {
keywords: ['like', keywords]
}
if (!filters) filters = {};
filters.keywords = ['like', keywords];
}
this.data = await frappe.db.getAll({
doctype: this.doctype,
@ -62,7 +65,7 @@ export default {
});
},
prepareColumns() {
this.columns = this.meta.listView.columns.map(col => {
this.columns = this.listConfig.columns.map(col => {
if (typeof col === 'string') {
const field = this.meta.getField(col);
if (!field) return null;
@ -77,11 +80,6 @@ export default {
return col;
}).filter(Boolean);
}
},
computed: {
meta() {
return frappe.getMeta(this.doctype);
}
}
};
</script>

View File

@ -4,7 +4,7 @@
<search-input class="mr-2" @change="keyword => filterList(keyword)"/>
</div>
<div class="col-6 d-flex flex-row-reverse">
<f-button primary @click="$emit('newClick')">{{ _('New {0}', doctype) }}</f-button>
<f-button primary @click="$emit('newClick')">{{ _('New {0}', listConfig.title) }}</f-button>
</div>
</div>
</template>
@ -13,7 +13,7 @@ import SearchInput from '@/components/SearchInput';
export default {
name: 'ListToolbar',
props: ['doctype'],
props: ['listConfig'],
components: {
SearchInput
},

View File

@ -1,15 +1,15 @@
<template>
<div class="bg-light">
<page-header :title="meta.label || meta.name" />
<page-header :title="listConfig.title" />
<div class="px-4 py-3">
<list-toolbar
:doctype="doctype"
:listConfig="listConfig"
@newClick="openNewForm"
@filterList="keyword => filterList(keyword)"
class="mb-4"
/>
<list
:doctype="doctype"
:listConfig="listConfig"
/>
</div>
</div>
@ -20,27 +20,35 @@ import Observable from 'frappejs/utils/observable';
import PageHeader from '@/components/PageHeader';
import ListToolbar from './ListToolbar';
import List from './List';
import listConfigs from './listConfig';
export default {
name: 'ListView',
props: ['doctype'],
props: ['listName'],
components: {
PageHeader,
ListToolbar,
List
},
computed: {
meta() {
return frappe.getMeta(this.doctype);
}
},
created() {
frappe.listView = new Observable();
},
methods: {
async openNewForm() {
const doc = await frappe.getNewDoc(this.doctype);
this.$router.push(`/edit/${this.doctype}/${doc.name}`);
const doctype = this.listConfig.doctype;
const doc = await frappe.getNewDoc(doctype);
if (this.listConfig.filters) {
doc.set(this.listConfig.filters);
}
this.$router.push(`/edit/${doctype}/${doc.name}`);
doc.on('afterInsert', () => {
this.$router.push(`/edit/${doctype}/${doc.name}`);
});
}
},
computed: {
listConfig() {
return listConfigs[this.listName];
}
}
}

View File

@ -0,0 +1,9 @@
import Invoice from '../../../models/doctype/Invoice/InvoiceList';
import Customer from '../../../models/doctype/Party/CustomerList';
import Item from '../../../models/doctype/Item/ItemList';
export default {
Invoice,
Customer,
Item
}

View File

@ -14,7 +14,7 @@ Vue.use(Router);
const routes = [
{
path: '/list/:doctype',
path: '/list/:listName',
name: 'ListView',
component: ListView,
props: true

View File

@ -1,5 +1,6 @@
@import "variables.scss";
@import "~bootstrap/scss/bootstrap";
@import "~frappe-datatable/dist/frappe-datatable.css";
html {
font-size: 14px;