Browse Source

Fixes in Attachments, User History and File Remove Permission Check

version-14
Anand Doshi 11 years ago
parent
commit
abf0b06823
8 changed files with 118 additions and 106 deletions
  1. +1
    -1
      frappe/core/page/data_import_tool/data_import_tool.js
  2. +1
    -1
      frappe/public/js/frappe/dom.js
  3. +26
    -24
      frappe/public/js/frappe/form/attachments.js
  4. +6
    -6
      frappe/public/js/frappe/form/control.js
  5. +10
    -9
      frappe/public/js/frappe/ui/toolbar/recent.js
  6. +13
    -13
      frappe/public/js/frappe/upload.js
  7. +49
    -49
      frappe/public/js/frappe/views/communication.js
  8. +12
    -3
      frappe/utils/file_manager.py

+ 1
- 1
frappe/core/page/data_import_tool/data_import_tool.js View File

@@ -197,7 +197,7 @@ frappe.pages['data-import-tool'].onload = function(wrapper) {
method: 'frappe.core.page.data_import_tool.importer.upload'
},
onerror: onerror,
callback: function(fid, filename, r) {
callback: function(attachment, r) {
if(r.message.error) {
onerror(r);
} else {


+ 1
- 1
frappe/public/js/frappe/dom.js View File

@@ -221,7 +221,7 @@ frappe.get_cookie = function(c) {
var cookies = {};
for(var i=0;i<clist.length;i++) {
var tmp = clist[i].split('=');
cookies[strip(tmp[0])] = strip(tmp[1]);
cookies[strip(tmp[0])] = strip($.trim(tmp.slice(1).join("=")), "\"");
}
return cookies[c];
}


+ 26
- 24
frappe/public/js/frappe/form/attachments.js View File

@@ -1,5 +1,5 @@
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
// MIT License. See license.txt

frappe.provide("frappe.ui.form");

@@ -22,7 +22,7 @@ frappe.ui.form.Attachments = Class.extend({
max_reached: function() {
// no of attachments
var n = keys(this.get_attachments()).length;
// button if the number of attachments is less than max
if(n < this.frm.meta.max_attachments || !this.frm.meta.max_attachments) {
return false;
@@ -37,13 +37,13 @@ frappe.ui.form.Attachments = Class.extend({
}
this.parent.toggle(true);
this.parent.find(".btn").toggle(!this.max_reached());
this.$list.empty();

var attachments = this.get_attachments();
var that = this;

// add attachment objects
if(attachments.length) {
attachments.forEach(function(attachment) {
@@ -52,7 +52,7 @@ frappe.ui.form.Attachments = Class.extend({
} else {
$('<p class="text-muted">' + __("None") + '</p>').appendTo(this.$list);
}
// refresh select fields with options attach_files:
this.refresh_attachment_select_fields();
},
@@ -66,7 +66,7 @@ frappe.ui.form.Attachments = Class.extend({
if (!file_name) {
file_name = file_url;
}
var me = this;
var $attach = $(repl('<div class="alert alert-info" style="margin-bottom: 7px">\
<span style="display: inline-block; width: 90%; \
@@ -78,7 +78,7 @@ frappe.ui.form.Attachments = Class.extend({
file_url: file_url
}))
.appendTo(this.$list)
var $close =
$attach.find(".close")
.data("fileid", fileid)
@@ -91,7 +91,7 @@ frappe.ui.form.Attachments = Class.extend({
);
return false
});
if(!frappe.model.can_write(this.frm.doctype, this.frm.name)) {
$close.remove();
}
@@ -104,9 +104,9 @@ frappe.ui.form.Attachments = Class.extend({
return frappe.call({
method: 'frappe.widgets.form.utils.remove_attach',
args: {
fid: fileid,
dt: me.frm.doctype,
dn: me.frm.docname
fid: fileid,
dt: me.frm.doctype,
dn: me.frm.docname
},
callback: function(r,rt) {
if(r.exc) {
@@ -128,7 +128,7 @@ frappe.ui.form.Attachments = Class.extend({
});
}
this.dialog.show();
$(this.dialog.body).empty();
frappe.upload.make({
parent: this.dialog.body,
@@ -137,9 +137,10 @@ frappe.ui.form.Attachments = Class.extend({
doctype: this.frm.doctype,
docname: this.frm.docname,
},
callback: function(fileid, filename, file_url, r) {
callback: function(attachment, r) {
me.dialog.hide();
me.update_attachment(fileid, filename, file_url, fieldname, r.message);
me.update_attachment(attachment);
if(fieldname) this.frm.set_value(fieldname, attachment.file_url);
},
onerror: function() {
me.dialog.hide();
@@ -148,19 +149,20 @@ frappe.ui.form.Attachments = Class.extend({
max_height: this.frm.cscript ? this.frm.cscript.attachment_max_height : null,
});
},
update_attachment: function(fileid, filename, fieldname, file_url, attachment) {
if(fileid) {
update_attachment: function(attachment, fieldname) {
if(attachment.name) {
this.add_to_attachments(attachment);
this.refresh();
if(fieldname) {
this.frm.set_value(fieldname, file_url);
this.frm.cscript[fieldname] && this.frm.cscript[fieldname](this.frm.doc);
this.frm.toolbar.show_infobar();
}
this.frm.toolbar.show_infobar();
}
},
add_to_attachments: function (attachment) {
this.get_attachments().push(attachment);
var form_attachments = this.get_attachments();
for(var i in form_attachments) {
// prevent duplicate
if(form_attachments[i]["name"] === attachment.name) return;
}
form_attachments.push(attachment);
},
remove_fileid: function(fileid) {
var attachments = this.get_attachments();
@@ -178,12 +180,12 @@ frappe.ui.form.Attachments = Class.extend({
if(this.frm.fields[i].df.options=="attach_files:" && this.frm.fields[i].$input) {
var fieldname = this.frm.fields[i].df.fieldname;
var selected_option = this.frm.fields[i].$input.find("option:selected").val();
if(this.frm.doc[fieldname]!=null && selected_option!==this.frm.doc[fieldname]) {
this.frm.script_manager.trigger(fieldname);
this.frm.set_value(fieldname, "");
}
this.frm.fields[i].refresh();
}
}


+ 6
- 6
frappe/public/js/frappe/form/control.js View File

@@ -587,9 +587,9 @@ frappe.ui.form.ControlAttach = frappe.ui.form.ControlData.extend({
args: {},
max_width: this.df.max_width,
max_height: this.df.max_height,
callback: function(fileid, filename, r) {
callback: function(attachment, r) {
me.dialog.hide();
me.on_upload_complete(fileid, filename, r);
me.on_upload_complete(attachment);
},
onerror: function() {
me.dialog.hide();
@@ -639,11 +639,11 @@ frappe.ui.form.ControlAttach = frappe.ui.form.ControlData.extend({
}
},

on_upload_complete: function(fileid, filename, r) {
on_upload_complete: function(attachment) {
if(this.frm) {
this.parse_validate_and_set_in_model(filename);
this.parse_validate_and_set_in_model(attachment.file_url);
this.refresh();
this.frm.attachments.update_attachment(fileid, filename, this.df.fieldname, r);
this.frm.attachments.update_attachment(attachment);
} else {
this.set_input(this.fileobj.filename, this.dataurl);
this.refresh();
@@ -712,7 +712,7 @@ frappe.ui.form.ControlSelect = frappe.ui.form.ControlData.extend({
})
.prependTo(this.input_area);

$(document).on("upload_complete", function(event, filename, file_url) {
$(document).on("upload_complete", function(event, attachment) {
if(cur_frm === me.frm) {
me.set_options();
}


+ 10
- 9
frappe/public/js/frappe/ui/toolbar/recent.js View File

@@ -1,5 +1,5 @@
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
// MIT License. See license.txt

// recent document list
frappe.ui.toolbar.RecentDocs = Class.extend({
@@ -13,7 +13,7 @@ frappe.ui.toolbar.RecentDocs = Class.extend({
this.setup();
this.bind_events();
},
bind_events: function() {
bind_events: function() {
// notify on rename
var me = this;
$(document).bind('rename', function(event, dt, old_name, new_name) {
@@ -26,14 +26,15 @@ frappe.ui.toolbar.RecentDocs = Class.extend({
},
add: function(dt, dn, on_top) {
if(this.istable(dt)) return;
this.remove(dt, dn);
var html = repl('<li data-docref="%(dt)s/%(dn)s">\
<a href="#Form/%(dt)s/%(dn)s">\
<a href="#Form/%(dt_encoded)s/%(dn_encoded)s">\
<i class="icon-fixed-width %(icon)s"></i> \
%(dn)s</span>\
</a></li>',
{dt:dt, dn:dn, icon:frappe.boot.doctype_icons[dt]});
</a></li>',
{dt_encoded:encodeURIComponent(dt), dn_encoded:encodeURIComponent(dn),
dt: dt, dn: dn, icon:frappe.boot.doctype_icons[dt]});
if(on_top) {
$('#toolbar-recent').prepend(html);
} else {
@@ -44,7 +45,7 @@ frappe.ui.toolbar.RecentDocs = Class.extend({
return locals.DocType[dt] && locals.DocType[dt].istable || false;
},
remove: function(dt, dn) {
$(repl('#toolbar-recent li[data-docref="%(dt)s/%(dn)s"]', {dt:dt, dn:dn})).remove();
$(repl('#toolbar-recent li[data-docref="%(dt)s/%(dn)s"]', {dt:dt, dn:dn})).remove();
},
setup: function() {
// add menu items
@@ -63,6 +64,6 @@ frappe.ui.toolbar.RecentDocs = Class.extend({
// don't crash
}
}
}
}
}
});
});

+ 13
- 13
frappe/public/js/frappe/upload.js View File

@@ -6,7 +6,7 @@ frappe.upload = {
make: function(opts) {
if(!opts.args) opts.args = {};
var $upload = $('<div class="file-upload">\
<p class="small"><a class="action-attach disabled" href="#"><i class="icon-upload"></i> '
<p class="small"><a class="action-attach disabled" href="#"><i class="icon-upload"></i> '
+ __('Upload a file') + '</a> | <a class="action-link" href="#"><i class="icon-link"></i> '
+ __('Attach as web link') + '</a></p>\
<div class="action-attach-input">\
@@ -14,13 +14,13 @@ frappe.upload = {
</div>\
<div class="action-link-input" style="display: none; margin-top: 7px;">\
<input class="form-control" style="max-width: 300px;" type="text" name="file_url" />\
<p class="text-muted">'
+ (opts.sample_url || 'e.g. http://example.com/somefile.png') +
<p class="text-muted">'
+ (opts.sample_url || 'e.g. http://example.com/somefile.png') +
'</p>\
</div>\
<button class="btn btn-info btn-upload"><i class="icon-upload"></i> ' +__('Upload')
+'</button></div>').appendTo(opts.parent);

$upload.find(".action-link").click(function() {
$upload.find(".action-attach").removeClass("disabled");
@@ -47,7 +47,7 @@ frappe.upload = {
if(typeof val==="function")
opt.args[key] = opts.args[key]();
}
// add other inputs in the div as arguments
opts.args.params = {};
$upload.find("input[name]").each(function() {
@@ -57,11 +57,11 @@ frappe.upload = {
if(type === "checkbox") {
opts.args.params[key] = $(this).is(":checked");
} else {
opts.args.params[key] = $(this).val();
opts.args.params[key] = $(this).val();
}
}
})
opts.args.file_url = $upload.find('[name="file_url"]').val();

var fileobj = $upload.find(":file").get(0).files[0];
@@ -73,7 +73,7 @@ frappe.upload = {
msgprint(__("Please attach a file or set a URL"));
return;
}
var dataurl = null;
var _upload_file = function() {
if(opts.on_attach) {
@@ -91,14 +91,14 @@ frappe.upload = {
opts.onerror ? opts.onerror(r) : opts.callback(null, null, r);
return;
}
opts.callback(r.message.name , r.message.file_name, r.message.file_url, r);
$(document).trigger("upload_complete",
[r.message.name , r.message.file_name]);
var attachment = r.message;
opts.callback(attachment, r);
$(document).trigger("upload_complete", attachment);
}
});
}
}
if(args.file_url) {
_upload_file();
} else {
@@ -119,7 +119,7 @@ frappe.upload = {
_upload_file();
}
};
freader.readAsDataURL(fileobj);
}
}


+ 49
- 49
frappe/public/js/frappe/views/communication.js View File

@@ -6,15 +6,15 @@ frappe.views.CommunicationList = Class.extend({
init: function(opts) {
this.comm_list = [];
$.extend(this, opts);
if(this.doc.__islocal) {
$(this.parent).empty();
return;
}
if(!this.list)
this.list = frappe.get_list("Communication", {"parenttype": this.doc.doctype, "parent": this.doc.name});
var sortfn = function (a, b) { return (b.creation > a.creation) ? 1 : -1; }
this.list = this.list.sort(sortfn);

@@ -28,22 +28,22 @@ frappe.views.CommunicationList = Class.extend({
$.each(this.list, function(i, d) {
me.prepare(d);
me.make_line(d);
});
});
// show first
this.comm_list[0].find('.comm-content').toggle(true);
this.comm_list[0].find('.comm-content').toggle(true);
} else {
this.clear_list()
}
},
clear_list: function() {
this.body.remove();
$("<p class='text-muted'>" + __("No Communication tagged with this ")
+ this.doc.doctype +" yet.</p>").appendTo(this.wrapper);
$("<p class='text-muted'>" + __("No Communication tagged with this ")
+ this.doc.doctype +" yet.</p>").appendTo(this.wrapper);
},
make_body: function() {
$(this.parent)
.empty()
this.wrapper = $("<div>\
<div style='margin-bottom: 8px;'>\
<button class='btn btn-default' \
@@ -51,12 +51,12 @@ frappe.views.CommunicationList = Class.extend({
<i class='icon-plus'></i> "+__("Add Message")+"</button></div>\
</div>")
.appendTo(this.parent);
this.body = $('<div class="list-group">')
.css({"border":"1px solid #dddddd", "border-radius":"4px"})
.appendTo(this.wrapper);
},
add_reply: function() {
var subject = this.doc.subject;
if(!subject && this.list.length) {
@@ -87,7 +87,7 @@ frappe.views.CommunicationList = Class.extend({
doc.content = doc.content.split("-----"+__("In response to")+"-----")[0];
doc.content = doc.content.split("-----"+__("Original Message")+"-----")[0];
},
make_line: function(doc) {
var me = this;
doc.icon = {
@@ -111,17 +111,17 @@ frappe.views.CommunicationList = Class.extend({
</div>\
</td></tr>', doc))
.appendTo(this.body);
if(!doc.name) {
comm.find(".show-details").toggle(false);
}
comm.find(".comm-header")
.css({"cursor":"pointer"})
.click(function() {
$(this).parent().find(".comm-content").toggle();
});
this.comm_list.push(comm);
comm.find(".comm-content .inner").html(doc.content);
}
@@ -139,21 +139,21 @@ frappe.views.CommunicationComposer = Class.extend({
title: __("Add Reply") + ": " + (this.subject || ""),
no_submit_on_enter: true,
fields: [
{label:__("To"), fieldtype:"Data", reqd: 1, fieldname:"recipients",
{label:__("To"), fieldtype:"Data", reqd: 1, fieldname:"recipients",
description:__("Email addresses, separted by commas")},
{label:__("Subject"), fieldtype:"Data", reqd: 1,
{label:__("Subject"), fieldtype:"Data", reqd: 1,
fieldname:"subject"},
{label:__("Message"), fieldtype:"Text Editor", reqd: 1,
{label:__("Message"), fieldtype:"Text Editor", reqd: 1,
fieldname:"content"},
{label:__("Send As Email"), fieldtype:"Check",
fieldname:"send_email"},
{label:__("Communication Medium"), fieldtype:"Select",
{label:__("Communication Medium"), fieldtype:"Select",
options: ["Phone", "Chat", "Email", "SMS", "Visit", "Other"],
fieldname:"communication_medium"},
{label:__("Sent or Received"), fieldtype:"Select",
{label:__("Sent or Received"), fieldtype:"Select",
options: ["Received", "Sent"],
fieldname:"sent_or_received"},
{label:__("Send"), fieldtype:"Button",
{label:__("Send"), fieldtype:"Button",
fieldname:"send"},
{label:__("Send Me A Copy"), fieldtype:"Check",
fieldname:"send_me_a_copy"},
@@ -168,8 +168,8 @@ frappe.views.CommunicationComposer = Class.extend({

this.dialog.$wrapper.find("[data-edit='outdent']").remove();
this.dialog.get_input("send").addClass("btn-primary");
$(document).on("upload_complete", function(event, filename, fileurl) {
$(document).on("upload_complete", function(event, attachment) {
if(me.dialog.display) {
var wrapper = $(me.dialog.fields_dict.select_attachments.wrapper);

@@ -177,13 +177,13 @@ frappe.views.CommunicationComposer = Class.extend({
var checked_items = wrapper.find('[data-file-name]:checked').map(function() {
return $(this).attr("data-file-name");
});
// reset attachment list
me.setup_attach();
// check latest added
checked_items.push(filename);
checked_items.push(attachment.file_name);
$.each(checked_items, function(i, filename) {
wrapper.find('[data-file-name="'+ filename +'"]').prop("checked", true);
});
@@ -203,7 +203,7 @@ frappe.views.CommunicationComposer = Class.extend({
setup_print: function() {
// print formats
var fields = this.dialog.fields_dict;
// toggle print format
$(fields.attach_document_print.input).click(function() {
$(fields.select_print_format.wrapper).toggle($(this).prop("checked"));
@@ -215,12 +215,12 @@ frappe.views.CommunicationComposer = Class.extend({
.empty()
.add_options(cur_frm.print_formats)
.val(cur_frm.print_formats[0]);
},
setup_attach: function() {
var fields = this.dialog.fields_dict;
var attach = $(fields.select_attachments.wrapper);
var files = cur_frm.get_files();
if(files.length) {
$("<p><b>"+__("Add Attachments")+":</b></p>").appendTo(attach.empty());
@@ -234,13 +234,13 @@ frappe.views.CommunicationComposer = Class.extend({
// email
var me = this;
var fields = this.dialog.fields_dict;
if(this.attach_document_print) {
$(fields.send_me_a_copy.input).click();
$(fields.attach_document_print.input).click();
$(fields.select_print_format.wrapper).toggle(true);
}
$(fields.send_email.input).prop("checked", true)

// toggle print format
@@ -258,12 +258,12 @@ frappe.views.CommunicationComposer = Class.extend({
var btn = this;
var form_values = me.dialog.get_values();
if(!form_values) return;
var selected_attachments = $.map($(me.dialog.wrapper)
.find("[data-file-name]:checked"), function(element) {
return $(element).attr("data-file-name");
})
if(form_values.attach_document_print) {
_p.build(form_values.select_print_format || "", function(print_format_html) {
me.send_email(btn, form_values, selected_attachments, print_format_html);
@@ -273,10 +273,10 @@ frappe.views.CommunicationComposer = Class.extend({
}
});
},
send_email: function(btn, form_values, selected_attachments, print_html) {
var me = this;
if(!form_values.attach_document_print) {
print_html = "";
}
@@ -286,11 +286,11 @@ frappe.views.CommunicationComposer = Class.extend({
msgprint(__("You are not allowed to send emails related to this document"));
return;
}
form_values.communication_medium = "Email";
form_values.sent_or_received = "Sent";
};
return frappe.call({
method:"frappe.core.doctype.communication.communication.make",
args: {
@@ -320,29 +320,29 @@ frappe.views.CommunicationComposer = Class.extend({
}
});
},
setup_earlier_reply: function() {
var fields = this.dialog.fields_dict;
var comm_list = cur_frm.communication_view
? cur_frm.communication_view.list
: [];
var signature = frappe.boot.user.email_signature || "";
if(!frappe.utils.is_html(signature)) {
signature = signature.replace(/\n/g, "<br>");
}
if(this.real_name) {
this.message = '<p>'+__('Dear') +' ' + this.real_name + ",</p>" + (this.message || "");
}
var reply = (this.message || "")
var reply = (this.message || "")
+ "<p></p>" + signature;
if(comm_list.length > 0) {
fields.content.set_input(reply
+ "<p></p>"
+"-----"+__("In response to")+"-----<p></p>"
+"-----"+__("In response to")+"-----<p></p>"
+ comm_list[0].content);
} else {
fields.content.set_input(reply);
@@ -364,15 +364,15 @@ frappe.views.CommunicationComposer = Class.extend({
$(this).data( "autocomplete" ).menu.active ) {
event.preventDefault();
}
})
})
.autocomplete({
source: function(request, response) {
return frappe.call({
method:'frappe.utils.email_lib.get_contact_list',
args: {
'select': "email_id",
'from': "Contact",
'where': "email_id",
'select': "email_id",
'from': "Contact",
'where': "email_id",
'txt': extractLast(request.term).value || '%'
},
callback: function(r) {
@@ -397,7 +397,7 @@ frappe.views.CommunicationComposer = Class.extend({
this.value = terms.join( ", " );
return false;
}
});
});
}
});


+ 12
- 3
frappe/utils/file_manager.py View File

@@ -167,13 +167,22 @@ def remove_all(dt, dn):
try:
for fid in frappe.db.sql_list("""select name from `tabFile Data` where
attached_to_doctype=%s and attached_to_name=%s""", (dt, dn)):
remove_file(fid)
remove_file(fid, dt, dn)
except Exception, e:
if e.args[0]!=1054: raise # (temp till for patched)

def remove_file(fid):
def remove_file(fid, attached_to_doctype=None, attached_to_name=None):
"""Remove file and File Data entry"""
frappe.delete_doc("File Data", fid)
if not (attached_to_doctype and attached_to_name):
attached = frappe.db.get_value("File Data", fid, ["attached_to_doctype", "attached_to_name"])
if attached:
attached_to_doctype, attached_to_name = attached

ignore_permissions = False
if attached_to_doctype and attached_to_name:
ignore_permissions = frappe.get_doc(attached_to_doctype, attached_to_name).has_permission("write") or False

frappe.delete_doc("File Data", fid, ignore_permissions=ignore_permissions)

def delete_file_data_content(doc):
method = get_hook_method('delete_file_data_content', fallback=delete_file_from_filesystem)


Loading…
Cancel
Save