2
0
mirror of https://github.com/frappe/books.git synced 2025-02-13 01:18:37 +00:00

welcome rollup, bye bye webpack

This commit is contained in:
Rushabh Mehta 2018-01-30 17:33:04 +05:30
parent ec0ebd95a5
commit f68ffb23ec
13 changed files with 930 additions and 997 deletions

View File

@ -5,6 +5,7 @@
"node": true
},
"parserOptions": {
"ecmaVersion": 2017
"ecmaVersion": 2017,
"sourceType": "module"
}
}

28
client/desk/formpage.js Normal file
View File

@ -0,0 +1,28 @@
const Page = require('frappejs/client/view/page');
const view = require('frappejs/client/view');
module.exports = class FormPage extends Page {
constructor(doctype) {
let meta = frappe.get_meta(doctype)
super(`Edit ${meta.name}`);
this.meta = meta;
this.form = new (view.get_form_class(doctype))({
doctype: doctype,
parent: this.body
});
this.on('show', async (params) => {
await this.show_doc(params.doctype, params.name);
});
}
async show_doc(doctype, name) {
try {
this.doc = await frappe.get_doc(doctype, name);
this.form.use(this.doc);
} catch (e) {
this.render_error(e.status_code, e.message);
}
}
}

View File

@ -2,8 +2,8 @@ const frappe = require('frappejs');
const Search = require('./search');
const Router = require('frappejs/common/router');
const Page = require('frappejs/client/view/page');
const BaseList = require('frappejs/client/view/list');
const BaseForm = require('frappejs/client/view/form');
const FormPage = require('frappejs/client/desk/formpage');
const ListPage = require('frappejs/client/desk/listpage');
const Navbar = require('./navbar');
module.exports = class Desk {
@ -60,53 +60,18 @@ module.exports = class Desk {
get_list_page(doctype) {
if (!this.pages.lists[doctype]) {
let page = new Page('List ' + frappe.get_meta(doctype).name);
page.list = new (this.get_view_class(doctype, 'List', BaseList))({
doctype: doctype,
parent: page.body
});
page.on('show', async () => {
await page.list.run();
});
this.pages.lists[doctype] = page;
this.pages.lists[doctype] = new ListPage(doctype);
}
return this.pages.lists[doctype];
}
get_form_page(doctype) {
if (!this.pages.forms[doctype]) {
let page = new Page('Edit ' + frappe.get_meta(doctype).name);
page.form = new (this.get_view_class(doctype, 'Form', BaseForm))({
doctype: doctype,
parent: page.body
});
page.on('show', async (params) => {
try {
page.doc = await frappe.get_doc(params.doctype, params.name);
page.form.use(page.doc);
} catch (e) {
page.render_error(e.status_code, e.message);
}
});
this.pages.forms[doctype] = page;
this.pages.forms[doctype] = new FormPage(doctype);
}
return this.pages.forms[doctype];
}
get_view_class(doctype, class_name, default_class) {
let client_module = this.get_client_module(doctype);
if (client_module && client_module[class_name]) {
return client_module[class_name];
} else {
return default_class;
}
}
get_client_module(doctype) {
return frappe.modules[`${doctype}_client`];
}
add_sidebar_item(label, action) {
let item = frappe.ui.add('a', '', frappe.ui.add('p', null, frappe.desk.sidebar));
item.textContent = label;

16
client/desk/listpage.js Normal file
View File

@ -0,0 +1,16 @@
const Page = require('frappejs/client/view/page');
const view = require('frappejs/client/view');
module.exports = class FormPage extends Page {
constructor(doctype) {
let meta = frappe.get_meta(doctype);
super(`List ${meta.name}`);
this.list = new (view.get_list_class(doctype))({
doctype: doctype,
parent: this.body
});
page.on('show', async () => {
await page.list.run();
});
}
}

23
client/view/index.js Normal file
View File

@ -0,0 +1,23 @@
const BaseList = require('frappejs/client/view/list');
const BaseForm = require('frappejs/client/view/form');
module.exports = {
get_form_class(doctype) {
return this.get_view_class(doctype, 'Form', BaseForm);
},
get_list_class(doctype) {
return this.get_view_class(doctype, 'List', BaseList);
},
get_view_class(doctype, class_name, default_class) {
let client_module = this.get_client_module(doctype);
if (client_module && client_module[class_name]) {
return client_module[class_name];
} else {
return default_class;
}
},
get_client_module(doctype) {
return frappe.modules[`${doctype}_client`];
}
}

View File

@ -0,0 +1,14 @@
module.exports = {
input: './src/index.js',
output: {
file: './dist/js/bundle.js',
format: 'iife',
name: 'desk'
},
plugins: [
require('rollup-plugin-commonjs')(),
require('rollup-plugin-json')(),
require('rollup-plugin-node-resolve')(),
require('rollup-plugin-node-builtins')()
]
}

View File

@ -0,0 +1,17 @@
module.exports = {
input: './node_modules/frappejs/client/style/index.scss',
output: {
file: './dist/css/style.css',
format: 'cjs'
},
plugins: [
require('rollup-plugin-sass')(),
require('rollup-plugin-postcss')({
extract: true,
plugins: [
require('precss'),
require('autoprefixer')
]
})
]
};

View File

@ -6,54 +6,22 @@
yarn add frappejs
```
## Webpack
FrappeJS comes with built in rollup config for your files
You can use webpack to build your JS bundle.
## Build
Since Frappe.js use Bootstrap 4, you will need to add SASS handlers
There are 2 files that get built for the Desk single page application
Your `webpack.config.js` should look like:
- `/dist/js/bundle.js`
- `/dist/css/style.css`
Your `rollup.config.js` should look like:
```js
const path = require('path');
module.exports = {
entry: './index.js',
devtool: 'inline-source-map',
output: {
filename: './js/bundle.js',
publicPath: '/'
},
module: {
rules: [{
test: /\.scss$/,
use: [
{
loader: "style-loader" // creates style nodes from JS strings
},
{
loader: "css-loader" // translates CSS into CommonJS
},
{
loader: 'postcss-loader', // Run post css actions
options: {
plugins: function () { // post css plugins, can be exported to postcss.config.js
return [
require('precss'),
require('autoprefixer')
];
}
},
},
{
loader: "sass-loader", // compiles Sass to CSS
options: {
includePaths: ["node_modules", "./client/scss"]
}
}]
}]
}
};
module.exports = [
require('frappejs/config/rollup.config.style.js'),
require('frappejs/config/rollup.config.app.js')
]
```
## Create a basic app
@ -70,6 +38,8 @@ Sample index.html
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="/dist/css/style.css" rel="stylesheet">
</head>
<body>
<script src="js/bundle.js"></script>
@ -123,7 +93,7 @@ To start the app and build webpack simultaneously you can use a `Procfile`
```yml
server: nodemon server.js
watch: node_modules/.bin/webpack --watch
watch: node_modules/.bin/rolluo -c --watch
```
You can use any procfile handler like `node-foreman` to start the processes.

View File

@ -28,7 +28,7 @@ To create a new Form, you need to pass the model (DocType) and `parent` element.
Controls will be created for all the `fields` of the model that is passed along with a `Submit` button
## Editing
## Set Document for Editing
To setup a form for editing, you can bind a document by calling the `use` method.
@ -39,6 +39,36 @@ edit_page.on('show', async (params) => {
})
```
## Extending
You can extend the form for any DocType by passing creating a module with `_client` suffix. For example `account_client` for Account
The module can export two classes `Form` and `List` these will be used to override the forms and list for the given doctypes
Example:
```js
const BaseForm = require('frappejs/client/view/form');
class AccountForm extends BaseForm {
make() {
super.make();
// override controller event
this.controls['parent_account'].get_filters = (query) => {
return {
keywords: ["like", query],
name: ["!=", this.doc.name]
}
}
}
}
module.exports = {
Form: AccountForm
}
```
## New Document
To setup a form for a new document, just create a new document with the Frappe.js document helpers, and `use` it with paramter `is_new` = true

View File

@ -29,4 +29,26 @@ You can create a new list object by passing the `DocType` and the parent element
## Refreshing
To reload the list, call the `run` method
To reload the list, call the `run` method
## Extending
Lists can be extended by defining a client module for the doctype, similar to forms
```js
const BaseList = require('frappejs/client/view/list');
class ToDoList extends BaseList {
get_fields() {
return ['name', 'subject', 'status'];
}
get_row_html(data) {
let symbol = data.status=="Closed" ? "✔" : "";
return `<a href="#edit/todo/${data.name}">${symbol} ${data.subject}</a>`;
}
}
module.exports = {
List: ToDoList
}
```

View File

@ -1,5 +1,4 @@
const BaseList = require('frappejs/client/view/list');
const BaseForm = require('frappejs/client/view/form');
class ToDoList extends BaseList {
get_fields() {
@ -12,6 +11,5 @@ class ToDoList extends BaseList {
}
module.exports = {
Form: BaseForm,
List: ToDoList
}

View File

@ -12,7 +12,9 @@
"body-parser": "^1.18.2",
"bootstrap": "^4.0.0",
"express": "^4.16.2",
"jquery": "^3.3.1",
"node-fetch": "^1.7.3",
"popper.js": "^1.12.9",
"sqlite3": "^3.1.13",
"walk": "^2.3.9"
},
@ -30,14 +32,18 @@
},
"homepage": "https://github.com/frappe/frappejs#readme",
"devDependencies": {
"css-loader": "^0.28.7",
"autoprefixer": "^7.2.4",
"eslint": "^4.9.0",
"mocha": "^4.0.1",
"node-sass": "^4.7.2",
"nodemon": "^1.14.7",
"primer": "10.2.0",
"sass-loader": "^6.0.6",
"style-loader": "^0.19.1",
"webpack": "^3.10.0"
"precss": "^2.0.0",
"rollup": "^0.55.1",
"rollup-plugin-postcss": "^1.2.7",
"rollup-plugin-sass": "^0.5.3",
"rollup-plugin-commonjs": "^8.3.0",
"rollup-plugin-json": "^2.3.0",
"rollup-plugin-node-builtins": "^2.1.2",
"rollup-plugin-node-resolve": "^3.0.2"
}
}

1651
yarn.lock

File diff suppressed because it is too large Load Diff