diff --git a/frappe/public/css/page.css b/frappe/public/css/page.css
index 5c106c7339..5dae59687c 100644
--- a/frappe/public/css/page.css
+++ b/frappe/public/css/page.css
@@ -277,13 +277,17 @@ select.input-sm {
opacity: 1;
cursor: pointer;
}
+.page-card-container,
.setup-state {
background-color: #f5f7fa;
}
+.page-card-container {
+ padding: 70px;
+}
.page-card {
max-width: 360px;
- padding: 15px;
margin: 70px auto;
+ padding: 15px;
border: 1px solid #d1d8dd;
border-radius: 4px;
background-color: #fff;
@@ -295,6 +299,9 @@ select.input-sm {
margin-bottom: 15px;
border-bottom: 1px solid #d1d8dd;
}
+.page-card .btn {
+ margin-top: 30px;
+}
.state-icon-container {
display: flex;
justify-content: center;
diff --git a/frappe/public/js/frappe/ui/page.js b/frappe/public/js/frappe/ui/page.js
index c244ceaa30..659d007e6a 100644
--- a/frappe/public/js/frappe/ui/page.js
+++ b/frappe/public/js/frappe/ui/page.js
@@ -1,20 +1,26 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
-// __("Form")
+/**
+ * Make a standard page layout with a toolbar and title
+ *
+ * @param {Object} opts
+ *
+ * @param {string} opts.parent [HTMLElement] Parent element
+ * @param {boolean} opts.single_column Whether to include sidebar
+ * @param {string} [opts.title] Page title
+ * @param {Object} [opts.required_libs] resources to load
+ * @param {Object} [opts.make_page]
+ *
+ * @returns {frappe.ui.Page}
+ */
+
+/**
+ * @typedef {Object} frappe.ui.Page
+ */
-// parent, title, single_column
-// standard page with page
frappe.ui.make_app_page = function(opts) {
- /* help: make a standard page layout with a toolbar and title */
- /* options: [
- "parent: [HTMLElement] parent element",
- "single_column: [Boolean] false/true",
- "title: [optional] set this title"
- ]
- */
-
opts.parent.page = new frappe.ui.Page(opts);
return opts.parent.page;
}
@@ -36,9 +42,47 @@ frappe.ui.Page = Class.extend({
make: function() {
this.wrapper = $(this.parent);
+ this.setup_render();
+ },
+ get_empty_state: function({title, message, primary_action}) {
+ let $empty_state = $(`
+
+
+
+ ${title}
+
+
${message}
+
+
+
`);
+
+ $empty_state.find('.btn-primary').on('click', () => {
+ primary_action.on_click();
+ });
+
+ return $empty_state;
+ },
+
+ setup_render: function() {
+ var lib_exists = (typeof this.required_libs === 'string' && this.required_libs)
+ || ($.isArray(this.required_libs) && this.required_libs.length);
+
+ if (lib_exists) {
+ this.load_lib(() => {
+ this.add_main_section();
+ });
+ } else {
+ this.add_main_section();
+ }
+ },
+
+ load_lib: function (callback) {
+ frappe.require(this.required_libs, callback);
+ },
+
+ add_main_section: function() {
$(frappe.render_template("page", {})).appendTo(this.wrapper);
-
if(this.single_column) {
// nesting under col-sm-12 for consistency
this.add_view("main", '\
@@ -48,18 +92,19 @@ frappe.ui.Page = Class.extend({
\
\
+ this.add_view("main", '
');
- // this.wrapper.find('.page-title')
- // .removeClass('col-md-7').addClass('col-md-offset-2 col-md-5')
- // .css({'padding-left': '45px'});
}
+ this.setup_page();
+ },
+
+ setup_page: function() {
this.$title_area = this.wrapper.find("h1");
this.$sub_title_area = this.wrapper.find("h6");
@@ -92,6 +137,10 @@ frappe.ui.Page = Class.extend({
this.page_form = $('
').prependTo(this.main);
this.inner_toolbar = $('
').prependTo(this.main);
this.icon_group = this.page_actions.find(".page-icon-group");
+
+ if(this.make_page) {
+ this.make_page();
+ }
},
set_indicator: function(label, color) {
@@ -437,7 +486,11 @@ frappe.ui.Page = Class.extend({
return values;
},
add_view: function(name, html) {
- this.views[name] = $(html).appendTo($(this.wrapper).find(".page-content"));
+ let element = html;
+ if(typeof(html) === "string") {
+ element = $(html);
+ }
+ this.views[name] = element.appendTo($(this.wrapper).find(".page-content"));
if(!this.current_view) {
this.current_view = this.views[name];
} else {
diff --git a/frappe/public/less/page.less b/frappe/public/less/page.less
index 8aecdce737..52294214d8 100644
--- a/frappe/public/less/page.less
+++ b/frappe/public/less/page.less
@@ -283,6 +283,7 @@ select.input-sm {
}
}
+
.missing-image {
display: block;
position: relative;
@@ -334,14 +335,18 @@ select.input-sm {
}
}
-.setup-state {
+.page-card-container, .setup-state {
background-color: #f5f7fa;
}
+.page-card-container {
+ padding: 70px;
+}
+
.page-card {
max-width: 360px;
+ margin: 70px auto;
padding: 15px;
- margin: 70px auto;
border: 1px solid #d1d8dd;
border-radius: 4px;
background-color: #fff;
@@ -353,6 +358,10 @@ select.input-sm {
margin-bottom: 15px;
border-bottom: 1px solid #d1d8dd;
}
+
+ .btn {
+ margin-top: 30px;
+ }
}
.state-icon-container {