Skip to content

Commit 9f1fe28

Browse files
committed
docs: adds info on how to create a tree in the client
1 parent ace5437 commit 9f1fe28

File tree

1 file changed

+121
-80
lines changed
  • 16/umbraco-cms/customizing/extending-overview/extension-types

1 file changed

+121
-80
lines changed

16/umbraco-cms/customizing/extending-overview/extension-types/tree.md

Lines changed: 121 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@ description: A guide to creating a custom tree in Umbraco
44

55
# Trees
66

7-
{% hint style="warning" %}
8-
This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
9-
{% endhint %}
10-
117
The tree is a hierarchical structure of nodes and is registered in the Backoffice extension registry. A tree can be rendered anywhere in the Backoffice with the help of the `<umb-tree />` element.
128

139
{% hint style="info" %}
@@ -16,13 +12,11 @@ If you are looking for information on how to register a tree as a menu in a sect
1612

1713
## Creating trees <a href="#creating-trees" id="creating-trees"></a>
1814

19-
To Create a Tree in a section of the Umbraco backoffice, you need to take multiple steps:
15+
To create a Tree in the Backoffice, you need to take multiple steps:
2016

2117
### Registering a tree <a href="#registering-a-tree" id="registering-a-tree"></a>
2218

23-
The backoffice comes with two different tree item kinds out of the box: entity and fileSystem.
24-
25-
Tree Manifest:
19+
To register a tree, you need to create a manifest:
2620

2721
```json
2822
{
@@ -32,15 +26,6 @@ Tree Manifest:
3226
"meta": {
3327
"repositoryAlias": "My.Repository.Alias"
3428
}
35-
},
36-
{
37-
"type": "treeItem",
38-
"kind": "entity",
39-
"alias": "My.TreeItem.Alias",
40-
"name": "My Tree Item",
41-
"conditions": {
42-
"entityType": "my-entity-type",
43-
},
4429
}
4530
```
4631

@@ -54,7 +39,7 @@ To render a tree in the Backoffice, you can use the `<umb-tree>` element. You ne
5439

5540
### Render a Custom Tree Item <a href="#render-a-custom-tree-item" id="render-a-custom-tree-item"></a>
5641

57-
The `<umb-tree />` element will render the tree items based on the registered tree item alias. If you want to render a custom tree item, you need to register a tree item manifest. This manifest can then show a custom element for the tree item.
42+
The `<umb-tree />` element will render the tree items based on the registered tree item alias. The tree will be rendered using the [<umb-default-tree-item />](https://apidocs.umbraco.com/v16/ui-api/classes/packages_core_tree.UmbDefaultTreeItemElement.html) element by default. If you want to render a custom tree item, you need to register a tree item manifest. This manifest can then show a custom element for the tree item.
5843

5944
#### **The Tree Item Manifest**
6045

@@ -72,88 +57,144 @@ The `<umb-tree />` element will render the tree items based on the registered tr
7257

7358
#### The Tree Item Element <a href="#the-tree-item-element" id="the-tree-item-element"></a>
7459

75-
To create a custom tree item, you need to create a custom element. This element can choose to use the `<umb-tree-item-base>` element underneath. However, it can also be used as a standalone element if you prefer to implement the tree item logic yourself.
60+
To create a custom tree item, you need to create a custom element. This element can optionally extend the [UmbTreeItemElementBase<T>](https://apidocs.umbraco.com/v16/ui-api/classes/packages_core_tree.UmbTreeItemElementBase.html) class. However, it can also be used as a standalone element if you prefer to implement the tree item logic yourself.
7661

77-
In this example, we will create a custom tree item that uses the `<umb-tree-item-base>` element. This base element provides the necessary context and functionality for the tree item.
62+
In this example, we will create a custom tree item that extends the base class. The base class provides the necessary context and functionality for the tree item.
7863

7964
```typescript
80-
import { css, html, nothing } from 'lit';
81-
import { customElement, property } from 'lit/decorators.js';
82-
import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
83-
import { UmbMyTreeItemContext, MyTreeItemDataModel } from './my-tree-item.context';
65+
import type { MyTreeItemDataModel } from './my-tree-item.model.js';
66+
import { UmbTreeItemElementBase } from '@umbraco-cms/backoffice/tree';
67+
import { html, nothing, customElement } from '@umbraco-cms/backoffice/external/lit';
8468

8569
@customElement('my-tree-item')
86-
export class MyTreeItemElement extends UmbElementMixin(LitElement) {
87-
private _item?: MyTreeItemDataModel;
88-
@property({ type: Object, attribute: false })
89-
public get item() {
90-
return this._item;
91-
}
92-
public set item(value: MyTreeItemDataModel | undefined) {
93-
this._item = value;
94-
this.#context.setTreeItem(value);
95-
}
96-
97-
// Register the context for the tree item
98-
#context = new UmbMyTreeItemContext(this);
99-
100-
render() {
101-
if (!this.item) return nothing;
102-
return html` <umb-tree-item-base> Some custom markup </umb-tree-item-base>`;
103-
}
70+
export class MyTreeItemElement extends UmbTreeItemElementBase<MyTreeItemDataModel> {
71+
override render() {
72+
if (!this.item) return nothing;
73+
return html`
74+
<div>
75+
<umb-icon .name=${this.item.icon}></umb-icon>
76+
<span>${this.item.name}</span>
77+
</div>
78+
`;
79+
}
10480
}
10581

10682
export default MyTreeItemElement;
10783
```
10884

109-
#### The Tree Item Context <a href="#the-tree-item-context" id="the-tree-item-context"></a>
110-
111-
The tree item context is a class that provides the necessary functionality for the tree item. It is used to manage the state of the tree item, such as loading children, selecting, and deselecting the item.
85+
#### The Tree Item Model <a href="#extending-the-tree-item-model" id="extending-the-tree-item-model"></a>
11286

113-
You can create a custom tree item context by implementing the `UmbTreeItemContext<T>` interface.
87+
To define the data model for your tree item, you can create a model that extends the [UmbTreeItemModel](https://apidocs.umbraco.com/v16/ui-api/interfaces/packages_core_tree.UmbTreeItemModel.html). This model will be used to provide the data for your custom tree item.
11488

89+
{% code title="my-tree-item.model.ts" %}
11590
```typescript
116-
// TODO: auto-generate this from the interface
117-
export interface UmbTreeItemContext<T> {
118-
host: UmbControllerHostElement;
119-
unique?: string;
120-
type?: string;
121-
122-
treeItem: Observable<T | undefined>;
123-
hasChildren: Observable<boolean>;
124-
isLoading: Observable<boolean>;
125-
isSelectable: Observable<boolean>;
126-
isSelected: Observable<boolean>;
127-
isActive: Observable<boolean>;
128-
hasActions: Observable<boolean>;
129-
path: Observable<string>;
130-
131-
setTreeItem(treeItem: T | undefined): void;
132-
133-
requestChildren(): Promise<{
134-
data: PagedResponse<T> | undefined;
135-
error: ProblemDetails | undefined;
136-
asObservable?: () => Observable<T[]>;
137-
}>;
138-
toggleContextMenu(): void;
139-
select(): void;
140-
deselect(): void;
141-
constructPath(pathname: string, entityType: string, unique: string): string;
91+
import type { UmbTreeItemModel } from '@umbraco-cms/backoffice/tree';
92+
93+
export interface MyTreeItemDataModel extends UmbTreeItemModel {
94+
// Add any additional properties you need for your tree item
14295
}
14396
```
97+
{% endcode %}
98+
14499

145-
#### Extending the Tree Item Context base <a href="#extending-the-tree-item-context-base" id="extending-the-tree-item-context-base"></a>
100+
### Adding data to the tree <a href="#adding-data-to-the-tree" id="adding-data-to-the-tree"></a>
146101

147-
The easiest way to create a custom tree item context is to extend the `UmbTreeItemContextBase<T>` class. This class provides a lot of the functionality you need out of the box, such as loading children, selecting, and deselecting the item.
102+
To add data to the tree, you need to create a repository that will provide the data for the tree. The repository is defined in the manifest of the tree and linked through its `repositoryAlias`.
148103

149-
We provide a base class for the tree item context. This class provides some default implementations for the context. You can extend this class to overwrite any of the default implementations.
104+
```json
105+
{
106+
"type": "repository",
107+
"alias": "My.Repository.Alias",
108+
"name": "My Repository",
109+
"api": "./my-repository.js"
110+
}
111+
```
150112

113+
#### Implementing the repository <a href="#implementing-the-repository" id="implementing-the-repository"></a>
114+
115+
The repository needs to be able to fetch data for the tree. You can implement the repository as a class that extends the [UmbTreeRepositoryBase](https://apidocs.umbraco.com/v16/ui-api/classes/packages_core_tree.UmbTreeRepositoryBase.html) class. This class provides the necessary methods to fetch data for the tree.
116+
117+
{% code title="my-repository.ts" %}
118+
```typescript
119+
import { MyTreeDataSource } from './my-tree-data-source.js';
120+
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
121+
import { UmbTreeRepositoryBase } from '@umbraco-cms/backoffice/tree';
122+
123+
export class MyRepository extends UmbTreeRepositoryBase {
124+
constructor(host: UmbControllerHost) {
125+
super(host, MyTreeDataSource);
126+
}
127+
}
128+
```
129+
{% endcode %}
130+
131+
#### Implementing the data source <a href="#implementing-the-data-source" id="implementing-the-data-source"></a>
132+
133+
The data source is responsible for fetching the data for the tree. You can implement the data source as a class that implements the [UmbTreeDataSource](https://apidocs.umbraco.com/v16/ui-api/interfaces/packages_core_tree.UmbTreeDataSource.html) interface.
134+
135+
{% code title="my-tree-data-source.ts" %}
151136
```typescript
152-
export class UmbMyTreeItemContext extends UmbTreeItemContextBase<MyTreeItemDataModel> {
153-
constructor(host: UmbControllerHostElement) {
154-
super(host, (x: MyTreeItemDataModel) => x.unique);
155-
}
137+
import type { MyTreeItemModel } from './my-tree-item.model.js';
138+
import type {
139+
UmbTreeAncestorsOfRequestArgs,
140+
UmbTreeChildrenOfRequestArgs,
141+
UmbTreeDataSource,
142+
UmbTreeRootItemsRequestArgs,
143+
} from '@umbraco-cms/backoffice/tree';
144+
145+
export class MyTreeDataSource implements UmbTreeDataSource<MyTreeItemModel> {
146+
async getRootItems(args: UmbTreeRootItemsRequestArgs) {
147+
// Fetch the root items for the tree
148+
return [
149+
{
150+
id: 'root1',
151+
name: 'Root Item 1',
152+
icon: 'icon-folder',
153+
},
154+
{
155+
id: 'root2',
156+
name: 'Root Item 2',
157+
icon: 'icon-folder',
158+
},
159+
];
160+
}
161+
162+
async getChildrenOf(args: UmbTreeChildrenOfRequestArgs) {
163+
// Fetch the children of the specified item
164+
if (args.id === 'root1') {
165+
return [
166+
{
167+
id: 'child1',
168+
name: 'Child Item 1',
169+
icon: 'icon-document',
170+
},
171+
{
172+
id: 'child2',
173+
name: 'Child Item 2',
174+
icon: 'icon-document',
175+
},
176+
];
177+
}
178+
return [];
179+
}
156180

157-
// overwrite any methods or properties here if needed
181+
async getAncestorsOf(args: UmbTreeAncestorsOfRequestArgs) {
182+
// Fetch the ancestors of the specified item
183+
if (args.id === 'child1') {
184+
return [
185+
{
186+
id: 'root1',
187+
name: 'Root Item 1',
188+
icon: 'icon-folder',
189+
},
190+
];
191+
}
192+
return [];
193+
}
158194
}
159195
```
196+
{% endcode %}
197+
198+
## Further reading <a href="#further-reading" id="further-reading"></a>
199+
200+
For more information on trees, you can refer to the examples folder in the GitHub repository: [Umbraco UI Examples - Trees](https://github.com/umbraco/Umbraco-CMS/tree/main/src/Umbraco.Web.UI.Client/examples/tree)

0 commit comments

Comments
 (0)