[FRONT COMPONENTS] Headless components (#18096)
## Description - Add `isHeadless` field to `FrontComponent` entity so front components can run without rendering UI in the command menu - Introduce headless front component mounting logic: `HeadlessFrontComponentMountRoot` at the application root, `useMountHeadlessFrontComponent`, and `useUnmountHeadlessFrontComponent` hooks to mount/unmount headless components - Expand the SDK with new action components (`Action`, `ActionLink`, `ActionOpenSidePanelPage`) and host communication functions (`openSidePanelPage`, `unmountFrontComponent`) - Move `CommandMenuPages` type to twenty-shared so the SDK can reference it for side panel navigation ## Video QA https://github.com/user-attachments/assets/4f9e3bb1-fcd1-42be-b3f4-a97e80c2add2
This commit is contained in:
+10
-14
@@ -29,38 +29,32 @@ export const FrontComponentWorkerEffect = ({
|
||||
setThread,
|
||||
setError,
|
||||
}: FrontComponentWorkerEffectProps) => {
|
||||
const frontComponentHostCommunicationApiRef = useRef(
|
||||
frontComponentHostCommunicationApi,
|
||||
);
|
||||
frontComponentHostCommunicationApiRef.current =
|
||||
frontComponentHostCommunicationApi;
|
||||
const isInitializedRef = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (isInitializedRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newReceiver = new RemoteReceiver({ retain, release });
|
||||
|
||||
const worker = createRemoteWorker();
|
||||
|
||||
worker.onerror = (event: ErrorEvent) => {
|
||||
const workerError =
|
||||
event.error ??
|
||||
new Error(event.message || 'Unknown worker error');
|
||||
event.error ?? new Error(event.message || 'Unknown worker error');
|
||||
|
||||
console.error('[FrontComponentRenderer] Worker error:', workerError);
|
||||
setError(workerError);
|
||||
};
|
||||
|
||||
const stableFrontComponentHostCommunicationApi: FrontComponentHostCommunicationApi =
|
||||
{
|
||||
navigate: (...args) =>
|
||||
frontComponentHostCommunicationApiRef.current.navigate(...args),
|
||||
};
|
||||
|
||||
const thread = new ThreadWebWorker<
|
||||
WorkerExports,
|
||||
FrontComponentHostCommunicationApi
|
||||
>(worker, {
|
||||
exports: stableFrontComponentHostCommunicationApi,
|
||||
exports: frontComponentHostCommunicationApi,
|
||||
});
|
||||
|
||||
setThread(thread);
|
||||
|
||||
thread.imports
|
||||
@@ -74,6 +68,7 @@ export const FrontComponentWorkerEffect = ({
|
||||
});
|
||||
|
||||
setReceiver(newReceiver);
|
||||
isInitializedRef.current = true;
|
||||
|
||||
return () => {
|
||||
setThread(null);
|
||||
@@ -86,6 +81,7 @@ export const FrontComponentWorkerEffect = ({
|
||||
setError,
|
||||
setReceiver,
|
||||
setThread,
|
||||
frontComponentHostCommunicationApi,
|
||||
]);
|
||||
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user