Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(uve): Add FF for Preview Mode #30623

Merged
merged 12 commits into from
Nov 12, 2024
3 changes: 2 additions & 1 deletion core-web/libs/dotcms-models/src/lib/shared-models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ export const enum FeaturedFlags {
FEATURE_FLAG_CONTENT_EDITOR2_ENABLED = 'CONTENT_EDITOR2_ENABLED',
FEATURE_FLAG_CONTENT_EDITOR2_CONTENT_TYPE = 'CONTENT_EDITOR2_CONTENT_TYPE',
FEATURE_FLAG_ANNOUNCEMENTS = 'FEATURE_FLAG_ANNOUNCEMENTS',
FEATURE_FLAG_NEW_EDIT_PAGE = 'FEATURE_FLAG_NEW_EDIT_PAGE'
FEATURE_FLAG_NEW_EDIT_PAGE = 'FEATURE_FLAG_NEW_EDIT_PAGE',
FEATURE_FLAG_UVE_PREVIEW_MODE = 'FEATURE_FLAG_UVE_PREVIEW_MODE'
}

export const FEATURE_FLAG_NOT_FOUND = 'NOT_FOUND';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
DotLanguagesService,
DotLicenseService,
DotMessageService,
DotPropertiesService,
DotWorkflowActionsFireService,
PushPublishService
} from '@dotcms/data-access';
Expand Down Expand Up @@ -56,6 +57,7 @@ import { DotPageApiService } from '../services/dot-page-api.service';
import { DEFAULT_PERSONA, WINDOW } from '../shared/consts';
import { FormStatus, NG_CUSTOM_EVENTS } from '../shared/enums';
import {
dotPropertiesServiceMock,
PAGE_RESPONSE_BY_LANGUAGE_ID,
PAGE_RESPONSE_URL_CONTENT_MAP,
PAYLOAD_MOCK
Expand Down Expand Up @@ -103,6 +105,10 @@ describe('DotEmaShellComponent', () => {
DotMessageService,
DialogService,
DotWorkflowActionsFireService,
{
provide: DotPropertiesService,
useValue: dotPropertiesServiceMock
},
{
provide: DotcmsConfigService,
useValue: new DotcmsConfigServiceMock()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>dot-uve-toolbar works!</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { DotUveToolbarComponent } from './dot-uve-toolbar.component';

describe('DotUveToolbarComponent', () => {
let component: DotUveToolbarComponent;
let fixture: ComponentFixture<DotUveToolbarComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [DotUveToolbarComponent]
}).compileComponents();

fixture = TestBed.createComponent(DotUveToolbarComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';

@Component({
selector: 'dot-uve-toolbar',
standalone: true,
imports: [],
templateUrl: './dot-uve-toolbar.component.html',
styleUrl: './dot-uve-toolbar.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class DotUveToolbarComponent {}
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
<dot-edit-ema-toolbar (editUrlContentMap)="editContentMap($event)" />
@if ($previewMode()) {
<dot-uve-toolbar />
} @else {
<dot-edit-ema-toolbar (editUrlContentMap)="editContentMap($event)" />
}

@if ($editorProps().seoResults && ogTagsResults$) {
<dot-results-seo-tool
[seoMedia]="$editorProps().seoResults.socialMedia"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ dot-ema-page-dropzone {
inset: 0;
}

dot-edit-ema-toolbar {
dot-edit-ema-toolbar,
dot-uve-toolbar {
grid-column: 1 / -1;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
DotLicenseService,
DotMessageService,
DotPersonalizeService,
DotPropertiesService,
DotSeoMetaTagsService,
DotSeoMetaTagsUtilService,
DotTempFileUploadService,
Expand Down Expand Up @@ -67,6 +68,7 @@ import {

import { DotEditEmaWorkflowActionsComponent } from './components/dot-edit-ema-workflow-actions/dot-edit-ema-workflow-actions.component';
import { DotEmaRunningExperimentComponent } from './components/dot-ema-running-experiment/dot-ema-running-experiment.component';
import { DotUveToolbarComponent } from './components/dot-uve-toolbar/dot-uve-toolbar.component';
import { CONTENT_TYPE_MOCK } from './components/edit-ema-palette/components/edit-ema-palette-content-type/edit-ema-palette-content-type.component.spec';
import { CONTENTLETS_MOCK } from './components/edit-ema-palette/edit-ema-palette.component.spec';
import { EditEmaToolbarComponent } from './components/edit-ema-toolbar/edit-ema-toolbar.component';
Expand All @@ -87,7 +89,8 @@ import {
newContentlet,
PAYLOAD_MOCK,
UVE_PAGE_RESPONSE_MAP,
EMA_DRAG_ITEM_CONTENTLET_MOCK
EMA_DRAG_ITEM_CONTENTLET_MOCK,
dotPropertiesServiceMock
} from '../shared/mocks';
import { ActionPayload, ContentTypeDragPayload } from '../shared/models';
import { UVEStore } from '../store/dot-uve.store';
Expand Down Expand Up @@ -144,6 +147,13 @@ const createRouting = () =>
UVEStore,
DotFavoritePageService,
DotESContentService,
{
provide: DotPropertiesService,
useValue: {
...dotPropertiesServiceMock,
getKeyAsList: () => of([])
}
},
{
provide: DotAlertConfirmService,
useValue: {
Expand Down Expand Up @@ -378,7 +388,6 @@ describe('EditEmaEditorComponent', () => {
dotWorkflowActionsFireService = spectator.inject(DotWorkflowActionsFireService, true);
router = spectator.inject(Router, true);
dotPageApiService = spectator.inject(DotPageApiService, true);

addMessageSpy = jest.spyOn(messageService, 'add');
jest.spyOn(dotLicenseService, 'isEnterprise').mockReturnValue(of(true));

Expand Down Expand Up @@ -421,6 +430,23 @@ describe('EditEmaEditorComponent', () => {
});
});

it('should show the old toolbar when FEATURE_FLAG_UVE_PREVIEW_MODE is false', () => {
const toolbar = spectator.query(EditEmaToolbarComponent);

expect(toolbar).not.toBeNull();
});

it('should show the new toolbar when FEATURE_FLAG_UVE_PREVIEW_MODE is true', () => {
store.setFlags({
FEATURE_FLAG_UVE_PREVIEW_MODE: true
});
spectator.detectChanges();

const toolbar = spectator.query(DotUveToolbarComponent);

expect(toolbar).not.toBeNull();
});

it('should hide components when the store changes for a variant', () => {
const componentsToHide = [
'palette',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,10 @@ import {
SeoMetaTagsResult
} from '@dotcms/dotcms-models';
import { DotResultsSeoToolComponent } from '@dotcms/portlets/dot-ema/ui';
import {
SafeUrlPipe,
DotSpinnerModule,
DotMessagePipe,
DotCopyContentModalService
} from '@dotcms/ui';
import { SafeUrlPipe, DotSpinnerModule, DotCopyContentModalService } from '@dotcms/ui';
import { isEqual } from '@dotcms/utils';

import { DotEmaBookmarksComponent } from './components/dot-ema-bookmarks/dot-ema-bookmarks.component';
import { DotUveToolbarComponent } from './components/dot-uve-toolbar/dot-uve-toolbar.component';
import { EditEmaPaletteComponent } from './components/edit-ema-palette/edit-ema-palette.component';
import { EditEmaToolbarComponent } from './components/edit-ema-toolbar/edit-ema-toolbar.component';
import { EmaContentletToolsComponent } from './components/ema-contentlet-tools/ema-contentlet-tools.component';
Expand Down Expand Up @@ -110,13 +105,12 @@ import {
DotEmaDialogComponent,
ConfirmDialogModule,
EditEmaToolbarComponent,
DotMessagePipe,
EmaPageDropzoneComponent,
EditEmaPaletteComponent,
EmaContentletToolsComponent,
DotEmaBookmarksComponent,
ProgressBarModule,
DotResultsSeoToolComponent,
DotUveToolbarComponent,
DotBlockEditorSidebarComponent
],
providers: [
Expand Down Expand Up @@ -158,6 +152,7 @@ export class EditEmaEditorComponent implements OnInit, OnDestroy {
readonly host = '*';
readonly $ogTags: WritableSignal<SeoMetaTags> = signal(undefined);
readonly $editorProps = this.uveStore.$editorProps;
readonly $previewMode = this.uveStore.$previewMode;

get contentWindow(): Window {
return this.iframe.nativeElement.contentWindow;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { InjectionToken } from '@angular/core';

import { DotPersona } from '@dotcms/dotcms-models';
import { DotPersona, FeaturedFlags } from '@dotcms/dotcms-models';

import { CommonErrors } from './enums';
import { CommonErrorsInfo } from './models';
Expand Down Expand Up @@ -67,3 +67,5 @@ export const DEFAULT_PERSONA: DotPersona = {
hasLiveVersion: false,
modUser: 'system'
};

export const UVE_FEATURE_FLAGS = [FeaturedFlags.FEATURE_FLAG_UVE_PREVIEW_MODE];
10 changes: 9 additions & 1 deletion core-web/libs/portlets/edit-ema/portlet/src/lib/shared/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { of } from 'rxjs';
import {
DEFAULT_VARIANT_ID,
DotPageContainerStructure,
CONTAINER_SOURCE
CONTAINER_SOURCE,
FeaturedFlags
} from '@dotcms/dotcms-models';
import {
mockSites,
Expand Down Expand Up @@ -956,3 +957,10 @@ export const UVE_PAGE_RESPONSE_MAP = {
containers: dotPageContainerStructureMock
})
};

export const dotPropertiesServiceMock = {
getFeatureFlags: () =>
of({
[FeaturedFlags.FEATURE_FLAG_UVE_PREVIEW_MODE]: false
})
};
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import {
DotExperimentsService,
DotLanguagesService,
DotLicenseService,
DotMessageService
DotMessageService,
DotPropertiesService
} from '@dotcms/data-access';
import { LoginService } from '@dotcms/dotcms-js';
import {
Expand All @@ -37,6 +38,7 @@ import { UVE_STATUS } from '../shared/enums';
import {
BASE_SHELL_ITEMS,
BASE_SHELL_PROPS_RESPONSE,
dotPropertiesServiceMock,
HEADLESS_BASE_QUERY_PARAMS,
MOCK_RESPONSE_HEADLESS,
MOCK_RESPONSE_VTL,
Expand Down Expand Up @@ -65,6 +67,10 @@ describe('UVEStore', () => {
MessageService,
mockProvider(Router),
mockProvider(ActivatedRoute),
{
provide: DotPropertiesService,
useValue: dotPropertiesServiceMock
},
{
provide: DotPageApiService,
useValue: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import { patchState, signalStore, withComputed, withMethods, withState } from '@
import { computed } from '@angular/core';

import { withEditor } from './features/editor/withEditor';
import { withFlags } from './features/flags/withFlags';
import { withLayout } from './features/layout/withLayout';
import { withLoad } from './features/load/withLoad';
import { ShellProps, TranslateProps, UVEState } from './models';

import { DotPageApiResponse } from '../services/dot-page-api.service';
import { UVE_FEATURE_FLAGS } from '../shared/consts';
import { UVE_STATUS } from '../shared/enums';
import { getErrorPayload, getRequestHostName, sanitizeURL } from '../utils';

Expand Down Expand Up @@ -145,5 +147,6 @@ export const UVEStore = signalStore(
}),
withLoad(),
withLayout(),
withEditor()
withEditor(),
withFlags(UVE_FEATURE_FLAGS)
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { FeaturedFlags } from '@dotcms/dotcms-models';

export type UVEFlags = { [key in FeaturedFlags]?: boolean };

export interface WithFlagsState {
flags: UVEFlags;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { describe } from '@jest/globals';
import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest';
import { signalStore, withState } from '@ngrx/signals';
import { of } from 'rxjs';

import { DotPropertiesService } from '@dotcms/data-access';
import { FeaturedFlags } from '@dotcms/dotcms-models';

import { withFlags } from './withFlags';

import { DotPageApiParams } from '../../../services/dot-page-api.service';
import { UVE_FEATURE_FLAGS } from '../../../shared/consts';
import { UVE_STATUS } from '../../../shared/enums';
import { UVEState } from '../../models';

const initialState: UVEState = {
isEnterprise: false,
languages: [],
pageAPIResponse: null,
currentUser: null,
experiment: null,
errorCode: null,
params: {} as DotPageApiParams,
status: UVE_STATUS.LOADING,
isTraditionalPage: true,
canEditPage: false,
pageIsLocked: true
};

export const uveStoreMock = signalStore(
withState<UVEState>(initialState),
withFlags(UVE_FEATURE_FLAGS)
);

const MOCK_RESPONSE = UVE_FEATURE_FLAGS.reduce((acc, flag) => {
acc[flag] = true;

return acc;
}, {});

describe('withFlags', () => {
let spectator: SpectatorService<InstanceType<typeof uveStoreMock>>;
let store: InstanceType<typeof uveStoreMock>;

const createService = createServiceFactory({
service: uveStoreMock,
providers: [
{
provide: DotPropertiesService,
useValue: {
getFeatureFlags: jest.fn().mockReturnValue(of(MOCK_RESPONSE))
}
}
]
});

beforeEach(() => {
spectator = createService();
store = spectator.service;
});

describe('onInit', () => {
it('should call propertiesService.getFeatureFlags with flags', () => {
const propertiesService = spectator.inject(DotPropertiesService);

expect(propertiesService.getFeatureFlags).toHaveBeenCalledWith(UVE_FEATURE_FLAGS);
});

it('should patch state with flags', () => {
expect(store.flags()).toEqual(MOCK_RESPONSE);
});
});
describe('methods', () => {
describe('setFlags', () => {
it('should patch state with flags', () => {
store.setFlags(MOCK_RESPONSE);

expect(store.flags()).toEqual(MOCK_RESPONSE);
});
});
});
describe('computed', () => {
it('should return $previewMode', () => {
expect(store.$previewMode()).toEqual(
MOCK_RESPONSE[FeaturedFlags.FEATURE_FLAG_UVE_PREVIEW_MODE]
);
});
});
});
Loading