diff --git a/frappe/public/css/form.css b/frappe/public/css/form.css index 94dee6b469..135f0c196d 100644 --- a/frappe/public/css/form.css +++ b/frappe/public/css/form.css @@ -474,15 +474,6 @@ h6.uppercase, .shared-user { margin-bottom: 10px; } -.linked-with-dialog { - width: 75%; -} -.linked-with-dialog .panel-body { - padding: 0px; -} -.linked-with-dialog .form-section { - padding-top: 15px; -} .attach-missing-image, .attach-image-display { cursor: pointer; diff --git a/frappe/public/css/list.css b/frappe/public/css/list.css index 8bc696f113..e63080dfb1 100644 --- a/frappe/public/css/list.css +++ b/frappe/public/css/list.css @@ -393,6 +393,10 @@ .list-item-container:last-child { border-bottom: none; } +.list-item-table { + border: 1px solid #d1d8dd; + border-radius: 3px; +} .list-item { display: flex; align-items: center; diff --git a/frappe/public/css/mobile.css b/frappe/public/css/mobile.css index e388fb24b2..5d954a9ce2 100644 --- a/frappe/public/css/mobile.css +++ b/frappe/public/css/mobile.css @@ -182,9 +182,6 @@ body { body[data-sidebar="0"] .navbar-home { margin-left: 15px !important; } - .linked-with-dialog { - width: 100% !important; - } } @media (max-width: 991px) and (max-width: 480px) { #navbar-breadcrumbs li a { diff --git a/frappe/public/js/frappe/form/linked_with.js b/frappe/public/js/frappe/form/linked_with.js index f04c7d89f5..70a096b234 100644 --- a/frappe/public/js/frappe/form/linked_with.js +++ b/frappe/public/js/frappe/form/linked_with.js @@ -3,156 +3,162 @@ frappe.provide("frappe.ui.form"); -frappe.ui.form.LinkedWith = Class.extend({ - init: function(opts) { - var me = this; +frappe.ui.form.LinkedWith = class LinkedWith { + + constructor(opts) { $.extend(this, opts); - }, - show: function() { + } + + show() { if(!this.dialog) this.make_dialog(); - this.dialog.fields_dict.list.$wrapper.html('
' - + __("Loading") + '...
'); + $(this.dialog.body).html( + `
+ ${__("Loading")}... +
`); this.dialog.show(); - }, - make_dialog: function() { + } + + make_dialog() { var me = this; this.dialog = new frappe.ui.Dialog({ hide_on_page_refresh: true, - title: __("Linked With"), - fields: [ - { fieldtype: "HTML", label: "list" } - ] + title: __("Linked With") }); - this.dialog.$wrapper.find(".modal-dialog").addClass("linked-with-dialog"); - - this.dialog.on_page_show = function() { + this.dialog.on_page_show = () => { // execute ajax calls sequentially // 1. get linked doctypes // 2. load all doctypes // 3. load linked docs - $.when(me.get_linked_doctypes()) - .then(function() { return me.load_doctypes() }) - .then(function() { - if (me.links_not_permitted_or_missing()) { - return; - } - - return me.get_linked_docs(); - }); + this.get_linked_doctypes() + .then(() => this.load_doctypes()) + .then(() => this.links_not_permitted_or_missing()) + .then(() => this.get_linked_docs()) + .then(() => this.make_html()) } + } - }, - - load_doctypes: function() { - var me = this; - var already_loaded = Object.keys(locals.DocType); - var doctypes_to_load = []; - if (me.frm.__linked_doctypes) { - $.each(Object.keys(me.frm.__linked_doctypes), function(i, v) { - if (already_loaded.indexOf(v)===-1) { - doctypes_to_load.push(v); - } + make_html() { + const linked_docs = this.frm.__linked_docs; + + let html; + + if(Object.keys(linked_docs).length === 0) { + html = __("Not Linked to any record"); + } else { + html = Object.keys(linked_docs).map(dt => { + return `
+ ${this.make_doc_head(dt)} + ${linked_docs[dt] + .map(doc => this.make_doc_row(doc, dt)) + .join("")} +
`; }); } - // load all doctypes sequentially using with_doctype - return $.when.apply($, $.map(doctypes_to_load, function(dt) { - return frappe.model.with_doctype(dt, function() { - if (frappe.listview_settings[dt]) { + + $(this.dialog.body).html(html); + } + + load_doctypes() { + const already_loaded = Object.keys(locals.DocType); + let doctypes_to_load = []; + + if (this.frm.__linked_doctypes) { + doctypes_to_load = + Object.keys(this.frm.__linked_doctypes) + .filter(doctype => !already_loaded.includes(doctype)); + } + + // load all doctypes asynchronously using with_doctype + const promises = doctypes_to_load.map(dt => { + return frappe.model.with_doctype(dt, () => { + if(frappe.listview_settings[dt]) { // add additional fields to __linked_doctypes - me.frm.__linked_doctypes[dt].add_fields = frappe.listview_settings[dt].add_fields; + this.frm.__linked_doctypes[dt].add_fields = + frappe.listview_settings[dt].add_fields; } - }, /*async*/ false); - })); - }, + }); + }); + + return Promise.all(promises); + } - links_not_permitted_or_missing: function() { + links_not_permitted_or_missing() { var me = this; - var links = []; - $.each(me.frm.__linked_doctypes, function(doctype, tmp) { - if(frappe.model.can_get_report(doctype)) { - links.push({label: __(doctype), value: doctype}); - } - }); + let links = null; - links = frappe.utils.sort(links, "label"); + links = + Object.keys(this.frm.__linked_doctypes) + .filter(frappe.model.can_get_report); + let flag; if(!links) { - me.dialog.fields_dict.list.$wrapper.html("
" - + me.frm.doctype + ": " - + (me.frm.__linked_doctypes ? __("Not Linked to any record.") : __("Not enough permission to see links.")) - + "
") - return true; + $(this.dialog.body).html( + `${this.frm.__linked_doctypes + ? __("Not enough permission to see links") + : __("Not Linked to any record")}`); + flag = true; } + flag = false; - return false; - }, - - get_linked_doctypes: function() { - var me = this; - if (this.frm.__linked_doctypes) { - return; - } + // reject Promise if not_permitted or missing + return new Promise( + (resolve, reject) => flag ? reject() : resolve() + ); + } - return frappe.call({ - method: "frappe.desk.form.linked_with.get_linked_doctypes", - args: { - doctype: this.frm.doctype - }, - callback: function(r) { - me.frm.__linked_doctypes = r.message; + get_linked_doctypes() { + return new Promise((resolve, reject) => { + if (this.frm.__linked_doctypes) { + resolve(); } + + frappe.call({ + method: "frappe.desk.form.linked_with.get_linked_doctypes", + args: { + doctype: this.frm.doctype + }, + callback: (r) => { + this.frm.__linked_doctypes = r.message; + resolve(); + } + }); }); - }, + } - get_linked_docs: function() { - var me = this; + get_linked_docs() { return frappe.call({ - method:"frappe.desk.form.linked_with.get_linked_docs", + method: "frappe.desk.form.linked_with.get_linked_docs", args: { - doctype: me.frm.doctype, - name: me.frm.docname, - linkinfo: me.frm.__linked_doctypes, - for_doctype: me.for_doctype + doctype: this.frm.doctype, + name: this.frm.docname, + linkinfo: this.frm.__linked_doctypes, + for_doctype: this.for_doctype }, - callback: function(r) { - var parent = me.dialog.fields_dict.list.$wrapper.empty(); - - if(keys(r.message || {}).length) { - $.each(keys(r.message).sort(), function(i, doctype) { - - if (Object.keys(locals.DocType).indexOf(doctype)=== -1) { - frappe.model.with_doctype(doctype, function() { - if (frappe.listview_settings[doctype]) { - // add additional fields to __linked_doctypes - me.frm.__linked_doctypes[doctype] = {} - me.frm.__linked_doctypes[doctype].add_fields = frappe.listview_settings[doctype].add_fields; - } - }, /*async*/ false); - } - - var listview = frappe.views.get_listview(doctype, me); - listview.no_delete = true; - me.current_view = "List" - - var wrapper = $('
').appendTo(parent); - $('
').html(__(doctype).bold()).appendTo(wrapper); - var body = $('
').appendTo(wrapper); - - $.each(r.message[doctype], function(i, d) { - d.doctype = doctype; - listview.render($('
') - .appendTo(body), d, me); - }) - }) - } else { - parent.html(__("Not Linked to any record.")); - } + callback: (r) => { + this.frm.__linked_docs = r.message || {}; } }); } -}); + + make_doc_head(heading) { + return `
+
+ ${heading} +
`; + } + + make_doc_row(doc, doctype) { + return `
+
+ +
+
`; + } +} diff --git a/frappe/public/less/form.less b/frappe/public/less/form.less index 11ea7dac21..3a7021418b 100644 --- a/frappe/public/less/form.less +++ b/frappe/public/less/form.less @@ -603,18 +603,6 @@ h6.uppercase, .h6.uppercase { margin-bottom: 10px; } -.linked-with-dialog { - width: 75%; - - .panel-body { - padding: 0px; - } - - .form-section { - padding-top: 15px; - } -} - .attach-missing-image, .attach-image-display { cursor: pointer; diff --git a/frappe/public/less/list.less b/frappe/public/less/list.less index cfe5e120a8..cd932b439d 100644 --- a/frappe/public/less/list.less +++ b/frappe/public/less/list.less @@ -483,6 +483,11 @@ } } +.list-item-table { + border: 1px solid @border-color; + border-radius: 3px; +} + .list-item { display: flex; align-items: center; diff --git a/frappe/public/less/mobile.less b/frappe/public/less/mobile.less index 9141d312ee..60fa2b4f6f 100644 --- a/frappe/public/less/mobile.less +++ b/frappe/public/less/mobile.less @@ -220,10 +220,6 @@ body { margin-left: 15px !important; } } - - .linked-with-dialog { - width: 100% !important; - } } @media(max-width: 767px) {