From 4f3f2efbdc2fab5070abeb325fa4d8a00069bd54 Mon Sep 17 00:00:00 2001 From: Lee Kelleher Date: Tue, 26 Nov 2024 13:45:09 +0000 Subject: [PATCH] Adds UFM Link component (#17636) to support the Multi-URL Picker editor. --- .../ufm/components/link/link.component.ts | 15 ++++ .../ufm/components/link/link.element.ts | 84 +++++++++++++++++++ .../src/packages/ufm/components/manifests.ts | 7 ++ 3 files changed, 106 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/ufm/components/link/link.component.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/ufm/components/link/link.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/link/link.component.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/link/link.component.ts new file mode 100644 index 0000000000..c49258e30f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/link/link.component.ts @@ -0,0 +1,15 @@ +import type { UfmToken } from '../../plugins/marked-ufm.plugin.js'; +import { UmbUfmComponentBase } from '../ufm-component-base.js'; + +import './link.element.js'; + +export class UmbUfmLinkComponent extends UmbUfmComponentBase { + render(token: UfmToken) { + if (!token.text) return; + + const attributes = super.getAttributes(token.text); + return ``; + } +} + +export { UmbUfmLinkComponent as api }; 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 new file mode 100644 index 0000000000..b53b276b00 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/link/link.element.ts @@ -0,0 +1,84 @@ +import { UmbUfmElementBase } from '../ufm-element-base.js'; +import { UMB_UFM_RENDER_CONTEXT } from '../ufm-render/ufm-render.context.js'; +import { customElement, property } from '@umbraco-cms/backoffice/external/lit'; +import { UmbDocumentItemRepository, UMB_DOCUMENT_ENTITY_TYPE } from '@umbraco-cms/backoffice/document'; +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) +export class UmbUfmLinkElement extends UmbUfmElementBase { + @property() + alias?: string; + + #documentRepository?: UmbDocumentItemRepository; + #mediaRepository?: UmbMediaItemRepository; + + constructor() { + super(); + + this.consumeContext(UMB_UFM_RENDER_CONTEXT, (context) => { + this.observe( + context.value, + async (value) => { + const temp = + this.alias && typeof value === 'object' + ? (value as Record)[this.alias] + : (value as unknown); + + if (!temp) return; + + const items = Array.isArray(temp) ? temp : [temp]; + const names = await Promise.all(items.map(async (item) => await this.#getName(item))); + this.value = names.filter((x) => x).join(', '); + }, + 'observeValue', + ); + }); + } + + async #getName(item?: unknown) { + const link = item as UmbLinkPickerLink; + + if (link.name) { + return link.name; + } + + const entityType = link.type; + const unique = link.unique; + + if (unique) { + const repository = this.#getRepository(entityType); + if (repository) { + const { data } = await repository.requestItems([unique]); + if (Array.isArray(data) && data.length > 0) { + return data.map((item) => item.name).join(', '); + } + } + } + + return ''; + } + + #getRepository(entityType?: string | null) { + switch (entityType) { + case UMB_MEDIA_ENTITY_TYPE: + if (!this.#mediaRepository) this.#mediaRepository = new UmbMediaItemRepository(this); + return this.#mediaRepository; + + case UMB_DOCUMENT_ENTITY_TYPE: + default: + if (!this.#documentRepository) this.#documentRepository = new UmbDocumentItemRepository(this); + return this.#documentRepository; + } + } +} + +export { UmbUfmLinkElement as element }; + +declare global { + interface HTMLElementTagNameMap { + [elementName]: UmbUfmLinkElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/manifests.ts index b9c7f5dc6f..c247af5a31 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/ufm/components/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/components/manifests.ts @@ -22,4 +22,11 @@ export const manifests: Array = [ api: () => import('./content-name/content-name.component.js'), meta: { alias: 'umbContentName', marker: '~' }, }, + { + type: 'ufmComponent', + alias: 'Umb.Markdown.Link', + name: 'Link UFM Component', + api: () => import('./link/link.component.js'), + meta: { alias: 'umbLink' }, + }, ];