All Downloads are FREE. Search and download functionalities are using the official Maven repository.

META-INF.resources.js.PagesTree.js Maven / Gradle / Ivy

The newest version!
/**
 * SPDX-FileCopyrightText: (c) 2000 Liferay, Inc. https://liferay.com
 * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06
 */

import ClayButton, {ClayButtonWithIcon} from '@clayui/button';
import {TreeView as ClayTreeView} from '@clayui/core';
import {ClayDropDownWithItems} from '@clayui/drop-down';
import ClayIcon from '@clayui/icon';
import {fetch, navigate, openModal, openToast, sub} from 'frontend-js-web';
import PropTypes from 'prop-types';
import React, {useCallback, useEffect, useState} from 'react';

const ACTION_COPY_PAGE = 'copy-page';
const ACTION_DELETE = 'delete';
const ACTION_PERMISSIONS = 'permissions';
const ENTER_KEYCODE = 13;
const ROOT_ITEM_ID = '0';

export default function PagesTree({
	config,
	isPrivateLayoutsTree,
	items,
	selectedLayoutId,
	selectedLayoutPath,
}) {
	const {
		isLayoutSetPrototype,
		loadMoreItemsURL,
		maxPageSize,
		moveItemURL,
		namespace,
	} = config;

	const onLoadMore = useCallback(
		(item) => {
			if (!item.hasChildren) {
				return Promise.resolve({
					cursor: null,
					items: null,
				});
			}

			const cursor = item.children
				? Math.floor(item.children.length / maxPageSize)
				: 0;

			return fetch(loadMoreItemsURL, {
				body: Liferay.Util.objectToURLSearchParams({
					[`${namespace}parentLayoutId`]: item.layoutId,
					[`${namespace}privateLayout`]: isPrivateLayoutsTree,
					[`${namespace}redirect`]:
						window.location.pathname + window.location.search,
					[`${namespace}selPlid`]: item.plid,
					[`${namespace}start`]: cursor * maxPageSize,
				}),
				method: 'post',
			})
				.then((response) => response.json())
				.then(({hasMoreElements, items: nextItems}) => ({
					cursor: hasMoreElements ? cursor + 1 : null,
					items: nextItems,
				}))
				.catch(() => openErrorToast());
		},
		[isPrivateLayoutsTree, loadMoreItemsURL, maxPageSize, namespace]
	);

	const onItemMove = useCallback(
		(item, parentItem, {next: priority}) => {
			if (!parentItem.parentable) {
				openErrorToast(
					sub(
						Liferay.Language.get(
							'pages-of-type-x-cannot-have-child-pages'
						),
						parentItem.typeName
					)
				);

				return false;
			}
			else if (priority === 0 && !item.firstPageable) {
				openErrorToast(
					sub(
						Liferay.Language.get(
							'the-first-page-cannot-be-of-type-x'
						),
						item.typeName
					)
				);

				return false;
			}
			else if (priority === 0 && !item.hasGuestViewPermission) {
				openErrorToast(
					Liferay.Language.get(
						'the-first-page-should-be-visible-for-guest-users'
					)
				);

				return false;
			}

			return fetch(moveItemURL, {
				body: Liferay.Util.objectToURLSearchParams({
					parentPlid: parentItem.plid,
					plid: item.plid,
					priority,
				}),
				method: 'post',
			})
				.then((response) => response.json())
				.then(({message}) => {
					if (message) {
						openErrorToast(message);

						navigate(window.location.href);
					}
				})
				.catch(() => openErrorToast());
		},
		[moveItemURL]
	);

	const [expandedKeys, setExpandedKeys] = useState(selectedLayoutPath);

	useEffect(() => {
		const activeElement = document.querySelector(
			'.pages-tree .treeview-link.active'
		);

		if (activeElement) {
			activeElement.scrollIntoView({
				behavior: 'auto',
				block: 'center',
				inline: 'center',
			});
		}
	}, []);

	return (
		
{ setExpandedKeys(Array.from(keys)); }} onItemMove={onItemMove} onLoadMore={onLoadMore} selectionMode={null} showExpanderOnHover={false} > {(item, selection, expand, load) => ( )}
); } PagesTree.propTypes = { config: PropTypes.object.isRequired, isPrivateLayoutsTree: PropTypes.bool.isRequired, items: PropTypes.array.isRequired, selectedLayoutId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), }; function TreeItem({ config, expand, isSiteTemplate, item, load, namespace, selectedLayoutId, }) { const warningMessage = isSiteTemplate ? Liferay.Language.get( 'there-is-a-page-with-the-same-friendly-url-in-a-site-using-this-site-template' ) : Liferay.Language.get( 'there-is-a-page-with-the-same-friendly-url-in-the-site-template' ); return ( } /> ) } > { if (event.keyCode === ENTER_KEYCODE && item.regularURL) { navigate(item.regularURL); } }} > {item.icon && } {(item) => ( } /> ) } active={selectedLayoutId === item.id ? 'true' : null} expandable={item.hasChildren} onKeyDown={(event) => { if ( event.keyCode === ENTER_KEYCODE && item.regularURL ) { navigate(item.regularURL); } }} > {item.icon && } )} {load.get(item.id) !== null && expand.has(item.id) && item.paginated && ( load.loadMore(item.id, item)} > {Liferay.Language.get('load-more-results')} )} ); } TreeItem.propTypes = { expand: PropTypes.object.isRequired, item: PropTypes.object.isRequired, load: PropTypes.object.isRequired, namespace: PropTypes.string.isRequired, selectedLayoutId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), }; function normalizeActions(actions, namespace) { return actions.map((group) => ({ ...group, items: group.items.map((item) => { const nextItem = {...item}; delete nextItem.data; if (item.data?.url) { nextItem.onClick = (event) => { event.preventDefault(); let modalData = { id: `${namespace}pagesTreeModal`, title: item.data.modalTitle, url: item.data.url, }; if (item.id === ACTION_DELETE) { delete modalData.url; modalData = { ...modalData, bodyHTML: item.data.message, buttons: [ { autoFocus: true, displayType: 'secondary', label: Liferay.Language.get('cancel'), type: 'cancel', }, { displayType: 'danger', label: Liferay.Language.get('delete'), onClick: ({processClose}) => { processClose(); fetch(item.data.url, { method: 'post', }) .then((response) => response.json()) .then( ({ errorMessage, redirectURL, }) => { if (errorMessage) { openErrorToast( errorMessage ); } else { openToast({ message: Liferay.Language.get( 'your-request-processed-successfully' ), toastProps: { autoClose: 5000, }, type: 'success', }); navigate(redirectURL); } } ) .catch(() => openErrorToast()); }, }, ], status: 'danger', }; } else if (item.id === ACTION_COPY_PAGE) { modalData = { ...modalData, containerProps: { className: 'cadmin copy-page-modal', }, id: 'addLayoutDialog', size: 'md', }; } else if (item.id === ACTION_PERMISSIONS) { modalData = { ...modalData, onClose: () => navigate(window.location.href), }; } openModal(modalData); }; } return nextItem; }), })); } function openErrorToast(message) { openToast({ message: message || Liferay.Language.get('an-unexpected-error-occurred'), title: Liferay.Language.get('error'), toastProps: { autoClose: 5000, }, type: 'danger', }); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy