[FRONT COMPONENTS] Add snackbar to the API (#18136)
## PR description - Adds `enqueueSnackbar` to the front component host communication API, allowing front components to display snack bar notifications (success, error, info, warning) to the user. - Introduces `frontComponentId` to the `FrontComponentExecutionContext` and a `useFrontComponentId` hook, enabling front components to identify themselves (used for dedupe keys). - Wires error/success notifications into the `Action`, `ActionLink`, and `ActionOpenSidePanelPage` SDK components -> actions now catch errors and display them as snack bars, and `Action` supports an optional `notifyOnEnd` prop for success feedback. ## Video QA ### Success example https://github.com/user-attachments/assets/8cc53d31-d9eb-49a8-9220-f7866ec1b415 ### Error example https://github.com/user-attachments/assets/a37d65b8-0b5f-4adb-bcdb-571bb2b997c3 --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
+43
-1
@@ -3,14 +3,16 @@ import {
|
||||
type FrontComponentExecutionContext,
|
||||
type FrontComponentHostCommunicationApi,
|
||||
} from 'twenty-sdk/front-component-renderer';
|
||||
import { type AppPath } from 'twenty-shared/types';
|
||||
import { type AppPath, type EnqueueSnackbarParams } from 'twenty-shared/types';
|
||||
|
||||
import { currentUserState } from '@/auth/states/currentUserState';
|
||||
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
||||
import { useNavigateCommandMenu } from '@/command-menu/hooks/useNavigateCommandMenu';
|
||||
import { commandMenuSearchState } from '@/command-menu/states/commandMenuSearchState';
|
||||
import { useUnmountHeadlessFrontComponent } from '@/front-components/hooks/useUnmountHeadlessFrontComponent';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { assertUnreachable } from 'twenty-shared/utils';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||
|
||||
@@ -28,6 +30,12 @@ export const useFrontComponentExecutionContext = ({
|
||||
const setCommandMenuSearchState = useSetRecoilState(commandMenuSearchState);
|
||||
const { getIcon } = useIcons();
|
||||
const unmountHeadlessFrontComponent = useUnmountHeadlessFrontComponent();
|
||||
const {
|
||||
enqueueSuccessSnackBar,
|
||||
enqueueErrorSnackBar,
|
||||
enqueueInfoSnackBar,
|
||||
enqueueWarningSnackBar,
|
||||
} = useSnackBar();
|
||||
const { closeCommandMenu } = useCommandMenu();
|
||||
|
||||
const navigate: FrontComponentHostCommunicationApi['navigate'] = async (
|
||||
@@ -57,7 +65,40 @@ export const useFrontComponentExecutionContext = ({
|
||||
}
|
||||
};
|
||||
|
||||
const enqueueSnackbar: FrontComponentHostCommunicationApi['enqueueSnackbar'] =
|
||||
async ({
|
||||
message,
|
||||
variant,
|
||||
duration,
|
||||
detailedMessage,
|
||||
dedupeKey,
|
||||
}: EnqueueSnackbarParams) => {
|
||||
const snackBarOptions = {
|
||||
duration,
|
||||
detailedMessage,
|
||||
dedupeKey,
|
||||
};
|
||||
|
||||
switch (variant) {
|
||||
case 'error':
|
||||
enqueueErrorSnackBar({ message, options: snackBarOptions });
|
||||
break;
|
||||
case 'info':
|
||||
enqueueInfoSnackBar({ message, options: snackBarOptions });
|
||||
break;
|
||||
case 'warning':
|
||||
enqueueWarningSnackBar({ message, options: snackBarOptions });
|
||||
break;
|
||||
case 'success':
|
||||
enqueueSuccessSnackBar({ message, options: snackBarOptions });
|
||||
break;
|
||||
default:
|
||||
assertUnreachable(variant);
|
||||
}
|
||||
};
|
||||
|
||||
const executionContext: FrontComponentExecutionContext = {
|
||||
frontComponentId,
|
||||
userId: currentUser?.id ?? null,
|
||||
};
|
||||
|
||||
@@ -75,6 +116,7 @@ export const useFrontComponentExecutionContext = ({
|
||||
{
|
||||
navigate,
|
||||
openSidePanelPage,
|
||||
enqueueSnackbar,
|
||||
unmountFrontComponent,
|
||||
closeSidePanel,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user