diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 9811efe485..942b806671 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -24,6 +24,7 @@ "./code-editor": "./dist-cms/packages/templating/code-editor/index.js", "./collection": "./dist-cms/packages/core/collection/index.js", "./components": "./dist-cms/packages/core/components/index.js", + "./content": "./dist-cms/packages/core/content/index.js", "./content-type": "./dist-cms/packages/core/content-type/index.js", "./culture": "./dist-cms/packages/core/culture/index.js", "./current-user": "./dist-cms/packages/user/current-user/index.js", diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-structure-manager.class.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-structure-manager.class.ts index 8140888825..22aafbf7b8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-structure-manager.class.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-structure-manager.class.ts @@ -26,7 +26,9 @@ import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; * - {@link UmbContentTypePropertyStructureHelper} for managing the structure of properties, optional of another container or root. * - {@link UmbContentTypeContainerStructureHelper} for managing the structure of containers, optional of another container or root. */ -export class UmbContentTypeStructureManager extends UmbControllerBase { +export class UmbContentTypeStructureManager< + T extends UmbContentTypeModel = UmbContentTypeModel, +> extends UmbControllerBase { #init!: Promise; #repository: UmbDetailRepository; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/manifests.ts new file mode 100644 index 0000000000..18e532ebf8 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/manifests.ts @@ -0,0 +1,3 @@ +import { manifests as workspaceManifests } from './workspace/manifests.js'; + +export const manifests = [...workspaceManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/manifests.ts new file mode 100644 index 0000000000..d30be86fd2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/manifests.ts @@ -0,0 +1,3 @@ +import { contentEditorManifest } from './views/edit/manifest.js'; + +export const manifests = [contentEditorManifest]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/views/edit/document-workspace-view-edit-properties.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/views/edit/content-editor-properties.element.ts similarity index 64% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/views/edit/document-workspace-view-edit-properties.element.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/views/edit/content-editor-properties.element.ts index e438e2e50a..4bb240de46 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/views/edit/document-workspace-view-edit-properties.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/views/edit/content-editor-properties.element.ts @@ -1,14 +1,17 @@ -import { UMB_DOCUMENT_WORKSPACE_CONTEXT } from '../../document-workspace.context-token.js'; import { css, html, customElement, property, state, repeat } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import type { UmbPropertyTypeModel } from '@umbraco-cms/backoffice/content-type'; +import type { + UmbContentTypeModel, + UmbContentTypeStructureManager, + UmbPropertyTypeModel, +} from '@umbraco-cms/backoffice/content-type'; import { UmbContentTypePropertyStructureHelper } from '@umbraco-cms/backoffice/content-type'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import type { UmbDocumentTypeDetailModel } from '@umbraco-cms/backoffice/document-type'; import { UmbDataPathValueFilter } from '@umbraco-cms/backoffice/validation'; +import { UMB_PROPERTY_STRUCTURE_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace'; -@customElement('umb-document-workspace-view-edit-properties') -export class UmbDocumentWorkspaceViewEditPropertiesElement extends UmbLitElement { +@customElement('umb-content-workspace-view-edit-properties') +export class UmbContentWorkspaceViewEditPropertiesElement extends UmbLitElement { @property({ type: String, attribute: 'container-id', reflect: false }) public get containerId(): string | null | undefined { return this.#propertyStructureHelper.getContainerId(); @@ -17,7 +20,7 @@ export class UmbDocumentWorkspaceViewEditPropertiesElement extends UmbLitElement this.#propertyStructureHelper.setContainerId(value); } - #propertyStructureHelper = new UmbContentTypePropertyStructureHelper(this); + #propertyStructureHelper = new UmbContentTypePropertyStructureHelper(this); @state() _propertyStructure?: Array; @@ -25,8 +28,11 @@ export class UmbDocumentWorkspaceViewEditPropertiesElement extends UmbLitElement constructor() { super(); - this.consumeContext(UMB_DOCUMENT_WORKSPACE_CONTEXT, (workspaceContext) => { - this.#propertyStructureHelper.setStructureManager(workspaceContext.structure); + this.consumeContext(UMB_PROPERTY_STRUCTURE_WORKSPACE_CONTEXT, (workspaceContext) => { + this.#propertyStructureHelper.setStructureManager( + // Assuming its the same content model type that we are working with here... [NL] + workspaceContext.structure as unknown as UmbContentTypeStructureManager, + ); }); this.observe( this.#propertyStructureHelper.propertyStructure, @@ -64,10 +70,10 @@ export class UmbDocumentWorkspaceViewEditPropertiesElement extends UmbLitElement ]; } -export default UmbDocumentWorkspaceViewEditPropertiesElement; +export default UmbContentWorkspaceViewEditPropertiesElement; declare global { interface HTMLElementTagNameMap { - 'umb-document-workspace-view-edit-properties': UmbDocumentWorkspaceViewEditPropertiesElement; + 'umb-content-workspace-view-edit-properties': UmbContentWorkspaceViewEditPropertiesElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/views/edit/document-workspace-view-edit-tab.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/views/edit/content-editor-tab.element.ts similarity index 58% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/views/edit/document-workspace-view-edit-tab.element.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/views/edit/content-editor-tab.element.ts index 4d1e83bc18..6319792753 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/views/edit/document-workspace-view-edit-tab.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/views/edit/content-editor-tab.element.ts @@ -1,13 +1,17 @@ -import { UMB_DOCUMENT_WORKSPACE_CONTEXT } from '../../document-workspace.context-token.js'; import { css, html, customElement, property, state, repeat } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import type { UmbPropertyTypeContainerModel } from '@umbraco-cms/backoffice/content-type'; +import type { + UmbContentTypeModel, + UmbContentTypeStructureManager, + UmbPropertyTypeContainerModel, +} from '@umbraco-cms/backoffice/content-type'; import { UmbContentTypeContainerStructureHelper } from '@umbraco-cms/backoffice/content-type'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UMB_PROPERTY_STRUCTURE_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace'; +import './content-editor-properties.element.js'; -import './document-workspace-view-edit-properties.element.js'; -@customElement('umb-document-workspace-view-edit-tab') -export class UmbDocumentWorkspaceViewEditTabElement extends UmbLitElement { +@customElement('umb-content-workspace-view-edit-tab') +export class UmbContentWorkspaceViewEditTabElement extends UmbLitElement { @property({ type: String }) public get containerId(): string | null | undefined { return this._containerId; @@ -19,7 +23,7 @@ export class UmbDocumentWorkspaceViewEditTabElement extends UmbLitElement { @state() private _containerId?: string | null; - #groupStructureHelper = new UmbContentTypeContainerStructureHelper(this); + #groupStructureHelper = new UmbContentTypeContainerStructureHelper(this); @state() _groups: Array = []; @@ -30,8 +34,11 @@ export class UmbDocumentWorkspaceViewEditTabElement extends UmbLitElement { constructor() { super(); - this.consumeContext(UMB_DOCUMENT_WORKSPACE_CONTEXT, (workspaceContext) => { - this.#groupStructureHelper.setStructureManager(workspaceContext.structure); + this.consumeContext(UMB_PROPERTY_STRUCTURE_WORKSPACE_CONTEXT, (workspaceContext) => { + this.#groupStructureHelper.setStructureManager( + // Assuming its the same content model type that we are working with here... [NL] + workspaceContext.structure as unknown as UmbContentTypeStructureManager, + ); }); this.observe(this.#groupStructureHelper.mergedContainers, (groups) => { this._groups = groups; @@ -46,9 +53,9 @@ export class UmbDocumentWorkspaceViewEditTabElement extends UmbLitElement { ${this._hasProperties ? html` - + .containerId=${this._containerId}> ` : ''} @@ -57,9 +64,9 @@ export class UmbDocumentWorkspaceViewEditTabElement extends UmbLitElement { (group) => group.id, (group) => html` - + .containerId=${group.id}> `, )} `; @@ -78,10 +85,10 @@ export class UmbDocumentWorkspaceViewEditTabElement extends UmbLitElement { ]; } -export default UmbDocumentWorkspaceViewEditTabElement; +export default UmbContentWorkspaceViewEditTabElement; declare global { interface HTMLElementTagNameMap { - 'umb-document-workspace-view-edit-tab': UmbDocumentWorkspaceViewEditTabElement; + 'umb-content-workspace-view-edit-tab': UmbContentWorkspaceViewEditTabElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/views/edit/document-workspace-view-edit.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/views/edit/content-editor.element.ts similarity index 74% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/views/edit/document-workspace-view-edit.element.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/views/edit/content-editor.element.ts index ecb678fe43..fa0dcdf51e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/views/edit/document-workspace-view-edit.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/views/edit/content-editor.element.ts @@ -1,16 +1,21 @@ -import { UMB_DOCUMENT_WORKSPACE_CONTEXT } from '../../document-workspace.context-token.js'; -import type { UmbDocumentWorkspaceViewEditTabElement } from './document-workspace-view-edit-tab.element.js'; +import type { UmbContentWorkspaceViewEditTabElement } from './content-editor-tab.element.js'; import { css, html, customElement, state, repeat } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import type { UmbPropertyTypeContainerModel } from '@umbraco-cms/backoffice/content-type'; +import type { + UmbContentTypeModel, + UmbContentTypeStructureManager, + UmbPropertyTypeContainerModel, +} 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 { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import type { UmbWorkspaceViewElement } from '@umbraco-cms/backoffice/extension-registry'; +import { UMB_PROPERTY_STRUCTURE_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace'; +import './content-editor-tab.element.js'; -@customElement('umb-document-workspace-view-edit') -export class UmbDocumentWorkspaceViewEditElement extends UmbLitElement implements UmbWorkspaceViewElement { +@customElement('umb-content-workspace-view-edit') +export class UmbContentWorkspaceViewEditElement extends UmbLitElement implements UmbWorkspaceViewElement { //@state() //private _hasRootProperties = false; @@ -29,9 +34,9 @@ export class UmbDocumentWorkspaceViewEditElement extends UmbLitElement implement @state() private _activePath = ''; - private _workspaceContext?: typeof UMB_DOCUMENT_WORKSPACE_CONTEXT.TYPE; + #structureManager?: UmbContentTypeStructureManager; - private _tabsStructureHelper = new UmbContentTypeContainerStructureHelper(this); + private _tabsStructureHelper = new UmbContentTypeContainerStructureHelper(this); constructor() { super(); @@ -49,18 +54,18 @@ export class UmbDocumentWorkspaceViewEditElement extends UmbLitElement implement // _hasRootProperties can be gotten via _tabsStructureHelper.hasProperties. But we do not support root properties currently. - this.consumeContext(UMB_DOCUMENT_WORKSPACE_CONTEXT, (workspaceContext) => { - this._workspaceContext = workspaceContext; + this.consumeContext(UMB_PROPERTY_STRUCTURE_WORKSPACE_CONTEXT, (workspaceContext) => { + this.#structureManager = workspaceContext.structure; this._tabsStructureHelper.setStructureManager(workspaceContext.structure); this._observeRootGroups(); }); } private _observeRootGroups() { - if (!this._workspaceContext) return; + if (!this.#structureManager) return; this.observe( - this._workspaceContext.structure.hasRootContainers('Group'), + this.#structureManager.hasRootContainers('Group'), (hasRootGroups) => { this._hasRootGroups = hasRootGroups; this._createRoutes(); @@ -70,7 +75,7 @@ export class UmbDocumentWorkspaceViewEditElement extends UmbLitElement implement } private _createRoutes() { - if (!this._tabs || !this._workspaceContext) return; + if (!this._tabs || !this.#structureManager) return; const routes: UmbRoute[] = []; if (this._tabs.length > 0) { @@ -78,9 +83,9 @@ export class UmbDocumentWorkspaceViewEditElement extends UmbLitElement implement const tabName = tab.name ?? ''; routes.push({ path: `tab/${encodeFolderName(tabName).toString()}`, - component: () => import('./document-workspace-view-edit-tab.element.js'), + component: () => import('./content-editor-tab.element.js'), setup: (component) => { - (component as UmbDocumentWorkspaceViewEditTabElement).containerId = tab.id; + (component as UmbContentWorkspaceViewEditTabElement).containerId = tab.id; }, }); }); @@ -89,9 +94,9 @@ export class UmbDocumentWorkspaceViewEditElement extends UmbLitElement implement if (this._hasRootGroups) { routes.push({ path: '', - component: () => import('./document-workspace-view-edit-tab.element.js'), + component: () => import('./content-editor-tab.element.js'), setup: (component) => { - (component as UmbDocumentWorkspaceViewEditTabElement).containerId = null; + (component as UmbContentWorkspaceViewEditTabElement).containerId = null; }, }); } @@ -166,10 +171,10 @@ export class UmbDocumentWorkspaceViewEditElement extends UmbLitElement implement ]; } -export default UmbDocumentWorkspaceViewEditElement; +export default UmbContentWorkspaceViewEditElement; declare global { interface HTMLElementTagNameMap { - 'umb-document-workspace-view-edit': UmbDocumentWorkspaceViewEditElement; + 'umb-content-workspace-view-edit': UmbContentWorkspaceViewEditElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/views/edit/manifest.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/views/edit/manifest.ts new file mode 100644 index 0000000000..3cb898bd97 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/views/edit/manifest.ts @@ -0,0 +1,19 @@ +import type { UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const contentEditorManifest: UmbBackofficeManifestKind = { + type: 'kind', + alias: 'Umb.Kind.WorkspaceView.ContentEditor', + matchKind: 'contentEditor', + matchType: 'workspaceView', + manifest: { + type: 'workspaceView', + kind: 'contentEditor', + element: () => import('./content-editor.element.js'), + weight: 1000, + meta: { + label: 'Content', + pathname: 'edit', + icon: 'icon-document-line', + }, + }, +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/manifests.ts index 14d59db61a..492e43c337 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/manifests.ts @@ -1,4 +1,5 @@ import { manifests as collectionManifests } from './collection/manifests.js'; +import { manifests as contentManifests } from './content/manifests.js'; import { manifests as contentTypeManifests } from './content-type/manifests.js'; import { manifests as cultureManifests } from './culture/manifests.js'; import { manifests as debugManifests } from './debug/manifests.js'; @@ -26,6 +27,7 @@ export const manifests: Array = [ ...treeManifests, ...collectionManifests, ...workspaceManifests, + ...contentManifests, ...contentTypeManifests, ...propertyEditorManifests, ...settingsManifests, diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/contexts/tokens/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/contexts/tokens/index.ts index 59e2bc1381..69ba11bc07 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/contexts/tokens/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/contexts/tokens/index.ts @@ -1,5 +1,6 @@ export * from './collection-workspace.context-token.js'; export * from './entity-workspace.context-token.js'; +export * from './property-structure-workspace.context-token.js'; export * from './publishable-workspace.context-token.js'; export * from './routable-workspace.context-token.js'; export * from './submittable-workspace.context-token.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/contexts/tokens/property-structure-workspace-context.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/contexts/tokens/property-structure-workspace-context.interface.ts index 682abaa2e6..07e5f045d0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/contexts/tokens/property-structure-workspace-context.interface.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/contexts/tokens/property-structure-workspace-context.interface.ts @@ -1,7 +1,12 @@ import type { UmbEntityWorkspaceContext } from './entity-workspace-context.interface.js'; +import type { UmbContentTypeModel, UmbContentTypeStructureManager } from '@umbraco-cms/backoffice/content-type'; import type { Observable } from '@umbraco-cms/backoffice/external/rxjs'; import type { UmbVariantPropertyValueModel } from '@umbraco-cms/backoffice/variant'; -export interface UmbPropertyStructureWorkspaceContext extends UmbEntityWorkspaceContext { +export interface UmbPropertyStructureWorkspaceContext< + ContentTypeModel extends UmbContentTypeModel = UmbContentTypeModel, +> extends UmbEntityWorkspaceContext { + structure: UmbContentTypeStructureManager; + // TODO: propertyStructureById is not used by anything in the codebase, should we remove it? [NL] propertyStructureById(id: string): Promise>; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/manifests.ts index a46f146d5c..adb25f6266 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/manifests.ts @@ -47,10 +47,9 @@ const workspaceViews: Array = [ }, { type: 'workspaceView', + kind: 'contentEditor', alias: 'Umb.WorkspaceView.Document.Edit', name: 'Document Workspace Edit View', - element: () => import('./views/edit/document-workspace-view-edit.element.js'), - weight: 200, meta: { label: 'Content', pathname: 'content', diff --git a/src/Umbraco.Web.UI.Client/tsconfig.json b/src/Umbraco.Web.UI.Client/tsconfig.json index 50c7d953fd..bc12880ae4 100644 --- a/src/Umbraco.Web.UI.Client/tsconfig.json +++ b/src/Umbraco.Web.UI.Client/tsconfig.json @@ -42,6 +42,7 @@ "@umbraco-cms/backoffice/code-editor": ["./src/packages/templating/code-editor/index.ts"], "@umbraco-cms/backoffice/collection": ["./src/packages/core/collection/index.ts"], "@umbraco-cms/backoffice/components": ["./src/packages/core/components/index.ts"], + "@umbraco-cms/backoffice/content": ["./src/packages/core/content/index.ts"], "@umbraco-cms/backoffice/content-type": ["./src/packages/core/content-type/index.ts"], "@umbraco-cms/backoffice/culture": ["./src/packages/core/culture/index.ts"], "@umbraco-cms/backoffice/current-user": ["./src/packages/user/current-user/index.ts"],