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 index 5c3f761fec..2e9266a82d 100644 --- 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 @@ -1,39 +1,27 @@ import { UmbUserCollectionFilterModel } from '../../types.js'; -import { UMB_USER_STORE_CONTEXT_TOKEN, UmbUserStore } from '../../repository/user.store.js'; +import { UmbUserRepositoryBase } from '../../repository/user-repository-base.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; +export class UmbUserCollectionRepository extends UmbUserRepositoryBase implements UmbCollectionRepository { #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(), - ]); + super(host); + this.#collectionSource = new UmbUserCollectionServerDataSource(this.host); } async requestCollection(filter: UmbUserCollectionFilterModel = { skip: 0, take: 100 }) { - await this.#init; + await this.init; const { data, error } = await this.#collectionSource.filterCollection(filter); if (data) { - this.#detailStore?.appendItems(data.items); + this.detailStore!.appendItems(data.items); } - return { data, error, asObservable: () => this.#detailStore!.all() }; + return { data, error, asObservable: () => this.detailStore!.all() }; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/change-password/change-user-password.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/change-password/change-user-password.repository.ts index d51923d9a0..4a96e2c2c6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/change-password/change-user-password.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/change-password/change-user-password.repository.ts @@ -1,30 +1,21 @@ +import { UmbUserRepositoryBase } from '../user-repository-base.js'; import { UmbChangeUserPasswordServerDataSource } from './change-user-password.server.data.js'; -import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; -import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; -import { UMB_NOTIFICATION_CONTEXT_TOKEN, UmbNotificationContext } from '@umbraco-cms/backoffice/notification'; - -export class UmbChangeUserPasswordRepository { - #host: UmbControllerHostElement; - #init!: Promise; +import { type UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; +import { UmbNotificationContext } from '@umbraco-cms/backoffice/notification'; +export class UmbChangeUserPasswordRepository extends UmbUserRepositoryBase { #changePasswordSource: UmbChangeUserPasswordServerDataSource; #notificationContext?: UmbNotificationContext; constructor(host: UmbControllerHostElement) { - this.#host = host; - this.#changePasswordSource = new UmbChangeUserPasswordServerDataSource(this.#host); - - this.#init = Promise.all([ - new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => { - this.#notificationContext = instance; - }).asPromise(), - ]); + super(host); + this.#changePasswordSource = new UmbChangeUserPasswordServerDataSource(this.host); } async changePassword(userId: string, newPassword: string) { if (!userId) throw new Error('User id is missing'); if (!newPassword) throw new Error('New password is missing'); - await this.#init; + await this.init; const { data, error } = await this.#changePasswordSource.changePassword(userId, newPassword); diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/disable/disable-user.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/disable/disable-user.repository.ts index f5f49e9fe4..37d50fece9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/disable/disable-user.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/disable/disable-user.repository.ts @@ -1,47 +1,29 @@ -import { UMB_USER_STORE_CONTEXT_TOKEN, UmbUserStore } from '../user.store.js'; -import { UMB_USER_ITEM_STORE_CONTEXT_TOKEN, UmbUserItemStore } from '../user-item.store.js'; +import { UmbUserRepositoryBase } from '../user-repository-base.js'; import { UmbDisableUserServerDataSource } from './disable-user.server.data.js'; import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; -import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; -import { UMB_NOTIFICATION_CONTEXT_TOKEN, UmbNotificationContext } from '@umbraco-cms/backoffice/notification'; import { UserStateModel } from '@umbraco-cms/backoffice/backend-api'; -export class UmbDisableUserRepository { - #host: UmbControllerHostElement; - #init; - +export class UmbDisableUserRepository extends UmbUserRepositoryBase { #disableSource: UmbDisableUserServerDataSource; - #notificationContext?: UmbNotificationContext; - #detailStore?: UmbUserStore; constructor(host: UmbControllerHostElement) { - this.#host = host; - this.#disableSource = new UmbDisableUserServerDataSource(this.#host); - - this.#init = Promise.all([ - new UmbContextConsumerController(this.#host, UMB_USER_STORE_CONTEXT_TOKEN, (instance) => { - this.#detailStore = instance; - }).asPromise(), - - new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => { - this.#notificationContext = instance; - }).asPromise(), - ]); + super(host); + this.#disableSource = new UmbDisableUserServerDataSource(this.host); } async disable(ids: Array) { if (ids.length === 0) throw new Error('User ids are missing'); - await this.#init; + await this.init; const { data, error } = await this.#disableSource.disable(ids); if (!error) { ids.forEach((id) => { - this.#detailStore?.updateItem(id, { state: UserStateModel.DISABLED }); + this.detailStore?.updateItem(id, { state: UserStateModel.DISABLED }); }); const notification = { data: { message: `User disabled` } }; - this.#notificationContext?.peek('positive', notification); + this.notificationContext?.peek('positive', notification); } return { data, error }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/enable/enable-user.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/enable/enable-user.repository.ts index fedbb29cac..d78f39eccb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/enable/enable-user.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/enable/enable-user.repository.ts @@ -1,46 +1,29 @@ -import { UMB_USER_STORE_CONTEXT_TOKEN, type UmbUserStore } from '../user.store.js'; +import { UmbUserRepositoryBase } from '../user-repository-base.js'; import { UmbEnableUserServerDataSource } from './enable-user.server.data.js'; import { type UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; -import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; import { UserStateModel } from '@umbraco-cms/backoffice/backend-api'; -import { UMB_NOTIFICATION_CONTEXT_TOKEN, UmbNotificationContext } from '@umbraco-cms/backoffice/notification'; - -export class UmbEnableUserRepository { - #host: UmbControllerHostElement; - #init; +export class UmbEnableUserRepository extends UmbUserRepositoryBase { #enableSource: UmbEnableUserServerDataSource; - #detailStore?: UmbUserStore; - #notificationContext?: UmbNotificationContext; constructor(host: UmbControllerHostElement) { - this.#host = host; - this.#enableSource = new UmbEnableUserServerDataSource(this.#host); - - this.#init = Promise.all([ - new UmbContextConsumerController(this.#host, UMB_USER_STORE_CONTEXT_TOKEN, (instance) => { - this.#detailStore = instance; - }).asPromise(), - - new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => { - this.#notificationContext = instance; - }).asPromise(), - ]); + super(host); + this.#enableSource = new UmbEnableUserServerDataSource(this.host); } async enable(ids: Array) { if (ids.length === 0) throw new Error('User ids are missing'); - await this.#init; + await this.init; const { data, error } = await this.#enableSource.enable(ids); if (!error) { ids.forEach((id) => { - this.#detailStore?.updateItem(id, { state: UserStateModel.ACTIVE }); + this.detailStore?.updateItem(id, { state: UserStateModel.ACTIVE }); }); const notification = { data: { message: `User disabled` } }; - this.#notificationContext?.peek('positive', notification); + this.notificationContext?.peek('positive', notification); } return { data, error }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/invite/invite-user.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/invite/invite-user.repository.ts index 32cc46c6fc..83733234fc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/invite/invite-user.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/invite/invite-user.repository.ts @@ -1,26 +1,15 @@ +import { UmbUserRepositoryBase } from '../user-repository-base.js'; import { type UmbInviteUserDataSource } from './types.js'; import { UmbInviteUserServerDataSource } from './invite-user.server.data.js'; import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; -import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; -import { UMB_NOTIFICATION_CONTEXT_TOKEN, UmbNotificationContext } from '@umbraco-cms/backoffice/notification'; import { InviteUserRequestModel } from '@umbraco-cms/backoffice/backend-api'; -export class UmbInviteUserRepository { - #host: UmbControllerHostElement; - #init; - +export class UmbInviteUserRepository extends UmbUserRepositoryBase { #inviteSource: UmbInviteUserDataSource; - #notificationContext?: UmbNotificationContext; constructor(host: UmbControllerHostElement) { - this.#host = host; - this.#inviteSource = new UmbInviteUserServerDataSource(this.#host); - - this.#init = Promise.all([ - new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => { - this.#notificationContext = instance; - }).asPromise(), - ]); + super(host); + this.#inviteSource = new UmbInviteUserServerDataSource(this.host); } /** @@ -31,13 +20,13 @@ export class UmbInviteUserRepository { */ async invite(requestModel: InviteUserRequestModel) { if (!requestModel) throw new Error('data is missing'); - await this.#init; + await this.init; const { error } = await this.#inviteSource.invite(requestModel); if (!error) { const notification = { data: { message: `Invite sent to user` } }; - this.#notificationContext?.peek('positive', notification); + this.notificationContext?.peek('positive', notification); } return { error }; @@ -53,13 +42,13 @@ export class UmbInviteUserRepository { async resendInvite(userId: string, requestModel: any) { if (!userId) throw new Error('User id is missing'); if (!requestModel) throw new Error('data is missing'); - await this.#init; + await this.init; const { error } = await this.#inviteSource.resendInvite(userId, requestModel); if (!error) { const notification = { data: { message: `Invite resent to user` } }; - this.#notificationContext?.peek('positive', notification); + this.notificationContext?.peek('positive', notification); } return { error }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/unlock/unlock-user.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/unlock/unlock-user.repository.ts index 4477f30f8e..e161ab5590 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/unlock/unlock-user.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/unlock/unlock-user.repository.ts @@ -1,46 +1,29 @@ -import { UMB_USER_STORE_CONTEXT_TOKEN, type UmbUserStore } from '../user.store.js'; +import { UmbUserRepositoryBase } from '../user-repository-base.js'; import { UmbUnlockUserServerDataSource } from './unlock-user.server.data.js'; import { type UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; -import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; import { UserStateModel } from '@umbraco-cms/backoffice/backend-api'; -import { UMB_NOTIFICATION_CONTEXT_TOKEN, UmbNotificationContext } from '@umbraco-cms/backoffice/notification'; - -export class UmbUnlockUserRepository { - #host: UmbControllerHostElement; - #init; +export class UmbUnlockUserRepository extends UmbUserRepositoryBase { #source: UmbUnlockUserServerDataSource; - #detailStore?: UmbUserStore; - #notificationContext?: UmbNotificationContext; constructor(host: UmbControllerHostElement) { - this.#host = host; - this.#source = new UmbUnlockUserServerDataSource(this.#host); - - this.#init = Promise.all([ - new UmbContextConsumerController(this.#host, UMB_USER_STORE_CONTEXT_TOKEN, (instance) => { - this.#detailStore = instance; - }).asPromise(), - - new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => { - this.#notificationContext = instance; - }).asPromise(), - ]); + super(host); + this.#source = new UmbUnlockUserServerDataSource(this.host); } async unlock(ids: Array) { if (ids.length === 0) throw new Error('User ids are missing'); - await this.#init; + await this.init; const { data, error } = await this.#source.unlock(ids); if (!error) { ids.forEach((id) => { - this.#detailStore?.updateItem(id, { state: UserStateModel.ACTIVE, failedPasswordAttempts: 0 }); + this.detailStore?.updateItem(id, { state: UserStateModel.ACTIVE, failedPasswordAttempts: 0 }); }); const notification = { data: { message: `User unlocked` } }; - this.#notificationContext?.peek('positive', notification); + this.notificationContext?.peek('positive', notification); } return { data, error }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/user-repository-base.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/user-repository-base.ts new file mode 100644 index 0000000000..fb3f67e4df --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/user-repository-base.ts @@ -0,0 +1,32 @@ +import { UMB_USER_STORE_CONTEXT_TOKEN, UmbUserStore } from './user.store.js'; +import { UMB_USER_ITEM_STORE_CONTEXT_TOKEN, UmbUserItemStore } from './user-item.store.js'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { UMB_NOTIFICATION_CONTEXT_TOKEN, UmbNotificationContext } from '@umbraco-cms/backoffice/notification'; + +export class UmbUserRepositoryBase { + protected host; + protected init; + + protected detailStore?: UmbUserStore; + protected itemStore?: UmbUserItemStore; + protected notificationContext?: UmbNotificationContext; + + constructor(host: UmbControllerHostElement) { + this.host = host; + + this.init = Promise.all([ + new UmbContextConsumerController(this.host, UMB_USER_STORE_CONTEXT_TOKEN, (instance) => { + this.detailStore = instance; + }).asPromise(), + + new UmbContextConsumerController(this.host, UMB_USER_ITEM_STORE_CONTEXT_TOKEN, (instance) => { + this.itemStore = instance; + }).asPromise(), + + new UmbContextConsumerController(this.host, UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => { + this.notificationContext = instance; + }).asPromise(), + ]); + } +} 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 a1e0ea06d4..9a0e212b25 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,10 +1,10 @@ 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 { UmbUserItemServerDataSource } from './sources/user-item.server.data.js'; -import { UMB_USER_ITEM_STORE_CONTEXT_TOKEN, UmbUserItemStore } from './user-item.store.js'; +import { UmbUserItemStore } from './user-item.store.js'; import { UmbUserSetGroupsServerDataSource } from './sources/user-set-group.server.data.js'; +import { UmbUserRepositoryBase } from './user-repository-base.js'; import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; import { UmbDetailRepository, UmbItemDataSource, UmbItemRepository } from '@umbraco-cms/backoffice/repository'; import { @@ -14,8 +14,7 @@ import { UserItemResponseModel, UserResponseModel, } from '@umbraco-cms/backoffice/backend-api'; -import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; -import { UMB_NOTIFICATION_CONTEXT_TOKEN, UmbNotificationContext } from '@umbraco-cms/backoffice/notification'; +import { UmbNotificationContext } from '@umbraco-cms/backoffice/notification'; export type UmbUserDetailRepository = UmbDetailRepository< CreateUserRequestModel, @@ -24,12 +23,11 @@ export type UmbUserDetailRepository = UmbDetailRepository< UserResponseModel >; -export class UmbUserRepository implements UmbUserDetailRepository, UmbItemRepository { - #host: UmbControllerHostElement; - #init; - +export class UmbUserRepository + extends UmbUserRepositoryBase + implements UmbUserDetailRepository, UmbItemRepository +{ #detailSource: UmbUserDetailDataSource; - #detailStore?: UmbUserStore; #itemSource: UmbItemDataSource; #itemStore?: UmbUserItemStore; #setUserGroupsSource: UmbUserSetGroupDataSource; @@ -37,31 +35,17 @@ export class UmbUserRepository implements UmbUserDetailRepository, UmbItemReposi #notificationContext?: UmbNotificationContext; constructor(host: UmbControllerHostElement) { - this.#host = host; + super(host); - this.#detailSource = new UmbUserServerDataSource(this.#host); - this.#itemSource = new UmbUserItemServerDataSource(this.#host); - this.#setUserGroupsSource = new UmbUserSetGroupsServerDataSource(this.#host); - - this.#init = Promise.all([ - new UmbContextConsumerController(this.#host, UMB_USER_STORE_CONTEXT_TOKEN, (instance) => { - this.#detailStore = instance; - }).asPromise(), - - new UmbContextConsumerController(this.#host, UMB_USER_ITEM_STORE_CONTEXT_TOKEN, (instance) => { - this.#itemStore = instance; - }).asPromise(), - - new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => { - this.#notificationContext = instance; - }).asPromise(), - ]); + this.#detailSource = new UmbUserServerDataSource(this.host); + this.#itemSource = new UmbUserItemServerDataSource(this.host); + this.#setUserGroupsSource = new UmbUserSetGroupsServerDataSource(this.host); } // ITEMS: async requestItems(ids: Array) { if (!ids) throw new Error('Ids are missing'); - await this.#init; + await this.init; const { data, error } = await this.#itemSource.getItems(ids); @@ -73,7 +57,7 @@ export class UmbUserRepository implements UmbUserDetailRepository, UmbItemReposi } async items(ids: Array) { - await this.#init; + await this.init; return this.#itemStore!.items(ids); } @@ -85,15 +69,15 @@ export class UmbUserRepository implements UmbUserDetailRepository, UmbItemReposi async requestById(id: string) { if (!id) throw new Error('Id is missing'); - await this.#init; + await this.init; const { data, error } = await this.#detailSource.get(id); if (data) { - this.#detailStore!.append(data); + this.detailStore!.append(data); } - return { data, error, asObservable: () => this.#detailStore!.byId(id) }; + return { data, error, asObservable: () => this.detailStore!.byId(id) }; } async setUserGroups(userIds: Array, userGroupIds: Array) { @@ -111,8 +95,8 @@ export class UmbUserRepository implements UmbUserDetailRepository, UmbItemReposi async byId(id: string) { if (!id) throw new Error('Key is missing'); - await this.#init; - return this.#detailStore!.byId(id); + await this.init; + return this.detailStore!.byId(id); } async create(userRequestData: CreateUserRequestModel) { @@ -121,7 +105,7 @@ export class UmbUserRepository implements UmbUserDetailRepository, UmbItemReposi const { data, error } = await this.#detailSource.insert(userRequestData); if (data) { - this.#detailStore?.append(data); + this.detailStore?.append(data); const notification = { data: { message: `User created` } }; this.#notificationContext?.peek('positive', notification); @@ -137,12 +121,12 @@ export class UmbUserRepository implements UmbUserDetailRepository, UmbItemReposi const { data, error } = await this.#detailSource.update(id, user); if (data) { - this.#detailStore?.append(data); + this.detailStore?.append(data); } if (!error) { const notification = { - data: { message: this.#host.localize?.term('speechBubbles_editUserSaved') ?? 'User saved' }, + data: { message: this.host.localize?.term('speechBubbles_editUserSaved') ?? 'User saved' }, }; this.#notificationContext?.peek('positive', notification); } @@ -156,7 +140,7 @@ export class UmbUserRepository implements UmbUserDetailRepository, UmbItemReposi const { error } = await this.#detailSource.delete(id); if (!error) { - this.#detailStore?.removeItem(id); + this.detailStore?.removeItem(id); const notification = { data: { message: `User deleted` } }; this.#notificationContext?.peek('positive', notification);