Skip to content

Commit

Permalink
Merge pull request #75 from tcmorris/feature/crud-options
Browse files Browse the repository at this point in the history
Add options over create/update/delete
  • Loading branch information
mattbrailsford authored Mar 8, 2019
2 parents 690f30a + ac3a8ec commit 3a7b481
Show file tree
Hide file tree
Showing 15 changed files with 134 additions and 30 deletions.
41 changes: 40 additions & 1 deletion docs/_pages/02-api-04-collections.md
Original file line number Diff line number Diff line change
Expand Up @@ -317,13 +317,52 @@ Sets the collection as read only and disables any CRUD operations from being per
collectionConfig.MakeReadOnly();
````

### Disable the option to create
{: .mt}

#### DisableCreate() *: FluidityCollectionConfig<TEntityType>*
{: .signature}

Disables the option to create entities on the current collection. An entity could be created via code-behind and then only editing is allowed in the UI for example.

````csharp
// Example
collectionConfig.DisableCreate();
````

### Disable the option to update
{: .mt}

#### DisableUpdate() *: FluidityCollectionConfig<TEntityType>*
{: .signature}

Disables the option to update entities on the current collection. An entity can be created, but further editing is not allowed.

````csharp
// Example
collectionConfig.DisableUpdate();
````

### Disable the option to delete
{: .mt}

#### DisableDelete() *: FluidityCollectionConfig<TEntityType>*
{: .signature}

Disables the option to delete entities on the current collection. Useful if the data needs to be retained and visible. See also [defining a deleted flag](#defining-a-deleted-flag).

````csharp
// Example
collectionConfig.DisableDelete();
````

### Setting a view mode
{: .mt}

#### SetViewMode(FluidityViewMode viewMode) *: FluidityCollectionConfig<TEntityType>*
{: .signature}

Sets the view mode of the current collection. Opions are `Tree` or `List`. When set to `Tree` then all entities will appear as nodes in the tree. When set as `List` then entities will be hidden from the tree and show in a [list view]({{ site.baseurl }}/api/collections/list-view/) in the right hand content area.
Sets the view mode of the current collection. Options are `Tree` or `List`. When set to `Tree` then all entities will appear as nodes in the tree. When set as `List` then entities will be hidden from the tree and show in a [list view]({{ site.baseurl }}/api/collections/list-view/) in the right hand content area.

````csharp
// Example
Expand Down
13 changes: 11 additions & 2 deletions src/Fluidity/Configuration/FluidityCollectionConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,14 @@ public abstract class FluidityCollectionConfig : FluidityTreeItemConfig
protected bool _isVisibleInTree;
internal bool IsVisibleInTree => _isVisibleInTree;

protected bool _isReadOnly;
internal bool IsReadOnly => _isReadOnly;
protected bool _canCreate;
internal bool CanCreate => _canCreate;

protected bool _canUpdate;
internal bool CanUpdate => _canUpdate;

protected bool _canDelete;
internal bool CanDelete => _canDelete;

protected FluidityViewMode _viewMode;
internal FluidityViewMode ViewMode => _viewMode;
Expand Down Expand Up @@ -119,6 +125,9 @@ protected FluidityCollectionConfig(Type entityType, LambdaExpression idPropertyE
_iconSingular = iconSingular ?? "icon-folder";
_iconPlural = iconPlural ?? "icon-folder";
_isVisibleInTree = true;
_canCreate = true;
_canUpdate = true;
_canDelete = true;

_containerMenuItems = new List<MenuItem>();
_entityMenuItems = new List<MenuItem>();
Expand Down
49 changes: 47 additions & 2 deletions src/Fluidity/Configuration/FluidityCollectionConfig`T.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
// </copyright>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Fluidity.Actions;
using Fluidity.Data;
using Umbraco.Core;
using Umbraco.Web.Models.Trees;
Expand Down Expand Up @@ -219,8 +222,45 @@ public FluidityCollectionConfig<TEntityType> HideFromTree()
/// </summary>
/// <returns>The collection configuration.</returns>
public FluidityCollectionConfig<TEntityType> MakeReadOnly()
{
DisableCreate();
DisableUpdate();
DisableDelete();
return this;
}

/// <summary>
/// Disable creating entities in collection.
/// </summary>
/// <returns>The collection configuration.</returns>
public FluidityCollectionConfig<TEntityType> DisableCreate()
{
_canCreate = false;
return this;
}

/// <summary>
/// Disable updating entities in collection.
/// </summary>
/// <returns>The collection configuration.</returns>
public FluidityCollectionConfig<TEntityType> DisableUpdate()
{
_isReadOnly = true;
_canUpdate = false;
return this;
}

/// <summary>
/// Disable deleting entities in collection.
/// </summary>
/// <returns>The collection configuration.</returns>
public FluidityCollectionConfig<TEntityType> DisableDelete()
{
_canDelete = false;
if (_listView != null)
{
_listView.DefaultBulkActions.RemoveAll(x => x.GetType() == typeof(FluidityDeleteBulkAction));
}

return this;
}

Expand Down Expand Up @@ -342,7 +382,12 @@ public FluidityCollectionConfig<TEntityType> SetDateModifiedProperty(Expression<
/// <returns>The list view configuration.</returns>
public new FluidityListViewConfig<TEntityType> ListView(FluidityListViewConfig<TEntityType> listViewConfig)
{
_listView = listViewConfig;
if (_canDelete)
{
listViewConfig.DefaultBulkActions.Add(new FluidityDeleteBulkAction());
}

_listView = listViewConfig;
return listViewConfig;
}

Expand Down
1 change: 0 additions & 1 deletion src/Fluidity/Configuration/FluidityEditorFieldConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ public abstract class FluidityEditorFieldConfig
protected bool _isReadOnly;
internal bool IsReadOnly => _isReadOnly;


/// <summary>
/// Initializes a new instance of the <see cref="FluidityEditorFieldConfig"/> class.
/// </summary>
Expand Down
4 changes: 3 additions & 1 deletion src/Fluidity/Configuration/FluidityListViewConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ public abstract class FluidityListViewConfig
internal int PageSize => _pageSize;

protected List<FluidityBulkAction> _defaultBulkActions;
internal ICollection<FluidityBulkAction> DefaultBulkActions => _defaultBulkActions;

protected List<FluidityBulkAction> _bulkActions;
internal IEnumerable<FluidityBulkAction> BulkActions => _bulkActions.Concat(_defaultBulkActions);

Expand All @@ -42,7 +44,7 @@ public abstract class FluidityListViewConfig
protected FluidityListViewConfig()
{
_pageSize = 20;
_defaultBulkActions = new List<FluidityBulkAction>(new [] { new FluidityDeleteBulkAction() });
_defaultBulkActions = new List<FluidityBulkAction>();
_bulkActions = new List<FluidityBulkAction>();
_dataViews = new List<FluidityDataViewConfig>();
_dataViewsBuilder = new DefaultFluidityDataViewsBuilder(this);
Expand Down
8 changes: 5 additions & 3 deletions src/Fluidity/Web/Api/FluidityApiController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,17 +129,19 @@ public object SaveEntity([ModelBinder(typeof(FluidityEntityBinder))] FluidityEnt
}

// Get or create entity
var entity = postModel.Id != null && !postModel.Id.Equals(defaultId)
var isNew = postModel.Id == null || postModel.Id.Equals(defaultId);
var entity = !isNew
? Context.Services.EntityService.GetEntity(collectionConfig, postModel.Id)
: Context.Services.EntityService.NewEntity(collectionConfig);

// Map property values
var isEditable = isNew && collectionConfig.CanCreate || !isNew && collectionConfig.CanUpdate;
var mapper = new FluidityEntityMapper();
entity = mapper.FromPostModel(sectionConfig, collectionConfig, postModel, entity);
entity = mapper.FromPostModel(sectionConfig, collectionConfig, postModel, entity, !isEditable);

// Validate the property values (review ContentItemValidationHelper)
var validator = new FluidityEntityPostValidator();
validator.Validate(ModelState, postModel, entity, collectionConfig);
validator.Validate(ModelState, postModel, entity, collectionConfig, !isEditable);

// Check to see if model is valid
if (!ModelState.IsValid)
Expand Down
12 changes: 9 additions & 3 deletions src/Fluidity/Web/Models/FluidityCollectionDisplayModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,18 @@ public class FluidityCollectionDisplayModel
[DataMember(Name = "description")]
public string Description { get; set; }

[DataMember(Name = "isReadOnly")]
public bool IsReadOnly { get; set; }

[DataMember(Name = "isSearchable")]
public bool IsSearchable { get; set; }

[DataMember(Name = "canCreate")]
public bool CanCreate { get; set; }

[DataMember(Name = "canUpdate")]
public bool CanUpdate { get; set; }

[DataMember(Name = "canDelete")]
public bool CanDelete { get; set; }

[DataMember(Name = "hasListView")]
public bool HasListView { get; set; }

Expand Down
4 changes: 2 additions & 2 deletions src/Fluidity/Web/Models/FluidityEntityEditModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ public FluidityEntityEditModel()
[DataMember(Name = "tree", IsRequired = true)]
public string Tree { get; set; }

[DataMember(Name = "collectionIsReadOnly")]
public bool CollectionIsReadOnly { get; set; }
[DataMember(Name = "collectionIsEditable")]
public bool CollectionIsEditable { get; set; }

[DataMember(Name = "collectionNameSingular")]
public string CollectionNameSingular { get; set; }
Expand Down
6 changes: 4 additions & 2 deletions src/Fluidity/Web/Models/Mappers/FluidityCollectionMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ public FluidityCollectionDisplayModel ToDisplayModel(FluiditySectionConfig secti
NamePlural = collection.NamePlural,
IconSingular = collection.IconSingular + (!collection.IconColor.IsNullOrWhiteSpace() ? " color-" + collection.IconColor : ""),
IconPlural = collection.IconPlural + (!collection.IconColor.IsNullOrWhiteSpace() ? " color-" + collection.IconColor : ""),
Description = collection.Description,
IsReadOnly = collection.IsReadOnly,
Description = collection.Description,
IsSearchable = collection.SearchableProperties.Any(),
CanCreate = collection.CanCreate,
CanUpdate = collection.CanUpdate,
CanDelete = collection.CanDelete,
HasListView = collection.ViewMode == FluidityViewMode.List,
Path = collection.Path
};
Expand Down
10 changes: 5 additions & 5 deletions src/Fluidity/Web/Models/Mappers/FluidityEntityMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public FluidityEntityEditModel ToEditModel(FluiditySectionConfig section, Fluidi
HasNameProperty = collection.NameProperty != null,
Section = section.Alias,
Tree = section.Tree.Alias,
CollectionIsReadOnly = collection.IsReadOnly,
CollectionIsEditable = isNew && collection.CanCreate || !isNew && collection.CanUpdate,
Collection = collection.Alias,
CollectionNameSingular = collection.NameSingular,
CollectionNamePlural = collection.NamePlural,
Expand Down Expand Up @@ -151,8 +151,8 @@ public FluidityEntityEditModel ToEditModel(FluiditySectionConfig section, Fluidi
if (tab.Fields != null)
{
foreach (var field in tab.Fields)
{
var dataTypeInfo = _dataTypeHelper.ResolveDataType(field, collection.IsReadOnly);
{
var dataTypeInfo = _dataTypeHelper.ResolveDataType(field, !display.CollectionIsEditable);

dataTypeInfo.PropertyEditor.ValueEditor.ConfigureForDisplay(dataTypeInfo.PreValues);

Expand Down Expand Up @@ -232,7 +232,7 @@ public FluidityEntityEditModel ToEditModel(FluiditySectionConfig section, Fluidi
return display;
}

public object FromPostModel(FluiditySectionConfig section, FluidityCollectionConfig collection, FluidityEntityPostModel postModel, object entity)
public object FromPostModel(FluiditySectionConfig section, FluidityCollectionConfig collection, FluidityEntityPostModel postModel, object entity, bool isReadOnly)
{
var editorProps = collection.Editor.Tabs.SelectMany(x => x.Fields).ToArray();

Expand Down Expand Up @@ -272,7 +272,7 @@ public object FromPostModel(FluiditySectionConfig section, FluidityCollectionCon
additionalData.Add("cuid", ObjectExtensions.EncodeAsGuid(cuid));
additionalData.Add("puid", ObjectExtensions.EncodeAsGuid(puid));

var dataTypeInfo = _dataTypeHelper.ResolveDataType(propConfig, collection.IsReadOnly);
var dataTypeInfo = _dataTypeHelper.ResolveDataType(propConfig, isReadOnly);
var data = new ContentPropertyData(prop.Value, dataTypeInfo.PreValues, additionalData);

if (!dataTypeInfo.PropertyEditor.ValueEditor.IsReadOnly) {
Expand Down
4 changes: 2 additions & 2 deletions src/Fluidity/Web/Trees/FluidityTreeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ protected override MenuItemCollection GetMenuForNode(string id, FormDataCollecti
hasMenuItems = true;
}

if (!currentCollectionConfig.IsReadOnly)
if (currentCollectionConfig.CanDelete)
{
// We create a custom item as we need to direct all fluidity delete commands to the
// same view, where as the in built delete dialog looks for seperate views per tree
Expand All @@ -213,7 +213,7 @@ protected override MenuItemCollection GetMenuForNode(string id, FormDataCollecti
{
var hasMenuItems = false;

if (!currentCollectionConfig.IsReadOnly)
if (currentCollectionConfig.CanCreate)
{
// We create a custom item as we need to direct all fluidity create commands to the
// same view, where as the in built create dialog looks for seperate views per tree
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
label-key="buttons_returnToList">
</umb-button>

<umb-button ng-if="!content.collectionIsReadOnly"
<umb-button ng-if="content.collectionIsEditable"
type="submit"
button-style="success"
state="page.saveButtonState"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<div class="inner">

<div class="fluidity__dashboard__item-overlay">
<a ng-if="!collection.isReadOnly" href="#/{{ collection.section }}/fluidity/edit/{{collection.alias}}"><i class="icon-add"></i></a>
<a ng-if="collection.canCreate" href="#/{{ collection.section }}/fluidity/edit/{{collection.alias}}"><i class="icon-add"></i></a>
<a ng-if="collection.hasListView" href="#/{{ collection.section }}/fluidity/list/{{collection.alias}}"><i class="icon-link"></i></a>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<umb-editor-sub-header-content-left>

<!-- Create Button -->
<umb-editor-sub-header-section ng-if="collection && !collection.isReadOnly && !isAnythingSelected()">
<umb-editor-sub-header-section ng-if="collection && collection.canCreate && !isAnythingSelected()">
<div class="btn-group">
<a class="btn" href="#/{{collection.section}}/fluidity/edit/{{collection.alias}}">
<i class="{{collection.iconSingular}}"></i>
Expand Down Expand Up @@ -75,7 +75,7 @@
</umb-editor-sub-header-section>

<!-- Bulk Actions -->
<umb-editor-sub-header-section ng-if="!collection.isReadOnly && isAnythingSelected()">
<umb-editor-sub-header-section ng-if="isAnythingSelected()">

<umb-button ng-repeat="bulkAction in options.bulkActions"
type="button"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ public FluidityEntityPostValidator()
: this(new UmbracoDataTypeHelper())
{ }

public void Validate(ModelStateDictionary modelState, FluidityEntityPostModel postModel, object entity, FluidityCollectionConfig config)
public void Validate(ModelStateDictionary modelState, FluidityEntityPostModel postModel, object entity, FluidityCollectionConfig config, bool isReadOnly)
{
var configProps = config.Editor?.Tabs.SelectMany(x => x.Fields).ToArray() ?? new FluidityEditorFieldConfig[0];

if (ValidateProperties(modelState, postModel, configProps) == false) return;
if (ValidatePropertyData(modelState, postModel, configProps, config.IsReadOnly) == false) return;
if (ValidatePropertyData(modelState, postModel, configProps, isReadOnly) == false) return;
if (ValidateDataAnnotations(modelState, entity) == false) return;
}

Expand Down

0 comments on commit 3a7b481

Please sign in to comment.