diff --git a/src/Umbraco.Core/Compose/AuditEventsComponent.cs b/src/Umbraco.Core/Compose/AuditEventsComponent.cs index 453fd6314a..033b46c13f 100644 --- a/src/Umbraco.Core/Compose/AuditEventsComponent.cs +++ b/src/Umbraco.Core/Compose/AuditEventsComponent.cs @@ -68,7 +68,7 @@ namespace Umbraco.Core.Compose { var httpContext = HttpContext.Current == null ? (HttpContextBase) null : new HttpContextWrapper(HttpContext.Current); var ip = httpContext.GetCurrentRequestIpAddress(); - if (ip.ToLowerInvariant().StartsWith("unknown")) ip = ""; + if (ip == null || ip.ToLowerInvariant().StartsWith("unknown")) ip = ""; return ip; } } diff --git a/src/Umbraco.Core/Manifest/ManifestContentAppFactory.cs b/src/Umbraco.Core/Manifest/ManifestContentAppFactory.cs index 788310d7a1..e0b63d1069 100644 --- a/src/Umbraco.Core/Manifest/ManifestContentAppFactory.cs +++ b/src/Umbraco.Core/Manifest/ManifestContentAppFactory.cs @@ -62,6 +62,10 @@ namespace Umbraco.Core.Manifest partA = "member"; partB = member.ContentType.Alias; break; + case IContentType contentType: + partA = "contentType"; + partB = contentType.Alias; + break; default: return null; diff --git a/src/Umbraco.Core/Models/PublishedContent/IndexedArrayItem.cs b/src/Umbraco.Core/Models/PublishedContent/IndexedArrayItem.cs index 5dc42cc542..f7d13fcf90 100644 --- a/src/Umbraco.Core/Models/PublishedContent/IndexedArrayItem.cs +++ b/src/Umbraco.Core/Models/PublishedContent/IndexedArrayItem.cs @@ -2,168 +2,441 @@ namespace Umbraco.Core.Models.PublishedContent { + /// + /// Represents an item in an array that stores its own index and the total count. + /// + /// The type of the content. public class IndexedArrayItem { + /// + /// Initializes a new instance of the class. + /// + /// The content. + /// The index. public IndexedArrayItem(TContent content, int index) { Content = content; Index = index; } + /// + /// Gets the content. + /// + /// + /// The content. + /// public TContent Content { get; } + /// + /// Gets the index. + /// + /// + /// The index. + /// public int Index { get; } + /// + /// Gets the total count. + /// + /// + /// The total count. + /// public int TotalCount { get; internal set; } + /// + /// Determines whether this item is the first. + /// + /// + /// true if this item is the first; otherwise, false. + /// public bool IsFirst() { return Index == 0; } + /// + /// If this item is the first, the HTML encoded will be returned; otherwise, . + /// + /// The value if true. + /// + /// The HTML encoded value. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public HtmlString IsFirst(string valueIfTrue) { return IsFirst(valueIfTrue, string.Empty); } + /// + /// If this item is the first, the HTML encoded will be returned; otherwise, . + /// + /// The value if true. + /// The value if false. + /// + /// The HTML encoded value. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public HtmlString IsFirst(string valueIfTrue, string valueIfFalse) { - return new HtmlString(IsFirst() ? valueIfTrue : valueIfFalse); + return new HtmlString(HttpUtility.HtmlEncode(IsFirst() ? valueIfTrue : valueIfFalse)); } + /// + /// Determines whether this item is not the first. + /// + /// + /// true if this item is not the first; otherwise, false. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public bool IsNotFirst() { return IsFirst() == false; } + /// + /// If this item is not the first, the HTML encoded will be returned; otherwise, . + /// + /// The value if true. + /// + /// The HTML encoded value. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public HtmlString IsNotFirst(string valueIfTrue) { return IsNotFirst(valueIfTrue, string.Empty); } + /// + /// If this item is not the first, the HTML encoded will be returned; otherwise, . + /// + /// The value if true. + /// The value if false. + /// + /// The HTML encoded value. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public HtmlString IsNotFirst(string valueIfTrue, string valueIfFalse) { - return new HtmlString(IsNotFirst() ? valueIfTrue : valueIfFalse); + return new HtmlString(HttpUtility.HtmlEncode(IsNotFirst() ? valueIfTrue : valueIfFalse)); } + /// + /// Determines whether this item is at the specified . + /// + /// The index. + /// + /// true if this item is at the specified ; otherwise, false. + /// public bool IsIndex(int index) { return Index == index; } + /// + /// If this item is at the specified , the HTML encoded will be returned; otherwise, . + /// + /// The index. + /// The value if true. + /// + /// The HTML encoded value. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public HtmlString IsIndex(int index, string valueIfTrue) { return IsIndex(index, valueIfTrue, string.Empty); } + /// + /// If this item is at the specified , the HTML encoded will be returned; otherwise, . + /// + /// The index. + /// The value if true. + /// The value if false. + /// + /// The HTML encoded value. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public HtmlString IsIndex(int index, string valueIfTrue, string valueIfFalse) { - return new HtmlString(IsIndex(index) ? valueIfTrue : valueIfFalse); + return new HtmlString(HttpUtility.HtmlEncode(IsIndex(index) ? valueIfTrue : valueIfFalse)); } + /// + /// Determines whether this item is at an index that can be divided by the specified . + /// + /// The modulus. + /// + /// true if this item is at an index that can be divided by the specified ; otherwise, false. + /// public bool IsModZero(int modulus) { return Index % modulus == 0; } + /// + /// If this item is at an index that can be divided by the specified , the HTML encoded will be returned; otherwise, . + /// + /// The modulus. + /// The value if true. + /// + /// The HTML encoded value. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public HtmlString IsModZero(int modulus, string valueIfTrue) { return IsModZero(modulus, valueIfTrue, string.Empty); } + /// + /// If this item is at an index that can be divided by the specified , the HTML encoded will be returned; otherwise, . + /// + /// The modulus. + /// The value if true. + /// The value if false. + /// + /// The HTML encoded value. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public HtmlString IsModZero(int modulus, string valueIfTrue, string valueIfFalse) { - return new HtmlString(IsModZero(modulus) ? valueIfTrue : valueIfFalse); + return new HtmlString(HttpUtility.HtmlEncode(IsModZero(modulus) ? valueIfTrue : valueIfFalse)); } + /// + /// Determines whether this item is not at an index that can be divided by the specified . + /// + /// The modulus. + /// + /// true if this item is not at an index that can be divided by the specified ; otherwise, false. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public bool IsNotModZero(int modulus) { return IsModZero(modulus) == false; } + /// + /// If this item is not at an index that can be divided by the specified , the HTML encoded will be returned; otherwise, . + /// + /// The modulus. + /// The value if true. + /// + /// The HTML encoded value. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public HtmlString IsNotModZero(int modulus, string valueIfTrue) { return IsNotModZero(modulus, valueIfTrue, string.Empty); } + /// + /// If this item is not at an index that can be divided by the specified , the HTML encoded will be returned; otherwise, . + /// + /// The modulus. + /// The value if true. + /// The value if false. + /// + /// The HTML encoded value. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public HtmlString IsNotModZero(int modulus, string valueIfTrue, string valueIfFalse) { - return new HtmlString(IsNotModZero(modulus) ? valueIfTrue : valueIfFalse); + return new HtmlString(HttpUtility.HtmlEncode(IsNotModZero(modulus) ? valueIfTrue : valueIfFalse)); } + /// + /// Determines whether this item is not at the specified . + /// + /// The index. + /// + /// true if this item is not at the specified ; otherwise, false. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public bool IsNotIndex(int index) { return IsIndex(index) == false; } + /// + /// If this item is not at the specified , the HTML encoded will be returned; otherwise, . + /// + /// The index. + /// The value if true. + /// + /// The HTML encoded value. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public HtmlString IsNotIndex(int index, string valueIfTrue) { return IsNotIndex(index, valueIfTrue, string.Empty); } + /// + /// If this item is at the specified , the HTML encoded will be returned; otherwise, . + /// + /// The index. + /// The value if true. + /// The value if false. + /// + /// The HTML encoded value. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public HtmlString IsNotIndex(int index, string valueIfTrue, string valueIfFalse) { - return new HtmlString(IsNotIndex(index) ? valueIfTrue : valueIfFalse); + return new HtmlString(HttpUtility.HtmlEncode(IsNotIndex(index) ? valueIfTrue : valueIfFalse)); } + /// + /// Determines whether this item is the last. + /// + /// + /// true if this item is the last; otherwise, false. + /// public bool IsLast() { return Index == TotalCount - 1; } + /// + /// If this item is the last, the HTML encoded will be returned; otherwise, . + /// + /// The value if true. + /// + /// The HTML encoded value. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public HtmlString IsLast(string valueIfTrue) { return IsLast(valueIfTrue, string.Empty); } + /// + /// If this item is the last, the HTML encoded will be returned; otherwise, . + /// + /// The value if true. + /// The value if false. + /// + /// The HTML encoded value. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public HtmlString IsLast(string valueIfTrue, string valueIfFalse) { - return new HtmlString(IsLast() ? valueIfTrue : valueIfFalse); + return new HtmlString(HttpUtility.HtmlEncode(IsLast() ? valueIfTrue : valueIfFalse)); } + /// + /// Determines whether this item is not the last. + /// + /// + /// true if this item is not the last; otherwise, false. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public bool IsNotLast() { return IsLast() == false; } + /// + /// If this item is not the last, the HTML encoded will be returned; otherwise, . + /// + /// The value if true. + /// + /// The HTML encoded value. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public HtmlString IsNotLast(string valueIfTrue) { return IsNotLast(valueIfTrue, string.Empty); } + /// + /// If this item is not the last, the HTML encoded will be returned; otherwise, . + /// + /// The value if true. + /// The value if false. + /// + /// The HTML encoded value. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public HtmlString IsNotLast(string valueIfTrue, string valueIfFalse) { - return new HtmlString(IsNotLast() ? valueIfTrue : valueIfFalse); + return new HtmlString(HttpUtility.HtmlEncode(IsNotLast() ? valueIfTrue : valueIfFalse)); } + /// + /// Determines whether this item is at an even index. + /// + /// + /// true if this item is at an even index; otherwise, false. + /// public bool IsEven() { return Index % 2 == 0; } + /// + /// If this item is at an even index, the HTML encoded will be returned; otherwise, . + /// + /// The value if true. + /// + /// The HTML encoded value. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public HtmlString IsEven(string valueIfTrue) { return IsEven(valueIfTrue, string.Empty); } + /// + /// If this item is at an even index, the HTML encoded will be returned; otherwise, . + /// + /// The value if true. + /// The value if false. + /// + /// The HTML encoded value. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public HtmlString IsEven(string valueIfTrue, string valueIfFalse) { - return new HtmlString(IsEven() ? valueIfTrue : valueIfFalse); + return new HtmlString(HttpUtility.HtmlEncode(IsEven() ? valueIfTrue : valueIfFalse)); } + /// + /// Determines whether this item is at an odd index. + /// + /// + /// true if this item is at an odd index; otherwise, false. + /// public bool IsOdd() { return Index % 2 == 1; } + /// + /// If this item is at an odd index, the HTML encoded will be returned; otherwise, . + /// + /// The value if true. + /// + /// The HTML encoded value. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public HtmlString IsOdd(string valueIfTrue) { return IsOdd(valueIfTrue, string.Empty); } + /// + /// If this item is at an odd index, the HTML encoded will be returned; otherwise, . + /// + /// The value if true. + /// The value if false. + /// + /// The HTML encoded value. + /// + // TODO: This method should be removed or moved to an extension method on HtmlHelper. public HtmlString IsOdd(string valueIfTrue, string valueIfFalse) { - return new HtmlString(IsOdd() ? valueIfTrue : valueIfFalse); + return new HtmlString(HttpUtility.HtmlEncode(IsOdd() ? valueIfTrue : valueIfFalse)); } } } diff --git a/src/Umbraco.Web.UI.Client/lib/bootstrap/less/type.less b/src/Umbraco.Web.UI.Client/lib/bootstrap/less/type.less index 3f93deaf56..414ab10ba8 100644 --- a/src/Umbraco.Web.UI.Client/lib/bootstrap/less/type.less +++ b/src/Umbraco.Web.UI.Client/lib/bootstrap/less/type.less @@ -56,7 +56,7 @@ a.text-success:focus { color: darken(@successText, 10%); } // Headings // ------------------------- -h1, h2, h3, h4, h5, h6 { +h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6 { margin: (@baseLineHeight / 2) 0; font-family: @headingsFontFamily; font-weight: @headingsFontWeight; @@ -70,21 +70,21 @@ h1, h2, h3, h4, h5, h6 { } } -h1, -h2, -h3 { line-height: @baseLineHeight * 2; } +h1, .h1, +h2, .h2, +h3, .h3 { line-height: @baseLineHeight * 2; } -h1 { font-size: @baseFontSize * 2.75; } // ~38px -h2 { font-size: @baseFontSize * 2.25; } // ~32px -h3 { font-size: @baseFontSize * 1.75; } // ~24px -h4 { font-size: @baseFontSize * 1.25; } // ~18px -h5 { font-size: @baseFontSize; } -h6 { font-size: @baseFontSize * 0.85; } // ~12px +h1, .h1 { font-size: @baseFontSize * 2.75; } // ~38px +h2, .h2 { font-size: @baseFontSize * 2.25; } // ~32px +h3, .h3 { font-size: @baseFontSize * 1.75; } // ~24px +h4, .h4 { font-size: @baseFontSize * 1.25; } // ~18px +h5, .h5 { font-size: @baseFontSize; } +h6, .h6 { font-size: @baseFontSize * 0.85; } // ~12px -h1 small { font-size: @baseFontSize * 1.75; } // ~24px -h2 small { font-size: @baseFontSize * 1.25; } // ~18px -h3 small { font-size: @baseFontSize; } -h4 small { font-size: @baseFontSize; } +h1 small, .h1 small { font-size: @baseFontSize * 1.75; } // ~24px +h2 small, .h2 small { font-size: @baseFontSize * 1.25; } // ~18px +h3 small, .h3 small { font-size: @baseFontSize; } +h4 small, .h4 small { font-size: @baseFontSize; } // Page header diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 1b0af95e13..0d6db9118f 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -11,7 +11,7 @@ }, "dependencies": { "ace-builds": "1.4.2", - "angular": "1.7.9", + "angular": "1.8.0", "angular-animate": "1.7.5", "angular-aria": "1.7.9", "angular-chart.js": "^1.1.1", @@ -32,13 +32,13 @@ "diff": "3.5.0", "flatpickr": "4.5.2", "font-awesome": "4.7.0", - "jquery": "^3.4.1", + "jquery": "^3.5.1", "jquery-ui-dist": "1.12.1", "jquery-ui-touch-punch": "0.2.3", "lazyload-js": "1.0.0", "moment": "2.22.2", "ng-file-upload": "12.2.13", - "nouislider": "14.1.1", + "nouislider": "14.4.0", "npm": "^6.14.0", "signalr": "2.4.0", "spectrum-colorpicker": "1.8.0", diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbcontextmenu.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbcontextmenu.directive.js index 8d1420b73e..32034818a3 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbcontextmenu.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbcontextmenu.directive.js @@ -1,5 +1,5 @@ angular.module("umbraco.directives") -.directive('umbContextMenu', function (navigationService, keyboardService) { +.directive('umbContextMenu', function (navigationService, keyboardService, backdropService) { return { scope: { menuDialogTitle: "@", @@ -30,7 +30,6 @@ angular.module("umbraco.directives") scope.$on('$destroy', function () { keyboardService.unbind("esc"); }); - } }; }); diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umblogin.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umblogin.directive.js index 6dd740e08b..c2b298ad24 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umblogin.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umblogin.directive.js @@ -274,6 +274,7 @@ vm.showEmailResetConfirmation = false; if (vm.requestPasswordResetForm.$invalid) { + vm.errorMsg = 'Email address cannot be empty'; return; } diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour.directive.js index 1a9c3c771a..514e26f38f 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour.directive.js @@ -11,7 +11,7 @@ You can easily add you own tours to the Help-drawer or show and start tours from anywhere in the Umbraco backoffice. To see a real world example of a custom tour implementation, install The Starter Kit in Umbraco 7.8

Extending the help drawer with custom tours

-The easiet way to add new tours to Umbraco is through the Help-drawer. All it requires is a my-tour.json file. +The easiet way to add new tours to Umbraco is through the Help-drawer. All it requires is a my-tour.json file. Place the file in App_Plugins/{MyPackage}/backoffice/tours/{my-tour}.json and it will automatically be picked up by Umbraco and shown in the Help-drawer. diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbbutton.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbbutton.directive.js index 56416e3544..dc012945dd 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbbutton.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbbutton.directive.js @@ -99,7 +99,7 @@ Use this directive to render an umbraco button. The directive can be used to gen alias: "@?", addEllipsis: "@?", showCaret: "@?", - autoFocus: "@?", + autoFocus: " { editor.moveRight = false; @@ -32,14 +41,20 @@ } function removeEditor(editor) { - editor.moveRight = true; editor.animating = true; setTimeout(removeEditorFromDOM.bind(this, editor), 400); updateEditors(-1); - + + if(scope.editors.length === 1){ + if(isLeftColumnAbove){ + $('#leftcolumn').addClass(aboveBackDropCssClass); + } + + isLeftColumnAbove = false; + } } function revealEditorContent(editor) { @@ -57,7 +72,7 @@ if (index !== -1) { scope.editors.splice(index, 1); } - + updateEditors(); scope.$digest(); diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/property/umbpropertyeditor.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/property/umbpropertyeditor.directive.js index 5eac7e5e24..8aaa4ff5ec 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/property/umbpropertyeditor.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/property/umbpropertyeditor.directive.js @@ -33,8 +33,15 @@ function umbPropEditor(umbPropEditorHelper) { scope.model.alias = Math.random().toString(36).slice(2); } - scope.propertyEditorView = umbPropEditorHelper.getViewPath(scope.model.view, scope.isPreValue); - + var unbindWatcher = scope.$watch("model.view", + function() { + scope.propertyEditorView = umbPropEditorHelper.getViewPath(scope.model.view, scope.isPreValue); + } + ); + + scope.$on("$destroy", function () { + unbindWatcher(); + }); } }; }; diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbcontextdialog/umbcontextdialog.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbcontextdialog/umbcontextdialog.directive.js index 904a2ce8ca..3b753a371c 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbcontextdialog/umbcontextdialog.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbcontextdialog/umbcontextdialog.directive.js @@ -1,7 +1,7 @@ (function() { 'use strict'; - function UmbContextDialog(navigationService, keyboardService, localizationService, overlayService) { + function UmbContextDialog(navigationService, keyboardService, localizationService, overlayService, backdropService) { function link($scope) { @@ -23,6 +23,7 @@ }); function hide() { + if ($scope.dialog.confirmDiscardChanges) { localizationService.localizeMany(["prompt_unsavedChanges", "prompt_unsavedChangesWarning", "prompt_discardChanges", "prompt_stay"]).then( function (values) { diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js index 5a7da80eff..0ccaf7b05c 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js @@ -3,7 +3,7 @@ * @name umbraco.directives.directive:umbTree * @restrict E **/ -function umbTreeDirective($q, $rootScope, treeService, notificationsService, userService) { +function umbTreeDirective($q, $rootScope, treeService, notificationsService, userService, backdropService) { return { restrict: 'E', @@ -319,6 +319,18 @@ function umbTreeDirective($q, $rootScope, treeService, notificationsService, use } } + // Close any potential backdrop and remove the #leftcolumn modifier class + function closeBackdrop() { + var aboveClass = 'above-backdrop'; + var leftColumn = $('#leftcolumn'); + var isLeftColumnOnTop = leftColumn.hasClass(aboveClass); + + if(isLeftColumnOnTop){ + backdropService.close(); + leftColumn.removeClass(aboveClass); + } + } + /** Returns the css classses assigned to the node (div element) */ $scope.getNodeCssClass = function (node) { if (!node) { @@ -368,6 +380,8 @@ function umbTreeDirective($q, $rootScope, treeService, notificationsService, use */ $scope.select = function (n, ev) { + closeBackdrop() + if (n.metaData && n.metaData.noAccess === true) { ev.preventDefault(); return; diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js index 0a6eeb8835..8767de446a 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js @@ -18,7 +18,7 @@ */ angular.module("umbraco.directives") - .directive('umbTreeItem', function(treeService, $timeout, localizationService, eventsService, appState) { + .directive('umbTreeItem', function(treeService, $timeout, localizationService, eventsService, appState, navigationService) { return { restrict: 'E', replace: true, diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umblistviewsettings.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umblistviewsettings.directive.js index 63c8427bfb..318ffebd1b 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umblistviewsettings.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umblistviewsettings.directive.js @@ -12,16 +12,18 @@ /* ---------- INIT ---------- */ + const setDataType = (dataType) => { + scope.dataType = dataType; + listViewPrevalueHelper.setPrevalues(dataType.preValues); + } + const activate = () => { if (scope.enableListView) { dataTypeResource.getByName(scope.listViewName) .then(dataType => { - - scope.dataType = dataType; - - listViewPrevalueHelper.setPrevalues(dataType.preValues); + setDataType(dataType); scope.customListViewCreated = checkForCustomListView(); }); @@ -64,7 +66,7 @@ dataTypeResource.createCustomListView(scope.modelAlias).then(dataType => { // store data type - scope.dataType = dataType; + setDataType(dataType); // set list view name on scope scope.listViewName = dataType.name; @@ -95,7 +97,7 @@ .then(defaultDataType => { // store data type - scope.dataType = defaultDataType; + setDataType(defaultDataType); // change state to default list view scope.customListViewCreated = false; diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbrangeslider.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbrangeslider.directive.js index 21a1f181a6..e467522c84 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbrangeslider.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbrangeslider.directive.js @@ -118,6 +118,8 @@ For extra details about options and events take a look here: https://refreshless // create new slider noUiSlider.create(sliderInstance, options); + mergeTooltips(sliderInstance, 15, ' - '); + if (ctrl.onSetup) { ctrl.onSetup({ slider: sliderInstance @@ -200,6 +202,91 @@ For extra details about options and events take a look here: https://refreshless } } + // Merging overlapping tooltips: https://refreshless.com/nouislider/examples/#section-merging-tooltips + + /** + * @param slider HtmlElement with an initialized slider + * @param threshold Minimum proximity (in percentages) to merge tooltips + * @param separator String joining tooltips + */ + function mergeTooltips(slider, threshold, separator) { + + var textIsRtl = getComputedStyle(slider).direction === 'rtl'; + var isRtl = slider.noUiSlider.options.direction === 'rtl'; + var isVertical = slider.noUiSlider.options.orientation === 'vertical'; + var tooltips = slider.noUiSlider.getTooltips(); + var origins = slider.noUiSlider.getOrigins(); + + // Move tooltips into the origin element. The default stylesheet handles this. + tooltips.forEach(function (tooltip, index) { + if (tooltip) { + origins[index].appendChild(tooltip); + } + }); + + slider.noUiSlider.on('update', function (values, handle, unencoded, tap, positions) { + + var pools = [[]]; + var poolPositions = [[]]; + var poolValues = [[]]; + var atPool = 0; + + // Assign the first tooltip to the first pool, if the tooltip is configured + if (tooltips[0]) { + pools[0][0] = 0; + poolPositions[0][0] = positions[0]; + poolValues[0][0] = values[0]; + } + + for (var i = 1; i < positions.length; i++) { + if (!tooltips[i] || (positions[i] - positions[i - 1]) > threshold) { + atPool++; + pools[atPool] = []; + poolValues[atPool] = []; + poolPositions[atPool] = []; + } + + if (tooltips[i]) { + pools[atPool].push(i); + poolValues[atPool].push(values[i]); + poolPositions[atPool].push(positions[i]); + } + } + + pools.forEach(function (pool, poolIndex) { + var handlesInPool = pool.length; + + for (var j = 0; j < handlesInPool; j++) { + var handleNumber = pool[j]; + + if (j === handlesInPool - 1) { + var offset = 0; + + poolPositions[poolIndex].forEach(function (value) { + offset += 1000 - 10 * value; + }); + + var direction = isVertical ? 'bottom' : 'right'; + var last = isRtl ? 0 : handlesInPool - 1; + var lastOffset = 1000 - 10 * poolPositions[poolIndex][last]; + offset = (textIsRtl && !isVertical ? 100 : 0) + (offset / handlesInPool) - lastOffset; + + // Filter to unique values + var tooltipValues = poolValues[poolIndex].filter((v, i, a) => a.indexOf(v) === i); + + // Center this tooltip over the affected handles + tooltips[handleNumber].innerHTML = tooltipValues.join(separator); + tooltips[handleNumber].style.display = 'block'; + tooltips[handleNumber].style[direction] = offset + '%'; + } else { + // Hide this tooltip + tooltips[handleNumber].style.display = 'none'; + } + } + }); + }); + } + } angular.module('umbraco.directives').component('umbRangeSlider', umbRangeSlider); diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfiledropzone.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfiledropzone.directive.js index 3fb1b3eb36..7f405eb28c 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfiledropzone.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfiledropzone.directive.js @@ -20,7 +20,7 @@ TODO angular.module("umbraco.directives") .directive('umbFileDropzone', - function($timeout, Upload, localizationService, umbRequestHelper) { + function ($timeout, Upload, localizationService, umbRequestHelper, overlayService) { return { restrict: 'E', replace: true, @@ -119,9 +119,8 @@ angular.module("umbraco.directives") //auto-clear the done queue after 3 secs var currentLength = scope.done.length; $timeout(function() { - scope.done.splice(0, currentLength); - }, - 3000); + scope.done.splice(0, currentLength); + }, 3000); } } @@ -197,30 +196,34 @@ angular.module("umbraco.directives") } function _chooseMediaType() { - scope.mediatypepickerOverlay = { - view: "mediatypepicker", - title: "Choose media type", - acceptedMediatypes: scope.acceptedMediatypes, - hideSubmitButton: true, - show: true, - submit: function(model) { - scope.contentTypeAlias = model.selectedType.alias; - scope.mediatypepickerOverlay.show = false; - scope.mediatypepickerOverlay = null; - _processQueueItem(); - }, - close: function(oldModel) { - scope.queue.map(function(file) { + const dialog = { + view: "itempicker", + filter: scope.acceptedMediatypes.length > 15, + availableItems: scope.acceptedMediatypes, + submit: function (model) { + scope.contentTypeAlias = model.selectedItem.alias; + _processQueueItem(); + + overlayService.close(); + }, + close: function () { + + scope.queue.map(function (file) { file.uploadStatus = "error"; file.serverErrorMessage = "Cannot upload this file, no mediatype selected"; scope.rejected.push(file); }); scope.queue = []; - scope.mediatypepickerOverlay.show = false; - scope.mediatypepickerOverlay = null; + + overlayService.close(); } }; + + localizationService.localize("defaultdialogs_selectMediaType").then(value => { + dialog.title = value; + overlayService.open(dialog); + }); } scope.handleFiles = function(files, event) { diff --git a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js index da784a1f9e..f903c44ad5 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js @@ -13,7 +13,7 @@ * Section navigation and search, and maintain their state for the entire application lifetime * */ -function navigationService($routeParams, $location, $q, $injector, eventsService, umbModelMapper, treeService, appState) { +function navigationService($routeParams, $location, $q, $injector, eventsService, umbModelMapper, treeService, appState, backdropService) { //the promise that will be resolved when the navigation is ready var navReadyPromise = $q.defer(); @@ -26,7 +26,10 @@ function navigationService($routeParams, $location, $q, $injector, eventsService navReadyPromise.resolve(mainTreeApi); }); - + eventsService.on('appState.backdrop', function(e, args){ + var element = $(args.element); + element.addClass('above-backdrop'); + }); //A list of query strings defined that when changed will not cause a reload of the route var nonRoutingQueryStrings = ["mculture", "cculture", "csegment", "lq", "sr"]; @@ -113,6 +116,17 @@ function navigationService($routeParams, $location, $q, $injector, eventsService } } + function closeBackdrop() { + var aboveClass = 'above-backdrop'; + var leftColumn = $('#leftcolumn'); + var isLeftColumnOnTop = leftColumn.hasClass(aboveClass); + + if(isLeftColumnOnTop){ + backdropService.close(); + leftColumn.removeClass(aboveClass); + } + } + var service = { /** @@ -410,12 +424,15 @@ function navigationService($routeParams, $location, $q, $injector, eventsService * @param {Event} event the click event triggering the method, passed from the DOM element */ showMenu: function (args) { - var self = this; + var backDropOptions = { + 'element': $('#leftcolumn')[0] + }; + return treeService.getMenu({ treeNode: args.node }) .then(function (data) { - + backdropService.open(backDropOptions); //check for a default //NOTE: event will be undefined when a call to hideDialog is made so it won't re-load the default again. // but perhaps there's a better way to deal with with an additional parameter in the args ? it works though. @@ -466,6 +483,7 @@ function navigationService($routeParams, $location, $q, $injector, eventsService appState.setMenuState("currentNode", null); appState.setMenuState("menuActions", []); setMode("tree"); + closeBackdrop(); }, /** Executes a given menu action */ @@ -650,6 +668,7 @@ function navigationService($routeParams, $location, $q, $injector, eventsService if (showMenu) { this.showMenu({ skipDefault: true, node: appState.getMenuState("currentNode") }); } else { + closeBackdrop(); setMode("default"); } }, @@ -685,6 +704,7 @@ function navigationService($routeParams, $location, $q, $injector, eventsService */ hideNavigation: function () { appState.setMenuState("menuActions", []); + closeBackdrop(); setMode("default"); } }; diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js index 66f0b110bf..41f240d3af 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js @@ -133,7 +133,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s else if (rule.selector[0] !== "." && rule.selector.indexOf(".") > -1) { var split = rule.selector.split("."); r.block = split[0]; - r.classes = rule.selector.substring(rule.selector.indexOf(".") + 1).replace(".", " "); + r.classes = rule.selector.substring(rule.selector.indexOf(".") + 1).replace(/\./g, " "); } else if (rule.selector[0] != "#" && rule.selector.indexOf("#") > -1) { var split = rule.selector.split("#"); diff --git a/src/Umbraco.Web.UI.Client/src/less/application/grid.less b/src/Umbraco.Web.UI.Client/src/less/application/grid.less index 0c6e790272..9e91da4792 100644 --- a/src/Umbraco.Web.UI.Client/src/less/application/grid.less +++ b/src/Umbraco.Web.UI.Client/src/less/application/grid.less @@ -80,6 +80,10 @@ body.umb-drawer-is-visible #mainwrapper{ float: left; position: absolute; top: 0; + + &.above-backdrop{ + z-index: 7501; + } } #navigation { diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-group-builder.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-group-builder.less index ac7a2c63ce..6eded29b8b 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-group-builder.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-group-builder.less @@ -527,7 +527,6 @@ input.umb-group-builder__group-sort-value { text-align: left; display: flex; align-items: center; - max-width: calc(100% - 48px); min-height: 80px; color: @ui-action-discreet-type; diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-property-file-upload.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-property-file-upload.less index 9550acfb1b..39b2f4002e 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-property-file-upload.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-property-file-upload.less @@ -1,7 +1,7 @@ .umb-property-file-upload { + .umb-property-editor--limit-width(); .umb-upload-button-big { - max-width: (@propertyEditorLimitedWidth - 40); display: block; padding: 20px; opacity: 1; diff --git a/src/Umbraco.Web.UI.Client/src/less/main.less b/src/Umbraco.Web.UI.Client/src/less/main.less index b34f313435..57d867ccd5 100644 --- a/src/Umbraco.Web.UI.Client/src/less/main.less +++ b/src/Umbraco.Web.UI.Client/src/less/main.less @@ -26,19 +26,29 @@ color: @gray-7; } -h5{ +h5, .h5{ color: @gray-1; font-weight: bold; font-size: 15px; margin-top: 15px; } -h5.-border-bottom { +h1.-border-bottom, +h2.-border-bottom, +h3.-border-bottom, +h4.-border-bottom, +h5.-border-bottom, +h6.-border-bottom { border-bottom: 1px solid @gray-9; padding-bottom: 5px; } -h5.-black { +h1.-black, +h2.-black, +h3.-black, +h4.-black, +h5.-black, +h6.-black { color: @black; } @@ -200,10 +210,16 @@ h5.-black { clear: both; } } + +.umb-editor--infiniteMode .umb-control-group .control-header { + padding-bottom: 5px; +} + .form-horizontal .umb-control-group .control-header { float: left; width: 160px; padding-top: 5px; + padding-bottom: 0; text-align: left; .control-label { @@ -347,10 +363,16 @@ label:not([for]) { border: none !important; } -table thead a { +table thead a, +table thead button { color: @gray-2; } +table thead button:hover, +table thead button:focus{ + text-decoration: underline; +} + /* UI interactions */ .umb-table tbody.ui-sortable tr diff --git a/src/Umbraco.Web.UI.Client/src/less/mixins.less b/src/Umbraco.Web.UI.Client/src/less/mixins.less index f5c499cbfc..a87080a326 100644 --- a/src/Umbraco.Web.UI.Client/src/less/mixins.less +++ b/src/Umbraco.Web.UI.Client/src/less/mixins.less @@ -448,9 +448,11 @@ } // in these cases the gradient won't cover the background, so we override + &:focus, &:hover { color: @textColorHover; background-color: @hoverColor; + text-decoration: none; } &.disabled, &[disabled] { 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 b5870b8dce..a3bdbb0996 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -724,6 +724,7 @@ // -------------------------------------------------- .umb-fileupload { display: flex; + flex-direction: column; } .umb-fileupload .preview { diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypeconfigurationpicker/datatypeconfigurationpicker.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypeconfigurationpicker/datatypeconfigurationpicker.html index 06162d2961..cbc5b102cc 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypeconfigurationpicker/datatypeconfigurationpicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypeconfigurationpicker/datatypeconfigurationpicker.html @@ -18,29 +18,28 @@
- diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypepicker/datatypepicker.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypepicker/datatypepicker.html index 768f8a8c24..d6e2d8133d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypepicker/datatypepicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypepicker/datatypepicker.html @@ -34,16 +34,19 @@
-
{{key | umbCmsTitleCase}}
+

{{key | umbCmsTitleCase}}

@@ -51,38 +54,50 @@
-
+

+ Available configurations +

-
{{result.group | umbCmsTitleCase}}
+

{{result.group | umbCmsTitleCase}}

-
+

+ Create a new configuration +

-
{{result.group | umbCmsTitleCase}}
+

{{result.group | umbCmsTitleCase}}

diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/macropicker/macropicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/macropicker/macropicker.controller.js index ba577045aa..40338f2dca 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/macropicker/macropicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/macropicker/macropicker.controller.js @@ -22,6 +22,7 @@ function MacroPickerController($scope, entityResource, macroResource, umbPropEdi if ($scope.wizardStep === "macroSelect") { editParams(true); } else { + $scope.$broadcast("formSubmitting", { scope: $scope }); $scope.model.submit($scope.model); } }; 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 e1a89061b6..51cbf0269a 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 @@ -20,15 +20,14 @@
@@ -155,8 +151,7 @@ + on-click="vm.toggleAllowSegmentVariants()">
@@ -195,7 +190,6 @@ on-click="vm.toggleIsSensitiveData()"> -
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js index 24ed971de0..fb8b649b55 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js @@ -68,14 +68,20 @@ if(version && version.versionId) { + vm.loading = true; + const culture = $scope.model.node.variants.length > 1 ? vm.currentVersion.language.culture : null; contentResource.getRollbackVersion(version.versionId, culture) - .then(function(data){ + .then(function(data) { vm.previousVersion = data; vm.previousVersion.versionId = version.versionId; createDiff(vm.currentVersion, vm.previousVersion); + + vm.loading = false; vm.rollbackButtonDisabled = false; + }, function () { + vm.loading = false; }); } else { @@ -118,6 +124,10 @@ tab.properties.forEach((property, propertyIndex) => { var oldProperty = previousVersion.tabs[tabIndex].properties[propertyIndex]; + // copy existing properties, so it doesn't manipulate existing properties on page + oldProperty = Utilities.copy(oldProperty); + property = Utilities.copy(property); + // we have to make properties storing values as object into strings (Grid, nested content, etc.) if(property.value instanceof Object) { property.value = JSON.stringify(property.value, null, 1); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html index e292a94606..49408d69c3 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html @@ -31,8 +31,8 @@
-
-

{{vm.currentVersion.name}} (Created: {{vm.currentVersion.createDate}})

+
Current version
+

{{vm.currentVersion.name}} (Created: {{vm.currentVersion.createDate}})

- + Your new password cannot be blank! Minimum {{vm.invitedUserPasswordModel.passwordPolicies.minPasswordLength}} characters {{inviteUserPasswordForm.password.errorMsg}} @@ -33,7 +33,7 @@
- + Required The confirmed password doesn't match the new password! @@ -41,11 +41,10 @@
- +
@@ -58,11 +57,10 @@ - +
@@ -70,19 +68,18 @@
+ ngf-select + ng-model="vm.avatarFile.filesHolder" + ngf-change="vm.changeAvatar($files, $event)" + ngf-multiple="false" + ngf-pattern="{{vm.avatarFile.acceptedFileTypes}}" + ngf-max-size="{{ vm.avatarFile.maxFileSize }}"> - + @@ -94,11 +91,10 @@

- +
@@ -153,7 +149,7 @@
- +
@@ -188,21 +184,21 @@

-
+
-
-
{{errorMsg}}
+
+
+ An email with password reset instructions will be sent to the specified address if it matched our records +

+
@@ -231,16 +227,16 @@
-
-
{{vm.errorMsg}}
+
+
-
+

Your new password has been set and you may now use it to log in. +

-
Return to login form @@ -251,7 +247,7 @@
- {{error}} +

{{error}}

diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html index 2b5bceb11a..9ec8ea9302 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html @@ -5,18 +5,16 @@ -
@@ -42,9 +43,8 @@ - - + + {{ item.comment }} - - +
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html index e1bc01a7a1..7929f92371 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html @@ -12,16 +12,16 @@
- @@ -67,7 +67,7 @@
-
{{ name }}
+

{{ name }}

-
{{ description }}
+

{{ description }}

diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-groups-builder.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-groups-builder.html index 0e1b2b4973..c46981a6cb 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/umb-groups-builder.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-groups-builder.html @@ -240,7 +240,7 @@
- + - - -
diff --git a/src/Umbraco.Web.UI.Client/src/views/content/content.create.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/content.create.controller.js index fc7d38fd37..487a73f948 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/content.create.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/content/content.create.controller.js @@ -92,6 +92,8 @@ function contentCreateController($scope, } else { createBlank(docType); } + + navigationService.hideDialog(); } function createFromBlueprint(blueprintId) { diff --git a/src/Umbraco.Web.UI.Client/src/views/content/content.sort.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/content.sort.controller.js index bd501a5b07..f3113f5c8f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/content.sort.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/content/content.sort.controller.js @@ -1,7 +1,7 @@ (function () { "use strict"; - function ContentSortController($scope, $filter, $routeParams, contentResource, navigationService) { + function ContentSortController($scope, $filter, $routeParams, contentResource, navigationService, eventsService) { var vm = this; var id = $scope.currentNode.id; @@ -50,6 +50,7 @@ navigationService.syncTree({ tree: "content", path: $scope.currentNode.path, forceReload: true }) .then(() => navigationService.reloadNode($scope.currentNode)); + eventsService.emit("sortCompleted", { id: id }); vm.saveButtonState = "success"; }, function(error) { vm.error = error; diff --git a/src/Umbraco.Web.UI.Client/src/views/content/sort.html b/src/Umbraco.Web.UI.Client/src/views/content/sort.html index 471f3de956..e6cc58c8be 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/sort.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/sort.html @@ -1,37 +1,35 @@
- +