import {useCallback, useState} from 'react'; import styled from '@emotion/styled'; import Button from 'sentry/components/button'; import {t} from 'sentry/locale'; import {LightFlamegraphTheme} from 'sentry/utils/profiling/flamegraph/flamegraphTheme'; import { importDroppedProfile, ProfileGroup, } from 'sentry/utils/profiling/profile/importProfile'; export interface ProfileDragDropImportProps { children: React.ReactNode; onImport: (profile: ProfileGroup) => void; } function ProfileDragDropImport({ onImport, children, }: ProfileDragDropImportProps): React.ReactElement { const [dropState, setDropState] = useState< 'idle' | 'dragover' | 'processing' | 'errored' >('idle'); const [errorMessage, setErrorMessage] = useState(null); const onDrop = useCallback( (evt: React.DragEvent) => { evt.preventDefault(); evt.stopPropagation(); const file = evt.dataTransfer.items[0].getAsFile(); if (file) { setDropState('processing'); importDroppedProfile(file) .then(profile => { setDropState('idle'); setErrorMessage(null); onImport(profile); }) .catch(e => { setDropState('errored'); setErrorMessage(e.message); }); } }, [onImport] ); const onDragEnter = useCallback((evt: React.DragEvent) => { evt.preventDefault(); evt.stopPropagation(); setDropState('dragover'); }, []); const onDragLeave = useCallback((evt: React.DragEvent) => { evt.preventDefault(); evt.stopPropagation(); setDropState('idle'); }, []); // This is required to indicate that onDrop is supported on this element const onDragOver = useCallback((evt: React.DragEvent) => { evt.preventDefault(); }, []); const onDismiss = useCallback(() => { setDropState('idle'); setErrorMessage(null); }, []); return ( {dropState === 'idle' ? null : dropState === 'errored' ? ( {t('Failed to import profile with error')}

{errorMessage}

) : ( {t('Drop profile here')} )} {children}
); } const DragDropContainer = styled('div')` display: flex; flex-direction: column; flex: 1 1 100%; `; const Overlay = styled('div')` position: absolute; left: 0; bottom: 0; width: 100%; height: calc(100% - ${LightFlamegraphTheme.SIZES.TIMELINE_HEIGHT}px); display: grid; grid: auto/50%; place-content: center; z-index: ${p => p.theme.zIndex.modal}; text-align: center; background-color: ${p => p.theme.surface100}; `; export {ProfileDragDropImport};