Skip to content

Commit d2c64ab

Browse files
committed
Merge remote-tracking branch 'remotes/origin/MAGETWO-87641-Validation-Message-Display' into team3-delivery2
2 parents 035efd5 + bda1366 commit d2c64ab

File tree

5 files changed

+349
-20
lines changed

5 files changed

+349
-20
lines changed

app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,19 @@ define([
1313
'jquery',
1414
'mage/template',
1515
'Magento_Ui/js/modal/alert',
16+
'Magento_Ui/js/form/element/file-uploader',
1617
'mage/translate',
1718
'jquery/file-uploader'
18-
], function ($, mageTemplate, alert) {
19+
], function ($, mageTemplate, alert, FileUploader) {
1920
'use strict';
2021

22+
var fileUploader = new FileUploader({
23+
dataScope: '',
24+
isMultipleFiles: true
25+
});
26+
27+
fileUploader.initUploader();
28+
2129
$.widget('mage.mediaUploader', {
2230

2331
/**
@@ -79,10 +87,9 @@ define([
7987
if (data.result && !data.result.error) {
8088
self.element.trigger('addItem', data.result);
8189
} else {
82-
alert({
83-
content: $.mage.__('We don\'t recognize or support this file extension type.')
84-
});
90+
fileUploader.aggregateError(data.files[0].name, data.result.error);
8591
}
92+
8693
self.element.find('#' + data.fileId).remove();
8794
},
8895

@@ -108,7 +115,9 @@ define([
108115
.delay(2000)
109116
.hide('highlight')
110117
.remove();
111-
}
118+
},
119+
120+
stop: fileUploader.uploaderConfig.stop
112121
});
113122

114123
this.element.find('input[type=file]').fileupload('option', {

app/code/Magento/Ui/i18n/en_US.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,4 @@ CSV,CSV
201201
"Please enter at least {0} characters.","Please enter at least {0} characters."
202202
"Please enter a value between {0} and {1} characters long.","Please enter a value between {0} and {1} characters long."
203203
"Please enter a value between {0} and {1}.","Please enter a value between {0} and {1}."
204+
"was not uploaded","was not uploaded"

app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js

Lines changed: 82 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@ define([
1313
'Magento_Ui/js/modal/alert',
1414
'Magento_Ui/js/lib/validation/validator',
1515
'Magento_Ui/js/form/element/abstract',
16+
'mage/backend/notification',
17+
'mage/translate',
1618
'jquery/file-uploader'
17-
], function ($, _, utils, uiAlert, validator, Element) {
19+
], function ($, _, utils, uiAlert, validator, Element, notification, $t) {
1820
'use strict';
1921

2022
return Element.extend({
2123
defaults: {
2224
value: [],
25+
aggregatedErrors: [],
2326
maxFileSize: false,
2427
isMultipleFiles: false,
2528
placeholderType: 'document', // 'image', 'video'
@@ -278,9 +281,15 @@ define([
278281
* @returns {FileUploader} Chainable.
279282
*/
280283
notifyError: function (msg) {
281-
uiAlert({
284+
var data = {
282285
content: msg
283-
});
286+
};
287+
288+
if (this.isMultipleFiles) {
289+
data.modalClass = '_image-box';
290+
}
291+
292+
uiAlert(data);
284293

285294
return this;
286295
},
@@ -309,13 +318,20 @@ define([
309318
},
310319

311320
/**
312-
* Abstract handler which is invoked when files are choosed for upload.
321+
* Handler which is invoked when files are choosed for upload.
313322
* May be used for implementation of aditional validation rules,
314323
* e.g. total files and a total size rules.
315324
*
316-
* @abstract
325+
* @param {Event} e - Event object.
326+
* @param {Object} data - File data that will be uploaded.
327+
* @returns {Boolean|void} - false if further processing should halt or undefined if processing should continue
317328
*/
318-
onFilesChoosed: function () {},
329+
onFilesChoosed: function (e, data) {
330+
// no option exists in fileuploader for restricting upload chains to single files; this enforces that policy
331+
if (!this.isMultipleFiles) {
332+
data.files.splice(1);
333+
}
334+
},
319335

320336
/**
321337
* Handler which is invoked prior to the start of a file upload.
@@ -337,22 +353,41 @@ define([
337353
data.submit();
338354
});
339355
} else {
340-
this.notifyError(allowed.message);
356+
this.aggregateError(file.name, allowed.message);
357+
358+
// if all files in upload chain are invalid, stop callback is never called; this resolves promise
359+
if (this.aggregatedErrors.length === data.originalFiles.length) {
360+
this.uploaderConfig.stop();
361+
}
341362
}
342363
},
343364

365+
/**
366+
* Add error message associated with filename for display when upload chain is complete
367+
*
368+
* @param {String} filename
369+
* @param {String} message
370+
*/
371+
aggregateError: function (filename, message) {
372+
this.aggregatedErrors.push({
373+
filename: filename,
374+
message: message
375+
});
376+
},
377+
344378
/**
345379
* Handler of the file upload complete event.
346380
*
347381
* @param {Event} e
348382
* @param {Object} data
349383
*/
350384
onFileUploaded: function (e, data) {
351-
var file = data.result,
385+
var uploadedFilename = data.files[0].name,
386+
file = data.result,
352387
error = file.error;
353388

354389
error ?
355-
this.notifyError(error) :
390+
this.aggregateError(uploadedFilename, error) :
356391
this.addFile(file);
357392
},
358393

@@ -367,7 +402,45 @@ define([
367402
* Load stop event handler.
368403
*/
369404
onLoadingStop: function () {
405+
var aggregatedErrorMessages = [];
406+
370407
this.isLoading = false;
408+
409+
if (!this.aggregatedErrors.length) {
410+
return;
411+
}
412+
413+
if (!this.isMultipleFiles) { // only single file upload occurred; use first file's error message
414+
aggregatedErrorMessages.push(this.aggregatedErrors[0].message);
415+
} else { // construct message from all aggregatedErrors
416+
_.each(this.aggregatedErrors, function (error) {
417+
notification().add({
418+
error: true,
419+
message: '%s' + error.message, // %s to be used as placeholder for html injection
420+
421+
/**
422+
* Adds constructed error notification to aggregatedErrorMessages
423+
*
424+
* @param {String} constructedMessage
425+
*/
426+
insertMethod: function (constructedMessage) {
427+
var errorMsgBodyHtml = '<strong>%s</strong> %s.<br>'
428+
.replace('%s', error.filename)
429+
.replace('%s', $t('was not uploaded'));
430+
431+
// html is escaped in message body for notification widget; prepend unescaped html here
432+
constructedMessage = constructedMessage.replace('%s', errorMsgBodyHtml);
433+
434+
aggregatedErrorMessages.push(constructedMessage);
435+
}
436+
});
437+
});
438+
}
439+
440+
this.notifyError(aggregatedErrorMessages.join(''));
441+
442+
// clear out aggregatedErrors array for this completed upload chain
443+
this.aggregatedErrors = [];
371444
},
372445

373446
/**

app/design/adminhtml/Magento/backend/web/css/source/components/_modals_extend.less

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
&.confirm,
8181
&.prompt {
8282
.modal-inner-wrap {
83-
.message {
83+
.message:not(.message-error) {
8484
background: @modal-popup-colorless__background;
8585
}
8686
}

0 commit comments

Comments
 (0)