diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/collection/views/user-group-table-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/collection/views/user-group-table-collection-view.element.ts index 06e927feb2..f5599fd17c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/collection/views/user-group-table-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/collection/views/user-group-table-collection-view.element.ts @@ -1,12 +1,9 @@ +import type { UmbUserGroupDetailModel } from '../../types.js'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import type { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collection'; import { UMB_DEFAULT_COLLECTION_CONTEXT } from '@umbraco-cms/backoffice/collection'; - -import '../components/user-group-table-name-column-layout.element.js'; -import '../components/user-group-table-sections-column-layout.element.js'; - import type { UmbTableColumn, UmbTableConfig, @@ -15,7 +12,11 @@ import type { UmbTableItem, UmbTableSelectedEvent, } from '@umbraco-cms/backoffice/components'; -import type { UmbUserGroupDetailModel } from '../../types.js'; +import { UmbDocumentItemRepository } from '@umbraco-cms/backoffice/document'; +import { UmbMediaItemRepository } from '@umbraco-cms/backoffice/media'; + +import '../components/user-group-table-name-column-layout.element.js'; +import '../components/user-group-table-sections-column-layout.element.js'; @customElement('umb-user-group-collection-table-view') export class UmbUserGroupCollectionTableViewElement extends UmbLitElement { @@ -54,6 +55,13 @@ export class UmbUserGroupCollectionTableViewElement extends UmbLitElement { #collectionContext?: UmbDefaultCollectionContext; + // TODO: hardcoded dependencies on document and media modules. We should figure out how these dependencies can be added through extensions. + #documentItemRepository = new UmbDocumentItemRepository(this); + #mediaItemRepository = new UmbMediaItemRepository(this); + + #documentStartNodeMap = new Map(); + #mediaStartNodeMap = new Map(); + constructor() { super(); @@ -74,7 +82,12 @@ export class UmbUserGroupCollectionTableViewElement extends UmbLitElement { }); } - private _createTableItems(userGroups: Array) { + private async _createTableItems(userGroups: Array) { + await Promise.all([ + this.#requestAndCacheDocumentStartNodes(userGroups), + this.#requestAndCacheMediaStartNodes(userGroups), + ]); + this._tableItems = userGroups.map((userGroup) => { return { id: userGroup.unique, @@ -92,17 +105,57 @@ export class UmbUserGroupCollectionTableViewElement extends UmbLitElement { }, { columnAlias: 'userGroupContentStartNode', - value: userGroup.documentStartNode?.unique || this.localize.term('content_contentRoot'), + value: userGroup.documentStartNode + ? this.#documentStartNodeMap.get(userGroup.documentStartNode.unique) + : this.localize.term('content_contentRoot'), }, { columnAlias: 'userGroupMediaStartNode', - value: userGroup.mediaStartNode?.unique || this.localize.term('media_mediaRoot'), + value: userGroup.mediaStartNode?.unique + ? this.#mediaStartNodeMap.get(userGroup.mediaStartNode.unique) + : this.localize.term('media_mediaRoot'), }, ], }; }); } + async #requestAndCacheDocumentStartNodes(userGroups: Array) { + const allStartNodes = userGroups + .map((userGroup) => userGroup.documentStartNode?.unique) + .filter(Boolean) as string[]; + const uniqueStartNodes = [...new Set(allStartNodes)]; + const uncachedStartNodes = uniqueStartNodes.filter((unique) => !this.#documentStartNodeMap.has(unique)); + + // If there are no uncached start nodes, we don't need to make a request + if (uncachedStartNodes.length === 0) return; + + const { data: items } = await this.#documentItemRepository.requestItems(uncachedStartNodes); + + if (items) { + items.forEach((item) => { + this.#documentStartNodeMap.set(item.unique, item.name); + }); + } + } + + async #requestAndCacheMediaStartNodes(userGroups: Array) { + const allStartNodes = userGroups.map((userGroup) => userGroup.mediaStartNode?.unique).filter(Boolean) as string[]; + const uniqueStartNodes = [...new Set(allStartNodes)]; + const uncachedStartNodes = uniqueStartNodes.filter((unique) => !this.#mediaStartNodeMap.has(unique)); + + // If there are no uncached start nodes, we don't need to make a request + if (uncachedStartNodes.length === 0) return; + + const { data: items } = await this.#mediaItemRepository.requestItems(uncachedStartNodes); + + if (items) { + items.forEach((item) => { + this.#mediaStartNodeMap.set(item.unique, item.name); + }); + } + } + private _handleSelected(event: UmbTableSelectedEvent) { event.stopPropagation(); const table = event.target as UmbTableElement;