Skip to content

Instantly share code, notes, and snippets.

@ryanschuhler
Last active August 20, 2024 17:57
Show Gist options
  • Save ryanschuhler/2fc83869dfeb13800ff82aed5ddc9cb7 to your computer and use it in GitHub Desktop.
Save ryanschuhler/2fc83869dfeb13800ff82aed5ddc9cb7 to your computer and use it in GitHub Desktop.

configuration.json

{
	"fieldSets": [
		{
			"fields": [
				{
					"dataType": "string",
					"defaultValue": "",
					"label": "Action URL",
					"name": "actionUrl",
					"type": "text"
				},
				{
					"dataType": "string",
					"defaultValue": "",
					"label": "Action Method",
					"name": "actionMethod",
					"type": "text"
				},
				{
					"dataType": "string",
					"defaultValue": "",
					"label": "Action Body",
					"name": "actionBody",
					"type": "text"
				},
				{
					"dataType": "string",
					"defaultValue": "",
					"label": "Redirect URL",
					"name": "redirectUrl",
					"type": "text"
				},
				{
					"defaultValue": false,
					"label": "Redirect Use Action Response",
					"name": "redirectUseActionResponse",
					"type": "checkbox"
				}
			]
		}
	]
}

index.html

[#assign displayObject = (request.getAttribute("LAYOUT_DISPLAY_PAGE_OBJECT_PROVIDER").getDisplayObject())!{} /]

[#assign objectDefinitionId = (displayObject.getObjectDefinitionId())! /]
[#assign objectEntryId = (displayObject.getObjectEntryId())! /]

<a class="btn btn-outline-primary" data-object-definition-id="${objectDefinitionId}" data-object-entry-id="${objectEntryId}" href="javascript:;" id="headlessActionButton_${fragmentEntryLinkNamespace}">
	<span data-lfr-editable-id="text" data-lfr-editable-type="text">+ Create</span>
</a>

index.js

/* eslint-disable no-undef */

/**
 * 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
 */

const actionUrl = configuration.actionUrl;
const headlessActionButton = fragmentElement.querySelector('#headlessActionButton_' + fragmentEntryLinkNamespace);
const redirectUrl = configuration.redirectUrl;

const parseAndReplaceVariables = (string, objectEntry) => {
	const regex = /\$\{([\w.]+)\}/g;

	return string.replace(regex, (match, variableName) => {
		const value = objectEntry[variableName];

		return value !== undefined ? value : match;
	});
}

headlessActionButton.onclick = async () => {
	const objectDefinitionId = headlessActionButton.getAttribute('data-object-definition-id');
	const objectEntryId = headlessActionButton.getAttribute('data-object-entry-id');

	const objectDefinitionResponse = await fetch(
		'/o/object-admin/v1.0/object-definitions/' + objectDefinitionId,
		{
			headers: {
				'content-type': 'application/json',
				'x-csrf-token': Liferay.authToken,
			},
			method: 'GET',
		}
	);

	const objectDefinition = await objectDefinitionResponse.json();

	const objectEntryResponse = await fetch(
		objectDefinition.restContextPath + '/' + objectEntryId,
		{
			headers: {
				'content-type': 'application/json',
				'x-csrf-token': Liferay.authToken,
			},
			method: 'GET',
		}
	);

	const objectEntry = await objectEntryResponse.json();

	if (actionUrl != '') {
		const actionResponse = await fetch(
			parseAndReplaceVariables(actionUrl, objectEntry),
			{
				body: configuration.actionBody != '' ? parseAndReplaceVariables(configuration.actionBody, objectEntry) : '{}',
				headers: {
					'content-type': 'application/json',
					'x-csrf-token': Liferay.authToken,
				},
				method: configuration.actionMethod != '' ? configuration.actionMethod : 'GET',
			}
		);

		const action = await actionResponse.json();
	
		if (!actionResponse.ok) {
			console.error(action);
	
			Liferay.Util.openToast({
				message: 'We encountered an error executing your action.',
				type: 'danger',
			});
	
			return;
		}

		if (redirectUrl != '' && configuration.redirectUseActionResponse) {
			location.href = parseAndReplaceVariables(redirectUrl, action);

			return;
		}
	}

	if (redirectUrl != '') {
		location.href = parseAndReplaceVariables(redirectUrl, objectEntry);
	}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment