Merge branch 'main' into chore/content-type-structure-type-refactoring

This commit is contained in:
Mads Rasmussen
2024-01-30 16:28:44 +01:00
27 changed files with 269 additions and 100 deletions

View File

@@ -27,7 +27,7 @@ export class UmbExtensionsElementInitializer<
> {
//
#extensionRegistry;
private _defaultElement?: string;
#defaultElement?: string;
#props?: Record<string, unknown>;
public get properties() {
@@ -50,7 +50,7 @@ export class UmbExtensionsElementInitializer<
) {
super(host, extensionRegistry, type, filter, onChange);
this.#extensionRegistry = extensionRegistry;
this._defaultElement = defaultElement;
this.#defaultElement = defaultElement;
this._init();
}
@@ -60,7 +60,7 @@ export class UmbExtensionsElementInitializer<
this.#extensionRegistry,
manifest.alias,
this._extensionChanged,
this._defaultElement,
this.#defaultElement,
) as ControllerType;
extController.properties = this.#props;

View File

@@ -512,6 +512,7 @@ export const data: Array<UmbMockDataTypeModel> = [
{
label: 'Mocked Block Type for Block List',
contentElementTypeKey: '4f68ba66-6fb2-4778-83b8-6ab4ca3a7c5c',
settingsElementTypeKey: 'all-property-editors-document-type-id',
icon: 'icon-server-alt',
},
{
@@ -551,7 +552,7 @@ export const data: Array<UmbMockDataTypeModel> = [
},
{
alias: 'useInlineEditingAsDefault',
value: true,
value: false,
},
{
alias: 'useLiveEditing',

View File

@@ -188,6 +188,7 @@ export const data: Array<UmbMockDocumentModel> = [
'Umbraco.BlockList': [
{
contentUdi: '1234',
settingsUdi: '5678',
},
],
},
@@ -198,7 +199,13 @@ export const data: Array<UmbMockDocumentModel> = [
elementProperty: 'Hello world',
},
],
settingsData: [],
settingsData: [
{
udi: '5678',
contentTypeKey: 'all-property-editors-document-type-id',
elementProperty: 'Hello world',
},
],
},
},
{

View File

@@ -28,6 +28,9 @@ export class UmbPropertyEditorUIBlockListBlockElement extends UmbLitElement impl
@state()
_contentUdi?: string;
@state()
_hasSettings = false;
@state()
_label = '';
@@ -37,6 +40,12 @@ export class UmbPropertyEditorUIBlockListBlockElement extends UmbLitElement impl
@state()
_inlineEditingMode?: boolean;
// TODO: Move type for the Block Properties, and use it on the Element Interface for the Manifest.
@state()
_blockViewProps: {
label?: string;
} = {};
constructor() {
super();
@@ -46,7 +55,11 @@ export class UmbPropertyEditorUIBlockListBlockElement extends UmbLitElement impl
this.observe(this.#context.contentUdi, (contentUdi) => {
this._contentUdi = contentUdi;
});
this.observe(this.#context.blockTypeSettingsElementTypeKey, (blockTypeSettingsElementTypeKey) => {
this._hasSettings = !!blockTypeSettingsElementTypeKey;
});
this.observe(this.#context.label, (label) => {
this._blockViewProps.label = label;
this._label = label;
});
this.observe(this.#context.inlineEditingMode, (inlineEditingMode) => {
@@ -70,22 +83,32 @@ export class UmbPropertyEditorUIBlockListBlockElement extends UmbLitElement impl
}
#renderRefBlock() {
return html`<umb-ref-list-block .name=${this._label}></umb-ref-list-block>`;
return html`<umb-ref-list-block .label=${this._label}></umb-ref-list-block>`;
}
#renderInlineBlock() {
return html`<umb-inline-list-block .name=${this._label}></umb-inline-list-block>`;
return html`<umb-inline-list-block .label=${this._label}></umb-inline-list-block>`;
}
#renderBlock() {
return html`
${this._inlineEditingMode ? this.#renderInlineBlock() : this.#renderRefBlock()}
<umb-extension-slot
type="blockEditorCustomView"
default-element=${this._inlineEditingMode ? 'umb-inline-list-block' : 'umb-ref-list-block'}
.props=${this._blockViewProps}
>${this._inlineEditingMode ? this.#renderInlineBlock() : this.#renderRefBlock()}</umb-extension-slot
>
<uui-action-bar>
${this._workspaceEditPath
? html`<uui-button label="edit" compact href=${this._workspaceEditPath}>
<uui-icon name="icon-edit"></uui-icon>
</uui-button>`
: ''}
${this._workspaceEditPath && this._hasSettings
? html`<uui-button label="Edit settings" compact href=${this._workspaceEditPath + '/view/settings'}>
<uui-icon name="icon-settings"></uui-icon>
</uui-button>`
: ''}
<uui-button label="delete" compact @click=${this.#requestDelete}>
<uui-icon name="icon-remove"></uui-icon>
</uui-button>

View File

@@ -3,7 +3,7 @@ import type { UMB_BLOCK_WORKSPACE_CONTEXT } from '../../../block/index.js';
import { UMB_BLOCK_WORKSPACE_ALIAS } from '../../../block/index.js';
import { UmbExtensionsApiInitializer, createExtensionApi } from '@umbraco-cms/backoffice/extension-api';
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
import { css, customElement, html, state } from '@umbraco-cms/backoffice/external/lit';
import { css, customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
import '../../../block/workspace/views/edit/block-workspace-view-edit-no-router.element.js';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
@@ -17,8 +17,8 @@ export class UmbInlineListBlockElement extends UmbLitElement {
#workspaceContext?: typeof UMB_BLOCK_WORKSPACE_CONTEXT.TYPE;
#contentUdi?: string;
@state()
_label = '';
@property({ type: String })
label?: string;
@state()
_isOpen = false;
@@ -36,9 +36,6 @@ export class UmbInlineListBlockElement extends UmbLitElement {
},
'observeContentUdi',
);
this.observe(blockContext.label, (label) => {
this._label = label;
});
});
this.observe(umbExtensionsRegistry.getByTypeAndAlias('workspace', UMB_BLOCK_WORKSPACE_ALIAS), (manifest) => {
if (manifest) {
@@ -73,7 +70,7 @@ export class UmbInlineListBlockElement extends UmbLitElement {
}}>
<uui-icon name="icon-document"></uui-icon>
<uui-symbol-expand .open=${this._isOpen}></uui-symbol-expand>
<span>${this._label}</span>
<span>${this.label}</span>
</button>
${this._isOpen === true
? html`<umb-block-workspace-view-edit-no-router></umb-block-workspace-view-edit-no-router>`
@@ -82,6 +79,7 @@ export class UmbInlineListBlockElement extends UmbLitElement {
}
static styles = [
UmbTextStyles,
css`
#accordion-button {
display: flex;

View File

@@ -1,6 +1,5 @@
import { UMB_BLOCK_LIST_CONTEXT } from '../../context/block-list.context-token.js';
import { css, customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit';
import { UUIRefNodeElement } from '@umbraco-cms/backoffice/external/uui';
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
/**
@@ -10,7 +9,7 @@ import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
export class UmbRefListBlockElement extends UmbLitElement {
//
@property({ type: String })
name?: string;
label?: string;
@state()
_workspaceEditPath?: string;
@@ -31,13 +30,12 @@ export class UmbRefListBlockElement extends UmbLitElement {
render() {
// href=${this._workspaceEditPath ?? '#'}
return html`<uui-ref-node border .name=${this.name ?? ''}></uui-ref-node>`;
return html`<uui-ref-node border .name=${this.label ?? ''}></uui-ref-node>`;
}
static styles = [
...UUIRefNodeElement.styles,
css`
:host {
uui-ref-node {
min-height: var(--uui-size-16);
}
`,

View File

@@ -0,0 +1,42 @@
import { UMB_BLOCK_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/block';
import { UmbBaseController } from '@umbraco-cms/backoffice/class-api';
import type {
ManifestCondition,
UmbConditionConfigBase,
UmbConditionControllerArguments,
UmbExtensionCondition,
} from '@umbraco-cms/backoffice/extension-api';
export class UmbBlockWorkspaceHasSettingsCondition extends UmbBaseController implements UmbExtensionCondition {
config: BlockWorkspaceHasSettingsConditionConfig;
permitted = false;
#onChange: () => void;
constructor(args: UmbConditionControllerArguments<BlockWorkspaceHasSettingsConditionConfig>) {
super(args.host);
this.config = args.config;
this.#onChange = args.onChange;
// TODO: Rename the Block Context, so it gets a name.. like Block Entry Context or something.
this.consumeContext(UMB_BLOCK_WORKSPACE_CONTEXT, (context) => {
this.observe(
context.settings.contentTypeId,
(settingsContentTypeId) => {
this.permitted = !!settingsContentTypeId;
this.#onChange();
},
'observeSettingsElementTypeId',
);
});
}
}
export type BlockWorkspaceHasSettingsConditionConfig =
UmbConditionConfigBase<'Umb.Condition.BlockWorkspaceHasSettings'>;
export const manifest: ManifestCondition = {
type: 'condition',
name: 'Block Has Settings Condition',
alias: 'Umb.Condition.BlockWorkspaceHasSettings',
api: UmbBlockWorkspaceHasSettingsCondition,
};

View File

@@ -0,0 +1 @@
export * from './block-workspace-has-settings.condition.js';

View File

@@ -60,7 +60,7 @@ export abstract class UmbBlockContext<
}
constructor(host: UmbControllerHost, blockManagerContextToken: BlockManagerContextTokenType) {
super(host, UMB_BLOCK_CONTEXT.toString());
super(host, UMB_BLOCK_ENTITY_CONTEXT.toString());
// Consume block manager:
this.consumeContext(blockManagerContextToken, (manager) => {
@@ -198,6 +198,6 @@ export abstract class UmbBlockContext<
}
}
export const UMB_BLOCK_CONTEXT = new UmbContextToken<
export const UMB_BLOCK_ENTITY_CONTEXT = new UmbContextToken<
UmbBlockContext<typeof UMB_BLOCK_MANAGER_CONTEXT, typeof UMB_BLOCK_MANAGER_CONTEXT.TYPE>
>('UmbBlockContext');

View File

@@ -1 +1 @@
export * from './block.context.js';
export * from './block-entity.context.js';

View File

@@ -1,5 +1,6 @@
export * from './conditions/index.js';
export * from './context/index.js';
export * from './manager/index.js';
export * from './modals/index.js';
export * from './workspace/index.js';
export * from './types.js';
export * from './workspace/index.js';

View File

@@ -4,13 +4,8 @@ import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbArrayState, UmbClassState, UmbStringState } from '@umbraco-cms/backoffice/observable-api';
import { UmbDocumentTypeDetailRepository } from '@umbraco-cms/backoffice/document-type';
import { buildUdi, getKeyFromUdi } from '@umbraco-cms/backoffice/utils';
import type {
UmbBlockTypeBaseModel,
UmbBlockWorkspaceData} from '@umbraco-cms/backoffice/block';
import {
UMB_BLOCK_MANAGER_CONTEXT,
UMB_BLOCK_WORKSPACE_MODAL
} from '@umbraco-cms/backoffice/block';
import type { UmbBlockTypeBaseModel, UmbBlockWorkspaceData } from '@umbraco-cms/backoffice/block';
import { UMB_BLOCK_MANAGER_CONTEXT, UMB_BLOCK_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/block';
import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/modal';
import type { UmbContentTypeModel } from '@umbraco-cms/backoffice/content-type';
import { UmbId } from '@umbraco-cms/backoffice/id';
@@ -72,6 +67,7 @@ export abstract class UmbBlockManagerContext<
constructor(host: UmbControllerHost) {
super(host, UMB_BLOCK_MANAGER_CONTEXT);
// TODO: This might will need the property alias as part of the URL, to avoid collision if multiple of these Editor on same Node.
// IDEA: Make a Workspace registration controller that can be used to register a workspace, which does both edit and create?.
new UmbModalRouteRegistrationController(this, UMB_BLOCK_WORKSPACE_MODAL)
.addAdditionalPath('block')

View File

@@ -1,4 +1,5 @@
import { manifest as blockWorkspaceHasSettingsConditionManifest } from './conditions/block-workspace-has-settings.condition.js';
import { manifests as modalManifests } from './modals/manifests.js';
import { manifests as workspaceManifests } from './workspace/manifests.js';
export const manifests = [...modalManifests, ...workspaceManifests];
export const manifests = [...modalManifests, ...workspaceManifests, blockWorkspaceHasSettingsConditionManifest];

View File

@@ -10,6 +10,7 @@ import { UMB_BLOCK_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/block';
import { buildUdi } from '@umbraco-cms/backoffice/utils';
import { UMB_MODAL_CONTEXT } from '@umbraco-cms/backoffice/modal';
export type UmbBlockWorkspaceElementManagerNames = 'content' | 'settings';
export class UmbBlockWorkspaceContext<
LayoutDataType extends UmbBlockLayoutBaseModel = UmbBlockLayoutBaseModel,
> extends UmbEditableWorkspaceContextBase<LayoutDataType> {

View File

@@ -6,9 +6,9 @@ import type { UmbRoute } from '@umbraco-cms/backoffice/router';
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
import { UmbWorkspaceIsNewRedirectController } from '@umbraco-cms/backoffice/workspace';
import type { UmbApi} from '@umbraco-cms/backoffice/extension-api';
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
import { UmbExtensionsApiInitializer, createExtensionApi } from '@umbraco-cms/backoffice/extension-api';
import type { ManifestWorkspace} from '@umbraco-cms/backoffice/extension-registry';
import type { ManifestWorkspace } from '@umbraco-cms/backoffice/extension-registry';
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
import { decodeFilePath } from '@umbraco-cms/backoffice/utils';
@@ -31,7 +31,7 @@ export class UmbBlockWorkspaceElement extends UmbLitElement {
createExtensionApi(manifest, [this, { manifest: manifest }]).then((context) => {
if (context) {
this.#gotWorkspaceContext(context);
// TODO: We need to recreate when ID changed?
// TODO: Do we need to recreate when ID changed? Or is that a responsibility of the context it self?
new UmbExtensionsApiInitializer(this, umbExtensionsRegistry, 'workspaceContext', [
this,
this.#workspaceContext,

View File

@@ -41,6 +41,7 @@ export const manifests: Array<ManifestTypes> = [
label: 'Content',
pathname: 'content',
icon: 'icon-document',
blockElementManagerName: 'content',
},
conditions: [
{
@@ -48,5 +49,27 @@ export const manifests: Array<ManifestTypes> = [
match: UMB_BLOCK_WORKSPACE_ALIAS,
},
],
},
} as any,
{
type: 'workspaceView',
alias: 'Umb.WorkspaceView.Block.Settings',
name: 'Block Workspace Settings View',
js: () => import('./views/edit/block-workspace-view-edit.element.js'),
weight: 1000,
meta: {
label: 'Settings',
pathname: 'settings',
icon: 'icon-settings',
blockElementManagerName: 'settings',
},
conditions: [
{
alias: 'Umb.Condition.WorkspaceAlias',
match: UMB_BLOCK_WORKSPACE_ALIAS,
},
{
alias: 'Umb.Condition.BlockWorkspaceHasSettings',
},
],
} as any,
];

View File

@@ -39,7 +39,6 @@ export class UmbBlockWorkspaceViewEditNoRouterElement extends UmbLitElement impl
this.consumeContext(UMB_BLOCK_WORKSPACE_CONTEXT, (workspaceContext) => {
this._workspaceContext = workspaceContext;
console.log('workspaceContext.content.structure', workspaceContext.content.structure);
this._tabsStructureHelper.setStructureManager(workspaceContext.content.structure);
this._observeRootGroups();
});

View File

@@ -1,4 +1,5 @@
import { UMB_BLOCK_WORKSPACE_CONTEXT } from '../../block-workspace.context-token.js';
import type { UmbBlockWorkspaceElementManagerNames } from '../../block-workspace.context.js';
import { css, html, customElement, property, state, repeat } from '@umbraco-cms/backoffice/external/lit';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import type {
@@ -11,24 +12,34 @@ import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
@customElement('umb-block-workspace-view-edit-properties')
export class UmbBlockWorkspaceViewEditPropertiesElement extends UmbLitElement {
@property({ attribute: false })
public get managerName(): UmbBlockWorkspaceElementManagerNames | undefined {
return this.#managerName;
}
public set managerName(value: UmbBlockWorkspaceElementManagerNames | undefined) {
this.#managerName = value;
this.#setStructureManager();
}
#managerName?: UmbBlockWorkspaceElementManagerNames;
#blockWorkspace?: typeof UMB_BLOCK_WORKSPACE_CONTEXT.TYPE;
#propertyStructureHelper = new UmbContentTypePropertyStructureHelper<UmbContentTypeModel>(this);
@property({ type: String, attribute: 'container-name', reflect: false })
public get containerName(): string | undefined {
return this._propertyStructureHelper.getContainerName();
return this.#propertyStructureHelper.getContainerName();
}
public set containerName(value: string | undefined) {
this._propertyStructureHelper.setContainerName(value);
this.#propertyStructureHelper.setContainerName(value);
}
@property({ type: String, attribute: 'container-type', reflect: false })
public get containerType(): UmbPropertyContainerTypes | undefined {
return this._propertyStructureHelper.getContainerType();
return this.#propertyStructureHelper.getContainerType();
}
public set containerType(value: UmbPropertyContainerTypes | undefined) {
this._propertyStructureHelper.setContainerType(value);
this.#propertyStructureHelper.setContainerType(value);
}
_propertyStructureHelper = new UmbContentTypePropertyStructureHelper<UmbContentTypeModel>(this);
@state()
_propertyStructure: Array<UmbPropertyTypeModel> = [];
@@ -36,13 +47,23 @@ export class UmbBlockWorkspaceViewEditPropertiesElement extends UmbLitElement {
super();
this.consumeContext(UMB_BLOCK_WORKSPACE_CONTEXT, (workspaceContext) => {
this._propertyStructureHelper.setStructureManager(workspaceContext.content.structure);
});
this.observe(this._propertyStructureHelper.propertyStructure, (propertyStructure) => {
this._propertyStructure = propertyStructure;
this.#blockWorkspace = workspaceContext;
this.#setStructureManager();
});
}
#setStructureManager() {
if (!this.#blockWorkspace || !this.#managerName) return;
this.#propertyStructureHelper.setStructureManager(this.#blockWorkspace[this.#managerName].structure);
this.observe(
this.#propertyStructureHelper.propertyStructure,
(propertyStructure) => {
this._propertyStructure = propertyStructure;
},
'observePropertyStructure',
);
}
render() {
return repeat(
this._propertyStructure,

View File

@@ -7,29 +7,42 @@ import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
import type { PropertyTypeContainerModelBaseModel } from '@umbraco-cms/backoffice/backend-api';
import './block-workspace-view-edit-properties.element.js';
// eslint-disable-next-line import/order
import type { UmbBlockWorkspaceElementManagerNames } from '../../block-workspace.context.js';
@customElement('umb-block-workspace-view-edit-tab')
export class UmbBlockWorkspaceViewEditTabElement extends UmbLitElement {
private _tabName?: string | undefined;
@property({ attribute: false })
public get managerName(): UmbBlockWorkspaceElementManagerNames | undefined {
return this.#managerName;
}
public set managerName(value: UmbBlockWorkspaceElementManagerNames | undefined) {
this.#managerName = value;
this.#setStructureManager();
}
#managerName?: UmbBlockWorkspaceElementManagerNames;
#blockWorkspace?: typeof UMB_BLOCK_WORKSPACE_CONTEXT.TYPE;
#groupStructureHelper = new UmbContentTypeContainerStructureHelper<UmbContentTypeModel>(this);
@property({ type: String })
public get tabName(): string | undefined {
return this._groupStructureHelper.getName();
return this.#groupStructureHelper.getName();
}
public set tabName(value: string | undefined) {
if (value === this._tabName) return;
const oldValue = this._tabName;
this._tabName = value;
this._groupStructureHelper.setName(value);
this.#groupStructureHelper.setName(value);
this.requestUpdate('tabName', oldValue);
}
private _tabName?: string | undefined;
@property({ type: Boolean })
public get noTabName(): boolean {
return this._groupStructureHelper.getIsRoot();
return this.#groupStructureHelper.getIsRoot();
}
public set noTabName(value: boolean) {
this._groupStructureHelper.setIsRoot(value);
this.#groupStructureHelper.setIsRoot(value);
}
private _ownerTabId?: string | null;
@@ -40,7 +53,7 @@ export class UmbBlockWorkspaceViewEditTabElement extends UmbLitElement {
public set ownerTabId(value: string | null | undefined) {
if (value === this._ownerTabId) return;
this._ownerTabId = value;
this._groupStructureHelper.setOwnerId(value);
this.#groupStructureHelper.setOwnerId(value);
}
/**
@@ -50,8 +63,6 @@ export class UmbBlockWorkspaceViewEditTabElement extends UmbLitElement {
@property({ type: Boolean, reflect: false })
hideSingleGroup = false;
_groupStructureHelper = new UmbContentTypeContainerStructureHelper<UmbContentTypeModel>(this);
@state()
_groups: Array<PropertyTypeContainerModelBaseModel> = [];
@@ -62,16 +73,30 @@ export class UmbBlockWorkspaceViewEditTabElement extends UmbLitElement {
super();
this.consumeContext(UMB_BLOCK_WORKSPACE_CONTEXT, (workspaceContext) => {
this._groupStructureHelper.setStructureManager(workspaceContext.content.structure);
});
this.observe(this._groupStructureHelper.containers, (groups) => {
this._groups = groups;
});
this.observe(this._groupStructureHelper.hasProperties, (hasProperties) => {
this._hasProperties = hasProperties;
this.#blockWorkspace = workspaceContext;
this.#setStructureManager();
});
}
#setStructureManager() {
if (!this.#blockWorkspace || !this.#managerName) return;
this.#groupStructureHelper.setStructureManager(this.#blockWorkspace[this.#managerName].structure);
this.observe(
this.#groupStructureHelper.containers,
(groups) => {
this._groups = groups;
},
'observeGroups',
);
this.observe(
this.#groupStructureHelper.hasProperties,
(hasProperties) => {
this._hasProperties = hasProperties;
},
'observeHasProperties',
);
}
render() {
return html`
${this._hasProperties ? this.#renderPart(this._tabName) : ''}
@@ -86,11 +111,13 @@ export class UmbBlockWorkspaceViewEditTabElement extends UmbLitElement {
#renderPart(groupName: string | null | undefined, boxName?: string | null | undefined) {
return this.hideSingleGroup && this._groups.length === 1
? html` <umb-block-workspace-view-edit-properties
.managerName=${this.#managerName}
class="properties"
container-type="Group"
container-name=${groupName || ''}></umb-block-workspace-view-edit-properties>`
: html` <uui-box .headline=${boxName || ''}
><umb-block-workspace-view-edit-properties
.managerName=${this.#managerName}
class="properties"
container-type="Group"
container-name=${groupName || ''}></umb-block-workspace-view-edit-properties

View File

@@ -1,23 +1,34 @@
import { UMB_BLOCK_WORKSPACE_CONTEXT } from '../../block-workspace.context-token.js';
import type { UmbBlockWorkspaceElementManagerNames } from '../../block-workspace.context.js';
import type { UmbBlockWorkspaceViewEditTabElement } from './block-workspace-view-edit-tab.element.js';
import { css, html, customElement, state, repeat } from '@umbraco-cms/backoffice/external/lit';
import { css, html, customElement, state, repeat, property } from '@umbraco-cms/backoffice/external/lit';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import type { UmbContentTypeModel } from '@umbraco-cms/backoffice/content-type';
import { UmbContentTypeContainerStructureHelper } from '@umbraco-cms/backoffice/content-type';
import type {
UmbRoute,
UmbRouterSlotChangeEvent,
UmbRouterSlotInitEvent} from '@umbraco-cms/backoffice/router';
import {
encodeFolderName
} from '@umbraco-cms/backoffice/router';
import type { UmbRoute, UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router';
import { encodeFolderName } from '@umbraco-cms/backoffice/router';
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
import type { PropertyTypeContainerModelBaseModel } from '@umbraco-cms/backoffice/backend-api';
import type { UmbWorkspaceViewElement } from '@umbraco-cms/backoffice/extension-registry';
import type { ManifestWorkspaceView, UmbWorkspaceViewElement } from '@umbraco-cms/backoffice/extension-registry';
@customElement('umb-block-workspace-view-edit')
export class UmbBlockWorkspaceViewEditElement extends UmbLitElement implements UmbWorkspaceViewElement {
@property({ attribute: false })
public get manifest(): ManifestWorkspaceView | undefined {
return;
}
public set manifest(value: ManifestWorkspaceView | undefined) {
this.#managerName = (value?.meta as any).blockElementManagerName ?? 'content';
this.#setStructureManager();
}
#managerName?: UmbBlockWorkspaceElementManagerNames;
#blockWorkspace?: typeof UMB_BLOCK_WORKSPACE_CONTEXT.TYPE;
#tabsStructureHelper = new UmbContentTypeContainerStructureHelper<UmbContentTypeModel>(this);
//@state()
//private _hasRootProperties = false;
@state()
private _hasRootGroups = false;
@state()
@@ -32,44 +43,44 @@ export class UmbBlockWorkspaceViewEditElement extends UmbLitElement implements U
@state()
private _activePath = '';
private _workspaceContext?: typeof UMB_BLOCK_WORKSPACE_CONTEXT.TYPE;
private _tabsStructureHelper = new UmbContentTypeContainerStructureHelper<UmbContentTypeModel>(this);
constructor() {
super();
this._tabsStructureHelper.setIsRoot(true);
this._tabsStructureHelper.setContainerChildType('Tab');
this.observe(this._tabsStructureHelper.containers, (tabs) => {
this._tabs = tabs;
this._createRoutes();
});
this.#tabsStructureHelper.setIsRoot(true);
this.#tabsStructureHelper.setContainerChildType('Tab');
// _hasRootProperties can be gotten via _tabsStructureHelper.hasProperties. But we do not support root properties currently.
this.consumeContext(UMB_BLOCK_WORKSPACE_CONTEXT, (workspaceContext) => {
this._workspaceContext = workspaceContext;
this._tabsStructureHelper.setStructureManager(workspaceContext.content.structure);
this._observeRootGroups();
this.#blockWorkspace = workspaceContext;
this.#setStructureManager();
});
}
private _observeRootGroups() {
if (!this._workspaceContext) return;
#setStructureManager() {
if (!this.#blockWorkspace || !this.#managerName) return;
this.#tabsStructureHelper.setStructureManager(this.#blockWorkspace[this.#managerName].structure);
this.observe(
this._workspaceContext.content.structure.hasRootContainers('Group'),
this.#blockWorkspace![this.#managerName!].structure.hasRootContainers('Group'),
(hasRootGroups) => {
this._hasRootGroups = hasRootGroups;
this._createRoutes();
},
'_observeGroups',
'observeGroups',
);
this.observe(
this.#tabsStructureHelper.containers,
(tabs) => {
this._tabs = tabs;
this._createRoutes();
},
'observeTabs',
);
}
private _createRoutes() {
if (!this._tabs || !this._workspaceContext) return;
if (!this._tabs || !this.#blockWorkspace) return;
const routes: UmbRoute[] = [];
if (this._tabs.length > 0) {
@@ -79,10 +90,11 @@ export class UmbBlockWorkspaceViewEditElement extends UmbLitElement implements U
path: `tab/${encodeFolderName(tabName).toString()}`,
component: () => import('./block-workspace-view-edit-tab.element.js'),
setup: (component) => {
(component as UmbBlockWorkspaceViewEditTabElement).managerName = this.#managerName;
(component as UmbBlockWorkspaceViewEditTabElement).tabName = tabName;
// TODO: Consider if we can link these more simple, and not parse this on.
// Instead have the structure manager looking at wether one of the OwnerALikecontainers is in the owner document.
(component as UmbBlockWorkspaceViewEditTabElement).ownerTabId = this._tabsStructureHelper.isOwnerContainer(
(component as UmbBlockWorkspaceViewEditTabElement).ownerTabId = this.#tabsStructureHelper.isOwnerContainer(
tab.id!,
)
? tab.id
@@ -97,6 +109,7 @@ export class UmbBlockWorkspaceViewEditElement extends UmbLitElement implements U
path: '',
component: () => import('./block-workspace-view-edit-tab.element.js'),
setup: (component) => {
(component as UmbBlockWorkspaceViewEditTabElement).managerName = this.#managerName;
(component as UmbBlockWorkspaceViewEditTabElement).noTabName = true;
(component as UmbBlockWorkspaceViewEditTabElement).ownerTabId = null;
},

View File

@@ -1,6 +1,6 @@
import { type ManifestTypes, umbExtensionsRegistry } from '../../extension-registry/index.js';
import type { TemplateResult } from '@umbraco-cms/backoffice/external/lit';
import { css, repeat, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
import { css, repeat, customElement, property, state, html } from '@umbraco-cms/backoffice/external/lit';
import {
type UmbExtensionElementInitializer,
UmbExtensionsElementInitializer,
@@ -122,11 +122,13 @@ export class UmbExtensionSlotElement extends UmbLitElement {
}
render() {
return repeat(
this._permittedExts,
(ext) => ext.alias,
(ext) => (this.renderMethod ? this.renderMethod(ext) : ext.component),
);
return this._permittedExts.length > 0
? repeat(
this._permittedExts,
(ext) => ext.alias,
(ext) => (this.renderMethod ? this.renderMethod(ext) : ext.component),
)
: html`<slot></slot>`;
}
static styles = css`

View File

@@ -1,4 +1,5 @@
import { manifest as switchConditionManifest } from './switch.condition.js';
import { manifest as menuAliasConditionManifest } from './menu-alias.condition.js';
import { manifest as sectionAliasConditionManifest } from './section-alias.condition.js';
import { manifest as switchConditionManifest } from './switch.condition.js';
export const manifests = [switchConditionManifest, sectionAliasConditionManifest];
export const manifests = [menuAliasConditionManifest, sectionAliasConditionManifest, switchConditionManifest];

View File

@@ -2,6 +2,7 @@ import type { CollectionAliasConditionConfig } from '../../collection/collection
import type { SectionAliasConditionConfig } from './section-alias.condition.js';
import type { SwitchConditionConfig } from './switch.condition.js';
import type { UserPermissionConditionConfig } from '@umbraco-cms/backoffice/user-permission';
import type { BlockWorkspaceHasSettingsConditionConfig } from '@umbraco-cms/backoffice/block';
import type {
WorkspaceAliasConditionConfig,
WorkspaceEntityTypeConditionConfig,
@@ -16,6 +17,7 @@ export type ConditionTypes =
| CollectionAliasConditionConfig
| SectionAliasConditionConfig
| WorkspaceAliasConditionConfig
| BlockWorkspaceHasSettingsConditionConfig
| WorkspaceEntityTypeConditionConfig
| SwitchConditionConfig
| UserPermissionConditionConfig

View File

@@ -0,0 +1,6 @@
import type { UmbPropertyEditorUiElement } from '../interfaces/index.js';
import type { ManifestElement } from '@umbraco-cms/backoffice/extension-api';
export interface ManifestBlockEditorCustomView extends ManifestElement<UmbPropertyEditorUiElement> {
type: 'bockEditorCustomView';
}

View File

@@ -1,3 +1,4 @@
import type { ManifestBlockEditorCustomView } from './block-editor-custom-view.model.js';
import type { ManifestCollection } from './collection.models.js';
import type { ManifestCollectionView } from './collection-view.model.js';
import type { ManifestDashboard } from './dashboard.model.js';
@@ -40,6 +41,7 @@ import type {
ManifestEntryPoint,
} from '@umbraco-cms/backoffice/extension-api';
export type * from './block-editor-custom-view.model.js';
export type * from './collection.models.js';
export type * from './collection-action.model.js';
export type * from './collection-view.model.js';
@@ -79,6 +81,7 @@ export type * from './workspace.model.js';
export type ManifestTypes =
| ManifestBundle<ManifestTypes>
| ManifestCondition
| ManifestBlockEditorCustomView
| ManifestCollection
| ManifestCollectionView
| ManifestCollectionAction

View File

@@ -1,5 +1,5 @@
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import type { CSSResultGroup} from '@umbraco-cms/backoffice/external/lit';
import type { CSSResultGroup } from '@umbraco-cms/backoffice/external/lit';
import { css, html, customElement, property } from '@umbraco-cms/backoffice/external/lit';
import type { UmbWorkspaceData } from '@umbraco-cms/backoffice/modal';
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';

View File

@@ -11,14 +11,17 @@ import type { UmbWorkspaceViewElement } from '@umbraco-cms/backoffice/extension-
@customElement('umb-document-workspace-view-edit')
export class UmbDocumentWorkspaceViewEditElement extends UmbLitElement implements UmbWorkspaceViewElement {
//@state()
//private _hasRootProperties = false;
@state()
private _hasRootGroups = false;
@state()
private _routes: UmbRoute[] = [];
@state()
_tabs?: Array<PropertyTypeContainerModelBaseModel>;
private _tabs?: Array<PropertyTypeContainerModelBaseModel>;
@state()
private _routerPath?: string;