Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New grid view property migrators, migrate column settings from grid to block grid #286

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions uSync.Migrations.Core/Context/DataTypeMigrationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ public class DataTypeMigrationContext
/// </summary>
private Dictionary<Guid, string> _dataTypeAliases { get; set; } = new();

private Dictionary<string, NewDataTypeInfo> _newDataTypes
= new Dictionary<string, NewDataTypeInfo>(StringComparer.OrdinalIgnoreCase);

/// <summary>
/// add a datatype alias to the lookup
/// </summary>
Expand Down Expand Up @@ -88,6 +91,30 @@ public string GetVariation(Guid guid, string defaultValue)
=> _dataTypeVariations?.TryGetValue(guid, out var variation) == true
? variation : defaultValue;

/// <summary>
/// add a new data type - will then be processed as part of the
/// migration process.
/// </summary>
public void AddNewDataType(NewDataTypeInfo newDataType)
{
if (!_newDataTypes.ContainsKey(newDataType.Alias))
_newDataTypes.Add(newDataType.Alias, newDataType);
}

/// <summary>
/// list of all the new data types to be created.
/// </summary>
/// <returns></returns>
public IList<NewDataTypeInfo> GetNewDataTypes()
=> _newDataTypes.Values.ToList();

/// <summary>
/// get new datatype by alias
/// </summary>
/// <returns></returns>
public NewDataTypeInfo? GetNewDataType(string alias)
=> _newDataTypes.Values.FirstOrDefault(dt => dt.Alias == alias);

/// <summary>
/// return the first definition that we find matching the editorAlias
/// </summary>
Expand Down
12 changes: 8 additions & 4 deletions uSync.Migrations.Core/Extensions/ContentTypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,21 @@ public static XElement MakeXMLFromNewDocType(this NewContentTypeInfo newDocType,
index++;

var dataType = dataTypeService.GetDataType(property.DataTypeAlias);
if (dataType == null) continue;
var newDataType = dataType == null ?
context.DataTypes.GetNewDataType(property.DataTypeAlias) :
null;

if (dataType == null && newDataType == null) continue;

var propNode = new XElement("GenericProperty",
new XElement("Key", $"{newDocType.Alias}_{property.Alias}".ToGuid()),
new XElement("Name", property.Name),
new XElement("Alias", property.Alias),
new XElement("Definition", dataType.Key),
new XElement("Type", dataType.EditorAlias),
new XElement("Definition", dataType == null ? newDataType!.Key : dataType.Key),
new XElement("Type", dataType == null ? newDataType!.EditorAlias : dataType.EditorAlias),
new XElement("Mandatory", false),
new XElement("Validation", ""),
new XElement("Description", new XCData("")),
new XElement("Description", new XCData(property.Description ?? "")),
new XElement("SortOrder", index),
GetTabElement(property, newDocType),
new XElement("Variations", "Nothing"),
Expand Down
32 changes: 32 additions & 0 deletions uSync.Migrations.Core/Extensions/DataTypeExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using Newtonsoft.Json;
using System.Xml.Linq;
using Umbraco.Extensions;

using uSync.Core;
using uSync.Migrations.Core.Context;
using uSync.Migrations.Core.Models;

namespace uSync.Migrations.Core.Extensions;
internal static class DataTypeExtensions
{
public static XElement MakeXMLFromNewDataType(this NewDataTypeInfo newDataType,
JsonSerializerSettings _jsonSerializerSettings)
{
var source = new XElement("DataType",
new XAttribute(uSyncConstants.Xml.Key, newDataType.Alias.ToGuid()),
new XAttribute(uSyncConstants.Xml.Alias, newDataType.Alias),
new XAttribute(uSyncConstants.Xml.Level, 1),
new XElement(uSyncConstants.Xml.Info,
new XElement(uSyncConstants.Xml.Name, newDataType.Name),
new XElement("EditorAlias", newDataType.EditorAlias),
new XElement("DatabaseType", newDataType.DatabaseType)));

if (newDataType.Config != null)
{
source.Add(new XElement("Config",
new XCData(JsonConvert.SerializeObject(newDataType.Config, _jsonSerializerSettings))));
}

return source;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -316,11 +316,17 @@ private void AddAdditionaProperties(NewContentTypeInfo contentType, SyncMigratio
foreach (var property in contentType.Properties)
{
var dataType = _dataTypeService.GetDataType(property.DataTypeAlias);
var newDataType = dataType == null ?
context.DataTypes.GetNewDataType(property.DataTypeAlias) :
null;

if (dataType != null)
if (dataType != null || newDataType != null)
{
var editorAlias = dataType == null ? newDataType!.EditorAlias : dataType.EditorAlias;
var key = dataType == null ? newDataType!.Key : dataType.Key;

context.ContentTypes.AddProperty(contentType.Alias, property.Alias,
property.OriginalEditorAlias ?? dataType.EditorAlias, dataType.EditorAlias, dataType.Key);
property.OriginalEditorAlias ?? editorAlias, editorAlias, key);
}
}
}
Expand Down
36 changes: 36 additions & 0 deletions uSync.Migrations.Core/Handlers/Shared/SharedDataTypeHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@

using uSync.Core;
using uSync.Migrations.Core.Context;
using uSync.Migrations.Core.Extensions;
using uSync.Migrations.Core.Migrators;
using uSync.Migrations.Core.Migrators.Models;
using uSync.Migrations.Core.Models;
using uSync.Migrations.Core.Serialization;
using uSync.Migrations.Core.Services;

Expand Down Expand Up @@ -195,4 +197,38 @@ protected virtual XElement MakeMigratedXml(
return target;
}

/// <summary>
/// hook into the DoMigration loop so we can add additional datatypes
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
protected override IEnumerable<MigrationMessage> PostDoMigration(SyncMigrationContext context)
{
var messages = new List<MigrationMessage>();
messages.AddRange(base.PostDoMigration(context));
messages.AddRange(CreateAdditional(context));
return messages;
}

/// <summary>
/// Add additional data types that might have been added by datatypes during the
/// first part of the migration (i.e BlockGrid conversion)
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
protected IEnumerable<MigrationMessage> CreateAdditional(SyncMigrationContext context)
{
var messages = new List<MigrationMessage>();

foreach (var dataType in context.DataTypes.GetNewDataTypes())
{
// if this has been blocked don't add it.
if (context.IsBlocked(ItemType, dataType.Alias)) continue;

var source = dataType.MakeXMLFromNewDataType(_jsonSerializerSettings);
messages.Add(SaveTargetXml(context.Metadata.MigrationId, source));
}
return messages;
}

}
9 changes: 8 additions & 1 deletion uSync.Migrations.Core/Models/NewContentTypeProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,23 @@ public NewContentTypeProperty(string name, string alias, string dataTypeAlias)
DataTypeAlias = dataTypeAlias ?? throw new ArgumentNullException(nameof(dataTypeAlias));
}

public NewContentTypeProperty(string name, string alias, string dataTypeAlias, string orginalEditorAlias)
public NewContentTypeProperty(string name, string alias, string dataTypeAlias, string? orginalEditorAlias)
: this(name, alias, dataTypeAlias)
{
OriginalEditorAlias = orginalEditorAlias;
}

public NewContentTypeProperty(string name, string alias, string dataTypeAlias, string? orginalEditorAlias, string? description)
: this(name, alias, dataTypeAlias, orginalEditorAlias)
{
Description = description;
}


public string Name { get; set; }
public string Alias { get; set; }
public string DataTypeAlias { get; set; }
public string? Description { get; set; }

public string? OriginalEditorAlias { get; set; }
public string TabAlias { get; set; } = "block";
Expand Down
26 changes: 26 additions & 0 deletions uSync.Migrations.Core/Models/NewDataTypeInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace uSync.Migrations.Core.Models;

public class NewDataTypeInfo
{
public NewDataTypeInfo(Guid key, string alias, string name, string editorAlias, string databaseType, object? config)
{
Key = key;
Alias = alias ?? throw new ArgumentNullException(nameof(alias));
Name = name ?? throw new ArgumentNullException(nameof(name));
EditorAlias = editorAlias ?? throw new ArgumentNullException(nameof(editorAlias));
DatabaseType = databaseType ?? throw new ArgumentNullException(nameof(databaseType));
Config = config;
}

public Guid Key { get; set; } = Guid.Empty;

public string Alias { get; set; }

public string Name { get; set; }

public string EditorAlias { get; set; }

public string DatabaseType { get; set; }

public object? Config { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,20 @@ public GridToBlockGridConfigLayoutBlockHelper(
_logger = logger;
}

public void AddLayoutBlocks(GridToBlockGridConfigContext gridBlockContext, SyncMigrationContext context, string dataTypeAlias)
public void AddLayoutBlocks(GridToBlockGridConfigContext gridBlockContext, SyncMigrationContext context, string dataTypeAlias, bool addAreaSettingsLayout = false)
{
// gather all the layout blocks we can from the templates
// and layouts sections of the config.
GetTemplateLayouts(gridBlockContext.GridConfiguration.GetItemBlock("templates"), gridBlockContext, context);

GetLayoutLayouts(gridBlockContext.GridConfiguration.GetItemBlock("layouts"), gridBlockContext, context, dataTypeAlias);

if (addAreaSettingsLayout)
{
// Add a single layout to serve as a container for areas with settings
GetSettingsContainerLayout(gridBlockContext, context, dataTypeAlias);
}

AddContentTypesForLayoutBlocks(gridBlockContext, context);
}

Expand Down Expand Up @@ -207,6 +213,52 @@ private void GetLayoutLayouts(JToken? layouts, GridToBlockGridConfigContext grid

}

private void GetSettingsContainerLayout(GridToBlockGridConfigContext gridBlockContext, SyncMigrationContext context, string dataTypeAlias)
{
var rowAreas = new List<BlockGridConfiguration.BlockGridAreaConfiguration>();

var allowed = new List<string> { "*" };

var label = _conventions.SettingsContainerLayoutBlockLabel;
var alias = label;

var area = new BlockGridConfiguration.BlockGridAreaConfiguration
{
Alias = _conventions.AreaAlias(0),
ColumnSpan = gridBlockContext.GridColumns,
RowSpan = 1,
Key = alias.ToGuid()
};

rowAreas.Add(area);

gridBlockContext.AllowedEditors[area] = allowed;

var contentTypeAlias = alias;
var settingsContentTypeAlias = _conventions.LayoutAreaSettingsContentTypeAlias(dataTypeAlias);

var layoutBlock = new BlockGridConfiguration.BlockGridBlockConfiguration
{
Label = label,
Areas = rowAreas.ToArray(),
ContentElementTypeKey = context.GetContentTypeKeyOrDefault(contentTypeAlias, contentTypeAlias.ToGuid()),
SettingsElementTypeKey = context.GetContentTypeKeyOrDefault(settingsContentTypeAlias, settingsContentTypeAlias.ToGuid()),
GroupKey = gridBlockContext.LayoutsGroup.Key.ToString(),
BackgroundColor = Grid.LayoutBlocks.Background,
IconColor = Grid.LayoutBlocks.Icon,
AllowAtRoot = false,
AllowInAreas = true
};

gridBlockContext.LayoutBlocks.TryAdd(contentTypeAlias, layoutBlock);

context.ContentTypes.AddNewContentType(new NewContentTypeInfo(layoutBlock.ContentElementTypeKey, contentTypeAlias, contentTypeAlias, "icon-layout color-purple", folder: "BlockGrid/Layouts")
{
Description = "Grid Layoutblock",
IsElement = true
});
}

private void AddContentTypesForLayoutBlocks(GridToBlockGridConfigContext gridBlockContext, SyncMigrationContext context)
{
var rootAllowed = gridBlockContext.GetRootAllowedLayouts();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ internal class GridToBlockGridConfigLayoutSettingsHelper
private readonly GridSettingsViewMigratorCollection _gridSettingsViewMigrators;
private readonly ILogger<GridToBlockGridConfigLayoutSettingsHelper> _logger;

public bool AnyAreaSettings { get; set; } = false;

public GridToBlockGridConfigLayoutSettingsHelper(
GridConventions conventions,
Expand All @@ -33,11 +34,15 @@ public void AddGridSettings(GridToBlockGridConfigContext gridBlockContext, SyncM

var gridStyles = GetGridSettingsFromConfig(gridBlockContext.GridConfiguration?.GetItemBlock("styles"));

// Take only the settings that have applyTo = row. Other value here could be cell.
// TODO: Implement cell settings converter.
var gridSettings = gridConfig.Concat(gridStyles).Where(s => s.ApplyTo != "cell");
var gridRowSettings = gridConfig.Concat(gridStyles).Where(s => s.ApplyTo != "cell");

AddGridLayoutSettings(gridSettings, gridBlockContext, context, gridAlias);
AddGridLayoutSettings(gridRowSettings, gridBlockContext, context, gridAlias, isArea: false);

var gridAreaSettings = gridConfig.Concat(gridStyles).Where(s => s.ApplyTo != "row");

AnyAreaSettings = gridAreaSettings.Any();

AddGridLayoutSettings(gridAreaSettings, gridBlockContext, context, gridAlias, isArea: true);
}

private IEnumerable<GridSettingsConfigurationItem> GetGridSettingsFromConfig(JToken? config)
Expand All @@ -50,7 +55,7 @@ private IEnumerable<GridSettingsConfigurationItem> GetGridSettingsFromConfig(JTo
return config.ToObject<IEnumerable<GridSettingsConfigurationItem>>() ?? Enumerable.Empty<GridSettingsConfigurationItem>();
}

private void AddGridLayoutSettings(IEnumerable<GridSettingsConfigurationItem> gridLayoutConfigurations, GridToBlockGridConfigContext gridBlockContext, SyncMigrationContext context, string gridAlias)
private void AddGridLayoutSettings(IEnumerable<GridSettingsConfigurationItem> gridLayoutConfigurations, GridToBlockGridConfigContext gridBlockContext, SyncMigrationContext context, string gridAlias, bool isArea = false)
{
var contentTypeProperties = gridLayoutConfigurations.Where(configItem => configItem.Key is not null).Select(configItem =>
{
Expand All @@ -61,20 +66,29 @@ private void AddGridLayoutSettings(IEnumerable<GridSettingsConfigurationItem> gr
return null;
}
var gridSettingPropertyMigrator = _gridSettingsViewMigrators.GetMigrator(configItem.View);
var dataTypeAlias = gridSettingPropertyMigrator is not null && !gridSettingPropertyMigrator.NewDataTypeAlias.IsNullOrWhiteSpace()
? gridSettingPropertyMigrator.NewDataTypeAlias
string? migratorDataTypeAlias = gridSettingPropertyMigrator?.GetNewDataTypeAlias(gridAlias, configItem.Label);

var dataTypeAlias = !migratorDataTypeAlias.IsNullOrWhiteSpace()
? migratorDataTypeAlias
: configItem.View;
if (dataTypeAlias.IsNullOrWhiteSpace() == true)
{
_logger.LogError("No view defined for grid layout configuration in {alias}", gridAlias);
return null;
}
return new NewContentTypeProperty(configItem.Label ?? contentTypeAlias, contentTypeAlias, dataTypeAlias);

var additionalDataType = gridSettingPropertyMigrator?.GetAdditionalDataType(dataTypeAlias, configItem.Prevalues);
if (additionalDataType != null)
{
context.DataTypes.AddNewDataType(additionalDataType);
}

return new NewContentTypeProperty(configItem.Label ?? contentTypeAlias, contentTypeAlias, dataTypeAlias, orginalEditorAlias: null, configItem.Description);
}).WhereNotNull();

var alias = _conventions.LayoutSettingsContentTypeAlias(gridAlias);
var alias = isArea ? _conventions.LayoutAreaSettingsContentTypeAlias(gridAlias) : _conventions.LayoutSettingsContentTypeAlias(gridAlias);

context.ContentTypes.AddNewContentType(new NewContentTypeInfo(alias.ToGuid(), alias, alias, "icon-book color-red", "BlockGrid/settings")
context.ContentTypes.AddNewContentType(new NewContentTypeInfo(alias.ToGuid(), alias, alias, "icon-book color-red", "BlockGrid/Settings")
{
Description = alias,
IsElement = true,
Expand Down
Loading