@@ -141,7 +141,7 @@ class File(NestedSet): | |||||
def check_folder_is_empty(self): | def check_folder_is_empty(self): | ||||
"""Throw exception if folder is not empty""" | """Throw exception if folder is not empty""" | ||||
if frappe.get_all("File", {"folder": self.name}): | |||||
if self.is_folder and frappe.get_all("File", filters={"folder": self.name}): | |||||
frappe.throw(_("Folder {0} is not empty").format(self.name)) | frappe.throw(_("Folder {0} is not empty").format(self.name)) | ||||
def check_reference_doc_permission(self): | def check_reference_doc_permission(self): | ||||
@@ -31,7 +31,11 @@ frappe.listview_settings['File'] = { | |||||
doclist.breadcrumb = $('<ol class="breadcrumb for-file-list"></ol>') | doclist.breadcrumb = $('<ol class="breadcrumb for-file-list"></ol>') | ||||
.insertBefore(doclist.filter_area); | .insertBefore(doclist.filter_area); | ||||
doclist.page.add_menu_item(__("Create Folder"), function() { | |||||
doclist.listview.settings.setup_new_folder(doclist); | |||||
doclist.listview.settings.setup_dragdrop(doclist); | |||||
}, | |||||
setup_new_folder: function(doclist) { | |||||
doclist.page.add_menu_item(__("New Folder"), function() { | |||||
var d = frappe.prompt(__("Name"), function(values) { | var d = frappe.prompt(__("Name"), function(values) { | ||||
if((values.value.indexOf("/") > -1)){ | if((values.value.indexOf("/") > -1)){ | ||||
frappe.throw("Folder name should not include / !!!") | frappe.throw("Folder name should not include / !!!") | ||||
@@ -39,17 +43,31 @@ frappe.listview_settings['File'] = { | |||||
} | } | ||||
var data = { | var data = { | ||||
"file_name": values.value, | "file_name": values.value, | ||||
"folder":doclist.current_folder | |||||
"folder": doclist.current_folder | |||||
}; | }; | ||||
frappe.call({ | frappe.call({ | ||||
method:"frappe.core.doctype.file.file.create_new_folder", | |||||
args: data, | |||||
callback:function(r){ | |||||
} | |||||
method: "frappe.core.doctype.file.file.create_new_folder", | |||||
args: data, | |||||
callback: function(r) { } | |||||
}) | }) | ||||
}, __('Enter folder name'), __("Create")); | }, __('Enter folder name'), __("Create")); | ||||
}); | }); | ||||
}, | }, | ||||
setup_dragdrop: function(doclist) { | |||||
$(doclist.$page).on('dragenter dragover', false) | |||||
.on('drop', function (e) { | |||||
var dataTransfer = e.originalEvent.dataTransfer; | |||||
if (!(dataTransfer && dataTransfer.files && dataTransfer.files.length > 0)) { | |||||
return; | |||||
} | |||||
e.stopPropagation(); | |||||
e.preventDefault(); | |||||
frappe.upload.upload_file(dataTransfer.files[0], { | |||||
"folder": doclist.current_folder, | |||||
"from_form": 1 | |||||
}, {}); | |||||
}); | |||||
}, | |||||
before_run: function(doclist) { | before_run: function(doclist) { | ||||
var name_filter = doclist.filter_list.get_filter("file_name"); | var name_filter = doclist.filter_list.get_filter("file_name"); | ||||
if(name_filter) { | if(name_filter) { | ||||
@@ -88,13 +106,18 @@ frappe.listview_settings['File'] = { | |||||
frappe.utils.set_title(doclist.current_folder_name); | frappe.utils.set_title(doclist.current_folder_name); | ||||
}, | }, | ||||
set_primary_action:function(doclist){ | set_primary_action:function(doclist){ | ||||
doclist.page.clear_primary_action(); | doclist.page.clear_primary_action(); | ||||
doclist.page.set_primary_action(__("New"), function() { | doclist.page.set_primary_action(__("New"), function() { | ||||
dialog = frappe.ui.get_upload_dialog({ | dialog = frappe.ui.get_upload_dialog({ | ||||
"data":{"folder": doclist.current_folder, "from_form": 1} | |||||
}) | |||||
"args": { | |||||
"folder": doclist.current_folder, | |||||
"from_form": 1 | |||||
}, | |||||
callback: function() { | |||||
console.log('here') | |||||
doclist.refresh(); | |||||
} | |||||
}); | |||||
}, "octicon octicon-plus"); | }, "octicon octicon-plus"); | ||||
}, | }, | ||||
post_render_item: function(list, row, data) { | post_render_item: function(list, row, data) { | ||||
@@ -146,10 +146,12 @@ frappe.ui.form.Attachments = Class.extend({ | |||||
new_attachment: function(fieldname) { | new_attachment: function(fieldname) { | ||||
var me = this; | var me = this; | ||||
if(!this.dialog){ | if(!this.dialog){ | ||||
this.dialog = frappe.ui.get_upload_dialog({"data": me.get_args(), | |||||
"callback": me.attachment_uploaded, "curr": me, | |||||
"max_width": me.frm.cscript ? me.frm.cscript.attachment_max_width : null, | |||||
"max_height": me.frm.cscript ? me.frm.cscript.attachment_max_height : null}); | |||||
this.dialog = frappe.ui.get_upload_dialog({ | |||||
"args": me.get_args(), | |||||
"callback": me.attachment_uploaded, "curr": me, | |||||
"max_width": me.frm.cscript ? me.frm.cscript.attachment_max_width : null, | |||||
"max_height": me.frm.cscript ? me.frm.cscript.attachment_max_height : null | |||||
}); | |||||
} | } | ||||
}, | }, | ||||
get_args: function() { | get_args: function() { | ||||
@@ -203,25 +205,29 @@ frappe.ui.get_upload_dialog = function(opts){ | |||||
title: __('Upload Attachment'), | title: __('Upload Attachment'), | ||||
}); | }); | ||||
var btn = dialog.set_primary_action(__("Attach")); | |||||
btn.removeClass("btn-primary").addClass("btn-default"); | |||||
dialog.show(); | dialog.show(); | ||||
$(dialog.body).empty(); | $(dialog.body).empty(); | ||||
frappe.upload.make({ | frappe.upload.make({ | ||||
parent: dialog.body, | parent: dialog.body, | ||||
args: opts.data, | |||||
args: opts.args, | |||||
callback: function(attachment, r) { | callback: function(attachment, r) { | ||||
dialog.hide(); | |||||
if(opts.callback){ | if(opts.callback){ | ||||
opts.callback.call(opts.curr, attachment, r); | |||||
} | |||||
else{ | |||||
dialog.hide(); | |||||
opts.callback(attachment, r); | |||||
} | } | ||||
}, | }, | ||||
on_select: function() { | |||||
btn.removeClass("btn-default").addClass("btn-primary"); | |||||
}, | |||||
onerror: function() { | onerror: function() { | ||||
dialog.hide(); | dialog.hide(); | ||||
}, | }, | ||||
btn: dialog.set_primary_action(__("Attach")), | |||||
btn: btn, | |||||
max_width: opts.max_width, | max_width: opts.max_width, | ||||
max_height: opts.max_height, | max_height: opts.max_height, | ||||
}); | }); | ||||
@@ -48,13 +48,18 @@ $(document).on("save", function(event, doc) { | |||||
frappe.views.set_list_as_dirty = function(doctype) { | frappe.views.set_list_as_dirty = function(doctype) { | ||||
var list_page = "List/" + doctype; | var list_page = "List/" + doctype; | ||||
if(frappe.pages[list_page]) { | if(frappe.pages[list_page]) { | ||||
if(frappe.pages[list_page].doclistview) | |||||
if(frappe.pages[list_page].doclistview) { | |||||
if(frappe.pages[list_page].doclistview.dirty) { | |||||
// already refreshing... | |||||
return; | |||||
} | |||||
frappe.pages[list_page].doclistview.dirty = true; | frappe.pages[list_page].doclistview.dirty = true; | ||||
} | |||||
} | } | ||||
var route = frappe.get_route(); | var route = frappe.get_route(); | ||||
if(route[0]==="List" && route[1]===doctype) { | if(route[0]==="List" && route[1]===doctype) { | ||||
setTimeout(function() { | setTimeout(function() { | ||||
frappe.pages[list_page].doclistview.run(); | |||||
frappe.pages[list_page].doclistview.refresh(); | |||||
}, 100); | }, 100); | ||||
} | } | ||||
} | } | ||||
@@ -158,7 +163,9 @@ frappe.views.DocListView = frappe.ui.Listing.extend({ | |||||
added = true; | added = true; | ||||
} | } | ||||
}); | }); | ||||
added && me.run(); | |||||
if(added) { | |||||
me.refresh(true); | |||||
} | |||||
}); | }); | ||||
this.$page.find(".result-list").on("click", ".list-row-left", function(e) { | this.$page.find(".result-list").on("click", ".list-row-left", function(e) { | ||||
// don't open in case of checkbox, star, filterable | // don't open in case of checkbox, star, filterable | ||||
@@ -231,8 +238,11 @@ frappe.views.DocListView = frappe.ui.Listing.extend({ | |||||
this.refresh(); | this.refresh(); | ||||
}, | }, | ||||
refresh: function() { | |||||
var me = this; | |||||
refresh: function(dirty) { | |||||
if(window.ttt) throw "here"; | |||||
if(dirty!==undefined) this.dirty = dirty; | |||||
this.init_stats(); | this.init_stats(); | ||||
if(this.listview.settings.refresh) { | if(this.listview.settings.refresh) { | ||||
@@ -240,14 +250,14 @@ frappe.views.DocListView = frappe.ui.Listing.extend({ | |||||
} | } | ||||
if(frappe.route_options) { | if(frappe.route_options) { | ||||
me.set_route_options(); | |||||
me.run(); | |||||
} else if(me.dirty) { | |||||
me.run(); | |||||
this.set_route_options(); | |||||
this.run(); | |||||
} else if(this.dirty) { | |||||
this.run(); | |||||
} else { | } else { | ||||
if(new Date() - (me.last_updated_on || 0) > 30000) { | |||||
if(new Date() - (this.last_updated_on || 0) > 30000) { | |||||
// older than 5 mins, refresh | // older than 5 mins, refresh | ||||
me.run(); | |||||
this.run(); | |||||
} | } | ||||
} | } | ||||
}, | }, | ||||
@@ -275,6 +285,12 @@ frappe.views.DocListView = frappe.ui.Listing.extend({ | |||||
run: function(more) { | run: function(more) { | ||||
// set filter from route | // set filter from route | ||||
var me = this; | |||||
if(this.fresh && !more) { | |||||
return; | |||||
} | |||||
if(this.listview.settings.before_run) { | if(this.listview.settings.before_run) { | ||||
this.listview.settings.before_run(this); | this.listview.settings.before_run(this); | ||||
} | } | ||||
@@ -294,6 +310,20 @@ frappe.views.DocListView = frappe.ui.Listing.extend({ | |||||
this.last_updated_on = new Date(); | this.last_updated_on = new Date(); | ||||
this.dirty = false; | this.dirty = false; | ||||
// set a fresh so that multiple refreshes do not happen | |||||
// at the same time. This is true when deleting. | |||||
// AJAX response will try to refresh and list_update notification | |||||
// via async will also try to update. | |||||
// It is not possible to guess which will reach first | |||||
// (most probably async will) but this is a forced way | |||||
// to prevent instant refreshes on mutilple triggers | |||||
// in a loosly coupled way. | |||||
this.fresh = true; | |||||
setTimeout(function() { | |||||
me.fresh = false; | |||||
}, 1000); | |||||
this._super(more); | this._super(more); | ||||
if(this.listview.settings.post_render) { | if(this.listview.settings.post_render) { | ||||
@@ -351,12 +381,14 @@ frappe.views.DocListView = frappe.ui.Listing.extend({ | |||||
this.$page.on("click", ".list-tag-preview", function() { me.toggle_tags(); }); | this.$page.on("click", ".list-tag-preview", function() { me.toggle_tags(); }); | ||||
this.page.set_secondary_action(__("Refresh"), function() { | this.page.set_secondary_action(__("Refresh"), function() { | ||||
me.run(); | |||||
me.dirty = true; | |||||
me.refresh(); | |||||
}, "octicon octicon-sync"); | }, "octicon octicon-sync"); | ||||
this.page.btn_secondary.addClass("hidden-xs"); | this.page.btn_secondary.addClass("hidden-xs"); | ||||
this.page.add_menu_item(__("Refresh"), function() { | this.page.add_menu_item(__("Refresh"), function() { | ||||
me.run(); | |||||
me.dirty = true; | |||||
me.refresh(); | |||||
}, "octicon octicon-sync").addClass("visible-xs"); | }, "octicon octicon-sync").addClass("visible-xs"); | ||||
if(frappe.model.can_import(this.doctype)) { | if(frappe.model.can_import(this.doctype)) { | ||||
@@ -541,7 +573,7 @@ frappe.views.DocListView = frappe.ui.Listing.extend({ | |||||
callback: function(r) { | callback: function(r) { | ||||
if(!r.exc) { | if(!r.exc) { | ||||
me.list_header.find(".list-select-all").prop("checked", false); | me.list_header.find(".list-select-all").prop("checked", false); | ||||
me.run(); | |||||
me.refresh(); | |||||
} | } | ||||
} | } | ||||
}); | }); | ||||
@@ -34,6 +34,10 @@ frappe.upload = { | |||||
$file_input.trigger("change"); | $file_input.trigger("change"); | ||||
}); | }); | ||||
if(opts.on_select) { | |||||
opts.on_select(); | |||||
} | |||||
} else { | } else { | ||||
$upload.find(".uploaded-filename").addClass("hidden") | $upload.find(".uploaded-filename").addClass("hidden") | ||||
$upload.find(".web-link-wrapper").removeClass("hidden"); | $upload.find(".web-link-wrapper").removeClass("hidden"); | ||||