From bb94fc7d712100652c22c510af64366fc9cb3dd8 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 30 Jul 2015 11:35:00 +0200 Subject: [PATCH] Ensures notifications are shown for drag/drop uploads --- .../imaging/umbimagefolder.directive.js | 7 ++ .../common/dialogs/mediapicker.controller.js | 8 ++- src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 2 + .../umbraco/config/lang/en_us.xml | 2 + .../Editors/ContentControllerBase.cs | 10 ++- src/Umbraco.Web/Editors/MediaController.cs | 72 ++++++++++--------- 6 files changed, 62 insertions(+), 39 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/imaging/umbimagefolder.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/imaging/umbimagefolder.directive.js index 5b1ad4f0dd..f7ca24303d 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/imaging/umbimagefolder.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/imaging/umbimagefolder.directive.js @@ -64,6 +64,13 @@ function umbImageFolder($rootScope, assetsService, $timeout, $log, umbRequestHel found.completed = true; } + //Show notifications!!!! + if (data.result && data.result.notifications && angular.isArray(data.result.notifications)) { + for (var n = 0; n < data.result.notifications.length; n++) { + notificationsService.showNotification(data.result.notifications[n]); + } + } + //when none are left resync everything var remaining = _.filter(scope.files, function (file) { return file.completed !== true; }); if (remaining.length === 0) { diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/mediapicker.controller.js index efbfff62d6..6e44c0465d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/mediapicker.controller.js @@ -1,7 +1,7 @@ //used for the media picker dialog angular.module("umbraco") .controller("Umbraco.Dialogs.MediaPickerController", - function ($scope, mediaResource, umbRequestHelper, entityResource, $log, mediaHelper, eventsService, treeService, $cookies, $element, $timeout) { + function ($scope, mediaResource, umbRequestHelper, entityResource, $log, mediaHelper, eventsService, treeService, $cookies, $element, $timeout, notificationsService) { var dialogOptions = $scope.dialogOptions; @@ -98,6 +98,12 @@ angular.module("umbraco") $scope.gotoFolder($scope.currentFolder); }); } + //Show notifications!!!! + if (data.result && data.result.notifications && angular.isArray(data.result.notifications)) { + for (var n = 0; n < data.result.notifications.length; n++) { + notificationsService.showNotification(data.result.notifications[n]); + } + } }); // All these sit-ups are to add dropzone area and make sure it gets removed if dragging is aborted! diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index 17317d282d..ca44fe7afa 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -774,6 +774,8 @@ To manage your website, simply open the Umbraco back office and start adding con
Do not close this window during sorting]]>
+ Failed + Insufficient user permissions, could not complete the operation Cancelled Operation was cancelled by a 3rd party add-in Publishing was cancelled by a 3rd party add-in diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml index 87e6fabdb1..c779e2b789 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -775,6 +775,8 @@ To manage your website, simply open the Umbraco back office and start adding con
Do not close this window during sorting]]>
+ Failed + Insufficient user permissions, could not complete the operation Cancelled Operation was cancelled by a 3rd party add-in Publishing was cancelled by a 3rd party add-in diff --git a/src/Umbraco.Web/Editors/ContentControllerBase.cs b/src/Umbraco.Web/Editors/ContentControllerBase.cs index e702da369e..bf9f2056b3 100644 --- a/src/Umbraco.Web/Editors/ContentControllerBase.cs +++ b/src/Umbraco.Web/Editors/ContentControllerBase.cs @@ -172,15 +172,19 @@ namespace Umbraco.Web.Editors return (action.ToString().EndsWith("New")); } - protected void AddCancelMessage(INotificationModel display, string header = "speechBubbles/operationCancelledHeader", string message = "speechBubbles/operationCancelledText") + protected void AddCancelMessage(INotificationModel display, + string header = "speechBubbles/operationCancelledHeader", + string message = "speechBubbles/operationCancelledText", + bool localizeHeader = true, + bool localizeMessage = true) { //if there's already a default event message, don't add our default one var msgs = UmbracoContext.GetCurrentEventMessages(); if (msgs != null && msgs.GetAll().Any(x => x.IsDefaultEventMessage)) return; display.AddWarningNotification( - Services.TextService.Localize(header), - Services.TextService.Localize(message)); + localizeHeader ? Services.TextService.Localize(header) : header, + localizeMessage ? Services.TextService.Localize(message): message); } } } diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs index e9fd8c8a85..12a35e3b20 100644 --- a/src/Umbraco.Web/Editors/MediaController.cs +++ b/src/Umbraco.Web/Editors/MediaController.cs @@ -34,6 +34,8 @@ using umbraco.BusinessLogic.Actions; using Constants = Umbraco.Core.Constants; using Umbraco.Core.Configuration; using Umbraco.Core.Persistence.FaultHandling; +using Umbraco.Web.UI; +using Notification = Umbraco.Web.Models.ContentEditing.Notification; namespace Umbraco.Web.Editors { @@ -397,9 +399,7 @@ namespace Umbraco.Web.Editors int parentId; if (int.TryParse(result.FormData["currentFolder"], out parentId) == false) { - var response = Request.CreateResponse(HttpStatusCode.BadRequest); - response.ReasonPhrase = "The request was not formatted correctly, the currentFolder is not an integer"; - throw new HttpResponseException(response); + return Request.CreateValidationErrorResponse("The request was not formatted correctly, the currentFolder is not an integer"); } //ensure the user has access to this folder by parent id! @@ -408,7 +408,12 @@ namespace Umbraco.Web.Editors Security.CurrentUser, Services.MediaService, parentId) == false) { - return Request.CreateResponse(HttpStatusCode.Unauthorized); + return Request.CreateResponse( + HttpStatusCode.Unauthorized, + new SimpleNotificationModel(new Notification( + Services.TextService.Localize("speechBubbles/operationFailedHeader"), + Services.TextService.Localize("speechBubbles/invalidUserPermissionsText"), + SpeechBubbleIcon.Warning))); } var tempFiles = new PostedFiles(); @@ -419,7 +424,7 @@ namespace Umbraco.Web.Editors var fileName = file.Headers.ContentDisposition.FileName.Trim(new[] { '\"' }); var ext = fileName.Substring(fileName.LastIndexOf('.')+1).ToLower(); - if (!UmbracoConfig.For.UmbracoSettings().Content.DisallowedUploadFiles.Contains(ext)) + if (UmbracoConfig.For.UmbracoSettings().Content.DisallowedUploadFiles.Contains(ext) == false) { var mediaType = Constants.Conventions.MediaTypes.File; @@ -437,19 +442,30 @@ namespace Umbraco.Web.Editors f.SetValue(Constants.Conventions.Media.File, fileName, fs); } - mediaService.Save(f, Security.CurrentUser.Id); + var saveResult = mediaService.WithResult().Save(f, Security.CurrentUser.Id); + if (saveResult == false) + { + AddCancelMessage(tempFiles, + message: Services.TextService.Localize("speechBubbles/operationCancelledText") + " -- " + fileName, + localizeMessage: false); + } + else + { + tempFiles.UploadedFiles.Add(new ContentItemFile + { + FileName = fileName, + PropertyAlias = Constants.Conventions.Media.File, + TempFilePath = file.LocalFileName + }); + } } else { - LogHelper.Warn("Cannot upload file " + file + ", it is not an approved file type"); + tempFiles.Notifications.Add(new Notification( + Services.TextService.Localize("speechBubbles/operationFailedHeader"), + "Cannot upload file " + file + ", it is not an approved file type", + SpeechBubbleIcon.Warning)); } - - tempFiles.UploadedFiles.Add(new ContentItemFile - { - FileName = fileName, - PropertyAlias = Constants.Conventions.Media.File, - TempFilePath = file.LocalFileName - }); } //Different response if this is a 'blueimp' request @@ -458,20 +474,8 @@ namespace Umbraco.Web.Editors var origin = Request.GetQueryNameValuePairs().First(x => x.Key == "origin"); if (origin.Value == "blueimp") { - var blueImpResult = new BlueImpPostedFileResult() - { - UploadedFiles = tempFiles.UploadedFiles - }; - blueImpResult.AddRange(tempFiles.UploadedFiles.Select(x => new - { - name = x.FileName, - size = "", - url = "", - thumbnailUrl = "" - })); - return Request.CreateResponse(HttpStatusCode.OK, - blueImpResult, + tempFiles, //Don't output the angular xsrf stuff, blue imp doesn't like that new JsonMediaTypeFormatter()); } @@ -480,24 +484,22 @@ namespace Umbraco.Web.Editors return Request.CreateResponse(HttpStatusCode.OK, tempFiles); } - [DataContract] - private class BlueImpPostedFileResult : List, IHaveUploadedFiles - { - [IgnoreDataMember] - public List UploadedFiles { get; set; } - } - /// /// This is used for the response of PostAddFile so that we can analyze the response in a filter and remove the /// temporary files that were created. /// - private class PostedFiles : IHaveUploadedFiles + [DataContract] + private class PostedFiles : IHaveUploadedFiles, INotificationModel { public PostedFiles() { UploadedFiles = new List(); + Notifications = new List(); } public List UploadedFiles { get; private set; } + + [DataMember(Name = "notifications")] + public List Notifications { get; private set; } } ///