mirror of
https://github.com/frappe/books.git
synced 2024-12-23 11:29:03 +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 {
|
module.exports = class FormPage extends Page {
|
||||||
constructor(doctype) {
|
constructor(doctype) {
|
||||||
let meta = frappe.getMeta(doctype)
|
let meta = frappe.getMeta(doctype)
|
||||||
super(`Edit ${meta.name}`);
|
super({title: `Edit ${meta.name}`});
|
||||||
this.meta = meta;
|
this.meta = meta;
|
||||||
|
|
||||||
this.form = new (view.getFormClass(doctype))({
|
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 FormPage = require('frappejs/client/desk/formpage');
|
||||||
const ListPage = require('frappejs/client/desk/listpage');
|
const ListPage = require('frappejs/client/desk/listpage');
|
||||||
const Navbar = require('./navbar');
|
const Navbar = require('./navbar');
|
||||||
|
const DeskMenu = require('./menu');
|
||||||
const FormModal = require('frappejs/client/desk/formmodal');
|
const FormModal = require('frappejs/client/desk/formmodal');
|
||||||
|
|
||||||
module.exports = class Desk {
|
module.exports = class Desk {
|
||||||
constructor() {
|
constructor(columns=2) {
|
||||||
frappe.router = new Router();
|
frappe.router = new Router();
|
||||||
frappe.router.listen();
|
frappe.router.listen();
|
||||||
|
|
||||||
let body = document.querySelector('body');
|
let body = document.querySelector('body');
|
||||||
this.navbar = new Navbar();
|
this.navbar = new Navbar();
|
||||||
this.container = frappe.ui.add('div', 'container-fluid', body);
|
this.container = frappe.ui.add('div', 'container-fluid', body);
|
||||||
|
|
||||||
this.containerRow = frappe.ui.add('div', 'row', this.container)
|
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.makeColumns(columns);
|
||||||
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.pages = {
|
this.pages = {
|
||||||
lists: {},
|
lists: {},
|
||||||
@ -33,10 +31,38 @@ module.exports = class Desk {
|
|||||||
// this.search = new Search(this.nav);
|
// 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() {
|
initRoutes() {
|
||||||
frappe.router.add('not-found', async (params) => {
|
frappe.router.add('not-found', async (params) => {
|
||||||
if (!this.notFoundPage) {
|
if (!this.notFoundPage) {
|
||||||
this.notFoundPage = new Page('Not Found');
|
this.notFoundPage = new Page({title: 'Not Found'});
|
||||||
}
|
}
|
||||||
await this.notFoundPage.show();
|
await this.notFoundPage.show();
|
||||||
this.notFoundPage.renderError('Not Found', params ? params.route : '');
|
this.notFoundPage.renderError('Not Found', params ? params.route : '');
|
||||||
@ -59,8 +85,8 @@ module.exports = class Desk {
|
|||||||
});
|
});
|
||||||
|
|
||||||
frappe.router.on('change', () => {
|
frappe.router.on('change', () => {
|
||||||
if (this.routeItems[window.location.hash]) {
|
if (this.menu) {
|
||||||
this.setActive(this.routeItems[window.location.hash]);
|
this.menu.setActive();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -5,12 +5,22 @@ const view = require('frappejs/client/view');
|
|||||||
module.exports = class ListPage extends Page {
|
module.exports = class ListPage extends Page {
|
||||||
constructor(doctype) {
|
constructor(doctype) {
|
||||||
let meta = frappe.getMeta(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))({
|
this.list = new (view.getList_class(doctype))({
|
||||||
doctype: doctype,
|
doctype: doctype,
|
||||||
parent: this.body,
|
parent: this.body,
|
||||||
page: this
|
page: this
|
||||||
});
|
});
|
||||||
|
|
||||||
this.on('show', async () => {
|
this.on('show', async () => {
|
||||||
await this.list.run();
|
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');
|
const Desk = require('./desk');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
async start({server}) {
|
async start({server, columns = 2}) {
|
||||||
window.frappe = frappe;
|
window.frappe = frappe;
|
||||||
frappe.init();
|
frappe.init();
|
||||||
common.init_libs(frappe);
|
common.init_libs(frappe);
|
||||||
@ -15,7 +15,7 @@ module.exports = {
|
|||||||
|
|
||||||
frappe.flags.cache_docs = true;
|
frappe.flags.cache_docs = true;
|
||||||
|
|
||||||
frappe.desk = new Desk();
|
frappe.desk = new Desk(columns);
|
||||||
await frappe.login();
|
await frappe.login();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -14,13 +14,16 @@ html {
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main {
|
.desk-body {
|
||||||
margin-left: -1px;
|
|
||||||
border-left: 1px solid $gray-300;
|
border-left: 1px solid $gray-300;
|
||||||
min-height: calc(100vh - 50px);
|
min-height: calc(100vh - 50px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar {
|
.desk-center {
|
||||||
|
border-left: 1px solid $gray-300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.desk-menu {
|
||||||
margin-right: -1px;
|
margin-right: -1px;
|
||||||
|
|
||||||
.list-group-item {
|
.list-group-item {
|
||||||
@ -76,7 +79,7 @@ html {
|
|||||||
margin-right: -15px;
|
margin-right: -15px;
|
||||||
|
|
||||||
.list-row {
|
.list-row {
|
||||||
padding: $spacer-2;
|
padding: $spacer-2 15px;
|
||||||
border-bottom: 1px solid $gray-200;
|
border-bottom: 1px solid $gray-200;
|
||||||
.checkbox {
|
.checkbox {
|
||||||
margin-right: $spacer-2;
|
margin-right: $spacer-2;
|
||||||
|
@ -74,7 +74,7 @@ module.exports = class BaseList {
|
|||||||
|
|
||||||
makeToolbar() {
|
makeToolbar() {
|
||||||
this.makeSearch();
|
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));
|
await frappe.router.setRoute('new', frappe.slug(this.doctype));
|
||||||
})
|
})
|
||||||
this.btnDelete = this.page.addButton(frappe._('Delete'), 'btn-outline-secondary hide', async () => {
|
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 = frappe.ui.add('div', 'list-toolbar', this.parent);
|
||||||
this.toolbar.innerHTML = `
|
this.toolbar.innerHTML = `
|
||||||
<div class="row">
|
<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">
|
<div class="input-group list-search mb-2">
|
||||||
<input class="form-control" type="text" placeholder="Search...">
|
<input class="form-control" type="text" placeholder="Search...">
|
||||||
<div class="input-group-append">
|
<div class="input-group-append">
|
||||||
|
@ -3,15 +3,18 @@ const Observable = require('frappejs/utils/observable');
|
|||||||
const Dropdown = require('frappejs/client/ui/dropdown');
|
const Dropdown = require('frappejs/client/ui/dropdown');
|
||||||
|
|
||||||
module.exports = class Page extends Observable {
|
module.exports = class Page extends Observable {
|
||||||
constructor(title) {
|
constructor({title, parent, hasRoute=true}) {
|
||||||
super();
|
super();
|
||||||
this.title = title;
|
Object.assign(this, arguments[0]);
|
||||||
|
if (!this.parent) {
|
||||||
|
this.parent = frappe.desk.body;
|
||||||
|
}
|
||||||
this.make();
|
this.make();
|
||||||
this.dropdowns = {};
|
this.dropdowns = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
make() {
|
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>
|
this.wrapper.innerHTML = `<div class="page-head hide"></div>
|
||||||
<div class="page-body"></div>`
|
<div class="page-body"></div>`
|
||||||
this.head = this.wrapper.querySelector('.page-head');
|
this.head = this.wrapper.querySelector('.page-head');
|
||||||
@ -39,9 +42,10 @@ module.exports = class Page extends Observable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async show(params) {
|
async show(params) {
|
||||||
if (frappe.router.current_page) {
|
if (this.parent.activePage) {
|
||||||
frappe.router.current_page.hide();
|
this.parent.activePage.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.wrapper.classList.remove('hide');
|
this.wrapper.classList.remove('hide');
|
||||||
this.body.classList.remove('hide');
|
this.body.classList.remove('hide');
|
||||||
|
|
||||||
@ -49,8 +53,11 @@ module.exports = class Page extends Observable {
|
|||||||
this.page_error.classList.add('hide');
|
this.page_error.classList.add('hide');
|
||||||
}
|
}
|
||||||
|
|
||||||
frappe.router.current_page = this;
|
this.parent.activePage = this;
|
||||||
|
|
||||||
|
if (this.hasRoute) {
|
||||||
document.title = this.title;
|
document.title = this.title;
|
||||||
|
}
|
||||||
|
|
||||||
await this.trigger('show', params);
|
await this.trigger('show', params);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user