diff --git a/core/doctype/profile/profile.js b/core/doctype/profile/profile.js
index 59bacdb85f..137747f48f 100644
--- a/core/doctype/profile/profile.js
+++ b/core/doctype/profile/profile.js
@@ -1,5 +1,4 @@
cur_frm.cscript.onload = function(doc) {
- cur_frm.frm_head.appframe.remove_tabs();
if(!cur_frm.roles_editor) {
var role_area = $('
')
.appendTo(cur_frm.fields_dict.roles_html.wrapper);
diff --git a/public/css/ui/appframe.css b/public/css/ui/appframe.css
index 0737687efd..6648fd0d4f 100644
--- a/public/css/ui/appframe.css
+++ b/public/css/ui/appframe.css
@@ -3,28 +3,53 @@ div.appframe-titlebar {
padding: 6px;
padding-left: 13px;
background: #dfdfdf; /* Old browsers */
- height: 30px;
+ height: 28px;
color: #555;
border-bottom: 1px solid #c2c2c2;
vertical-align: middle;
border-radius: 5px 5px 0px 0px;
}
-div.appframe-marker {
- position: absolute;
- width: 7px;
- margin: -6px; margin-left: -13px;
- height: 42px;
-}
-
.appframe-center {
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
- width: 60%;
+ width: 74%;
}
+span.appframe-breadcrumb {
+ display: inline-block;
+ margin: 5px 0px 0px 0px;
+ padding: 0px;
+ float: left;
+}
+span.appframe-breadcrumb span {
+ display: inline-block;
+ padding: 4px 19px 0px 0px;
+ margin-right: 13px;
+ background: url('../lib/images/ui/navbarsep.png') right no-repeat;
+ margin-top: -4px;
+ color: #777;
+ font-size: 20px;
+}
+
+span.appframe-breadcrumb span:last-child {
+ background: none;
+ margin-right: 0px;
+ padding-right: 10px;
+}
+
+.appframe-breadcrumb span a {
+ color: #777;
+ text-decoration: none;
+}
+
+.appframe-breadcrumb span a:hover {
+ color: #999;
+}
+
+
.appframe-title {
font-size: 150%;
text-overflow: ellipsis;
@@ -42,7 +67,8 @@ div.appframe-toolbar {
div.appframe-titlebar .label {
display: inline-block;
- margin-bottom: 7px;
+ margin-bottom: 3px;
+ margin-left: 14px;
}
div.appframe-titlebar .avatar {
@@ -55,7 +81,7 @@ div.appframe-titlebar .close {
margin: 0px 12px;
}
-.appframe-toolbar select, .appframe-toolbar input, .appframe-toolbar .label {
+.appframe-toolbar select, .appframe-toolbar input {
margin-bottom: 0px;
margin-left: 3px;
}
@@ -68,7 +94,7 @@ span.appframe-tab {
margin-top: -6px;
padding: 12px 11px;
height: 18px;
- vertical-align: middle;
+ /*vertical-align: middle;*/
cursor: pointer;
}
diff --git a/public/images/ui/navbarsep.png b/public/images/ui/navbarsep.png
new file mode 100644
index 0000000000..86e54b2b17
Binary files /dev/null and b/public/images/ui/navbarsep.png differ
diff --git a/public/js/legacy/widgets/form/form.js b/public/js/legacy/widgets/form/form.js
index d27b29a5b1..dfba099619 100644
--- a/public/js/legacy/widgets/form/form.js
+++ b/public/js/legacy/widgets/form/form.js
@@ -982,7 +982,7 @@ _f.Frm.prototype.disable_save = function() {
// IMPORTANT: this function should be called in refresh event
cur_frm.save_disabled = true;
cur_frm.page_layout.footer.hide_save();
- cur_frm.frm_head.appframe.buttons.Save.toggle(false);
+ cur_frm.frm_head.appframe.buttons.Save.remove();
}
_f.get_value = function(dt, dn, fn) {
diff --git a/public/js/legacy/widgets/form/form_header.js b/public/js/legacy/widgets/form/form_header.js
index 28cec3f556..f56006c214 100644
--- a/public/js/legacy/widgets/form/form_header.js
+++ b/public/js/legacy/widgets/form/form_header.js
@@ -33,12 +33,13 @@ _f.FrmHeader = Class.extend({
this.$w = this.appframe.$w;
this.frm = frm;
+ this.appframe.add_home_breadcrumb();
+ this.appframe.add_module_breadcrumb(frm.meta.module)
+
if(!frm.meta.issingle) {
- this.appframe.add_tab(frm.doctype + " List", 0.5, function() {
- wn.set_route("List", frm.doctype);
- });
+ this.appframe.add_list_breadcrumb(frm.meta.name)
}
- this.appframe.add_module_tab(frm.meta.module);
+ this.appframe.add_breadcrumb("icon-file");
},
refresh: function() {
this.appframe.set_title(this.frm.docname);
@@ -110,7 +111,7 @@ _f.FrmHeader = Class.extend({
%(lab_status)s', {
lab_status: labinfo[0],
lab_class: labinfo[1]
- })).insertBefore(this.$w.find('.appframe-title'))
+ })).appendTo(this.$w.find('.appframe-subject'))
},
refresh_toolbar: function() {
// clear
diff --git a/public/js/wn/dom.js b/public/js/wn/dom.js
index b0f745520d..64c0d2320e 100644
--- a/public/js/wn/dom.js
+++ b/public/js/wn/dom.js
@@ -138,9 +138,10 @@ wn.get_shade = function(color, factor) {
+ get_hex(get_int(color.substr(4,2)) + factor)
}
-wn.get_gradient_css = function(col) {
- var col1 = wn.get_shade(col, 10);
- var col2 = wn.get_shade(col, -10);
+wn.get_gradient_css = function(col, diff) {
+ if(!diff) diff = 10
+ var col1 = wn.get_shade(col, diff);
+ var col2 = wn.get_shade(col, -diff);
return "\nbackground-color: " + col + " !important;"
+"\nbackground: -moz-linear-gradient(top, #"+col1+" 0%, #"+col2+" 99%) !important;"
+"\nbackground:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#"+col1+"), color-stop(99%,#"+col2+")) !important;"
diff --git a/public/js/wn/misc/user.js b/public/js/wn/misc/user.js
index 6848c32d72..4c73233ad9 100644
--- a/public/js/wn/misc/user.js
+++ b/public/js/wn/misc/user.js
@@ -64,6 +64,20 @@ $.extend(wn.user, {
}
}
},
+ get_desktop_items: function() {
+ var user_list = wn.user.get_default("_desktop_items");
+ if(user_list && user_list.length)
+ var modules_list = user_list;
+ else
+ try {
+ var modules_list = JSON.parse(wn.boot.modules_list);
+ } catch(e) {
+
+ }
+
+ if(!modules_list) modules_list = keys(wn.modules);
+ return modules_list;
+ },
is_report_manager: function() {
return wn.user.has_role(['Administrator', 'System Manager', 'Report Manager']);
}
diff --git a/public/js/wn/misc/utils.js b/public/js/wn/misc/utils.js
index dc49440ce9..1e3b479bb1 100644
--- a/public/js/wn/misc/utils.js
+++ b/public/js/wn/misc/utils.js
@@ -2,7 +2,7 @@ wn.provide('wn.utils');
wn.utils = {
get_file_link: function(filename) {
- return wn.utils.is_url(filename) || (filename.indexOf("images/")!=-1)
+ return wn.utils.is_url(filename) || (filename.indexOf("images/")!=-1) || (filename.indexOf("files/")!=-1)
? filename : 'files/' + filename;
},
is_url: function(txt) {
diff --git a/public/js/wn/model/model.js b/public/js/wn/model/model.js
index 87e6c0938c..9ad5c0beea 100644
--- a/public/js/wn/model/model.js
+++ b/public/js/wn/model/model.js
@@ -184,6 +184,13 @@ $.extend(wn.model, {
if(d) wn.model.clear_doc(d.doctype, d.name);
});
},
+
+ remove_from_locals: function(doctype, name) {
+ this.clear_doclist(doctype, name);
+ if(wn.views.formview[doctype]) {
+ delete wn.views.formview[doctype].frm.opendocs[name];
+ }
+ },
clear_doc: function(doctype, name) {
delete locals[doctype][name];
diff --git a/public/js/wn/provide.js b/public/js/wn/provide.js
index 3fe2ef8cf5..429431d2cb 100644
--- a/public/js/wn/provide.js
+++ b/public/js/wn/provide.js
@@ -43,4 +43,5 @@ wn._ = function(txt) {
wn.provide("locals");
wn.provide("wn.settings");
wn.provide("wn.utils");
-wn.provide("wn.ui");
\ No newline at end of file
+wn.provide("wn.ui");
+wn.provide("wn.modules");
\ No newline at end of file
diff --git a/public/js/wn/ui/appframe.js b/public/js/wn/ui/appframe.js
index 73444e3056..0a0f4e3dae 100644
--- a/public/js/wn/ui/appframe.js
+++ b/public/js/wn/ui/appframe.js
@@ -5,7 +5,8 @@ wn.ui.AppFrame = Class.extend({
this.$w = $('
').appendTo(parent);
this.$titlebar = $('
\
-
\
+
\
+ \
\
\
\
@@ -19,6 +20,7 @@ wn.ui.AppFrame = Class.extend({
if(title)
this.set_title(title);
+
},
title: function(txt) {
this.set_title(txt);
@@ -28,27 +30,36 @@ wn.ui.AppFrame = Class.extend({
document.title = txt;
this.$titlebar.find(".appframe-title").html(txt);
},
- add_tab: function(tab_name, opacity, click) {
- var span = $('')
- .html(tab_name).insertAfter(this.$titlebar.find(".close"));
- opacity && span.css("opacity", opacity);
- click && span.click(click);
- return span
+ clear_breadcrumbs: function() {
+ this.$w.find(".appframe-breadcrumb").empty();
},
-
- remove_tabs: function() {
- this.$w.find(".appframe-tab").remove();
+ add_breadcrumb: function(icon, link, title) {
+ if(link) {
+ $(repl("\
+ ", {
+ icon: icon,
+ link: link,
+ title: title
+ })).appendTo(this.$w.find(".appframe-breadcrumb"));
+ } else {
+ $(repl("", {
+ icon: icon,
+ })).appendTo(this.$w.find(".appframe-breadcrumb"));
+ }
},
-
- add_module_tab: function(module) {
- if(!erpnext.modules[module]) return;
- this.add_tab(''+' '
- + wn._(module) + "", 0.7, function() {
- wn.set_route(erpnext.modules[module]);
- });
+ add_home_breadcrumb: function() {
+ this.add_breadcrumb("icon-home", wn.home_page, "Home");
+ },
+ add_list_breadcrumb: function(doctype) {
+ this.add_breadcrumb("icon-list", "List/" + encodeURIComponent(doctype), doctype + " List");
+ },
+ add_module_breadcrumb: function(module) {
+ var module_info = wn.modules[module];
+ if(module_info) {
+ this.add_breadcrumb(module_info.icon, module_info.link,
+ module_info.label || module);
+ }
},
-
add_button: function(label, click, icon) {
this.add_toolbar();
args = { label: label, icon:'' };
diff --git a/public/js/wn/views/doclistview.js b/public/js/wn/views/doclistview.js
index 7530b02151..0d9f0ebe39 100644
--- a/public/js/wn/views/doclistview.js
+++ b/public/js/wn/views/doclistview.js
@@ -82,7 +82,9 @@ wn.views.DocListView = wn.ui.Listing.extend({
var module = locals.DocType[this.doctype].module;
this.appframe.set_title(this.doctype + " List");
- this.appframe.add_module_tab(module);
+ this.appframe.add_home_breadcrumb();
+ this.appframe.add_module_breadcrumb(module);
+ this.appframe.add_breadcrumb("icon-list");
},
setup: function() {
diff --git a/public/js/wn/views/grid_report.js b/public/js/wn/views/grid_report.js
index 6b374847ba..05b3a9f2b1 100644
--- a/public/js/wn/views/grid_report.js
+++ b/public/js/wn/views/grid_report.js
@@ -74,7 +74,7 @@ $.extend(wn.report_dump, {
} else {
callback();
}
- }
+ },
});
wn.provide("wn.views");
diff --git a/public/js/wn/views/listview.js b/public/js/wn/views/listview.js
index 9f7756b41b..156ccea0fc 100644
--- a/public/js/wn/views/listview.js
+++ b/public/js/wn/views/listview.js
@@ -39,7 +39,7 @@ wn.views.ListView = Class.extend({
opts.content(parent, data, me);
}
else if(opts.content=='name') {
- $(parent).append(repl('%(name)s', data));
+ $(parent).append(repl('%(name)s', data));
}
else if(opts.content=='avatar') {
$(parent).append(wn.avatar(data.owner, false, "Created by: "
@@ -67,7 +67,7 @@ wn.views.ListView = Class.extend({
this.render_bar_graph(parent, data, opts.content, opts.label);
}
else if(opts.type=='link' && opts.doctype) {
- $(parent).append(repl(''+data[opts.content]+'', data));
}
else if(opts.template) {
diff --git a/public/js/wn/views/reportview.js b/public/js/wn/views/reportview.js
index 080f4dc129..5f59dc461d 100644
--- a/public/js/wn/views/reportview.js
+++ b/public/js/wn/views/reportview.js
@@ -28,7 +28,9 @@ wn.views.ReportViewPage = Class.extend({
make_report_view: function() {
var module = locals.DocType[this.doctype].module;
this.page.appframe.set_title(this.doctype);
- this.page.appframe.add_module_tab(module);
+ this.page.appframe.add_home_breadcrumb()
+ this.page.appframe.add_module_breadcrumb(module)
+ this.page.appframe.add_breadcrumb("icon-table");
this.page.reportview = new wn.views.ReportView({
doctype: this.doctype,
diff --git a/webnotes/model/__init__.py b/webnotes/model/__init__.py
index 7cbd28e879..46ad008f30 100644
--- a/webnotes/model/__init__.py
+++ b/webnotes/model/__init__.py
@@ -66,7 +66,12 @@ def check_if_doc_is_linked(dt, dn):
else:
item = None
try:
- item = sql("select name, parent, parenttype from `tab%s` where `%s`='%s' and docstatus!=2 and `%s`!=parent limit 1" % (link_dt, link_field, dn, link_field))
+ # (ifnull(parent, '')='' or `%s`!=`parent`)
+ # this condition ensures that it allows deletion when child table field references parent
+
+ item = sql("select name, parent, parenttype from `tab%s` where `%s`='%s' and docstatus!=2 and (ifnull(parent, '')='' or `%s`!=`parent`) \
+ limit 1" % (link_dt, link_field, dn, link_field), debug=1)
+
except Exception, e:
if e.args[0]==1146: pass
else: raise e