Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

See real time updates when you change title in sidebar #49

Merged
merged 8 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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']);
MAX-786 marked this conversation as resolved.
Show resolved Hide resolved

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
MAX-786 marked this conversation as resolved.
Show resolved Hide resolved
const savedUrl = Cookies.get('iframe_url');
const initialUrl = savedUrl
? `${savedUrl}${history.location.pathname.replace('/edit', '')}`
: `${defaultUrl}${history.location.pathname.replace('/edit', '')}`;
MAX-786 marked this conversation as resolved.
Show resolved Hide resolved
const [url, setUrl] = useState(initialUrl);
const [src, setSrc] = useState(initialUrl);
MAX-786 marked this conversation as resolved.
Show resolved Hide resolved

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;
MAX-786 marked this conversation as resolved.
Show resolved Hide resolved
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);
MAX-786 marked this conversation as resolved.
Show resolved Hide resolved
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