Skip to content

Commit c097ff9

Browse files
authored
Merge pull request #7285 from umbraco/v16/docs/section-trees
V16: Adds information to creating trees in the Backoffice
2 parents f868a91 + bd987ef commit c097ff9

File tree

2 files changed

+147
-88
lines changed

2 files changed

+147
-88
lines changed

16/umbraco-cms/customizing/extending-overview/extension-types/tiny-mce-plugin.md

Whitespace-only changes.

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

Lines changed: 147 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -4,138 +4,197 @@ 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 %}
7+
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.
108

11-
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.
9+
{% hint style="info" %}
10+
To see how to register a tree as a menu in a section, please refer to the [Section Sidebar](./sections/section-sidebar.md) article.
11+
{% endhint %}
1212

1313
## Creating trees <a href="#creating-trees" id="creating-trees"></a>
1414

15-
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:
1616

1717
### Registering a tree <a href="#registering-a-tree" id="registering-a-tree"></a>
1818

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

21-
Tree Manifest:
22-
23-
```typescript
24-
// TODO: add interface
21+
```json
2522
{
26-
"type": "tree",
27-
"alias": "My.Tree.Alias",
28-
"name": "My Tree",
29-
"meta": {
30-
"repositoryAlias": "My.Repository.Alias"
31-
}
32-
},
33-
{
34-
"type": "treeItem",
35-
"kind": "entity",
36-
"alias": "My.TreeItem.Alias",
37-
"name": "My Tree Item",
38-
"conditions": {
39-
"entityType": "my-entity-type",
40-
},
23+
"type": "tree",
24+
"alias": "My.Tree.Alias",
25+
"name": "My Tree",
26+
"meta": {
27+
"repositoryAlias": "My.Repository.Alias"
28+
}
4129
}
4230
```
4331

4432
### Rendering a tree <a href="#rendering-a-tree" id="rendering-a-tree"></a>
4533

34+
To render a tree in the Backoffice, you can use the `<umb-tree>` element. You need to provide the alias of the tree you want to render. The alias is the same as the one you registered in the manifest.
35+
4636
```typescript
4737
<umb-tree alias="My.Tree.Alias"></umb-tree>
4838
```
4939

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

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.
43+
5244
#### **The Tree Item Manifest**
5345

54-
```typescript
46+
```json
5547
{
56-
"type": "treeItem",
57-
"alias": "Umb.TreeItem.Alias",
58-
"name": "My Tree Item",
59-
"element": "./my-tree-item.element.js",
60-
"conditions": {
61-
"entityType": "my-entity-type",
62-
},
48+
"type": "treeItem",
49+
"alias": "Umb.TreeItem.Alias",
50+
"name": "My Tree Item",
51+
"element": "./my-tree-item.element.js",
52+
"conditions": {
53+
"entityType": "my-entity-type",
54+
},
6355
};
6456
```
6557

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

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.
61+
62+
This example creates a custom tree item that extends the base class. The base class provides the necessary context and functionality for the tree item.
63+
6864
```typescript
69-
import { css, html, nothing } from 'lit';
70-
import { customElement, property } from 'lit/decorators.js';
71-
import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
72-
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';
7368

7469
@customElement('my-tree-item')
75-
export class MyTreeItemElement extends UmbElementMixin(LitElement) {
76-
private _item?: MyTreeItemDataModel;
77-
@property({ type: Object, attribute: false })
78-
public get item() {
79-
return this._item;
80-
}
81-
public set item(value: MyTreeItemDataModel | undefined) {
82-
this._item = value;
83-
this.#context.setTreeItem(value);
84-
}
85-
86-
#context = new UmbMyTreeItemContext(this);
87-
88-
render() {
89-
if (!this.item) return nothing;
90-
return html` <umb-tree-item-base> Some custom markup </umb-tree-item-base>`;
91-
}
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+
}
9280
}
9381

9482
export default MyTreeItemElement;
9583
```
9684

97-
#### The Tree Item Context <a href="#the-tree-item-context" id="the-tree-item-context"></a>
85+
#### The Tree Item Model <a href="#extending-the-tree-item-model" id="extending-the-tree-item-model"></a>
9886

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.
88+
89+
{% code title="my-tree-item.model.ts" %}
9990
```typescript
100-
// TODO: auto-generate this from the interface
101-
export interface UmbTreeItemContext<T> {
102-
host: UmbControllerHostElement;
103-
unique?: string;
104-
type?: string;
105-
106-
treeItem: Observable<T | undefined>;
107-
hasChildren: Observable<boolean>;
108-
isLoading: Observable<boolean>;
109-
isSelectable: Observable<boolean>;
110-
isSelected: Observable<boolean>;
111-
isActive: Observable<boolean>;
112-
hasActions: Observable<boolean>;
113-
path: Observable<string>;
114-
115-
setTreeItem(treeItem: T | undefined): void;
116-
117-
requestChildren(): Promise<{
118-
data: PagedResponse<T> | undefined;
119-
error: ProblemDetails | undefined;
120-
asObservable?: () => Observable<T[]>;
121-
}>;
122-
toggleContextMenu(): void;
123-
select(): void;
124-
deselect(): void;
125-
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
95+
}
96+
```
97+
{% endcode %}
98+
99+
100+
### Adding data to the tree <a href="#adding-data-to-the-tree" id="adding-data-to-the-tree"></a>
101+
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`.
103+
104+
```json
105+
{
106+
"type": "repository",
107+
"alias": "My.Repository.Alias",
108+
"name": "My Repository",
109+
"api": "./my-repository.js"
126110
}
127111
```
128112

129-
#### Extending the Tree Item Context base <a href="#extending-the-tree-item-context-base" id="extending-the-tree-item-context-base"></a>
113+
#### Implementing the repository <a href="#implementing-the-repository" id="implementing-the-repository"></a>
130114

131-
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.
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.
132116

117+
{% code title="my-repository.ts" %}
133118
```typescript
134-
export class UmbMyTreeItemContext extends UmbTreeItemContextBase<MyTreeItemDataModel> {
135-
constructor(host: UmbControllerHostElement) {
136-
super(host, (x: MyTreeItemDataModel) => x.unique);
137-
}
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.
138134

139-
// overwrite any methods or properties here if needed
135+
{% code title="my-tree-data-source.ts" %}
136+
```typescript
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+
}
180+
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+
}
140194
}
141195
```
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)