Merge branch 'main' into bugfix/create-document-with-blueprint-endpoint

This commit is contained in:
Lone Iversen
2024-04-17 09:02:03 +02:00
committed by GitHub
8 changed files with 53 additions and 39 deletions

View File

@@ -65,6 +65,12 @@ export class UmbPropertyTypeSettingsModalElement extends UmbModalBaseElement<
this.consumeContext(UMB_CONTENT_TYPE_WORKSPACE_CONTEXT, (instance) => {
if (!this.data?.contentTypeId) return;
if (instance.getUnique() !== this.data.contentTypeId) {
// We can currently only edit properties that are part of a content type workspace, which has to be present outside of the modal. [NL]
throw new Error(
'The content type workspace context does not match the content type id of the property type settings modal.',
);
}
this.observe(instance.variesByCulture, (variesByCulture) => (this._contentTypeVariesByCulture = variesByCulture));
this.observe(instance.variesBySegment, (variesBySegment) => (this._contentTypeVariesBySegment = variesBySegment));

View File

@@ -178,6 +178,13 @@ export class UmbContentTypePropertyStructureHelper<T extends UmbContentTypeModel
return this.#structure.ownerContentTypePart((x) => x?.properties.some((y) => y.id === propertyId));
}
async contentTypeOfProperty(propertyId: UmbPropertyTypeId) {
await this.#init;
if (!this.#structure) return;
return this.#structure.contentTypeOfProperty(propertyId);
}
// TODO: consider moving this to another class, to separate 'viewer' from 'manipulator':
/** Manipulate methods: */

View File

@@ -19,6 +19,8 @@ import {
import { incrementString } from '@umbraco-cms/backoffice/utils';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
type UmbPropertyTypeId = UmbPropertyTypeModel['id'];
/**
* Manages a structure of a Content Type and its properties and containers.
* This loads and merges the structures of the Content Type and its inherited and composed Content Types.
@@ -192,6 +194,10 @@ export class UmbContentTypeStructureManager<
return this.#contentTypes.getValue().find((y) => y.unique === this.#ownerContentTypeUnique);
}
getOwnerContentTypeUnique() {
return this.#ownerContentTypeUnique;
}
updateOwnerContentType(entry: Partial<T>) {
this.#contentTypes.updateOne(this.#ownerContentTypeUnique, entry);
}
@@ -391,7 +397,7 @@ export class UmbContentTypeStructureManager<
throw new Error('Could not find the Content Type to remove container from');
}
const frozenContainers = contentType.containers ?? [];
const containers = frozenContainers.filter((x) => x.id !== containerId || x.parent?.id !== containerId);
const containers = frozenContainers.filter((x) => x.id !== containerId && x.parent?.id !== containerId);
const frozenProperties = contentType.properties ?? [];
const properties = frozenProperties.filter((x) => x.container?.id !== containerId);
@@ -670,6 +676,12 @@ export class UmbContentTypeStructureManager<
});
}
contentTypeOfProperty(propertyId: UmbPropertyTypeId) {
return this.#contentTypes.asObservablePart((contentTypes) =>
contentTypes.find((contentType) => contentType.properties.some((p) => p.id === propertyId)),
);
}
private _reset() {
this.#contentTypeObservers.forEach((observer) => observer.destroy());
this.#contentTypeObservers = [];

View File

@@ -208,10 +208,7 @@ export class UmbContentTypeDesignEditorPropertiesElement extends UmbLitElement {
return html`
<umb-content-type-design-editor-property
data-umb-property-id=${property.id}
owner-content-type-id=${ifDefined(this._ownerContentType!.unique)}
owner-content-type-name=${ifDefined(this._ownerContentType!.name)}
.editContentTypePath=${this._editContentTypePath}
?inherited=${property.container?.id !== this.containerId}
?sort-mode-active=${this._sortModeActive}
.propertyStructureHelper=${this.#propertyStructureHelper}
.property=${property}>

View File

@@ -58,28 +58,21 @@ export class UmbContentTypeDesignEditorPropertyElement extends UmbLitElement {
}
private _property?: UmbPropertyTypeModel | UmbPropertyTypeScaffoldModel | undefined;
/**
* Inherited, Determines if the property is part of the main content type thats being edited.
* If true, then the property is inherited from another content type, not a part of the main content type.
* @type {boolean}
* @attr
* @default undefined
*/
@property({ type: Boolean })
public inherited?: boolean;
@property({ type: Boolean, reflect: true, attribute: 'sort-mode-active' })
public sortModeActive = false;
@property({ type: String, attribute: 'owner-content-type-id' })
public ownerContentTypeId?: string;
@property({ type: String, attribute: 'owner-content-type-name' })
public ownerContentTypeName?: string;
@property({ type: String, attribute: 'edit-content-type-path' })
public editContentTypePath?: string;
@state()
public _inherited?: boolean;
@state()
public _inheritedContentTypeId?: string;
@state()
public _inheritedContentTypeName?: string;
@state()
protected _modalRoute?: string;
@@ -96,7 +89,7 @@ export class UmbContentTypeDesignEditorPropertyElement extends UmbLitElement {
this.#settingsModal = new UmbModalRouteRegistrationController(this, UMB_PROPERTY_TYPE_SETTINGS_MODAL)
.addUniquePaths(['propertyId'])
.onSetup(() => {
const id = this.ownerContentTypeId;
const id = this._inheritedContentTypeId;
if (id === undefined) return false;
const propertyData = this.property;
if (propertyData === undefined) return false;
@@ -114,9 +107,12 @@ export class UmbContentTypeDesignEditorPropertyElement extends UmbLitElement {
if (this._propertyStructureHelper && this._property) {
// We can first match with something if we have a name [NL]
this.observe(
await this._propertyStructureHelper!.isOwnerProperty(this._property.id),
(isOwned) => {
this.inherited = !isOwned;
await this._propertyStructureHelper!.contentTypeOfProperty(this._property.id),
(contentType) => {
this._inherited =
this._propertyStructureHelper?.getStructureManager()?.getOwnerContentTypeUnique() !== contentType?.unique;
this._inheritedContentTypeId = contentType?.unique;
this._inheritedContentTypeName = contentType?.name;
},
'observeIsOwnerProperty',
);
@@ -196,7 +192,7 @@ export class UmbContentTypeDesignEditorPropertyElement extends UmbLitElement {
render() {
// TODO: Only show alias on label if user has access to DocumentType within settings: [NL]
return this.inherited ? this.renderInheritedProperty() : this.renderEditableProperty();
return this._inherited ? this.renderInheritedProperty() : this.renderEditableProperty();
}
renderInheritedProperty() {
@@ -217,8 +213,8 @@ export class UmbContentTypeDesignEditorPropertyElement extends UmbLitElement {
<uui-icon name="icon-merge"></uui-icon>
<span
>${this.localize.term('contentTypeEditor_inheritedFrom')}
<a href=${this.editContentTypePath + 'edit/' + this.ownerContentTypeId}>
${this.ownerContentTypeName ?? '??'}
<a href=${this.editContentTypePath + 'edit/' + this._inheritedContentTypeId}>
${this._inheritedContentTypeName ?? '??'}
</a>
</span>
</uui-tag>
@@ -275,12 +271,12 @@ export class UmbContentTypeDesignEditorPropertyElement extends UmbLitElement {
if (!this.property) return;
return html`
<div class="sortable">
<uui-icon name="${this.inherited ? 'icon-merge' : 'icon-navigation'}"></uui-icon>
<uui-icon name="${this._inherited ? 'icon-merge' : 'icon-navigation'}"></uui-icon>
${this.property.name} <span style="color: var(--uui-color-disabled-contrast)">(${this.property.alias})</span>
</div>
<uui-input
type="number"
?readonly=${this.inherited}
?readonly=${this._inherited}
label="sort order"
@change=${(e: UUIInputEvent) =>
this.#partialUpdate({ sortOrder: parseInt(e.target.value as string) ?? 0 } as UmbPropertyTypeModel)}

View File

@@ -228,7 +228,7 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements
this._routes = routes;
}
async #requestRemoveTab(tab: UmbPropertyTypeContainerModel | undefined) {
async #requestDeleteTab(tab: UmbPropertyTypeContainerModel | undefined) {
// TODO: Localize this:
const modalData: UmbConfirmModalData = {
headline: 'Delete tab',
@@ -248,9 +248,9 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements
await umbConfirmModal(this, modalData);
this.#remove(tab?.id);
this.#deleteTab(tab?.id);
}
#remove(tabId?: string) {
#deleteTab(tabId?: string) {
if (!tabId) return;
this.#workspaceContext?.structure.removeContainer(null, tabId);
// TODO: We should only navigate away if it was the last tab and if it was the active one... [NL]
@@ -495,7 +495,7 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements
@click=${(e: MouseEvent) => {
e.stopPropagation();
e.preventDefault();
this.#requestRemoveTab(tab);
this.#requestDeleteTab(tab);
}}
compact>
<uui-icon name="icon-trash"></uui-icon>

View File

@@ -191,7 +191,7 @@ export class UmbInputDocumentElement extends UUIFormControlMixin(UmbLitElement,
const name = item.variants[0]?.name;
return html`
<uui-ref-node name=${name} detail=${ifDefined(item.unique)}>
<uui-ref-node name=${name}>
${this.#renderIcon(item)} ${this.#renderIsTrashed(item)}
<uui-action-bar slot="actions">
${this.#renderOpenButton(item)}

View File

@@ -124,11 +124,7 @@ export class UmbLogViewerWorkspaceContext extends UmbControllerBase implements U
onChangeState = () => {
const searchQuery = query();
let sanitizedQuery = '';
if (searchQuery.lq) {
sanitizedQuery = decodeURIComponent(searchQuery.lq);
}
this.setFilterExpression(sanitizedQuery);
this.setFilterExpression(searchQuery.lq);
let validLogLevels: LogLevelModel[] = [];
if (searchQuery.loglevels) {