vue plugin system somehow works

This commit is contained in:
2021-12-29 01:25:35 +01:00
parent 1954659a82
commit ee20eb16e1
30 changed files with 136 additions and 51 deletions
@@ -13,7 +13,7 @@ public abstract class ZeroApiTreeEntityStoreController<TModel, TStore> : ZeroApi
protected async Task<ActionResult<Paged>> GetChildModels<T>(string parentId, ListQuery<TModel> query)
{
query.OrderQuery ??= q => q.OrderByDescending(x => x.CreatedDate);
Paged<TModel> result = await Store.LoadChildren(parentId, query.Page, query.PageSize, q => q.Filter(query));
Paged<TModel> result = await Store.LoadChildren(NormalizeParentId(parentId), query.Page, query.PageSize, q => q.Filter(query));
return Mapper.Map<TModel, T>(result);
}
@@ -22,7 +22,7 @@ public abstract class ZeroApiTreeEntityStoreController<TModel, TStore> : ZeroApi
protected async Task<ActionResult<Paged>> GetChildModels(string parentId, ListQuery<TModel> query)
{
query.OrderQuery ??= q => q.OrderByDescending(x => x.CreatedDate);
Paged<TModel> result = await Store.LoadChildren(parentId, query.Page, query.PageSize, q => q.Filter(query));
Paged<TModel> result = await Store.LoadChildren(NormalizeParentId(parentId), query.Page, query.PageSize, q => q.Filter(query));
return result;
}
@@ -31,7 +31,7 @@ public abstract class ZeroApiTreeEntityStoreController<TModel, TStore> : ZeroApi
protected async Task<ActionResult<Paged>> GetChildModelsByIndex<T, TIndex>(string parentId, ListQuery<TModel> query) where TIndex : AbstractCommonApiForIndexes, new()
{
query.OrderQuery ??= q => q.OrderByDescending(x => x.CreatedDate);
Paged<TModel> result = await Store.LoadChildren<TIndex>(parentId, query.Page, query.PageSize, q => q.Filter(query));
Paged<TModel> result = await Store.LoadChildren<TIndex>(NormalizeParentId(parentId), query.Page, query.PageSize, q => q.Filter(query));
return Mapper.Map<TModel, T>(result);
}
@@ -40,7 +40,7 @@ public abstract class ZeroApiTreeEntityStoreController<TModel, TStore> : ZeroApi
protected async Task<ActionResult<Paged>> GetChildModelsByIndex<TIndex>(string parentId, ListQuery<TModel> query) where TIndex : AbstractCommonApiForIndexes, new()
{
query.OrderQuery ??= q => q.OrderByDescending(x => x.CreatedDate);
Paged<TModel> result = await Store.LoadChildren<TIndex>(parentId, query.Page, query.PageSize, q => q.Filter(query));
Paged<TModel> result = await Store.LoadChildren<TIndex>(NormalizeParentId(parentId), query.Page, query.PageSize, q => q.Filter(query));
return result;
}
@@ -54,37 +54,37 @@ public abstract class ZeroApiTreeEntityStoreController<TModel, TStore> : ZeroApi
protected async Task<ActionResult<Result>> MoveModel<TEdit>(string id, string newParentId)
{
return await PutOperation<TEdit>(async () => await Store.Move(id, newParentId));
return await PutOperation<TEdit>(async () => await Store.Move(id, NormalizeParentId(newParentId)));
}
protected async Task<ActionResult<Result>> MoveModel(string id, string newParentId)
{
return await PutOperation(async () => await Store.Move(id, newParentId));
return await PutOperation(async () => await Store.Move(id, NormalizeParentId(newParentId)));
}
protected async Task<ActionResult<Result>> CopyModel<TEdit>(string id, string newParentId)
{
return await PutOperation<TEdit>(async () => await Store.Copy(id, newParentId));
return await PutOperation<TEdit>(async () => await Store.Copy(id, NormalizeParentId(newParentId)));
}
protected async Task<ActionResult<Result>> CopyModel(string id, string newParentId)
{
return await PutOperation(async () => await Store.Copy(id, newParentId));
return await PutOperation(async () => await Store.Copy(id, NormalizeParentId(newParentId)));
}
protected async Task<ActionResult<Result>> CopyModelWithDescendants<TEdit>(string id, string newParentId)
{
return await PutOperation<TEdit>(async () => await Store.CopyWithDescendants(id, newParentId));
return await PutOperation<TEdit>(async () => await Store.CopyWithDescendants(id, NormalizeParentId(newParentId)));
}
protected async Task<ActionResult<Result>> CopyModelWithDescendants(string id, string newParentId)
{
return await PutOperation(async () => await Store.CopyWithDescendants(id, newParentId));
return await PutOperation(async () => await Store.CopyWithDescendants(id, NormalizeParentId(newParentId)));
}
@@ -127,4 +127,10 @@ public abstract class ZeroApiTreeEntityStoreController<TModel, TStore> : ZeroApi
return result;
}
protected string NormalizeParentId(string id)
{
return id == "root" ? null : id;
}
}
@@ -286,10 +286,4 @@ public class MediaController : ZeroApiTreeEntityStoreController<zero.Media.Media
}
#endregion
string NormalizeParentId(string id)
{
return id == "root" ? null : id;
}
}
@@ -70,8 +70,6 @@ public class PagesController : ZeroApiTreeEntityStoreController<Page, IPagesStor
[ZeroAuthorize(PagePermissions.Read)]
public virtual async Task<ActionResult<Paged>> GetChildren(string id, [FromQuery] ListQuery<Page> query)
{
id = NormalizeParentId(id);
query.SearchFor(x => x.Name);
query.OrderQuery = q => q.OrderByDescending(x => x.Sort).ThenByDescending(x => x.CreatedDate);
Paged<Page> result = await Store.LoadChildren<zero_Api_Pages_Listing>(id, query.Page, query.PageSize, q => q.Filter(query));
@@ -82,12 +80,6 @@ public class PagesController : ZeroApiTreeEntityStoreController<Page, IPagesStor
}
string NormalizeParentId(string id)
{
return id == "root" ? null : id;
}
//[HttpPost("")]
//[ZeroAuthorize(PagePermissions.Create)]
//public virtual Task<ActionResult<Result>> Create(MailSave saveModel) => CreateModel<MailSave, MailEdit>(saveModel);
@@ -26,6 +26,7 @@ import editorPlugin from '../editor/plugin';
import { ZeroSchema } from 'zero/schemas';
import { ZeroSchemaProp } from './zero';
import * as zeroOptions from '../options';
import plugins from '../plugins.generated';
export class ZeroRuntime implements Zero
{
@@ -113,6 +114,11 @@ export class ZeroRuntime implements Zero
translationPlugin.install(pluginOptions);
integrationPlugin.install(pluginOptions);
userPlugin.install(pluginOptions);
plugins.forEach(plugin =>
{
plugin.install(pluginOptions);
});
}
@@ -122,7 +122,7 @@
strong
{
display: inline-block;
margin-bottom: 5px;
margin-bottom: 3px;
color: var(--color-text);
}
}
@@ -1 +0,0 @@
export default [ ];
@@ -0,0 +1,2 @@
import zeroPlugin0 from '@zeroplugin0/plugin';
export default [ zeroPlugin0 ];
+3
View File
@@ -6,6 +6,9 @@
"dev": "vite",
"build": "vite build"
},
"workspaces": [
"../plugins/zero.Commerce/zero.Commerce.Plugin"
],
"dependencies": {
"axios": "^0.24.0",
"dayjs": "^1.10.7",
+2 -1
View File
@@ -11,5 +11,6 @@
"esModuleInterop": true,
"lib": [ "esnext", "dom" ]
},
"include": [ "app/**/*.ts", "app/**/*.d.ts", "app/**/*.tsx", "app/**/*.vue" ]
"include": [ "app/**/*.ts", "app/**/*.d.ts", "app/**/*.tsx", "app/**/*.vue" ],
"exclude": [ "node_modules" ]
}
+6 -4
View File
@@ -10,7 +10,8 @@ let loadedPlugins = JSON.parse(process.env.ZERO_PLUGINS || "[]");
if (!process.env.ZERO_PLUGINS)
{
//loadedPlugins = ["../zero.Commerce/Plugin", "../zero.Stories/Plugin", "../zero.Forms/Plugin", "../../Laola/Laola.Backoffice/Plugin"];
loadedPlugins = [];
loadedPlugins = ["../plugins/zero.Commerce/zero.Commerce.Plugin"]
//loadedPlugins = [];
}
let zeroPlugins = [];
@@ -40,12 +41,12 @@ loadedPlugins.forEach(pluginPath =>
}
pluginNames.push(name);
pluginFileContent += "import " + name + " from '" + alias + "/plugin.js';\n";
pluginFileContent += "import " + name + " from '" + alias + "/plugin';\n";
});
pluginFileContent += "export default [ " + pluginNames.join(', ') + " ];";
fs.writeFile(path.resolve(__dirname, 'app/plugins.generated.js'), pluginFileContent, err =>
fs.writeFile(path.resolve(__dirname, 'app/plugins.generated.ts'), pluginFileContent, err =>
{
if (err)
{
@@ -76,7 +77,8 @@ let config = defineConfig({
},
resolve: {
alias: {
vue: '@vue/compat'
vue: '@vue/compat',
...pluginAliases,
}
},
plugins: [
@@ -34,7 +34,7 @@ public class SectionService : ISectionService
List<BackofficeSectionPresentation> sections = new();
foreach (IBackofficeSection section in Sections)
foreach (IBackofficeSection section in Sections.OrderBy(x => x.Sort))
{
//if (!isSuperUser && !Permission.CanReadKey(permissions, section.Alias, true))
//{
@@ -114,7 +114,7 @@ public class SectionService : ISectionService
Name = area.Name,
Description = area.Description,
Icon = area.Icon,
Url = Constants.Sections.Settings.EnsureStartsWith('/') + Safenames.Alias(area.Alias).EnsureStartsWith('/'),
Url = Constants.Sections.Settings.EnsureStartsWith('/') + area.CustomUrl.Or(Safenames.Alias(area.Alias)).EnsureStartsWith('/'),
IsPlugin = true
};
@@ -14,6 +14,9 @@ public class BackofficeSection : IBackofficeSection, IChildBackofficeSection
/// <inheritdoc />
public string Icon { get; set; }
/// <inheritdoc />
public int Sort { get; set; }
/// <summary>
/// HEX color (#aabbcc or #abc). Defaults to a neutral color
/// </summary>
@@ -25,11 +28,12 @@ public class BackofficeSection : IBackofficeSection, IChildBackofficeSection
public BackofficeSection() { }
public BackofficeSection(string alias, string name, string icon = null, string color = null)
public BackofficeSection(string alias, string name, string icon = null, string color = null, int sort = 0)
{
Alias = alias;
Name = name;
Icon = icon;
Color = color;
Sort = sort;
}
}
@@ -17,6 +17,9 @@ public class DashboardSection : IInternalBackofficeSection
/// <inheritdoc />
public string Color => null;
/// <inheritdoc />
public int Sort => 0;
/// <inheritdoc />
public IList<IChildBackofficeSection> Children => new List<IChildBackofficeSection>();
}
@@ -34,4 +34,9 @@ public interface IBackofficeSection
/// Children are displayed as a sub-navigation in the main nav area
/// </summary>
IList<IChildBackofficeSection> Children { get; }
/// <summary>
/// Sort order
/// </summary>
int Sort { get; }
}
@@ -17,6 +17,9 @@ public class MediaSection : IInternalBackofficeSection
/// <inheritdoc />
public string Color => "#d82853";
/// <inheritdoc />
public int Sort => 300;
/// <inheritdoc />
public IList<IChildBackofficeSection> Children => new List<IChildBackofficeSection>();
}
@@ -17,6 +17,9 @@ public class PagesSection : IInternalBackofficeSection
/// <inheritdoc />
public string Color => "#0cb0f5";
/// <inheritdoc />
public int Sort => 100;
/// <inheritdoc />
public IList<IChildBackofficeSection> Children => new List<IChildBackofficeSection>();
}
@@ -17,6 +17,9 @@ public class SettingsSection : IInternalBackofficeSection
/// <inheritdoc />
public string Color => null;
/// <inheritdoc />
public int Sort => 1000;
/// <inheritdoc />
public IList<IChildBackofficeSection> Children => new List<IChildBackofficeSection>();
}
@@ -17,6 +17,9 @@ public class SpacesSection : IInternalBackofficeSection
/// <inheritdoc />
public string Color => "#f9c202";
/// <inheritdoc />
public int Sort => 200;
/// <inheritdoc />
public IList<IChildBackofficeSection> Children => new List<IChildBackofficeSection>();
}
@@ -10,5 +10,6 @@ public class CommunicationModule : ZeroModule
services.AddScoped<IInterceptors, Interceptors>();
services.AddSingleton<IMessageAggregator, MessageAggregator>();
services.AddTransient<IHandlerHolder, HandlerHolder>();
services.AddTransient(typeof(Lazy<>), typeof(LazilyResolved<>));
}
}
@@ -16,7 +16,7 @@ public class InterceptorInstruction<T> where T : ZeroIdEntity, new()
protected IZeroContext Context { get; private set; }
protected IEnumerable<IInterceptor> Interceptors { get; private set; }
protected Lazy<IEnumerable<IInterceptor>> Interceptors { get; private set; }
protected Dictionary<IInterceptor, InterceptorParameters> InterceptorCache { get; private set; } = new();
@@ -27,7 +27,7 @@ public class InterceptorInstruction<T> where T : ZeroIdEntity, new()
protected Func<IInterceptor, bool> InterceptorFilter { get; private set; } = x => true;
internal InterceptorInstruction(IInterceptors interceptors, IZeroContext context, IEnumerable<IInterceptor> registrations, ILogger<IInterceptor> logger, InterceptorRunType runtype, T model)
internal InterceptorInstruction(IInterceptors interceptors, IZeroContext context, Lazy<IEnumerable<IInterceptor>> registrations, ILogger<IInterceptor> logger, InterceptorRunType runtype, T model)
{
InterceptorHandler = interceptors;
Context = context;
@@ -37,7 +37,6 @@ public class InterceptorInstruction<T> where T : ZeroIdEntity, new()
Model = model;
ModelType = model.GetType();
Interceptors = registrations.OrderByDescending(x => x.Gravity);
}
@@ -115,7 +114,7 @@ public class InterceptorInstruction<T> where T : ZeroIdEntity, new()
protected IEnumerable<IInterceptor> GetInterceptors()
{
return Interceptors.Where(InterceptorFilter).OrderByDescending(x => x.Gravity);
return Interceptors.Value.Where(InterceptorFilter).OrderByDescending(x => x.Gravity);
}
@@ -6,12 +6,12 @@ public class Interceptors : IInterceptors
{
protected IZeroContext Context { get; set; }
protected IEnumerable<IInterceptor> Registrations { get; set; }
protected Lazy<IEnumerable<IInterceptor>> Registrations { get; set; }
protected ILogger<IInterceptor> Logger { get; set; }
public Interceptors(IZeroContext context, IEnumerable<IInterceptor> registrations, ILogger<IInterceptor> logger)
public Interceptors(IZeroContext context, Lazy<IEnumerable<IInterceptor>> registrations, ILogger<IInterceptor> logger)
{
Context = context;
Registrations = registrations;
+11
View File
@@ -0,0 +1,11 @@
using Microsoft.Extensions.DependencyInjection;
namespace zero.Communication;
public class LazilyResolved<T> : Lazy<T>
{
public LazilyResolved(IServiceProvider serviceProvider): base(serviceProvider.GetRequiredService<T>)
{
}
}
+1 -4
View File
@@ -4,10 +4,7 @@ namespace zero.Media;
public class MediaStore : TreeEntityStore<Media>, IMediaStore
{
public MediaStore(IStoreContext context) : base(context)
{
Config.IncludeInactive = true;
}
public MediaStore(IStoreContext context) : base(context) { }
/// <summary>
/// A media (either file or folder) can only be saved for the following circumstances:
+1 -1
View File
@@ -4,7 +4,7 @@
/// A media file (can contain an image or other media like videos and documents)
/// </summary>
[RavenCollection("Media")]
public class Media : ZeroEntity, ISupportsTrees
public class Media : ZeroEntity, ISupportsTrees, IAlwaysActive
{
public Media()
{
+12
View File
@@ -0,0 +1,12 @@
namespace zero.Models;
/// <summary>
/// Entities decorated with this interface are always set to IsActive=true
/// </summary>
public interface IAlwaysActive
{
/// <summary>
/// Whether the entity is visible in the frontend
/// </summary>
bool IsActive { get; set; }
}
+2
View File
@@ -9,6 +9,8 @@ public class Paged<T> : Paged
Items = items;
}
public Paged(long totalItems, long pageNumber, long pageSize) : base(totalItems, pageNumber, pageSize) { }
public Paged<TTarget> MapTo<TTarget>(Func<T, TTarget> convertItem)
{
return new Paged<TTarget>(Items.Select(x => convertItem(x)).Where(x => x != null).ToList(), TotalItems, Page, PageSize);
+7 -4
View File
@@ -72,10 +72,8 @@ public partial class StoreOperations :
// set IDs
AutoSetIds(model);
if (model is ZeroEntity)
if (model is ZeroEntity zeroModel)
{
ZeroEntity zeroModel = model as ZeroEntity;
// get current user
string userId = Context.BackofficeUser.FindFirstValue(Constants.Auth.Claims.UserId);
@@ -101,6 +99,11 @@ public partial class StoreOperations :
zeroModel.Hash ??= IdGenerator.Create();
}
if (model is IAlwaysActive activeModel)
{
activeModel.IsActive = true;
}
return model;
}
@@ -110,7 +113,7 @@ public partial class StoreOperations :
/// </summary>
protected virtual T WhenActive<T>(T model) where T : ZeroIdEntity, new()
{
return model != null && (Config.IncludeInactive || model is not ZeroEntity || (model as ZeroEntity).IsActive) ? model : default;
return model != null && (Config.IncludeInactive || model is IAlwaysActive || model is not ZeroEntity || (model as ZeroEntity).IsActive) ? model : default;
}
}
+7 -2
View File
@@ -4,6 +4,7 @@ using zero.Applications;
using zero.Architecture;
using zero.Backoffice;
using zero.Backoffice.DevServer;
using zero.Commerce;
using zero.Configuration;
using zero.Demo;
using zero.Localization;
@@ -17,9 +18,13 @@ builder.Services.AddRazorPages();
builder.Services.AddTransient<IApplicationResolverHandler, DevApplicationResolverHandler>();
builder.Services
.AddZero(builder.Configuration)
.AddZero(builder.Configuration, cfg =>
{
cfg.Mvc.AddApplicationPart(typeof(CommercePlugin).Assembly);
})
.AddApi()
.AddBackoffice();
.AddBackoffice()
.AddCommerce();
builder.Services.Configure<ZeroDevOptions>(opts =>
{
+1
View File
@@ -10,6 +10,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\plugins\zero.Commerce\zero.Commerce.csproj" />
<ProjectReference Include="..\zero.Core\zero.Core.csproj" />
<ProjectReference Include="..\zero.Backoffice\zero.Backoffice.csproj" />
<ProjectReference Include="..\zero.Api\zero.Api.csproj" />
+25
View File
@@ -49,6 +49,26 @@ Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "zero.Backoffice.UI", "zero.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "zero.Demo", "zero.Demo\zero.Demo.csproj", "{8AD56129-2104-4DF5-A08E-1A94A8EC205B}"
EndProject
Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "zero.Commerce.Plugin", "plugins\zero.Commerce\zero.Commerce.Plugin\", "{645DAEC9-73CA-41C3-ADFA-7576E2D6B216}"
ProjectSection(WebsiteProperties) = preProject
TargetFrameworkMoniker = ".NETFramework,Version%3Dv4.0"
Debug.AspNetCompiler.VirtualPath = "/localhost_64677"
Debug.AspNetCompiler.PhysicalPath = "plugins\zero.Commerce\zero.Commerce.Plugin\"
Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_64677\"
Debug.AspNetCompiler.Updateable = "true"
Debug.AspNetCompiler.ForceOverwrite = "true"
Debug.AspNetCompiler.FixedNames = "false"
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.VirtualPath = "/localhost_64677"
Release.AspNetCompiler.PhysicalPath = "plugins\zero.Commerce\zero.Commerce.Plugin\"
Release.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_64677\"
Release.AspNetCompiler.Updateable = "true"
Release.AspNetCompiler.ForceOverwrite = "true"
Release.AspNetCompiler.FixedNames = "false"
Release.AspNetCompiler.Debug = "False"
VWDPort = "64677"
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -91,6 +111,10 @@ Global
{8AD56129-2104-4DF5-A08E-1A94A8EC205B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8AD56129-2104-4DF5-A08E-1A94A8EC205B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8AD56129-2104-4DF5-A08E-1A94A8EC205B}.Release|Any CPU.Build.0 = Release|Any CPU
{645DAEC9-73CA-41C3-ADFA-7576E2D6B216}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{645DAEC9-73CA-41C3-ADFA-7576E2D6B216}.Debug|Any CPU.Build.0 = Debug|Any CPU
{645DAEC9-73CA-41C3-ADFA-7576E2D6B216}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{645DAEC9-73CA-41C3-ADFA-7576E2D6B216}.Release|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -99,6 +123,7 @@ Global
{63A8AD15-15F0-4555-BD62-C38B4465FFC1} = {6FAA92A8-CA1A-48EA-9857-C9092971B4D1}
{C23CF90A-DB90-427F-816C-0E2FE20E29D0} = {6FAA92A8-CA1A-48EA-9857-C9092971B4D1}
{A8E5F34F-5400-4F92-96C6-7F91645BC220} = {6FAA92A8-CA1A-48EA-9857-C9092971B4D1}
{645DAEC9-73CA-41C3-ADFA-7576E2D6B216} = {6FAA92A8-CA1A-48EA-9857-C9092971B4D1}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AD3F31B9-8BBB-4334-9571-F556B9E632C9}