Merge branch 'develop' into ui-test-fix
This commit is contained in:
commit
2e80f044c2
10 changed files with 234 additions and 119 deletions
|
|
@ -72,14 +72,14 @@ context("Timeline", () => {
|
|||
cy.click_listview_row_item(0);
|
||||
|
||||
//To check if the submission of the documemt is visible in the timeline content
|
||||
cy.get(".timeline-content").should("contain", "Frappe submitted this document");
|
||||
cy.get(".timeline-content").should("contain", "You submitted this document");
|
||||
cy.get('[id="page-Custom Submittable DocType"] .page-actions')
|
||||
.findByRole("button", { name: "Cancel" })
|
||||
.click();
|
||||
cy.get_open_dialog().findByRole("button", { name: "Yes" }).click();
|
||||
|
||||
//To check if the cancellation of the documemt is visible in the timeline content
|
||||
cy.get(".timeline-content").should("contain", "Frappe cancelled this document");
|
||||
cy.get(".timeline-content").should("contain", "You cancelled this document");
|
||||
|
||||
//Deleting the document
|
||||
cy.visit("/app/custom-submittable-doctype");
|
||||
|
|
|
|||
|
|
@ -841,7 +841,7 @@ class Database:
|
|||
val=None,
|
||||
modified=None,
|
||||
modified_by=None,
|
||||
update_modified=True,
|
||||
update_modified=False,
|
||||
debug=False,
|
||||
for_update=True,
|
||||
):
|
||||
|
|
|
|||
|
|
@ -1144,7 +1144,7 @@ class Document(BaseDocument):
|
|||
data = {"doctype": self.doctype, "name": self.name, "user": frappe.session.user}
|
||||
frappe.publish_realtime("list_update", data, after_commit=True)
|
||||
|
||||
def db_set(self, fieldname, value=None, update_modified=True, notify=False, commit=False):
|
||||
def db_set(self, fieldname, value=None, update_modified=False, notify=False, commit=False):
|
||||
"""Set a value in the document object, update the timestamp and update the database.
|
||||
|
||||
WARNING: This method does not trigger controller validations and should
|
||||
|
|
|
|||
|
|
@ -214,3 +214,4 @@ execute:frappe.delete_doc('Page', 'background_jobs', ignore_missing=True, force=
|
|||
frappe.patches.v14_0.drop_unused_indexes
|
||||
frappe.patches.v15_0.drop_modified_index
|
||||
frappe.patches.v14_0.add_manage_subscriptions_in_navbar_settings
|
||||
frappe.patches.v14_0.update_attachment_comment
|
||||
|
|
|
|||
33
frappe/patches/v14_0/update_attachment_comment.py
Normal file
33
frappe/patches/v14_0/update_attachment_comment.py
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import frappe
|
||||
|
||||
|
||||
def execute():
|
||||
frappe.db.auto_commit_on_many_writes = 1
|
||||
|
||||
# Strip everything except link to attachment and icon from comments of type "Attached"
|
||||
for name, content in frappe.get_all(
|
||||
"Comment", filters={"comment_type": "Attachment"}, fields=["name", "content"], as_list=True
|
||||
):
|
||||
if not content:
|
||||
continue
|
||||
|
||||
start = content.find("<a href")
|
||||
if start != -1:
|
||||
content = content[start:]
|
||||
|
||||
end = content.find("</i>")
|
||||
end = content.find("</a>") if end == -1 else end
|
||||
if end != -1:
|
||||
content = content[: end + 4]
|
||||
|
||||
frappe.db.set_value("Comment", name, "content", content, update_modified=False)
|
||||
|
||||
# Strip "Removed " from comments of type "Attachment Removed"
|
||||
for name, content in frappe.get_all(
|
||||
"Comment",
|
||||
filters={"comment_type": "Attachment Removed"},
|
||||
fields=["name", "content"],
|
||||
as_list=True,
|
||||
):
|
||||
if content and content.startswith("Removed "):
|
||||
frappe.db.set_value("Comment", name, "content", content[8:], update_modified=False)
|
||||
|
|
@ -1,7 +1,11 @@
|
|||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// MIT License. See license.txt
|
||||
import BaseTimeline from "./base_timeline";
|
||||
import { get_version_timeline_content } from "./version_timeline_content_builder";
|
||||
import {
|
||||
get_version_timeline_content,
|
||||
get_user_link,
|
||||
get_user_message,
|
||||
} from "./version_timeline_content_builder";
|
||||
|
||||
class FormTimeline extends BaseTimeline {
|
||||
make() {
|
||||
|
|
@ -106,54 +110,50 @@ class FormTimeline extends BaseTimeline {
|
|||
|
||||
render_timeline_items() {
|
||||
super.render_timeline_items();
|
||||
this.set_document_info();
|
||||
this.add_web_page_view_count();
|
||||
frappe.utils.bind_actions_with_object(this.timeline_items_wrapper, this);
|
||||
}
|
||||
|
||||
set_document_info() {
|
||||
// TODO: handle creation via automation
|
||||
const creation = comment_when(this.frm.doc.creation);
|
||||
let creation_message = frappe.utils.is_current_user(this.frm.doc.owner)
|
||||
? __("You created this {0}", [creation], "Form timeline")
|
||||
: __(
|
||||
"{0} created this {1}",
|
||||
[this.get_user_link(this.frm.doc.owner), creation],
|
||||
"Form timeline"
|
||||
);
|
||||
|
||||
const modified = comment_when(this.frm.doc.modified);
|
||||
let modified_message = frappe.utils.is_current_user(this.frm.doc.modified_by)
|
||||
? __("You edited this {0}", [modified], "Form timeline")
|
||||
: __(
|
||||
"{0} edited this {1}",
|
||||
[this.get_user_link(this.frm.doc.modified_by), modified],
|
||||
"Form timeline"
|
||||
);
|
||||
|
||||
add_web_page_view_count() {
|
||||
if (this.frm.doc.route && cint(frappe.boot.website_tracking_enabled)) {
|
||||
let route = this.frm.doc.route;
|
||||
frappe.utils.get_page_view_count(route).then((res) => {
|
||||
let page_view_count_message = __("{0} Page views", [res.message], "Form timeline");
|
||||
this.add_timeline_item(
|
||||
{
|
||||
content: `${creation_message} • ${modified_message} • ${page_view_count_message}`,
|
||||
hide_timestamp: true,
|
||||
},
|
||||
true
|
||||
);
|
||||
});
|
||||
} else {
|
||||
this.add_timeline_item(
|
||||
{
|
||||
content: `${creation_message} • ${modified_message}`,
|
||||
frappe.utils.get_page_view_count(this.frm.doc.route).then((res) => {
|
||||
this.add_timeline_item({
|
||||
content: __("{0} Web page views", [res.message], "Form timeline"),
|
||||
hide_timestamp: true,
|
||||
},
|
||||
true
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
get_creation_message() {
|
||||
const user_link = get_user_link(this.frm.doc.owner);
|
||||
|
||||
return {
|
||||
creation: this.frm.doc.creation,
|
||||
content: get_user_message(
|
||||
this.frm.doc.owner,
|
||||
__("You created this", null, "Form timeline"),
|
||||
__("{0} created this", [user_link], "Form timeline")
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
get_modified_message() {
|
||||
const user_link = get_user_link(this.frm.doc.modified_by);
|
||||
|
||||
return {
|
||||
creation: this.frm.doc.modified,
|
||||
content: get_user_message(
|
||||
this.frm.doc.modified_by,
|
||||
__("You last edited this", null, "Form timeline"),
|
||||
__("{0} last edited this", [user_link], "Form timeline")
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
prepare_timeline_contents() {
|
||||
this.timeline_items.push(this.get_creation_message());
|
||||
this.timeline_items.push(this.get_modified_message());
|
||||
this.timeline_items.push(...this.get_communication_timeline_contents());
|
||||
this.timeline_items.push(...this.get_auto_messages_timeline_contents());
|
||||
this.timeline_items.push(...this.get_comment_timeline_contents());
|
||||
|
|
@ -172,29 +172,24 @@ class FormTimeline extends BaseTimeline {
|
|||
}
|
||||
}
|
||||
|
||||
get_user_link(user) {
|
||||
const user_display_text = (frappe.user_info(user).fullname || "").bold();
|
||||
return frappe.utils.get_form_link("User", user, true, user_display_text);
|
||||
}
|
||||
|
||||
get_view_timeline_contents() {
|
||||
let view_timeline_contents = [];
|
||||
(this.doc_info.views || []).forEach((view) => {
|
||||
const view_time = comment_when(view.creation);
|
||||
let view_message = frappe.utils.is_current_user(view.owner)
|
||||
? __("You viewed this {0}", [view_time], "Form timeline")
|
||||
: __(
|
||||
"{0} viewed this {1}",
|
||||
[this.get_user_link(view.owner), view_time],
|
||||
"Form timeline"
|
||||
);
|
||||
const user_link = get_user_link(view.owner);
|
||||
const timeline_content = get_user_message(
|
||||
view.owner,
|
||||
__("You viewed this {0}", [view_time], "Form timeline"),
|
||||
__("{0} viewed this {1}", [user_link, view_time], "Form timeline")
|
||||
);
|
||||
|
||||
view_timeline_contents.push({
|
||||
creation: view.creation,
|
||||
content: view_message,
|
||||
content: timeline_content,
|
||||
hide_timestamp: true,
|
||||
});
|
||||
});
|
||||
|
||||
return view_timeline_contents;
|
||||
}
|
||||
|
||||
|
|
@ -337,7 +332,7 @@ class FormTimeline extends BaseTimeline {
|
|||
(this.doc_info.info_logs || []).forEach((info_log) => {
|
||||
info_timeline_contents.push({
|
||||
creation: info_log.creation,
|
||||
content: `${this.get_user_link(info_log.owner)} ${info_log.content}`,
|
||||
content: `${get_user_link(info_log.owner)} ${info_log.content}`,
|
||||
});
|
||||
});
|
||||
return info_timeline_contents;
|
||||
|
|
@ -345,45 +340,76 @@ class FormTimeline extends BaseTimeline {
|
|||
|
||||
get_attachment_timeline_contents() {
|
||||
let attachment_timeline_contents = [];
|
||||
|
||||
(this.doc_info.attachment_logs || []).forEach((attachment_log) => {
|
||||
let is_file_upload = attachment_log.comment_type == "Attachment";
|
||||
const is_file_upload = attachment_log.comment_type == "Attachment";
|
||||
const user_link = get_user_link(attachment_log.owner);
|
||||
const filename = attachment_log.content;
|
||||
const timeline_content = is_file_upload
|
||||
? get_user_message(
|
||||
attachment_log.owner,
|
||||
__("You attached {0}", [filename], "Form timeline"),
|
||||
__("{0} attached {1}", [user_link, filename], "Form timeline")
|
||||
)
|
||||
: get_user_message(
|
||||
attachment_log.owner,
|
||||
__("You removed attachment {0}", [filename], "Form timeline"),
|
||||
__("{0} removed attachment {1}", [user_link, filename], "Form timeline")
|
||||
);
|
||||
|
||||
attachment_timeline_contents.push({
|
||||
icon: is_file_upload ? "upload" : "delete",
|
||||
icon_size: "sm",
|
||||
creation: attachment_log.creation,
|
||||
content: `${this.get_user_link(attachment_log.owner)} ${attachment_log.content}`,
|
||||
content: timeline_content,
|
||||
});
|
||||
});
|
||||
|
||||
return attachment_timeline_contents;
|
||||
}
|
||||
|
||||
get_milestone_timeline_contents() {
|
||||
let milestone_timeline_contents = [];
|
||||
|
||||
(this.doc_info.milestones || []).forEach((milestone_log) => {
|
||||
const field = frappe.meta.get_label(this.frm.doctype, milestone_log.track_field);
|
||||
const value = milestone_log.value.bold();
|
||||
const user_link = get_user_link(milestone_log.owner);
|
||||
const timeline_content = get_user_message(
|
||||
milestone_log.owner,
|
||||
__("You changed {0} to {1}", [field, value], "Form timeline"),
|
||||
__("{0} changed {1} to {2}", [user_link, field, value], "Form timeline")
|
||||
);
|
||||
|
||||
milestone_timeline_contents.push({
|
||||
icon: "milestone",
|
||||
creation: milestone_log.creation,
|
||||
content: __("{0} changed {1} to {2}", [
|
||||
this.get_user_link(milestone_log.owner),
|
||||
frappe.meta.get_label(this.frm.doctype, milestone_log.track_field),
|
||||
milestone_log.value.bold(),
|
||||
]),
|
||||
content: timeline_content,
|
||||
});
|
||||
});
|
||||
|
||||
return milestone_timeline_contents;
|
||||
}
|
||||
|
||||
get_like_timeline_contents() {
|
||||
let like_timeline_contents = [];
|
||||
|
||||
(this.doc_info.like_logs || []).forEach((like_log) => {
|
||||
const timeline_content = get_user_message(
|
||||
like_log.owner,
|
||||
__("You Liked", null, "Form timeline"),
|
||||
__("{0} Liked", [get_user_link(like_log.owner)], "Form timeline")
|
||||
);
|
||||
|
||||
like_timeline_contents.push({
|
||||
icon: "heart",
|
||||
icon_size: "sm",
|
||||
creation: like_log.creation,
|
||||
content: __("{0} Liked", [this.get_user_link(like_log.owner)]),
|
||||
content: timeline_content,
|
||||
title: "Like",
|
||||
});
|
||||
});
|
||||
|
||||
return like_timeline_contents;
|
||||
}
|
||||
|
||||
|
|
@ -394,7 +420,7 @@ class FormTimeline extends BaseTimeline {
|
|||
icon: "branch",
|
||||
icon_size: "sm",
|
||||
creation: workflow_log.creation,
|
||||
content: `${this.get_user_link(workflow_log.owner)} ${__(workflow_log.content)}`,
|
||||
content: `${get_user_link(workflow_log.owner)} ${__(workflow_log.content)}`,
|
||||
title: "Workflow",
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -30,19 +30,55 @@ function get_version_timeline_content(version_doc, frm) {
|
|||
if (p[0] === "docstatus") {
|
||||
if (p[2] === 1) {
|
||||
let message = updater_reference_link
|
||||
? __("{0} submitted this document {1}", [
|
||||
get_user_link(version_doc),
|
||||
updater_reference_link,
|
||||
])
|
||||
: __("{0} submitted this document", [get_user_link(version_doc)]);
|
||||
? get_user_message(
|
||||
version_doc.owner,
|
||||
__(
|
||||
"You submitted this document {0}",
|
||||
[updater_reference_link],
|
||||
"Form timeline"
|
||||
),
|
||||
__(
|
||||
"{0} submitted this document {1}",
|
||||
[get_user_link(version_doc.owner), updater_reference_link],
|
||||
"Form timeline"
|
||||
)
|
||||
)
|
||||
: get_user_message(
|
||||
version_doc.owner,
|
||||
__("You submitted this document", null, "Form timeline"),
|
||||
__(
|
||||
"{0} submitted this document",
|
||||
[get_user_link(version_doc.owner)],
|
||||
"Form timeline"
|
||||
)
|
||||
);
|
||||
|
||||
out.push(get_version_comment(version_doc, message));
|
||||
} else if (p[2] === 2) {
|
||||
let message = updater_reference_link
|
||||
? __("{0} cancelled this document {1}", [
|
||||
get_user_link(version_doc),
|
||||
updater_reference_link,
|
||||
])
|
||||
: __("{0} cancelled this document", [get_user_link(version_doc)]);
|
||||
? get_user_message(
|
||||
version_doc.owner,
|
||||
__(
|
||||
"You cancelled this document {1}",
|
||||
[updater_reference_link],
|
||||
"Form timeline"
|
||||
),
|
||||
__(
|
||||
"{0} cancelled this document {1}",
|
||||
[get_user_link(version_doc.owner), updater_reference_link],
|
||||
"Form timeline"
|
||||
)
|
||||
)
|
||||
: get_user_message(
|
||||
version_doc.owner,
|
||||
__("You cancelled this document", null, "Form timeline"),
|
||||
__(
|
||||
"{0} cancelled this document",
|
||||
[get_user_link(version_doc.owner)],
|
||||
"Form timeline"
|
||||
)
|
||||
);
|
||||
|
||||
out.push(get_version_comment(version_doc, message));
|
||||
}
|
||||
} else {
|
||||
|
|
@ -67,19 +103,28 @@ function get_version_timeline_content(version_doc, frm) {
|
|||
return parts.length < 3;
|
||||
});
|
||||
if (parts.length) {
|
||||
let message;
|
||||
if (updater_reference_link) {
|
||||
message = __("{0} changed value of {1} {2}", [
|
||||
get_user_link(version_doc),
|
||||
parts.join(", "),
|
||||
updater_reference_link,
|
||||
]);
|
||||
} else {
|
||||
message = __("{0} changed value of {1}", [
|
||||
get_user_link(version_doc),
|
||||
parts.join(", "),
|
||||
]);
|
||||
}
|
||||
let message = updater_reference_link
|
||||
? get_user_message(
|
||||
version_doc.owner,
|
||||
__("You changed the value of {0} {1}", [
|
||||
parts.join(", "),
|
||||
updater_reference_link,
|
||||
]),
|
||||
__("{0} changed the value of {1} {2}", [
|
||||
get_user_link(version_doc.owner),
|
||||
parts.join(", "),
|
||||
updater_reference_link,
|
||||
])
|
||||
)
|
||||
: get_user_message(
|
||||
version_doc.owner,
|
||||
__("You changed the value of {0}", [parts.join(", ")]),
|
||||
__("{0} changed the value of {1}", [
|
||||
get_user_link(version_doc.owner),
|
||||
parts.join(", "),
|
||||
])
|
||||
);
|
||||
|
||||
out.push(get_version_comment(version_doc, message));
|
||||
}
|
||||
}
|
||||
|
|
@ -120,19 +165,28 @@ function get_version_timeline_content(version_doc, frm) {
|
|||
return parts.length < 3;
|
||||
});
|
||||
if (parts.length) {
|
||||
let message;
|
||||
if (updater_reference_link) {
|
||||
message = __("{0} changed values for {1} {2}", [
|
||||
get_user_link(version_doc),
|
||||
parts.join(", "),
|
||||
updater_reference_link,
|
||||
]);
|
||||
} else {
|
||||
message = __("{0} changed values for {1}", [
|
||||
get_user_link(version_doc),
|
||||
parts.join(", "),
|
||||
]);
|
||||
}
|
||||
let message = updater_reference_link
|
||||
? get_user_message(
|
||||
version_doc.owner,
|
||||
__("You changed the values for {0} {1}", [
|
||||
parts.join(", "),
|
||||
updater_reference_link,
|
||||
]),
|
||||
__("{0} changed the values for {1} {2}", [
|
||||
get_user_link(version_doc.owner),
|
||||
parts.join(", "),
|
||||
updater_reference_link,
|
||||
])
|
||||
)
|
||||
: get_user_message(
|
||||
version_doc.owner,
|
||||
__("You changed the values for {0}", [parts.join(", ")]),
|
||||
__("{0} changed the values for {1}", [
|
||||
get_user_link(version_doc.owner),
|
||||
parts.join(", "),
|
||||
])
|
||||
);
|
||||
|
||||
out.push(get_version_comment(version_doc, message));
|
||||
}
|
||||
}
|
||||
|
|
@ -168,7 +222,7 @@ function get_version_timeline_content(version_doc, frm) {
|
|||
}
|
||||
|
||||
let version_comment = get_version_comment(version_doc, message);
|
||||
let user_link = get_user_link(version_doc);
|
||||
let user_link = get_user_link(version_doc.owner);
|
||||
out.push(`${user_link} ${version_comment}`);
|
||||
}
|
||||
}
|
||||
|
|
@ -230,10 +284,13 @@ function format_content_for_timeline(content) {
|
|||
return content.bold();
|
||||
}
|
||||
|
||||
function get_user_link(doc) {
|
||||
const user = doc.owner;
|
||||
function get_user_link(user) {
|
||||
const user_display_text = (frappe.user_info(user).fullname || "").bold();
|
||||
return frappe.utils.get_form_link("User", user, true, user_display_text);
|
||||
}
|
||||
|
||||
export { get_version_timeline_content };
|
||||
function get_user_message(user, message_self, message_other) {
|
||||
return frappe.utils.is_current_user(user) ? message_self : message_other;
|
||||
}
|
||||
|
||||
export { get_version_timeline_content, get_user_link, get_user_message };
|
||||
|
|
|
|||
|
|
@ -728,6 +728,7 @@ class TestDBSetValue(FrappeTestCase):
|
|||
"test_set_value change 1",
|
||||
modified=custom_modified,
|
||||
modified_by=custom_modified_by,
|
||||
update_modified=True,
|
||||
)
|
||||
self.assertTupleEqual(
|
||||
(custom_modified, custom_modified_by),
|
||||
|
|
|
|||
|
|
@ -4727,8 +4727,12 @@ Copy,Kopieren,
|
|||
Hide Saved,Gespeicherte ausblenden,
|
||||
Show Saved,Gespeicherte anzeigen,
|
||||
{0} created this {1},{0} erstellte dies {1},
|
||||
{0} created this,{0} erstellte dies,
|
||||
You created this,Sie erstellten dies,
|
||||
{0} edited this {1},{0} bearbeitete dies {1},
|
||||
You edited this {0},Sie bearbeiteten dies {0},
|
||||
{0} viewed this {1},{0} sah sich dies {1} an,
|
||||
You viewed this {0},Sie sahen sich dies {0} an,
|
||||
Toggle Full Width,Toggle Volle Breite,
|
||||
Documentation,Dokumentation,
|
||||
About,Über,
|
||||
|
|
|
|||
|
|
|
@ -54,19 +54,12 @@ def upload():
|
|||
|
||||
comment = {}
|
||||
if dt and dn:
|
||||
file_url = file_doc.file_url.replace("#", "%23") if file_doc.file_name else file_doc.file_url
|
||||
icon = ' <i class="fa fa-lock text-warning"></i>' if file_doc.is_private else ""
|
||||
file_name = file_doc.file_name or file_doc.file_url
|
||||
comment = frappe.get_doc(dt, dn).add_comment(
|
||||
"Attachment",
|
||||
_("added {0}").format(
|
||||
"<a href='{file_url}' target='_blank'>{file_name}</a>{icon}".format(
|
||||
**{
|
||||
"icon": ' <i class="fa fa-lock text-warning"></i>' if file_doc.is_private else "",
|
||||
"file_url": file_doc.file_url.replace("#", "%23")
|
||||
if file_doc.file_name
|
||||
else file_doc.file_url,
|
||||
"file_name": file_doc.file_name or file_doc.file_url,
|
||||
}
|
||||
)
|
||||
),
|
||||
f"<a href='{file_url}' target='_blank'>{file_name}</a>{icon}",
|
||||
)
|
||||
|
||||
return {
|
||||
|
|
@ -295,7 +288,7 @@ def remove_file(
|
|||
ignore_permissions = True
|
||||
if not file_name:
|
||||
file_name = frappe.db.get_value("File", fid, "file_name")
|
||||
comment = doc.add_comment("Attachment Removed", _("Removed {0}").format(file_name))
|
||||
comment = doc.add_comment("Attachment Removed", file_name)
|
||||
frappe.delete_doc(
|
||||
"File", fid, ignore_permissions=ignore_permissions, delete_permanently=delete_permanently
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue