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

META-INF.resources.js.components.ModelBuilder.EditObjectFolderHeader.ModalPublishObjectDefinitions.tsx 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 from '@clayui/button';
import {Text} from '@clayui/core';
import {ClayCheckbox} from '@clayui/form';
import ClayIcon from '@clayui/icon';
import ClayList from '@clayui/list';
import ClayLoadingIndicator from '@clayui/loading-indicator';
import ClayModal, {useModal} from '@clayui/modal';
import {API, stringUtils} from '@liferay/object-js-components-web';
import {sub} from 'frontend-js-web';
import React, {useEffect, useState} from 'react';
import {Elements, FlowElement, isNode} from 'react-flow-renderer';

import {TYPES} from '../ModelBuilderContext/typesEnum';
import {ObjectRelationshipEdgeData, TAction} from '../types';

import './ModalPublishObjectDefinitions.scss';

enum STATUS {
	APPROVED = 0,
	DRAFT = 2,
	PENDING = 1,
	REJECTED = -1,
}

interface ModalPublishObjectDefinitionsProps {
	disableAutoClose: boolean;
	dispatch: React.Dispatch;
	elements: Elements;
	handleOnClose: () => void;
}

interface ObjectDefinitionStatus {
	code: number;
	label?: string;
	label_i18n?: string;
}

interface SelectedDraftObjectDefinition {
	errorMessage?: string;
	id: number;
	status: ObjectDefinitionStatus;
}

type TStatus = 'danger' | 'info' | 'success' | 'warning';

export function ModalPublishObjectDefinitions({
	disableAutoClose,
	dispatch,
	elements,
	handleOnClose,
}: ModalPublishObjectDefinitionsProps) {
	const {observer, onClose} = useModal({
		onClose: () => handleOnClose(),
	});

	const objectDefinitionNodes = elements.filter((element) =>
		isNode(element)
	) as Elements;

	const [draftObjectDefinitionNodes] = useState<
		Elements
	>(
		objectDefinitionNodes.filter(
			(objectDefinitionNode) =>
				objectDefinitionNode.data?.status?.code === STATUS.DRAFT &&
				!objectDefinitionNode.data.linkedObjectDefinition
		)
	);
	const [modalHeaderMessage, setModalHeaderMessage] = useState(
		Liferay.Language.get('confirm-publishing')
	);
	const [publishObjectDefinitionsStatus, setPublishObjectDefinitionsStatus] =
		useState(STATUS.DRAFT);
	const [
		selectAllDraftObjectDefinitions,
		setSelectAllDraftObjectDefinitions,
	] = useState(false);
	const [selectedDraftObjectDefinitions, setSelectedDraftObjectDefinitions] =
		useState([]);

	const updateObjectDefinitionStatus = (
		selectedDraftObjectDefinitions: SelectedDraftObjectDefinition[],
		objectDefinitionId: number,
		objectDefinitionStatus: ObjectDefinitionStatus,
		errorMessage?: string
	) => {
		return selectedDraftObjectDefinitions.map(
			(selectedDraftObjectDefinition) => {
				if (selectedDraftObjectDefinition.id === objectDefinitionId) {
					return {
						id: objectDefinitionId,
						status: objectDefinitionStatus,
						...(objectDefinitionStatus.code === STATUS.REJECTED && {
							errorMessage,
						}),
					};
				}
				else {
					return selectedDraftObjectDefinition;
				}
			}
		) as SelectedDraftObjectDefinition[];
	};

	const publishObjectDefinition = (
		objectDefinitionId: number
	): Promise => {

		// eslint-disable-next-line no-async-promise-executor
		return new Promise(async (resolve) => {
			try {
				const objectDefinitionResponse: any =
					await API.postObjectDefinitionPublish(objectDefinitionId);

				const objectDefinitionResponseJSON =
					await objectDefinitionResponse.json();

				if (!objectDefinitionResponse.ok) {
					const {detail, title} = objectDefinitionResponseJSON;

					if (detail) {
						const [details] = JSON.parse(detail);
						throw new Error(details.message);
					}
					else if (title) {
						throw new Error(title);
					}
				}

				setSelectedDraftObjectDefinitions((prevState) =>
					updateObjectDefinitionStatus(
						prevState,
						objectDefinitionId,
						objectDefinitionResponseJSON.status
					)
				);

				resolve(objectDefinitionResponseJSON);
			}
			catch (error: any) {
				setSelectedDraftObjectDefinitions((prevState) =>
					updateObjectDefinitionStatus(
						prevState,
						objectDefinitionId,
						{code: STATUS.REJECTED},
						error.message
					)
				);

				// don't throw reject, so that it doesn't go to the catch flow of the promise.all

				resolve(STATUS.REJECTED);
			}
		});
	};

	const handleOnClickPublish = async () => {
		setModalHeaderMessage(`${Liferay.Language.get('publishing')}...`);
		setPublishObjectDefinitionsStatus(STATUS.PENDING);

		try {
			const publishObjectDefinitionResponses = [];

			for (const selectedDraftObjectDefinition of selectedDraftObjectDefinitions) {
				setSelectedDraftObjectDefinitions((prevState) =>
					updateObjectDefinitionStatus(
						prevState,
						selectedDraftObjectDefinition.id,
						selectedDraftObjectDefinition.status
					)
				);

				const publishObjectDefinitionResponse =
					await publishObjectDefinition(
						selectedDraftObjectDefinition.id
					);

				publishObjectDefinitionResponses.push(
					publishObjectDefinitionResponse
				);
			}

			const hasRejectedPublishObjectDefinitionResponses =
				publishObjectDefinitionResponses.some(
					(publishObjectDefinitionResponse) =>
						typeof publishObjectDefinitionResponse === 'number' &&
						publishObjectDefinitionResponse === STATUS.REJECTED
				);
			const acceptedPublishObjectDefinitionResponses =
				publishObjectDefinitionResponses.filter(
					(publishObjectDefinitionResponse) =>
						typeof publishObjectDefinitionResponse === 'object'
				);

			setModalHeaderMessage(
				!hasRejectedPublishObjectDefinitionResponses
					? Liferay.Language.get('successfully-published')
					: Liferay.Language.get('published-with-errors')
			);
			setPublishObjectDefinitionsStatus(
				!hasRejectedPublishObjectDefinitionResponses
					? STATUS.APPROVED
					: STATUS.REJECTED
			);

			const newElements = elements.map((element) => {
				if (isNode(element)) {
					const elementId =
						(element as FlowElement).data
							?.id || 0;

					const currentObjectDefinitionPublishedResponse = (
						acceptedPublishObjectDefinitionResponses as ObjectDefinition[]
					).find(
						(acceptedPublishObjectDefinitionResponse) =>
							acceptedPublishObjectDefinitionResponse.id ===
							elementId
					);

					if (currentObjectDefinitionPublishedResponse) {
						return {
							...element,
							data: {
								...element.data,
								status: currentObjectDefinitionPublishedResponse.status,
							},
						};
					}

					return element;
				}

				return element;
			}) as Elements;

			dispatch({
				payload: {
					newElements,
				},
				type: TYPES.SET_ELEMENTS,
			});
		}
		catch (error) {
			setModalHeaderMessage(Liferay.Language.get('confirm-publishing'));
			setPublishObjectDefinitionsStatus(STATUS.REJECTED);
		}
	};

	const handleSelectAllObjectDefinitions = (
		actionType?: 'checkAll' | 'checkRemoveAll'
	): void => {
		if (actionType) {
			const allSelectedDraftObjectDefinitions =
				selectedDraftObjectDefinitions.length ===
				draftObjectDefinitionNodes.length;

			if (
				allSelectedDraftObjectDefinitions &&
				actionType !== 'checkAll'
			) {
				setSelectAllDraftObjectDefinitions(false);
				setSelectedDraftObjectDefinitions([]);
			}
			else {
				const newSelectedDraftObjectDefinitions =
					draftObjectDefinitionNodes.map(
						(draftObjectDefinitionNode) => {
							const {data} = draftObjectDefinitionNode;

							return {id: data?.id!, status: data?.status!};
						}
					);

				setSelectAllDraftObjectDefinitions(true);
				setSelectedDraftObjectDefinitions(
					newSelectedDraftObjectDefinitions
				);
			}
		}
	};

	const handleCheckboxChange = (objectDefinitionId: number): void => {
		if (
			selectedDraftObjectDefinitions.some(
				(selectedDraftObjectDefinition) =>
					selectedDraftObjectDefinition.id === objectDefinitionId
			)
		) {
			setSelectedDraftObjectDefinitions(
				selectedDraftObjectDefinitions.filter(
					(selectedDraftObjectDefinition) =>
						selectedDraftObjectDefinition.id !== objectDefinitionId
				)
			);
		}
		else {
			const selectedDraftObjectDefinitionNode =
				objectDefinitionNodes.find(
					(objectDefinitionNode) =>
						objectDefinitionNode.data?.id === objectDefinitionId
				)!;

			setSelectedDraftObjectDefinitions([
				...selectedDraftObjectDefinitions,
				{
					id: objectDefinitionId,
					status: selectedDraftObjectDefinitionNode.data?.status!,
				},
			]);
		}
	};

	const modalStatus = (): TStatus => {
		switch (publishObjectDefinitionsStatus) {
			case STATUS.APPROVED:
				return 'success';
			case STATUS.PENDING:
				return 'info';
			case STATUS.REJECTED:
				return 'warning';
			default:
				return 'warning';
		}
	};

	useEffect(
		() =>
			setSelectAllDraftObjectDefinitions(
				!!selectedDraftObjectDefinitions.length
			),
		[selectedDraftObjectDefinitions]
	);

	return (
		
			{publishObjectDefinitionsStatus !== STATUS.PENDING ? (
				{modalHeaderMessage}
			) : (
				
					
						
							
								
									
								

								{modalHeaderMessage}
							
						
					
				
			)}

			
				
{`${Liferay.Language.get( 'publishing-all-draft-objects-at-once-can-make-them-available-for-creating-entries' )} ${Liferay.Language.get( 'please-check-before-confirming' )}`}
{publishObjectDefinitionsStatus === STATUS.DRAFT && (
handleSelectAllObjectDefinitions( 'checkRemoveAll' ) } /> handleSelectAllObjectDefinitions('checkAll') } size="sm" > {Liferay.Language.get('select-all')}
)} {draftObjectDefinitionNodes.map( (draftObjectDefinitionNode) => { const {data, id} = draftObjectDefinitionNode; const selectedDraftObjectDefinition = selectedDraftObjectDefinitions.find( (draftObjectDefinition) => draftObjectDefinition.id === data?.id! ); const isDraftObjectDefinitionSelected = selectedDraftObjectDefinition?.id === data?.id!; return (
{publishObjectDefinitionsStatus === STATUS.DRAFT && ( handleCheckboxChange( data?.id! ) } /> )}
{stringUtils.getLocalizableLabel( { fallbackLabel: data?.name, labels: data?.label, } )}
{selectedDraftObjectDefinition ?.status?.code === STATUS.REJECTED && ( { selectedDraftObjectDefinition?.errorMessage } )}
{selectedDraftObjectDefinition?.status ?.code === STATUS.PENDING && ( )} {selectedDraftObjectDefinition?.status ?.code === STATUS.APPROVED && ( )}
); } )}
{Liferay.Language.get('close')} ) : ( <> {publishObjectDefinitionsStatus !== STATUS.PENDING && ( {Liferay.Language.get('cancel')} )} {publishObjectDefinitionsStatus === STATUS.PENDING ? Liferay.Language.get('please-wait') + '...' : Liferay.Language.get( 'publish-objects' )} ) } >
); }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy