From 4d67cfc8706acd4c18eb9142e22aea27f6357d83 Mon Sep 17 00:00:00 2001
From: Lone Iversen <108085781+loivsen@users.noreply.github.com>
Date: Fri, 16 Feb 2024 15:32:57 +0100
Subject: [PATCH] template page field modal beginning
---
.../dictionary-item-picker-modal.token.ts | 1 +
...ction-view-column-configuration.element.ts | 1 +
.../templating-item-menu.element.ts | 116 +++++++++---------
.../src/packages/templating/modals/index.ts | 1 +
.../packages/templating/modals/manifests.ts | 6 +
.../templating-item-picker-modal.element.ts | 70 +++++++----
.../templating-item-picker-modal.token.ts | 3 +-
.../templating-page-field-builder/index.ts | 2 +
...lating-page-field-builder-modal.element.ts | 116 ++++++++++++++++++
...mplating-page-field-builder-modal.token.ts | 17 +++
.../src/packages/templating/types.ts | 1 +
11 files changed, 247 insertions(+), 87 deletions(-)
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/templating/modals/templating-page-field-builder/index.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/templating/modals/templating-page-field-builder/templating-page-field-builder-modal.element.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/templating/modals/templating-page-field-builder/templating-page-field-builder-modal.token.ts
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/dictionary-item-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/dictionary-item-picker-modal.token.ts
index 14c4f80d06..a537235eb5 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/dictionary-item-picker-modal.token.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/dictionary-item-picker-modal.token.ts
@@ -14,6 +14,7 @@ export const UMB_DICTIONARY_ITEM_PICKER_MODAL = new UmbModalToken<
size: 'small',
},
data: {
+ hideTreeRoot: true,
treeAlias: 'Umb.Tree.Dictionary',
},
});
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/uis/collection-view/config/column-configuration/property-editor-ui-collection-view-column-configuration.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/uis/collection-view/config/column-configuration/property-editor-ui-collection-view-column-configuration.element.ts
index 4625960edb..838f3fb4d3 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/uis/collection-view/config/column-configuration/property-editor-ui-collection-view-column-configuration.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/uis/collection-view/config/column-configuration/property-editor-ui-collection-view-column-configuration.element.ts
@@ -110,6 +110,7 @@ export class UmbPropertyEditorUICollectionViewColumnConfigurationElement
}
render() {
+ console.log(this.config);
return html`
diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/components/templating-item-menu/templating-item-menu.element.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/components/templating-item-menu/templating-item-menu.element.ts
index 59bb18f5b4..4ffa8cae20 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/templating/components/templating-item-menu/templating-item-menu.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/templating/components/templating-item-menu/templating-item-menu.element.ts
@@ -1,7 +1,5 @@
-import {
- UMB_PARTIAL_VIEW_PICKER_MODAL,
- type UmbPartialViewPickerModalValue,
-} from '../../modals/partial-view-picker/partial-view-picker-modal.token.js';
+import { UMB_PARTIAL_VIEW_PICKER_MODAL } from '../../modals/partial-view-picker/partial-view-picker-modal.token.js';
+import { UMB_TEMPLATING_PAGE_FIELD_BUILDER_MODAL } from '../../modals/templating-page-field-builder/templating-page-field-builder-modal.token.js';
import { CodeSnippetType } from '../../types.js';
import {
UMB_TEMPLATING_ITEM_PICKER_MODAL,
@@ -11,11 +9,7 @@ import { getInsertDictionarySnippet, getInsertPartialSnippet } from '../../utils
import { UmbDictionaryDetailRepository } from '@umbraco-cms/backoffice/dictionary';
import { customElement, property, css, html } from '@umbraco-cms/backoffice/external/lit';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
-import type {
- UmbDictionaryItemPickerModalValue,
- UmbModalManagerContext,
- UmbModalContext,
-} from '@umbraco-cms/backoffice/modal';
+import type { UmbModalManagerContext, UmbModalContext } from '@umbraco-cms/backoffice/modal';
import { UMB_DICTIONARY_ITEM_PICKER_MODAL, UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
@@ -42,78 +36,82 @@ export class UmbTemplatingInsertMenuElement extends UmbLitElement {
switch (type) {
case CodeSnippetType.partialView: {
- this.#getPartialViewSnippet(value as UmbPartialViewPickerModalValue);
+ this.value = getInsertPartialSnippet(value);
+ this.#dispatchInsertEvent();
break;
}
case CodeSnippetType.dictionaryItem: {
- await this.#getDictionaryItemSnippet(value as UmbDictionaryItemPickerModalValue);
+ await this.#getDictionaryItemSnippet(value);
+ this.#dispatchInsertEvent();
+ break;
+ }
+ case CodeSnippetType.pageField: {
+ this.value = value;
this.#dispatchInsertEvent();
-
break;
}
}
}
- #getDictionaryItemSnippet = async (modalValue: UmbDictionaryItemPickerModalValue) => {
- const unique = modalValue.selection[0];
+ async #getDictionaryItemSnippet(unique: string) {
if (unique === null) return;
const { data } = await this.#dictionaryDetailRepository.requestByUnique(unique);
this.value = getInsertDictionarySnippet(data?.name ?? '');
- };
-
- #getPartialViewSnippet = async (modalValue: UmbPartialViewPickerModalValue) => {
- this.value = getInsertPartialSnippet(modalValue.selection?.[0] ?? '');
- };
-
- #openChooseTypeModal = () => {
- this.#openModal = this._modalContext?.open(UMB_TEMPLATING_ITEM_PICKER_MODAL, {
- data: {
- hidePartialViews: this.hidePartialView,
- },
- });
- this.#openModal?.onSubmit().then((closedModal: UmbTemplatingItemPickerModalValue) => {
- this.determineInsertValue(closedModal);
- });
- };
-
- #openInsertPageFieldSidebar() {
- //this.#openModel = this._modalContext?.open();
}
- #openInsertPartialViewSidebar() {
- this.#openModal = this._modalContext?.open(UMB_PARTIAL_VIEW_PICKER_MODAL);
- this.#openModal?.onSubmit().then((value) => {
- this.#getPartialViewSnippet(value).then(() => {
- this.#dispatchInsertEvent();
- });
- });
+ async #openTemplatingItemPickerModal() {
+ const itemPickerContext = this._modalContext?.open(UMB_TEMPLATING_ITEM_PICKER_MODAL);
+ await itemPickerContext?.onSubmit();
+
+ const value = itemPickerContext?.getValue();
+ if (!value) return;
+
+ this.determineInsertValue(value);
}
- #openInsertDictionaryItemModal() {
- this.#openModal = this._modalContext?.open(UMB_DICTIONARY_ITEM_PICKER_MODAL, {
- data: {
- hideTreeRoot: true,
- pickableFilter: (item) => item.id !== null,
- },
- });
- this.#openModal?.onSubmit().then((value) => {
- this.#getDictionaryItemSnippet(value).then(() => {
- this.#dispatchInsertEvent();
- });
- });
+ async #openPartialViewPickerModal() {
+ const partialViewPickerContext = this._modalContext?.open(UMB_PARTIAL_VIEW_PICKER_MODAL);
+ await partialViewPickerContext?.onSubmit();
+
+ const path = partialViewPickerContext?.getValue().selection[0];
+ if (!path) return;
+
+ this.determineInsertValue({ type: CodeSnippetType.partialView, value: path });
+ }
+
+ async #openDictionaryItemPickerModal() {
+ const dictionaryItemPickerContext = this._modalContext?.open(UMB_DICTIONARY_ITEM_PICKER_MODAL);
+ await dictionaryItemPickerContext?.onSubmit();
+
+ const item = dictionaryItemPickerContext?.getValue().selection[0];
+ if (!item) return;
+
+ this.determineInsertValue({ type: CodeSnippetType.dictionaryItem, value: item });
+ }
+
+ async #openPageFieldBuilderModal() {
+ const pageFieldBuilderContext = this._modalContext?.open(UMB_TEMPLATING_PAGE_FIELD_BUILDER_MODAL);
+ await pageFieldBuilderContext?.onSubmit();
+
+ const output = pageFieldBuilderContext?.getValue().output;
+ if (!output) return;
+
+ // The output is already built due to the preview in the modal. Can insert it directly now.
+ this.value = output;
+ this.#dispatchInsertEvent();
}
#dispatchInsertEvent() {
this.dispatchEvent(new CustomEvent('insert', { bubbles: false, cancelable: true, composed: false }));
}
- @property({ type: Boolean })
- hidePartialView = false;
-
render() {
return html`
-
+
${this.localize.term('template_insert')}
+ @click=${this.#openPageFieldBuilderModal}>
diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/modals/index.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/modals/index.ts
index b95cabeeec..a3237a45c0 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/templating/modals/index.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/templating/modals/index.ts
@@ -1,3 +1,4 @@
export * from './templating-section-picker/index.js';
export * from './templating-item-picker/index.js';
export * from './partial-view-picker/index.js';
+export * from './templating-page-field-builder/index.js';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/modals/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/modals/manifests.ts
index fac1177afb..4270e4c145 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/templating/modals/manifests.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/templating/modals/manifests.ts
@@ -13,6 +13,12 @@ const modals: Array
= [
name: 'Templating Section Picker Modal',
js: () => import('./templating-section-picker/templating-section-picker-modal.element.js'),
},
+ {
+ type: 'modal',
+ alias: 'Umb.Modal.TemplatingPageFieldBuilder',
+ name: 'Templating Page Field Builder Modal',
+ js: () => import('./templating-page-field-builder/templating-page-field-builder-modal.element.js'),
+ },
];
export const manifests = [...modals];
diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/modals/templating-item-picker/templating-item-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/modals/templating-item-picker/templating-item-picker-modal.element.ts
index 7450061be1..de6a71cf18 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/templating/modals/templating-item-picker/templating-item-picker-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/templating/modals/templating-item-picker/templating-item-picker-modal.element.ts
@@ -1,12 +1,13 @@
import { CodeSnippetType } from '../../types.js';
import { UMB_PARTIAL_VIEW_PICKER_MODAL } from '../partial-view-picker/partial-view-picker-modal.token.js';
+import { UMB_TEMPLATING_PAGE_FIELD_BUILDER_MODAL } from '../templating-page-field-builder/templating-page-field-builder-modal.token.js';
import type {
UmbTemplatingItemPickerModalData,
UmbTemplatingItemPickerModalValue,
} from './templating-item-picker-modal.token.js';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { css, html, customElement } from '@umbraco-cms/backoffice/external/lit';
-import type { UmbModalManagerContext, UmbModalContext } from '@umbraco-cms/backoffice/modal';
+import type { UmbModalManagerContext } from '@umbraco-cms/backoffice/modal';
import {
UMB_MODAL_MANAGER_CONTEXT,
UMB_DICTIONARY_ITEM_PICKER_MODAL,
@@ -22,43 +23,58 @@ export class UmbTemplatingItemPickerModalElement extends UmbModalBaseElement<
this.modalContext?.reject();
}
- private _modalContext?: UmbModalManagerContext;
+ private _itemModalContext?: UmbModalManagerContext;
constructor() {
super();
this.consumeContext(UMB_MODAL_MANAGER_CONTEXT, (instance) => {
- this._modalContext = instance;
+ this._itemModalContext = instance;
});
}
- #openModal?: UmbModalContext;
+ async #openTemplatingPageFieldModal() {
+ const pageFieldBuilderContext = this._itemModalContext?.open(UMB_TEMPLATING_PAGE_FIELD_BUILDER_MODAL);
+ await pageFieldBuilderContext?.onSubmit();
- #openInsertPartialViewSidebar() {
- this.#openModal = this._modalContext?.open(UMB_PARTIAL_VIEW_PICKER_MODAL);
- this.#openModal?.onSubmit().then((partialViewPickerModalValue) => {
- if (partialViewPickerModalValue) {
- this.value = {
- type: CodeSnippetType.partialView,
- value: partialViewPickerModalValue.selection[0],
- };
- this.modalContext?.submit();
- }
- });
+ const output = pageFieldBuilderContext?.getValue().output;
+
+ if (output) {
+ this.value = { value: output, type: CodeSnippetType.pageField };
+ this.modalContext?.submit();
+ }
}
- #openInsertDictionaryItemModal() {
- this.#openModal = this._modalContext?.open(UMB_DICTIONARY_ITEM_PICKER_MODAL, {
+ async #openPartialViewPickerModal() {
+ const partialViewPickerContext = this._itemModalContext?.open(UMB_PARTIAL_VIEW_PICKER_MODAL);
+ await partialViewPickerContext?.onSubmit();
+
+ const path = partialViewPickerContext?.getValue().selection[0];
+
+ if (path) {
+ const regex = /^%2F|%25dot%25cshtml$/g;
+ const prettyPath = path.replace(regex, '').replace(/%2F/g, '/');
+ this.value = {
+ value: prettyPath,
+ type: CodeSnippetType.partialView,
+ };
+ this.modalContext?.submit();
+ }
+ }
+
+ async #openDictionaryItemPickerModal() {
+ const dictionaryItemPickerModal = this._itemModalContext?.open(UMB_DICTIONARY_ITEM_PICKER_MODAL, {
data: {
- hideTreeRoot: true,
pickableFilter: (item) => item.id !== null,
},
});
- this.#openModal?.onSubmit().then((dictionaryItemPickerModalValue) => {
- if (dictionaryItemPickerModalValue) {
- this.value = { value: dictionaryItemPickerModalValue, type: CodeSnippetType.dictionaryItem };
- this.modalContext?.submit();
- }
- });
+ await dictionaryItemPickerModal?.onSubmit();
+
+ const dictionaryItem = dictionaryItemPickerModal?.getValue().selection[0];
+
+ if (dictionaryItem) {
+ this.value = { value: dictionaryItem, type: CodeSnippetType.dictionaryItem };
+ this.modalContext?.submit();
+ }
}
render() {
@@ -77,7 +93,7 @@ export class UmbTemplatingItemPickerModalElement extends UmbModalBaseElement<
#renderItems() {
return html`
console.log('to be continued')}
+ @click=${this.#openTemplatingPageFieldModal}
look="placeholder"
label=${this.localize.term('template_insert')}>
Value (Not implemented)
@@ -89,7 +105,7 @@ export class UmbTemplatingItemPickerModalElement extends UmbModalBaseElement<
Partial view
@@ -101,7 +117,7 @@ export class UmbTemplatingItemPickerModalElement extends UmbModalBaseElement<
Dictionary Item
diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/modals/templating-item-picker/templating-item-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/modals/templating-item-picker/templating-item-picker-modal.token.ts
index 79e593dae8..9a0a15e733 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/templating/modals/templating-item-picker/templating-item-picker-modal.token.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/templating/modals/templating-item-picker/templating-item-picker-modal.token.ts
@@ -1,4 +1,5 @@
import type { CodeSnippetType } from '../../types.js';
+import type { UmbPartialViewPickerModalValue, UmbTemplatingPageFieldBuilderModalValue } from '../index.js';
import { type UmbDictionaryItemPickerModalValue, UmbModalToken } from '@umbraco-cms/backoffice/modal';
export interface UmbTemplatingItemPickerModalData {
@@ -6,7 +7,7 @@ export interface UmbTemplatingItemPickerModalData {
}
export type UmbTemplatingItemPickerModalValue = {
- value: string | UmbDictionaryItemPickerModalValue;
+ value: string;
type: CodeSnippetType;
};
diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/modals/templating-page-field-builder/index.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/modals/templating-page-field-builder/index.ts
new file mode 100644
index 0000000000..696a5c05e5
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/templating/modals/templating-page-field-builder/index.ts
@@ -0,0 +1,2 @@
+export * from './templating-page-field-builder-modal.element.js';
+export * from './templating-page-field-builder-modal.token.js';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/modals/templating-page-field-builder/templating-page-field-builder-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/modals/templating-page-field-builder/templating-page-field-builder-modal.element.ts
new file mode 100644
index 0000000000..fa026ffe32
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/templating/modals/templating-page-field-builder/templating-page-field-builder-modal.element.ts
@@ -0,0 +1,116 @@
+import type {
+ UmbTemplatingPageFieldBuilderModalData,
+ UmbTemplatingPageFieldBuilderModalValue,
+} from './templating-page-field-builder-modal.token.js';
+import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
+import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit';
+import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
+
+@customElement('umb-templating-page-field-builder-modal')
+export class UmbTemplatingPageFieldBuilderModalElement extends UmbModalBaseElement<
+ UmbTemplatingPageFieldBuilderModalData,
+ UmbTemplatingPageFieldBuilderModalValue
+> {
+ private _close() {
+ this.modalContext?.reject();
+ }
+
+ private _submit() {
+ this.value = { output: this.#generateOutput() };
+ this.modalContext?.submit();
+ }
+
+ @state()
+ private _field?: string;
+
+ @state()
+ private _haveDefault: boolean = false;
+
+ @state()
+ private _default?: string;
+
+ @state()
+ private _recursive: boolean = false;
+
+ #generateOutput() {
+ if (!this._field) return '';
+ if (this._default && !this._recursive) {
+ return `@Model.Value("${this._field}", fallback: Fallback.ToDefaultValue, defaultValue: new HtmlString("${this._default}"))`;
+ } else if (this._default && this._recursive) {
+ return `@Model.Value("${this._field}", fallback: Fallback.To(Fallback.Ancestors, Fallback.DefaultValue), defaultValue: new HtmlString("${this._default}"))`;
+ } else if (!this._default && this._recursive) {
+ return `@Model.Value("${this._field}", fallback: Fallback.ToAncestors)`;
+ } else {
+ return `@Model.Value("${this._field}")`;
+ }
+ }
+
+ render() {
+ return html`
+
+
+
+
+ Choose field
+
+ (Not implemented yet)
+
+
+ Default value
+
+ ${!this._haveDefault
+ ? html` (this._haveDefault = true)}>`
+ : html``}
+
+ Recursive
+
+
+ Output sample
+ ${this.#generateOutput()}
+
+
+
+
+
+ `;
+ }
+
+ static styles = [
+ UmbTextStyles,
+ css`
+ uui-box > div {
+ display: grid;
+ gap: var(--uui-size-space-2);
+ }
+
+ uui-label:not(:first-child) {
+ margin-top: var(--uui-size-space-6);
+ }
+ `,
+ ];
+}
+
+export default UmbTemplatingPageFieldBuilderModalElement;
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'umb-templating-page-field-builder-modal': UmbTemplatingPageFieldBuilderModalElement;
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/modals/templating-page-field-builder/templating-page-field-builder-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/modals/templating-page-field-builder/templating-page-field-builder-modal.token.ts
new file mode 100644
index 0000000000..ad621e61b5
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/templating/modals/templating-page-field-builder/templating-page-field-builder-modal.token.ts
@@ -0,0 +1,17 @@
+import { UmbModalToken } from '@umbraco-cms/backoffice/modal';
+
+export interface UmbTemplatingPageFieldBuilderModalData {}
+
+export type UmbTemplatingPageFieldBuilderModalValue = {
+ output: string;
+};
+
+export const UMB_TEMPLATING_PAGE_FIELD_BUILDER_MODAL = new UmbModalToken<
+ UmbTemplatingPageFieldBuilderModalData,
+ UmbTemplatingPageFieldBuilderModalValue
+>('Umb.Modal.TemplatingPageFieldBuilder', {
+ modal: {
+ type: 'sidebar',
+ size: 'small',
+ },
+});
diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/types.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/types.ts
index 01a83f31b0..30d70c464b 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/templating/types.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/templating/types.ts
@@ -1,4 +1,5 @@
export enum CodeSnippetType {
partialView = 'partialView',
dictionaryItem = 'dictionaryItem',
+ pageField = 'pageField',
}