Merge pull request #15003 from mituldavid/file-uploader
refactor: Display errors in FilePreview
This commit is contained in:
commit
e94ce5c8a0
5 changed files with 66 additions and 21 deletions
|
|
@ -120,6 +120,8 @@ def init_request(request):
|
|||
else:
|
||||
frappe.connect(set_admin_as_user=False)
|
||||
|
||||
request.max_content_length = frappe.local.conf.get('max_file_size') or 10 * 1024 * 1024
|
||||
|
||||
make_form_dict(request)
|
||||
|
||||
if request.method != "OPTIONS":
|
||||
|
|
|
|||
|
|
@ -716,13 +716,11 @@ def delete_file(path):
|
|||
os.remove(path)
|
||||
|
||||
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_max_file_size():
|
||||
return cint(conf.get('max_file_size')) or 10485760
|
||||
|
||||
|
||||
|
||||
def has_permission(doc, ptype=None, user=None):
|
||||
has_access = False
|
||||
user = user or frappe.session.user
|
||||
|
|
|
|||
|
|
@ -29,21 +29,26 @@
|
|||
</span>
|
||||
</div>
|
||||
<label v-if="is_optimizable" class="optimize-checkbox"><input type="checkbox" :checked="optimize" @change="$emit('toggle_optimize')">Optimize</label>
|
||||
<div>
|
||||
<span v-if="file.error_message" class="file-error text-danger">
|
||||
{{ file.error_message }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="file-actions">
|
||||
<ProgressRing
|
||||
v-show="file.uploading && !uploaded"
|
||||
v-show="file.uploading && !uploaded && !file.failed"
|
||||
primary="var(--primary-color)"
|
||||
secondary="var(--gray-200)"
|
||||
radius="24"
|
||||
:radius="24"
|
||||
:progress="progress"
|
||||
stroke="3"
|
||||
:stroke="3"
|
||||
/>
|
||||
<div v-if="uploaded" v-html="frappe.utils.icon('solid-success', 'lg')"></div>
|
||||
<div v-if="file.failed" v-html="frappe.utils.icon('solid-red', 'lg')"></div>
|
||||
<div v-if="file.failed" v-html="frappe.utils.icon('solid-error', 'lg')"></div>
|
||||
<div class="file-action-buttons">
|
||||
<button v-if="is_cropable" class="btn btn-crop muted" @click="$emit('toggle_image_cropper')" v-html="frappe.utils.icon('crop', 'md')"></button>
|
||||
<button v-if="!uploaded && !file.uploading" class="btn muted" @click="$emit('remove')" v-html="frappe.utils.icon('delete', 'md')"></button>
|
||||
<button v-if="!uploaded && !file.uploading && !file.failed" class="btn muted" @click="$emit('remove')" v-html="frappe.utils.icon('delete', 'md')"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -89,18 +94,18 @@ export default {
|
|||
return this.file.doc ? this.file.doc.is_private : this.file.private;
|
||||
},
|
||||
uploaded() {
|
||||
return this.file.total && this.file.total === this.file.progress && !this.file.failed;
|
||||
return this.file.request_succeeded;
|
||||
},
|
||||
is_image() {
|
||||
return this.file.file_obj.type.startsWith('image');
|
||||
},
|
||||
is_optimizable() {
|
||||
let is_svg = this.file.file_obj.type == 'image/svg+xml';
|
||||
return this.is_image && !is_svg;
|
||||
return this.is_image && !is_svg && !this.uploaded && !this.file.failed;
|
||||
},
|
||||
is_cropable() {
|
||||
let croppable_types = ['image/jpeg', 'image/png'];
|
||||
return !this.uploaded && !this.file.uploading && croppable_types.includes(this.file.file_obj.type);
|
||||
return !this.uploaded && !this.file.uploading && !this.file.failed && croppable_types.includes(this.file.file_obj.type);
|
||||
},
|
||||
progress() {
|
||||
let value = Math.round((this.file.progress * 100) / this.file.total);
|
||||
|
|
@ -208,4 +213,9 @@ export default {
|
|||
align-items: center;
|
||||
padding-top: 0.25rem;
|
||||
}
|
||||
|
||||
.file-error {
|
||||
font-size: var(--text-sm);
|
||||
font-weight: var(--text-bold);
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -197,6 +197,7 @@ export default {
|
|||
show_image_cropper: false,
|
||||
crop_image_with_index: -1,
|
||||
trigger_upload: false,
|
||||
close_dialog: false,
|
||||
hide_dialog_footer: false,
|
||||
allow_take_photo: false,
|
||||
allow_web_link: true,
|
||||
|
|
@ -218,6 +219,12 @@ export default {
|
|||
}
|
||||
});
|
||||
}
|
||||
if (this.restrictions.max_file_size == null) {
|
||||
frappe.call('frappe.core.doctype.file.file.get_max_file_size')
|
||||
.then(res => {
|
||||
this.restrictions.max_file_size = Number(res.message);
|
||||
});
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
files(newvalue, oldvalue) {
|
||||
|
|
@ -289,6 +296,8 @@ export default {
|
|||
progress: 0,
|
||||
total: 0,
|
||||
failed: false,
|
||||
request_succeeded: false,
|
||||
error_message: null,
|
||||
uploading: false,
|
||||
private: !is_image
|
||||
}
|
||||
|
|
@ -329,9 +338,17 @@ export default {
|
|||
|
||||
if (!is_correct_type) {
|
||||
console.warn('File skipped because of invalid file type', file);
|
||||
frappe.show_alert({
|
||||
message: __('File "{0}" was skipped because of invalid file type', [file.name]),
|
||||
indicator: 'orange'
|
||||
});
|
||||
}
|
||||
if (!valid_file_size) {
|
||||
console.warn('File skipped because of invalid file size', file.size, file);
|
||||
frappe.show_alert({
|
||||
message: __('File "{0}" was skipped because size exceeds {1} MB', [file.name, max_file_size / (1024 * 1024)]),
|
||||
indicator: 'orange'
|
||||
});
|
||||
}
|
||||
|
||||
return is_correct_type && valid_file_size;
|
||||
|
|
@ -357,9 +374,10 @@ export default {
|
|||
let selected_file = this.$refs.file_browser.selected_node;
|
||||
if (!selected_file.value) {
|
||||
frappe.msgprint(__('Click on a file to select it.'));
|
||||
this.close_dialog = true;
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
this.close_dialog = true;
|
||||
return this.upload_file({
|
||||
file_url: selected_file.file_url
|
||||
});
|
||||
|
|
@ -368,9 +386,11 @@ export default {
|
|||
let file_url = this.$refs.web_link.url;
|
||||
if (!file_url) {
|
||||
frappe.msgprint(__('Invalid URL'));
|
||||
this.close_dialog = true;
|
||||
return Promise.reject();
|
||||
}
|
||||
file_url = decodeURI(file_url)
|
||||
this.close_dialog = true;
|
||||
return this.upload_file({
|
||||
file_url
|
||||
});
|
||||
|
|
@ -383,6 +403,7 @@ export default {
|
|||
this.on_success && this.on_success(file);
|
||||
})
|
||||
);
|
||||
this.close_dialog = true;
|
||||
return Promise.all(promises);
|
||||
},
|
||||
upload_file(file, i) {
|
||||
|
|
@ -410,6 +431,7 @@ export default {
|
|||
xhr.onreadystatechange = () => {
|
||||
if (xhr.readyState == XMLHttpRequest.DONE) {
|
||||
if (xhr.status === 200) {
|
||||
file.request_succeeded = true;
|
||||
let r = null;
|
||||
let file_doc = null;
|
||||
try {
|
||||
|
|
@ -426,15 +448,24 @@ export default {
|
|||
if (this.on_success) {
|
||||
this.on_success(file_doc, r);
|
||||
}
|
||||
|
||||
if (i == this.files.length - 1 && this.files.every(file => file.request_succeeded)) {
|
||||
this.close_dialog = true;
|
||||
}
|
||||
|
||||
} else if (xhr.status === 403) {
|
||||
file.failed = true;
|
||||
let response = JSON.parse(xhr.responseText);
|
||||
frappe.msgprint({
|
||||
title: __('Not permitted'),
|
||||
indicator: 'red',
|
||||
message: response._error_message
|
||||
});
|
||||
file.error_message = `Not permitted. ${response._error_message || ''}`;
|
||||
|
||||
} else if (xhr.status === 413) {
|
||||
file.failed = true;
|
||||
file.error_message = 'Size exceeds the maximum allowed file size.';
|
||||
|
||||
} else {
|
||||
file.failed = true;
|
||||
file.error_message = xhr.status === 0 ? 'XMLHttpRequest Error' : `${xhr.status} : ${xhr.statusText}`;
|
||||
|
||||
let error = null;
|
||||
try {
|
||||
error = JSON.parse(xhr.responseText);
|
||||
|
|
|
|||
|
|
@ -67,6 +67,12 @@ export default class FileUploader {
|
|||
}
|
||||
});
|
||||
|
||||
this.uploader.$watch('close_dialog', (close_dialog) => {
|
||||
if (close_dialog) {
|
||||
this.dialog && this.dialog.hide();
|
||||
}
|
||||
});
|
||||
|
||||
this.uploader.$watch('hide_dialog_footer', (hide_dialog_footer) => {
|
||||
if (hide_dialog_footer) {
|
||||
this.dialog && this.dialog.footer.addClass('hide');
|
||||
|
|
@ -84,10 +90,8 @@ export default class FileUploader {
|
|||
|
||||
upload_files() {
|
||||
this.dialog && this.dialog.get_primary_btn().prop('disabled', true);
|
||||
return this.uploader.upload_files()
|
||||
.then(() => {
|
||||
this.dialog && this.dialog.hide();
|
||||
});
|
||||
this.dialog && this.dialog.get_secondary_btn().prop('disabled', true);
|
||||
return this.uploader.upload_files();
|
||||
}
|
||||
|
||||
make_dialog() {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue