🐛 Fixed inability to re-upload the same redirects file (#912)

closes https://github.com/TryGhost/Ghost/issues/9266
- `emberx-file-input` passes a `resetInput` function through to it's action handler but we weren't doing that in our override component. Added the missing functionality and updated all of our handlers to use that instead of doing manual resets
- added a `setFiles` action to `{{gh-uploader}}` and yield it for use in block invocations
This commit is contained in:
Kevin Ansfield 2017-11-22 17:04:48 +00:00 committed by GitHub
parent 7d1ee9386b
commit d33cfdac30
12 changed files with 79 additions and 65 deletions

View File

@ -155,8 +155,9 @@ export default Component.extend({
run.scheduleOnce('afterRender', this, this._setHeaderClass);
},
uploadImages(fileList) {
uploadImages(fileList, resetInput) {
this.set('droppedFiles', fileList);
resetInput();
},
uploadComplete(uploads) {

View File

@ -1,12 +1,21 @@
import Ember from 'ember';
import XFileInput from 'emberx-file-input/components/x-file-input';
// ember-cli-shims doesn't export Ember.testing
const {testing} = Ember;
// TODO: remove this override and use {{x-file-input}} directly once we've
// upgraded to emberx-file-input@1.2.0
export default XFileInput.extend({
change(e) {
let files = testing ? (e.originalEvent || e).testingFiles : e.target.files;
this.sendAction('action', files);
this.sendAction('action', this.files(e), this.resetInput.bind(this));
},
/**
* Gets files from event object.
*
* @method
* @private
* @param {$.Event || Event}
*/
files(e) {
return (e.originalEvent || e).testingFiles || e.target.files;
}
});

View File

@ -208,11 +208,8 @@ export default Component.extend({
},
actions: {
fileSelected(fileList) {
// can't use array destructuring here as FileList is not a strict
// array and fails in Safari
// eslint-disable-next-line ember-suave/prefer-destructuring
let file = fileList[0];
fileSelected(fileList, resetInput) {
let [file] = Array.from(fileList);
let validationResult = this._validate(file);
this.set('file', file);
@ -221,9 +218,17 @@ export default Component.extend({
if (validationResult === true) {
run.schedule('actions', this, function () {
this.generateRequest();
if (resetInput) {
resetInput();
}
});
} else {
this._uploadFailed(validationResult);
if (resetInput) {
resetInput();
}
}
},

View File

@ -229,7 +229,7 @@ export default Component.extend({
},
actions: {
fileSelected(fileList) {
fileSelected(fileList, resetInput) {
// can't use array destructuring here as FileList is not a strict
// array and fails in Safari
// eslint-disable-next-line ember-suave/prefer-destructuring
@ -242,9 +242,17 @@ export default Component.extend({
if (validationResult === true) {
run.schedule('actions', this, function () {
this.generateRequest();
if (resetInput) {
resetInput();
}
});
} else {
this._uploadFailed(validationResult);
if (resetInput) {
resetInput();
}
}
},

View File

@ -196,8 +196,6 @@ export default Component.extend(ShortcutsMixin, {
// a single render
run.scheduleOnce('afterRender', this, () => {
this._insertImages(uploadedImageUrls);
// reset the file input so the same file can be selected again
this.$('input[type=file]').val('');
});
}

View File

@ -127,7 +127,7 @@ export default Component.extend({
},
actions: {
imageSelected(fileList) {
imageSelected(fileList, resetInput) {
// eslint-disable-next-line
let imageFile = fileList[0];
@ -144,22 +144,17 @@ export default Component.extend({
reader.readAsDataURL(imageFile);
}
resetInput();
},
openFileDialog(event) {
let fileInput = $(event.target)
// simulate click to open file dialog
// using jQuery because IE11 doesn't support MouseEvent
$(event.target)
.closest('figure')
.find('input[type="file"]');
if (fileInput.length > 0) {
// reset file input value before clicking so that the same image
// can be selected again
fileInput.value = '';
// simulate click to open file dialog
// using jQuery because IE11 doesn't support MouseEvent
$(fileInput).click();
}
.find('input[type="file"]')
.click();
}
}
});

View File

@ -94,6 +94,12 @@ export default Component.extend({
// if we have new files, validate and start an upload
let files = this.get('files');
this._setFiles(files);
},
_setFiles(files) {
this.set('files', files);
if (files && files !== this._files) {
if (this.get('_uploadFiles.isRunning')) {
// eslint-disable-next-line
@ -289,6 +295,14 @@ export default Component.extend({
},
actions: {
setFiles(files, resetInput) {
this._setFiles(files);
if (resetInput) {
resetInput();
}
},
cancel() {
this._reset();
this.onCancel();

View File

@ -103,6 +103,11 @@ export default Controller.extend({
this.get('model').set(image, '');
},
updateImage(property, image, resetInput) {
this.get('model').set(property, image);
resetInput();
},
/**
* Opens a file selection dialog - Triggered by "Upload Image" buttons,
* searches for the hidden file input within the .gh-setting element
@ -110,19 +115,12 @@ export default Controller.extend({
* @param {MouseEvent} event - MouseEvent fired by the button click
*/
triggerFileDialog(event) {
let fileInput = $(event.target)
.closest('.gh-setting')
.find('input[type="file"]');
if (fileInput.length > 0) {
// reset file input value before clicking so that the same image
// can be selected again
fileInput.val('');
// simulate click to open file dialog
// using jQuery because IE11 doesn't support MouseEvent
$(fileInput).click();
}
// simulate click to open file dialog
// using jQuery because IE11 doesn't support MouseEvent
$(event.target)
.closest('figure')
.find('input[type="file"]')
.click();
},
/**
@ -133,10 +131,6 @@ export default Controller.extend({
*/
imageUploaded(property, results) {
if (results[0]) {
// Note: We have to reset the file input after upload, otherwise you can't upload the same image again
// See https://github.com/thefrontside/emberx-file-input/blob/master/addon/components/x-file-input.js#L37
// See https://github.com/TryGhost/Ghost/issues/8545
$('.x-file--input').val('');
return this.get('model').set(property, results[0].url);
}
},

View File

@ -193,19 +193,12 @@ export default Controller.extend({
* @param {MouseEvent} event - MouseEvent fired by the button click
*/
triggerFileDialog(event) {
let fileInput = $(event.target)
.closest('.gh-setting')
.find('input[type="file"]');
if (fileInput.length > 0) {
// reset file input value before clicking so that the same image
// can be selected again
fileInput.val('');
// simulate click to open file dialog
// using jQuery because IE11 doesn't support MouseEvent
$(fileInput).click();
}
// simulate click to open file dialog
// using jQuery because IE11 doesn't support MouseEvent
$(event.target)
.closest('figure')
.find('input[type="file"]')
.click();
}
}
});

View File

@ -4,4 +4,5 @@
files=files
isUploading=_uploadFiles.isRunning
progressBar=(component "gh-progress-bar" percentage=uploadPercentage)
setFiles=(action 'setFiles')
)}}

View File

@ -61,7 +61,6 @@
<div class="gh-setting-header">Publication identity</div>
<div class="gh-setting" data-test-setting="icon">
{{#gh-uploader
files=iconUpload
extensions=iconExtensions
uploadUrl="/uploads/icon/"
onComplete=(action "imageUploaded" "icon")
@ -88,14 +87,13 @@
</button>
{{/if}}
<div style="display:none">
{{gh-file-input multiple=false action=(action (mut iconUpload)) accept=iconMimeTypes data-test-file-input="icon"}}
{{gh-file-input multiple=false action=uploader.setFiles accept=iconMimeTypes data-test-file-input="icon"}}
</div>
</div>
{{/gh-uploader}}
</div>
<div class="gh-setting" data-test-setting="logo">
{{#gh-uploader
files=logoUpload
extensions=imageExtensions
onComplete=(action "imageUploaded" "logo")
as |uploader|
@ -121,14 +119,13 @@
</button>
{{/if}}
<div style="display:none">
{{gh-file-input multiple=false action=(action (mut logoUpload)) accept=imageMimeTypes data-test-file-input="logo"}}
{{gh-file-input multiple=false action=uploader.setFiles accept=imageMimeTypes data-test-file-input="logo"}}
</div>
</div>
{{/gh-uploader}}
</div>
<div class="gh-setting" data-test-setting="coverImage">
{{#gh-uploader
files=coverImageUpload
extensions=imageExtensions
onComplete=(action "imageUploaded" "coverImage")
as |uploader|
@ -154,7 +151,7 @@
</button>
{{/if}}
<div style="display:none">
{{gh-file-input multiple=false action=(action (mut coverImageUpload)) accept=imageMimeTypes data-test-file-input="coverImage"}}
{{gh-file-input multiple=false action=uploader.setFiles accept=imageMimeTypes data-test-file-input="coverImage"}}
</div>
</div>
{{/gh-uploader}}

View File

@ -111,7 +111,6 @@
</div>
<div class="gh-setting">
{{#gh-uploader
files=redirectsUpload
extensions=jsonExtension
uploadUrl="/redirects/json/"
paramName="redirects"
@ -150,7 +149,7 @@
{{/if}}
<div style="display:none">
{{gh-file-input multiple=false action=(action (mut redirectsUpload)) accept=jsonMimeType data-test-file-input="redirects"}}
{{gh-file-input multiple=false action=uploader.setFiles accept=jsonMimeType data-test-file-input="redirects"}}
</div>
</div>
{{/gh-uploader}}