Skip to content

Commit

Permalink
feat(edit-page-v2): Enable Navigation Sorting feature (#28208)
Browse files Browse the repository at this point in the history
* create new macro

* listen to new dispatched event

* testing

* testing solution

* Update edit-ema-editor.component.ts

* potential fix

* final implementation

* code cleaning

* add test cases

* Update edit-ema-editor.component.ts

* add test cases

* Update edit-ema-editor.component.spec.ts

* Update dotCMS/src/main/webapp/WEB-INF/velocity/VM_global_library.vm

Co-authored-by: Freddy Montes <751424+fmontes@users.noreply.github.com>

---------

Co-authored-by: Freddy Montes <751424+fmontes@users.noreply.github.com>
  • Loading branch information
zJaaal and fmontes authored Apr 16, 2024
1 parent a5c816a commit e8eba24
Show file tree
Hide file tree
Showing 11 changed files with 945 additions and 659 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -325,5 +325,16 @@ describe('DotEmaDialogComponent', () => {

expect(resetSpy).toHaveBeenCalled();
});

it("should trigger openDialogOnURL in the store when it's a URL", () => {
const openDialogOnURLSpy = jest.spyOn(storeSpy, 'openDialogOnURL');

component.openDialogOnUrl('https://demo.dotcms.com/jsp.jsp', 'test');

expect(openDialogOnURLSpy).toHaveBeenCalledWith({
title: 'test',
url: 'https://demo.dotcms.com/jsp.jsp'
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,17 @@ export class DotEmaDialogComponent {
});
}

/**
* Open dialog on URL
*
* @param {string} url
* @param {string} title
* @memberof DotEmaDialogComponent
*/
openDialogOnUrl(url: string, title: string) {
this.store.openDialogOnURL({ url, title });
}

/**
* Iframe load event
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,4 +205,21 @@ describe('DotEmaDialogStoreService', () => {
done();
});
});

it('should update the state to show dialog with a specific URL', (done) => {
spectator.service.openDialogOnURL({
url: 'https://demo.dotcms.com/jsp.jsp',
title: 'test'
});

spectator.service.dialogState$.subscribe((state) => {
expect(state).toEqual({
url: 'https://demo.dotcms.com/jsp.jsp',
status: DialogStatus.LOADING,
header: 'test',
type: 'content'
});
done();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,23 @@ export class DotEmaDialogStore extends ComponentStore<EditEmaDialogState> {
}
);

/**
* This method is called when we need to open a dialog with a specific URL
*
* @memberof DotEmaDialogStore
*/
readonly openDialogOnURL = this.updater(
(state, { url, title }: { url: string; title: string }) => {
return {
...state,
header: title,
status: DialogStatus.LOADING,
url,
type: 'content'
};
}
);

/**
* This method is called when the user clicks in the + button in the jsp dialog or drag a contentType from the palette
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,126 @@ describe('EditEmaEditorComponent', () => {
);
});

describe('reorder navigation', () => {
it('should open a dialog to reorder the navigation', () => {
window.dispatchEvent(
new MessageEvent('message', {
origin: HOST,
data: {
action: CUSTOMER_ACTIONS.REORDER_MENU,
payload: {
reorderUrl: 'http://localhost:3000/reorder-menu'
}
}
})
);

spectator.detectComponentChanges();

const dialog = spectator.debugElement.query(
By.css("[data-testId='ema-dialog']")
);

const pDialog = dialog.query(By.css('p-dialog'));

expect(pDialog.attributes['ng-reflect-visible']).toBe('true');
});

it('should reload the page after saving the new navigation order', () => {
const reloadSpy = jest.spyOn(store, 'reload');
const messageSpy = jest.spyOn(messageService, 'add');
const dialog = spectator.debugElement.query(
By.css("[data-testId='ema-dialog']")
);

triggerCustomEvent(dialog, 'action', {
event: new CustomEvent('ng-event', {
detail: {
name: NG_CUSTOM_EVENTS.SAVE_MENU_ORDER
}
})
});

expect(reloadSpy).toHaveBeenCalledWith({
params: {
language_id: 1,
url: 'page-one'
}
});

expect(messageSpy).toHaveBeenCalledWith({
severity: 'success',
summary: 'editpage.content.contentlet.menu.reorder.title',
detail: 'message.menu.reordered',
life: 2000
});

const pDialog = dialog.query(By.css('p-dialog'));

expect(pDialog.attributes['ng-reflect-visible']).toBe('false');
});

it('should advice the users when they can not save the new order', () => {
const messageSpy = jest.spyOn(messageService, 'add');
const dialog = spectator.debugElement.query(
By.css("[data-testId='ema-dialog']")
);

triggerCustomEvent(dialog, 'action', {
event: new CustomEvent('ng-event', {
detail: {
name: NG_CUSTOM_EVENTS.ERROR_SAVING_MENU_ORDER
}
})
});

expect(messageSpy).toHaveBeenCalledWith({
severity: 'error',
summary: 'editpage.content.contentlet.menu.reorder.title',
detail: 'error.menu.reorder.user_has_not_permission',
life: 2000
});
});

it('should close the dialog if the users cancel the reorder action', () => {
window.dispatchEvent(
new MessageEvent('message', {
origin: HOST,
data: {
action: CUSTOMER_ACTIONS.REORDER_MENU,
payload: {
reorderUrl: 'http://localhost:3000/reorder-menu'
}
}
})
);

spectator.detectComponentChanges();

let dialog = spectator.debugElement.query(
By.css("[data-testId='ema-dialog']")
);

let pDialog = dialog.query(By.css('p-dialog'));

expect(pDialog.attributes['ng-reflect-visible']).toBe('true');

dialog = spectator.debugElement.query(By.css("[data-testId='ema-dialog']"));

triggerCustomEvent(dialog, 'action', {
event: new CustomEvent('ng-event', {
detail: {
name: NG_CUSTOM_EVENTS.CANCEL_SAVING_MENU_ORDER
}
})
});

pDialog = dialog.query(By.css('p-dialog'));

expect(pDialog.attributes['ng-reflect-visible']).toBe('false');
});
});

xdescribe('reload', () => {
let spyContentlet: jest.SpyInstance;
let spyDialog: jest.SpyInstance;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,56 +68,20 @@ import {
PositionPayload,
ClientData,
SetUrlPayload,
ContainerPayload,
ContentletPayload,
PageContainer,
VTLFile
VTLFile,
ReorderPayload,
PostMessagePayload,
ContentletDragPayload,
DeletePayload,
DraggedPalettePayload,
InsertPayloadFromDelete
} from '../shared/models';
import {
areContainersEquals,
deleteContentletFromContainer,
insertContentletInContainer
} from '../utils';

interface DeletePayload {
payload: ActionPayload;
originContainer: ContainerPayload;
contentletToMove: ContentletPayload;
}

interface InsertPayloadFromDelete {
payload: ActionPayload;
pageContainers: PageContainer[];
contentletsId: string[];
destinationContainer: ContainerPayload;
pivotContentlet: ContentletPayload;
positionToInsert: 'before' | 'after';
}

interface BasePayload {
type: 'contentlet' | 'content-type';
}

interface ContentletDragPayload extends BasePayload {
type: 'contentlet';
item: {
container?: ContainerPayload;
contentlet: ContentletPayload;
};
move: boolean;
}

// Specific interface when type is 'content-type'
interface ContentTypeDragPayload extends BasePayload {
type: 'content-type';
item: {
variable: string;
name: string;
};
}

type DraggedPalettePayload = ContentletDragPayload | ContentTypeDragPayload;

@Component({
selector: 'dot-edit-ema-editor',
standalone: true,
Expand Down Expand Up @@ -248,8 +212,8 @@ export class EditEmaEditorComponent implements OnInit, OnDestroy {
requestAnimationFrame(() => {
this.iframe.nativeElement.contentWindow.addEventListener('click', (e) => {
const href =
(e.target as HTMLAnchorElement).href ||
((e.target as HTMLElement).closest('a') as HTMLAnchorElement).href;
(e.target as HTMLAnchorElement)?.href ||
(e.target as HTMLElement).closest('a')?.href;

if (href) {
e.preventDefault();
Expand Down Expand Up @@ -631,6 +595,36 @@ export class EditEmaEditorComponent implements OnInit, OnDestroy {
this.dialog.resetDialog();
}
});
},
[NG_CUSTOM_EVENTS.SAVE_MENU_ORDER]: () => {
this.messageService.add({
severity: 'success',
summary: this.dotMessageService.get(
'editpage.content.contentlet.menu.reorder.title'
),
detail: this.dotMessageService.get('message.menu.reordered'),
life: 2000
});

this.store.reload({
params: this.queryParams
});
this.dialog.resetDialog();
},
[NG_CUSTOM_EVENTS.ERROR_SAVING_MENU_ORDER]: () => {
this.messageService.add({
severity: 'error',
summary: this.dotMessageService.get(
'editpage.content.contentlet.menu.reorder.title'
),
detail: this.dotMessageService.get(
'error.menu.reorder.user_has_not_permission'
),
life: 2000
});
},
[NG_CUSTOM_EVENTS.CANCEL_SAVING_MENU_ORDER]: () => {
this.dialog.resetDialog();
}
})[detail.name];
}
Expand All @@ -650,7 +644,7 @@ export class EditEmaEditorComponent implements OnInit, OnDestroy {
origin: string;
data: {
action: CUSTOMER_ACTIONS;
payload: ActionPayload | SetUrlPayload | Container[] | ClientContentletArea;
payload: PostMessagePayload;
};
}): () => void {
return (<Record<CUSTOMER_ACTIONS, () => void>>{
Expand Down Expand Up @@ -696,6 +690,14 @@ export class EditEmaEditorComponent implements OnInit, OnDestroy {
this.host
);
},
[CUSTOMER_ACTIONS.REORDER_MENU]: () => {
const { reorderUrl } = <ReorderPayload>data.payload;

this.dialog.openDialogOnUrl(
reorderUrl,
this.dotMessageService.get('editpage.content.contentlet.menu.reorder.title')
);
},
[CUSTOMER_ACTIONS.NOOP]: () => {
/* Do Nothing because is not the origin we are expecting */
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ export enum NG_CUSTOM_EVENTS {
CREATE_CONTENTLET = 'create-contentlet-from-edit-page',
SAVE_PAGE = 'save-page',
FORM_SELECTED = 'form-selected',
SAVE_MENU_ORDER = 'save-menu-order',
ERROR_SAVING_MENU_ORDER = 'error-saving-menu-order',
CANCEL_SAVING_MENU_ORDER = 'cancel-save-menu-order',
OPEN_WIZARD = 'workflow-wizard'
}

Expand Down
Loading

0 comments on commit e8eba24

Please sign in to comment.