diff --git a/src/Umbraco.Web.UI.Client/src/common/services/blockeditormodelobject.service.js b/src/Umbraco.Web.UI.Client/src/common/services/blockeditormodelobject.service.js index fe57534ffb..d744f8277f 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/blockeditormodelobject.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/blockeditormodelobject.service.js @@ -730,7 +730,7 @@ return null; } - var dataModel = getDataByUdi(layoutEntry.udi, this.value.contentData); + var dataModel = getDataByUdi(layoutEntry.contentUdi, this.value.contentData); if (dataModel === null) { return null; } diff --git a/src/Umbraco.Web.UI.Client/src/less/alerts.less b/src/Umbraco.Web.UI.Client/src/less/alerts.less index 3907b59f58..3539e21064 100644 --- a/src/Umbraco.Web.UI.Client/src/less/alerts.less +++ b/src/Umbraco.Web.UI.Client/src/less/alerts.less @@ -7,6 +7,7 @@ // ------------------------- .alert { + position: relative; padding: 8px 35px 8px 14px; margin-bottom: @baseLineHeight; background-color: @warningBackground; @@ -98,3 +99,29 @@ .alert-block p + p { margin-top: 5px; } + + +// Property error alerts +// ------------------------- +.alert.property-error { + + display: inline-block; + font-size: 14px; + padding: 6px 16px 6px 12px; + margin-bottom: 6px; + + &::after { + content:''; + position: absolute; + bottom:-6px; + left: 6px; + width: 0; + height: 0; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-top: 6px solid; + } + &.alert-error::after { + border-top-color: @errorBackground; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/less/components/editor/umb-variant-switcher.less b/src/Umbraco.Web.UI.Client/src/less/components/editor/umb-variant-switcher.less index 8dbc070856..eae25b273c 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/editor/umb-variant-switcher.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/editor/umb-variant-switcher.less @@ -50,6 +50,19 @@ button.umb-variant-switcher__toggle { font-weight: bold; background-color: @errorBackground; color: @errorText; + + animation-duration: 1.4s; + animation-iteration-count: infinite; + animation-name: umb-variant-switcher__toggle--badge-bounce; + animation-timing-function: ease; + @keyframes umb-variant-switcher__toggle--badge-bounce { + 0% { transform: translateY(0); } + 20% { transform: translateY(-6px); } + 40% { transform: translateY(0); } + 55% { transform: translateY(-3px); } + 70% { transform: translateY(0); } + 100% { transform: translateY(0); } + } } } } @@ -226,6 +239,19 @@ button.umb-variant-switcher__toggle { font-weight: bold; background-color: @errorBackground; color: @errorText; + + animation-duration: 1.4s; + animation-iteration-count: infinite; + animation-name: umb-variant-switcher__name--badge-bounce; + animation-timing-function: ease; + @keyframes umb-variant-switcher__name--badge-bounce { + 0% { transform: translateY(0); } + 20% { transform: translateY(-6px); } + 40% { transform: translateY(0); } + 55% { transform: translateY(-3px); } + 70% { transform: translateY(0); } + 100% { transform: translateY(0); } + } } } } diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation-item.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation-item.less index cb673e3c6f..2fc705b11b 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation-item.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation-item.less @@ -53,6 +53,39 @@ height: 4px; } } + + // Validation + .show-validation &.-has-error { + color: @red; + + &:hover { + color: @red !important; + } + + &::before { + background-color: @red; + } + + &:not(.is-active) { + .badge { + animation-duration: 1.4s; + animation-iteration-count: infinite; + animation-name: umb-sub-views-nav-item--badge-bounce; + animation-timing-function: ease; + @keyframes umb-sub-views-nav-item--badge-bounce { + 0% { transform: translateY(0); } + 20% { transform: translateY(-6px); } + 40% { transform: translateY(0); } + 55% { transform: translateY(-3px); } + 70% { transform: translateY(0); } + 100% { transform: translateY(0); } + } + } + .badge.--error-badge { + display: block; + } + } + } } &__action:active, @@ -101,6 +134,10 @@ height: 12px; min-width: 12px; } + &.--error-badge { + display: none; + font-weight: 900; + } } &-text { @@ -182,13 +219,3 @@ } } } - -// Validation -.show-validation .umb-sub-views-nav-item__action.-has-error, -.show-validation .umb-sub-views-nav-item > a.-has-error { - color: @red; - - &::before { - background-color: @red; - } -} diff --git a/src/Umbraco.Web.UI.Client/src/less/main.less b/src/Umbraco.Web.UI.Client/src/less/main.less index ce20b8dc88..2354e96d38 100644 --- a/src/Umbraco.Web.UI.Client/src/less/main.less +++ b/src/Umbraco.Web.UI.Client/src/less/main.less @@ -272,6 +272,7 @@ label:not([for]) { /* CONTROL VALIDATION */ .umb-control-required { color: @controlRequiredColor; + font-weight: 900; } .controls-row { diff --git a/src/Umbraco.Web.UI.Client/src/less/mixins.less b/src/Umbraco.Web.UI.Client/src/less/mixins.less index a87080a326..9739a90dae 100644 --- a/src/Umbraco.Web.UI.Client/src/less/mixins.less +++ b/src/Umbraco.Web.UI.Client/src/less/mixins.less @@ -138,7 +138,9 @@ // additional targetting of the ng-invalid class. .formFieldState(@textColor: @gray-4, @borderColor: @gray-7, @backgroundColor: @gray-10) { // Set the text color - .control-label, + > .control-label, + > .umb-el-wrap > .control-label, + > .umb-el-wrap > .control-header > .control-label, .help-block, .help-inline { color: @textColor; diff --git a/src/Umbraco.Web.UI.Client/src/less/variables.less b/src/Umbraco.Web.UI.Client/src/less/variables.less index 2f627f3ab3..840c6d529f 100644 --- a/src/Umbraco.Web.UI.Client/src/less/variables.less +++ b/src/Umbraco.Web.UI.Client/src/less/variables.less @@ -481,7 +481,7 @@ @formErrorText: @errorBackground; @formErrorBackground: lighten(@errorBackground, 55%); -@formErrorBorder: darken(spin(@errorBackground, -10), 3%); +@formErrorBorder: @red; @formSuccessText: @successBackground; @formSuccessBackground: lighten(@successBackground, 48%); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/blockeditor/blockeditor.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/blockeditor/blockeditor.controller.js index f515cbb4ba..af13ef6241 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/blockeditor/blockeditor.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/blockeditor/blockeditor.controller.js @@ -1,6 +1,6 @@ angular.module("umbraco") .controller("Umbraco.Editors.BlockEditorController", - function ($scope, localizationService, formHelper) { + function ($scope, localizationService, formHelper, overlayService) { var vm = this; vm.model = $scope.model; @@ -42,6 +42,7 @@ angular.module("umbraco") vm.submitAndClose = function () { if (vm.model && vm.model.submit) { + // always keep server validations since this will be a nested editor and server validations are global if (formHelper.submitForm({ scope: $scope, @@ -49,13 +50,16 @@ angular.module("umbraco") keepServerValidation: true })) { vm.model.submit(vm.model); + vm.saveButtonState = "success"; + } else { + vm.saveButtonState = "error"; } } } vm.close = function () { if (vm.model && vm.model.close) { - // TODO: At this stage there could very well have been server errors that have been cleared + // TODO: At this stage there could very well have been server errors that have been cleared // but if we 'close' we are basically cancelling the value changes which means we'd want to cancel // all of the server errors just cleared. It would be possible to do that but also quite annoying. // The rudimentary way would be to: @@ -67,6 +71,29 @@ angular.module("umbraco") // * It would have a 'commit' method to commit the removed errors - which we would call in the formHelper.submitForm when it's successful // * It would have a 'rollback' method to reset the removed errors - which we would call here + + if (vm.blockForm.$dirty === true) { + localizationService.localizeMany(["prompt_discardChanges", "blockEditor_blockHasChanges"]).then(function (localizations) { + const confirm = { + title: localizations[0], + view: "default", + content: localizations[1], + submitButtonLabelKey: "general_discard", + submitButtonStyle: "danger", + closeButtonLabelKey: "general_cancel", + submit: function () { + overlayService.close(); + vm.model.close(vm.model); + }, + close: function () { + overlayService.close(); + } + }; + overlayService.open(confirm); + }); + + return; + } // TODO: check if content/settings has changed and ask user if they are sure. vm.model.close(vm.model); } diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/blockeditor/blockeditor.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/blockeditor/blockeditor.html index de18f13d2c..dfcfd48887 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/blockeditor/blockeditor.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/blockeditor/blockeditor.html @@ -44,7 +44,7 @@ diff --git a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html index 484e0175c5..9e5669f443 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html @@ -9,6 +9,7 @@ {{ vm.item.name }}
{{vm.item.badge.count}}
+
!