From de7ba147df697fa324a382fb091a891c9edd8761 Mon Sep 17 00:00:00 2001 From: Kevin Davila <144152756+KevinDavilaDotCMS@users.noreply.github.com> Date: Thu, 19 Dec 2024 10:59:15 -0500 Subject: [PATCH] chore(uve): FTM - Implement Date picker and render future contentlets page (#30930) https://github.com/user-attachments/assets/8bf71b49-bcf4-4033-b5b8-27d72804a194 This pull request includes several changes to improve the preview functionality and UI components of the `dot-ema-shell` and `dot-uve-toolbar` components. The key changes involve adding support for handling the `publishDate` parameter, updating the UI to reflect these changes, and enhancing the related tests. ### Enhancements to preview functionality: * [`dot-ema-shell.component.ts`](diffhunk://#diff-677330662fea6dadc7e48fd8455ec2a6fe60d624c7ed1f01f0a3e985aacd05c6R213-R216): Added logic to set the `publishDate` parameter to the current date if it is not present when the preview mode is enabled. * [`dot-ema-shell.component.spec.ts`](diffhunk://#diff-8843e3a4ce8c16e83408b1a6dcc3ad54eaddd17f8e986bbdb502e11bd4446ab4R526-R549): Added a test case to verify that the `publishDate` is set correctly when the preview mode is enabled. ### UI updates: * [`dot-uve-toolbar.component.html`](diffhunk://#diff-9937556e73b051b878ba22ad1ce971a70019a617d7979b3e0bcc814801ad350bL15-R26): Updated the toolbar to include a calendar input for selecting the preview date and a button to set the preview mode. * [`dot-uve-toolbar.component.scss`](diffhunk://#diff-dd2bc3ab605f3a154f1a4b3b5de1f8e364e7bbc5a3fb4b078bba74aaedcad312L7-R19): Updated styles for the new toolbar button and calendar input. ### Test enhancements: * [`dot-uve-toolbar.component.spec.ts`](diffhunk://#diff-3eaa147616a5d1ff374a5fa27b0f38f0159a9039ef7e8d672dec43631f48a9e1R104-R106): Added multiple test cases to verify the correct behavior of the preview date functionality, including setting the preview date and handling past dates. [[1]](diffhunk://#diff-3eaa147616a5d1ff374a5fa27b0f38f0159a9039ef7e8d672dec43631f48a9e1R104-R106) [[2]](diffhunk://#diff-3eaa147616a5d1ff374a5fa27b0f38f0159a9039ef7e8d672dec43631f48a9e1L239-R245) [[3]](diffhunk://#diff-3eaa147616a5d1ff374a5fa27b0f38f0159a9039ef7e8d672dec43631f48a9e1L372-R381) [[4]](diffhunk://#diff-3eaa147616a5d1ff374a5fa27b0f38f0159a9039ef7e8d672dec43631f48a9e1L390-R453) ### Code improvements: * [`dot-uve-toolbar.component.ts`](diffhunk://#diff-217a9e619d6590c4f652e85353b9637ba5e464ddeb0424be35aef39bb8dceb30R9-R13): Refactored the component to include the new `publishDate` parameter and updated the logic for setting and handling the preview date. [[1]](diffhunk://#diff-217a9e619d6590c4f652e85353b9637ba5e464ddeb0424be35aef39bb8dceb30R9-R13) [[2]](diffhunk://#diff-217a9e619d6590c4f652e85353b9637ba5e464ddeb0424be35aef39bb8dceb30R26) [[3]](diffhunk://#diff-217a9e619d6590c4f652e85353b9637ba5e464ddeb0424be35aef39bb8dceb30L52-R57) [[4]](diffhunk://#diff-217a9e619d6590c4f652e85353b9637ba5e464ddeb0424be35aef39bb8dceb30R79-R80) [[5]](diffhunk://#diff-217a9e619d6590c4f652e85353b9637ba5e464ddeb0424be35aef39bb8dceb30L84-R127) [[6]](diffhunk://#diff-217a9e619d6590c4f652e85353b9637ba5e464ddeb0424be35aef39bb8dceb30L101-R136) [[7]](diffhunk://#diff-217a9e619d6590c4f652e85353b9637ba5e464ddeb0424be35aef39bb8dceb30R165-R169) ### Service updates: * [`dot-page-api.service.ts`](diffhunk://#diff-9acb0e7dc2619395c49047164381778d2b6d6c41f58b30aa3cd6a798044007c6R52): Added the `publishDate` parameter to the `DotPageApiParams` interface and updated the `get` method to handle this new parameter. [[1]](diffhunk://#diff-9acb0e7dc2619395c49047164381778d2b6d6c41f58b30aa3cd6a798044007c6R52) [[2]](diffhunk://#diff-9acb0e7dc2619395c49047164381778d2b6d6c41f58b30aa3cd6a798044007c6L63-R65) [[3]](diffhunk://#diff-9acb0e7dc2619395c49047164381778d2b6d6c41f58b30aa3cd6a798044007c6L97-R107) [[4]](diffhunk://#diff-9acb0e7dc2619395c49047164381778d2b6d6c41f58b30aa3cd6a798044007c6L110-R121) --------- Co-authored-by: Kevin Davila --- .../dot-ema-shell.component.spec.ts | 51 ++++++++++++++-- .../dot-ema-shell/dot-ema-shell.component.ts | 15 ++++- .../dot-uve-toolbar.component.html | 25 ++++---- .../dot-uve-toolbar.component.scss | 12 ++-- .../dot-uve-toolbar.component.spec.ts | 47 +++++++++++++-- .../dot-uve-toolbar.component.ts | 60 ++++++++++++++++--- .../edit-ema-editor.component.spec.ts | 15 ----- .../edit-ema-editor.component.ts | 7 --- .../lib/services/dot-page-api.service.spec.ts | 6 +- .../src/lib/services/dot-page-api.service.ts | 28 ++++++--- .../edit-ema/portlet/src/lib/shared/models.ts | 4 +- .../src/lib/store/dot-uve.store.spec.ts | 5 +- .../portlet/src/lib/store/dot-uve.store.ts | 4 +- .../lib/store/features/client/withClient.ts | 2 + .../features/editor/toolbar/withUVEToolbar.ts | 3 +- .../store/features/editor/withEditor.spec.ts | 19 +++++- .../lib/store/features/editor/withEditor.ts | 9 ++- .../src/lib/store/features/load/withLoad.ts | 11 ++-- .../edit-ema/portlet/src/lib/store/models.ts | 6 +- .../edit-ema/portlet/src/lib/utils/index.ts | 21 ++++--- .../portlet/src/lib/utils/utils.spec.ts | 5 +- core-web/libs/sdk/client/src/index.ts | 6 +- .../src/lib/editor/models/editor.model.ts | 5 ++ .../client/src/lib/editor/sdk-editor.spec.ts | 21 ++++--- .../sdk/client/src/lib/editor/sdk-editor.ts | 18 +++--- .../src/lib/utils/page/common-utils.spec.ts | 6 +- .../client/src/lib/utils/page/common-utils.ts | 9 ++- examples/nextjs/src/hooks/usePageAsset.js | 1 - 28 files changed, 293 insertions(+), 128 deletions(-) diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/dot-ema-shell/dot-ema-shell.component.spec.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/dot-ema-shell/dot-ema-shell.component.spec.ts index 1c4ee37ba0ae..d427ab38fdd7 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/dot-ema-shell/dot-ema-shell.component.spec.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/dot-ema-shell/dot-ema-shell.component.spec.ts @@ -12,7 +12,7 @@ import { ConfirmDialogModule } from 'primeng/confirmdialog'; import { DialogService } from 'primeng/dynamicdialog'; import { ToastModule } from 'primeng/toast'; -import { CLIENT_ACTIONS } from '@dotcms/client'; +import { CLIENT_ACTIONS, UVE_MODE } from '@dotcms/client'; import { DotContentletLockerService, DotExperimentsService, @@ -115,7 +115,8 @@ const INITIAL_PAGE_PARAMS = { language_id: 1, url: 'index', variantName: 'DEFAULT', - 'com.dotmarketing.persona.id': 'modes.persona.no.persona' + 'com.dotmarketing.persona.id': 'modes.persona.no.persona', + editorMode: UVE_MODE.EDIT }; const BASIC_OPTIONS = { @@ -320,7 +321,7 @@ describe('DotEmaShellComponent', () => { expect(spyloadPageAsset).toHaveBeenCalledWith(INITIAL_PAGE_PARAMS); expect(spyStoreLoadPage).toHaveBeenCalledWith(INITIAL_PAGE_PARAMS); expect(spyLocation).toHaveBeenCalledWith( - '/?language_id=1&url=index&variantName=DEFAULT&com.dotmarketing.persona.id=modes.persona.no.persona' + '/?language_id=1&url=index&variantName=DEFAULT&com.dotmarketing.persona.id=modes.persona.no.persona&editorMode=edit' ); }); @@ -376,7 +377,8 @@ describe('DotEmaShellComponent', () => { language_id: 2, url: 'my-awesome-page', variantName: 'DEFAULT', - 'com.dotmarketing.persona.id': 'SomeCoolDude' + 'com.dotmarketing.persona.id': 'SomeCoolDude', + editorMode: UVE_MODE.EDIT }; const url = router.createUrlTree([], { queryParams: newParams }); @@ -530,6 +532,47 @@ describe('DotEmaShellComponent', () => { }); }); + describe('Editor Mode', () => { + it('should set editorMode to EDIT when wrong editorMode is passed', () => { + const spyStoreLoadPage = jest.spyOn(store, 'loadPageAsset'); + const params = { + ...INITIAL_PAGE_PARAMS, + editorMode: 'WRONG' + }; + overrideRouteSnashot( + activatedRoute, + SNAPSHOT_MOCK({ queryParams: params, data: UVE_CONFIG_MOCK(BASIC_OPTIONS) }) + ); + spectator.detectChanges(); + expect(spyStoreLoadPage).toHaveBeenCalledWith({ + ...INITIAL_PAGE_PARAMS, + editorMode: UVE_MODE.EDIT + }); + }); + + it('should add the current date if preview param is true and publishDate is not present', () => { + const spyStoreLoadPage = jest.spyOn(store, 'loadPageAsset'); + const params = { + ...INITIAL_PAGE_PARAMS, + editorMode: UVE_MODE.PREVIEW + }; + + // override the new Date() to return a fixed date + const fixedDate = new Date('2024-01-01'); + jest.spyOn(global, 'Date').mockImplementation(() => fixedDate); + + const data = UVE_CONFIG_MOCK(BASIC_OPTIONS); + + overrideRouteSnashot(activatedRoute, SNAPSHOT_MOCK({ queryParams: params, data })); + + spectator.detectChanges(); + expect(spyStoreLoadPage).toHaveBeenCalledWith({ + ...params, + publishDate: fixedDate.toISOString() + }); + }); + }); + describe('Site Changes', () => { it('should trigger a navigate to /pages when site changes', async () => { const navigate = jest.spyOn(router, 'navigate'); diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/dot-ema-shell/dot-ema-shell.component.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/dot-ema-shell/dot-ema-shell.component.ts index fc10066c55c1..1a8e96406d19 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/dot-ema-shell/dot-ema-shell.component.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/dot-ema-shell/dot-ema-shell.component.ts @@ -11,6 +11,7 @@ import { ToastModule } from 'primeng/toast'; import { skip } from 'rxjs/operators'; +import { UVE_MODE } from '@dotcms/client'; import { DotESContentService, DotExperimentsService, @@ -30,10 +31,10 @@ import { EditEmaNavigationBarComponent } from './components/edit-ema-navigation- import { DotEmaDialogComponent } from '../components/dot-ema-dialog/dot-ema-dialog.component'; import { DotActionUrlService } from '../services/dot-action-url/dot-action-url.service'; -import { DotPageApiParams, DotPageApiService } from '../services/dot-page-api.service'; +import { DotPageApiService } from '../services/dot-page-api.service'; import { WINDOW } from '../shared/consts'; import { NG_CUSTOM_EVENTS } from '../shared/enums'; -import { DialogAction } from '../shared/models'; +import { DialogAction, DotPageAssetParams } from '../shared/models'; import { UVEStore } from '../store/dot-uve.store'; import { checkClientHostAccess, @@ -201,7 +202,7 @@ export class DotEmaShellComponent implements OnInit, OnDestroy { * @return {*} {DotPageApiParams} * @memberof DotEmaShellComponent */ - #getPageParams(): DotPageApiParams { + #getPageParams(): DotPageAssetParams { const { queryParams, data } = this.#activatedRoute.snapshot; const uveConfig = data?.uveConfig; const allowedDevURLs = uveConfig?.options?.allowedDevURLs; @@ -218,6 +219,14 @@ export class DotEmaShellComponent implements OnInit, OnDestroy { params.clientHost = uveConfig.url; } + if (params.editorMode !== UVE_MODE.EDIT && params.editorMode !== UVE_MODE.PREVIEW) { + params.editorMode = UVE_MODE.EDIT; + } + + if (params.editorMode === UVE_MODE.PREVIEW && !params.publishDate) { + params.publishDate = new Date().toISOString(); + } + return params; } diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.html b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.html index e5e086766816..cb5d2ae65352 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.html +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.html @@ -12,21 +12,18 @@ @if (preview) {
-
- - -
- +
} @@ -62,7 +59,7 @@ icon="pi pi-eye" styleClass="p-button-text p-button-sm" data-testId="uve-toolbar-preview" - (click)="setPreviewMode()" /> + (click)="triggerPreviewMode()" /> @@ -89,7 +86,7 @@
diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.scss b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.scss index d8049559596f..d8302f003f62 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.scss +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.scss @@ -4,19 +4,17 @@ .uve-toolbar { padding: 0 $spacing-4; transition: padding 0.2s ease; - border-color: $color-palette-primary-200; border-top: 1px solid transparent; // Avoid jump } - .uve-toolbar-preview { - border-top-color: $color-palette-primary-200; - padding-inline: $spacing-5; - } - - .p-chip.uve-toolbar-chips { + .p-button.uve-toolbar-chips, + .p-button.uve-toolbar-chips:hover, + .p-button.uve-toolbar-chips:focus { height: $field-height-sm; background-color: $color-palette-primary-op-10; border-color: $color-palette-primary-op-10; + color: var(--color-palette-primary-500); + cursor: pointer; } } diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.spec.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.spec.ts index 291efdc4c758..603ddb209a08 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.spec.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.spec.ts @@ -9,6 +9,7 @@ import { By } from '@angular/platform-browser'; import { ConfirmationService, MessageService } from 'primeng/api'; +import { UVE_MODE } from '@dotcms/client'; import { DotExperimentsService, DotLanguagesService, @@ -103,6 +104,9 @@ describe('DotUveToolbarComponent', () => { let messageService: MessageService; let confirmationService: ConfirmationService; + const fixedDate = new Date('2024-01-01'); + jest.spyOn(global, 'Date').mockImplementation(() => fixedDate); + const createComponent = createComponentFactory({ component: DotUveToolbarComponent, imports: [ @@ -249,7 +253,10 @@ describe('DotUveToolbarComponent', () => { spectator.click(byTestId('uve-toolbar-preview')); - expect(spy).toHaveBeenCalledWith({ preview: 'true' }); + expect(spy).toHaveBeenCalledWith({ + editorMode: UVE_MODE.PREVIEW, + publishDate: fixedDate.toISOString() + }); }); }); @@ -378,7 +385,10 @@ describe('DotUveToolbarComponent', () => { beforeEach(() => { spectator = createComponent({ providers: [ - mockProvider(UVEStore, { ...baseUVEState, $isPreviewMode: signal(true) }) + mockProvider(UVEStore, { + ...baseUVEState, + $isPreviewMode: signal(true) + }) ] }); @@ -390,33 +400,62 @@ describe('DotUveToolbarComponent', () => { expect(spectator.query(byTestId('close-preview-mode'))).toBeTruthy(); }); - it('should call store.loadPageAsset with preview null', () => { + it('should call store.loadPageAsset without editorMode and publishDate', () => { const spy = jest.spyOn(store, 'loadPageAsset'); spectator.click(byTestId('close-preview-mode')); spectator.detectChanges(); - expect(spy).toHaveBeenCalledWith({ preview: null }); + expect(spy).toHaveBeenCalledWith({ editorMode: undefined, publishDate: undefined }); + }); + + it('should call store.loadPageAsset when datePreview model is updated', () => { + const spy = jest.spyOn(store, 'loadPageAsset'); + + spectator.debugElement.componentInstance.$previewDate.set(new Date('2024-02-01')); + spectator.detectChanges(); + + expect(spy).toHaveBeenCalledWith({ + editorMode: UVE_MODE.PREVIEW, + publishDate: new Date('2024-02-01').toISOString() + }); + }); + + it('should call store.loadPageAsset with currentDate when datePreview model is updated with a past date', () => { + const spy = jest.spyOn(store, 'loadPageAsset'); + + spectator.debugElement.componentInstance.$previewDate.set(new Date('2023-02-01')); + spectator.detectChanges(); + + expect(spy).toHaveBeenCalledWith({ + editorMode: UVE_MODE.PREVIEW, + publishDate: fixedDate.toISOString() + }); }); }); it('should have desktop button', () => { + spectator.detectChanges(); expect(spectator.query(byTestId('desktop-preview'))).toBeTruthy(); }); it('should have mobile button', () => { + spectator.detectChanges(); expect(spectator.query(byTestId('mobile-preview'))).toBeTruthy(); }); it('should have tablet button', () => { + spectator.detectChanges(); expect(spectator.query(byTestId('tablet-preview'))).toBeTruthy(); }); it('should have more devices button', () => { + spectator.detectChanges(); expect(spectator.query(byTestId('more-devices-preview'))).toBeTruthy(); }); it('should not have experiments', () => { + spectator.detectChanges(); expect(spectator.query(byTestId('uve-toolbar-running-experiment'))).toBeFalsy(); }); diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.ts index 0f649288747d..7c8d9d567d4b 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.ts @@ -6,8 +6,11 @@ import { computed, EventEmitter, inject, + model, Output, - viewChild + effect, + viewChild, + untracked } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; @@ -18,8 +21,10 @@ import { ChipModule } from 'primeng/chip'; import { SplitButtonModule } from 'primeng/splitbutton'; import { ToolbarModule } from 'primeng/toolbar'; +import { UVE_MODE } from '@dotcms/client'; import { DotMessageService, DotPersonalizeService } from '@dotcms/data-access'; import { DotPersona, DotLanguage } from '@dotcms/dotcms-models'; +import { DotMessagePipe } from '@dotcms/ui'; import { DEFAULT_PERSONA } from '../../../shared/consts'; import { DotPage } from '../../../shared/models'; @@ -49,6 +54,8 @@ import { EditEmaPersonaSelectorComponent } from '../edit-ema-persona-selector/ed ReactiveFormsModule, EditEmaPersonaSelectorComponent, EditEmaLanguageSelectorComponent, + ClipboardModule, + DotMessagePipe, DotUveWorkflowActionsComponent, ChipModule ], @@ -74,6 +81,8 @@ export class DotUveToolbarComponent { readonly $apiURL = this.#store.$apiURL; readonly $personaSelectorProps = this.#store.$personaSelector; + protected readonly CURRENT_DATE = new Date(); + readonly $styleToolbarClass = computed(() => { if (!this.$isPreviewMode()) { return 'uve-toolbar'; @@ -82,6 +91,35 @@ export class DotUveToolbarComponent { return 'uve-toolbar uve-toolbar-preview'; }); + protected readonly publishDateParam = this.#store.pageParams().publishDate; + protected readonly $previewDate = model( + this.publishDateParam ? new Date(this.publishDateParam) : null + ); + + readonly $previewDateEffect = effect( + () => { + const previewDate = this.$previewDate(); + + if (!previewDate) { + return; + } + + // If previewDate is minor that the CURRENT DATE, set previewDate to CURRENT DATE + if (previewDate < this.CURRENT_DATE) { + this.$previewDate.set(this.CURRENT_DATE); + + return; + } + + untracked(() => { + this.#store.loadPageAsset({ + editorMode: UVE_MODE.PREVIEW, + publishDate: previewDate?.toISOString() + }); + }); + }, + { allowSignalWrites: true } + ); readonly $pageInode = computed(() => { return this.#store.pageAPIResponse()?.page.inode; }); @@ -89,24 +127,23 @@ export class DotUveToolbarComponent { readonly $actions = this.#store.workflowLoading; readonly $workflowLoding = this.#store.workflowLoading; - protected readonly date = new Date(); - /** - * Set the preview mode + * Initialize the preview mode * + * @param {Date} publishDate * @memberof DotUveToolbarComponent */ - protected setPreviewMode() { - this.#store.loadPageAsset({ preview: 'true' }); + protected triggerPreviewMode(publishDate = new Date()) { + this.$previewDate.set(publishDate); } /** - * Set the edit mode + * Initialize the edit mode * * @memberof DotUveToolbarComponent */ - protected setEditMode() { - this.#store.loadPageAsset({ preview: null }); + protected triggerEditMode() { + this.#store.loadPageAsset({ editorMode: undefined, publishDate: undefined }); } /** @@ -135,6 +172,11 @@ export class DotUveToolbarComponent { this.#store.loadPageAsset({ language_id }); } + /** + * Trigger the copy toasts + * + * @memberof DotUveToolbarComponent + */ triggerCopyToast() { this.#messageService.add({ severity: 'success', diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/edit-ema-editor.component.spec.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/edit-ema-editor.component.spec.ts index d40d3308e568..9e26efa742fe 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/edit-ema-editor.component.spec.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/edit-ema-editor.component.spec.ts @@ -2918,21 +2918,6 @@ describe('EditEmaEditorComponent', () => { describe('CUSTOMER ACTIONS', () => { describe('CLIENT_READY', () => { - it('should set client is ready when not extra configuration is send', () => { - const setIsClientReadySpy = jest.spyOn(store, 'setIsClientReady'); - - window.dispatchEvent( - new MessageEvent('message', { - origin: HOST, - data: { - action: CLIENT_ACTIONS.CLIENT_READY - } - }) - ); - - expect(setIsClientReadySpy).toHaveBeenCalledWith(true); - }); - it('should set client GraphQL configuration and call the reload', () => { const setClientConfigurationSpy = jest.spyOn( store, diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/edit-ema-editor.component.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/edit-ema-editor.component.ts index a26c028c30cf..03adcd56f94e 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/edit-ema-editor.component.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/edit-ema-editor.component.ts @@ -1011,13 +1011,6 @@ export class EditEmaEditorComponent implements OnInit, OnDestroy { return; } - // If there is no client configuration, we just set the client as ready - if (!clientConfig) { - this.uveStore.setIsClientReady(true); - - return; - } - this.uveStore.setClientConfiguration({ query, params }); this.uveStore.reloadCurrentPage(); }, diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/services/dot-page-api.service.spec.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/services/dot-page-api.service.spec.ts index 903e24d7e79a..e881a5096d35 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/services/dot-page-api.service.spec.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/services/dot-page-api.service.spec.ts @@ -1,5 +1,7 @@ import { createHttpFactory, HttpMethod, SpectatorHttp } from '@ngneat/spectator'; +import { UVE_MODE } from '@dotcms/client'; + import { DotPageApiService } from './dot-page-api.service'; describe('DotPageApiService', () => { @@ -109,13 +111,13 @@ describe('DotPageApiService', () => { }); describe('preview', () => { - it("should request page in preview mode if 'preview' is true", () => { + it("should request page in preview mode if 'editorMode' is 'preview'", () => { spectator.service .get({ url: 'test-url', language_id: 'en', 'com.dotmarketing.persona.id': 'modes.persona.no.persona', - preview: 'true' + editorMode: UVE_MODE.PREVIEW }) .subscribe(); diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/services/dot-page-api.service.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/services/dot-page-api.service.ts index 252b60f6609e..9669f7e82fda 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/services/dot-page-api.service.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/services/dot-page-api.service.ts @@ -5,7 +5,7 @@ import { Injectable } from '@angular/core'; import { catchError, map, pluck } from 'rxjs/operators'; -import { graphqlToPageEntity } from '@dotcms/client'; +import { graphqlToPageEntity, UVE_MODE } from '@dotcms/client'; import { Site } from '@dotcms/dotcms-js'; import { DEFAULT_VARIANT_ID, @@ -19,7 +19,7 @@ import { } from '@dotcms/dotcms-models'; import { PAGE_MODE } from '../shared/enums'; -import { DotPage, SavePagePayload } from '../shared/models'; +import { DotPage, DotPageAssetParams, SavePagePayload } from '../shared/models'; import { ClientRequestProps } from '../store/features/client/withClient'; import { createPageApiUrlWithQueryParams } from '../utils'; @@ -43,15 +43,15 @@ export interface DotPageApiParams { url: string; language_id: string; 'com.dotmarketing.persona.id': string; - preview?: string; variantName?: string; experimentId?: string; mode?: string; clientHost?: string; depth?: string; + publishDate?: string; } -export enum DotPageApiKeys { +export enum DotPageAssetKeys { URL = 'url', MODE = 'mode', DEPTH = 'depth', @@ -60,7 +60,8 @@ export enum DotPageApiKeys { LANGUAGE_ID = 'language_id', EXPERIMENT_ID = 'experimentId', PERSONA_ID = 'com.dotmarketing.persona.id', - PREVIEW = 'preview' + PUBLISH_DATE = 'publishDate', + EDITOR_MODE = 'editorMode' } export interface GetPersonasParams { @@ -92,13 +93,21 @@ export class DotPageApiService { * @return {*} {Observable} * @memberof DotPageApiService */ - get(params: DotPageApiParams): Observable { + get(params: DotPageAssetParams): Observable { // Remove trailing and leading slashes - const { clientHost, preview, depth = '0', language_id, variantName, experimentId } = params; + const { + clientHost, + editorMode, + depth = '0', + language_id, + variantName, + experimentId, + publishDate + } = params; const url = params.url.replace(/^\/+|\/+$/g, ''); - const isPreview = preview === 'true'; const pageType = clientHost ? 'json' : 'render'; + const isPreview = editorMode === UVE_MODE.PREVIEW; const mode = isPreview ? PAGE_MODE.LIVE : PAGE_MODE.EDIT; const pageApiUrl = createPageApiUrlWithQueryParams(url, { @@ -107,7 +116,8 @@ export class DotPageApiService { variantName, experimentId, depth, - mode + mode, + publishDate: publishDate ?? undefined }); const apiUrl = `/api/v1/page/${pageType}/${pageApiUrl}`; diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/shared/models.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/shared/models.ts index d37c3ea172d1..9384e66bf6a9 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/shared/models.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/shared/models.ts @@ -1,4 +1,4 @@ -import { CLIENT_ACTIONS } from '@dotcms/client'; +import { UVE_MODE, CLIENT_ACTIONS } from '@dotcms/client'; import { DotCMSContentlet, DotDevice } from '@dotcms/dotcms-models'; import { InfoPage } from '@dotcms/ui'; @@ -246,3 +246,5 @@ export interface ReorderMenuPayload { startLevel: number; depth: number; } + +export type DotPageAssetParams = DotPageApiParams & { editorMode?: UVE_MODE }; diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/store/dot-uve.store.spec.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/store/dot-uve.store.spec.ts index 4755c10f8e5e..2e676a06596b 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/store/dot-uve.store.spec.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/store/dot-uve.store.spec.ts @@ -12,6 +12,7 @@ import { ActivatedRoute, Router } from '@angular/router'; import { MessageService } from 'primeng/api'; +import { UVE_MODE } from '@dotcms/client'; import { DotExperimentsService, DotLanguagesService, @@ -362,13 +363,13 @@ describe('UVEStore', () => { describe('$isPreviewMode', () => { it("should return true when the preview is 'true'", () => { - store.loadPageAsset({ preview: 'true' }); + store.loadPageAsset({ editorMode: UVE_MODE.PREVIEW }); expect(store.$isPreviewMode()).toBe(true); }); it("should return false when the preview is not 'true'", () => { - store.loadPageAsset({ preview: null }); + store.loadPageAsset({ editorMode: null }); expect(store.$isPreviewMode()).toBe(false); }); diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/store/dot-uve.store.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/store/dot-uve.store.ts index e6fb45529b9d..c28caa65b7de 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/store/dot-uve.store.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/store/dot-uve.store.ts @@ -2,6 +2,8 @@ import { patchState, signalStore, withComputed, withMethods, withState } from '@ import { computed, untracked } from '@angular/core'; +import { UVE_MODE } from '@dotcms/client'; + import { withEditor } from './features/editor/withEditor'; import { withFlags } from './features/flags/withFlags'; import { withLayout } from './features/layout/withLayout'; @@ -126,7 +128,7 @@ export const UVEStore = signalStore( return pageAPIResponse()?.viewAs.language?.id || 1; }), $isPreviewMode: computed(() => { - return pageParams()?.preview === 'true'; + return pageParams()?.editorMode === UVE_MODE.PREVIEW; }) }; } diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/client/withClient.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/client/withClient.ts index 6cd615abea96..30690ba2c8f1 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/client/withClient.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/client/withClient.ts @@ -55,6 +55,8 @@ export function withClient() { }, setClientConfiguration: ({ query, params }: ClientRequestProps) => { patchState(store, { + // Added this to avoid the client ready event to be triggered + isClientReady: true, clientRequestProps: { query, params diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/editor/toolbar/withUVEToolbar.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/editor/toolbar/withUVEToolbar.ts index 1bd25f53c8fd..7b6281746207 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/editor/toolbar/withUVEToolbar.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/editor/toolbar/withUVEToolbar.ts @@ -9,6 +9,7 @@ import { import { computed } from '@angular/core'; +import { UVE_MODE } from '@dotcms/client'; import { DotExperimentStatus } from '@dotcms/dotcms-models'; import { DEFAULT_PERSONA } from '../../../../shared/consts'; @@ -87,7 +88,7 @@ export function withUVEToolbar() { const siteId = pageAPIResponse?.site?.identifier; const clientHost = `${params?.clientHost ?? window.location.origin}`; - const isPreview = params?.preview === 'true'; + const isPreview = params?.editorMode === UVE_MODE.PREVIEW; const prevewItem = isPreview ? { deviceSelector: { diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/editor/withEditor.spec.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/editor/withEditor.spec.ts index 14dc9b20de07..b98da56a9667 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/editor/withEditor.spec.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/editor/withEditor.spec.ts @@ -6,6 +6,7 @@ import { of } from 'rxjs'; import { ActivatedRoute, Router } from '@angular/router'; +import { UVE_MODE } from '@dotcms/client'; import { CurrentUser } from '@dotcms/dotcms-js'; import { DEFAULT_VARIANT_ID, DEFAULT_VARIANT_NAME, DotCMSContentlet } from '@dotcms/dotcms-models'; import { getRunningExperimentMock, mockDotDevices, seoOGTagsMock } from '@dotcms/utils-testing'; @@ -672,7 +673,9 @@ describe('withEditor', () => { }); it('should not have opacity or progressBar in preview mode', () => { - patchState(store, { pageParams: { ...emptyParams, preview: 'true' } }); + patchState(store, { + pageParams: { ...emptyParams, editorMode: UVE_MODE.PREVIEW } + }); expect(store.$editorProps().iframe.opacity).toBe('1'); expect(store.$editorProps().progressBar).toBe(false); @@ -831,6 +834,20 @@ describe('withEditor', () => { expect(store.$editorProps().contentletTools).toBe(null); }); + + it('should have contentletTools when the page can be edited and is in preview mode', () => { + patchState(store, { + isEditState: true, + canEditPage: true, + pageParams: { + ...emptyParams, + editorMode: UVE_MODE.PREVIEW + }, + state: EDITOR_STATE.IDLE + }); + + expect(store.$editorProps().contentletTools).toEqual(null); + }); }); describe('dropzone', () => { const bounds = getBoundsMock(ACTION_MOCK); diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/editor/withEditor.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/editor/withEditor.ts index fe52357aa962..0e60b8be6d6c 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/editor/withEditor.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/editor/withEditor.ts @@ -9,6 +9,7 @@ import { import { computed, untracked } from '@angular/core'; +import { UVE_MODE } from '@dotcms/client'; import { DotTreeNode, SeoMetaTags } from '@dotcms/dotcms-models'; import { @@ -115,7 +116,7 @@ export function withEditor() { const dragItem = store.dragItem(); const isEditState = store.isEditState(); - const isPreview = params?.preview === 'true'; + const isPreview = params?.editorMode === UVE_MODE.PREVIEW; const isPageReady = isTraditionalPage || isClientReady || isPreview; const isLoading = !isPageReady || store.status() === UVE_STATUS.LOADING; @@ -129,7 +130,11 @@ export function withEditor() { const showBlockEditorSidebar = canEditPage && isEditState && isEnterprise; const canUserHaveContentletTools = - !!contentletArea && canEditPage && isEditState && !isScrolling; + !!contentletArea && + canEditPage && + isEditState && + !isScrolling && + !isPreview; const showDropzone = canEditPage && state === EDITOR_STATE.DRAGGING; const showPalette = isEnterprise && canEditPage && isEditState && !isPreview; diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/load/withLoad.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/load/withLoad.ts index fb532018d950..ca4c9ef6ae96 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/load/withLoad.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/load/withLoad.ts @@ -12,8 +12,9 @@ import { DotExperimentsService, DotLanguagesService, DotLicenseService } from '@ import { LoginService } from '@dotcms/dotcms-js'; import { DEFAULT_VARIANT_ID } from '@dotcms/dotcms-models'; -import { DotPageApiParams, DotPageApiService } from '../../../services/dot-page-api.service'; +import { DotPageApiService } from '../../../services/dot-page-api.service'; import { UVE_STATUS } from '../../../shared/enums'; +import { DotPageAssetParams } from '../../../shared/models'; import { computeCanEditPage, computePageIsLocked, isForwardOrPage } from '../../../utils'; import { UVEState } from '../../models'; import { withClient } from '../client/withClient'; @@ -48,11 +49,11 @@ export function withLoad() { * @param {DotPageApiParams} pageParams - The parameters used to fetch the page asset. * @memberof DotEmaShellComponent */ - loadPageAsset: rxMethod>( + loadPageAsset: rxMethod>( pipe( map((params) => { if (!store.pageParams()) { - return params as DotPageApiParams; + return params as DotPageAssetParams; } return { @@ -140,9 +141,7 @@ export function withLoad() { currentUser ); - const isPreview = pageParams.preview === 'true'; const isTraditionalPage = !pageParams.clientHost; - const isClientReady = isTraditionalPage || isPreview; patchState(store, { pageAPIResponse: pageAsset, @@ -152,7 +151,7 @@ export function withLoad() { languages, canEditPage, pageIsLocked, - isClientReady, + isClientReady: isTraditionalPage, isTraditionalPage, status: UVE_STATUS.LOADED }); diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/store/models.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/store/models.ts index 113a528e5bcc..6e0d7e59fb3d 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/store/models.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/store/models.ts @@ -7,15 +7,15 @@ import { } from '@dotcms/dotcms-models'; import { InfoPage } from '@dotcms/ui'; -import { DotPageApiParams, DotPageApiResponse } from '../services/dot-page-api.service'; +import { DotPageApiResponse } from '../services/dot-page-api.service'; import { UVE_STATUS } from '../shared/enums'; -import { DotPage, NavigationBarItem } from '../shared/models'; +import { DotPage, DotPageAssetParams, NavigationBarItem } from '../shared/models'; export interface UVEState { languages: DotLanguage[]; isEnterprise: boolean; pageAPIResponse?: DotPageApiResponse; - pageParams?: DotPageApiParams; + pageParams?: DotPageAssetParams; currentUser?: CurrentUser; experiment?: DotExperiment; errorCode?: number; diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/index.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/index.ts index fa42f0370dfe..897ce5f41314 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/index.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/index.ts @@ -1,5 +1,6 @@ import { Params } from '@angular/router'; +import { UVE_MODE } from '@dotcms/client'; import { CurrentUser } from '@dotcms/dotcms-js'; import { DEFAULT_VARIANT_ID, @@ -12,15 +13,16 @@ import { } from '@dotcms/dotcms-models'; import { EmaDragItem } from '../edit-ema-editor/components/ema-page-dropzone/types'; -import { DotPageApiKeys, DotPageApiParams } from '../services/dot-page-api.service'; +import { DotPageAssetKeys, DotPageApiParams } from '../services/dot-page-api.service'; import { COMMON_ERRORS, DEFAULT_PERSONA } from '../shared/consts'; -import { EDITOR_STATE } from '../shared/enums'; +import { EDITOR_STATE, PAGE_MODE } from '../shared/enums'; import { ActionPayload, ContainerPayload, ContentletDragPayload, ContentTypeDragPayload, DotPage, + DotPageAssetParams, DragDatasetItem, PageContainer } from '../shared/models'; @@ -218,12 +220,12 @@ export const getPersonalization = (persona: Record) => { * * @export * @param {string} url - * @param {Partial} params + * @param {Partial} params * @return {*} {string} */ export function createPageApiUrlWithQueryParams( url: string, - params: Partial + params: Partial ): string { // Set default values const completedParams = { @@ -231,7 +233,8 @@ export function createPageApiUrlWithQueryParams( language_id: params?.language_id ?? '1', 'com.dotmarketing.persona.id': params?.['com.dotmarketing.persona.id'] ?? DEFAULT_PERSONA.identifier, - variantName: params?.variantName ?? DEFAULT_VARIANT_ID + variantName: params?.variantName ?? DEFAULT_VARIANT_ID, + mode: params?.editorMode === UVE_MODE.PREVIEW ? PAGE_MODE.LIVE : params.mode }; // Filter out undefined values and url @@ -594,16 +597,16 @@ export const checkClientHostAccess = ( * @param {Params} params * @return {*} {DotPageApiParams} */ -export function getAllowedPageParams(params: Params): DotPageApiParams { - const allowedParams: DotPageApiKeys[] = Object.values(DotPageApiKeys); +export function getAllowedPageParams(params: Params): DotPageAssetParams { + const allowedParams: DotPageAssetKeys[] = Object.values(DotPageAssetKeys); return Object.keys(params) - .filter((key) => key && allowedParams.includes(key as DotPageApiKeys)) + .filter((key) => key && allowedParams.includes(key as DotPageAssetKeys)) .reduce((obj, key) => { obj[key] = params[key]; return obj; - }, {}) as DotPageApiParams; + }, {}) as DotPageAssetParams; } /** diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/utils.spec.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/utils.spec.ts index 9419124736a7..5e909c09d4d0 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/utils.spec.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/utils.spec.ts @@ -23,6 +23,7 @@ import { } from '.'; import { DotPageApiParams } from '../services/dot-page-api.service'; +import { PAGE_MODE } from '../shared/enums'; import { dotPageContainerStructureMock } from '../shared/mocks'; import { ContentletDragPayload, ContentTypeDragPayload, DotPage } from '../shared/models'; @@ -357,11 +358,11 @@ describe('utils functions', () => { language_id: '20', 'com.dotmarketing.persona.id': 'the-chosen-one', experimentId: '123', - mode: 'PREVIEW_MODE' + mode: PAGE_MODE.LIVE }; const result = createPageApiUrlWithQueryParams('test', queryParams); expect(result).toBe( - 'test?variantName=test&language_id=20&com.dotmarketing.persona.id=the-chosen-one&experimentId=123&mode=PREVIEW_MODE' + 'test?variantName=test&language_id=20&com.dotmarketing.persona.id=the-chosen-one&experimentId=123&mode=LIVE' ); }); diff --git a/core-web/libs/sdk/client/src/index.ts b/core-web/libs/sdk/client/src/index.ts index ede6358c0df3..2ed10316e5a3 100644 --- a/core-web/libs/sdk/client/src/index.ts +++ b/core-web/libs/sdk/client/src/index.ts @@ -3,7 +3,8 @@ import { CLIENT_ACTIONS, postMessageToEditor } from './lib/editor/models/client. import { CustomClientParams, DotCMSPageEditorConfig, - EditorConfig + EditorConfig, + UVE_MODE } from './lib/editor/models/editor.model'; import { InlineEditorData, @@ -42,5 +43,6 @@ export { initInlineEditing, InlineEditEventData, InlineEditorData, - INLINE_EDITING_EVENT_KEY + INLINE_EDITING_EVENT_KEY, + UVE_MODE }; diff --git a/core-web/libs/sdk/client/src/lib/editor/models/editor.model.ts b/core-web/libs/sdk/client/src/lib/editor/models/editor.model.ts index 07f28b7784be..3848e895d750 100644 --- a/core-web/libs/sdk/client/src/lib/editor/models/editor.model.ts +++ b/core-web/libs/sdk/client/src/lib/editor/models/editor.model.ts @@ -66,3 +66,8 @@ export interface ReorderMenuConfig { */ depth: number; } + +export enum UVE_MODE { + EDIT = 'edit', + PREVIEW = 'preview' +} diff --git a/core-web/libs/sdk/client/src/lib/editor/sdk-editor.spec.ts b/core-web/libs/sdk/client/src/lib/editor/sdk-editor.spec.ts index 3e0b9e8ebbdd..d65dbf56d602 100644 --- a/core-web/libs/sdk/client/src/lib/editor/sdk-editor.spec.ts +++ b/core-web/libs/sdk/client/src/lib/editor/sdk-editor.spec.ts @@ -108,6 +108,16 @@ describe('DotCMSPageEditor', () => { lastScrollYPosition: 0 }); }); + + it('should isInsideEditor return false when is preview mode', () => { + Object.defineProperty(window, 'location', { + value: { + search: '?editorMode=preview' + }, + writable: true + }); + expect(isInsideEditor()).toBe(false); + }); }); describe('Add Class to Empty Contentets', () => { @@ -164,15 +174,4 @@ describe('DotCMSPageEditor', () => { }); }); }); - - it('should isInsideEditor return false when is preview mode', () => { - Object.defineProperty(window, 'location', { - value: { - search: '?preview=true' - }, - writable: true - }); - - expect(isInsideEditor()).toBe(false); - }); }); diff --git a/core-web/libs/sdk/client/src/lib/editor/sdk-editor.ts b/core-web/libs/sdk/client/src/lib/editor/sdk-editor.ts index 54df6ccae698..e1132cfc1341 100644 --- a/core-web/libs/sdk/client/src/lib/editor/sdk-editor.ts +++ b/core-web/libs/sdk/client/src/lib/editor/sdk-editor.ts @@ -93,15 +93,21 @@ export function reorderMenu(config?: ReorderMenuConfig): void { } /** - * Checks if the code is running inside an editor. + * Checks if the code is running inside the DotCMS Universal Visual Editor (UVE). * - * @returns {boolean} Returns true if the code is running inside an editor, otherwise false. + * The function checks three conditions: + * 1. If window is defined (for SSR environments) + * 2. If the page is not in preview mode + * 3. If the current window is embedded in a parent frame + * + * @returns {boolean} Returns true if running inside the UVE editor, false if running standalone or in preview mode * @example * ```ts + * // Check if code is running in editor before initializing editor-specific features * if (isInsideEditor()) { - * console.log('Running inside the editor'); + * initEditor(config); * } else { - * console.log('Running outside the editor'); + * initStandaloneMode(); * } * ``` */ @@ -110,9 +116,7 @@ export function isInsideEditor(): boolean { return false; } - const preview = isPreviewMode(); - - if (preview) { + if (isPreviewMode()) { return false; } diff --git a/core-web/libs/sdk/client/src/lib/utils/page/common-utils.spec.ts b/core-web/libs/sdk/client/src/lib/utils/page/common-utils.spec.ts index 7d1c40c6aa61..79afca346758 100644 --- a/core-web/libs/sdk/client/src/lib/utils/page/common-utils.spec.ts +++ b/core-web/libs/sdk/client/src/lib/utils/page/common-utils.spec.ts @@ -36,15 +36,15 @@ describe('Common Utils', () => { }); describe('Is Preview Mode', () => { - it('should return true when preview mode is enabled', () => { + it('should return true when editorMode is preview', () => { jest.spyOn(window, 'location', 'get').mockReturnValueOnce({ - search: '?preview=true' + search: '?editorMode=preview' } as Location); expect(isPreviewMode()).toBe(true); }); - it('should return false when preview mode is disabled', () => { + it('should return false when editorMode is not preview', () => { jest.spyOn(window, 'location', 'get').mockReturnValueOnce({ search: '' } as Location); diff --git a/core-web/libs/sdk/client/src/lib/utils/page/common-utils.ts b/core-web/libs/sdk/client/src/lib/utils/page/common-utils.ts index b9580fc444be..f7c8c86aa26e 100644 --- a/core-web/libs/sdk/client/src/lib/utils/page/common-utils.ts +++ b/core-web/libs/sdk/client/src/lib/utils/page/common-utils.ts @@ -1,4 +1,5 @@ import { PageApiOptions } from '../../client/sdk-js-client'; +import { UVE_MODE } from '../../editor/models/editor.model'; /** * Interface representing the properties for page request parameters. @@ -57,6 +58,10 @@ export const getPageRequestParams = ({ finalParams['personaId'] = copiedParams['personaId'] || dotMarketingPersonaId; } + if (copiedParams['publishDate']) { + finalParams['publishDate'] = copiedParams['publishDate']; + } + return { path, ...finalParams @@ -70,7 +75,7 @@ export const getPageRequestParams = ({ */ export const isPreviewMode = (): boolean => { const queryParams = new URLSearchParams(window.location.search); - const isPreviewMode = queryParams.get('preview'); + const editorMode = queryParams.get('editorMode'); - return isPreviewMode === 'true'; + return editorMode === UVE_MODE.PREVIEW; }; diff --git a/examples/nextjs/src/hooks/usePageAsset.js b/examples/nextjs/src/hooks/usePageAsset.js index c67553920274..c46270d8c84f 100644 --- a/examples/nextjs/src/hooks/usePageAsset.js +++ b/examples/nextjs/src/hooks/usePageAsset.js @@ -5,7 +5,6 @@ import { CLIENT_ACTIONS, isInsideEditor, postMessageToEditor } from '@dotcms/cli export const usePageAsset = (currentPageAsset) => { const [pageAsset, setPageAsset] = useState(null); - useEffect(() => { if (!isInsideEditor()) { return;