Updated the data type controller post method and moved validation, etc... over to a filter, updated data type tree with the create menu action to launch into a blank element.
This commit is contained in:
@@ -14,7 +14,7 @@ function umbracoMenuActions($q, treeService, $location) {
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name umbraco.services.umbracoMenuActions#RefreshNodeMenuItem
|
||||
* @name umbraco.services.umbracoMenuActions#RefreshNode
|
||||
* @methodOf umbraco.services.umbracoMenuActions
|
||||
* @function
|
||||
*
|
||||
@@ -24,7 +24,7 @@ function umbracoMenuActions($q, treeService, $location) {
|
||||
* @param {object} args.treeNode The tree node
|
||||
* @param {object} args.section The current section
|
||||
*/
|
||||
"RefreshNodeMenuItem": function (args) {
|
||||
"RefreshNode": function (args) {
|
||||
treeService.loadNodeChildren({ node: args.treeNode, section: args.section });
|
||||
},
|
||||
|
||||
|
||||
@@ -108,10 +108,7 @@ function DataTypeEditController($scope, $routeParams, $location, dataTypeResourc
|
||||
contentEditingHelper.handleSaveError({
|
||||
err: err,
|
||||
allNewProps: $scope.preValues,
|
||||
allOrigProps: $scope.preValues,
|
||||
rebindCallback: function () {
|
||||
createPreValueProps(err.data.preValues);
|
||||
}
|
||||
allOrigProps: $scope.preValues
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Web.Http;
|
||||
using System.Web.Http.ModelBinding;
|
||||
using AutoMapper;
|
||||
@@ -68,79 +67,17 @@ namespace Umbraco.Web.Editors
|
||||
/// </summary>
|
||||
/// <param name="dataType"></param>
|
||||
/// <returns></returns>
|
||||
[DataTypeValidate]
|
||||
public DataTypeDisplay PostSave(DataTypeSave dataType)
|
||||
{
|
||||
//Validate that the property editor exists
|
||||
var propertyEditor = PropertyEditorResolver.Current.GetById(dataType.SelectedEditor);
|
||||
if (propertyEditor == null)
|
||||
{
|
||||
var message = string.Format("Property editor with id: {0} was not found", dataType.SelectedEditor);
|
||||
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, message));
|
||||
}
|
||||
|
||||
//Validate the data type exists or create one if required
|
||||
IDataTypeDefinition persisted;
|
||||
switch (dataType.Action)
|
||||
{
|
||||
case ContentSaveAction.Save:
|
||||
persisted = ApplicationContext.Services.DataTypeService.GetDataTypeDefinitionById(dataType.Id);
|
||||
if (persisted == null)
|
||||
{
|
||||
var message = string.Format("Data type with id: {0} was not found", dataType.Id);
|
||||
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, message));
|
||||
}
|
||||
//map the model to the persisted instance
|
||||
Mapper.Map(dataType, persisted);
|
||||
break;
|
||||
case ContentSaveAction.SaveNew:
|
||||
//create the persisted model from mapping the saved model
|
||||
persisted = Mapper.Map<IDataTypeDefinition>(dataType);
|
||||
break;
|
||||
default:
|
||||
throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||
}
|
||||
|
||||
//Validate each field
|
||||
foreach (var preVal in dataType.PreValues)
|
||||
{
|
||||
var postedValue = preVal.Value;
|
||||
|
||||
foreach (var v in propertyEditor.PreValueEditor.Fields.SelectMany(x => x.Validators))
|
||||
{
|
||||
foreach (var result in v.Validate(postedValue, preVal.Key, propertyEditor))
|
||||
{
|
||||
//if there are no member names supplied then we assume that the validation message is for the overall property
|
||||
// not a sub field on the property editor
|
||||
if (!result.MemberNames.Any())
|
||||
{
|
||||
//add a model state error for the entire property
|
||||
ModelState.AddModelError(string.Format("{0}.{1}", "Properties", preVal.Key), result.ErrorMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
//there's assigned field names so we'll combine the field name with the property name
|
||||
// so that we can try to match it up to a real sub field of this editor
|
||||
foreach (var field in result.MemberNames)
|
||||
{
|
||||
ModelState.AddModelError(string.Format("{0}.{1}.{2}", "Properties", preVal.Key, field), result.ErrorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ModelState.IsValid == false)
|
||||
{
|
||||
//if it is not valid, do not continue and return the model state
|
||||
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.Forbidden, ModelState));
|
||||
}
|
||||
//If we've made it here, then everything has been wired up and validated by the attribute
|
||||
|
||||
//finally we need to save the data type and it's pre-vals
|
||||
var dtService = (DataTypeService) ApplicationContext.Services.DataTypeService;
|
||||
var preVals = Mapper.Map<PreValueCollection>(dataType.PreValues);
|
||||
dtService.SaveDataTypeAndPreValues(persisted, preVals, (int)Security.CurrentUser.Id);
|
||||
dtService.SaveDataTypeAndPreValues(dataType.PersistedDataType, preVals, (int)Security.CurrentUser.Id);
|
||||
|
||||
var display = Mapper.Map<IDataTypeDefinition, DataTypeDisplay>(persisted);
|
||||
var display = Mapper.Map<IDataTypeDefinition, DataTypeDisplay>(dataType.PersistedDataType);
|
||||
display.AddSuccessNotification(ui.Text("speechBubbles", "dataTypeSaved"), "");
|
||||
|
||||
//now return the updated model
|
||||
|
||||
119
src/Umbraco.Web/Editors/DataTypeValidateAttribute.cs
Normal file
119
src/Umbraco.Web/Editors/DataTypeValidateAttribute.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Web.Http;
|
||||
using System.Web.Http.Controllers;
|
||||
using System.Web.Http.Filters;
|
||||
using AutoMapper;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
|
||||
namespace Umbraco.Web.Editors
|
||||
{
|
||||
/// <summary>
|
||||
/// An action filter that wires up the persisted entity of the DataTypeSave model and validates the whole request
|
||||
/// </summary>
|
||||
internal sealed class DataTypeValidateAttribute : ActionFilterAttribute
|
||||
{
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
|
||||
public DataTypeValidateAttribute()
|
||||
{
|
||||
}
|
||||
|
||||
public DataTypeValidateAttribute(IDataTypeService dataTypeService)
|
||||
{
|
||||
if (dataTypeService == null) throw new ArgumentNullException("dataTypeService");
|
||||
_dataTypeService = dataTypeService;
|
||||
}
|
||||
|
||||
private IDataTypeService DataTypeService
|
||||
{
|
||||
get { return _dataTypeService ?? ApplicationContext.Current.Services.DataTypeService; }
|
||||
}
|
||||
|
||||
public override void OnActionExecuting(HttpActionContext actionContext)
|
||||
{
|
||||
var dataType = (DataTypeSave)actionContext.ActionArguments["dataType"];
|
||||
|
||||
//Validate that the property editor exists
|
||||
var propertyEditor = PropertyEditorResolver.Current.GetById(dataType.SelectedEditor);
|
||||
if (propertyEditor == null)
|
||||
{
|
||||
var message = string.Format("Property editor with id: {0} was not found", dataType.SelectedEditor);
|
||||
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.NotFound, message);
|
||||
return;
|
||||
}
|
||||
|
||||
//assign the prop editor to the model
|
||||
dataType.PropertyEditor = propertyEditor;
|
||||
|
||||
//Validate the data type exists or create one if required
|
||||
IDataTypeDefinition persisted;
|
||||
switch (dataType.Action)
|
||||
{
|
||||
case ContentSaveAction.Save:
|
||||
persisted = DataTypeService.GetDataTypeDefinitionById(dataType.Id);
|
||||
if (persisted == null)
|
||||
{
|
||||
var message = string.Format("Data type with id: {0} was not found", dataType.Id);
|
||||
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.NotFound, message);
|
||||
return;
|
||||
}
|
||||
//map the model to the persisted instance
|
||||
Mapper.Map(dataType, persisted);
|
||||
break;
|
||||
case ContentSaveAction.SaveNew:
|
||||
//create the persisted model from mapping the saved model
|
||||
persisted = Mapper.Map<IDataTypeDefinition>(dataType);
|
||||
break;
|
||||
default:
|
||||
throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||
}
|
||||
|
||||
//now assign the persisted entity to the model so we can use it in the action
|
||||
dataType.PersistedDataType = persisted;
|
||||
|
||||
//Validate each field
|
||||
foreach (var preVal in dataType.PreValues)
|
||||
{
|
||||
var postedValue = preVal.Value;
|
||||
|
||||
foreach (var v in propertyEditor.PreValueEditor.Fields.SelectMany(x => x.Validators))
|
||||
{
|
||||
foreach (var result in v.Validate(postedValue, preVal.Key, propertyEditor))
|
||||
{
|
||||
//if there are no member names supplied then we assume that the validation message is for the overall property
|
||||
// not a sub field on the property editor
|
||||
if (!result.MemberNames.Any())
|
||||
{
|
||||
//add a model state error for the entire property
|
||||
actionContext.ModelState.AddModelError(string.Format("{0}.{1}", "Properties", preVal.Key), result.ErrorMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
//there's assigned field names so we'll combine the field name with the property name
|
||||
// so that we can try to match it up to a real sub field of this editor
|
||||
foreach (var field in result.MemberNames)
|
||||
{
|
||||
actionContext.ModelState.AddModelError(string.Format("{0}.{1}.{2}", "Properties", preVal.Key, field), result.ErrorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (actionContext.ModelState.IsValid == false)
|
||||
{
|
||||
//if it is not valid, do not continue and return the model state
|
||||
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Forbidden, actionContext.ModelState);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Runtime.Serialization;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.Models.ContentEditing
|
||||
{
|
||||
@@ -25,5 +28,17 @@ namespace Umbraco.Web.Models.ContentEditing
|
||||
[DataMember(Name = "preValues")]
|
||||
public IEnumerable<PreValueFieldSave> PreValues { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The real persisted data type
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
internal IDataTypeDefinition PersistedDataType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The PropertyEditor assigned
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
internal PropertyEditor PropertyEditor { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@ namespace Umbraco.Web.Trees
|
||||
|
||||
// add default actions for *all* users
|
||||
allowedMenu.AddMenuItem<ActionRePublish>();
|
||||
allowedMenu.AddMenuItem<RefreshNodeMenuItem, ActionRefresh>(true);
|
||||
allowedMenu.AddMenuItem<RefreshNode, ActionRefresh>(true);
|
||||
return allowedMenu;
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ namespace Umbraco.Web.Trees
|
||||
menu.AddMenuItem<ActionNotify>(true);
|
||||
menu.AddMenuItem<ActionSendToTranslate>();
|
||||
|
||||
menu.AddMenuItem<RefreshNodeMenuItem, ActionRefresh>(true);
|
||||
menu.AddMenuItem<RefreshNode, ActionRefresh>(true);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@ namespace Umbraco.Web.Trees
|
||||
if (id == Constants.System.Root.ToInvariantString())
|
||||
{
|
||||
// root actions
|
||||
menu.AddMenuItem<ActionNew>();
|
||||
menu.AddMenuItem<RefreshNodeMenuItem, ActionRefresh>(true);
|
||||
menu.AddMenuItem<CreateChildEntity, ActionNew>();
|
||||
menu.AddMenuItem<RefreshNode, ActionRefresh>(true);
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Umbraco.Web.Trees
|
||||
// root actions
|
||||
menu.AddMenuItem<ActionNew>();
|
||||
menu.AddMenuItem<ActionSort>(true);
|
||||
menu.AddMenuItem<RefreshNodeMenuItem, ActionRefresh>(true);
|
||||
menu.AddMenuItem<RefreshNode, ActionRefresh>(true);
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
||||
10
src/Umbraco.Web/Trees/Menu/CreateChildEntity.cs
Normal file
10
src/Umbraco.Web/Trees/Menu/CreateChildEntity.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace Umbraco.Web.Trees.Menu
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the refresh node menu item
|
||||
/// </summary>
|
||||
[ActionMenuItem("umbracoMenuActions")]
|
||||
public sealed class CreateChildEntity : ActionMenuItem
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
namespace Umbraco.Web.Trees.Menu
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the refresh node menu item
|
||||
/// </summary>
|
||||
[ActionMenuItem("umbracoMenuActions")]
|
||||
public sealed class RefreshNodeMenuItem : ActionMenuItem
|
||||
{
|
||||
}
|
||||
namespace Umbraco.Web.Trees.Menu
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the refresh node menu item
|
||||
/// </summary>
|
||||
[ActionMenuItem("umbracoMenuActions")]
|
||||
public sealed class RefreshNode : ActionMenuItem
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -299,6 +299,7 @@
|
||||
<Compile Include="Editors\AuthenticationController.cs" />
|
||||
<Compile Include="Editors\ContentController.cs" />
|
||||
<Compile Include="Editors\DataTypeController.cs" />
|
||||
<Compile Include="Editors\DataTypeValidateAttribute.cs" />
|
||||
<Compile Include="Editors\EntityController.cs" />
|
||||
<Compile Include="Models\ContentEditing\DataTypeDisplay.cs" />
|
||||
<Compile Include="Models\ContentEditing\DataTypeSave.cs" />
|
||||
@@ -320,6 +321,7 @@
|
||||
<Compile Include="PropertyEditors\LabelValueEditor.cs" />
|
||||
<Compile Include="Routing\UrlProviderExtensions.cs" />
|
||||
<Compile Include="Trees\DataTypeTreeController.cs" />
|
||||
<Compile Include="Trees\Menu\CreateChildEntity.cs" />
|
||||
<Compile Include="WebApi\ControllerContextExtensions.cs" />
|
||||
<Compile Include="WebApi\CustomDateTimeConvertor.cs" />
|
||||
<Compile Include="Models\ContentEditing\ContentSortOrder.cs" />
|
||||
@@ -379,7 +381,7 @@
|
||||
<Compile Include="Trees\Menu\MenuItem.cs" />
|
||||
<Compile Include="Trees\Menu\MenuItemCollection.cs" />
|
||||
<Compile Include="Trees\Menu\MenuItemExtensions.cs" />
|
||||
<Compile Include="Trees\Menu\RefreshNodeMenuItem.cs" />
|
||||
<Compile Include="Trees\Menu\RefreshNode.cs" />
|
||||
<Compile Include="Trees\SearchResultItem.cs" />
|
||||
<Compile Include="Trees\SectionRootNode.cs" />
|
||||
<Compile Include="Trees\TreeApiController.cs" />
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace umbraco.BusinessLogic.Actions
|
||||
/// Concerns only the tree itself and thus you should not handle
|
||||
/// this action from without umbraco.
|
||||
/// </summary>
|
||||
[LegacyActionMenuItem("umbracoMenuActions", "RefreshNodeMenuItem")]
|
||||
[LegacyActionMenuItem("umbracoMenuActions", "RefreshNode")]
|
||||
public class ActionRefresh : IAction
|
||||
{
|
||||
//create singleton
|
||||
|
||||
Reference in New Issue
Block a user