Skip to content

Commit

Permalink
Merge pull request #90 from collective/select-url-preference
Browse files Browse the repository at this point in the history
Select/Enter frontend URL under "pereferences"
  • Loading branch information
MAX-786 committed Jul 5, 2024
2 parents bf3efc8 + 4380ec2 commit 01589ac
Show file tree
Hide file tree
Showing 17 changed files with 656 additions and 549 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,26 @@ Each level requires more work to integrate but makes editing easier.
As the GSoC projects progresses more of these levels will be enabled so you can try them out.
see [Hydra GSoC project progresses](https://github.com/orgs/collective/projects/3/views/4)

## Managing multiple frontends

To switch to a different frontend in the Volto Hydra AdminUI, follow these steps:

1. **Navigate to Personal Tools**:
- In the bottom of the toolbar on the left, click on "Personal Tools".

2. **Go to Preferences**:
- From the Personal Tools menu, select "Preferences".

3. **Change Frontend URL**:
- In the Preferences section, you will find an option to select the Frontend URL.
- You can either select a frontend URL from the available options or type in a custom URL:
- To select a URL from the options, simply choose from the dropdown menu.
- To enter a custom URL, click on the toggle to make the input field appear and type in your desired URL.

This allows you to switch seamlessly between different frontend URLs for testing or editing purposes.

**Note**: Make sure the frontend URL is correct and accessible to avoid any CORS issues.

### Level 1: Show changes after save

This is the most basic form of integration.
Expand Down
8 changes: 4 additions & 4 deletions packages/volto-hydra/src/actions.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { SET_SELECTED_BLOCK } from './constants';
import { SET_FRONTEND_PREVIEW_URL } from './constants';

export function setSelectedBlock(uid) {
export function setFrontendPreviewUrl(url) {
return {
type: SET_SELECTED_BLOCK,
uid: uid,
type: SET_FRONTEND_PREVIEW_URL,
url: url,
};
}
74 changes: 31 additions & 43 deletions packages/volto-hydra/src/components/Iframe/View.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,19 @@ import {
import './styles.css';
import { useIntl } from 'react-intl';
import config from '@plone/volto/registry';
import usePresetUrls from '../../utils/usePreseturls';
import isValidUrl from '../../utils/isValidUrl';
import { BlockChooser } from '@plone/volto/components';
import { createPortal } from 'react-dom';
import { usePopper } from 'react-popper';
import UrlInput from '../UrlInput';
import { useDispatch } from 'react-redux';
import { useSelector, useDispatch } from 'react-redux';
import { getURlsFromEnv } from '../../utils/getSavedURLs';
import { setSidebarTab } from '@plone/volto/actions';

/**
* Format the URL for the Iframe with location, token and enabling edit mode
* @param {*} url
* @param {*} token
* @returns {string} URL with the admin params
* Format the URL for the Iframe with location, token and edit mode
* @param {URL} url
* @param {String} token
* @returns {URL} URL with the admin params
*/
const getUrlWithAdminParams = (url, token) => {
return typeof window !== 'undefined'
Expand All @@ -51,10 +50,7 @@ const Iframe = (props) => {
type: contentType,
selectedBlock,
} = props;
// const [ready, setReady] = useState(false);
// useEffect(() => {
// setReady(true);
// }, []);

const dispatch = useDispatch();
const [addNewBlockOpened, setAddNewBlockOpened] = useState(false);
const [popperElement, setPopperElement] = useState(null);
Expand All @@ -67,7 +63,7 @@ const Iframe = (props) => {
{
name: 'offset',
options: {
offset: [0, -250],
offset: [0, -350],
},
},
{
Expand All @@ -88,16 +84,18 @@ const Iframe = (props) => {
}, [selectedBlock]);
//-------------------------

const [url, setUrl] = useState('');
const [src, setSrc] = useState('');
const history = useHistory();
const [iframeSrc, setIframeSrc] = useState(null);
const urlFromEnv = getURlsFromEnv();
const u =
useSelector((state) => state.frontendPreviewUrl.url) ||
Cookies.get('iframe_url') ||
urlFromEnv[0];

const presetUrls = usePresetUrls();
const defaultUrl = presetUrls[0];
const savedUrl = Cookies.get('iframe_url');
const initialUrl = savedUrl
? getUrlWithAdminParams(savedUrl, token)
: getUrlWithAdminParams(defaultUrl, token);
useEffect(() => {
setIframeSrc(getUrlWithAdminParams(u, token));
u && Cookies.set('iframe_url', u, { expires: 7 });
}, [token, u]);
const history = useHistory();

//-----Experimental-----
const intl = useIntl();
Expand Down Expand Up @@ -132,26 +130,19 @@ const Iframe = (props) => {

const handleNavigateToUrl = useCallback(
(givenUrl = null) => {
if (!isValidUrl(givenUrl) && !isValidUrl(url)) {
if (!isValidUrl(givenUrl)) {
return;
}
// Update adminUI URL with the new URL
const formattedUrl = givenUrl ? new URL(givenUrl) : new URL(url);
const formattedUrl = new URL(givenUrl);
const newOrigin = formattedUrl.origin;
Cookies.set('iframe_url', newOrigin, { expires: 7 });

history.push(`${formattedUrl.pathname}`);
},
[history, url],
[history],
);

useEffect(() => {
setUrl(
`${savedUrl || defaultUrl}${window.location.pathname.replace('/edit', '')}`,
);
setSrc(initialUrl);
}, [savedUrl, defaultUrl, initialUrl]);

useEffect(() => {
//----------------Experimental----------------
const onDeleteBlock = (id, selectPrev) => {
Expand All @@ -160,7 +151,7 @@ const Iframe = (props) => {
onChangeFormData(newFormData);

onSelectBlock(selectPrev ? previous : null);
const origin = new URL(src).origin;
const origin = new URL(iframeSrc).origin;
document
.getElementById('previewIframe')
.contentWindow.postMessage(
Expand All @@ -169,7 +160,7 @@ const Iframe = (props) => {
);
};
//----------------------------------------------
const initialUrlOrigin = initialUrl ? new URL(initialUrl).origin : '';
const initialUrlOrigin = iframeSrc && new URL(iframeSrc).origin;
const messageHandler = (event) => {
if (event.origin !== initialUrlOrigin) {
return;
Expand Down Expand Up @@ -210,31 +201,28 @@ const Iframe = (props) => {
window.removeEventListener('message', messageHandler);
};
}, [
dispatch,
handleNavigateToUrl,
history.location.pathname,
initialUrl,
iframeSrc,
onChangeFormData,
onSelectBlock,
properties,
src,
token,
]);

useEffect(() => {
if (form && Object.keys(form).length > 0 && isValidUrl(src)) {
if (form && Object.keys(form).length > 0 && isValidUrl(iframeSrc)) {
// Send the form data to the iframe
const origin = new URL(src).origin;
const origin = new URL(iframeSrc).origin;
document
.getElementById('previewIframe')
.contentWindow.postMessage({ type: 'FORM_DATA', data: form }, origin);
}
}, [form, initialUrl, src]);
}, [form, iframeSrc]);

return (
<div id="iframeContainer">
<div className="input-container">
<UrlInput urls={presetUrls} onSelect={handleNavigateToUrl} />
</div>
{addNewBlockOpened &&
createPortal(
<div
Expand All @@ -256,7 +244,7 @@ const Iframe = (props) => {
? (id, value) => {
setAddNewBlockOpened(false);
const newId = onInsertBlock(id, value);
const origin = new URL(src).origin;
const origin = new URL(iframeSrc).origin;
document
.getElementById('previewIframe')
.contentWindow.postMessage(
Expand Down Expand Up @@ -284,7 +272,7 @@ const Iframe = (props) => {
<iframe
id="previewIframe"
title="Preview"
src={src}
src={iframeSrc}
ref={setReferenceElement}
/>
</div>
Expand Down
2 changes: 1 addition & 1 deletion packages/volto-hydra/src/components/Iframe/styles.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#iframeContainer {
position: relative;
width: 100%;
height: calc(100vh - 87px);
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
Expand Down
2 changes: 1 addition & 1 deletion packages/volto-hydra/src/constants.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const SET_SELECTED_BLOCK = 'SET_SELECTED_BLOCK';
export const SET_FRONTEND_PREVIEW_URL = 'SET_FRONTEND_PREVIEW_URL';
Loading

0 comments on commit 01589ac

Please sign in to comment.