Skip to content

Commit

Permalink
Merge pull request #31 from jcdcdev/dev/v10
Browse files Browse the repository at this point in the history
10.1.0
  • Loading branch information
jcdcdev authored Aug 31, 2024
2 parents d5caa5a + c50c299 commit 3a34e56
Show file tree
Hide file tree
Showing 16 changed files with 284 additions and 50 deletions.
36 changes: 25 additions & 11 deletions .github/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
[![Umbraco Marketplace](https://img.shields.io/badge/Umbraco-Marketplace-%233544B1?style=flat&logo=umbraco)](https://marketplace.umbraco.com/package/umbraco.community.backofficeorganiser)
[![GitHub License](https://img.shields.io/github/license/jcdcdev/Umbraco.Community.BackOfficeOrganiser?color=8AB803&label=License&logo=github)](https://github.com/jcdcdev/Umbraco.Community.BackOfficeOrganiser/blob/main/LICENSE)
[![NuGet Downloads](https://img.shields.io/nuget/dt/Umbraco.Community.BackOfficeOrganiser?color=cc9900&label=Downloads&logo=nuget)](https://www.nuget.org/packages/Umbraco.Community.BackOfficeOrganiser/)
[![Project Website](https://img.shields.io/badge/Project%20Website-jcdc.dev-jcdcdev?style=flat&color=3c4834&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0id2hpdGUiIGNsYXNzPSJiaSBiaS1wYy1kaXNwbGF5IiB2aWV3Qm94PSIwIDAgMTYgMTYiPgogIDxwYXRoIGQ9Ik04IDFhMSAxIDAgMCAxIDEtMWg2YTEgMSAwIDAgMSAxIDF2MTRhMSAxIDAgMCAxLTEgMUg5YTEgMSAwIDAgMS0xLTF6bTEgMTMuNWEuNS41IDAgMSAwIDEgMCAuNS41IDAgMCAwLTEgMG0yIDBhLjUuNSAwIDEgMCAxIDAgLjUuNSAwIDAgMC0xIDBNOS41IDFhLjUuNSAwIDAgMCAwIDFoNWEuNS41IDAgMCAwIDAtMXpNOSAzLjVhLjUuNSAwIDAgMCAuNS41aDVhLjUuNSAwIDAgMCAwLTFoLTVhLjUuNSAwIDAgMC0uNS41TTEuNSAyQTEuNSAxLjUgMCAwIDAgMCAzLjV2N0ExLjUgMS41IDAgMCAwIDEuNSAxMkg2djJoLS41YS41LjUgMCAwIDAgMCAxSDd2LTRIMS41YS41LjUgMCAwIDEtLjUtLjV2LTdhLjUuNSAwIDAgMSAuNS0uNUg3VjJ6Ii8+Cjwvc3ZnPg==)](https://jcdc.dev/umbraco-packages/back-office-organiser)

Is your backoffice a bit untidy?

- Single-click (and opinionated) organiser for
- Document Types
- Media Types
- Member Types
- Data Types
- Document Types
- Media Types
- Member Types
- Data Types
- Automatically sorts on save (configurable)

![A screenshot of the Back Office Organiser in action](https://raw.githubusercontent.com/jcdcdev/Umbraco.Community.BackOfficeOrganiser/main/docs/screenshots/backoffice.png)

Expand All @@ -27,13 +29,25 @@ Is your backoffice a bit untidy?
Add the following to your `appsettings.json` file

```JSON
"BackOfficeOrganiser": {
"DataTypes": {
"InternalFolderName": "Internal",
"ThirdPartyFolderName": "Third Party",
"CustomFolderName": "Custom"
}
}
{
"BackOfficeOrganiser": {
"DataTypes": {
"InternalFolderName": "Internal",
"ThirdPartyFolderName": "Third Party",
"CustomFolderName": "Custom",
"OrganiseOnSave": true
},
"ContentTypes": {
"OrganiseOnSave": true
},
"MediaTypes": {
"OrganiseOnSave": true
},
"MemberTypes": {
"OrganiseOnSave": true
}
}
}
```

## Extending
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Community.BackOfficeOrganiser.Models;
using Umbraco.Community.BackOfficeOrganiser.Organisers.ContentTypes;
using Umbraco.Community.BackOfficeOrganiser.Organisers.DataTypes;
using Umbraco.Community.BackOfficeOrganiser.Organisers.MediaTypes;
using Umbraco.Community.BackOfficeOrganiser.Organisers.MemberTypes;

namespace Umbraco.Community.BackOfficeOrganiser.Composing;

public class BackofficeOrganiserNotificationHandler :
INotificationHandler<DataTypeSavedNotification>,
INotificationHandler<ContentTypeSavedNotification>,
INotificationHandler<MemberTypeSavedNotification>,
INotificationHandler<MediaTypeSavedNotification>
{
private readonly ContentTypeOrganiser _contentTypeOrganiser;
private readonly DataTypeOrganiser _dataTypeOrganiser;
private readonly MediaTypeOrganiser _mediaTypeOrganiser;
private readonly MemberTypeOrganiser _memberTypeOrganiser;
private readonly BackOfficeOrganiserOptions _options;

public BackofficeOrganiserNotificationHandler(
DataTypeOrganiser dataTypeOrganiser,
ContentTypeOrganiser contentTypeOrganiser,
MediaTypeOrganiser mediaTypeOrganiser,
MemberTypeOrganiser memberTypeOrganiser,
IOptions<BackOfficeOrganiserOptions> options)
{
_dataTypeOrganiser = dataTypeOrganiser;
_contentTypeOrganiser = contentTypeOrganiser;
_mediaTypeOrganiser = mediaTypeOrganiser;
_memberTypeOrganiser = memberTypeOrganiser;
_options = options.Value;
}

public void Handle(ContentTypeSavedNotification notification)
{
if (!_options.ContentTypes.OrganiseOnSave)
{
return;
}

foreach (var item in notification.SavedEntities)
{
_contentTypeOrganiser.Organise(item);
}
}

public void Handle(DataTypeSavedNotification notification)
{
if (!_options.DataTypes.OrganiseOnSave)
{
return;
}

foreach (var dataType in notification.SavedEntities)
{
_dataTypeOrganiser.Organise(dataType);
}
}

public void Handle(MediaTypeSavedNotification notification)
{
if (!_options.MediaTypes.OrganiseOnSave)
{
return;
}

foreach (var item in notification.SavedEntities)
{
_mediaTypeOrganiser.Organise(item);
}
}

public void Handle(MemberTypeSavedNotification notification)
{
if (!_options.MemberTypes.OrganiseOnSave)
{
return;
}

foreach (var item in notification.SavedEntities)
{
_memberTypeOrganiser.Organise(item);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Community.BackOfficeOrganiser.Models;
using Umbraco.Community.BackOfficeOrganiser.Organisers.ContentTypes;
using Umbraco.Community.BackOfficeOrganiser.Organisers.DataTypes;
Expand All @@ -27,8 +28,14 @@ public void Compose(IUmbracoBuilder builder)
builder.ManifestFilters().Append<ManifestFilter>();

builder.DataTypeOrganiseActions().Append<DefaultDataTypeOrganiseAction>();
builder.ContentTypeOrganiseActions().Append<ElementTypeOrganiser>();
builder.ContentTypeOrganiseActions().Append<DefaultContentTypeOrganiseAction>();
builder.MediaTypeOrganiseActions().Append<DefaultMediaTypeOrganiseAction>();
builder.MemberTypeOrganiseActions().Append<DefaultMemberTypeOrganiseAction>();

builder.AddNotificationHandler<DataTypeSavedNotification, BackofficeOrganiserNotificationHandler>();
builder.AddNotificationHandler<ContentTypeSavedNotification, BackofficeOrganiserNotificationHandler>();
builder.AddNotificationHandler<MemberTypeSavedNotification, BackofficeOrganiserNotificationHandler>();
builder.AddNotificationHandler<MediaTypeSavedNotification, BackofficeOrganiserNotificationHandler>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@ namespace Umbraco.Community.BackOfficeOrganiser.Models;
public class BackOfficeOrganiserOptions
{
public DataTypeOptions DataTypes { get; set; } = new();
public ContentTypeOptions ContentTypes { get; set; } = new();
public MemberTypeOptions MemberTypes { get; set; } = new();
public MediaTypeOptions MediaTypes { get; set; } = new();
public static string SectionName => "BackOfficeOrganiser";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Umbraco.Community.BackOfficeOrganiser.Models;

public class ContentTypeOptions
{
public bool OrganiseOnSave { get; set; } = true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ public class DataTypeOptions
public string InternalFolderName { get; set; } = "🔒 Internal";
public string ThirdPartyFolderName { get; set; } = "🦄 Third Party";
public string CustomFolderName { get; set; } = "🔧 Custom";
public bool OrganiseOnSave { get; set; } = true;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Umbraco.Community.BackOfficeOrganiser.Models;

public class MediaTypeOptions
{
public bool OrganiseOnSave { get; set; } = true;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Umbraco.Community.BackOfficeOrganiser.Models;

public class MemberTypeOptions
{
public bool OrganiseOnSave { get; set; } = true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,22 @@ protected BackOfficeOrganiserBase(ILogger logger)
Logger = logger;
}

public void OrganiseType()
protected virtual void PostOrganiseAll()
{
}

public void OrganiseAll()
{
Logger.LogInformation("BackOfficeOrganiser: Cleanup for {Type} Started", typeof(T).Name);

try
{
Organise();
var items = GetAll();
foreach (var item in items)
{
Organise(item);
}
PostOrganiseAll();
}
catch (Exception ex)
{
Expand All @@ -28,5 +37,7 @@ public void OrganiseType()
Logger.LogInformation("BackOfficeOrganiser: Cleanup for {Type} Complete", typeof(T).Name);
}

public abstract void Organise();
public abstract void Organise(T item);

protected abstract List<T> GetAll();
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ public ContentTypeOrganiser(
_organiseActions = organiseActions;
}

public override void Organise()
{
var contentTypes = _contentTypeService.GetAll().ToList();
protected override List<IContentType> GetAll() => _contentTypeService.GetAll().ToList();

foreach (var contentType in contentTypes)
{
var organiser = _organiseActions.FirstOrDefault(x => x.CanMove(contentType, _contentTypeService));
organiser?.Move(contentType, _contentTypeService);
}
public override void Organise(IContentType contentType)
{
var organiser = _organiseActions.FirstOrDefault(x => x.CanMove(contentType, _contentTypeService));
organiser?.Move(contentType, _contentTypeService);
}

protected override void PostOrganiseAll()
{
_contentTypeService.DeleteAllEmptyContainers();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using jcdcdev.Umbraco.Core.Extensions;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.PropertyEditors;
using Umbraco.Cms.Core.Services;
using Umbraco.Extensions;

namespace Umbraco.Community.BackOfficeOrganiser.Organisers.ContentTypes;

public class ElementTypeOrganiser : IContentTypeOrganiseAction
{
private readonly IDataTypeService _dataTypeService;

public ElementTypeOrganiser(IDataTypeService dataTypeService)
{
_dataTypeService = dataTypeService;
}

public bool CanMove(IContentType contentType, IContentTypeService contentTypeService) => contentType.IsElement;

public void Move(IContentType contentType, IContentTypeService contentTypeService)
{
var nestedContentDataTypes = _dataTypeService.GetByEditorAlias(Umbraco.Cms.Core.Constants.PropertyEditors.Aliases.NestedContent).Select(x => x.ConfigurationAs<NestedContentConfiguration>());
var blockGridDataTypes = _dataTypeService.GetByEditorAlias(Umbraco.Cms.Core.Constants.PropertyEditors.Aliases.BlockGrid).Select(x => x.ConfigurationAs<BlockGridConfiguration>());
var blockListDataTypes = _dataTypeService.GetByEditorAlias(Umbraco.Cms.Core.Constants.PropertyEditors.Aliases.BlockList).Select(x => x.ConfigurationAs<BlockListConfiguration>());

var nestedContentContentTypeAliases = new List<string>();
var gridContentTypeKeys = new List<Guid>();
var blockContentTypeKeys = new List<Guid>();
foreach (var blockGridDataType in blockGridDataTypes)
{
foreach (var blockGrid in blockGridDataType?.Blocks ?? Array.Empty<BlockGridConfiguration.BlockGridBlockConfiguration>())
{
gridContentTypeKeys.Add(blockGrid.ContentElementTypeKey);
if (blockGrid.SettingsElementTypeKey.HasValue)
{
gridContentTypeKeys.Add(blockGrid.SettingsElementTypeKey.Value);
}
}
}

foreach (var blockListDataType in blockListDataTypes)
{
foreach (var blockList in blockListDataType?.Blocks ?? Array.Empty<BlockListConfiguration.BlockConfiguration>())
{
blockContentTypeKeys.Add(blockList.ContentElementTypeKey);
if (blockList.SettingsElementTypeKey.HasValue)
{
blockContentTypeKeys.Add(blockList.SettingsElementTypeKey.Value);
}
}
}

foreach (var nestedContentDataType in nestedContentDataTypes)
{
if (nestedContentDataType == null)
{
continue;
}

var aliases = nestedContentDataType.ContentTypes?.Select(x => x.Alias).WhereNotNull() ?? Array.Empty<string>();
nestedContentContentTypeAliases.AddRange(aliases);
}

var isNestedContent = nestedContentContentTypeAliases.Contains(contentType.Alias);
var isBlockGrid = gridContentTypeKeys.Contains(contentType.Key);
var isBlockList = blockContentTypeKeys.Contains(contentType.Key);

var parent = contentTypeService.GetOrCreateFolder("Element Types");
var folderName = string.Empty;
if (isNestedContent && !isBlockGrid && !isBlockList)
{
folderName = "Nested Content";
}
else if (isBlockGrid && !isNestedContent && !isBlockList)
{
folderName = "Block Grid";
}
else if (isBlockList && !isNestedContent && !isBlockGrid)
{
folderName = "Block List";
}

if (!string.IsNullOrWhiteSpace(folderName))
{
parent = contentTypeService.GetOrCreateFolder(folderName, parent.Id);
}

contentTypeService.Move(contentType, parent.Id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ public DataTypeOrganiser(
_organiseActions = organiseActions;
}

public override void Organise()
public override void Organise(IDataType dataType)
{
var dataTypes = _dataTypeService.GetAll().ToList();

foreach (var dataType in dataTypes)
{
var organiser = _organiseActions.FirstOrDefault(x => x.CanMove(dataType, _dataTypeService));
organiser?.Move(dataType, _dataTypeService);
}
var organiser = _organiseActions.FirstOrDefault(x => x.CanMove(dataType, _dataTypeService));
organiser?.Move(dataType, _dataTypeService);
}

protected override List<IDataType> GetAll() => _dataTypeService.GetAll().ToList();

protected override void PostOrganiseAll()
{
_dataTypeService.DeleteAllEmptyContainers();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ namespace Umbraco.Community.BackOfficeOrganiser.Organisers;

public interface IBackOfficeOrganiser<T>
{
void OrganiseType();
void OrganiseAll();
void Organise(T item);
}
Loading

0 comments on commit 3a34e56

Please sign in to comment.