Skip to content

Commit

Permalink
Add a way to hide ContentTypeDefinitionSettings (#15472)
Browse files Browse the repository at this point in the history
Co-authored-by: Zoltán Lehóczky <zoltan.lehoczky@lombiq.com>
  • Loading branch information
MikeAlhayek and Piedone authored Mar 24, 2024
1 parent ba718ab commit 5b91276
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 41 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
using OrchardCore.ContentManagement.Metadata.Models;
using OrchardCore.ContentManagement.Metadata.Settings;
using OrchardCore.ContentTypes.ViewModels;
Expand All @@ -10,16 +11,22 @@ namespace OrchardCore.ContentTypes.Editors
{
public class ContentTypeSettingsDisplayDriver : ContentTypeDefinitionDisplayDriver
{
private static readonly ContentTypeDefinitionDriverOptions _defaultOptions = new();

private readonly ContentTypeDefinitionOptions _options;

protected readonly IStringLocalizer S;

public ContentTypeSettingsDisplayDriver(IStringLocalizer<ContentTypeSettingsDisplayDriver> stringLocalizer)
public ContentTypeSettingsDisplayDriver(
IStringLocalizer<ContentTypeSettingsDisplayDriver> stringLocalizer,
IOptions<ContentTypeDefinitionOptions> options)
{
S = stringLocalizer;
_options = options.Value;
}

public override IDisplayResult Edit(ContentTypeDefinition contentTypeDefinition)
{
return Initialize<ContentTypeSettingsViewModel>("ContentTypeSettings_Edit", model =>
=> Initialize<ContentTypeSettingsViewModel>("ContentTypeSettings_Edit", model =>
{
var settings = contentTypeDefinition.GetSettings<ContentTypeSettings>();

Expand All @@ -30,34 +37,72 @@ public override IDisplayResult Edit(ContentTypeDefinition contentTypeDefinition)
model.Securable = settings.Securable;
model.Stereotype = settings.Stereotype;
model.Description = settings.Description;
model.Options = GetOptions(contentTypeDefinition, settings.Stereotype);
}).Location("Content:5");
}

public override async Task<IDisplayResult> UpdateAsync(ContentTypeDefinition contentTypeDefinition, UpdateTypeEditorContext context)
{
var model = new ContentTypeSettingsViewModel();

if (await context.Updater.TryUpdateModelAsync(model, Prefix))
{
context.Builder.Creatable(model.Creatable);
context.Builder.Listable(model.Listable);
context.Builder.Draftable(model.Draftable);
context.Builder.Versionable(model.Versionable);
context.Builder.Securable(model.Securable);
context.Builder.WithDescription(model.Description);

var stereotype = model.Stereotype?.Trim();
context.Builder.WithDescription(model.Description);
context.Builder.Stereotype(stereotype);

if (!IsAlphaNumericOrEmpty(stereotype))
{
context.Updater.ModelState.AddModelError(nameof(ContentTypeSettingsViewModel.Stereotype), S["The stereotype should be alphanumeric."]);
}

var options = GetOptions(contentTypeDefinition, stereotype);

Apply(context, model, options);
}

return Edit(contentTypeDefinition);
}

private static void Apply(UpdateTypeEditorContext context, ContentTypeSettingsViewModel model, ContentTypeDefinitionDriverOptions options)
{
if (options.ShowVersionable)
{
context.Builder.Versionable(model.Versionable);
}

if (options.ShowCreatable)
{
context.Builder.Creatable(model.Creatable);
}

if (options.ShowSecurable)
{
context.Builder.Securable(model.Securable);
}

if (options.ShowListable)
{
context.Builder.Listable(model.Listable);
}
}

private ContentTypeDefinitionDriverOptions GetOptions(ContentTypeDefinition contentTypeDefinition, string stereotype)
{
if (contentTypeDefinition.Name != null
&& _options.ContentTypes.TryGetValue(contentTypeDefinition.Name, out var typeOptions))
{
return typeOptions;
}

if (stereotype != null
&& _options.Stereotypes.TryGetValue(stereotype, out var stereotypesOptions))
{
return stereotypesOptions;
}

return _defaultOptions;
}

private static bool IsAlphaNumericOrEmpty(string value)
{
if (string.IsNullOrEmpty(value))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
using Microsoft.AspNetCore.Mvc.ModelBinding;
using OrchardCore.ContentManagement.Metadata.Models;

namespace OrchardCore.ContentTypes.ViewModels
{
public class ContentTypeSettingsViewModel
{
public bool Creatable { get; set; }

public bool Listable { get; set; }

public bool Draftable { get; set; }

public bool Versionable { get; set; }

public bool Securable { get; set; }

public string Stereotype { get; set; }

public string Description { get; set; }

[BindNever]
public ContentTypeDefinitionDriverOptions Options { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,45 +8,60 @@
<span class="hint">@T["(Optional) Description of the content type"]</span>
</div>

<div class="mb-3">
<div class="form-check">
<input type="checkbox" class="form-check-input" asp-for="Creatable">
<label class="form-check-label" asp-for="Creatable">@T["Creatable"]</label>
<span class="hint dashed">@T["Determines if an instance of this content type can be created through the UI."]</span>
@if (Model.Options.ShowCreatable)
{
<div class="mb-3">
<div class="form-check">
<input type="checkbox" class="form-check-input" asp-for="Creatable">
<label class="form-check-label" asp-for="Creatable">@T["Creatable"]</label>
<span class="hint dashed">@T["Determines if an instance of this content type can be created through the UI."]</span>
</div>
</div>
</div>
}

<div class="mb-3">
<div class="form-check">
<input type="checkbox" class="form-check-input" asp-for="Listable">
<label class="form-check-label" asp-for="Listable">@T["Listable"]</label>
<span class="hint dashed">@T["Determines if an instance of this content type can be listed through the UI."]</span>
@if (Model.Options.ShowListable)
{
<div class="mb-3">
<div class="form-check">
<input type="checkbox" class="form-check-input" asp-for="Listable">
<label class="form-check-label" asp-for="Listable">@T["Listable"]</label>
<span class="hint dashed">@T["Determines if an instance of this content type can be listed through the UI."]</span>
</div>
</div>
</div>
}

<div class="mb-3">
<div class="form-check">
<input type="checkbox" class="form-check-input" asp-for="Draftable">
<label class="form-check-label" asp-for="Draftable">@T["Draftable"]</label>
<span class="hint dashed">@T["Determines if this content type supports draft versions."]</span>
@if (Model.Options.ShowDraftable)
{
<div class="mb-3">
<div class="form-check">
<input type="checkbox" class="form-check-input" asp-for="Draftable">
<label class="form-check-label" asp-for="Draftable">@T["Draftable"]</label>
<span class="hint dashed">@T["Determines if this content type supports draft versions."]</span>
</div>
</div>
</div>
}

<div class="mb-3">
<div class="form-check">
<input type="checkbox" class="form-check-input" asp-for="Versionable">
<label class="form-check-label" asp-for="Versionable">@T["Versionable"]</label>
<span class="hint dashed">@T["Determines if this content type supports versioning."]</span>
@if (Model.Options.ShowVersionable)
{
<div class="mb-3">
<div class="form-check">
<input type="checkbox" class="form-check-input" asp-for="Versionable">
<label class="form-check-label" asp-for="Versionable">@T["Versionable"]</label>
<span class="hint dashed">@T["Determines if this content type supports versioning."]</span>
</div>
</div>
</div>
}

<div class="mb-3">
<div class="form-check">
<input type="checkbox" class="form-check-input" asp-for="Securable">
<label class="form-check-label" asp-for="Securable">@T["Securable"]</label>
<span class="hint dashed">@T["Determines if this content type can have custom permissions."]</span>
@if (Model.Options.ShowSecurable)
{
<div class="mb-3">
<div class="form-check">
<input type="checkbox" class="form-check-input" asp-for="Securable">
<label class="form-check-label" asp-for="Securable">@T["Securable"]</label>
<span class="hint dashed">@T["Determines if this content type can have custom permissions."]</span>
</div>
</div>
</div>
}

<div class="mb-3">
<div class="w-md-75 w-xl-50">
Expand Down
12 changes: 12 additions & 0 deletions src/OrchardCore.Modules/OrchardCore.CustomSettings/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
using OrchardCore.ContentManagement.Metadata.Models;
using OrchardCore.CustomSettings.Deployment;
using OrchardCore.CustomSettings.Drivers;
using OrchardCore.CustomSettings.Recipes;
Expand Down Expand Up @@ -27,6 +28,17 @@ public override void ConfigureServices(IServiceCollection services)
services.AddScoped<IAuthorizationHandler, CustomSettingsAuthorizationHandler>();

services.AddRecipeExecutionStep<CustomSettingsStep>();

services.Configure<ContentTypeDefinitionOptions>(options =>
{
options.Stereotypes.TryAdd("CustomSettings", new ContentTypeDefinitionDriverOptions
{
ShowCreatable = false,
ShowListable = false,
ShowDraftable = false,
ShowVersionable = false,
});
});
}
}

Expand Down
12 changes: 12 additions & 0 deletions src/OrchardCore.Modules/OrchardCore.Users/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using OrchardCore.Admin.Models;
using OrchardCore.ContentManagement.Metadata.Models;
using OrchardCore.Data;
using OrchardCore.Data.Migration;
using OrchardCore.Deployment;
Expand Down Expand Up @@ -459,6 +460,17 @@ public override void ConfigureServices(IServiceCollection services)
services.AddScoped<IDisplayDriver<User>, CustomUserSettingsDisplayDriver>();
services.AddScoped<IPermissionProvider, CustomUserSettingsPermissions>();
services.AddDeployment<CustomUserSettingsDeploymentSource, CustomUserSettingsDeploymentStep, CustomUserSettingsDeploymentStepDriver>();

services.Configure<ContentTypeDefinitionOptions>(options =>
{
options.Stereotypes.TryAdd("CustomUserSettings", new ContentTypeDefinitionDriverOptions
{
ShowCreatable = false,
ShowListable = false,
ShowDraftable = false,
ShowVersionable = false,
});
});
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace OrchardCore.ContentManagement.Metadata.Models;

public class ContentTypeDefinitionDriverOptions
{
public bool ShowCreatable { get; set; }

public bool ShowListable { get; set; }

public bool ShowDraftable { get; set; }

public bool ShowVersionable { get; set; }

public bool ShowSecurable { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Collections.Generic;

namespace OrchardCore.ContentManagement.Metadata.Models;

/// <summary>
/// Offers a method for configuring content type definitions to either display or conceal global settings from appearing on the UI.
/// </summary>
public class ContentTypeDefinitionOptions
{
/// <summary>
/// Configure the driver options for all content types that share the same Stereotype.
/// In this dictionary, the 'key' denotes the Stereotype, while the 'value' corresponds to the driver options.
/// </summary>
public Dictionary<string, ContentTypeDefinitionDriverOptions> Stereotypes { get; } = [];

/// <summary>
/// Configure the driver options for each content type.
/// In this dictionary, the 'key' denotes the content type, while the 'value' corresponds to the driver options.
/// </summary>
public Dictionary<string, ContentTypeDefinitionDriverOptions> ContentTypes { get; } = [];
}

0 comments on commit 5b91276

Please sign in to comment.