diff --git a/zero.Backoffice.UI/app/api/countries.js b/zero.Backoffice.UI/app/api/countries.js
index fd723b2f..e801b4eb 100644
--- a/zero.Backoffice.UI/app/api/countries.js
+++ b/zero.Backoffice.UI/app/api/countries.js
@@ -1,4 +1,10 @@
-//import { collection } from '../helpers/request.ts';
-import { RequestHelper } from '../helpers/all.js';
+import { get, post, put, del } from '../helpers/request.ts';
-export default { ...RequestHelper.collection('countries/') };
\ No newline at end of file
+export default {
+ getById: async (id, config) => await get('countries/' + id, { ...config }),
+ getEmpty: async config => await get('countries/empty', { ...config }),
+ getByQuery: async (query, config) => await get('countries', { ...config, params: { query } }),
+ create: async (model, config) => await post('countries', model, { ...config }),
+ update: async (model, config) => await put('countries/' + model.id, model, { ...config }),
+ delete: async (id, config) => await del('countries/' + id, { ...config, params: { id } })
+};
\ No newline at end of file
diff --git a/zero.Backoffice/Configuration/BackofficeConstants.cs b/zero.Backoffice/Configuration/BackofficeConstants.cs
new file mode 100644
index 00000000..61c66ea8
--- /dev/null
+++ b/zero.Backoffice/Configuration/BackofficeConstants.cs
@@ -0,0 +1,9 @@
+namespace zero.Backoffice.Configuration;
+
+public static class BackofficeConstants
+{
+ public static class HttpErrors
+ {
+ public const string NoIdMatchOnUpdate = "The Id as part of the URL does not match the Id of the model";
+ }
+}
\ No newline at end of file
diff --git a/zero.Backoffice/Controllers/ZeroBackofficeApiController.cs b/zero.Backoffice/Controllers/ZeroBackofficeApiController.cs
index f6e27b65..b5a35646 100644
--- a/zero.Backoffice/Controllers/ZeroBackofficeApiController.cs
+++ b/zero.Backoffice/Controllers/ZeroBackofficeApiController.cs
@@ -1,4 +1,5 @@
-using Microsoft.AspNetCore.Mvc;
+using AutoMapper;
+using Microsoft.AspNetCore.Mvc;
namespace zero.Backoffice.Controllers;
@@ -7,5 +8,5 @@ namespace zero.Backoffice.Controllers;
//[ServiceFilter(typeof(BackofficeFilterAttribute))]
public abstract class ZeroBackofficeApiController : ZeroBackofficeController
{
-
+ protected IMapper Mapper { get; private set; }
}
diff --git a/zero.Backoffice/Controllers/ZeroBackofficeController.cs b/zero.Backoffice/Controllers/ZeroBackofficeController.cs
index 7b673474..481cfe17 100644
--- a/zero.Backoffice/Controllers/ZeroBackofficeController.cs
+++ b/zero.Backoffice/Controllers/ZeroBackofficeController.cs
@@ -9,16 +9,16 @@ public abstract class ZeroBackofficeController : ControllerBase
///
/// Create an edit model with associated metadata and permissions from a model
///
- protected EditModel GetEditModel(T model)
+ protected DisplayModel GetEditModel(T model)
{
- return GetEditModel>(new EditModel() { Entity = model });
+ return GetEditModel>(new DisplayModel() { Entity = model });
}
///
/// Create an edit model with associated metadata and permissions from a model
///
- protected TWrapper GetEditModel(TWrapper editModel) where TWrapper : EditModel, new()
+ protected TWrapper GetEditModel(TWrapper editModel) where TWrapper : DisplayModel, new()
{
editModel.Meta = new()
{
diff --git a/zero.Backoffice/Controllers/ZeroSetupController.cs b/zero.Backoffice/Controllers/ZeroSetupController.cs
index 58d53c0e..51dd4088 100644
--- a/zero.Backoffice/Controllers/ZeroSetupController.cs
+++ b/zero.Backoffice/Controllers/ZeroSetupController.cs
@@ -37,7 +37,7 @@ public class ZeroSetupController : Controller
{
model.ContentRootPath = Env.ContentRootPath;
- EntityResult result = await Api.Install(model);
+ Result result = await Api.Install(model);
if (result.IsSuccess)
{
diff --git a/zero.Backoffice/Controllers/_ZeroBackofficeCollectionController.cs b/zero.Backoffice/Controllers/_ZeroBackofficeCollectionController.cs
index 659923ba..58c963dc 100644
--- a/zero.Backoffice/Controllers/_ZeroBackofficeCollectionController.cs
+++ b/zero.Backoffice/Controllers/_ZeroBackofficeCollectionController.cs
@@ -34,22 +34,22 @@ public abstract class _ZeroBackofficeCollectionController
}
- public virtual async Task> GetById([FromQuery] string id, [FromQuery] string changeVector = null) => Edit(await Collection.Load(id, changeVector));
+ public virtual async Task> GetById([FromQuery] string id, [FromQuery] string changeVector = null) => Edit(await Collection.Load(id, changeVector));
public virtual async Task> GetByIds([FromQuery] string[] ids) => await Collection.Load(ids);
- public virtual async Task> GetEmpty() => Edit(await Collection.Empty());
+ public virtual async Task> GetEmpty() => Edit(await Collection.Empty());
- public virtual async Task> GetByQuery([FromQuery] ListBackofficeQuery query)
+ public virtual async Task> GetByQuery([FromQuery] ListQuery query)
{
return await Collection.Load(query);
}
- public virtual async Task> GetRevisions([FromQuery] string id, [FromQuery] ListBackofficeQuery query)
+ public virtual async Task> GetRevisions([FromQuery] string id, [FromQuery] ListQuery query)
{
return null; // TODO
//return await Collection.GetRevisions(id, query.Page, query.PageSize);
@@ -63,9 +63,9 @@ public abstract class _ZeroBackofficeCollectionController
[HttpPost]
- public virtual async Task> Save([FromBody] TEntity model) => await Collection.Save(model);
+ public virtual async Task> Save([FromBody] TEntity model) => await Collection.Save(model);
[HttpDelete]
- public virtual async Task> Delete([FromQuery] string id) => await Collection.Delete(id);
+ public virtual async Task> Delete([FromQuery] string id) => await Collection.Delete(id);
}
\ No newline at end of file
diff --git a/zero.Backoffice/Mapper/MapperExtensions.cs b/zero.Backoffice/Mapper/MapperExtensions.cs
new file mode 100644
index 00000000..a998f7c8
--- /dev/null
+++ b/zero.Backoffice/Mapper/MapperExtensions.cs
@@ -0,0 +1,17 @@
+using AutoMapper;
+
+namespace zero.Backoffice.Mapper;
+
+public static class MapperExtensions
+{
+ public static Paged Map(this IMapper mapper, Paged source)
+ {
+ return source.MapTo(srcItem => mapper.Map(srcItem));
+ }
+
+ public static Result Map(this IMapper mapper, Result source)
+ {
+ TDestination model = mapper.Map(source.Model);
+ return source.ConvertTo(model);
+ }
+}
diff --git a/zero.Backoffice/Mapper/ZeroMapper.cs b/zero.Backoffice/Mapper/ZeroMapper.cs
new file mode 100644
index 00000000..1a307112
--- /dev/null
+++ b/zero.Backoffice/Mapper/ZeroMapper.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace zero.Backoffice.Mapper
+{
+ public class ZeroMapper : AutoMapper.Mapper
+ {
+ public ZeroMapper(AutoMapper.IConfigurationProvider provider) : base(provider)
+ {
+
+ }
+ }
+}
diff --git a/zero.Backoffice/Mapper/ZeroMapperProfile.cs b/zero.Backoffice/Mapper/ZeroMapperProfile.cs
new file mode 100644
index 00000000..32c9c61e
--- /dev/null
+++ b/zero.Backoffice/Mapper/ZeroMapperProfile.cs
@@ -0,0 +1,8 @@
+using AutoMapper;
+
+namespace zero.Backoffice.Mapper;
+
+public class ZeroMapperProfile : Profile
+{
+
+}
diff --git a/zero.Backoffice/Models/BasicModel.cs b/zero.Backoffice/Models/BasicModel.cs
new file mode 100644
index 00000000..ff7774bf
--- /dev/null
+++ b/zero.Backoffice/Models/BasicModel.cs
@@ -0,0 +1,6 @@
+namespace zero.Backoffice.Models;
+
+public abstract class BasicModel : ZeroIdEntity where T : ZeroIdEntity
+{
+ public string Name { get; set; }
+}
\ No newline at end of file
diff --git a/zero.Backoffice/Models/EditModel.cs b/zero.Backoffice/Models/DisplayModel.cs
similarity index 81%
rename from zero.Backoffice/Models/EditModel.cs
rename to zero.Backoffice/Models/DisplayModel.cs
index 0af0f978..48b2a288 100644
--- a/zero.Backoffice/Models/EditModel.cs
+++ b/zero.Backoffice/Models/DisplayModel.cs
@@ -1,27 +1,20 @@
namespace zero.Backoffice.Models;
-public class EditModel : EditModel