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 3 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
25 changes: 23 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,30 @@ 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 send blocks or metadata changes.
MAX-786 marked this conversation as resolved.
Show resolved Hide resolved

TODO: not implemented yet.
The `onEditChange` method listens for changes in the Hydra and triggers a callback with updated data or the initial data if no update is available.
MAX-786 marked this conversation as resolved.
Show resolved Hide resolved
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 |
| :-----------:| :-------|
| *initialData*| The initial data to fall back on if no updated data is received. |
MAX-786 marked this conversation as resolved.
Show resolved Hide resolved
| *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(initialData, callback) {
window.addEventListener('message', (event) => {
if (event.origin === this.adminOrigin) {
if (event.data.type === 'FORM') {
if (event.data.data) {
callback(event.data.data);
} else {
callback(initialData);
}
}
}
});
}
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(initialData, callback) {
if (bridgeInstance) {
bridgeInstance.onEditChange(initialData, callback);
}
}
MAX-786 marked this conversation as resolved.
Show resolved Hide resolved
36 changes: 21 additions & 15 deletions packages/volto-hydra/src/components/Iframe/View.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,22 @@ import Cookies from 'js-cookie';
import './styles.css';

const Iframe = () => {
const [url, setUrl] = useState('');

const [src, setSrc] = useState('');
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 +47,25 @@ const Iframe = () => {
});
}, [token]);

useEffect(() => {
if (typeof window !== 'undefined') {
// 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]);
MAX-786 marked this conversation as resolved.
Show resolved Hide resolved

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

const handleNavigateToUrl = (givenUrl = '') => {
// Update adminUI URL with the new URL
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