From 0e962078feb87695716b1f8f639c454ee62c3429 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Tue, 13 Jun 2023 16:20:07 +0530 Subject: [PATCH 1/4] revert: temp fix to load communications --- frappe/desk/form/load.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/desk/form/load.py b/frappe/desk/form/load.py index 55d57a0a82..9e7e818cf0 100644 --- a/frappe/desk/form/load.py +++ b/frappe/desk/form/load.py @@ -253,7 +253,7 @@ def get_point_logs(doctype, docname): ) -def _get_communications(doctype, name, start=0, limit=100): +def _get_communications(doctype, name, start=0, limit=20): communications = get_communication_data(doctype, name, start, limit) for c in communications: if c.communication_type == "Communication": From 82464a41497b6ec7027b6220bef247344b6404f9 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Tue, 13 Jun 2023 16:22:22 +0530 Subject: [PATCH 2/4] fix: add timestamp attr on timeline-item --- frappe/public/js/frappe/form/footer/base_timeline.js | 1 + 1 file changed, 1 insertion(+) diff --git a/frappe/public/js/frappe/form/footer/base_timeline.js b/frappe/public/js/frappe/form/footer/base_timeline.js index af07b1cb95..e040ec75af 100644 --- a/frappe/public/js/frappe/form/footer/base_timeline.js +++ b/frappe/public/js/frappe/form/footer/base_timeline.js @@ -90,6 +90,7 @@ class BaseTimeline { timeline_item.attr({ "data-doctype": item.doctype, "data-name": item.name, + "data-timestamp": item.creation, }); if (item.icon) { timeline_item.append(` From 9e0ed9d2a2bf9c8f09b16429983bc6a6c45519e6 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Tue, 13 Jun 2023 16:23:39 +0530 Subject: [PATCH 3/4] fix: convert string to int --- frappe/desk/form/load.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frappe/desk/form/load.py b/frappe/desk/form/load.py index 9e7e818cf0..e6f735e9d7 100644 --- a/frappe/desk/form/load.py +++ b/frappe/desk/form/load.py @@ -202,11 +202,13 @@ def get_versions(doc): @frappe.whitelist() def get_communications(doctype, name, start=0, limit=20): + from frappe.utils import cint + doc = frappe.get_doc(doctype, name) if not doc.has_permission("read"): raise frappe.PermissionError - return _get_communications(doctype, name, start, limit) + return _get_communications(doctype, name, cint(start), cint(limit)) def get_comments( From b3ab63e697bf9a8df6e63ad11ae29ac9b0706e38 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Tue, 13 Jun 2023 16:24:58 +0530 Subject: [PATCH 4/4] feat: load more communications button in timeline --- .../js/frappe/form/footer/base_timeline.js | 29 ++++++++++++++++++ .../js/frappe/form/footer/form_timeline.js | 30 +++++++++++++++++-- frappe/public/scss/desk/timeline.scss | 5 ++++ 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/frappe/public/js/frappe/form/footer/base_timeline.js b/frappe/public/js/frappe/form/footer/base_timeline.js index e040ec75af..d7ae78d748 100644 --- a/frappe/public/js/frappe/form/footer/base_timeline.js +++ b/frappe/public/js/frappe/form/footer/base_timeline.js @@ -82,6 +82,18 @@ class BaseTimeline { items.forEach((item) => this.add_timeline_item(item, append_at_the_end)); } + add_timeline_items_based_on_creation(items) { + items.forEach((item) => { + this.timeline_items_wrapper.find(".timeline-item").each((i, el) => { + let creation = $(el).attr("data-timestamp"); + if (creation && new Date(creation) < new Date(item.creation)) { + $(el).before(this.get_timeline_item(item)); + return false; + } + }); + }); + } + get_timeline_item(item) { // item can have content*, creation*, // timeline_badge, icon, icon_size, @@ -115,6 +127,23 @@ class BaseTimeline { if (item.id) { timeline_content.attr("id", item.id); } + + if (item.append_load_more) { + timeline_item.append( + `
+ +
` + ); + } + + timeline_item.find(".btn-load-more").on("click", async () => { + let more_items = await this.get_more_communication_timeline_contents(); + timeline_item.find(".timeline-load-more").remove(); + this.add_timeline_items_based_on_creation(more_items); + }); + return timeline_item; } } diff --git a/frappe/public/js/frappe/form/footer/form_timeline.js b/frappe/public/js/frappe/form/footer/form_timeline.js index 5514693c05..4d2b8e8a1c 100644 --- a/frappe/public/js/frappe/form/footer/form_timeline.js +++ b/frappe/public/js/frappe/form/footer/form_timeline.js @@ -193,7 +193,7 @@ class FormTimeline extends BaseTimeline { return view_timeline_contents; } - get_communication_timeline_contents() { + get_communication_timeline_contents(more_items) { let communication_timeline_contents = []; let icon_set = { Email: "mail", @@ -201,7 +201,8 @@ class FormTimeline extends BaseTimeline { Meeting: "calendar", Other: "dot-horizontal", }; - (this.doc_info.communications || []).forEach((communication) => { + let items = more_items ? more_items : this.doc_info.communications || []; + items.forEach((communication) => { let medium = communication.communication_medium; communication_timeline_contents.push({ icon: icon_set[medium], @@ -214,9 +215,34 @@ class FormTimeline extends BaseTimeline { name: communication.name, }); }); + + if (communication_timeline_contents.length >= 20) { + communication_timeline_contents[ + communication_timeline_contents.length - 1 + ].append_load_more = true; + } + return communication_timeline_contents; } + async get_more_communication_timeline_contents() { + let more_items = []; + let response = await frappe.call({ + method: "frappe.desk.form.load.get_communications", + args: { + doctype: this.doc_info.doctype, + name: this.doc_info.name, + start: this.doc_info.communications.length, + limit: 20, + }, + }); + if (response.message) { + this.doc_info.communications.push(...response.message); + more_items = this.get_communication_timeline_contents(response.message); + } + return more_items; + } + get_communication_timeline_content(doc, allow_reply = true) { doc._url = frappe.utils.get_form_link("Communication", doc.name); this.set_communication_doc_status(doc); diff --git a/frappe/public/scss/desk/timeline.scss b/frappe/public/scss/desk/timeline.scss index a99f2648e8..187fc4bc6c 100644 --- a/frappe/public/scss/desk/timeline.scss +++ b/frappe/public/scss/desk/timeline.scss @@ -95,6 +95,11 @@ $threshold: 34; .timeline-badge { @include timeline-badge(var(--timeline-item-icon-size)) } + .timeline-load-more { + margin-left: calc(var(--timeline-item-left-margin) + var(--padding-sm)); + width: var(--timeline-content-max-width); + text-align: center; + } .timeline-message-box { .content {