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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions 17/umbraco-cms/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
* [Date Time (Unspecified)](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/date-time-editor/date-time-unspecified.md)
* [Decimal](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/decimal.md)
* [Email Address](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/email-address.md)
* [Entity Data Picker](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/entity-data-picker.md)
* [Eye Dropper Color Picker](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/eye-dropper-color-picker.md)
* [File Upload](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/file-upload.md)
* [Image Cropper](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/image-cropper.md)
Expand Down Expand Up @@ -227,6 +228,11 @@
* [Property Editors Composition](customizing/property-editors/composition/README.md)
* [Property Editor Schema](customizing/property-editors/composition/property-editor-schema.md)
* [Property Editor UI](customizing/property-editors/composition/property-editor-ui.md)
* [Property Editor Data Source](customizing/property-editors/composition/property-editor-data-source.md)
* Property Editor Data Source Types
* [Picker Data Source Type](customizing/property-editors/data-source-types/picker/README.md)
* [Collection Data Source](customizing/property-editors/data-source-types/picker/picker-collection-data-source.md)
* [Tree Data Source](customizing/property-editors/data-source-types/picker/picker-tree-data-source.md)
* [Property Value Converters](customizing/property-editors/property-value-converters.md)
* [Property Value Converter Example](customizing/property-editors/full-examples-value-converters.md)
* [Property Actions](customizing/property-editors/property-actions.md)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,8 @@ A Property Editor UI is utilizing a Property Editor Schema, and you can have mul

* Data Type Settings for a Property Editor or Property Editor UI is defined in the manifests.
* They both use the same format for their settings.

## Property Editor Data Sources
A Property Editor Data Source is an optional way to provide data to a Property Editor UI. This allows for reuse of the same Property Editor UI but with different data sources.

* [Property Editor Data Source](property-editor-data-source.md)
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Property Editor Data Source

A Property Editor Data Source is a way to provide data to a Property Editor UI. This allows for the reuse of the same UI across different data sources.

Data Sources are an opt-in feature for the Property Editor UI. When enabled, extensions can register Data Sources, which can be selected in the UI if their type is supported.

## Enable Data Source Support

The Data Source support is enabled in the Property Editor UI manifest. Below is a snippet showing how to enable it. The `forDataSourceTypes` can include any already existing Data Source Types or new custom ones.

**Property Editor UI Manifest**

```typescript
{
type: 'propertyEditorUi',
name: 'My Property Editor UI with Data Source support',
//... more
meta: {
//... more
supportsDataSource: {
enabled: true,
forDataSourceTypes: ['My.DataSourceType.Custom']
}
}
}
```

When this feature is enabled, you can pick a Data Source in the Data Type Workspace next to the Property Editor field. The available Data Sources will match the supported Data Source Types of the chosen Property Editor UI.

<figure><img src="../../../.gitbook/assets/umbraco-docs-data-type-property-editor-data-source.png" alt=""><figcaption><p>Property Editor Data Source Picker</p></figcaption></figure>

## Register a Property Editor Data Source

**Data Source Manifest**

```typescript
{
type: 'propertyEditorDataSource',
dataSourceType: 'My.DataSourceType.Custom',
alias: 'Umb.PropertyEditorDataSource.MyCustomDataSource',
name: 'My Custom Data Source',
api: () => import('./my-custom-data-source.js'),
meta: {
label: 'My Data',
description: 'A good description of the data',
icon: 'icon-database',
},
},
```

### Data Source Settings

Like Property Editor UIs and Schemas, Data Sources can have settings for configuration of the data source. These settings are defined in the manifest under `meta.settings`. The settings for a Data Source will be rendered in the Data Type Workspace together with the Property Editor UI and Schema settings.

**Data Source Manifest**

```typescript
{
type: 'propertyEditorDataSource',
alias: 'Umb.PropertyEditorDataSource.MyCustomDataSource',
//... more
meta: {
//... more
settings: {
properties: [],
},
},
};
```

## Access Data Source Alias in Property Editor UI

When implementing a Property Editor UI element, the Data Source alias can be accessed through the `dataSourceAlias` property.

```typescript
interface UmbPropertyEditorUiElement extends HTMLElement {
dataSourceAlias?: string;
}
```

## Access Data Source Config in Property Editor UI

The Data Source configuration can be accessed through the `config` property of the Property Editor UI element merged with the UI and Schema config.

## Built-in Data Source Types

- [Picker](../data-source-types/picker/README.md) - Used by Property Editors that pick entities, for example, the Entity Data Picker Property Editor.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Picker Data Source Type

The `Umb.DataSourceType.Picker` Data Source Type is used by Property Editors that pick entities, for example, the built-in [Entity Data Picker Property Editor](../../../../fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/entity-data-picker.md).

## Register a Picker Data Source

**Data Source Manifest**

```typescript
{
type: 'propertyEditorDataSource',
dataSourceType: 'Umb.DataSourceType.Picker',
alias: 'Umb.PropertyEditorDataSource.MyPickerDataSource',
name: 'My Picker Data Source',
api: () => import('./my-picker-data-source.js'),
meta: {
label: 'My Data Source',
description: 'A good description of the data source',
icon: 'icon-database',
},
},
```

The Picker Data Source supports two types of data structures:

- [Collection Data](./picker-collection-data-source.md)
- [Tree Data](./picker-tree-data-source.md)
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
## Picker Collection Data Source

The interface below is simplified for clarity and omits return types and arguments. See full interfaces in the [UI API Documentation](https://apidocs.umbraco.com/v17/ui-api/modules/packages_core_picker-data-source.html)

```typescript
interface UmbPickerPropertyEditorCollectionDataSource {
requestCollection();
requestItems();
search?();
setConfig?();
getConfig?();
}
```

### Example
```typescript
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import type { UmbCollectionFilterModel, UmbCollectionItemModel } from '@umbraco-cms/backoffice/collection';
import type {
UmbPickerCollectionDataSource,
UmbPickerSearchableDataSource,
} from '@umbraco-cms/backoffice/picker-data-source';
import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';

interface ExampleCollectionItemModel extends UmbCollectionItemModel {
isPickable: boolean;
}

export class MyCustomPickerCollectionPropertyEditorDataSource
extends UmbControllerBase
implements UmbPickerCollectionDataSource<ExampleCollectionItemModel>, UmbPickerSearchableDataSource
{
collectionPickableFilter = (item: ExampleCollectionItemModel) => item.isPickable;

async requestCollection(args: UmbCollectionFilterModel) {
const data = {
items: customItems,
total: customItems.length,
};

return { data };
}

async requestItems(uniques: Array<string>) {
const items = customItems.filter((x) => uniques.includes(x.unique));
return { data: items };
}

async search(args: UmbSearchRequestArgs) {
const items = customItems.filter((item) => item.name?.toLowerCase().includes(args.query.toLowerCase()));
const total = items.length;

const data = {
items,
total,
};

return { data };
}
}

export { ExampleCustomPickerCollectionPropertyEditorDataSource as api };

const customItems: Array<ExampleCollectionItemModel> = [
{
unique: '1',
entityType: 'example',
name: 'Example 1',
icon: 'icon-shape-triangle',
isPickable: true,
},
{
unique: '2',
entityType: 'example',
name: 'Example 2',
icon: 'icon-shape-triangle',
isPickable: false,
},
{
unique: '3',
entityType: 'example',
name: 'Example 3',
icon: 'icon-shape-triangle',
isPickable: true,
},
];

```
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
## Picker Tree Data Source

The interface below is simplified for clarity and omits return types and arguments. See full interfaces in the [UI API Documentation](https://apidocs.umbraco.com/v17/ui-api/modules/packages_core_picker-data-source.html)


```typescript
interface UmbPickerPropertyEditorCollectionDataSource {
requestTreeRoot();
requestTreeRootItems();
requestTreeItemsOf();
requestTreeItemAncestors();
requestItems();
search?();
setConfig?();
getConfig?();
}
```


### Example
```typescript
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
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, 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,
name: 'Examples',
icon: 'icon-folder',
hasChildren: true,
entityType: 'example-root',
isFolder: true,
};

return { data: root };
}

async requestTreeRootItems() {
const rootItems = customItems.filter((item) => item.parent.unique === null);

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

return { data };
}

async requestTreeItemsOf(args: UmbTreeChildrenOfRequestArgs) {
const items = customItems.filter(
(item) => item.parent.entityType === args.parent.entityType && item.parent.unique === args.parent.unique,
);

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

return { data };
}

async requestTreeItemAncestors() {
// TODO: implement when needed
return { data: [] };
}

async requestItems(uniques: Array<string>) {
const items = customItems.filter((x) => uniques.includes(x.unique));
return { data: items };
}

async search(args: UmbSearchRequestArgs) {
const result = customItems.filter((item) => item.name.toLowerCase().includes(args.query.toLowerCase()));

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

return { data };
}
}

export { ExampleCustomPickerTreePropertyEditorDataSource as api };

const customItems: Array<UmbTreeItemModel> = [
{
unique: '1',
entityType: 'example',
name: 'Example 1',
icon: 'icon-shape-triangle',
parent: { unique: null, entityType: 'example-root' },
isFolder: false,
hasChildren: false,
},
{
unique: '2',
entityType: 'example',
name: 'Example 2',
icon: 'icon-shape-triangle',
parent: { unique: null, entityType: 'example-root' },
isFolder: false,
hasChildren: false,
},
{
unique: '3',
entityType: 'example',
name: 'Example 3',
icon: 'icon-shape-triangle',
parent: { unique: null, entityType: 'example-root' },
isFolder: false,
hasChildren: false,
},
{
unique: '4',
entityType: 'example',
name: 'Example 4',
icon: 'icon-shape-triangle',
parent: { unique: '6', entityType: 'example-folder' },
isFolder: false,
hasChildren: false,
},
{
unique: '5',
entityType: 'example',
name: 'Example 5',
icon: 'icon-shape-triangle',
parent: { unique: '6', entityType: 'example-folder' },
isFolder: false,
hasChildren: false,
},
{
unique: '6',
entityType: 'example-folder',
name: 'Example Folder 1',
parent: { unique: null, entityType: 'example-root' },
isFolder: true,
hasChildren: true,
},
];
```
Loading
Loading