diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/manifests.ts new file mode 100644 index 0000000000..c48b1c6d57 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/manifests.ts @@ -0,0 +1,3 @@ +import { manifests as collectionRepositoryManifests } from './repository/manifests.js'; + +export const manifests = [...collectionRepositoryManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/repository/index.ts new file mode 100644 index 0000000000..96f4e5b899 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/repository/index.ts @@ -0,0 +1 @@ +export * from './user-collection.repository.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/repository/manifests.ts new file mode 100644 index 0000000000..ad36411412 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/repository/manifests.ts @@ -0,0 +1,13 @@ +import { UmbUserCollectionRepository } from './user-collection.repository.js'; +import { ManifestRepository } from '@umbraco-cms/backoffice/extension-registry'; + +export const USER_COLLECTION_REPOSITORY_ALIAS = 'Umb.Repository.UserCollection'; + +const repository: ManifestRepository = { + type: 'repository', + alias: USER_COLLECTION_REPOSITORY_ALIAS, + name: 'User Collection Repository', + api: UmbUserCollectionRepository, +}; + +export const manifests = [repository]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/repository/user-collection.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/repository/user-collection.repository.ts new file mode 100644 index 0000000000..5c3f761fec --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/repository/user-collection.repository.ts @@ -0,0 +1,39 @@ +import { UmbUserCollectionFilterModel } from '../../types.js'; +import { UMB_USER_STORE_CONTEXT_TOKEN, UmbUserStore } from '../../repository/user.store.js'; +import { UmbUserCollectionServerDataSource } from './user-collection.server.data.js'; +import { UserResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbCollectionDataSource, UmbCollectionRepository } from '@umbraco-cms/backoffice/repository'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; + +export class UmbUserCollectionRepository implements UmbCollectionRepository { + #host: UmbControllerHostElement; + #init; + + #detailStore?: UmbUserStore; + #collectionSource: UmbCollectionDataSource; + + constructor(host: UmbControllerHostElement) { + this.#host = host; + + this.#collectionSource = new UmbUserCollectionServerDataSource(this.#host); + + this.#init = Promise.all([ + new UmbContextConsumerController(this.#host, UMB_USER_STORE_CONTEXT_TOKEN, (instance) => { + this.#detailStore = instance; + }).asPromise(), + ]); + } + + async requestCollection(filter: UmbUserCollectionFilterModel = { skip: 0, take: 100 }) { + await this.#init; + + const { data, error } = await this.#collectionSource.filterCollection(filter); + + if (data) { + this.#detailStore?.appendItems(data.items); + } + + return { data, error, asObservable: () => this.#detailStore!.all() }; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/sources/user-collection.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/repository/user-collection.server.data.ts similarity index 54% rename from src/Umbraco.Web.UI.Client/src/packages/user/user/repository/sources/user-collection.server.data.ts rename to src/Umbraco.Web.UI.Client/src/packages/user/user/collection/repository/user-collection.server.data.ts index 7d8317fa62..72f15f73e9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/sources/user-collection.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/repository/user-collection.server.data.ts @@ -1,14 +1,14 @@ -import type { UmbUserCollectionFilterModel, UmbUserDetail } from '../../types.js'; +import { USER_ENTITY_TYPE, type UmbUserCollectionFilterModel, type UmbUserDetail } from '../../types.js'; import { UmbCollectionDataSource, extendDataSourcePagedResponseData } from '@umbraco-cms/backoffice/repository'; import { UserResource } from '@umbraco-cms/backoffice/backend-api'; import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; /** - * A data source for the User that fetches data from the server + * A data source that fetches the user collection data from the server. * @export * @class UmbUserCollectionServerDataSource - * @implements {RepositoryDetailDataSource} + * @implements {UmbCollectionDataSource} */ export class UmbUserCollectionServerDataSource implements UmbCollectionDataSource { #host: UmbControllerHostElement; @@ -22,15 +22,28 @@ export class UmbUserCollectionServerDataSource implements UmbCollectionDataSourc this.#host = host; } + /** + * Gets the user collection from the server. + * @return {*} + * @memberof UmbUserCollectionServerDataSource + */ async getCollection() { const response = await tryExecuteAndNotify(this.#host, UserResource.getUser({})); return extendDataSourcePagedResponseData(response, { - entityType: 'user', + entityType: USER_ENTITY_TYPE, }); } - filterCollection(filter: UmbUserCollectionFilterModel) { - return tryExecuteAndNotify(this.#host, UserResource.getUserFilter(filter)); - // TODO: Most likely missing the right type, and should then extend the data set with entityType. + /** + * Gets the user collection filtered by the given filter. + * @param {UmbUserCollectionFilterModel} filter + * @return {*} + * @memberof UmbUserCollectionServerDataSource + */ + async filterCollection(filter: UmbUserCollectionFilterModel) { + const response = await tryExecuteAndNotify(this.#host, UserResource.getUserFilter(filter)); + return extendDataSourcePagedResponseData(response, { + entityType: USER_ENTITY_TYPE, + }); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/user-collection.context.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/user-collection.context.ts index 10e9000cef..f7e7452fbc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/user-collection.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/user-collection.context.ts @@ -1,12 +1,12 @@ -import { USER_REPOSITORY_ALIAS } from '../repository/manifests.js'; -import { UmbUserCollectionFilterModel, UmbUserDetail } from '../types.js'; +import { USER_ENTITY_TYPE, UmbUserCollectionFilterModel, UmbUserDetail } from '../types.js'; +import { USER_COLLECTION_REPOSITORY_ALIAS } from './repository/manifests.js'; import { UmbCollectionContext } from '@umbraco-cms/backoffice/collection'; import { UserOrderModel, UserStateModel } from '@umbraco-cms/backoffice/backend-api'; import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; export class UmbUserCollectionContext extends UmbCollectionContext { constructor(host: UmbControllerHostElement) { - super(host, 'user', USER_REPOSITORY_ALIAS); + super(host, USER_ENTITY_TYPE, USER_COLLECTION_REPOSITORY_ALIAS); } /** diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/user-collection.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/user-collection.element.ts index 1f2ea624e5..484ba84622 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/user-collection.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/user-collection.element.ts @@ -1,6 +1,6 @@ import { UmbUserCollectionContext } from './user-collection.context.js'; import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; -import { UmbTextStyles } from "@umbraco-cms/backoffice/style"; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UMB_COLLECTION_CONTEXT } from '@umbraco-cms/backoffice/collection'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import type { UmbRoute } from '@umbraco-cms/backoffice/router'; @@ -40,7 +40,6 @@ export class UmbUserCollectionElement extends UmbLitElement { - `; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/entity-bulk-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/entity-bulk-actions/manifests.ts index e06c06f4e2..a350b335c1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/entity-bulk-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/entity-bulk-actions/manifests.ts @@ -1,12 +1,11 @@ import { USER_REPOSITORY_ALIAS } from '../repository/manifests.js'; +import { USER_ENTITY_TYPE } from '../types.js'; import { UmbEnableUserEntityBulkAction } from './enable/enable.action.js'; import { UmbSetGroupUserEntityBulkAction } from './set-group/set-group.action.js'; import { UmbUnlockUserEntityBulkAction } from './unlock/unlock.action.js'; import { UmbDisableUserEntityBulkAction } from './disable/disable.action.js'; import { ManifestEntityBulkAction } from '@umbraco-cms/backoffice/extension-registry'; -const entityType = 'user'; - const entityActions: Array = [ { type: 'entityBulkAction', @@ -18,10 +17,12 @@ const entityActions: Array = [ label: 'SetGroup', repositoryAlias: USER_REPOSITORY_ALIAS, }, - conditions: [{ - alias: 'Umb.Condition.CollectionEntityType', - match: entityType, - }], + conditions: [ + { + alias: 'Umb.Condition.CollectionEntityType', + match: USER_ENTITY_TYPE, + }, + ], }, { type: 'entityBulkAction', @@ -33,10 +34,12 @@ const entityActions: Array = [ label: 'Enable', repositoryAlias: USER_REPOSITORY_ALIAS, }, - conditions: [{ - alias: 'Umb.Condition.CollectionEntityType', - match: entityType, - }], + conditions: [ + { + alias: 'Umb.Condition.CollectionEntityType', + match: USER_ENTITY_TYPE, + }, + ], }, { type: 'entityBulkAction', @@ -48,10 +51,12 @@ const entityActions: Array = [ label: 'Unlock', repositoryAlias: USER_REPOSITORY_ALIAS, }, - conditions: [{ - alias: 'Umb.Condition.CollectionEntityType', - match: entityType, - }], + conditions: [ + { + alias: 'Umb.Condition.CollectionEntityType', + match: USER_ENTITY_TYPE, + }, + ], }, { type: 'entityBulkAction', @@ -63,10 +68,12 @@ const entityActions: Array = [ label: 'Disable', repositoryAlias: USER_REPOSITORY_ALIAS, }, - conditions: [{ - alias: 'Umb.Condition.CollectionEntityType', - match: entityType, - }], + conditions: [ + { + alias: 'Umb.Condition.CollectionEntityType', + match: USER_ENTITY_TYPE, + }, + ], }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/manifests.ts index 5df3013681..b412dc5a55 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/manifests.ts @@ -1,3 +1,4 @@ +import { manifests as collectionManifests } from './collection/manifests.js'; import { manifests as repositoryManifests } from './repository/manifests.js'; import { manifests as workspaceManifests } from './workspace/manifests.js'; import { manifests as modalManifests } from './modals/manifests.js'; @@ -7,6 +8,7 @@ import { manifests as entityBulkActionManifests } from './entity-bulk-actions/ma import { manifests as conditionsManifests } from './conditions/manifests.js'; export const manifests = [ + ...collectionManifests, ...repositoryManifests, ...workspaceManifests, ...modalManifests, diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/sources/user.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/sources/user.server.data.ts index 4a6fe8f002..fc61193283 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/sources/user.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/sources/user.server.data.ts @@ -1,4 +1,4 @@ -import { UmbUserDetail, UmbUserDetailDataSource } from '../../types.js'; +import { USER_ENTITY_TYPE, UmbUserDetail, UmbUserDetailDataSource } from '../../types.js'; import { DataSourceResponse, extendDataSourceResponseData } from '@umbraco-cms/backoffice/repository'; import { CreateUserRequestModel, @@ -37,7 +37,7 @@ export class UmbUserServerDataSource implements UmbUserDetailDataSource { if (!id) throw new Error('Id is missing'); const response = await tryExecuteAndNotify(this.#host, UserResource.getUserById({ id })); return extendDataSourceResponseData(response, { - entityType: 'user', + entityType: USER_ENTITY_TYPE, }); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/user.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/user.repository.ts index 51f88c98c5..a1e0ea06d4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/user.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/user.repository.ts @@ -1,25 +1,12 @@ -import { - UmbUserCollectionFilterModel, - UmbUserDetail, - UmbUserDetailDataSource, - UmbUserSetGroupDataSource, -} from '../types.js'; - +import { UmbUserDetailDataSource, UmbUserSetGroupDataSource } from '../types.js'; import { UMB_USER_STORE_CONTEXT_TOKEN, UmbUserStore } from './user.store.js'; import { UmbUserServerDataSource } from './sources/user.server.data.js'; -import { UmbUserCollectionServerDataSource } from './sources/user-collection.server.data.js'; import { UmbUserItemServerDataSource } from './sources/user-item.server.data.js'; import { UMB_USER_ITEM_STORE_CONTEXT_TOKEN, UmbUserItemStore } from './user-item.store.js'; import { UmbUserSetGroupsServerDataSource } from './sources/user-set-group.server.data.js'; import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; -import { - UmbCollectionDataSource, - UmbCollectionRepository, - UmbDetailRepository, - UmbItemDataSource, - UmbItemRepository, -} from '@umbraco-cms/backoffice/repository'; +import { UmbDetailRepository, UmbItemDataSource, UmbItemRepository } from '@umbraco-cms/backoffice/repository'; import { CreateUserRequestModel, CreateUserResponseModel, @@ -37,9 +24,7 @@ export type UmbUserDetailRepository = UmbDetailRepository< UserResponseModel >; -export class UmbUserRepository - implements UmbUserDetailRepository, UmbCollectionRepository, UmbItemRepository -{ +export class UmbUserRepository implements UmbUserDetailRepository, UmbItemRepository { #host: UmbControllerHostElement; #init; @@ -49,15 +34,12 @@ export class UmbUserRepository #itemStore?: UmbUserItemStore; #setUserGroupsSource: UmbUserSetGroupDataSource; - #collectionSource: UmbCollectionDataSource; - #notificationContext?: UmbNotificationContext; constructor(host: UmbControllerHostElement) { this.#host = host; this.#detailSource = new UmbUserServerDataSource(this.#host); - this.#collectionSource = new UmbUserCollectionServerDataSource(this.#host); this.#itemSource = new UmbUserItemServerDataSource(this.#host); this.#setUserGroupsSource = new UmbUserSetGroupsServerDataSource(this.#host); @@ -76,16 +58,6 @@ export class UmbUserRepository ]); } - // COLLECTION - async requestCollection(filter: UmbUserCollectionFilterModel = { skip: 0, take: 100000 }) { - //TODO: missing observable - return this.#collectionSource.filterCollection(filter); - } - - async filterCollection(filter: UmbUserCollectionFilterModel) { - return this.#collectionSource.filterCollection(filter); - } - // ITEMS: async requestItems(ids: Array) { if (!ids) throw new Error('Ids are missing'); diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/types.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/types.ts index a2cfe2e28d..156299afa8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/types.ts @@ -10,6 +10,8 @@ import type { import { UmbDataSource, UmbDataSourceErrorResponse } from '@umbraco-cms/backoffice/repository'; +export const USER_ENTITY_TYPE = 'user'; + export type UmbUserDetail = UserResponseModel & { entityType: 'user'; }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/workspace/manifests.ts index a08bf1141a..87a3718fd2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/workspace/manifests.ts @@ -1,3 +1,4 @@ +import { USER_ENTITY_TYPE } from '../types.js'; import { UmbSaveWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; import type { ManifestWorkspace, @@ -11,7 +12,7 @@ const workspace: ManifestWorkspace = { name: 'User Workspace', loader: () => import('./user-workspace.element.js'), meta: { - entityType: 'user', + entityType: USER_ENTITY_TYPE, }, }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/workspace/user-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/workspace/user-workspace.context.ts index e13e5466da..65a4cf5c06 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/workspace/user-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/workspace/user-workspace.context.ts @@ -1,5 +1,5 @@ import { UmbUserRepository } from '../repository/user.repository.js'; -import { type UmbUserDetail } from '../index.js'; +import { USER_ENTITY_TYPE, type UmbUserDetail } from '../index.js'; import { UmbSaveableWorkspaceContextInterface, UmbWorkspaceContext } from '@umbraco-cms/backoffice/workspace'; import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; import type { UpdateUserRequestModel } from '@umbraco-cms/backoffice/backend-api'; @@ -50,7 +50,7 @@ export class UmbUserWorkspaceContext } getEntityType(): string { - return 'user'; + return USER_ENTITY_TYPE; } getData() { @@ -97,4 +97,7 @@ export class UmbUserWorkspaceContext export const UMB_USER_WORKSPACE_CONTEXT = new UmbContextToken< UmbSaveableWorkspaceContextInterface, UmbUserWorkspaceContext ->('UmbWorkspaceContext', (context): context is UmbUserWorkspaceContext => context.getEntityType?.() === 'user'); +>( + 'UmbWorkspaceContext', + (context): context is UmbUserWorkspaceContext => context.getEntityType?.() === USER_ENTITY_TYPE, +);