From 534a490328f48bec344fc1d5fcf9c07ebf696ad8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Wed, 17 May 2023 17:31:00 +1200 Subject: [PATCH 1/6] enable and disable bulk actions --- .../delete/delete.action.ts | 2 +- .../user-collection-header.element.ts | 4 ++-- .../delete/delete.action.ts | 24 +++++++++++++++---- .../disable/disable.action.ts | 5 ++-- .../enable/enable.action.ts | 5 ++-- 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/entity-bulk-actions/delete/delete.action.ts b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/entity-bulk-actions/delete/delete.action.ts index 89382d2400..5bf5f5858c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/entity-bulk-actions/delete/delete.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/user-groups/entity-bulk-actions/delete/delete.action.ts @@ -1,7 +1,7 @@ import { html } from 'lit'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; import type { UmbUserGroupRepository } from '../../repository/user-group.repository'; import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-action'; -import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/users/collection/user-collection-header.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/users/collection/user-collection-header.element.ts index ffe7482905..7703246858 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/users/collection/user-collection-header.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/users/collection/user-collection-header.element.ts @@ -2,6 +2,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { UUIBooleanInputEvent, UUICheckboxElement, UUIRadioGroupElement, UUIRadioGroupEvent } from '@umbraco-ui/uui'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import { UmbDropdownElement } from '../../../core/components/dropdown/dropdown.element'; import { UmbUserCollectionContext } from './user-collection.context'; import { UMB_COLLECTION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/collection'; @@ -11,13 +12,12 @@ import { UMB_MODAL_CONTEXT_TOKEN, UmbModalContext, } from '@umbraco-cms/backoffice/modal'; -import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import { UserOrderModel, UserStateModel } from '@umbraco-cms/backoffice/backend-api'; @customElement('umb-user-collection-header') export class UmbUserCollectionHeaderElement extends UmbLitElement { @state() - private _isCloud = true; //NOTE: Used to show either invite or create user buttons and views. + private _isCloud = false; //NOTE: Used to show either invite or create user buttons and views. @state() private _stateFilterOptions: Array = Object.values(UserStateModel); diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/users/entity-bulk-actions/delete/delete.action.ts b/src/Umbraco.Web.UI.Client/src/packages/users/users/entity-bulk-actions/delete/delete.action.ts index c32c90557b..7f931962e3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/users/entity-bulk-actions/delete/delete.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/users/entity-bulk-actions/delete/delete.action.ts @@ -1,8 +1,9 @@ +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; +import { html } from 'lit'; import { UmbUserRepository } from '../../repository/user.repository'; import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-action'; -import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal'; export class UmbUserDeleteEntityBulkAction extends UmbEntityBulkActionBase { #modalContext?: UmbModalContext; @@ -16,7 +17,22 @@ export class UmbUserDeleteEntityBulkAction extends UmbEntityBulkActionBase { constructor(host: UmbControllerHostElement, repositoryAlias: string, selection: Array) { @@ -8,7 +8,6 @@ export class UmbDisableUserEntityBulkAction extends UmbEntityBulkActionBase { constructor(host: UmbControllerHostElement, repositoryAlias: string, selection: Array) { @@ -8,7 +8,6 @@ export class UmbEnableUserEntityBulkAction extends UmbEntityBulkActionBase Date: Wed, 17 May 2023 17:42:32 +1200 Subject: [PATCH 2/6] add enable and disable data sources --- .../sources/user-disable.server.data.ts | 41 +++++++++++++++++++ .../sources/user-enable.server.data.ts | 41 +++++++++++++++++++ .../users/users/repository/user.repository.ts | 2 +- .../src/packages/users/users/types.ts | 7 ++++ 4 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/users/users/repository/sources/user-disable.server.data.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/users/users/repository/sources/user-enable.server.data.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/users/repository/sources/user-disable.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/users/users/repository/sources/user-disable.server.data.ts new file mode 100644 index 0000000000..ec5a749646 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/users/users/repository/sources/user-disable.server.data.ts @@ -0,0 +1,41 @@ +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; +import { UmbUserDisableDataSource } from '../../types'; +import { UserResource } from '@umbraco-cms/backoffice/backend-api'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; + +/** + * A data source for Data Type items that fetches data from the server + * @export + * @class UmbUserDisableServerDataSource + */ +export class UmbUserDisableServerDataSource implements UmbUserDisableDataSource { + #host: UmbControllerHostElement; + + /** + * Creates an instance of UmbUserDisableServerDataSource. + * @param {UmbControllerHostElement} host + * @memberof UmbUserDisableServerDataSource + */ + constructor(host: UmbControllerHostElement) { + this.#host = host; + } + + /** + * Set groups for users + * @param {Array} id + * @return {*} + * @memberof UmbUserDisableServerDataSource + */ + async disable(userIds: string[]) { + if (!userIds) throw new Error('User ids are missing'); + + return tryExecuteAndNotify( + this.#host, + UserResource.postUserDisable({ + requestBody: { + userIds, + }, + }) + ); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/users/repository/sources/user-enable.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/users/users/repository/sources/user-enable.server.data.ts new file mode 100644 index 0000000000..2ef3def21e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/users/users/repository/sources/user-enable.server.data.ts @@ -0,0 +1,41 @@ +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; +import { UmbUserEnableDataSource } from '../../types'; +import { UserResource } from '@umbraco-cms/backoffice/backend-api'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; + +/** + * A data source for Data Type items that fetches data from the server + * @export + * @class UmbUserEnableServerDataSource + */ +export class UmbUserEnableServerDataSource implements UmbUserEnableDataSource { + #host: UmbControllerHostElement; + + /** + * Creates an instance of UmbUserEnableServerDataSource. + * @param {UmbControllerHostElement} host + * @memberof UmbUserEnableServerDataSource + */ + constructor(host: UmbControllerHostElement) { + this.#host = host; + } + + /** + * Set groups for users + * @param {Array} id + * @return {*} + * @memberof UmbUserEnableServerDataSource + */ + async enable(userIds: string[]) { + if (!userIds) throw new Error('User ids are missing'); + + return tryExecuteAndNotify( + this.#host, + UserResource.postUserEnable({ + requestBody: { + userIds, + }, + }) + ); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/users/repository/user.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/users/users/repository/user.repository.ts index 94e6063f7d..4a25d4455b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/users/repository/user.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/users/repository/user.repository.ts @@ -1,3 +1,4 @@ +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; import { UmbUserCollectionFilterModel, UmbUserDetailDataSource, @@ -16,7 +17,6 @@ import { UmbItemDataSource, UmbItemRepository, } from '@umbraco-cms/backoffice/repository'; -import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; import { CreateUserRequestModel, InviteUserRequestModel, diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/users/types.ts b/src/Umbraco.Web.UI.Client/src/packages/users/users/types.ts index 5faf7a45bd..a368dc4039 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/users/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/users/types.ts @@ -44,6 +44,13 @@ export interface UmbUserSetGroupDataSource { setGroups(userIds: string[], userGroupIds: string[]): Promise; } +export interface UmbUserDisableDataSource { + disable(userIds: string[]): Promise; +} +export interface UmbUserEnableDataSource { + enable(userIds: string[]): Promise; +} + export interface UmbUserDetailRepository extends UmbDetailRepository< CreateUserRequestModel, From 9d462e6af6a56bf3147cf05bc3727bb6fbf1ab13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Wed, 17 May 2023 17:52:36 +1200 Subject: [PATCH 3/6] added enable and disable to user repo --- .../users/users/repository/user.repository.ts | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/users/repository/user.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/users/users/repository/user.repository.ts index 4a25d4455b..ab34c28810 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/users/repository/user.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/users/repository/user.repository.ts @@ -11,6 +11,8 @@ import { UmbUserCollectionServerDataSource } from './sources/user-collection.ser import { UmbUserItemServerDataSource } from './sources/user-item.server.data'; import { UMB_USER_ITEM_STORE_CONTEXT_TOKEN, UmbUserItemStore } from './user-item.store'; import { UmbUserSetGroupsServerDataSource } from './sources/user-set-group.server.data'; +import { UmbUserEnableServerDataSource } from './sources/user-enable.server.data'; +import { UmbUserDisableServerDataSource } from './sources/user-disable.server.data'; import { UmbCollectionDataSource, UmbCollectionRepository, @@ -39,6 +41,9 @@ export class UmbUserRepository #itemStore?: UmbUserItemStore; #setUserGroupsSource: UmbUserSetGroupDataSource; + #enableSource: UmbUserEnableServerDataSource; + #disableSource: UmbUserDisableServerDataSource; + #collectionSource: UmbCollectionDataSource; #notificationContext?: UmbNotificationContext; @@ -48,6 +53,8 @@ export class UmbUserRepository this.#detailSource = new UmbUserServerDataSource(this.#host); this.#collectionSource = new UmbUserCollectionServerDataSource(this.#host); + this.#enableSource = new UmbUserEnableServerDataSource(this.#host); + this.#disableSource = new UmbUserDisableServerDataSource(this.#host); this.#itemSource = new UmbUserItemServerDataSource(this.#host); this.#setUserGroupsSource = new UmbUserSetGroupsServerDataSource(this.#host); @@ -199,12 +206,24 @@ export class UmbUserRepository async enable(ids: Array) { if (ids.length === 0) throw new Error('User ids are missing'); - const { data, error } = await this.#detailSource.enable({ userIds: ids }); + const { error } = await this.#enableSource.enable(ids); + + if (!error) { + //TODO: UPDATE STORE + const notification = { data: { message: `${ids.length > 1 ? 'Users' : 'User'} enabled` } }; + this.#notificationContext?.peek('positive', notification); + } } async disable(ids: Array) { if (ids.length === 0) throw new Error('User ids are missing'); - const { data, error } = await this.#detailSource.disable({ userIds: ids }); + const { error } = await this.#disableSource.disable(ids); + + if (!error) { + //TODO: UPDATE STORE + const notification = { data: { message: `${ids.length > 1 ? 'Users' : 'User'} disabled` } }; + this.#notificationContext?.peek('positive', notification); + } } } From 4923e05380d4f65beac6c93b298d729fcaa176a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Wed, 17 May 2023 17:57:38 +1200 Subject: [PATCH 4/6] remove enable and disable from detail source --- .../users/repository/sources/user.server.data.ts | 12 ------------ .../src/packages/users/users/types.ts | 11 +---------- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/users/repository/sources/user.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/users/users/repository/sources/user.server.data.ts index 4e5cbba292..d5b5c8b87f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/users/repository/sources/user.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/users/repository/sources/user.server.data.ts @@ -66,16 +66,4 @@ export class UmbUserServerDataSource implements UmbUserDetailDataSource { if (!data) throw new Error('Invite data is missing'); return tryExecuteAndNotify(this.#host, UserResource.postUserInvite({ requestBody: data })); } - - // Enable - enable(data: EnableUserRequestModel) { - if (!data) throw new Error('enable data is missing'); - return tryExecuteAndNotify(this.#host, UserResource.postUserEnable({ requestBody: data })); - } - - // Disable - disable(data: DisableUserRequestModel) { - if (!data) throw new Error('disable data is missing'); - return tryExecuteAndNotify(this.#host, UserResource.postUserDisable({ requestBody: data })); - } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/users/types.ts b/src/Umbraco.Web.UI.Client/src/packages/users/users/types.ts index a368dc4039..79119afdd5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/users/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/users/types.ts @@ -2,8 +2,6 @@ import type { CreateUserRequestModel, CreateUserResponseModel, DirectionModel, - DisableUserRequestModel, - EnableUserRequestModel, InviteUserRequestModel, UpdateUserRequestModel, UserOrderModel, @@ -11,12 +9,7 @@ import type { UserStateModel, } from '@umbraco-cms/backoffice/backend-api'; -import { - DataSourceResponse, - UmbDataSource, - UmbDataSourceErrorResponse, - UmbDetailRepository, -} from '@umbraco-cms/backoffice/repository'; +import { UmbDataSource, UmbDataSourceErrorResponse, UmbDetailRepository } from '@umbraco-cms/backoffice/repository'; export interface UmbCreateUserResponseModel { user: UserResponseModel; @@ -36,8 +29,6 @@ export interface UmbUserCollectionFilterModel { export interface UmbUserDetailDataSource extends UmbDataSource { invite(data: InviteUserRequestModel): Promise; - enable(data: EnableUserRequestModel): Promise; - disable(data: DisableUserRequestModel): Promise; } export interface UmbUserSetGroupDataSource { From 2cb853acac58e1cdc240525adbbdadc37e77222e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Wed, 17 May 2023 18:04:25 +1200 Subject: [PATCH 5/6] added unlock action --- .../unlock/unlock.action.ts | 5 +-- .../sources/user-unlock.server.data.ts | 41 +++++++++++++++++++ .../users/users/repository/user.repository.ts | 16 ++++++++ .../src/packages/users/users/types.ts | 3 ++ 4 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/users/users/repository/sources/user-unlock.server.data.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/users/entity-bulk-actions/unlock/unlock.action.ts b/src/Umbraco.Web.UI.Client/src/packages/users/users/entity-bulk-actions/unlock/unlock.action.ts index 114e8924e5..27fe636138 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/users/entity-bulk-actions/unlock/unlock.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/users/entity-bulk-actions/unlock/unlock.action.ts @@ -1,6 +1,6 @@ +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; import { UmbUserRepository } from '../../repository/user.repository'; import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-action'; -import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; export class UmbUnlockUserEntityBulkAction extends UmbEntityBulkActionBase { constructor(host: UmbControllerHostElement, repositoryAlias: string, selection: Array) { @@ -8,7 +8,6 @@ export class UmbUnlockUserEntityBulkAction extends UmbEntityBulkActionBase} id + * @return {*} + * @memberof UmbUserUnlockServerDataSource + */ + async unlock(userIds: string[]) { + if (!userIds) throw new Error('User ids are missing'); + + return tryExecuteAndNotify( + this.#host, + UserResource.postUserUnlock({ + requestBody: { + userIds, + }, + }) + ); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/users/repository/user.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/users/users/repository/user.repository.ts index ab34c28810..6875089fe2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/users/repository/user.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/users/repository/user.repository.ts @@ -13,6 +13,7 @@ import { UMB_USER_ITEM_STORE_CONTEXT_TOKEN, UmbUserItemStore } from './user-item import { UmbUserSetGroupsServerDataSource } from './sources/user-set-group.server.data'; import { UmbUserEnableServerDataSource } from './sources/user-enable.server.data'; import { UmbUserDisableServerDataSource } from './sources/user-disable.server.data'; +import { UmbUserUnlockServerDataSource } from './sources/user-unlock.server.data'; import { UmbCollectionDataSource, UmbCollectionRepository, @@ -41,8 +42,10 @@ export class UmbUserRepository #itemStore?: UmbUserItemStore; #setUserGroupsSource: UmbUserSetGroupDataSource; + //ACTIONS #enableSource: UmbUserEnableServerDataSource; #disableSource: UmbUserDisableServerDataSource; + #unlockSource: UmbUserUnlockServerDataSource; #collectionSource: UmbCollectionDataSource; @@ -55,6 +58,7 @@ export class UmbUserRepository this.#collectionSource = new UmbUserCollectionServerDataSource(this.#host); this.#enableSource = new UmbUserEnableServerDataSource(this.#host); this.#disableSource = new UmbUserDisableServerDataSource(this.#host); + this.#unlockSource = new UmbUserUnlockServerDataSource(this.#host); this.#itemSource = new UmbUserItemServerDataSource(this.#host); this.#setUserGroupsSource = new UmbUserSetGroupsServerDataSource(this.#host); @@ -226,4 +230,16 @@ export class UmbUserRepository this.#notificationContext?.peek('positive', notification); } } + + async unlock(ids: Array) { + if (ids.length === 0) throw new Error('User ids are missing'); + + const { error } = await this.#unlockSource.unlock(ids); + + if (!error) { + //TODO: UPDATE STORE + const notification = { data: { message: `${ids.length > 1 ? 'Users' : 'User'} unlocked` } }; + this.#notificationContext?.peek('positive', notification); + } + } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/users/types.ts b/src/Umbraco.Web.UI.Client/src/packages/users/users/types.ts index 79119afdd5..e52348d32c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/users/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/users/types.ts @@ -41,6 +41,9 @@ export interface UmbUserDisableDataSource { export interface UmbUserEnableDataSource { enable(userIds: string[]): Promise; } +export interface UmbUserUnlockDataSource { + unlock(userIds: string[]): Promise; +} export interface UmbUserDetailRepository extends UmbDetailRepository< From aab3078045cb2441d6edc2bfd047f1ab8fb46195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Wed, 17 May 2023 18:20:45 +1200 Subject: [PATCH 6/6] uncomment invite call --- .../invite/user-invite-modal.element.ts | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/users/users/modals/invite/user-invite-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/users/users/modals/invite/user-invite-modal.element.ts index 47fd7c568e..464e6e8a24 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/users/users/modals/invite/user-invite-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/users/users/modals/invite/user-invite-modal.element.ts @@ -40,18 +40,17 @@ export class UmbUserInviteModalElement extends UmbModalBaseElement { // TODO: figure out when to use email or username // TODO: invite request gives 500 error. - alert('Implement invite'); - // const { data } = await this.#userRepository.invite({ - // name, - // email, - // userName: email, - // message, - // userGroupIds, - // }); + const { data } = await this.#userRepository.invite({ + name, + email, + userName: email, + message, + userGroupIds, + }); - // if (data) { - // this._invitedUser = data; - // } + if (data) { + this._invitedUser = data; + } } private _submitForm() {