mirror of
https://github.com/frappe/books.git
synced 2024-12-23 03:19:01 +00:00
multi column layout
This commit is contained in:
parent
1f5e3d8fcb
commit
a10f75b195
@ -5,7 +5,7 @@ const frappe = require('frappejs');
|
||||
module.exports = class FormPage extends Page {
|
||||
constructor(doctype) {
|
||||
let meta = frappe.getMeta(doctype)
|
||||
super(`Edit ${meta.name}`);
|
||||
super({title: `Edit ${meta.name}`});
|
||||
this.meta = meta;
|
||||
|
||||
this.form = new (view.getFormClass(doctype))({
|
||||
|
@ -5,21 +5,19 @@ const Page = require('frappejs/client/view/page');
|
||||
const FormPage = require('frappejs/client/desk/formpage');
|
||||
const ListPage = require('frappejs/client/desk/listpage');
|
||||
const Navbar = require('./navbar');
|
||||
const DeskMenu = require('./menu');
|
||||
const FormModal = require('frappejs/client/desk/formmodal');
|
||||
|
||||
module.exports = class Desk {
|
||||
constructor() {
|
||||
constructor(columns=2) {
|
||||
frappe.router = new Router();
|
||||
frappe.router.listen();
|
||||
|
||||
let body = document.querySelector('body');
|
||||
this.navbar = new Navbar();
|
||||
this.container = frappe.ui.add('div', 'container-fluid', body);
|
||||
|
||||
this.containerRow = frappe.ui.add('div', 'row', this.container)
|
||||
this.sidebar = frappe.ui.add('div', 'col-md-2 sidebar d-none d-md-block', this.containerRow);
|
||||
this.sidebarList = frappe.ui.add('div', 'list-group list-group-flush', this.sidebar);
|
||||
this.body = frappe.ui.add('div', 'col-md-10 main', this.containerRow);
|
||||
this.makeColumns(columns);
|
||||
|
||||
this.pages = {
|
||||
lists: {},
|
||||
@ -33,10 +31,38 @@ module.exports = class Desk {
|
||||
// this.search = new Search(this.nav);
|
||||
}
|
||||
|
||||
makeColumns(columns) {
|
||||
this.menu = null; this.center = null;
|
||||
this.columnCount = columns;
|
||||
if (columns === 3) {
|
||||
this.makeMenu();
|
||||
this.center = frappe.ui.add('div', 'col-md-4 desk-center', this.containerRow);
|
||||
this.body = frappe.ui.add('div', 'col-md-6 desk-body', this.containerRow);
|
||||
} else if (columns === 2) {
|
||||
this.makeMenu();
|
||||
this.body = frappe.ui.add('div', 'col-md-10 desk-body', this.containerRow);
|
||||
} else if (columns === 1) {
|
||||
this.makeMenuPage();
|
||||
this.body = frappe.ui.add('div', 'col-md-12 desk-body', this.containerRow);
|
||||
} else {
|
||||
throw 'columns can be 1, 2 or 3'
|
||||
}
|
||||
}
|
||||
|
||||
makeMenu() {
|
||||
this.menuColumn = frappe.ui.add('div', 'col-md-2 desk-menu', this.containerRow);
|
||||
this.menu = new DeskMenu(this.menuColumn);
|
||||
}
|
||||
|
||||
makeMenuPage() {
|
||||
// make menu page for 1 column layout
|
||||
this.menuPage = null;
|
||||
}
|
||||
|
||||
initRoutes() {
|
||||
frappe.router.add('not-found', async (params) => {
|
||||
if (!this.notFoundPage) {
|
||||
this.notFoundPage = new Page('Not Found');
|
||||
this.notFoundPage = new Page({title: 'Not Found'});
|
||||
}
|
||||
await this.notFoundPage.show();
|
||||
this.notFoundPage.renderError('Not Found', params ? params.route : '');
|
||||
@ -59,8 +85,8 @@ module.exports = class Desk {
|
||||
});
|
||||
|
||||
frappe.router.on('change', () => {
|
||||
if (this.routeItems[window.location.hash]) {
|
||||
this.setActive(this.routeItems[window.location.hash]);
|
||||
if (this.menu) {
|
||||
this.menu.setActive();
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -5,12 +5,22 @@ const view = require('frappejs/client/view');
|
||||
module.exports = class ListPage extends Page {
|
||||
constructor(doctype) {
|
||||
let meta = frappe.getMeta(doctype);
|
||||
super(frappe._("List: {0}", meta.name));
|
||||
|
||||
// if center column is present, list does not have its route
|
||||
const hasRoute = frappe.desk.center ? false : true;
|
||||
|
||||
super({
|
||||
title: frappe._("List: {0}", meta.name),
|
||||
parent: hasRoute ? frappe.desk.body : frappe.desk.center,
|
||||
hasRoute: hasRoute
|
||||
});
|
||||
|
||||
this.list = new (view.getList_class(doctype))({
|
||||
doctype: doctype,
|
||||
parent: this.body,
|
||||
page: this
|
||||
});
|
||||
|
||||
this.on('show', async () => {
|
||||
await this.list.run();
|
||||
});
|
||||
|
40
client/desk/menu.js
Normal file
40
client/desk/menu.js
Normal file
@ -0,0 +1,40 @@
|
||||
const frappe = require('frappejs');
|
||||
|
||||
module.exports = class DeskMenu {
|
||||
constructor(parent) {
|
||||
this.parent = parent;
|
||||
this.routeItems = {};
|
||||
this.make();
|
||||
}
|
||||
|
||||
make() {
|
||||
this.listGroup = frappe.ui.add('div', 'list-group list-group-flush', this.parent);
|
||||
}
|
||||
|
||||
addItem(label, action) {
|
||||
let item = frappe.ui.add('a', 'list-group-item list-group-item-action', this.listGroup);
|
||||
item.textContent = label;
|
||||
if (typeof action === 'string') {
|
||||
item.href = action;
|
||||
this.routeItems[action] = item;
|
||||
} else {
|
||||
item.addEventListener('click', () => {
|
||||
action();
|
||||
this.setActive(item);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
setActive() {
|
||||
if (this.routeItems[window.location.hash]) {
|
||||
let item = this.routeItems[window.location.hash];
|
||||
let className = 'list-group-item-secondary';
|
||||
let activeItem = this.listGroup.querySelector('.' + className);
|
||||
|
||||
if (activeItem) {
|
||||
activeItem.classList.remove(className);
|
||||
}
|
||||
item.classList.add(className);
|
||||
}
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@ frappe.ui = require('./ui');
|
||||
const Desk = require('./desk');
|
||||
|
||||
module.exports = {
|
||||
async start({server}) {
|
||||
async start({server, columns = 2}) {
|
||||
window.frappe = frappe;
|
||||
frappe.init();
|
||||
common.init_libs(frappe);
|
||||
@ -15,7 +15,7 @@ module.exports = {
|
||||
|
||||
frappe.flags.cache_docs = true;
|
||||
|
||||
frappe.desk = new Desk();
|
||||
frappe.desk = new Desk(columns);
|
||||
await frappe.login();
|
||||
}
|
||||
};
|
||||
|
@ -14,13 +14,16 @@ html {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.main {
|
||||
margin-left: -1px;
|
||||
.desk-body {
|
||||
border-left: 1px solid $gray-300;
|
||||
min-height: calc(100vh - 50px);
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
.desk-center {
|
||||
border-left: 1px solid $gray-300;
|
||||
}
|
||||
|
||||
.desk-menu {
|
||||
margin-right: -1px;
|
||||
|
||||
.list-group-item {
|
||||
@ -76,7 +79,7 @@ html {
|
||||
margin-right: -15px;
|
||||
|
||||
.list-row {
|
||||
padding: $spacer-2;
|
||||
padding: $spacer-2 15px;
|
||||
border-bottom: 1px solid $gray-200;
|
||||
.checkbox {
|
||||
margin-right: $spacer-2;
|
||||
|
@ -74,7 +74,7 @@ module.exports = class BaseList {
|
||||
|
||||
makeToolbar() {
|
||||
this.makeSearch();
|
||||
this.btnNew = this.page.addButton(frappe._('New'), 'btn-primary', async () => {
|
||||
this.btnNew = this.page.addButton(frappe._('New'), 'btn-outline-primary', async () => {
|
||||
await frappe.router.setRoute('new', frappe.slug(this.doctype));
|
||||
})
|
||||
this.btnDelete = this.page.addButton(frappe._('Delete'), 'btn-outline-secondary hide', async () => {
|
||||
@ -92,7 +92,7 @@ module.exports = class BaseList {
|
||||
this.toolbar = frappe.ui.add('div', 'list-toolbar', this.parent);
|
||||
this.toolbar.innerHTML = `
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-9">
|
||||
<div class="col-12" style="max-width: 300px">
|
||||
<div class="input-group list-search mb-2">
|
||||
<input class="form-control" type="text" placeholder="Search...">
|
||||
<div class="input-group-append">
|
||||
|
@ -3,15 +3,18 @@ const Observable = require('frappejs/utils/observable');
|
||||
const Dropdown = require('frappejs/client/ui/dropdown');
|
||||
|
||||
module.exports = class Page extends Observable {
|
||||
constructor(title) {
|
||||
constructor({title, parent, hasRoute=true}) {
|
||||
super();
|
||||
this.title = title;
|
||||
Object.assign(this, arguments[0]);
|
||||
if (!this.parent) {
|
||||
this.parent = frappe.desk.body;
|
||||
}
|
||||
this.make();
|
||||
this.dropdowns = {};
|
||||
}
|
||||
|
||||
make() {
|
||||
this.wrapper = frappe.ui.add('div', 'page hide', frappe.desk.body);
|
||||
this.wrapper = frappe.ui.add('div', 'page hide', this.parent);
|
||||
this.wrapper.innerHTML = `<div class="page-head hide"></div>
|
||||
<div class="page-body"></div>`
|
||||
this.head = this.wrapper.querySelector('.page-head');
|
||||
@ -39,9 +42,10 @@ module.exports = class Page extends Observable {
|
||||
}
|
||||
|
||||
async show(params) {
|
||||
if (frappe.router.current_page) {
|
||||
frappe.router.current_page.hide();
|
||||
if (this.parent.activePage) {
|
||||
this.parent.activePage.hide();
|
||||
}
|
||||
|
||||
this.wrapper.classList.remove('hide');
|
||||
this.body.classList.remove('hide');
|
||||
|
||||
@ -49,8 +53,11 @@ module.exports = class Page extends Observable {
|
||||
this.page_error.classList.add('hide');
|
||||
}
|
||||
|
||||
frappe.router.current_page = this;
|
||||
this.parent.activePage = this;
|
||||
|
||||
if (this.hasRoute) {
|
||||
document.title = this.title;
|
||||
}
|
||||
|
||||
await this.trigger('show', params);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user