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 sort navigation to traditional and nextjs example #30624

Merged
merged 18 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ import { ClientRequestProps } from '../store/features/client/withClient';
import {
SDK_EDITOR_SCRIPT_SOURCE,
TEMPORAL_DRAG_ITEM,
createReorderMenuURL,
compareUrlPaths,
deleteContentletFromContainer,
getDragItemData,
Expand Down Expand Up @@ -801,6 +802,15 @@ export class EditEmaEditorComponent implements OnInit, OnDestroy {

this.uveStore.reload();
this.dialog.resetDialog();

// This is a temporary solution to "reload" the content by reloading the window
// we should change this with a new SDK reload strategy
this.contentWindow?.postMessage(
{
name: NOTIFY_CLIENT.UVE_RELOAD_PAGE
},
this.host
);
},
[NG_CUSTOM_EVENTS.ERROR_SAVING_MENU_ORDER]: () => {
this.messageService.add({
Expand Down Expand Up @@ -996,8 +1006,14 @@ export class EditEmaEditorComponent implements OnInit, OnDestroy {
this.dialog.editContentlet({ ...contentlet, clientAction: action });
},
[CLIENT_ACTIONS.REORDER_MENU]: ({ reorderUrl }: ReorderPayload) => {
const urlObject = createReorderMenuURL({
url: reorderUrl,
pagePath: this.uveStore.params().url,
hostId: this.uveStore.pageAPIResponse().site.identifier
});

this.dialog.openDialogOnUrl(
reorderUrl,
urlObject,
this.dotMessageService.get('editpage.content.contentlet.menu.reorder.title')
);
},
Expand Down
33 changes: 33 additions & 0 deletions core-web/libs/portlets/edit-ema/portlet/src/lib/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -510,3 +510,36 @@ export const getDragItemData = ({ type, item }: DOMStringMap) => {
return null;
}
};

/**
* Adds missing query parameters `pagePath` and `hostId` to the given URL if they are not already present.
*
* @param {Object} params - The parameters object.
* @param {string} params.url - The URL to which the parameters will be added.
* @param {string} params.pagePath - The page path to be added as a query parameter if missing.
* @param {string} params.hostId - The host ID to be added as a query parameter if missing.
* @returns {string} - The updated URL with the missing parameters added.
*/
export const createReorderMenuURL = ({
url,
pagePath,
hostId
}: {
url: string;
pagePath: string;
hostId: string;
}) => {
const urlObject = new URL(url, window.location.origin);

const params = urlObject.searchParams;

if (!params.has('pagePath')) {
params.set('pagePath', pagePath);
}

if (!params.has('hostId')) {
params.set('hostId', hostId);
}

return urlObject.toString();
};
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import {
areContainersEquals,
compareUrlPaths,
createFullURL,
getDragItemData
getDragItemData,
createReorderMenuURL
} from '.';

import { dotPageContainerStructureMock } from '../shared/mocks';
Expand Down Expand Up @@ -709,4 +710,32 @@ describe('utils functions', () => {
expect(result).toBeNull();
});
});

describe('createReorderMenuURL', () => {
it('should add the missing params', () => {
const url = 'some-url?language_id=1';
const result = createReorderMenuURL({
url,
pagePath: '123',
hostId: '456'
});

expect(result).toEqual(
'http://localhost/some-url?language_id=1&pagePath=123&hostId=456'
);
});

it('should not add the missing params', () => {
const url = 'some-url?language_id=1&pagePath=111&hostId=333';
const result = createReorderMenuURL({
url,
pagePath: '123',
hostId: '456'
});

expect(result).toEqual(
'http://localhost/some-url?language_id=1&pagePath=111&hostId=333'
);
});
});
});
2 changes: 2 additions & 0 deletions core-web/libs/sdk/client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { NOTIFY_CLIENT } from './lib/editor/models/listeners.model';
import {
destroyEditor,
editContentlet,
reorderMenu,
initEditor,
isInsideEditor,
updateNavigation
Expand All @@ -20,6 +21,7 @@ export {
getPageRequestParams,
isInsideEditor,
editContentlet,
reorderMenu,
DotCmsClient,
DotCMSPageEditorConfig,
CLIENT_ACTIONS,
KevinDavilaDotCMS marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { editContentlet } from '../sdk-editor';
import { editContentlet, reorderMenu } from '../sdk-editor';
declare global {
interface Window {
dotUVE: DotUVE;
Expand All @@ -7,6 +7,7 @@ declare global {

export const INITIAL_DOT_UVE: DotUVE = {
editContentlet,
reorderMenu,
lastScrollYPosition: 0
};
KevinDavilaDotCMS marked this conversation as resolved.
Show resolved Hide resolved

Expand Down Expand Up @@ -105,5 +106,6 @@ export function postMessageToEditor<T = unknown>(message: PostMessageProps<T>) {

export interface DotUVE {
editContentlet: typeof editContentlet;
reorderMenu: typeof reorderMenu;
lastScrollYPosition: number;
}
2 changes: 2 additions & 0 deletions core-web/libs/sdk/client/src/lib/editor/sdk-editor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ jest.mock('./models/client.model', () => {
},
INITIAL_DOT_UVE: {
editContentlet: jest.fn(),
reorderMenu: jest.fn(),
lastScrollYPosition: 0
}
};
Expand Down Expand Up @@ -102,6 +103,7 @@ describe('DotCMSPageEditor', () => {
expect(scrollHandler).toHaveBeenCalled();
expect(window.dotUVE).toEqual({
editContentlet: expect.any(Function),
reorderMenu: expect.any(Function),
lastScrollYPosition: 0
});
});
Expand Down
19 changes: 19 additions & 0 deletions core-web/libs/sdk/client/src/lib/editor/sdk-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,25 @@ export function editContentlet<T>(contentlet: Contentlet<T>) {
});
}

/**
* Reorders the menu starting from a specified level.
*
* @param {number} [startLevel=1] - The level from which to start reordering the menu. Defaults to 1.
*
* This function constructs a URL for the reorder menu page with the given start level and a fixed depth of 2.
* It then sends a message to the editor with the action to reorder the menu and the constructed URL as the payload.
*/
export function reorderMenu(startLevel = 1) {
// This is the URL for the reorder menu page
// All params are hardcoded on the jsp, so here we just need to send the same URL
const reorderUrl = `/c/portal/layout?p_l_id=2df9f117-b140-44bf-93d7-5b10a36fb7f9&p_p_id=site-browser&p_p_action=1&p_p_state=maximized&_site_browser_struts_action=%2Fext%2Ffolders%2Forder_menu&startLevel=${startLevel}&depth=2`;
KevinDavilaDotCMS marked this conversation as resolved.
Show resolved Hide resolved

postMessageToEditor({
action: CLIENT_ACTIONS.REORDER_MENU,
payload: { reorderUrl }
});
}

/**
* Checks if the code is running inside an editor.
*
Expand Down
38 changes: 3 additions & 35 deletions dotCMS/src/main/webapp/WEB-INF/velocity/VM_global_library.vm
Original file line number Diff line number Diff line change
Expand Up @@ -172,29 +172,18 @@
#if ($EDIT_MODE && $PUBLISH_HTMLPAGE_PERMISSION)
#set($menuLevel = $VTLSERVLET_URI.split('/').size() - 1)

<a href="#" onclick="openReorderDialog(event)" class="btn btn-primary btn-xs normaltip" data-original-title="Reorder Menu">
<a href="#" onclick="window.dotUVE.reorderMenu($menuLevel)" class="btn btn-primary btn-xs normaltip" data-original-title="Reorder Menu">
<i class="fa fa-arrow-up"></i>
<i class="fa fa-arrow-down"></i>
</a>
<script>
function openReorderDialog(event) {
event.preventDefault();
var reorderUrl = "${directorURL}&startLevel=${menuLevel}&depth=2&pagePath=${VTLSERVLET_URI}&hostId=${host.identifier}";
var customEvent = window.top.document.createEvent("CustomEvent");
customEvent.initCustomEvent("ng-event", false, false, {
name: "reorder-menu",
data: reorderUrl
});
window.top.document.dispatchEvent(customEvent);
}
</script>
#end
#end

#macro(sortNavigation)
#if ($EDIT_MODE && $PUBLISH_HTMLPAGE_PERMISSION)
#set($menuLevel = $VTLSERVLET_URI.split('/').size() - 1)
<button
onclick="openReorderDialog(event)"
onclick='window.dotUVE.reorderMenu($menuLevel)'
style="
background-color: #426BF0;
border-radius: 3px;
Expand Down Expand Up @@ -223,27 +212,6 @@
width: 36px;
"></span>
</button>
<script>
function openReorderDialog(event) {
event.preventDefault();
var reorderUrl =
'${directorURL}&startLevel=1&depth=2&pagePath=${VTLSERVLET_URI}&hostId=${host.identifier}';

window.parent.postMessage(
{
action: 'reorder-menu',
payload: { reorderUrl }
},
'*'
);
var customEvent = window.top.document.createEvent('CustomEvent');
customEvent.initCustomEvent('ng-event', false, false, {
name: 'reorder-menu',
data: reorderUrl
});
window.top.document.dispatchEvent(customEvent);
}
</script>

#end
#end
Expand Down
3 changes: 2 additions & 1 deletion dotCMS/src/main/webapp/html/js/editor-js/sdk-editor.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions examples/nextjs/src/components/layout/header.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import Link from 'next/link';
import { reorderMenu } from '@dotcms/client';
import Image from 'next/image';
import PublicImageLoader from '@/utils/publicImageLoader';

function Header({ children }) {
return (
Expand All @@ -8,9 +11,21 @@ function Header({ children }) {
<Link href="/">TravelLux in NextJS</Link>
</h2>
</div>
<ReorderButton />
{children}
</header>
);
}

function ReorderButton() {

return (
<button className="bg-[#426BF0] rounded-sm flex cursor-pointer border-none px-2 py-1 gap-2" onClick={() => reorderMenu()} >
<Image src="/assets/icons/arrow-up.svg" width="0" height="0" className='w-6 h-6' alt="arrow up" loader={PublicImageLoader}/>
<Image src="/assets/icons/arrow-down.svg" width="0" height="0" className='w-6 h-6' alt="arrow down" loader={PublicImageLoader}/>
KevinDavilaDotCMS marked this conversation as resolved.
Show resolved Hide resolved
</button>
);
}


export default Header;
11 changes: 11 additions & 0 deletions examples/nextjs/src/utils/publicImageLoader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"use client";

import { useEffect, useState } from "react";

const PublicImageLoader = ({ src }) => {
const [imageSrc, setImageSrc] = useState(null);
useEffect(() => setImageSrc(`${window.location.origin}${src}`), [src]);
return imageSrc ?? "/";
};

export default PublicImageLoader;
KevinDavilaDotCMS marked this conversation as resolved.
Show resolved Hide resolved