2a82df7073
This PR adds the necessary tool to create a demo workspace with : relevant custom objects and fields, mock data and a real dashboard with graph widgets. It is still a bit under-optimized and slow but it works. This PR also adds an AI tool that allows to see what happens in real time, it navigates the app and waits when necessary. --------- Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
66 lines
2.0 KiB
TypeScript
66 lines
2.0 KiB
TypeScript
import { agentChatHasMessageComponentSelector } from '@/ai/states/agentChatHasMessageComponentSelector';
|
|
import { agentChatIsLoadingState } from '@/ai/states/agentChatIsLoadingState';
|
|
import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue';
|
|
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
|
import { styled } from '@linaria/react';
|
|
import { useContext } from 'react';
|
|
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
|
import { ThemeContext } from 'twenty-ui/theme';
|
|
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
|
|
|
const StyledSkeletonContainer = styled.div`
|
|
display: flex;
|
|
flex: 1;
|
|
flex-direction: column;
|
|
gap: ${themeCssVariables.spacing[6]};
|
|
padding: ${themeCssVariables.spacing[3]};
|
|
`;
|
|
|
|
const StyledMessageBubble = styled.div`
|
|
align-items: center;
|
|
display: flex;
|
|
gap: ${themeCssVariables.spacing[3]};
|
|
`;
|
|
|
|
const StyledMessageSkeleton = styled.div`
|
|
width: 100%;
|
|
`;
|
|
|
|
const NUMBER_OF_SKELETONS = 6;
|
|
|
|
export const AIChatSkeletonLoader = () => {
|
|
const { theme } = useContext(ThemeContext);
|
|
|
|
const agentChatIsLoading = useAtomStateValue(agentChatIsLoadingState);
|
|
|
|
const hasMessages = useAtomComponentSelectorValue(
|
|
agentChatHasMessageComponentSelector,
|
|
);
|
|
|
|
const shouldRender = agentChatIsLoading && !hasMessages;
|
|
|
|
if (!shouldRender) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<SkeletonTheme
|
|
baseColor={theme.background.tertiary}
|
|
highlightColor={theme.background.transparent.lighter}
|
|
borderRadius={4}
|
|
>
|
|
<StyledSkeletonContainer>
|
|
{Array.from({ length: NUMBER_OF_SKELETONS }).map((_, index) => (
|
|
<StyledMessageBubble key={index}>
|
|
<Skeleton width={24} height={24} borderRadius={4} />
|
|
|
|
<StyledMessageSkeleton>
|
|
<Skeleton height={20} borderRadius={8} />
|
|
</StyledMessageSkeleton>
|
|
</StyledMessageBubble>
|
|
))}
|
|
</StyledSkeletonContainer>
|
|
</SkeletonTheme>
|
|
);
|
|
};
|