Skip to content

Commit 8345d67

Browse files
committed
add document for collection view extension
1 parent 35a278d commit 8345d67

File tree

4 files changed

+362
-0
lines changed

4 files changed

+362
-0
lines changed

16/umbraco-cms/SUMMARY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@
188188
* [Workspace Context](customizing/extending-overview/extension-types/workspaces/workspace-context.md)
189189
* [Workspace Views](customizing/extending-overview/extension-types/workspaces/workspace-views.md)
190190
* [Workspace Footer Apps](customizing/extending-overview/extension-types/workspaces/workspace-footer-apps.md)
191+
* [Collections](customizing/extending-overview/extension-types/collections/README.md)
192+
* [Collection View](customizing/extending-overview/extension-types/collections/collection-view.md)
191193
* [Extension Kind](customizing/extending-overview/extension-kind.md)
192194
* [Extension Conditions](customizing/extending-overview/extension-conditions.md)
193195
* [Custom Extension types](customizing/extending-overview/custom-extension-type.md)
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
---
2+
description: >-
3+
Learn how to create a Collection View that defines how data is displayed within a collection in Umbraco.
4+
---
5+
6+
## Purpose
7+
Use a collection view when you need to:
8+
- Present data in a structured or visual way (e.g, table, cards, grid)
9+
- Customize how entity fields are displayed
10+
11+
## Create a Collection View
12+
13+
{% hint style="info" %}
14+
Before creating a Collection view, make sure you are familiar with the [Extension Registry in Umbraco](../../../../customizing/extending-overview/extension-registry/register-extensions.md).
15+
{% endhint %}
16+
17+
### Manifest
18+
{% code title="umbraco-package.json" %}
19+
```json
20+
{
21+
"type": "collectionView",
22+
"alias": "My.CollectionView.Alias",
23+
"name": "My Collection View",
24+
"element": "/App_Plugins/my-collection-view/my-collection-view.js",
25+
"meta": {
26+
"label": "Table",
27+
"icon": "icon-list",
28+
"pathName": "table"
29+
},
30+
"conditions": [
31+
{
32+
"alias": "Umb.Condition.CollectionAlias",
33+
"match": "Umb.Collection.Document" // Type of entity to display in this collection view
34+
}
35+
]
36+
}
37+
```
38+
{% endcode %}
39+
40+
### Implementation
41+
42+
Implement your collection view as a Lit element that extends `UmbLitElement`.
43+
This defines how a list of entities is rendered in your collection.
44+
45+
{% code title="my-collection-view.ts" %}
46+
```typescript
47+
import { css, customElement, html, state } from '@umbraco-cms/backoffice/external/lit';
48+
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
49+
import { UMB_DOCUMENT_COLLECTION_CONTEXT } from '@umbraco-cms/backoffice/document';
50+
import type { UmbDocumentCollectionItemModel } from '@umbraco-cms/backoffice/document';
51+
import type { UmbCollectionColumnConfiguration } from '@umbraco-cms/backoffice/collection';
52+
53+
@customElement('my-document-table-collection-view')
54+
export class MyDocumentTableCollectionViewElement extends UmbLitElement {
55+
56+
@state() private _columns: Array<{ name: string; alias: string; align?: string }> = [];
57+
@state() private _items?: Array<UmbDocumentCollectionItemModel> = [];
58+
59+
constructor() {
60+
super();
61+
62+
this.consumeContext(UMB_DOCUMENT_COLLECTION_CONTEXT, (collectionContext) => {
63+
collectionContext?.setupView(this);
64+
65+
this.observe(collectionContext?.userDefinedProperties, (props) => {
66+
this.#createColumns(props);
67+
});
68+
69+
this.observe(collectionContext?.items, (items) => {
70+
this._items = items;
71+
});
72+
});
73+
}
74+
75+
#createColumns(userProps: Array<UmbCollectionColumnConfiguration> = []) {
76+
const baseCols = [
77+
{ name: 'Name', alias: 'name' },
78+
{ name: 'State', alias: 'state' },
79+
];
80+
const userCols = userProps.map((p) => ({
81+
name: p.nameTemplate ?? p.alias,
82+
alias: p.alias,
83+
}));
84+
this._columns = [...baseCols, ...userCols, { name: '', alias: 'entityActions', align: 'right' }];
85+
}
86+
87+
override render() {
88+
if (this._items === undefined) return html`<p>Not found...</p>`;
89+
return html`
90+
<table>
91+
<thead>
92+
<tr>
93+
${this._columns.map((col) => html`<th style="text-align:${col.align ?? 'left'}">${col.name}</th>`)}
94+
</tr>
95+
</thead>
96+
<tbody>
97+
${this._items.map(
98+
(item) => html`
99+
<tr>
100+
${this._columns.map((col) => {
101+
switch (col.alias) {
102+
case 'name':
103+
return html`<td><a href="#">${item.name}</a></td>`;
104+
case 'state':
105+
return html`<td>${item.state}</td>`;
106+
case 'sortOrder':
107+
return html`<td>${item.sortOrder}</td>`;
108+
case 'updateDate':
109+
return html`<td>${item.updateDate}</td>`
110+
case 'creator':
111+
return html`<td>${item.creator}</td>`;
112+
case 'entityActions':
113+
return html`<td style="text-align:right;">⋮</td>`;
114+
default:
115+
const val = item.values.find((v) => v.alias === col.alias)?.value ?? '';
116+
return html`<td>${val}</td>`;
117+
}
118+
})}
119+
</tr>
120+
`
121+
)}
122+
</tbody>
123+
</table>
124+
`;
125+
}
126+
127+
static override styles = css`
128+
:host {
129+
display: block;
130+
width: 100%;
131+
overflow-x: auto;
132+
font-family: sans-serif;
133+
}
134+
table {
135+
width: 100%;
136+
border-collapse: collapse;
137+
}
138+
th,
139+
td {
140+
padding: 6px 10px;
141+
border: 1px solid #ddd;
142+
white-space: nowrap;
143+
}
144+
th {
145+
background: #f8f8f8;
146+
font-weight: 600;
147+
}
148+
a {
149+
color: var(--uui-color-interactive, #0366d6);
150+
text-decoration: none;
151+
}
152+
a:hover {
153+
text-decoration: underline;
154+
}
155+
`;
156+
}
157+
158+
export default MyDocumentTableCollectionViewElement;
159+
160+
declare global {
161+
interface HTMLElementTagNameMap {
162+
'my-document-table-collection-view': MyDocumentTableCollectionViewElement;
163+
}
164+
}
165+
```
166+
{% endcode %}
167+
168+
### Common Collection Match Values
169+
170+
Use the `match` property in your manifest to target a specific collection type.
171+
| **Match Value** | **Description** |
172+
|------------------|-----------------|
173+
| `Umb.Collection.Document` | Targets the **Document** collection (content items). |
174+
| `Umb.Collection.Media` | Targets the **Media** collection (images, videos, files). |
175+
| `Umb.Collection.Member` | Targets the **Member** collection (users or members). |
176+
| `Umb.Collection.MemberGroup` | Targets the **Member Group** collection (users or members). |
177+
| `Umb.Collection.User` | Targets the **User** collection in Settings. |
178+
| `Umb.Collection.UserGroup` | Targets the **User** collection in Settings. |
179+
| `Umb.Collection.Dictionary` | Targets the **Dictionary** collection. |

17/umbraco-cms/SUMMARY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@
194194
* [Workspace Context](customizing/extending-overview/extension-types/workspaces/workspace-context.md)
195195
* [Workspace Footer Apps](customizing/extending-overview/extension-types/workspaces/workspace-footer-apps.md)
196196
* [Workspace Views](customizing/extending-overview/extension-types/workspaces/workspace-views.md)
197+
* [Collections](customizing/extending-overview/extension-types/collections/README.md)
198+
* [Collection View](customizing/extending-overview/extension-types/collections/collection-view.md)
197199
* [Extension Kind](customizing/extending-overview/extension-kind.md)
198200
* [Extension Conditions](customizing/extending-overview/extension-conditions.md)
199201
* [Custom Extension types](customizing/extending-overview/custom-extension-type.md)
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
---
2+
description: >-
3+
Learn how to create a Collection View that defines how data is displayed within a collection in Umbraco.
4+
---
5+
6+
## Purpose
7+
Use a collection view when you need to:
8+
- Present data in a structured or visual way (e.g, table, cards, grid)
9+
- Customize how entity fields are displayed
10+
11+
## Create a Collection View
12+
13+
{% hint style="info" %}
14+
Before creating a Collection view, make sure you are familiar with the [Extension Registry in Umbraco](../../../../customizing/extending-overview/extension-registry/register-extensions.md).
15+
{% endhint %}
16+
17+
### Manifest
18+
{% code title="umbraco-package.json" %}
19+
```json
20+
{
21+
"type": "collectionView",
22+
"alias": "My.CollectionView.Alias",
23+
"name": "My Collection View",
24+
"element": "/App_Plugins/my-collection-view/my-collection-view.js",
25+
"meta": {
26+
"label": "Table",
27+
"icon": "icon-list",
28+
"pathName": "table"
29+
},
30+
"conditions": [
31+
{
32+
"alias": "Umb.Condition.CollectionAlias",
33+
"match": "Umb.Collection.Document" // Type of entity to display in this collection view
34+
}
35+
]
36+
}
37+
```
38+
{% endcode %}
39+
40+
### Implementation
41+
42+
Implement your collection view as a Lit element that extends `UmbLitElement`.
43+
This defines how a list of entities is rendered in your collection.
44+
45+
{% code title="my-collection-view.ts" %}
46+
```typescript
47+
import { css, customElement, html, state } from '@umbraco-cms/backoffice/external/lit';
48+
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
49+
import { UMB_DOCUMENT_COLLECTION_CONTEXT } from '@umbraco-cms/backoffice/document';
50+
import type { UmbDocumentCollectionItemModel } from '@umbraco-cms/backoffice/document';
51+
import type { UmbCollectionColumnConfiguration } from '@umbraco-cms/backoffice/collection';
52+
53+
@customElement('my-document-table-collection-view')
54+
export class MyDocumentTableCollectionViewElement extends UmbLitElement {
55+
56+
@state() private _columns: Array<{ name: string; alias: string; align?: string }> = [];
57+
@state() private _items?: Array<UmbDocumentCollectionItemModel> = [];
58+
59+
constructor() {
60+
super();
61+
62+
this.consumeContext(UMB_DOCUMENT_COLLECTION_CONTEXT, (collectionContext) => {
63+
collectionContext?.setupView(this);
64+
65+
this.observe(collectionContext?.userDefinedProperties, (props) => {
66+
this.#createColumns(props);
67+
});
68+
69+
this.observe(collectionContext?.items, (items) => {
70+
this._items = items;
71+
});
72+
});
73+
}
74+
75+
#createColumns(userProps: Array<UmbCollectionColumnConfiguration> = []) {
76+
const baseCols = [
77+
{ name: 'Name', alias: 'name' },
78+
{ name: 'State', alias: 'state' },
79+
];
80+
const userCols = userProps.map((p) => ({
81+
name: p.nameTemplate ?? p.alias,
82+
alias: p.alias,
83+
}));
84+
this._columns = [...baseCols, ...userCols, { name: '', alias: 'entityActions', align: 'right' }];
85+
}
86+
87+
override render() {
88+
if (this._items === undefined) return html`<p>Not found...</p>`;
89+
return html`
90+
<table>
91+
<thead>
92+
<tr>
93+
${this._columns.map((col) => html`<th style="text-align:${col.align ?? 'left'}">${col.name}</th>`)}
94+
</tr>
95+
</thead>
96+
<tbody>
97+
${this._items.map(
98+
(item) => html`
99+
<tr>
100+
${this._columns.map((col) => {
101+
switch (col.alias) {
102+
case 'name':
103+
return html`<td><a href="#">${item.name}</a></td>`;
104+
case 'state':
105+
return html`<td>${item.state}</td>`;
106+
case 'sortOrder':
107+
return html`<td>${item.sortOrder}</td>`;
108+
case 'updateDate':
109+
return html`<td>${item.updateDate}</td>`
110+
case 'creator':
111+
return html`<td>${item.creator}</td>`;
112+
case 'entityActions':
113+
return html`<td style="text-align:right;">⋮</td>`;
114+
default:
115+
const val = item.values.find((v) => v.alias === col.alias)?.value ?? '';
116+
return html`<td>${val}</td>`;
117+
}
118+
})}
119+
</tr>
120+
`
121+
)}
122+
</tbody>
123+
</table>
124+
`;
125+
}
126+
127+
static override styles = css`
128+
:host {
129+
display: block;
130+
width: 100%;
131+
overflow-x: auto;
132+
font-family: sans-serif;
133+
}
134+
table {
135+
width: 100%;
136+
border-collapse: collapse;
137+
}
138+
th,
139+
td {
140+
padding: 6px 10px;
141+
border: 1px solid #ddd;
142+
white-space: nowrap;
143+
}
144+
th {
145+
background: #f8f8f8;
146+
font-weight: 600;
147+
}
148+
a {
149+
color: var(--uui-color-interactive, #0366d6);
150+
text-decoration: none;
151+
}
152+
a:hover {
153+
text-decoration: underline;
154+
}
155+
`;
156+
}
157+
158+
export default MyDocumentTableCollectionViewElement;
159+
160+
declare global {
161+
interface HTMLElementTagNameMap {
162+
'my-document-table-collection-view': MyDocumentTableCollectionViewElement;
163+
}
164+
}
165+
```
166+
{% endcode %}
167+
168+
### Common Collection Match Values
169+
170+
Use the `match` property in your manifest to target a specific collection type.
171+
| **Match Value** | **Description** |
172+
|------------------|-----------------|
173+
| `Umb.Collection.Document` | Targets the **Document** collection (content items). |
174+
| `Umb.Collection.Media` | Targets the **Media** collection (images, videos, files). |
175+
| `Umb.Collection.Member` | Targets the **Member** collection (users or members). |
176+
| `Umb.Collection.MemberGroup` | Targets the **Member Group** collection (users or members). |
177+
| `Umb.Collection.User` | Targets the **User** collection in Settings. |
178+
| `Umb.Collection.UserGroup` | Targets the **User** collection in Settings. |
179+
| `Umb.Collection.Dictionary` | Targets the **Dictionary** collection. |

0 commit comments

Comments
 (0)