diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/schemas/Umbraco.MediaPicker.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/schemas/Umbraco.MediaPicker.ts index c03b67a7a3..12b32ace13 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/schemas/Umbraco.MediaPicker.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/schemas/Umbraco.MediaPicker.ts @@ -12,7 +12,7 @@ export const manifest: ManifestPropertyEditorSchema = { alias: 'filter', label: 'Accepted types', description: 'Limit to specific types', - propertyEditorUiAlias: 'Umb.PropertyEditorUi.TreePicker', + propertyEditorUiAlias: 'Umb.PropertyEditorUi.MediaTypePicker', }, { alias: 'multiple', diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/uis/tree-picker/property-editor-ui-tree-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/uis/tree-picker/property-editor-ui-tree-picker.element.ts index c01c6eae0c..d1952c415c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/uis/tree-picker/property-editor-ui-tree-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/uis/tree-picker/property-editor-ui-tree-picker.element.ts @@ -56,6 +56,7 @@ export class UmbPropertyEditorUITreePickerElement extends UmbLitElement implemen this.min = Number(config?.getValueByAlias('minNumber')) || 0; this.max = Number(config?.getValueByAlias('maxNumber')) || 0; + this.type = config?.getValueByAlias('type') ?? 'content'; this.allowedContentTypeIds = config?.getValueByAlias('filter'); this.showOpenButton = config?.getValueByAlias('showOpenButton'); this.ignoreUserStartNodes = config?.getValueByAlias('ignoreUserStartNodes'); diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/components/input-document-type/input-document-type.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/components/input-document-type/input-document-type.element.ts index 3e5be1075f..89978f248b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/components/input-document-type/input-document-type.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/components/input-document-type/input-document-type.element.ts @@ -72,12 +72,13 @@ export class UmbInputDocumentTypeElement extends FormControlMixin(UmbLitElement) @property({ type: String, attribute: 'min-message' }) maxMessage = 'This field exceeds the allowed amount of items'; - public get selectedIds(): Array { - return this.#pickerContext.getSelection(); - } + @property({ type: Array }) public set selectedIds(ids: Array | undefined) { this.#pickerContext.setSelection(ids ?? []); } + public get selectedIds(): Array { + return this.#pickerContext.getSelection(); + } @property() public set value(idsString: string) { @@ -165,9 +166,7 @@ export class UmbInputDocumentTypeElement extends FormControlMixin(UmbLitElement) id="add-button" look="placeholder" @click=${this.#openPicker} - label="${this.localize.term('general_choose')}" - >${this.localize.term('general_choose')} + label="${this.localize.term('general_choose')}"> `; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/property-editors/document-type-picker/property-editor-ui-document-type-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/property-editors/document-type-picker/property-editor-ui-document-type-picker.element.ts index f7c7c37b07..b90e5184f2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/property-editors/document-type-picker/property-editor-ui-document-type-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/property-editors/document-type-picker/property-editor-ui-document-type-picker.element.ts @@ -2,18 +2,15 @@ import type { UmbInputDocumentTypeElement } from '../../components/input-documen import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor'; +import { + UmbPropertyValueChangeEvent, + type UmbPropertyEditorConfigCollection, +} from '@umbraco-cms/backoffice/property-editor'; @customElement('umb-property-editor-ui-document-type-picker') export class UmbPropertyEditorUIDocumentTypePickerElement extends UmbLitElement implements UmbPropertyEditorUiElement { - @property({ type: Array }) - public get value(): Array | string | undefined { - return this._value; - } - public set value(value: Array | string | undefined) { - this._value = value; - } - private _value?: Array | string; + @property() + public value?: string; @property({ attribute: false }) public set config(config: UmbPropertyEditorConfigCollection | undefined) { @@ -27,6 +24,9 @@ export class UmbPropertyEditorUIDocumentTypePickerElement extends UmbLitElement this._onlyElementTypes = config.getValueByAlias('onlyPickElementTypes') ?? false; } } + public get config() { + return undefined; + } @state() private _limitMin?: number; @@ -39,8 +39,8 @@ export class UmbPropertyEditorUIDocumentTypePickerElement extends UmbLitElement private _onChange(event: CustomEvent) { const selectedIds = (event.target as UmbInputDocumentTypeElement).selectedIds; - this.value = this._multiPicker ? selectedIds : selectedIds[0]; - this.dispatchEvent(new CustomEvent('property-value-change')); + this.value = this._multiPicker ? selectedIds.join(',') : selectedIds[0]; + this.dispatchEvent(new UmbPropertyValueChangeEvent()); } // TODO: Implement mandatory? @@ -49,17 +49,13 @@ export class UmbPropertyEditorUIDocumentTypePickerElement extends UmbLitElement ? html` ) ?? [] - : this._value - ? [this._value as string] - : []} + .value=${this.value ?? ''} .min=${this._limitMin ?? 0} .max=${this._limitMax ?? Infinity} - .elementTypesOnly=${this._onlyElementTypes ?? false} - >Add - ` + .elementTypesOnly=${this._onlyElementTypes ?? false}> + Add + + ` : ''; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts index 200afe809a..ac14ad3495 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts @@ -96,6 +96,9 @@ export class UmbInputDocumentElement extends FormControlMixin(UmbLitElement) { // Its with full purpose we don't call super.value, as thats being handled by the observation of the context selection. this.selectedIds = splitStringToArray(idsString); } + public get value() { + return this.selectedIds.join(','); + } @state() private _editDocumentPath = ''; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/property-editors/document-picker/property-editor-ui-document-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/property-editors/document-picker/property-editor-ui-document-picker.element.ts index 1239e92c6b..e70230c44a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/property-editors/document-picker/property-editor-ui-document-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/property-editors/document-picker/property-editor-ui-document-picker.element.ts @@ -2,19 +2,15 @@ import type { UmbInputDocumentElement } from '../../components/input-document/in import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor'; +import { + UmbPropertyValueChangeEvent, + type UmbPropertyEditorConfigCollection, +} from '@umbraco-cms/backoffice/property-editor'; @customElement('umb-property-editor-ui-document-picker') export class UmbPropertyEditorUIDocumentPickerElement extends UmbLitElement implements UmbPropertyEditorUiElement { - private _value: Array = []; - - @property({ type: Array }) - public get value(): Array { - return this._value; - } - public set value(value: Array) { - this._value = Array.isArray(value) ? value : value ? [value] : []; - } + @property() + public value?: string; @property({ attribute: false }) public set config(config: UmbPropertyEditorConfigCollection | undefined) { @@ -23,6 +19,9 @@ export class UmbPropertyEditorUIDocumentPickerElement extends UmbLitElement impl this._limitMin = (validationLimit?.value as any)?.min; this._limitMax = (validationLimit?.value as any)?.max; } + public get config() { + return undefined; + } @state() private _limitMin?: number; @@ -30,8 +29,8 @@ export class UmbPropertyEditorUIDocumentPickerElement extends UmbLitElement impl private _limitMax?: number; private _onChange(event: CustomEvent) { - this.value = (event.target as UmbInputDocumentElement).selectedIds; - this.dispatchEvent(new CustomEvent('property-value-change')); + this.value = (event.target as UmbInputDocumentElement).selectedIds.join(','); + this.dispatchEvent(new UmbPropertyValueChangeEvent()); } // TODO: Implement mandatory? @@ -39,11 +38,11 @@ export class UmbPropertyEditorUIDocumentPickerElement extends UmbLitElement impl return html` Add + .max=${this._limitMax ?? Infinity}> + Add + `; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/components/input-media-type/input-media-type.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/components/input-media-type/input-media-type.element.ts index f6f590da8e..b17f6f80e4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/components/input-media-type/input-media-type.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/components/input-media-type/input-media-type.element.ts @@ -53,18 +53,22 @@ export class UmbInputMediaTypeElement extends FormControlMixin(UmbLitElement) { @property({ type: String, attribute: 'min-message' }) maxMessage = 'This field exceeds the allowed amount of items'; - public get selectedIds(): Array { - return this.#pickerContext.getSelection(); - } + @property({ type: Array }) public set selectedIds(ids: Array) { this.#pickerContext.setSelection(ids); } + public get selectedIds(): Array { + return this.#pickerContext.getSelection(); + } @property() public set value(idsString: string) { // Its with full purpose we don't call super.value, as thats being handled by the observation of the context selection. this.selectedIds = splitStringToArray(idsString); } + public get value() { + return this.selectedIds.join(','); + } @state() private _items?: Array; @@ -107,13 +111,13 @@ export class UmbInputMediaTypeElement extends FormControlMixin(UmbLitElement) { #renderItems() { if (!this._items) return; return html` - ${repeat( + + ${repeat( this._items, (item) => item.unique, (item) => this.#renderItem(item), - )} + )} + `; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/manifests.ts index 51dc7d38ed..208a10d90d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/manifests.ts @@ -3,6 +3,7 @@ import { manifests as menuItemManifests } from './menu-item/manifests.js'; import { manifests as repositoryManifests } from './repository/manifests.js'; import { manifests as treeManifests } from './tree/manifests.js'; import { manifests as workspaceManifests } from './workspace/manifests.js'; +import { manifests as propertyEditorUiManifests } from './property-editors/manifests.js'; export const manifests = [ ...entityActionsManifests, @@ -10,4 +11,5 @@ export const manifests = [ ...repositoryManifests, ...treeManifests, ...workspaceManifests, + ...propertyEditorUiManifests, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/property-editors/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/property-editors/manifests.ts new file mode 100644 index 0000000000..7e8e7ff3b2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/property-editors/manifests.ts @@ -0,0 +1,4 @@ +import { manifest as mediaTypePickerUI } from './media-type-picker/manifests.js'; +import type { ManifestPropertyEditorUi } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [mediaTypePickerUI]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/property-editors/media-type-picker/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/property-editors/media-type-picker/manifests.ts new file mode 100644 index 0000000000..3d30182b52 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/property-editors/media-type-picker/manifests.ts @@ -0,0 +1,23 @@ +import type { ManifestPropertyEditorUi } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifest: ManifestPropertyEditorUi = { + type: 'propertyEditorUi', + alias: 'Umb.PropertyEditorUi.MediaTypePicker', + name: 'Media Type Picker Property Editor UI', + js: () => import('./property-editor-ui-media-type-picker.element.js'), + meta: { + label: 'Media Type Picker', + icon: 'icon-media-dashed-line', + group: 'advanced', + settings: { + properties: [ + { + alias: 'showOpenButton', + label: 'Show open button', + description: 'Opens the node in a dialog', + propertyEditorUiAlias: 'Umb.PropertyEditorUi.Toggle', + }, + ], + }, + }, +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/property-editors/media-type-picker/property-editor-ui-media-type-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/property-editors/media-type-picker/property-editor-ui-media-type-picker.element.ts new file mode 100644 index 0000000000..38365a5c35 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/property-editors/media-type-picker/property-editor-ui-media-type-picker.element.ts @@ -0,0 +1,56 @@ +import type { UmbInputMediaTypeElement } from '../../components/index.js'; +import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; +import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { + UmbPropertyValueChangeEvent, + type UmbPropertyEditorConfigCollection, +} from '@umbraco-cms/backoffice/property-editor'; + +@customElement('umb-property-editor-ui-media-type-picker') +export class UmbPropertyEditorUIMediaTypePickerElement extends UmbLitElement implements UmbPropertyEditorUiElement { + @property() + public value?: string; + + @property({ attribute: false }) + public set config(config: UmbPropertyEditorConfigCollection | undefined) { + if (config) { + const validationLimit = config.getValueByAlias('validationLimit'); + this._limitMin = validationLimit?.min; + this._limitMax = validationLimit?.max; + } + } + public get config() { + return undefined; + } + + @state() + private _limitMin?: number; + @state() + private _limitMax?: number; + + private _onChange(event: CustomEvent) { + this.value = (event.target as UmbInputMediaTypeElement).selectedIds.join(','); + this.dispatchEvent(new UmbPropertyValueChangeEvent()); + } + + render() { + return html` + + Add + + `; + } +} + +export default UmbPropertyEditorUIMediaTypePickerElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-property-editor-ui-media-type-picker': UmbPropertyEditorUIMediaTypePickerElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/property-editors/media-type-picker/property-editor-ui-media-type-picker.stories.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/property-editors/media-type-picker/property-editor-ui-media-type-picker.stories.ts new file mode 100644 index 0000000000..5ceb9df55a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/property-editors/media-type-picker/property-editor-ui-media-type-picker.stories.ts @@ -0,0 +1,15 @@ +import type { Meta, Story } from '@storybook/web-components'; +import type { UmbPropertyEditorUIMediaTypePickerElement } from './property-editor-ui-media-type-picker.element.js'; +import { html } from '@umbraco-cms/backoffice/external/lit'; + +import './property-editor-ui-media-type-picker.element.js'; + +export default { + title: 'Property Editor UIs/Media Type Picker', + component: 'umb-property-editor-ui-media-type-picker', + id: 'umb-property-editor-ui-media-type-picker', +} as Meta; + +export const AAAOverview: Story = () => + html` `; +AAAOverview.storyName = 'Overview'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/item/media-type-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/item/media-type-item.server.data-source.ts index 1e0529824e..cc8f9099c2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/item/media-type-item.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/item/media-type-item.server.data-source.ts @@ -34,6 +34,6 @@ const mapper = (item: MediaTypeItemResponseModel): UmbMediaTypeItemModel => { return { icon: item.icon || null, name: item.name, - unique: item.name, + unique: item.id, }; }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-media/input-media.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-media/input-media.element.ts index 2e7f622da6..dfe4b9d75e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-media/input-media.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-media/input-media.element.ts @@ -96,6 +96,9 @@ export class UmbInputMediaElement extends FormControlMixin(UmbLitElement) { // Its with full purpose we don't call super.value, as thats being handled by the observation of the context selection. this.selectedIds = splitStringToArray(idsString); } + public get value() { + return this.selectedIds.join(','); + } @state() private _editMediaPath = ''; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/media-picker/property-editor-ui-media-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/media-picker/property-editor-ui-media-picker.element.ts index 46c7a69758..2443efbfa6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/media-picker/property-editor-ui-media-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/media-picker/property-editor-ui-media-picker.element.ts @@ -1,7 +1,10 @@ import type { UmbInputMediaElement } from '../../components/input-media/input-media.element.js'; import '../../components/input-media/input-media.element.js'; import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; -import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor'; +import { + UmbPropertyValueChangeEvent, + type UmbPropertyEditorConfigCollection, +} from '@umbraco-cms/backoffice/property-editor'; import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; @@ -10,15 +13,8 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; */ @customElement('umb-property-editor-ui-media-picker') export class UmbPropertyEditorUIMediaPickerElement extends UmbLitElement implements UmbPropertyEditorUiElement { - private _value: Array = []; - - @property({ type: Array }) - public get value(): Array { - return this._value; - } - public set value(value: Array | undefined) { - this._value = value || []; - } + @property() + public value?: string; @property({ attribute: false }) public set config(config: UmbPropertyEditorConfigCollection | undefined) { @@ -30,6 +26,9 @@ export class UmbPropertyEditorUIMediaPickerElement extends UmbLitElement impleme this._limitMin = minMax.min ?? 0; this._limitMax = minMax.max ?? Infinity; } + public get config() { + return undefined; + } @state() private _limitMin: number = 0; @@ -37,19 +36,19 @@ export class UmbPropertyEditorUIMediaPickerElement extends UmbLitElement impleme private _limitMax: number = Infinity; private _onChange(event: CustomEvent) { - this.value = (event.target as UmbInputMediaElement).selectedIds; - this.dispatchEvent(new CustomEvent('property-value-change')); + this.value = (event.target as UmbInputMediaElement).selectedIds.join(','); + this.dispatchEvent(new UmbPropertyValueChangeEvent()); } render() { return html` Add + .max=${this._limitMax}> + Add + `; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/components/input-member-type/input-member-type.context.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/components/input-member-type/input-member-type.context.ts index 0915ef4d24..30b7ab1cea 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/components/input-member-type/input-member-type.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/components/input-member-type/input-member-type.context.ts @@ -1,11 +1,10 @@ import { UMB_MEMBER_TYPE_PICKER_MODAL } from '../../modal/member-type-picker-modal.token.js'; +import { UMB_MEMBER_TYPE_ITEM_REPOSITORY_ALIAS } from '@umbraco-cms/backoffice/member-type'; import { UmbPickerInputContext } from '@umbraco-cms/backoffice/picker-input'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; export class UmbMemberTypePickerContext extends UmbPickerInputContext { constructor(host: UmbControllerHost) { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore super(host, UMB_MEMBER_TYPE_ITEM_REPOSITORY_ALIAS, UMB_MEMBER_TYPE_PICKER_MODAL); } }