Skip to content

Commit 4f3f2ef

Browse files
authored
Adds UFM Link component (#17636)
to support the Multi-URL Picker editor.
1 parent bea12b7 commit 4f3f2ef

File tree

3 files changed

+106
-0
lines changed

3 files changed

+106
-0
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import type { UfmToken } from '../../plugins/marked-ufm.plugin.js';
2+
import { UmbUfmComponentBase } from '../ufm-component-base.js';
3+
4+
import './link.element.js';
5+
6+
export class UmbUfmLinkComponent extends UmbUfmComponentBase {
7+
render(token: UfmToken) {
8+
if (!token.text) return;
9+
10+
const attributes = super.getAttributes(token.text);
11+
return `<ufm-link ${attributes}></ufm-link>`;
12+
}
13+
}
14+
15+
export { UmbUfmLinkComponent as api };
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { UmbUfmElementBase } from '../ufm-element-base.js';
2+
import { UMB_UFM_RENDER_CONTEXT } from '../ufm-render/ufm-render.context.js';
3+
import { customElement, property } from '@umbraco-cms/backoffice/external/lit';
4+
import { UmbDocumentItemRepository, UMB_DOCUMENT_ENTITY_TYPE } from '@umbraco-cms/backoffice/document';
5+
import { UmbMediaItemRepository, UMB_MEDIA_ENTITY_TYPE } from '@umbraco-cms/backoffice/media';
6+
import type { UmbLinkPickerLink } from '@umbraco-cms/backoffice/multi-url-picker';
7+
8+
const elementName = 'ufm-link';
9+
10+
@customElement(elementName)
11+
export class UmbUfmLinkElement extends UmbUfmElementBase {
12+
@property()
13+
alias?: string;
14+
15+
#documentRepository?: UmbDocumentItemRepository;
16+
#mediaRepository?: UmbMediaItemRepository;
17+
18+
constructor() {
19+
super();
20+
21+
this.consumeContext(UMB_UFM_RENDER_CONTEXT, (context) => {
22+
this.observe(
23+
context.value,
24+
async (value) => {
25+
const temp =
26+
this.alias && typeof value === 'object'
27+
? (value as Record<string, unknown>)[this.alias]
28+
: (value as unknown);
29+
30+
if (!temp) return;
31+
32+
const items = Array.isArray(temp) ? temp : [temp];
33+
const names = await Promise.all(items.map(async (item) => await this.#getName(item)));
34+
this.value = names.filter((x) => x).join(', ');
35+
},
36+
'observeValue',
37+
);
38+
});
39+
}
40+
41+
async #getName(item?: unknown) {
42+
const link = item as UmbLinkPickerLink;
43+
44+
if (link.name) {
45+
return link.name;
46+
}
47+
48+
const entityType = link.type;
49+
const unique = link.unique;
50+
51+
if (unique) {
52+
const repository = this.#getRepository(entityType);
53+
if (repository) {
54+
const { data } = await repository.requestItems([unique]);
55+
if (Array.isArray(data) && data.length > 0) {
56+
return data.map((item) => item.name).join(', ');
57+
}
58+
}
59+
}
60+
61+
return '';
62+
}
63+
64+
#getRepository(entityType?: string | null) {
65+
switch (entityType) {
66+
case UMB_MEDIA_ENTITY_TYPE:
67+
if (!this.#mediaRepository) this.#mediaRepository = new UmbMediaItemRepository(this);
68+
return this.#mediaRepository;
69+
70+
case UMB_DOCUMENT_ENTITY_TYPE:
71+
default:
72+
if (!this.#documentRepository) this.#documentRepository = new UmbDocumentItemRepository(this);
73+
return this.#documentRepository;
74+
}
75+
}
76+
}
77+
78+
export { UmbUfmLinkElement as element };
79+
80+
declare global {
81+
interface HTMLElementTagNameMap {
82+
[elementName]: UmbUfmLinkElement;
83+
}
84+
}

src/Umbraco.Web.UI.Client/src/packages/ufm/components/manifests.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,11 @@ export const manifests: Array<ManifestUfmComponent> = [
2222
api: () => import('./content-name/content-name.component.js'),
2323
meta: { alias: 'umbContentName', marker: '~' },
2424
},
25+
{
26+
type: 'ufmComponent',
27+
alias: 'Umb.Markdown.Link',
28+
name: 'Link UFM Component',
29+
api: () => import('./link/link.component.js'),
30+
meta: { alias: 'umbLink' },
31+
},
2532
];

0 commit comments

Comments
 (0)