Merge branch 'main' into feature/document-type-workspace-take-5

This commit is contained in:
Niels Lyngsø
2023-05-23 10:33:33 +02:00
committed by GitHub
13 changed files with 211 additions and 52 deletions

View File

@@ -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';

View File

@@ -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<UserStateModel> = Object.values(UserStateModel);

View File

@@ -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<UmbUserRepository> {
#modalContext?: UmbModalContext;
@@ -16,7 +17,22 @@ export class UmbUserDeleteEntityBulkAction extends UmbEntityBulkActionBase<UmbUs
}
async execute() {
//TODO: we need bulk actions on the server
alert('Bulk delete is not implemented yet');
if (!this.#modalContext || this.selection.length === 0) return;
const modalHandler = this.#modalContext.open(UMB_CONFIRM_MODAL, {
color: 'danger',
headline: `Delete users?`,
content: html`Are you sure you want to delete selected users?`,
confirmLabel: 'Delete',
});
await modalHandler.onSubmit();
//TODO: How should we handle bulk actions? right now we send a request per item we want to change.
//TODO: For now we have to reload the page to see the update
for (let index = 0; index < this.selection.length; index++) {
const element = this.selection[index];
await this.repository?.delete(element);
}
}
}

View File

@@ -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 UmbDisableUserEntityBulkAction extends UmbEntityBulkActionBase<UmbUserRepository> {
constructor(host: UmbControllerHostElement, repositoryAlias: string, selection: Array<string>) {
@@ -8,7 +8,6 @@ export class UmbDisableUserEntityBulkAction extends UmbEntityBulkActionBase<UmbU
}
async execute() {
//TODO: Implement
alert('Bulk disable is not implemented yet');
await this.repository?.disable(this.selection);
}
}

View File

@@ -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 UmbEnableUserEntityBulkAction extends UmbEntityBulkActionBase<UmbUserRepository> {
constructor(host: UmbControllerHostElement, repositoryAlias: string, selection: Array<string>) {
@@ -8,7 +8,6 @@ export class UmbEnableUserEntityBulkAction extends UmbEntityBulkActionBase<UmbUs
}
async execute() {
//TODO: Implement
alert('Bulk enable is not implemented yet');
await this.repository?.enable(this.selection);
}
}

View File

@@ -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<UmbUserRepository> {
constructor(host: UmbControllerHostElement, repositoryAlias: string, selection: Array<string>) {
@@ -8,7 +8,6 @@ export class UmbUnlockUserEntityBulkAction extends UmbEntityBulkActionBase<UmbUs
}
async execute() {
//TODO: Implement
alert('Bulk unlock is not implemented yet');
await this.repository?.unlock(this.selection);
}
}

View File

@@ -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() {

View File

@@ -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<string>} 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,
},
})
);
}
}

View File

@@ -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<string>} 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,
},
})
);
}
}

View File

@@ -0,0 +1,41 @@
import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
import { UmbUserUnlockDataSource } 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 UmbUserUnlockServerDataSource
*/
export class UmbUserUnlockServerDataSource implements UmbUserUnlockDataSource {
#host: UmbControllerHostElement;
/**
* Creates an instance of UmbUserUnlockServerDataSource.
* @param {UmbControllerHostElement} host
* @memberof UmbUserUnlockServerDataSource
*/
constructor(host: UmbControllerHostElement) {
this.#host = host;
}
/**
* unlock users
* @param {Array<string>} 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,
},
})
);
}
}

View File

@@ -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 }));
}
}

View File

@@ -1,3 +1,4 @@
import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
import {
UmbUserCollectionFilterModel,
UmbUserDetailDataSource,
@@ -10,13 +11,15 @@ 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 { UmbUserUnlockServerDataSource } from './sources/user-unlock.server.data';
import {
UmbCollectionDataSource,
UmbCollectionRepository,
UmbItemDataSource,
UmbItemRepository,
} from '@umbraco-cms/backoffice/repository';
import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
import {
CreateUserRequestModel,
InviteUserRequestModel,
@@ -39,6 +42,11 @@ export class UmbUserRepository
#itemStore?: UmbUserItemStore;
#setUserGroupsSource: UmbUserSetGroupDataSource;
//ACTIONS
#enableSource: UmbUserEnableServerDataSource;
#disableSource: UmbUserDisableServerDataSource;
#unlockSource: UmbUserUnlockServerDataSource;
#collectionSource: UmbCollectionDataSource<UserResponseModel>;
#notificationContext?: UmbNotificationContext;
@@ -48,6 +56,9 @@ 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.#unlockSource = new UmbUserUnlockServerDataSource(this.#host);
this.#itemSource = new UmbUserItemServerDataSource(this.#host);
this.#setUserGroupsSource = new UmbUserSetGroupsServerDataSource(this.#host);
@@ -199,12 +210,36 @@ export class UmbUserRepository
async enable(ids: Array<string>) {
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<string>) {
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);
}
}
async unlock(ids: Array<string>) {
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);
}
}
}

View File

@@ -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,14 +29,22 @@ export interface UmbUserCollectionFilterModel {
export interface UmbUserDetailDataSource
extends UmbDataSource<CreateUserRequestModel, CreateUserResponseModel, UpdateUserRequestModel, UserResponseModel> {
invite(data: InviteUserRequestModel): Promise<any>;
enable(data: EnableUserRequestModel): Promise<any>;
disable(data: DisableUserRequestModel): Promise<any>;
}
export interface UmbUserSetGroupDataSource {
setGroups(userIds: string[], userGroupIds: string[]): Promise<UmbDataSourceErrorResponse>;
}
export interface UmbUserDisableDataSource {
disable(userIds: string[]): Promise<UmbDataSourceErrorResponse>;
}
export interface UmbUserEnableDataSource {
enable(userIds: string[]): Promise<UmbDataSourceErrorResponse>;
}
export interface UmbUserUnlockDataSource {
unlock(userIds: string[]): Promise<UmbDataSourceErrorResponse>;
}
export interface UmbUserDetailRepository
extends UmbDetailRepository<
CreateUserRequestModel,