Adds UFM Link component (#17636)

to support the Multi-URL Picker editor.
This commit is contained in:
Lee Kelleher
2024-11-26 13:45:09 +00:00
committed by GitHub
parent bea12b7a50
commit 4f3f2efbdc
3 changed files with 106 additions and 0 deletions

View File

@@ -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 `<ufm-link ${attributes}></ufm-link>`;
}
}
export { UmbUfmLinkComponent as api };

View File

@@ -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<string, unknown>)[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;
}
}

View File

@@ -22,4 +22,11 @@ export const manifests: Array<ManifestUfmComponent> = [
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' },
},
];