Fixes relations editor and loading in relations, allows creating relations without object types, fixes migration
This commit is contained in:
@@ -11,11 +11,27 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_5_0
|
||||
public override void Migrate()
|
||||
{
|
||||
|
||||
Alter.Table(Constants.DatabaseSchema.Tables.RelationType).AlterColumn("parentObjectType").AsGuid().Nullable();
|
||||
Alter.Table(Constants.DatabaseSchema.Tables.RelationType).AlterColumn("childObjectType").AsGuid().Nullable();
|
||||
Alter.Table(Constants.DatabaseSchema.Tables.RelationType).AlterColumn("parentObjectType").AsGuid().Nullable().Do();
|
||||
Alter.Table(Constants.DatabaseSchema.Tables.RelationType).AlterColumn("childObjectType").AsGuid().Nullable().Do();
|
||||
|
||||
//TODO: We have to update this field to ensure it's not null, we can just copy across the name since that is not nullable
|
||||
Alter.Table(Constants.DatabaseSchema.Tables.RelationType).AlterColumn("alias").AsString(100).NotNullable();
|
||||
|
||||
//drop index before we can alter the column
|
||||
if (IndexExists("IX_umbracoRelationType_alias"))
|
||||
Delete
|
||||
.Index("IX_umbracoRelationType_alias")
|
||||
.OnTable(Constants.DatabaseSchema.Tables.RelationType)
|
||||
.Do();
|
||||
//change the column to non nullable
|
||||
Alter.Table(Constants.DatabaseSchema.Tables.RelationType).AlterColumn("alias").AsString(100).NotNullable().Do();
|
||||
//re-create the index
|
||||
Create
|
||||
.Index("IX_umbracoRelationType_alias")
|
||||
.OnTable(Constants.DatabaseSchema.Tables.RelationType)
|
||||
.OnColumn("alias")
|
||||
.Ascending()
|
||||
.WithOptions().Unique().WithOptions().NonClustered()
|
||||
.Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +134,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
protected override void PersistNewItem(IRelationType entity)
|
||||
{
|
||||
entity.AddingEntity();
|
||||
|
||||
|
||||
CheckNullObjectTypeValues(entity);
|
||||
|
||||
var dto = RelationTypeFactory.BuildDto(entity);
|
||||
|
||||
var id = Convert.ToInt32(Database.Insert(dto));
|
||||
@@ -146,7 +148,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
protected override void PersistUpdatedItem(IRelationType entity)
|
||||
{
|
||||
entity.UpdatingEntity();
|
||||
|
||||
|
||||
CheckNullObjectTypeValues(entity);
|
||||
|
||||
var dto = RelationTypeFactory.BuildDto(entity);
|
||||
Database.Update(dto);
|
||||
|
||||
@@ -154,5 +158,13 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void CheckNullObjectTypeValues(IRelationType entity)
|
||||
{
|
||||
if (entity.ParentObjectType.HasValue && entity.ParentObjectType == Guid.Empty)
|
||||
entity.ParentObjectType = null;
|
||||
if (entity.ChildObjectType.HasValue && entity.ChildObjectType == Guid.Empty)
|
||||
entity.ChildObjectType = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,6 +326,8 @@ namespace Umbraco.Core.Services.Implement
|
||||
/// <returns>An enumerable list of <see cref="IUmbracoEntity"/></returns>
|
||||
public IEnumerable<IUmbracoEntity> GetChildEntitiesFromRelations(IEnumerable<IRelation> relations)
|
||||
{
|
||||
//TODO: Argh! N+1
|
||||
|
||||
foreach (var relation in relations)
|
||||
{
|
||||
var objectType = ObjectTypes.GetUmbracoObjectType(relation.ChildObjectType);
|
||||
@@ -340,6 +342,8 @@ namespace Umbraco.Core.Services.Implement
|
||||
/// <returns>An enumerable list of <see cref="IUmbracoEntity"/></returns>
|
||||
public IEnumerable<IUmbracoEntity> GetParentEntitiesFromRelations(IEnumerable<IRelation> relations)
|
||||
{
|
||||
//TODO: Argh! N+1
|
||||
|
||||
foreach (var relation in relations)
|
||||
{
|
||||
var objectType = ObjectTypes.GetUmbracoObjectType(relation.ParentObjectType);
|
||||
@@ -354,6 +358,8 @@ namespace Umbraco.Core.Services.Implement
|
||||
/// <returns>An enumerable list of <see cref="Tuple"/> with <see cref="IUmbracoEntity"/></returns>
|
||||
public IEnumerable<Tuple<IUmbracoEntity, IUmbracoEntity>> GetEntitiesFromRelations(IEnumerable<IRelation> relations)
|
||||
{
|
||||
//TODO: Argh! N+1
|
||||
|
||||
foreach (var relation in relations)
|
||||
{
|
||||
var childObjectType = ObjectTypes.GetUmbracoObjectType(relation.ChildObjectType);
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
<umb-control-group label="@relationType_parent">
|
||||
<select name="relationType-parent"
|
||||
ng-model="vm.relationType.parentObjectType"
|
||||
class="umb-property-editor umb-dropdown"
|
||||
required>
|
||||
class="umb-property-editor umb-dropdown">
|
||||
<option ng-repeat="objectType in vm.objectTypes" value="{{objectType.id}}">{{objectType.name}}</option>
|
||||
</select>
|
||||
</umb-control-group>
|
||||
@@ -41,8 +40,7 @@
|
||||
<umb-control-group label="@relationType_child">
|
||||
<select name="relationType-child"
|
||||
ng-model="vm.relationType.childObjectType"
|
||||
class="umb-property-editor umb-dropdown"
|
||||
required>
|
||||
class="umb-property-editor umb-dropdown">
|
||||
<option ng-repeat="objectType in vm.objectTypes" value="{{objectType.id}}">{{objectType.name}}</option>
|
||||
</select>
|
||||
</umb-control-group>
|
||||
|
||||
@@ -46,7 +46,7 @@ function RelationTypeEditController($scope, $routeParams, relationTypeResource,
|
||||
});
|
||||
|
||||
relationTypeResource.getById($routeParams.id)
|
||||
.then(function(data) {
|
||||
.then(function (data) {
|
||||
bindRelationType(data);
|
||||
vm.page.loading = false;
|
||||
});
|
||||
@@ -54,7 +54,6 @@ function RelationTypeEditController($scope, $routeParams, relationTypeResource,
|
||||
|
||||
function bindRelationType(relationType) {
|
||||
formatDates(relationType.relations);
|
||||
getRelationNames(relationType);
|
||||
|
||||
// Convert property value to string, since the umb-radiobutton component at the moment only handle string values.
|
||||
// Sometime later the umb-radiobutton might be able to handle value as boolean.
|
||||
@@ -70,7 +69,7 @@ function RelationTypeEditController($scope, $routeParams, relationTypeResource,
|
||||
}
|
||||
|
||||
function formatDates(relations) {
|
||||
if(relations) {
|
||||
if (relations) {
|
||||
userService.getCurrentUser().then(function (currentUser) {
|
||||
angular.forEach(relations, function (relation) {
|
||||
relation.timestampFormatted = dateHelper.getLocalDate(relation.createDate, currentUser.locale, 'LLL');
|
||||
@@ -79,41 +78,6 @@ function RelationTypeEditController($scope, $routeParams, relationTypeResource,
|
||||
}
|
||||
}
|
||||
|
||||
function getRelationNames(relationType) {
|
||||
if (relationType.relations) {
|
||||
// can we grab app entity types in one go?
|
||||
if (relationType.parentObjectType === relationType.childObjectType) {
|
||||
// yep, grab the distinct list of parent and child entities
|
||||
var entityIds = _.uniq(_.union(_.pluck(relationType.relations, "parentId"), _.pluck(relationType.relations, "childId")));
|
||||
entityResource.getByIds(entityIds, relationType.parentObjectTypeName).then(function (entities) {
|
||||
updateRelationNames(relationType, entities);
|
||||
});
|
||||
} else {
|
||||
// nope, grab the parent and child entities individually
|
||||
var parentEntityIds = _.uniq(_.pluck(relationType.relations, "parentId"));
|
||||
var childEntityIds = _.uniq(_.pluck(relationType.relations, "childId"));
|
||||
entityResource.getByIds(parentEntityIds, relationType.parentObjectTypeName).then(function (entities) {
|
||||
updateRelationNames(relationType, entities);
|
||||
});
|
||||
entityResource.getByIds(childEntityIds, relationType.childObjectTypeName).then(function (entities) {
|
||||
updateRelationNames(relationType, entities);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateRelationNames(relationType, entities) {
|
||||
var entitiesById = _.indexBy(entities, "id");
|
||||
_.each(relationType.relations, function(relation) {
|
||||
if (entitiesById[relation.parentId]) {
|
||||
relation.parentName = entitiesById[relation.parentId].name;
|
||||
}
|
||||
if (entitiesById[relation.childId]) {
|
||||
relation.childName = entitiesById[relation.childId].name;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function saveRelationType() {
|
||||
|
||||
if (formHelper.submitForm({ scope: $scope, statusMessage: "Saving..." })) {
|
||||
|
||||
@@ -45,11 +45,8 @@ namespace Umbraco.Web.Editors
|
||||
throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||
}
|
||||
|
||||
var relations = Services.RelationService.GetByRelationTypeId(relationType.Id);
|
||||
|
||||
var display = Mapper.Map<IRelationType, RelationTypeDisplay>(relationType);
|
||||
display.Relations = Mapper.MapEnumerable<IRelation, RelationDisplay>(relations);
|
||||
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,12 +16,12 @@ namespace Umbraco.Web.Models.ContentEditing
|
||||
/// Gets or sets the parent object type ID.
|
||||
/// </summary>
|
||||
[DataMember(Name = "parentObjectType", IsRequired = false)]
|
||||
public Guid ParentObjectType { get; set; }
|
||||
public Guid? ParentObjectType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the child object type ID.
|
||||
/// </summary>
|
||||
[DataMember(Name = "childObjectType", IsRequired = false)]
|
||||
public Guid ChildObjectType { get; set; }
|
||||
public Guid? ChildObjectType { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,23 @@
|
||||
using Umbraco.Core;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Mapping;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
|
||||
namespace Umbraco.Web.Models.Mapping
|
||||
{
|
||||
internal class RelationMapDefinition : IMapDefinition
|
||||
{
|
||||
private readonly IEntityService _entityService;
|
||||
private readonly IRelationService _relationService;
|
||||
|
||||
public RelationMapDefinition(IEntityService entityService, IRelationService relationService)
|
||||
{
|
||||
_entityService = entityService;
|
||||
_relationService = relationService;
|
||||
}
|
||||
|
||||
public void DefineMaps(UmbracoMapper mapper)
|
||||
{
|
||||
mapper.Define<IRelationType, RelationTypeDisplay>((source, context) => new RelationTypeDisplay(), Map);
|
||||
@@ -15,8 +26,8 @@ namespace Umbraco.Web.Models.Mapping
|
||||
}
|
||||
|
||||
// Umbraco.Code.MapAll -Icon -Trashed -AdditionalData
|
||||
// Umbraco.Code.MapAll -Relations -ParentId -Notifications
|
||||
private static void Map(IRelationType source, RelationTypeDisplay target, MapperContext context)
|
||||
// Umbraco.Code.MapAll -ParentId -Notifications
|
||||
private void Map(IRelationType source, RelationTypeDisplay target, MapperContext context)
|
||||
{
|
||||
target.ChildObjectType = source.ChildObjectType;
|
||||
target.Id = source.Id;
|
||||
@@ -28,13 +39,44 @@ namespace Umbraco.Web.Models.Mapping
|
||||
target.Udi = Udi.Create(Constants.UdiEntityType.RelationType, source.Key);
|
||||
target.Path = "-1," + source.Id;
|
||||
|
||||
// Set the "friendly" names for the parent and child object types
|
||||
target.ParentObjectTypeName = source.ParentObjectType.HasValue ? ObjectTypes.GetUmbracoObjectType(source.ParentObjectType.Value).GetFriendlyName() : string.Empty;
|
||||
target.ChildObjectTypeName = source.ChildObjectType.HasValue ? ObjectTypes.GetUmbracoObjectType(source.ChildObjectType.Value).GetFriendlyName() : string.Empty;
|
||||
// Set the "friendly" and entity names for the parent and child object types
|
||||
if (source.ParentObjectType.HasValue)
|
||||
{
|
||||
var objType = ObjectTypes.GetUmbracoObjectType(source.ParentObjectType.Value);
|
||||
target.ParentObjectTypeName = objType.GetFriendlyName();
|
||||
}
|
||||
|
||||
if (source.ChildObjectType.HasValue)
|
||||
{
|
||||
var objType = ObjectTypes.GetUmbracoObjectType(source.ChildObjectType.Value);
|
||||
target.ChildObjectTypeName = objType.GetFriendlyName();
|
||||
}
|
||||
|
||||
// Load the relations
|
||||
|
||||
var relations = _relationService.GetByRelationTypeId(source.Id);
|
||||
var displayRelations = context.MapEnumerable<IRelation, RelationDisplay>(relations);
|
||||
|
||||
// Load the entities
|
||||
var entities = _relationService.GetEntitiesFromRelations(relations)
|
||||
.ToDictionary(x => (x.Item1.Id, x.Item2.Id), x => x);
|
||||
|
||||
foreach(var r in displayRelations)
|
||||
{
|
||||
var pair = entities[(r.ParentId, r.ChildId)];
|
||||
var parent = pair.Item1;
|
||||
var child = pair.Item2;
|
||||
|
||||
r.ChildName = child.Name;
|
||||
r.ParentName = parent.Name;
|
||||
}
|
||||
|
||||
target.Relations = displayRelations;
|
||||
|
||||
}
|
||||
|
||||
// Umbraco.Code.MapAll -ParentName -ChildName
|
||||
private static void Map(IRelation source, RelationDisplay target, MapperContext context)
|
||||
private void Map(IRelation source, RelationDisplay target, MapperContext context)
|
||||
{
|
||||
target.ChildId = source.ChildId;
|
||||
target.Comment = source.Comment;
|
||||
|
||||
Reference in New Issue
Block a user