Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{
"cSpell.words": [
"backoffice",
"pickable",
"Pickable",
"unprovide",
"Unproviding"
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import type { UmbPickerTreeDataSource } from '@umbraco-cms/backoffice/picker-data-source';
import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import type {
UmbPickerSearchableDataSource,
UmbPickerTreeDataSource,
} from '@umbraco-cms/backoffice/picker-data-source';
import type { UmbSearchRequestArgs, UmbSearchResultItemModel } from '@umbraco-cms/backoffice/search';
import type { UmbTreeChildrenOfRequestArgs, UmbTreeItemModel } from '@umbraco-cms/backoffice/tree';

export class ExampleCustomPickerTreePropertyEditorDataSource
extends UmbControllerBase
implements UmbPickerTreeDataSource
implements UmbPickerTreeDataSource, UmbPickerSearchableDataSource
{
treePickableFilter: (treeItem: UmbTreeItemModel) => boolean = (treeItem) =>
!!treeItem.unique && treeItem.entityType === 'example';

searchPickableFilter: (searchItem: UmbSearchResultItemModel) => boolean = (searchItem) =>
!!searchItem.unique && searchItem.entityType === 'example';

async requestTreeRoot() {
const root = {
unique: null,
Expand Down Expand Up @@ -60,7 +69,7 @@ export class ExampleCustomPickerTreePropertyEditorDataSource

const data = {
items: result,
totalItems: result.length,
total: result.length,
};

return { data };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import {
UmbDocumentItemRepository,
UmbDocumentSearchRepository,
UmbDocumentTreeRepository,
type UmbDocumentSearchItemModel,
type UmbDocumentSearchRequestArgs,
type UmbDocumentTreeItemModel,
type UmbDocumentTreeRootModel,
} from '@umbraco-cms/backoffice/document';
import { UMB_DOCUMENT_TYPE_ENTITY_TYPE } from '@umbraco-cms/backoffice/document-type';
import type {
Expand All @@ -20,16 +23,21 @@ import { getConfigValue, type UmbConfigCollectionModel } from '@umbraco-cms/back

export class ExampleDocumentPickerPropertyEditorDataSource
extends UmbControllerBase
implements UmbPickerTreeDataSource, UmbPickerSearchableDataSource
implements
UmbPickerTreeDataSource<UmbDocumentTreeItemModel, UmbDocumentTreeRootModel>,
UmbPickerSearchableDataSource<UmbDocumentSearchItemModel>
{
#tree = new UmbDocumentTreeRepository(this);
#item = new UmbDocumentItemRepository(this);
#search = new UmbDocumentSearchRepository(this);
#config: UmbConfigCollectionModel = [];

treePickableFilter: (treeItem: UmbDocumentTreeItemModel) => boolean = (treeItem) => !!treeItem.unique;

setConfig(config: UmbConfigCollectionModel) {
// TODO: add examples for all config options
this.#config = config;
this.#applyPickableFilterFromConfig();
}

getConfig(): UmbConfigCollectionModel {
Expand Down Expand Up @@ -57,6 +65,13 @@ export class ExampleDocumentPickerPropertyEditorDataSource
}

search(args: UmbSearchRequestArgs) {
const allowedContentTypes = this.#getAllowedDocumentTypesConfig();
const combinedArgs: UmbDocumentSearchRequestArgs = { ...args, allowedContentTypes };

return this.#search.search(combinedArgs);
}

#getAllowedDocumentTypesConfig() {
const filterString = getConfigValue<string>(this.#config, 'filter');
const filterArray = filterString ? filterString.split(',') : [];
const allowedContentTypes: UmbDocumentSearchRequestArgs['allowedContentTypes'] = filterArray.map(
Expand All @@ -65,10 +80,14 @@ export class ExampleDocumentPickerPropertyEditorDataSource
unique,
}),
);
return allowedContentTypes;
}

const combinedArgs: UmbDocumentSearchRequestArgs = { ...args, allowedContentTypes };

return this.#search.search(combinedArgs);
#applyPickableFilterFromConfig() {
const allowedDocumentTypes = this.#getAllowedDocumentTypesConfig();
if (!allowedDocumentTypes || allowedDocumentTypes.length === 0) return;
this.treePickableFilter = (treeItem: UmbDocumentTreeItemModel) =>
allowedDocumentTypes.some((entityType) => entityType.unique === treeItem.documentType.unique);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ export class UmbCollectionItemPickerModalElement extends UmbModalBaseElement<
this.modalContext?.dispatchEvent(new UmbDeselectedEvent(event.unique));
}

#searchSelectableFilter = () => true;

override render() {
return html`
<umb-body-layout headline=${this.localize.term('general_choose')}>
Expand All @@ -106,10 +108,14 @@ export class UmbCollectionItemPickerModalElement extends UmbModalBaseElement<
</umb-body-layout>
`;
}

#renderSearch() {
const selectableFilter =
this.data?.search?.pickableFilter ?? this.data?.pickableFilter ?? this.#searchSelectableFilter;

return html`
<umb-picker-search-field></umb-picker-search-field>
<umb-picker-search-result .pickableFilter=${this.data?.pickableFilter}></umb-picker-search-result>
<umb-picker-search-result .pickableFilter=${selectableFilter}></umb-picker-search-result>
`;
}

Expand Down
7 changes: 6 additions & 1 deletion src/Umbraco.Web.UI.Client/src/packages/core/modal/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { ElementLoaderProperty } from '@umbraco-cms/backoffice/extension-api';
import type { UUIModalElement, UUIModalSidebarSize } from '@umbraco-cms/backoffice/external/uui';
import type { UmbSearchResultItemModel } from '@umbraco-cms/backoffice/search';

export type * from './extensions/types.js';

Expand All @@ -10,9 +11,13 @@ export interface UmbPickerModalData<ItemType> {
search?: UmbPickerModalSearchConfig;
}

export interface UmbPickerModalSearchConfig<QueryParamsType = Record<string, unknown>> {
export interface UmbPickerModalSearchConfig<
QueryParamsType = Record<string, unknown>,
SearchResultItemType extends UmbSearchResultItemModel = UmbSearchResultItemModel,
> {
providerAlias: string;
queryParams?: QueryParamsType;
pickableFilter?: (item: SearchResultItemType) => boolean;
}

export interface UmbPickerModalValue {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import type { UmbPickerDataSource } from '../data-source/types.js';
import type { UmbCollectionRepository } from '@umbraco-cms/backoffice/collection';
import type { UmbItemModel } from '@umbraco-cms/backoffice/entity-item';
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';

export interface UmbPickerCollectionDataSource extends UmbPickerDataSource, UmbCollectionRepository, UmbApi {}
export interface UmbPickerCollectionDataSource<CollectionItemType extends UmbItemModel = UmbItemModel>
extends UmbPickerDataSource,
UmbCollectionRepository<CollectionItemType>,
UmbApi {
collectionPickableFilter?: (item: CollectionItemType) => boolean;
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import type { UmbItemModel } from '@umbraco-cms/backoffice/entity-item';
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository';
import type { UmbConfigCollectionModel } from '@umbraco-cms/backoffice/utils';

export interface UmbPickerDataSource extends UmbItemRepository<any>, UmbApi {
export interface UmbPickerDataSource<PickedItemType extends UmbItemModel = UmbItemModel>
extends UmbItemRepository<PickedItemType>,
UmbApi {
setConfig?(config: UmbConfigCollectionModel | undefined): void;
getConfig?(): UmbConfigCollectionModel | undefined;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import type { UmbPickerDataSource } from '../types.js';
import type { UmbSearchRepository } from '@umbraco-cms/backoffice/search';
import type { UmbSearchRepository, UmbSearchResultItemModel } from '@umbraco-cms/backoffice/search';

export interface UmbPickerSearchableDataSource extends UmbPickerDataSource, UmbSearchRepository<any> {}
export interface UmbPickerSearchableDataSource<
SearchResultItemType extends UmbSearchResultItemModel = UmbSearchResultItemModel,
> extends UmbPickerDataSource,
UmbSearchRepository<SearchResultItemType> {
searchPickableFilter?: (searchItem: SearchResultItemType) => boolean;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import type { UmbPickerDataSource } from '../data-source/types.js';
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
import type { UmbTreeRepository } from '@umbraco-cms/backoffice/tree';
import type { UmbTreeItemModel, UmbTreeRepository, UmbTreeRootModel } from '@umbraco-cms/backoffice/tree';

export interface UmbPickerTreeDataSource extends UmbPickerDataSource, UmbTreeRepository, UmbApi {}
export interface UmbPickerTreeDataSource<
TreeItemType extends UmbTreeItemModel = UmbTreeItemModel,
TreeRootType extends UmbTreeRootModel = UmbTreeRootModel,
> extends UmbPickerDataSource,
UmbTreeRepository<TreeItemType, TreeRootType>,
UmbApi {
treePickableFilter?: (item: TreeItemType) => boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UmbSearchRequestArgs, UmbSearchResultItemModel } from '@umbraco-cms/backoffice/search';
import type { UmbItemModel } from '@umbraco-cms/backoffice/entity-item';

type PickableFilterMethodType<T extends UmbItemModel = UmbItemModel> = (item: T) => boolean;
type PickableFilterMethodType<T extends UmbSearchResultItemModel = UmbSearchResultItemModel> = (item: T) => boolean;

@customElement('umb-picker-search-result')
export class UmbPickerSearchResultElement extends UmbLitElement {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ export class UmbTreePickerModalElement<TreeItemType extends UmbTreeItemModelBase
this._pickerContext.expansion.setExpansion(expansion);
}

#searchSelectableFilter = () => true;

override render() {
return html`
<umb-body-layout headline=${this.localize.term('general_choose')}>
Expand All @@ -181,9 +183,12 @@ export class UmbTreePickerModalElement<TreeItemType extends UmbTreeItemModelBase
`;
}
#renderSearch() {
const selectableFilter =
this.data?.search?.pickableFilter ?? this.data?.pickableFilter ?? this.#searchSelectableFilter;

return html`
<umb-picker-search-field></umb-picker-search-field>
<umb-picker-search-result .pickableFilter=${this.data?.pickableFilter}></umb-picker-search-result>
<umb-picker-search-result .pickableFilter=${selectableFilter}></umb-picker-search-result>
`;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registr
import { UmbModalToken, type UmbPickerModalData } from '@umbraco-cms/backoffice/modal';
import {
UMB_TREE_PICKER_MODAL_ALIAS,
type UmbTreeItemModel,
type UmbTreePickerModalData,
type UmbTreePickerModalValue,
} from '@umbraco-cms/backoffice/tree';
Expand Down Expand Up @@ -84,6 +85,9 @@ export class UmbEntityDataPickerInputContext extends UmbPickerInputContext<UmbIt
}

override async openPicker(pickerData?: Partial<UmbPickerModalData<UmbItemModel>>) {
// TODO: investigate type issues
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
this.modalAlias = this.#getModalToken();
await super.openPicker(pickerData);
}
Expand Down Expand Up @@ -133,7 +137,7 @@ export class UmbEntityDataPickerInputContext extends UmbPickerInputContext<UmbIt
#createTreeItemPickerModalToken(api: UmbPickerTreeDataSource) {
const supportsSearch = isPickerSearchableDataSource(api);

return new UmbModalToken<UmbTreePickerModalData<UmbItemModel>, UmbTreePickerModalValue>(
return new UmbModalToken<UmbTreePickerModalData<UmbTreeItemModel>, UmbTreePickerModalValue>(
UMB_TREE_PICKER_MODAL_ALIAS,
{
modal: {
Expand All @@ -143,9 +147,12 @@ export class UmbEntityDataPickerInputContext extends UmbPickerInputContext<UmbIt
data: {
treeAlias: UMB_ENTITY_DATA_PICKER_TREE_ALIAS,
hideTreeRoot: true,
// TODO: make specific pickable filter for tree to avoid type issues
pickableFilter: api.treePickableFilter,
search: supportsSearch
? {
providerAlias: UMB_ENTITY_DATA_PICKER_SEARCH_PROVIDER_ALIAS,
pickableFilter: api.searchPickableFilter,
}
: undefined,
},
Expand All @@ -167,9 +174,12 @@ export class UmbEntityDataPickerInputContext extends UmbPickerInputContext<UmbIt
collection: {
menuAlias: UMB_ENTITY_DATA_PICKER_COLLECTION_MENU_ALIAS,
},
// TODO: make specific pickable filter for collection to avoid type issues
pickableFilter: api.collectionPickableFilter,
search: supportsSearch
? {
providerAlias: UMB_ENTITY_DATA_PICKER_SEARCH_PROVIDER_ALIAS,
pickableFilter: api.searchPickableFilter,
}
: undefined,
},
Expand Down
Loading