Skip to content

Commit

Permalink
Merge pull request #28 from jcdcdev/dev/v13
Browse files Browse the repository at this point in the history
13.1.0
  • Loading branch information
jcdcdev authored Aug 31, 2024
2 parents 75f1c4c + e01edf9 commit 6c906b1
Show file tree
Hide file tree
Showing 25 changed files with 301 additions and 169 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
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ jobs:
with:
project-name: ${{ needs.metadata.outputs.project-name}}
project-path: ${{ needs.metadata.outputs.project-path }}
npm-working-dir: ${{ needs.metadata.outputs.npm-working-dir }}
npm-enabled: true
umbraco-version: 13
2 changes: 2 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ jobs:
with:
project-name: ${{ needs.metadata.outputs.project-name}}
project-path: ${{ needs.metadata.outputs.project-path }}
npm-working-dir: ${{ needs.metadata.outputs.npm-working-dir }}
npm-enabled: true
umbraco-version: 13
- name: Release
uses: jcdcdev/jcdcdev.Umbraco.GitHub.Release@main
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
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(
DataTypeOrganiser dataTypeOrganiser,
ContentTypeOrganiser contentTypeOrganiser,
MediaTypeOrganiser mediaTypeOrganiser,
MemberTypeOrganiser memberTypeOrganiser,
IOptions<BackOfficeOrganiserOptions> options)
:
INotificationHandler<DataTypeSavedNotification>,
INotificationHandler<ContentTypeSavedNotification>,
INotificationHandler<MemberTypeSavedNotification>,
INotificationHandler<MediaTypeSavedNotification>
{
private readonly BackOfficeOrganiserOptions _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 @@ -15,22 +15,15 @@ namespace Umbraco.Community.BackOfficeOrganiser.Controllers;
[Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)]
[DisableBrowserCache]
[UmbracoRequireHttps]
public class BackOfficeOrganiserController : UmbracoApiController
public class BackOfficeOrganiserController(IBackOfficeOrganiserService service) : UmbracoApiController
{
private readonly IBackOfficeOrganiserService _service;

public BackOfficeOrganiserController(IBackOfficeOrganiserService service)
{
_service = service;
}

[HttpPost]
public IActionResult Organise(OrganiseRequest model)
{
var success = true;
foreach (var type in model.Types.Select(DetermineOrganiseType).Distinct())
{
var attempt = _service.Organise(type);
var attempt = service.Organise(type);
if (!attempt.Success)
{
success = false;
Expand Down
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 @@ -2,22 +2,26 @@

namespace Umbraco.Community.BackOfficeOrganiser.Organisers;

public abstract class BackOfficeOrganiserBase<T> : IBackOfficeOrganiser<T>
public abstract class BackOfficeOrganiserBase<T>(ILogger logger) : IBackOfficeOrganiser<T>
{
public readonly ILogger Logger;
public readonly ILogger Logger = logger;

protected BackOfficeOrganiserBase(ILogger logger)
protected virtual void PostOrganiseAll()
{
Logger = logger;
}

public void OrganiseType()
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 +32,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 @@ -2,10 +2,4 @@

namespace Umbraco.Community.BackOfficeOrganiser.Organisers.ContentTypes;

public class ContentTypeOrganiseActionCollection : BuilderCollectionBase<IContentTypeOrganiseAction>
{
public ContentTypeOrganiseActionCollection(Func<IEnumerable<IContentTypeOrganiseAction>> items)
: base(items)
{
}
}
public class ContentTypeOrganiseActionCollection(Func<IEnumerable<IContentTypeOrganiseAction>> items) : BuilderCollectionBase<IContentTypeOrganiseAction>(items);
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,22 @@

namespace Umbraco.Community.BackOfficeOrganiser.Organisers.ContentTypes;

public class ContentTypeOrganiser : BackOfficeOrganiserBase<IContentType>
public class ContentTypeOrganiser(
ILogger<ContentTypeOrganiser> logger,
IContentTypeService contentTypeService,
ContentTypeOrganiseActionCollection organiseActions)
: BackOfficeOrganiserBase<IContentType>(logger)
{
private readonly IContentTypeService _contentTypeService;
private readonly ContentTypeOrganiseActionCollection _organiseActions;
protected override List<IContentType> GetAll() => contentTypeService.GetAll().ToList();

public ContentTypeOrganiser(
ILogger<ContentTypeOrganiser> logger,
IContentTypeService contentTypeService,
ContentTypeOrganiseActionCollection organiseActions) : base(logger)
public override void Organise(IContentType contentType)
{
_contentTypeService = contentTypeService;
_organiseActions = organiseActions;
var organiser = organiseActions.FirstOrDefault(x => x.CanMove(contentType, contentTypeService));
organiser?.Move(contentType, contentTypeService);
}

public override void Organise()
protected override void PostOrganiseAll()
{
var contentTypes = _contentTypeService.GetAll().ToList();

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

_contentTypeService.DeleteAllEmptyContainers();
contentTypeService.DeleteAllEmptyContainers();
}
}
Loading

0 comments on commit 6c906b1

Please sign in to comment.