diff --git a/src/Umbraco.Web.UI.Client/src/less/panel.less b/src/Umbraco.Web.UI.Client/src/less/panel.less index 19159638a4..ded8411dea 100644 --- a/src/Umbraco.Web.UI.Client/src/less/panel.less +++ b/src/Umbraco.Web.UI.Client/src/less/panel.less @@ -484,6 +484,8 @@ input.umb-panel-header-description { font-size: 12px; margin-left: 2px; margin-top: 3px; + height: 25px; + line-height: 25px; } .umb-editor-drawer-content { 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 558f94d387..f218e983e7 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 @@ -28,8 +28,6 @@ umb-auto-focus val-server-field="Name" required /> -
Required name
-
{{ name }}
diff --git a/src/Umbraco.Web.UI.Client/src/views/templates/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/templates/edit.controller.js index 3cf454c886..f661b82e7b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/templates/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/templates/edit.controller.js @@ -1,10 +1,11 @@ (function () { "use strict"; - function TemplatesEditController($scope, $routeParams, templateResource, assetsService, notificationsService, editorState, navigationService, appState, macroService, treeService, angularHelper, $timeout) { + function TemplatesEditController($scope, $routeParams, $timeout, templateResource, assetsService, notificationsService, editorState, navigationService, appState, macroService, treeService, contentEditingHelper, localizationService, angularHelper) { var vm = this; var oldMasterTemplateAlias = null; + var localizeSaving = localizationService.localize("general_saving"); vm.page = {}; vm.page.loading = true; @@ -20,8 +21,18 @@ vm.template.content = vm.editor.getValue(); - templateResource.save(vm.template).then(function (saved) { - + contentEditingHelper.contentEditorPerformSave({ + statusMessage: localizeSaving, + saveMethod: templateResource.save, + scope: $scope, + content: vm.template, + //We do not redirect on failure for templates - this is because it is not possible to actually save the doc + // type when server side validation fails - as opposed to content where we are capable of saving the content + // item if server side validation fails + redirectOnFailure: false, + rebindCallback: function (orignal, saved) {} + }).then(function (saved) { + notificationsService.success("Template saved"); vm.page.saveButtonState = "success"; vm.template = saved; @@ -58,9 +69,17 @@ }, function (err) { - notificationsService.error("Template save failed"); + vm.page.saveButtonState = "error"; + + localizationService.localize("speechBubbles_validationFailedHeader").then(function (headerValue) { + localizationService.localize("speechBubbles_validationFailedMessage").then(function(msgValue) { + notificationsService.error(headerValue, msgValue); + }); + }); + }); + }; vm.init = function () { diff --git a/src/Umbraco.Web.UI.Client/test/unit/app/templates/template-editor-controller.spec.js b/src/Umbraco.Web.UI.Client/test/unit/app/templates/template-editor-controller.spec.js index 7820beaf16..8208999536 100644 --- a/src/Umbraco.Web.UI.Client/test/unit/app/templates/template-editor-controller.spec.js +++ b/src/Umbraco.Web.UI.Client/test/unit/app/templates/template-editor-controller.spec.js @@ -90,6 +90,10 @@ getSectionState : function() { return {}; } }, macroService: {}, + contentEditingHelper: {}, + localizationService: { + localize: resolvedPromise({}) + }, angularHelper: { getCurrentForm: function() { return { diff --git a/src/Umbraco.Web/Editors/TemplateController.cs b/src/Umbraco.Web/Editors/TemplateController.cs index fb93a8f34e..58a4053de1 100644 --- a/src/Umbraco.Web/Editors/TemplateController.cs +++ b/src/Umbraco.Web/Editors/TemplateController.cs @@ -6,8 +6,10 @@ using System.Web.Http; using AutoMapper; using Umbraco.Core.IO; using Umbraco.Core.Models; +using Umbraco.Core.Services; using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Mvc; +using Umbraco.Web.WebApi; using Umbraco.Web.WebApi.Filters; using Constants = Umbraco.Core.Constants; @@ -86,6 +88,14 @@ namespace Umbraco.Web.Editors /// public TemplateDisplay PostSave(TemplateDisplay display) { + + //Checking the submitted is valid with the Required attributes decorated on the ViewModel + if (ModelState.IsValid == false) + { + throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState)); + } + + if (display.Id > 0) { // update @@ -100,11 +110,16 @@ namespace Umbraco.Web.Editors { if (string.IsNullOrEmpty(display.MasterTemplateAlias) == false) { + var master = Services.FileService.GetTemplate(display.MasterTemplateAlias); - if (master != null) - { - template.SetMasterTemplate(master); + if(master == null || master.Id == display.Id) + { + template.SetMasterTemplate(null); + }else + { + template.SetMasterTemplate(master); } + } else { diff --git a/src/Umbraco.Web/Models/ContentEditing/TemplateDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/TemplateDisplay.cs index bbe1e63573..8e813bd3d3 100644 --- a/src/Umbraco.Web/Models/ContentEditing/TemplateDisplay.cs +++ b/src/Umbraco.Web/Models/ContentEditing/TemplateDisplay.cs @@ -1,21 +1,26 @@ using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Linq; using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; +using Umbraco.Core.Models.Validation; namespace Umbraco.Web.Models.ContentEditing { [DataContract(Name = "template", Namespace = "")] public class TemplateDisplay : INotificationModel { + [DataMember(Name = "id")] public int Id { get; set; } + [Required] [DataMember(Name = "name")] public string Name { get; set; } + [Required] [DataMember(Name = "alias")] public string Alias { get; set; }