Skip to content

Commit

Permalink
See real time updates when you change title in sidebar (#49)
Browse files Browse the repository at this point in the history
* send fomData to iframe whenever it is updated and hydra.js will provide onEditChange to subscribe for changes

* update readme

* update readme for referencing ploneClient data

* update description in readme

* removing initialData param from onEditChange and handling edge cases at adminUI

* update readme

* update review changes

---------

Co-authored-by: [email protected] <[email protected]>
  • Loading branch information
MAX-786 and JeffersonBledsoe authored Jun 20, 2024
1 parent a099b0e commit ca3664b
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 18 deletions.
24 changes: 22 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,29 @@ If you wish to make the editing experience faster you can register for ```onSave
#### Enable Show changes while editing
You will need to subscribe to an ```onEditChange``` event that will send blocks or metadata changes
You will need to subscribe to an ```onEditChange``` event that will call the callback with the updated data.
TODO: not implemented yet.
The `onEditChange` method listens for changes in the Hydra and triggers a callback with updated data.
The 'data' object follows the same format as you get from the [ploneClient](https://6.docs.plone.org/volto/client/quick-start.html?highlight=data#query-or-mutation-options-factories).
`onEditChange` takes following args:
| Args | Description |
| :-----------:| :-------|
| *callback* | A function to call with the updated data when a change is detected. |
Usage:
```js
// the initial data (from ploneClient)
const initialData = data;
// Define the callback function
function handleEditChange(updatedData) {
console.log('Updated data:', updatedData);
}
// Set up the onEditChange listener
onEditChange(initialData, handleEditChange);
```
#### Enable Managing Blocks directly on your frontend
Expand Down
24 changes: 23 additions & 1 deletion hydra.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,19 @@ class Bridge {
}
});
}

onEditChange(callback) {
window.addEventListener('message', (event) => {
if (event.origin === this.adminOrigin) {
if (event.data.type === 'FORM') {
if (event.data.data) {
callback(event.data.data);
} else {
throw new Error('No form data has been sent from the adminUI');
}
}
}
});
}
async get_token() {
if (this.token !== null) {
return this.token;
Expand Down Expand Up @@ -130,3 +142,13 @@ export async function getToken() {
}
return '';
}
/**
* Enable the frontend to listen for changes in the admin and call the callback with updated data
* @param {*} initialData
* @param {*} callback
*/
export function onEditChange(callback) {
if (bridgeInstance) {
bridgeInstance.onEditChange(callback);
}
}
49 changes: 34 additions & 15 deletions packages/volto-hydra/src/components/Iframe/View.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,33 @@ import { useSelector } from 'react-redux';
import Cookies from 'js-cookie';
import './styles.css';

const Iframe = () => {
const [url, setUrl] = useState('');
function isValidUrl(string) {
try {
new URL(string);
return true;
} catch (error) {
console.error(error);
return false;
}
}

const [src, setSrc] = useState('');
const Iframe = () => {
const history = useHistory();
const token = useSelector((state) => state.userSession.token);

const form = useSelector((state) => state.form.global);
const getDefualtUrlFromEnv = () =>
process.env['RAZZLE_DEFAULT_IFRAME_URL'] ||
(typeof window !== 'undefined' && window.env['RAZZLE_DEFAULT_IFRAME_URL']);

useEffect(() => {
const defaultUrl = getDefualtUrlFromEnv() || 'http://localhost:3002'; // fallback if env is not set
const savedUrl = Cookies.get('iframe_url');
const initialUrl = savedUrl
? `${savedUrl}${window.location.pathname.replace('/edit', '')}`
: `${defaultUrl}${window.location.pathname.replace('/edit', '')}`;

setUrl(initialUrl);
setSrc(initialUrl);
const defaultUrl = getDefualtUrlFromEnv() || 'http://localhost:3002'; // fallback if env is not set
const savedUrl = Cookies.get('iframe_url');
const initialUrl = savedUrl
? `${savedUrl}${history.location.pathname.replace('/edit', '')}`
: `${defaultUrl}${history.location.pathname.replace('/edit', '')}`;
const [url, setUrl] = useState(initialUrl);
const [src, setSrc] = useState(initialUrl);

useEffect(() => {
// Listen for messages from the iframe
const initialUrlOrigin = new URL(initialUrl).origin;
window.addEventListener('message', (event) => {
Expand All @@ -51,15 +57,28 @@ const Iframe = () => {
});
}, [token]);

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

const handleUrlChange = (event) => {
setUrl(event.target.value);
};

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

Expand Down

0 comments on commit ca3664b

Please sign in to comment.