Merge branch 'main' into bugfix/content-type-designer-tab-sort-order

This commit is contained in:
Niels Lyngsø
2024-05-03 10:06:14 +02:00
committed by GitHub
31 changed files with 440 additions and 189 deletions

View File

@@ -113,7 +113,7 @@ export type CopyMediaTypeRequestModel = {
export type CreateDataTypeRequestModel = {
name: string
editorAlias: string
editorUiAlias?: string | null
editorUiAlias: string
values: Array<DataTypePropertyPresentationModel>
id?: string | null
parent?: ReferenceByIdModel | null
@@ -333,6 +333,7 @@ stylesheets: Array<string>
scripts: Array<string>
languages: Array<string>
dictionaryItems: Array<string>
id?: string | null
};
export type CreatePartialViewFolderRequestModel = {
@@ -436,7 +437,9 @@ userName: string
name: string
languageIsoCode?: string | null
documentStartNodeIds: Array<string>
hasDocumentRootAccess: boolean
mediaStartNodeIds: Array<string>
hasMediaRootAccess: boolean
avatarUrls: Array<string>
languages: Array<string>
hasAccessToAllLanguages: boolean
@@ -479,7 +482,7 @@ properties: Array<DataTypePropertyReferenceModel>
export type DataTypeResponseModel = {
name: string
editorAlias: string
editorUiAlias?: string | null
editorUiAlias: string
values: Array<DataTypePropertyPresentationModel>
id: string
isDeletable: boolean
@@ -1811,6 +1814,11 @@ export type PagedUserResponseModel = {
items: Array<UserResponseModel>
};
export type PagedWebhookEventModel = {
total: number
items: Array<WebhookEventModel>
};
export type PagedWebhookResponseModel = {
total: number
items: Array<WebhookResponseModel>
@@ -2263,7 +2271,7 @@ export type UnpublishDocumentRequestModel = {
export type UpdateDataTypeRequestModel = {
name: string
editorAlias: string
editorUiAlias?: string | null
editorUiAlias: string
values: Array<DataTypePropertyPresentationModel>
};
@@ -2512,7 +2520,9 @@ name: string
userGroupIds: Array<string>
languageIsoCode: string
documentStartNodeIds: Array<string>
hasDocumentRootAccess: boolean
mediaStartNodeIds: Array<string>
hasMediaRootAccess: boolean
};
export type UpdateWebhookRequestModel = {
@@ -2621,7 +2631,9 @@ userGroupIds: Array<string>
id: string
languageIsoCode?: string | null
documentStartNodeIds: Array<string>
hasDocumentRootAccess: boolean
mediaStartNodeIds: Array<string>
hasMediaRootAccess: boolean
avatarUrls: Array<string>
state: UserStateModel
failedLoginAttempts: number
@@ -2676,6 +2688,12 @@ export type VerifyResetPasswordTokenRequestModel = {
resetCode: string
};
export type WebhookEventModel = {
eventName: string
eventType: string
alias: string
};
export type WebhookEventResponseModel = {
eventName: string
eventType: string
@@ -5221,6 +5239,11 @@ requestBody?: UpdateWebhookRequestModel
DeleteWebhookById: {
id: string
};
GetWebhookEvents: {
skip?: number
take?: number
};
}
@@ -5232,6 +5255,7 @@ DeleteWebhookById: {
,GetWebhookById: WebhookResponseModel
,PutWebhookById: string
,DeleteWebhookById: string
,GetWebhookEvents: PagedWebhookEventModel
}

View File

@@ -9071,4 +9071,26 @@ requestBody
});
}
/**
* @returns unknown Success
* @throws ApiError
*/
public static getWebhookEvents(data: WebhookData['payloads']['GetWebhookEvents'] = {}): CancelablePromise<WebhookData['responses']['GetWebhookEvents']> {
const {
skip,
take
} = data;
return __request(OpenAPI, {
method: 'GET',
url: '/umbraco/management/api/v1/webhook/events',
query: {
skip, take
},
errors: {
401: `The resource is protected and requires an authentication token`,
},
});
}
}

View File

@@ -14,6 +14,7 @@ export const data: Array<UmbMockDataTypeModel> = [
isFolder: true,
hasChildren: false,
editorAlias: '',
editorUiAlias: '',
values: [],
isDeletable: true,
canIgnoreStartNodes: false,
@@ -25,6 +26,7 @@ export const data: Array<UmbMockDataTypeModel> = [
isFolder: true,
hasChildren: true,
editorAlias: '',
editorUiAlias: '',
values: [],
isDeletable: true,
canIgnoreStartNodes: false,
@@ -308,6 +310,7 @@ export const data: Array<UmbMockDataTypeModel> = [
id: 'dt-datePicker-time',
parent: null,
editorAlias: 'Umbraco.DateTime',
editorUiAlias: 'Umb.PropertyEditorUi.DatePicker',
hasChildren: false,
isFolder: false,
isDeletable: true,

View File

@@ -44,6 +44,7 @@ const createFolderMockMapper = (request: CreateFolderRequestModel): UmbMockDataT
isFolder: true,
hasChildren: false,
editorAlias: '',
editorUiAlias: '',
isDeletable: true,
canIgnoreStartNodes: false,
values: [],

View File

@@ -11,7 +11,9 @@ export const data: Array<UmbMockUserModel> = [
{
id: 'bca6c733-a63d-4353-a271-9a8b6bcca8bd',
documentStartNodeIds: [],
hasDocumentRootAccess: true,
mediaStartNodeIds: [],
hasMediaRootAccess: true,
name: 'Umbraco User',
email: 'noreply@umbraco.com',
languageIsoCode: 'en-us',
@@ -30,7 +32,9 @@ export const data: Array<UmbMockUserModel> = [
{
id: '82e11d3d-b91d-43c9-9071-34d28e62e81d',
documentStartNodeIds: ['simple-document-id'],
hasDocumentRootAccess: true,
mediaStartNodeIds: ['f2f81a40-c989-4b6b-84e2-057cecd3adc1'],
hasMediaRootAccess: true,
name: 'Amelie Walker',
email: 'awalker1@domain.com',
languageIsoCode: 'da-dk',
@@ -50,6 +54,8 @@ export const data: Array<UmbMockUserModel> = [
id: 'aa1d83a9-bc7f-47d2-b288-58d8a31f5017',
documentStartNodeIds: [],
mediaStartNodeIds: [],
hasDocumentRootAccess: true,
hasMediaRootAccess: true,
name: 'Oliver Kim',
email: 'okim1@domain.com',
languageIsoCode: 'da-dk',
@@ -69,6 +75,8 @@ export const data: Array<UmbMockUserModel> = [
id: 'ff2f4a50-d3d4-4bc4-869d-c7948c160e54',
documentStartNodeIds: [],
mediaStartNodeIds: [],
hasDocumentRootAccess: true,
hasMediaRootAccess: true,
name: 'Eliana Nieves',
email: 'enieves1@domain.com',
languageIsoCode: 'en-us',
@@ -88,6 +96,8 @@ export const data: Array<UmbMockUserModel> = [
id: 'c290c6d9-9f12-4838-8567-621b52a178de',
documentStartNodeIds: [],
mediaStartNodeIds: [],
hasDocumentRootAccess: true,
hasMediaRootAccess: true,
name: 'Jasmine Patel',
email: 'jpatel1@domain.com',
languageIsoCode: 'en-us',

View File

@@ -68,6 +68,8 @@ class UmbUserMockDB extends UmbEntityMockDbBase<UmbMockUserModel> {
languages: [],
documentStartNodeIds: firstUser.documentStartNodeIds,
mediaStartNodeIds: firstUser.mediaStartNodeIds,
hasDocumentRootAccess: firstUser.hasDocumentRootAccess,
hasMediaRootAccess: firstUser.hasMediaRootAccess,
fallbackPermissions: [],
permissions,
allowedSections,
@@ -197,6 +199,8 @@ const createMockMapper = (item: CreateUserRequestModel): UmbMockUserModel => {
languageIsoCode: null,
documentStartNodeIds: [],
mediaStartNodeIds: [],
hasDocumentRootAccess: false,
hasMediaRootAccess: false,
avatarUrls: [],
state: UserStateModel.INACTIVE,
failedLoginAttempts: 0,
@@ -219,6 +223,8 @@ const detailResponseMapper = (item: UmbMockUserModel): UserResponseModel => {
languageIsoCode: item.languageIsoCode,
documentStartNodeIds: item.documentStartNodeIds,
mediaStartNodeIds: item.mediaStartNodeIds,
hasDocumentRootAccess: item.hasDocumentRootAccess,
hasMediaRootAccess: item.hasMediaRootAccess,
avatarUrls: item.avatarUrls,
state: item.state,
failedLoginAttempts: item.failedLoginAttempts,

View File

@@ -2,7 +2,10 @@ import type { UmbBlockGridTypeColumnSpanOption } from '../../types.js';
import { html, customElement, property, css, state, repeat } from '@umbraco-cms/backoffice/external/lit';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
import {
UmbPropertyValueChangeEvent,
type UmbPropertyEditorConfigCollection,
} from '@umbraco-cms/backoffice/property-editor';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
@customElement('umb-property-editor-ui-block-grid-column-span')
@@ -30,7 +33,7 @@ export class UmbPropertyEditorUIBlockGridColumnSpanElement extends UmbLitElement
this.value = [...value, { columnSpan: index }];
}
this.dispatchEvent(new CustomEvent('property-value-change'));
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
render() {

View File

@@ -1,7 +1,10 @@
import { html, customElement, property, css } from '@umbraco-cms/backoffice/external/lit';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
import {
UmbPropertyValueChangeEvent,
type UmbPropertyEditorConfigCollection,
} from '@umbraco-cms/backoffice/property-editor';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { UmbId } from '@umbraco-cms/backoffice/id';
import type { UmbBlockGridTypeGroupType } from '@umbraco-cms/backoffice/block-grid';
@@ -25,7 +28,7 @@ export class UmbPropertyEditorUIBlockGridGroupConfigurationElement
#addGroup() {
this.value = [...this._value, { name: 'Unnamed group', key: UmbId.new() }];
this.dispatchEvent(new CustomEvent('property-value-change'));
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
render() {

View File

@@ -6,7 +6,10 @@ import '@umbraco-cms/backoffice/static-file';
import { html, customElement, property } from '@umbraco-cms/backoffice/external/lit';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
import {
UmbPropertyValueChangeEvent,
type UmbPropertyEditorConfigCollection,
} from '@umbraco-cms/backoffice/property-editor';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
@customElement('umb-property-editor-ui-block-grid-layout-stylesheet')
@@ -29,7 +32,7 @@ export class UmbPropertyEditorUIBlockGridLayoutStylesheetElement
private _onChange(event: CustomEvent) {
this.value = (event.target as UmbInputStaticFileElement).selection;
this.dispatchEvent(new CustomEvent('property-value-change'));
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
// TODO: Implement mandatory?

View File

@@ -86,6 +86,7 @@ export class UmbDataTypeServerDataSource implements UmbDetailDataSource<UmbDataT
if (!model) throw new Error('Data Type is missing');
if (!model.unique) throw new Error('Data Type unique is missing');
if (!model.editorAlias) throw new Error('Property Editor Alias is missing');
if (!model.editorUiAlias) throw new Error('Property Editor UI Alias is missing');
// TODO: make data mapper to prevent errors
const requestBody: CreateDataTypeRequestModel = {
@@ -120,6 +121,7 @@ export class UmbDataTypeServerDataSource implements UmbDetailDataSource<UmbDataT
async update(model: UmbDataTypeDetailModel) {
if (!model.unique) throw new Error('Unique is missing');
if (!model.editorAlias) throw new Error('Property Editor Alias is missing');
if (!model.editorUiAlias) throw new Error('Property Editor UI Alias is missing');
// TODO: make data mapper to prevent errors
const requestBody: UpdateDataTypeRequestModel = {

View File

@@ -29,7 +29,7 @@ export class UmbPropertyEditorUIMarkdownEditorElement extends UmbLitElement impl
#onChange(e: Event) {
this.value = (e.target as UmbInputMarkdownElement).value as string;
this.dispatchEvent(new CustomEvent('property-value-change'));
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
render() {

View File

@@ -2,6 +2,7 @@ import { html, customElement, property, css, repeat, state } from '@umbraco-cms/
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbPropertyValueChangeEvent } from '@umbraco-cms/backoffice/property-editor';
export type UmbCrop = {
label: string;
@@ -27,7 +28,7 @@ export class UmbPropertyEditorUIImageCropsConfigurationElement
#onRemove(alias: string) {
this.value = [...this.value.filter((item) => item.alias !== alias)];
this.dispatchEvent(new CustomEvent('property-value-change'));
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
#onEdit(crop: UmbCrop) {
@@ -88,7 +89,7 @@ export class UmbPropertyEditorUIImageCropsConfigurationElement
} else {
this.value = [...this.value, newCrop];
}
this.dispatchEvent(new CustomEvent('property-value-change'));
this.dispatchEvent(new UmbPropertyValueChangeEvent());
form.reset();
}

View File

@@ -1,10 +0,0 @@
import type { ManifestPropertyEditorSchema } from '@umbraco-cms/backoffice/extension-registry';
export const manifest: ManifestPropertyEditorSchema = {
type: 'propertyEditorSchema',
name: 'Icon Picker',
alias: 'Umbraco.IconPicker',
meta: {
defaultPropertyEditorUiAlias: 'Umb.PropertyEditorUi.IconPicker',
},
};

View File

@@ -1,4 +1,3 @@
import { manifest as schemaManifest } from './Umbraco.IconPicker.js';
import type { ManifestPropertyEditorUi, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
const manifest: ManifestPropertyEditorUi = {
@@ -8,10 +7,9 @@ const manifest: ManifestPropertyEditorUi = {
element: () => import('./property-editor-ui-icon-picker.element.js'),
meta: {
label: 'Icon Picker',
propertyEditorSchemaAlias: 'Umbraco.IconPicker',
icon: 'icon-autofill',
group: 'common',
},
};
export const manifests: Array<ManifestTypes> = [manifest, schemaManifest];
export const manifests: Array<ManifestTypes> = [manifest];

View File

@@ -3,6 +3,7 @@ import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extensi
import { UMB_MODAL_MANAGER_CONTEXT, UMB_ICON_PICKER_MODAL } from '@umbraco-cms/backoffice/modal';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { extractUmbColorVariable } from '@umbraco-cms/backoffice/resources';
import { UmbPropertyValueChangeEvent } from '@umbraco-cms/backoffice/property-editor';
/**
* @element umb-property-editor-ui-icon-picker
@@ -46,7 +47,7 @@ export class UmbPropertyEditorUIIconPickerElement extends UmbLitElement implemen
this.value = data.icon as string;
}
this.dispatchEvent(new CustomEvent('property-value-change'));
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
render() {

View File

@@ -1,7 +1,10 @@
import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
import {
UmbPropertyValueChangeEvent,
type UmbPropertyEditorConfigCollection,
} from '@umbraco-cms/backoffice/property-editor';
import type { UUIModalSidebarSize, UUISelectEvent } from '@umbraco-cms/backoffice/external/uui';
/**
@@ -33,7 +36,7 @@ export class UmbPropertyEditorUIOverlaySizeElement extends UmbLitElement impleme
#onChange(event: UUISelectEvent) {
this.value = event.target.value as string;
this.dispatchEvent(new CustomEvent('property-value-change'));
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
render() {

View File

@@ -9,7 +9,10 @@ import {
} from '@umbraco-cms/backoffice/external/lit';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
import {
UmbPropertyValueChangeEvent,
type UmbPropertyEditorConfigCollection,
} from '@umbraco-cms/backoffice/property-editor';
import type { UUIInputElement } from '@umbraco-cms/backoffice/external/uui';
import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation';
@@ -50,7 +53,7 @@ export class UmbPropertyEditorUITextBoxElement
const newValue = (e.target as HTMLInputElement).value;
if (newValue === this.value) return;
this.value = newValue;
this.dispatchEvent(new CustomEvent('property-value-change'));
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
render() {

View File

@@ -2,7 +2,10 @@ import { css, html, customElement, property, state, ifDefined, styleMap } from '
import type { UUITextareaElement } from '@umbraco-cms/backoffice/external/uui';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
import {
UmbPropertyValueChangeEvent,
type UmbPropertyEditorConfigCollection,
} from '@umbraco-cms/backoffice/property-editor';
@customElement('umb-property-editor-ui-textarea')
export class UmbPropertyEditorUITextareaElement extends UmbLitElement implements UmbPropertyEditorUiElement {
@@ -38,7 +41,7 @@ export class UmbPropertyEditorUITextareaElement extends UmbLitElement implements
private onInput(e: InputEvent) {
this.value = (e.target as UUITextareaElement).value as string;
this.dispatchEvent(new CustomEvent('property-value-change'));
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
render() {

View File

@@ -2,7 +2,10 @@ import type { UmbInputUploadFieldElement } from '../../core/components/input-upl
import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
import {
UmbPropertyValueChangeEvent,
type UmbPropertyEditorConfigCollection,
} from '@umbraco-cms/backoffice/property-editor';
/**
* @element umb-property-editor-ui-upload-field
@@ -28,7 +31,7 @@ export class UmbPropertyEditorUIUploadFieldElement extends UmbLitElement impleme
private _onChange(event: CustomEvent) {
this.value = (event.target as unknown as UmbInputUploadFieldElement).value as string;
this.dispatchEvent(new CustomEvent('property-value-change'));
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
render() {

View File

@@ -2,7 +2,10 @@ import { html, customElement, property, state, query } from '@umbraco-cms/backof
import type { UUISelectElement, UUISelectEvent } from '@umbraco-cms/backoffice/external/uui';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
import {
UmbPropertyValueChangeEvent,
type UmbPropertyEditorConfigCollection,
} from '@umbraco-cms/backoffice/property-editor';
/**
* @element umb-property-editor-ui-value-type
@@ -46,7 +49,7 @@ export class UmbPropertyEditorUIValueTypeElement extends UmbLitElement implement
#onChange(e: UUISelectEvent) {
this.value = e.target.value as string;
this.dispatchEvent(new CustomEvent('property-value-change'));
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
render() {

View File

@@ -2,7 +2,10 @@ import type { UmbInputStaticFileElement } from '../../components/index.js';
import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
import {
UmbPropertyValueChangeEvent,
type UmbPropertyEditorConfigCollection,
} from '@umbraco-cms/backoffice/property-editor';
import '../../components/input-static-file/index.js';
@customElement('umb-property-editor-ui-static-file-picker')
@@ -31,7 +34,7 @@ export class UmbPropertyEditorUIStaticFilePickerElement extends UmbLitElement im
private _onChange(event: CustomEvent) {
this.value = (event.target as UmbInputStaticFileElement).selection;
this.dispatchEvent(new CustomEvent('property-value-change'));
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
// TODO: Implement mandatory?

View File

@@ -1,7 +1,10 @@
import type { UmbTagsInputElement } from '../../components/tags-input/tags-input.element.js';
import { UMB_PROPERTY_CONTEXT } from '@umbraco-cms/backoffice/property';
import { html, customElement, property, state, ifDefined } from '@umbraco-cms/backoffice/external/lit';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
import {
UmbPropertyValueChangeEvent,
type UmbPropertyEditorConfigCollection,
} from '@umbraco-cms/backoffice/property-editor';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
@@ -51,7 +54,7 @@ export class UmbPropertyEditorUITagsElement extends UmbLitElement implements Umb
#onChange(event: CustomEvent) {
this.value = ((event.target as UmbTagsInputElement).value as string).split(',');
this.dispatchEvent(new CustomEvent('property-value-change'));
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
render() {

View File

@@ -5,7 +5,10 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
import { firstValueFrom } from '@umbraco-cms/backoffice/external/rxjs';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
import {
UmbPropertyValueChangeEvent,
type UmbPropertyEditorConfigCollection,
} from '@umbraco-cms/backoffice/property-editor';
import { tinymce } from '@umbraco-cms/backoffice/external/tinymce';
const tinyIconSet = tinymce.IconManager.get('default');
@@ -106,7 +109,7 @@ export class UmbPropertyEditorUITinyMceToolbarConfigurationElement
this.value = value;
this.dispatchEvent(new CustomEvent('property-value-change'));
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
render() {

View File

@@ -64,6 +64,8 @@ export class UmbUserCollectionServerDataSource implements UmbCollectionDataSourc
languageIsoCode: item.languageIsoCode || null,
documentStartNodeUniques: item.documentStartNodeIds,
mediaStartNodeUniques: item.mediaStartNodeIds,
hasDocumentRootAccess: item.hasDocumentRootAccess,
hasMediaRootAccess: item.hasMediaRootAccess,
avatarUrls: item.avatarUrls,
state: item.state,
failedLoginAttempts: item.failedLoginAttempts,

View File

@@ -34,15 +34,18 @@ export class UmbUserServerDataSource implements UmbDetailDataSource<UmbUserDetai
async createScaffold() {
const data: UmbUserDetailModel = {
avatarUrls: [],
documentStartNodeUniques: [],
createDate: null,
hasDocumentRootAccess: false,
documentStartNodeUniques: [],
email: '',
entityType: UMB_USER_ENTITY_TYPE,
failedLoginAttempts: 0,
isAdmin: false,
languageIsoCode: '',
lastLockoutDate: null,
lastLoginDate: null,
lastPasswordChangeDate: null,
hasMediaRootAccess: false,
mediaStartNodeUniques: [],
name: '',
state: null,
@@ -50,7 +53,6 @@ export class UmbUserServerDataSource implements UmbDetailDataSource<UmbUserDetai
updateDate: null,
userGroupUniques: [],
userName: '',
isAdmin: false,
};
return { data };
@@ -72,17 +74,20 @@ export class UmbUserServerDataSource implements UmbDetailDataSource<UmbUserDetai
}
// TODO: make data mapper to prevent errors
const dataType: UmbUserDetailModel = {
const user: UmbUserDetailModel = {
avatarUrls: data.avatarUrls,
documentStartNodeUniques: data.documentStartNodeIds,
createDate: data.createDate,
hasDocumentRootAccess: data.hasDocumentRootAccess,
documentStartNodeUniques: data.documentStartNodeIds,
email: data.email,
entityType: UMB_USER_ENTITY_TYPE,
failedLoginAttempts: data.failedLoginAttempts,
isAdmin: data.isAdmin,
languageIsoCode: data.languageIsoCode || null,
lastLockoutDate: data.lastLockoutDate || null,
lastLoginDate: data.lastLoginDate || null,
lastPasswordChangeDate: data.lastPasswordChangeDate || null,
hasMediaRootAccess: data.hasMediaRootAccess,
mediaStartNodeUniques: data.mediaStartNodeIds,
name: data.name,
state: data.state,
@@ -90,10 +95,9 @@ export class UmbUserServerDataSource implements UmbDetailDataSource<UmbUserDetai
updateDate: data.updateDate,
userGroupUniques: data.userGroupIds,
userName: data.userName,
isAdmin: data.isAdmin,
};
return { data: dataType };
return { data: user };
}
/**
@@ -140,6 +144,8 @@ export class UmbUserServerDataSource implements UmbDetailDataSource<UmbUserDetai
const requestBody: UpdateUserRequestModel = {
documentStartNodeIds: model.documentStartNodeUniques,
email: model.email,
hasDocumentRootAccess: model.hasDocumentRootAccess,
hasMediaRootAccess: model.hasMediaRootAccess,
languageIsoCode: model.languageIsoCode || '',
mediaStartNodeIds: model.mediaStartNodeUniques,
name: model.name,

View File

@@ -5,24 +5,26 @@ export type UmbUserStateEnum = UserStateModel;
export const UmbUserStateEnum = UserStateModel;
export interface UmbUserDetailModel {
entityType: UmbUserEntityType;
email: string;
userName: string;
name: string;
userGroupUniques: Array<string>;
unique: string;
languageIsoCode: string | null;
documentStartNodeUniques: Array<string>;
mediaStartNodeUniques: Array<string>;
avatarUrls: Array<string>;
state: UmbUserStateEnum | null;
failedLoginAttempts: number;
createDate: string | null;
updateDate: string | null;
lastLoginDate: string | null;
lastLockoutDate: string | null;
lastPasswordChangeDate: string | null;
documentStartNodeUniques: Array<string>;
email: string;
entityType: UmbUserEntityType;
failedLoginAttempts: number;
hasDocumentRootAccess: boolean;
hasMediaRootAccess: boolean;
isAdmin: boolean;
languageIsoCode: string | null;
lastLockoutDate: string | null;
lastLoginDate: string | null;
lastPasswordChangeDate: string | null;
mediaStartNodeUniques: Array<string>;
name: string;
state: UmbUserStateEnum | null;
unique: string;
updateDate: string | null;
userGroupUniques: Array<string>;
userName: string;
}
export type UmbUserMfaProviderModel = UserTwoFactorProviderModel;

View File

@@ -1,123 +0,0 @@
import { UMB_USER_WORKSPACE_CONTEXT } from '../../user-workspace.context-token.js';
import type { UmbUserDetailModel } from '../../../types.js';
import { html, customElement, state, css } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import type { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
import type { UmbInputDocumentElement } from '@umbraco-cms/backoffice/document';
import type { UmbInputMediaElement } from '@umbraco-cms/backoffice/media';
import type { UmbUserGroupInputElement } from '@umbraco-cms/backoffice/user-group';
@customElement('umb-user-workspace-access-settings')
export class UmbUserWorkspaceAccessSettingsElement extends UmbLitElement {
@state()
private _user?: UmbUserDetailModel;
#userWorkspaceContext?: typeof UMB_USER_WORKSPACE_CONTEXT.TYPE;
constructor() {
super();
this.consumeContext(UMB_USER_WORKSPACE_CONTEXT, (instance) => {
this.#userWorkspaceContext = instance;
this.observe(this.#userWorkspaceContext.data, (user) => (this._user = user), 'umbUserObserver');
});
}
#onUserGroupsChange(event: UmbChangeEvent) {
const target = event.target as UmbUserGroupInputElement;
this.#userWorkspaceContext?.updateProperty('userGroupUniques', target.selection);
}
#onDocumentStartNodeChange(event: UmbChangeEvent) {
const target = event.target as UmbInputDocumentElement;
this.#userWorkspaceContext?.updateProperty('documentStartNodeUniques', target.selection);
}
#onMediaStartNodeChange(event: UmbChangeEvent) {
const target = event.target as UmbInputMediaElement;
this.#userWorkspaceContext?.updateProperty('mediaStartNodeUniques', target.selection);
}
render() {
return html` <uui-box>
<div slot="headline"><umb-localize key="user_assignAccess">Assign Access</umb-localize></div>
<div id="assign-access">
<umb-property-layout
label="${this.localize.term('general_groups')}"
description="${this.localize.term('user_groupsHelp')}">
<umb-user-group-input
slot="editor"
.selection=${this._user?.userGroupUniques ?? []}
@change=${this.#onUserGroupsChange}></umb-user-group-input>
</umb-property-layout>
<umb-property-layout
label=${this.localize.term('user_startnodes')}
description=${this.localize.term('user_startnodeshelp')}>
<umb-input-document
.selection=${this._user?.documentStartNodeUniques ?? []}
@change=${this.#onDocumentStartNodeChange}
slot="editor"></umb-input-document>
</umb-property-layout>
<umb-property-layout
label=${this.localize.term('user_mediastartnodes')}
description=${this.localize.term('user_mediastartnodeshelp')}>
<umb-input-media
.selection=${this._user?.mediaStartNodeUniques ?? []}
@change=${this.#onMediaStartNodeChange}
slot="editor"></umb-input-media>
</umb-property-layout>
</div>
</uui-box>
<uui-box id="access" headline=${this.localize.term('user_access')}>
<div slot="header" class="faded-text">
<umb-localize key="user_accessHelp"
>Based on the assigned groups and start nodes, the user has access to the following nodes</umb-localize
>
</div>
${this.#renderDocumentStartNodes()}
<hr />
${this.#renderMediaStartNodes()}
</uui-box>`;
}
#renderDocumentStartNodes() {
return html` <b><umb-localize key="sections_content">Content</umb-localize></b>
<umb-user-document-start-node
.uniques=${this._user?.documentStartNodeUniques || []}></umb-user-document-start-node>`;
}
#renderMediaStartNodes() {
return html` <b><umb-localize key="sections_media">Media</umb-localize></b>
<umb-user-media-start-node .uniques=${this._user?.mediaStartNodeUniques || []}></umb-user-media-start-node>`;
}
static styles = [
UmbTextStyles,
css`
#access {
margin-top: var(--uui-size-space-4);
}
hr {
border: none;
border-bottom: 1px solid var(--uui-color-divider);
width: 100%;
}
.faded-text {
color: var(--uui-color-text-alt);
font-size: 0.8rem;
}
`,
];
}
export default UmbUserWorkspaceAccessSettingsElement;
declare global {
interface HTMLElementTagNameMap {
'umb-user-workspace-access-settings': UmbUserWorkspaceAccessSettingsElement;
}
}

View File

@@ -0,0 +1,77 @@
import { UMB_USER_WORKSPACE_CONTEXT } from '../../user-workspace.context-token.js';
import type { UmbUserDetailModel } from '../../../types.js';
import { html, customElement, state, css } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import '../user-workspace-assign-access/user-workspace-assign-access.element.js';
const elementName = 'umb-user-workspace-access';
@customElement(elementName)
export class UmbUserWorkspaceAccessElement extends UmbLitElement {
@state()
private _user?: UmbUserDetailModel;
#userWorkspaceContext?: typeof UMB_USER_WORKSPACE_CONTEXT.TYPE;
constructor() {
super();
this.consumeContext(UMB_USER_WORKSPACE_CONTEXT, (instance) => {
this.#userWorkspaceContext = instance;
this.observe(this.#userWorkspaceContext.data, (user) => (this._user = user), 'umbUserObserver');
});
}
render() {
return html` <uui-box id="access" headline=${this.localize.term('user_access')}>
<div slot="header" class="faded-text">
<umb-localize key="user_accessHelp"
>Based on the assigned groups and start nodes, the user has access to the following nodes</umb-localize
>
</div>
${this.#renderDocumentStartNodes()}
<hr />
${this.#renderMediaStartNodes()}
</uui-box>`;
}
#renderDocumentStartNodes() {
return html` <b><umb-localize key="sections_content">Content</umb-localize></b>
<umb-user-document-start-node
.uniques=${this._user?.documentStartNodeUniques || []}></umb-user-document-start-node>`;
}
#renderMediaStartNodes() {
return html` <b><umb-localize key="sections_media">Media</umb-localize></b>
<umb-user-media-start-node .uniques=${this._user?.mediaStartNodeUniques || []}></umb-user-media-start-node>`;
}
static styles = [
UmbTextStyles,
css`
#access {
margin-top: var(--uui-size-space-4);
}
hr {
border: none;
border-bottom: 1px solid var(--uui-color-divider);
width: 100%;
}
.faded-text {
color: var(--uui-color-text-alt);
font-size: 0.8rem;
}
`,
];
}
export default UmbUserWorkspaceAccessElement;
declare global {
interface HTMLElementTagNameMap {
[elementName]: UmbUserWorkspaceAccessElement;
}
}

View File

@@ -0,0 +1,188 @@
import { UMB_USER_WORKSPACE_CONTEXT } from '../../user-workspace.context-token.js';
import type { UmbUserDetailModel } from '../../../types.js';
import { html, customElement, state, css, nothing } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import type { UmbInputDocumentElement } from '@umbraco-cms/backoffice/document';
import type { UmbInputMediaElement } from '@umbraco-cms/backoffice/media';
import type { UmbUserGroupInputElement } from '@umbraco-cms/backoffice/user-group';
import type { UUIBooleanInputEvent } from '@umbraco-cms/backoffice/external/uui';
const elementName = 'umb-user-workspace-assign-access';
@customElement(elementName)
export class UmbUserWorkspaceAssignAccessElement extends UmbLitElement {
@state()
private _userGroupUniques: UmbUserDetailModel['userGroupUniques'] = [];
@state()
private _documentStartNodeUniques: UmbUserDetailModel['documentStartNodeUniques'] = [];
@state()
private _documentRootAccess: UmbUserDetailModel['hasDocumentRootAccess'] = false;
@state()
private _mediaStartNodeUniques: UmbUserDetailModel['documentStartNodeUniques'] = [];
@state()
private _mediaRootAccess: UmbUserDetailModel['hasMediaRootAccess'] = false;
#workspaceContext?: typeof UMB_USER_WORKSPACE_CONTEXT.TYPE;
constructor() {
super();
this.consumeContext(UMB_USER_WORKSPACE_CONTEXT, (instance) => {
this.#workspaceContext = instance;
this.observe(
this.#workspaceContext.userGroupUniques,
(value) => (this._userGroupUniques = value),
'_observeUserGroupAccess',
);
this.observe(
this.#workspaceContext.hasDocumentRootAccess,
(value) => (this._documentRootAccess = value),
'_observeDocumentRootAccess',
);
this.observe(
this.#workspaceContext.documentStartNodeUniques,
(value) => (this._documentStartNodeUniques = value),
'_observeDocumentStartNode',
);
this.observe(
this.#workspaceContext.hasMediaRootAccess,
(value) => (this._mediaRootAccess = value),
'_observeMediaRootAccess',
);
this.observe(
this.#workspaceContext.mediaStartNodeUniques,
(value) => (this._mediaStartNodeUniques = value),
'_observeMediaStartNode',
);
});
}
#onUserGroupsChange(event: CustomEvent) {
event.stopPropagation();
const target = event.target as UmbUserGroupInputElement;
const selection = target.selection;
// TODO make contexts method
this.#workspaceContext?.updateProperty('userGroupUniques', selection);
}
#onAllowAllDocumentsChange(event: UUIBooleanInputEvent) {
event.stopPropagation();
const target = event.target;
// TODO make contexts method
this.#workspaceContext?.updateProperty('hasDocumentRootAccess', target.checked);
this.#workspaceContext?.updateProperty('documentStartNodeUniques', []);
}
#onDocumentStartNodeChange(event: CustomEvent) {
event.stopPropagation();
const target = event.target as UmbInputDocumentElement;
const selection = target.selection;
// TODO make contexts method
this.#workspaceContext?.updateProperty('documentStartNodeUniques', selection);
}
#onAllowAllMediaChange(event: UUIBooleanInputEvent) {
event.stopPropagation();
const target = event.target;
// TODO make contexts method
this.#workspaceContext?.updateProperty('hasMediaRootAccess', target.checked);
this.#workspaceContext?.updateProperty('mediaStartNodeUniques', []);
}
#onMediaStartNodeChange(event: CustomEvent) {
event.stopPropagation();
const target = event.target as UmbInputMediaElement;
const selection = target.selection;
// TODO make contexts method
this.#workspaceContext?.updateProperty('mediaStartNodeUniques', selection);
}
render() {
return html`
<uui-box>
<div slot="headline"><umb-localize key="user_assignAccess">Assign Access</umb-localize></div>
<div id="assign-access">
${this.#renderGroupAccess()} ${this.#renderDocumentAccess()} ${this.#renderMediaAccess()}
</div>
</uui-box>
`;
}
#renderGroupAccess() {
return html`<umb-property-layout
label="${this.localize.term('general_groups')}"
description="${this.localize.term('user_groupsHelp')}">
<umb-user-group-input
slot="editor"
.selection=${this._userGroupUniques}
@change=${this.#onUserGroupsChange}></umb-user-group-input>
</umb-property-layout>`;
}
#renderDocumentAccess() {
return html`
<umb-property-layout
label=${this.localize.term('user_startnodes')}
description=${this.localize.term('user_startnodeshelp')}>
<div slot="editor">
<uui-toggle
style="margin-bottom: var(--uui-size-space-3);"
label="${this.localize.term('user_allowAccessToAllDocuments')}"
.checked=${this._documentRootAccess}
@change=${this.#onAllowAllDocumentsChange}></uui-toggle>
</div>
${this._documentRootAccess === false
? html`
<umb-input-document
slot="editor"
.selection=${this._documentStartNodeUniques}
@change=${this.#onDocumentStartNodeChange}></umb-input-document>
`
: nothing}
</umb-property-layout>
`;
}
#renderMediaAccess() {
return html`
<umb-property-layout
label=${this.localize.term('defaultdialogs_selectMediaStartNode')}
description=${this.localize.term('user_mediastartnodehelp')}>
<div slot="editor">
<uui-toggle
style="margin-bottom: var(--uui-size-space-3);"
label="${this.localize.term('user_allowAccessToAllMedia')}"
.checked=${this._mediaRootAccess}
@change=${this.#onAllowAllMediaChange}></uui-toggle>
</div>
${this._mediaRootAccess === false
? html`
<umb-input-media
slot="editor"
.selection=${this._mediaStartNodeUniques}
@change=${this.#onMediaStartNodeChange}></umb-input-media>
`
: nothing}
</umb-property-layout>
`;
}
static styles = [UmbTextStyles];
}
declare global {
interface HTMLElementTagNameMap {
[elementName]: UmbUserWorkspaceAssignAccessElement;
}
}

View File

@@ -10,7 +10,7 @@ import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
// import local components. Theses are not meant to be used outside of this component.
import './components/user-workspace-profile-settings/user-workspace-profile-settings.element.js';
import './components/user-workspace-access-settings/user-workspace-access-settings.element.js';
import './components/user-workspace-access/user-workspace-access.element.js';
import './components/user-workspace-info/user-workspace-info.element.js';
import './components/user-workspace-avatar/user-workspace-avatar.element.js';
@@ -72,8 +72,9 @@ export class UmbUserWorkspaceEditorElement extends UmbLitElement {
if (!this._user) return nothing;
return html`
<umb-user-workspace-profile-settings></umb-user-workspace-profile-settings
><umb-user-workspace-access-settings></umb-user-workspace-access-settings>
<umb-user-workspace-profile-settings></umb-user-workspace-profile-settings>
<umb-user-workspace-assign-access></umb-user-workspace-assign-access>
<umb-user-workspace-access></umb-user-workspace-access>
`;
}

View File

@@ -23,6 +23,13 @@ export class UmbUserWorkspaceContext
readonly data = this.#currentData.asObservable();
readonly state = this.#currentData.asObservablePart((x) => x?.state);
readonly unique = this.#currentData.asObservablePart((x) => x?.unique);
readonly userGroupUniques = this.#currentData.asObservablePart((x) => x?.userGroupUniques || []);
readonly documentStartNodeUniques = this.#currentData.asObservablePart(
(data) => data?.documentStartNodeUniques || [],
);
readonly hasDocumentRootAccess = this.#currentData.asObservablePart((data) => data?.hasDocumentRootAccess || false);
readonly mediaStartNodeUniques = this.#currentData.asObservablePart((data) => data?.mediaStartNodeUniques || []);
readonly hasMediaRootAccess = this.#currentData.asObservablePart((data) => data?.hasMediaRootAccess || false);
readonly routes = new UmbWorkspaceRouteManager(this);