From 0d0e45ad922ce3cf265391d21d660a321591272c Mon Sep 17 00:00:00 2001 From: leekelleher Date: Mon, 15 Jan 2024 15:35:24 +0000 Subject: [PATCH 1/6] Document Picker: Filter option Enables the `pickableFilter` option on the picker modal. --- .../input-tree/input-tree.element.ts | 4 +-- .../input-document/input-document.element.ts | 34 ++++++++++++------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/components/input-tree/input-tree.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/components/input-tree/input-tree.element.ts index 234a127b12..043bc5b2c6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/components/input-tree/input-tree.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/components/input-tree/input-tree.element.ts @@ -38,7 +38,7 @@ export class UmbInputTreeElement extends FormControlMixin(UmbLitElement) { private _filter: Array = []; @property() public set filter(value: string) { - this._filter = value.split(','); + this._filter = value ? value.split(',') : []; } public get filter(): string { return this._filter.join(','); @@ -104,7 +104,7 @@ export class UmbInputTreeElement extends FormControlMixin(UmbLitElement) { return html` (this._items = selectedItems)); } - protected _openPicker() { - // TODO: Configure the content picker, with `startNodeId`, `filter` and `ignoreUserStartNodes` [LK] - console.log("_openPicker", [this.startNodeId, this.filter, this.ignoreUserStartNodes]); + protected getFormElement() { + return undefined; + } + + #pickableFilter: (item: DocumentTreeItemResponseModel) => boolean = (item) => { + if (this.filter && this.filter.length > 0) { + return this.filter.includes(item.contentTypeId); + } + return true; + } + + #openPicker() { + // TODO: Configure the content picker, with `startNodeId` and `ignoreUserStartNodes` [LK] + console.log('_openPicker', [this.startNodeId, this.ignoreUserStartNodes]); this.#pickerContext.openPicker({ hideTreeRoot: true, + pickableFilter: this.#pickableFilter, }); } - protected _openItem(item: DocumentItemResponseModel) { + #openItem(item: DocumentItemResponseModel) { // TODO: Implement the Content editing infinity editor. [LK] console.log('TODO: _openItem', item); } - protected getFormElement() { - return undefined; - } - render() { return html` ${this.#renderItems()} ${this.#renderAddButton()} `; } @@ -144,7 +152,7 @@ export class UmbInputDocumentElement extends FormControlMixin(UmbLitElement) { return html``; } @@ -172,7 +180,7 @@ export class UmbInputDocumentElement extends FormControlMixin(UmbLitElement) { private _renderOpenButton(item: DocumentItemResponseModel) { if (!this.showOpenButton) return; - return html` this._openItem(item)} label="Open document ${item.name}" + return html` this.#openItem(item)} label="Open document ${item.name}" >${this.localize.term('general_open')}`; } From 6a98fd2e96cba926eed8a10be68f6728c2235d1c Mon Sep 17 00:00:00 2001 From: leekelleher Date: Mon, 15 Jan 2024 16:07:32 +0000 Subject: [PATCH 2/6] Media Picker: Filter option Enables the `pickableFilter` option on the picker modal. --- .../input-tree/input-tree.element.ts | 2 +- .../input-media/input-media.element.ts | 45 +++++++++++++------ 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/components/input-tree/input-tree.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/components/input-tree/input-tree.element.ts index 043bc5b2c6..090b4c610a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/components/input-tree/input-tree.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/components/input-tree/input-tree.element.ts @@ -115,7 +115,7 @@ export class UmbInputTreeElement extends FormControlMixin(UmbLitElement) { #renderMediaPicker() { return html` (this._items = selectedItems)); } - protected _openPicker() { + protected getFormElement() { + return undefined; + } + + #pickableFilter: (item: MediaItemResponseModel) => boolean = (item) => { + /* TODO: Media item doesn't have the content/media-type ID available to query. + Commenting out until the Management API model is updated. [LK] + */ + // if (this.filter && this.filter.length > 0) { + // return this.filter.includes(item.contentTypeId); + // } + return true; + }; + + #openPicker() { // TODO: Configure the media picker, with `filter` and `ignoreUserStartNodes` [LK] - console.log('_openPicker', [this.filter, this.ignoreUserStartNodes]); + console.log('#openPicker', [this.filter, this.ignoreUserStartNodes]); this.#pickerContext.openPicker({ hideTreeRoot: true, + pickableFilter: this.#pickableFilter, }); } - protected _openItem(item: MediaItemResponseModel) { - // TODO: Implement the Content editing infinity editor. [LK] + #openItem(item: MediaItemResponseModel) { + // TODO: Implement the Media editing infinity editor. [LK] console.log('TODO: _openItem', item); } - protected getFormElement() { - return undefined; - } - render() { return html` ${this.#renderItems()} ${this.#renderButton()} `; } @@ -127,7 +138,13 @@ export class UmbInputMediaElement extends FormControlMixin(UmbLitElement) { #renderItems() { if (!this._items) return; // TODO: Add sorting. [LK] - return html` ${this._items?.map((item) => this.#renderItem(item))} `; + return html` + ${repeat( + this._items, + (item) => item.id, + (item) => this.#renderItem(item), + )} + `; } #renderButton() { @@ -136,7 +153,7 @@ export class UmbInputMediaElement extends FormControlMixin(UmbLitElement) { ${this.localize.term('general_choose')} From 0785547005dcaa97e4ffdf6356b6680d4be4c525 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Mon, 15 Jan 2024 16:19:54 +0000 Subject: [PATCH 3/6] Member Picker: Filter option Enables the `pickableFilter` option on the picker modal. --- .../components/input-tree/input-tree.element.ts | 2 +- .../components/input-member/input-member.element.ts | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/components/input-tree/input-tree.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/components/input-tree/input-tree.element.ts index 090b4c610a..283fd45c9a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/components/input-tree/input-tree.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/components/input-tree/input-tree.element.ts @@ -126,7 +126,7 @@ export class UmbInputTreeElement extends FormControlMixin(UmbLitElement) { #renderMemberPicker() { return html` (this._items = selectedItems)); } + #pickableFilter: (item: MemberItemResponseModel) => boolean = (item) => { + // TODO: Uncomment, once `UmbMemberPickerContext` has been implemented. [LK] + console.log('member.pickableFilter', item); + // if (this.filter && this.filter.length > 0) { + // return this.filter.includes(item.contentTypeId); + // } + return true; + }; + protected _openPicker() { console.log("member.openPicker"); // this.#pickerContext.openPicker({ // hideTreeRoot: true, + // pickableFilter: this.#pickableFilter, // }); } From a20d93afb8e197df5394798958fa04f3114c65dc Mon Sep 17 00:00:00 2001 From: leekelleher Date: Mon, 15 Jan 2024 16:22:11 +0000 Subject: [PATCH 4/6] Content Type pickers - aligning method names For consistency, replacing `private` with `#` hash prefix. --- .../input-document/input-document.element.ts | 12 +++--- .../input-media/input-media.element.ts | 8 ++-- .../input-member/input-member.element.ts | 40 +++++++++---------- 3 files changed, 30 insertions(+), 30 deletions(-) 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 7b0229043e..cd040f7b8f 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 @@ -142,7 +142,7 @@ export class UmbInputDocumentElement extends FormControlMixin(UmbLitElement) { >${repeat( this._items, (item) => item.id, - (item) => this._renderItem(item), + (item) => this.#renderItem(item), )} `; } @@ -156,13 +156,13 @@ export class UmbInputDocumentElement extends FormControlMixin(UmbLitElement) { label=${this.localize.term('general_choose')}>`; } - private _renderItem(item: DocumentItemResponseModel) { + #renderItem(item: DocumentItemResponseModel) { if (!item.id) return; return html` - ${this._renderIsTrashed(item)} + ${this.#renderIsTrashed(item)} - ${this._renderOpenButton(item)} + ${this.#renderOpenButton(item)} this.#pickerContext.requestRemoveItem(item.id!)} label="Remove document ${item.name}" @@ -173,12 +173,12 @@ export class UmbInputDocumentElement extends FormControlMixin(UmbLitElement) { `; } - private _renderIsTrashed(item: DocumentItemResponseModel) { + #renderIsTrashed(item: DocumentItemResponseModel) { if (!item.isTrashed) return; return html`Trashed`; } - private _renderOpenButton(item: DocumentItemResponseModel) { + #renderOpenButton(item: DocumentItemResponseModel) { if (!this.showOpenButton) return; return html` this.#openItem(item)} label="Open document ${item.name}" >${this.localize.term('general_open')}= this.max) return; return html` - ${this._renderIsTrashed(item)} + ${this.#renderIsTrashed(item)} @@ -182,7 +182,7 @@ export class UmbInputMediaElement extends FormControlMixin(UmbLitElement) { `; } - private _renderIsTrashed(item: MediaItemResponseModel) { + #renderIsTrashed(item: MediaItemResponseModel) { if (!item.isTrashed) return; return html`Trashed`; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/members/components/input-member/input-member.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/members/components/input-member/input-member.element.ts index 5a53560ec0..0b2f689408 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/members/components/input-member/input-member.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/members/components/input-member/input-member.element.ts @@ -95,6 +95,9 @@ export class UmbInputMemberElement extends FormControlMixin(UmbLitElement) { // this.observe(this.#pickerContext.selection, (selection) => (super.value = selection.join(','))); // this.observe(this.#pickerContext.selectedItems, (selectedItems) => (this._items = selectedItems)); } + protected getFormElement() { + return undefined; + } #pickableFilter: (item: MemberItemResponseModel) => boolean = (item) => { // TODO: Uncomment, once `UmbMemberPickerContext` has been implemented. [LK] @@ -105,28 +108,21 @@ export class UmbInputMemberElement extends FormControlMixin(UmbLitElement) { return true; }; - protected _openPicker() { - console.log("member.openPicker"); + #openPicker() { + console.log('member.openPicker'); // this.#pickerContext.openPicker({ // hideTreeRoot: true, // pickableFilter: this.#pickableFilter, // }); } - protected _requestRemoveItem(item: MemberItemResponseModel){ - console.log("member.requestRemoveItem", item); + #requestRemoveItem(item: MemberItemResponseModel) { + console.log('member.requestRemoveItem', item); //this.#pickerContext.requestRemoveItem(item.id!); } - protected getFormElement() { - return undefined; - } - render() { - return html` - ${this.#renderItems()} - ${this.#renderAddButton()} - `; + return html` ${this.#renderItems()} ${this.#renderAddButton()} `; } #renderItems() { @@ -136,7 +132,7 @@ export class UmbInputMemberElement extends FormControlMixin(UmbLitElement) { >${repeat( this._items, (item) => item.id, - (item) => this._renderItem(item), + (item) => this.#renderItem(item), )} `; } @@ -146,19 +142,17 @@ export class UmbInputMemberElement extends FormControlMixin(UmbLitElement) { return html``; + @click=${this.#openPicker} + label=${this.localize.term('general_choose')}>`; } - private _renderItem(item: MemberItemResponseModel) { + #renderItem(item: MemberItemResponseModel) { if (!item.id) return; return html` - + ${this.#renderIsTrashed(item)} - this._requestRemoveItem(item)} - label="Remove member ${item.name}" + this.#requestRemoveItem(item)} label="Remove member ${item.name}" >Remove @@ -166,6 +160,12 @@ export class UmbInputMemberElement extends FormControlMixin(UmbLitElement) { `; } + #renderIsTrashed(item: MemberItemResponseModel) { + // TODO: Uncomment, once the Management API model support deleted members. [LK] + //if (!item.isTrashed) return; + //return html`Trashed`; + } + static styles = [ css` #add-button { From 39303092c54ebbaffeb8c1c10c1854a62ddf4311 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Mon, 15 Jan 2024 16:22:35 +0000 Subject: [PATCH 5/6] Member Picker: Added TODO notes. --- .../components/input-member/input-member.element.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/members/components/input-member/input-member.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/members/components/input-member/input-member.element.ts index 0b2f689408..a034d02f5d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/members/components/input-member/input-member.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/members/components/input-member/input-member.element.ts @@ -14,10 +14,12 @@ export class UmbInputMemberElement extends FormControlMixin(UmbLitElement) { */ @property({ type: Number }) public get min(): number { + // TODO: Uncomment, once `UmbMemberPickerContext` has been implemented. [LK] //return this.#pickerContext.min; return 0; } public set min(value: number) { + // TODO: Uncomment, once `UmbMemberPickerContext` has been implemented. [LK] //this.#pickerContext.min = value; } @@ -38,10 +40,12 @@ export class UmbInputMemberElement extends FormControlMixin(UmbLitElement) { */ @property({ type: Number }) public get max(): number { + // TODO: Uncomment, once `UmbMemberPickerContext` has been implemented. [LK] //return this.#pickerContext.max; return Infinity; } public set max(value: number) { + // TODO: Uncomment, once `UmbMemberPickerContext` has been implemented. [LK] //this.#pickerContext.max = value; } @@ -55,10 +59,12 @@ export class UmbInputMemberElement extends FormControlMixin(UmbLitElement) { maxMessage = 'This field exceeds the allowed amount of items'; public get selectedIds(): Array { + // TODO: Uncomment, once `UmbMemberPickerContext` has been implemented. [LK] //return this.#pickerContext.getSelection(); return []; } public set selectedIds(ids: Array) { + // TODO: Uncomment, once `UmbMemberPickerContext` has been implemented. [LK] //this.#pickerContext.setSelection(ids); } @@ -80,6 +86,7 @@ export class UmbInputMemberElement extends FormControlMixin(UmbLitElement) { constructor() { super(); + // TODO: Uncomment, once `UmbMemberPickerContext` has been implemented. [LK] // this.addValidator( // 'rangeUnderflow', // () => this.minMessage, @@ -109,6 +116,7 @@ export class UmbInputMemberElement extends FormControlMixin(UmbLitElement) { }; #openPicker() { + // TODO: Uncomment, once `UmbMemberPickerContext` has been implemented. [LK] console.log('member.openPicker'); // this.#pickerContext.openPicker({ // hideTreeRoot: true, @@ -117,6 +125,7 @@ export class UmbInputMemberElement extends FormControlMixin(UmbLitElement) { } #requestRemoveItem(item: MemberItemResponseModel) { + // TODO: Uncomment, once `UmbMemberPickerContext` has been implemented. [LK] console.log('member.requestRemoveItem', item); //this.#pickerContext.requestRemoveItem(item.id!); } From aeae42c48ed5a35db3c828cfee0e084137469b29 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Tue, 16 Jan 2024 16:18:12 +0000 Subject: [PATCH 6/6] Renamed `filter` to `allowedContentTypeIds` ref: https://github.com/umbraco/Umbraco.CMS.Backoffice/pull/1125#pullrequestreview-1823376278 --- .../property-editor-ui-tree-picker.element.ts | 6 +++--- .../components/input-tree/input-tree.element.ts | 16 ++++++++-------- .../input-document/input-document.element.ts | 6 +++--- .../input-media/input-media.element.ts | 10 +++++----- .../input-member/input-member.element.ts | 6 +++--- 5 files changed, 22 insertions(+), 22 deletions(-) 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 43c5f393ee..0b6d9b8133 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 @@ -28,7 +28,7 @@ export class UmbPropertyEditorUITreePickerElement extends UmbLitElement implemen max = 0; @state() - filter?: string | null; + allowedContentTypeIds?: string | null; @state() showOpenButton?: boolean; @@ -47,7 +47,7 @@ export class UmbPropertyEditorUITreePickerElement extends UmbLitElement implemen this.min = Number(config?.getValueByAlias('minNumber')) || 0; this.max = Number(config?.getValueByAlias('maxNumber')) || 0; - this.filter = config?.getValueByAlias('filter'); + this.allowedContentTypeIds = config?.getValueByAlias('filter'); this.showOpenButton = config?.getValueByAlias('showOpenButton'); this.ignoreUserStartNodes = config?.getValueByAlias('ignoreUserStartNodes'); } @@ -64,7 +64,7 @@ export class UmbPropertyEditorUITreePickerElement extends UmbLitElement implemen .startNodeId=${this.startNodeId ?? ''} .min=${this.min} .max=${this.max} - .filter=${this.filter ?? ''} + .allowedContentTypeIds=${this.allowedContentTypeIds ?? ''} ?showOpenButton=${this.showOpenButton} ?ignoreUserStartNodes=${this.ignoreUserStartNodes} @change=${this.#onChange}>`; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/components/input-tree/input-tree.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/components/input-tree/input-tree.element.ts index 283fd45c9a..f1d5c16f53 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/components/input-tree/input-tree.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/components/input-tree/input-tree.element.ts @@ -35,13 +35,13 @@ export class UmbInputTreeElement extends FormControlMixin(UmbLitElement) { @property({ type: Number }) max = 0; - private _filter: Array = []; + private _allowedContentTypeIds: Array = []; @property() - public set filter(value: string) { - this._filter = value ? value.split(',') : []; + public set allowedContentTypeIds(value: string) { + this._allowedContentTypeIds = value ? value.split(',') : []; } - public get filter(): string { - return this._filter.join(','); + public get allowedContentTypeIds(): string { + return this._allowedContentTypeIds.join(','); } @property({ type: Boolean }) @@ -104,7 +104,7 @@ export class UmbInputTreeElement extends FormControlMixin(UmbLitElement) { return html` boolean = (item) => { - if (this.filter && this.filter.length > 0) { - return this.filter.includes(item.contentTypeId); + if (this.allowedContentTypeIds && this.allowedContentTypeIds.length > 0) { + return this.allowedContentTypeIds.includes(item.contentTypeId); } return true; } 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 3e55684de7..99723e608a 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 @@ -61,7 +61,7 @@ export class UmbInputMediaElement extends FormControlMixin(UmbLitElement) { } @property({ type: Array }) - filter?: string[] | undefined; + allowedContentTypeIds?: string[] | undefined; @property({ type: Boolean }) showOpenButton?: boolean; @@ -111,15 +111,15 @@ export class UmbInputMediaElement extends FormControlMixin(UmbLitElement) { /* TODO: Media item doesn't have the content/media-type ID available to query. Commenting out until the Management API model is updated. [LK] */ - // if (this.filter && this.filter.length > 0) { - // return this.filter.includes(item.contentTypeId); + // if (this.allowedContentTypeIds && this.allowedContentTypeIds.length > 0) { + // return this.allowedContentTypeIds.includes(item.contentTypeId); // } return true; }; #openPicker() { - // TODO: Configure the media picker, with `filter` and `ignoreUserStartNodes` [LK] - console.log('#openPicker', [this.filter, this.ignoreUserStartNodes]); + // TODO: Configure the media picker, with `allowedContentTypeIds` and `ignoreUserStartNodes` [LK] + console.log('#openPicker', [this.allowedContentTypeIds, this.ignoreUserStartNodes]); this.#pickerContext.openPicker({ hideTreeRoot: true, pickableFilter: this.#pickableFilter, diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/members/components/input-member/input-member.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/members/components/input-member/input-member.element.ts index a034d02f5d..6ba7bfd177 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/members/components/input-member/input-member.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/members/components/input-member/input-member.element.ts @@ -69,7 +69,7 @@ export class UmbInputMemberElement extends FormControlMixin(UmbLitElement) { } @property({ type: Array }) - filter?: string[] | undefined; + allowedContentTypeIds?: string[] | undefined; @property() public set value(idsString: string) { @@ -109,8 +109,8 @@ export class UmbInputMemberElement extends FormControlMixin(UmbLitElement) { #pickableFilter: (item: MemberItemResponseModel) => boolean = (item) => { // TODO: Uncomment, once `UmbMemberPickerContext` has been implemented. [LK] console.log('member.pickableFilter', item); - // if (this.filter && this.filter.length > 0) { - // return this.filter.includes(item.contentTypeId); + // if (this.allowedContentTypeIds && this.allowedContentTypeIds.length > 0) { + // return this.allowedContentTypeIds.includes(item.contentTypeId); // } return true; };