Fixes relations editor and loading in relations, allows creating relations without object types, fixes migration

This commit is contained in:
Shannon
2019-10-24 22:38:11 +11:00
parent ae64fe49be
commit f656f7d0a0
8 changed files with 95 additions and 60 deletions

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);

View File

@@ -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>

View File

@@ -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..." })) {

View File

@@ -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;
}

View File

@@ -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; }
}
}

View File

@@ -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;