Refactored the repository, introduced UmbDocumentCollectionItemModel

This commit is contained in:
leekelleher
2024-02-19 12:41:18 +00:00
parent 760421a877
commit cbc4f412e6
6 changed files with 96 additions and 64 deletions

View File

@@ -1,11 +1,10 @@
import type { UmbDocumentDetailModel } from '../types.js';
import type { UmbDocumentCollectionFilterModel } from './types.js';
import type { UmbDocumentCollectionFilterModel, UmbDocumentCollectionItemModel } from './types.js';
import { UMB_DOCUMENT_TABLE_COLLECTION_VIEW_ALIAS } from './views/index.js';
import { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collection';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
export class UmbDocumentCollectionContext extends UmbDefaultCollectionContext<
UmbDocumentDetailModel,
UmbDocumentCollectionItemModel,
UmbDocumentCollectionFilterModel
> {
constructor(host: UmbControllerHost) {

View File

@@ -10,8 +10,8 @@ export class UmbDocumentCollectionRepository implements UmbCollectionRepository
this.#collectionSource = new UmbDocumentCollectionServerDataSource(host);
}
async requestCollection(filter: UmbDocumentCollectionFilterModel) {
return this.#collectionSource.getCollection(filter);
async requestCollection(query: UmbDocumentCollectionFilterModel) {
return this.#collectionSource.getCollection(query);
}
destroy(): void {}

View File

@@ -1,61 +1,62 @@
import { UMB_DOCUMENT_ENTITY_TYPE } from '../../entity.js';
import type { UmbDocumentCollectionFilterModel } from '../types.js';
import type { UmbDocumentTreeItemModel } from '../../tree/types.js';
import { DocumentResource } from '@umbraco-cms/backoffice/external/backend-api';
import type { UmbDocumentCollectionFilterModel, UmbDocumentCollectionItemModel } from '../types.js';
import { DirectionModel, DocumentResource } from '@umbraco-cms/backoffice/external/backend-api';
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
import type { DocumentTreeItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api';
import type { DocumentCollectionResponseModel } from '@umbraco-cms/backoffice/external/backend-api';
import type { UmbCollectionDataSource } from '@umbraco-cms/backoffice/repository';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
export class UmbDocumentCollectionServerDataSource implements UmbCollectionDataSource<UmbDocumentTreeItemModel> {
export class UmbDocumentCollectionServerDataSource implements UmbCollectionDataSource<UmbDocumentCollectionItemModel> {
#host: UmbControllerHost;
constructor(host: UmbControllerHost) {
this.#host = host;
}
async getCollection(filter: UmbDocumentCollectionFilterModel) {
// TODO: [LK] Replace the Management API call with the correct endpoint once it is available.
const { data, error } = await tryExecuteAndNotify(this.#host, DocumentResource.getTreeDocumentRoot(filter));
async getCollection(query: UmbDocumentCollectionFilterModel) {
if (!query.unique) {
throw new Error('Unique ID is required to fetch a collection.');
}
if (!query.dataTypeId) {
throw new Error('Data type ID is required to fetch a collection.');
}
const params = {
id: query.unique,
dataTypeId: query.dataTypeId,
orderBy: query.orderBy ?? 'updateDate',
orderCulture: query.orderCulture ?? 'en-US',
orderDirection: query.orderDirection === 'asc' ? DirectionModel.ASCENDING : DirectionModel.DESCENDING,
filter: query.filter,
skip: query.skip ?? 0,
take: query.take ?? 100,
};
const { data, error } = await tryExecuteAndNotify(this.#host, DocumentResource.getCollectionDocumentById(params));
if (data) {
const skip = Number(filter.skip) ?? 0;
const take = Number(filter.take) ?? 100;
const items = data.items.map((item: DocumentCollectionResponseModel) => {
const items = data.items.slice(skip, skip + take).map((item) => this.#mapper(item));
// TODO: [LK] Temp solution, review how to get the name from the corresponding variant.
const variant = item.variants[0];
//console.log('UmbDocumentCollectionServerDataSource.getCollection', [data, items]);
const model: UmbDocumentCollectionItemModel = {
unique: item.id,
createDate: new Date(variant.createDate),
creator: item.creator,
icon: item.documentType.icon,
name: variant.name,
state: variant.state,
updateDate: new Date(variant.updateDate),
updater: item.updater,
values: item.values.map((item) => { return { alias: item.alias, value: item.value }; }),
};
return model;
});
return { data: { items, total: data.total } };
}
return { error };
}
// TODO: [LK] Temp solution. Copied from "src\packages\documents\documents\tree\document-tree.server.data-source.ts"
#mapper = (item: DocumentTreeItemResponseModel): UmbDocumentTreeItemModel => {
return {
unique: item.id,
parentUnique: item.parent ? item.parent.id : null,
entityType: UMB_DOCUMENT_ENTITY_TYPE,
noAccess: item.noAccess,
isTrashed: item.isTrashed,
hasChildren: item.hasChildren,
isProtected: item.isProtected,
documentType: {
unique: item.documentType.id,
icon: item.documentType.icon,
hasCollection: item.documentType.hasListView,
},
variants: item.variants.map((variant) => {
return {
name: variant.name,
culture: variant.culture || null,
state: variant.state,
};
}),
name: item.variants[0]?.name, // TODO: this is not correct. We need to get it from the variants. This is a temp solution.
isFolder: false,
};
};
}

View File

@@ -1,5 +1,22 @@
export interface UmbDocumentCollectionFilterModel {
skip?: number;
take?: number;
filter?: string;
import type { UmbCollectionFilterModel } from '@umbraco-cms/backoffice/collection';
export interface UmbDocumentCollectionFilterModel extends UmbCollectionFilterModel {
unique: string;
dataTypeId?: string;
orderBy?: string;
orderCulture?: string;
orderDirection?: 'asc' | 'desc';
userDefinedProperties: Array<{alias: string, header: string, isSystem: boolean}>;
}
export interface UmbDocumentCollectionItemModel {
unique: string;
createDate: Date;
creator?: string | null;
icon: string;
name: string;
state: string;
updateDate: Date;
updater?: string | null;
values: Array<{ alias: string; value: string }>;
}

View File

@@ -1,5 +1,4 @@
import type { UmbDocumentCollectionFilterModel } from '../../types.js';
import type { UmbDocumentTreeItemModel } from '../../../tree/types.js';
import type { UmbDocumentCollectionFilterModel, UmbDocumentCollectionItemModel } from '../../types.js';
import { css, html, nothing, customElement, state, repeat } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
@@ -9,7 +8,7 @@ import type { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collec
@customElement('umb-document-grid-collection-view')
export class UmbDocumentGridCollectionViewElement extends UmbLitElement {
@state()
private _items: Array<UmbDocumentTreeItemModel> = [];
private _items: Array<UmbDocumentCollectionItemModel> = [];
@state()
private _selection: Array<string | null> = [];
@@ -17,7 +16,7 @@ export class UmbDocumentGridCollectionViewElement extends UmbLitElement {
@state()
private _loading = false;
#collectionContext?: UmbDefaultCollectionContext<UmbDocumentTreeItemModel, UmbDocumentCollectionFilterModel>;
#collectionContext?: UmbDefaultCollectionContext<UmbDocumentCollectionItemModel, UmbDocumentCollectionFilterModel>;
constructor() {
super();
@@ -39,11 +38,11 @@ export class UmbDocumentGridCollectionViewElement extends UmbLitElement {
history.pushState(null, '', 'section/content/workspace/document/edit/' + id);
}
#onSelect(item: UmbDocumentTreeItemModel) {
#onSelect(item: UmbDocumentCollectionItemModel) {
this.#collectionContext?.selection.select(item.unique ?? '');
}
#onDeselect(item: UmbDocumentTreeItemModel) {
#onDeselect(item: UmbDocumentCollectionItemModel) {
this.#collectionContext?.selection.deselect(item.unique ?? '');
}
@@ -60,7 +59,7 @@ export class UmbDocumentGridCollectionViewElement extends UmbLitElement {
`;
}
#renderCard(item: UmbDocumentTreeItemModel) {
#renderCard(item: UmbDocumentCollectionItemModel) {
return html`
<uui-card-content-node
.name=${item.name ?? 'Unnamed Document'}
@@ -70,7 +69,7 @@ export class UmbDocumentGridCollectionViewElement extends UmbLitElement {
@open=${() => this._handleOpenCard(item.unique ?? '')}
@selected=${() => this.#onSelect(item)}
@deselected=${() => this.#onDeselect(item)}>
<uui-icon slot="icon" name=${item.documentType.icon}></uui-icon>
<uui-icon slot="icon" name=${item.icon}></uui-icon>
</uui-card-content-node>
`;
}

View File

@@ -1,5 +1,4 @@
import type { UmbDocumentCollectionFilterModel } from '../../types.js';
import type { UmbDocumentTreeItemModel } from '../../../tree/types.js';
import type { UmbDocumentCollectionFilterModel, UmbDocumentCollectionItemModel } from '../../types.js';
import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
@@ -20,7 +19,10 @@ import type { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collec
@customElement('umb-document-table-collection-view')
export class UmbDocumentTableCollectionViewElement extends UmbLitElement {
@state()
private _items?: Array<UmbDocumentTreeItemModel>;
private _busy = false;
@state()
private _items?: Array<UmbDocumentCollectionItemModel>;
@state()
private _tableConfig: UmbTableConfig = {
@@ -49,7 +51,10 @@ export class UmbDocumentTableCollectionViewElement extends UmbLitElement {
@state()
private _selection: Array<string> = [];
private _collectionContext?: UmbDefaultCollectionContext<UmbDocumentTreeItemModel, UmbDocumentCollectionFilterModel>;
private _collectionContext?: UmbDefaultCollectionContext<
UmbDocumentCollectionItemModel,
UmbDocumentCollectionFilterModel
>;
constructor() {
super();
@@ -64,7 +69,7 @@ export class UmbDocumentTableCollectionViewElement extends UmbLitElement {
this.observe(this._collectionContext.items, (items) => {
this._items = items;
this._createTableItems(this._items);
this.#createTableItems(this._items);
});
this.observe(this._collectionContext.selection.selection, (selection) => {
@@ -72,12 +77,11 @@ export class UmbDocumentTableCollectionViewElement extends UmbLitElement {
});
}
private _createTableItems(items: Array<UmbDocumentTreeItemModel>) {
#createTableItems(items: Array<UmbDocumentCollectionItemModel>) {
this._tableItems = items.map((item) => {
if (!item.unique) throw new Error('Item id is missing.');
return {
id: item.unique,
icon: item.documentType.icon,
data: [
{
columnAlias: 'entityName',
@@ -90,6 +94,7 @@ export class UmbDocumentTableCollectionViewElement extends UmbLitElement {
// },
// },
],
icon: item.icon,
};
});
}
@@ -116,6 +121,11 @@ export class UmbDocumentTableCollectionViewElement extends UmbLitElement {
}
render() {
if (this._busy) return html`<div class="container"><uui-loader></uui-loader></div>`;
if (this._tableItems.length === 0)
return html`<div class="container"><p>${this.localize.term('content_listViewNoItems')}</p></div>`;
return html`
<umb-table
.config=${this._tableConfig}
@@ -143,6 +153,12 @@ export class UmbDocumentTableCollectionViewElement extends UmbLitElement {
umb-table {
padding: 0; /* To fix the embedded padding in the table component. */
}
.container {
display: flex;
justify-content: center;
align-items: center;
}
`,
];
}