From 4f3c271217845e0754c9f120e484e727e4111e99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 4 Nov 2020 16:33:04 +0100 Subject: [PATCH 01/90] set input file accept --- .../upload/umbpropertyfileupload.directive.js | 7 ++++--- .../upload/umbsinglefileupload.directive.js | 15 ++++++++++----- .../upload/umb-property-file-upload.html | 4 ++-- .../fileupload/fileupload.controller.js | 6 +++--- .../propertyeditors/fileupload/fileupload.html | 3 ++- 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbpropertyfileupload.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbpropertyfileupload.directive.js index db1e38adc626..5492fee1a0ab 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbpropertyfileupload.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbpropertyfileupload.directive.js @@ -85,7 +85,7 @@ /** Called when the component has linked all elements, this is when the form controller is available */ function postLink() { - + } function initialize() { @@ -186,7 +186,7 @@ }); } } - + } } @@ -325,7 +325,8 @@ */ onFilesChanged: "&", onInit: "&", - required: "=" + required: "=", + acceptFileExt: ""; + return { restrict: "E", scope: { - rebuild: "=" + rebuild: "=", + acceptFileExt: "", - link: function (scope, el, attrs) { + template: "
"+innerTemplate+"
", + link: function (scope, el) { scope.$watch("rebuild", function (newVal, oldVal) { if (newVal && newVal !== oldVal) { //recompile it! - el.html(""); + el.html(innerTemplate); $compile(el.contents())(scope); } }); @@ -30,4 +35,4 @@ function umbSingleFileUpload($compile) { }; } -angular.module('umbraco.directives').directive("umbSingleFileUpload", umbSingleFileUpload); \ No newline at end of file +angular.module('umbraco.directives').directive("umbSingleFileUpload", umbSingleFileUpload); diff --git a/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-property-file-upload.html b/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-property-file-upload.html index a6eb60d15cfe..09e85ff3995e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-property-file-upload.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-property-file-upload.html @@ -6,9 +6,9 @@

Click to upload

- +
- +
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 c485f4bbc6e9..4560025372d1 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 @@ -11,7 +11,7 @@ * */ function fileUploadController($scope, fileManager) { - + $scope.fileChanged = onFileChanged; //declare a special method which will be called whenever the value has changed from the server $scope.model.onValueChanged = onValueChanged; @@ -38,12 +38,12 @@ files: [] }); } - + }; angular.module("umbraco") .controller('Umbraco.PropertyEditors.FileUploadController', fileUploadController) - .run(function (mediaHelper, umbRequestHelper, assetsService) { + .run(function (mediaHelper) { if (mediaHelper && mediaHelper.registerFileResolver) { //NOTE: The 'entity' can be either a normal media entity or an "entity" returned from the entityResource diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.html index 522278e99ec4..1504f4ab04b9 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.html @@ -4,6 +4,7 @@ property-alias="{{model.alias}}" value="model.value" required="model.validation.mandatory" - on-files-selected="fileChanged(value)"> + on-files-selected="fileChanged(value)" + accept-file-ext="'.jpg,.png'">
From 732ee76542932ba09f0c885ede639f534cacb21b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 4 Nov 2020 17:52:24 +0100 Subject: [PATCH 02/90] Use PreValue file extensions for limiting the files to be chosen in file input --- .../fileupload/fileupload.controller.js | 3 +++ .../fileupload/fileupload.html | 2 +- .../FileUploadConfiguration.cs | 26 +++++++++++++++++++ .../FileUploadConfigurationEditor.cs | 14 ++++++++++ .../FileUploadPropertyEditor.cs | 4 +++ src/Umbraco.Web/Umbraco.Web.csproj | 2 ++ 6 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/Umbraco.Web/PropertyEditors/FileUploadConfiguration.cs create mode 100644 src/Umbraco.Web/PropertyEditors/FileUploadConfigurationEditor.cs 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 4560025372d1..9f9842261123 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 @@ -16,6 +16,9 @@ //declare a special method which will be called whenever the value has changed from the server $scope.model.onValueChanged = onValueChanged; + + $scope.fileExtensionsString = $scope.model.config.fileExtensions.map(x => "."+x.value).join(","); + /** * Called when the file selection value changes * @param {any} value diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.html index 1504f4ab04b9..36509e894796 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.html @@ -5,6 +5,6 @@ value="model.value" required="model.validation.mandatory" on-files-selected="fileChanged(value)" - accept-file-ext="'.jpg,.png'"> + accept-file-ext="fileExtensionsString">
diff --git a/src/Umbraco.Web/PropertyEditors/FileUploadConfiguration.cs b/src/Umbraco.Web/PropertyEditors/FileUploadConfiguration.cs new file mode 100644 index 000000000000..bf12b2a2d66a --- /dev/null +++ b/src/Umbraco.Web/PropertyEditors/FileUploadConfiguration.cs @@ -0,0 +1,26 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using Umbraco.Core.PropertyEditors; + +namespace Umbraco.Web.PropertyEditors +{ + /// + /// Represents the configuration for the file upload address value editor. + /// + public class FileUploadConfiguration + { + + [ConfigurationField("fileExtensions", "Accepted file extensions", "multivalues")] + public List FileExtensions { get; set; } = new List(); + + public class ValueListItem + { + [JsonProperty("id")] + public int Id { get; set; } + + [JsonProperty("value")] + public string Value { get; set; } + } + } +} diff --git a/src/Umbraco.Web/PropertyEditors/FileUploadConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/FileUploadConfigurationEditor.cs new file mode 100644 index 000000000000..4803254eb762 --- /dev/null +++ b/src/Umbraco.Web/PropertyEditors/FileUploadConfigurationEditor.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Umbraco.Core; +using Umbraco.Core.PropertyEditors; + +namespace Umbraco.Web.PropertyEditors +{ + /// + /// Represents the configuration editor for the file upload value editor. + /// + public class FileUploadConfigurationEditor : ConfigurationEditor + { + + } +} diff --git a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs index 052af18aa10a..a105d490be26 100644 --- a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs @@ -32,6 +32,10 @@ public FileUploadPropertyEditor(ILogger logger, IMediaFileSystem mediaFileSystem _uploadAutoFillProperties = new UploadAutoFillProperties(_mediaFileSystem, logger, contentSection); } + + /// + protected override IConfigurationEditor CreateConfigurationEditor() => new FileUploadConfigurationEditor(); + /// /// Creates the corresponding property value editor. /// diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 1b48b9ca0d37..fbd8acfdb941 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -258,6 +258,8 @@ + + From a76f64fc4c745dfc7b67bd64a1a923f2334fd14f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 5 Nov 2020 12:48:34 +0100 Subject: [PATCH 03/90] Current state for Warren to review --- src/Umbraco.Web/Editors/MediaController.cs | 42 ++++++++++++++++++- .../FileExtensionConfigItem.cs | 13 ++++++ .../FileUploadConfiguration.cs | 14 ++----- .../PropertyEditors/IFileExtensionConfig.cs | 13 ++++++ .../IFileExtensionConfigItem.cs | 11 +++++ src/Umbraco.Web/Umbraco.Web.csproj | 3 ++ 6 files changed, 84 insertions(+), 12 deletions(-) create mode 100644 src/Umbraco.Web/PropertyEditors/FileExtensionConfigItem.cs create mode 100644 src/Umbraco.Web/PropertyEditors/IFileExtensionConfig.cs create mode 100644 src/Umbraco.Web/PropertyEditors/IFileExtensionConfigItem.cs diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs index dfe6939552a7..d9fb7270e4bc 100644 --- a/src/Umbraco.Web/Editors/MediaController.cs +++ b/src/Umbraco.Web/Editors/MediaController.cs @@ -37,6 +37,8 @@ using Umbraco.Web.Editors.Binders; using Umbraco.Web.Editors.Filters; using Umbraco.Core.Models.Entities; +using static Umbraco.Web.PropertyEditors.FileUploadConfiguration; +using Umbraco.Web.PropertyEditors; namespace Umbraco.Web.Editors { @@ -704,10 +706,48 @@ public async Task PostAddFile() if (result.FormData["contentTypeAlias"] == Constants.Conventions.MediaTypes.AutoSelect) { - if (Current.Configs.Settings().Content.ImageFileTypes.Contains(ext)) + IEnumerable MediaTypes = Services.MediaTypeService.GetAll(); + // Look up MediaTypes + foreach (var MediaType in MediaTypes) + { + var fileProperty = MediaType.CompositionPropertyTypes.Where(x => x.Alias == "umbracoFile").FirstOrDefault(); + if (fileProperty != null) { + var dataTypeKey = fileProperty.DataTypeKey; + var dataType = Services.DataTypeService.GetDataType(dataTypeKey); + + if (dataType != null && dataType.Configuration is IFileExtensionsConfig fileExtensionsConfig) { + var fileExtensions = fileExtensionsConfig.FileExtensions; + if (fileExtensions != null) + { + if (fileExtensions.Where(x => x.Value == ext).Count() != 0) + { + mediaType = MediaType.Alias; + break; + } + } + } + + + /* + IDataEditor editor = Current.Data[propertyTypeAlias]; + List fileExtensions = (List)editor.DefaultConfiguration.GetValue("fileExtensions", null); + if (fileExtensions != null) { + if (fileExtensions.Where(x => x.Value == ext).Count() != 0) { + mediaType = MediaType.Alias; + break; + } + } + */ + } + + } + + // If media type is still File then lets check if its a image. + if (mediaType == Constants.Conventions.MediaTypes.File && Current.Configs.Settings().Content.ImageFileTypes.Contains(ext)) { mediaType = Constants.Conventions.MediaTypes.Image; } + } else { diff --git a/src/Umbraco.Web/PropertyEditors/FileExtensionConfigItem.cs b/src/Umbraco.Web/PropertyEditors/FileExtensionConfigItem.cs new file mode 100644 index 000000000000..859b3b35ebe6 --- /dev/null +++ b/src/Umbraco.Web/PropertyEditors/FileExtensionConfigItem.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json; + +namespace Umbraco.Web.PropertyEditors +{ + public class FileExtensionConfigItem : IFileExtensionConfigItem + { + [JsonProperty("id")] + public int Id { get; set; } + + [JsonProperty("value")] + public string Value { get; set; } + } +} diff --git a/src/Umbraco.Web/PropertyEditors/FileUploadConfiguration.cs b/src/Umbraco.Web/PropertyEditors/FileUploadConfiguration.cs index bf12b2a2d66a..f9c68659b3eb 100644 --- a/src/Umbraco.Web/PropertyEditors/FileUploadConfiguration.cs +++ b/src/Umbraco.Web/PropertyEditors/FileUploadConfiguration.cs @@ -8,19 +8,11 @@ namespace Umbraco.Web.PropertyEditors /// /// Represents the configuration for the file upload address value editor. /// - public class FileUploadConfiguration + public class FileUploadConfiguration : IFileExtensionsConfig { [ConfigurationField("fileExtensions", "Accepted file extensions", "multivalues")] - public List FileExtensions { get; set; } = new List(); - - public class ValueListItem - { - [JsonProperty("id")] - public int Id { get; set; } - - [JsonProperty("value")] - public string Value { get; set; } - } + //public List FileExtensions { get; set; } = new List(); + List IFileExtensionsConfig.FileExtensions { get; set; } = new List(); } } diff --git a/src/Umbraco.Web/PropertyEditors/IFileExtensionConfig.cs b/src/Umbraco.Web/PropertyEditors/IFileExtensionConfig.cs new file mode 100644 index 000000000000..bc222aaec09b --- /dev/null +++ b/src/Umbraco.Web/PropertyEditors/IFileExtensionConfig.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using Umbraco.Web.PropertyEditors; + +namespace Umbraco.Core.PropertyEditors +{ + /// + /// Marker interface for any editor configuration that supports defining file extensions + /// + public interface IFileExtensionsConfig + { + List FileExtensions { get; set; } + } +} diff --git a/src/Umbraco.Web/PropertyEditors/IFileExtensionConfigItem.cs b/src/Umbraco.Web/PropertyEditors/IFileExtensionConfigItem.cs new file mode 100644 index 000000000000..682e8815659a --- /dev/null +++ b/src/Umbraco.Web/PropertyEditors/IFileExtensionConfigItem.cs @@ -0,0 +1,11 @@ +using Newtonsoft.Json; + +namespace Umbraco.Web.PropertyEditors +{ + public interface IFileExtensionConfigItem + { + int Id { get; set; } + + string Value { get; set; } + } +} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index fbd8acfdb941..42d1b34f4ed9 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -257,6 +257,9 @@ + + + From 995b114b9eb208b540f7d93990558f16456a1c79 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 5 Nov 2020 14:09:04 +0000 Subject: [PATCH 04/90] This should fix up what you need Niels --- src/Umbraco.Web/Editors/MediaController.cs | 8 ++++---- .../PropertyEditors/FileUploadConfiguration.cs | 7 ++----- src/Umbraco.Web/PropertyEditors/IFileExtensionConfig.cs | 2 +- src/Umbraco.Web/Umbraco.Web.csproj | 4 ++-- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs index d9fb7270e4bc..3f3d5d68a8fb 100644 --- a/src/Umbraco.Web/Editors/MediaController.cs +++ b/src/Umbraco.Web/Editors/MediaController.cs @@ -706,11 +706,11 @@ public async Task PostAddFile() if (result.FormData["contentTypeAlias"] == Constants.Conventions.MediaTypes.AutoSelect) { - IEnumerable MediaTypes = Services.MediaTypeService.GetAll(); + var mediaTypes = Services.MediaTypeService.GetAll(); // Look up MediaTypes - foreach (var MediaType in MediaTypes) + foreach (var mediaTypeItem in mediaTypes) { - var fileProperty = MediaType.CompositionPropertyTypes.Where(x => x.Alias == "umbracoFile").FirstOrDefault(); + var fileProperty = mediaTypeItem.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == "umbracoFile"); if (fileProperty != null) { var dataTypeKey = fileProperty.DataTypeKey; var dataType = Services.DataTypeService.GetDataType(dataTypeKey); @@ -721,7 +721,7 @@ public async Task PostAddFile() { if (fileExtensions.Where(x => x.Value == ext).Count() != 0) { - mediaType = MediaType.Alias; + mediaType = mediaTypeItem.Alias; break; } } diff --git a/src/Umbraco.Web/PropertyEditors/FileUploadConfiguration.cs b/src/Umbraco.Web/PropertyEditors/FileUploadConfiguration.cs index f9c68659b3eb..aa1310776d9e 100644 --- a/src/Umbraco.Web/PropertyEditors/FileUploadConfiguration.cs +++ b/src/Umbraco.Web/PropertyEditors/FileUploadConfiguration.cs @@ -1,6 +1,4 @@ -using Newtonsoft.Json; -using System; -using System.Collections.Generic; +using System.Collections.Generic; using Umbraco.Core.PropertyEditors; namespace Umbraco.Web.PropertyEditors @@ -12,7 +10,6 @@ public class FileUploadConfiguration : IFileExtensionsConfig { [ConfigurationField("fileExtensions", "Accepted file extensions", "multivalues")] - //public List FileExtensions { get; set; } = new List(); - List IFileExtensionsConfig.FileExtensions { get; set; } = new List(); + List IFileExtensionsConfig.FileExtensions { get; set; } = new List(); } } diff --git a/src/Umbraco.Web/PropertyEditors/IFileExtensionConfig.cs b/src/Umbraco.Web/PropertyEditors/IFileExtensionConfig.cs index bc222aaec09b..c4934540c793 100644 --- a/src/Umbraco.Web/PropertyEditors/IFileExtensionConfig.cs +++ b/src/Umbraco.Web/PropertyEditors/IFileExtensionConfig.cs @@ -8,6 +8,6 @@ namespace Umbraco.Core.PropertyEditors /// public interface IFileExtensionsConfig { - List FileExtensions { get; set; } + List FileExtensions { get; set; } } } diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 42d1b34f4ed9..764d11d2fcc9 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -257,12 +257,12 @@ - - + + From 7aefd96d6f9cd6d9942878efdaaeb8d85c25fbf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 5 Nov 2020 16:31:51 +0100 Subject: [PATCH 05/90] update csproj --- src/Umbraco.Web/Umbraco.Web.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 42d1b34f4ed9..0fa7aa07c455 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -257,8 +257,8 @@ - - + + From cf320e5c81ccc27850938566a72a2bad982c9ea2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 9 Nov 2020 08:56:09 +0100 Subject: [PATCH 06/90] use empty string if fileExtensions is undefined --- .../views/propertyeditors/fileupload/fileupload.controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 9f9842261123..4f1016e68028 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 @@ -17,7 +17,7 @@ $scope.model.onValueChanged = onValueChanged; - $scope.fileExtensionsString = $scope.model.config.fileExtensions.map(x => "."+x.value).join(","); + $scope.fileExtensionsString = $scope.model.config.fileExtensions ? $scope.model.config.fileExtensions.map(x => "."+x.value).join(",") : ""; /** * Called when the file selection value changes From 45d44e3cae310cf004768b3c14a2481a3380fc3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 9 Nov 2020 12:41:11 +0100 Subject: [PATCH 07/90] public interface --- src/Umbraco.Web/PropertyEditors/FileUploadConfiguration.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web/PropertyEditors/FileUploadConfiguration.cs b/src/Umbraco.Web/PropertyEditors/FileUploadConfiguration.cs index aa1310776d9e..51259a90fa69 100644 --- a/src/Umbraco.Web/PropertyEditors/FileUploadConfiguration.cs +++ b/src/Umbraco.Web/PropertyEditors/FileUploadConfiguration.cs @@ -10,6 +10,6 @@ public class FileUploadConfiguration : IFileExtensionsConfig { [ConfigurationField("fileExtensions", "Accepted file extensions", "multivalues")] - List IFileExtensionsConfig.FileExtensions { get; set; } = new List(); + public List FileExtensions { get; set; } = new List(); } } From 4efdb90b6d25ba0e622e4e08d88dabc2b8bd301f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 10 Nov 2020 21:59:49 +0100 Subject: [PATCH 08/90] initial work --- src/Umbraco.Core/Constants-PropertyEditors.cs | 7 +- .../components/forms/validwhen.directive.js | 12 + .../validation/valservermatch.directive.js | 4 +- src/Umbraco.Web.UI.Client/src/less/belle.less | 1 + .../mediacard/umb-media-card-grid.less | 3 + .../components/mediacard/umb-media-card.html | 34 ++ .../components/mediacard/umb-media-card.less | 152 +++++++++ .../mediacard/umbMediaCard.component.js | 54 ++++ .../treesourcetypepicker.controller.js | 5 + .../mediapicker3/mediapicker3.html | 1 + .../prevalue/mediapicker3.crops.controller.js | 103 ++++++ .../prevalue/mediapicker3.crops.html | 96 ++++++ .../prevalue/mediapicker3.crops.less | 40 +++ .../umb-media-picker3-property-editor.html | 115 +++++++ ...umbMediaPicker3PropertyEditor.component.js | 297 ++++++++++++++++++ .../MediaPicker3Configuration.cs | 62 ++++ .../MediaPicker3ConfigurationEditor.cs | 29 ++ .../MediaPicker3PropertyEditor.cs | 58 ++++ src/Umbraco.Web/Umbraco.Web.csproj | 5 +- 19 files changed, 1074 insertions(+), 4 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/common/directives/components/forms/validwhen.directive.js create mode 100644 src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less create mode 100644 src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.html create mode 100644 src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less create mode 100644 src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js create mode 100644 src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/mediapicker3.html create mode 100644 src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.controller.js create mode 100644 src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.html create mode 100644 src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.less create mode 100644 src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.html create mode 100644 src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js create mode 100644 src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs create mode 100644 src/Umbraco.Web/PropertyEditors/MediaPicker3ConfigurationEditor.cs create mode 100644 src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs diff --git a/src/Umbraco.Core/Constants-PropertyEditors.cs b/src/Umbraco.Core/Constants-PropertyEditors.cs index dcd7eb9d0546..9def3df7ef50 100644 --- a/src/Umbraco.Core/Constants-PropertyEditors.cs +++ b/src/Umbraco.Core/Constants-PropertyEditors.cs @@ -90,12 +90,17 @@ public static class Aliases /// ListView. /// public const string ListView = "Umbraco.ListView"; - + /// /// Media Picker. /// public const string MediaPicker = "Umbraco.MediaPicker"; + /// + /// Media Picker v.4. + /// + public const string MediaPicker3 = "Umbraco.MediaPicker3"; + /// /// Multiple Media Picker. /// diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/validwhen.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/validwhen.directive.js new file mode 100644 index 000000000000..63681a380a3a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/validwhen.directive.js @@ -0,0 +1,12 @@ +angular.module("umbraco.directives").directive('validWhen', function () { + return { + require: 'ngModel', + restrict: 'A', + link: function (scope, element, attr, ngModel) { + + attr.$observe("validWhen", function (newValue) { + ngModel.$setValidity("validWhen", newValue === "true"); + }); + } + }; +}); diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valservermatch.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valservermatch.directive.js index 5f8600c8c0fe..b07ab55436f8 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valservermatch.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valservermatch.directive.js @@ -2,8 +2,8 @@ * @ngdoc directive * @name umbraco.directives.directive:valServerMatch * @restrict A - * @description A custom validator applied to a form/ng-form within an umbProperty that validates server side validation data - * contained within the serverValidationManager. The data can be matched on "exact", "prefix", "suffix" or "contains" matches against + * @description A custom validator applied to a form/ng-form within an umbProperty that validates server side validation data + * contained within the serverValidationManager. The data can be matched on "exact", "prefix", "suffix" or "contains" matches against * a property validation key. The attribute value can be in multiple value types: * - STRING = The property validation key to have an exact match on. If matched, then the form will have a valServerMatch validator applied. * - OBJECT = A dictionary where the key is the match type: "contains", "prefix", "suffix" and the value is either: diff --git a/src/Umbraco.Web.UI.Client/src/less/belle.less b/src/Umbraco.Web.UI.Client/src/less/belle.less index e5ce8d572cfd..7f8dd3dedf7e 100644 --- a/src/Umbraco.Web.UI.Client/src/less/belle.less +++ b/src/Umbraco.Web.UI.Client/src/less/belle.less @@ -213,6 +213,7 @@ @import "../views/propertyeditors/blocklist/blocklistentryeditors/unsupportedblock/unsupportedblock.editor.less"; @import "../views/propertyeditors/blocklist/blocklistentryeditors/labelblock/labelblock.editor.less"; @import "../views/propertyeditors/blocklist/blocklistentryeditors/inlineblock/inlineblock.editor.less"; +@import "../views/propertyeditors/MediaPicker3/prevalue/mediapicker3.crops.less"; // Utilities diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less new file mode 100644 index 000000000000..4eba1102b119 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less @@ -0,0 +1,3 @@ +.umb-media-card-grid { + +} diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.html b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.html new file mode 100644 index 000000000000..2222c22661d6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.html @@ -0,0 +1,34 @@ + +
+ + + {{vm.media.name}} + + + {{vm.media.name}} + + + + + +
+ + + + diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less new file mode 100644 index 000000000000..da27a29192e9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less @@ -0,0 +1,152 @@ +.umb-media-card, +umb-media-card { + position: relative; + display: inline-block; + width: 100%; + height: auto; + background-color: white; + border-radius: @doubleBorderRadius; + box-shadow: 0 1px 2px rgba(0,0,0,.2); + + transition: box-shadow 120ms; + + cursor: pointer; + + .umb-outline(); + + &:hover { + box-shadow: 0 1px 3px rgba(@ui-action-type-hover, .5); + } + + &.--isOpen { + &::after { + content: ""; + position: absolute; + border: 2px solid @ui-active-border; + border-radius: @doubleBorderRadius; + top:0; + bottom: 0; + left: 0; + right: 0; + } + } + + &.--sortable-placeholder { + &::after { + content: ""; + position: absolute; + background-color:rgba(@ui-drop-area-color, .05); + border: 2px solid rgba(@ui-drop-area-color, .1); + border-radius: @doubleBorderRadius; + box-shadow: 0 0 4px rgba(@ui-drop-area-color, 0.05); + top:0; + bottom: 0; + left: 0; + right: 0; + animation: umb-block-card--sortable-placeholder 400ms ease-in-out alternate infinite; + @keyframes umb-block-card--sortable-placeholder { + 0% { opacity: 1; } + 100% { opacity: 0.5; } + } + } + box-shadow: none; + } + + .__showcase { + position: relative; + width: 100%; + padding-bottom: 10/16*100%; + background-color: @gray-12; + + background-size: contain; + background-position: 50% 50%; + background-repeat: no-repeat; + + border-top-left-radius: @doubleBorderRadius; + border-top-right-radius: @doubleBorderRadius; + + &.--error { + border: 2px solid @errorBackground; + border-bottom: none; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + box-sizing: border-box; + } + + .__icon { + position: absolute; + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + font-size:42px; + } + } + + .__info { + width: 100%; + background-color: #fff; + padding-top: 10px; + padding-bottom: 11px;// 10 + 1 to compentiate for the -1 substraction in margin-bottom. + border-bottom-left-radius: @doubleBorderRadius; + border-bottom-right-radius: @doubleBorderRadius; + + &.--error { + background-color: @errorBackground; + .__name, .__subname { + color: @errorText; + } + } + + .__name { + font-weight: bold; + font-size: 14px; + color: @ui-action-type; + margin-left: 16px; + margin-bottom: -1px; + } + .__subname { + color: @gray-4; + font-size: 12px; + margin-left: 16px; + margin-top: 1px; + margin-bottom: -1px; + line-height: 1.5em; + } + } + + &:hover { + .__info:not(.--error) { + .__name { + color: @ui-action-type-hover; + } + } + } + + .__actions { + position: absolute; + top: 10px; + right: 0; + opacity: 0; + transition: opacity 120ms; + .__action { + display: inline-block; + border-radius: 50%; + width: 28px; + height: 28px; + margin-right: 10px; + background-color: white; + color:@ui-action-type; + &:hover { + color: @ui-action-type-hover; + } + } + } + &:hover, &:focus, &:focus-within { + .__actions { + opacity: 1; + } + } + +} diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js new file mode 100644 index 000000000000..13ee5a25eb8c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js @@ -0,0 +1,54 @@ +(function () { + "use strict"; + + angular + .module("umbraco") + .component("umbMediaCard", { + templateUrl: "views/components/mediacard/umb-media-card.html", + controller: MediaCardController, + controllerAs: "vm", + transclude: true, + bindings: { + mediaUdi: "<" + } + }); + + function MediaCardController($scope, entityResource) { + + var vm = this; + vm.loading = true; + + var unwatch = $scope.$watch("vm.mediaUdi", (newValue, oldValue) => { + if(newValue !== oldValue) { + vm.updateThumbnail(); + } + }); + + vm.$onInit = function () { + + vm.updateThumbnail(); + + } + vm.$onDestroy = function () { + unwatch(); + } + + vm.updateThumbnail = function () { + + vm.loading = true; + entityResource.getById(media.udi, "Media").then(function (mediaEntity) { + vm.media = mediaEntity; + vm.thumbnail = mediaHelper.resolveFileFromEntity(media, true); + vm.loading = false; + }); + } + + vm.clickButton = function () { + + console.log("click button!") + + } + + } + +})(); diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treesourcetypepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treesourcetypepicker.controller.js index a87377c84b8d..05043e0b9202 100644 --- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treesourcetypepicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treesourcetypepicker.controller.js @@ -93,6 +93,11 @@ function TreeSourceTypePickerController($scope, contentTypeResource, mediaTypeRe currentItemType = args.value; init(); }); + + if ($scope.model.config.itemType) { + currentItemType = $scope.model.config.itemType; + init(); + } } angular.module('umbraco').controller("Umbraco.PrevalueEditors.TreeSourceTypePickerController", TreeSourceTypePickerController); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/mediapicker3.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/mediapicker3.html new file mode 100644 index 000000000000..5e67aafe3e0b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/mediapicker3.html @@ -0,0 +1 @@ + diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.controller.js new file mode 100644 index 000000000000..418766994274 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.controller.js @@ -0,0 +1,103 @@ +angular.module("umbraco").controller("Umbraco.PropertyEditors.MediaPicker3.CropConfigurationController", + function ($scope) { + + var unsubscribe = []; + + if (!$scope.model.value) { + $scope.model.value = []; + } + + $scope.setFocus = false; + + $scope.remove = function (crop, evt) { + evt.preventDefault(); + const i = $scope.model.value.indexOf(crop); + if (i > -1) { + $scope.model.value.splice(i, 1); + } + }; + + $scope.edit = function (crop, evt) { + evt.preventDefault(); + crop.editMode = true; + }; + + $scope.addNewCrop = function (evt) { + evt.preventDefault(); + + var crop = {}; + crop.editMode = true; + + $scope.model.value.push(crop); + + } + $scope.setChanges = function (crop) { + if( + crop.hasWidthError !== true && + crop.hasHeightError !== true && + crop.hasAliasError !== true + ) { + crop.editMode = false; + } + }; + $scope.useForAlias = function (crop) { + if (crop.alias == null || crop.alias === "") { + crop.alias = crop.label.toCamelCase(); + } + }; + $scope.validateWidth = function (crop) { + crop.hasWidthError = !(Utilities.isNumber(crop.width) && crop.width > 0); + }; + $scope.validateHeight = function (crop) { + crop.hasHeightError = !(Utilities.isNumber(crop.height) && crop.height > 0); + }; + $scope.validateAlias = function (crop, $event) { + var exists = $scope.model.value.find( x => crop !== x && crop.alias === x.alias); + if (exists !== undefined || crop.alias === "") { + // alias is not valid + crop.hasAliasError = true; + } else { + // everything was good: + crop.hasAliasError = false; + } + + }; + + $scope.confirmChanges = function (crop, event) { + if (event.keyCode == 13) { + $scope.setChanges(crop, event); + event.preventDefault(); + } + }; + $scope.focusNextField = function (event) { + if (event.keyCode == 13) { + + var el = event.target; + + var inputs = Array.from(document.querySelectorAll("input:not(disabled)")); + var inputIndex = inputs.indexOf(el); + if (inputIndex > -1) { + var nextIndex = inputs.indexOf(el) +1; + + if(inputs.length > nextIndex) { + inputs[nextIndex].focus(); + event.preventDefault(); + } + } + } + }; + + $scope.sortableOptions = { + axis: 'y', + containment: 'parent', + cursor: 'move', + tolerance: 'pointer' + }; + + $scope.$on("$destroy", function () { + for (const subscription of unsubscribe) { + subscription(); + } + }); + + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.html new file mode 100644 index 000000000000..46b9ddb15f64 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.html @@ -0,0 +1,96 @@ +
+ +
+
+
+
+ Label +
+
+ Alias +
+
+ Width +
+
+ Height +
+
+ Actions +
+
+
+
+ +
+ +
{{crop.label}}
+
{{crop.alias}}
+
{{crop.width}}px
+
{{crop.height}}px
+
+ + +
+ + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+ +
+ +
+
+
+ + + +
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.less b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.less new file mode 100644 index 000000000000..5f5a2d468979 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.less @@ -0,0 +1,40 @@ +.umb-mediapicker3-crops { + + input.ng-invalid.ng-touched { + border-color:@formErrorBorder; + color:@formErrorBorder + } + + .umb-table button { + position: relative; + color: @ui-action-discreet-type; + margin-right: 10px; + font-size: 14px; + &:hover { + color: @ui-action-discreet-type-hover; + } + } + +} + +.umb-mediapicker3-crops__add { + + margin-top:10px; + + display: flex; + align-items: center; + justify-content: center; + background: transparent; + border: 1px dashed @ui-action-discreet-border; + color: @ui-action-discreet-type; + font-weight: bold; + padding: 5px 15px; + box-sizing: border-box; + width: 100%; +} + +.umb-mediapicker3-crops__add:hover { + color: @ui-action-discreet-type-hover; + border-color: @ui-action-discreet-border-hover; + text-decoration: none; +} diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.html new file mode 100644 index 000000000000..358e3d6898b0 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.html @@ -0,0 +1,115 @@ +
+ +

+

+ +
+
    +
  • + +

    + + +

    + +
    +
    +
    + + + {{media.name}} + + + {{media.name}} + + + + + +
    + + +
    +
  • +
  • + +
  • +
+
+ +
+ + + +
+ + + +
+ +
+ +
+ + + + + + +
+
+ + + + + + +
+
+ Minimum %0% entries, needs %1% more. +
+ > +
+
+
+ Maximum %0% entries, %1% too many. +
+ +
+ +
+ +
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js new file mode 100644 index 000000000000..5f991cb32503 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js @@ -0,0 +1,297 @@ +(function () { + "use strict"; + + + /** + * @ngdoc directive + * @name umbraco.directives.directive:umbMediaPicker3PropertyEditor + * @function + * + * @description + * The component for the Media Picker property editor. + */ + angular + .module("umbraco") + .component("umbMediaPicker3PropertyEditor", { + templateUrl: "views/propertyeditors/MediaPicker3/umb-media-picker3-property-editor.html", + controller: MediaPicker3Controller, + controllerAs: "vm", + bindings: { + model: "=" + }, + require: { + propertyForm: "^form", + umbProperty: "?^umbProperty", + umbVariantContent: '?^^umbVariantContent', + umbVariantContentEditors: '?^^umbVariantContentEditors', + umbElementEditorContent: '?^^umbElementEditorContent' + } + }); + + function MediaPicker3Controller($scope, editorService, clipboardService, localizationService, overlayService, userService) { + + var unsubscribe = []; + + // Property actions: + var copyAllBlocksAction = null; + var deleteAllBlocksAction = null; + + var vm = this; + + vm.loading = true; + vm.currentMediaInFocus = null; + vm.setMediaFocus = function (media) { + if (vm.currentMediaInFocus !== null) { + vm.currentMediaInFocus.focus = false; + } + vm.currentMediaInFocus = media; + media.focus = true; + }; + + vm.supportCopy = clipboardService.isSupported(); + + + vm.labels = {}; + + localizationService.localizeMany(["grid_addElement", "content_createEmpty"]).then(function (data) { + vm.labels.grid_addElement = data[0]; + vm.labels.content_createEmpty = data[1]; + }); + + vm.$onInit = function() { + + vm.singleMode = vm.model.config.singleMode || false; + vm.validationLimit = vm.model.config.validationLimit; + + if(typeof vm.model.value !== 'array' || vm.model.value === null) { + vm.model.value = []; + } + + copyAllBlocksAction = { + labelKey: "clipboard_labelForCopyAllEntries", + labelTokens: [vm.model.label], + icon: "documents", + method: requestCopyAllMedias, + isDisabled: true + }; + + deleteAllBlocksAction = { + labelKey: 'clipboard_labelForRemoveAllEntries', + labelTokens: [], + icon: 'trash', + method: requestDeleteAllMedia, + isDisabled: true + }; + + var propertyActions = [ + copyAllBlocksAction, + deleteAllBlocksAction + ]; + + if (vm.umbProperty) { + vm.umbProperty.setPropertyActions(propertyActions); + } + + userService.getCurrentUser().then(function (userData) { + + if (!vm.model.config.startNodeId) { + if (vm.model.config.ignoreUserStartNodes === true) { + vm.model.config.startNodeId = -1; + vm.model.config.startNodeIsVirtual = true; + } else { + vm.model.config.startNodeId = userData.startMediaIds.length !== 1 ? -1 : userData.startMediaIds[0]; + vm.model.config.startNodeIsVirtual = userData.startMediaIds.length !== 1; + } + } + + // only allow users to add and edit media if they have access to the media section + var hasAccessToMedia = userData.allowedSections.indexOf("media") !== -1; + vm.allowEdit = hasAccessToMedia; + vm.allowAdd = hasAccessToMedia; + + vm.loading = false; + }); + + }; + + function setDirty() { + if (vm.propertyForm) { + vm.propertyForm.$setDirty(); + } + } + + vm.add = add; + function add() { + var mediaPicker = { + startNodeId: vm.model.config.startNodeId, + startNodeIsVirtual: vm.model.config.startNodeIsVirtual, + //dataTypeKey: vm.model.dataTypeKey, + multiPicker: vm.isSingleMode !== true, + submit: function (model) { + editorService.close(); + setDirty(); + }, + close: function (model) { + editorService.close(); + reloadUpdatedMediaItems(model.updatedMediaNodes); + } + } + + editorService.mediaPicker(mediaPicker); + } + + + function deleteAllMedias() { + vm.model.value = []; + } + + function activateBlock(mediaObject) { + mediaObject.active = true; + } + + function editBlock(mediaObject, mediaIndex, parentForm) { + + options = options || {}; + + // this must be set + if (mediaIndex === undefined) { + throw "mediaIndex was not specified on call to editBlock"; + } + + var wasNotActiveBefore = mediaObject.active !== true; + activateMedia(mediaObject); + + // make a clone to avoid editing model directly. + var mediaObjectClone = Utilities.copy(mediaObject); + + var blockEditorModel = { + $parentScope: $scope, // pass in a $parentScope, this maintains the scope inheritance in infinite editing + $parentForm: parentForm || vm.propertyForm, // pass in a $parentForm, this maintains the FormController hierarchy with the infinite editing view (if it contains a form) + createFlow: options.createFlow === true, + title: mediaObjectClone.label, + view: "views/common/infiniteeditors/MediaPicker3/mediapicker.html", + submit: function(blockEditorModel) { + mediaObject.active = false; + editorService.close(); + }, + close: function(model) { + if (model.createFlow) { + deleteBlock(mediaObject); + } else { + if (wasNotActiveBefore === true) { + mediaObject.active = false; + } + } + editorService.close(); + } + }; + + // open property settings editor + editorService.open(blockEditorModel); + } + + vm.showAddDialog = showAddDialog; + function showAddDialog(createIndex, $event) { + console.log("shoa add dialog") + }; + + var requestCopyAllMedias = function() { + // TODO.. + } + function copyBlock(block) { + //clipboardService.copy(clipboardService.TYPES.BLOCK, block.content.contentTypeAlias, {"layout": block.layout, "data": block.data, "settingsData":block.settingsData}, block.label, block.content.icon, block.content.udi); + } + function requestPasteFromClipboard(index, pasteEntry, pasteType) { + + if (pasteEntry === undefined) { + return false; + } + + //TODO... + + return true; + + } + + function requestDeleteBlock(block) { + localizationService.localizeMany(["general_delete", "blockEditor_confirmDeleteBlockMessage", "contentTypeEditor_yesDelete"]).then(function (data) { + const overlay = { + title: data[0], + content: localizationService.tokenReplace(data[1], [block.label]), + submitButtonLabel: data[2], + close: function () { + overlayService.close(); + }, + submit: function () { + deleteBlock(block); + overlayService.close(); + } + }; + + overlayService.confirmDelete(overlay); + }); + } + function requestDeleteAllMedia() { + localizationService.localizeMany(["content_nestedContentDeleteAllItems", "general_delete"]).then(function (data) { + overlayService.confirmDelete({ + title: data[1], + content: data[0], + close: function () { + overlayService.close(); + }, + submit: function () { + deleteAllBlocks(); + overlayService.close(); + } + }); + }); + } + + + vm.sortableOptions = { + axis: "y", + containment: "parent", + cursor: "grabbing", + handle: "umb-media-card", + cancel: "input,textarea,select,option", + classes: ".umb-media-card--dragging", + distance: 5, + tolerance: "pointer", + scroll: true, + update: function (ev, ui) { + setDirty(); + } + }; + + + function onAmountOfMediaChanged() { + + // enable/disable property actions + if (copyAllBlocksAction) { + copyAllBlocksAction.isDisabled = vm.model.value.length === 0; + } + if (deleteAllBlocksAction) { + deleteAllBlocksAction.isDisabled = vm.model.value.length === 0; + } + + // validate limits: + if (vm.propertyForm && vm.validationLimit) { + + var isMinRequirementGood = vm.validationLimit.min === null || vm.model.value.length >= vm.validationLimit.min; + vm.propertyForm.minCount.$setValidity("minCount", isMinRequirementGood); + + var isMaxRequirementGood = vm.validationLimit.max === null || vm.model.value.length <= vm.validationLimit.max; + vm.propertyForm.maxCount.$setValidity("maxCount", isMaxRequirementGood); + } + } + + unsubscribe.push($scope.$watch(() => vm.model.value.length, onAmountOfMediaChanged)); + + $scope.$on("$destroy", function () { + for (const subscription of unsubscribe) { + subscription(); + } + }); + } + +})(); diff --git a/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs b/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs new file mode 100644 index 000000000000..0417e90612ef --- /dev/null +++ b/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs @@ -0,0 +1,62 @@ +using Newtonsoft.Json; +using System.Collections.Generic; +using Umbraco.Core; +using Umbraco.Core.PropertyEditors; + +namespace Umbraco.Web.PropertyEditors +{ + /// + /// Represents the configuration for the media picker value editor. + /// + public class MediaPicker3Configuration : IIgnoreUserStartNodesConfig + { + + [ConfigurationField("filter", "Accepted types", "treesourcetypepicker", + Description = "Limit to specific types")] + public string Filter { get; set; } + + [ConfigurationField("singleMode", "Single Mode", "boolean")] + public bool SingleMode { get; set; } + + [ConfigurationField("validationLimit", "Amount", "numberrange", Description = "Set a required range of medias")] + public NumberRange ValidationLimit { get; set; } = new NumberRange(); + + public class NumberRange + { + [JsonProperty("min")] + public int? Min { get; set; } + + [JsonProperty("max")] + public int? Max { get; set; } + } + + [ConfigurationField("startNodeId", "Start node", "mediapicker")] + public Udi StartNodeId { get; set; } + + [ConfigurationField(Core.Constants.DataTypes.ReservedPreValueKeys.IgnoreUserStartNodes, + "Ignore User Start Nodes", "boolean", + Description = "Selecting this option allows a user to choose nodes that they normally don't have access to.")] + public bool IgnoreUserStartNodes { get; set; } + + [ConfigurationField("crops", "Image Croppings", "views/propertyeditors/MediaPicker3/prevalue/mediapicker3.crops.html")] + public CropConfiguration[] Crops { get; set; } + + public class CropConfiguration + { + [JsonProperty("alias")] + public string Alias { get; set; } + + [JsonProperty("label")] + public string Label { get; set; } + + [JsonProperty("width")] + public int Width { get; set; } + + [JsonProperty("height")] + public int Height { get; set; } + + [JsonProperty("mandatory")] + public bool Mandatory { get; set; } + } + } +} diff --git a/src/Umbraco.Web/PropertyEditors/MediaPicker3ConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/MediaPicker3ConfigurationEditor.cs new file mode 100644 index 000000000000..268da64eb52b --- /dev/null +++ b/src/Umbraco.Web/PropertyEditors/MediaPicker3ConfigurationEditor.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using Umbraco.Core.PropertyEditors; + +namespace Umbraco.Web.PropertyEditors +{ + /// + /// Represents the configuration editor for the media picker value editor. + /// + public class MediaPicker3ConfigurationEditor : ConfigurationEditor + { + /// + /// Initializes a new instance of the class. + /// + public MediaPicker3ConfigurationEditor() + { + // configure fields + // this is not part of ContentPickerConfiguration, + // but is required to configure the UI editor (when editing the configuration) + + Field(nameof(MediaPicker3Configuration.StartNodeId)) + .Config = new Dictionary { { "idType", "udi" } }; + + Field(nameof(MediaPicker3Configuration.Filter)) + .Config = new Dictionary { { "itemType", "media" } }; + + } + + } +} diff --git a/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs new file mode 100644 index 000000000000..2c6d600b91af --- /dev/null +++ b/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs @@ -0,0 +1,58 @@ +using System.Collections.Generic; +using Umbraco.Core; +using Umbraco.Core.Logging; +using Umbraco.Core.Models.Editors; +using Umbraco.Core.PropertyEditors; + +namespace Umbraco.Web.PropertyEditors +{ + /// + /// Represents a media picker property editor. + /// + [DataEditor( + Constants.PropertyEditors.Aliases.MediaPicker3, + EditorType.PropertyValue | EditorType.MacroParameter, + "Media Picker v3", + "mediapicker3", + ValueType = ValueTypes.Text, + Group = Constants.PropertyEditors.Groups.Media, + Icon = Constants.Icons.MediaImage)] + public class MediaPicker3PropertyEditor : DataEditor + { + + /// + /// Initializes a new instance of the class. + /// + public MediaPicker3PropertyEditor(ILogger logger) + : base(logger) + { + } + + /// + protected override IConfigurationEditor CreateConfigurationEditor() => new MediaPicker3ConfigurationEditor(); + + protected override IDataValueEditor CreateValueEditor() => new MediaPicker3PropertyValueEditor(Attribute); + + internal class MediaPicker3PropertyValueEditor : DataValueEditor, IDataValueReference + { + public MediaPicker3PropertyValueEditor(DataEditorAttribute attribute) : base(attribute) + { + } + + public IEnumerable GetReferences(object value) + { + var asString = value is string str ? str : value?.ToString(); + + if (string.IsNullOrEmpty(asString)) yield break; + + foreach (var udiStr in asString.Split(',')) + { + if (Udi.TryParse(udiStr, out var udi)) + yield return new UmbracoEntityReference(udi); + } + } + } + } + + +} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 6f7d2b3166d7..1a6d35acf686 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -264,6 +264,9 @@ + + + @@ -1309,4 +1312,4 @@ - \ No newline at end of file + From 203605700c217a6b9d29113d5b319ef3bd7cbe67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Sat, 14 Nov 2020 09:58:25 +0100 Subject: [PATCH 09/90] local crops --- src/Umbraco.Web.UI.Client/src/less/belle.less | 5 +- .../mediaentryeditor.controller.js | 147 ++++++++++++++++++ .../mediapicker3/mediaentryeditor.html | 107 +++++++++++++ .../mediacard/umb-media-card-grid.less | 136 +++++++++++++++- .../components/mediacard/umb-media-card.html | 25 +-- .../components/mediacard/umb-media-card.less | 67 ++++---- .../mediacard/umbMediaCard.component.js | 41 +++-- .../src/views/media/media.edit.controller.js | 60 +++---- .../umb-media-picker3-property-editor.html | 104 ++++--------- .../umb-media-picker3-property-editor.less | 3 + ...umbMediaPicker3PropertyEditor.component.js | 115 +++++++++----- ...3PropertyEditor.createButton.controller.js | 18 +++ .../MediaPicker3PropertyEditor.cs | 18 ++- 13 files changed, 641 insertions(+), 205 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.controller.js create mode 100644 src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.html create mode 100644 src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.less create mode 100644 src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.createButton.controller.js diff --git a/src/Umbraco.Web.UI.Client/src/less/belle.less b/src/Umbraco.Web.UI.Client/src/less/belle.less index 7f8dd3dedf7e..8038320cf379 100644 --- a/src/Umbraco.Web.UI.Client/src/less/belle.less +++ b/src/Umbraco.Web.UI.Client/src/less/belle.less @@ -213,7 +213,10 @@ @import "../views/propertyeditors/blocklist/blocklistentryeditors/unsupportedblock/unsupportedblock.editor.less"; @import "../views/propertyeditors/blocklist/blocklistentryeditors/labelblock/labelblock.editor.less"; @import "../views/propertyeditors/blocklist/blocklistentryeditors/inlineblock/inlineblock.editor.less"; -@import "../views/propertyeditors/MediaPicker3/prevalue/mediapicker3.crops.less"; +@import "../views/components/mediacard/umb-media-card-grid.less"; +@import "../views/components/mediacard/umb-media-card.less"; +@import "../views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.less"; +@import "../views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.less"; // Utilities diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.controller.js new file mode 100644 index 000000000000..079cdba0f8c2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.controller.js @@ -0,0 +1,147 @@ +angular.module("umbraco") + .controller("Umbraco.Editors.MediaEntryEditorController", + function ($scope, localizationService, entityResource, overlayService, eventsService, mediaHelper) { + + var unsubscribe = []; + var vm = this; + + vm.loading = true; + vm.model = $scope.model; + vm.mediaEntry = vm.model.mediaEntry; + + localizationService.localizeMany([ + vm.model.createFlow ? "general_cancel" : "general_close", + vm.model.createFlow ? "general_create" : "buttons_submitChanges" + ]).then(function (data) { + vm.closeLabel = data[0]; + vm.submitLabel = data[1]; + }); + + console.log("MediaEntryEditorController", vm.model, vm.mediaEntry); + + function init() { + + updateMedia(); + + unsubscribe.push(eventsService.on("editors.media.saved", function(name, args) { + // if this media item uses the updated media type we want to reload the media file + if(args && args.media && args.media.key === vm.model.mediaEntry.mediaKey) { + updateMedia(); + } + })); + } + + function updateMedia() { + + // TODO: test that we update a media if its saved.. + console.log("updateMedia", vm.model.mediaEntry.mediaKey); + + vm.loading = true; + entityResource.getById(vm.model.mediaEntry.mediaKey, "Media").then(function (mediaEntity) { + vm.media = mediaEntity; + vm.imageSrc = mediaHelper.resolveFileFromEntity(mediaEntity, true); + vm.loading = false; + vm.hasDimensions = false; + vm.isCroppable = false; + console.log(vm.media); + }, function () { + localizationService.localize("mediaPicker_deletedItem").then(function (localized) { + vm.media = { + name: localized, + icon: "icon-picture", + trashed: true + }; + vm.loading = false; + vm.hasDimensions = false; + vm.isCroppable = false; + console.log(vm.media); + }); + }); + } + + vm.onImageLoaded = onImageLoaded; + function onImageLoaded(isCroppable, hasDimensions) { + console.log("onImageLoaded") + vm.isCroppable = isCroppable; + vm.hasDimensions = hasDimensions; + }; + + + vm.focalPointChanged = function(left, top) { + //update the model focalpoint value + vm.mediaEntry.focalPoint = { + left: left, + top: top + }; + + //set form to dirty to track changes + vm.imageCropperForm.$setDirty(); + } + + + + /** + * crop a specific crop + * @param {any} targetCrop + */ + vm.onCropClicked = onCropClicked; + function onCropClicked(targetCrop) { + if (vm.currentCrop === targetCrop) { + vm.currentCrop = null; + } else { + vm.currentCrop = targetCrop; + vm.imageCropperForm.$setDirty(); + } + }; + + function resetCrop(crop) { + // TODO: find a way to reset. + //vm.currentCrop.coordinates = {}; + //crop.defined = false;// concept? + vm.imageCropperForm.$setDirty(); + } + + + + vm.submitAndClose = function () { + if (vm.model && vm.model.submit) { + vm.model.submit(vm.model); + } + } + + vm.close = function () { + if (vm.model && vm.model.close) { + if (vm.model.createFlow === true || vm.imageCropperForm.$dirty === true) { + var labels = vm.model.createFlow === true ? ["blockEditor_confirmCancelBlockCreationHeadline", "blockEditor_confirmCancelBlockCreationMessage"] : ["prompt_discardChanges", "blockEditor_blockHasChanges"]; + localizationService.localizeMany(labels).then(function (localizations) { + const confirm = { + title: localizations[0], + view: "default", + content: localizations[1], + submitButtonLabelKey: "general_discard", + submitButtonStyle: "danger", + closeButtonLabelKey: "prompt_stay", + submit: function () { + overlayService.close(); + vm.model.close(vm.model); + }, + close: function () { + overlayService.close(); + } + }; + overlayService.open(confirm); + }); + } else { + vm.model.close(vm.model); + } + + } + } + + init(); + $scope.$on("$destroy", function () { + unsubscribe.forEach(x => x()); + }); + + } + ); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.html new file mode 100644 index 000000000000..273a8382ed1c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.html @@ -0,0 +1,107 @@ +
+ + + + + + + + +
+ +
+ This item is in the Recycle Bin +
+ +
+
+ +
+
+ +
+ + +
+ +
+ +
+ +
+
+ +
+ + + + +
+ + +
    +
  • + + + + +
    + {{crop.alias}} + {{crop.width}}px x {{crop.height}}px + User defined  +
    +
  • +
+ +
+
+ +
+ + + + + + + + + + + + + + + + +
+
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less index 4eba1102b119..b2fd0e1c2da7 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less @@ -1,3 +1,137 @@ .umb-media-card-grid { - + /* Grid Setup */ + display: grid; + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + grid-auto-rows: minmax(160px, auto); + grid-gap: 10px; + + justify-items: center; + align-items: center; + + padding: 20px; + border: 1px solid @inputBorder; +} +.umb-media-card-grid__cell { + position: relative; + display: flex; + height: 100%; + align-items: center; +} + +.umb-media-card-grid--inline-create-button { + position: absolute; + height: 100%; + z-index: 1; + opacity: 0; + outline: none; + width: 12px; + margin-left: -9px; + padding-left: 6px; + margin-right: -6px; + transition: opacity 240ms; + + &::before { + content: ''; + position: absolute; + background: @blueMid; + background: linear-gradient(0deg, rgba(@blueMid,0) 0%, rgba(@blueMid,1) 50%, rgba(@blueMid,0) 100%); + border-left: 1px solid white; + border-right: 1px solid white; + border-radius: 2px; + left: 0; + top: 0; + bottom: 0; + width: 2px; + animation: umb-media-card-grid--inline-create-button_before 400ms ease-in-out alternate infinite; + transform: scaleX(.99); + transition: transform 240ms ease-out; + + @keyframes umb-media-card-grid--inline-create-button_before { + 0% { opacity: 1; } + 100% { opacity: 0.5; } + } + } + + > .__plus { + position: absolute; + display: flex; + justify-content: center; + align-items: center; + pointer-events: none; // lets stop avoiding the mouse values in JS move event. + box-sizing: border-box; + width: 28px; + height: 28px; + margin-left: -18px; + margin-top: -18px - 8px; + border-radius: 3em; + font-size: 14px; + border: 2px solid @blueMid; + color: @blueMid; + background-color: rgba(255, 255, 255, .96); + box-shadow: 0 0 0 2px rgba(255, 255, 255, .96); + transform: scale(0); + transition: transform 240ms ease-in; + + animation: umb-media-card-grid--inline-create-button__plus 400ms ease-in-out alternate infinite; + + @keyframes umb-media-card-grid--inline-create-button__plus { + 0% { color: rgba(@blueMid, 1); } + 100% { color: rgba(@blueMid, 0.8); } + } + + } + + &:focus { + > .__plus { + border-color: @ui-outline; + } + } + + &:hover, &:focus { + opacity: 1; + + &::before { + transform: scaleX(1); + } + > .__plus { + transform: scale(1); + transition-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1.275); + + } + } +} + +.umb-media-card-grid__create-button { + position: relative; + width: 100%; + padding-bottom: 100%; + + border: 1px dashed @ui-action-discreet-border; + color: @ui-action-discreet-type; + font-weight: bold; + box-sizing: border-box; + border-radius: @baseBorderRadius; + + > div { + position: absolute; + height: 100%; + width: 100%; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + } +} + +.umb-media-card-grid__create-button:hover { + color: @ui-action-discreet-type-hover; + border-color: @ui-action-discreet-border-hover; + text-decoration: none; +} + +.umb-media-card-grid__create-button.--disabled, +.umb-media-card-grid__create-button.--disabled:hover { + color: @gray-7; + border-color: @gray-7; + cursor: default; } diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.html b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.html index 2222c22661d6..aea28877b650 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.html @@ -1,22 +1,23 @@ -
+
- - {{vm.media.name}} +
- - + {{vm.media.name}} + + -
- diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less index da27a29192e9..6a5eb60d1306 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less @@ -2,11 +2,11 @@ umb-media-card { position: relative; display: inline-block; - width: 100%; - height: auto; - background-color: white; - border-radius: @doubleBorderRadius; - box-shadow: 0 1px 2px rgba(0,0,0,.2); + width: 200px; + //background-color: white; + border-radius: @baseBorderRadius; + //box-shadow: 0 1px 2px rgba(0,0,0,.2); + overflow: hidden; transition: box-shadow 120ms; @@ -23,7 +23,7 @@ umb-media-card { content: ""; position: absolute; border: 2px solid @ui-active-border; - border-radius: @doubleBorderRadius; + border-radius: @baseBorderRadius; top:0; bottom: 0; left: 0; @@ -37,7 +37,7 @@ umb-media-card { position: absolute; background-color:rgba(@ui-drop-area-color, .05); border: 2px solid rgba(@ui-drop-area-color, .1); - border-radius: @doubleBorderRadius; + border-radius: @baseBorderRadius; box-shadow: 0 0 4px rgba(@ui-drop-area-color, 0.05); top:0; bottom: 0; @@ -54,16 +54,12 @@ umb-media-card { .__showcase { position: relative; - width: 100%; - padding-bottom: 10/16*100%; - background-color: @gray-12; - - background-size: contain; - background-position: 50% 50%; - background-repeat: no-repeat; - - border-top-left-radius: @doubleBorderRadius; - border-top-right-radius: @doubleBorderRadius; + max-width: 100%; + min-height: 120px; + max-height: 240px; + text-align: center; + //padding-bottom: 10/16*100%; + //background-color: @gray-12; &.--error { border: 2px solid @errorBackground; @@ -72,27 +68,43 @@ umb-media-card { border-top-right-radius: 6px; box-sizing: border-box; } + + img { + object-fit: contain; + max-height: 240px; + } - .__icon { - position: absolute; + umb-file-icon { width: 100%; - height: 100%; - display: flex; - align-items: center; - justify-content: center; - font-size:42px; + padding-bottom: 100%; + display: block; + .umb-file-icon { + position: absolute; + top: 0; + bottom: 30px; + left: 10px; + right: 10px; + display: flex; + align-items: center; + justify-content: center; + } } } .__info { + position: absolute; + text-align: left; + bottom: 0; width: 100%; background-color: #fff; padding-top: 10px; padding-bottom: 11px;// 10 + 1 to compentiate for the -1 substraction in margin-bottom. - border-bottom-left-radius: @doubleBorderRadius; - border-bottom-right-radius: @doubleBorderRadius; + + opacity: 0; + transition: opacity 120ms; &.--error { + opacity: 1; background-color: @errorBackground; .__name, .__subname { color: @errorText; @@ -117,6 +129,9 @@ umb-media-card { } &:hover { + .__info { + opacity: 1; + } .__info:not(.--error) { .__name { color: @ui-action-type-hover; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js index 13ee5a25eb8c..f99acaaea77d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js @@ -9,16 +9,19 @@ controllerAs: "vm", transclude: true, bindings: { - mediaUdi: "<" + mediaKey: "<", + onNameClicked: "&?" } }); - function MediaCardController($scope, entityResource) { + function MediaCardController($scope, entityResource, mediaHelper, eventsService, localizationService) { + var unsubscribe = []; var vm = this; + vm.paddingBottom = 100;// Square while loading. vm.loading = true; - var unwatch = $scope.$watch("vm.mediaUdi", (newValue, oldValue) => { + var unwatch = $scope.$watch("vm.mediaKey", (newValue, oldValue) => { if(newValue !== oldValue) { vm.updateThumbnail(); } @@ -28,24 +31,42 @@ vm.updateThumbnail(); + unsubscribe.push(eventsService.on("editors.media.saved", function(name, args) { + // if this media item uses the updated media type we want to reload the media file + if(args && args.media && args.media.key === vm.mediaKey) { + vm.updateThumbnail(); + } + })); } + + vm.$onDestroy = function () { unwatch(); + unsubscribe.forEach(x => x()); } vm.updateThumbnail = function () { + // TODO: test that we update a media if its saved.. + console.log("updateThumbnail", vm.mediaKey) + vm.loading = true; - entityResource.getById(media.udi, "Media").then(function (mediaEntity) { + + entityResource.getById(vm.mediaKey, "Media").then(function (mediaEntity) { vm.media = mediaEntity; - vm.thumbnail = mediaHelper.resolveFileFromEntity(media, true); + vm.thumbnail = mediaHelper.resolveFileFromEntity(mediaEntity, true); + vm.loading = false; + }, function () { + localizationService.localize("mediaPicker_deletedItem").then(function (localized) { + vm.media = { + name: localized, + icon: "icon-picture", + trashed: true + }; + vm.loading = false; + }); }); - } - - vm.clickButton = function () { - - console.log("click button!") } diff --git a/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js index f41f22a1a9c9..57bb037f939a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js @@ -2,29 +2,29 @@ * @ngdoc controller * @name Umbraco.Editors.Media.EditController * @function - * + * * @description * The controller for the media editor */ -function mediaEditController($scope, $routeParams, $location, $http, $q, appState, mediaResource, - entityResource, navigationService, notificationsService, localizationService, - serverValidationManager, contentEditingHelper, fileManager, formHelper, +function mediaEditController($scope, $routeParams, $location, $http, $q, appState, mediaResource, + entityResource, navigationService, notificationsService, localizationService, + serverValidationManager, contentEditingHelper, fileManager, formHelper, editorState, umbRequestHelper, eventsService) { - + var evts = []; var nodeId = null; var create = false; var infiniteMode = $scope.model && $scope.model.infiniteMode; - // when opening the editor through infinite editing get the + // when opening the editor through infinite editing get the // node id from the model instead of the route param if(infiniteMode && $scope.model.id) { nodeId = $scope.model.id; } else { nodeId = $routeParams.id; } - - // when opening the editor through infinite editing get the + + // when opening the editor through infinite editing get the // create option from the model instead of the route param if(infiniteMode) { create = $scope.model.create; @@ -72,22 +72,22 @@ function mediaEditController($scope, $routeParams, $location, $http, $q, appStat } function init() { - + var content = $scope.content; - + // we need to check whether an app is present in the current data, if not we will present the default app. var isAppPresent = false; - + // on first init, we dont have any apps. but if we are re-initializing, we do, but ... if ($scope.app) { - + // lets check if it still exists as part of our apps array. (if not we have made a change to our docType, even just a re-save of the docType it will turn into new Apps.) content.apps.forEach(app => { if (app === $scope.app) { isAppPresent = true; } }); - + // if we did reload our DocType, but still have the same app we will try to find it by the alias. if (isAppPresent === false) { content.apps.forEach(app => { @@ -98,9 +98,9 @@ function mediaEditController($scope, $routeParams, $location, $http, $q, appStat } }); } - + } - + // if we still dont have a app, lets show the first one: if (isAppPresent === false) { content.apps[0].active = true; @@ -108,16 +108,16 @@ function mediaEditController($scope, $routeParams, $location, $http, $q, appStat } editorState.set($scope.content); - + bindEvents(); } - + function bindEvents() { //bindEvents can be called more than once and we don't want to have multiple bound events for (var e in evts) { eventsService.unsubscribe(evts[e]); } - + evts.push(eventsService.on("editors.mediaType.saved", function(name, args) { // if this media item uses the updated media type we need to reload the media item if(args && args.mediaType && args.mediaType.key === $scope.content.contentType.key) { @@ -131,7 +131,7 @@ function mediaEditController($scope, $routeParams, $location, $http, $q, appStat })); } $scope.page.submitButtonLabelKey = "buttons_save"; - + /** Syncs the content item to it's tree node - this occurs on first load and after saving */ function syncTreeNode(content, path, initialLoad) { @@ -149,7 +149,7 @@ function mediaEditController($scope, $routeParams, $location, $http, $q, appStat //it's a child item, just sync the ui node to the parent navigationService.syncTree({ tree: "media", path: path.substring(0, path.lastIndexOf(",")).split(","), forceReload: initialLoad !== true }); - //if this is a child of a list view and it's the initial load of the editor, we need to get the tree node + //if this is a child of a list view and it's the initial load of the editor, we need to get the tree node // from the server so that we can load in the actions menu. umbRequestHelper.resourcePromise( $http.get(content.treeNodeUrl), @@ -176,7 +176,7 @@ function mediaEditController($scope, $routeParams, $location, $http, $q, appStat $scope.save = function () { if (formHelper.submitForm({ scope: $scope })) { - + $scope.page.saveButtonState = "busy"; mediaResource.save($scope.content, create, fileManager.getFiles()) @@ -200,7 +200,7 @@ function mediaEditController($scope, $routeParams, $location, $http, $q, appStat editorState.set($scope.content); syncTreeNode($scope.content, data.path); - + $scope.page.saveButtonState = "success"; init(); @@ -213,16 +213,16 @@ function mediaEditController($scope, $routeParams, $location, $http, $q, appStat err: err, rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, err.data) }); - + editorState.set($scope.content); $scope.page.saveButtonState = "error"; }); } else { - showValidationNotification(); + showValidationNotification(); } - + }; function loadMedia() { @@ -231,7 +231,7 @@ function mediaEditController($scope, $routeParams, $location, $http, $q, appStat .then(function (data) { $scope.content = data; - + if (data.isChildOfListView && data.trashed === false) { $scope.page.listViewPath = ($routeParams.page) ? "/media/media/edit/" + data.parentId + "?page=" + $routeParams.page @@ -247,9 +247,9 @@ function mediaEditController($scope, $routeParams, $location, $http, $q, appStat serverValidationManager.notifyAndClearAllSubscriptions(); if(!infiniteMode) { - syncTreeNode($scope.content, data.path, true); + syncTreeNode($scope.content, data.path, true); } - + if ($scope.content.parentId && $scope.content.parentId !== -1 && $scope.content.parentId !== -21) { //We fetch all ancestors of the node to generate the footer breadcrump navigation entityResource.getAncestors(nodeId, "media") @@ -279,7 +279,7 @@ function mediaEditController($scope, $routeParams, $location, $http, $q, appStat $scope.appChanged = function (app) { $scope.app = app; - + // setup infinite mode if(infiniteMode) { $scope.page.submitButtonLabelKey = "buttons_saveAndClose"; @@ -296,7 +296,7 @@ function mediaEditController($scope, $routeParams, $location, $http, $q, appStat $location.path($scope.page.listViewPath.split("?")[0]); } }; - + //ensure to unregister from all events! $scope.$on('$destroy', function () { for (var e in evts) { diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.html index 358e3d6898b0..ebc5385a47eb 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.html @@ -1,97 +1,49 @@ -
- -

-

- -
-
    -
  • - -

    - - -

    - -
    -
    -
    - - - {{media.name}} - - - {{media.name}} - - - - - -
    - - -
    -
  • -
  • - -
  • -
-
- -
- - - -
+
-
+
-
+
- - + +
+ +
- diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.less b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.less new file mode 100644 index 000000000000..20d7445bcc50 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.less @@ -0,0 +1,3 @@ +.umb-mediapicker3 { + +} diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js index 5f991cb32503..9b95738b42b4 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js @@ -60,13 +60,11 @@ vm.$onInit = function() { + console.log("property model: ", vm.model) + vm.singleMode = vm.model.config.singleMode || false; vm.validationLimit = vm.model.config.validationLimit; - if(typeof vm.model.value !== 'array' || vm.model.value === null) { - vm.model.value = []; - } - copyAllBlocksAction = { labelKey: "clipboard_labelForCopyAllEntries", labelTokens: [vm.model.label], @@ -92,6 +90,12 @@ vm.umbProperty.setPropertyActions(propertyActions); } + if(vm.model.value === null || !Array.isArray(vm.model.value)) { + vm.model.value = []; + } + + vm.model.value.forEach(mediaEntry => updateMediaEntryData(mediaEntry)); + userService.getCurrentUser().then(function (userData) { if (!vm.model.config.startNodeId) { @@ -110,6 +114,8 @@ vm.allowAdd = hasAccessToMedia; vm.loading = false; + + //editMedia(vm.model.value[0]); }); }; @@ -120,8 +126,8 @@ } } - vm.add = add; - function add() { + vm.addMediaAt = addMediaAt; + function addMediaAt(createIndex, $event) { var mediaPicker = { startNodeId: vm.model.config.startNodeId, startNodeIsVirtual: vm.model.config.startNodeIsVirtual, @@ -129,72 +135,98 @@ multiPicker: vm.isSingleMode !== true, submit: function (model) { editorService.close(); + + var indexIncrementor = 0; + model.selection.forEach((entry) => { + var mediaEntry = {}; + mediaEntry.key = String.CreateGuid(); + mediaEntry.mediaKey = entry.key; + updateMediaEntryData(mediaEntry); + vm.model.value.splice(createIndex + indexIncrementor, 0, mediaEntry); + indexIncrementor++; + }); + setDirty(); }, - close: function (model) { + close: function () { editorService.close(); - reloadUpdatedMediaItems(model.updatedMediaNodes); } } editorService.mediaPicker(mediaPicker); } + function updateMediaEntryData(mediaEntry) { + + mediaEntry.crops = mediaEntry.crops || []; + mediaEntry.focalPoint = mediaEntry.focalPoint || { + left: 0.5, + top: 0.5 + };; + + // Copy config and only transfer coordinates. + var newCrops = Utilities.copy(vm.model.config.crops); + newCrops.forEach(crop => { + console.log("mediaEntry.crops", mediaEntry.crops); + var oldCrop = mediaEntry.crops.filter(x => x.alias === crop.alias).shift(); + console.log("oldCrop", oldCrop); + if (oldCrop && oldCrop.height === crop.height && oldCrop.width === crop.width) { + crop.coordinates = oldCrop.coordinates; + } + }); + mediaEntry.crops = newCrops; + + } + function deleteAllMedias() { vm.model.value = []; } - function activateBlock(mediaObject) { - mediaObject.active = true; + vm.activeMediaEntry = null; + function setActiveMedia(mediaEntryOrNull) { + vm.activeMediaEntry = mediaEntryOrNull; } - function editBlock(mediaObject, mediaIndex, parentForm) { + vm.editMedia = editMedia; + function editMedia(mediaEntry, options) { options = options || {}; - // this must be set - if (mediaIndex === undefined) { - throw "mediaIndex was not specified on call to editBlock"; - } - - var wasNotActiveBefore = mediaObject.active !== true; - activateMedia(mediaObject); + setActiveMedia(mediaEntry); // make a clone to avoid editing model directly. - var mediaObjectClone = Utilities.copy(mediaObject); + var mediaEntryClone = Utilities.copy(mediaEntry); - var blockEditorModel = { + var mediaEditorModel = { $parentScope: $scope, // pass in a $parentScope, this maintains the scope inheritance in infinite editing - $parentForm: parentForm || vm.propertyForm, // pass in a $parentForm, this maintains the FormController hierarchy with the infinite editing view (if it contains a form) + $parentForm: vm.propertyForm, // pass in a $parentForm, this maintains the FormController hierarchy with the infinite editing view (if it contains a form) createFlow: options.createFlow === true, - title: mediaObjectClone.label, - view: "views/common/infiniteeditors/MediaPicker3/mediapicker.html", - submit: function(blockEditorModel) { - mediaObject.active = false; + title: "TODO media editor label", + mediaEntry: mediaEntryClone, + //cropsConfig: config.crops, + //api: vm, + view: "views/common/infiniteeditors/mediapicker3/mediaEntryEditor.html", + size: "large", + submit: function(model) { + vm.model.value[vm.model.value.indexOf(mediaEntry)] = mediaEntryClone; + setActiveMedia(null) editorService.close(); }, close: function(model) { - if (model.createFlow) { - deleteBlock(mediaObject); - } else { - if (wasNotActiveBefore === true) { - mediaObject.active = false; - } + if(model.createFlow === true) { + // This means that the user cancelled the creation and we should remove the media item. + // TODO: remove new media item. } + setActiveMedia(null) editorService.close(); } }; // open property settings editor - editorService.open(blockEditorModel); + editorService.open(mediaEditorModel); } - vm.showAddDialog = showAddDialog; - function showAddDialog(createIndex, $event) { - console.log("shoa add dialog") - }; - var requestCopyAllMedias = function() { // TODO.. } @@ -213,7 +245,7 @@ } - function requestDeleteBlock(block) { + function requestDeleteMedia(media) { localizationService.localizeMany(["general_delete", "blockEditor_confirmDeleteBlockMessage", "contentTypeEditor_yesDelete"]).then(function (data) { const overlay = { title: data[0], @@ -223,7 +255,7 @@ overlayService.close(); }, submit: function () { - deleteBlock(block); + deleteMedia(media); overlayService.close(); } }; @@ -240,7 +272,7 @@ overlayService.close(); }, submit: function () { - deleteAllBlocks(); + deleteAllMedias(); overlayService.close(); } }); @@ -249,8 +281,7 @@ vm.sortableOptions = { - axis: "y", - containment: "parent", + //containment: "parent", cursor: "grabbing", handle: "umb-media-card", cancel: "input,textarea,select,option", diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.createButton.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.createButton.controller.js new file mode 100644 index 000000000000..b561784d9f06 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.createButton.controller.js @@ -0,0 +1,18 @@ +(function () { + "use strict"; + + angular + .module("umbraco") + .controller("Umbraco.PropertyEditors.MediaPicker3PropertyEditor.CreateButtonController", + function Controller($scope) { + + var vm = this; + vm.plusPosY = 0; + + vm.onMouseMove = function($event) { + vm.plusPosY = $event.offsetY; + } + + }); + +})(); diff --git a/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs index 2c6d600b91af..28d2aac2e52d 100644 --- a/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs @@ -1,7 +1,5 @@ -using System.Collections.Generic; -using Umbraco.Core; +using Umbraco.Core; using Umbraco.Core.Logging; -using Umbraco.Core.Models.Editors; using Umbraco.Core.PropertyEditors; namespace Umbraco.Web.PropertyEditors @@ -11,15 +9,16 @@ namespace Umbraco.Web.PropertyEditors /// [DataEditor( Constants.PropertyEditors.Aliases.MediaPicker3, - EditorType.PropertyValue | EditorType.MacroParameter, + EditorType.PropertyValue, "Media Picker v3", "mediapicker3", - ValueType = ValueTypes.Text, + ValueType = ValueTypes.Json, Group = Constants.PropertyEditors.Groups.Media, Icon = Constants.Icons.MediaImage)] public class MediaPicker3PropertyEditor : DataEditor { + /// /// Initializes a new instance of the class. /// @@ -33,12 +32,13 @@ public MediaPicker3PropertyEditor(ILogger logger) protected override IDataValueEditor CreateValueEditor() => new MediaPicker3PropertyValueEditor(Attribute); - internal class MediaPicker3PropertyValueEditor : DataValueEditor, IDataValueReference + internal class MediaPicker3PropertyValueEditor : DataValueEditor { public MediaPicker3PropertyValueEditor(DataEditorAttribute attribute) : base(attribute) { } + /* public IEnumerable GetReferences(object value) { var asString = value is string str ? str : value?.ToString(); @@ -51,8 +51,12 @@ public IEnumerable GetReferences(object value) yield return new UmbracoEntityReference(udi); } } + */ + } - } + + } + } From fcda22b764da2243c9487b26a209d43f59a5d600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Sat, 14 Nov 2020 10:14:52 +0100 Subject: [PATCH 10/90] translations --- .../mediaentryeditor.controller.js | 5 +--- .../mediapicker3/mediaentryeditor.html | 23 +++++++++++++++---- ...umbMediaPicker3PropertyEditor.component.js | 4 ++-- src/Umbraco.Web.UI/Umbraco/config/lang/da.xml | 9 ++++++++ src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 9 ++++++++ .../Umbraco/config/lang/en_us.xml | 9 ++++++++ 6 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.controller.js index 079cdba0f8c2..d6a1c93469c0 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.controller.js @@ -43,7 +43,6 @@ angular.module("umbraco") vm.loading = false; vm.hasDimensions = false; vm.isCroppable = false; - console.log(vm.media); }, function () { localizationService.localize("mediaPicker_deletedItem").then(function (localized) { vm.media = { @@ -54,14 +53,12 @@ angular.module("umbraco") vm.loading = false; vm.hasDimensions = false; vm.isCroppable = false; - console.log(vm.media); }); }); } vm.onImageLoaded = onImageLoaded; function onImageLoaded(isCroppable, hasDimensions) { - console.log("onImageLoaded") vm.isCroppable = isCroppable; vm.hasDimensions = hasDimensions; }; @@ -112,7 +109,7 @@ angular.module("umbraco") vm.close = function () { if (vm.model && vm.model.close) { if (vm.model.createFlow === true || vm.imageCropperForm.$dirty === true) { - var labels = vm.model.createFlow === true ? ["blockEditor_confirmCancelBlockCreationHeadline", "blockEditor_confirmCancelBlockCreationMessage"] : ["prompt_discardChanges", "blockEditor_blockHasChanges"]; + var labels = vm.model.createFlow === true ? ["media_confirmCancelMediaEntryCreationHeadline", "media_confirmCancelMediaEntryCreationMessage"] : ["prompt_discardChanges", "media_confirmCancelMediaEntryHasChanges"]; localizationService.localizeMany(labels).then(function (localizations) { const confirm = { title: localizations[0], diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.html index 273a8382ed1c..2e6cda170bb3 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.html @@ -15,7 +15,7 @@
-
+
This item is in the Recycle Bin
@@ -43,11 +43,24 @@
- + + + + + +
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js index 9b95738b42b4..83f3b106e012 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js @@ -246,7 +246,7 @@ } function requestDeleteMedia(media) { - localizationService.localizeMany(["general_delete", "blockEditor_confirmDeleteBlockMessage", "contentTypeEditor_yesDelete"]).then(function (data) { + localizationService.localizeMany(["general_delete", "media_confirmRemoveMediaEntryMessage", "general_remove"]).then(function (data) { const overlay = { title: data[0], content: localizationService.tokenReplace(data[1], [block.label]), @@ -264,7 +264,7 @@ }); } function requestDeleteAllMedia() { - localizationService.localizeMany(["content_nestedContentDeleteAllItems", "general_delete"]).then(function (data) { + localizationService.localizeMany(["media_confirmRemoveAllMediaEntryMessage", "general_remove"]).then(function (data) { overlayService.confirmDelete({ title: data[1], content: data[0], diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml index cc728e364087..50c26462084b 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml @@ -1081,6 +1081,15 @@ Mange hilsner fra Umbraco robotten Du har valgt et medie som er slettet eller lagt i papirkurven Du har valgt medier som er slettede eller lagt i papirkurven Slettet + Åben medie + Udskift mediet + Nulstil medie beskæring + Rediger brugen af%0% + Annuller indsættelse? + + Du har foretaget ændringer til bruge af dette media. Er du sikker på at du vil annullere? + Fjern? + Fjern brugen af alle medier? indtast eksternt link diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml index 3cacea1674eb..9838a2012a7d 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml @@ -1331,6 +1331,15 @@ To manage your website, simply open the Umbraco back office and start adding con You have picked a media item currently deleted or in the recycle bin You have picked media items currently deleted or in the recycle bin Trashed + Open media + Replace media + Reset media crop + Edit usage of %0% + Discard creation? + + You have made changes to this content. Are you sure you want to discard them? + Remove? + Remove all medias? enter external link 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 b86424a68db3..904fe7189384 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml @@ -1341,6 +1341,15 @@ To manage your website, simply open the Umbraco back office and start adding con You have picked a media item currently deleted or in the recycle bin You have picked media items currently deleted or in the recycle bin Trashed + Open media + Replace media + Reset media crop + Edit usage of %0% + Discard creation? + + You have made changes to this content. Are you sure you want to discard them? + Remove? + Remove all medias? enter external link From 74e5dea58258c0217a99dee7d92eef1a2de00e77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Sat, 14 Nov 2020 10:23:26 +0100 Subject: [PATCH 11/90] translation correction --- .../infiniteeditors/mediapicker3/mediaentryeditor.html | 4 ++-- .../mediapicker3/umbMediaPicker3PropertyEditor.component.js | 5 +++-- src/Umbraco.Web.UI/Umbraco/config/lang/da.xml | 2 +- src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 2 +- src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml | 2 +- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.html index 2e6cda170bb3..1c1c7681367b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.html @@ -61,8 +61,8 @@ text="{{vm.media.name}}"> - - + +
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js index 83f3b106e012..aaa3a4ad51b8 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js @@ -53,9 +53,10 @@ vm.labels = {}; - localizationService.localizeMany(["grid_addElement", "content_createEmpty"]).then(function (data) { + localizationService.localizeMany(["grid_addElement", "content_createEmpty", "mediaPicker_editMediaEntryLabel"]).then(function (data) { vm.labels.grid_addElement = data[0]; vm.labels.content_createEmpty = data[1]; + vm.labels.mediaPicker_editMediaEntryLabel = data[2]; }); vm.$onInit = function() { @@ -202,7 +203,7 @@ $parentScope: $scope, // pass in a $parentScope, this maintains the scope inheritance in infinite editing $parentForm: vm.propertyForm, // pass in a $parentForm, this maintains the FormController hierarchy with the infinite editing view (if it contains a form) createFlow: options.createFlow === true, - title: "TODO media editor label", + title: vm.label.mediaPicker_editMediaEntryLabel, mediaEntry: mediaEntryClone, //cropsConfig: config.crops, //api: vm, diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml index 50c26462084b..9473f022ec36 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml @@ -1084,7 +1084,7 @@ Mange hilsner fra Umbraco robotten Åben medie Udskift mediet Nulstil medie beskæring - Rediger brugen af%0% + Rediger medie tilretninger Annuller indsættelse? Du har foretaget ændringer til bruge af dette media. Er du sikker på at du vil annullere? diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml index 9838a2012a7d..33aecac9022b 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml @@ -1334,7 +1334,7 @@ To manage your website, simply open the Umbraco back office and start adding con Open media Replace media Reset media crop - Edit usage of %0% + Edit media adjustments Discard creation? You have made changes to this content. Are you sure you want to discard them? 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 904fe7189384..3afcc72aafaa 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml @@ -1344,7 +1344,7 @@ To manage your website, simply open the Umbraco back office and start adding con Open media Replace media Reset media crop - Edit usage of %0% + Edit media adjustments Discard creation? You have made changes to this content. Are you sure you want to discard them? From 450df17d19acf9377fa3fa97b8f2685c337556cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 16 Nov 2020 08:18:20 +0100 Subject: [PATCH 12/90] fix misspeling --- .../mediapicker3/umbMediaPicker3PropertyEditor.component.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js index aaa3a4ad51b8..f69bcc622795 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js @@ -203,7 +203,7 @@ $parentScope: $scope, // pass in a $parentScope, this maintains the scope inheritance in infinite editing $parentForm: vm.propertyForm, // pass in a $parentForm, this maintains the FormController hierarchy with the infinite editing view (if it contains a form) createFlow: options.createFlow === true, - title: vm.label.mediaPicker_editMediaEntryLabel, + title: vm.labels.mediaPicker_editMediaEntryLabel, mediaEntry: mediaEntryClone, //cropsConfig: config.crops, //api: vm, From 755c709ccaa3cd78b1cecc13edddfc1f569b4b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 23 Nov 2020 13:11:29 +0100 Subject: [PATCH 13/90] some progress --- .../infiniteeditors/mediapicker/mediapicker.controller.js | 1 + .../mediapicker3/umbMediaPicker3PropertyEditor.component.js | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js index 7214e0b0ea4a..58a678a4aa80 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js @@ -40,6 +40,7 @@ angular.module("umbraco") $scope.lastOpenedNode = localStorageService.get("umbLastOpenedMediaNodeId"); $scope.lockedFolder = true; $scope.allowMediaEdit = dialogOptions.allowMediaEdit ? dialogOptions.allowMediaEdit : false; + $scope.onlySpecificMediaTypes = dialogOptions.onlySpecificMediaTypes || null; $scope.filterOptions = { excludeSubFolders: umbSessionStorage.get("mediaPickerExcludeSubFolders") || false diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js index f69bcc622795..ca37d16e6c64 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js @@ -168,9 +168,7 @@ // Copy config and only transfer coordinates. var newCrops = Utilities.copy(vm.model.config.crops); newCrops.forEach(crop => { - console.log("mediaEntry.crops", mediaEntry.crops); var oldCrop = mediaEntry.crops.filter(x => x.alias === crop.alias).shift(); - console.log("oldCrop", oldCrop); if (oldCrop && oldCrop.height === crop.height && oldCrop.width === crop.width) { crop.coordinates = oldCrop.coordinates; } @@ -231,8 +229,8 @@ var requestCopyAllMedias = function() { // TODO.. } - function copyBlock(block) { - //clipboardService.copy(clipboardService.TYPES.BLOCK, block.content.contentTypeAlias, {"layout": block.layout, "data": block.data, "settingsData":block.settingsData}, block.label, block.content.icon, block.content.udi); + function copyMedia(media) { + //clipboardService.copy(clipboardService.TYPES.MEDIA, block.content.contentTypeAlias, {"layout": block.layout, "data": block.data, "settingsData":block.settingsData}, block.label, block.content.icon, block.content.udi); } function requestPasteFromClipboard(index, pasteEntry, pasteType) { From 2d67e81ecd2eeff3775eef733e4e64697040cd71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 23 Nov 2020 13:45:03 +0100 Subject: [PATCH 14/90] filter media picker --- .../src/less/components/umb-media-grid.less | 8 +++- .../mediapicker/mediapicker.controller.js | 1 - .../src/views/components/umb-media-grid.html | 2 +- .../umb-media-picker3-property-editor.html | 2 +- ...umbMediaPicker3PropertyEditor.component.js | 43 ++++++++++++------- 5 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-media-grid.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-media-grid.less index d05139a06fcf..344681afd670 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-media-grid.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-media-grid.less @@ -100,6 +100,12 @@ opacity: .75; } } +.umb-media-grid__item.-filtered { + cursor:not-allowed; + * { + pointer-events: none; + } +} .umb-media-grid__item-file-icon { transform: translate(-50%,-50%); @@ -180,7 +186,7 @@ } } -.umb-media-grid__item-name { +.umb-media-grid__item-overlay { cursor: pointer; } diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js index 58a678a4aa80..7214e0b0ea4a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js @@ -40,7 +40,6 @@ angular.module("umbraco") $scope.lastOpenedNode = localStorageService.get("umbLastOpenedMediaNodeId"); $scope.lockedFolder = true; $scope.allowMediaEdit = dialogOptions.allowMediaEdit ? dialogOptions.allowMediaEdit : false; - $scope.onlySpecificMediaTypes = dialogOptions.onlySpecificMediaTypes || null; $scope.filterOptions = { excludeSubFolders: umbSessionStorage.get("mediaPickerExcludeSubFolders") || false diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html index f41390bce3a7..20e2efbd416c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html @@ -6,7 +6,7 @@ ng-click="clickItem(item, $event, $index)" ng-repeat="item in items | filter:filterBy" ng-style="item.flexStyle" - ng-class="{'-selected': item.selected, '-file': !item.thumbnail, '-folder': item.isFolder, '-svg': item.extension == 'svg', '-selectable': item.selectable, '-unselectable': !item.selectable}"> + ng-class="{'-selected': item.selected, '-file': !item.thumbnail, '-folder': item.isFolder, '-svg': item.extension == 'svg', '-selectable': item.selectable, '-unselectable': !item.selectable, '-filtered': item.filtered}">
- diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js index ca37d16e6c64..fea823e790bf 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js @@ -33,8 +33,8 @@ var unsubscribe = []; // Property actions: - var copyAllBlocksAction = null; - var deleteAllBlocksAction = null; + var copyAllMediasAction = null; + var removeAllMediasAction = null; var vm = this; @@ -66,7 +66,7 @@ vm.singleMode = vm.model.config.singleMode || false; vm.validationLimit = vm.model.config.validationLimit; - copyAllBlocksAction = { + copyAllMediasAction = { labelKey: "clipboard_labelForCopyAllEntries", labelTokens: [vm.model.label], icon: "documents", @@ -74,17 +74,17 @@ isDisabled: true }; - deleteAllBlocksAction = { + removeAllMediasAction = { labelKey: 'clipboard_labelForRemoveAllEntries', labelTokens: [], icon: 'trash', - method: requestDeleteAllMedia, + method: requestRemoveAllMedia, isDisabled: true }; var propertyActions = [ - copyAllBlocksAction, - deleteAllBlocksAction + copyAllMediasAction, + removeAllMediasAction ]; if (vm.umbProperty) { @@ -132,7 +132,7 @@ var mediaPicker = { startNodeId: vm.model.config.startNodeId, startNodeIsVirtual: vm.model.config.startNodeIsVirtual, - //dataTypeKey: vm.model.dataTypeKey, + dataTypeKey: vm.model.dataTypeKey, multiPicker: vm.isSingleMode !== true, submit: function (model) { editorService.close(); @@ -154,6 +154,10 @@ } } + if(vm.model.config.filter) { + mediaPicker.filter = vm.model.config.filter; + } + editorService.mediaPicker(mediaPicker); } @@ -178,6 +182,12 @@ } + function removeMedia(media) { + var index = vm.model.value.indexOf(media); + if(index !== -1) { + vm.model.value.splice(index, 1); + } + } function deleteAllMedias() { vm.model.value = []; } @@ -244,17 +254,18 @@ } - function requestDeleteMedia(media) { + vm.requestRemoveMedia = requestRemoveMedia; + function requestRemoveMedia(media) { localizationService.localizeMany(["general_delete", "media_confirmRemoveMediaEntryMessage", "general_remove"]).then(function (data) { const overlay = { title: data[0], - content: localizationService.tokenReplace(data[1], [block.label]), + content: localizationService.tokenReplace(data[1], [media.name]), submitButtonLabel: data[2], close: function () { overlayService.close(); }, submit: function () { - deleteMedia(media); + removeMedia(media); overlayService.close(); } }; @@ -262,7 +273,7 @@ overlayService.confirmDelete(overlay); }); } - function requestDeleteAllMedia() { + function requestRemoveAllMedia() { localizationService.localizeMany(["media_confirmRemoveAllMediaEntryMessage", "general_remove"]).then(function (data) { overlayService.confirmDelete({ title: data[1], @@ -297,11 +308,11 @@ function onAmountOfMediaChanged() { // enable/disable property actions - if (copyAllBlocksAction) { - copyAllBlocksAction.isDisabled = vm.model.value.length === 0; + if (copyAllMediasAction) { + copyAllMediasAction.isDisabled = vm.model.value.length === 0; } - if (deleteAllBlocksAction) { - deleteAllBlocksAction.isDisabled = vm.model.value.length === 0; + if (removeAllMediasAction) { + removeAllMediasAction.isDisabled = vm.model.value.length === 0; } // validate limits: From 1b4502cf29982411f58b34cc4922644083fe5b1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 23 Nov 2020 14:11:02 +0100 Subject: [PATCH 15/90] align media card grid items correctly --- .../src/views/components/mediacard/umb-media-card-grid.less | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less index b2fd0e1c2da7..907e0659c404 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less @@ -16,6 +16,7 @@ display: flex; height: 100%; align-items: center; + justify-content: center; } .umb-media-card-grid--inline-create-button { @@ -24,6 +25,7 @@ z-index: 1; opacity: 0; outline: none; + left: 0; width: 12px; margin-left: -9px; padding-left: 6px; From 17e6681ed64528dfb9f895f1bad66f3bc7525ff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 26 Nov 2020 10:21:51 +0100 Subject: [PATCH 16/90] responsive media cropper --- .../imaging/umbimagecrop.directive.js | 246 +++++++++++------- .../common/services/cropperhelper.service.js | 46 ++-- src/Umbraco.Web.UI.Client/src/less/belle.less | 1 + .../src/less/property-editors.less | 71 +++-- .../mediaentryeditor.controller.js | 60 +++-- .../mediaentryeditor.html | 69 +++-- .../mediaentryeditor/mediaentryeditor.less | 78 ++++++ .../components/imaging/umb-image-crop.html | 16 +- .../mediacard/umb-media-card-grid.less | 7 +- .../components/mediacard/umb-media-card.less | 8 +- .../imagecropper/imagecropper.html | 3 +- .../prevalue/mediapicker3.crops.controller.js | 2 +- ...umbMediaPicker3PropertyEditor.component.js | 50 +++- 13 files changed, 446 insertions(+), 211 deletions(-) rename src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/{mediapicker3 => mediaentryeditor}/mediaentryeditor.controller.js (79%) rename src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/{mediapicker3 => mediaentryeditor}/mediaentryeditor.html (57%) create mode 100644 src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js index f1f2cb38e84c..6abe91898ae0 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js @@ -6,7 +6,7 @@ **/ angular.module("umbraco.directives") .directive('umbImageCrop', - function ($timeout, cropperHelper) { + function ($timeout, $window, cropperHelper) { return { restrict: 'E', replace: true, @@ -17,21 +17,26 @@ angular.module("umbraco.directives") height: '@', crop: "=", center: "=", - maxSize: '@' + maxSize: '@', + alias: '@?', + forceUpdate: '@?' }, link: function (scope, element, attrs) { + var unsubscribe = []; let sliderRef = null; - scope.width = 400; - scope.height = 320; + scope.loaded = false; + scope.width = 0; + scope.height = 0; scope.dimensions = { + element: {}, image: {}, cropper: {}, viewport: {}, - margin: 20, + margin: {}, scale: { min: 0, max: 3, @@ -59,19 +64,24 @@ angular.module("umbraco.directives") scope.setup = function (slider) { sliderRef = slider; - - // Set slider handle position - sliderRef.noUiSlider.set(scope.dimensions.scale.current); - - // Update slider range min/max - sliderRef.noUiSlider.updateOptions({ - "range": { - "min": scope.dimensions.scale.min, - "max": scope.dimensions.scale.max - } - }); + updateSlider(); }; + function updateSlider() { + if(sliderRef) { + // Set slider handle position + sliderRef.noUiSlider.set(scope.dimensions.scale.current); + + // Update slider range min/max + sliderRef.noUiSlider.updateOptions({ + "range": { + "min": scope.dimensions.scale.min, + "max": scope.dimensions.scale.max + } + }); + } + } + scope.slide = function (values) { if (values) { scope.dimensions.scale.current = parseFloat(values); @@ -84,77 +94,102 @@ angular.module("umbraco.directives") } }; + //live rendering of viewport and image styles - scope.style = function () { - return { - 'height': (parseInt(scope.dimensions.viewport.height, 10)) + 'px', - 'width': (parseInt(scope.dimensions.viewport.width, 10)) + 'px' + function updateStyles() { + /* + scope.viewportStyle = { + 'top': (parseInt(scope.dimensions.image.top + scope.dimensions.margin.top, 10)) + 'px', + 'left': (parseInt(scope.dimensions.image.left + scope.dimensions.margin.left, 10)) + 'px', + 'width': (parseInt(scope.dimensions.image.width, 10)) + 'px', + 'height': (parseInt(scope.dimensions.image.height, 10)) + 'px' }; + */ + scope.maskStyle = { + 'height': (parseInt(scope.dimensions.cropper.height, 10)) + 'px', + 'width': (parseInt(scope.dimensions.cropper.width, 10)) + 'px', + 'top': (parseInt(scope.dimensions.margin.top, 10)) + 'px', + 'left': (parseInt(scope.dimensions.margin.left, 10)) + 'px' + } }; + updateStyles(); //elements var $viewport = element.find(".viewport"); var $image = element.find("img"); var $overlay = element.find(".overlay"); - var $container = element.find(".crop-container"); + //var $container = element.find(".crop-container"); //default constraints for drag n drop - var constraints = { left: { max: scope.dimensions.margin, min: scope.dimensions.margin }, top: { max: scope.dimensions.margin, min: scope.dimensions.margin } }; + var constraints = { left: { max: 0, min: 0 }, top: { max: 0, min: 0 } }; scope.constraints = constraints; //set constaints for cropping drag and drop var setConstraints = function () { - constraints.left.min = scope.dimensions.margin + scope.dimensions.cropper.width - scope.dimensions.image.width; - constraints.top.min = scope.dimensions.margin + scope.dimensions.cropper.height - scope.dimensions.image.height; + constraints.left.min = scope.dimensions.cropper.width - scope.dimensions.image.width; + constraints.top.min = scope.dimensions.cropper.height - scope.dimensions.image.height; }; - var setDimensions = function (originalImage) { - originalImage.width("auto"); - originalImage.height("auto"); - - var image = {}; - image.originalWidth = originalImage.width(); - image.originalHeight = originalImage.height(); - - image.width = image.originalWidth; - image.height = image.originalHeight; - image.left = originalImage[0].offsetLeft; - image.top = originalImage[0].offsetTop; + var setDimensions = function () { - scope.dimensions.image = image; + scope.dimensions.image.width = scope.dimensions.image.originalWidth; + scope.dimensions.image.height = scope.dimensions.image.originalHeight; //unscaled editor size - //var viewPortW = $viewport.width(); - //var viewPortH = $viewport.height(); - var _viewPortW = parseInt(scope.width, 10); - var _viewPortH = parseInt(scope.height, 10); + var _cropW = parseInt(scope.width, 10); + var _cropH = parseInt(scope.height, 10); //if we set a constraint we will scale it down if needed if (scope.maxSize) { - var ratioCalculation = cropperHelper.scaleToMaxSize( - _viewPortW, - _viewPortH, - scope.maxSize); - - //so if we have a max size, override the thumb sizes - _viewPortW = ratioCalculation.width; - _viewPortH = ratioCalculation.height; + if (scope.maxSize < scope.dimensions.viewport.width) { + $viewport.css("width", parseInt(scope.maxSize, 10) + "px"); + scope.dimensions.viewport.width = scope.maxSize; + } + if (scope.maxSize < scope.dimensions.viewport.height) { + $viewport.css("height", parseInt(scope.maxSize, 10) + "px"); + scope.dimensions.viewport.height = scope.maxSize; + } } - scope.dimensions.viewport.width = _viewPortW + 2 * scope.dimensions.margin; - scope.dimensions.viewport.height = _viewPortH + 2 * scope.dimensions.margin; - scope.dimensions.cropper.width = _viewPortW; // scope.dimensions.viewport.width - 2 * scope.dimensions.margin; - scope.dimensions.cropper.height = _viewPortH; // scope.dimensions.viewport.height - 2 * scope.dimensions.margin; + var ratioCalculation = cropperHelper.scaleToMaxSize( + _cropW, + _cropH, + scope.dimensions.viewport.width - 40, + scope.dimensions.viewport.height - 40); + + //so if we have a max size, override the thumb sizes + _cropW = ratioCalculation.width; + _cropH = ratioCalculation.height; + + // set margins: + scope.dimensions.margin.left = (scope.dimensions.viewport.width - _cropW) * 0.5; + scope.dimensions.margin.top = (scope.dimensions.viewport.height - _cropH) * 0.5; + + scope.dimensions.cropper.width = _cropW; + scope.dimensions.cropper.height = _cropH; + updateStyles(); }; //resize to a given ratio var resizeImageToScale = function (ratio) { - //do stuff - var size = cropperHelper.calculateSizeToRatio(scope.dimensions.image.originalWidth, scope.dimensions.image.originalHeight, ratio); - scope.dimensions.image.width = size.width; - scope.dimensions.image.height = size.height; + + var prevWidth = scope.dimensions.image.width; + var prevHeight = scope.dimensions.image.height; + + scope.dimensions.image.width = scope.dimensions.image.originalWidth * ratio; + scope.dimensions.image.height = scope.dimensions.image.originalHeight * ratio; + + var difW = (scope.dimensions.image.width - prevWidth); + var difH = (scope.dimensions.image.height - prevHeight); + + // normalized focus point: + var focusNormX = (-scope.dimensions.image.left + scope.dimensions.cropper.width*.5) / prevWidth; + var focusNormY = (-scope.dimensions.image.top + scope.dimensions.cropper.height*.5) / prevHeight; + + scope.dimensions.image.left = scope.dimensions.image.left - difW * focusNormX; + scope.dimensions.image.top = scope.dimensions.image.top - difH * focusNormY; setConstraints(); validatePosition(scope.dimensions.image.left, scope.dimensions.image.top); @@ -163,10 +198,10 @@ angular.module("umbraco.directives") //resize the image to a predefined crop coordinate var resizeImageToCrop = function () { scope.dimensions.image = cropperHelper.convertToStyle( - scope.crop, + runtimeCrop, { width: scope.dimensions.image.originalWidth, height: scope.dimensions.image.originalHeight }, scope.dimensions.cropper, - scope.dimensions.margin); + 0); var ratioCalculation = cropperHelper.calculateAspectRatioFit( scope.dimensions.image.originalWidth, @@ -179,24 +214,15 @@ angular.module("umbraco.directives") // Update min and max based on original width/height scope.dimensions.scale.min = ratioCalculation.ratio; - scope.dimensions.scale.max = 2; + //scope.dimensions.scale.max = 2; + + updateSlider(); }; var validatePosition = function (left, top) { - if (left > constraints.left.max) { - left = constraints.left.max; - } - if (left <= constraints.left.min) { - left = constraints.left.min; - } - - if (top > constraints.top.max) { - top = constraints.top.max; - } - if (top <= constraints.top.min) { - top = constraints.top.min; - } + left = Math.min(Math.max(left, constraints.left.min), constraints.left.max); + top = Math.min(Math.max(top, constraints.top.min), constraints.top.max); if (scope.dimensions.image.left !== left) { scope.dimensions.image.left = left; @@ -209,36 +235,54 @@ angular.module("umbraco.directives") //sets scope.crop to the recalculated % based crop - var calculateCropBox = function () { - scope.crop = cropperHelper.pixelsToCoordinates(scope.dimensions.image, scope.dimensions.cropper.width, scope.dimensions.cropper.height, scope.dimensions.margin); + function calculateCropBox() { + runtimeCrop = cropperHelper.pixelsToCoordinates(scope.dimensions.image, scope.dimensions.cropper.width, scope.dimensions.cropper.height, 0); }; + function saveCropBox() { + scope.crop = Utilities.copy(runtimeCrop); + } //Drag and drop positioning, using jquery ui draggable - var onStartDragPosition, top, left; + //var onStartDragPosition, top, left; + var dragStartPosition = {}; $overlay.draggable({ + start: function (event, ui) { + dragStartPosition.left = scope.dimensions.image.left; + dragStartPosition.top = scope.dimensions.image.top; + }, drag: function (event, ui) { scope.$apply(function () { - validatePosition(ui.position.left, ui.position.top); + validatePosition(dragStartPosition.left + (ui.position.left - ui.originalPosition.left), dragStartPosition.top + (ui.position.top - ui.originalPosition.top)); }); }, stop: function (event, ui) { scope.$apply(function () { //make sure that every validates one more time... - validatePosition(ui.position.left, ui.position.top); + validatePosition(dragStartPosition.left + (ui.position.left - ui.originalPosition.left), dragStartPosition.top + (ui.position.top - ui.originalPosition.top)); calculateCropBox(); - scope.dimensions.image.rnd = Math.random(); + saveCropBox(); }); } }); - var init = function (image) { - scope.loaded = false; + var runtimeCrop; + var init = function () { + + // store original size: + scope.dimensions.image.originalWidth = $image.width(); + scope.dimensions.image.originalHeight = $image.height(); + + // runtime Crop, should not be saved until we have interactions: + runtimeCrop = Utilities.copy(scope.crop); + + onViewportSizeChanged(); - //set dimensions on image, viewport, cropper etc - setDimensions(image); + scope.loaded = true; + }; + function setCrop() { //create a default crop if we haven't got one already var createDefaultCrop = !scope.crop; if (createDefaultCrop) { @@ -275,41 +319,59 @@ angular.module("umbraco.directives") resizeImageToCrop(); } } + } + - //sets constaints for the cropper + function onViewportSizeChanged() { + scope.dimensions.viewport.width = $viewport.width(); + scope.dimensions.viewport.height = $viewport.height(); + + setDimensions(); + setCrop(); setConstraints(); - scope.loaded = true; - }; + } // Watchers - scope.$watchCollection('[width, height]', function (newValues, oldValues) { + unsubscribe.push(scope.$watchCollection('[width, height, alias, forceUpdate]', function (newValues, oldValues) { // We have to reinit the whole thing if // one of the external params changes if (newValues !== oldValues) { - setDimensions($image); + runtimeCrop = Utilities.copy(scope.crop); + setDimensions(); + setCrop(); setConstraints(); } - }); + })); var throttledResizing = _.throttle(function () { resizeImageToScale(scope.dimensions.scale.current); calculateCropBox(); + saveCropBox(); }, 15); // Happens when we change the scale - scope.$watch("dimensions.scale.current", function (newValue, oldValue) { + unsubscribe.push(scope.$watch("dimensions.scale.current", function (newValue, oldValue) { if (scope.loaded) { throttledResizing(); } - }); + })); // Init $image.on("load", function () { $timeout(function () { - init($image); + init(); }); }); + + $window.addEventListener("resize", onViewportSizeChanged) + + scope.$on('$destroy', function () { + console.log("DESTROY!!"); + $image.prop("src", ""); + $window.removeEventListener("resize", onViewportSizeChanged) + unsubscribe.forEach(u => u()); + }) } }; }); diff --git a/src/Umbraco.Web.UI.Client/src/common/services/cropperhelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/cropperhelper.service.js index 256a1461db3f..1f860f237caa 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/cropperhelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/cropperhelper.service.js @@ -44,24 +44,23 @@ function cropperHelper(umbRequestHelper, $http) { return { width:srcWidth*ratio, height:srcHeight*ratio, ratio: ratio}; }, - scaleToMaxSize : function(srcWidth, srcHeight, maxSize) { - - var retVal = {height: srcHeight, width: srcWidth}; + scaleToMaxSize : function(srcWidth, srcHeight, maxWidth, maxHeight) { - if(srcWidth > maxSize ||srcHeight > maxSize){ - var ratio = [maxSize / srcWidth, maxSize / srcHeight ]; - ratio = Math.min(ratio[0], ratio[1]); - - retVal.height = srcHeight * ratio; - retVal.width = srcWidth * ratio; - } - - return retVal; + // fallback to maxHeight: + maxHeight = maxHeight || maxWidth; + + // get smallest ratio, if ratio exceeds 1 we will not scale(hence we parse 1 as the maximum allowed ratio) + var ratio = Math.min(maxWidth / srcWidth, maxHeight / srcHeight, 1); + + return { + width: srcWidth * ratio, + height:srcHeight * ratio + }; }, //returns a ng-style object with top,left,width,height pixel measurements //expects {left,right,top,bottom} - {width,height}, {width,height}, int - //offset is just to push the image position a number of pixels from top,left + //offset is just to push the image position a number of pixels from top,left convertToStyle : function(coordinates, originalSize, viewPort, offset){ var coordinates_px = service.coordinatesToPixels(coordinates, originalSize, offset); @@ -85,14 +84,14 @@ function cropperHelper(umbRequestHelper, $http) { return style; }, - + coordinatesToPixels : function(coordinates, originalSize, offset){ var coordinates_px = { x1: Math.floor(coordinates.x1 * originalSize.width), y1: Math.floor(coordinates.y1 * originalSize.height), x2: Math.floor(coordinates.x2 * originalSize.width), - y2: Math.floor(coordinates.y2 * originalSize.height) + y2: Math.floor(coordinates.y2 * originalSize.height) }; return coordinates_px; @@ -106,25 +105,18 @@ function cropperHelper(umbRequestHelper, $http) { var x2_px = image.width - (x1_px + width); var y2_px = image.height - (y1_px + height); - //crop coordinates in % var crop = {}; - crop.x1 = x1_px / image.width; - crop.y1 = y1_px / image.height; - crop.x2 = x2_px / image.width; - crop.y2 = y2_px / image.height; - - for(var coord in crop){ - if(crop[coord] < 0){ - crop[coord] = 0; - } - } + crop.x1 = Math.max(x1_px / image.width, 0); + crop.y1 = Math.max(y1_px / image.height, 0); + crop.x2 = Math.max(x2_px / image.width, 0); + crop.y2 = Math.max(y2_px / image.height, 0); return crop; }, alignToCoordinates : function(image, center, viewport){ - + var min_left = (image.width) - (viewport.width); var min_top = (image.height) - (viewport.height); diff --git a/src/Umbraco.Web.UI.Client/src/less/belle.less b/src/Umbraco.Web.UI.Client/src/less/belle.less index 9d751bee1104..6f95608d7a8d 100644 --- a/src/Umbraco.Web.UI.Client/src/less/belle.less +++ b/src/Umbraco.Web.UI.Client/src/less/belle.less @@ -219,6 +219,7 @@ @import "../views/components/mediacard/umb-media-card.less"; @import "../views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.less"; @import "../views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.less"; +@import "../views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less"; // Utilities diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 0d8f270f1b18..348cfc4a0910 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -463,6 +463,13 @@ .umb-cropper{ position: relative; + width: 100%; +} + +.umb-cropper .crop-container { + position: relative; + width: 100%; + padding-bottom: 9 / 16 * 100%; } .umb-cropper img, .umb-cropper-gravity img{ @@ -477,20 +484,32 @@ max-width: none; } - .umb-cropper .overlay, .umb-cropper-gravity .overlay { + .umb-cropper .overlay { + position: absolute; + top: 0 !important; + bottom: 0; + left: 0 !important; + right: 0; + cursor: move; + z-index: @zindexCropperOverlay; +} +.umb-cropper-gravity .overlay { + position: absolute; top: 0; left: 0; cursor: move; z-index: @zindexCropperOverlay; - position: absolute; } -.umb-cropper .viewport{ +.umb-cropper .viewport { + position: absolute; overflow: hidden; - position: relative; - margin: auto; - max-width: 100%; - height: auto; + width: 100%; + height: 100%; + .checkeredBackground(); + > img { + position: absolute; + } } .umb-cropper-gravity .viewport{ @@ -498,19 +517,27 @@ position: relative; width: 100%; height: 100%; + contain: content; } -.umb-cropper .viewport:after { - content: ""; +.umb-cropper .viewport .__mask { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: @zindexCropperOverlay - 1; - opacity: .75; - box-shadow: inset 0 0 0 20px white,inset 0 0 0 21px rgba(0,0,0,.1),inset 0 0 20px 21px rgba(0,0,0,.2); + box-shadow: 0 0 0 2000px rgba(255, 255, 255, .8); +} +.umb-cropper .viewport .__mask-info { + position: absolute; + bottom: 0; + right: 0; + z-index: @zindexCropperOverlay - 1; + font-size: 12px; + background-color: rgba(255, 255, 255, 0.5); + padding: 0px 6px; } .umb-cropper-gravity .overlay{ @@ -529,10 +556,6 @@ opacity: 0.8 !important; } -.umb-cropper .crop-container { - text-align: center; -} - .umb-cropper .crop-slider-wrapper { padding: 10px; border-top: 1px solid @gray-10; @@ -572,6 +595,16 @@ float: left; } + .umb-cropper-imageholder umb-image-gravity { + display:block; + } + + .umb-crop-thumbnail-container { + img { + max-width: unset; + } + } + .cropList { display: inline-block; position: relative; @@ -611,8 +644,6 @@ @media (max-width: 768px) { flex-direction: column; - float: left; - max-width: 100%; } .viewport img { @@ -623,12 +654,8 @@ .imagecropper .umb-cropper__container { position: relative; margin-bottom: 10px; - max-width: 100%; + width: 100%; border: 1px solid @gray-10; - - @media (min-width: 769px) { - width: 600px; - } } .imagecropper .umb-cropper__container .button-drawer { diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js similarity index 79% rename from src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.controller.js rename to src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js index d6a1c93469c0..6c71ae131700 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js @@ -64,6 +64,24 @@ angular.module("umbraco") }; + vm.repickMedia = repickMedia; + function repickMedia() { + vm.model.propertyEditor.changeMediaFor(vm.model.mediaEntry, onMediaReplaced); + } + + function onMediaReplaced() { + + // mark we have changes: + vm.imageCropperForm.$setDirty(); + + // un-select crop: + vm.currentCrop = null; + + // + updateMedia(); + } + + vm.focalPointChanged = function(left, top) { //update the model focalpoint value vm.mediaEntry.focalPoint = { @@ -72,32 +90,38 @@ angular.module("umbraco") }; //set form to dirty to track changes - vm.imageCropperForm.$setDirty(); + setDirty(); } - /** - * crop a specific crop - * @param {any} targetCrop - */ - vm.onCropClicked = onCropClicked; - function onCropClicked(targetCrop) { - if (vm.currentCrop === targetCrop) { - vm.currentCrop = null; - } else { - vm.currentCrop = targetCrop; - vm.imageCropperForm.$setDirty(); - } + vm.selectCrop = selectCrop; + function selectCrop(targetCrop) { + vm.currentCrop = targetCrop; + setDirty(); + // TODO: start watchin values of crop, first when changed set to dirty. }; - function resetCrop(crop) { - // TODO: find a way to reset. - //vm.currentCrop.coordinates = {}; - //crop.defined = false;// concept? - vm.imageCropperForm.$setDirty(); + vm.deselectCrop = deselectCrop; + function deselectCrop() { + vm.currentCrop = null; + }; + + vm.resetCrop = resetCrop; + function resetCrop() { + if (vm.currentCrop) { + $scope.$evalAsync( () => { + console.log(vm.currentCrop); + vm.model.propertyEditor.resetCrop(vm.currentCrop); + vm.forceUpdateCrop = Math.random(); + console.log(vm.forceUpdateCrop); + }); + } } + function setDirty() { + vm.imageCropperForm.$setDirty(); + } vm.submitAndClose = function () { diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html similarity index 57% rename from src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.html rename to src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html index 1c1c7681367b..d4b34de17717 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker3/mediaentryeditor.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html @@ -1,11 +1,11 @@ -
+
This item is in the Recycle Bin
+
+ + + + +
+
-
+
+ +
-
-
- - -
+ +
- +
-
+
- -
    -
  • - - - - -
    - {{crop.alias}} - {{crop.width}}px x {{crop.height}}px - User defined  -
    -
  • -
-
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less new file mode 100644 index 000000000000..6f110d973c11 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less @@ -0,0 +1,78 @@ +.umb-media-entry-editor { + + .imagecropper > div { + width: 100%; + } + .umb-cropper .crop-container { + padding-bottom: 0; + height: calc(100vh - 320px); + } +} + +.umb-media-entry-editor__crops { + background-color: white; + + display: flex; + + > button { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + position: relative; + text-align: center; + padding: 4px 10px 0 10px; + border-right: 1px solid @gray-9; + box-sizing: border-box; + height: 120px; + color: @ui-active-type; + + &:hover { + color: @ui-active-type-hover; + text-decoration: none; + } + + :active { + .box-shadow(~"inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05)"); + } + + &::before { + content: ""; + position: absolute; + height: 0px; + max-width: 50px; + width: (100% - 16px); + left: auto; + right: auto; + background-color: @ui-light-active-border; + bottom: 0; + border-radius: 3px 3px 0 0; + opacity: 0; + transition: all .2s linear; + } + + &.--is-active { + color: @ui-light-active-type; + + &::before { + opacity: 1; + height: 4px; + } + } + &.--is-defined { + + } + + > .__icon { + font-size: 24px; + display: block; + text-align: center; + margin-bottom: 7px; + } + + > .__text { + font-size: 12px; + line-height: 1em; + } + } +} diff --git a/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-crop.html b/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-crop.html index 933551bbff8d..776cb673f1a6 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-crop.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-crop.html @@ -1,9 +1,17 @@
-
- -
-
+
+ +
{{width}}px x {{height}}px
+
+
+
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less index 907e0659c404..6c5d1fadd621 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less @@ -1,8 +1,8 @@ .umb-media-card-grid { /* Grid Setup */ display: grid; - grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); - grid-auto-rows: minmax(160px, auto); + grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); + grid-auto-rows: minmax(100px, auto); grid-gap: 10px; justify-items: center; @@ -14,6 +14,7 @@ .umb-media-card-grid__cell { position: relative; display: flex; + width: 100%; height: 100%; align-items: center; justify-content: center; @@ -27,7 +28,7 @@ outline: none; left: 0; width: 12px; - margin-left: -9px; + margin-left: -7px; padding-left: 6px; margin-right: -6px; transition: opacity 240ms; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less index 6a5eb60d1306..a10c8feb1466 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less @@ -2,7 +2,7 @@ umb-media-card { position: relative; display: inline-block; - width: 200px; + width: 100%; //background-color: white; border-radius: @baseBorderRadius; //box-shadow: 0 1px 2px rgba(0,0,0,.2); @@ -97,8 +97,8 @@ umb-media-card { bottom: 0; width: 100%; background-color: #fff; - padding-top: 10px; - padding-bottom: 11px;// 10 + 1 to compentiate for the -1 substraction in margin-bottom. + padding-top: 6px; + padding-bottom: 7px;// 7 + 1 to compentiate for the -1 substraction in margin-bottom. opacity: 0; transition: opacity 120ms; @@ -113,7 +113,7 @@ umb-media-card { .__name { font-weight: bold; - font-size: 14px; + font-size: 13px; color: @ui-action-type; margin-left: 16px; margin-bottom: -1px; 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 91abc3be8775..74da39ae1456 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 @@ -22,7 +22,6 @@ width="{{currentCrop.width}}" crop="currentCrop.coordinates" center="model.value.focalPoint" - max-size="450" src="imageSrc">
@@ -46,7 +45,7 @@
- +
  • diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.controller.js index 418766994274..525ddbec08e6 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.controller.js @@ -42,7 +42,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.MediaPicker3.CropC }; $scope.useForAlias = function (crop) { if (crop.alias == null || crop.alias === "") { - crop.alias = crop.label.toCamelCase(); + crop.alias = (crop.label || "").toCamelCase(); } }; $scope.validateWidth = function (crop) { diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js index fea823e790bf..7bc12316350f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js @@ -116,6 +116,7 @@ vm.loading = false; + // testing: //editMedia(vm.model.value[0]); }); @@ -161,6 +162,47 @@ editorService.mediaPicker(mediaPicker); } + // To be used by infinte editor. (defined here cause we need configuration from property editor) + function changeMediaFor(mediaEntry, onSuccess) { + var mediaPicker = { + startNodeId: vm.model.config.startNodeId, + startNodeIsVirtual: vm.model.config.startNodeIsVirtual, + dataTypeKey: vm.model.dataTypeKey, + multiPicker: false, + submit: function (model) { + editorService.close(); + + model.selection.forEach((entry) => {// only one. + mediaEntry.mediaKey = entry.key; + }); + + // reset focal and crops: + mediaEntry.crops = null; + mediaEntry.focalPoint = null; + updateMediaEntryData(mediaEntry); + + if(onSuccess) { + onSuccess(); + } + }, + close: function () { + editorService.close(); + } + } + + if(vm.model.config.filter) { + mediaPicker.filter = vm.model.config.filter; + } + + editorService.mediaPicker(mediaPicker); + } + + function resetCrop(cropEntry) { + Object.assign(cropEntry, vm.model.config.crops.find( c => c.alias === cropEntry.alias)); + cropEntry.coordinates = null; + setDirty(); + } + function updateMediaEntryData(mediaEntry) { mediaEntry.crops = mediaEntry.crops || []; @@ -213,9 +255,11 @@ createFlow: options.createFlow === true, title: vm.labels.mediaPicker_editMediaEntryLabel, mediaEntry: mediaEntryClone, - //cropsConfig: config.crops, - //api: vm, - view: "views/common/infiniteeditors/mediapicker3/mediaEntryEditor.html", + propertyEditor: { + changeMediaFor: changeMediaFor, + resetCrop: resetCrop + }, + view: "views/common/infiniteeditors/mediaEntryEditor/mediaEntryEditor.html", size: "large", submit: function(model) { vm.model.value[vm.model.value.indexOf(mediaEntry)] = mediaEntryClone; From ee07a87a551724851ab2a67147d3c4f2ea01b2e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 26 Nov 2020 10:38:35 +0100 Subject: [PATCH 17/90] always be able to scale 3 times smallest scale --- .../directives/components/imaging/umbimagecrop.directive.js | 6 +++--- .../src/less/components/umb-range-slider.less | 6 ++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js index 6abe91898ae0..9dbc369be890 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js @@ -50,10 +50,10 @@ angular.module("umbraco.directives") "tooltips": [false], "format": { to: function (value) { - return parseFloat(parseFloat(value).toFixed(3)); //Math.round(value); + return parseFloat(parseFloat(value).toFixed(3)); }, from: function (value) { - return parseFloat(parseFloat(value).toFixed(3)); //Math.round(value); + return parseFloat(parseFloat(value).toFixed(3)); } }, "range": { @@ -214,7 +214,7 @@ angular.module("umbraco.directives") // Update min and max based on original width/height scope.dimensions.scale.min = ratioCalculation.ratio; - //scope.dimensions.scale.max = 2; + scope.dimensions.scale.max = ratioCalculation.ratio * 3; updateSlider(); }; diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-range-slider.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-range-slider.less index 6ae92ffa4e99..0014bdb1582c 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-range-slider.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-range-slider.less @@ -9,11 +9,13 @@ } .umb-range-slider .noUi-handle { + outline: none; border-radius: 100px; border: none; box-shadow: none; width: 20px !important; height: 20px !important; + right: -10px !important; // half the handle width background-color: @blueMid; } @@ -25,10 +27,6 @@ display: none; } -.umb-range-slider .noUi-handle { - right: -10px !important; // half the handle width -} - .umb-range-slider .noUi-marker-large.noUi-marker-horizontal { height: 10px; } From 96ee5f7b6723181baf18e4ef86e3746267c26d77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 26 Nov 2020 11:02:37 +0100 Subject: [PATCH 18/90] making image cropper property editor responsive --- .../imaging/umbimagecrop.directive.js | 24 ++++++++----------- .../src/less/property-editors.less | 1 + .../imagecropper/imagecropper.html | 4 ++-- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js index 9dbc369be890..7eb493dc639b 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js @@ -17,7 +17,7 @@ angular.module("umbraco.directives") height: '@', crop: "=", center: "=", - maxSize: '@', + maxSize: '@?', alias: '@?', forceUpdate: '@?' }, @@ -141,18 +141,6 @@ angular.module("umbraco.directives") var _cropW = parseInt(scope.width, 10); var _cropH = parseInt(scope.height, 10); - //if we set a constraint we will scale it down if needed - if (scope.maxSize) { - if (scope.maxSize < scope.dimensions.viewport.width) { - $viewport.css("width", parseInt(scope.maxSize, 10) + "px"); - scope.dimensions.viewport.width = scope.maxSize; - } - if (scope.maxSize < scope.dimensions.viewport.height) { - $viewport.css("height", parseInt(scope.maxSize, 10) + "px"); - scope.dimensions.viewport.height = scope.maxSize; - } - } - var ratioCalculation = cropperHelper.scaleToMaxSize( _cropW, _cropH, @@ -357,7 +345,16 @@ angular.module("umbraco.directives") } })); + // Init + + //if we have a max-size we will use it, to keep this backwards compatible. + // I dont see this max size begin usefull, as we should aim for responsive UI. + if (scope.maxSize) { + element.css("max-width", parseInt(scope.maxSize, 10) + "px"); + element.css("max-height", parseInt(scope.maxSize, 10) + "px"); + } + $image.on("load", function () { $timeout(function () { init(); @@ -367,7 +364,6 @@ angular.module("umbraco.directives") $window.addEventListener("resize", onViewportSizeChanged) scope.$on('$destroy', function () { - console.log("DESTROY!!"); $image.prop("src", ""); $window.removeEventListener("resize", onViewportSizeChanged) unsubscribe.forEach(u => u()); diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 348cfc4a0910..643aa9aa0873 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -609,6 +609,7 @@ display: inline-block; position: relative; vertical-align: top; + flex:0; } .gravity-container { 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 74da39ae1456..8bac6e768444 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 @@ -12,9 +12,9 @@ on-init="fileUploaderInit(value, files)" hide-selection="true"> -
    +
    -
    +
    From d583955c2d02ff63f76d9c54f3d4df3ebd4ebf7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 26 Nov 2020 13:54:08 +0100 Subject: [PATCH 19/90] scroll to scale --- .../imaging/umbimagecrop.directive.js | 43 +++++++++++++++++-- .../src/less/property-editors.less | 31 +++++++------ .../components/imaging/umb-image-crop.html | 6 +-- 3 files changed, 62 insertions(+), 18 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js index 7eb493dc639b..bf89c9039713 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js @@ -94,6 +94,35 @@ angular.module("umbraco.directives") } }; + function onScroll(event) { + // cross-browser wheel delta + var event = window.event || event; // old IE support + var delta = Math.max(-50, Math.min(50, (event.wheelDelta || -event.detail))); + + if(sliderRef) { + var currentScale =sliderRef.noUiSlider.get(); + /* + if (delta > 0 && scope.dimensions.scale.max.toFixed(3) === currentScale.toFixed(3)) + return; + if (delta < 0 && scope.dimensions.scale.min.toFixed(3) === currentScale.toFixed(3)) + return; + */ + + var newScale = Math.min(Math.max(currentScale + delta*.001*scope.dimensions.image.ratio, scope.dimensions.scale.min), scope.dimensions.scale.max); + sliderRef.noUiSlider.set(newScale); + scope.$evalAsync(() => { + scope.dimensions.scale.current = newScale; + }); + + // for IE + event.returnValue = false; + // for Chrome and Firefox + if(event.preventDefault) { + event.preventDefault(); + } + } + } + //live rendering of viewport and image styles function updateStyles() { @@ -121,6 +150,14 @@ angular.module("umbraco.directives") var $overlay = element.find(".overlay"); //var $container = element.find(".crop-container"); + $overlay.bind("focus", function () { + $overlay.bind("DOMMouseScroll mousewheel onmousewheel", onScroll); + }); + $overlay.bind("blur", function () { + $overlay.unbind("DOMMouseScroll mousewheel onmousewheel", onScroll); + }); + + //default constraints for drag n drop var constraints = { left: { max: 0, min: 0 }, top: { max: 0, min: 0 } }; scope.constraints = constraints; @@ -332,16 +369,16 @@ angular.module("umbraco.directives") } })); - var throttledResizing = _.throttle(function () { + var throttledScale = _.throttle(() => scope.$evalAsync(() => { resizeImageToScale(scope.dimensions.scale.current); calculateCropBox(); saveCropBox(); - }, 15); + }), 16); // Happens when we change the scale unsubscribe.push(scope.$watch("dimensions.scale.current", function (newValue, oldValue) { if (scope.loaded) { - throttledResizing(); + throttledScale(); } })); diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 643aa9aa0873..76ee39c03bb1 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -492,6 +492,12 @@ right: 0; cursor: move; z-index: @zindexCropperOverlay; + border: 1px solid @inputBorder; + outline: none; + + &:focus { + border-color: @inputBorderFocus; + } } .umb-cropper-gravity .overlay { position: absolute; @@ -501,26 +507,27 @@ z-index: @zindexCropperOverlay; } +.umb-cropper-gravity .viewport{ + overflow: hidden; + position: relative; + width: 100%; + height: 100%; + contain: content; +} + + .umb-cropper .viewport { position: absolute; overflow: hidden; width: 100%; height: 100%; .checkeredBackground(); + > img { position: absolute; } } -.umb-cropper-gravity .viewport{ - overflow: hidden; - position: relative; - width: 100%; - height: 100%; - contain: content; -} - - .umb-cropper .viewport .__mask { position: absolute; top: 0; @@ -532,11 +539,12 @@ } .umb-cropper .viewport .__mask-info { position: absolute; - bottom: 0; + bottom: -20px; + height: 20px; right: 0; z-index: @zindexCropperOverlay - 1; font-size: 12px; - background-color: rgba(255, 255, 255, 0.5); + opacity: 0.7; padding: 0px 6px; } @@ -656,7 +664,6 @@ position: relative; margin-bottom: 10px; width: 100%; - border: 1px solid @gray-10; } .imagecropper .umb-cropper__container .button-drawer { diff --git a/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-crop.html b/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-crop.html index 776cb673f1a6..d73d47c3d321 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-crop.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-crop.html @@ -7,10 +7,10 @@ 'width': dimensions.image.width, 'height': dimensions.image.height }"/> -
    {{width}}px x {{height}}px
    +
    {{width}}px x {{height}}px
    -
    +
    @@ -29,5 +29,5 @@
    - +
    From e02732b19bb0a5d5df58af1fd2c527510403f241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 26 Nov 2020 16:07:21 +0100 Subject: [PATCH 20/90] adjust slider look --- .../src/less/components/umb-range-slider.less | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-range-slider.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-range-slider.less index 0014bdb1582c..cc5c17ba70cb 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-range-slider.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-range-slider.less @@ -2,21 +2,35 @@ .umb-range-slider.noUi-target { background: linear-gradient(to bottom, @grayLighter 0%, @grayLighter 100%); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: none; border-radius: 20px; - height: 10px; - border: none; + height: 8px; + border: 1px solid @inputBorder; + &:focus, &:focus-within { + border-color: @inputBorderFocus; + } +} +.umb-range-slider .noUi-connects { + cursor: pointer; + height: 20px; + top: -6px; +} +.umb-range-slider .noUi-tooltip { + padding: 2px 6px; } - .umb-range-slider .noUi-handle { outline: none; + cursor: grab; border-radius: 100px; border: none; box-shadow: none; width: 20px !important; height: 20px !important; right: -10px !important; // half the handle width - background-color: @blueMid; + background-color: @blueExtraDark; +} +.umb-range-slider .noUi-horizontal .noUi-handle { + top: -7px; } .umb-range-slider .noUi-handle::before { From 9c679a9f0386644920306b6401f61c9f9eed70a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 27 Nov 2020 09:30:50 +0100 Subject: [PATCH 21/90] rearrange parts of mediaentryeditor --- .../mediaentryeditor/mediaentryeditor.html | 39 ++++++++++--------- .../mediaentryeditor/mediaentryeditor.less | 14 ++++++- 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html index d4b34de17717..0940d6afe010 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html @@ -13,33 +13,34 @@ hide-description="true"> -
    +
    -
    + +
    This item is in the Recycle Bin
    -
    +
    +
    - + - -
    + + + {{crop.alias}} + +
    -
    -
    +
    diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less index 6f110d973c11..f29e296e4075 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less @@ -9,10 +9,18 @@ } } +.umb-media-entry-editor__pane { + display: flex; + flex-direction: column; + height: 100%; + width: 100%; +} + .umb-media-entry-editor__crops { background-color: white; - + display: flex; + flex-direction: column; > button { display: flex; @@ -76,3 +84,7 @@ } } } + +.umb-media-entry-editor__imagecropper { + flex: auto; +} From b901fa68b6bbdd01878ef5e7d0a24185fc6dcd74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 27 Nov 2020 11:00:55 +0100 Subject: [PATCH 22/90] test helper --- .../mediapicker3/umbMediaPicker3PropertyEditor.component.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js index 7bc12316350f..9ea7f31fcb24 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js @@ -117,7 +117,7 @@ vm.loading = false; // testing: - //editMedia(vm.model.value[0]); + editMedia(vm.model.value[0]); }); }; From ee788e6632a347864ead761c524f1b786ce9b3b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 27 Nov 2020 11:01:05 +0100 Subject: [PATCH 23/90] styling --- src/Umbraco.Web.UI.Client/src/less/property-editors.less | 7 ------- .../infiniteeditors/mediaentryeditor/mediaentryeditor.less | 3 +-- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 76ee39c03bb1..9e253eeb92d8 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -565,18 +565,11 @@ } .umb-cropper .crop-slider-wrapper { - padding: 10px; - border-top: 1px solid @gray-10; - margin-top: 10px; display: flex; align-items: center; justify-content: center; flex-wrap: wrap; - @media (min-width: 769px) { - padding: 10px 50px 10px 50px; - } - i { color: @gray-3; flex: 0 0 25px; diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less index f29e296e4075..a5804efe609d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less @@ -11,14 +11,13 @@ .umb-media-entry-editor__pane { display: flex; - flex-direction: column; height: 100%; width: 100%; } .umb-media-entry-editor__crops { background-color: white; - + display: flex; flex-direction: column; From 864bd9b7e9c44ac2fb23edba9277d12559bbb77c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 30 Nov 2020 09:09:48 +0100 Subject: [PATCH 24/90] move controls inside umb-image-crop --- .../imaging/umbimagecrop.directive.js | 1 + .../src/less/property-editors.less | 27 ++++++++++++++++--- .../mediaentryeditor.controller.js | 2 +- .../mediaentryeditor/mediaentryeditor.html | 5 +--- .../mediaentryeditor/mediaentryeditor.less | 22 +++++++++++---- .../components/imaging/umb-image-crop.html | 27 ++++++++++--------- .../imagecropper/imagecropper.html | 6 ++--- ...umbMediaPicker3PropertyEditor.component.js | 4 +-- 8 files changed, 63 insertions(+), 31 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js index bf89c9039713..7883694bc705 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js @@ -10,6 +10,7 @@ angular.module("umbraco.directives") return { restrict: 'E', replace: true, + transclude: true, templateUrl: 'views/components/imaging/umb-image-crop.html', scope: { src: '=', diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 9e253eeb92d8..759828e9c096 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -522,7 +522,8 @@ width: 100%; height: 100%; .checkeredBackground(); - + contain: strict; + > img { position: absolute; } @@ -564,7 +565,18 @@ opacity: 0.8 !important; } +.umb-cropper .crop-controls-wrapper { + display: flex; + height: 50px; + align-items: center; + background-color: #fff; + .btn:last-of-type { + margin-right: 10px; + } +} + .umb-cropper .crop-slider-wrapper { + flex: auto; display: flex; align-items: center; justify-content: center; @@ -582,11 +594,19 @@ } .crop-slider { - padding: 50px 15px 40px 15px; - width: 66.6%; + width: calc(100% - 100px); } } +.umb-cropper .crop-controls-wrapper__icon-left { + margin-right: 10px; + +} +.umb-cropper .crop-controls-wrapper__icon-right { + margin-left: 10px; + font-size: 22px; +} + .umb-cropper-gravity .viewport, .umb-cropper-gravity, .umb-cropper-imageholder { display: inline-block; max-width: 100%; @@ -655,7 +675,6 @@ .imagecropper .umb-cropper__container { position: relative; - margin-bottom: 10px; width: 100%; } diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js index 6c71ae131700..458ec6a71521 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js @@ -133,7 +133,7 @@ angular.module("umbraco") vm.close = function () { if (vm.model && vm.model.close) { if (vm.model.createFlow === true || vm.imageCropperForm.$dirty === true) { - var labels = vm.model.createFlow === true ? ["media_confirmCancelMediaEntryCreationHeadline", "media_confirmCancelMediaEntryCreationMessage"] : ["prompt_discardChanges", "media_confirmCancelMediaEntryHasChanges"]; + var labels = vm.model.createFlow === true ? ["mediaPicker_confirmCancelMediaEntryCreationHeadline", "mediaPicker_confirmCancelMediaEntryCreationMessage"] : ["prompt_discardChanges", "mediaPicker_confirmCancelMediaEntryHasChanges"]; localizationService.localizeMany(labels).then(function (localizations) { const confirm = { title: localizations[0], diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html index 0940d6afe010..ed682e2df7a1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html @@ -53,11 +53,8 @@ force-update="{{vm.forceUpdateCrop}}" center="vm.mediaEntry.focalPoint" src="vm.imageSrc"> - - -
    -
    +
    diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less index a5804efe609d..8cada80eab9f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less @@ -1,11 +1,24 @@ .umb-media-entry-editor { + .imagecropper { + height: 100%; + } + .umb-cropper-imageholder { + + } + .imagecropper .umb-cropper__container { + height: 100%; + } .imagecropper > div { width: 100%; + height: 100%; + } + .umb-cropper { + height: 100%; } .umb-cropper .crop-container { padding-bottom: 0; - height: calc(100vh - 320px); + height: calc(100% - 50px) } } @@ -18,9 +31,6 @@ .umb-media-entry-editor__crops { background-color: white; - display: flex; - flex-direction: column; - > button { display: flex; flex-direction: column; @@ -29,9 +39,10 @@ position: relative; text-align: center; padding: 4px 10px 0 10px; - border-right: 1px solid @gray-9; + border-bottom: 1px solid @gray-9; box-sizing: border-box; height: 120px; + width: 120px; color: @ui-active-type; &:hover { @@ -80,6 +91,7 @@ > .__text { font-size: 12px; line-height: 1em; + margin-top: 4px; } } } diff --git a/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-crop.html b/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-crop.html index d73d47c3d321..af692f8322e1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-crop.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-crop.html @@ -14,20 +14,23 @@
    -
    - +
    +
    + -
    - - -
    +
    + + +
    - + +
    +
    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 8bac6e768444..efa49fa41dc7 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 @@ -23,13 +23,13 @@ crop="currentCrop.coordinates" center="model.value.focalPoint" src="imageSrc"> + + +
    - - -
    diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js index 9ea7f31fcb24..cb2b0fed57e7 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js @@ -300,7 +300,7 @@ vm.requestRemoveMedia = requestRemoveMedia; function requestRemoveMedia(media) { - localizationService.localizeMany(["general_delete", "media_confirmRemoveMediaEntryMessage", "general_remove"]).then(function (data) { + localizationService.localizeMany(["general_delete", "mediaPicker_confirmRemoveMediaEntryMessage", "general_remove"]).then(function (data) { const overlay = { title: data[0], content: localizationService.tokenReplace(data[1], [media.name]), @@ -318,7 +318,7 @@ }); } function requestRemoveAllMedia() { - localizationService.localizeMany(["media_confirmRemoveAllMediaEntryMessage", "general_remove"]).then(function (data) { + localizationService.localizeMany(["mediaPicker_confirmRemoveAllMediaEntryMessage", "general_remove"]).then(function (data) { overlayService.confirmDelete({ title: data[1], content: data[0], From 5c442dbc3f9a5527a5db1a35ff2659b153d59000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 30 Nov 2020 09:46:18 +0100 Subject: [PATCH 25/90] seperate umg-cropper-gravity styling --- src/Umbraco.Web.UI.Client/src/less/property-editors.less | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 759828e9c096..35b8a5ab6ee6 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -472,7 +472,7 @@ padding-bottom: 9 / 16 * 100%; } -.umb-cropper img, .umb-cropper-gravity img{ +.umb-cropper img { position: relative; max-width: 100%; height: auto; @@ -499,6 +499,13 @@ border-color: @inputBorderFocus; } } +.umb-cropper-gravity img { + position: relative; + max-width: 100%; + height: auto; + top: 0; + left: 0; + } .umb-cropper-gravity .overlay { position: absolute; top: 0; From cd947c2152cd6926cbbe8aaf801b783f63dcc3f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 30 Nov 2020 14:45:50 +0100 Subject: [PATCH 26/90] corrected layout --- .../src/less/property-editors.less | 34 ++++++++---------- .../mediaentryeditor/mediaentryeditor.html | 35 ++++++++++--------- .../mediaentryeditor/mediaentryeditor.less | 29 +++++++++++---- 3 files changed, 55 insertions(+), 43 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 35b8a5ab6ee6..348a07397012 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -514,15 +514,6 @@ z-index: @zindexCropperOverlay; } -.umb-cropper-gravity .viewport{ - overflow: hidden; - position: relative; - width: 100%; - height: 100%; - contain: content; -} - - .umb-cropper .viewport { position: absolute; overflow: hidden; @@ -614,6 +605,7 @@ font-size: 22px; } +/* .umb-cropper-gravity .viewport, .umb-cropper-gravity, .umb-cropper-imageholder { display: inline-block; max-width: 100%; @@ -626,6 +618,7 @@ .umb-cropper-imageholder umb-image-gravity { display:block; } + */ .umb-crop-thumbnail-container { img { @@ -643,21 +636,24 @@ .gravity-container { border: 1px solid @gray-8; line-height: 0; + width: 100%; + height: 100%; + overflow: hidden; + .checkeredBackground(); + display: flex; + justify-content: center; + align-items: center; + contain: content; .viewport { - max-width: 600px; - .checkeredBackground(); - - img { - display: block; - margin-left: auto; - margin-right: auto; - } + position: relative; + margin-left: auto; + margin-right: auto; + max-height: 100%; + max-width: 100%; img { display: block; - margin-left: auto; - margin-right: auto; } &:hover { diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html index ed682e2df7a1..d3369b82a98d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html @@ -42,26 +42,24 @@
    -
    +
    + + + + -
    - - - - - -
    -
    +
    - - +
    + + +
    diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less index 8cada80eab9f..db0df8d5ffae 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less @@ -1,15 +1,14 @@ .umb-media-entry-editor { - - .imagecropper { - height: 100%; - } + .umb-cropper-imageholder { - + position: relative; + width: 100%; + height: 100%; } - .imagecropper .umb-cropper__container { + .umb-cropper-gravity { height: 100%; } - .imagecropper > div { + .umb-cropper__container { width: 100%; height: 100%; } @@ -24,12 +23,14 @@ .umb-media-entry-editor__pane { display: flex; + flex-flow: row-reverse; height: 100%; width: 100%; } .umb-media-entry-editor__crops { background-color: white; + overflow: auto; > button { display: flex; @@ -98,4 +99,18 @@ .umb-media-entry-editor__imagecropper { flex: auto; + height: 100%; } + +.umb-media-entry-editor__imageholder { + display: block; + position: relative; + height: calc(100% - 50px); +} +.umb-media-entry-editor__imageholder-actions { + background-color: white; + height: 50px; + display: flex; + justify-content: flex-end; +} + From 9c01cbb92591afdf7311d5d5a465491e7a8a3f47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 1 Dec 2020 12:28:03 +0100 Subject: [PATCH 27/90] more ui refinement --- .../imaging/umbimagecrop.directive.js | 14 ++++++++--- .../src/less/property-editors.less | 1 + .../mediaentryeditor.controller.js | 14 +++++++++++ .../mediaentryeditor/mediaentryeditor.html | 2 +- .../mediaentryeditor/mediaentryeditor.less | 24 ++++++++++++------- 5 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js index 7883694bc705..7b09f87ad112 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js @@ -7,6 +7,9 @@ angular.module("umbraco.directives") .directive('umbImageCrop', function ($timeout, $window, cropperHelper) { + + const MAX_SCALE = 4; + return { restrict: 'E', replace: true, @@ -39,8 +42,8 @@ angular.module("umbraco.directives") viewport: {}, margin: {}, scale: { - min: 0, - max: 3, + min: 1, + max: MAX_SCALE, current: 1 } }; @@ -70,7 +73,9 @@ angular.module("umbraco.directives") function updateSlider() { if(sliderRef) { + // Set slider handle position + console.log("set:", scope.dimensions.scale.current.toFixed(3), " ", scope.dimensions.scale.min, " max", scope.dimensions.scale.max) sliderRef.noUiSlider.set(scope.dimensions.scale.current); // Update slider range min/max @@ -239,8 +244,11 @@ angular.module("umbraco.directives") scope.dimensions.scale.current = scope.dimensions.image.ratio; // Update min and max based on original width/height + // Here we update the slider to use the scala of the current setup, i dont know why its made in this way but this is how it is. scope.dimensions.scale.min = ratioCalculation.ratio; - scope.dimensions.scale.max = ratioCalculation.ratio * 3; + // TODO: Investigate wether we can limit users to not scale bigger than the amount of pixels in the source: + //scope.dimensions.scale.max = ratioCalculation.ratio * Math.min(MAX_SCALE, scope.dimensions.image.originalWidth/scope.dimensions.cropper.width); + scope.dimensions.scale.max = ratioCalculation.ratio * MAX_SCALE; updateSlider(); }; diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 348a07397012..aec464824dfd 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -635,6 +635,7 @@ .gravity-container { border: 1px solid @gray-8; + box-sizing: border-box; line-height: 0; width: 100%; height: 100%; diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js index 458ec6a71521..9504b9ee6379 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js @@ -81,6 +81,20 @@ angular.module("umbraco") updateMedia(); } + vm.openMedia = openMedia; + function openMedia(item) { + var mediaEditor = { + id: item.id, + submit: function () { + editorService.close(); + }, + close: function () { + editorService.close(); + } + }; + editorService.mediaEditor(mediaEditor); + } + vm.focalPointChanged = function(left, top) { //update the model focalpoint value diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html index d3369b82a98d..43e33532fcff 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html @@ -51,7 +51,7 @@ force-update="{{vm.forceUpdateCrop}}" center="vm.mediaEntry.focalPoint" src="vm.imageSrc"> - +
    diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less index db0df8d5ffae..305c204038eb 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.less @@ -19,6 +19,12 @@ padding-bottom: 0; height: calc(100% - 50px) } + .umb-cropper .crop-controls-wrapper { + justify-content: center; + } + .umb-cropper .crop-slider-wrapper { + max-width: 500px; + } } .umb-media-entry-editor__pane { @@ -58,14 +64,14 @@ &::before { content: ""; position: absolute; - height: 0px; - max-width: 50px; - width: (100% - 16px); - left: auto; - right: auto; + width: 0px; + max-height: 50px; + height: (100% - 16px); + top: auto; + bottom: auto; background-color: @ui-light-active-border; - bottom: 0; - border-radius: 3px 3px 0 0; + left: 0; + border-radius: 0 3px 3px 0; opacity: 0; transition: all .2s linear; } @@ -75,7 +81,7 @@ &::before { opacity: 1; - height: 4px; + width: 4px; } } &.--is-defined { @@ -111,6 +117,6 @@ background-color: white; height: 50px; display: flex; - justify-content: flex-end; + justify-content: center; } From fb790789764bf1bdaa02527d4ac85bee6395bd72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 17 Dec 2020 14:18:14 +0100 Subject: [PATCH 28/90] keep the idea of mandatory out for now. --- src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs b/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs index 0417e90612ef..ac24a1ddc4b1 100644 --- a/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs +++ b/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs @@ -54,9 +54,10 @@ public class CropConfiguration [JsonProperty("height")] public int Height { get; set; } - + /* [JsonProperty("mandatory")] public bool Mandatory { get; set; } + */ } } } From 93d5a86a47a0e17ea29ead95783a74237042f59a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 17 Dec 2020 14:18:20 +0100 Subject: [PATCH 29/90] remove double ; --- .../mediapicker3/umbMediaPicker3PropertyEditor.component.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js index cb2b0fed57e7..af6274efe3bc 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js @@ -209,7 +209,7 @@ mediaEntry.focalPoint = mediaEntry.focalPoint || { left: 0.5, top: 0.5 - };; + }; // Copy config and only transfer coordinates. var newCrops = Utilities.copy(vm.model.config.crops); From 15fe8bab8c77ea652f6ca264691737a9d38b6958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 5 Feb 2021 10:03:36 +0100 Subject: [PATCH 30/90] removed testing code --- .../mediapicker3/umbMediaPicker3PropertyEditor.component.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js index af6274efe3bc..cbf31f995954 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js @@ -61,8 +61,6 @@ vm.$onInit = function() { - console.log("property model: ", vm.model) - vm.singleMode = vm.model.config.singleMode || false; vm.validationLimit = vm.model.config.validationLimit; @@ -115,9 +113,6 @@ vm.allowAdd = hasAccessToMedia; vm.loading = false; - - // testing: - editMedia(vm.model.value[0]); }); }; From 8c9aec85407ae5342c3d6ba2c2547008c5b90853 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Mon, 8 Feb 2021 14:21:44 +0000 Subject: [PATCH 31/90] JSON Property Value Convertor now has an array of property editors to exclude --- .../PropertyEditors/ValueConverters/JsonValueConverter.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/JsonValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/JsonValueConverter.cs index 12e62387050c..105b0f65990c 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/JsonValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/JsonValueConverter.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Umbraco.Core.Composing; @@ -18,6 +19,8 @@ public class JsonValueConverter : PropertyValueConverterBase { private readonly PropertyEditorCollection _propertyEditors; + string[] ExcludedPropertyEditors = new string[] { Constants.PropertyEditors.Aliases.MediaPicker3 }; + /// /// Initializes a new instance of the class. /// @@ -28,13 +31,16 @@ public JsonValueConverter(PropertyEditorCollection propertyEditors) /// /// It is a converter for any value type that is "JSON" + /// Unless its in the Excluded Property Editors list + /// The new MediaPicker 3 stores JSON but we want to use its own ValueConvertor /// /// /// public override bool IsConverter(IPublishedPropertyType propertyType) { return _propertyEditors.TryGet(propertyType.EditorAlias, out var editor) - && editor.GetValueEditor().ValueType.InvariantEquals(ValueTypes.Json); + && editor.GetValueEditor().ValueType.InvariantEquals(ValueTypes.Json) + && Array.IndexOf(ExcludedPropertyEditors, propertyType.EditorAlias) == -1; } public override Type GetPropertyValueType(IPublishedPropertyType propertyType) From cf304817d1e84de10a9a4ad6820940e531f02c6b Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Mon, 8 Feb 2021 15:52:22 +0000 Subject: [PATCH 32/90] Property Value Convertor for Media Picker 3 aka Media Picker with Local Crops --- .../MediaPicker3PropertyEditor.cs | 23 +-- .../MediaPickerWithCropsValueConverter.cs | 154 ++++++++++++++++++ 2 files changed, 163 insertions(+), 14 deletions(-) create mode 100644 src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs diff --git a/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs index 28d2aac2e52d..5008c125a288 100644 --- a/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs @@ -34,24 +34,19 @@ public MediaPicker3PropertyEditor(ILogger logger) internal class MediaPicker3PropertyValueEditor : DataValueEditor { + /// + /// Note no FromEditor() and ToEditor() methods + /// We do not want to transform the way the data is stored in the DB and would like to keep a raw JSON string + /// public MediaPicker3PropertyValueEditor(DataEditorAttribute attribute) : base(attribute) { } - /* - public IEnumerable GetReferences(object value) - { - var asString = value is string str ? str : value?.ToString(); - - if (string.IsNullOrEmpty(asString)) yield break; - - foreach (var udiStr in asString.Split(',')) - { - if (Udi.TryParse(udiStr, out var udi)) - yield return new UmbracoEntityReference(udi); - } - } - */ + // TODO: Perhaps needed?! from IDataValueReference + //public IEnumerable GetReferences(object value) + //{ + // throw new NotImplementedException(); + //} } diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs new file mode 100644 index 000000000000..3e47b91185b4 --- /dev/null +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs @@ -0,0 +1,154 @@ +using Newtonsoft.Json; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.PropertyEditors; +using Umbraco.Core.PropertyEditors.ValueConverters; +using Umbraco.Web.PublishedCache; + +namespace Umbraco.Web.PropertyEditors.ValueConverters +{ + [DefaultPropertyValueConverter] + public class MediaPickerWithCropsValueConverter : PropertyValueConverterBase + { + // JSON is an array of the following JSON + /* + "key": "d1e9c080-5aef-48f6-9b37-47e84de7ad8b", + "mediaKey": "80e2507b-c5f9-4c8a-ab14-5dae717a49b3", + "crops": [ + { + "alias": "square", + "label": "Square", + "width": 200, + "height": 200, + "coordinates": { + "x1": 0.4489663034789123, + "y1": 0.7192332259400422, + "x2": 0.39324276949939146, + "y2": 0 + } + }, + ... + ] + "focalPoint": { + "left": 0.846, + "top": 0.7964285714285714 + } + */ + + private IPublishedSnapshotAccessor _publishedSnapshotAccessor; + + public MediaPickerWithCropsValueConverter(IPublishedSnapshotAccessor publishedSnapshotAccessor) + { + _publishedSnapshotAccessor = publishedSnapshotAccessor ?? throw new ArgumentNullException(nameof(publishedSnapshotAccessor)); + } + + public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType) => PropertyCacheLevel.Snapshot; + + /// + /// Enusre this property value convertor is for the New Media Picker with Crops aka MediaPicker 3 + /// + public override bool IsConverter(IPublishedPropertyType propertyType) => propertyType.EditorAlias.Equals(Core.Constants.PropertyEditors.Aliases.MediaPicker3); + + /// + /// Check if the raw JSON value is not an empty array + /// + public override bool? IsValue(object value, PropertyValueLevel level) => value?.ToString() != "[]"; + + /// + /// What C# model type does the raw JSON return for Models & Views + /// + public override Type GetPropertyValueType(IPublishedPropertyType propertyType) + { + // Check do we want to return IPublishedContent collection still or a NEW model ? + var isMultiple = IsMultipleDataType(propertyType.DataType); + return isMultiple + ? typeof(IEnumerable) + : typeof(MediaWithCrops); + } + + public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object source, bool preview) => source?.ToString(); + + public override object ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview) + { + var mediaItems = new List(); + var isMultiple = IsMultipleDataType(propertyType.DataType); + if (inter == null) + { + return isMultiple ? mediaItems: null; + } + + var dtos = JsonConvert.DeserializeObject>(inter.ToString()); + + foreach(var media in dtos) + { + var item = _publishedSnapshotAccessor.PublishedSnapshot.Media.GetById(media.MediaKey); + if (item != null) + { + mediaItems.Add(new MediaWithCrops + { + MediaItem = item, + Crops = media.Crops, + FocalPoint = media.FocalPoint + }); + } + } + + return isMultiple ? mediaItems : FirstOrDefault(mediaItems); + } + + /// + /// Is the media picker configured to pick multiple media items + /// + /// + /// + private bool IsMultipleDataType(PublishedDataType dataType) + { + var config = dataType.ConfigurationAs(); + return !config.SingleMode; + } + + private object FirstOrDefault(IList mediaItems) + { + return mediaItems.Count == 0 ? null : mediaItems[0]; + } + + + /// + /// Model/DTO that represents the JSON that the MediaPicker3 stores + /// + [DataContract] + internal class MediaWithCropsDto + { + [DataMember(Name = "key")] + public Guid Key { get; set; } + + [DataMember(Name = "mediaKey")] + public Guid MediaKey { get; set; } + + [DataMember(Name = "crops")] + public IEnumerable Crops { get; set; } + + [DataMember(Name = "focalPoint")] + public ImageCropperValue.ImageCropperFocalPoint FocalPoint { get; set; } + } + + /// + /// Model used in Razor Views for rendering + /// + public class MediaWithCrops + { + public IPublishedContent MediaItem { get; set; } + + public IEnumerable Crops { get; set; } + + public ImageCropperValue.ImageCropperFocalPoint FocalPoint { get; set; } + + } + + + } +} From edec35433af9af945a559845db9ae9cd7ba9517b Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Mon, 8 Feb 2021 15:58:34 +0000 Subject: [PATCH 33/90] Experimenting on best approach to retrieve local crop in razor view when iterating over picked media items --- .../ValueConverters/MediaPickerWithCropsValueConverter.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs index 3e47b91185b4..5af260f5ccad 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs @@ -147,6 +147,14 @@ public class MediaWithCrops public ImageCropperValue.ImageCropperFocalPoint FocalPoint { get; set; } + public string GetLocalCropUrl(string cropAlias) + { + if (MediaItem == null) return null; + + if (Crops.SingleOrDefault(x => x.Alias == cropAlias) == null) return null; + + return "?magic"; + } } From d1c357b51cdb3e40e42b33eb8fd75aacf8f5d96f Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Tue, 9 Feb 2021 12:05:37 +0000 Subject: [PATCH 34/90] Update ValueConvertor to use ImageCropperValue as part of the model for views as alot of existing CropUrls can then use it --- .../MediaPickerWithCropsValueConverter.cs | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs index 5af260f5ccad..9b1de9410b6b 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs @@ -2,7 +2,6 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; @@ -91,8 +90,12 @@ public override object ConvertIntermediateToObject(IPublishedElement owner, IPub mediaItems.Add(new MediaWithCrops { MediaItem = item, - Crops = media.Crops, - FocalPoint = media.FocalPoint + LocalCrops = new ImageCropperValue + { + Crops = media.Crops, + FocalPoint = media.FocalPoint, + Src = item.Url() + } }); } } @@ -143,20 +146,7 @@ public class MediaWithCrops { public IPublishedContent MediaItem { get; set; } - public IEnumerable Crops { get; set; } - - public ImageCropperValue.ImageCropperFocalPoint FocalPoint { get; set; } - - public string GetLocalCropUrl(string cropAlias) - { - if (MediaItem == null) return null; - - if (Crops.SingleOrDefault(x => x.Alias == cropAlias) == null) return null; - - return "?magic"; - } + public ImageCropperValue LocalCrops { get; set; } } - - } } From 8a6057dfb0bc528ffb27827047e978b3fe301536 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Tue, 9 Feb 2021 12:06:22 +0000 Subject: [PATCH 35/90] Update extension methods to take an ImageCropperValue model (localCropData) --- src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs | 5 +++++ src/Umbraco.Web/ImageCropperTemplateExtensions.cs | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs b/src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs index f39b267e18b0..9200c7dfe365 100644 --- a/src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs +++ b/src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs @@ -28,6 +28,11 @@ public static string GetCropUrl(this IPublishedContent mediaItem, string cropAli return mediaItem.GetCropUrl(imageUrlGenerator, cropAlias: cropAlias, useCropDimensions: true); } + public static string GetCropUrl(this IPublishedContent mediaItem, string cropAlias, IImageUrlGenerator imageUrlGenerator, ImageCropperValue imageCropperValue) + { + return mediaItem.Url().GetCropUrl(imageUrlGenerator, imageCropperValue, cropAlias: cropAlias, useCropDimensions: true); + } + /// /// Gets the ImageProcessor URL by the crop alias using the specified property containing the image cropper Json data on the IPublishedContent item. /// diff --git a/src/Umbraco.Web/ImageCropperTemplateExtensions.cs b/src/Umbraco.Web/ImageCropperTemplateExtensions.cs index 26dd2a5d36c6..2e9101a537d4 100644 --- a/src/Umbraco.Web/ImageCropperTemplateExtensions.cs +++ b/src/Umbraco.Web/ImageCropperTemplateExtensions.cs @@ -31,6 +31,8 @@ public static class ImageCropperTemplateExtensions /// public static string GetCropUrl(this IPublishedContent mediaItem, string cropAlias) => ImageCropperTemplateCoreExtensions.GetCropUrl(mediaItem, cropAlias, Current.ImageUrlGenerator); + public static string GetCropUrl(this IPublishedContent mediaItem, string cropAlias, ImageCropperValue imageCropperValue) => ImageCropperTemplateCoreExtensions.GetCropUrl(mediaItem, cropAlias, Current.ImageUrlGenerator, imageCropperValue); + /// /// Gets the ImageProcessor URL by the crop alias using the specified property containing the image cropper Json data on the IPublishedContent item. /// From a1c059f5c4f5bfb852a768cc254c0bb2416f9e05 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Tue, 9 Feb 2021 12:06:40 +0000 Subject: [PATCH 36/90] Forgot to update CSProj for new ValueConvertor --- src/Umbraco.Web/Umbraco.Web.csproj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 58b857cc70c4..4fe5cccb18b4 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -276,6 +276,7 @@ + @@ -1315,4 +1316,4 @@ - + \ No newline at end of file From e74a9258d4d794a33cb7edadcf64cd57af751652 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Tue, 9 Feb 2021 12:12:00 +0000 Subject: [PATCH 37/90] New GetCropUrl @Url.GetCropUrl(crop.Alias, media.LocalCrops) as oppposed to @Url.GetCropUrl(media.LocalCrops, cropAlias:crop.Alias, useCropDimensions: true) --- src/Umbraco.Web/UrlHelperRenderExtensions.cs | 26 ++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/Umbraco.Web/UrlHelperRenderExtensions.cs b/src/Umbraco.Web/UrlHelperRenderExtensions.cs index 0f5b0557f4a1..44c3e05972ce 100644 --- a/src/Umbraco.Web/UrlHelperRenderExtensions.cs +++ b/src/Umbraco.Web/UrlHelperRenderExtensions.cs @@ -262,6 +262,32 @@ public static IHtmlString GetCropUrl(this UrlHelper urlHelper, return htmlEncode ? new HtmlString(HttpUtility.HtmlEncode(url)) : new HtmlString(url); } + public static IHtmlString GetCropUrl(this UrlHelper urlHelper, + string cropAlias, + ImageCropperValue imageCropperValue, + int? width = null, + int? height = null, + int? quality = null, + ImageCropMode? imageCropMode = null, + ImageCropAnchor? imageCropAnchor = null, + bool preferFocalPoint = false, + bool useCropDimensions = true, + string cacheBusterValue = null, + string furtherOptions = null, + ImageCropRatioMode? ratioMode = null, + bool upScale = true, + bool htmlEncode = true) + { + if (imageCropperValue == null) return EmptyHtmlString; + + var imageUrl = imageCropperValue.Src; + var url = imageUrl.GetCropUrl(imageCropperValue, width, height, cropAlias, quality, imageCropMode, + imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBusterValue, furtherOptions, ratioMode, + upScale); + return htmlEncode ? new HtmlString(HttpUtility.HtmlEncode(url)) : new HtmlString(url); + } + + #endregion /// From d6b4c689a66c9f91d18415ee5cbcdde24ecaf7f7 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Wed, 17 Feb 2021 11:13:31 +0000 Subject: [PATCH 38/90] Remove dupe item in CSProj --- src/Umbraco.Web/Umbraco.Web.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 4fe5cccb18b4..0efb288e78d5 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -263,7 +263,6 @@ - From 763a65ffde52ae25f002a74abcc17e27c2b526d2 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Wed, 17 Feb 2021 11:17:20 +0000 Subject: [PATCH 39/90] Use a contains as an opposed to Array.IndexOf --- .../PropertyEditors/ValueConverters/JsonValueConverter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/JsonValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/JsonValueConverter.cs index 105b0f65990c..7f16108727c0 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/JsonValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/JsonValueConverter.cs @@ -40,7 +40,7 @@ public override bool IsConverter(IPublishedPropertyType propertyType) { return _propertyEditors.TryGet(propertyType.EditorAlias, out var editor) && editor.GetValueEditor().ValueType.InvariantEquals(ValueTypes.Json) - && Array.IndexOf(ExcludedPropertyEditors, propertyType.EditorAlias) == -1; + && ExcludedPropertyEditors.Contains(propertyType.EditorAlias) == false; } public override Type GetPropertyValueType(IPublishedPropertyType propertyType) From bfc20d13270a695df1409e555500fdd50c2acff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 25 Mar 2021 08:29:52 +0100 Subject: [PATCH 40/90] various corrections, SingleMode based on max 1, remove double checkerBackground, enforce validation for Crops, changed error indication --- .../src/less/property-editors.less | 5 +-- .../mediacard/umb-media-card-grid.less | 4 +++ .../components/mediacard/umb-media-card.html | 4 +-- .../components/mediacard/umb-media-card.less | 12 +++---- .../mediacard/umbMediaCard.component.js | 17 ++++++++-- .../prevalue/mediapicker3.crops.controller.js | 8 ++++- .../umb-media-picker3-property-editor.html | 33 ++++++++++--------- ...umbMediaPicker3PropertyEditor.component.js | 4 +-- .../MediaPicker3Configuration.cs | 3 -- .../MediaPickerWithCropsValueConverter.cs | 2 +- 10 files changed, 52 insertions(+), 40 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index aec464824dfd..94eb156570bf 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -671,10 +671,7 @@ @media (max-width: 768px) { flex-direction: column; } - - .viewport img { - .checkeredBackground(); - } + } .imagecropper .umb-cropper__container { diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less index 6c5d1fadd621..51ab125b01a0 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less @@ -10,6 +10,10 @@ padding: 20px; border: 1px solid @inputBorder; + + &.--singleMode { + max-width: 160px; + } } .umb-media-card-grid__cell { position: relative; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.html b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.html index aea28877b650..78c5c630120a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.html @@ -1,5 +1,5 @@ -
    +
    @@ -26,7 +26,7 @@
    - diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less index a10c8feb1466..d55ea09697e9 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less @@ -31,6 +31,10 @@ umb-media-card { } } + &.--hasError { + border: 2px solid @errorBackground; + } + &.--sortable-placeholder { &::after { content: ""; @@ -61,14 +65,6 @@ umb-media-card { //padding-bottom: 10/16*100%; //background-color: @gray-12; - &.--error { - border: 2px solid @errorBackground; - border-bottom: none; - border-top-left-radius: 6px; - border-top-right-radius: 6px; - box-sizing: border-box; - } - img { object-fit: contain; max-height: 240px; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js index f99acaaea77d..ab556f6b809b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js @@ -10,22 +10,33 @@ transclude: true, bindings: { mediaKey: "<", + hasError: "<", onNameClicked: "&?" } }); - function MediaCardController($scope, entityResource, mediaHelper, eventsService, localizationService) { + function MediaCardController($scope, $element, entityResource, mediaHelper, eventsService, localizationService) { var unsubscribe = []; var vm = this; vm.paddingBottom = 100;// Square while loading. vm.loading = true; - var unwatch = $scope.$watch("vm.mediaKey", (newValue, oldValue) => { + unsubscribe.push($scope.$watch("vm.mediaKey", (newValue, oldValue) => { if(newValue !== oldValue) { vm.updateThumbnail(); } - }); + })); + + function checkErrorState() { + if (vm.hasError === true || (vm.media && vm.media.trashed === true)) { + $element.addClass("--hasError") + } else { + $element.removeClass("--hasError") + } + } + checkErrorState(); + unsubscribe.push($scope.$watch(["vm.media.trashed", "vm.hasError"], checkErrorState)); vm.$onInit = function () { diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.controller.js index 525ddbec08e6..84fc920cc6da 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.controller.js @@ -29,9 +29,10 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.MediaPicker3.CropC crop.editMode = true; $scope.model.value.push(crop); - + $scope.validate(crop); } $scope.setChanges = function (crop) { + $scope.validate(crop); if( crop.hasWidthError !== true && crop.hasHeightError !== true && @@ -45,6 +46,11 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.MediaPicker3.CropC crop.alias = (crop.label || "").toCamelCase(); } }; + $scope.validate = function(crop) { + $scope.validateWidth(crop); + $scope.validateHeight(crop); + $scope.validateAlias(crop); + } $scope.validateWidth = function (crop) { crop.hasWidthError = !(Utilities.isNumber(crop.width) && crop.width > 0); }; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.html index d1806892f592..3ea4ea599d68 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.html @@ -2,7 +2,7 @@ -
    +
    @@ -22,7 +22,8 @@ + ng-class="{'--active': vm.activeMediaEntry === media}" + has-error="vm.propertyForm.maxCount.$valid === false && $index >= vm.validationLimit.max">
    - - - +
    -
    -
    - Minimum %0% entries, needs %1% more. -
    - > + + + +
    +
    + Minimum %0% entries, needs %1% more.
    -
    -
    - Maximum %0% entries, %1% too many. -
    - + > +
    +
    +
    + Maximum %0% entries, %1% too many.
    - +
    diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js index cbf31f995954..acff5f53e62f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js @@ -61,8 +61,8 @@ vm.$onInit = function() { - vm.singleMode = vm.model.config.singleMode || false; vm.validationLimit = vm.model.config.validationLimit; + vm.singleMode = vm.validationLimit.max === 1; copyAllMediasAction = { labelKey: "clipboard_labelForCopyAllEntries", @@ -129,7 +129,7 @@ startNodeId: vm.model.config.startNodeId, startNodeIsVirtual: vm.model.config.startNodeIsVirtual, dataTypeKey: vm.model.dataTypeKey, - multiPicker: vm.isSingleMode !== true, + multiPicker: vm.singleMode !== true, submit: function (model) { editorService.close(); diff --git a/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs b/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs index ac24a1ddc4b1..56fd7ad88743 100644 --- a/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs +++ b/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs @@ -15,9 +15,6 @@ public class MediaPicker3Configuration : IIgnoreUserStartNodesConfig Description = "Limit to specific types")] public string Filter { get; set; } - [ConfigurationField("singleMode", "Single Mode", "boolean")] - public bool SingleMode { get; set; } - [ConfigurationField("validationLimit", "Amount", "numberrange", Description = "Set a required range of medias")] public NumberRange ValidationLimit { get; set; } = new NumberRange(); diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs index 9b1de9410b6b..adf777a5fbdd 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs @@ -111,7 +111,7 @@ public override object ConvertIntermediateToObject(IPublishedElement owner, IPub private bool IsMultipleDataType(PublishedDataType dataType) { var config = dataType.ConfigurationAs(); - return !config.SingleMode; + return config.ValidationLimit.Max != 1; } private object FirstOrDefault(IList mediaItems) From 03a9dbc0b14d6deae22218b5228ca8fc6a781365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 26 Mar 2021 11:17:04 +0100 Subject: [PATCH 41/90] mediapicker v3 --- .../imaging/umbimagegravity.directive.js | 130 +++++++++--------- .../src/less/property-editors.less | 103 +++++++++----- .../mediaentryeditor.controller.js | 19 +-- .../mediaentryeditor/mediaentryeditor.html | 2 +- .../mediaentryeditor/mediaentryeditor.less | 2 +- .../components/imaging/umb-image-gravity.html | 11 +- .../mediacard/umbMediaCard.component.js | 3 - .../src/views/media/media.edit.controller.js | 4 + .../prevalue/mediapicker3.crops.controller.js | 1 + 9 files changed, 153 insertions(+), 122 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js index fd9a236f87f3..c4f52797a668 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js @@ -13,8 +13,8 @@ top: 0 }; - var htmlImage = null; //DOM element reference - var htmlOverlay = null; //DOM element reference + var imageElement = null; //DOM element reference + var focalPointElement = null; //DOM element reference var draggable = null; vm.loaded = false; @@ -22,33 +22,33 @@ vm.$onChanges = onChanges; vm.$postLink = postLink; vm.$onDestroy = onDestroy; - vm.style = style; + vm.style = {}; + vm.overlayStyle = {}; vm.setFocalPoint = setFocalPoint; /** Sets the css style for the Dot */ - function style() { - - if (vm.dimensions.width <= 0 || vm.dimensions.height <= 0) { - //this initializes the dimensions since when the image element first loads - //there will be zero dimensions - setDimensions(); - } - - return { + function updateStyle() { + vm.style = { 'top': vm.dimensions.top + 'px', 'left': vm.dimensions.left + 'px' }; + vm.overlayStyle = { + 'width': vm.dimensions.width + 'px', + 'height': vm.dimensions.height + 'px' + }; + }; - function setFocalPoint (event) { + function setFocalPoint(event) { $scope.$emit("imageFocalPointStart"); - var offsetX = event.offsetX - 10; - var offsetY = event.offsetY - 10; + // We do this to get the right position, no matter the focalPoint was clicked. + var viewportPosition = imageElement[0].getBoundingClientRect(); + var offsetX = event.clientX - viewportPosition.left; + var offsetY = event.clientY - viewportPosition.top; calculateGravity(offsetX, offsetY); - - lazyEndEvent(); + $scope.$emit("imageFocalPointStop"); }; /** Initializes the component */ @@ -61,33 +61,31 @@ /** Called when the component has linked everything and the DOM is available */ function postLink() { //elements - htmlImage = $element.find("img"); - htmlOverlay = $element.find(".overlay"); + imageElement = $element.find("img"); + focalPointElement = $element.find(".focalPoint"); //Drag and drop positioning, using jquery ui draggable - draggable = htmlOverlay.draggable({ + draggable = focalPointElement.draggable({ containment: "parent", start: function () { - $scope.$apply(function () { - $scope.$emit("imageFocalPointStart"); - }); + $scope.$emit("imageFocalPointStart"); }, - stop: function () { - $scope.$apply(function () { - var offsetX = htmlOverlay[0].offsetLeft; - var offsetY = htmlOverlay[0].offsetTop; - calculateGravity(offsetX, offsetY); - }); - - lazyEndEvent(); + stop: function (event, ui) { + + var offsetX = ui.position.left; + var offsetY = ui.position.top; + calculateGravity(offsetX, offsetY); + + $scope.$emit("imageFocalPointStop"); + } }); - $(window).on('resize.umbImageGravity', function () { - $scope.$apply(function () { - resized(); - }); - }); + console.log(focalPointElement.draggable) + + window.addEventListener('resize.umbImageGravity', onResizeHandler); + window.addEventListener('resize', onResizeHandler); + //if any ancestor directive emits this event, we need to resize $scope.$on("editors.content.splitViewChanged", function () { @@ -95,12 +93,12 @@ }); //listen for the image DOM element loading - htmlImage.on("load", function () { + imageElement.on("load", function () { $timeout(function () { vm.isCroppable = true; vm.hasDimensions = true; - + if (vm.src) { if (vm.src.endsWith(".svg")) { vm.isCroppable = false; @@ -117,6 +115,8 @@ } setDimensions(); + updateStyle(); + vm.loaded = true; if (vm.onImageLoaded) { vm.onImageLoaded({ @@ -129,16 +129,20 @@ } function onDestroy() { - $(window).off('resize.umbImageGravity'); - if (htmlOverlay) { + window.removeEventListener('resize.umbImageGravity', onResizeHandler); + window.removeEventListener('resize', onResizeHandler); + + if (focalPointElement && draggable) { // TODO: This should be destroyed but this will throw an exception: // "cannot call methods on draggable prior to initialization; attempted to call method 'destroy'" // I've tried lots of things and cannot get this to work, we weren't destroying before so hopefully // there's no mem leaks? - //htmlOverlay.draggable("destroy"); + console.log(focalPointElement.draggable) + focalPointElement.draggable("destroy"); + draggable = null; } - if (htmlImage) { - htmlImage.off("load"); + if (imageElement) { + imageElement.off("load"); } } @@ -146,14 +150,21 @@ function resized() { $timeout(function () { setDimensions(); + updateStyle(); }); + /* // Make sure we can find the offset values for the overlay(dot) before calculating // fixes issue with resize event when printing the page (ex. hitting ctrl+p inside the rte) - if (htmlOverlay.is(':visible')) { - var offsetX = htmlOverlay[0].offsetLeft; - var offsetY = htmlOverlay[0].offsetTop; + if (focalPointElement.is(':visible')) { + var offsetX = focalPointElement[0].offsetLeft; + var offsetY = focalPointElement[0].offsetTop; calculateGravity(offsetX, offsetY); } + */ + } + + function onResizeHandler() { + $scope.$evalAsync(resized); } /** Watches the one way binding changes */ @@ -163,17 +174,18 @@ && !Utilities.equals(changes.center.currentValue, changes.center.previousValue)) { //when center changes update the dimensions setDimensions(); + updateStyle(); } } /** Sets the width/height/left/top dimentions based on the image size and the "center" value */ function setDimensions() { - if (vm.isCroppable && htmlImage && vm.center) { - vm.dimensions.width = htmlImage.width(); - vm.dimensions.height = htmlImage.height(); - vm.dimensions.left = vm.center.left * vm.dimensions.width - 10; - vm.dimensions.top = vm.center.top * vm.dimensions.height - 10; + if (vm.isCroppable && imageElement && vm.center) { + vm.dimensions.width = imageElement.width(); + vm.dimensions.height = imageElement.height(); + vm.dimensions.left = vm.center.left * vm.dimensions.width; + vm.dimensions.top = vm.center.top * vm.dimensions.height; } return vm.dimensions.width; @@ -185,29 +197,19 @@ * @param {any} offsetY */ function calculateGravity(offsetX, offsetY) { - vm.onValueChanged({ - left: (offsetX + 10) / vm.dimensions.width, - top: (offsetY + 10) / vm.dimensions.height + left: Math.min(Math.max(offsetX, 0), vm.dimensions.width) / vm.dimensions.width, + top: Math.min(Math.max(offsetY, 0), vm.dimensions.height) / vm.dimensions.height }); - - //vm.center.left = (offsetX + 10) / scope.dimensions.width; - //vm.center.top = (offsetY + 10) / scope.dimensions.height; }; - var lazyEndEvent = _.debounce(function () { - $scope.$apply(function () { - $scope.$emit("imageFocalPointStop"); - }); - }, 2000); - } var umbImageGravityComponent = { templateUrl: 'views/components/imaging/umb-image-gravity.html', bindings: { src: "<", - center: "<", + center: "<", onImageLoaded: "&?", onValueChanged: "&" }, diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 94eb156570bf..5512f52d853c 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -499,20 +499,6 @@ border-color: @inputBorderFocus; } } -.umb-cropper-gravity img { - position: relative; - max-width: 100%; - height: auto; - top: 0; - left: 0; - } -.umb-cropper-gravity .overlay { - position: absolute; - top: 0; - left: 0; - cursor: move; - z-index: @zindexCropperOverlay; -} .umb-cropper .viewport { position: absolute; @@ -547,22 +533,6 @@ padding: 0px 6px; } -.umb-cropper-gravity .overlay{ - width: 14px; - height: 14px; - text-align: center; - border-radius: 20px; - background: @pinkLight; - border: 3px solid @white; - opacity: 0.8; -} - -.umb-cropper-gravity .overlay i { - font-size: 26px; - line-height: 26px; - opacity: 0.8 !important; -} - .umb-cropper .crop-controls-wrapper { display: flex; height: 50px; @@ -633,7 +603,7 @@ flex:0; } - .gravity-container { + .umb-cropper-gravity .gravity-container { border: 1px solid @gray-8; box-sizing: border-box; line-height: 0; @@ -641,20 +611,21 @@ height: 100%; overflow: hidden; .checkeredBackground(); - display: flex; - justify-content: center; - align-items: center; contain: content; .viewport { position: relative; - margin-left: auto; - margin-right: auto; - max-height: 100%; - max-width: 100%; + width: 100%; + height: 100%; + + display: flex; + justify-content: center; + align-items: center; img { display: block; + max-width: 100%; + max-height: 100%; } &:hover { @@ -663,6 +634,62 @@ } } + + .umb-cropper-gravity img { + position: relative; + max-width: 100%; + height: auto; + top: 0; + left: 0; + } + + .umb-cropper-gravity .overlayViewport { + position: absolute; + top:0; + bottom:0; + left:0; + right:0; + contain: strict; + + display: flex; + justify-content: center; + align-items: center; + } + .umb-cropper-gravity .overlay { + position: relative; + display: block; + max-width: 100%; + max-height: 100%; + cursor: crosshair; + } + .umb-cropper-gravity .overlay .focalPoint { + position: absolute; + top: 0; + left: 0; + cursor: move; + z-index: @zindexCropperOverlay; + + width: 14px; + height: 14px; + // this element should have no width or height as its preventing the jQuery draggable-plugin to go all the way to the sides: + margin-left: -10px; + margin-top: -10px; + margin-right: -10px; + margin-bottom: -10px; + + text-align: center; + border-radius: 20px; + background: @pinkLight; + border: 3px solid @white; + opacity: 0.8; + } + + .umb-cropper-gravity .overlay .focalPoint i { + font-size: 26px; + line-height: 26px; + opacity: 0.8 !important; + } + .imagecropper { display: flex; align-items: flex-start; diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js index 9504b9ee6379..d43e6198d1b7 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js @@ -1,6 +1,6 @@ angular.module("umbraco") .controller("Umbraco.Editors.MediaEntryEditorController", - function ($scope, localizationService, entityResource, overlayService, eventsService, mediaHelper) { + function ($scope, localizationService, entityResource, editorService, overlayService, eventsService, mediaHelper) { var unsubscribe = []; var vm = this; @@ -8,6 +8,7 @@ angular.module("umbraco") vm.loading = true; vm.model = $scope.model; vm.mediaEntry = vm.model.mediaEntry; + vm.currentCrop = null; localizationService.localizeMany([ vm.model.createFlow ? "general_cancel" : "general_close", @@ -17,15 +18,13 @@ angular.module("umbraco") vm.submitLabel = data[1]; }); - console.log("MediaEntryEditorController", vm.model, vm.mediaEntry); - function init() { updateMedia(); unsubscribe.push(eventsService.on("editors.media.saved", function(name, args) { // if this media item uses the updated media type we want to reload the media file - if(args && args.media && args.media.key === vm.model.mediaEntry.mediaKey) { + if(args && args.media && args.media.key === vm.mediaEntry.mediaKey) { updateMedia(); } })); @@ -33,11 +32,8 @@ angular.module("umbraco") function updateMedia() { - // TODO: test that we update a media if its saved.. - console.log("updateMedia", vm.model.mediaEntry.mediaKey); - vm.loading = true; - entityResource.getById(vm.model.mediaEntry.mediaKey, "Media").then(function (mediaEntity) { + entityResource.getById(vm.mediaEntry.mediaKey, "Media").then(function (mediaEntity) { vm.media = mediaEntity; vm.imageSrc = mediaHelper.resolveFileFromEntity(mediaEntity, true); vm.loading = false; @@ -82,9 +78,10 @@ angular.module("umbraco") } vm.openMedia = openMedia; - function openMedia(item) { + function openMedia() { + var mediaEditor = { - id: item.id, + id: vm.mediaEntry.mediaKey, submit: function () { editorService.close(); }, @@ -125,10 +122,8 @@ angular.module("umbraco") function resetCrop() { if (vm.currentCrop) { $scope.$evalAsync( () => { - console.log(vm.currentCrop); vm.model.propertyEditor.resetCrop(vm.currentCrop); vm.forceUpdateCrop = Math.random(); - console.log(vm.forceUpdateCrop); }); } } diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html index 43e33532fcff..eed85e54ead7 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html @@ -56,7 +56,7 @@
    -
    +
    - +
    - + -
    +
    +
    + +
    +
    +
    diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js index ab556f6b809b..e3f427c41819 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js @@ -58,9 +58,6 @@ vm.updateThumbnail = function () { - // TODO: test that we update a media if its saved.. - console.log("updateThumbnail", vm.mediaKey) - vm.loading = true; entityResource.getById(vm.mediaKey, "Media").then(function (mediaEntity) { diff --git a/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js index 57bb037f939a..88d112e2d638 100644 --- a/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js @@ -206,6 +206,10 @@ function mediaEditController($scope, $routeParams, $location, $http, $q, appStat init(); } + eventsService.emit("editors.media.saved", {media: data}); + + return data; + }, function(err) { formHelper.resetForm({ scope: $scope, hasErrors: true }); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.controller.js index 84fc920cc6da..922370a032ca 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/prevalue/mediapicker3.crops.controller.js @@ -39,6 +39,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.MediaPicker3.CropC crop.hasAliasError !== true ) { crop.editMode = false; + window.dispatchEvent(new Event('resize.umbImageGravity')); } }; $scope.useForAlias = function (crop) { From 0fb259140e905f7777eb3dd84e38eb541c8fffa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 26 Mar 2021 12:13:37 +0100 Subject: [PATCH 42/90] correct version --- src/Umbraco.Core/Constants-PropertyEditors.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Core/Constants-PropertyEditors.cs b/src/Umbraco.Core/Constants-PropertyEditors.cs index 364013e6b2b6..3bd9f3374c7f 100644 --- a/src/Umbraco.Core/Constants-PropertyEditors.cs +++ b/src/Umbraco.Core/Constants-PropertyEditors.cs @@ -97,7 +97,7 @@ public static class Aliases public const string MediaPicker = "Umbraco.MediaPicker"; /// - /// Media Picker v.4. + /// Media Picker v.3. /// public const string MediaPicker3 = "Umbraco.MediaPicker3"; From 90d62c2d7b25df3da1bf125114a5bf4848166885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 29 Mar 2021 08:05:47 +0200 Subject: [PATCH 43/90] fixing file ext label text color --- .../src/less/components/umb-file-icon.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-file-icon.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-file-icon.less index febee80a9778..ffe87277e660 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-file-icon.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-file-icon.less @@ -20,7 +20,7 @@ > span { position: absolute; - color: @white; + color: @ui-active-type; background: @ui-active; padding: 1px 3px; font-size: 10px; From 6857e0e020797e58634ecc02d5c9584bf4673d4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 29 Mar 2021 13:48:45 +0200 Subject: [PATCH 44/90] clipboard features for MediaPicker v3 --- .../imaging/umbimagegravity.directive.js | 7 +- .../src/common/services/clipboard.service.js | 6 ++ .../src/main.controller.js | 24 ++--- .../mediapicker/mediapicker.controller.js | 41 +++++++++ .../mediapicker/mediapicker.html | 29 +++++- .../mediacard/umb-media-card-grid.less | 3 - .../components/mediacard/umb-media-card.html | 14 +-- .../components/mediacard/umb-media-card.less | 24 +++-- .../mediacard/umbMediaCard.component.js | 35 +++---- .../umb-block-list-property-editor.less | 2 +- .../umb-media-picker3-property-editor.html | 10 +- .../umb-media-picker3-property-editor.less | 6 ++ ...umbMediaPicker3PropertyEditor.component.js | 92 ++++++++++++++++--- src/Umbraco.Web.UI/Umbraco/config/lang/da.xml | 1 + src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 1 + .../Umbraco/config/lang/en_us.xml | 1 + 16 files changed, 226 insertions(+), 70 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js index c4f52797a668..3c4be47b13dc 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js @@ -131,16 +131,15 @@ function onDestroy() { window.removeEventListener('resize.umbImageGravity', onResizeHandler); window.removeEventListener('resize', onResizeHandler); - - if (focalPointElement && draggable) { + /* + if (focalPointElement) { // TODO: This should be destroyed but this will throw an exception: // "cannot call methods on draggable prior to initialization; attempted to call method 'destroy'" // I've tried lots of things and cannot get this to work, we weren't destroying before so hopefully // there's no mem leaks? - console.log(focalPointElement.draggable) focalPointElement.draggable("destroy"); - draggable = null; } + */ if (imageElement) { imageElement.off("load"); } diff --git a/src/Umbraco.Web.UI.Client/src/common/services/clipboard.service.js b/src/Umbraco.Web.UI.Client/src/common/services/clipboard.service.js index 83fd3d08c233..901e5fa93cf7 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/clipboard.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/clipboard.service.js @@ -17,6 +17,7 @@ function clipboardService($window, notificationsService, eventsService, localSto TYPES.ELEMENT_TYPE = "elementType"; TYPES.BLOCK = "block"; TYPES.RAW = "raw"; + TYPES.MEDIA = "media"; var clearPropertyResolvers = {}; var pastePropertyResolvers = {}; @@ -70,6 +71,9 @@ function clipboardService($window, notificationsService, eventsService, localSto propMethod(data[p], TYPES.RAW); } } + clipboardTypeResolvers[TYPES.MEDIA] = function(data, propMethod) { + // no resolving needed for this type currently. + } var STORAGE_KEY = "umbClipboardService"; @@ -147,6 +151,8 @@ function clipboardService($window, notificationsService, eventsService, localSto return entry.type === type && ( + allowedAliases === null + || (entry.alias && allowedAliases.filter(allowedAlias => allowedAlias === entry.alias).length > 0) || (entry.aliases && entry.aliases.filter(entryAlias => allowedAliases.filter(allowedAlias => allowedAlias === entryAlias).length > 0).length === entry.aliases.length) diff --git a/src/Umbraco.Web.UI.Client/src/main.controller.js b/src/Umbraco.Web.UI.Client/src/main.controller.js index d21331f1069a..7d9431fcae6f 100644 --- a/src/Umbraco.Web.UI.Client/src/main.controller.js +++ b/src/Umbraco.Web.UI.Client/src/main.controller.js @@ -1,18 +1,18 @@ -/** +/** * @ngdoc controller - * @name Umbraco.MainController + * @name Umbraco.MainController * @function - * - * @description + * + * @description * The main application controller - * + * */ -function MainController($scope, $location, appState, treeService, notificationsService, - userService, historyService, updateChecker, navigationService, eventsService, +function MainController($scope, $location, appState, treeService, notificationsService, + userService, historyService, updateChecker, navigationService, eventsService, tmhDynamicLocale, localStorageService, editorService, overlayService, assetsService, tinyMceAssets) { - + //the null is important because we do an explicit bool check on this in the view - $scope.authenticated = null; + $scope.authenticated = null; $scope.touchDevice = appState.getGlobalState("touchDevice"); $scope.infiniteMode = false; $scope.overlay = {}; @@ -27,14 +27,14 @@ function MainController($scope, $location, appState, treeService, notificationsS assetsService.loadJs(tinyJsAsset, $scope); }); - // There are a number of ways to detect when a focus state should be shown when using the tab key and this seems to be the simplest solution. + // There are a number of ways to detect when a focus state should be shown when using the tab key and this seems to be the simplest solution. // For more information about this approach, see https://hackernoon.com/removing-that-ugly-focus-ring-and-keeping-it-too-6c8727fefcd2 function handleFirstTab(evt) { if (evt.keyCode === 9) { enableTabbingActive(); } } - + function enableTabbingActive() { $scope.tabbingActive = true; $scope.$digest(); @@ -185,7 +185,7 @@ function MainController($scope, $location, appState, treeService, notificationsS evts.push(eventsService.on("appState.overlay", function (name, args) { $scope.overlay = args; })); - + // events for tours evts.push(eventsService.on("appState.tour.start", function (name, args) { $scope.tour = args; diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js index 6f9ce6ee3405..c6b1e9b8e5bb 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js @@ -571,6 +571,47 @@ angular.module("umbraco") } } + + vm.navigation = []; + + localizationService.localizeMany(["sections_media", "mediaPicker_tabClipboard"]).then( + function (data) { + + vm.navigation = [{ + "alias": "empty", + "name": data[0], + "icon": "icon-umb-media", + "active": true, + "view": "" + }]; + + if(dialogOptions.clipboardItems) { + vm.navigation.push({ + "alias": "clipboard", + "name": data[1], + "icon": "icon-paste-in", + "view": "", + "disabled": dialogOptions.clipboardItems.length === 0 + }); + } + + vm.activeTab = vm.navigation[0]; + } + ); + + vm.onNavigationChanged = function(tab) { + vm.activeTab.active = false; + vm.activeTab = tab; + vm.activeTab.active = true; + } + + vm.clickClearClipboard = function() { + vm.onNavigationChanged(vm.navigation[0]); + vm.navigation[1].disabled = true;// disabled ws determined when creating the navigation, so we need to update it here. + dialogOptions.clipboardItems = [];// This dialog is not connected via the clipboardService events, so we need to update manually. + dialogOptions.clickClearClipboard(); + } + onInit(); }); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.html index df0c8e3cef72..6e47345621b1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.html @@ -6,10 +6,12 @@ name-locked="true" hide-alias="true" hide-icon="true" - hide-description="true"> + hide-description="true" + navigation="vm.navigation" + on-select-navigation-item="vm.onNavigationChanged(item)"> - +
    @@ -151,6 +153,29 @@
    +
    + + +
    + + +
    + +
    + + +
    +
    diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less index 51ab125b01a0..9365cfd38a07 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less @@ -8,9 +8,6 @@ justify-items: center; align-items: center; - padding: 20px; - border: 1px solid @inputBorder; - &.--singleMode { max-width: 160px; } diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.html b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.html index 78c5c630120a..14a1a6cb2a52 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.html @@ -10,11 +10,11 @@ ng-attr-title="{{vm.media.trashed ? (vm.labels.trashed || 'Trashed') + ': ' + vm.media.name : vm.media.name}}" alt="{{vm.media.name}}" /> - + +
    - diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less index d55ea09697e9..2b852364f328 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less @@ -113,6 +113,10 @@ umb-media-card { color: @ui-action-type; margin-left: 16px; margin-bottom: -1px; + + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } .__subname { color: @gray-4; @@ -138,19 +142,23 @@ umb-media-card { .__actions { position: absolute; top: 10px; - right: 0; + right: 10px; + font-size: 0; + background-color: rgba(255, 255, 255, .96); + border-radius: 16px; + padding-left: 5px; + padding-right: 5px; + opacity: 0; transition: opacity 120ms; .__action { display: inline-block; - border-radius: 50%; - width: 28px; - height: 28px; - margin-right: 10px; - background-color: white; - color:@ui-action-type; + padding: 5px; + font-size: 18px; + + color: @ui-action-discreet-type; &:hover { - color: @ui-action-type-hover; + color: @ui-action-discreet-type-hover; } } } diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js index e3f427c41819..b9e1b9825bc4 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js @@ -9,7 +9,9 @@ controllerAs: "vm", transclude: true, bindings: { - mediaKey: "<", + mediaKey: " { if(newValue !== oldValue) { @@ -52,29 +54,30 @@ vm.$onDestroy = function () { - unwatch(); unsubscribe.forEach(x => x()); } vm.updateThumbnail = function () { - vm.loading = true; + if(vm.mediaKey && vm.mediaKey !== "") { + vm.loading = true; - entityResource.getById(vm.mediaKey, "Media").then(function (mediaEntity) { - vm.media = mediaEntity; - vm.thumbnail = mediaHelper.resolveFileFromEntity(mediaEntity, true); + entityResource.getById(vm.mediaKey, "Media").then(function (mediaEntity) { + vm.media = mediaEntity; + vm.thumbnail = mediaHelper.resolveFileFromEntity(mediaEntity, true); - vm.loading = false; - }, function () { - localizationService.localize("mediaPicker_deletedItem").then(function (localized) { - vm.media = { - name: localized, - icon: "icon-picture", - trashed: true - }; vm.loading = false; + }, function () { + localizationService.localize("mediaPicker_deletedItem").then(function (localized) { + vm.media = { + name: localized, + icon: "icon-picture", + trashed: true + }; + vm.loading = false; + }); }); - }); + } } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/umb-block-list-property-editor.less b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/umb-block-list-property-editor.less index e290c6e85684..63ea661de707 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/umb-block-list-property-editor.less +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/umb-block-list-property-editor.less @@ -10,7 +10,7 @@ .umb-block-list__wrapper { position: relative; - max-width: 1024px; + .umb-property-editor--limit-width(); > .ui-sortable > .ui-sortable-helper > .umb-block-list__block > .umb-block-list__block--content > * { box-shadow: 0px 5px 10px 0 rgba(0,0,0,.2); } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.html index 3ea4ea599d68..76b3dd99b61b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.html @@ -21,13 +21,15 @@
    - +
    diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.less b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.less index 20d7445bcc50..3f2b7229564a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.less +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.less @@ -1,3 +1,9 @@ .umb-mediapicker3 { + .umb-media-card-grid { + padding: 20px; + border: 1px solid @inputBorder; + box-sizing: border-box; + .umb-property-editor--limit-width(); + } } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js index acff5f53e62f..f798acd1070f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js @@ -28,7 +28,7 @@ } }); - function MediaPicker3Controller($scope, editorService, clipboardService, localizationService, overlayService, userService) { + function MediaPicker3Controller($scope, editorService, clipboardService, localizationService, overlayService, userService, entityResource) { var unsubscribe = []; @@ -80,10 +80,11 @@ isDisabled: true }; - var propertyActions = [ - copyAllMediasAction, - removeAllMediasAction - ]; + var propertyActions = []; + if(vm.supportCopy) { + propertyActions.push(copyAllMediasAction); + } + propertyActions.push(removeAllMediasAction); if (vm.umbProperty) { vm.umbProperty.setPropertyActions(propertyActions); @@ -130,6 +131,22 @@ startNodeIsVirtual: vm.model.config.startNodeIsVirtual, dataTypeKey: vm.model.dataTypeKey, multiPicker: vm.singleMode !== true, + clickPasteItem: function(item, mouseEvent) { + console.log("clickPasteItem", item, mouseEvent) + if (Array.isArray(item.data)) { + var indexIncrementor = 0; + item.data.forEach(function (entry) { + if (requestPasteFromClipboard(createIndex + indexIncrementor, entry, item.type)) { + indexIncrementor++; + } + }); + } else { + requestPasteFromClipboard(createIndex, item.data, item.type); + } + if(!(mouseEvent.ctrlKey || mouseEvent.metaKey)) { + mediaPicker.close(); + } + }, submit: function (model) { editorService.close(); @@ -154,10 +171,21 @@ mediaPicker.filter = vm.model.config.filter; } + console.log("vm.model.config.filter", vm.model.config.filter) + + mediaPicker.clickClearClipboard = function ($event) { + clipboardService.clearEntriesOfType(clipboardService.TYPES.Media, vm.model.config.filter || null); + }; + + mediaPicker.clipboardItems = clipboardService.retriveEntriesOfType(clipboardService.TYPES.MEDIA, vm.model.config.filter || null); + mediaPicker.clipboardItems.sort( (a, b) => { + return b.date - a.date + }); + editorService.mediaPicker(mediaPicker); } - // To be used by infinte editor. (defined here cause we need configuration from property editor) + // To be used by infinite editor. (defined here cause we need configuration from property editor) function changeMediaFor(mediaEntry, onSuccess) { var mediaPicker = { startNodeId: vm.model.config.startNodeId, @@ -218,7 +246,7 @@ } - + vm.removeMedia = removeMedia; function removeMedia(media) { var index = vm.model.value.indexOf(media); if(index !== -1) { @@ -235,7 +263,10 @@ } vm.editMedia = editMedia; - function editMedia(mediaEntry, options) { + function editMedia(mediaEntry, options, $event) { + + if($event) + $event.stopPropagation(); options = options || {}; @@ -276,23 +307,57 @@ } var requestCopyAllMedias = function() { - // TODO.. + var mediaKeys = vm.model.value.map(x => x.mediaKey) + entityResource.getByIds(mediaKeys, "Media").then(function (entities) { + + // gather aliases + var aliases = entities.map(mediaEntity => mediaEntity.metaData.ContentTypeAlias) + + // remove duplicate aliases + aliases = aliases.filter((item, index) => aliases.indexOf(item) === index); + + // get node name + var contentNodeName = "?"; + var contentNodeIcon = null; + if(vm.umbVariantContent) { + contentNodeName = vm.umbVariantContent.editor.content.name; + if(vm.umbVariantContentEditors) { + contentNodeIcon = vm.umbVariantContentEditors.content.icon.split(" ")[0]; + } else if (vm.umbElementEditorContent) { + contentNodeIcon = vm.umbElementEditorContent.model.documentType.icon.split(" ")[0]; + } + } else if (vm.umbElementEditorContent) { + contentNodeName = vm.umbElementEditorContent.model.documentType.name; + contentNodeIcon = vm.umbElementEditorContent.model.documentType.icon.split(" ")[0]; + } + + localizationService.localize("clipboard_labelForArrayOfItemsFrom", [vm.model.label, contentNodeName]).then(function(localizedLabel) { + clipboardService.copyArray(clipboardService.TYPES.MEDIA, aliases, vm.model.value, localizedLabel, contentNodeIcon || "icon-thumbnail-list", vm.model.id); + }); + }); } - function copyMedia(media) { - //clipboardService.copy(clipboardService.TYPES.MEDIA, block.content.contentTypeAlias, {"layout": block.layout, "data": block.data, "settingsData":block.settingsData}, block.label, block.content.icon, block.content.udi); + + vm.copyMedia = copyMedia; + function copyMedia(mediaEntry) { + entityResource.getById(mediaEntry.mediaKey, "Media").then(function (mediaEntity) { + clipboardService.copy(clipboardService.TYPES.MEDIA, mediaEntity.metaData.ContentTypeAlias, mediaEntry, mediaEntity.name, mediaEntity.icon, mediaEntity.udi); + }); } - function requestPasteFromClipboard(index, pasteEntry, pasteType) { + function requestPasteFromClipboard(createIndex, pasteEntry, pasteType) { if (pasteEntry === undefined) { return false; } - //TODO... + pasteEntry.key = String.CreateGuid(); + updateMediaEntryData(pasteEntry); + vm.model.value.splice(createIndex, 0, pasteEntry); return true; } + /* vm.requestRemoveMedia = requestRemoveMedia; function requestRemoveMedia(media) { localizationService.localizeMany(["general_delete", "mediaPicker_confirmRemoveMediaEntryMessage", "general_remove"]).then(function (data) { @@ -312,6 +377,7 @@ overlayService.confirmDelete(overlay); }); } + */ function requestRemoveAllMedia() { localizationService.localizeMany(["mediaPicker_confirmRemoveAllMediaEntryMessage", "general_remove"]).then(function (data) { overlayService.confirmDelete({ diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml index feb5cf1cb93b..8e0124e6853a 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml @@ -1098,6 +1098,7 @@ Mange hilsner fra Umbraco robotten Du har foretaget ændringer til bruge af dette media. Er du sikker på at du vil annullere? Fjern? Fjern brugen af alle medier? + Udklipsholder indtast eksternt link diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml index 22050d117d5f..b82d7dac3fb8 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml @@ -1351,6 +1351,7 @@ To manage your website, simply open the Umbraco back office and start adding con You have made changes to this content. Are you sure you want to discard them? Remove? Remove all medias? + Clipboard enter external link 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 74b0fe5481ec..6b9e80faa58a 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml @@ -1361,6 +1361,7 @@ To manage your website, simply open the Umbraco back office and start adding con You have made changes to this content. Are you sure you want to discard them? Remove? Remove all medias? + Clipboard enter external link From 2e92730e25168b7cf4c63f84931ea7b6ec79a39b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 29 Mar 2021 14:47:59 +0200 Subject: [PATCH 45/90] highlight not allowed types --- .../components/mediacard/umb-media-card.html | 16 ++++++++++++++-- .../components/mediacard/umb-media-card.less | 16 +++++++++++++++- .../mediacard/umbMediaCard.component.js | 15 ++++++++++++--- .../umb-media-picker3-property-editor.html | 3 ++- .../umbMediaPicker3PropertyEditor.component.js | 7 +++---- src/Umbraco.Web.UI/Umbraco/config/lang/da.xml | 1 + src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 1 + src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml | 1 + 8 files changed, 49 insertions(+), 11 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.html b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.html index 14a1a6cb2a52..01ce31415ee1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.html @@ -1,13 +1,23 @@ - +
    +

    + + +

    + +

    + + +

    + {{vm.media.name}} + diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less index 2b852364f328..d1b76102fff3 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less @@ -56,6 +56,20 @@ umb-media-card { box-shadow: none; } + .__status { + + position: absolute; + top: 0; + left: 0; + right: 0; + padding: 2px; + + &.--error { + background-color: @errorBackground; + color: @errorText; + } + } + .__showcase { position: relative; max-width: 100%; @@ -77,7 +91,7 @@ umb-media-card { .umb-file-icon { position: absolute; top: 0; - bottom: 30px; + bottom: 0; left: 10px; right: 10px; display: flex; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js index b9e1b9825bc4..6363ba5153ba 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js @@ -13,6 +13,7 @@ icon: " 0 && vm.allowedTypes.indexOf(vm.media.metaData.ContentTypeAlias) === -1); + + if ( + vm.hasError === true || vm.notAllowed === true || (vm.media && vm.media.trashed === true) + ) { $element.addClass("--hasError") + vm.mediaCardForm.$setValidity('error', false) } else { $element.removeClass("--hasError") + vm.mediaCardForm.$setValidity('error', true) } } - checkErrorState(); - unsubscribe.push($scope.$watch(["vm.media.trashed", "vm.hasError"], checkErrorState)); vm.$onInit = function () { + unsubscribe.push($scope.$watch(["vm.media.trashed", "vm.hasError"], checkErrorState)); + vm.updateThumbnail(); unsubscribe.push(eventsService.on("editors.media.saved", function(name, args) { @@ -64,6 +72,7 @@ entityResource.getById(vm.mediaKey, "Media").then(function (mediaEntity) { vm.media = mediaEntity; + checkErrorState(); vm.thumbnail = mediaHelper.resolveFileFromEntity(mediaEntity, true); vm.loading = false; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.html index 76b3dd99b61b..aa9f50b7df17 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.html @@ -23,7 +23,8 @@ media-key="media.mediaKey" on-name-clicked="vm.editMedia(media, $index, $event)" ng-class="{'--active': vm.activeMediaEntry === media}" - has-error="vm.propertyForm.maxCount.$valid === false && $index >= vm.validationLimit.max"> + has-error="vm.propertyForm.maxCount.$valid === false && $index >= vm.validationLimit.max" + allowed-types="vm.allowedTypes">
    public const string Image = "Image"; + /// + /// MediaType alias for an video-. + /// + public const string Video = "Video"; + + /// + /// MediaType alias for an sound. + /// + public const string Sound = "Sound"; + + /// + /// MediaType alias for an document. + /// + public const string Document = "Document"; + + /// + /// MediaType alias for an vector. + /// + public const string VectorImage = "VectorImage"; + /// /// MediaType alias indicating allowing auto-selection. /// diff --git a/src/Umbraco.Core/Constants-DataTypes.cs b/src/Umbraco.Core/Constants-DataTypes.cs index 673da8f9a360..c0934ba7491a 100644 --- a/src/Umbraco.Core/Constants-DataTypes.cs +++ b/src/Umbraco.Core/Constants-DataTypes.cs @@ -25,6 +25,10 @@ public static class DataTypes public const int DropDownSingle = -39; public const int DropDownMultiple = -42; public const int Upload = -90; + public const int UploadVideo = -100; + public const int UploadSound = -101; + public const int UploadDocument = -102; + public const int UploadVectorImage = -103; public const int DefaultContentListView = -95; public const int DefaultMediaListView = -96; @@ -307,6 +311,46 @@ public static class Guids /// public static readonly Guid UploadGuid = new Guid(Upload); + /// + /// Guid for UploadVideo as string + /// + public const string UploadVideo = "70575fe7-9812-4396-bbe1-c81a76db71b5"; + + /// + /// Guid for UploadVideo + /// + public static readonly Guid UploadVideoGuid = new Guid(UploadVideo); + + /// + /// Guid for UploadSound as string + /// + public const string UploadSound = "8f430dd6-4e96-447e-9dc0-cb552c8cd1f3"; + + /// + /// Guid for UploadSound + /// + public static readonly Guid UploadSoundGuid = new Guid(UploadSound); + + /// + /// Guid for UploadDocument as string + /// + public const string UploadDocument = "bc1e266c-dac4-4164-bf08-8a1ec6a7143d"; + + /// + /// Guid for UploadDocument + /// + public static readonly Guid UploadDocumentGuid = new Guid(UploadDocument); + + /// + /// Guid for UploadVectorImage as string + /// + public const string UploadVectorImage = "215cb418-2153-4429-9aef-8c0f0041191b"; + + /// + /// Guid for UploadVectorImage + /// + public static readonly Guid UploadVectorImageGuid = new Guid(UploadVectorImage); + /// /// Guid for Label as string diff --git a/src/Umbraco.Core/Constants-Icons.cs b/src/Umbraco.Core/Constants-Icons.cs index d5cc37c9a58e..0a2dc7df9b59 100644 --- a/src/Umbraco.Core/Constants-Icons.cs +++ b/src/Umbraco.Core/Constants-Icons.cs @@ -59,6 +59,26 @@ public static class Icons /// public const string MediaFile = "icon-document"; + /// + /// System media video icon + /// + public const string MediaVideo = "icon-video"; + + /// + /// System media sound icon + /// + public const string MediaSound = "icon-sound-waves"; + + /// + /// System media document icon + /// + public const string MediaDocument = "icon-article"; + + /// + /// System media vector icon + /// + public const string MediaVector = "icon-picture"; + /// /// System media folder icon /// diff --git a/src/Umbraco.Core/Constants-PropertyTypeGroups.cs b/src/Umbraco.Core/Constants-PropertyTypeGroups.cs index d3402e69f894..2813dc6d44fd 100644 --- a/src/Umbraco.Core/Constants-PropertyTypeGroups.cs +++ b/src/Umbraco.Core/Constants-PropertyTypeGroups.cs @@ -17,6 +17,26 @@ public static class PropertyTypeGroups /// public const string File = "50899F9C-023A-4466-B623-ABA9049885FE"; + /// + /// Guid for a Video PropertyTypeGroup object. + /// + public const string Video = "2F0A61B6-CF92-4FF4-B437-751AB35EB254"; + + /// + /// Guid for a Video PropertyTypeGroup object. + /// + public const string Sound = "335FB495-0A87-4E82-B902-30EB367B767C"; + + /// + /// Guid for a Video PropertyTypeGroup object. + /// + public const string Document = "9AF3BD65-F687-4453-9518-5F180D1898EC"; + + /// + /// Guid for a Video PropertyTypeGroup object. + /// + public const string Vector = "F199B4D7-9E84-439F-8531-F87D9AF37711"; + /// /// Guid for a Image PropertyTypeGroup object. /// diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs index 9bd26749ad72..d476aa2e17ee 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs @@ -107,7 +107,11 @@ void InsertDataTypeNodeDto(int id, int sortOrder, string uniqueId, string text) InsertDataTypeNodeDto(Constants.DataTypes.LabelDateTime, 37, Constants.DataTypes.Guids.LabelDateTime, "Label (datetime)"); InsertDataTypeNodeDto(Constants.DataTypes.LabelTime, 38, Constants.DataTypes.Guids.LabelTime, "Label (time)"); InsertDataTypeNodeDto(Constants.DataTypes.LabelDecimal, 39, Constants.DataTypes.Guids.LabelDecimal, "Label (decimal)"); - _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Upload, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Upload}", SortOrder = 34, UniqueId = Constants.DataTypes.Guids.UploadGuid, Text = "Upload", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Upload, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Upload}", SortOrder = 34, UniqueId = Constants.DataTypes.Guids.UploadGuid, Text = "Upload File", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.UploadVideo, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.UploadVideo}", SortOrder = 35, UniqueId = Constants.DataTypes.Guids.UploadVideoGuid, Text = "Upload Video", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.UploadSound, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.UploadSound}", SortOrder = 36, UniqueId = Constants.DataTypes.Guids.UploadSoundGuid, Text = "Upload Sound", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.UploadDocument, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.UploadDocument}", SortOrder = 37, UniqueId = Constants.DataTypes.Guids.UploadDocumentGuid, Text = "Upload Document", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.UploadVectorImage, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.UploadVectorImage}", SortOrder = 38, UniqueId = Constants.DataTypes.Guids.UploadVectorImageGuid, Text = "Upload Vector Image", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Textarea, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Textarea}", SortOrder = 33, UniqueId = Constants.DataTypes.Guids.TextareaGuid, Text = "Textarea", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Textbox, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Textbox}", SortOrder = 32, UniqueId = Constants.DataTypes.Guids.TextstringGuid, Text = "Textstring", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.RichtextEditor, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.RichtextEditor}", SortOrder = 4, UniqueId = Constants.DataTypes.Guids.RichtextEditorGuid, Text = "Richtext editor", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); @@ -126,6 +130,10 @@ void InsertDataTypeNodeDto(int id, int sortOrder, string uniqueId, string text) _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1031, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1031", SortOrder = 2, UniqueId = new Guid("f38bd2d7-65d0-48e6-95dc-87ce06ec2d3d"), Text = Constants.Conventions.MediaTypes.Folder, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1032, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1032", SortOrder = 2, UniqueId = new Guid("cc07b313-0843-4aa8-bbda-871c8da728c8"), Text = Constants.Conventions.MediaTypes.Image, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1033, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1033", SortOrder = 2, UniqueId = new Guid("4c52d8ab-54e6-40cd-999c-7a5f24903e4d"), Text = Constants.Conventions.MediaTypes.File, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1034, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1034", SortOrder = 2, UniqueId = new Guid("f6c515bb-653c-4bdc-821c-987729ebe327"), Text = Constants.Conventions.MediaTypes.Video, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1035, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1035", SortOrder = 2, UniqueId = new Guid("a5ddeee0-8fd8-4cee-a658-6f1fcdb00de3"), Text = Constants.Conventions.MediaTypes.Sound, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1036, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1036", SortOrder = 2, UniqueId = new Guid("a43e3414-9599-4230-a7d3-943a21b20122"), Text = Constants.Conventions.MediaTypes.Document, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1037, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1037", SortOrder = 2, UniqueId = new Guid("c4b1efcf-a9d5-41c4-9621-e9d273b52a9c"), Text = Constants.Conventions.MediaTypes.Vector, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Tags, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Tags}", SortOrder = 2, UniqueId = new Guid("b6b73142-b9c1-4bf8-a16d-e1c23320b549"), Text = "Tags", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.ImageCropper, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.ImageCropper}", SortOrder = 2, UniqueId = new Guid("1df9f033-e6d4-451f-b8d2-e0cbc50a836f"), Text = "Image Cropper", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1044, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1044", SortOrder = 0, UniqueId = new Guid("d59be02f-1df9-4228-aa1e-01917d806cda"), Text = Constants.Conventions.MemberTypes.DefaultAlias, NodeObjectType = Constants.ObjectTypes.MemberType, CreateDate = DateTime.Now }); @@ -160,6 +168,10 @@ private void CreateContentTypeData() _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 532, NodeId = 1031, Alias = Constants.Conventions.MediaTypes.Folder, Icon = Constants.Icons.MediaFolder, Thumbnail = Constants.Icons.MediaFolder, IsContainer = false, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 533, NodeId = 1032, Alias = Constants.Conventions.MediaTypes.Image, Icon = Constants.Icons.MediaImage, Thumbnail = Constants.Icons.MediaImage, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 534, NodeId = 1033, Alias = Constants.Conventions.MediaTypes.File, Icon = Constants.Icons.MediaFile, Thumbnail = Constants.Icons.MediaFile, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 540, NodeId = 1034, Alias = Constants.Conventions.MediaTypes.Video, Icon = Constants.Icons.MediaVideo, Thumbnail = Constants.Icons.MediaVideo, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 541, NodeId = 1035, Alias = Constants.Conventions.MediaTypes.Sound, Icon = Constants.Icons.MediaSound, Thumbnail = Constants.Icons.MediaSound, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 542, NodeId = 1036, Alias = Constants.Conventions.MediaTypes.Document, Icon = Constants.Icons.MediaDocument, Thumbnail = Constants.Icons.MediaDocument, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 543, NodeId = 1037, Alias = Constants.Conventions.MediaTypes.Vector, Icon = Constants.Icons.MediaVector, Thumbnail = Constants.Icons.MediaVector, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 531, NodeId = 1044, Alias = Constants.Conventions.MemberTypes.DefaultAlias, Icon = Constants.Icons.Member, Thumbnail = Constants.Icons.Member, Variations = (byte) ContentVariation.Nothing }); } @@ -207,20 +219,44 @@ private void CreatePropertyTypeGroupData() { _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 3, ContentTypeNodeId = 1032, Text = "Image", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.Image) }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 4, ContentTypeNodeId = 1033, Text = "File", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.File) }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 52, ContentTypeNodeId = 1034, Text = "Video", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.Video) }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 53, ContentTypeNodeId = 1035, Text = "Sound", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.Sound) }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 54, ContentTypeNodeId = 1036, Text = "Document", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.Document) }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 55, ContentTypeNodeId = 1037, Text = "Vector Image", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.Vector) }); //membership property group _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 11, ContentTypeNodeId = 1044, Text = "Membership", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.Membership) }); } private void CreatePropertyTypeData() { - _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 6, UniqueId = 6.ToGuid(), DataTypeId = Constants.DataTypes.ImageCropper, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.File, Name = "Upload image", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 6, UniqueId = 6.ToGuid(), DataTypeId = Constants.DataTypes.ImageCropper, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.File, Name = "Image", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 7, UniqueId = 7.ToGuid(), DataTypeId = Constants.DataTypes.LabelInt, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Width, Name = "Width", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in pixels", Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 8, UniqueId = 8.ToGuid(), DataTypeId = Constants.DataTypes.LabelInt, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Height, Name = "Height", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in pixels", Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 9, UniqueId = 9.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 10, UniqueId = 10.ToGuid(), DataTypeId = -92, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); - _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 24, UniqueId = 24.ToGuid(), DataTypeId = Constants.DataTypes.Upload, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.File, Name = "Upload file", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 24, UniqueId = 24.ToGuid(), DataTypeId = Constants.DataTypes.Upload, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.File, Name = "File", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 25, UniqueId = 25.ToGuid(), DataTypeId = -92, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 26, UniqueId = 26.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing }); + + _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 40, UniqueId = 40.ToGuid(), DataTypeId = Constants.DataTypes.UploadVideo, ContentTypeId = 1034, PropertyTypeGroupId = 52, Alias = Constants.Conventions.Media.File, Name = "Video", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 41, UniqueId = 41.ToGuid(), DataTypeId = -92, ContentTypeId = 1034, PropertyTypeGroupId = 52, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 42, UniqueId = 42.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1034, PropertyTypeGroupId = 52, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing }); + + _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 43, UniqueId = 43.ToGuid(), DataTypeId = Constants.DataTypes.UploadSound, ContentTypeId = 1035, PropertyTypeGroupId = 53, Alias = Constants.Conventions.Media.File, Name = "Sound", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 44, UniqueId = 44.ToGuid(), DataTypeId = -92, ContentTypeId = 1035, PropertyTypeGroupId = 53, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 45, UniqueId = 45.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1035, PropertyTypeGroupId = 53, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing }); + + _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 46, UniqueId = 46.ToGuid(), DataTypeId = Constants.DataTypes.UploadDocument, ContentTypeId = 1036, PropertyTypeGroupId = 54, Alias = Constants.Conventions.Media.File, Name = "Document", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 47, UniqueId = 47.ToGuid(), DataTypeId = -92, ContentTypeId = 1036, PropertyTypeGroupId = 54, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 48, UniqueId = 48.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1036, PropertyTypeGroupId = 54, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing }); + + _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 49, UniqueId = 49.ToGuid(), DataTypeId = Constants.DataTypes.UploadVectorImage, ContentTypeId = 1037, PropertyTypeGroupId = 55, Alias = Constants.Conventions.Media.File, Name = "Vector Image", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 50, UniqueId = 50.ToGuid(), DataTypeId = -92, ContentTypeId = 1037, PropertyTypeGroupId = 55, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 51, UniqueId = 51.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1037, PropertyTypeGroupId = 55, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing }); + + + + //membership property types _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 28, UniqueId = 28.ToGuid(), DataTypeId = Constants.DataTypes.Textarea, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.Comments, Name = Constants.Conventions.Member.CommentsLabel, SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 29, UniqueId = 29.ToGuid(), DataTypeId = Constants.DataTypes.LabelInt, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.FailedPasswordAttempts, Name = Constants.Conventions.Member.FailedPasswordAttemptsLabel, SortOrder = 1, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); @@ -244,6 +280,10 @@ private void CreateContentChildTypeData() _database.Insert(Constants.DatabaseSchema.Tables.ContentChildType, "Id", false, new ContentTypeAllowedContentTypeDto { Id = 1031, AllowedId = 1031 }); _database.Insert(Constants.DatabaseSchema.Tables.ContentChildType, "Id", false, new ContentTypeAllowedContentTypeDto { Id = 1031, AllowedId = 1032 }); _database.Insert(Constants.DatabaseSchema.Tables.ContentChildType, "Id", false, new ContentTypeAllowedContentTypeDto { Id = 1031, AllowedId = 1033 }); + _database.Insert(Constants.DatabaseSchema.Tables.ContentChildType, "Id", false, new ContentTypeAllowedContentTypeDto { Id = 1031, AllowedId = 1034 }); + _database.Insert(Constants.DatabaseSchema.Tables.ContentChildType, "Id", false, new ContentTypeAllowedContentTypeDto { Id = 1031, AllowedId = 1035 }); + _database.Insert(Constants.DatabaseSchema.Tables.ContentChildType, "Id", false, new ContentTypeAllowedContentTypeDto { Id = 1031, AllowedId = 1036 }); + _database.Insert(Constants.DatabaseSchema.Tables.ContentChildType, "Id", false, new ContentTypeAllowedContentTypeDto { Id = 1031, AllowedId = 1037 }); } private void CreateDataTypeData() @@ -307,6 +347,39 @@ void InsertDataTypeDto(int id, string editorAlias, string dbType, string configu _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1049, EditorAlias = Constants.PropertyEditors.Aliases.MediaPicker, DbType = "Ntext", Configuration = "{\"multiPicker\":1}" }); _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1050, EditorAlias = Constants.PropertyEditors.Aliases.MultiUrlPicker, DbType = "Ntext" }); + + _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto + { + NodeId = Constants.DataTypes.UploadVideo, + EditorAlias = Constants.PropertyEditors.Aliases.UploadField, + DbType = "Nvarchar", + Configuration = "{\"fileExtensions\":[{\"id\":0, \"value\":\"mp4\"}, {\"id\":1, \"value\":\"webm\"}, {\"id\":2, \"value\":\"ogv\"}]}" + }); + + _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto + { + NodeId = Constants.DataTypes.UploadSound, + EditorAlias = Constants.PropertyEditors.Aliases.UploadField, + DbType = "Nvarchar", + Configuration = "{\"fileExtensions\":[{\"id\":0, \"value\":\"mp3\"}, {\"id\":1, \"value\":\"weba\"}, {\"id\":2, \"value\":\"oga\"}, {\"id\":3, \"value\":\"opus\"}]}" + }); + + _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto + { + NodeId = Constants.DataTypes.UploadDocument, + EditorAlias = Constants.PropertyEditors.Aliases.UploadField, + DbType = "Nvarchar", + Configuration = "{\"fileExtensions\":[{\"id\":0, \"value\":\"pdf\"}, {\"id\":1, \"value\":\"docx\"}, {\"id\":2, \"value\":\"doc\"}, {\"id\":3, \"value\":\"xlsx\"}, {\"id\":4, \"value\":\"xls\"}, {\"id\":5, \"value\":\"pptx\"}, {\"id\":6, \"value\":\"ppt\"}, {\"id\":7, \"value\":\"epub\"}, {\"id\":8, \"value\":\"txt\"}, {\"id\":9, \"value\":\"rtf\"}]}" + }); + + _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto + { + NodeId = Constants.DataTypes.UploadVectorImage, + EditorAlias = Constants.PropertyEditors.Aliases.UploadField, + DbType = "Nvarchar", + Configuration = "{\"fileExtensions\":[{\"id\":0, \"value\":\"svg\"}]}" + }); + } private void CreateRelationTypeData() From 1bb69831135b08bc904376e8b11a1f2cf8fa9735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 30 Mar 2021 11:41:05 +0200 Subject: [PATCH 48/90] Rename to Audio and VectorGraphics --- src/Umbraco.Core/Constants-Conventions.cs | 8 +++--- src/Umbraco.Core/Constants-DataTypes.cs | 26 +++++++++---------- src/Umbraco.Core/Constants-Icons.cs | 8 +++--- .../Constants-PropertyTypeGroups.cs | 10 +++---- .../Migrations/Install/DatabaseDataCreator.cs | 24 ++++++++--------- 5 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/Umbraco.Core/Constants-Conventions.cs b/src/Umbraco.Core/Constants-Conventions.cs index 51bd077ba5bf..e983c429e461 100644 --- a/src/Umbraco.Core/Constants-Conventions.cs +++ b/src/Umbraco.Core/Constants-Conventions.cs @@ -124,9 +124,9 @@ public static class MediaTypes public const string Video = "Video"; /// - /// MediaType alias for an sound. + /// MediaType alias for an audio. /// - public const string Sound = "Sound"; + public const string Audio = "Audio"; /// /// MediaType alias for an document. @@ -134,9 +134,9 @@ public static class MediaTypes public const string Document = "Document"; /// - /// MediaType alias for an vector. + /// MediaType alias for an vector graphics. /// - public const string VectorImage = "VectorImage"; + public const string VectorGraphics = "VectorGraphics"; /// /// MediaType alias indicating allowing auto-selection. diff --git a/src/Umbraco.Core/Constants-DataTypes.cs b/src/Umbraco.Core/Constants-DataTypes.cs index c0934ba7491a..a1f801e0e66f 100644 --- a/src/Umbraco.Core/Constants-DataTypes.cs +++ b/src/Umbraco.Core/Constants-DataTypes.cs @@ -26,9 +26,9 @@ public static class DataTypes public const int DropDownMultiple = -42; public const int Upload = -90; public const int UploadVideo = -100; - public const int UploadSound = -101; + public const int UploadAudio = -101; public const int UploadDocument = -102; - public const int UploadVectorImage = -103; + public const int UploadVectorGraphics = -103; public const int DefaultContentListView = -95; public const int DefaultMediaListView = -96; @@ -46,7 +46,7 @@ public static class ReservedPreValueKeys /// Defines the identifiers for Umbraco data types as constants for easy centralized access/management. /// public static class Guids - { + { /// /// Guid for Content Picker as string @@ -322,14 +322,14 @@ public static class Guids public static readonly Guid UploadVideoGuid = new Guid(UploadVideo); /// - /// Guid for UploadSound as string + /// Guid for UploadAudio as string /// - public const string UploadSound = "8f430dd6-4e96-447e-9dc0-cb552c8cd1f3"; + public const string UploadAudio = "8f430dd6-4e96-447e-9dc0-cb552c8cd1f3"; /// - /// Guid for UploadSound + /// Guid for UploadAudio /// - public static readonly Guid UploadSoundGuid = new Guid(UploadSound); + public static readonly Guid UploadAudioGuid = new Guid(UploadAudio); /// /// Guid for UploadDocument as string @@ -342,14 +342,14 @@ public static class Guids public static readonly Guid UploadDocumentGuid = new Guid(UploadDocument); /// - /// Guid for UploadVectorImage as string + /// Guid for UploadVectorGraphics as string /// - public const string UploadVectorImage = "215cb418-2153-4429-9aef-8c0f0041191b"; + public const string UploadVectorGraphics = "215cb418-2153-4429-9aef-8c0f0041191b"; /// - /// Guid for UploadVectorImage + /// Guid for UploadVectorGraphics /// - public static readonly Guid UploadVectorImageGuid = new Guid(UploadVectorImage); + public static readonly Guid UploadVectorGraphicsGuid = new Guid(UploadVectorGraphics); /// @@ -411,8 +411,8 @@ public static class Guids /// Guid for Label decimal /// public static readonly Guid LabelDecimalGuid = new Guid(LabelDecimal); - - + + } } } diff --git a/src/Umbraco.Core/Constants-Icons.cs b/src/Umbraco.Core/Constants-Icons.cs index 0a2dc7df9b59..0476ed691111 100644 --- a/src/Umbraco.Core/Constants-Icons.cs +++ b/src/Umbraco.Core/Constants-Icons.cs @@ -65,9 +65,9 @@ public static class Icons public const string MediaVideo = "icon-video"; /// - /// System media sound icon + /// System media audio icon /// - public const string MediaSound = "icon-sound-waves"; + public const string MediaAudio = "icon-sound-waves"; /// /// System media document icon @@ -77,7 +77,7 @@ public static class Icons /// /// System media vector icon /// - public const string MediaVector = "icon-picture"; + public const string MediaVectorGraphics = "icon-picture"; /// /// System media folder icon @@ -113,7 +113,7 @@ public static class Icons /// System packages icon /// public const string Packages = "icon-box"; - + /// /// System property editor icon /// diff --git a/src/Umbraco.Core/Constants-PropertyTypeGroups.cs b/src/Umbraco.Core/Constants-PropertyTypeGroups.cs index 2813dc6d44fd..4aecec6b1cc4 100644 --- a/src/Umbraco.Core/Constants-PropertyTypeGroups.cs +++ b/src/Umbraco.Core/Constants-PropertyTypeGroups.cs @@ -23,19 +23,19 @@ public static class PropertyTypeGroups public const string Video = "2F0A61B6-CF92-4FF4-B437-751AB35EB254"; /// - /// Guid for a Video PropertyTypeGroup object. + /// Guid for a Audio PropertyTypeGroup object. /// - public const string Sound = "335FB495-0A87-4E82-B902-30EB367B767C"; + public const string Audio = "335FB495-0A87-4E82-B902-30EB367B767C"; /// - /// Guid for a Video PropertyTypeGroup object. + /// Guid for a Document PropertyTypeGroup object. /// public const string Document = "9AF3BD65-F687-4453-9518-5F180D1898EC"; /// - /// Guid for a Video PropertyTypeGroup object. + /// Guid for a VectorGraphics PropertyTypeGroup object. /// - public const string Vector = "F199B4D7-9E84-439F-8531-F87D9AF37711"; + public const string VectorGraphics = "F199B4D7-9E84-439F-8531-F87D9AF37711"; /// /// Guid for a Image PropertyTypeGroup object. diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs index d476aa2e17ee..00e3d9f67c0b 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs @@ -109,9 +109,9 @@ void InsertDataTypeNodeDto(int id, int sortOrder, string uniqueId, string text) InsertDataTypeNodeDto(Constants.DataTypes.LabelDecimal, 39, Constants.DataTypes.Guids.LabelDecimal, "Label (decimal)"); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Upload, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Upload}", SortOrder = 34, UniqueId = Constants.DataTypes.Guids.UploadGuid, Text = "Upload File", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.UploadVideo, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.UploadVideo}", SortOrder = 35, UniqueId = Constants.DataTypes.Guids.UploadVideoGuid, Text = "Upload Video", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); - _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.UploadSound, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.UploadSound}", SortOrder = 36, UniqueId = Constants.DataTypes.Guids.UploadSoundGuid, Text = "Upload Sound", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.UploadAudio, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.UploadAudio}", SortOrder = 36, UniqueId = Constants.DataTypes.Guids.UploadAudioGuid, Text = "Upload Audio", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.UploadDocument, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.UploadDocument}", SortOrder = 37, UniqueId = Constants.DataTypes.Guids.UploadDocumentGuid, Text = "Upload Document", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); - _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.UploadVectorImage, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.UploadVectorImage}", SortOrder = 38, UniqueId = Constants.DataTypes.Guids.UploadVectorImageGuid, Text = "Upload Vector Image", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.UploadVectorGraphics, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.UploadVectorGraphics}", SortOrder = 38, UniqueId = Constants.DataTypes.Guids.UploadVectorGraphicsGuid, Text = "Upload Vector Graphics", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Textarea, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Textarea}", SortOrder = 33, UniqueId = Constants.DataTypes.Guids.TextareaGuid, Text = "Textarea", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Textbox, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Textbox}", SortOrder = 32, UniqueId = Constants.DataTypes.Guids.TextstringGuid, Text = "Textstring", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.RichtextEditor, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.RichtextEditor}", SortOrder = 4, UniqueId = Constants.DataTypes.Guids.RichtextEditorGuid, Text = "Richtext editor", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); @@ -131,9 +131,9 @@ void InsertDataTypeNodeDto(int id, int sortOrder, string uniqueId, string text) _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1032, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1032", SortOrder = 2, UniqueId = new Guid("cc07b313-0843-4aa8-bbda-871c8da728c8"), Text = Constants.Conventions.MediaTypes.Image, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1033, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1033", SortOrder = 2, UniqueId = new Guid("4c52d8ab-54e6-40cd-999c-7a5f24903e4d"), Text = Constants.Conventions.MediaTypes.File, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1034, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1034", SortOrder = 2, UniqueId = new Guid("f6c515bb-653c-4bdc-821c-987729ebe327"), Text = Constants.Conventions.MediaTypes.Video, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); - _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1035, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1035", SortOrder = 2, UniqueId = new Guid("a5ddeee0-8fd8-4cee-a658-6f1fcdb00de3"), Text = Constants.Conventions.MediaTypes.Sound, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1035, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1035", SortOrder = 2, UniqueId = new Guid("a5ddeee0-8fd8-4cee-a658-6f1fcdb00de3"), Text = Constants.Conventions.MediaTypes.Audio, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1036, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1036", SortOrder = 2, UniqueId = new Guid("a43e3414-9599-4230-a7d3-943a21b20122"), Text = Constants.Conventions.MediaTypes.Document, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); - _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1037, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1037", SortOrder = 2, UniqueId = new Guid("c4b1efcf-a9d5-41c4-9621-e9d273b52a9c"), Text = Constants.Conventions.MediaTypes.Vector, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1037, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1037", SortOrder = 2, UniqueId = new Guid("c4b1efcf-a9d5-41c4-9621-e9d273b52a9c"), Text = Constants.Conventions.MediaTypes.VectorGraphics, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Tags, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Tags}", SortOrder = 2, UniqueId = new Guid("b6b73142-b9c1-4bf8-a16d-e1c23320b549"), Text = "Tags", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.ImageCropper, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.ImageCropper}", SortOrder = 2, UniqueId = new Guid("1df9f033-e6d4-451f-b8d2-e0cbc50a836f"), Text = "Image Cropper", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1044, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1044", SortOrder = 0, UniqueId = new Guid("d59be02f-1df9-4228-aa1e-01917d806cda"), Text = Constants.Conventions.MemberTypes.DefaultAlias, NodeObjectType = Constants.ObjectTypes.MemberType, CreateDate = DateTime.Now }); @@ -169,9 +169,9 @@ private void CreateContentTypeData() _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 533, NodeId = 1032, Alias = Constants.Conventions.MediaTypes.Image, Icon = Constants.Icons.MediaImage, Thumbnail = Constants.Icons.MediaImage, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 534, NodeId = 1033, Alias = Constants.Conventions.MediaTypes.File, Icon = Constants.Icons.MediaFile, Thumbnail = Constants.Icons.MediaFile, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 540, NodeId = 1034, Alias = Constants.Conventions.MediaTypes.Video, Icon = Constants.Icons.MediaVideo, Thumbnail = Constants.Icons.MediaVideo, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing }); - _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 541, NodeId = 1035, Alias = Constants.Conventions.MediaTypes.Sound, Icon = Constants.Icons.MediaSound, Thumbnail = Constants.Icons.MediaSound, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 541, NodeId = 1035, Alias = Constants.Conventions.MediaTypes.Audio, Icon = Constants.Icons.MediaAudio, Thumbnail = Constants.Icons.MediaAudio, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 542, NodeId = 1036, Alias = Constants.Conventions.MediaTypes.Document, Icon = Constants.Icons.MediaDocument, Thumbnail = Constants.Icons.MediaDocument, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing }); - _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 543, NodeId = 1037, Alias = Constants.Conventions.MediaTypes.Vector, Icon = Constants.Icons.MediaVector, Thumbnail = Constants.Icons.MediaVector, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 543, NodeId = 1037, Alias = Constants.Conventions.MediaTypes.VectorGraphics, Icon = Constants.Icons.MediaVectorGraphics, Thumbnail = Constants.Icons.MediaVectorGraphics, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 531, NodeId = 1044, Alias = Constants.Conventions.MemberTypes.DefaultAlias, Icon = Constants.Icons.Member, Thumbnail = Constants.Icons.Member, Variations = (byte) ContentVariation.Nothing }); } @@ -220,9 +220,9 @@ private void CreatePropertyTypeGroupData() _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 3, ContentTypeNodeId = 1032, Text = "Image", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.Image) }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 4, ContentTypeNodeId = 1033, Text = "File", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.File) }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 52, ContentTypeNodeId = 1034, Text = "Video", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.Video) }); - _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 53, ContentTypeNodeId = 1035, Text = "Sound", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.Sound) }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 53, ContentTypeNodeId = 1035, Text = "Audio", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.Audio) }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 54, ContentTypeNodeId = 1036, Text = "Document", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.Document) }); - _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 55, ContentTypeNodeId = 1037, Text = "Vector Image", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.Vector) }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 55, ContentTypeNodeId = 1037, Text = "Vector Graphics", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.VectorGraphics) }); //membership property group _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 11, ContentTypeNodeId = 1044, Text = "Membership", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.Membership) }); } @@ -242,7 +242,7 @@ private void CreatePropertyTypeData() _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 41, UniqueId = 41.ToGuid(), DataTypeId = -92, ContentTypeId = 1034, PropertyTypeGroupId = 52, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 42, UniqueId = 42.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1034, PropertyTypeGroupId = 52, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing }); - _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 43, UniqueId = 43.ToGuid(), DataTypeId = Constants.DataTypes.UploadSound, ContentTypeId = 1035, PropertyTypeGroupId = 53, Alias = Constants.Conventions.Media.File, Name = "Sound", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 43, UniqueId = 43.ToGuid(), DataTypeId = Constants.DataTypes.UploadAudio, ContentTypeId = 1035, PropertyTypeGroupId = 53, Alias = Constants.Conventions.Media.File, Name = "Audio", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 44, UniqueId = 44.ToGuid(), DataTypeId = -92, ContentTypeId = 1035, PropertyTypeGroupId = 53, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 45, UniqueId = 45.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1035, PropertyTypeGroupId = 53, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing }); @@ -250,7 +250,7 @@ private void CreatePropertyTypeData() _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 47, UniqueId = 47.ToGuid(), DataTypeId = -92, ContentTypeId = 1036, PropertyTypeGroupId = 54, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 48, UniqueId = 48.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1036, PropertyTypeGroupId = 54, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing }); - _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 49, UniqueId = 49.ToGuid(), DataTypeId = Constants.DataTypes.UploadVectorImage, ContentTypeId = 1037, PropertyTypeGroupId = 55, Alias = Constants.Conventions.Media.File, Name = "Vector Image", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 49, UniqueId = 49.ToGuid(), DataTypeId = Constants.DataTypes.UploadVectorGraphics, ContentTypeId = 1037, PropertyTypeGroupId = 55, Alias = Constants.Conventions.Media.File, Name = "Vector Graphics", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 50, UniqueId = 50.ToGuid(), DataTypeId = -92, ContentTypeId = 1037, PropertyTypeGroupId = 55, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 51, UniqueId = 51.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1037, PropertyTypeGroupId = 55, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing }); @@ -358,7 +358,7 @@ void InsertDataTypeDto(int id, string editorAlias, string dbType, string configu _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { - NodeId = Constants.DataTypes.UploadSound, + NodeId = Constants.DataTypes.UploadAudio, EditorAlias = Constants.PropertyEditors.Aliases.UploadField, DbType = "Nvarchar", Configuration = "{\"fileExtensions\":[{\"id\":0, \"value\":\"mp3\"}, {\"id\":1, \"value\":\"weba\"}, {\"id\":2, \"value\":\"oga\"}, {\"id\":3, \"value\":\"opus\"}]}" @@ -374,7 +374,7 @@ void InsertDataTypeDto(int id, string editorAlias, string dbType, string configu _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { - NodeId = Constants.DataTypes.UploadVectorImage, + NodeId = Constants.DataTypes.UploadVectorGraphics, EditorAlias = Constants.PropertyEditors.Aliases.UploadField, DbType = "Nvarchar", Configuration = "{\"fileExtensions\":[{\"id\":0, \"value\":\"svg\"}]}" From 8380e0e145c46a1d41fdb7f015a191652875c204 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 30 Mar 2021 15:58:18 +0200 Subject: [PATCH 49/90] Add (SVG) in the name for Vector Graphics --- src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs index 00e3d9f67c0b..ffcdec335132 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs @@ -133,7 +133,7 @@ void InsertDataTypeNodeDto(int id, int sortOrder, string uniqueId, string text) _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1034, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1034", SortOrder = 2, UniqueId = new Guid("f6c515bb-653c-4bdc-821c-987729ebe327"), Text = Constants.Conventions.MediaTypes.Video, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1035, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1035", SortOrder = 2, UniqueId = new Guid("a5ddeee0-8fd8-4cee-a658-6f1fcdb00de3"), Text = Constants.Conventions.MediaTypes.Audio, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1036, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1036", SortOrder = 2, UniqueId = new Guid("a43e3414-9599-4230-a7d3-943a21b20122"), Text = Constants.Conventions.MediaTypes.Document, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); - _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1037, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1037", SortOrder = 2, UniqueId = new Guid("c4b1efcf-a9d5-41c4-9621-e9d273b52a9c"), Text = Constants.Conventions.MediaTypes.VectorGraphics, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1037, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1037", SortOrder = 2, UniqueId = new Guid("c4b1efcf-a9d5-41c4-9621-e9d273b52a9c"), Text = "Vector Graphics (SVG)", NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Tags, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Tags}", SortOrder = 2, UniqueId = new Guid("b6b73142-b9c1-4bf8-a16d-e1c23320b549"), Text = "Tags", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.ImageCropper, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.ImageCropper}", SortOrder = 2, UniqueId = new Guid("1df9f033-e6d4-451f-b8d2-e0cbc50a836f"), Text = "Image Cropper", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1044, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1044", SortOrder = 0, UniqueId = new Guid("d59be02f-1df9-4228-aa1e-01917d806cda"), Text = Constants.Conventions.MemberTypes.DefaultAlias, NodeObjectType = Constants.ObjectTypes.MemberType, CreateDate = DateTime.Now }); From 2777a662bbc6a11e0ebe15f378062ac68d51bf12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 31 Mar 2021 11:58:02 +0200 Subject: [PATCH 50/90] adding CSV to Documents --- src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs index ffcdec335132..be2c8bcf73a7 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs @@ -369,7 +369,7 @@ void InsertDataTypeDto(int id, string editorAlias, string dbType, string configu NodeId = Constants.DataTypes.UploadDocument, EditorAlias = Constants.PropertyEditors.Aliases.UploadField, DbType = "Nvarchar", - Configuration = "{\"fileExtensions\":[{\"id\":0, \"value\":\"pdf\"}, {\"id\":1, \"value\":\"docx\"}, {\"id\":2, \"value\":\"doc\"}, {\"id\":3, \"value\":\"xlsx\"}, {\"id\":4, \"value\":\"xls\"}, {\"id\":5, \"value\":\"pptx\"}, {\"id\":6, \"value\":\"ppt\"}, {\"id\":7, \"value\":\"epub\"}, {\"id\":8, \"value\":\"txt\"}, {\"id\":9, \"value\":\"rtf\"}]}" + Configuration = "{\"fileExtensions\":[{\"id\":0, \"value\":\"pdf\"}, {\"id\":1, \"value\":\"docx\"}, {\"id\":2, \"value\":\"doc\"}, {\"id\":3, \"value\":\"xlsx\"}, {\"id\":4, \"value\":\"xls\"}, {\"id\":5, \"value\":\"csv\"}, {\"id\":6, \"value\":\"pptx\"}, {\"id\":7, \"value\":\"ppt\"}, {\"id\":8, \"value\":\"epub\"}, {\"id\":9, \"value\":\"txt\"}, {\"id\":10, \"value\":\"rtf\"}]}" }); _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto From 29742c04a3d920b75a104dc810e4832791d8e9ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 31 Mar 2021 11:59:25 +0200 Subject: [PATCH 51/90] remove this commented code. --- src/Umbraco.Web/Editors/MediaController.cs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs index cb366a256f62..5f3a2612e510 100644 --- a/src/Umbraco.Web/Editors/MediaController.cs +++ b/src/Umbraco.Web/Editors/MediaController.cs @@ -726,18 +726,6 @@ public async Task PostAddFile() } } } - - - /* - IDataEditor editor = Current.Data[propertyTypeAlias]; - List fileExtensions = (List)editor.DefaultConfiguration.GetValue("fileExtensions", null); - if (fileExtensions != null) { - if (fileExtensions.Where(x => x.Value == ext).Count() != 0) { - mediaType = MediaType.Alias; - break; - } - } - */ } } From cb8a422a08fa2ed8a7c06fbc8033f6017c131559 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 31 Mar 2021 12:00:07 +0200 Subject: [PATCH 52/90] remove this commented code --- src/Umbraco.Web/Editors/MediaController.cs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs index 3f3d5d68a8fb..38ab4e4f4e2b 100644 --- a/src/Umbraco.Web/Editors/MediaController.cs +++ b/src/Umbraco.Web/Editors/MediaController.cs @@ -726,18 +726,6 @@ public async Task PostAddFile() } } } - - - /* - IDataEditor editor = Current.Data[propertyTypeAlias]; - List fileExtensions = (List)editor.DefaultConfiguration.GetValue("fileExtensions", null); - if (fileExtensions != null) { - if (fileExtensions.Where(x => x.Value == ext).Count() != 0) { - mediaType = MediaType.Alias; - break; - } - } - */ } } From f6591a5cfeaf1df5c1df73f085778195756aac9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 31 Mar 2021 14:11:36 +0200 Subject: [PATCH 53/90] number range should not go below 0, at-least as default until we make that configurable. --- .../src/views/prevalueeditors/numberrange.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/numberrange.html b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/numberrange.html index d9d8cad9821b..f6b59d4a8a0b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/numberrange.html +++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/numberrange.html @@ -4,6 +4,7 @@ type="number" ng-model="model.value.min" placeholder="0" + ng-min="0" ng-max="model.value.max" fix-number /> @@ -11,7 +12,7 @@ type="number" ng-model="model.value.max" placeholder="∞" - ng-min="model.value.min" + ng-min="model.value.min || 0" fix-number /> From fe9fbe99eacd58a787314399c19ce0f9291f0622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 31 Mar 2021 14:26:18 +0200 Subject: [PATCH 54/90] use min not ng-min --- .../src/views/prevalueeditors/numberrange.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/numberrange.html b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/numberrange.html index f6b59d4a8a0b..6e67c947936f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/numberrange.html +++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/numberrange.html @@ -4,7 +4,7 @@ type="number" ng-model="model.value.min" placeholder="0" - ng-min="0" + min="0" ng-max="model.value.max" fix-number /> From ac9830478d2a375279cf25a3c6be4c5ec089e14d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 31 Mar 2021 14:26:31 +0200 Subject: [PATCH 55/90] description for local crops --- .../PropertyEditors/MediaPicker3Configuration.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs b/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs index 56fd7ad88743..b447633e70c2 100644 --- a/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs +++ b/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs @@ -35,7 +35,7 @@ public class NumberRange Description = "Selecting this option allows a user to choose nodes that they normally don't have access to.")] public bool IgnoreUserStartNodes { get; set; } - [ConfigurationField("crops", "Image Croppings", "views/propertyeditors/MediaPicker3/prevalue/mediapicker3.crops.html")] + [ConfigurationField("crops", "Image Croppings", "views/propertyeditors/MediaPicker3/prevalue/mediapicker3.crops.html", Description = "Local croppings, stored on document")] public CropConfiguration[] Crops { get; set; } public class CropConfiguration @@ -51,10 +51,6 @@ public class CropConfiguration [JsonProperty("height")] public int Height { get; set; } - /* - [JsonProperty("mandatory")] - public bool Mandatory { get; set; } - */ } } } From e9a47df408b05b31cbd5f2502da58327e8bdeac3 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 31 Mar 2021 14:28:45 +0200 Subject: [PATCH 56/90] Error/Limits highlighting reactive --- .../src/views/components/mediacard/umbMediaCard.component.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js index 502ff81db685..24b20367aa79 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umbMediaCard.component.js @@ -48,7 +48,7 @@ vm.$onInit = function () { - unsubscribe.push($scope.$watch(["vm.media.trashed", "vm.hasError"], checkErrorState)); + unsubscribe.push($scope.$watchGroup(["vm.media.trashed", "vm.hasError"], checkErrorState)); vm.updateThumbnail(); From c09f25651f78ba381b152924e05a0da62bb76d37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 31 Mar 2021 14:50:27 +0200 Subject: [PATCH 57/90] visual adjustments --- src/Umbraco.Web.UI.Client/src/less/mixins.less | 2 +- src/Umbraco.Web.UI.Client/src/less/property-editors.less | 6 +++++- .../src/views/components/imaging/umb-image-gravity.html | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/mixins.less b/src/Umbraco.Web.UI.Client/src/less/mixins.less index 9739a90dae7a..b046ca69d923 100644 --- a/src/Umbraco.Web.UI.Client/src/less/mixins.less +++ b/src/Umbraco.Web.UI.Client/src/less/mixins.less @@ -405,7 +405,7 @@ } } -.checkeredBackground(@backgroundColor: @gray-9, @fillColor: @black, @fillOpacity: 0.25) { +.checkeredBackground(@backgroundColor: @white, @fillColor: @black, @fillOpacity: 0.1) { background-image: url('data:image/svg+xml;charset=utf-8,\ \ \ diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 5512f52d853c..70783de9ead8 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -604,7 +604,7 @@ } .umb-cropper-gravity .gravity-container { - border: 1px solid @gray-8; + border: 1px solid @inputBorder; box-sizing: border-box; line-height: 0; width: 100%; @@ -613,6 +613,10 @@ .checkeredBackground(); contain: content; + &:focus, &:focus-within { + border-color: @inputBorderFocus; + } + .viewport { position: relative; width: 100%; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-gravity.html b/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-gravity.html index f3f236a3bb63..71e7292feadb 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-gravity.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-gravity.html @@ -9,7 +9,7 @@
    -
    +
    From 4e03ec9c3fc7f4f0ad82b255e6e01c68789ffa61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 31 Mar 2021 15:39:32 +0200 Subject: [PATCH 58/90] Enabling opening filtered folders + corrected select hover states --- .../components/umbmediagrid.directive.js | 27 +++++---- .../src/less/components/umb-media-grid.less | 45 +++++---------- .../src/views/components/umb-media-grid.html | 55 ++++++++++--------- 3 files changed, 59 insertions(+), 68 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbmediagrid.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbmediagrid.directive.js index 241f1e80e8d2..cc480efea505 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbmediagrid.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbmediagrid.directive.js @@ -118,9 +118,9 @@ Use this directive to generate a thumbnail grid of media items. var item = scope.items[i]; setItemData(item); setOriginalSize(item, itemMaxHeight); - + item.selectable = getSelectableState(item); - + // remove non images when onlyImages is set to true if (scope.onlyImages === "true" && !item.isFolder && !item.thumbnail){ scope.items.splice(i, 1); @@ -141,7 +141,7 @@ Use this directive to generate a thumbnail grid of media items. } } - + if (scope.items.length > 0) { setFlexValues(scope.items); } @@ -188,7 +188,7 @@ Use this directive to generate a thumbnail grid of media items. } } } - + /** * Returns wether a item should be selectable or not. */ @@ -203,9 +203,9 @@ Use this directive to generate a thumbnail grid of media items. } else { return scope.onlyFolders !== "true"; } - + return false; - + } function setOriginalSize(item, maxHeight) { @@ -255,7 +255,7 @@ Use this directive to generate a thumbnail grid of media items. } } - + function setFlexValues(mediaItems) { var flexSortArray = mediaItems; @@ -292,8 +292,11 @@ Use this directive to generate a thumbnail grid of media items. mediaItem.flexStyle = flexStyle; } } - + scope.clickItem = function(item, $event, $index) { + if (item.isFolder === true && item.filtered) { + scope.clickItemName(item, $event, $index); + } if (scope.onClick) { scope.onClick(item, $event, $index); $event.stopPropagation(); @@ -312,7 +315,7 @@ Use this directive to generate a thumbnail grid of media items. scope.onDetailsHover(item, $event, hover); } }; - + var unbindItemsWatcher = scope.$watch('items', function(newValue, oldValue) { if (Utilities.isArray(newValue)) { activate(); @@ -333,7 +336,7 @@ Use this directive to generate a thumbnail grid of media items. //change sort scope.setSort = function (col) { if (scope.sortColumn === col) { - scope.sortReverse = !scope.sortReverse; + scope.sortReverse = !scope.sortReverse; } else { scope.sortColumn = col; @@ -345,9 +348,9 @@ Use this directive to generate a thumbnail grid of media items. } } scope.sortDirection = scope.sortReverse ? "desc" : "asc"; - + } - // sort function + // sort function scope.sortBy = function (item) { if (scope.sortColumn === "updateDate") { return [-item['isFolder'],item['updateDate']]; diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-media-grid.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-media-grid.less index e2b8ea5073a6..307eb5551229 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-media-grid.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-media-grid.less @@ -34,21 +34,6 @@ } -.umb-media-grid__item.-unselectable { - &::before { - content: ""; - position: absolute; - z-index: 1; - top: 0; - left: 0; - right: 0; - bottom: 0; - border-radius: @baseBorderRadius; - background-color: rgba(230, 230, 230, .8); - pointer-events: none; - } -} - .umb-media-grid__item.-selectable, .umb-media-grid__item.-folder {// If folders isnt selectable, they opens if clicked, therefor... cursor: pointer; @@ -59,21 +44,12 @@ } .umb-media-grid__item.-folder { - &.-selectable { .media-grid-item-edit:hover .umb-media-grid__item-name, .media-grid-item-edit:focus .umb-media-grid__item-name { text-decoration: underline; } } - - &.-unselectable { - &:hover, &:focus { - .umb-media-grid__item-name { - text-decoration: underline; - } - } - } } @@ -85,8 +61,7 @@ } .umb-media-grid__item.-selected, .umb-media-grid__item.-selectable:hover { - &::before { - content: ""; + .umb-media-grid__item-select { position: absolute; z-index:2; top: -2px; @@ -100,16 +75,16 @@ } } .umb-media-grid__item.-selectable:hover { - &::before { + .umb-media-grid__item-select { opacity: .33; } } .umb-media-grid__item.-selected:hover { - &::before { + .umb-media-grid__item-select { opacity: .75; } } -.umb-media-grid__item.-filtered { +.umb-media-grid__item.-filtered:not(.-folder) { cursor:not-allowed; * { pointer-events: none; @@ -196,13 +171,23 @@ } .umb-media-grid__item-overlay { - cursor: pointer; + cursor: pointer; + + &:hover .umb-media-grid__item-name{ + text-decoration: underline; + } + +.umb-media-grid__item-overlay:not(.-selected) { + &:hover + .umb-media-grid__item-select { + display: none; + } } .umb-media-grid__item-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; + } diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html index 20e2efbd416c..27411afca185 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html @@ -7,38 +7,41 @@ ng-repeat="item in items | filter:filterBy" ng-style="item.flexStyle" ng-class="{'-selected': item.selected, '-file': !item.thumbnail, '-folder': item.isFolder, '-svg': item.extension == 'svg', '-selectable': item.selectable, '-unselectable': !item.selectable, '-filtered': item.filtered}"> -
    - -
    - -
    {{item.name}}
    -
    - -
    + +
    + +
    {{item.name}}
    +
    - - {{item.name}} + +
    - - {{item.name}} + +
    - - {{item.name}} + + {{item.name}} + + + {{item.name}} + + + {{item.name}} + + + + - - - -
    From d938315f0cd9c901103c8c54b863188ef591515e Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Wed, 31 Mar 2021 17:57:58 +0200 Subject: [PATCH 59/90] Varous fixes to resolve issues with unit tests. --- .../Persistence/Dtos/ContentTypeDto.cs | 2 +- .../Persistence/Dtos/PropertyTypeDto.cs | 2 +- .../DataTypeDefinitionRepositoryTest.cs | 2 +- .../Repositories/MediaTypeRepositoryTest.cs | 16 +++++----- .../PublishedContent/PublishedMediaTests.cs | 29 +++++++++---------- .../Services/MediaServiceTests.cs | 4 +-- .../Entities/MockedContentTypes.cs | 8 ++--- 7 files changed, 31 insertions(+), 32 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs b/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs index e7a14a26e2e7..68036dab4bc3 100644 --- a/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs +++ b/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs @@ -11,7 +11,7 @@ internal class ContentTypeDto public const string TableName = Constants.DatabaseSchema.Tables.ContentType; [Column("pk")] - [PrimaryKeyColumn(IdentitySeed = 535)] + [PrimaryKeyColumn(IdentitySeed = 700)] public int PrimaryKey { get; set; } [Column("nodeId")] diff --git a/src/Umbraco.Core/Persistence/Dtos/PropertyTypeDto.cs b/src/Umbraco.Core/Persistence/Dtos/PropertyTypeDto.cs index 572201c94a0e..f22e4453f420 100644 --- a/src/Umbraco.Core/Persistence/Dtos/PropertyTypeDto.cs +++ b/src/Umbraco.Core/Persistence/Dtos/PropertyTypeDto.cs @@ -11,7 +11,7 @@ namespace Umbraco.Core.Persistence.Dtos internal class PropertyTypeDto { [Column("id")] - [PrimaryKeyColumn(IdentitySeed = 50)] + [PrimaryKeyColumn(IdentitySeed = 100)] public int Id { get; set; } [Column("dataTypeId")] diff --git a/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs index ca8ee29ee3a7..f2913bd39378 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs @@ -279,7 +279,7 @@ public void Can_Perform_GetAll_On_DataTypeDefinitionRepository() Assert.That(dataTypeDefinitions, Is.Not.Null); Assert.That(dataTypeDefinitions.Any(), Is.True); Assert.That(dataTypeDefinitions.Any(x => x == null), Is.False); - Assert.That(dataTypeDefinitions.Length, Is.EqualTo(29)); + Assert.That(dataTypeDefinitions.Length, Is.EqualTo(33)); } } diff --git a/src/Umbraco.Tests/Persistence/Repositories/MediaTypeRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MediaTypeRepositoryTest.cs index bb3286daedad..e048886dbe4f 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MediaTypeRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MediaTypeRepositoryTest.cs @@ -50,7 +50,7 @@ public void Can_Move() containerRepository.Save(container2); - var contentType = (IMediaType)MockedContentTypes.CreateVideoMediaType(); + var contentType = (IMediaType)MockedContentTypes.CreateNewMediaType(); contentType.ParentId = container2.Id; repository.Save(contentType); @@ -133,7 +133,7 @@ public void Can_Create_Container_Containing_Media_Types() containerRepository.Save(container); - var contentType = MockedContentTypes.CreateVideoMediaType(); + var contentType = MockedContentTypes.CreateNewMediaType(); contentType.ParentId = container.Id; repository.Save(contentType); @@ -155,7 +155,7 @@ public void Can_Delete_Container_Containing_Media_Types() containerRepository.Save(container); - IMediaType contentType = MockedContentTypes.CreateVideoMediaType(); + IMediaType contentType = MockedContentTypes.CreateNewMediaType(); contentType.ParentId = container.Id; repository.Save(contentType); @@ -183,7 +183,7 @@ public void Can_Perform_Add_On_MediaTypeRepository() var repository = CreateRepository(provider); // Act - var contentType = MockedContentTypes.CreateVideoMediaType(); + var contentType = MockedContentTypes.CreateNewMediaType(); repository.Save(contentType); @@ -210,7 +210,7 @@ public void Can_Perform_Update_On_MediaTypeRepository() { var repository = CreateRepository(provider); - var videoMediaType = MockedContentTypes.CreateVideoMediaType(); + var videoMediaType = MockedContentTypes.CreateNewMediaType(); repository.Save(videoMediaType); @@ -249,7 +249,7 @@ public void Can_Perform_Delete_On_MediaTypeRepository() var repository = CreateRepository(provider); // Act - var mediaType = MockedContentTypes.CreateVideoMediaType(); + var mediaType = MockedContentTypes.CreateNewMediaType(); repository.Save(mediaType); @@ -378,7 +378,7 @@ public void Can_Update_MediaType_With_PropertyType_Removed() { var repository = CreateRepository(provider); - var mediaType = MockedContentTypes.CreateVideoMediaType(); + var mediaType = MockedContentTypes.CreateNewMediaType(); repository.Save(mediaType); @@ -406,7 +406,7 @@ public void Can_Verify_PropertyTypes_On_Video_MediaType() { var repository = CreateRepository(provider); - var mediaType = MockedContentTypes.CreateVideoMediaType(); + var mediaType = MockedContentTypes.CreateNewMediaType(); repository.Save(mediaType); diff --git a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs index f801d02c5bc0..bf8450383720 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs @@ -1,29 +1,27 @@ -using System.Web; -using System.Xml.Linq; -using System.Xml.XPath; +using Examine; using NUnit.Framework; -using Umbraco.Core; -using Umbraco.Core.Models; -using Umbraco.Tests.TestHelpers; -using Umbraco.Tests.TestHelpers.Entities; -using Umbraco.Tests.UmbracoExamine; -using Umbraco.Web; using System.Linq; using System.Threading; +using System.Web; using System.Xml; -using Examine; +using System.Xml.Linq; +using System.Xml.XPath; +using Umbraco.Core; using Umbraco.Core.Cache; -using Umbraco.Core.Models.PublishedContent; -using Umbraco.Core.Strings; -using Umbraco.Examine; -using Current = Umbraco.Web.Composing.Current; -using Umbraco.Tests.Testing; using Umbraco.Core.Composing; +using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; +using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; +using Umbraco.Core.Strings; +using Umbraco.Examine; using Umbraco.Tests.LegacyXmlPublishedCache; +using Umbraco.Tests.TestHelpers.Entities; +using Umbraco.Tests.Testing; using Umbraco.Tests.Testing.Objects.Accessors; +using Umbraco.Tests.UmbracoExamine; +using Umbraco.Web; namespace Umbraco.Tests.PublishedContent { @@ -94,6 +92,7 @@ public void Get_Property_Value_Uses_Converter() Name = "Rich Text", DataTypeId = -87 //tiny mce }); + var existing = ServiceContext.MediaTypeService.GetAll(); ServiceContext.MediaTypeService.Save(mType); var media = MockedMedia.CreateMediaImage(mType, -1); media.Properties["content"].SetValue("
    This is some content
    "); diff --git a/src/Umbraco.Tests/Services/MediaServiceTests.cs b/src/Umbraco.Tests/Services/MediaServiceTests.cs index 52f26ecb4d15..d5cec11211c1 100644 --- a/src/Umbraco.Tests/Services/MediaServiceTests.cs +++ b/src/Umbraco.Tests/Services/MediaServiceTests.cs @@ -163,7 +163,7 @@ public void Cannot_Save_Media_With_Empty_Name() { // Arrange var mediaService = ServiceContext.MediaService; - var mediaType = MockedContentTypes.CreateVideoMediaType(); + var mediaType = MockedContentTypes.CreateNewMediaType(); ServiceContext.MediaTypeService.Save(mediaType); var media = mediaService.CreateMedia(string.Empty, -1, "video"); @@ -175,7 +175,7 @@ public void Cannot_Save_Media_With_Empty_Name() public void Ensure_Content_Xml_Created() { var mediaService = ServiceContext.MediaService; - var mediaType = MockedContentTypes.CreateVideoMediaType(); + var mediaType = MockedContentTypes.CreateNewMediaType(); ServiceContext.MediaTypeService.Save(mediaType); var media = mediaService.CreateMedia("Test", -1, "video"); diff --git a/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs b/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs index e3bb012dae0d..1b85787fee3a 100644 --- a/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs +++ b/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs @@ -378,13 +378,13 @@ public static ContentType CreateAllTypesContentType(string alias, string name) return contentType; } - public static MediaType CreateVideoMediaType() + public static MediaType CreateNewMediaType() { var mediaType = new MediaType(-1) { - Alias = "video", - Name = "Video", - Description = "ContentType used for videos", + Alias = "newMediaType", + Name = "New Media Type", + Description = "ContentType used for a new format", Icon = ".sprTreeDoc3", Thumbnail = "doc.png", SortOrder = 1, From f80b99718224de443548ec91b7b1f85c1476dc57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 6 Apr 2021 10:02:08 +0200 Subject: [PATCH 60/90] Refactor MediaType Documents to only contain Article file type --- src/Umbraco.Core/Constants-Conventions.cs | 4 ++-- src/Umbraco.Core/Constants-DataTypes.cs | 10 +++++----- src/Umbraco.Core/Constants-Icons.cs | 4 ++-- src/Umbraco.Core/Constants-PropertyTypeGroups.cs | 4 ++-- .../Migrations/Install/DatabaseDataCreator.cs | 14 +++++++------- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Umbraco.Core/Constants-Conventions.cs b/src/Umbraco.Core/Constants-Conventions.cs index e983c429e461..e563ae3ca3c9 100644 --- a/src/Umbraco.Core/Constants-Conventions.cs +++ b/src/Umbraco.Core/Constants-Conventions.cs @@ -129,9 +129,9 @@ public static class MediaTypes public const string Audio = "Audio"; /// - /// MediaType alias for an document. + /// MediaType alias for an article. /// - public const string Document = "Document"; + public const string Article = "Article"; /// /// MediaType alias for an vector graphics. diff --git a/src/Umbraco.Core/Constants-DataTypes.cs b/src/Umbraco.Core/Constants-DataTypes.cs index a1f801e0e66f..b3c3c030f6d7 100644 --- a/src/Umbraco.Core/Constants-DataTypes.cs +++ b/src/Umbraco.Core/Constants-DataTypes.cs @@ -27,7 +27,7 @@ public static class DataTypes public const int Upload = -90; public const int UploadVideo = -100; public const int UploadAudio = -101; - public const int UploadDocument = -102; + public const int UploadArticle = -102; public const int UploadVectorGraphics = -103; public const int DefaultContentListView = -95; @@ -332,14 +332,14 @@ public static class Guids public static readonly Guid UploadAudioGuid = new Guid(UploadAudio); /// - /// Guid for UploadDocument as string + /// Guid for UploadArticle as string /// - public const string UploadDocument = "bc1e266c-dac4-4164-bf08-8a1ec6a7143d"; + public const string UploadArticle = "bc1e266c-dac4-4164-bf08-8a1ec6a7143d"; /// - /// Guid for UploadDocument + /// Guid for UploadArticle /// - public static readonly Guid UploadDocumentGuid = new Guid(UploadDocument); + public static readonly Guid UploadArticleGuid = new Guid(UploadArticle); /// /// Guid for UploadVectorGraphics as string diff --git a/src/Umbraco.Core/Constants-Icons.cs b/src/Umbraco.Core/Constants-Icons.cs index 0476ed691111..e15c1e162bea 100644 --- a/src/Umbraco.Core/Constants-Icons.cs +++ b/src/Umbraco.Core/Constants-Icons.cs @@ -70,9 +70,9 @@ public static class Icons public const string MediaAudio = "icon-sound-waves"; /// - /// System media document icon + /// System media article icon /// - public const string MediaDocument = "icon-article"; + public const string MediaArticle = "icon-article"; /// /// System media vector icon diff --git a/src/Umbraco.Core/Constants-PropertyTypeGroups.cs b/src/Umbraco.Core/Constants-PropertyTypeGroups.cs index 4aecec6b1cc4..9321b1f83754 100644 --- a/src/Umbraco.Core/Constants-PropertyTypeGroups.cs +++ b/src/Umbraco.Core/Constants-PropertyTypeGroups.cs @@ -28,9 +28,9 @@ public static class PropertyTypeGroups public const string Audio = "335FB495-0A87-4E82-B902-30EB367B767C"; /// - /// Guid for a Document PropertyTypeGroup object. + /// Guid for a Article PropertyTypeGroup object. /// - public const string Document = "9AF3BD65-F687-4453-9518-5F180D1898EC"; + public const string Article = "9AF3BD65-F687-4453-9518-5F180D1898EC"; /// /// Guid for a VectorGraphics PropertyTypeGroup object. diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs index be2c8bcf73a7..0c2f02306cd8 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs @@ -110,7 +110,7 @@ void InsertDataTypeNodeDto(int id, int sortOrder, string uniqueId, string text) _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Upload, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Upload}", SortOrder = 34, UniqueId = Constants.DataTypes.Guids.UploadGuid, Text = "Upload File", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.UploadVideo, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.UploadVideo}", SortOrder = 35, UniqueId = Constants.DataTypes.Guids.UploadVideoGuid, Text = "Upload Video", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.UploadAudio, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.UploadAudio}", SortOrder = 36, UniqueId = Constants.DataTypes.Guids.UploadAudioGuid, Text = "Upload Audio", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); - _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.UploadDocument, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.UploadDocument}", SortOrder = 37, UniqueId = Constants.DataTypes.Guids.UploadDocumentGuid, Text = "Upload Document", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.UploadArticle, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.UploadArticle}", SortOrder = 37, UniqueId = Constants.DataTypes.Guids.UploadArticleGuid, Text = "Upload Article", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.UploadVectorGraphics, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.UploadVectorGraphics}", SortOrder = 38, UniqueId = Constants.DataTypes.Guids.UploadVectorGraphicsGuid, Text = "Upload Vector Graphics", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Textarea, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Textarea}", SortOrder = 33, UniqueId = Constants.DataTypes.Guids.TextareaGuid, Text = "Textarea", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Textbox, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Textbox}", SortOrder = 32, UniqueId = Constants.DataTypes.Guids.TextstringGuid, Text = "Textstring", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); @@ -132,7 +132,7 @@ void InsertDataTypeNodeDto(int id, int sortOrder, string uniqueId, string text) _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1033, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1033", SortOrder = 2, UniqueId = new Guid("4c52d8ab-54e6-40cd-999c-7a5f24903e4d"), Text = Constants.Conventions.MediaTypes.File, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1034, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1034", SortOrder = 2, UniqueId = new Guid("f6c515bb-653c-4bdc-821c-987729ebe327"), Text = Constants.Conventions.MediaTypes.Video, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1035, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1035", SortOrder = 2, UniqueId = new Guid("a5ddeee0-8fd8-4cee-a658-6f1fcdb00de3"), Text = Constants.Conventions.MediaTypes.Audio, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); - _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1036, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1036", SortOrder = 2, UniqueId = new Guid("a43e3414-9599-4230-a7d3-943a21b20122"), Text = Constants.Conventions.MediaTypes.Document, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1036, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1036", SortOrder = 2, UniqueId = new Guid("a43e3414-9599-4230-a7d3-943a21b20122"), Text = Constants.Conventions.MediaTypes.Article, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1037, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1037", SortOrder = 2, UniqueId = new Guid("c4b1efcf-a9d5-41c4-9621-e9d273b52a9c"), Text = "Vector Graphics (SVG)", NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Tags, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Tags}", SortOrder = 2, UniqueId = new Guid("b6b73142-b9c1-4bf8-a16d-e1c23320b549"), Text = "Tags", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.ImageCropper, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.ImageCropper}", SortOrder = 2, UniqueId = new Guid("1df9f033-e6d4-451f-b8d2-e0cbc50a836f"), Text = "Image Cropper", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); @@ -170,7 +170,7 @@ private void CreateContentTypeData() _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 534, NodeId = 1033, Alias = Constants.Conventions.MediaTypes.File, Icon = Constants.Icons.MediaFile, Thumbnail = Constants.Icons.MediaFile, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 540, NodeId = 1034, Alias = Constants.Conventions.MediaTypes.Video, Icon = Constants.Icons.MediaVideo, Thumbnail = Constants.Icons.MediaVideo, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 541, NodeId = 1035, Alias = Constants.Conventions.MediaTypes.Audio, Icon = Constants.Icons.MediaAudio, Thumbnail = Constants.Icons.MediaAudio, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing }); - _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 542, NodeId = 1036, Alias = Constants.Conventions.MediaTypes.Document, Icon = Constants.Icons.MediaDocument, Thumbnail = Constants.Icons.MediaDocument, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 542, NodeId = 1036, Alias = Constants.Conventions.MediaTypes.Article, Icon = Constants.Icons.MediaArticle, Thumbnail = Constants.Icons.MediaArticle, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 543, NodeId = 1037, Alias = Constants.Conventions.MediaTypes.VectorGraphics, Icon = Constants.Icons.MediaVectorGraphics, Thumbnail = Constants.Icons.MediaVectorGraphics, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 531, NodeId = 1044, Alias = Constants.Conventions.MemberTypes.DefaultAlias, Icon = Constants.Icons.Member, Thumbnail = Constants.Icons.Member, Variations = (byte) ContentVariation.Nothing }); } @@ -221,7 +221,7 @@ private void CreatePropertyTypeGroupData() _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 4, ContentTypeNodeId = 1033, Text = "File", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.File) }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 52, ContentTypeNodeId = 1034, Text = "Video", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.Video) }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 53, ContentTypeNodeId = 1035, Text = "Audio", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.Audio) }); - _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 54, ContentTypeNodeId = 1036, Text = "Document", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.Document) }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 54, ContentTypeNodeId = 1036, Text = "Article", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.Article) }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 55, ContentTypeNodeId = 1037, Text = "Vector Graphics", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.VectorGraphics) }); //membership property group _database.Insert(Constants.DatabaseSchema.Tables.PropertyTypeGroup, "id", false, new PropertyTypeGroupDto { Id = 11, ContentTypeNodeId = 1044, Text = "Membership", SortOrder = 1, UniqueId = new Guid(Constants.PropertyTypeGroups.Membership) }); @@ -246,7 +246,7 @@ private void CreatePropertyTypeData() _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 44, UniqueId = 44.ToGuid(), DataTypeId = -92, ContentTypeId = 1035, PropertyTypeGroupId = 53, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 45, UniqueId = 45.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1035, PropertyTypeGroupId = 53, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing }); - _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 46, UniqueId = 46.ToGuid(), DataTypeId = Constants.DataTypes.UploadDocument, ContentTypeId = 1036, PropertyTypeGroupId = 54, Alias = Constants.Conventions.Media.File, Name = "Document", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 46, UniqueId = 46.ToGuid(), DataTypeId = Constants.DataTypes.UploadArticle, ContentTypeId = 1036, PropertyTypeGroupId = 54, Alias = Constants.Conventions.Media.File, Name = "Article", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 47, UniqueId = 47.ToGuid(), DataTypeId = -92, ContentTypeId = 1036, PropertyTypeGroupId = 54, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 48, UniqueId = 48.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1036, PropertyTypeGroupId = 54, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing }); @@ -366,10 +366,10 @@ void InsertDataTypeDto(int id, string editorAlias, string dbType, string configu _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { - NodeId = Constants.DataTypes.UploadDocument, + NodeId = Constants.DataTypes.UploadArticle, EditorAlias = Constants.PropertyEditors.Aliases.UploadField, DbType = "Nvarchar", - Configuration = "{\"fileExtensions\":[{\"id\":0, \"value\":\"pdf\"}, {\"id\":1, \"value\":\"docx\"}, {\"id\":2, \"value\":\"doc\"}, {\"id\":3, \"value\":\"xlsx\"}, {\"id\":4, \"value\":\"xls\"}, {\"id\":5, \"value\":\"csv\"}, {\"id\":6, \"value\":\"pptx\"}, {\"id\":7, \"value\":\"ppt\"}, {\"id\":8, \"value\":\"epub\"}, {\"id\":9, \"value\":\"txt\"}, {\"id\":10, \"value\":\"rtf\"}]}" + Configuration = "{\"fileExtensions\":[{\"id\":0, \"value\":\"pdf\"}, {\"id\":1, \"value\":\"docx\"}, {\"id\":2, \"value\":\"doc\"}]}" }); _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto From 1791ce12809f28f116793484fce4151c73461a71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 6 Apr 2021 10:51:40 +0200 Subject: [PATCH 61/90] mark as build-in --- src/Umbraco.Core/Models/DataTypeExtensions.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Umbraco.Core/Models/DataTypeExtensions.cs b/src/Umbraco.Core/Models/DataTypeExtensions.cs index f460edbde70f..913aa4773ef2 100644 --- a/src/Umbraco.Core/Models/DataTypeExtensions.cs +++ b/src/Umbraco.Core/Models/DataTypeExtensions.cs @@ -62,6 +62,10 @@ public static T ConfigurationAs(this IDataType dataType) Constants.DataTypes.Guids.TextstringGuid, Constants.DataTypes.Guids.TextareaGuid, Constants.DataTypes.Guids.UploadGuid, + Constants.DataTypes.Guids.UploadArticleGuid, + Constants.DataTypes.Guids.UploadAudioGuid, + Constants.DataTypes.Guids.UploadVectorGraphicsGuid, + Constants.DataTypes.Guids.UploadVideoGuid, Constants.DataTypes.Guids.LabelStringGuid, Constants.DataTypes.Guids.LabelDecimalGuid, Constants.DataTypes.Guids.LabelDateTimeGuid, From 3934f052448f0faa1a1631ec192b79f78111b2b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 6 Apr 2021 11:58:54 +0200 Subject: [PATCH 62/90] predefined MediaPicker3 DataTypes, renaming v2 to "old" --- src/Umbraco.Core/Constants-DataTypes.cs | 43 +++++++++++++++++++ .../Migrations/Install/DatabaseDataCreator.cs | 33 +++++++++++++- 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Core/Constants-DataTypes.cs b/src/Umbraco.Core/Constants-DataTypes.cs index b3c3c030f6d7..ddeaa5278b78 100644 --- a/src/Umbraco.Core/Constants-DataTypes.cs +++ b/src/Umbraco.Core/Constants-DataTypes.cs @@ -92,6 +92,49 @@ public static class Guids public static readonly Guid MultipleMediaPickerGuid = new Guid(MultipleMediaPicker); + /// + /// Guid for Media Picker v3 as string + /// + public const string MediaPicker3 = "4309A3EA-0D78-4329-A06C-C80B036AF19A"; + + /// + /// Guid for Media Picker + /// + public static readonly Guid MediaPicker3Guid = new Guid(MediaPicker3); + + /// + /// Guid for Media Picker v3 multiple as string + /// + public const string MediaPicker3Multiple = "1B661F40-2242-4B44-B9CB-3990EE2B13C0"; + + /// + /// Guid for Media Picker + /// + public static readonly Guid MediaPicker3MultipleGuid = new Guid(MediaPicker3Multiple); + + + /// + /// Guid for Media Picker v3 single-image as string + /// + public const string MediaPicker3SingleImage = "AD9F0CF2-BDA2-45D5-9EA1-A63CFC873FD3"; + + /// + /// Guid for Media Picker + /// + public static readonly Guid MediaPicker3SingleImageGuid = new Guid(MediaPicker3SingleImage); + + + /// + /// Guid for Media Picker v3 images multi-image as string + /// + public const string MediaPicker3MultipleImages = "0E63D883-B62B-4799-88C3-157F82E83ECC"; + + /// + /// Guid for Media Picker + /// + public static readonly Guid MediaPicker3MultipleImagesGuid = new Guid(MediaPicker3MultipleImages); + + /// /// Guid for Related Links as string /// diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs index 4fe4905d30c0..61da9b9e6364 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs @@ -141,9 +141,15 @@ void InsertDataTypeNodeDto(int id, int sortOrder, string uniqueId, string text) //New UDI pickers with newer Ids _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1046, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1046", SortOrder = 2, UniqueId = new Guid("FD1E0DA5-5606-4862-B679-5D0CF3A52A59"), Text = "Content Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1047, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1047", SortOrder = 2, UniqueId = new Guid("1EA2E01F-EBD8-4CE1-8D71-6B1149E63548"), Text = "Member Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); - _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1048, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1048", SortOrder = 2, UniqueId = new Guid("135D60E0-64D9-49ED-AB08-893C9BA44AE5"), Text = "Media Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); - _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1049, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1049", SortOrder = 2, UniqueId = new Guid("9DBBCBBB-2327-434A-B355-AF1B84E5010A"), Text = "Multiple Media Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1048, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1048", SortOrder = 2, UniqueId = new Guid("135D60E0-64D9-49ED-AB08-893C9BA44AE5"), Text = "Media Picker (old)", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1049, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1049", SortOrder = 2, UniqueId = new Guid("9DBBCBBB-2327-434A-B355-AF1B84E5010A"), Text = "Multiple Media Picker (old)", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1050, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1050", SortOrder = 2, UniqueId = new Guid("B4E3535A-1753-47E2-8568-602CF8CFEE6F"), Text = "Multi URL Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1051, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1051", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3Guid, Text = "Media Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1052, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1052", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3MultipleGuid, Text = "Multiple Media Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1053, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1053", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3SingleImageGuid, Text = "Image Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1054, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1054", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3MultipleImagesGuid, Text = "Multiple Image Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + } private void CreateLockData() @@ -380,6 +386,29 @@ void InsertDataTypeDto(int id, string editorAlias, string dbType, string configu Configuration = "{\"fileExtensions\":[{\"id\":0, \"value\":\"svg\"}]}" }); + _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { + NodeId = 1051, + EditorAlias = Constants.PropertyEditors.Aliases.MediaPicker3, + DbType = "Ntext", + Configuration = "{\"validationLimit\":{\"min\":0,\"max\":1}}" + }); + _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { + NodeId = 1052, + EditorAlias = Constants.PropertyEditors.Aliases.MediaPicker3, + DbType = "Ntext" + }); + _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { + NodeId = 1053, + EditorAlias = Constants.PropertyEditors.Aliases.MediaPicker3, + DbType = "Ntext", + Configuration = "{\"filter\":\"" + Constants.Conventions.MediaTypes.Image + "\", \"validationLimit\":{\"min\":0,\"max\":1}}" + }); + _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { + NodeId = 1054, + EditorAlias = Constants.PropertyEditors.Aliases.MediaPicker3, + DbType = "Ntext", + Configuration = "{\"filter\":\"" + Constants.Conventions.MediaTypes.Image + "\" }" + }); } private void CreateRelationTypeData() From 6f85e55bd4410fd58a2f0b203abdb76a35418743 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 6 Apr 2021 13:20:21 +0200 Subject: [PATCH 63/90] set scale bar current value after min and max has been set --- .../components/imaging/umbimagecrop.directive.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js index 7b09f87ad112..bf03aac3abd8 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js @@ -73,11 +73,6 @@ angular.module("umbraco.directives") function updateSlider() { if(sliderRef) { - - // Set slider handle position - console.log("set:", scope.dimensions.scale.current.toFixed(3), " ", scope.dimensions.scale.min, " max", scope.dimensions.scale.max) - sliderRef.noUiSlider.set(scope.dimensions.scale.current); - // Update slider range min/max sliderRef.noUiSlider.updateOptions({ "range": { @@ -85,6 +80,9 @@ angular.module("umbraco.directives") "max": scope.dimensions.scale.max } }); + + // Set slider handle position + sliderRef.noUiSlider.set(scope.dimensions.scale.current); } } From 31f2087907590d12f8ab3b30698cca9d07dc5394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 6 Apr 2021 13:42:21 +0200 Subject: [PATCH 64/90] added missing } --- .../src/less/components/umb-media-grid.less | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-media-grid.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-media-grid.less index 307eb5551229..71be01e6fff8 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-media-grid.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-media-grid.less @@ -176,6 +176,7 @@ &:hover .umb-media-grid__item-name{ text-decoration: underline; } +} .umb-media-grid__item-overlay:not(.-selected) { &:hover + .umb-media-grid__item-select { From 13b958c37dce063a1394cb9deab685c0e3f08a60 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 6 Apr 2021 13:50:46 +0200 Subject: [PATCH 65/90] update when focal point is dragged --- .../directives/components/imaging/umbimagegravity.directive.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js index 3c4be47b13dc..f17651200b65 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js @@ -74,7 +74,8 @@ var offsetX = ui.position.left; var offsetY = ui.position.top; - calculateGravity(offsetX, offsetY); + + $scope.$evalAsync(calculateGravity(offsetX, offsetY)); $scope.$emit("imageFocalPointStop"); From 2fd71eb6dc329ff48ab372ae91920f10f3d2c2be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 6 Apr 2021 13:58:40 +0200 Subject: [PATCH 66/90] adjusted styling for Image Cropper property editor --- .../src/views/propertyeditors/imagecropper/imagecropper.html | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) 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 84ddf7ee3b92..86a5353391f3 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 @@ -14,7 +14,7 @@
    -
    +
    @@ -22,7 +22,6 @@ width="{{currentCrop.width}}" crop="currentCrop.coordinates" center="model.value.focalPoint" - max-size="450" src="imageSrc">
    @@ -46,7 +45,7 @@
    - +
    • From 8a64c384afe0d40668a202f25358a73c00f1bb3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 6 Apr 2021 14:20:13 +0200 Subject: [PATCH 67/90] correcting comment --- .../src/views/components/umb-media-grid.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html index 27411afca185..975405626772 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html @@ -21,7 +21,7 @@
      - +
      From 4daca6434229a57e8f0622e9e7b8314368baa8e4 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 7 Apr 2021 09:44:12 +0200 Subject: [PATCH 68/90] remove todo - message for trashed media items works --- .../infiniteeditors/mediaentryeditor/mediaentryeditor.html | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html index eed85e54ead7..7b7ef4322527 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html @@ -15,7 +15,6 @@
      -
      This item is in the Recycle Bin
      From 86fd4d121d4d4972fe3b0077491c2a04cec8cd31 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Wed, 7 Apr 2021 09:50:20 +0200 Subject: [PATCH 69/90] Changed parameter ordering --- src/Umbraco.Web/UrlHelperRenderExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web/UrlHelperRenderExtensions.cs b/src/Umbraco.Web/UrlHelperRenderExtensions.cs index 44c3e05972ce..592c88945bae 100644 --- a/src/Umbraco.Web/UrlHelperRenderExtensions.cs +++ b/src/Umbraco.Web/UrlHelperRenderExtensions.cs @@ -263,8 +263,8 @@ public static IHtmlString GetCropUrl(this UrlHelper urlHelper, } public static IHtmlString GetCropUrl(this UrlHelper urlHelper, - string cropAlias, ImageCropperValue imageCropperValue, + string cropAlias, int? width = null, int? height = null, int? quality = null, From 159c57a702ac025d495038636315bd32c4ad9af3 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Wed, 7 Apr 2021 09:51:04 +0200 Subject: [PATCH 70/90] Introduced new extension method on MediaWithCrops to get croppings urls in with full path --- src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs | 7 +++++++ src/Umbraco.Web/ImageCropperTemplateExtensions.cs | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs b/src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs index 9200c7dfe365..3adb699a3612 100644 --- a/src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs +++ b/src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs @@ -6,6 +6,7 @@ using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors.ValueConverters; using Umbraco.Web.Models; +using Umbraco.Web.PropertyEditors.ValueConverters; namespace Umbraco.Web { @@ -380,5 +381,11 @@ public static string GetCropUrl( return imageUrlGenerator.GetImageUrl(options); } + + public static string GetLocalCropUrl(this MediaPickerWithCropsValueConverter.MediaWithCrops mediaWithCrops, string alias, IImageUrlGenerator imageUrlGenerator, string cacheBusterValue) + { + return mediaWithCrops.LocalCrops.Src + mediaWithCrops.LocalCrops.GetCropUrl(alias, imageUrlGenerator, cacheBusterValue: cacheBusterValue); + + } } } diff --git a/src/Umbraco.Web/ImageCropperTemplateExtensions.cs b/src/Umbraco.Web/ImageCropperTemplateExtensions.cs index 8aa0bbdfcf2e..1b8f640d1205 100644 --- a/src/Umbraco.Web/ImageCropperTemplateExtensions.cs +++ b/src/Umbraco.Web/ImageCropperTemplateExtensions.cs @@ -10,6 +10,7 @@ using Umbraco.Core.PropertyEditors.ValueConverters; using Umbraco.Web.Models; using Umbraco.Core.Logging; +using Umbraco.Web.PropertyEditors.ValueConverters; namespace Umbraco.Web { @@ -120,6 +121,13 @@ public static string GetCropUrl( ImageCropRatioMode? ratioMode = null, bool upScale = true) => ImageCropperTemplateCoreExtensions.GetCropUrl(mediaItem, Current.ImageUrlGenerator, width, height, propertyAlias, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBuster, furtherOptions, ratioMode, upScale); + public static string GetLocalCropUrl(this MediaPickerWithCropsValueConverter.MediaWithCrops mediaWithCrops, + string alias, + string cacheBusterValue = null) + => ImageCropperTemplateCoreExtensions.GetLocalCropUrl(mediaWithCrops, alias, Current.ImageUrlGenerator, cacheBusterValue); + + + /// /// Gets the ImageProcessor URL from the image path. /// From 65e790f27bc3fc21521b7dadaa9dba155a0302ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 7 Apr 2021 09:58:38 +0200 Subject: [PATCH 71/90] Reintroducing Single Item Mode --- .../umbMediaPicker3PropertyEditor.component.js | 9 +++++++-- .../PropertyEditors/MediaPicker3Configuration.cs | 3 +++ .../MediaPickerWithCropsValueConverter.cs | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js index f86a969a34b5..02e03ed9d03b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js @@ -61,8 +61,13 @@ vm.$onInit = function() { - vm.validationLimit = vm.model.config.validationLimit; - vm.singleMode = vm.validationLimit.max === 1; + vm.validationLimit = vm.model.config.validationLimit || {}; + // If single-mode we only allow 1 item as the maximum: + if(vm.model.config.singleMode) { + vm.validationLimit.max = 1; + } + // If single-mode isn't set and validation limit maximum is set to 1. + vm.singleMode = vm.model.config.singleMode || (vm.validationLimit.max === 1); vm.allowedTypes = vm.model.config.filter ? vm.model.config.filter.split(",") : null; copyAllMediasAction = { diff --git a/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs b/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs index b447633e70c2..df790252fa98 100644 --- a/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs +++ b/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs @@ -15,6 +15,9 @@ public class MediaPicker3Configuration : IIgnoreUserStartNodesConfig Description = "Limit to specific types")] public string Filter { get; set; } + [ConfigurationField("singleMode", "Single Mode", "boolean", Description = "Outputs a single entry, instead of IEnumerable")] + public bool SingleMode { get; set; } + [ConfigurationField("validationLimit", "Amount", "numberrange", Description = "Set a required range of medias")] public NumberRange ValidationLimit { get; set; } = new NumberRange(); diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs index adf777a5fbdd..9b1de9410b6b 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs @@ -111,7 +111,7 @@ public override object ConvertIntermediateToObject(IPublishedElement owner, IPub private bool IsMultipleDataType(PublishedDataType dataType) { var config = dataType.ConfigurationAs(); - return config.ValidationLimit.Max != 1; + return !config.SingleMode; } private object FirstOrDefault(IList mediaItems) From 41a209335577d7773f31e26d46d9d4bbe9d78b0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 7 Apr 2021 10:04:43 +0200 Subject: [PATCH 72/90] use Multiple instead of SingleMode --- .../mediapicker3/umbMediaPicker3PropertyEditor.component.js | 5 ++--- src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs | 4 ++-- .../ValueConverters/MediaPickerWithCropsValueConverter.cs | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js index 02e03ed9d03b..014f27715237 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js @@ -63,11 +63,10 @@ vm.validationLimit = vm.model.config.validationLimit || {}; // If single-mode we only allow 1 item as the maximum: - if(vm.model.config.singleMode) { + if(vm.model.config.multiple === false) { vm.validationLimit.max = 1; } - // If single-mode isn't set and validation limit maximum is set to 1. - vm.singleMode = vm.model.config.singleMode || (vm.validationLimit.max === 1); + vm.singleMode = vm.validationLimit.max === 1; vm.allowedTypes = vm.model.config.filter ? vm.model.config.filter.split(",") : null; copyAllMediasAction = { diff --git a/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs b/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs index df790252fa98..46c48d7c95ba 100644 --- a/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs +++ b/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs @@ -15,8 +15,8 @@ public class MediaPicker3Configuration : IIgnoreUserStartNodesConfig Description = "Limit to specific types")] public string Filter { get; set; } - [ConfigurationField("singleMode", "Single Mode", "boolean", Description = "Outputs a single entry, instead of IEnumerable")] - public bool SingleMode { get; set; } + [ConfigurationField("multiple", "Pick multiple items", "boolean", Description = "Outputs a IEnumerable")] + public bool Multiple { get; set; } [ConfigurationField("validationLimit", "Amount", "numberrange", Description = "Set a required range of medias")] public NumberRange ValidationLimit { get; set; } = new NumberRange(); diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs index 9b1de9410b6b..2e92c3bce5ec 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs @@ -111,7 +111,7 @@ public override object ConvertIntermediateToObject(IPublishedElement owner, IPub private bool IsMultipleDataType(PublishedDataType dataType) { var config = dataType.ConfigurationAs(); - return !config.SingleMode; + return config.Multiple; } private object FirstOrDefault(IList mediaItems) From 82b71cb527a06e8d086896404426a1d4440d26ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 7 Apr 2021 10:36:44 +0200 Subject: [PATCH 73/90] renaming and adding multiple to preconfigured datatypes --- .../Migrations/Install/DatabaseDataCreator.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs index 61da9b9e6364..264733e5b9a8 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs @@ -145,10 +145,10 @@ void InsertDataTypeNodeDto(int id, int sortOrder, string uniqueId, string text) _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1049, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1049", SortOrder = 2, UniqueId = new Guid("9DBBCBBB-2327-434A-B355-AF1B84E5010A"), Text = "Multiple Media Picker (old)", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1050, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1050", SortOrder = 2, UniqueId = new Guid("B4E3535A-1753-47E2-8568-602CF8CFEE6F"), Text = "Multi URL Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); - _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1051, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1051", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3Guid, Text = "Media Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); - _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1052, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1052", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3MultipleGuid, Text = "Multiple Media Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); - _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1053, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1053", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3SingleImageGuid, Text = "Image Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); - _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1054, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1054", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3MultipleImagesGuid, Text = "Multiple Image Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1051, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1051", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3Guid, Text = "Media Picker 3", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1052, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1052", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3MultipleGuid, Text = "Multiple Media Picker 3", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1053, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1053", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3SingleImageGuid, Text = "Image Media Picker 3", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1054, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1054", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3MultipleImagesGuid, Text = "Multiple Image Media Picker 3", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); } @@ -390,24 +390,25 @@ void InsertDataTypeDto(int id, string editorAlias, string dbType, string configu NodeId = 1051, EditorAlias = Constants.PropertyEditors.Aliases.MediaPicker3, DbType = "Ntext", - Configuration = "{\"validationLimit\":{\"min\":0,\"max\":1}}" + Configuration = "{\"multiple\": false, \"validationLimit\":{\"min\":0,\"max\":1}}" }); _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1052, EditorAlias = Constants.PropertyEditors.Aliases.MediaPicker3, - DbType = "Ntext" + DbType = "Ntext", + Configuration = "{\"multiple\": true}" }); _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1053, EditorAlias = Constants.PropertyEditors.Aliases.MediaPicker3, DbType = "Ntext", - Configuration = "{\"filter\":\"" + Constants.Conventions.MediaTypes.Image + "\", \"validationLimit\":{\"min\":0,\"max\":1}}" + Configuration = "{\"filter\":\"" + Constants.Conventions.MediaTypes.Image + "\", \"multiple\": false, \"validationLimit\":{\"min\":0,\"max\":1}}" }); _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1054, EditorAlias = Constants.PropertyEditors.Aliases.MediaPicker3, DbType = "Ntext", - Configuration = "{\"filter\":\"" + Constants.Conventions.MediaTypes.Image + "\" }" + Configuration = "{\"filter\":\"" + Constants.Conventions.MediaTypes.Image + "\", \"multiple\": true}" }); } From 5739f054097172407f4e5141a3c305a1bce5bee4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 7 Apr 2021 12:47:45 +0200 Subject: [PATCH 74/90] Change existing media picker to use the Clipboard type MEDIA, enabling shared functionality. --- .../src/common/services/clipboard.service.js | 40 --- .../mediapicker/mediapicker.controller.js | 67 +--- .../mediapicker/mediapicker.html | 288 +++++++++--------- .../mediacard/umb-media-card-grid.less | 4 - .../mediapicker/mediapicker.controller.js | 123 ++++++-- .../umb-media-picker3-property-editor.less | 4 + ...umbMediaPicker3PropertyEditor.component.js | 4 +- src/Umbraco.Web.UI/Umbraco/config/lang/da.xml | 1 + src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 1 + .../Umbraco/config/lang/en_us.xml | 1 + 10 files changed, 263 insertions(+), 270 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/clipboard.service.js b/src/Umbraco.Web.UI.Client/src/common/services/clipboard.service.js index 0eee5c0b1977..e34ae047fd90 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/clipboard.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/clipboard.service.js @@ -325,46 +325,6 @@ function clipboardService($window, notificationsService, eventsService, localSto }; - /** - * @ngdoc method - * @name umbraco.services.clipboardService#copy - * @methodOf umbraco.services.clipboardService - * - * @param {string} type A string defining the type of data to storing, example: 'elementType', 'contentNode' - * @param {string} alias A string defining the alias of the data to store, example: 'product' - * @param {object[]} data An array of objects containing the properties to be saved, this could be the object of a ElementType, ContentNode, ... - * - * @description - * Saves multiple JS-object to the clipboard. - */ - service.copyMultiple = function (type, alias, data, firstLevelClearupMethod) { - - var storage = retriveStorage(); - - data.forEach(item => { - var displayLabel = item.displayLabel || item.name; - var displayIcon = item.displayIcon || iconHelper.convertFromLegacyIcon(item.icon); - var uniqueKey = item.uniqueKey || item.key || console.error("missing unique key for this content"); - - // remove previous copies of this entry: - storage.entries = storage.entries.filter( - (entry) => { - return entry.unique !== uniqueKey; - } - ); - - var entry = { unique: uniqueKey, type: type, alias: alias, data: prepareEntryForStorage(type, item, firstLevelClearupMethod), label: displayLabel, icon: displayIcon, date: Date.now() }; - storage.entries.push(entry); - }); - - if (saveStorage(storage) === true) { - notificationsService.success("Clipboard", "Copied to clipboard."); - } else { - notificationsService.error("Clipboard", "Couldnt copy this data to clipboard."); - } - - }; - /** * @ngdoc method diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js index 58cb019c9a17..b524ac594941 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js @@ -30,9 +30,9 @@ angular.module("umbraco") vm.showMediaList = false; vm.navigation = []; - vm.clipboardImages = []; var dialogOptions = $scope.model; + vm.clipboardItems = dialogOptions.clipboardItems; $scope.disableFolderSelect = (dialogOptions.disableFolderSelect && dialogOptions.disableFolderSelect !== "0") ? true : false; $scope.disableFocalPoint = (dialogOptions.disableFocalPoint && dialogOptions.disableFocalPoint !== "0") ? true : false; @@ -116,22 +116,27 @@ angular.module("umbraco") "icon": "icon-umb-media", "active": true, "view": "" - }, - { - "alias": "clipboard", - "name": data[1], - "icon": "icon-paste-in", - "view": "", - "disabled": vm.clipboardImages.length === 0 }]; + if(vm.clipboardItems) { + vm.navigation.push({ + "alias": "clipboard", + "name": data[1], + "icon": "icon-paste-in", + "view": "", + "disabled": vm.clipboardItems.length === 0 + }); + } + vm.activeTab = vm.navigation[0]; }); + } } function onInit() { + /* clipboardService.retriveEntriesOfType(clipboardService.TYPES.IMAGE, ["Media"]).forEach(item => { var media = item.data.media; if ((($scope.disableFolderSelect || $scope.onlyImages) && media.isFolder) || @@ -141,6 +146,7 @@ angular.module("umbraco") setDefaultData(media); vm.clipboardImages.push(media); }); + */ setTitle(); @@ -437,8 +443,8 @@ angular.module("umbraco") function clickClearClipboard() { vm.onNavigationChanged(vm.navigation[0]); vm.navigation[1].disabled = true; - vm.clipboardImages = []; - clipboardService.clearEntriesOfType(clipboardService.TYPES.IMAGE, ["Media"]); + vm.clipboardItems = []; + dialogOptions.clickClearClipboard(); }; var debounceSearchMedia = _.debounce(function () { @@ -621,47 +627,6 @@ angular.module("umbraco") } } - - vm.navigation = []; - - localizationService.localizeMany(["sections_media", "mediaPicker_tabClipboard"]).then( - function (data) { - - vm.navigation = [{ - "alias": "empty", - "name": data[0], - "icon": "icon-umb-media", - "active": true, - "view": "" - }]; - - if(dialogOptions.clipboardItems) { - vm.navigation.push({ - "alias": "clipboard", - "name": data[1], - "icon": "icon-paste-in", - "view": "", - "disabled": dialogOptions.clipboardItems.length === 0 - }); - } - - vm.activeTab = vm.navigation[0]; - } - ); - - vm.onNavigationChanged = function(tab) { - vm.activeTab.active = false; - vm.activeTab = tab; - vm.activeTab.active = true; - } - - vm.clickClearClipboard = function() { - vm.onNavigationChanged(vm.navigation[0]); - vm.navigation[1].disabled = true;// disabled ws determined when creating the navigation, so we need to update it here. - dialogOptions.clipboardItems = [];// This dialog is not connected via the clipboardService events, so we need to update manually. - dialogOptions.clickClearClipboard(); - } - onInit(); }); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.html index 3a81575afa9e..ca3a070b3d43 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.html @@ -15,163 +15,165 @@ -
      -
      - -
      - -
      - -
      - - -
      - - + + +
      + +
      + +
      + -
      -
      -
      - - + +
      + +
      -
      -
      - - -
      - -
        -
      • - - -
      • -
      • - - -
      • -
      • - - - -
      • -
      - +
      +
      +
      + +
      - - - - - - - - - - - -
      - - +
      +
      +
      + +
      - - - +
        +
      • + + +
      • +
      • + + +
      • +
      • + + + +
      • +
      + +
      + + + + + + + + + + +
      + +
      - -
      -
      -
      - - + + + + +
      + - - + +
      diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less index 9365cfd38a07..f7e576433570 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card-grid.less @@ -7,10 +7,6 @@ justify-items: center; align-items: center; - - &.--singleMode { - max-width: 160px; - } } .umb-media-card-grid__cell { position: relative; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js index b47dd2f4704e..f90583aed86f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js @@ -68,27 +68,29 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl return mediaItem; }); - medias.forEach(media => { - if (!media.extension && media.id && media.metaData) { - media.extension = mediaHelper.getFileExtension(media.metaData.MediaPath); - } + medias.forEach(media => appendMedia(media)); - // if there is no thumbnail, try getting one if the media is not a placeholder item - if (!media.thumbnail && media.id && media.metaData) { - media.thumbnail = mediaHelper.resolveFileFromEntity(media, true); - } + sync(); + }); + } + } - $scope.mediaItems.push(media); + function appendMedia(media) { + if (!media.extension && media.id && media.metaData) { + media.extension = mediaHelper.getFileExtension(media.metaData.MediaPath); + } - if ($scope.model.config.idType === "udi") { - $scope.ids.push(media.udi); - } else { - $scope.ids.push(media.id); - } - }); + // if there is no thumbnail, try getting one if the media is not a placeholder item + if (!media.thumbnail && media.id && media.metaData) { + media.thumbnail = mediaHelper.resolveFileFromEntity(media, true); + } - sync(); - }); + $scope.mediaItems.push(media); + + if ($scope.model.config.idType === "udi") { + $scope.ids.push(media.udi); + } else { + $scope.ids.push(media.id); } } @@ -103,9 +105,9 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl } function reloadUpdatedMediaItems(updatedMediaNodes) { - // because the images can be edited through the media picker we need to + // because the images can be edited through the media picker we need to // reload. We only reload the images that is already picked but has been updated. - // We have to get the entities from the server because the media + // We have to get the entities from the server because the media // can be edited without being selected $scope.mediaItems.forEach(media => { if (updatedMediaNodes.indexOf(media.udi) !== -1) { @@ -164,20 +166,50 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl } function copyAllEntries() { - clipboardService.copyMultiple(clipboardService.TYPES.IMAGE, - "Media", - $scope.mediaItems.map(item => { - return { "media": item, "key": item.udi } - }), clearNodeForCopy); + if($scope.mediaItems.length > 0) { + + // gather aliases + var aliases = $scope.mediaItems.map(mediaEntity => mediaEntity.metaData.ContentTypeAlias); + + // remove duplicate aliases + aliases = aliases.filter((item, index) => aliases.indexOf(item) === index); + + var data = $scope.mediaItems.map(mediaEntity => { return {"mediaKey": mediaEntity.key }}); + + localizationService.localize("clipboard_labelForArrayOfItems", [$scope.model.label]).then(function(localizedLabel) { + clipboardService.copyArray(clipboardService.TYPES.MEDIA, aliases, data, localizedLabel, "icon-thumbnail-list", $scope.model.id, clearNodeForCopy); + }); + } } - function copyItem(item) { - clipboardService.copy(clipboardService.TYPES.IMAGE, "Media", { "media": item }, null, null, item.udi, clearNodeForCopy); + function copyItem(mediaItem) { + + var mediaEntry = {}; + mediaEntry.mediaKey = mediaItem.key; + + clipboardService.copy(clipboardService.TYPES.MEDIA, mediaItem.metaData.ContentTypeAlias, mediaEntry, mediaItem.name, mediaItem.icon, mediaItem.udi, clearNodeForCopy); } - function clearNodeForCopy(item) { - delete item.media.selected; - delete item.media.selectable; + function clearNodeForCopy(mediaItem) { + delete mediaItem.selected; + delete mediaItem.selectable; + } + + function pasteFromClipboard(pasteEntry, pasteType) { + + if (pasteEntry === undefined) { + return; + } + + entityResource.getById(pasteEntry.mediaKey, "Media").then(function (mediaEntity) { + + if(disableFolderSelect === true && mediaEntity.metaData.ContentTypeAlias === "Folder") { + return; + } + + appendMedia(mediaEntity); + sync(); + }); } function editItem(item) { @@ -191,7 +223,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl if (model && model.mediaNode) { entityResource.getById(model.mediaNode.id, "Media") .then(function (mediaEntity) { - // if an image is selecting more than once + // if an image is selecting more than once // we need to update all the media items $scope.mediaItems.forEach(media => { if (media.id === model.mediaNode.id) { @@ -217,6 +249,22 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl multiPicker: multiPicker, onlyImages: onlyImages, disableFolderSelect: disableFolderSelect, + clickPasteItem: function(item, mouseEvent) { + if (Array.isArray(item.data)) { + var indexIncrementor = 0; + item.data.forEach(function (entry) { + if (pasteFromClipboard(entry, item.type)) { + indexIncrementor++; + } + }); + } else { + pasteFromClipboard(item.data, item.type); + } + if(!(mouseEvent.ctrlKey || mouseEvent.metaKey)) { + editorService.close(); + } + setDirty(); + }, submit: function (model) { editorService.close(); @@ -248,6 +296,21 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl } } + + var allowedTypes = null; + if(onlyImages) { + allowedTypes = ["Image"]; // Media Type Image Alias. + } + + mediaPicker.clickClearClipboard = function ($event) { + clipboardService.clearEntriesOfType(clipboardService.TYPES.Media, allowedTypes); + }; + + mediaPicker.clipboardItems = clipboardService.retriveEntriesOfType(clipboardService.TYPES.MEDIA, allowedTypes); + mediaPicker.clipboardItems.sort( (a, b) => { + return b.date - a.date + }); + editorService.mediaPicker(mediaPicker); } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.less b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.less index 3f2b7229564a..d02c0b055c90 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.less +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umb-media-picker3-property-editor.less @@ -5,5 +5,9 @@ border: 1px solid @inputBorder; box-sizing: border-box; .umb-property-editor--limit-width(); + + &.--singleMode { + max-width: 202px; + } } } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js index 014f27715237..c589a1a12c12 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js @@ -314,7 +314,7 @@ entityResource.getByIds(mediaKeys, "Media").then(function (entities) { // gather aliases - var aliases = entities.map(mediaEntity => mediaEntity.metaData.ContentTypeAlias) + var aliases = entities.map(mediaEntity => mediaEntity.metaData.ContentTypeAlias); // remove duplicate aliases aliases = aliases.filter((item, index) => aliases.indexOf(item) === index); @@ -343,7 +343,7 @@ vm.copyMedia = copyMedia; function copyMedia(mediaEntry) { entityResource.getById(mediaEntry.mediaKey, "Media").then(function (mediaEntity) { - clipboardService.copy(clipboardService.TYPES.MEDIA, mediaEntity.metaData.ContentTypeAlias, mediaEntry, mediaEntity.name, mediaEntity.icon, mediaEntity.udi); + clipboardService.copy(clipboardService.TYPES.MEDIA, mediaEntity.metaData.ContentTypeAlias, mediaEntry, mediaEntity.name, mediaEntity.icon, mediaEntry.key); }); } function requestPasteFromClipboard(createIndex, pasteEntry, pasteType) { diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml index c0503f05556b..586946250e1b 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml @@ -1856,6 +1856,7 @@ Mange hilsner fra Umbraco robotten Kopier %0% %0% fra %1% + Samling af %0% Fjern alle elementer Ryd udklipsholder diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml index 12f53245bff5..3955300b7bfa 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml @@ -2389,6 +2389,7 @@ To manage your website, simply open the Umbraco backoffice and start adding cont Copy %0% %0% from %1% + Collection of %0% Remove all items Clear clipboard 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 e062d06530e6..6b057a151d57 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml @@ -2408,6 +2408,7 @@ To manage your website, simply open the Umbraco backoffice and start adding cont Copy %0% %0% from %1% + Collection of %0% Remove all items Clear clipboard From 3d07c6f07bf46af58a6c91dd74434c7a9557eea0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 7 Apr 2021 13:02:49 +0200 Subject: [PATCH 75/90] clean up unused clipboard parts --- .../src/common/services/clipboard.service.js | 1 - .../mediapicker/mediapicker.controller.js | 9 ++------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/clipboard.service.js b/src/Umbraco.Web.UI.Client/src/common/services/clipboard.service.js index e34ae047fd90..83f770ba9c0f 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/clipboard.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/clipboard.service.js @@ -16,7 +16,6 @@ function clipboardService($window, notificationsService, eventsService, localSto const TYPES = {}; TYPES.ELEMENT_TYPE = "elementType"; TYPES.BLOCK = "block"; - TYPES.IMAGE = "image"; TYPES.RAW = "raw"; TYPES.MEDIA = "media"; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js index f90583aed86f..e5e1fe30d5b8 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js @@ -177,7 +177,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl var data = $scope.mediaItems.map(mediaEntity => { return {"mediaKey": mediaEntity.key }}); localizationService.localize("clipboard_labelForArrayOfItems", [$scope.model.label]).then(function(localizedLabel) { - clipboardService.copyArray(clipboardService.TYPES.MEDIA, aliases, data, localizedLabel, "icon-thumbnail-list", $scope.model.id, clearNodeForCopy); + clipboardService.copyArray(clipboardService.TYPES.MEDIA, aliases, data, localizedLabel, "icon-thumbnail-list", $scope.model.id); }); } } @@ -187,12 +187,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl var mediaEntry = {}; mediaEntry.mediaKey = mediaItem.key; - clipboardService.copy(clipboardService.TYPES.MEDIA, mediaItem.metaData.ContentTypeAlias, mediaEntry, mediaItem.name, mediaItem.icon, mediaItem.udi, clearNodeForCopy); - } - - function clearNodeForCopy(mediaItem) { - delete mediaItem.selected; - delete mediaItem.selectable; + clipboardService.copy(clipboardService.TYPES.MEDIA, mediaItem.metaData.ContentTypeAlias, mediaEntry, mediaItem.name, mediaItem.icon, mediaItem.udi); } function pasteFromClipboard(pasteEntry, pasteType) { From 520e3ed2a4bb09d29b57f4d472ee186f059aa5a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 7 Apr 2021 14:09:42 +0200 Subject: [PATCH 76/90] adjusted to new amount --- .../Repositories/DataTypeDefinitionRepositoryTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs index f2913bd39378..339b3d4931b4 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs @@ -279,7 +279,7 @@ public void Can_Perform_GetAll_On_DataTypeDefinitionRepository() Assert.That(dataTypeDefinitions, Is.Not.Null); Assert.That(dataTypeDefinitions.Any(), Is.True); Assert.That(dataTypeDefinitions.Any(x => x == null), Is.False); - Assert.That(dataTypeDefinitions.Length, Is.EqualTo(33)); + Assert.That(dataTypeDefinitions.Length, Is.EqualTo(37)); } } From 7dddb4b48cd4050c6ebd4f3a900ffa8935b61faa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 7 Apr 2021 16:41:09 +0200 Subject: [PATCH 77/90] correcting test --- src/Umbraco.Tests/Composing/TypeLoaderTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Tests/Composing/TypeLoaderTests.cs b/src/Umbraco.Tests/Composing/TypeLoaderTests.cs index b0c57b685b83..968081f1e095 100644 --- a/src/Umbraco.Tests/Composing/TypeLoaderTests.cs +++ b/src/Umbraco.Tests/Composing/TypeLoaderTests.cs @@ -268,7 +268,7 @@ public void Resolves_Types() public void GetDataEditors() { var types = _typeLoader.GetDataEditors(); - Assert.AreEqual(40, types.Count()); + Assert.AreEqual(47, types.Count()); } /// From e029ffa95c9b7461fc2b3f494337caa38cac4c9d Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Wed, 7 Apr 2021 16:47:20 +0200 Subject: [PATCH 78/90] Fix unit test --- src/Umbraco.Tests/Composing/TypeLoaderTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Tests/Composing/TypeLoaderTests.cs b/src/Umbraco.Tests/Composing/TypeLoaderTests.cs index 968081f1e095..d2bbf3e86529 100644 --- a/src/Umbraco.Tests/Composing/TypeLoaderTests.cs +++ b/src/Umbraco.Tests/Composing/TypeLoaderTests.cs @@ -268,7 +268,7 @@ public void Resolves_Types() public void GetDataEditors() { var types = _typeLoader.GetDataEditors(); - Assert.AreEqual(47, types.Count()); + Assert.AreEqual(41, types.Count()); } /// From 4e87c8e8370d67b6b87bb21fcc4f81e9106463ba Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Thu, 8 Apr 2021 11:37:31 +0200 Subject: [PATCH 79/90] Move MediaWithCrops to separate file and move to Core.Models --- src/Umbraco.Core/Models/MediaWithCrops.cs | 15 +++++++++++++++ src/Umbraco.Core/Umbraco.Core.csproj | 1 + .../ImageCropperTemplateCoreExtensions.cs | 2 +- src/Umbraco.Web/ImageCropperTemplateExtensions.cs | 2 +- .../MediaPickerWithCropsValueConverter.cs | 14 +++----------- 5 files changed, 21 insertions(+), 13 deletions(-) create mode 100644 src/Umbraco.Core/Models/MediaWithCrops.cs diff --git a/src/Umbraco.Core/Models/MediaWithCrops.cs b/src/Umbraco.Core/Models/MediaWithCrops.cs new file mode 100644 index 000000000000..ef3205bd9436 --- /dev/null +++ b/src/Umbraco.Core/Models/MediaWithCrops.cs @@ -0,0 +1,15 @@ +using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.PropertyEditors.ValueConverters; + +namespace Umbraco.Core.Models +{ + /// + /// Model used in Razor Views for rendering + /// + public class MediaWithCrops + { + public IPublishedContent MediaItem { get; set; } + + public ImageCropperValue LocalCrops { get; set; } + } +} diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 2ea5292d7327..0a453ad75f07 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -156,6 +156,7 @@ + diff --git a/src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs b/src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs index 3adb699a3612..026bcd6cdba0 100644 --- a/src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs +++ b/src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs @@ -382,7 +382,7 @@ public static string GetCropUrl( return imageUrlGenerator.GetImageUrl(options); } - public static string GetLocalCropUrl(this MediaPickerWithCropsValueConverter.MediaWithCrops mediaWithCrops, string alias, IImageUrlGenerator imageUrlGenerator, string cacheBusterValue) + public static string GetLocalCropUrl(this MediaWithCrops mediaWithCrops, string alias, IImageUrlGenerator imageUrlGenerator, string cacheBusterValue) { return mediaWithCrops.LocalCrops.Src + mediaWithCrops.LocalCrops.GetCropUrl(alias, imageUrlGenerator, cacheBusterValue: cacheBusterValue); diff --git a/src/Umbraco.Web/ImageCropperTemplateExtensions.cs b/src/Umbraco.Web/ImageCropperTemplateExtensions.cs index 1b8f640d1205..d4188c9e6830 100644 --- a/src/Umbraco.Web/ImageCropperTemplateExtensions.cs +++ b/src/Umbraco.Web/ImageCropperTemplateExtensions.cs @@ -121,7 +121,7 @@ public static string GetCropUrl( ImageCropRatioMode? ratioMode = null, bool upScale = true) => ImageCropperTemplateCoreExtensions.GetCropUrl(mediaItem, Current.ImageUrlGenerator, width, height, propertyAlias, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBuster, furtherOptions, ratioMode, upScale); - public static string GetLocalCropUrl(this MediaPickerWithCropsValueConverter.MediaWithCrops mediaWithCrops, + public static string GetLocalCropUrl(this MediaWithCrops mediaWithCrops, string alias, string cacheBusterValue = null) => ImageCropperTemplateCoreExtensions.GetLocalCropUrl(mediaWithCrops, alias, Current.ImageUrlGenerator, cacheBusterValue); diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs index 2e92c3bce5ec..5751db2b8599 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs @@ -3,9 +3,11 @@ using System.Collections; using System.Collections.Generic; using System.Runtime.Serialization; +using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; using Umbraco.Core.PropertyEditors.ValueConverters; +using Umbraco.Web.Models; using Umbraco.Web.PublishedCache; namespace Umbraco.Web.PropertyEditors.ValueConverters @@ -79,7 +81,7 @@ public override object ConvertIntermediateToObject(IPublishedElement owner, IPub { return isMultiple ? mediaItems: null; } - + var dtos = JsonConvert.DeserializeObject>(inter.ToString()); foreach(var media in dtos) @@ -138,15 +140,5 @@ internal class MediaWithCropsDto [DataMember(Name = "focalPoint")] public ImageCropperValue.ImageCropperFocalPoint FocalPoint { get; set; } } - - /// - /// Model used in Razor Views for rendering - /// - public class MediaWithCrops - { - public IPublishedContent MediaItem { get; set; } - - public ImageCropperValue LocalCrops { get; set; } - } } } From b8b8c29795d18b4d6abd50a13b11683dc4861d8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 9 Apr 2021 12:20:07 +0200 Subject: [PATCH 80/90] parseContentForPaste --- .../infiniteeditors/mediapicker/mediapicker.controller.js | 2 +- .../propertyeditors/mediapicker/mediapicker.controller.js | 2 ++ .../mediapicker3/umbMediaPicker3PropertyEditor.component.js | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js index b524ac594941..b39e629fd5b2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js @@ -105,7 +105,7 @@ angular.module("umbraco") function setTitle() { if (!$scope.model.title) { - localizationService.localizeMany(["defaultdialogs_selectMedia", "defaultdialogs_tabClipboard"]) + localizationService.localizeMany(["defaultdialogs_selectMedia", "mediaPicker_tabClipboard"]) .then(function (data) { $scope.model.title = data[0]; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js index e5e1fe30d5b8..a864f0a2a18c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js @@ -196,6 +196,8 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl return; } + pasteEntry = clipboardService.parseContentForPaste(pasteEntry, pasteType); + entityResource.getById(pasteEntry.mediaKey, "Media").then(function (mediaEntity) { if(disableFolderSelect === true && mediaEntity.metaData.ContentTypeAlias === "Folder") { diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js index c589a1a12c12..89148cbaed6c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js @@ -352,10 +352,13 @@ return false; } + pasteEntry = clipboardService.parseContentForPaste(pasteEntry, pasteType); + pasteEntry.key = String.CreateGuid(); updateMediaEntryData(pasteEntry); vm.model.value.splice(createIndex, 0, pasteEntry); + return true; } From 6d47eebc8f87d7eec5aff2a56714cf6a20b429c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 12 Apr 2021 09:11:26 +0200 Subject: [PATCH 81/90] clean up --- ...umbMediaPicker3PropertyEditor.component.js | 24 +------------------ 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js index 89148cbaed6c..4d2aef6c336b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js @@ -137,7 +137,7 @@ dataTypeKey: vm.model.dataTypeKey, multiPicker: vm.singleMode !== true, clickPasteItem: function(item, mouseEvent) { - console.log("clickPasteItem", item, mouseEvent) + if (Array.isArray(item.data)) { var indexIncrementor = 0; item.data.forEach(function (entry) { @@ -363,27 +363,6 @@ } - /* - vm.requestRemoveMedia = requestRemoveMedia; - function requestRemoveMedia(media) { - localizationService.localizeMany(["general_delete", "mediaPicker_confirmRemoveMediaEntryMessage", "general_remove"]).then(function (data) { - const overlay = { - title: data[0], - content: localizationService.tokenReplace(data[1], [media.name]), - submitButtonLabel: data[2], - close: function () { - overlayService.close(); - }, - submit: function () { - removeMedia(media); - overlayService.close(); - } - }; - - overlayService.confirmDelete(overlay); - }); - } - */ function requestRemoveAllMedia() { localizationService.localizeMany(["mediaPicker_confirmRemoveAllMediaEntryMessage", "general_remove"]).then(function (data) { overlayService.confirmDelete({ @@ -402,7 +381,6 @@ vm.sortableOptions = { - //containment: "parent", cursor: "grabbing", handle: "umb-media-card", cancel: "input,textarea,select,option", From 06a3ec1c2436c3ef9fa6007a098359582e2b89e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 12 Apr 2021 10:20:25 +0200 Subject: [PATCH 82/90] ensure crops is an array. --- .../mediapicker3/umbMediaPicker3PropertyEditor.component.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js index 4d2aef6c336b..b3efef061a65 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js @@ -66,6 +66,7 @@ if(vm.model.config.multiple === false) { vm.validationLimit.max = 1; } + vm.model.config.crops = vm.model.config.crops || []; vm.singleMode = vm.validationLimit.max === 1; vm.allowedTypes = vm.model.config.filter ? vm.model.config.filter.split(",") : null; From 6143a51ed1fdf95a2ebfced404e18b489fcb9f7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 13 Apr 2021 13:37:13 +0200 Subject: [PATCH 83/90] actively enable focal points, so we dont set focal points that aren't used. --- .../components/imaging/umbimagegravity.directive.js | 5 ++--- .../infiniteeditors/mediaentryeditor/mediaentryeditor.html | 1 + .../src/views/components/imaging/umb-image-gravity.html | 2 +- .../mediapicker3/umbMediaPicker3PropertyEditor.component.js | 1 + src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs | 5 ++++- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js index f17651200b65..277848811b53 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js @@ -82,8 +82,6 @@ } }); - console.log(focalPointElement.draggable) - window.addEventListener('resize.umbImageGravity', onResizeHandler); window.addEventListener('resize', onResizeHandler); @@ -211,7 +209,8 @@ src: "<", center: "<", onImageLoaded: "&?", - onValueChanged: "&" + onValueChanged: "&", + disableFocalPoint: " diff --git a/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-gravity.html b/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-gravity.html index 71e7292feadb..10aa6a774ab6 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-gravity.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-gravity.html @@ -9,7 +9,7 @@
      -
      +
      diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js index b3efef061a65..34cef49d3363 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js @@ -289,6 +289,7 @@ changeMediaFor: changeMediaFor, resetCrop: resetCrop }, + enableFocalPointSetter: vm.model.config.enableLocalFocalPoint || false, view: "views/common/infiniteeditors/mediaEntryEditor/mediaEntryEditor.html", size: "large", submit: function(model) { diff --git a/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs b/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs index 46c48d7c95ba..c404638d4213 100644 --- a/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs +++ b/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs @@ -38,7 +38,10 @@ public class NumberRange Description = "Selecting this option allows a user to choose nodes that they normally don't have access to.")] public bool IgnoreUserStartNodes { get; set; } - [ConfigurationField("crops", "Image Croppings", "views/propertyeditors/MediaPicker3/prevalue/mediapicker3.crops.html", Description = "Local croppings, stored on document")] + [ConfigurationField("enableLocalFocalPoint", "Enable Focal Point", "boolean")] + public bool EnableLocalFocalPoint { get; set; } + + [ConfigurationField("crops", "Image Crops", "views/propertyeditors/MediaPicker3/prevalue/mediapicker3.crops.html", Description = "Local crops, stored on document")] public CropConfiguration[] Crops { get; set; } public class CropConfiguration From 5da17dba90ecd209048eecb8dc2645c1003ef3cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 13 Apr 2021 14:11:36 +0200 Subject: [PATCH 84/90] only accept files that matches file extensions from Umbraco Settings --- .../propertyeditors/imagecropper/imagecropper.controller.js | 6 ++++-- .../views/propertyeditors/imagecropper/imagecropper.html | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) 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 70c74d0391cb..792e7b245549 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 @@ -1,6 +1,6 @@ angular.module('umbraco') .controller("Umbraco.PropertyEditors.ImageCropperController", - function ($scope, fileManager, $timeout) { + function ($scope, fileManager, $timeout, mediaHelper) { var config = Utilities.copy($scope.model.config); @@ -18,6 +18,8 @@ angular.module('umbraco') //declare a special method which will be called whenever the value has changed from the server $scope.model.onValueChanged = onValueChanged; + var umbracoSettings = Umbraco.Sys.ServerVariables.umbracoSettings; + $scope.acceptFileExt = mediaHelper.formatFileTypes(umbracoSettings.imageFileTypes); /** * Called when the umgImageGravity component updates the focal point value * @param {any} left @@ -144,7 +146,7 @@ angular.module('umbraco') // we have a crop open already - close the crop (this will discard any changes made) close(); - // the crop editor needs a digest cycle to close down properly, otherwise its state + // the crop editor needs a digest cycle to close down properly, otherwise its state // is reused for the new crop... and that's really bad $timeout(function () { crop(targetCrop); 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 86a5353391f3..f86d07f52a72 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 @@ -10,7 +10,8 @@ on-files-selected="filesSelected(value, files)" on-files-changed="filesChanged(files)" on-init="fileUploaderInit(value, files)" - hide-selection="true"> + hide-selection="true" + accept-file-ext="acceptFileExt">
      From c2526e3f52d309b2cc7a949dbbb846ebdbfee93e Mon Sep 17 00:00:00 2001 From: Elitsa Marinovska Date: Wed, 14 Apr 2021 15:21:23 +0200 Subject: [PATCH 85/90] Cleanup --- src/Umbraco.Core/Constants-Conventions.cs | 4 ++-- src/Umbraco.Core/Constants-DataTypes.cs | 10 +++++----- src/Umbraco.Core/Constants-PropertyTypeGroups.cs | 8 ++++---- .../ValueConverters/JsonValueConverter.cs | 2 +- src/Umbraco.Web/Editors/MediaController.cs | 5 +---- src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs | 1 - src/Umbraco.Web/ImageCropperTemplateExtensions.cs | 3 --- .../PropertyEditors/FileUploadConfiguration.cs | 1 - .../PropertyEditors/FileUploadConfigurationEditor.cs | 4 +--- .../PropertyEditors/MediaPicker3Configuration.cs | 2 -- .../PropertyEditors/MediaPicker3ConfigurationEditor.cs | 2 -- .../PropertyEditors/MediaPicker3PropertyEditor.cs | 9 +-------- .../MediaPickerWithCropsValueConverter.cs | 3 +-- 13 files changed, 16 insertions(+), 38 deletions(-) diff --git a/src/Umbraco.Core/Constants-Conventions.cs b/src/Umbraco.Core/Constants-Conventions.cs index e563ae3ca3c9..c8233c8d340f 100644 --- a/src/Umbraco.Core/Constants-Conventions.cs +++ b/src/Umbraco.Core/Constants-Conventions.cs @@ -119,7 +119,7 @@ public static class MediaTypes public const string Image = "Image"; /// - /// MediaType alias for an video-. + /// MediaType alias for a video. /// public const string Video = "Video"; @@ -134,7 +134,7 @@ public static class MediaTypes public const string Article = "Article"; /// - /// MediaType alias for an vector graphics. + /// MediaType alias for vector graphics. /// public const string VectorGraphics = "VectorGraphics"; diff --git a/src/Umbraco.Core/Constants-DataTypes.cs b/src/Umbraco.Core/Constants-DataTypes.cs index ddeaa5278b78..f1af0ba99e6c 100644 --- a/src/Umbraco.Core/Constants-DataTypes.cs +++ b/src/Umbraco.Core/Constants-DataTypes.cs @@ -98,7 +98,7 @@ public static class Guids public const string MediaPicker3 = "4309A3EA-0D78-4329-A06C-C80B036AF19A"; /// - /// Guid for Media Picker + /// Guid for Media Picker v3 /// public static readonly Guid MediaPicker3Guid = new Guid(MediaPicker3); @@ -108,7 +108,7 @@ public static class Guids public const string MediaPicker3Multiple = "1B661F40-2242-4B44-B9CB-3990EE2B13C0"; /// - /// Guid for Media Picker + /// Guid for Media Picker v3 multiple /// public static readonly Guid MediaPicker3MultipleGuid = new Guid(MediaPicker3Multiple); @@ -119,18 +119,18 @@ public static class Guids public const string MediaPicker3SingleImage = "AD9F0CF2-BDA2-45D5-9EA1-A63CFC873FD3"; /// - /// Guid for Media Picker + /// Guid for Media Picker v3 single-image /// public static readonly Guid MediaPicker3SingleImageGuid = new Guid(MediaPicker3SingleImage); /// - /// Guid for Media Picker v3 images multi-image as string + /// Guid for Media Picker v3 multi-image as string /// public const string MediaPicker3MultipleImages = "0E63D883-B62B-4799-88C3-157F82E83ECC"; /// - /// Guid for Media Picker + /// Guid for Media Picker v3 multi-image /// public static readonly Guid MediaPicker3MultipleImagesGuid = new Guid(MediaPicker3MultipleImages); diff --git a/src/Umbraco.Core/Constants-PropertyTypeGroups.cs b/src/Umbraco.Core/Constants-PropertyTypeGroups.cs index 9321b1f83754..20ada8c0f4a3 100644 --- a/src/Umbraco.Core/Constants-PropertyTypeGroups.cs +++ b/src/Umbraco.Core/Constants-PropertyTypeGroups.cs @@ -8,7 +8,7 @@ public static partial class Constants public static class PropertyTypeGroups { /// - /// Guid for a Image PropertyTypeGroup object. + /// Guid for an Image PropertyTypeGroup object. /// public const string Image = "79ED4D07-254A-42CF-8FA9-EBE1C116A596"; @@ -23,12 +23,12 @@ public static class PropertyTypeGroups public const string Video = "2F0A61B6-CF92-4FF4-B437-751AB35EB254"; /// - /// Guid for a Audio PropertyTypeGroup object. + /// Guid for an Audio PropertyTypeGroup object. /// public const string Audio = "335FB495-0A87-4E82-B902-30EB367B767C"; /// - /// Guid for a Article PropertyTypeGroup object. + /// Guid for an Article PropertyTypeGroup object. /// public const string Article = "9AF3BD65-F687-4453-9518-5F180D1898EC"; @@ -38,7 +38,7 @@ public static class PropertyTypeGroups public const string VectorGraphics = "F199B4D7-9E84-439F-8531-F87D9AF37711"; /// - /// Guid for a Image PropertyTypeGroup object. + /// Guid for a Membership PropertyTypeGroup object. /// public const string Membership = "0756729D-D665-46E3-B84A-37ACEAA614F8"; } diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/JsonValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/JsonValueConverter.cs index 4a660d237620..694ebfde2780 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/JsonValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/JsonValueConverter.cs @@ -31,7 +31,7 @@ public JsonValueConverter(PropertyEditorCollection propertyEditors) /// /// It is a converter for any value type that is "JSON" - /// Unless its in the Excluded Property Editors list + /// Unless it's in the Excluded Property Editors list /// The new MediaPicker 3 stores JSON but we want to use its own ValueConvertor /// /// diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs index 5f3a2612e510..7160a87351ab 100644 --- a/src/Umbraco.Web/Editors/MediaController.cs +++ b/src/Umbraco.Web/Editors/MediaController.cs @@ -37,8 +37,6 @@ using Umbraco.Web.Editors.Binders; using Umbraco.Web.Editors.Filters; using Umbraco.Core.Models.Entities; -using static Umbraco.Web.PropertyEditors.FileUploadConfiguration; -using Umbraco.Web.PropertyEditors; namespace Umbraco.Web.Editors { @@ -730,12 +728,11 @@ public async Task PostAddFile() } - // If media type is still File then lets check if its a image. + // If media type is still File then let's check if it's an image. if (mediaType == Constants.Conventions.MediaTypes.File && Current.Configs.Settings().Content.ImageFileTypes.Contains(ext)) { mediaType = Constants.Conventions.MediaTypes.Image; } - } else { diff --git a/src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs b/src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs index 026bcd6cdba0..766cb1e99f91 100644 --- a/src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs +++ b/src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs @@ -6,7 +6,6 @@ using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors.ValueConverters; using Umbraco.Web.Models; -using Umbraco.Web.PropertyEditors.ValueConverters; namespace Umbraco.Web { diff --git a/src/Umbraco.Web/ImageCropperTemplateExtensions.cs b/src/Umbraco.Web/ImageCropperTemplateExtensions.cs index d4188c9e6830..51845946f133 100644 --- a/src/Umbraco.Web/ImageCropperTemplateExtensions.cs +++ b/src/Umbraco.Web/ImageCropperTemplateExtensions.cs @@ -1,7 +1,5 @@ using System; -using Newtonsoft.Json.Linq; using System.Globalization; -using System.Text; using Newtonsoft.Json; using Umbraco.Core; using Umbraco.Core.Composing; @@ -10,7 +8,6 @@ using Umbraco.Core.PropertyEditors.ValueConverters; using Umbraco.Web.Models; using Umbraco.Core.Logging; -using Umbraco.Web.PropertyEditors.ValueConverters; namespace Umbraco.Web { diff --git a/src/Umbraco.Web/PropertyEditors/FileUploadConfiguration.cs b/src/Umbraco.Web/PropertyEditors/FileUploadConfiguration.cs index 51259a90fa69..55f947797a26 100644 --- a/src/Umbraco.Web/PropertyEditors/FileUploadConfiguration.cs +++ b/src/Umbraco.Web/PropertyEditors/FileUploadConfiguration.cs @@ -8,7 +8,6 @@ namespace Umbraco.Web.PropertyEditors ///
    public class FileUploadConfiguration : IFileExtensionsConfig { - [ConfigurationField("fileExtensions", "Accepted file extensions", "multivalues")] public List FileExtensions { get; set; } = new List(); } diff --git a/src/Umbraco.Web/PropertyEditors/FileUploadConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/FileUploadConfigurationEditor.cs index 4803254eb762..abbd19a79315 100644 --- a/src/Umbraco.Web/PropertyEditors/FileUploadConfigurationEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/FileUploadConfigurationEditor.cs @@ -1,6 +1,4 @@ -using System.Collections.Generic; -using Umbraco.Core; -using Umbraco.Core.PropertyEditors; +using Umbraco.Core.PropertyEditors; namespace Umbraco.Web.PropertyEditors { diff --git a/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs b/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs index c404638d4213..4c3c6564a5da 100644 --- a/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs +++ b/src/Umbraco.Web/PropertyEditors/MediaPicker3Configuration.cs @@ -1,5 +1,4 @@ using Newtonsoft.Json; -using System.Collections.Generic; using Umbraco.Core; using Umbraco.Core.PropertyEditors; @@ -10,7 +9,6 @@ namespace Umbraco.Web.PropertyEditors ///
    public class MediaPicker3Configuration : IIgnoreUserStartNodesConfig { - [ConfigurationField("filter", "Accepted types", "treesourcetypepicker", Description = "Limit to specific types")] public string Filter { get; set; } diff --git a/src/Umbraco.Web/PropertyEditors/MediaPicker3ConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/MediaPicker3ConfigurationEditor.cs index 268da64eb52b..37063aa1536f 100644 --- a/src/Umbraco.Web/PropertyEditors/MediaPicker3ConfigurationEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MediaPicker3ConfigurationEditor.cs @@ -22,8 +22,6 @@ public MediaPicker3ConfigurationEditor() Field(nameof(MediaPicker3Configuration.Filter)) .Config = new Dictionary { { "itemType", "media" } }; - } - } } diff --git a/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs index 5008c125a288..76f342aff0ad 100644 --- a/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs @@ -17,8 +17,6 @@ namespace Umbraco.Web.PropertyEditors Icon = Constants.Icons.MediaImage)] public class MediaPicker3PropertyEditor : DataEditor { - - /// /// Initializes a new instance of the class. /// @@ -35,7 +33,7 @@ public MediaPicker3PropertyEditor(ILogger logger) internal class MediaPicker3PropertyValueEditor : DataValueEditor { /// - /// Note no FromEditor() and ToEditor() methods + /// Note: no FromEditor() and ToEditor() methods /// We do not want to transform the way the data is stored in the DB and would like to keep a raw JSON string /// public MediaPicker3PropertyValueEditor(DataEditorAttribute attribute) : base(attribute) @@ -47,11 +45,6 @@ public MediaPicker3PropertyValueEditor(DataEditorAttribute attribute) : base(att //{ // throw new NotImplementedException(); //} - } - - - } - } diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs index 5751db2b8599..6826d3b729a9 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs @@ -7,7 +7,6 @@ using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; using Umbraco.Core.PropertyEditors.ValueConverters; -using Umbraco.Web.Models; using Umbraco.Web.PublishedCache; namespace Umbraco.Web.PropertyEditors.ValueConverters @@ -40,7 +39,7 @@ public class MediaPickerWithCropsValueConverter : PropertyValueConverterBase } */ - private IPublishedSnapshotAccessor _publishedSnapshotAccessor; + private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; public MediaPickerWithCropsValueConverter(IPublishedSnapshotAccessor publishedSnapshotAccessor) { From 753a2fd6e8670b3ec28fbb23a831cec927afb380 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Thu, 15 Apr 2021 14:10:26 +0200 Subject: [PATCH 86/90] Add references from MediaPicker3 to media --- .../MediaPicker3PropertyEditor.cs | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs index 76f342aff0ad..526b4830c8cd 100644 --- a/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs @@ -1,6 +1,10 @@ -using Umbraco.Core; +using System.Collections.Generic; +using Newtonsoft.Json; +using Umbraco.Core; using Umbraco.Core.Logging; +using Umbraco.Core.Models.Editors; using Umbraco.Core.PropertyEditors; +using Umbraco.Web.PropertyEditors.ValueConverters; namespace Umbraco.Web.PropertyEditors { @@ -30,7 +34,7 @@ public MediaPicker3PropertyEditor(ILogger logger) protected override IDataValueEditor CreateValueEditor() => new MediaPicker3PropertyValueEditor(Attribute); - internal class MediaPicker3PropertyValueEditor : DataValueEditor + internal class MediaPicker3PropertyValueEditor : DataValueEditor, IDataValueReference { /// /// Note: no FromEditor() and ToEditor() methods @@ -40,11 +44,21 @@ public MediaPicker3PropertyValueEditor(DataEditorAttribute attribute) : base(att { } - // TODO: Perhaps needed?! from IDataValueReference - //public IEnumerable GetReferences(object value) - //{ - // throw new NotImplementedException(); - //} + public IEnumerable GetReferences(object value) + { + var rawJson = value == null ? string.Empty : value is string str ? str : value.ToString(); + + if (rawJson.IsNullOrWhiteSpace()) + yield break; + + var mediaWithCropsDtos = JsonConvert.DeserializeObject(rawJson); + + foreach (var mediaWithCropsDto in mediaWithCropsDtos) + { + yield return new UmbracoEntityReference(GuidUdi.Create(Constants.UdiEntityType.Media, mediaWithCropsDto.MediaKey)); + } + } + } } } From fc7a53015df5e054a55f5c7de220b8e013c02226 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 15 Apr 2021 14:11:51 +0200 Subject: [PATCH 87/90] corrections from various feedback --- .../imaging/umbimagecrop.directive.js | 19 ------- .../mediaentryeditor.controller.js | 6 ++ .../mediaentryeditor/mediaentryeditor.html | 4 +- .../mediapicker/mediapicker.controller.js | 12 ---- .../mediapicker/mediapicker.html | 31 +--------- .../components/mediacard/umb-media-card.less | 3 +- ...umbMediaPicker3PropertyEditor.component.js | 56 ++++++++++--------- src/Umbraco.Web.UI/Umbraco/config/lang/da.xml | 6 +- src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 6 +- .../Umbraco/config/lang/en_us.xml | 6 +- 10 files changed, 49 insertions(+), 100 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js index bf03aac3abd8..199463b9f875 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js @@ -100,17 +100,10 @@ angular.module("umbraco.directives") function onScroll(event) { // cross-browser wheel delta - var event = window.event || event; // old IE support var delta = Math.max(-50, Math.min(50, (event.wheelDelta || -event.detail))); if(sliderRef) { var currentScale =sliderRef.noUiSlider.get(); - /* - if (delta > 0 && scope.dimensions.scale.max.toFixed(3) === currentScale.toFixed(3)) - return; - if (delta < 0 && scope.dimensions.scale.min.toFixed(3) === currentScale.toFixed(3)) - return; - */ var newScale = Math.min(Math.max(currentScale + delta*.001*scope.dimensions.image.ratio, scope.dimensions.scale.min), scope.dimensions.scale.max); sliderRef.noUiSlider.set(newScale); @@ -118,9 +111,6 @@ angular.module("umbraco.directives") scope.dimensions.scale.current = newScale; }); - // for IE - event.returnValue = false; - // for Chrome and Firefox if(event.preventDefault) { event.preventDefault(); } @@ -130,14 +120,6 @@ angular.module("umbraco.directives") //live rendering of viewport and image styles function updateStyles() { - /* - scope.viewportStyle = { - 'top': (parseInt(scope.dimensions.image.top + scope.dimensions.margin.top, 10)) + 'px', - 'left': (parseInt(scope.dimensions.image.left + scope.dimensions.margin.left, 10)) + 'px', - 'width': (parseInt(scope.dimensions.image.width, 10)) + 'px', - 'height': (parseInt(scope.dimensions.image.height, 10)) + 'px' - }; - */ scope.maskStyle = { 'height': (parseInt(scope.dimensions.cropper.height, 10)) + 'px', 'width': (parseInt(scope.dimensions.cropper.width, 10)) + 'px', @@ -152,7 +134,6 @@ angular.module("umbraco.directives") var $viewport = element.find(".viewport"); var $image = element.find("img"); var $overlay = element.find(".overlay"); - //var $container = element.find(".crop-container"); $overlay.bind("focus", function () { $overlay.bind("DOMMouseScroll mousewheel onmousewheel", onScroll); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js index d43e6198d1b7..6c8a0385365e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.controller.js @@ -18,6 +18,8 @@ angular.module("umbraco") vm.submitLabel = data[1]; }); + vm.title = ""; + function init() { updateMedia(); @@ -39,6 +41,10 @@ angular.module("umbraco") vm.loading = false; vm.hasDimensions = false; vm.isCroppable = false; + + localizationService.localize("mediaPicker_editMediaEntryLabel", [vm.media.name, vm.model.documentName]).then(function (data) { + vm.title = data; + }); }, function () { localizationService.localize("mediaPicker_deletedItem").then(function (localized) { vm.media = { diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html index 3a798fd8b414..afa34518999b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html @@ -5,7 +5,7 @@
    - +
    diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js index b39e629fd5b2..029dedf214a0 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js @@ -136,18 +136,6 @@ angular.module("umbraco") function onInit() { - /* - clipboardService.retriveEntriesOfType(clipboardService.TYPES.IMAGE, ["Media"]).forEach(item => { - var media = item.data.media; - if ((($scope.disableFolderSelect || $scope.onlyImages) && media.isFolder) || - ($scope.onlyFolders && !media.isFolder)) { - return; - } - setDefaultData(media); - vm.clipboardImages.push(media); - }); - */ - setTitle(); userService.getCurrentUser().then(function (userData) { diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.html index ca3a070b3d43..d1f0699b1373 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.html @@ -8,9 +8,7 @@ name-locked="true" hide-alias="true" hide-icon="true" - hide-description="true" - navigation="vm.navigation" - on-select-navigation-item="vm.onNavigationChanged(item)"> + hide-description="true"> @@ -147,33 +145,6 @@ -
    diff --git a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less index d1b76102fff3..de3840b4d786 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less +++ b/src/Umbraco.Web.UI.Client/src/views/components/mediacard/umb-media-card.less @@ -142,7 +142,7 @@ umb-media-card { } } - &:hover { + &:hover, &:focus, &:focus-within { .__info { opacity: 1; } @@ -166,6 +166,7 @@ umb-media-card { opacity: 0; transition: opacity 120ms; .__action { + position: relative; display: inline-block; padding: 5px; font-size: 18px; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js index 34cef49d3363..675381d46e3b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker3/umbMediaPicker3PropertyEditor.component.js @@ -39,24 +39,15 @@ var vm = this; vm.loading = true; - vm.currentMediaInFocus = null; - vm.setMediaFocus = function (media) { - if (vm.currentMediaInFocus !== null) { - vm.currentMediaInFocus.focus = false; - } - vm.currentMediaInFocus = media; - media.focus = true; - }; vm.supportCopy = clipboardService.isSupported(); vm.labels = {}; - localizationService.localizeMany(["grid_addElement", "content_createEmpty", "mediaPicker_editMediaEntryLabel"]).then(function (data) { + localizationService.localizeMany(["grid_addElement", "content_createEmpty"]).then(function (data) { vm.labels.grid_addElement = data[0]; vm.labels.content_createEmpty = data[1]; - vm.labels.mediaPicker_editMediaEntryLabel = data[2]; }); vm.$onInit = function() { @@ -276,6 +267,8 @@ setActiveMedia(mediaEntry); + var documentInfo = getDocumentNameAndIcon(); + // make a clone to avoid editing model directly. var mediaEntryClone = Utilities.copy(mediaEntry); @@ -283,7 +276,7 @@ $parentScope: $scope, // pass in a $parentScope, this maintains the scope inheritance in infinite editing $parentForm: vm.propertyForm, // pass in a $parentForm, this maintains the FormController hierarchy with the infinite editing view (if it contains a form) createFlow: options.createFlow === true, - title: vm.labels.mediaPicker_editMediaEntryLabel, + documentName: documentInfo.name, mediaEntry: mediaEntryClone, propertyEditor: { changeMediaFor: changeMediaFor, @@ -311,6 +304,28 @@ editorService.open(mediaEditorModel); } + var getDocumentNameAndIcon = function() { + // get node name + var contentNodeName = "?"; + var contentNodeIcon = null; + if(vm.umbVariantContent) { + contentNodeName = vm.umbVariantContent.editor.content.name; + if(vm.umbVariantContentEditors) { + contentNodeIcon = vm.umbVariantContentEditors.content.icon.split(" ")[0]; + } else if (vm.umbElementEditorContent) { + contentNodeIcon = vm.umbElementEditorContent.model.documentType.icon.split(" ")[0]; + } + } else if (vm.umbElementEditorContent) { + contentNodeName = vm.umbElementEditorContent.model.documentType.name; + contentNodeIcon = vm.umbElementEditorContent.model.documentType.icon.split(" ")[0]; + } + + return { + name: contentNodeName, + icon: contentNodeIcon + } + } + var requestCopyAllMedias = function() { var mediaKeys = vm.model.value.map(x => x.mediaKey) entityResource.getByIds(mediaKeys, "Media").then(function (entities) { @@ -321,23 +336,10 @@ // remove duplicate aliases aliases = aliases.filter((item, index) => aliases.indexOf(item) === index); - // get node name - var contentNodeName = "?"; - var contentNodeIcon = null; - if(vm.umbVariantContent) { - contentNodeName = vm.umbVariantContent.editor.content.name; - if(vm.umbVariantContentEditors) { - contentNodeIcon = vm.umbVariantContentEditors.content.icon.split(" ")[0]; - } else if (vm.umbElementEditorContent) { - contentNodeIcon = vm.umbElementEditorContent.model.documentType.icon.split(" ")[0]; - } - } else if (vm.umbElementEditorContent) { - contentNodeName = vm.umbElementEditorContent.model.documentType.name; - contentNodeIcon = vm.umbElementEditorContent.model.documentType.icon.split(" ")[0]; - } + var documentInfo = getDocumentNameAndIcon(); - localizationService.localize("clipboard_labelForArrayOfItemsFrom", [vm.model.label, contentNodeName]).then(function(localizedLabel) { - clipboardService.copyArray(clipboardService.TYPES.MEDIA, aliases, vm.model.value, localizedLabel, contentNodeIcon || "icon-thumbnail-list", vm.model.id); + localizationService.localize("clipboard_labelForArrayOfItemsFrom", [vm.model.label, documentInfo.name]).then(function(localizedLabel) { + clipboardService.copyArray(clipboardService.TYPES.MEDIA, aliases, vm.model.value, localizedLabel, documentInfo.icon || "icon-thumbnail-list", vm.model.id); }); }); } diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml index 4d98ee4fa2d1..4abcdf8a40bf 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml @@ -1100,10 +1100,10 @@ Mange hilsner fra Umbraco robotten Du har valgt et medie som er slettet eller lagt i papirkurven Du har valgt medier som er slettede eller lagt i papirkurven Slettet - Åben medie - Udskift mediet + Åben i mediebiblioteket + Skift medie Nulstil medie beskæring - Rediger medie tilretninger + Rediger %0% på %1% Annuller indsættelse? Du har foretaget ændringer til bruge af dette media. Er du sikker på at du vil annullere? diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml index efa449c9958c..27220d357ae2 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml @@ -1353,10 +1353,10 @@ To manage your website, simply open the Umbraco backoffice and start adding cont You have picked a media item currently deleted or in the recycle bin You have picked media items currently deleted or in the recycle bin Trashed - Open media - Replace media + Open item in Media + Change Media Item Reset media crop - Edit media adjustments + Edit %0% on %1% Discard creation? You have made changes to this content. Are you sure you want to discard them? 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 ac0b1ce90e2a..590a24839347 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml @@ -1363,10 +1363,10 @@ To manage your website, simply open the Umbraco backoffice and start adding cont You have picked a media item currently deleted or in the recycle bin You have picked media items currently deleted or in the recycle bin Trashed - Open media - Replace media + Open in Media Library + Change Media Item Reset media crop - Edit media adjustments + Edit %0% on %1% Discard creation? You have made changes to this content. Are you sure you want to discard them? From 5aa62183e8ce32f49cb17df75c7f48f115c44c24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 20 Apr 2021 15:21:43 +0200 Subject: [PATCH 88/90] remove comment --- .../MediaPickerWithCropsValueConverter.cs | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs index 6826d3b729a9..f9b2ad75e169 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerWithCropsValueConverter.cs @@ -14,30 +14,6 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters [DefaultPropertyValueConverter] public class MediaPickerWithCropsValueConverter : PropertyValueConverterBase { - // JSON is an array of the following JSON - /* - "key": "d1e9c080-5aef-48f6-9b37-47e84de7ad8b", - "mediaKey": "80e2507b-c5f9-4c8a-ab14-5dae717a49b3", - "crops": [ - { - "alias": "square", - "label": "Square", - "width": 200, - "height": 200, - "coordinates": { - "x1": 0.4489663034789123, - "y1": 0.7192332259400422, - "x2": 0.39324276949939146, - "y2": 0 - } - }, - ... - ] - "focalPoint": { - "left": 0.846, - "top": 0.7964285714285714 - } - */ private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; From 69372dc5d76b873abe796540a7ff792f7b95f8b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 20 Apr 2021 15:25:47 +0200 Subject: [PATCH 89/90] correct wording --- src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml index 27220d357ae2..cbb6902d744b 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml @@ -1353,7 +1353,7 @@ To manage your website, simply open the Umbraco backoffice and start adding cont You have picked a media item currently deleted or in the recycle bin You have picked media items currently deleted or in the recycle bin Trashed - Open item in Media + Open in Media Library Change Media Item Reset media crop Edit %0% on %1% From 98bede746fe561ce4f77519e148e7fe438f74b41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 20 Apr 2021 15:27:15 +0200 Subject: [PATCH 90/90] use windowResizeListener --- .../directives/components/imaging/umbimagecrop.directive.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js index 199463b9f875..744e4280db74 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js @@ -386,11 +386,11 @@ angular.module("umbraco.directives") }); }); - $window.addEventListener("resize", onViewportSizeChanged) + windowResizeListener.register(onViewportSizeChanged); scope.$on('$destroy', function () { $image.prop("src", ""); - $window.removeEventListener("resize", onViewportSizeChanged) + windowResizeListener.unregister(onViewportSizeChanged); unsubscribe.forEach(u => u()); }) }