diff --git a/src/Umbraco.Web.UI.Client/devops/eslint/rules/enforce-umb-prefix-on-element-name.cjs b/src/Umbraco.Web.UI.Client/devops/eslint/rules/enforce-umb-prefix-on-element-name.cjs index 5db023e932..2fc62a385a 100644 --- a/src/Umbraco.Web.UI.Client/devops/eslint/rules/enforce-umb-prefix-on-element-name.cjs +++ b/src/Umbraco.Web.UI.Client/devops/eslint/rules/enforce-umb-prefix-on-element-name.cjs @@ -23,13 +23,14 @@ module.exports = { if (isCustomElementDecorator) { const elementName = node.arguments[0].value; - // check if the element name starts with 'umb-', or 'test-', to be allow tests to have custom elements: - const isElementNameValid = elementName.startsWith('umb-') ? true : elementName.startsWith('test-'); + // check if the element name starts with 'umb-', 'ufm-', or 'test-', to be allow tests to have custom elements: + const prefixes = ['umb-', 'ufm-', 'test-']; + const isElementNameValid = prefixes.some((prefix) => elementName.startsWith(prefix)); if (!isElementNameValid) { context.report({ node, - message: 'Custom Element name should start with "umb-".', + message: 'Custom Element name should start with "umb-" or "ufm-".', // There is no fixer on purpose because it's not safe to automatically rename the element name. // Renaming should be done manually with consideration of potential impacts. }); diff --git a/src/Umbraco.Web.UI.Client/examples/ufm-custom-component/custom-ufm-component.ts b/src/Umbraco.Web.UI.Client/examples/ufm-custom-component/custom-ufm-component.ts index 9f4486eb7a..8df2bc229a 100644 --- a/src/Umbraco.Web.UI.Client/examples/ufm-custom-component/custom-ufm-component.ts +++ b/src/Umbraco.Web.UI.Client/examples/ufm-custom-component/custom-ufm-component.ts @@ -11,7 +11,6 @@ export class UmbCustomUfmComponent extends UmbUfmComponentBase { } } -// eslint-disable-next-line local-rules/enforce-umb-prefix-on-element-name @customElement('ufm-custom-component') export class UmbCustomUfmComponentElement extends UmbLitElement { @property() diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/content-name/content-name.element.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/content-name/content-name.element.ts index b9875ce9f9..176e58c3b6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/content-name/content-name.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/content-name/content-name.element.ts @@ -6,9 +6,7 @@ import { UmbId } from '@umbraco-cms/backoffice/id'; import { UmbMediaItemRepository, UMB_MEDIA_ENTITY_TYPE } from '@umbraco-cms/backoffice/media'; import { UmbMemberItemRepository, UMB_MEMBER_ENTITY_TYPE } from '@umbraco-cms/backoffice/member'; -const elementName = 'ufm-content-name'; - -@customElement(elementName) +@customElement('ufm-content-name') export class UmbUfmContentNameElement extends UmbUfmElementBase { @property() alias?: string; @@ -95,6 +93,6 @@ export { UmbUfmContentNameElement as element }; declare global { interface HTMLElementTagNameMap { - [elementName]: UmbUfmContentNameElement; + 'ufm-content-name': UmbUfmContentNameElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/label-value/label-value.element.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/label-value/label-value.element.ts index f2ab78c8ac..0c5f9e0b4d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/label-value/label-value.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/label-value/label-value.element.ts @@ -2,9 +2,7 @@ import { UMB_UFM_RENDER_CONTEXT } from '../ufm-render/ufm-render.context.js'; import { UmbUfmElementBase } from '../ufm-element-base.js'; import { customElement, property } from '@umbraco-cms/backoffice/external/lit'; -const elementName = 'ufm-label-value'; - -@customElement(elementName) +@customElement('ufm-label-value') export class UmbUfmLabelValueElement extends UmbUfmElementBase { @property() alias?: string; @@ -32,6 +30,6 @@ export { UmbUfmLabelValueElement as element }; declare global { interface HTMLElementTagNameMap { - [elementName]: UmbUfmLabelValueElement; + 'ufm-label-value': UmbUfmLabelValueElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/link/link.element.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/link/link.element.ts index 268cd9c82f..59b6540fd1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/link/link.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/link/link.element.ts @@ -5,9 +5,7 @@ import { UmbDocumentItemRepository, UMB_DOCUMENT_ENTITY_TYPE } from '@umbraco-cm import { UmbMediaItemRepository, UMB_MEDIA_ENTITY_TYPE } from '@umbraco-cms/backoffice/media'; import type { UmbLinkPickerLink } from '@umbraco-cms/backoffice/multi-url-picker'; -const elementName = 'ufm-link'; - -@customElement(elementName) +@customElement('ufm-link') export class UmbUfmLinkElement extends UmbUfmElementBase { @property() alias?: string; @@ -79,6 +77,6 @@ export { UmbUfmLinkElement as element }; declare global { interface HTMLElementTagNameMap { - [elementName]: UmbUfmLinkElement; + 'ufm-link': UmbUfmLinkElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/localize/localize.element.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/localize/localize.element.ts index 9f440de11a..09ec97738c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/localize/localize.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/localize/localize.element.ts @@ -1,9 +1,7 @@ import { UmbUfmElementBase } from '../ufm-element-base.js'; import { customElement, property } from '@umbraco-cms/backoffice/external/lit'; -const elementName = 'ufm-localize'; - -@customElement(elementName) +@customElement('ufm-localize') export class UmbUfmLocalizeElement extends UmbUfmElementBase { @property() public set alias(value: string | undefined) { @@ -21,6 +19,6 @@ export { UmbUfmLocalizeElement as element }; declare global { interface HTMLElementTagNameMap { - [elementName]: UmbUfmLocalizeElement; + 'ufm-localize': UmbUfmLocalizeElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/ufm-element-base.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/ufm-element-base.ts index 14e9d85201..7e16889dbe 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/ufm-element-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/ufm-element-base.ts @@ -1,10 +1,12 @@ import { UMB_UFM_CONTEXT } from '../contexts/ufm.context.js'; -import { nothing, property, state } from '@umbraco-cms/backoffice/external/lit'; +import { property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; export abstract class UmbUfmElementBase extends UmbLitElement { #filterFuncArgs?: Array<{ alias: string; args: Array }>; + #ufmContext?: typeof UMB_UFM_CONTEXT.TYPE; + @property() public set filters(value: string | undefined) { this.#filters = value; @@ -25,8 +27,6 @@ export abstract class UmbUfmElementBase extends UmbLitElement { @state() value?: unknown; - #ufmContext?: typeof UMB_UFM_CONTEXT.TYPE; - constructor() { super(); @@ -36,16 +36,23 @@ export abstract class UmbUfmElementBase extends UmbLitElement { } override render() { - if (!this.#ufmContext) return nothing; - let values = Array.isArray(this.value) ? this.value : [this.value]; + if (this.#filterFuncArgs) { + const missing = new Set(); + for (const item of this.#filterFuncArgs) { - const filter = this.#ufmContext.getFilterByAlias(item.alias); + const filter = this.#ufmContext?.getFilterByAlias(item.alias); if (filter) { values = values.map((value) => filter(value, ...item.args)); + } else { + missing.add(item.alias); } } + + if (missing.size > 0) { + console.warn(`UFM filters with aliases "${Array.from(missing).join('", "')}" were not found.`); + } } return values.join(', '); diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/ufm-render/ufm-render.element.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/ufm-render/ufm-render.element.ts index a589c32d34..54f7d0c8c0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/ufm-render/ufm-render.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/ufm-render/ufm-render.element.ts @@ -4,9 +4,7 @@ import { css, customElement, nothing, property, unsafeHTML, until } from '@umbra import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -const elementName = 'umb-ufm-render'; - -@customElement(elementName) +@customElement('umb-ufm-render') export class UmbUfmRenderElement extends UmbLitElement { #context = new UmbUfmRenderContext(this); @@ -16,7 +14,8 @@ export class UmbUfmRenderElement extends UmbLitElement { @property() markdown?: string; - // No reactive property declaration cause its causing a re-render that is not needed. This just works as a shortcut to set the values on the context. [NL] + // No reactive property declaration because it's causing a re-render that is not needed. + // This just works as a shortcut to set the values on the context. [NL] public set value(value: string | unknown | undefined) { this.#context.setValue(value); } @@ -75,6 +74,6 @@ export { UmbUfmRenderElement as element }; declare global { interface HTMLElementTagNameMap { - [elementName]: UmbUfmRenderElement; + 'umb-ufm-render': UmbUfmRenderElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/contexts/ufm.context.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/contexts/ufm.context.ts index bcf9b84510..8c8d3971f5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/ufm/contexts/ufm.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/contexts/ufm.context.ts @@ -32,9 +32,7 @@ export const UmbMarked = new Marked({ gfm: true, breaks: true, hooks: { - postprocess: (markup) => { - return UmbDomPurify.sanitize(markup, UmbDomPurifyConfig) as string; - }, + postprocess: (markup) => UmbDomPurify.sanitize(markup, UmbDomPurifyConfig), }, });