From cbc4f412e64c44965f8f5f03aaa46347573ead4b Mon Sep 17 00:00:00 2001 From: leekelleher Date: Mon, 19 Feb 2024 12:41:18 +0000 Subject: [PATCH] Refactored the repository, introduced `UmbDocumentCollectionItemModel` --- .../collection/document-collection.context.ts | 5 +- .../document-collection.repository.ts | 4 +- .../document-collection.server.data-source.ts | 81 ++++++++++--------- .../documents/documents/collection/types.ts | 25 +++++- .../document-grid-collection-view.element.ts | 15 ++-- .../document-table-collection-view.element.ts | 30 +++++-- 6 files changed, 96 insertions(+), 64 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/document-collection.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/document-collection.context.ts index f0ae2555d7..139d393fd6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/document-collection.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/document-collection.context.ts @@ -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) { diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.repository.ts index e55d9882b5..ebd5b771b2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.repository.ts @@ -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 {} diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.server.data-source.ts index 68e5150b99..febaef4250 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.server.data-source.ts @@ -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 { +export class UmbDocumentCollectionServerDataSource implements UmbCollectionDataSource { #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, - }; - }; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/types.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/types.ts index fa6136bb06..dc13ccc403 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/types.ts @@ -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 }>; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/grid/document-grid-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/grid/document-grid-collection-view.element.ts index d4579cd483..849d61d38b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/grid/document-grid-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/grid/document-grid-collection-view.element.ts @@ -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 = []; + private _items: Array = []; @state() private _selection: Array = []; @@ -17,7 +16,7 @@ export class UmbDocumentGridCollectionViewElement extends UmbLitElement { @state() private _loading = false; - #collectionContext?: UmbDefaultCollectionContext; + #collectionContext?: UmbDefaultCollectionContext; 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` this._handleOpenCard(item.unique ?? '')} @selected=${() => this.#onSelect(item)} @deselected=${() => this.#onDeselect(item)}> - + `; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts index 99aeff126e..8824d99342 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts @@ -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; + private _busy = false; + + @state() + private _items?: Array; @state() private _tableConfig: UmbTableConfig = { @@ -49,7 +51,10 @@ export class UmbDocumentTableCollectionViewElement extends UmbLitElement { @state() private _selection: Array = []; - private _collectionContext?: UmbDefaultCollectionContext; + 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) { + #createTableItems(items: Array) { 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`
`; + + if (this._tableItems.length === 0) + return html`

${this.localize.term('content_listViewNoItems')}

`; + return html`