From bac646f5144c8b631f24b953e0f70d639f5d474d Mon Sep 17 00:00:00 2001 From: Will Ezell Date: Wed, 14 Jan 2026 14:32:50 -0500 Subject: [PATCH 1/5] fix(containers): this re-adds the hostname to the container object api response ref: #34296 --- .../portlets/containers/model/Container.java | 16 ++++++++++++++++ .../containers/model/FileAssetContainer.java | 3 +++ .../containers/model/SystemContainer.java | 13 +++++++++++++ 3 files changed, 32 insertions(+) diff --git a/dotCMS/src/main/java/com/dotmarketing/portlets/containers/model/Container.java b/dotCMS/src/main/java/com/dotmarketing/portlets/containers/model/Container.java index 0db7e42efead..5bbe71c3429e 100644 --- a/dotCMS/src/main/java/com/dotmarketing/portlets/containers/model/Container.java +++ b/dotCMS/src/main/java/com/dotmarketing/portlets/containers/model/Container.java @@ -310,6 +310,22 @@ public List acceptedPermissions() { } + public String getHostId() throws DotDataException { + Host host = (Host) getParentPermissionable(); + return host.getIdentifier(); + } + + + + + public String getHostName() throws DotDataException { + Host host = (Host) getParentPermissionable(); + + + return host.getHostname(); + } + + @JsonIgnore public Permissionable getParentPermissionable() throws DotDataException { diff --git a/dotCMS/src/main/java/com/dotmarketing/portlets/containers/model/FileAssetContainer.java b/dotCMS/src/main/java/com/dotmarketing/portlets/containers/model/FileAssetContainer.java index 9e2e3b6edd4f..496e06bffc60 100644 --- a/dotCMS/src/main/java/com/dotmarketing/portlets/containers/model/FileAssetContainer.java +++ b/dotCMS/src/main/java/com/dotmarketing/portlets/containers/model/FileAssetContainer.java @@ -172,9 +172,12 @@ public Host getHost() { return host; } + @Override public String getHostId() { return host.getIdentifier(); } + + @Override public String getHostName() { return host.getHostname(); } diff --git a/dotCMS/src/main/java/com/dotmarketing/portlets/containers/model/SystemContainer.java b/dotCMS/src/main/java/com/dotmarketing/portlets/containers/model/SystemContainer.java index fd936fb077a0..cdff19dfc76f 100644 --- a/dotCMS/src/main/java/com/dotmarketing/portlets/containers/model/SystemContainer.java +++ b/dotCMS/src/main/java/com/dotmarketing/portlets/containers/model/SystemContainer.java @@ -6,6 +6,7 @@ import com.dotmarketing.business.DotStateException; import com.dotmarketing.exception.DotDataException; import com.dotmarketing.exception.DotSecurityException; +import com.dotmarketing.portlets.contentlet.business.HostAPI; import com.dotmarketing.util.Config; import com.dotmarketing.util.Logger; import com.dotmarketing.util.UtilMethods; @@ -117,4 +118,16 @@ public boolean isLive() { return true; } + + @Override + public String getHostId() { + return Host.SYSTEM_HOST; + } + + @Override + public String getHostName() { + return Host.SYSTEM_HOST; + } + + } From 7efede030e11049e22ff78ea81a2ea5331d06394 Mon Sep 17 00:00:00 2001 From: Rafael Velazco Date: Wed, 14 Jan 2026 17:07:48 -0400 Subject: [PATCH 2/5] feat(containers): add hostName and hostId to DotContainer interface --- .../dot-containers.service.spec.ts | 4 +- .../dot-template-containers-cache.spec.ts | 8 +-- .../container-list.component.spec.ts | 20 ++----- .../dot-container-create.component.spec.ts | 4 +- .../dot-template-advanced.component.spec.ts | 2 +- .../dot-template-advanced.component.ts | 8 +-- .../searchable-dropdown.component.spec.ts | 18 ++---- .../dot-container-selector.component.spec.ts | 13 +--- .../dot-containers.service.spec.ts | 5 +- .../src/lib/dot-container.model.ts | 5 +- .../libs/sdk/uve/src/lib/dom/dom.utils.ts | 2 + .../store/template-builder.store.spec.ts | 4 +- .../template-builder/utils/mocks.ts | 15 +---- .../dot-container-options.directive.spec.ts | 2 +- .../dot-container-options.directive.ts | 4 +- .../src/lib/dot-containers.mock.ts | 60 +++++-------------- .../src/lib/dot-page-render.mock.ts | 10 +--- 17 files changed, 52 insertions(+), 132 deletions(-) diff --git a/core-web/apps/dotcms-ui/src/app/api/services/dot-containers/dot-containers.service.spec.ts b/core-web/apps/dotcms-ui/src/app/api/services/dot-containers/dot-containers.service.spec.ts index 7cd37166d7a5..fff7080b1b84 100644 --- a/core-web/apps/dotcms-ui/src/app/api/services/dot-containers/dot-containers.service.spec.ts +++ b/core-web/apps/dotcms-ui/src/app/api/services/dot-containers/dot-containers.service.spec.ts @@ -30,9 +30,7 @@ const mockContainer: DotContainerEntity = { identifier: '1234', live: true, name: 'movie', - parentPermissionable: { - hostname: 'default' - }, + hostName: 'default', path: null, source: CONTAINER_SOURCE.DB, title: 'movie', diff --git a/core-web/apps/dotcms-ui/src/app/api/services/dot-template-containers-cache/dot-template-containers-cache.spec.ts b/core-web/apps/dotcms-ui/src/app/api/services/dot-template-containers-cache/dot-template-containers-cache.spec.ts index 7e19b160180d..eacc47b17701 100644 --- a/core-web/apps/dotcms-ui/src/app/api/services/dot-template-containers-cache/dot-template-containers-cache.spec.ts +++ b/core-web/apps/dotcms-ui/src/app/api/services/dot-template-containers-cache/dot-template-containers-cache.spec.ts @@ -22,18 +22,14 @@ describe('TemplateContainersCacheService', () => { type: 'type', source: CONTAINER_SOURCE.FILE, path: '/containers/path', - parentPermissionable: { - hostname: 'demo.dotcms.com' - } + hostName: 'demo.dotcms.com' }, '2': { identifier: '2', name: 'container 2', type: 'type', source: CONTAINER_SOURCE.DB, - parentPermissionable: { - hostname: 'demo.dotcms.com' - } + hostName: 'demo.dotcms.com' } }; }); diff --git a/core-web/apps/dotcms-ui/src/app/portlets/dot-containers/container-list/container-list.component.spec.ts b/core-web/apps/dotcms-ui/src/app/portlets/dot-containers/container-list/container-list.component.spec.ts index dfdb9f6b3d09..6ab89db3992e 100644 --- a/core-web/apps/dotcms-ui/src/app/portlets/dot-containers/container-list/container-list.component.spec.ts +++ b/core-web/apps/dotcms-ui/src/app/portlets/dot-containers/container-list/container-list.component.spec.ts @@ -83,9 +83,7 @@ const containersMock: DotContainer[] = [ identifier: '123Published', live: true, name: 'movie', - parentPermissionable: { - hostname: 'default' - }, + hostName: 'default', path: null, source: CONTAINER_SOURCE.DB, title: 'movie', @@ -100,9 +98,7 @@ const containersMock: DotContainer[] = [ identifier: '123Unpublish', live: false, name: 'test', - parentPermissionable: { - hostname: 'default' - }, + hostName: 'default', path: null, source: CONTAINER_SOURCE.DB, title: 'test', @@ -117,9 +113,7 @@ const containersMock: DotContainer[] = [ identifier: '123Archived', live: false, name: 'test', - parentPermissionable: { - hostname: 'default' - }, + hostName: 'default', path: null, source: CONTAINER_SOURCE.DB, title: 'test', @@ -134,9 +128,7 @@ const containersMock: DotContainer[] = [ identifier: 'SYSTEM_CONTAINER', live: false, name: 'test', - parentPermissionable: { - hostname: 'default' - }, + hostName: 'default', path: null, source: CONTAINER_SOURCE.DB, title: 'test', @@ -151,9 +143,7 @@ const containersMock: DotContainer[] = [ identifier: 'FILE_CONTAINER', live: false, name: 'test', - parentPermissionable: { - hostname: 'default' - }, + hostName: 'default', path: '//demo.dotcms.com/application/containers/default/', pathName: '//demo.dotcms.com/application/containers/default/', source: CONTAINER_SOURCE.FILE, diff --git a/core-web/apps/dotcms-ui/src/app/portlets/dot-containers/dot-container-create/dot-container-create.component.spec.ts b/core-web/apps/dotcms-ui/src/app/portlets/dot-containers/dot-container-create/dot-container-create.component.spec.ts index bdb67b96138c..380da37b9112 100644 --- a/core-web/apps/dotcms-ui/src/app/portlets/dot-containers/dot-container-create/dot-container-create.component.spec.ts +++ b/core-web/apps/dotcms-ui/src/app/portlets/dot-containers/dot-container-create/dot-container-create.component.spec.ts @@ -57,9 +57,7 @@ describe('ContainerCreateComponent', () => { name: '', type: '', source: CONTAINER_SOURCE.DB, - parentPermissionable: { - hostname: 'dotcms.com' - } + hostName: 'dotcms.com' }, containerStructures: [] } diff --git a/core-web/apps/dotcms-ui/src/app/portlets/dot-templates/dot-template-create-edit/dot-template-advanced/dot-template-advanced.component.spec.ts b/core-web/apps/dotcms-ui/src/app/portlets/dot-templates/dot-template-create-edit/dot-template-advanced/dot-template-advanced.component.spec.ts index 28cc0eaf0553..67761bddf09c 100644 --- a/core-web/apps/dotcms-ui/src/app/portlets/dot-templates/dot-template-create-edit/dot-template-advanced/dot-template-advanced.component.spec.ts +++ b/core-web/apps/dotcms-ui/src/app/portlets/dot-templates/dot-template-create-edit/dot-template-advanced/dot-template-advanced.component.spec.ts @@ -198,7 +198,7 @@ describe('DotTemplateAdvancedComponent', () => { container.triggerEventHandler('swap', { identifier: '123', - parentPermissionable: { hostname: 'demo.com' } + hostName: 'demo.com' }); expect(component.editor.executeEdits).toHaveBeenCalledWith('source', [ diff --git a/core-web/apps/dotcms-ui/src/app/portlets/dot-templates/dot-template-create-edit/dot-template-advanced/dot-template-advanced.component.ts b/core-web/apps/dotcms-ui/src/app/portlets/dot-templates/dot-template-create-edit/dot-template-advanced/dot-template-advanced.component.ts index 0257bf4375f3..b65afef6545c 100644 --- a/core-web/apps/dotcms-ui/src/app/portlets/dot-templates/dot-template-create-edit/dot-template-advanced/dot-template-advanced.component.ts +++ b/core-web/apps/dotcms-ui/src/app/portlets/dot-templates/dot-template-create-edit/dot-template-advanced/dot-template-advanced.component.ts @@ -122,12 +122,10 @@ export class DotTemplateAdvancedComponent implements OnInit, OnDestroy, OnChange this.editor.executeEdits('source', [operation]); } - private setContainerId({ identifier, parentPermissionable }: DotContainer): string { - const regex = new RegExp('//' + parentPermissionable.hostname); + private setContainerId({ identifier, hostName }: DotContainer): string { + const regex = new RegExp('//' + hostName); - return identifier?.includes(parentPermissionable.hostname) - ? identifier.replace(regex, '') - : identifier; + return identifier?.includes(hostName) ? identifier.replace(regex, '') : identifier; } private getActions(disabled = true): DotPortletToolbarActions { diff --git a/core-web/apps/dotcms-ui/src/app/view/components/_common/searchable-dropdown/component/searchable-dropdown.component.spec.ts b/core-web/apps/dotcms-ui/src/app/view/components/_common/searchable-dropdown/component/searchable-dropdown.component.spec.ts index b764d87cd673..b49dcc5bb8e5 100644 --- a/core-web/apps/dotcms-ui/src/app/view/components/_common/searchable-dropdown/component/searchable-dropdown.component.spec.ts +++ b/core-web/apps/dotcms-ui/src/app/view/components/_common/searchable-dropdown/component/searchable-dropdown.component.spec.ts @@ -116,9 +116,7 @@ describe('SearchableDropdownComponent', () => { id: i, label: `site-${i}`, name: `site-${i}`, - parentPermissionable: { - hostname: 'demo.dotcms.com' - } + hostName: 'demo.dotcms.com' }; } @@ -252,7 +250,7 @@ describe('SearchableDropdownComponent', () => { it('should render a string array of properties in p-dataview', () => { hostComp.data = data; - hostComp.labelPropertyName = ['name', 'parentPermissionable.hostname']; + hostComp.labelPropertyName = ['name', 'hostName']; hostFixture.detectChanges(); @@ -350,9 +348,7 @@ describe('SearchableDropdownComponent', () => { id: 1, label: `label`, name: `label`, - parentPermissionable: { - hostname: 'demo.dotcms.com' - }, + hostName: 'demo.dotcms.com', default: true } ]; @@ -372,9 +368,7 @@ describe('SearchableDropdownComponent', () => { id: 1, label: `label`, name: `label`, - parentPermissionable: { - hostname: 'demo.dotcms.com' - }, + hostName: 'demo.dotcms.com', default: false } ]; @@ -504,9 +498,7 @@ describe('SearchableDropdownComponent', () => { id: i, label: `site-${i}`, name: `site-${i}`, - parentPermissionable: { - hostname: 'demo.dotcms.com' - } + hostName: 'demo.dotcms.com' }; } diff --git a/core-web/apps/dotcms-ui/src/app/view/components/dot-container-selector/dot-container-selector.component.spec.ts b/core-web/apps/dotcms-ui/src/app/view/components/dot-container-selector/dot-container-selector.component.spec.ts index d9f6ad7eaaa0..5eb0cb41fea9 100644 --- a/core-web/apps/dotcms-ui/src/app/view/components/dot-container-selector/dot-container-selector.component.spec.ts +++ b/core-web/apps/dotcms-ui/src/app/view/components/dot-container-selector/dot-container-selector.component.spec.ts @@ -70,9 +70,7 @@ describe('ContainerSelectorComponent', () => { name: 'Container 1', type: 'Container', source: CONTAINER_SOURCE.DB, - parentPermissionable: { - hostname: 'demo.dotcms.com' - } + hostName: 'demo.dotcms.com' }, { categoryId: '40204d-c380-439f-a6d0-97d8sdeed57e', @@ -83,9 +81,7 @@ describe('ContainerSelectorComponent', () => { type: 'Container', source: CONTAINER_SOURCE.FILE, path: 'container/path', - parentPermissionable: { - hostname: 'demo.dotcms.com' - } + hostName: 'demo.dotcms.com' } ]; @@ -108,10 +104,7 @@ describe('ContainerSelectorComponent', () => { const searchableComponent = searchable.componentInstance as SearchableDropdownComponent; // Verify component properties directly - expect(searchableComponent.labelPropertyName).toEqual([ - 'name', - 'parentPermissionable.hostname' - ]); + expect(searchableComponent.labelPropertyName).toEqual(['name', 'hostName']); expect(searchableComponent.multiple).toBe(true); expect(searchableComponent.pageLinkSize).toBe(5); expect(searchableComponent.persistentPlaceholder).toBeTruthy(); diff --git a/core-web/libs/data-access/src/lib/dot-containers/dot-containers.service.spec.ts b/core-web/libs/data-access/src/lib/dot-containers/dot-containers.service.spec.ts index d18846c1f68f..30530de50372 100644 --- a/core-web/libs/data-access/src/lib/dot-containers/dot-containers.service.spec.ts +++ b/core-web/libs/data-access/src/lib/dot-containers/dot-containers.service.spec.ts @@ -25,10 +25,7 @@ describe('DotContainersService', () => { title: 'Test Container Title', path: '/test-container', archived: false, - categoryId: 'test-category', - parentPermissionable: { - hostname: 'test-host' - } + categoryId: 'test-category' }; const mockSystemContainer: DotContainer = { diff --git a/core-web/libs/dotcms-models/src/lib/dot-container.model.ts b/core-web/libs/dotcms-models/src/lib/dot-container.model.ts index f24c6da97426..8b37c2adbafc 100644 --- a/core-web/libs/dotcms-models/src/lib/dot-container.model.ts +++ b/core-web/libs/dotcms-models/src/lib/dot-container.model.ts @@ -12,6 +12,8 @@ export interface DotContainerEntity { export interface DotContainer { archived?: boolean; + hostName?: string; + hostId?: string; categoryId?: string; deleted?: boolean; live?: boolean; @@ -28,9 +30,6 @@ export interface DotContainer { preLoop?: string; postLoop?: string; code?: string; - parentPermissionable?: { - hostname: string; - }; disableInteraction?: boolean; pathName?: string; } diff --git a/core-web/libs/sdk/uve/src/lib/dom/dom.utils.ts b/core-web/libs/sdk/uve/src/lib/dom/dom.utils.ts index 9ce0a9a0e6ce..f1b0a960353c 100644 --- a/core-web/libs/sdk/uve/src/lib/dom/dom.utils.ts +++ b/core-web/libs/sdk/uve/src/lib/dom/dom.utils.ts @@ -318,6 +318,8 @@ export const getContainersData = ( const acceptTypes = containerStructures?.map((structure) => structure.contentTypeVar).join(',') ?? ''; + // TODO: Check if the variantId is needed and we need to find another way to get it. + // Since the parentPermissionable is not available after: https://github.com/dotCMS/core/pull/32890 const variantId = container?.parentPermissionable?.variantId; const maxContentlets = container?.maxContentlets ?? 0; const path = container?.path; diff --git a/core-web/libs/template-builder/src/lib/components/template-builder/store/template-builder.store.spec.ts b/core-web/libs/template-builder/src/lib/components/template-builder/store/template-builder.store.spec.ts index f0e9d6bb42b4..3f0b494df4be 100644 --- a/core-web/libs/template-builder/src/lib/components/template-builder/store/template-builder.store.spec.ts +++ b/core-web/libs/template-builder/src/lib/components/template-builder/store/template-builder.store.spec.ts @@ -866,9 +866,7 @@ describe('DotTemplateBuilderStore', () => { path: '/new/default/container/path', archived: false, categoryId: 'new-category', - parentPermissionable: { - hostname: 'new-host' - } + hostName: 'new-host' }; service.updateDefaultContainer(newDefaultContainer); diff --git a/core-web/libs/template-builder/src/lib/components/template-builder/utils/mocks.ts b/core-web/libs/template-builder/src/lib/components/template-builder/utils/mocks.ts index 552356a48e23..3a3ff7c198d6 100644 --- a/core-web/libs/template-builder/src/lib/components/template-builder/utils/mocks.ts +++ b/core-web/libs/template-builder/src/lib/components/template-builder/utils/mocks.ts @@ -71,10 +71,7 @@ export const mockDefaultContainerWithPath: DotContainer = { title: 'Default Container Title', path: '/default/container/path', archived: false, - categoryId: 'default-category', - parentPermissionable: { - hostname: 'default-host' - } + categoryId: 'default-category' }; export const mockDefaultContainerWithoutPath: DotContainer = { @@ -88,10 +85,7 @@ export const mockDefaultContainerWithoutPath: DotContainer = { locked: false, title: 'Default Container Title', archived: false, - categoryId: 'default-category', - parentPermissionable: { - hostname: 'default-host' - } + categoryId: 'default-category' }; export const mockTempContainer: DotContainer = { @@ -106,10 +100,7 @@ export const mockTempContainer: DotContainer = { title: 'Temp Container Title', path: '/temp/container/path', archived: false, - categoryId: 'temp-category', - parentPermissionable: { - hostname: 'temp-host' - } + categoryId: 'temp-category' }; export const CONTAINERS_DATA_MOCK = [ diff --git a/core-web/libs/ui/src/lib/dot-container-options/dot-container-options.directive.spec.ts b/core-web/libs/ui/src/lib/dot-container-options/dot-container-options.directive.spec.ts index 1a64bd528538..007195f46775 100644 --- a/core-web/libs/ui/src/lib/dot-container-options/dot-container-options.directive.spec.ts +++ b/core-web/libs/ui/src/lib/dot-container-options/dot-container-options.directive.spec.ts @@ -34,7 +34,7 @@ const sortedContainersMock = containersMock function getGroupByHostContainersMock() { const containerobj = sortedContainersMock.reduce((acc, option) => { - const { hostname } = option.value.parentPermissionable; + const hostname = option.value.hostName || 'SYSTEM_HOST'; if (!acc[hostname]) { acc[hostname] = { items: [] }; diff --git a/core-web/libs/ui/src/lib/dot-container-options/dot-container-options.directive.ts b/core-web/libs/ui/src/lib/dot-container-options/dot-container-options.directive.ts index 07663da128b1..83a171c7f9d3 100644 --- a/core-web/libs/ui/src/lib/dot-container-options/dot-container-options.directive.ts +++ b/core-web/libs/ui/src/lib/dot-container-options/dot-container-options.directive.ts @@ -17,6 +17,8 @@ import { const DEFAULT_LABEL_NAME_INDEX = 'label'; const DEFAULT_VALUE_NAME_INDEX = 'value'; +const DEFAULT_HOST_NAME = 'SYSTEM_HOST'; + /** * Directive to set an element's options from dotCMS's containers * @@ -134,7 +136,7 @@ export class DotContainerOptionsDirective implements OnInit { [key: string]: { items: DotDropdownSelectOption[] }; } { return options.reduce((acc, option) => { - const { hostname } = option.value.parentPermissionable; + const hostname = option.value.hostName || DEFAULT_HOST_NAME; if (!acc[hostname]) { acc[hostname] = { items: [] }; diff --git a/core-web/libs/utils-testing/src/lib/dot-containers.mock.ts b/core-web/libs/utils-testing/src/lib/dot-containers.mock.ts index b0c9ef351802..50408d51b260 100644 --- a/core-web/libs/utils-testing/src/lib/dot-containers.mock.ts +++ b/core-web/libs/utils-testing/src/lib/dot-containers.mock.ts @@ -8,9 +8,7 @@ export const dotContainerMapMock = (): DotContainerMap => { name: 'System Container', categoryId: 'dbdec5e2-c02b-4cfb-83a9-4a4c4f3b2eb0', source: CONTAINER_SOURCE.DB, - parentPermissionable: { - hostname: 'System Host' - } + hostName: 'System Host' }, '5363c6c6-5ba0-4946-b7af-cf875188ac2e': { type: 'containers', @@ -18,9 +16,7 @@ export const dotContainerMapMock = (): DotContainerMap => { name: 'Medium Column (md-1)', categoryId: '9ab97328-e72f-4d7e-8be6-232f53218a93', source: CONTAINER_SOURCE.DB, - parentPermissionable: { - hostname: 'demo.dotcms.com' - } + hostName: 'demo.dotcms.com' }, '56bd55ea-b04b-480d-9e37-5d6f9217dcc3': { type: 'containers', @@ -29,9 +25,7 @@ export const dotContainerMapMock = (): DotContainerMap => { categoryId: 'dde0b865-6cea-4ff0-8582-85e5974cf94f', source: CONTAINER_SOURCE.FILE, path: '/container/path', - parentPermissionable: { - hostname: 'demo.dotcms.com' - } + hostName: 'demo.dotcms.com' }, '/container/path': { type: 'containers', @@ -40,9 +34,7 @@ export const dotContainerMapMock = (): DotContainerMap => { categoryId: 'dde0b865-6cea-4ff0-8582-85e5974cf94f', source: CONTAINER_SOURCE.FILE, path: '/container/path', - parentPermissionable: { - hostname: 'demo.dotcms.com' - } + hostName: 'demo.dotcms.com' }, '6a12bbda-0ae2-4121-a98b-ad8069eaff3a': { type: 'containers', @@ -50,9 +42,7 @@ export const dotContainerMapMock = (): DotContainerMap => { name: 'Banner Carousel ', categoryId: '427c47a4-c380-439f-a6d0-97d81deed57e', source: CONTAINER_SOURCE.DB, - parentPermissionable: { - hostname: 'demo.dotcms.com' - } + hostName: 'demo.dotcms.com' }, 'a6e9652b-8183-4c09-b775-26196b09a300': { type: 'containers', @@ -60,9 +50,7 @@ export const dotContainerMapMock = (): DotContainerMap => { name: 'Default 4 (Page Content)', categoryId: '8cbcb97e-8e04-4691-8555-da82c3dc4a91', source: CONTAINER_SOURCE.DB, - parentPermissionable: { - hostname: 'demo.dotcms.com' - } + hostName: 'demo.dotcms.com' }, 'd71d56b4-0a8b-4bb2-be15-ffa5a23366ea': { type: 'containers', @@ -70,9 +58,7 @@ export const dotContainerMapMock = (): DotContainerMap => { name: 'Blank Container', categoryId: '3ba890c5-670c-467d-890d-bd8e9b9bb5ef', source: CONTAINER_SOURCE.DB, - parentPermissionable: { - hostname: 'demo.dotcms.com' - } + hostName: 'demo.dotcms.com' } }; }; @@ -84,9 +70,7 @@ export const containersMockArray = [ name: 'System Container', categoryId: 'dbdec5e2-c02b-4cfb-83a9-4a4c4f3b2eb0', source: CONTAINER_SOURCE.DB, - parentPermissionable: { - hostname: 'System Host' - } + hostName: 'System Host' }, { type: 'containers', @@ -94,9 +78,7 @@ export const containersMockArray = [ name: 'Medium Column (md-1)', categoryId: '9ab97328-e72f-4d7e-8be6-232f53218a93', source: CONTAINER_SOURCE.DB, - parentPermissionable: { - hostname: 'demo.dotcms.com' - } + hostName: 'demo.dotcms.com' }, { type: 'containers', @@ -105,9 +87,7 @@ export const containersMockArray = [ categoryId: 'dde0b865-6cea-4ff0-8582-85e5974cf94f', source: CONTAINER_SOURCE.FILE, path: '/container/path', - parentPermissionable: { - hostname: 'demo.dotcms.com' - } + hostName: 'demo.dotcms.com' }, { type: 'containers', @@ -116,9 +96,7 @@ export const containersMockArray = [ categoryId: 'dde0b865-6cea-4ff0-8582-85e5974cf94f', source: CONTAINER_SOURCE.FILE, path: '/container/path', - parentPermissionable: { - hostname: 'demo.dotcms.com' - } + hostName: 'demo.dotcms.com' }, { type: 'containers', @@ -126,9 +104,7 @@ export const containersMockArray = [ name: 'Banner Carousel ', categoryId: '427c47a4-c380-439f-a6d0-97d81deed57e', source: CONTAINER_SOURCE.DB, - parentPermissionable: { - hostname: 'demo.dotcms.com' - } + hostName: 'demo.dotcms.com' }, { type: 'containers', @@ -136,9 +112,7 @@ export const containersMockArray = [ name: 'Default 4 (Page Content)', categoryId: '8cbcb97e-8e04-4691-8555-da82c3dc4a91', source: CONTAINER_SOURCE.DB, - parentPermissionable: { - hostname: 'demo.dotcms.com' - } + hostName: 'demo.dotcms.com' }, { type: 'containers', @@ -146,17 +120,15 @@ export const containersMockArray = [ name: 'Blank Container', categoryId: '3ba890c5-670c-467d-890d-bd8e9b9bb5ef', source: CONTAINER_SOURCE.DB, - parentPermissionable: { - hostname: 'demo.dotcms.com' - } + hostName: 'demo.dotcms.com' } ]; export const containersMock: DotContainer[] = containersMockArray.map( - ({ name, identifier, parentPermissionable, path, source }) => ({ + ({ name, identifier, hostName, path, source }) => ({ friendlyName: name, title: name, - parentPermissionable: { hostname: parentPermissionable.hostname }, + hostName, identifier: identifier, source, path diff --git a/core-web/libs/utils-testing/src/lib/dot-page-render.mock.ts b/core-web/libs/utils-testing/src/lib/dot-page-render.mock.ts index fca0a0e4d997..fecfc25302d9 100644 --- a/core-web/libs/utils-testing/src/lib/dot-page-render.mock.ts +++ b/core-web/libs/utils-testing/src/lib/dot-page-render.mock.ts @@ -282,10 +282,7 @@ export const processedContainers = [ identifier: '5363c6c6-5ba0-4946-b7af-cf875188ac2e', name: 'Medium Column (md-1)', categoryId: '9ab97328-e72f-4d7e-8be6-232f53218a93', - source: CONTAINER_SOURCE.DB, - parentPermissionable: { - hostname: 'demo.dotcms.com' - } + source: CONTAINER_SOURCE.DB } }, { @@ -295,10 +292,7 @@ export const processedContainers = [ name: 'Large Column (lg-1)', categoryId: 'dde0b865-6cea-4ff0-8582-85e5974cf94f', source: CONTAINER_SOURCE.FILE, - path: '/container/path', - parentPermissionable: { - hostname: 'demo.dotcms.com' - } + path: '/container/path' } } ]; From 66812c9a10ad7b6d24e5f533f66e882cc4ef856d Mon Sep 17 00:00:00 2001 From: Will Ezell Date: Wed, 14 Jan 2026 16:12:04 -0500 Subject: [PATCH 3/5] fix(containers): this re-adds the hostname to the container object api response ref: #34296 --- .../portlets/containers/model/Container.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dotCMS/src/main/java/com/dotmarketing/portlets/containers/model/Container.java b/dotCMS/src/main/java/com/dotmarketing/portlets/containers/model/Container.java index 5bbe71c3429e..2adf94d61a9b 100644 --- a/dotCMS/src/main/java/com/dotmarketing/portlets/containers/model/Container.java +++ b/dotCMS/src/main/java/com/dotmarketing/portlets/containers/model/Container.java @@ -2,6 +2,8 @@ import com.dotcms.publisher.util.PusheableAsset; import com.dotcms.publishing.manifest.ManifestItem; +import com.dotcms.variant.VariantAPI; +import com.dotcms.variant.model.Variant; import com.dotmarketing.beans.ContainerStructure; import com.dotmarketing.beans.Host; import com.dotmarketing.beans.Inode; @@ -43,9 +45,6 @@ public class Container extends WebAsset implements Serializable, ManifestItem { public static final String SYSTEM_CONTAINER = "SYSTEM_CONTAINER"; - /* - * Convenience access - */ public static final String LEGACY_RELATION_TYPE = MultiTree.LEGACY_RELATION_TYPE; private static final long serialVersionUID = 1L; @@ -326,6 +325,10 @@ public String getHostName() throws DotDataException { } + public String getVariant(){ + return "DEFAULT"; + } + @JsonIgnore public Permissionable getParentPermissionable() throws DotDataException { From e20c2b00f4e7461a2a44e9f45160d00245832a7d Mon Sep 17 00:00:00 2001 From: Rafael Velazco Date: Wed, 14 Jan 2026 19:15:08 -0400 Subject: [PATCH 4/5] fix: tests --- .../dot-container-selector.component.html | 2 +- .../dot-edit-content-binary-field.component.spec.ts | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/core-web/apps/dotcms-ui/src/app/view/components/dot-container-selector/dot-container-selector.component.html b/core-web/apps/dotcms-ui/src/app/view/components/dot-container-selector/dot-container-selector.component.html index 3890db3fa79f..05edea86074e 100644 --- a/core-web/apps/dotcms-ui/src/app/view/components/dot-container-selector/dot-container-selector.component.html +++ b/core-web/apps/dotcms-ui/src/app/view/components/dot-container-selector/dot-container-selector.component.html @@ -6,7 +6,7 @@ [pageLinkSize]="5" [rows]="paginationService.paginationPerPage" [totalRecords]="paginationService.totalRecords" - [labelPropertyName]="['name', 'parentPermissionable.hostname']" + [labelPropertyName]="['name', 'hostName']" [class]="innerClass" [multiple]="true" data-testId="searchableDropdown" diff --git a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-binary-field/dot-edit-content-binary-field.component.spec.ts b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-binary-field/dot-edit-content-binary-field.component.spec.ts index b5b7a96f7acb..4a67b5d4e128 100644 --- a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-binary-field/dot-edit-content-binary-field.component.spec.ts +++ b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-binary-field/dot-edit-content-binary-field.component.spec.ts @@ -129,6 +129,11 @@ describe('DotEditContentBinaryFieldComponent', () => { }); beforeEach(() => { + // This spec relies on async Angular stabilization (whenStable). + // In large Jest runs, other suites can leave fake timers enabled in the same worker, + // which can cause these async setups to hang/flap. Force real timers for isolation. + jest.useRealTimers(); + spectator = createComponent({ detectChanges: false, props: { @@ -769,6 +774,8 @@ describe('DotEditContentBinaryFieldComponent', () => { }); afterEach(() => { + jest.clearAllTimers(); + jest.useRealTimers(); jest.resetAllMocks(); }); }); From 5538aca22338c6c162d6cf70c8ed6fa863caa5e8 Mon Sep 17 00:00:00 2001 From: Will Ezell Date: Wed, 14 Jan 2026 19:08:17 -0500 Subject: [PATCH 5/5] git commit -m "fix(containers): this re-adds the hostname to the container object api response ref: #34296" --- dotCMS/src/main/webapp/WEB-INF/openapi/openapi.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dotCMS/src/main/webapp/WEB-INF/openapi/openapi.yaml b/dotCMS/src/main/webapp/WEB-INF/openapi/openapi.yaml index 6ffb32b034a5..41fd71486a10 100644 --- a/dotCMS/src/main/webapp/WEB-INF/openapi/openapi.yaml +++ b/dotCMS/src/main/webapp/WEB-INF/openapi/openapi.yaml @@ -20286,6 +20286,10 @@ components: getiDate: type: string format: date-time + hostId: + type: string + hostName: + type: string idate: type: string format: date-time @@ -20343,6 +20347,8 @@ components: type: string useDiv: type: boolean + variant: + type: string versionId: type: string versionType: