diff --git a/src/assets/lang/da-dk.ts b/src/assets/lang/da-dk.ts index 17d2f3271e..483843c117 100644 --- a/src/assets/lang/da-dk.ts +++ b/src/assets/lang/da-dk.ts @@ -2285,7 +2285,7 @@ export default { forceHideContentEditorHelp: 'Skjul indholds redigerings knappen samt indholdseditoren i Blok Redigerings vinduet', gridInlineEditing: 'Direkte redigering', gridInlineEditingHelp: - 'Tilføjer direkte redigering a det første felt. Yderligere felter optræder kun i redigerings vinduet.', + 'Tilføjer direkte redigering af det første felt. Yderligere felter optræder kun i redigerings vinduet.', blockHasChanges: 'Du har lavet ændringer til dette indhold. Er du sikker på at du vil kassere dem?', confirmCancelBlockCreationHeadline: 'Annuller oprettelse?', confirmCancelBlockCreationMessage: 'Er du sikker på at du vil annullere oprettelsen.', @@ -2361,6 +2361,9 @@ export default { allowBlockInAreas: 'Allow in areas', allowBlockInAreasHelp: 'Make this block available by default within the areas of other Blocks (unless explicit permissions are set for these areas).', + createThisFor: 'Opret %0% for %1%', + insertBlock: 'Indsæt Block', + labelInlineMode: 'Indsæt på linje med tekst', }, contentTemplatesDashboard: { whatHeadline: 'Hvad er Indholdsskabeloner?', diff --git a/src/assets/lang/en-us.ts b/src/assets/lang/en-us.ts index f14e5b19fc..812586f5c8 100644 --- a/src/assets/lang/en-us.ts +++ b/src/assets/lang/en-us.ts @@ -2510,6 +2510,9 @@ export default { configureArea: 'Configure area', deleteArea: 'Delete area', addColumnSpanOption: 'Add spanning %0% columns option', + createThisFor: 'Create %0% for %1%', + insertBlock: 'Insert Block', + labelInlineMode: 'Display inline with text', }, contentTemplatesDashboard: { whatHeadline: 'What are Document Blueprints?', diff --git a/src/assets/lang/en.ts b/src/assets/lang/en.ts index 816ef955ea..18827472af 100644 --- a/src/assets/lang/en.ts +++ b/src/assets/lang/en.ts @@ -2571,6 +2571,7 @@ export default { configureArea: 'Configure area', deleteArea: 'Delete area', addColumnSpanOption: 'Add spanning %0% columns option', + createThisFor: 'Create %0% for %1%', insertBlock: 'Insert Block', labelInlineMode: 'Display inline with text', }, diff --git a/src/packages/block/block-list/context/block-list-entries.context.ts b/src/packages/block/block-list/context/block-list-entries.context.ts index 6d6b573564..2e20c5836e 100644 --- a/src/packages/block/block-list/context/block-list-entries.context.ts +++ b/src/packages/block/block-list/context/block-list-entries.context.ts @@ -141,7 +141,11 @@ export class UmbBlockListEntriesContext extends UmbBlockEntriesContext< originData: UmbBlockListWorkspaceOriginData, ) { await this._retrieveManager; - return this._manager?.insert(layoutEntry, content, settings, originData) ?? false; + const success = this._manager?.insert(layoutEntry, content, settings, originData) ?? false; + if (success) { + this._manager?.setOneExpose(layoutEntry.contentKey); + } + return success; } // create Block? diff --git a/src/packages/block/block/context/block-entry.context.ts b/src/packages/block/block/context/block-entry.context.ts index e21288f03e..03d92d381b 100644 --- a/src/packages/block/block/context/block-entry.context.ts +++ b/src/packages/block/block/context/block-entry.context.ts @@ -566,7 +566,7 @@ export abstract class UmbBlockEntryContext< if (!variantId || !this.#contentKey) return; // TODO: Handle variantId changes this.observe( - this._manager?.hasExposeOf(this.#contentKey, variantId), + this._manager?.hasExposeOf(this.#contentKey), (hasExpose) => { this.#hasExpose.setValue(hasExpose); }, @@ -604,9 +604,8 @@ export abstract class UmbBlockEntryContext< } public expose() { - const variantId = this.#variantId.getValue(); - if (!this.#contentKey || !variantId) return; - this._manager?.setOneExpose(this.#contentKey, variantId); + if (!this.#contentKey) return; + this._manager?.setOneExpose(this.#contentKey); } //copy diff --git a/src/packages/block/block/context/block-manager.context.ts b/src/packages/block/block/context/block-manager.context.ts index e823da7bfd..ffb1de2a12 100644 --- a/src/packages/block/block/context/block-manager.context.ts +++ b/src/packages/block/block/context/block-manager.context.ts @@ -3,7 +3,13 @@ import type { UmbBlockLayoutBaseModel, UmbBlockDataModel, UmbBlockExposeModel } import { UMB_BLOCK_MANAGER_CONTEXT } from './block-manager.context-token.js'; import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import { UmbArrayState, UmbBooleanState, UmbClassState, UmbStringState } from '@umbraco-cms/backoffice/observable-api'; +import { + UmbArrayState, + UmbBooleanState, + UmbClassState, + UmbStringState, + mergeObservables, +} from '@umbraco-cms/backoffice/observable-api'; import { UmbDocumentTypeDetailRepository } from '@umbraco-cms/backoffice/document-type'; import { UmbContentTypeStructureManager, type UmbContentTypeModel } from '@umbraco-cms/backoffice/content-type'; import { UmbId } from '@umbraco-cms/backoffice/id'; @@ -170,12 +176,18 @@ export abstract class UmbBlockManagerContext< settingsOf(key: string) { return this.#settings.asObservablePart((source) => source.find((x) => x.key === key)); } - exposeOf(contentKey: string, variantId: UmbVariantId) { - return this.#exposes.asObservablePart((source) => - source.filter((x) => x.contentKey === contentKey && variantId.compare(x)), + currentExposeOf(contentKey: string) { + const variantId = this.#variantId.getValue(); + if (!variantId) return; + return mergeObservables( + [this.#exposes.asObservablePart((source) => source.filter((x) => x.contentKey === contentKey)), this.variantId], + ([exposes, variantId]) => (variantId ? exposes.find((x) => variantId.compare(x)) : undefined), ); } - hasExposeOf(contentKey: string, variantId: UmbVariantId) { + + hasExposeOf(contentKey: string) { + const variantId = this.#variantId.getValue(); + if (!variantId) return; return this.#exposes.asObservablePart((source) => source.some((x) => x.contentKey === contentKey && variantId.compare(x)), ); @@ -196,7 +208,9 @@ export abstract class UmbBlockManagerContext< setOneSettings(settingsData: UmbBlockDataModel) { this.#settings.appendOne(settingsData); } - setOneExpose(contentKey: string, variantId: UmbVariantId) { + setOneExpose(contentKey: string) { + const variantId = this.#variantId.getValue(); + if (!variantId) return; this.#exposes.appendOne({ contentKey, ...variantId.toObject() }); } @@ -209,7 +223,9 @@ export abstract class UmbBlockManagerContext< removeExposesOf(contentKey: string) { this.#exposes.filter((x) => x.contentKey !== contentKey); } - removeOneExpose(contentKey: string, variantId: UmbVariantId) { + removeCurrentExpose(contentKey: string) { + const variantId = this.#variantId.getValue(); + if (!variantId) return; this.#exposes.filter((x) => !(x.contentKey === contentKey && variantId.compare(x))); } diff --git a/src/packages/block/block/workspace/block-workspace.context.ts b/src/packages/block/block/workspace/block-workspace.context.ts index 5138075110..4c0ad16a16 100644 --- a/src/packages/block/block/workspace/block-workspace.context.ts +++ b/src/packages/block/block/workspace/block-workspace.context.ts @@ -118,19 +118,19 @@ export class UmbBlockWorkspaceContext { - if (!variantId || !contentKey) return; + this.contentKey, + (contentKey) => { + if (!contentKey) return; this.observe( - manager.hasExposeOf(contentKey, variantId), + manager.hasExposeOf(contentKey), (exposed) => { this.#exposed.setValue(exposed); }, 'observeHasExpose', ); }, - 'observeVariantIdContentKey', + 'observeContentKey', ); }).asPromise(); @@ -462,13 +462,14 @@ export class UmbBlockWorkspaceContext { diff --git a/src/packages/block/block/workspace/views/edit/block-workspace-view-edit-content-no-router.element.ts b/src/packages/block/block/workspace/views/edit/block-workspace-view-edit-content-no-router.element.ts index 33a9972bdb..29a1e01e71 100644 --- a/src/packages/block/block/workspace/views/edit/block-workspace-view-edit-content-no-router.element.ts +++ b/src/packages/block/block/workspace/views/edit/block-workspace-view-edit-content-no-router.element.ts @@ -1,11 +1,12 @@ import { UMB_BLOCK_WORKSPACE_CONTEXT } from '../../block-workspace.context-token.js'; import './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, nothing } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbContentTypeContainerStructureHelper } from '@umbraco-cms/backoffice/content-type'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import type { UmbPropertyTypeContainerModel } from '@umbraco-cms/backoffice/content-type'; import type { UmbWorkspaceViewElement } from '@umbraco-cms/backoffice/workspace'; +import { UmbLanguageItemRepository } from '@umbraco-cms/backoffice/language'; /** * @element umb-block-workspace-view-edit-content-no-router @@ -25,11 +26,19 @@ export class UmbBlockWorkspaceViewEditContentNoRouterElement extends UmbLitEleme @state() private _activeTabId?: string | null | undefined; + //@state() + //private _activeTabName?: string | null | undefined; + @state() - private _activeTabName?: string | null | undefined; + private _ownerContentTypeName?: string; - #blockWorkspace?: typeof UMB_BLOCK_WORKSPACE_CONTEXT.TYPE; + @state() + private _variantName?: string; + + @state() + private _exposed?: boolean; + #blockWorkspace?: typeof UMB_BLOCK_WORKSPACE_CONTEXT.TYPE; #tabsStructureHelper = new UmbContentTypeContainerStructureHelper(this); constructor() { @@ -44,12 +53,45 @@ export class UmbBlockWorkspaceViewEditContentNoRouterElement extends UmbLitEleme // _hasRootProperties can be gotten via _tabsStructureHelper.hasProperties. But we do not support root properties currently. - this.consumeContext(UMB_BLOCK_WORKSPACE_CONTEXT, (workspaceContext) => { - this.#blockWorkspace = workspaceContext; - this.#tabsStructureHelper.setStructureManager(workspaceContext.content.structure); + this.consumeContext(UMB_BLOCK_WORKSPACE_CONTEXT, (context) => { + this.#blockWorkspace = context; + this.#tabsStructureHelper.setStructureManager(context.content.structure); - workspaceContext.content.setup(this); + context.content.setup(this); this.#observeRootGroups(); + + this.observe( + context.content.structure.ownerContentTypeName, + (name) => { + this._ownerContentTypeName = name; + }, + 'observeContentTypeName', + ); + + this.observe( + context.variantId, + async (variantId) => { + if (variantId) { + // TODO: Support segment name? + const culture = variantId.culture; + if (culture) { + const languageRepository = new UmbLanguageItemRepository(this); + const { data } = await languageRepository.requestItems([culture]); + const name = data?.[0].name; + this._variantName = name ? this.localize.string(name) : undefined; + } + } + }, + 'observeVariant', + ); + + this.observe( + context.exposed, + (exposed) => { + this._exposed = exposed; + }, + 'observeExposed', + ); }); } @@ -72,21 +114,33 @@ export class UmbBlockWorkspaceViewEditContentNoRouterElement extends UmbLitEleme // Find the default tab to grab: if (this._activeTabId === undefined) { if (this._hasRootGroups) { - this._activeTabName = null; + //this._activeTabName = null; this._activeTabId = null; } else if (this._tabs.length > 0) { - this._activeTabName = this._tabs[0].name; + //this._activeTabName = this._tabs[0].name; this._activeTabId = this._tabs[0].id; } } } #setTabName(tabName: string | undefined | null, tabId: string | null | undefined) { - this._activeTabName = tabName; + //this._activeTabName = tabName; this._activeTabId = tabId; } + #expose = () => { + this.#blockWorkspace?.expose(); + }; + override render() { + if (this._exposed === false) { + return html` + `; + } if (!this._tabs) return; return html` ${this._tabs.length > 1 || (this._tabs.length === 1 && this._hasRootGroups) @@ -100,7 +154,7 @@ export class UmbBlockWorkspaceViewEditContentNoRouterElement extends UmbLitEleme >Content ` - : ''} + : nothing} ${repeat( this._tabs, (tab) => tab.name, @@ -114,14 +168,14 @@ export class UmbBlockWorkspaceViewEditContentNoRouterElement extends UmbLitEleme }, )} ` - : ''} + : nothing} ${this._activeTabId !== undefined ? html` ` - : ''} + : nothing} `; } @@ -129,6 +183,7 @@ export class UmbBlockWorkspaceViewEditContentNoRouterElement extends UmbLitEleme UmbTextStyles, css` :host { + position: relative; display: block; height: 100%; --uui-tab-background: var(--uui-color-surface); diff --git a/src/packages/core/content-type/structure/content-type-structure-manager.class.ts b/src/packages/core/content-type/structure/content-type-structure-manager.class.ts index 3ff0363183..2cc6b7187f 100644 --- a/src/packages/core/content-type/structure/content-type-structure-manager.class.ts +++ b/src/packages/core/content-type/structure/content-type-structure-manager.class.ts @@ -45,12 +45,9 @@ export class UmbContentTypeStructureManager< readonly ownerContentType = this.#contentTypes.asObservablePart((x) => x.find((y) => y.unique === this.#ownerContentTypeUnique), ); - readonly ownerContentTypeAlias = this.#contentTypes.asObservablePart( - (x) => x.find((y) => y.unique === this.#ownerContentTypeUnique)?.alias, - ); - readonly ownerContentTypeCompositions = this.#contentTypes.asObservablePart( - (x) => x.find((y) => y.unique === this.#ownerContentTypeUnique)?.compositions, - ); + readonly ownerContentTypeAlias = createObservablePart(this.ownerContentType, (x) => x?.alias); + readonly ownerContentTypeName = createObservablePart(this.ownerContentType, (x) => x?.name); + readonly ownerContentTypeCompositions = createObservablePart(this.ownerContentType, (x) => x?.compositions); readonly #contentTypeContainers = this.#contentTypes.asObservablePart((contentTypes) => { // Notice this may need to use getValue to avoid resetting it self. [NL] diff --git a/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/packages/documents/documents/workspace/document-workspace.context.ts index a082d780ae..e6590a0620 100644 --- a/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -101,6 +101,10 @@ export class UmbDocumentWorkspaceContext // TODo: Optimize this so it uses either a App Language Context? [NL] #languageRepository = new UmbLanguageCollectionRepository(this); #languages = new UmbArrayState([], (x) => x.unique); + /** + * @private + * @description - Should not be used by external code. + */ public readonly languages = this.#languages.asObservable(); #serverValidation = new UmbServerModelValidatorContext(this);