template page field modal beginning

This commit is contained in:
Lone Iversen
2024-02-16 15:32:57 +01:00
parent 73eec75e00
commit 4d67cfc870
11 changed files with 247 additions and 87 deletions

View File

@@ -14,6 +14,7 @@ export const UMB_DICTIONARY_ITEM_PICKER_MODAL = new UmbModalToken<
size: 'small',
},
data: {
hideTreeRoot: true,
treeAlias: 'Umb.Tree.Dictionary',
},
});

View File

@@ -110,6 +110,7 @@ export class UmbPropertyEditorUICollectionViewColumnConfigurationElement
}
render() {
console.log(this.config);
return html`<div>
<uui-select .options=${this._options} label="Select"></uui-select>
<uui-button label=${this.localize.term('general_add')} look="secondary" @click=${this.#onAdd}></uui-button>

View File

@@ -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`
<uui-button-group>
<uui-button look="secondary" @click=${this.#openChooseTypeModal} label=${this.localize.term('template_insert')}>
<uui-button
look="secondary"
@click=${this.#openTemplatingItemPickerModal}
label=${this.localize.term('template_insert')}>
<uui-icon name="icon-add"></uui-icon>${this.localize.term('template_insert')}
</uui-button>
<umb-dropdown
@@ -126,18 +124,18 @@ export class UmbTemplatingInsertMenuElement extends UmbLitElement {
class="insert-menu-item"
label=${this.localize.term('template_insertPageField')}
title=${this.localize.term('template_insertPageField')}
@click=${this.#openInsertPageFieldSidebar}></uui-menu-item>
@click=${this.#openPageFieldBuilderModal}></uui-menu-item>
<uui-menu-item
class="insert-menu-item"
label=${this.localize.term('template_insertPartialView')}
title=${this.localize.term('template_insertPartialView')}
@click=${this.#openInsertPartialViewSidebar}>
@click=${this.#openPartialViewPickerModal}>
</uui-menu-item>
<uui-menu-item
class="insert-menu-item"
label=${this.localize.term('template_insertDictionaryItem')}
title=${this.localize.term('template_insertDictionaryItem')}
@click=${this.#openInsertDictionaryItemModal}>
@click=${this.#openDictionaryItemPickerModal}>
</uui-menu-item>
</umb-dropdown>
</uui-button-group>

View File

@@ -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';

View File

@@ -13,6 +13,12 @@ const modals: Array<ManifestModal> = [
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];

View File

@@ -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`<div id="main">
<uui-button
@click=${() => console.log('to be continued')}
@click=${this.#openTemplatingPageFieldModal}
look="placeholder"
label=${this.localize.term('template_insert')}>
<h3><umb-localize key="template_insertPageField">Value</umb-localize> (Not implemented)</h3>
@@ -89,7 +105,7 @@ export class UmbTemplatingItemPickerModalElement extends UmbModalBaseElement<
</p>
</uui-button>
<uui-button
@click=${this.#openInsertPartialViewSidebar}
@click=${this.#openPartialViewPickerModal}
look="placeholder"
label=${this.localize.term('template_insert')}>
<h3><umb-localize key="template_insertPartialView">Partial view</umb-localize></h3>
@@ -101,7 +117,7 @@ export class UmbTemplatingItemPickerModalElement extends UmbModalBaseElement<
</p>
</uui-button>
<uui-button
@click=${this.#openInsertDictionaryItemModal}
@click=${this.#openDictionaryItemPickerModal}
look="placeholder"
label=${this.localize.term('template_insertDictionaryItem')}>
<h3><umb-localize key="template_insertDictionaryItem">Dictionary Item</umb-localize></h3>

View File

@@ -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;
};

View File

@@ -0,0 +1,2 @@
export * from './templating-page-field-builder-modal.element.js';
export * from './templating-page-field-builder-modal.token.js';

View File

@@ -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`
<umb-body-layout headline=${this.localize.term('template_insert')}>
<uui-box>
<div>
<uui-label for="page-field-value">
<umb-localize key="templateEditor_chooseField">Choose field</umb-localize>
</uui-label>
(Not implemented yet)
<uui-label for="page-field-default-value">
<umb-localize key="templateEditor_defaultValue">Default value</umb-localize>
</uui-label>
${!this._haveDefault
? html`<uui-button
label=${this.localize.term('templateEditor_addDefaultValue')}
look="placeholder"
@click=${() => (this._haveDefault = true)}></uui-button>`
: html`<uui-input
id="page-field-default-value"
label=${this.localize.term('templateEditor_defaultValue')}></uui-input>`}
<uui-label for="recursive"><umb-localize key="templateEditor_recursive">Recursive</umb-localize></uui-label>
<uui-checkbox
id="recursive"
label=${this.localize.term('templateEditor_recursiveDescr')}
?disabled=${this._field ? false : true}></uui-checkbox>
<uui-label><umb-localize key="templateEditor_outputSample">Output sample</umb-localize></uui-label>
<umb-code-block language="C#" copy>${this.#generateOutput()}</umb-code-block>
</div>
</uui-box>
<uui-button
slot="actions"
@click=${this._close}
look="secondary"
label=${this.localize.term('general_close')}></uui-button>
<uui-button
slot="actions"
@click=${this._submit}
color="positive"
look="primary"
label=${this.localize.term('general_close')}></uui-button>
</umb-body-layout>
`;
}
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;
}
}

View File

@@ -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',
},
});

View File

@@ -1,4 +1,5 @@
export enum CodeSnippetType {
partialView = 'partialView',
dictionaryItem = 'dictionaryItem',
pageField = 'pageField',
}