ToolJet/frontend/src/Editor/Components/CustomComponent/CustomComponent.jsx

114 lines
3.5 KiB
React
Raw Normal View History

import React, { useEffect, useState, useRef } from 'react';
import { isEqual } from 'lodash';
import iframeContent from './iframe.html';
import { useDataQueries } from '@/_stores/dataQueriesStore';
export const CustomComponent = (props) => {
const dataQueries = useDataQueries();
const { height, properties, styles, id, setExposedVariable, exposedVariables, fireEvent, dataCy } = props;
const { visibility, boxShadow } = styles;
const { code, data } = properties;
const [customProps, setCustomProps] = useState(data);
const iFrameRef = useRef(null);
const dataQueryRef = useRef(dataQueries);
const customPropRef = useRef(data);
useEffect(() => {
setCustomProps(data);
customPropRef.current = data;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [JSON.stringify(data)]);
useEffect(() => {
if (!isEqual(exposedVariables.data, customProps)) {
setExposedVariable('data', customProps);
sendMessageToIframe({ message: 'DATA_UPDATED' });
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [setExposedVariable, customProps, exposedVariables.data]);
useEffect(() => {
sendMessageToIframe({ message: 'CODE_UPDATED' });
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [code]);
useEffect(() => {
dataQueryRef.current = dataQueries;
}, [dataQueries]);
useEffect(() => {
window.addEventListener('message', (e) => {
try {
if (e.data.from === 'customComponent' && e.data.componentId === id) {
if (e.data.message === 'UPDATE_DATA') {
setCustomProps({ ...customPropRef.current, ...e.data.updatedObj });
} else if (e.data.message === 'RUN_QUERY') {
const filteredQuery = dataQueryRef.current.filter((query) => query.name === e.data.queryName);
Parameters support on RunJS (#7033) * feat: resolve passed arguments in runjs * feat: added popup form for runs params * fix: fixed issue with close function of popupover with codehinter * feat: added input for runjs args * style: for runjs args * fix: added support for params in custom components * fix: fixed default query param for runjs * fix: remove debuggers * refactor: removed commented code * fix: removed unused code * style: arguments input style in event manager * refactor: Moved argument list to separate component * refactor: moved runjs components to single folder * fix: minor refactorings * fix: renamed arguments to parameters for compoennts * refactor: reanamed argument to parameter in runjs * refactor: removed commented code * fix: added hasPramSupported flag against runjs queries * Update frontend/src/Editor/Inspector/ActionConfigurationPanels/RunjsParamters.jsx Co-authored-by: Kavin Venkatachalam <50441969+kavinvenkatachalam@users.noreply.github.com> * Update frontend/src/Editor/QueryManager/QueryEditors/Runjs/ParameterForm.jsx Co-authored-by: Kavin Venkatachalam <50441969+kavinvenkatachalam@users.noreply.github.com> * fix: prevent duplication of name * fix: fixed issue that blocked query params from returning * fix: remove extra params from runjs * fix: updated reference to current satte * fix: updated `query.run()` signature * fix: added duplicate check on param add and update * fix: added additonal null check for params runjs * feat: resolve runjs params default value without currentState * fix: hide defaultvalue of runjs in events form * fix: minor UX experience in runjs params * fix: set runjs default values to events on creation * style: updated the runjs param UI * style: runjs param form minor ux improvement * fix: close modal on add button click again --------- Co-authored-by: Kavin Venkatachalam <50441969+kavinvenkatachalam@users.noreply.github.com>
2023-07-20 11:05:39 +00:00
const parameters = e.data.parameters ? JSON.parse(e.data.parameters) : {};
filteredQuery.length === 1 &&
Parameters support on RunJS (#7033) * feat: resolve passed arguments in runjs * feat: added popup form for runs params * fix: fixed issue with close function of popupover with codehinter * feat: added input for runjs args * style: for runjs args * fix: added support for params in custom components * fix: fixed default query param for runjs * fix: remove debuggers * refactor: removed commented code * fix: removed unused code * style: arguments input style in event manager * refactor: Moved argument list to separate component * refactor: moved runjs components to single folder * fix: minor refactorings * fix: renamed arguments to parameters for compoennts * refactor: reanamed argument to parameter in runjs * refactor: removed commented code * fix: added hasPramSupported flag against runjs queries * Update frontend/src/Editor/Inspector/ActionConfigurationPanels/RunjsParamters.jsx Co-authored-by: Kavin Venkatachalam <50441969+kavinvenkatachalam@users.noreply.github.com> * Update frontend/src/Editor/QueryManager/QueryEditors/Runjs/ParameterForm.jsx Co-authored-by: Kavin Venkatachalam <50441969+kavinvenkatachalam@users.noreply.github.com> * fix: prevent duplication of name * fix: fixed issue that blocked query params from returning * fix: remove extra params from runjs * fix: updated reference to current satte * fix: updated `query.run()` signature * fix: added duplicate check on param add and update * fix: added additonal null check for params runjs * feat: resolve runjs params default value without currentState * fix: hide defaultvalue of runjs in events form * fix: minor UX experience in runjs params * fix: set runjs default values to events on creation * style: updated the runjs param UI * style: runjs param form minor ux improvement * fix: close modal on add button click again --------- Co-authored-by: Kavin Venkatachalam <50441969+kavinvenkatachalam@users.noreply.github.com>
2023-07-20 11:05:39 +00:00
fireEvent('onTrigger', {
queryId: filteredQuery[0].id,
queryName: filteredQuery[0].name,
parameters,
});
} else {
sendMessageToIframe(e.data);
}
}
} catch (err) {
console.log(err);
}
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const sendMessageToIframe = ({ message }) => {
if (!iFrameRef.current) return;
switch (message) {
case 'INIT':
return iFrameRef.current.contentWindow.postMessage(
{
message: 'INIT_RESPONSE',
componentId: id,
data: customProps,
code: code,
},
'*'
);
case 'CODE_UPDATED':
return iFrameRef.current.contentWindow.postMessage(
{
message: 'CODE_UPDATED',
componentId: id,
data: customProps,
code: code,
},
'*'
);
case 'DATA_UPDATED':
return iFrameRef.current.contentWindow.postMessage(
{
message: 'DATA_UPDATED',
componentId: id,
data: customProps,
},
'*'
);
default:
return;
}
};
return (
<div className="card" style={{ display: visibility ? '' : 'none', height, boxShadow }} data-cy={dataCy}>
<iframe
srcDoc={iframeContent}
style={{ width: '100%', height: '100%', border: 'none' }}
ref={iFrameRef}
data-id={id}
></iframe>
</div>
);
};