Files
twenty/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/components/SnackBarProvider.tsx
Thomas Trompette 069c34cd7b Add link on snack bar (#9873)
Add link to workflow execution 

<img width="639" alt="Capture d’écran 2025-01-27 à 18 15 34"
src="https://github.com/user-attachments/assets/f2a1b3b5-7bf6-4b33-bba7-bf8907f6bcc6"
/>
2025-01-28 11:26:20 +01:00

86 lines
2.2 KiB
TypeScript

import styled from '@emotion/styled';
import { AnimatePresence, motion } from 'framer-motion';
import { MOBILE_VIEWPORT } from 'twenty-ui';
import { useSnackBarManagerScopedStates } from '@/ui/feedback/snack-bar-manager/hooks/internal/useSnackBarManagerScopedStates';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { SnackBar } from './SnackBar';
const StyledSnackBarContainer = styled.div`
display: flex;
flex-direction: column;
position: fixed;
right: ${({ theme }) => theme.spacing(3)};
bottom: ${({ theme }) => theme.spacing(3)};
z-index: ${({ theme }) => theme.lastLayerZIndex};
@media (max-width: ${MOBILE_VIEWPORT}px) {
top: 0;
bottom: auto;
left: 0;
right: 0;
}
`;
export const SnackBarProvider = ({ children }: React.PropsWithChildren) => {
const { snackBarInternal } = useSnackBarManagerScopedStates();
const { handleSnackBarClose } = useSnackBar();
const isMobile = useIsMobile();
const variants = {
out: {
opacity: 0,
y: isMobile ? -40 : 40,
},
in: {
opacity: 1,
y: 0,
},
};
return (
<>
{children}
<StyledSnackBarContainer>
<AnimatePresence>
{snackBarInternal.queue.map(
({
duration,
icon,
id,
message,
detailedMessage,
variant,
link,
}) => (
<motion.div
key={id}
variants={variants}
initial="out"
animate="in"
exit="out"
transition={{ duration: 0.5 }}
layout
>
<SnackBar
{...{
duration,
icon,
message,
detailedMessage,
variant,
link,
}}
onClose={() => handleSnackBarClose(id)}
/>
</motion.div>
),
)}
</AnimatePresence>
</StyledSnackBarContainer>
</>
);
};