diff --git a/frappe/public/css/form.css b/frappe/public/css/form.css index 1b14e969bf..b3ca3d9d56 100644 --- a/frappe/public/css/form.css +++ b/frappe/public/css/form.css @@ -22,7 +22,7 @@ .form-clickable-section { border-top: 1px solid #d1d8dd; padding: 10px 15px; - background-color: #F7FAFC; + background-color: #f7fafc; } .form-page.second-page { border-top: 1px solid #d1d8dd; @@ -33,7 +33,7 @@ .document-flow-wrapper { padding: 40px 15px 30px; font-size: 12px; - border-bottom: 1px solid #EBEFF2; + border-bottom: 1px solid #ebeff2; } .document-flow-wrapper .document-flow { display: inline-block; @@ -80,7 +80,7 @@ } .form-dashboard-section { padding: 15px 30px; - border-bottom: 1px solid #EBEFF2; + border-bottom: 1px solid #ebeff2; } .form-dashboard-section:last-child { border-bottom: none; @@ -126,7 +126,7 @@ border-radius: 0px 3px 3px 0px; } .inline-graph .inline-graph-half .inline-graph-bar-inner.dark { - background-color: #36414C; + background-color: #36414c; } .inline-graph .inline-graph-half:first-child { border-right: 1px solid #d1d8dd; @@ -158,7 +158,7 @@ h6.uppercase, font-weight: normal; letter-spacing: 0.4px; text-transform: uppercase; - color: #8D99A6; + color: #8d99a6; } .form-section { margin: 0px; @@ -188,7 +188,7 @@ h6.uppercase, } .form-section:not(:last-child), .form-inner-toolbar { - border-bottom: 1px solid #EBEFF2; + border-bottom: 1px solid #ebeff2; } .empty-section { display: none !important; @@ -269,8 +269,8 @@ h6.uppercase, background-color: #fafbfc; padding: 7px 15px; margin: 0px; - color: #8D99A6; - border-bottom: 1px solid #EBEFF2; + color: #8d99a6; + border-bottom: 1px solid #ebeff2; } .timeline-item.user-content .comment-header .octicon-heart { color: #ff5858; @@ -286,7 +286,23 @@ h6.uppercase, margin-bottom: 0px; } .timeline-item.user-content .close-btn-container { - padding: 2px 15px; + padding: 2px 10px 2px 5px; +} +.timeline-item.user-content .edit-btn-container { + padding: 2px 5px; +} +.timeline-item.user-content .edit-btn-container .edit { + color: inherit; + font-size: 21px; + line-height: 1; +} +.timeline-item.user-content .edit-btn-container .edit .octicon-check { + color: #98d85b; + font-size: 1em; +} +.timeline-item.user-content .edit-btn-container .edit:hover, +.timeline-item.user-content .edit-btn-container .edit:focus { + color: #000; } .timeline-item.user-content .comment-likes { margin-left: 5px; @@ -318,10 +334,10 @@ h6.uppercase, padding-left: 30px; margin: 30px 0px; position: relative; - color: #8D99A6; + color: #8d99a6; } .timeline-item.notification-content * { - color: #8D99A6; + color: #8d99a6; } .timeline-item.notification-content .fa-fw { margin-left: 36px; @@ -356,7 +372,7 @@ h6.uppercase, .timeline-head .comment-input-header { background-color: #fafbfc; padding: 7px 15px; - border-bottom: 1px solid #EBEFF2; + border-bottom: 1px solid #ebeff2; } .timeline-head .comment-input-container { padding: 15px; @@ -365,7 +381,7 @@ h6.uppercase, min-width: 200px; } .timeline-head .comment-input { - border-color: #EBEFF2; + border-color: #ebeff2; max-width: 100%; } .timeline-head .comment-input:focus { @@ -399,7 +415,7 @@ h6.uppercase, } .control-label, .grid-heading-row { - color: #8D99A6; + color: #8d99a6; font-size: 12px; } .control-label { @@ -472,7 +488,7 @@ select.form-control { margin-top: -3px; margin-left: 1px; font-weight: 500; - color: #8D99A6; + color: #8d99a6; } @media (min-width: 768px) { .layout-main .form-column.col-sm-12 > form > .input-max-width { @@ -497,7 +513,7 @@ select.form-control { padding: 15px 15px 15px 0px; } .form-column { - border-bottom: 1px solid #EBEFF2; + border-bottom: 1px solid #ebeff2; } .form-column:last-child { border-bottom: 0px; @@ -518,7 +534,7 @@ select.form-control { } .frappe-control.form-page { padding: 7px 15px; - border-bottom: 1px solid #EBEFF2; + border-bottom: 1px solid #ebeff2; margin: 0px -15px; } .frappe-control.form-page .link-btn { diff --git a/frappe/public/js/frappe/form/footer/timeline.js b/frappe/public/js/frappe/form/footer/timeline.js index 84c24847d1..64405dac95 100644 --- a/frappe/public/js/frappe/form/footer/timeline.js +++ b/frappe/public/js/frappe/form/footer/timeline.js @@ -129,8 +129,39 @@ frappe.ui.form.Timeline = Class.extend({ var $timeline_item = $(frappe.render_template("timeline_item", {data:c})) .appendTo(me.list) .on("click", ".close", function() { - var name = $(this).parents(".timeline-item:first").attr("data-name"); + var name = $timeline_item.data('name'); me.delete_comment(name); + + return false; + }) + .on('click', '.edit', function() { + var is_editing = 'is-editing'; + var content = $timeline_item.find('.timeline-item-content'); + var name = $timeline_item.data('name'); + + if(content.hasClass(is_editing)) { + var val = content.find('textarea').val(); + // set content to new val so that on save and refresh the new content is shown + c.content = val; + + frappe.timeline.update_communication(c); + me.update_comment(name, val); + + // all changes to the timeline_item for editing are reset after calling refresh + me.refresh(); + } else { + var $edit_btn = $(this); + var editing_textarea = me.input.clone() + .removeClass('comment-input'); + + frappe.db.get_value('Communication', {name: name}, 'content', function(r) { + $edit_btn.find('i').removeClass('octicon-pencil').addClass('octicon-check'); + editing_textarea.val(r.content); + content.html(editing_textarea); + content.addClass(is_editing); + }); + } + return false; }); @@ -167,12 +198,6 @@ frappe.ui.form.Timeline = Class.extend({ }, prepare_timeline_item: function(c) { - if(c.communication_type=="Comment" && (c.comment_type || "Comment") === "Comment" && frappe.model.can_delete("Communication")) { - c["delete"] = ''; - } else { - c["delete"] = ""; - } - if(!c.sender) c.sender = this.frm.doc.owner; if(c.sender && c.sender.indexOf("<")!==-1) { @@ -185,6 +210,18 @@ frappe.ui.form.Timeline = Class.extend({ c.user_info = frappe.user_info(c.owner); } + c["delete"] = ""; + c["edit"] = ""; + if(c.communication_type=="Comment" && (c.comment_type || "Comment") === "Comment") { + if(frappe.model.can_delete("Communication")) { + c["delete"] = ''; + } + + if(frappe.user.name == c.sender || (frappe.user.name == 'Administrator')) { + c["edit"] = ''; + } + } + c.comment_on = comment_when(c.creation); c.fullname = c.sender_full_name || frappe.user.full_name(c.sender); @@ -429,25 +466,52 @@ frappe.ui.form.Timeline = Class.extend({ delete_comment: function(name) { var me = this; - return frappe.call({ - method: "frappe.client.delete", - args: { - doctype: "Communication", - name: name - }, - callback: function(r) { - if(!r.exc) { - frappe.utils.play_sound("delete"); - me.frm.get_docinfo().communications = - $.map(me.frm.get_docinfo().communications, - function(v) { - if(v.name==name) return null; - else return v; - } - ); - me.refresh(true); + frappe.confirm(__('Delete comment?'), function() { + return frappe.call({ + method: "frappe.client.delete", + args: { + doctype: "Communication", + name: name + }, + callback: function(r) { + if(!r.exc) { + frappe.utils.play_sound("delete"); + + me.frm.get_docinfo().communications = + $.map(me.frm.get_docinfo().communications, + function(v) { + if(v.name==name) return null; + else return v; + } + ); + me.refresh(true); + } } + }); + }); + }, + + /** + * Update comment + * + * @param {string} name + * @param {string} content + * + * @returns {boolean} + */ + update_comment: function(name, content) + { + // TODO: is there a frappe.client.update function? + return frappe.call({ + method: 'frappe.client.set_value', + args: { + doctype: 'Communication', + name: name, + fieldname: 'content', + value: content, + }, callback: function(r) { + frappe.utils.play_sound('click'); } }); }, diff --git a/frappe/public/js/frappe/form/footer/timeline_item.html b/frappe/public/js/frappe/form/footer/timeline_item.html index 3ff038991e..1bc5df9081 100755 --- a/frappe/public/js/frappe/form/footer/timeline_item.html +++ b/frappe/public/js/frappe/form/footer/timeline_item.html @@ -17,9 +17,15 @@ {%= data.delete %} +
+ + {%= data.edit %} + +
{% if(data.communication_type==="Communication" || (data.communication_type==="Comment" && data.comment_type==="Comment")) { %} +
{%= data.fullname %} @@ -89,6 +95,7 @@ {%= data.content_html %}
+ {% } else if(in_list(["Assignment Completed", "Assigned", "Shared", "Unshared"], data.comment_type)) { %}
diff --git a/frappe/public/less/form.less b/frappe/public/less/form.less index 6a6e028b58..6278d288aa 100644 --- a/frappe/public/less/form.less +++ b/frappe/public/less/form.less @@ -370,7 +370,26 @@ h6.uppercase, .h6.uppercase { } .close-btn-container { - padding: 2px 15px; + padding: 2px 10px 2px 5px; + } + + .edit-btn-container { + padding: 2px 5px; + + .edit { + color: inherit; + font-size: 21px; + line-height: 1; + + .octicon-check { + color: #98d85b; + font-size: 1em; + } + + &:hover, &:focus { + color: #000; + } + } } .comment-likes { @@ -390,15 +409,15 @@ h6.uppercase, .h6.uppercase { .media-body:after { border-color: rgba(136, 183, 213, 0); - border-right-color: #fafbfc; - border-width: 6px; - margin-top: -6px; + border-right-color: #fafbfc; + border-width: 6px; + margin-top: -6px; } .media-body:before { border-color: rgba(194, 225, 245, 0); - border-right-color: @border-color; - border-width: 7px; - margin-top: -7px; + border-right-color: @border-color; + border-width: 7px; + margin-top: -7px; } } @@ -430,20 +449,20 @@ h6.uppercase, .h6.uppercase { } .timeline-indicator() { - content: " "; - width: 7px; - height: 7px; - background-color: @border-color; + content: " "; + width: 7px; + height: 7px; + background-color: @border-color; // background-color: white; // border: 1px solid @border-color; - position: absolute; - left: 40px; - border-radius: 50%; - top: 5px; + position: absolute; + left: 40px; + border-radius: 50%; + top: 5px; } .timeline-item.notification-content::before { - .timeline-indicator(); + .timeline-indicator(); } .timeline-item .reply-link {