Merge branch 'main' into bugfix/create-document-with-blueprint-endpoint
This commit is contained in:
@@ -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));
|
||||
|
||||
@@ -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: */
|
||||
|
||||
|
||||
@@ -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 = [];
|
||||
|
||||
@@ -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}>
|
||||
|
||||
@@ -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)}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user