Migrating some more classes that are using EntityBasic

This commit is contained in:
Elitsa Marinovska
2020-10-29 12:45:35 +01:00
parent c304bf07cb
commit 77544812e6
35 changed files with 15 additions and 37 deletions

View File

@@ -0,0 +1,21 @@
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
/// <summary>
/// The permissions assigned to a content node
/// </summary>
/// <remarks>
/// The underlying <see cref="EntityBasic"/> data such as Name, etc... is that of the Content item
/// </remarks>
[DataContract(Name = "contentPermissions", Namespace = "")]
public class AssignedContentPermissions : EntityBasic
{
/// <summary>
/// The assigned permissions to the content item organized by permission group name
/// </summary>
[DataMember(Name = "permissions")]
public IDictionary<string, IEnumerable<Permission>> AssignedPermissions { get; set; }
}
}

View File

@@ -0,0 +1,38 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
/// <summary>
/// The user group permissions assigned to a content node
/// </summary>
/// <remarks>
/// The underlying <see cref="EntityBasic"/> data such as Name, etc... is that of the User Group
/// </remarks>
[DataContract(Name = "userGroupPermissions", Namespace = "")]
public class AssignedUserGroupPermissions : EntityBasic
{
/// <summary>
/// The assigned permissions for the user group organized by permission group name
/// </summary>
[DataMember(Name = "permissions")]
public IDictionary<string, IEnumerable<Permission>> AssignedPermissions { get; set; }
/// <summary>
/// The default permissions for the user group organized by permission group name
/// </summary>
[DataMember(Name = "defaultPermissions")]
public IDictionary<string, IEnumerable<Permission>> DefaultPermissions { get; set; }
public static IDictionary<string, IEnumerable<Permission>> ClonePermissions(IDictionary<string, IEnumerable<Permission>> permissions)
{
var result = new Dictionary<string, IEnumerable<Permission>>();
foreach (var permission in permissions)
{
result[permission.Key] = new List<Permission>(permission.Value.Select(x => (Permission)x.Clone()));
}
return result;
}
}
}

View File

@@ -0,0 +1,108 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using Umbraco.Core;
namespace Umbraco.Web.Models.ContentEditing
{
/// <summary>
/// A basic version of a content type
/// </summary>
/// <remarks>
/// Generally used to return the minimal amount of data about a content type
/// </remarks>
[DataContract(Name = "contentType", Namespace = "")]
public class ContentTypeBasic : EntityBasic
{
public ContentTypeBasic()
{
Blueprints = new Dictionary<int, string>();
}
/// <summary>
/// Overridden to apply our own validation attributes since this is not always required for other classes
/// </summary>
[Required]
[RegularExpression(@"^([a-zA-Z]\w.*)$", ErrorMessage = "Invalid alias")]
[DataMember(Name = "alias")]
public override string Alias { get; set; }
[DataMember(Name = "updateDate")]
[ReadOnly(true)]
public DateTime UpdateDate { get; set; }
[DataMember(Name = "createDate")]
[ReadOnly(true)]
public DateTime CreateDate { get; set; }
[DataMember(Name = "description")]
public string Description { get; set; }
[DataMember(Name = "thumbnail")]
public string Thumbnail { get; set; }
/// <summary>
/// Returns true if the icon represents a CSS class instead of a file path
/// </summary>
[DataMember(Name = "iconIsClass")]
[ReadOnly(true)]
public bool IconIsClass
{
get
{
if (Icon.IsNullOrWhiteSpace())
{
return true;
}
//if it starts with a '.' or doesn't contain a '.' at all then it is a class
return Icon.StartsWith(".") || Icon.Contains(".") == false;
}
}
/// <summary>
/// Returns the icon file path if the icon is not a class, otherwise returns an empty string
/// </summary>
[DataMember(Name = "iconFilePath")]
[ReadOnly(true)]
public string IconFilePath { get; set; }
/// <summary>
/// Returns true if the icon represents a CSS class instead of a file path
/// </summary>
[DataMember(Name = "thumbnailIsClass")]
[ReadOnly(true)]
public bool ThumbnailIsClass
{
get
{
if (Thumbnail.IsNullOrWhiteSpace())
{
return true;
}
//if it starts with a '.' or doesn't contain a '.' at all then it is a class
return Thumbnail.StartsWith(".") || Thumbnail.Contains(".") == false;
}
}
/// <summary>
/// Returns the icon file path if the icon is not a class, otherwise returns an empty string
/// </summary>
[DataMember(Name = "thumbnailFilePath")]
[ReadOnly(true)]
public string ThumbnailFilePath { get; set; }
[DataMember(Name = "blueprints")]
[ReadOnly(true)]
public IDictionary<int, string> Blueprints { get; set; }
[DataMember(Name = "isContainer")]
[ReadOnly(true)]
public bool IsContainer { get; set; }
[DataMember(Name = "isElement")]
[ReadOnly(true)]
public bool IsElement { get; set; }
}
}

View File

@@ -0,0 +1,74 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
public abstract class ContentTypeCompositionDisplay : ContentTypeBasic, INotificationModel
{
protected ContentTypeCompositionDisplay()
{
//initialize collections so at least their never null
AllowedContentTypes = new List<int>();
CompositeContentTypes = new List<string>();
Notifications = new List<BackOfficeNotification>();
}
//name, alias, icon, thumb, desc, inherited from basic
[DataMember(Name = "listViewEditorName")]
[ReadOnly(true)]
public string ListViewEditorName { get; set; }
//Allowed child types
[DataMember(Name = "allowedContentTypes")]
public IEnumerable<int> AllowedContentTypes { get; set; }
//Compositions
[DataMember(Name = "compositeContentTypes")]
public IEnumerable<string> CompositeContentTypes { get; set; }
//Locked compositions
[DataMember(Name = "lockedCompositeContentTypes")]
public IEnumerable<string> LockedCompositeContentTypes { get; set; }
[DataMember(Name = "allowAsRoot")]
public bool AllowAsRoot { get; set; }
/// <summary>
/// This is used to add custom localized messages/strings to the response for the app to use for localized UI purposes.
/// </summary>
[DataMember(Name = "notifications")]
[ReadOnly(true)]
public List<BackOfficeNotification> Notifications { get; private set; }
/// <summary>
/// This is used for validation of a content item.
/// </summary>
/// <remarks>
/// A content item can be invalid but still be saved. This occurs when there's property validation errors, we will
/// still save the item but it cannot be published. So we need a way of returning validation errors as well as the
/// updated model.
///
/// NOTE: The ProperCase is important because when we return ModeState normally it will always be proper case.
/// </remarks>
[DataMember(Name = "ModelState")]
[ReadOnly(true)]
public IDictionary<string, object> Errors { get; set; }
}
[DataContract(Name = "contentType", Namespace = "")]
public abstract class ContentTypeCompositionDisplay<TPropertyTypeDisplay> : ContentTypeCompositionDisplay
where TPropertyTypeDisplay : PropertyTypeDisplay
{
protected ContentTypeCompositionDisplay()
{
//initialize collections so at least their never null
Groups = new List<PropertyGroupDisplay<TPropertyTypeDisplay>>();
}
//Tabs
[DataMember(Name = "groups")]
public IEnumerable<PropertyGroupDisplay<TPropertyTypeDisplay>> Groups { get; set; }
}
}

View File

@@ -0,0 +1,110 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Runtime.Serialization;
using Umbraco.Core;
namespace Umbraco.Web.Models.ContentEditing
{
/// <summary>
/// Abstract model used to save content types
/// </summary>
[DataContract(Name = "contentType", Namespace = "")]
public abstract class ContentTypeSave : ContentTypeBasic, IValidatableObject
{
protected ContentTypeSave()
{
AllowedContentTypes = new List<int>();
CompositeContentTypes = new List<string>();
}
//Compositions
[DataMember(Name = "compositeContentTypes")]
public IEnumerable<string> CompositeContentTypes { get; set; }
[DataMember(Name = "allowAsRoot")]
public bool AllowAsRoot { get; set; }
//Allowed child types
[DataMember(Name = "allowedContentTypes")]
public IEnumerable<int> AllowedContentTypes { get; set; }
/// <summary>
/// Custom validation
/// </summary>
/// <param name="validationContext"></param>
/// <returns></returns>
public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (CompositeContentTypes.Any(x => x.IsNullOrWhiteSpace()))
yield return new ValidationResult("Composite Content Type value cannot be null", new[] { "CompositeContentTypes" });
}
}
/// <summary>
/// Abstract model used to save content types
/// </summary>
/// <typeparam name="TPropertyType"></typeparam>
[DataContract(Name = "contentType", Namespace = "")]
public abstract class ContentTypeSave<TPropertyType> : ContentTypeSave
where TPropertyType : PropertyTypeBasic
{
protected ContentTypeSave()
{
Groups = new List<PropertyGroupBasic<TPropertyType>>();
}
/// <summary>
/// A rule for defining how a content type can be varied
/// </summary>
/// <remarks>
/// This is only supported on document types right now but in the future it could be media types too
/// </remarks>
[DataMember(Name = "allowCultureVariant")]
public bool AllowCultureVariant { get; set; }
[DataMember(Name = "allowSegmentVariant")]
public bool AllowSegmentVariant { get; set; }
//Tabs
[DataMember(Name = "groups")]
public IEnumerable<PropertyGroupBasic<TPropertyType>> Groups { get; set; }
/// <summary>
/// Custom validation
/// </summary>
/// <param name="validationContext"></param>
/// <returns></returns>
public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
foreach (var validationResult in base.Validate(validationContext))
{
yield return validationResult;
}
var duplicateGroups = Groups.GroupBy(x => x.Name).Where(x => x.Count() > 1).ToArray();
if (duplicateGroups.Any())
{
//we need to return the field name with an index so it's wired up correctly
var lastIndex = Groups.IndexOf(duplicateGroups.Last().Last());
yield return new ValidationResult("Duplicate group names not allowed", new[]
{
$"Groups[{lastIndex}].Name"
});
}
var duplicateProperties = Groups.SelectMany(x => x.Properties).Where(x => x.Inherited == false).GroupBy(x => x.Alias).Where(x => x.Count() > 1).ToArray();
if (duplicateProperties.Any())
{
//we need to return the field name with an index so it's wired up correctly
var lastProperty = duplicateProperties.Last().Last();
var propertyGroup = Groups.Single(x => x.Properties.Contains(lastProperty));
yield return new ValidationResult("Duplicate property aliases not allowed: " + lastProperty.Alias, new[]
{
$"Groups[{propertyGroup.SortOrder}].Properties[{lastProperty.SortOrder}].Alias"
});
}
}
}
}

View File

@@ -0,0 +1,27 @@
using System.ComponentModel;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
/// <summary>
/// The basic data type information
/// </summary>
[DataContract(Name = "dataType", Namespace = "")]
public class DataTypeBasic : EntityBasic
{
/// <summary>
/// Whether or not this is a system data type, in which case it cannot be deleted
/// </summary>
[DataMember(Name = "isSystem")]
[ReadOnly(true)]
public bool IsSystemDataType { get; set; }
[DataMember(Name = "group")]
[ReadOnly(true)]
public string Group { get; set; }
[DataMember(Name = "hasPrevalues")]
[ReadOnly(true)]
public bool HasPrevalues { get; set; }
}
}

View File

@@ -0,0 +1,37 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
/// <summary>
/// Represents a data type that is being edited
/// </summary>
[DataContract(Name = "dataType", Namespace = "")]
public class DataTypeDisplay : DataTypeBasic, INotificationModel
{
public DataTypeDisplay()
{
Notifications = new List<BackOfficeNotification>();
}
/// <summary>
/// The alias of the property editor
/// </summary>
[DataMember(Name = "selectedEditor", IsRequired = true)]
[Required]
public string SelectedEditor { get; set; }
[DataMember(Name = "availableEditors")]
public IEnumerable<PropertyEditorBasic> AvailableEditors { get; set; }
[DataMember(Name = "preValues")]
public IEnumerable<DataTypeConfigurationFieldDisplay> PreValues { get; set; }
/// <summary>
/// This is used to add custom localized messages/strings to the response for the app to use for localized UI purposes.
/// </summary>
[DataMember(Name = "notifications")]
public List<BackOfficeNotification> Notifications { get; private set; }
}
}

View File

@@ -0,0 +1,36 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
[DataContract(Name = "dataTypeReferences", Namespace = "")]
public class DataTypeReferences
{
[DataMember(Name = "documentTypes")]
public IEnumerable<ContentTypeReferences> DocumentTypes { get; set; } = Enumerable.Empty<ContentTypeReferences>();
[DataMember(Name = "mediaTypes")]
public IEnumerable<ContentTypeReferences> MediaTypes { get; set; } = Enumerable.Empty<ContentTypeReferences>();
[DataMember(Name = "memberTypes")]
public IEnumerable<ContentTypeReferences> MemberTypes { get; set; } = Enumerable.Empty<ContentTypeReferences>();
[DataContract(Name = "contentType", Namespace = "")]
public class ContentTypeReferences : EntityBasic
{
[DataMember(Name = "properties")]
public object Properties { get; set; }
[DataContract(Name = "property", Namespace = "")]
public class PropertyTypeReferences
{
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "alias")]
public string Alias { get; set; }
}
}
}
}

View File

@@ -0,0 +1,50 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Web.Models.ContentEditing
{
/// <summary>
/// Represents a datatype model for editing.
/// </summary>
[DataContract(Name = "dataType", Namespace = "")]
public class DataTypeSave : EntityBasic
{
/// <summary>
/// Gets or sets the action to perform.
/// </summary>
/// <remarks>
/// Some values (publish) are illegal here.
/// </remarks>
[DataMember(Name = "action", IsRequired = true)]
[Required]
public ContentSaveAction Action { get; set; }
/// <summary>
/// Gets or sets the datatype editor.
/// </summary>
[DataMember(Name = "selectedEditor", IsRequired = true)]
[Required]
public string EditorAlias { get; set; }
/// <summary>
/// Gets or sets the datatype configuration fields.
/// </summary>
[DataMember(Name = "preValues")]
public IEnumerable<DataTypeConfigurationFieldSave> ConfigurationFields { get; set; }
/// <summary>
/// Gets or sets the persisted data type.
/// </summary>
[IgnoreDataMember]
public IDataType PersistedDataType { get; set; }
/// <summary>
/// Gets or sets the property editor.
/// </summary>
[IgnoreDataMember]
public IDataEditor PropertyEditor { get; set; }
}
}

View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
/// <summary>
/// The dictionary display model
/// </summary>
[DataContract(Name = "dictionary", Namespace = "")]
public class DictionaryDisplay : EntityBasic, INotificationModel
{
/// <summary>
/// Initializes a new instance of the <see cref="DictionaryDisplay"/> class.
/// </summary>
public DictionaryDisplay()
{
Notifications = new List<BackOfficeNotification>();
Translations = new List<DictionaryTranslationDisplay>();
}
/// <inheritdoc />
/// <summary>
/// This is used to add custom localized messages/strings to the response for the app to use for localized UI purposes.
/// </summary>
[DataMember(Name = "notifications")]
public List<BackOfficeNotification> Notifications { get; private set; }
/// <summary>
/// Gets or sets the parent id.
/// </summary>
[DataMember(Name = "parentId")]
public new Guid ParentId { get; set; }
/// <summary>
/// Gets the translations.
/// </summary>
[DataMember(Name = "translations")]
public List<DictionaryTranslationDisplay> Translations { get; private set; }
}
}

View File

@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
/// <summary>
/// Dictionary Save model
/// </summary>
[DataContract(Name = "dictionary", Namespace = "")]
public class DictionarySave : EntityBasic
{
/// <summary>
/// Initializes a new instance of the <see cref="DictionarySave"/> class.
/// </summary>
public DictionarySave()
{
Translations = new List<DictionaryTranslationSave>();
}
/// <summary>
/// Gets or sets a value indicating whether name is dirty.
/// </summary>
[DataMember(Name = "nameIsDirty")]
public bool NameIsDirty { get; set; }
/// <summary>
/// Gets the translations.
/// </summary>
[DataMember(Name = "translations")]
public List<DictionaryTranslationSave> Translations { get; private set; }
/// <summary>
/// Gets or sets the parent id.
/// </summary>
[DataMember(Name = "parentId")]
public new Guid ParentId { get; set; }
}
}

View File

@@ -0,0 +1,34 @@
using System.Collections.Generic;
using System.Runtime.Serialization;
using Umbraco.Core.Models.ContentEditing;
namespace Umbraco.Web.Models.ContentEditing
{
[DataContract(Name = "contentType", Namespace = "")]
public class DocumentTypeDisplay : ContentTypeCompositionDisplay<PropertyTypeDisplay>
{
public DocumentTypeDisplay()
{
//initialize collections so at least their never null
AllowedTemplates = new List<EntityBasic>();
}
//name, alias, icon, thumb, desc, inherited from the content type
// Templates
[DataMember(Name = "allowedTemplates")]
public IEnumerable<EntityBasic> AllowedTemplates { get; set; }
[DataMember(Name = "defaultTemplate")]
public EntityBasic DefaultTemplate { get; set; }
[DataMember(Name = "allowCultureVariant")]
public bool AllowCultureVariant { get; set; }
[DataMember(Name = "allowSegmentVariant")]
public bool AllowSegmentVariant { get; set; }
[DataMember(Name = "apps")]
public IEnumerable<ContentApp> ContentApps { get; set; }
}
}

View File

@@ -0,0 +1,43 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Runtime.Serialization;
using Umbraco.Core;
namespace Umbraco.Web.Models.ContentEditing
{
/// <summary>
/// Model used to save a document type
/// </summary>
[DataContract(Name = "contentType", Namespace = "")]
public class DocumentTypeSave : ContentTypeSave<PropertyTypeBasic>
{
/// <summary>
/// The list of allowed templates to assign (template alias)
/// </summary>
[DataMember(Name = "allowedTemplates")]
public IEnumerable<string> AllowedTemplates { get; set; }
/// <summary>
/// The default template to assign (template alias)
/// </summary>
[DataMember(Name = "defaultTemplate")]
public string DefaultTemplate { get; set; }
/// <summary>
/// Custom validation
/// </summary>
/// <param name="validationContext"></param>
/// <returns></returns>
public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (AllowedTemplates.Any(x => x.IsNullOrWhiteSpace()))
yield return new ValidationResult("Template value cannot be null", new[] { "AllowedTemplates" });
foreach (var v in base.Validate(validationContext))
{
yield return v;
}
}
}
}

View File

@@ -0,0 +1,67 @@
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
/// <summary>
/// The macro display model
/// </summary>
[DataContract(Name = "dictionary", Namespace = "")]
public class MacroDisplay : EntityBasic, INotificationModel
{
/// <summary>
/// Initializes a new instance of the <see cref="MacroDisplay"/> class.
/// </summary>
public MacroDisplay()
{
Notifications = new List<BackOfficeNotification>();
Parameters = new List<MacroParameterDisplay>();
}
/// <inheritdoc />
[DataMember(Name = "notifications")]
public List<BackOfficeNotification> Notifications { get; }
/// <summary>
/// Gets or sets a value indicating whether the macro can be used in a rich text editor.
/// </summary>
[DataMember(Name = "useInEditor")]
public bool UseInEditor { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the macro should be rendered a rich text editor.
/// </summary>
[DataMember(Name = "renderInEditor")]
public bool RenderInEditor { get; set; }
/// <summary>
/// Gets or sets the cache period.
/// </summary>
[DataMember(Name = "cachePeriod")]
public int CachePeriod { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the macro should be cached by page
/// </summary>
[DataMember(Name = "cacheByPage")]
public bool CacheByPage { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the macro should be cached by user
/// </summary>
[DataMember(Name = "cacheByUser")]
public bool CacheByUser { get; set; }
/// <summary>
/// Gets or sets the view.
/// </summary>
[DataMember(Name = "view")]
public string View { get; set; }
/// <summary>
/// Gets or sets the parameters.
/// </summary>
[DataMember(Name = "parameters")]
public IEnumerable<MacroParameterDisplay> Parameters { get; set; }
}
}

View File

@@ -0,0 +1,11 @@
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
[DataContract(Name = "contentType", Namespace = "")]
public class MediaTypeDisplay : ContentTypeCompositionDisplay<PropertyTypeDisplay>
{
[DataMember(Name = "isSystemMediaType")]
public bool IsSystemMediaType { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
/// <summary>
/// Model used to save a media type
/// </summary>
[DataContract(Name = "contentType", Namespace = "")]
public class MediaTypeSave : ContentTypeSave<PropertyTypeBasic>
{
}
}

View File

@@ -0,0 +1,20 @@
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
[DataContract(Name = "memberGroup", Namespace = "")]
public class MemberGroupDisplay : EntityBasic, INotificationModel
{
public MemberGroupDisplay()
{
Notifications = new List<BackOfficeNotification>();
}
/// <summary>
/// This is used to add custom localized messages/strings to the response for the app to use for localized UI purposes.
/// </summary>
[DataMember(Name = "notifications")]
public List<BackOfficeNotification> Notifications { get; private set; }
}
}

View File

@@ -0,0 +1,9 @@
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
[DataContract(Name = "memberGroup", Namespace = "")]
public class MemberGroupSave : EntityBasic
{
}
}

View File

@@ -0,0 +1,9 @@
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
[DataContract(Name = "contentType", Namespace = "")]
public class MemberTypeDisplay : ContentTypeCompositionDisplay<MemberPropertyTypeDisplay>
{
}
}

View File

@@ -0,0 +1,9 @@
namespace Umbraco.Web.Models.ContentEditing
{
/// <summary>
/// Model used to save a member type
/// </summary>
public class MemberTypeSave : ContentTypeSave<MemberPropertyTypeBasic>
{
}
}

View File

@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
[DataContract(Name = "relationType", Namespace = "")]
public class RelationTypeDisplay : EntityBasic, INotificationModel
{
public RelationTypeDisplay()
{
Notifications = new List<BackOfficeNotification>();
}
[DataMember(Name = "isSystemRelationType")]
public bool IsSystemRelationType { get; set; }
/// <summary>
/// Gets or sets a boolean indicating whether the RelationType is Bidirectional (true) or Parent to Child (false)
/// </summary>
[DataMember(Name = "isBidirectional", IsRequired = true)]
public bool IsBidirectional { get; set; }
/// <summary>
/// Gets or sets the Parents object type id
/// </summary>
/// <remarks>Corresponds to the NodeObjectType in the umbracoNode table</remarks>
[DataMember(Name = "parentObjectType", IsRequired = true)]
public Guid? ParentObjectType { get; set; }
/// <summary>
/// Gets or sets the Parent's object type name.
/// </summary>
[DataMember(Name = "parentObjectTypeName")]
[ReadOnly(true)]
public string ParentObjectTypeName { get; set; }
/// <summary>
/// Gets or sets the Child's object type id
/// </summary>
/// <remarks>Corresponds to the NodeObjectType in the umbracoNode table</remarks>
[DataMember(Name = "childObjectType", IsRequired = true)]
public Guid? ChildObjectType { get; set; }
/// <summary>
/// Gets or sets the Child's object type name.
/// </summary>
[DataMember(Name = "childObjectTypeName")]
[ReadOnly(true)]
public string ChildObjectTypeName { get; set; }
/// <summary>
/// This is used to add custom localized messages/strings to the response for the app to use for localized UI purposes.
/// </summary>
[DataMember(Name = "notifications")]
public List<BackOfficeNotification> Notifications { get; private set; }
}
}

View File

@@ -0,0 +1,27 @@
using System;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
[DataContract(Name = "relationType", Namespace = "")]
public class RelationTypeSave : EntityBasic
{
/// <summary>
/// Gets or sets a boolean indicating whether the RelationType is Bidirectional (true) or Parent to Child (false)
/// </summary>
[DataMember(Name = "isBidirectional", IsRequired = true)]
public bool IsBidirectional { get; set; }
/// <summary>
/// Gets or sets the parent object type ID.
/// </summary>
[DataMember(Name = "parentObjectType", IsRequired = false)]
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; }
}
}

View File

@@ -0,0 +1,14 @@
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
[DataContract(Name = "searchResult", Namespace = "")]
public class SearchResultEntity : EntityBasic
{
/// <summary>
/// The score of the search result
/// </summary>
[DataMember(Name = "score")]
public float Score { get; set; }
}
}

View File

@@ -0,0 +1,34 @@
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
/// <summary>
/// Represents a search result by entity type
/// </summary>
[DataContract(Name = "searchResult", Namespace = "")]
public class TreeSearchResult
{
[DataMember(Name = "appAlias")]
public string AppAlias { get; set; }
[DataMember(Name = "treeAlias")]
public string TreeAlias { get; set; }
/// <summary>
/// This is optional but if specified should be the name of an angular service to format the search result.
/// </summary>
[DataMember(Name = "jsSvc")]
public string JsFormatterService { get; set; }
/// <summary>
/// This is optional but if specified should be the name of a method on the jsSvc angular service to use, if not
/// specified than it will expect the method to be called `format(searchResult, appAlias, treeAlias)`
/// </summary>
[DataMember(Name = "jsMethod")]
public string JsFormatterMethod { get; set; }
[DataMember(Name = "results")]
public IEnumerable<SearchResultEntity> Results { get; set; }
}
}

View File

@@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.Serialization;
using Umbraco.Core.Models.Membership;
namespace Umbraco.Web.Models.ContentEditing
{
/// <summary>
/// The user model used for paging and listing users in the UI
/// </summary>
[DataContract(Name = "user", Namespace = "")]
[ReadOnly(true)]
public class UserBasic : EntityBasic, INotificationModel
{
public UserBasic()
{
Notifications = new List<BackOfficeNotification>();
UserGroups = new List<UserGroupBasic>();
}
[DataMember(Name = "username")]
public string Username { get; set; }
/// <summary>
/// The MD5 lowercase hash of the email which can be used by gravatar
/// </summary>
[DataMember(Name = "emailHash")]
public string EmailHash { get; set; }
[DataMember(Name = "lastLoginDate")]
public DateTime? LastLoginDate { get; set; }
/// <summary>
/// Returns a list of different size avatars
/// </summary>
[DataMember(Name = "avatars")]
public string[] Avatars { get; set; }
[DataMember(Name = "userState")]
public UserState UserState { get; set; }
[DataMember(Name = "culture", IsRequired = true)]
public string Culture { get; set; }
[DataMember(Name = "email", IsRequired = true)]
public string Email { get; set; }
/// <summary>
/// The list of group aliases assigned to the user
/// </summary>
[DataMember(Name = "userGroups")]
public IEnumerable<UserGroupBasic> UserGroups { get; set; }
/// <summary>
/// This is an info flag to denote if this object is the equivalent of the currently logged in user
/// </summary>
[DataMember(Name = "isCurrentUser")]
[ReadOnly(true)]
public bool IsCurrentUser { get; set; }
/// <summary>
/// This is used to add custom localized messages/strings to the response for the app to use for localized UI purposes.
/// </summary>
[DataMember(Name = "notifications")]
public List<BackOfficeNotification> Notifications { get; private set; }
}
}

View File

@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
/// <summary>
/// Represents a user that is being edited
/// </summary>
[DataContract(Name = "user", Namespace = "")]
[ReadOnly(true)]
public class UserDisplay : UserBasic
{
public UserDisplay()
{
AvailableCultures = new Dictionary<string, string>();
StartContentIds = new List<EntityBasic>();
StartMediaIds = new List<EntityBasic>();
Navigation = new List<EditorNavigation>();
}
[DataMember(Name = "navigation")]
[ReadOnly(true)]
public IEnumerable<EditorNavigation> Navigation { get; set; }
/// <summary>
/// Gets the available cultures (i.e. to populate a drop down)
/// The key is the culture stored in the database, the value is the Name
/// </summary>
[DataMember(Name = "availableCultures")]
public IDictionary<string, string> AvailableCultures { get; set; }
[DataMember(Name = "startContentIds")]
public IEnumerable<EntityBasic> StartContentIds { get; set; }
[DataMember(Name = "startMediaIds")]
public IEnumerable<EntityBasic> StartMediaIds { get; set; }
/// <summary>
/// If the password is reset on save, this value will be populated
/// </summary>
[DataMember(Name = "resetPasswordValue")]
[ReadOnly(true)]
public string ResetPasswordValue { get; set; }
/// <summary>
/// A readonly value showing the user's current calculated start content ids
/// </summary>
[DataMember(Name = "calculatedStartContentIds")]
[ReadOnly(true)]
public IEnumerable<EntityBasic> CalculatedStartContentIds { get; set; }
/// <summary>
/// A readonly value showing the user's current calculated start media ids
/// </summary>
[DataMember(Name = "calculatedStartMediaIds")]
[ReadOnly(true)]
public IEnumerable<EntityBasic> CalculatedStartMediaIds { get; set; }
[DataMember(Name = "failedPasswordAttempts")]
[ReadOnly(true)]
public int FailedPasswordAttempts { get; set; }
[DataMember(Name = "lastLockoutDate")]
[ReadOnly(true)]
public DateTime LastLockoutDate { get; set; }
[DataMember(Name = "lastPasswordChangeDate")]
[ReadOnly(true)]
public DateTime LastPasswordChangeDate { get; set; }
[DataMember(Name = "createDate")]
[ReadOnly(true)]
public DateTime CreateDate { get; set; }
[DataMember(Name = "updateDate")]
[ReadOnly(true)]
public DateTime UpdateDate { get; set; }
}
}

View File

@@ -0,0 +1,43 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
[DataContract(Name = "userGroup", Namespace = "")]
public class UserGroupBasic : EntityBasic, INotificationModel
{
public UserGroupBasic()
{
Notifications = new List<BackOfficeNotification>();
Sections = Enumerable.Empty<Section>();
}
/// <summary>
/// This is used to add custom localized messages/strings to the response for the app to use for localized UI purposes.
/// </summary>
[DataMember(Name = "notifications")]
public List<BackOfficeNotification> Notifications { get; private set; }
[DataMember(Name = "sections")]
public IEnumerable<Section> Sections { get; set; }
[DataMember(Name = "contentStartNode")]
public EntityBasic ContentStartNode { get; set; }
[DataMember(Name = "mediaStartNode")]
public EntityBasic MediaStartNode { get; set; }
/// <summary>
/// The number of users assigned to this group
/// </summary>
[DataMember(Name = "userCount")]
public int UserCount { get; set; }
/// <summary>
/// Is the user group a system group e.g. "Administrators", "Sensitive data" or "Translators"
/// </summary>
[DataMember(Name = "isSystemUserGroup")]
public bool IsSystemUserGroup { get; set; }
}
}

View File

@@ -0,0 +1,31 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
[DataContract(Name = "userGroup", Namespace = "")]
public class UserGroupDisplay : UserGroupBasic
{
public UserGroupDisplay()
{
Users = Enumerable.Empty<UserBasic>();
AssignedPermissions = Enumerable.Empty<AssignedContentPermissions>();
}
[DataMember(Name = "users")]
public IEnumerable<UserBasic> Users { get; set; }
/// <summary>
/// The default permissions for the user group organized by permission group name
/// </summary>
[DataMember(Name = "defaultPermissions")]
public IDictionary<string, IEnumerable<Permission>> DefaultPermissions { get; set; }
/// <summary>
/// The assigned permissions for the user group organized by permission group name
/// </summary>
[DataMember(Name = "assignedPermissions")]
public IEnumerable<AssignedContentPermissions> AssignedPermissions { get; set; }
}
}

View File

@@ -0,0 +1,77 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Runtime.Serialization;
using Umbraco.Core;
using Umbraco.Core.Models.Membership;
namespace Umbraco.Web.Models.ContentEditing
{
[DataContract(Name = "userGroup", Namespace = "")]
public class UserGroupSave : EntityBasic, IValidatableObject
{
/// <summary>
/// The action to perform when saving this user group
/// </summary>
/// <remarks>
/// If either of the Publish actions are specified an exception will be thrown.
/// </remarks>
[DataMember(Name = "action", IsRequired = true)]
[Required]
public ContentSaveAction Action { get; set; }
[DataMember(Name = "alias", IsRequired = true)]
[Required]
public override string Alias { get; set; }
[DataMember(Name = "sections")]
public IEnumerable<string> Sections { get; set; }
[DataMember(Name = "users")]
public IEnumerable<int> Users { get; set; }
[DataMember(Name = "startContentId")]
public int? StartContentId { get; set; }
[DataMember(Name = "startMediaId")]
public int? StartMediaId { get; set; }
/// <summary>
/// The list of letters (permission codes) to assign as the default for the user group
/// </summary>
[DataMember(Name = "defaultPermissions")]
public IEnumerable<string> DefaultPermissions { get; set; }
/// <summary>
/// The assigned permissions for content
/// </summary>
/// <remarks>
/// The key is the content id and the list is the list of letters (permission codes) to assign
/// </remarks>
[DataMember(Name = "assignedPermissions")]
public IDictionary<int, IEnumerable<string>> AssignedPermissions { get; set; }
/// <summary>
/// The real persisted user group
/// </summary>
[IgnoreDataMember]
public IUserGroup PersistedUserGroup { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (DefaultPermissions.Any(x => x.IsNullOrWhiteSpace()))
{
yield return new ValidationResult("A permission value cannot be null or empty", new[] { "Permissions" });
}
foreach (var assignedPermission in AssignedPermissions)
{
foreach (var permission in assignedPermission.Value)
{
if (permission.IsNullOrWhiteSpace())
yield return new ValidationResult("A permission value cannot be null or empty", new[] { "AssignedPermissions" });
}
}
}
}
}

View File

@@ -0,0 +1,41 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Runtime.Serialization;
using Umbraco.Composing;
using Umbraco.Core;
namespace Umbraco.Web.Models.ContentEditing
{
/// <summary>
/// Represents the data used to invite a user
/// </summary>
[DataContract(Name = "user", Namespace = "")]
public class UserInvite : EntityBasic, IValidatableObject
{
[DataMember(Name = "userGroups")]
[Required]
public IEnumerable<string> UserGroups { get; set; }
[DataMember(Name = "email", IsRequired = true)]
[Required]
[EmailAddress]
public string Email { get; set; }
[DataMember(Name = "username")]
public string Username { get; set; }
[DataMember(Name = "message")]
public string Message { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (UserGroups.Any() == false)
yield return new ValidationResult("A user must be assigned to at least one group", new[] { nameof(UserGroups) });
// TODO: this will need another way of retrieving this setting if and when Configs are removed from Current.
if (Current.SecuritySettings.UsernameIsEmail == false && Username.IsNullOrWhiteSpace())
yield return new ValidationResult("A username cannot be empty", new[] { nameof(Username) });
}
}
}

View File

@@ -0,0 +1,55 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
/// <summary>
/// Represents the data used to persist a user
/// </summary>
/// <remarks>
/// This will be different from the model used to display a user and we don't want to "Overpost" data back to the server,
/// and there will most likely be different bits of data required for updating passwords which will be different from the
/// data used to display vs save
/// </remarks>
[DataContract(Name = "user", Namespace = "")]
public class UserSave : EntityBasic, IValidatableObject
{
[DataMember(Name = "changePassword", IsRequired = true)]
public ChangingPasswordModel ChangePassword { get; set; }
[DataMember(Name = "id", IsRequired = true)]
[Required]
public new int Id { get; set; }
[DataMember(Name = "username", IsRequired = true)]
[Required]
public string Username { get; set; }
[DataMember(Name = "culture", IsRequired = true)]
[Required]
public string Culture { get; set; }
[DataMember(Name = "email", IsRequired = true)]
[Required]
[EmailAddress]
public string Email { get; set; }
[DataMember(Name = "userGroups")]
[Required]
public IEnumerable<string> UserGroups { get; set; }
[DataMember(Name = "startContentIds")]
public int[] StartContentIds { get; set; }
[DataMember(Name = "startMediaIds")]
public int[] StartMediaIds { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (UserGroups.Any() == false)
yield return new ValidationResult("A user must be assigned to at least one group", new[] { "UserGroups" });
}
}
}