Skip to content

Commit

Permalink
chore(uve): FTM - Implement Date picker and render future contentlets…
Browse files Browse the repository at this point in the history
… 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 <[email protected]>
  • Loading branch information
KevinDavilaDotCMS and kevindaviladev authored Dec 19, 2024
1 parent 8495afd commit de7ba14
Show file tree
Hide file tree
Showing 28 changed files with 293 additions and 128 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 = {
Expand Down Expand Up @@ -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'
);
});

Expand Down Expand Up @@ -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 });
Expand Down Expand Up @@ -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');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { ToastModule } from 'primeng/toast';

import { skip } from 'rxjs/operators';

import { UVE_MODE } from '@dotcms/client';
import {
DotESContentService,
DotExperimentsService,
Expand All @@ -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,
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,18 @@

@if (preview) {
<div class="p-toolbar-group-center">
<div>
<p-button
icon="pi pi-chevron-left"
styleClass="p-button-text p-button-sm"
data-testId="arrow-left" />
<p-button
icon="pi pi-chevron-right"
styleClass="p-button-text p-button-sm"
data-testId="arrow-right" />
</div>
<p-calendar
inputStyleClass="p-inputtext-sm"
[(ngModel)]="date"
[(ngModel)]="$previewDate"
[showTime]="true"
[hourFormat]="'12'"
[minDate]="CURRENT_DATE"
[readonlyInput]="true" />
<p-chip styleClass="uve-toolbar-chips" label="Today" alt="Page Day" />
<p-button
styleClass="uve-toolbar-chips"
[label]="'Today' | dm"
alt="Page Day"
(click)="triggerPreviewMode()" />
</div>
}

Expand Down Expand Up @@ -62,7 +59,7 @@
icon="pi pi-eye"
styleClass="p-button-text p-button-sm"
data-testId="uve-toolbar-preview"
(click)="setPreviewMode()" />
(click)="triggerPreviewMode()" />

<dot-ema-bookmarks [url]="$toolbar().editor.bookmarksUrl" />

Expand All @@ -89,7 +86,7 @@
<p-button
icon="pi pi-times"
styleClass="p-button-text p-button-sm"
(click)="setEditMode()"
(click)="triggerEditMode()"
data-testId="close-preview-mode" />

<div class="vertical-divider"></div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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: [
Expand Down Expand Up @@ -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()
});
});
});

Expand Down Expand Up @@ -378,7 +385,10 @@ describe('DotUveToolbarComponent', () => {
beforeEach(() => {
spectator = createComponent({
providers: [
mockProvider(UVEStore, { ...baseUVEState, $isPreviewMode: signal(true) })
mockProvider(UVEStore, {
...baseUVEState,
$isPreviewMode: signal(true)
})
]
});

Expand All @@ -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();
});

Expand Down
Loading

0 comments on commit de7ba14

Please sign in to comment.