Merge remote-tracking branch 'origin/main' into feature/individual-publication-modals

This commit is contained in:
Jacob Overgaard
2024-03-14 11:44:17 +01:00
12 changed files with 156 additions and 78 deletions

View File

@@ -129,11 +129,11 @@ export class UmbContentTypePropertyStructureManager<T extends UmbContentTypeMode
if (!unique) return {};
// Lets initiate the content type:
const { data } = await this.#contentTypeRepository.requestByUnique(unique);
const { data, asObservable } = await this.#contentTypeRepository.requestByUnique(unique);
if (!data) return {};
await this._observeContentType(data);
return { data };
return { data, asObservable };
}
private async _observeContentType(data: T) {

View File

@@ -23,3 +23,8 @@ export interface NumberRangeValueType {
export interface UmbReferenceByUnique {
unique: string;
}
export interface UmbReferenceByUniqueAndType {
type: string;
unique: string;
}

View File

@@ -11,11 +11,10 @@ import type { UmbTreePickerSource } from '@umbraco-cms/backoffice/components';
/**
* @element umb-property-editor-ui-tree-picker
*/
@customElement('umb-property-editor-ui-tree-picker')
export class UmbPropertyEditorUITreePickerElement extends UmbLitElement implements UmbPropertyEditorUiElement {
@property()
value = '';
@property({ type: Array })
value: UmbInputTreeElement['items'] = [];
@state()
type: UmbTreePickerSource['type'] = 'content';
@@ -42,8 +41,6 @@ export class UmbPropertyEditorUITreePickerElement extends UmbLitElement implemen
#dynamicRootRepository = new UmbDynamicRootRepository(this);
#workspaceContext?: typeof UMB_WORKSPACE_CONTEXT.TYPE;
@property({ attribute: false })
public set config(config: UmbPropertyEditorConfigCollection | undefined) {
const startNode: UmbTreePickerSource | undefined = config?.getValueByAlias('startNode');
@@ -62,14 +59,6 @@ export class UmbPropertyEditorUITreePickerElement extends UmbLitElement implemen
this.ignoreUserStartNodes = config?.getValueByAlias('ignoreUserStartNodes');
}
constructor() {
super();
this.consumeContext(UMB_WORKSPACE_CONTEXT, (workspaceContext) => {
this.#workspaceContext = workspaceContext;
});
}
connectedCallback() {
super.connectedCallback();
@@ -79,9 +68,10 @@ export class UmbPropertyEditorUITreePickerElement extends UmbLitElement implemen
async #setStartNodeId() {
if (this.startNodeId) return;
const unique = this.#workspaceContext?.getUnique();
// TODO: Awaiting the workspace context to have a parent entity ID value. [LK]
// e.g. const parentEntityId = this.#workspaceContext?.getParentEntityId();
const workspaceContext = await this.getContext(UMB_WORKSPACE_CONTEXT);
const unique = workspaceContext.getUnique();
if (unique && this.#dynamicRoot) {
const result = await this.#dynamicRootRepository.postDynamicRootQuery(this.#dynamicRoot, unique);
if (result && result.length > 0) {
@@ -91,13 +81,14 @@ export class UmbPropertyEditorUITreePickerElement extends UmbLitElement implemen
}
#onChange(e: CustomEvent) {
this.value = (e.target as UmbInputTreeElement).value as string;
const input = e.target as UmbInputTreeElement;
this.value = input.items;
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
render() {
return html`<umb-input-tree
.value=${this.value}
.items=${this.value}
.type=${this.type}
.startNodeId=${this.startNodeId ?? ''}
.min=${this.min}

View File

@@ -1,10 +1,11 @@
import type { UmbInputMemberElement } from '@umbraco-cms/backoffice/member';
import { css, html, customElement, property } from '@umbraco-cms/backoffice/external/lit';
import { FormControlMixin } from '@umbraco-cms/backoffice/external/uui';
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UmbInputDocumentElement } from '@umbraco-cms/backoffice/document';
import type { UmbInputMediaElement } from '@umbraco-cms/backoffice/media';
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
import type { UmbInputMemberElement } from '@umbraco-cms/backoffice/member';
import type { UmbReferenceByUniqueAndType } from '@umbraco-cms/backoffice/models';
import type { UmbTreePickerSource } from '@umbraco-cms/backoffice/components';
@customElement('umb-input-tree')
@@ -50,32 +51,40 @@ export class UmbInputTreeElement extends FormControlMixin(UmbLitElement) {
@property({ type: Boolean })
ignoreUserStartNodes?: boolean;
@property()
public set value(newValue: string) {
super.value = newValue;
if (newValue) {
this.selectedIds = newValue.split(',');
} else {
this.selectedIds = [];
}
#entityTypeLookup = { content: 'document', media: 'media', member: 'member' };
@property({ type: Array })
public set items(items: Array<UmbReferenceByUniqueAndType>) {
this.#selectedIds = items?.map((item) => item.unique) ?? [];
this.value = items?.map((item) => item.unique).join(',');
}
public get value(): string {
return super.value as string;
public get items(): Array<UmbReferenceByUniqueAndType> {
return this.#selectedIds.map((id) => ({ type: this.#entityTypeLookup[this._type], unique: id }));
}
selectedIds: Array<string> = [];
#selectedIds: Array<string> = [];
#onChange(event: CustomEvent) {
switch (this._type) {
case 'content':
this.value = (event.target as UmbInputDocumentElement).selectedIds.join(',');
{
const input = event.target as UmbInputDocumentElement;
this.#selectedIds = input.selectedIds;
this.value = input.selectedIds.join(',');
}
break;
case 'media':
this.value = (event.target as UmbInputMediaElement).selectedIds.join(',');
case 'media': {
const input = event.target as UmbInputMediaElement;
this.#selectedIds = input.selectedIds;
this.value = input.selectedIds.join(',');
break;
case 'member':
this.value = (event.target as UmbInputMemberElement).selectedIds.join(',');
}
case 'member': {
const input = event.target as UmbInputMemberElement;
this.#selectedIds = input.selectedIds;
this.value = input.selectedIds.join(',');
break;
}
default:
break;
}
@@ -90,7 +99,7 @@ export class UmbInputTreeElement extends FormControlMixin(UmbLitElement) {
render() {
switch (this._type) {
case 'content':
return this.#renderContentPicker();
return this.#renderDocumentPicker();
case 'media':
return this.#renderMediaPicker();
case 'member':
@@ -100,9 +109,9 @@ export class UmbInputTreeElement extends FormControlMixin(UmbLitElement) {
}
}
#renderContentPicker() {
#renderDocumentPicker() {
return html`<umb-input-document
.selectedIds=${this.selectedIds}
.selectedIds=${this.#selectedIds}
.startNodeId=${this.startNodeId}
.allowedContentTypeIds=${this._allowedContentTypeIds}
.min=${this.min}
@@ -113,8 +122,9 @@ export class UmbInputTreeElement extends FormControlMixin(UmbLitElement) {
}
#renderMediaPicker() {
// TODO: [LK] Review the data structure of this input editor.
return html`<umb-input-media
.selectedIds=${this.selectedIds}
.selectedIds=${this.#selectedIds}
.allowedContentTypeIds=${this._allowedContentTypeIds}
.min=${this.min}
.max=${this.max}
@@ -125,7 +135,7 @@ export class UmbInputTreeElement extends FormControlMixin(UmbLitElement) {
#renderMemberPicker() {
return html`<umb-input-member
.selectedIds=${this.selectedIds}
.selectedIds=${this.#selectedIds}
.allowedContentTypeIds=${this._allowedContentTypeIds}
.min=${this.min}
.max=${this.max}

View File

@@ -178,14 +178,27 @@ export class UmbDataTypeWorkspaceContext
async load(unique: string) {
this.resetState();
const request = this.repository.requestByUnique(unique);
this.#getDataPromise = request;
const { data } = await request;
this.#getDataPromise = this.repository.requestByUnique(unique);
type GetDataType = Awaited<ReturnType<UmbDataTypeDetailRepository['requestByUnique']>>;
const { data, asObservable } = (await this.#getDataPromise) as GetDataType;
if (!data) return undefined;
this.setIsNew(false);
this.#persistedData.setValue(data);
this.#currentData.setValue(data);
if (data) {
this.setIsNew(false);
this.#persistedData.setValue(data);
this.#currentData.setValue(data);
}
if (asObservable) {
this.observe(asObservable(), (entity) => this.#onStoreChange(entity), 'umbDataTypeStoreObserver');
}
}
#onStoreChange(entity: EntityType | undefined) {
if (!entity) {
//TODO: This solution is alright for now. But reconsider when we introduce signal-r
history.pushState(null, '', 'section/settings/workspace/data-type-root');
}
}
async create(parent: { entityType: string; unique: string | null }) {

View File

@@ -166,13 +166,24 @@ export class UmbDocumentTypeWorkspaceContext
async load(unique: string) {
this.resetState();
const { data } = await this.structure.loadType(unique);
if (!data) return undefined;
const { data, asObservable } = await this.structure.loadType(unique);
this.setIsNew(false);
this.setIsSorting(false);
this.#persistedData.setValue(data);
return data;
if (data) {
this.setIsNew(false);
this.setIsSorting(false);
this.#persistedData.update(data);
}
if (asObservable) {
this.observe(asObservable(), (entity) => this.#onStoreChange(entity), 'umbDocumentTypeStoreObserver');
}
}
#onStoreChange(entity: EntityType | undefined) {
if (!entity) {
//TODO: This solution is alright for now. But reconsider when we introduce signal-r
history.pushState(null, '', 'section/settings/workspace/document-type-root');
}
}
/**

View File

@@ -143,13 +143,23 @@ export class UmbDocumentWorkspaceContext
async load(unique: string) {
this.resetState();
this.#getDataPromise = this.repository.requestByUnique(unique);
const { data } = await this.#getDataPromise;
if (!data) return undefined;
type GetDataType = Awaited<ReturnType<UmbDocumentDetailRepository['requestByUnique']>>;
const { data, asObservable } = (await this.#getDataPromise) as GetDataType;
this.setIsNew(false);
this.#persistedData.setValue(data);
this.#currentData.setValue(data);
return data || undefined;
if (data) {
this.setIsNew(false);
this.#persistedData.update(data);
this.#currentData.update(data);
}
this.observe(asObservable(), (entity) => this.#onStoreChange(entity), 'umbDocumentStoreObserver');
}
#onStoreChange(entity: EntityType | undefined) {
if (!entity) {
//TODO: This solution is alright for now. But reconsider when we introduce signal-r
history.pushState(null, '', 'section/content');
}
}
async create(parent: { entityType: string; unique: string | null }, documentTypeUnique: string) {

View File

@@ -127,15 +127,26 @@ export class UmbMediaTypeWorkspaceContext
return data;
}
async load(entityId: string) {
async load(unique: string) {
this.resetState();
const { data } = await this.structure.loadType(entityId);
if (!data) return undefined;
const { data, asObservable } = await this.structure.loadType(unique);
this.setIsNew(false);
this.setIsSorting(false);
this.#persistedData.setValue(data);
return data;
if (data) {
this.setIsNew(false);
this.setIsSorting(false);
this.#persistedData.update(data);
}
if (asObservable) {
this.observe(asObservable(), (entity) => this.#onStoreChange(entity), 'umbMediaTypeStoreObserver');
}
}
#onStoreChange(entity: EntityType | undefined) {
if (!entity) {
//TODO: This solution is alright for now. But reconsider when we introduce signal-r
history.pushState(null, '', 'section/settings/workspace/media-type-root');
}
}
/**

View File

@@ -125,13 +125,23 @@ export class UmbMediaWorkspaceContext
async load(unique: string) {
this.resetState();
this.#getDataPromise = this.repository.requestByUnique(unique);
const { data } = await this.#getDataPromise;
if (!data) return undefined;
type GetDataType = Awaited<ReturnType<UmbMediaDetailRepository['requestByUnique']>>;
const { data, asObservable } = (await this.#getDataPromise) as GetDataType;
this.setIsNew(false);
this.#persistedData.setValue(data);
this.#currentData.setValue(data);
return data || undefined;
if (data) {
this.setIsNew(false);
this.#persistedData.update(data);
this.#currentData.update(data);
}
this.observe(asObservable(), (entity) => this.#onStoreChange(entity), 'umbMediaStoreObserver');
}
#onStoreChange(entity: EntityType | undefined) {
if (!entity) {
//TODO: This solution is alright for now. But reconsider when we introduce signal-r
history.pushState(null, '', 'section/media');
}
}
async create(parent: { entityType: string; unique: string | null }, mediaTypeUnique: string) {

View File

@@ -72,13 +72,25 @@ export class UmbMemberTypeWorkspaceContext
}
async load(unique: string) {
const { data } = await this.structure.loadType(unique);
if (!data) return undefined;
this.resetState();
const { data, asObservable } = await this.structure.loadType(unique);
this.setIsNew(false);
this.setIsSorting(false);
return { data } || undefined;
if (data) {
this.setIsNew(false);
this.setIsSorting(false);
this.#persistedData.update(data);
}
if (asObservable) {
this.observe(asObservable(), (entity) => this.#onStoreChange(entity), 'umbMemberTypeStoreObserver');
}
}
#onStoreChange(entity: EntityType | undefined) {
if (!entity) {
//TODO: This solution is alright for now. But reconsider when we introduce signal-r
history.pushState(null, '', 'section/settings/workspace/member-type-root');
}
}
async create(parent: { entityType: string; unique: string | null }) {

View File

@@ -128,6 +128,7 @@ export class UmbMemberWorkspaceContext
#onMemberStoreChange(member: EntityType | undefined) {
if (!member) {
//TODO: This solution is alright for now. But reconsider when we introduce signal-r
history.pushState(null, '', 'section/member-management');
}
}

View File

@@ -45,7 +45,11 @@ export class UmbUserWorkspaceContext
There might be a less manual way to do this.
*/
onUserStoreChanges(user: EntityType | undefined) {
if (!user) return;
if (!user) {
//TODO: This solution is alright for now. But reconsider when we introduce signal-r
history.pushState(null, '', 'section/user-management');
return;
}
this.#currentData.update({ state: user.state, avatarUrls: user.avatarUrls });
}