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