New backoffice: models builder dashboard controller (#13050)

* Add OutOfDateType model

* Add ModelsBuilderDashboardControllerBase

* Add BuildModelsController.cs

* Add StatusModelsBuilderDashboardController

* Change to return created and not OK

* Remove unused usings

* Add GetModelsBuilderDashboardController

* Add OpenApi attributes

* Fix formatting

* Fix up dependency injection for ModelsBuilderSettings

* Fix up naming and routing

* Fix up OpenApi attributes

* Remove ability to send raw HTML in dashboard

* Remove obsolete property

* Dont include dashboard in the name

* Async controllers

* Return ActionResults

* Fix up OpenApi contract

* Fix missing usings

* Update src/Umbraco.Cms.ManagementApi/Controllers/ModelsBuilderDashboard/ModelsBuilderControllerBase.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* use VersionedApiBackOfficeRouteAttribute for routing

* Fix up open api spec

Co-authored-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>
This commit is contained in:
Nikolaj Geisle
2022-10-04 12:11:30 +01:00
committed by GitHub
parent 72fd393272
commit cd748cd7c8
12 changed files with 284 additions and 1 deletions

View File

@@ -0,0 +1,62 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Infrastructure.ModelsBuilder;
using Umbraco.Cms.Infrastructure.ModelsBuilder.Building;
using Umbraco.Extensions;
namespace Umbraco.Cms.ManagementApi.Controllers.ModelsBuilderDashboard;
public class BuildModelsBuilderController : ModelsBuilderControllerBase
{
private ModelsBuilderSettings _modelsBuilderSettings;
private readonly ModelsGenerationError _mbErrors;
private readonly ModelsGenerator _modelGenerator;
public BuildModelsBuilderController(
IOptionsMonitor<ModelsBuilderSettings> modelsBuilderSettings,
ModelsGenerationError mbErrors,
ModelsGenerator modelGenerator)
{
_mbErrors = mbErrors;
_modelGenerator = modelGenerator;
_modelsBuilderSettings = modelsBuilderSettings.CurrentValue;
modelsBuilderSettings.OnChange(x => _modelsBuilderSettings = x);
}
[HttpPost("build")]
[ProducesResponseType(typeof(CreatedResult), StatusCodes.Status201Created)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status428PreconditionRequired)]
[MapToApiVersion("1.0")]
public async Task<IActionResult> BuildModels()
{
try
{
if (!_modelsBuilderSettings.ModelsMode.SupportsExplicitGeneration())
{
var problemDetailsModel = new ProblemDetails
{
Title = "Models generation is not enabled",
Detail = "ModelsBuilderMode is not set to SourceCodeManual or SourceCodeAuto",
Status = StatusCodes.Status428PreconditionRequired,
Type = "Error",
};
return await Task.FromResult(new ObjectResult(problemDetailsModel) { StatusCode = StatusCodes.Status428PreconditionRequired });
}
_modelGenerator.GenerateModels();
_mbErrors.Clear();
}
catch (Exception e)
{
_mbErrors.Report("Failed to build models.", e);
}
return await Task.FromResult(Created("api/v1/modelsBuilderDashboard", null));
}
}

View File

@@ -0,0 +1,19 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.ManagementApi.Factories;
using Umbraco.Cms.ManagementApi.ViewModels.ModelsBuilderDashboard;
namespace Umbraco.Cms.ManagementApi.Controllers.ModelsBuilderDashboard;
public class GetModelsBuilderController : ModelsBuilderControllerBase
{
private readonly IModelsBuilderViewModelFactory _modelsBuilderViewModelFactory;
public GetModelsBuilderController(IModelsBuilderViewModelFactory modelsBuilderViewModelFactory) => _modelsBuilderViewModelFactory = modelsBuilderViewModelFactory;
[HttpGet]
[ProducesResponseType(typeof(CreatedResult), StatusCodes.Status200OK)]
[MapToApiVersion("1.0")]
public async Task<ActionResult<ModelsBuilderViewModel>> GetDashboard() => await Task.FromResult(Ok(_modelsBuilderViewModelFactory.Create()));
}

View File

@@ -0,0 +1,14 @@
using Microsoft.AspNetCore.Mvc;
using NSwag.Annotations;
using Umbraco.New.Cms.Web.Common.Routing;
namespace Umbraco.Cms.ManagementApi.Controllers.ModelsBuilderDashboard;
[ApiController]
[VersionedApiBackOfficeRoute("modelsBuilder")]
[OpenApiTag("ModelsBuilder")]
[ApiVersion("1.0")]
public class ModelsBuilderControllerBase : ManagementApiControllerBase
{
}

View File

@@ -0,0 +1,29 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Infrastructure.ModelsBuilder;
using Umbraco.Cms.ManagementApi.ViewModels.ModelsBuilderDashboard;
using Umbraco.New.Cms.Core.Models;
namespace Umbraco.Cms.ManagementApi.Controllers.ModelsBuilderDashboard;
public class StatusModelsBuilderController : ModelsBuilderControllerBase
{
private readonly OutOfDateModelsStatus _outOfDateModelsStatus;
public StatusModelsBuilderController(OutOfDateModelsStatus outOfDateModelsStatus) => _outOfDateModelsStatus = outOfDateModelsStatus;
[HttpGet("status")]
[ProducesResponseType(typeof(OutOfDateStatusViewModel), StatusCodes.Status200OK)]
[MapToApiVersion("1.0")]
public async Task<ActionResult<OutOfDateStatusViewModel>> GetModelsOutOfDateStatus()
{
OutOfDateStatusViewModel status = _outOfDateModelsStatus.IsEnabled
? _outOfDateModelsStatus.IsOutOfDate
? new OutOfDateStatusViewModel { Status = OutOfDateType.OutOfDate }
: new OutOfDateStatusViewModel { Status = OutOfDateType.Current }
: new OutOfDateStatusViewModel { Status = OutOfDateType.Unknown };
return await Task.FromResult(Ok(status));
}
}

View File

@@ -9,9 +9,9 @@ public static class FactoryBuilderExtensions
{
internal static IUmbracoBuilder AddFactories(this IUmbracoBuilder builder)
{
builder.Services.AddTransient<IModelsBuilderViewModelFactory, ModelsBuilderViewModelFactory>();
builder.Services.AddTransient<IRelationViewModelFactory, RelationViewModelFactory>();
builder.Services.AddTransient<IDictionaryFactory, DictionaryFactory>();
return builder;
}
}

View File

@@ -0,0 +1,8 @@
using Umbraco.Cms.ManagementApi.ViewModels.ModelsBuilderDashboard;
namespace Umbraco.Cms.ManagementApi.Factories;
public interface IModelsBuilderViewModelFactory
{
ModelsBuilderViewModel Create();
}

View File

@@ -0,0 +1,39 @@
using System.Text;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Infrastructure.ModelsBuilder;
using Umbraco.Cms.ManagementApi.ViewModels.ModelsBuilderDashboard;
using Umbraco.Extensions;
namespace Umbraco.Cms.ManagementApi.Factories;
public class ModelsBuilderViewModelFactory : IModelsBuilderViewModelFactory
{
private ModelsBuilderSettings _modelsBuilderSettings;
private readonly ModelsGenerationError _mbErrors;
private readonly OutOfDateModelsStatus _outOfDateModels;
public ModelsBuilderViewModelFactory(IOptionsMonitor<ModelsBuilderSettings> modelsBuilderSettings, ModelsGenerationError mbErrors, OutOfDateModelsStatus outOfDateModels)
{
_mbErrors = mbErrors;
_outOfDateModels = outOfDateModels;
_modelsBuilderSettings = modelsBuilderSettings.CurrentValue;
modelsBuilderSettings.OnChange(x => _modelsBuilderSettings = x);
}
public ModelsBuilderViewModel Create() =>
new()
{
Mode = _modelsBuilderSettings.ModelsMode,
CanGenerate = _modelsBuilderSettings.ModelsMode.SupportsExplicitGeneration(),
OutOfDateModels = _outOfDateModels.IsOutOfDate,
LastError = _mbErrors.GetLastError(),
Version = ApiVersion.Current.Version.ToString(),
ModelsNamespace = _modelsBuilderSettings.ModelsNamespace,
TrackingOutOfDateModels = _modelsBuilderSettings.FlagOutOfDateModels,
};
}

View File

@@ -40,6 +40,7 @@ public class ManagementApiComposer : IComposer
.AddNewInstaller()
.AddUpgrader()
.AddExamineManagement()
.AddFactories()
.AddTrees()
.AddFactories()
.AddServices()

View File

@@ -3721,6 +3721,78 @@
}
}
}
},
"/umbraco/api/v1/modelsBuilder/build": {
"post": {
"tags": [
"ModelsBuilder"
],
"operationId": "BuildModelsBuilder_BuildModels",
"responses": {
"201": {
"description": "",
"content": {
"application/octet-stream": {
"schema": {
"type": "string",
"format": "binary"
}
}
}
},
"428": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
}
}
},
"/umbraco/api/v1/modelsBuilder": {
"get": {
"tags": [
"ModelsBuilder"
],
"operationId": "GetModelsBuilder_GetDashboard",
"responses": {
"200": {
"description": "",
"content": {
"application/octet-stream": {
"schema": {
"type": "string",
"format": "binary"
}
}
}
}
}
}
},
"/umbraco/api/v1/modelsBuilder/status": {
"get": {
"tags": [
"ModelsBuilder"
],
"operationId": "StatusModelsBuilder_GetModelsOutOfDateStatus",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/OutOfDateStatusViewModel"
}
}
}
}
}
}
}
},
"components": {
@@ -4519,6 +4591,9 @@
{
"name": "MemberType"
},
{
"name": "ModelsBuilder"
},
{
"name": "PartialView"
},

View File

@@ -0,0 +1,20 @@
using Umbraco.Cms.Core.Configuration;
namespace Umbraco.Cms.ManagementApi.ViewModels.ModelsBuilderDashboard;
public class ModelsBuilderViewModel
{
public ModelsMode Mode { get; set; }
public bool CanGenerate { get; set; }
public bool OutOfDateModels { get; set; }
public string? LastError { get; set; }
public string? Version { get; set; }
public string? ModelsNamespace { get; set; }
public bool TrackingOutOfDateModels { get; set; }
}

View File

@@ -0,0 +1,8 @@
using Umbraco.New.Cms.Core.Models;
namespace Umbraco.Cms.ManagementApi.ViewModels.ModelsBuilderDashboard;
public class OutOfDateStatusViewModel
{
public OutOfDateType Status { get; set; }
}

View File

@@ -0,0 +1,8 @@
namespace Umbraco.New.Cms.Core.Models;
public enum OutOfDateType
{
OutOfDate,
Current,
Unknown = 100
}