diff --git a/zero.Core/Api/ModulesApi.cs b/zero.Core/Api/ModulesApi.cs index 64e09b10..154d0376 100644 --- a/zero.Core/Api/ModulesApi.cs +++ b/zero.Core/Api/ModulesApi.cs @@ -1,7 +1,10 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using zero.Core.Entities; +using zero.Core.Extensions; +using zero.Core.Handlers; using zero.Core.Options; namespace zero.Core.Api @@ -10,23 +13,41 @@ namespace zero.Core.Api { protected IZeroOptions Options { get; private set; } - public ModulesApi(IZeroOptions options, IBackofficeStore store) : base(store) + protected IHandlerHolder Handler { get; private set; } + + public ModulesApi(IZeroOptions options, IBackofficeStore store, IHandlerHolder handler) : base(store) { Options = options; + Handler = handler; } /// - public IList GetModuleTypes(string[] tags = default) + public async Task> GetModuleTypes(string[] tags = default, string pageId = default) { - IEnumerable modules = Options.Modules.GetAllItems(); + IEnumerable types = Options.Modules.GetAllItems(); + List modules = types.ToList(); + IPage page = null; + + if (!pageId.IsNullOrEmpty()) + { + page = await GetById(pageId); + } if (tags?.Length > 0) { - modules = modules.Where(x => x.Tags.Any(t => tags.Contains(t, StringComparer.InvariantCultureIgnoreCase))); + modules = types.Where(x => x.Tags.Any(t => tags.Contains(t, StringComparer.InvariantCultureIgnoreCase))).ToList(); } - return modules.ToList(); + IModuleTypeHandler handler = Handler.Get(); + + // if there is no registered handler we just allow all page types + if (handler == null) + { + return modules; + } + + return handler.GetAllowedModuleTypes(Backoffice.Context.Application, types, page, tags)?.ToList() ?? new(); } @@ -43,7 +64,7 @@ namespace zero.Core.Api /// /// Get all available module types (can be limited to the passed tags) /// - IList GetModuleTypes(string[] tags = default); + Task> GetModuleTypes(string[] tags = default, string pageId = default); /// /// Get a specific module type by alias diff --git a/zero.Core/Api/PagesApi.cs b/zero.Core/Api/PagesApi.cs index 1b3ad61a..c6d5ba23 100644 --- a/zero.Core/Api/PagesApi.cs +++ b/zero.Core/Api/PagesApi.cs @@ -118,7 +118,6 @@ namespace zero.Core.Api return types.ToList(); } - return handler.GetAllowedPageTypes(Backoffice.Context.Application, types, parents)?.ToList() ?? new(); } diff --git a/zero.Core/Handlers/IModuleTypeHandler.cs b/zero.Core/Handlers/IModuleTypeHandler.cs new file mode 100644 index 00000000..76759f6d --- /dev/null +++ b/zero.Core/Handlers/IModuleTypeHandler.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using zero.Core.Entities; + +namespace zero.Core.Handlers +{ + public interface IModuleTypeHandler : IHandler + { + IEnumerable GetAllowedModuleTypes(IApplication application, IEnumerable registeredTypes, IPage page = default, string[] tags = default); + } +} diff --git a/zero.Web.UI/App/components/header-bar.vue b/zero.Web.UI/App/components/header-bar.vue index d300bfb2..d2a854f5 100644 --- a/zero.Web.UI/App/components/header-bar.vue +++ b/zero.Web.UI/App/components/header-bar.vue @@ -2,7 +2,7 @@
- +

diff --git a/zero.Web.UI/App/components/modules/_module-select.vue b/zero.Web.UI/App/components/modules/_module-select.vue new file mode 100644 index 00000000..578b61c3 --- /dev/null +++ b/zero.Web.UI/App/components/modules/_module-select.vue @@ -0,0 +1,270 @@ + + + + + + \ No newline at end of file diff --git a/zero.Web.UI/App/components/modules/modules.vue b/zero.Web.UI/App/components/modules/modules.vue index db82d6bc..ecd0356d 100644 --- a/zero.Web.UI/App/components/modules/modules.vue +++ b/zero.Web.UI/App/components/modules/modules.vue @@ -3,7 +3,10 @@
- +

@@ -12,14 +15,14 @@ import ModulesApi from 'zero/api/modules.js'; import EditModuleOverlay from './edit-module.vue'; import ModulePreview from './module-preview.vue'; - import ModuleSelect from './module-select.vue'; + import ModuleSelectOverlay from './module-select.vue'; import Overlay from 'zero/helpers/overlay.js'; import Arrays from 'zero/helpers/arrays.js'; export default { name: 'uiModules', - components: { ModulePreview, ModuleSelect }, + components: { ModulePreview }, props: { value: { @@ -78,6 +81,16 @@ }, + selectModule() + { + Overlay.open({ + component: ModuleSelectOverlay, + types: this.moduleTypes, + width: 480 + }).then(module => this.onAdd(module), () => { }); + }, + + onAdd(module) { this.edit(module, null, true); @@ -98,6 +111,8 @@ const alias = 'modules.' + module.alias; const editor = this.zero.getEditor(alias); + console.info(editor); + if (!editor) { // TODO throw error @@ -109,7 +124,6 @@ return ModulesApi.getEmpty(module.alias).then(res => { this.items.push(res.entity); - this.$refs.moduleSelect.reset(); this.onChange(); }); } @@ -127,7 +141,6 @@ if (isAdd) { this.items.push(value); - this.$refs.moduleSelect.reset(); } else { @@ -159,4 +172,47 @@ { margin-top: -32px; } + + .ui-modules-start-button + { + color: var(--color-primary); + font-size: var(--font-size); + display: inline-grid; + grid-template-columns: auto 1fr; + gap: 25px; + align-items: center; + } + + .ui-modules-inner-sortable + .ui-modules-start-button + { + margin-top: var(--padding); + } + + .ui-modules-start-button-icon + { + width: 52px; + height: 52px; + line-height: 50px !important; + font-size: 20px; + text-align: center; + background: var(--color-button-light); + border-radius: var(--radius); + } + + .ui-modules-start-button-text + { + line-height: 1.3; + color: var(--color-text-dim); + margin: 0; + font-size: var(--font-size-s); + strong + + { + display: inline-block; + margin-bottom: 2px; + color: var(--color-text); + font-size: var(--font-size); + } + + } \ No newline at end of file diff --git a/zero.Web.UI/App/pages/pages/overlays/create.vue b/zero.Web.UI/App/pages/pages/overlays/create.vue index 95a96023..57d0ba34 100644 --- a/zero.Web.UI/App/pages/pages/overlays/create.vue +++ b/zero.Web.UI/App/pages/pages/overlays/create.vue @@ -118,7 +118,7 @@ { display: grid; width: 100%; - grid-template-columns: 48px 1fr auto; + grid-template-columns: 40px 1fr auto; gap: 12px; align-items: center; position: relative; @@ -157,6 +157,6 @@ position: relative; top: -2px; left: 4px; - color: var(--color-text); + color: var(--color-text); } \ No newline at end of file diff --git a/zero.Web.UI/App/pages/pages/pages.vue b/zero.Web.UI/App/pages/pages/pages.vue index 6371b699..75b04023 100644 --- a/zero.Web.UI/App/pages/pages/pages.vue +++ b/zero.Web.UI/App/pages/pages/pages.vue @@ -126,7 +126,7 @@ { Overlay.open({ component: CreateOverlay, - width: 520, + width: 480, parent: parent }).then(() => { diff --git a/zero.Web.UI/Sass/Settings/_theme-dark.scss b/zero.Web.UI/Sass/Settings/_theme-dark.scss index 1b47a3bc..b24f9ad5 100644 --- a/zero.Web.UI/Sass/Settings/_theme-dark.scss +++ b/zero.Web.UI/Sass/Settings/_theme-dark.scss @@ -12,12 +12,12 @@ // foreground colors $color-fg: #fff; - $color-fg-shade-1: #a8abad; // dim + $color-fg-shade-1: #7b848a; // dim $color-fg-shade-2: #8c9094; // dim-two // background colors $color-bg: #191e25; - $color-bg-shade-0: #1f2329; + $color-bg-shade-0: #1d2229; $color-bg-shade-1: #22272e; // bright $color-bg-shade-2: #1d2229; // dim $color-bg-shade-3: #2a2f36; // bright-two diff --git a/zero.Web.UI/app/api/modules.js b/zero.Web.UI/app/api/modules.js index 683ff342..9bb0a9f3 100644 --- a/zero.Web.UI/app/api/modules.js +++ b/zero.Web.UI/app/api/modules.js @@ -3,7 +3,7 @@ import { get } from '../helpers/request.ts'; const base = 'modules/'; export default { - getModuleTypes: async tags => await get(base + 'getModuleTypes', { params: { tags } }), + getModuleTypes: async (tags, pageId) => await get(base + 'getModuleTypes', { params: { tags, pageId } }), getModuleType: async alias => await get(base + 'getModuleType', { params: { alias } }), diff --git a/zero.Web.UI/app/components/modules/module-select.vue b/zero.Web.UI/app/components/modules/module-select.vue index 578b61c3..c8afe1e0 100644 --- a/zero.Web.UI/app/components/modules/module-select.vue +++ b/zero.Web.UI/app/components/modules/module-select.vue @@ -1,270 +1,148 @@  \ No newline at end of file diff --git a/zero.Web.UI/app/helpers/overlay.js b/zero.Web.UI/app/helpers/overlay.js index 3a9aa602..ecf5da4d 100644 --- a/zero.Web.UI/app/helpers/overlay.js +++ b/zero.Web.UI/app/helpers/overlay.js @@ -1,5 +1,5 @@ import Vue from 'vue'; -//import AppConfirm from 'zero/components/overlays/confirm.vue'; +import AppConfirm from 'zero/components/overlays/confirm.vue'; // TODO importing vue files in js/ts files causes a Rollup production build error import Strings from 'zero/helpers/strings.js'; import { find as _find, extend as _extend } from 'underscore'; diff --git a/zero.Web/Controllers/ModulesController.cs b/zero.Web/Controllers/ModulesController.cs index a83f0370..0643d4bb 100644 --- a/zero.Web/Controllers/ModulesController.cs +++ b/zero.Web/Controllers/ModulesController.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; +using System.Threading.Tasks; using zero.Core.Api; using zero.Core.Entities; using zero.Core.Utils; @@ -18,7 +19,7 @@ namespace zero.Web.Controllers } - public IList GetModuleTypes([FromQuery] string[] tags = default) => Api.GetModuleTypes(tags); + public async Task> GetModuleTypes([FromQuery] string[] tags = default, [FromQuery] string pageId = default) => await Api.GetModuleTypes(tags, pageId); public ModuleType GetModuleType([FromQuery] string alias) => Api.GetModuleType(alias);