@rivm-loculus-tools/common-frontend 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/FastaDataImportDialog.js.map +1 -1
- package/dist/_chunks/react.js.map +1 -1
- package/dist/classes/services/FastaDataEventBusService/index.js.map +1 -1
- package/dist/components/FastaDataImportDialog/index.js +1 -2
- package/dist/components/FastaDataImportDialogLoader/index.js.map +1 -1
- package/dist/components/FastaNotLoaded/index.js.map +1 -1
- package/dist/components/FastaPageHeaderCenterComponent/index.js.map +1 -1
- package/dist/components/FastaPageHeaderImportButton/index.js.map +1 -1
- package/dist/components/FastaPageHeaderResetButton/index.js.map +1 -1
- package/dist/components/I18nWrapper/index.js.map +1 -1
- package/dist/components/PageHeaderDocumentationButton/index.js.map +1 -1
- package/dist/components/SearchBar/index.js.map +1 -1
- package/dist/components/page/index.js.map +1 -1
- package/dist/constants/page.js.map +1 -1
- package/dist/models/fasta.js.map +1 -1
- package/dist/stores/fastaDataStore/index.js.map +1 -1
- package/dist/theme/index.js.map +1 -1
- package/dist/utils/DownloadUtil/index.js.map +1 -1
- package/dist/utils/ErrorUtil/index.js.map +1 -1
- package/dist/utils/FastaUtil/index.js +12 -19
- package/dist/utils/FastaUtil/index.js.map +1 -1
- package/dist/utils/MetaDataUtil/index.js.map +1 -1
- package/dist/utils/UrlUtil/index.js.map +1 -1
- package/package.json +22 -22
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FastaDataImportDialog.js","names":[],"sources":["../../src/components/FastaDataImportDialog/FastaDataImportDialog.tsx"],"sourcesContent":["import type {\n ChangeEvent,\n ReactElement,\n SyntheticEvent,\n} from 'react';\nimport {\n useCallback,\n useEffect,\n useState,\n} from 'react';\nimport {\n Alert,\n Box,\n CircularProgress,\n Paper,\n Tab,\n Tabs,\n TextField,\n Typography,\n} from '@mui/material';\nimport DnaIcon from '@mui/icons-material/Biotech';\nimport TableChartIcon from '@mui/icons-material/TableChart';\nimport { FileDropZone } from '@gen-epix/ui-core-components/components/FileDropZone';\nimport type {\n WithDialogRefMethods,\n WithDialogRenderProps,\n} from '@gen-epix/ui-core-components/hoc/withDialog';\nimport { withDialog } from '@gen-epix/ui-core-components/hoc/withDialog';\nimport type { DialogAction } from '@gen-epix/ui-core-components/components/Dialog';\n\n\nenum FASTA_TAB {\n DROP = 0,\n URL = 1,\n PASTE = 2,\n}\n\nenum META_DATA_TAB {\n DROP = 0,\n URL = 1,\n PASTE = 2,\n}\n\nexport interface FastaDataImportDialogOpenProps {\n initialErrorMessage?: string;\n}\n\nexport interface FastaDataImportDialogProps extends WithDialogRenderProps<FastaDataImportDialogOpenProps> {\n extraActions?: DialogAction[];\n onDataChange: (fasta: string, metaData?: string) => void;\n onError: (error: unknown) => void;\n}\n\nexport type FastaDataImportDialogRefMethods = WithDialogRefMethods<FastaDataImportDialogProps, FastaDataImportDialogOpenProps>;\n\nexport const FastaDataImportDialog = withDialog<FastaDataImportDialogProps, FastaDataImportDialogOpenProps>((\n {\n extraActions,\n onActionsChange,\n onClose,\n onDataChange,\n onDisableBackdropClickChange,\n onError,\n onNoCloseButtonChange,\n openProps,\n }: FastaDataImportDialogProps,\n): ReactElement => {\n // FASTA state\n const [fastaTab, setFastaTab] = useState(FASTA_TAB.DROP);\n const [fastaFile, setFastaFile] = useState<FileList | null>(null);\n const [fastaUrl, setFastaUrl] = useState('');\n const [fastaText, setFastaText] = useState('');\n\n // Metadata state\n const [metadataTab, setMetadataTab] = useState(META_DATA_TAB.DROP);\n const [metadataFile, setMetadataFile] = useState<FileList | null>(null);\n const [metadataUrl, setMetadataUrl] = useState('');\n const [metadataText, setMetadataText] = useState('');\n\n const [isLoading, setIsLoading] = useState(false);\n const [errorMsg, setErrorMsg] = useState<null | string>(null);\n\n useEffect(() => {\n setErrorMsg(openProps?.initialErrorMessage ?? null);\n }, [openProps]);\n\n useEffect(() => {\n if (onNoCloseButtonChange) {\n onNoCloseButtonChange(!!openProps?.initialErrorMessage);\n }\n if (onDisableBackdropClickChange) {\n onDisableBackdropClickChange(!!openProps?.initialErrorMessage);\n }\n }, [onDisableBackdropClickChange, onNoCloseButtonChange, openProps?.initialErrorMessage]);\n\n const onCloseError = useCallback(() => setErrorMsg(null), []);\n const onChangeFastaTab = useCallback((_event: SyntheticEvent, value: number) => {\n setFastaTab(value);\n }, []);\n const onChangeMetadataTab = useCallback((_event: SyntheticEvent, value: number) => {\n setMetadataTab(value);\n }, []);\n const onFileSelectedFasta = useCallback((file: FileList) => setFastaFile(file), []);\n const onFileSelectedMetadata = useCallback((file: FileList) => setMetadataFile(file), []);\n const onChangeFastaUrl = useCallback((event: ChangeEvent<HTMLInputElement>) => {\n setFastaUrl(event.target.value);\n }, []);\n const onChangeFastaText = useCallback((event: ChangeEvent<HTMLInputElement>) => {\n setFastaText(event.target.value);\n }, []);\n const onChangeMetadataUrl = useCallback((event: ChangeEvent<HTMLInputElement>) => {\n setMetadataUrl(event.target.value);\n }, []);\n const onChangeMetadataText = useCallback((event: ChangeEvent<HTMLInputElement>) => {\n setMetadataText(event.target.value);\n }, []);\n\n const onClickLoadData = useCallback(async () => {\n setErrorMsg(null);\n setIsLoading(true);\n\n try {\n // 1. Resolve FASTA content\n let fastaContent = '';\n if (fastaTab === FASTA_TAB.DROP && fastaFile) {\n fastaContent = await fastaFile[0].text();\n } else if (fastaTab === FASTA_TAB.URL && fastaUrl.trim()) {\n const res = await fetch(fastaUrl.trim());\n if (!res.ok) {\n throw new Error(`Failed to fetch FASTA from URL (${res.status} ${res.statusText})`);\n }\n fastaContent = await res.text();\n } else if (fastaTab === FASTA_TAB.PASTE && fastaText.trim()) {\n fastaContent = fastaText.trim();\n }\n\n if (!fastaContent?.trim()) {\n throw new Error('Please provide FASTA sequence data via file, URL, or paste.');\n }\n\n // 2. Resolve Metadata content (optional)\n let metadataContent = '';\n if (metadataTab === META_DATA_TAB.DROP && metadataFile) {\n metadataContent = await metadataFile[0].text();\n } else if (metadataTab === META_DATA_TAB.URL && metadataUrl.trim()) {\n const res = await fetch(metadataUrl.trim());\n if (!res.ok) {\n throw new Error(`Failed to fetch Metadata from URL (${res.status} ${res.statusText})`);\n }\n metadataContent = await res.text();\n } else if (metadataTab === META_DATA_TAB.PASTE && metadataText.trim()) {\n metadataContent = metadataText.trim();\n }\n onDataChange(fastaContent, metadataContent);\n if (onClose) {\n onClose();\n }\n } catch (err: unknown) {\n console.error('Data import failed:', err);\n onError(err);\n } finally {\n setIsLoading(false);\n }\n }, [fastaFile, fastaTab, fastaText, fastaUrl, metadataFile, metadataTab, metadataText, metadataUrl, onClose, onDataChange, onError]);\n\n\n useEffect(() => {\n const actions: DialogAction[] = [\n {\n disabled: isLoading,\n label: isLoading ? 'Processing...' : 'Load & Calculate',\n onClick: onClickLoadData,\n startIcon: isLoading ? (\n <CircularProgress\n color={'inherit'}\n size={18}\n />\n ) : undefined,\n variant: 'contained',\n },\n ];\n if (extraActions?.length) {\n actions.unshift(...extraActions);\n }\n if (onActionsChange) {\n onActionsChange(actions);\n }\n }, [onActionsChange, onClickLoadData, isLoading, extraActions]);\n\n return (\n <>\n {errorMsg && (\n <Alert\n onClose={onCloseError}\n severity={'error'}\n sx={{\n marginBottom: 2,\n }}\n >\n {errorMsg}\n </Alert>\n )}\n <Box sx={{ display: 'grid', gap: 3, gridTemplateColumns: { md: '1fr 1fr', xs: '1fr' } }}>\n {/* FASTA Sequences Group */}\n <Paper\n sx={{ borderRadius: 2, p: 2.5 }}\n variant={'outlined'}\n >\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1, mb: 1.5 }}>\n <DnaIcon color={'primary'} />\n <Typography\n sx={{ fontWeight: 700 }}\n variant={'subtitle1'}\n >\n {'1. FASTA Sequences (Required)'}\n </Typography>\n </Box>\n <Typography\n color={'text.secondary'}\n sx={{ display: 'block', mb: 2 }}\n variant={'caption'}\n >\n {'Pre-aligned nucleotide or amino-acid sequence data.'}\n </Typography>\n <Tabs\n onChange={onChangeFastaTab}\n sx={{ mb: 2, minHeight: 36 }}\n value={fastaTab}\n >\n <Tab\n label={'File Upload'}\n sx={{ fontSize: '0.85rem', py: 0.5 }}\n />\n <Tab\n label={'Public URL'}\n sx={{ fontSize: '0.85rem', py: 0.5 }}\n />\n <Tab\n label={'Direct Paste'}\n sx={{ fontSize: '0.85rem', py: 0.5 }}\n />\n </Tabs>\n {fastaTab === FASTA_TAB.DROP && (\n <FileDropZone\n accept={'.fasta,.fa,.fna,.aln'}\n files={fastaFile}\n helperText={'Drag & drop .fasta / .fa alignment file'}\n onFilesSelected={onFileSelectedFasta}\n />\n )}\n {fastaTab === FASTA_TAB.URL && (\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5, justifyContent: 'center', minHeight: 180 }}>\n <TextField\n fullWidth\n helperText={'Enter a publicly accessible URL to a FASTA alignment'}\n label={'FASTA URL'}\n onChange={onChangeFastaUrl}\n placeholder={'https://example.com/sequences.fasta'}\n value={fastaUrl}\n variant={'outlined'}\n />\n </Box>\n )}\n {fastaTab === FASTA_TAB.PASTE && (\n <Box sx={{ minHeight: 180 }}>\n <TextField\n fullWidth\n label={'Paste FASTA Content'}\n multiline\n onChange={onChangeFastaText}\n placeholder={'>seq1 ACTG... >seq2 ACTG...'}\n rows={6}\n sx={{ fontFamily: 'monospace' }}\n value={fastaText}\n variant={'outlined'}\n />\n </Box>\n )}\n </Paper>\n {/* TSV Metadata Group */}\n <Paper\n sx={{ borderRadius: 2, p: 2.5 }}\n variant={'outlined'}\n >\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1, mb: 1.5 }}>\n <TableChartIcon color={'primary'} />\n <Typography\n sx={{ fontWeight: 700 }}\n variant={'subtitle1'}\n >\n {'2. TSV Metadata (Optional)'}\n </Typography>\n </Box>\n <Typography\n color={'text.primary'}\n sx={{ display: 'block', mb: 2 }}\n variant={'caption'}\n >\n {'Sample attributes for coloring, search & custom leaf labels.'}\n </Typography>\n <Tabs\n onChange={onChangeMetadataTab}\n sx={{ mb: 2, minHeight: 36 }}\n value={metadataTab}\n >\n <Tab\n label={'File Upload'}\n sx={{ fontSize: '0.85rem', py: 0.5 }}\n />\n <Tab\n label={'Public URL'}\n sx={{ fontSize: '0.85rem', py: 0.5 }}\n />\n <Tab\n label={'Direct Paste'}\n sx={{ fontSize: '0.85rem', py: 0.5 }}\n />\n </Tabs>\n {metadataTab === META_DATA_TAB.DROP && (\n <FileDropZone\n accept={'.tsv,.txt,.csv'}\n files={metadataFile}\n label={'TSV Metadata File'}\n onFilesSelected={onFileSelectedMetadata}\n />\n )}\n {metadataTab === META_DATA_TAB.URL && (\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5, justifyContent: 'center', minHeight: 180 }}>\n <TextField\n fullWidth\n helperText={'Enter a publicly accessible URL to a TSV metadata file'}\n label={'Metadata TSV URL'}\n onChange={onChangeMetadataUrl}\n placeholder={'https://example.com/metadata.tsv'}\n value={metadataUrl}\n variant={'outlined'}\n />\n </Box>\n )}\n {metadataTab === META_DATA_TAB.PASTE && (\n <Box sx={{ minHeight: 180 }}>\n <TextField\n fullWidth\n label={'Paste TSV Content'}\n multiline\n onChange={onChangeMetadataText}\n placeholder={'SampleID	Country	Date Sample1	NL	2024-01-01'}\n rows={6}\n sx={{ fontFamily: 'monospace' }}\n value={metadataText}\n variant={'outlined'}\n />\n </Box>\n )}\n </Paper>\n </Box>\n </>\n );\n}, {\n defaultTitle: 'Load Phylogenetic Data',\n fullWidth: true,\n maxWidth: 'xl',\n testId: 'FastaDataImportDialog',\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FastaDataImportDialog.js","names":["_Fragment","DnaIcon","TableChartIcon","FastaDataImportDialog","withDialog","fastaTab","setFastaTab","useState","fastaFile","setFastaFile","fastaUrl","setFastaUrl","fastaText","setFastaText","metadataTab","setMetadataTab","metadataFile","setMetadataFile","metadataUrl","setMetadataUrl","metadataText","setMetadataText","isLoading","setIsLoading","errorMsg","setErrorMsg","useEffect","openProps","onNoCloseButtonChange","onDisableBackdropClickChange","onCloseError","useCallback","onChangeFastaTab","value","onChangeMetadataTab","onFileSelectedFasta","file","onFileSelectedMetadata","onChangeFastaUrl","event","onChangeFastaText","onChangeMetadataUrl","onChangeMetadataText","onClickLoadData","fastaContent","res","metadataContent","onDataChange","onClose","err","onError","actions","CircularProgress","extraActions","onActionsChange","Fragment","Alert","Box","Paper","Typography","Tabs","Tab","FileDropZone","TextField"],"sources":["../../src/components/FastaDataImportDialog/FastaDataImportDialog.tsx"],"sourcesContent":["import type {\n ChangeEvent,\n ReactElement,\n SyntheticEvent,\n} from 'react';\nimport {\n useCallback,\n useEffect,\n useState,\n} from 'react';\nimport {\n Alert,\n Box,\n CircularProgress,\n Paper,\n Tab,\n Tabs,\n TextField,\n Typography,\n} from '@mui/material';\nimport DnaIcon from '@mui/icons-material/Biotech';\nimport TableChartIcon from '@mui/icons-material/TableChart';\nimport { FileDropZone } from '@gen-epix/ui-core-components/components/FileDropZone';\nimport type {\n WithDialogRefMethods,\n WithDialogRenderProps,\n} from '@gen-epix/ui-core-components/hoc/withDialog';\nimport { withDialog } from '@gen-epix/ui-core-components/hoc/withDialog';\nimport type { DialogAction } from '@gen-epix/ui-core-components/components/Dialog';\n\n\nenum FASTA_TAB {\n DROP = 0,\n URL = 1,\n PASTE = 2,\n}\n\nenum META_DATA_TAB {\n DROP = 0,\n URL = 1,\n PASTE = 2,\n}\n\nexport interface FastaDataImportDialogOpenProps {\n initialErrorMessage?: string;\n}\n\nexport interface FastaDataImportDialogProps extends WithDialogRenderProps<FastaDataImportDialogOpenProps> {\n extraActions?: DialogAction[];\n onDataChange: (fasta: string, metaData?: string) => void;\n onError: (error: unknown) => void;\n}\n\nexport type FastaDataImportDialogRefMethods = WithDialogRefMethods<FastaDataImportDialogProps, FastaDataImportDialogOpenProps>;\n\nexport const FastaDataImportDialog = withDialog<FastaDataImportDialogProps, FastaDataImportDialogOpenProps>((\n {\n extraActions,\n onActionsChange,\n onClose,\n onDataChange,\n onDisableBackdropClickChange,\n onError,\n onNoCloseButtonChange,\n openProps,\n }: FastaDataImportDialogProps,\n): ReactElement => {\n // FASTA state\n const [fastaTab, setFastaTab] = useState(FASTA_TAB.DROP);\n const [fastaFile, setFastaFile] = useState<FileList | null>(null);\n const [fastaUrl, setFastaUrl] = useState('');\n const [fastaText, setFastaText] = useState('');\n\n // Metadata state\n const [metadataTab, setMetadataTab] = useState(META_DATA_TAB.DROP);\n const [metadataFile, setMetadataFile] = useState<FileList | null>(null);\n const [metadataUrl, setMetadataUrl] = useState('');\n const [metadataText, setMetadataText] = useState('');\n\n const [isLoading, setIsLoading] = useState(false);\n const [errorMsg, setErrorMsg] = useState<null | string>(null);\n\n useEffect(() => {\n setErrorMsg(openProps?.initialErrorMessage ?? null);\n }, [openProps]);\n\n useEffect(() => {\n if (onNoCloseButtonChange) {\n onNoCloseButtonChange(!!openProps?.initialErrorMessage);\n }\n if (onDisableBackdropClickChange) {\n onDisableBackdropClickChange(!!openProps?.initialErrorMessage);\n }\n }, [onDisableBackdropClickChange, onNoCloseButtonChange, openProps?.initialErrorMessage]);\n\n const onCloseError = useCallback(() => setErrorMsg(null), []);\n const onChangeFastaTab = useCallback((_event: SyntheticEvent, value: number) => {\n setFastaTab(value);\n }, []);\n const onChangeMetadataTab = useCallback((_event: SyntheticEvent, value: number) => {\n setMetadataTab(value);\n }, []);\n const onFileSelectedFasta = useCallback((file: FileList) => setFastaFile(file), []);\n const onFileSelectedMetadata = useCallback((file: FileList) => setMetadataFile(file), []);\n const onChangeFastaUrl = useCallback((event: ChangeEvent<HTMLInputElement>) => {\n setFastaUrl(event.target.value);\n }, []);\n const onChangeFastaText = useCallback((event: ChangeEvent<HTMLInputElement>) => {\n setFastaText(event.target.value);\n }, []);\n const onChangeMetadataUrl = useCallback((event: ChangeEvent<HTMLInputElement>) => {\n setMetadataUrl(event.target.value);\n }, []);\n const onChangeMetadataText = useCallback((event: ChangeEvent<HTMLInputElement>) => {\n setMetadataText(event.target.value);\n }, []);\n\n const onClickLoadData = useCallback(async () => {\n setErrorMsg(null);\n setIsLoading(true);\n\n try {\n // 1. Resolve FASTA content\n let fastaContent = '';\n if (fastaTab === FASTA_TAB.DROP && fastaFile) {\n fastaContent = await fastaFile[0].text();\n } else if (fastaTab === FASTA_TAB.URL && fastaUrl.trim()) {\n const res = await fetch(fastaUrl.trim());\n if (!res.ok) {\n throw new Error(`Failed to fetch FASTA from URL (${res.status} ${res.statusText})`);\n }\n fastaContent = await res.text();\n } else if (fastaTab === FASTA_TAB.PASTE && fastaText.trim()) {\n fastaContent = fastaText.trim();\n }\n\n if (!fastaContent?.trim()) {\n throw new Error('Please provide FASTA sequence data via file, URL, or paste.');\n }\n\n // 2. Resolve Metadata content (optional)\n let metadataContent = '';\n if (metadataTab === META_DATA_TAB.DROP && metadataFile) {\n metadataContent = await metadataFile[0].text();\n } else if (metadataTab === META_DATA_TAB.URL && metadataUrl.trim()) {\n const res = await fetch(metadataUrl.trim());\n if (!res.ok) {\n throw new Error(`Failed to fetch Metadata from URL (${res.status} ${res.statusText})`);\n }\n metadataContent = await res.text();\n } else if (metadataTab === META_DATA_TAB.PASTE && metadataText.trim()) {\n metadataContent = metadataText.trim();\n }\n onDataChange(fastaContent, metadataContent);\n if (onClose) {\n onClose();\n }\n } catch (err: unknown) {\n console.error('Data import failed:', err);\n onError(err);\n } finally {\n setIsLoading(false);\n }\n }, [fastaFile, fastaTab, fastaText, fastaUrl, metadataFile, metadataTab, metadataText, metadataUrl, onClose, onDataChange, onError]);\n\n\n useEffect(() => {\n const actions: DialogAction[] = [\n {\n disabled: isLoading,\n label: isLoading ? 'Processing...' : 'Load & Calculate',\n onClick: onClickLoadData,\n startIcon: isLoading ? (\n <CircularProgress\n color={'inherit'}\n size={18}\n />\n ) : undefined,\n variant: 'contained',\n },\n ];\n if (extraActions?.length) {\n actions.unshift(...extraActions);\n }\n if (onActionsChange) {\n onActionsChange(actions);\n }\n }, [onActionsChange, onClickLoadData, isLoading, extraActions]);\n\n return (\n <>\n {errorMsg && (\n <Alert\n onClose={onCloseError}\n severity={'error'}\n sx={{\n marginBottom: 2,\n }}\n >\n {errorMsg}\n </Alert>\n )}\n <Box sx={{ display: 'grid', gap: 3, gridTemplateColumns: { md: '1fr 1fr', xs: '1fr' } }}>\n {/* FASTA Sequences Group */}\n <Paper\n sx={{ borderRadius: 2, p: 2.5 }}\n variant={'outlined'}\n >\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1, mb: 1.5 }}>\n <DnaIcon color={'primary'} />\n <Typography\n sx={{ fontWeight: 700 }}\n variant={'subtitle1'}\n >\n {'1. FASTA Sequences (Required)'}\n </Typography>\n </Box>\n <Typography\n color={'text.secondary'}\n sx={{ display: 'block', mb: 2 }}\n variant={'caption'}\n >\n {'Pre-aligned nucleotide or amino-acid sequence data.'}\n </Typography>\n <Tabs\n onChange={onChangeFastaTab}\n sx={{ mb: 2, minHeight: 36 }}\n value={fastaTab}\n >\n <Tab\n label={'File Upload'}\n sx={{ fontSize: '0.85rem', py: 0.5 }}\n />\n <Tab\n label={'Public URL'}\n sx={{ fontSize: '0.85rem', py: 0.5 }}\n />\n <Tab\n label={'Direct Paste'}\n sx={{ fontSize: '0.85rem', py: 0.5 }}\n />\n </Tabs>\n {fastaTab === FASTA_TAB.DROP && (\n <FileDropZone\n accept={'.fasta,.fa,.fna,.aln'}\n files={fastaFile}\n helperText={'Drag & drop .fasta / .fa alignment file'}\n onFilesSelected={onFileSelectedFasta}\n />\n )}\n {fastaTab === FASTA_TAB.URL && (\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5, justifyContent: 'center', minHeight: 180 }}>\n <TextField\n fullWidth\n helperText={'Enter a publicly accessible URL to a FASTA alignment'}\n label={'FASTA URL'}\n onChange={onChangeFastaUrl}\n placeholder={'https://example.com/sequences.fasta'}\n value={fastaUrl}\n variant={'outlined'}\n />\n </Box>\n )}\n {fastaTab === FASTA_TAB.PASTE && (\n <Box sx={{ minHeight: 180 }}>\n <TextField\n fullWidth\n label={'Paste FASTA Content'}\n multiline\n onChange={onChangeFastaText}\n placeholder={'>seq1 ACTG... >seq2 ACTG...'}\n rows={6}\n sx={{ fontFamily: 'monospace' }}\n value={fastaText}\n variant={'outlined'}\n />\n </Box>\n )}\n </Paper>\n {/* TSV Metadata Group */}\n <Paper\n sx={{ borderRadius: 2, p: 2.5 }}\n variant={'outlined'}\n >\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1, mb: 1.5 }}>\n <TableChartIcon color={'primary'} />\n <Typography\n sx={{ fontWeight: 700 }}\n variant={'subtitle1'}\n >\n {'2. TSV Metadata (Optional)'}\n </Typography>\n </Box>\n <Typography\n color={'text.primary'}\n sx={{ display: 'block', mb: 2 }}\n variant={'caption'}\n >\n {'Sample attributes for coloring, search & custom leaf labels.'}\n </Typography>\n <Tabs\n onChange={onChangeMetadataTab}\n sx={{ mb: 2, minHeight: 36 }}\n value={metadataTab}\n >\n <Tab\n label={'File Upload'}\n sx={{ fontSize: '0.85rem', py: 0.5 }}\n />\n <Tab\n label={'Public URL'}\n sx={{ fontSize: '0.85rem', py: 0.5 }}\n />\n <Tab\n label={'Direct Paste'}\n sx={{ fontSize: '0.85rem', py: 0.5 }}\n />\n </Tabs>\n {metadataTab === META_DATA_TAB.DROP && (\n <FileDropZone\n accept={'.tsv,.txt,.csv'}\n files={metadataFile}\n label={'TSV Metadata File'}\n onFilesSelected={onFileSelectedMetadata}\n />\n )}\n {metadataTab === META_DATA_TAB.URL && (\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5, justifyContent: 'center', minHeight: 180 }}>\n <TextField\n fullWidth\n helperText={'Enter a publicly accessible URL to a TSV metadata file'}\n label={'Metadata TSV URL'}\n onChange={onChangeMetadataUrl}\n placeholder={'https://example.com/metadata.tsv'}\n value={metadataUrl}\n variant={'outlined'}\n />\n </Box>\n )}\n {metadataTab === META_DATA_TAB.PASTE && (\n <Box sx={{ minHeight: 180 }}>\n <TextField\n fullWidth\n label={'Paste TSV Content'}\n multiline\n onChange={onChangeMetadataText}\n placeholder={'SampleID	Country	Date Sample1	NL	2024-01-01'}\n rows={6}\n sx={{ fontFamily: 'monospace' }}\n value={metadataText}\n variant={'outlined'}\n />\n </Box>\n )}\n </Paper>\n </Box>\n </>\n );\n}, {\n defaultTitle: 'Load Phylogenetic Data',\n fullWidth: true,\n maxWidth: 'xl',\n testId: 'FastaDataImportDialog',\n});\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.js","names":[],"sources":["../../../../../node_modules/.pnpm/zustand@5.0.15_@types+react@19.3.0_react@19.3.0_use-sync-external-store@1.7.0_react@19.3.0_/node_modules/zustand/esm/react.mjs"],"sourcesContent":["import React from 'react';\nimport { createStore } from 'zustand/vanilla';\n\nconst identity = (arg) => arg;\nfunction useStore(api, selector = identity) {\n const slice = React.useSyncExternalStore(\n api.subscribe,\n React.useCallback(() => selector(api.getState()), [api, selector]),\n React.useCallback(() => selector(api.getInitialState()), [api, selector])\n );\n React.useDebugValue(slice);\n return slice;\n}\nconst createImpl = (createState) => {\n const api = createStore(createState);\n const useBoundStore = (selector) => useStore(api, selector);\n Object.assign(useBoundStore, api);\n return useBoundStore;\n};\nconst create = ((createState) => createState ? createImpl(createState) : createImpl);\n\nexport { create, useStore };\n"],"
|
|
1
|
+
{"version":3,"file":"react.js","names":["React","identity","arg","useStore","slice","api","selector"],"sources":["../../../../../node_modules/.pnpm/zustand@5.0.15_@types+react@19.3.0_react@19.3.0_use-sync-external-store@1.7.0_react@19.3.0_/node_modules/zustand/esm/react.mjs"],"sourcesContent":["import React from 'react';\nimport { createStore } from 'zustand/vanilla';\n\nconst identity = (arg) => arg;\nfunction useStore(api, selector = identity) {\n const slice = React.useSyncExternalStore(\n api.subscribe,\n React.useCallback(() => selector(api.getState()), [api, selector]),\n React.useCallback(() => selector(api.getInitialState()), [api, selector])\n );\n React.useDebugValue(slice);\n return slice;\n}\nconst createImpl = (createState) => {\n const api = createStore(createState);\n const useBoundStore = (selector) => useStore(api, selector);\n Object.assign(useBoundStore, api);\n return useBoundStore;\n};\nconst create = ((createState) => createState ? createImpl(createState) : createImpl);\n\nexport { create, useStore };\n"],"ignoreList":[0],"mappings":";;AAGA,IAAMC,KAAY,MAAQC;AAC1B,SAASC,EAAS,GAAK,IAAWF,GAAU;CAC1C,IAAMG,IAAQJ,EAAM,qBAClBK,EAAI,WACJL,EAAM,kBAAkBM,EAASD,EAAI,SAAS,CAAC,GAAG,CAACA,GAAKC,CAAQ,CAAC,GACjEN,EAAM,kBAAkBM,EAASD,EAAI,gBAAgB,CAAC,GAAG,CAACA,GAAKC,CAAQ,CAAC,CAC1E;CAEA,OADAN,EAAM,cAAcI,CAAK,GAClBA;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/classes/services/FastaDataEventBusService/FastaDataEventBusService.ts"],"sourcesContent":["import { EventBusAbstract } from '@gen-epix/ui-core/classes/abstracts/EventBusAbstract';\nimport { HmrUtil } from '@gen-epix/ui-core/utils/HmrUtil';\n\n\nexport type Event = {\n onCloseImportDialog: undefined;\n onShowImportDialog: string | undefined;\n};\n\nexport class FastaDataEventBusService extends EventBusAbstract<Event> {\n private static __instance: FastaDataEventBusService;\n\n\n private constructor() {\n super();\n }\n\n public static getInstance(): FastaDataEventBusService {\n FastaDataEventBusService.__instance = HmrUtil.getHmrSingleton('fastaDataEventBusService', FastaDataEventBusService.__instance, () => new FastaDataEventBusService());\n return FastaDataEventBusService.__instance;\n }\n}\n"],"mappings":";;;AASA,
|
|
1
|
+
{"version":3,"file":"index.js","names":["FastaDataEventBusService","EventBusAbstract","HmrUtil"],"sources":["../../../../src/classes/services/FastaDataEventBusService/FastaDataEventBusService.ts"],"sourcesContent":["import { EventBusAbstract } from '@gen-epix/ui-core/classes/abstracts/EventBusAbstract';\nimport { HmrUtil } from '@gen-epix/ui-core/utils/HmrUtil';\n\n\nexport type Event = {\n onCloseImportDialog: undefined;\n onShowImportDialog: string | undefined;\n};\n\nexport class FastaDataEventBusService extends EventBusAbstract<Event> {\n private static __instance: FastaDataEventBusService;\n\n\n private constructor() {\n super();\n }\n\n public static getInstance(): FastaDataEventBusService {\n FastaDataEventBusService.__instance = HmrUtil.getHmrSingleton('fastaDataEventBusService', FastaDataEventBusService.__instance, () => new FastaDataEventBusService());\n return FastaDataEventBusService.__instance;\n }\n}\n"],"mappings":";;;AASA,IAAaA,IAAb,MAAaA,UAAiCC,EAAwB;CACpE,OAAe;CAGf,cAAsB;EACpB,MAAM;CACR;CAEA,OAAc,cAAwC;EAEpD,OADA,EAAyB,aAAaC,EAAQ,gBAAgB,4BAA4BF,EAAyB,kBAAkB,IAAIA,EAAyB,CAAC,GAC5JA,EAAyB;CAClC;AACF"}
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { e as FastaDataImportDialog };
|
|
1
|
+
export { t as FastaDataImportDialog } from "../../_chunks/FastaDataImportDialog.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/FastaDataImportDialogLoader/FastaDataImportDialogLoader.tsx"],"sourcesContent":["import type { DialogAction } from '@gen-epix/ui-core-components/components/Dialog';\nimport {\n useCallback,\n useEffect,\n useRef,\n} from 'react';\nimport type { StoreApi } from 'zustand';\nimport { useStore } from 'zustand';\n\nimport { FastaDataEventBusService } from '../../classes/services/FastaDataEventBusService';\nimport { LOADING_STATUS } from '../../models/fasta';\nimport type { FastaDataStore } from '../../stores/fastaDataStore';\nimport { UrlUtil } from '../../utils/UrlUtil';\nimport type { FastaDataImportDialogRefMethods } from '../FastaDataImportDialog/FastaDataImportDialog';\nimport { FastaDataImportDialog } from '../FastaDataImportDialog/FastaDataImportDialog';\nimport { ErrorUtil } from '../../utils/ErrorUtil';\n\n\nexport type FastaDataImportDialogLoaderProps = {\n extraActions: DialogAction[];\n store: StoreApi<FastaDataStore>;\n};\n\nexport const FastaDataImportDialogLoader = ({ extraActions, store }: FastaDataImportDialogLoaderProps) => {\n const setData = useStore(store, (state) => state.setData);\n const setLoadingStatus = useStore(store, (state) => state.setLoadingStatus);\n const fastaDataImportDialogRef = useRef<FastaDataImportDialogRefMethods>(null);\n\n useEffect(() => {\n const removers = [\n // eslint-disable-next-line @eslint-react/web-api-no-leaked-event-listener\n FastaDataEventBusService.getInstance().addEventListener('onShowImportDialog', (initialErrorMessage?: string) => {\n fastaDataImportDialogRef.current?.open(initialErrorMessage ? { initialErrorMessage } : undefined);\n }),\n // eslint-disable-next-line @eslint-react/web-api-no-leaked-event-listener\n FastaDataEventBusService.getInstance().addEventListener('onCloseImportDialog', () => {\n fastaDataImportDialogRef.current?.close();\n }),\n ];\n return () => {\n removers.forEach((remove) => remove());\n };\n }, []);\n\n useEffect(() => {\n // Scan URL parameters for deep-linking\n const urlParams = new URLSearchParams(window.location.search);\n const inputFastaUrl = urlParams.get('input-fasta');\n const inputMetadataUrl = urlParams.get('input-metadata');\n\n const handleDeepLinking = async () => {\n if (inputFastaUrl) {\n setLoadingStatus(LOADING_STATUS.LOADING);\n try {\n const fastaRes = await fetch(inputFastaUrl);\n if (!fastaRes.ok) {\n throw new Error(`FASTA fetch failed (${fastaRes.status})`);\n }\n const fastaText = await fastaRes.text();\n\n if (!fastaText.trim()) {\n setLoadingStatus(LOADING_STATUS.ERROR);\n throw new Error('The input-fasta URL returned no sequence data. Check that the URL and requested accession(s) are correct.');\n }\n\n let metaText: string | undefined;\n if (inputMetadataUrl) {\n try {\n const metaRes = await fetch(inputMetadataUrl);\n if (metaRes.ok) {\n metaText = await metaRes.text();\n }\n } catch (metaErr) {\n console.warn('[App] Failed to auto-fetch metadata:', metaErr);\n }\n }\n\n await setData(fastaText, metaText);\n } catch (fastaErr) {\n console.error('[App] Failed to auto-load FASTA:', fastaErr);\n const message = fastaErr instanceof Error ? fastaErr.message : 'Failed to auto-load FASTA from the provided URL.';\n FastaDataEventBusService.getInstance().emit('onShowImportDialog', message);\n }\n } else {\n // PV1-02: Show data loading modal if no data provided via URL query params\n FastaDataEventBusService.getInstance().emit('onShowImportDialog');\n }\n };\n\n void handleDeepLinking();\n }, [setData, setLoadingStatus]);\n\n const handleError = useCallback((errorMessage: string) => {\n fastaDataImportDialogRef.current?.close();\n FastaDataEventBusService.getInstance().emit('onShowImportDialog', errorMessage);\n }, []);\n\n const onDataChange = useCallback(async (fastaContent: string, metadataContent?: string) => {\n try {\n await setData(fastaContent, metadataContent);\n fastaDataImportDialogRef.current?.close();\n } catch (e) {\n handleError(ErrorUtil.getErrorMessage(e, 'Unknown error'));\n } finally {\n // clear any search params from the URL\n UrlUtil.clearSearchParams();\n }\n }, [handleError, setData]);\n\n const onError = useCallback((errorMessage: unknown) => {\n handleError(ErrorUtil.getErrorMessage(errorMessage, 'Unknown error'));\n }, [handleError]);\n\n return (\n <>\n <FastaDataImportDialog\n extraActions={extraActions}\n onDataChange={onDataChange}\n onError={onError}\n ref={fastaDataImportDialogRef}\n />\n </>\n );\n};\n"],"mappings":";;;;;;;;;AAuBA,
|
|
1
|
+
{"version":3,"file":"index.js","names":["_Fragment","useStore","FastaDataImportDialog","FastaDataImportDialogLoader","setData","store","state","setLoadingStatus","fastaDataImportDialogRef","useRef","useEffect","removers","FastaDataEventBusService","initialErrorMessage","remove","urlParams","inputFastaUrl","inputMetadataUrl","LOADING_STATUS","fastaRes","fastaText","metaText","metaRes","metaErr","fastaErr","message","handleError","useCallback","errorMessage","onDataChange","fastaContent","metadataContent","ErrorUtil","onError","Fragment"],"sources":["../../../src/components/FastaDataImportDialogLoader/FastaDataImportDialogLoader.tsx"],"sourcesContent":["import type { DialogAction } from '@gen-epix/ui-core-components/components/Dialog';\nimport {\n useCallback,\n useEffect,\n useRef,\n} from 'react';\nimport type { StoreApi } from 'zustand';\nimport { useStore } from 'zustand';\n\nimport { FastaDataEventBusService } from '../../classes/services/FastaDataEventBusService';\nimport { LOADING_STATUS } from '../../models/fasta';\nimport type { FastaDataStore } from '../../stores/fastaDataStore';\nimport { UrlUtil } from '../../utils/UrlUtil';\nimport type { FastaDataImportDialogRefMethods } from '../FastaDataImportDialog/FastaDataImportDialog';\nimport { FastaDataImportDialog } from '../FastaDataImportDialog/FastaDataImportDialog';\nimport { ErrorUtil } from '../../utils/ErrorUtil';\n\n\nexport type FastaDataImportDialogLoaderProps = {\n extraActions: DialogAction[];\n store: StoreApi<FastaDataStore>;\n};\n\nexport const FastaDataImportDialogLoader = ({ extraActions, store }: FastaDataImportDialogLoaderProps) => {\n const setData = useStore(store, (state) => state.setData);\n const setLoadingStatus = useStore(store, (state) => state.setLoadingStatus);\n const fastaDataImportDialogRef = useRef<FastaDataImportDialogRefMethods>(null);\n\n useEffect(() => {\n const removers = [\n // eslint-disable-next-line @eslint-react/web-api-no-leaked-event-listener\n FastaDataEventBusService.getInstance().addEventListener('onShowImportDialog', (initialErrorMessage?: string) => {\n fastaDataImportDialogRef.current?.open(initialErrorMessage ? { initialErrorMessage } : undefined);\n }),\n // eslint-disable-next-line @eslint-react/web-api-no-leaked-event-listener\n FastaDataEventBusService.getInstance().addEventListener('onCloseImportDialog', () => {\n fastaDataImportDialogRef.current?.close();\n }),\n ];\n return () => {\n removers.forEach((remove) => remove());\n };\n }, []);\n\n useEffect(() => {\n // Scan URL parameters for deep-linking\n const urlParams = new URLSearchParams(window.location.search);\n const inputFastaUrl = urlParams.get('input-fasta');\n const inputMetadataUrl = urlParams.get('input-metadata');\n\n const handleDeepLinking = async () => {\n if (inputFastaUrl) {\n setLoadingStatus(LOADING_STATUS.LOADING);\n try {\n const fastaRes = await fetch(inputFastaUrl);\n if (!fastaRes.ok) {\n throw new Error(`FASTA fetch failed (${fastaRes.status})`);\n }\n const fastaText = await fastaRes.text();\n\n if (!fastaText.trim()) {\n setLoadingStatus(LOADING_STATUS.ERROR);\n throw new Error('The input-fasta URL returned no sequence data. Check that the URL and requested accession(s) are correct.');\n }\n\n let metaText: string | undefined;\n if (inputMetadataUrl) {\n try {\n const metaRes = await fetch(inputMetadataUrl);\n if (metaRes.ok) {\n metaText = await metaRes.text();\n }\n } catch (metaErr) {\n console.warn('[App] Failed to auto-fetch metadata:', metaErr);\n }\n }\n\n await setData(fastaText, metaText);\n } catch (fastaErr) {\n console.error('[App] Failed to auto-load FASTA:', fastaErr);\n const message = fastaErr instanceof Error ? fastaErr.message : 'Failed to auto-load FASTA from the provided URL.';\n FastaDataEventBusService.getInstance().emit('onShowImportDialog', message);\n }\n } else {\n // PV1-02: Show data loading modal if no data provided via URL query params\n FastaDataEventBusService.getInstance().emit('onShowImportDialog');\n }\n };\n\n void handleDeepLinking();\n }, [setData, setLoadingStatus]);\n\n const handleError = useCallback((errorMessage: string) => {\n fastaDataImportDialogRef.current?.close();\n FastaDataEventBusService.getInstance().emit('onShowImportDialog', errorMessage);\n }, []);\n\n const onDataChange = useCallback(async (fastaContent: string, metadataContent?: string) => {\n try {\n await setData(fastaContent, metadataContent);\n fastaDataImportDialogRef.current?.close();\n } catch (e) {\n handleError(ErrorUtil.getErrorMessage(e, 'Unknown error'));\n } finally {\n // clear any search params from the URL\n UrlUtil.clearSearchParams();\n }\n }, [handleError, setData]);\n\n const onError = useCallback((errorMessage: unknown) => {\n handleError(ErrorUtil.getErrorMessage(errorMessage, 'Unknown error'));\n }, [handleError]);\n\n return (\n <>\n <FastaDataImportDialog\n extraActions={extraActions}\n onDataChange={onDataChange}\n onError={onError}\n ref={fastaDataImportDialogRef}\n />\n </>\n );\n};\n"],"mappings":";;;;;;;;;AAuBA,IAAaG,KAA+B,EAAE,iBAAc,eAA8C;CACxG,IAAMC,IAAUH,EAASI,IAAQ,MAAUC,EAAM,OAAO,GAClDC,IAAmBN,EAASI,IAAQ,MAAUC,EAAM,gBAAgB,GACpEE,IAA2BC,EAAwC,IAAI;CAkB7E,AAhBAC,QAAgB;EACd,IAAMC,IAAW,CAEfC,EAAyB,YAAY,CAAC,CAAC,iBAAiB,uBAAuB,MAAiC;GAC9G,EAAyB,SAAS,KAAKC,IAAsB,EAAE,uBAAoB,IAAI,KAAA,CAAS;EAClG,CAAC,GAEDD,EAAyB,YAAY,CAAC,CAAC,iBAAiB,6BAA6B;GACnF,EAAyB,SAAS,MAAM;EAC1C,CAAC,CACH;EACA,aAAa;GACX,EAAS,SAAS,MAAWE,EAAO,CAAC;EACvC;CACF,GAAG,CAAC,CAAC,GAELJ,QAAgB;EAEd,IAAMK,IAAY,IAAI,gBAAgB,OAAO,SAAS,MAAM,GACtDC,IAAgBD,EAAU,IAAI,aAAa,GAC3CE,IAAmBF,EAAU,IAAI,gBAAgB;EAyCvD,aAvCsC;GACpC,IAAIC,GAAe;IACjB,EAAiBE,EAAe,OAAO;IACvC,IAAI;KACF,IAAMC,IAAW,MAAM,MAAMH,CAAa;KAC1C,IAAI,CAACG,EAAS,IACZ,MAAU,MAAM,uBAAuBA,EAAS,OAAO,EAAE;KAE3D,IAAMC,IAAY,MAAMD,EAAS,KAAK;KAEtC,IAAI,CAACC,EAAU,KAAK,GAElB,MADAb,EAAiBW,EAAe,KAAK,GAC3B,MAAM,2GAA2G;KAG7H,IAAIG;KACJ,IAAIJ,GACF,IAAI;MACF,IAAMK,IAAU,MAAM,MAAML,CAAgB;MAC5C,AAAIK,EAAQ,OACV,IAAW,MAAMA,EAAQ,KAAK;KAElC,SAASC,GAAS;MAChB,QAAQ,KAAK,wCAAwCA,CAAO;KAC9D;KAGF,MAAMnB,EAAQgB,GAAWC,CAAQ;IACnC,SAASG,GAAU;KACjB,QAAQ,MAAM,oCAAoCA,CAAQ;KAC1D,IAAMC,IAAUD,aAAoB,QAAQA,EAAS,UAAU;KAC/D,EAAyB,YAAY,CAAC,CAAC,KAAK,sBAAsBC,CAAO;IAC3E;GACF,OAEE,EAAyB,YAAY,CAAC,CAAC,KAAK,oBAAoB;EAEpE,EAEK,CAAkB;CACzB,GAAG,CAACrB,GAASG,CAAgB,CAAC;CAE9B,IAAMmB,IAAcC,GAAa,MAAyB;EAExD,AADAnB,EAAyB,SAAS,MAAM,GACxCI,EAAyB,YAAY,CAAC,CAAC,KAAK,sBAAsBgB,CAAY;CAChF,GAAG,CAAC,CAAC,GAECC,IAAeF,EAAY,OAAO,GAAsB,MAA6B;EACzF,IAAI;GAEF,AADA,MAAMvB,EAAQ0B,GAAcC,CAAe,GAC3CvB,EAAyB,SAAS,MAAM;EAC1C,SAAS,GAAG;GACV,EAAYwB,EAAU,gBAAgB,GAAG,eAAe,CAAC;EAC3D,UAAU;GAER,EAAQ,kBAAkB;EAC5B;CACF,GAAG,CAACN,GAAatB,CAAO,CAAC,GAEnB6B,IAAUN,GAAa,MAA0B;EACrD,EAAYK,EAAU,gBAAgBJ,GAAc,eAAe,CAAC;CACtE,GAAG,CAACF,CAAW,CAAC;CAEhB,OACE,kBAAA1B,GAAA,EAAA,UACE,kBAACE,GAAD;EACgB;EACA;EACL;EACT,KAAKM;CACN,CAAA,EACD,CAAA;AAEN"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/FastaNotLoaded/FastaNotLoaded.tsx"],"sourcesContent":["import {\n Box,\n Button,\n Typography,\n} from '@mui/material';\nimport FileUploadOutlinedIcon from '@mui/icons-material/FileUploadOutlined';\nimport type { ReactNode } from 'react';\nimport { useCallback } from 'react';\n\nimport { FastaDataEventBusService } from '../../classes/services/FastaDataEventBusService';\n\nexport type FastaNotLoadedProps = {\n description: ReactNode;\n icon: ReactNode;\n title: ReactNode;\n};\n\nexport const FastaNotLoaded = ({ description, icon, title }: FastaNotLoadedProps) => {\n const onClickLoadData = useCallback(() => {\n FastaDataEventBusService.getInstance().emit('onShowImportDialog');\n }, []);\n\n return (\n <Box\n sx={{\n alignItems: 'center',\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n height: '100%',\n justifyContent: 'center',\n p: 3,\n width: '100%',\n }}\n >\n {icon}\n <Typography\n color={'text.secondary'}\n sx={{ fontWeight: 600 }}\n variant={'h6'}\n >\n {title}\n </Typography>\n <Typography\n color={'text.secondary'}\n sx={{ maxWidth: 450, textAlign: 'center' }}\n variant={'body2'}\n >\n {description}\n </Typography>\n <Button\n color={'primary'}\n onClick={onClickLoadData}\n startIcon={<FileUploadOutlinedIcon />}\n sx={{ mt: 1 }}\n variant={'contained'}\n >\n {'Load Data'}\n </Button>\n </Box>\n );\n};\n"],"mappings":";;;;;;AAiBA,
|
|
1
|
+
{"version":3,"file":"index.js","names":["FileUploadOutlinedIcon","FastaNotLoaded","onClickLoadData","useCallback","Box","icon","Typography","title","description","Button"],"sources":["../../../src/components/FastaNotLoaded/FastaNotLoaded.tsx"],"sourcesContent":["import {\n Box,\n Button,\n Typography,\n} from '@mui/material';\nimport FileUploadOutlinedIcon from '@mui/icons-material/FileUploadOutlined';\nimport type { ReactNode } from 'react';\nimport { useCallback } from 'react';\n\nimport { FastaDataEventBusService } from '../../classes/services/FastaDataEventBusService';\n\nexport type FastaNotLoadedProps = {\n description: ReactNode;\n icon: ReactNode;\n title: ReactNode;\n};\n\nexport const FastaNotLoaded = ({ description, icon, title }: FastaNotLoadedProps) => {\n const onClickLoadData = useCallback(() => {\n FastaDataEventBusService.getInstance().emit('onShowImportDialog');\n }, []);\n\n return (\n <Box\n sx={{\n alignItems: 'center',\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n height: '100%',\n justifyContent: 'center',\n p: 3,\n width: '100%',\n }}\n >\n {icon}\n <Typography\n color={'text.secondary'}\n sx={{ fontWeight: 600 }}\n variant={'h6'}\n >\n {title}\n </Typography>\n <Typography\n color={'text.secondary'}\n sx={{ maxWidth: 450, textAlign: 'center' }}\n variant={'body2'}\n >\n {description}\n </Typography>\n <Button\n color={'primary'}\n onClick={onClickLoadData}\n startIcon={<FileUploadOutlinedIcon />}\n sx={{ mt: 1 }}\n variant={'contained'}\n >\n {'Load Data'}\n </Button>\n </Box>\n );\n};\n"],"mappings":";;;;;;AAiBA,IAAaC,KAAkB,EAAE,gBAAa,SAAM,eAAiC;CACnF,IAAMC,IAAkBC,QAAkB;EACxC,EAAyB,YAAY,CAAC,CAAC,KAAK,oBAAoB;CAClE,GAAG,CAAC,CAAC;CAEL,OACE,kBAACC,GAAD;EACE,IAAI;GACF,YAAY;GACZ,SAAS;GACT,eAAe;GACf,KAAK;GACL,QAAQ;GACR,gBAAgB;GAChB,GAAG;GACH,OAAO;EACT;EAVF,UAAA;GAYGC;GACD,kBAACC,GAAD;IACE,OAAO;IACP,IAAI,EAAE,YAAY,IAAI;IACtB,SAAS;IAER,UAAAC;GACS,CAAA;GACZ,kBAACD,GAAD;IACE,OAAO;IACP,IAAI;KAAE,UAAU;KAAK,WAAW;IAAS;IACzC,SAAS;IAER,UAAAE;GACS,CAAA;GACZ,kBAACC,GAAD;IACE,OAAO;IACP,SAASP;IACT,WAAW,kBAACF,GAAD,CAAyB,CAAA;IACpC,IAAI,EAAE,IAAI,EAAE;IACZ,SAAS;IAER,UAAA;GACK,CAAA;EACL;;AAET"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/FastaPageHeaderCenterComponent/FastaPageHeaderCenterComponent.tsx"],"sourcesContent":["import {\n Box,\n Chip,\n} from '@mui/material';\nimport type { StoreApi } from 'zustand';\nimport { useStore } from 'zustand';\n\nimport type { FastaDataStore } from '../../stores/fastaDataStore';\n\n\nexport type FastaPageHeaderCenterComponentProps = {\n store: StoreApi<FastaDataStore>;\n};\n\nexport const FastaPageHeaderCenterComponent = ({ store }: FastaPageHeaderCenterComponentProps) => {\n const parsedFasta = useStore(store, (state) => state.parsedFasta);\n const parsedMetadata = useStore(store, (state) => state.parsedMetadata);\n\n const seqCount = parsedFasta?.sequences?.length || 0;\n const metaCount = parsedMetadata?.records?.length || 0;\n\n return (\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1 }}>\n {seqCount > 0 && (\n <Chip\n label={`${seqCount} Sequences`}\n size={'small'}\n sx={{\n backgroundColor: 'rgba(255, 255, 255, 0.2)',\n color: '#FFFFFF',\n fontSize: '0.75rem',\n fontWeight: 600,\n }}\n />\n )}\n {metaCount > 0 && (\n <Chip\n label={`${metaCount} Metadata Records`}\n size={'small'}\n sx={{\n backgroundColor: 'rgba(255, 255, 255, 0.2)',\n color: '#FFFFFF',\n fontSize: '0.75rem',\n fontWeight: 600,\n }}\n />\n )}\n </Box>\n );\n};\n"],"mappings":";;;;AAcA,
|
|
1
|
+
{"version":3,"file":"index.js","names":["useStore","FastaPageHeaderCenterComponent","parsedFasta","store","state","parsedMetadata","seqCount","metaCount","Box","Chip"],"sources":["../../../src/components/FastaPageHeaderCenterComponent/FastaPageHeaderCenterComponent.tsx"],"sourcesContent":["import {\n Box,\n Chip,\n} from '@mui/material';\nimport type { StoreApi } from 'zustand';\nimport { useStore } from 'zustand';\n\nimport type { FastaDataStore } from '../../stores/fastaDataStore';\n\n\nexport type FastaPageHeaderCenterComponentProps = {\n store: StoreApi<FastaDataStore>;\n};\n\nexport const FastaPageHeaderCenterComponent = ({ store }: FastaPageHeaderCenterComponentProps) => {\n const parsedFasta = useStore(store, (state) => state.parsedFasta);\n const parsedMetadata = useStore(store, (state) => state.parsedMetadata);\n\n const seqCount = parsedFasta?.sequences?.length || 0;\n const metaCount = parsedMetadata?.records?.length || 0;\n\n return (\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1 }}>\n {seqCount > 0 && (\n <Chip\n label={`${seqCount} Sequences`}\n size={'small'}\n sx={{\n backgroundColor: 'rgba(255, 255, 255, 0.2)',\n color: '#FFFFFF',\n fontSize: '0.75rem',\n fontWeight: 600,\n }}\n />\n )}\n {metaCount > 0 && (\n <Chip\n label={`${metaCount} Metadata Records`}\n size={'small'}\n sx={{\n backgroundColor: 'rgba(255, 255, 255, 0.2)',\n color: '#FFFFFF',\n fontSize: '0.75rem',\n fontWeight: 600,\n }}\n />\n )}\n </Box>\n );\n};\n"],"mappings":";;;;AAcA,IAAaC,KAAkC,EAAE,eAAiD;CAChG,IAAMC,IAAcF,EAASG,IAAQ,MAAUC,EAAM,WAAW,GAC1DC,IAAiBL,EAASG,IAAQ,MAAUC,EAAM,cAAc,GAEhEE,IAAWJ,GAAa,WAAW,UAAU,GAC7CK,IAAYF,GAAgB,SAAS,UAAU;CAErD,OACE,kBAACG,GAAD;EAAK,IAAI;GAAE,YAAY;GAAU,SAAS;GAAQ,KAAK;EAAE;EAAzD,UAAA,CACGF,IAAW,KACV,kBAACG,GAAD;GACE,OAAO,GAAGH,EAAS;GACnB,MAAM;GACN,IAAI;IACF,iBAAiB;IACjB,OAAO;IACP,UAAU;IACV,YAAY;GACd;EACD,CAAA,GAEFC,IAAY,KACX,kBAACE,GAAD;GACE,OAAO,GAAGF,EAAU;GACpB,MAAM;GACN,IAAI;IACF,iBAAiB;IACjB,OAAO;IACP,UAAU;IACV,YAAY;GACd;EACD,CAAA,CAEA;;AAET"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/FastaPageHeaderImportButton/FastaPageHeaderImportButton.tsx"],"sourcesContent":["import FileUploadOutlinedIcon from '@mui/icons-material/FileUploadOutlined';\nimport { Button } from '@mui/material';\nimport { useCallback } from 'react';\n\nimport { FastaDataEventBusService } from '../../classes/services/FastaDataEventBusService';\n\nexport const FastaPageHeaderImportButton = () => {\n const onImportDataButtonClick = useCallback(() => FastaDataEventBusService.getInstance().emit('onShowImportDialog'), []);\n\n return (\n <Button\n color={'inherit'}\n onClick={onImportDataButtonClick}\n size={'small'}\n startIcon={<FileUploadOutlinedIcon />}\n sx={{\n '&:hover': {\n backgroundColor: 'rgba(255, 255, 255, 0.25)',\n },\n backgroundColor: 'rgba(255, 255, 255, 0.15)',\n color: '#FFFFFF',\n }}\n variant={'contained'}\n >\n {'Import Data'}\n </Button>\n );\n};\n"],"mappings":";;;;;;AAMA,
|
|
1
|
+
{"version":3,"file":"index.js","names":["FileUploadOutlinedIcon","FastaPageHeaderImportButton","onImportDataButtonClick","useCallback","FastaDataEventBusService","Button"],"sources":["../../../src/components/FastaPageHeaderImportButton/FastaPageHeaderImportButton.tsx"],"sourcesContent":["import FileUploadOutlinedIcon from '@mui/icons-material/FileUploadOutlined';\nimport { Button } from '@mui/material';\nimport { useCallback } from 'react';\n\nimport { FastaDataEventBusService } from '../../classes/services/FastaDataEventBusService';\n\nexport const FastaPageHeaderImportButton = () => {\n const onImportDataButtonClick = useCallback(() => FastaDataEventBusService.getInstance().emit('onShowImportDialog'), []);\n\n return (\n <Button\n color={'inherit'}\n onClick={onImportDataButtonClick}\n size={'small'}\n startIcon={<FileUploadOutlinedIcon />}\n sx={{\n '&:hover': {\n backgroundColor: 'rgba(255, 255, 255, 0.25)',\n },\n backgroundColor: 'rgba(255, 255, 255, 0.15)',\n color: '#FFFFFF',\n }}\n variant={'contained'}\n >\n {'Import Data'}\n </Button>\n );\n};\n"],"mappings":";;;;;;AAMA,IAAaC,UAAoC;CAC/C,IAAMC,IAA0BC,QAAkBC,EAAyB,YAAY,CAAC,CAAC,KAAK,oBAAoB,GAAG,CAAC,CAAC;CAEvH,OACE,kBAACC,GAAD;EACE,OAAO;EACP,SAASH;EACT,MAAM;EACN,WAAW,kBAACF,GAAD,CAAyB,CAAA;EACpC,IAAI;GACF,WAAW,EACT,iBAAiB,4BACnB;GACA,iBAAiB;GACjB,OAAO;EACT;EACA,SAAS;EAER,UAAA;CACK,CAAA;AAEZ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/FastaPageHeaderResetButton/FastaPageHeaderResetButton.tsx"],"sourcesContent":["import RestartAltIcon from '@mui/icons-material/RestartAlt';\nimport {\n IconButton,\n Tooltip,\n} from '@mui/material';\nimport {\n useCallback,\n useRef,\n} from 'react';\nimport { Confirmation } from '@gen-epix/ui-core-components/components/Confirmation';\nimport type { ConfirmationRefMethods } from '@gen-epix/ui-core-components/components/Confirmation';\nimport { t } from 'i18next';\n\nexport type FastaPageHeaderResetButtonProps = {\n onReset: () => void;\n};\n\nexport const FastaPageHeaderResetButton = ({ onReset }: FastaPageHeaderResetButtonProps) => {\n const confirmationRef = useRef<ConfirmationRefMethods>(null);\n const onClickResetSession = useCallback(() => {\n confirmationRef.current?.open();\n }, []);\n\n const onConfirm = useCallback(() => {\n onReset();\n }, [onReset]);\n\n return (\n <>\n <Tooltip title={'Reset current session and dataset'}>\n <IconButton\n color={'inherit'}\n onClick={onClickResetSession}\n size={'small'}\n sx={{ opacity: 0.85 }}\n >\n <RestartAltIcon fontSize={'small'} />\n </IconButton>\n </Tooltip>\n <Confirmation\n body={t`Are you sure you want to reset the current session and dataset?`}\n cancelLabel={t`Cancel`}\n confirmLabel={t`Reset`}\n onConfirm={onConfirm}\n ref={confirmationRef}\n title={t`Reset current session and dataset?`}\n />\n </>\n );\n};\n"],"mappings":";;;;;;;AAiBA,
|
|
1
|
+
{"version":3,"file":"index.js","names":["_Fragment","RestartAltIcon","FastaPageHeaderResetButton","confirmationRef","useRef","onClickResetSession","useCallback","onConfirm","onReset","Fragment","Tooltip","IconButton","Confirmation"],"sources":["../../../src/components/FastaPageHeaderResetButton/FastaPageHeaderResetButton.tsx"],"sourcesContent":["import RestartAltIcon from '@mui/icons-material/RestartAlt';\nimport {\n IconButton,\n Tooltip,\n} from '@mui/material';\nimport {\n useCallback,\n useRef,\n} from 'react';\nimport { Confirmation } from '@gen-epix/ui-core-components/components/Confirmation';\nimport type { ConfirmationRefMethods } from '@gen-epix/ui-core-components/components/Confirmation';\nimport { t } from 'i18next';\n\nexport type FastaPageHeaderResetButtonProps = {\n onReset: () => void;\n};\n\nexport const FastaPageHeaderResetButton = ({ onReset }: FastaPageHeaderResetButtonProps) => {\n const confirmationRef = useRef<ConfirmationRefMethods>(null);\n const onClickResetSession = useCallback(() => {\n confirmationRef.current?.open();\n }, []);\n\n const onConfirm = useCallback(() => {\n onReset();\n }, [onReset]);\n\n return (\n <>\n <Tooltip title={'Reset current session and dataset'}>\n <IconButton\n color={'inherit'}\n onClick={onClickResetSession}\n size={'small'}\n sx={{ opacity: 0.85 }}\n >\n <RestartAltIcon fontSize={'small'} />\n </IconButton>\n </Tooltip>\n <Confirmation\n body={t`Are you sure you want to reset the current session and dataset?`}\n cancelLabel={t`Cancel`}\n confirmLabel={t`Reset`}\n onConfirm={onConfirm}\n ref={confirmationRef}\n title={t`Reset current session and dataset?`}\n />\n </>\n );\n};\n"],"mappings":";;;;;;;AAiBA,IAAaE,KAA8B,EAAE,iBAA+C;CAC1F,IAAMC,IAAkBC,EAA+B,IAAI,GACrDC,IAAsBC,QAAkB;EAC5C,EAAgB,SAAS,KAAK;CAChC,GAAG,CAAC,CAAC,GAECC,IAAYD,QAAkB;EAClC,EAAQ;CACV,GAAG,CAACE,CAAO,CAAC;CAEZ,OACE,kBAAAR,GAAA,EAAA,UAAA,CACE,kBAACU,GAAD;EAAS,OAAO;EACd,UAAA,kBAACC,GAAD;GACE,OAAO;GACP,SAASN;GACT,MAAM;GACN,IAAI,EAAE,SAAS,IAAK;GAEpB,UAAA,kBAACJ,GAAD,EAAgB,UAAU,QAAU,CAAA;EAC1B,CAAA;CACL,CAAA,GACT,kBAACW,GAAD;EACE,MAAM,CAAC;EACP,aAAa,CAAC;EACd,cAAc,CAAC;EACJ;EACX,KAAKT;EACL,OAAO,CAAC;CACT,CAAA,CACD,EAAA,CAAA;AAEN"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/I18nWrapper/I18nWrapper.tsx"],"sourcesContent":["import {\n useEffect,\n useState,\n} from 'react';\nimport type { ReactNode } from 'react';\nimport i18n from 'i18next';\nimport { initReactI18next } from 'react-i18next';\n\nexport const I18nWrapper = ({ children }: { children: ReactNode }) => {\n const [isInitialized, setIsInitialized] = useState(false);\n\n useEffect(() => {\n const performInitialization = async () => {\n await i18n\n .use(initReactI18next) // passes i18n down to react-i18next\n .init({\n interpolation: {\n escapeValue: false, // react already safes from xss\n },\n lng: 'en',\n resources: {\n en: {\n translation: {\n },\n },\n },\n });\n setIsInitialized(true);\n };\n void performInitialization();\n }, []);\n\n\n return (\n <>\n {isInitialized ? children : null}\n </>\n );\n};\n"],"mappings":";;;;;AAQA,
|
|
1
|
+
{"version":3,"file":"index.js","names":["_Fragment","i18n","I18nWrapper","isInitialized","setIsInitialized","useState","useEffect","initReactI18next","Fragment","children"],"sources":["../../../src/components/I18nWrapper/I18nWrapper.tsx"],"sourcesContent":["import {\n useEffect,\n useState,\n} from 'react';\nimport type { ReactNode } from 'react';\nimport i18n from 'i18next';\nimport { initReactI18next } from 'react-i18next';\n\nexport const I18nWrapper = ({ children }: { children: ReactNode }) => {\n const [isInitialized, setIsInitialized] = useState(false);\n\n useEffect(() => {\n const performInitialization = async () => {\n await i18n\n .use(initReactI18next) // passes i18n down to react-i18next\n .init({\n interpolation: {\n escapeValue: false, // react already safes from xss\n },\n lng: 'en',\n resources: {\n en: {\n translation: {\n },\n },\n },\n });\n setIsInitialized(true);\n };\n void performInitialization();\n }, []);\n\n\n return (\n <>\n {isInitialized ? children : null}\n </>\n );\n};\n"],"mappings":";;;;;AAQA,IAAaE,KAAe,EAAE,kBAAwC;CACpE,IAAM,CAACC,GAAeC,KAAoBC,EAAS,EAAK;CAwBxD,OAtBAC,QAAgB;EAkBd,aAjB0C;GAexC,AAdA,MAAML,EACH,IAAIM,CAAgB,CAAC,CACrB,KAAK;IACJ,eAAe,EACb,aAAa,GACf;IACA,KAAK;IACL,WAAW,EACT,IAAI,EACF,aAAa,CACb,EACF,EACF;GACF,CAAC,GACHH,EAAiB,EAAI;EACvB,EACK,CAAsB;CAC7B,GAAG,CAAC,CAAC,GAIH,kBAAAJ,GAAA,EAAA,UACGG,IAAgBM,IAAW,KAC5B,CAAA;AAEN"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/PageHeaderDocumentationButton/PageHeaderDocumentationButton.tsx"],"sourcesContent":["import { useCallback } from 'react';\nimport {\n IconButton,\n Tooltip,\n} from '@mui/material';\nimport HelpOutlineIcon from '@mui/icons-material/HelpOutlineOutlined';\n\nexport const PageHeaderDocumentationButton = () => {\n const onDocumentationButtonClick = useCallback(() => {\n window.open('https://github.com/RIVM-bioinformatics/loculus-tools', '_blank');\n }, []);\n\n return (\n <Tooltip title={'Documentation & Specifications'}>\n <IconButton\n color={'inherit'}\n onClick={onDocumentationButtonClick}\n size={'small'}\n sx={{ opacity: 0.85 }}\n >\n <HelpOutlineIcon fontSize={'small'} />\n </IconButton>\n </Tooltip>\n );\n};\n"],"mappings":";;;;;AAOA,
|
|
1
|
+
{"version":3,"file":"index.js","names":["HelpOutlineIcon","PageHeaderDocumentationButton","onDocumentationButtonClick","useCallback","Tooltip","IconButton"],"sources":["../../../src/components/PageHeaderDocumentationButton/PageHeaderDocumentationButton.tsx"],"sourcesContent":["import { useCallback } from 'react';\nimport {\n IconButton,\n Tooltip,\n} from '@mui/material';\nimport HelpOutlineIcon from '@mui/icons-material/HelpOutlineOutlined';\n\nexport const PageHeaderDocumentationButton = () => {\n const onDocumentationButtonClick = useCallback(() => {\n window.open('https://github.com/RIVM-bioinformatics/loculus-tools', '_blank');\n }, []);\n\n return (\n <Tooltip title={'Documentation & Specifications'}>\n <IconButton\n color={'inherit'}\n onClick={onDocumentationButtonClick}\n size={'small'}\n sx={{ opacity: 0.85 }}\n >\n <HelpOutlineIcon fontSize={'small'} />\n </IconButton>\n </Tooltip>\n );\n};\n"],"mappings":";;;;;AAOA,IAAaC,UAAsC;CACjD,IAAMC,IAA6BC,QAAkB;EACnD,OAAO,KAAK,wDAAwD,QAAQ;CAC9E,GAAG,CAAC,CAAC;CAEL,OACE,kBAACC,GAAD;EAAS,OAAO;EACd,UAAA,kBAACC,GAAD;GACE,OAAO;GACP,SAASH;GACT,MAAM;GACN,IAAI,EAAE,SAAS,IAAK;GAEpB,UAAA,kBAACF,GAAD,EAAiB,UAAU,QAAU,CAAA;EAC3B,CAAA;CACL,CAAA;AAEb"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/SearchBar/SearchBar.tsx"],"sourcesContent":["import type {\n ChangeEvent,\n KeyboardEvent,\n} from 'react';\nimport {\n useCallback,\n useMemo,\n useRef,\n} from 'react';\nimport {\n Box,\n FilledInput,\n IconButton,\n InputAdornment,\n useTheme,\n} from '@mui/material';\nimport SearchIcon from '@mui/icons-material/Search';\nimport KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';\nimport KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';\nimport CloseIcon from '@mui/icons-material/Close';\n\n\nexport type SearchBarProps = {\n allowNavigation?: boolean;\n highlightedIndex?: null | number;\n numResults?: number;\n onHighlightedIndexChange?: (index: number) => void;\n onSearchQueryChange: (query: string) => void;\n searchQuery: string;\n truncated?: boolean;\n};\n\nexport const SearchBar = ({ allowNavigation, highlightedIndex, numResults = 0, onHighlightedIndexChange, onSearchQueryChange, searchQuery, truncated }: SearchBarProps) => {\n const theme = useTheme();\n const inputRef = useRef<HTMLInputElement>(null);\n const arrowUpButtonRef = useRef<HTMLButtonElement>(null);\n const arrowDownButtonRef = useRef<HTMLButtonElement>(null);\n\n const onTextInputChange = useCallback((event: ChangeEvent<HTMLInputElement>) => {\n const nextSearchText = event.target.value;\n onSearchQueryChange(nextSearchText);\n }, [onSearchQueryChange]);\n\n const onClearButtonClick = useCallback(() => {\n onSearchQueryChange('');\n inputRef.current?.focus();\n }, [onSearchQueryChange]);\n\n const onTextInputKeyDown = useCallback((event: KeyboardEvent<HTMLInputElement>) => {\n // on enter press, highlight the first result and focus the down arrow button\n if (event.key === 'Enter') {\n if (!numResults) {\n return;\n }\n event.preventDefault();\n onHighlightedIndexChange?.(0);\n arrowDownButtonRef.current?.focus();\n }\n }, [numResults, onHighlightedIndexChange]);\n\n const onUpArrowButtonClick = useCallback(() => {\n // goto previous result\n if (!numResults) {\n return;\n }\n const newHighlightedIndex = highlightedIndex === null || highlightedIndex === undefined || Number.isNaN(highlightedIndex) || highlightedIndex <= 0 ? numResults - 1 : highlightedIndex - 1;\n\n onHighlightedIndexChange?.(newHighlightedIndex);\n }, [numResults, highlightedIndex, onHighlightedIndexChange]);\n\n const onDownArrowButtonClick = useCallback(() => {\n // goto next result\n if (!numResults) {\n return;\n }\n const newHighlightedIndex = highlightedIndex === null || highlightedIndex === undefined || Number.isNaN(highlightedIndex) || highlightedIndex >= numResults - 1 ? 0 : highlightedIndex + 1;\n onHighlightedIndexChange?.(newHighlightedIndex);\n }, [numResults, highlightedIndex, onHighlightedIndexChange]);\n\n const onGenericKeyDown = useCallback((event: KeyboardEvent<HTMLButtonElement>) => {\n // arrow right, focus the next focusable element\n if (event.key === 'ArrowRight') {\n event.preventDefault();\n const nextFocusableElement = event.currentTarget.nextElementSibling as HTMLElement;\n if (nextFocusableElement) {\n nextFocusableElement.focus();\n }\n }\n // arrow left, focus the previous focusable element\n if (event.key === 'ArrowLeft') {\n event.preventDefault();\n if (event.target === arrowUpButtonRef.current) {\n inputRef.current?.focus();\n return;\n }\n const previousFocusableElement = event.currentTarget.previousElementSibling as HTMLElement;\n if (previousFocusableElement) {\n previousFocusableElement.focus();\n }\n }\n }, []);\n\n const searchResultStatusText = useMemo(() => {\n if (!searchQuery) {\n return '';\n }\n if (searchQuery && (Number.isNaN(numResults) || numResults <= 0)) {\n return 'No results';\n } else if (highlightedIndex === null || highlightedIndex === undefined || Number.isNaN(highlightedIndex) || highlightedIndex < 0 || !allowNavigation) {\n return `${numResults}${truncated ? '+' : ''} results`;\n } else if (allowNavigation) {\n return `${highlightedIndex + 1}/${numResults}${truncated ? '+' : ''} results`;\n }\n return '';\n }, [searchQuery, numResults, highlightedIndex, allowNavigation, truncated]);\n\n\n return (\n <FilledInput\n endAdornment={(\n <InputAdornment position={'end'}>\n {searchResultStatusText && (\n <Box\n aria-atomic={'true'}\n aria-live={'polite'}\n role={'status'}\n sx={{\n fontSize: '1rem',\n }}\n >\n {searchResultStatusText}\n </Box>\n )}\n {numResults > 0 && allowNavigation && (\n <>\n <IconButton\n aria-label={'Goto previous search result'}\n disabled={!numResults}\n edge={'end'}\n onClick={onUpArrowButtonClick}\n onKeyDown={onGenericKeyDown}\n ref={arrowUpButtonRef}\n sx={{ color: theme.palette.primary.main }}\n >\n <KeyboardArrowUpIcon />\n </IconButton>\n <IconButton\n aria-label={'Goto next search result'}\n disabled={!numResults}\n edge={'end'}\n onClick={onDownArrowButtonClick}\n onKeyDown={onGenericKeyDown}\n ref={arrowDownButtonRef}\n sx={{ color: theme.palette.primary.main }}\n >\n <KeyboardArrowDownIcon />\n </IconButton>\n </>\n )}\n {searchQuery && (\n <IconButton\n aria-label={'Clear'}\n edge={'end'}\n onClick={onClearButtonClick}\n onKeyDown={onGenericKeyDown}\n >\n <CloseIcon />\n </IconButton>\n )}\n </InputAdornment>\n )}\n fullWidth\n inputRef={inputRef}\n name={'Search'}\n onChange={onTextInputChange}\n onKeyDown={onTextInputKeyDown}\n placeholder={'Search'}\n size={'small'}\n slotProps={{\n input: {\n 'aria-label': 'Search',\n sx: {\n '&::-webkit-search-cancel-button': {\n display: 'none',\n },\n fontSize: '1rem',\n height: theme.spacing(4),\n outline: 'none !important',\n paddingBottom: '0 !important',\n paddingTop: '0 !important',\n },\n },\n }}\n startAdornment={(\n <InputAdornment position={'start'}>\n <SearchIcon fontSize={'small'} />\n </InputAdornment>\n )}\n sx={{\n backgroundColor: theme.palette.background.paper,\n height: theme.spacing(4),\n }}\n type={'search'}\n value={searchQuery}\n />\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["_Fragment","SearchIcon","KeyboardArrowUpIcon","KeyboardArrowDownIcon","CloseIcon","SearchBar","theme","useTheme","inputRef","useRef","arrowUpButtonRef","arrowDownButtonRef","onTextInputChange","useCallback","nextSearchText","event","onSearchQueryChange","onClearButtonClick","onTextInputKeyDown","numResults","onHighlightedIndexChange","onUpArrowButtonClick","newHighlightedIndex","highlightedIndex","onDownArrowButtonClick","onGenericKeyDown","nextFocusableElement","previousFocusableElement","searchResultStatusText","useMemo","searchQuery","allowNavigation","truncated","FilledInput","InputAdornment","Box","Fragment","IconButton"],"sources":["../../../src/components/SearchBar/SearchBar.tsx"],"sourcesContent":["import type {\n ChangeEvent,\n KeyboardEvent,\n} from 'react';\nimport {\n useCallback,\n useMemo,\n useRef,\n} from 'react';\nimport {\n Box,\n FilledInput,\n IconButton,\n InputAdornment,\n useTheme,\n} from '@mui/material';\nimport SearchIcon from '@mui/icons-material/Search';\nimport KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';\nimport KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';\nimport CloseIcon from '@mui/icons-material/Close';\n\n\nexport type SearchBarProps = {\n allowNavigation?: boolean;\n highlightedIndex?: null | number;\n numResults?: number;\n onHighlightedIndexChange?: (index: number) => void;\n onSearchQueryChange: (query: string) => void;\n searchQuery: string;\n truncated?: boolean;\n};\n\nexport const SearchBar = ({ allowNavigation, highlightedIndex, numResults = 0, onHighlightedIndexChange, onSearchQueryChange, searchQuery, truncated }: SearchBarProps) => {\n const theme = useTheme();\n const inputRef = useRef<HTMLInputElement>(null);\n const arrowUpButtonRef = useRef<HTMLButtonElement>(null);\n const arrowDownButtonRef = useRef<HTMLButtonElement>(null);\n\n const onTextInputChange = useCallback((event: ChangeEvent<HTMLInputElement>) => {\n const nextSearchText = event.target.value;\n onSearchQueryChange(nextSearchText);\n }, [onSearchQueryChange]);\n\n const onClearButtonClick = useCallback(() => {\n onSearchQueryChange('');\n inputRef.current?.focus();\n }, [onSearchQueryChange]);\n\n const onTextInputKeyDown = useCallback((event: KeyboardEvent<HTMLInputElement>) => {\n // on enter press, highlight the first result and focus the down arrow button\n if (event.key === 'Enter') {\n if (!numResults) {\n return;\n }\n event.preventDefault();\n onHighlightedIndexChange?.(0);\n arrowDownButtonRef.current?.focus();\n }\n }, [numResults, onHighlightedIndexChange]);\n\n const onUpArrowButtonClick = useCallback(() => {\n // goto previous result\n if (!numResults) {\n return;\n }\n const newHighlightedIndex = highlightedIndex === null || highlightedIndex === undefined || Number.isNaN(highlightedIndex) || highlightedIndex <= 0 ? numResults - 1 : highlightedIndex - 1;\n\n onHighlightedIndexChange?.(newHighlightedIndex);\n }, [numResults, highlightedIndex, onHighlightedIndexChange]);\n\n const onDownArrowButtonClick = useCallback(() => {\n // goto next result\n if (!numResults) {\n return;\n }\n const newHighlightedIndex = highlightedIndex === null || highlightedIndex === undefined || Number.isNaN(highlightedIndex) || highlightedIndex >= numResults - 1 ? 0 : highlightedIndex + 1;\n onHighlightedIndexChange?.(newHighlightedIndex);\n }, [numResults, highlightedIndex, onHighlightedIndexChange]);\n\n const onGenericKeyDown = useCallback((event: KeyboardEvent<HTMLButtonElement>) => {\n // arrow right, focus the next focusable element\n if (event.key === 'ArrowRight') {\n event.preventDefault();\n const nextFocusableElement = event.currentTarget.nextElementSibling as HTMLElement;\n if (nextFocusableElement) {\n nextFocusableElement.focus();\n }\n }\n // arrow left, focus the previous focusable element\n if (event.key === 'ArrowLeft') {\n event.preventDefault();\n if (event.target === arrowUpButtonRef.current) {\n inputRef.current?.focus();\n return;\n }\n const previousFocusableElement = event.currentTarget.previousElementSibling as HTMLElement;\n if (previousFocusableElement) {\n previousFocusableElement.focus();\n }\n }\n }, []);\n\n const searchResultStatusText = useMemo(() => {\n if (!searchQuery) {\n return '';\n }\n if (searchQuery && (Number.isNaN(numResults) || numResults <= 0)) {\n return 'No results';\n } else if (highlightedIndex === null || highlightedIndex === undefined || Number.isNaN(highlightedIndex) || highlightedIndex < 0 || !allowNavigation) {\n return `${numResults}${truncated ? '+' : ''} results`;\n } else if (allowNavigation) {\n return `${highlightedIndex + 1}/${numResults}${truncated ? '+' : ''} results`;\n }\n return '';\n }, [searchQuery, numResults, highlightedIndex, allowNavigation, truncated]);\n\n\n return (\n <FilledInput\n endAdornment={(\n <InputAdornment position={'end'}>\n {searchResultStatusText && (\n <Box\n aria-atomic={'true'}\n aria-live={'polite'}\n role={'status'}\n sx={{\n fontSize: '1rem',\n }}\n >\n {searchResultStatusText}\n </Box>\n )}\n {numResults > 0 && allowNavigation && (\n <>\n <IconButton\n aria-label={'Goto previous search result'}\n disabled={!numResults}\n edge={'end'}\n onClick={onUpArrowButtonClick}\n onKeyDown={onGenericKeyDown}\n ref={arrowUpButtonRef}\n sx={{ color: theme.palette.primary.main }}\n >\n <KeyboardArrowUpIcon />\n </IconButton>\n <IconButton\n aria-label={'Goto next search result'}\n disabled={!numResults}\n edge={'end'}\n onClick={onDownArrowButtonClick}\n onKeyDown={onGenericKeyDown}\n ref={arrowDownButtonRef}\n sx={{ color: theme.palette.primary.main }}\n >\n <KeyboardArrowDownIcon />\n </IconButton>\n </>\n )}\n {searchQuery && (\n <IconButton\n aria-label={'Clear'}\n edge={'end'}\n onClick={onClearButtonClick}\n onKeyDown={onGenericKeyDown}\n >\n <CloseIcon />\n </IconButton>\n )}\n </InputAdornment>\n )}\n fullWidth\n inputRef={inputRef}\n name={'Search'}\n onChange={onTextInputChange}\n onKeyDown={onTextInputKeyDown}\n placeholder={'Search'}\n size={'small'}\n slotProps={{\n input: {\n 'aria-label': 'Search',\n sx: {\n '&::-webkit-search-cancel-button': {\n display: 'none',\n },\n fontSize: '1rem',\n height: theme.spacing(4),\n outline: 'none !important',\n paddingBottom: '0 !important',\n paddingTop: '0 !important',\n },\n },\n }}\n startAdornment={(\n <InputAdornment position={'start'}>\n <SearchIcon fontSize={'small'} />\n </InputAdornment>\n )}\n sx={{\n backgroundColor: theme.palette.background.paper,\n height: theme.spacing(4),\n }}\n type={'search'}\n value={searchQuery}\n />\n );\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/page/ErrorPageCommon.tsx","../../../src/components/page/PageCommonContext.ts","../../../src/components/page/PageCommon.tsx","../../../src/components/page/PageCommonContextProvider.tsx","../../../src/components/page/PageCommonDrawer.tsx","../../../src/components/page/PageCommonHeader.tsx"],"sourcesContent":["import {\n Box,\n Typography,\n} from '@mui/material';\nimport { t } from 'i18next';\n\nexport type ErrorPageCommonProps = {\n error: unknown;\n};\n\nexport const ErrorPageCommon = ({ error }: ErrorPageCommonProps) => {\n return (\n <Box\n sx={{\n alignItems: 'center',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n width: '100%',\n }}\n >\n <Box sx={{ padding: 1 }}>\n <Typography\n variant={'h1'}\n >\n {t`Something went wrong`}\n </Typography>\n </Box>\n <Box sx={{ padding: 1 }}>\n <Typography\n variant={'body2'}\n >\n {error instanceof Error ? error.message : t`An unexpected error occurred.`}\n </Typography>\n </Box>\n <Box sx={{ padding: 1 }}>\n <Typography variant={'h6'}>\n {t`Details for our technicians`}\n </Typography>\n <Box\n component={'pre'}\n sx={{\n fontSize: '0.8rem',\n }}\n >\n {(error as Error)?.stack}\n </Box>\n </Box>\n </Box>\n );\n};\n","import { createContext } from 'react';\n\nexport type PageCommonContextData = {\n readonly isDrawerOpen: boolean;\n readonly isNoInteraction: boolean;\n readonly setIsDrawerOpen: (open: boolean) => void;\n readonly setIsNoInteraction: (open: boolean) => void;\n};\n\nexport const PageCommonContext = createContext<PageCommonContextData>({\n isDrawerOpen: false,\n isNoInteraction: false,\n setIsDrawerOpen: () => null,\n setIsNoInteraction: () => null,\n});\n","import {\n Box,\n useTheme,\n} from '@mui/material';\nimport {\n use,\n useEffect,\n} from 'react';\nimport type { ReactNode } from 'react';\n\nimport { DRAWER_WIDTH } from '../../constants/page';\n\nimport { PageCommonContext } from './PageCommonContext';\n\nexport type PageCommonProps = {\n readonly children: ReactNode;\n readonly drawerComponent?: ReactNode;\n readonly headerComponent?: ReactNode;\n readonly isNoInteraction?: boolean;\n};\n\n\nexport const PageCommon = ({ children, drawerComponent, headerComponent, isNoInteraction }: PageCommonProps) => {\n const theme = useTheme();\n const { isDrawerOpen, setIsNoInteraction } = use(PageCommonContext);\n\n useEffect(() => {\n setIsNoInteraction(!!isNoInteraction);\n }, [isNoInteraction, setIsNoInteraction]);\n\n return (\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n height: '100vh',\n overflow: 'hidden',\n position: 'relative',\n width: '100vw',\n }}\n >\n {headerComponent}\n {/* Main Body */}\n <Box\n sx={{\n display: 'flex',\n flex: 1,\n height: 'calc(100vh - 56px)',\n overflow: 'hidden',\n position: 'relative',\n width: '100%',\n }}\n >\n {drawerComponent}\n <Box\n component={'main'}\n sx={{\n flexGrow: 1,\n height: '100%',\n overflow: 'hidden',\n position: 'relative',\n transition: () =>\n theme.transitions.create(['margin', 'width'], {\n duration: theme.transitions.duration.leavingScreen,\n easing: theme.transitions.easing.sharp,\n }),\n width: isDrawerOpen ? `calc(100% - ${DRAWER_WIDTH}px)` : '100%',\n }}\n >\n {children}\n </Box>\n\n </Box>\n </Box>\n );\n};\n","import {\n useMemo,\n useState,\n} from 'react';\nimport type { PropsWithChildren } from 'react';\n\nimport type { PageCommonContextData } from './PageCommonContext';\nimport { PageCommonContext } from './PageCommonContext';\n\nexport type PageCommonContextProviderProps = PropsWithChildren;\n\nexport const PageCommonContextProvider = ({ children }: PageCommonContextProviderProps) => {\n const [isDrawerOpen, setIsDrawerOpen] = useState(false);\n const [isNoInteraction, setIsNoInteraction] = useState(false);\n\n const contextValue = useMemo<PageCommonContextData>(() => {\n return {\n isDrawerOpen,\n isNoInteraction,\n setIsDrawerOpen,\n setIsNoInteraction,\n };\n }, [isDrawerOpen, isNoInteraction]);\n\n return (\n <PageCommonContext value={contextValue}>\n { children }\n </PageCommonContext>\n );\n};\n","import { Drawer } from '@mui/material';\nimport { use } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { DRAWER_WIDTH } from '../../constants/page';\n\nimport { PageCommonContext } from './PageCommonContext';\n\nexport type PageCommonDrawerProps = {\n readonly children: ReactNode;\n};\n\nexport const PageCommonDrawer = ({ children }: PageCommonDrawerProps) => {\n const { isDrawerOpen } = use(PageCommonContext);\n\n return (\n <Drawer\n anchor={'left'}\n open={isDrawerOpen}\n sx={{\n '& .MuiDrawer-paper': {\n height: 'calc(100% - 56px)',\n overflowY: 'auto',\n top: '56px',\n width: DRAWER_WIDTH,\n },\n flexShrink: 0,\n width: isDrawerOpen ? DRAWER_WIDTH : 0,\n }}\n variant={'persistent'}\n >\n {children}\n </Drawer>\n );\n};\n","import type { ReactNode } from 'react';\nimport {\n use,\n useCallback,\n} from 'react';\nimport {\n AppBar,\n Box,\n IconButton,\n Toolbar,\n Typography,\n} from '@mui/material';\nimport MenuIcon from '@mui/icons-material/Menu';\n\nimport { PageCommonContext } from './PageCommonContext';\n\nexport type PageCommonHeaderProps = {\n readonly centerComponent?: ReactNode;\n readonly icon?: ReactNode;\n readonly rightComponent?: ReactNode;\n readonly title: string;\n};\n\nexport const PageCommonHeader = ({ centerComponent, icon, rightComponent, title }: PageCommonHeaderProps) => {\n const { isDrawerOpen, isNoInteraction, setIsDrawerOpen } = use(PageCommonContext);\n\n const onToggleDrawerButtonClick = useCallback(() => {\n setIsDrawerOpen(!isDrawerOpen);\n }, [isDrawerOpen, setIsDrawerOpen]);\n\n return (\n <AppBar\n elevation={1}\n position={'static'}\n sx={{\n backgroundColor: 'primary.main',\n color: '#FFFFFF',\n height: 56,\n justifyContent: 'center',\n zIndex: (theme) => theme.zIndex.drawer + 1,\n }}\n >\n <Toolbar\n sx={{ display: 'flex', justifyContent: 'space-between', px: 2 }}\n variant={'dense'}\n >\n {/* Left: Menu toggle and App Branding */}\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1.5 }}>\n {!isNoInteraction && (\n <IconButton\n aria-label={'open drawer'}\n color={'inherit'}\n edge={'start'}\n onClick={onToggleDrawerButtonClick}\n size={'small'}\n >\n <MenuIcon />\n </IconButton>\n )}\n {icon && (\n <>\n {icon}\n </>\n )}\n <Typography\n component={'div'}\n noWrap\n sx={{ color: 'inherit', fontSize: '1.05rem', fontWeight: 700, letterSpacing: '-0.01em' }}\n variant={'h6'}\n >\n {title}\n </Typography>\n <Typography\n sx={{\n backgroundColor: 'rgba(255, 255, 255, 0.15)',\n borderRadius: 1,\n display: { sm: 'inline-block', xs: 'none' },\n fontSize: '0.7rem',\n fontWeight: 600,\n px: 1,\n py: 0.25,\n }}\n variant={'caption'}\n >\n {'Loculus Tool'}\n </Typography>\n </Box>\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1 }}>\n {centerComponent}\n </Box>\n {!isNoInteraction && (\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1 }}>\n {rightComponent}\n </Box>\n )}\n </Toolbar>\n </AppBar>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["_Fragment","MenuIcon","ErrorPageCommon","Box","Typography","error","PageCommonContext","createContext","PageCommon","theme","useTheme","use","useEffect","isNoInteraction","setIsNoInteraction","headerComponent","drawerComponent","isDrawerOpen","PageCommonContextProvider","setIsDrawerOpen","useState","contextValue","useMemo","PageCommonDrawer","Drawer","PageCommonHeader","onToggleDrawerButtonClick","useCallback","AppBar","Toolbar","IconButton","icon","Fragment","title","centerComponent","rightComponent"],"sources":["../../../src/components/page/ErrorPageCommon.tsx","../../../src/components/page/PageCommonContext.ts","../../../src/components/page/PageCommon.tsx","../../../src/components/page/PageCommonContextProvider.tsx","../../../src/components/page/PageCommonDrawer.tsx","../../../src/components/page/PageCommonHeader.tsx"],"sourcesContent":["import {\n Box,\n Typography,\n} from '@mui/material';\nimport { t } from 'i18next';\n\nexport type ErrorPageCommonProps = {\n error: unknown;\n};\n\nexport const ErrorPageCommon = ({ error }: ErrorPageCommonProps) => {\n return (\n <Box\n sx={{\n alignItems: 'center',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n width: '100%',\n }}\n >\n <Box sx={{ padding: 1 }}>\n <Typography\n variant={'h1'}\n >\n {t`Something went wrong`}\n </Typography>\n </Box>\n <Box sx={{ padding: 1 }}>\n <Typography\n variant={'body2'}\n >\n {error instanceof Error ? error.message : t`An unexpected error occurred.`}\n </Typography>\n </Box>\n <Box sx={{ padding: 1 }}>\n <Typography variant={'h6'}>\n {t`Details for our technicians`}\n </Typography>\n <Box\n component={'pre'}\n sx={{\n fontSize: '0.8rem',\n }}\n >\n {(error as Error)?.stack}\n </Box>\n </Box>\n </Box>\n );\n};\n","import { createContext } from 'react';\n\nexport type PageCommonContextData = {\n readonly isDrawerOpen: boolean;\n readonly isNoInteraction: boolean;\n readonly setIsDrawerOpen: (open: boolean) => void;\n readonly setIsNoInteraction: (open: boolean) => void;\n};\n\nexport const PageCommonContext = createContext<PageCommonContextData>({\n isDrawerOpen: false,\n isNoInteraction: false,\n setIsDrawerOpen: () => null,\n setIsNoInteraction: () => null,\n});\n","import {\n Box,\n useTheme,\n} from '@mui/material';\nimport {\n use,\n useEffect,\n} from 'react';\nimport type { ReactNode } from 'react';\n\nimport { DRAWER_WIDTH } from '../../constants/page';\n\nimport { PageCommonContext } from './PageCommonContext';\n\nexport type PageCommonProps = {\n readonly children: ReactNode;\n readonly drawerComponent?: ReactNode;\n readonly headerComponent?: ReactNode;\n readonly isNoInteraction?: boolean;\n};\n\n\nexport const PageCommon = ({ children, drawerComponent, headerComponent, isNoInteraction }: PageCommonProps) => {\n const theme = useTheme();\n const { isDrawerOpen, setIsNoInteraction } = use(PageCommonContext);\n\n useEffect(() => {\n setIsNoInteraction(!!isNoInteraction);\n }, [isNoInteraction, setIsNoInteraction]);\n\n return (\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n height: '100vh',\n overflow: 'hidden',\n position: 'relative',\n width: '100vw',\n }}\n >\n {headerComponent}\n {/* Main Body */}\n <Box\n sx={{\n display: 'flex',\n flex: 1,\n height: 'calc(100vh - 56px)',\n overflow: 'hidden',\n position: 'relative',\n width: '100%',\n }}\n >\n {drawerComponent}\n <Box\n component={'main'}\n sx={{\n flexGrow: 1,\n height: '100%',\n overflow: 'hidden',\n position: 'relative',\n transition: () =>\n theme.transitions.create(['margin', 'width'], {\n duration: theme.transitions.duration.leavingScreen,\n easing: theme.transitions.easing.sharp,\n }),\n width: isDrawerOpen ? `calc(100% - ${DRAWER_WIDTH}px)` : '100%',\n }}\n >\n {children}\n </Box>\n\n </Box>\n </Box>\n );\n};\n","import {\n useMemo,\n useState,\n} from 'react';\nimport type { PropsWithChildren } from 'react';\n\nimport type { PageCommonContextData } from './PageCommonContext';\nimport { PageCommonContext } from './PageCommonContext';\n\nexport type PageCommonContextProviderProps = PropsWithChildren;\n\nexport const PageCommonContextProvider = ({ children }: PageCommonContextProviderProps) => {\n const [isDrawerOpen, setIsDrawerOpen] = useState(false);\n const [isNoInteraction, setIsNoInteraction] = useState(false);\n\n const contextValue = useMemo<PageCommonContextData>(() => {\n return {\n isDrawerOpen,\n isNoInteraction,\n setIsDrawerOpen,\n setIsNoInteraction,\n };\n }, [isDrawerOpen, isNoInteraction]);\n\n return (\n <PageCommonContext value={contextValue}>\n { children }\n </PageCommonContext>\n );\n};\n","import { Drawer } from '@mui/material';\nimport { use } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { DRAWER_WIDTH } from '../../constants/page';\n\nimport { PageCommonContext } from './PageCommonContext';\n\nexport type PageCommonDrawerProps = {\n readonly children: ReactNode;\n};\n\nexport const PageCommonDrawer = ({ children }: PageCommonDrawerProps) => {\n const { isDrawerOpen } = use(PageCommonContext);\n\n return (\n <Drawer\n anchor={'left'}\n open={isDrawerOpen}\n sx={{\n '& .MuiDrawer-paper': {\n height: 'calc(100% - 56px)',\n overflowY: 'auto',\n top: '56px',\n width: DRAWER_WIDTH,\n },\n flexShrink: 0,\n width: isDrawerOpen ? DRAWER_WIDTH : 0,\n }}\n variant={'persistent'}\n >\n {children}\n </Drawer>\n );\n};\n","import type { ReactNode } from 'react';\nimport {\n use,\n useCallback,\n} from 'react';\nimport {\n AppBar,\n Box,\n IconButton,\n Toolbar,\n Typography,\n} from '@mui/material';\nimport MenuIcon from '@mui/icons-material/Menu';\n\nimport { PageCommonContext } from './PageCommonContext';\n\nexport type PageCommonHeaderProps = {\n readonly centerComponent?: ReactNode;\n readonly icon?: ReactNode;\n readonly rightComponent?: ReactNode;\n readonly title: string;\n};\n\nexport const PageCommonHeader = ({ centerComponent, icon, rightComponent, title }: PageCommonHeaderProps) => {\n const { isDrawerOpen, isNoInteraction, setIsDrawerOpen } = use(PageCommonContext);\n\n const onToggleDrawerButtonClick = useCallback(() => {\n setIsDrawerOpen(!isDrawerOpen);\n }, [isDrawerOpen, setIsDrawerOpen]);\n\n return (\n <AppBar\n elevation={1}\n position={'static'}\n sx={{\n backgroundColor: 'primary.main',\n color: '#FFFFFF',\n height: 56,\n justifyContent: 'center',\n zIndex: (theme) => theme.zIndex.drawer + 1,\n }}\n >\n <Toolbar\n sx={{ display: 'flex', justifyContent: 'space-between', px: 2 }}\n variant={'dense'}\n >\n {/* Left: Menu toggle and App Branding */}\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1.5 }}>\n {!isNoInteraction && (\n <IconButton\n aria-label={'open drawer'}\n color={'inherit'}\n edge={'start'}\n onClick={onToggleDrawerButtonClick}\n size={'small'}\n >\n <MenuIcon />\n </IconButton>\n )}\n {icon && (\n <>\n {icon}\n </>\n )}\n <Typography\n component={'div'}\n noWrap\n sx={{ color: 'inherit', fontSize: '1.05rem', fontWeight: 700, letterSpacing: '-0.01em' }}\n variant={'h6'}\n >\n {title}\n </Typography>\n <Typography\n sx={{\n backgroundColor: 'rgba(255, 255, 255, 0.15)',\n borderRadius: 1,\n display: { sm: 'inline-block', xs: 'none' },\n fontSize: '0.7rem',\n fontWeight: 600,\n px: 1,\n py: 0.25,\n }}\n variant={'caption'}\n >\n {'Loculus Tool'}\n </Typography>\n </Box>\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1 }}>\n {centerComponent}\n </Box>\n {!isNoInteraction && (\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1 }}>\n {rightComponent}\n </Box>\n )}\n </Toolbar>\n </AppBar>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page.js","names":[],"sources":["../../src/constants/page.ts"],"sourcesContent":["export const DRAWER_WIDTH = 340;\n"],"mappings":";AAAA,
|
|
1
|
+
{"version":3,"file":"page.js","names":["DRAWER_WIDTH"],"sources":["../../src/constants/page.ts"],"sourcesContent":["export const DRAWER_WIDTH = 340;\n"],"mappings":";AAAA,IAAaA,IAAe"}
|
package/dist/models/fasta.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fasta.js","names":[],"sources":["../../src/models/fasta.ts"],"sourcesContent":["export enum LOADING_STATUS {\n ERROR = 'ERROR',\n IDLE = 'IDLE',\n LOADING = 'LOADING',\n SUCCESS = 'SUCCESS',\n}\n\nexport type FastaParseResult = {\n error?: string;\n expectedLength: number;\n invalidSequences?: { id: string; length: number }[];\n isAligned: boolean;\n sequences: FastaSequence[];\n};\n\nexport type FastaSequence = {\n accessionVersion: string;\n header: string;\n id: string;\n length: number;\n sequence: string;\n};\n"],"mappings":";AAAA,
|
|
1
|
+
{"version":3,"file":"fasta.js","names":["LOADING_STATUS","\"ERROR\"","\"IDLE\"","\"LOADING\"","\"SUCCESS\""],"sources":["../../src/models/fasta.ts"],"sourcesContent":["export enum LOADING_STATUS {\n ERROR = 'ERROR',\n IDLE = 'IDLE',\n LOADING = 'LOADING',\n SUCCESS = 'SUCCESS',\n}\n\nexport type FastaParseResult = {\n error?: string;\n expectedLength: number;\n invalidSequences?: { id: string; length: number }[];\n isAligned: boolean;\n sequences: FastaSequence[];\n};\n\nexport type FastaSequence = {\n accessionVersion: string;\n header: string;\n id: string;\n length: number;\n sequence: string;\n};\n"],"mappings":";AAAA,IAAYA,IAAL,yBAAA,GAAA;QACL,EAAAC,QAAA,SACA,EAAAC,OAAA,QACA,EAAAC,UAAA,WACA,EAAAC,UAAA;AACF,EAAA,CAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/stores/fastaDataStore/fastaDataStore.ts"],"sourcesContent":["import type { StoreApi } from 'zustand';\n\nimport type { FastaParseResult } from '../../models/fasta';\nimport { LOADING_STATUS } from '../../models/fasta';\nimport type { MetadataParseResult } from '../../models/metadata';\nimport { FastaUtil } from '../../utils/FastaUtil';\nimport { MetaDataUtil } from '../../utils/MetaDataUtil';\n\nexport type FastaDataStore = FastaDataStoreActions & FastaDataStoreState;\n\nexport interface FastaDataStoreActions {\n resetDataset: () => void;\n setColumnMatchCounts: (counts: Record<string, number>) => void;\n setData: (fasta: string, tsv?: string) => Promise<{ fastaResult: FastaParseResult; metadataResult?: MetadataParseResult }>;\n setLoadingStatus: (status: LOADING_STATUS) => void;\n setMatchKeyField: (field: null | string) => void;\n}\n\nexport interface FastaDataStoreState {\n columnMatchCounts: Record<string, number>;\n loadingError: null | string;\n loadingStatus: LOADING_STATUS;\n matchKeyField: null | string;\n parsedFasta: FastaParseResult | null;\n parsedMetadata: MetadataParseResult | null;\n rawFasta: string;\n rawMetadata: string;\n}\n\nexport const createFastaDataStoreInitialState = (): FastaDataStoreState => ({\n columnMatchCounts: {},\n loadingError: null,\n loadingStatus: LOADING_STATUS.IDLE,\n matchKeyField: null,\n parsedFasta: null,\n parsedMetadata: null,\n rawFasta: '',\n rawMetadata: '',\n});\n\n\ntype Get<T extends FastaDataStore> = StoreApi<T>['getState'];\ntype Set<T extends FastaDataStore> = StoreApi<T>['setState'];\n\nexport const createFastaDataStoreActions = <T extends FastaDataStore>(kwArgs: { get: Get<T>; set: Set<T> }): FastaDataStoreActions => {\n const { get, set } = kwArgs;\n const setBaseState = (partial: Partial<FastaDataStoreState>) => set(partial as Partial<T>);\n\n return {\n resetDataset: () => setBaseState(createFastaDataStoreInitialState()),\n setColumnMatchCounts: (counts: Record<string, number>) => setBaseState({ columnMatchCounts: counts }),\n setData: async (fasta: string, tsv?: string) => {\n const parsedFasta = FastaUtil.parseFasta(fasta);\n\n if (parsedFasta.error) {\n setBaseState({\n loadingError: parsedFasta.error,\n loadingStatus: LOADING_STATUS.ERROR,\n });\n throw new Error(parsedFasta.error);\n }\n\n setBaseState({\n parsedFasta,\n rawFasta: fasta,\n });\n\n let parsedMetadata: MetadataParseResult | undefined;\n if (tsv) {\n parsedMetadata = MetaDataUtil.parseTsv(tsv);\n if (parsedMetadata.error) {\n setBaseState({\n loadingError: parsedMetadata.error,\n loadingStatus: LOADING_STATUS.ERROR,\n });\n throw new Error(parsedMetadata.error);\n }\n\n setBaseState({\n parsedMetadata,\n rawMetadata: tsv,\n });\n\n const fastaIds = parsedFasta.sequences.map((s) => s.id);\n const { bestColumn, matchCounts } = MetaDataUtil.findBestMatchingColumn(\n parsedMetadata.columns,\n parsedMetadata.recordsByColumn,\n fastaIds,\n );\n get().setColumnMatchCounts(matchCounts);\n get().setMatchKeyField(bestColumn);\n }\n\n setBaseState({\n loadingError: null,\n loadingStatus: LOADING_STATUS.SUCCESS,\n });\n return Promise.resolve({ fastaResult: parsedFasta, metadataResult: parsedMetadata });\n },\n setLoadingStatus: (status: LOADING_STATUS) => setBaseState({ loadingStatus: status }),\n setMatchKeyField: (field: null | string) => setBaseState({ matchKeyField: field }),\n };\n};\n"],"mappings":";;;;AA6BA,
|
|
1
|
+
{"version":3,"file":"index.js","names":["createFastaDataStoreInitialState","LOADING_STATUS","createFastaDataStoreActions","kwArgs","setBaseState","set","partial","counts","parsedFasta","FastaUtil","fasta","parsedMetadata","tsv","MetaDataUtil","fastaIds","s","get","matchCounts","bestColumn","status","field"],"sources":["../../../src/stores/fastaDataStore/fastaDataStore.ts"],"sourcesContent":["import type { StoreApi } from 'zustand';\n\nimport type { FastaParseResult } from '../../models/fasta';\nimport { LOADING_STATUS } from '../../models/fasta';\nimport type { MetadataParseResult } from '../../models/metadata';\nimport { FastaUtil } from '../../utils/FastaUtil';\nimport { MetaDataUtil } from '../../utils/MetaDataUtil';\n\nexport type FastaDataStore = FastaDataStoreActions & FastaDataStoreState;\n\nexport interface FastaDataStoreActions {\n resetDataset: () => void;\n setColumnMatchCounts: (counts: Record<string, number>) => void;\n setData: (fasta: string, tsv?: string) => Promise<{ fastaResult: FastaParseResult; metadataResult?: MetadataParseResult }>;\n setLoadingStatus: (status: LOADING_STATUS) => void;\n setMatchKeyField: (field: null | string) => void;\n}\n\nexport interface FastaDataStoreState {\n columnMatchCounts: Record<string, number>;\n loadingError: null | string;\n loadingStatus: LOADING_STATUS;\n matchKeyField: null | string;\n parsedFasta: FastaParseResult | null;\n parsedMetadata: MetadataParseResult | null;\n rawFasta: string;\n rawMetadata: string;\n}\n\nexport const createFastaDataStoreInitialState = (): FastaDataStoreState => ({\n columnMatchCounts: {},\n loadingError: null,\n loadingStatus: LOADING_STATUS.IDLE,\n matchKeyField: null,\n parsedFasta: null,\n parsedMetadata: null,\n rawFasta: '',\n rawMetadata: '',\n});\n\n\ntype Get<T extends FastaDataStore> = StoreApi<T>['getState'];\ntype Set<T extends FastaDataStore> = StoreApi<T>['setState'];\n\nexport const createFastaDataStoreActions = <T extends FastaDataStore>(kwArgs: { get: Get<T>; set: Set<T> }): FastaDataStoreActions => {\n const { get, set } = kwArgs;\n const setBaseState = (partial: Partial<FastaDataStoreState>) => set(partial as Partial<T>);\n\n return {\n resetDataset: () => setBaseState(createFastaDataStoreInitialState()),\n setColumnMatchCounts: (counts: Record<string, number>) => setBaseState({ columnMatchCounts: counts }),\n setData: async (fasta: string, tsv?: string) => {\n const parsedFasta = FastaUtil.parseFasta(fasta);\n\n if (parsedFasta.error) {\n setBaseState({\n loadingError: parsedFasta.error,\n loadingStatus: LOADING_STATUS.ERROR,\n });\n throw new Error(parsedFasta.error);\n }\n\n setBaseState({\n parsedFasta,\n rawFasta: fasta,\n });\n\n let parsedMetadata: MetadataParseResult | undefined;\n if (tsv) {\n parsedMetadata = MetaDataUtil.parseTsv(tsv);\n if (parsedMetadata.error) {\n setBaseState({\n loadingError: parsedMetadata.error,\n loadingStatus: LOADING_STATUS.ERROR,\n });\n throw new Error(parsedMetadata.error);\n }\n\n setBaseState({\n parsedMetadata,\n rawMetadata: tsv,\n });\n\n const fastaIds = parsedFasta.sequences.map((s) => s.id);\n const { bestColumn, matchCounts } = MetaDataUtil.findBestMatchingColumn(\n parsedMetadata.columns,\n parsedMetadata.recordsByColumn,\n fastaIds,\n );\n get().setColumnMatchCounts(matchCounts);\n get().setMatchKeyField(bestColumn);\n }\n\n setBaseState({\n loadingError: null,\n loadingStatus: LOADING_STATUS.SUCCESS,\n });\n return Promise.resolve({ fastaResult: parsedFasta, metadataResult: parsedMetadata });\n },\n setLoadingStatus: (status: LOADING_STATUS) => setBaseState({ loadingStatus: status }),\n setMatchKeyField: (field: null | string) => setBaseState({ matchKeyField: field }),\n };\n};\n"],"mappings":";;;;AA6BA,IAAaA,WAA+D;CAC1E,mBAAmB,CAAC;CACpB,cAAc;CACd,eAAeC,EAAe;CAC9B,eAAe;CACf,aAAa;CACb,gBAAgB;CAChB,UAAU;CACV,aAAa;AACf,IAMaC,KAAyD,MAAgE;CACpI,IAAM,EAAE,QAAK,WAAQC,GACfC,KAAgB,MAA0CC,EAAIC,CAAqB;CAEzF,OAAO;EACL,oBAAoBF,EAAaJ,EAAiC,CAAC;EACnE,uBAAuB,MAAmCI,EAAa,EAAE,mBAAmBG,EAAO,CAAC;EACpG,SAAS,OAAO,GAAe,MAAiB;GAC9C,IAAMC,IAAcC,EAAU,WAAWC,CAAK;GAE9C,IAAIF,EAAY,OAKd,MAJAJ,EAAa;IACX,cAAcI,EAAY;IAC1B,eAAeP,EAAe;GAChC,CAAC,GACS,MAAMO,EAAY,KAAK;GAGnC,EAAa;IACX;IACA,UAAUE;GACZ,CAAC;GAED,IAAIC;GACJ,IAAIC,GAAK;IAEP,IADA,IAAiBC,EAAa,SAASD,CAAG,GACtCD,EAAe,OAKjB,MAJAP,EAAa;KACX,cAAcO,EAAe;KAC7B,eAAeV,EAAe;IAChC,CAAC,GACS,MAAMU,EAAe,KAAK;IAGtC,EAAa;KACX;KACA,aAAaC;IACf,CAAC;IAED,IAAME,IAAWN,EAAY,UAAU,KAAK,MAAMO,EAAE,EAAE,GAChD,EAAE,eAAY,mBAAgBF,EAAa,uBAC/CF,EAAe,SACfA,EAAe,iBACfG,CACF;IAEA,AADAE,EAAI,CAAC,CAAC,qBAAqBC,CAAW,GACtCD,EAAI,CAAC,CAAC,iBAAiBE,CAAU;GACnC;GAMA,OAJAd,EAAa;IACX,cAAc;IACd,eAAeH,EAAe;GAChC,CAAC,GACM,QAAQ,QAAQ;IAAE,aAAaO;IAAa,gBAAgBG;GAAe,CAAC;EACrF;EACA,mBAAmB,MAA2BP,EAAa,EAAE,eAAee,EAAO,CAAC;EACpF,mBAAmB,MAAyBf,EAAa,EAAE,eAAegB,EAAM,CAAC;CACnF;AACF"}
|