diff --git a/src/Umbraco.Web.UI.Client/src/common/services/filemanager.service.js b/src/Umbraco.Web.UI.Client/src/common/services/filemanager.service.js index 158c9202eb..6d319ad90a 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/filemanager.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/filemanager.service.js @@ -33,9 +33,9 @@ function fileManager() { throw "args.files must be an object"; } - var culture = null; - if (args.culture) { - culture = args.culture; + //normalize to null + if (!args.culture) { + args.culture = null; } var metaData = []; @@ -49,7 +49,7 @@ function fileManager() { }); for (var i = 0; i < args.files.length; i++) { //save the file object to the files collection - fileCollection.push({ alias: args.propertyAlias, file: args.files[i], culture: culture, metaData: metaData }); + fileCollection.push({ alias: args.propertyAlias, file: args.files[i], culture: args.culture, metaData: metaData }); } }, diff --git a/src/Umbraco.Web.UI.Client/src/common/services/umbrequesthelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/umbrequesthelper.service.js index 69fe6a6818..d15a213bea 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/umbrequesthelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/umbrequesthelper.service.js @@ -221,7 +221,8 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ for (var f in args.files) { //each item has a property alias and the file object, we'll ensure that the alias is suffixed to the key // so we know which property it belongs to on the server side - var fileKey = "file_" + args.files[f].alias + "_" + args.files[f].culture; + var fileKey = "file_" + args.files[f].alias + "_" + (args.files[f].culture ? args.files[f].culture : ""); + if (angular.isArray(args.files[f].metaData) && args.files[f].metaData.length > 0) { fileKey += ("_" + args.files[f].metaData.join("_")); } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.controller.js index cbc88ebacb..9cd0fb9b27 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.controller.js @@ -14,6 +14,16 @@ $scope.valueChanged = valueChanged; + //here we declare a special method which will be called whenever the value has changed from the server + $scope.model.onValueChanged = function (newVal, oldVal) { + //clear current uploaded files + fileManager.setFiles({ + propertyAlias: $scope.model.alias, + culture: $scope.model.culture, + files: [] + }); + }; + /** * Called when the file selection value changes * @param {any} value diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.controller.js index c38e282ffa..fabdbfad41 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.controller.js @@ -36,12 +36,18 @@ angular.module('umbraco') $scope.crop = function (crop) { $scope.currentCrop = crop; $scope.currentPoint = undefined; + + //set form to dirty to track changes + $scope.imageCropperForm.$setDirty(); }; //done cropping $scope.done = function () { $scope.currentCrop = undefined; $scope.currentPoint = undefined; + + //set form to dirty to track changes + $scope.imageCropperForm.$setDirty(); }; //crop a specific crop @@ -49,6 +55,7 @@ angular.module('umbraco') //clear current uploaded files fileManager.setFiles({ propertyAlias: $scope.model.alias, + culture: $scope.model.culture, files: [] }); @@ -58,9 +65,8 @@ angular.module('umbraco') delete $scope.model.value; } - // set form to dirty to tricker discard changes dialog - var currForm = angularHelper.getCurrentForm($scope); - currForm.$setDirty(); + //set form to dirty to track changes + $scope.imageCropperForm.$setDirty(); }; //show previews @@ -83,7 +89,11 @@ angular.module('umbraco') if (args.files && args.files[0]) { - fileManager.setFiles({ propertyAlias: $scope.model.alias, files: args.files}); + fileManager.setFiles({ + propertyAlias: $scope.model.alias, + culture: $scope.model.culture, + files: args.files + }); var reader = new FileReader(); reader.onload = function (e) { @@ -95,6 +105,9 @@ angular.module('umbraco') }; reader.readAsDataURL(args.files[0]); + + //set form to dirty to track changes + $scope.imageCropperForm.$setDirty(); } }); @@ -102,7 +115,11 @@ angular.module('umbraco') //here we declare a special method which will be called whenever the value has changed from the server $scope.model.onValueChanged = function (newVal, oldVal) { //clear current uploaded files - fileManager.setFiles({ propertyAlias: $scope.model.alias, files: [] }); + fileManager.setFiles({ + propertyAlias: $scope.model.alias, + culture: $scope.model.culture, + files: [] + }); }; var unsubscribe = $scope.$on("formSubmitting", function () { diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.html index 64a2b97ef4..791f94116a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.html @@ -1,72 +1,69 @@
+ + + +

Click to upload

+ +
- - -

Click to upload

- -
+
+
-
+
+
+ -
+
+ + +
-
-
- - - - - - - Reset -
+ +
+ + + Remove file +
+ +
    +
  • + + + + +
    + {{value.alias}} + {{value.width}}px x {{value.height}}px +
    +
  • +
+
-
- - - Remove file -
- -
    -
  • - - - - -
    - {{value.alias}} - {{value.width}}px x {{value.height}}px -
    -
  • -
- -
- -
+
diff --git a/src/Umbraco.Web/Editors/Binders/ContentModelBinderHelper.cs b/src/Umbraco.Web/Editors/Binders/ContentModelBinderHelper.cs index d36a9aef0f..8c3edd915d 100644 --- a/src/Umbraco.Web/Editors/Binders/ContentModelBinderHelper.cs +++ b/src/Umbraco.Web/Editors/Binders/ContentModelBinderHelper.cs @@ -2,6 +2,7 @@ using System.Net.Http; using System.Web.Http; using System.Web.Http.Controllers; +using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Models.Editors; using Umbraco.Web.Models.ContentEditing; @@ -41,9 +42,14 @@ namespace Umbraco.Web.Editors.Binders if (parts.Length > 2) { culture = parts[2]; + //normalize to null if empty + if (culture.IsNullOrWhiteSpace()) + { + culture = null; + } } - //anything after 3 parts + //TODO: anything after 3 parts we can put in metadata var fileName = file.Headers.ContentDisposition.FileName.Trim('\"'); diff --git a/src/Umbraco.Web/Models/ContentEditing/ContentPropertyDto.cs b/src/Umbraco.Web/Models/ContentEditing/ContentPropertyDto.cs index b76552f0dc..1f9d0e9b77 100644 --- a/src/Umbraco.Web/Models/ContentEditing/ContentPropertyDto.cs +++ b/src/Umbraco.Web/Models/ContentEditing/ContentPropertyDto.cs @@ -16,12 +16,5 @@ namespace Umbraco.Web.Models.ContentEditing public bool IsRequired { get; set; } public string ValidationRegExp { get; set; } - /// - /// The culture for the property which is only relevant for variant properties - /// - /// - /// Since content currently is the only thing that can be variant this will only be relevant to content - /// - public string Culture { get; set; } } } diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyDtoConverter.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyDtoConverter.cs index 896aacd4ec..b8333b6229 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentPropertyDtoConverter.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyDtoConverter.cs @@ -27,16 +27,7 @@ namespace Umbraco.Web.Models.Mapping propertyDto.Description = property.PropertyType.Description; propertyDto.Label = property.PropertyType.Name; propertyDto.DataType = DataTypeService.GetDataType(property.PropertyType.DataTypeId); - - //Get the culture from the context which will be set during the mapping operation for each property - var culture = context.GetCulture(); - - //a culture needs to be in the context for a property type that can vary - if (culture == null && property.PropertyType.VariesByCulture()) - throw new InvalidOperationException($"No culture found in mapping operation when one is required for the culture variant property type {property.PropertyType.Alias}"); - - propertyDto.Culture = culture; - + return propertyDto; } }