@rivm-loculus-tools/common-frontend 0.1.3 → 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.
Files changed (126) hide show
  1. package/dist/_chunks/FastaDataImportDialog.js +309 -0
  2. package/dist/_chunks/FastaDataImportDialog.js.map +1 -0
  3. package/dist/_chunks/react.js +11 -0
  4. package/dist/_chunks/react.js.map +1 -0
  5. package/dist/classes/services/FastaDataEventBusService/FastaDataEventBusService.d.ts +10 -0
  6. package/dist/classes/services/FastaDataEventBusService/index.js +16 -0
  7. package/dist/classes/services/FastaDataEventBusService/index.js.map +1 -0
  8. package/dist/components/FastaDataImportDialog/FastaDataImportDialog.d.ts +12 -0
  9. package/dist/components/FastaDataImportDialog/index.js +1 -0
  10. package/dist/components/FastaDataImportDialogLoader/FastaDataImportDialogLoader.d.ts +8 -0
  11. package/dist/components/FastaDataImportDialogLoader/index.js +70 -0
  12. package/dist/components/FastaDataImportDialogLoader/index.js.map +1 -0
  13. package/dist/components/FastaNotLoaded/FastaNotLoaded.d.ts +7 -0
  14. package/dist/components/FastaNotLoaded/index.js +53 -0
  15. package/dist/components/FastaNotLoaded/index.js.map +1 -0
  16. package/dist/components/FastaPageHeaderCenterComponent/FastaPageHeaderCenterComponent.d.ts +6 -0
  17. package/dist/components/FastaPageHeaderCenterComponent/index.js +37 -0
  18. package/dist/components/FastaPageHeaderCenterComponent/index.js.map +1 -0
  19. package/dist/components/FastaPageHeaderImportButton/FastaPageHeaderImportButton.d.ts +1 -0
  20. package/dist/components/FastaPageHeaderImportButton/index.js +26 -0
  21. package/dist/components/FastaPageHeaderImportButton/index.js.map +1 -0
  22. package/dist/components/FastaPageHeaderResetButton/FastaPageHeaderResetButton.d.ts +4 -0
  23. package/dist/components/FastaPageHeaderResetButton/index.js +35 -0
  24. package/dist/components/FastaPageHeaderResetButton/index.js.map +1 -0
  25. package/dist/components/I18nWrapper/I18nWrapper.d.ts +4 -0
  26. package/dist/components/I18nWrapper/index.js +21 -0
  27. package/dist/components/I18nWrapper/index.js.map +1 -0
  28. package/dist/components/PageHeaderDocumentationButton/PageHeaderDocumentationButton.d.ts +1 -0
  29. package/dist/components/PageHeaderDocumentationButton/index.js +24 -0
  30. package/dist/components/PageHeaderDocumentationButton/index.js.map +1 -0
  31. package/dist/components/SearchBar/SearchBar.d.ts +10 -0
  32. package/dist/components/SearchBar/SearchBarNodeCounter.d.ts +4 -0
  33. package/dist/components/SearchBar/index.js +129 -0
  34. package/dist/components/SearchBar/index.js.map +1 -0
  35. package/dist/components/page/ErrorPageCommon.d.ts +4 -0
  36. package/dist/components/page/PageCommon.d.ts +8 -0
  37. package/dist/components/page/PageCommonContext.d.ts +7 -0
  38. package/dist/components/page/PageCommonContextProvider.d.ts +3 -0
  39. package/dist/components/page/PageCommonDrawer.d.ts +5 -0
  40. package/dist/components/page/PageCommonHeader.d.ts +8 -0
  41. package/dist/components/page/index.js +207 -0
  42. package/dist/components/page/index.js.map +1 -0
  43. package/dist/constants/page.d.ts +1 -0
  44. package/dist/constants/page.js +6 -0
  45. package/dist/constants/page.js.map +1 -0
  46. package/dist/models/fasta.d.ts +23 -0
  47. package/dist/models/fasta.js +8 -0
  48. package/dist/models/fasta.js.map +1 -0
  49. package/dist/models/metadata.d.ts +9 -0
  50. package/dist/stores/fastaDataStore/fastaDataStore.d.ts +32 -0
  51. package/dist/stores/fastaDataStore/index.js +57 -0
  52. package/dist/stores/fastaDataStore/index.js.map +1 -0
  53. package/dist/theme/index.js +257 -0
  54. package/dist/theme/index.js.map +1 -0
  55. package/dist/theme/theme.d.ts +1 -0
  56. package/dist/utils/DownloadUtil/DownloadUtil.d.ts +3 -0
  57. package/dist/utils/DownloadUtil/index.js +10 -0
  58. package/dist/utils/DownloadUtil/index.js.map +1 -0
  59. package/dist/utils/ErrorUtil/ErrorUtil.d.ts +3 -0
  60. package/dist/utils/ErrorUtil/index.js +10 -0
  61. package/dist/utils/ErrorUtil/index.js.map +1 -0
  62. package/dist/utils/FastaUtil/FastaUtil.d.ts +6 -0
  63. package/dist/utils/FastaUtil/index.js +56 -0
  64. package/dist/utils/FastaUtil/index.js.map +1 -0
  65. package/dist/utils/MetaDataUtil/MetaDataUtil.d.ts +20 -0
  66. package/dist/utils/MetaDataUtil/index.js +133 -0
  67. package/dist/utils/MetaDataUtil/index.js.map +1 -0
  68. package/dist/utils/UrlUtil/UrlUtil.d.ts +5 -0
  69. package/dist/utils/UrlUtil/index.js +30 -0
  70. package/dist/utils/UrlUtil/index.js.map +1 -0
  71. package/package.json +27 -28
  72. package/CHANGELOG.md +0 -29
  73. package/eslint.config.js +0 -16
  74. package/scripts/update-exports.js +0 -9
  75. package/src/classes/services/FastaDataEventBusService/FastaDataEventBusService.ts +0 -22
  76. package/src/components/FastaDataImportDialog/FastaDataImportDialog.tsx +0 -364
  77. package/src/components/FastaDataImportDialogLoader/FastaDataImportDialogLoader.tsx +0 -124
  78. package/src/components/FastaNotLoaded/FastaNotLoaded.tsx +0 -62
  79. package/src/components/FastaPageHeaderCenterComponent/FastaPageHeaderCenterComponent.tsx +0 -50
  80. package/src/components/FastaPageHeaderImportButton/FastaPageHeaderImportButton.tsx +0 -28
  81. package/src/components/FastaPageHeaderResetButton/FastaPageHeaderResetButton.tsx +0 -50
  82. package/src/components/I18nWrapper/I18nWrapper.tsx +0 -39
  83. package/src/components/PageHeaderDocumentationButton/PageHeaderDocumentationButton.tsx +0 -25
  84. package/src/components/SearchBar/SearchBar.tsx +0 -207
  85. package/src/components/SearchBar/SearchBarNodeCounter.tsx +0 -23
  86. package/src/components/page/ErrorPageCommon.tsx +0 -51
  87. package/src/components/page/PageCommon.tsx +0 -76
  88. package/src/components/page/PageCommonContext.ts +0 -15
  89. package/src/components/page/PageCommonContextProvider.tsx +0 -30
  90. package/src/components/page/PageCommonDrawer.tsx +0 -35
  91. package/src/components/page/PageCommonHeader.tsx +0 -99
  92. package/src/constants/page.ts +0 -1
  93. package/src/index.ts +0 -21
  94. package/src/models/fasta.ts +0 -22
  95. package/src/models/metadata.ts +0 -10
  96. package/src/stores/fastaDataStore/fastaDataStore.ts +0 -103
  97. package/src/theme/fonts/RobotoFlex.woff2 +0 -0
  98. package/src/theme/theme.ts +0 -368
  99. package/src/utils/DownloadUtil/DownloadUtil.ts +0 -10
  100. package/src/utils/ErrorUtil/ErrorUtil.ts +0 -5
  101. package/src/utils/FastaUtil/FastaUtil.ts +0 -109
  102. package/src/utils/MetaDataUtil/MetaDataUtil.ts +0 -292
  103. package/src/utils/UrlUtil/UrlUtil.ts +0 -35
  104. package/tsconfig.build.json +0 -14
  105. package/tsconfig.json +0 -32
  106. package/vite.config.ts +0 -137
  107. /package/{src → dist}/@types/vite-env.d.ts +0 -0
  108. /package/{src/classes/services/FastaDataEventBusService/index.ts → dist/classes/services/FastaDataEventBusService/index.d.ts} +0 -0
  109. /package/{src/components/FastaDataImportDialog/index.ts → dist/components/FastaDataImportDialog/index.d.ts} +0 -0
  110. /package/{src/components/FastaDataImportDialogLoader/index.ts → dist/components/FastaDataImportDialogLoader/index.d.ts} +0 -0
  111. /package/{src/components/FastaNotLoaded/index.ts → dist/components/FastaNotLoaded/index.d.ts} +0 -0
  112. /package/{src/components/FastaPageHeaderCenterComponent/index.ts → dist/components/FastaPageHeaderCenterComponent/index.d.ts} +0 -0
  113. /package/{src/components/FastaPageHeaderImportButton/index.ts → dist/components/FastaPageHeaderImportButton/index.d.ts} +0 -0
  114. /package/{src/components/FastaPageHeaderResetButton/index.ts → dist/components/FastaPageHeaderResetButton/index.d.ts} +0 -0
  115. /package/{src/components/I18nWrapper/index.ts → dist/components/I18nWrapper/index.d.ts} +0 -0
  116. /package/{src/components/PageHeaderDocumentationButton/index.ts → dist/components/PageHeaderDocumentationButton/index.d.ts} +0 -0
  117. /package/{src/components/SearchBar/index.ts → dist/components/SearchBar/index.d.ts} +0 -0
  118. /package/{src/components/page/index.ts → dist/components/page/index.d.ts} +0 -0
  119. /package/{src/.gitkeep → dist/models/metadata.js} +0 -0
  120. /package/{src/stores/fastaDataStore/index.ts → dist/stores/fastaDataStore/index.d.ts} +0 -0
  121. /package/{src/theme/index.ts → dist/theme/index.d.ts} +0 -0
  122. /package/{src/utils/DownloadUtil/index.ts → dist/utils/DownloadUtil/index.d.ts} +0 -0
  123. /package/{src/utils/ErrorUtil/index.ts → dist/utils/ErrorUtil/index.d.ts} +0 -0
  124. /package/{src/utils/FastaUtil/index.ts → dist/utils/FastaUtil/index.d.ts} +0 -0
  125. /package/{src/utils/MetaDataUtil/index.ts → dist/utils/MetaDataUtil/index.d.ts} +0 -0
  126. /package/{src/utils/UrlUtil/index.ts → dist/utils/UrlUtil/index.d.ts} +0 -0
@@ -1,39 +0,0 @@
1
- import {
2
- useEffect,
3
- useState,
4
- } from 'react';
5
- import type { ReactNode } from 'react';
6
- import i18n from 'i18next';
7
- import { initReactI18next } from 'react-i18next';
8
-
9
- export const I18nWrapper = ({ children }: { children: ReactNode }) => {
10
- const [isInitialized, setIsInitialized] = useState(false);
11
-
12
- useEffect(() => {
13
- const performInitialization = async () => {
14
- await i18n
15
- .use(initReactI18next) // passes i18n down to react-i18next
16
- .init({
17
- interpolation: {
18
- escapeValue: false, // react already safes from xss
19
- },
20
- lng: 'en',
21
- resources: {
22
- en: {
23
- translation: {
24
- },
25
- },
26
- },
27
- });
28
- setIsInitialized(true);
29
- };
30
- void performInitialization();
31
- }, []);
32
-
33
-
34
- return (
35
- <>
36
- {isInitialized ? children : null}
37
- </>
38
- );
39
- };
@@ -1,25 +0,0 @@
1
- import { useCallback } from 'react';
2
- import {
3
- IconButton,
4
- Tooltip,
5
- } from '@mui/material';
6
- import HelpOutlineIcon from '@mui/icons-material/HelpOutlineOutlined';
7
-
8
- export const PageHeaderDocumentationButton = () => {
9
- const onDocumentationButtonClick = useCallback(() => {
10
- window.open('https://github.com/RIVM-bioinformatics/loculus-tools', '_blank');
11
- }, []);
12
-
13
- return (
14
- <Tooltip title={'Documentation & Specifications'}>
15
- <IconButton
16
- color={'inherit'}
17
- onClick={onDocumentationButtonClick}
18
- size={'small'}
19
- sx={{ opacity: 0.85 }}
20
- >
21
- <HelpOutlineIcon fontSize={'small'} />
22
- </IconButton>
23
- </Tooltip>
24
- );
25
- };
@@ -1,207 +0,0 @@
1
- import type {
2
- ChangeEvent,
3
- KeyboardEvent,
4
- } from 'react';
5
- import {
6
- useCallback,
7
- useMemo,
8
- useRef,
9
- } from 'react';
10
- import {
11
- Box,
12
- FilledInput,
13
- IconButton,
14
- InputAdornment,
15
- useTheme,
16
- } from '@mui/material';
17
- import SearchIcon from '@mui/icons-material/Search';
18
- import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';
19
- import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
20
- import CloseIcon from '@mui/icons-material/Close';
21
-
22
-
23
- export type SearchBarProps = {
24
- allowNavigation?: boolean;
25
- highlightedIndex?: null | number;
26
- numResults?: number;
27
- onHighlightedIndexChange?: (index: number) => void;
28
- onSearchQueryChange: (query: string) => void;
29
- searchQuery: string;
30
- truncated?: boolean;
31
- };
32
-
33
- export const SearchBar = ({ allowNavigation, highlightedIndex, numResults = 0, onHighlightedIndexChange, onSearchQueryChange, searchQuery, truncated }: SearchBarProps) => {
34
- const theme = useTheme();
35
- const inputRef = useRef<HTMLInputElement>(null);
36
- const arrowUpButtonRef = useRef<HTMLButtonElement>(null);
37
- const arrowDownButtonRef = useRef<HTMLButtonElement>(null);
38
-
39
- const onTextInputChange = useCallback((event: ChangeEvent<HTMLInputElement>) => {
40
- const nextSearchText = event.target.value;
41
- onSearchQueryChange(nextSearchText);
42
- }, [onSearchQueryChange]);
43
-
44
- const onClearButtonClick = useCallback(() => {
45
- onSearchQueryChange('');
46
- inputRef.current?.focus();
47
- }, [onSearchQueryChange]);
48
-
49
- const onTextInputKeyDown = useCallback((event: KeyboardEvent<HTMLInputElement>) => {
50
- // on enter press, highlight the first result and focus the down arrow button
51
- if (event.key === 'Enter') {
52
- if (!numResults) {
53
- return;
54
- }
55
- event.preventDefault();
56
- onHighlightedIndexChange?.(0);
57
- arrowDownButtonRef.current?.focus();
58
- }
59
- }, [numResults, onHighlightedIndexChange]);
60
-
61
- const onUpArrowButtonClick = useCallback(() => {
62
- // goto previous result
63
- if (!numResults) {
64
- return;
65
- }
66
- const newHighlightedIndex = highlightedIndex === null || highlightedIndex === undefined || Number.isNaN(highlightedIndex) || highlightedIndex <= 0 ? numResults - 1 : highlightedIndex - 1;
67
-
68
- onHighlightedIndexChange?.(newHighlightedIndex);
69
- }, [numResults, highlightedIndex, onHighlightedIndexChange]);
70
-
71
- const onDownArrowButtonClick = useCallback(() => {
72
- // goto next result
73
- if (!numResults) {
74
- return;
75
- }
76
- const newHighlightedIndex = highlightedIndex === null || highlightedIndex === undefined || Number.isNaN(highlightedIndex) || highlightedIndex >= numResults - 1 ? 0 : highlightedIndex + 1;
77
- onHighlightedIndexChange?.(newHighlightedIndex);
78
- }, [numResults, highlightedIndex, onHighlightedIndexChange]);
79
-
80
- const onGenericKeyDown = useCallback((event: KeyboardEvent<HTMLButtonElement>) => {
81
- // arrow right, focus the next focusable element
82
- if (event.key === 'ArrowRight') {
83
- event.preventDefault();
84
- const nextFocusableElement = event.currentTarget.nextElementSibling as HTMLElement;
85
- if (nextFocusableElement) {
86
- nextFocusableElement.focus();
87
- }
88
- }
89
- // arrow left, focus the previous focusable element
90
- if (event.key === 'ArrowLeft') {
91
- event.preventDefault();
92
- if (event.target === arrowUpButtonRef.current) {
93
- inputRef.current?.focus();
94
- return;
95
- }
96
- const previousFocusableElement = event.currentTarget.previousElementSibling as HTMLElement;
97
- if (previousFocusableElement) {
98
- previousFocusableElement.focus();
99
- }
100
- }
101
- }, []);
102
-
103
- const searchResultStatusText = useMemo(() => {
104
- if (!searchQuery) {
105
- return '';
106
- }
107
- if (searchQuery && (Number.isNaN(numResults) || numResults <= 0)) {
108
- return 'No results';
109
- } else if (highlightedIndex === null || highlightedIndex === undefined || Number.isNaN(highlightedIndex) || highlightedIndex < 0 || !allowNavigation) {
110
- return `${numResults}${truncated ? '+' : ''} results`;
111
- } else if (allowNavigation) {
112
- return `${highlightedIndex + 1}/${numResults}${truncated ? '+' : ''} results`;
113
- }
114
- return '';
115
- }, [searchQuery, numResults, highlightedIndex, allowNavigation, truncated]);
116
-
117
-
118
- return (
119
- <FilledInput
120
- endAdornment={(
121
- <InputAdornment position={'end'}>
122
- {searchResultStatusText && (
123
- <Box
124
- aria-atomic={'true'}
125
- aria-live={'polite'}
126
- role={'status'}
127
- sx={{
128
- fontSize: '1rem',
129
- }}
130
- >
131
- {searchResultStatusText}
132
- </Box>
133
- )}
134
- {numResults > 0 && allowNavigation && (
135
- <>
136
- <IconButton
137
- aria-label={'Goto previous search result'}
138
- disabled={!numResults}
139
- edge={'end'}
140
- onClick={onUpArrowButtonClick}
141
- onKeyDown={onGenericKeyDown}
142
- ref={arrowUpButtonRef}
143
- sx={{ color: theme.palette.primary.main }}
144
- >
145
- <KeyboardArrowUpIcon />
146
- </IconButton>
147
- <IconButton
148
- aria-label={'Goto next search result'}
149
- disabled={!numResults}
150
- edge={'end'}
151
- onClick={onDownArrowButtonClick}
152
- onKeyDown={onGenericKeyDown}
153
- ref={arrowDownButtonRef}
154
- sx={{ color: theme.palette.primary.main }}
155
- >
156
- <KeyboardArrowDownIcon />
157
- </IconButton>
158
- </>
159
- )}
160
- {searchQuery && (
161
- <IconButton
162
- aria-label={'Clear'}
163
- edge={'end'}
164
- onClick={onClearButtonClick}
165
- onKeyDown={onGenericKeyDown}
166
- >
167
- <CloseIcon />
168
- </IconButton>
169
- )}
170
- </InputAdornment>
171
- )}
172
- fullWidth
173
- inputRef={inputRef}
174
- name={'Search'}
175
- onChange={onTextInputChange}
176
- onKeyDown={onTextInputKeyDown}
177
- placeholder={'Search'}
178
- size={'small'}
179
- slotProps={{
180
- input: {
181
- 'aria-label': 'Search',
182
- sx: {
183
- '&::-webkit-search-cancel-button': {
184
- display: 'none',
185
- },
186
- fontSize: '1rem',
187
- height: theme.spacing(4),
188
- outline: 'none !important',
189
- paddingBottom: '0 !important',
190
- paddingTop: '0 !important',
191
- },
192
- },
193
- }}
194
- startAdornment={(
195
- <InputAdornment position={'start'}>
196
- <SearchIcon fontSize={'small'} />
197
- </InputAdornment>
198
- )}
199
- sx={{
200
- backgroundColor: theme.palette.background.paper,
201
- height: theme.spacing(4),
202
- }}
203
- type={'search'}
204
- value={searchQuery}
205
- />
206
- );
207
- };
@@ -1,23 +0,0 @@
1
- import { Chip } from '@mui/material';
2
-
3
- export type SearchBarNodeCounterProps = {
4
- numResults?: number;
5
- };
6
-
7
- export const SearchBarNodeCounter = ({ numResults }: SearchBarNodeCounterProps) => {
8
- if (numResults === undefined || Number.isNaN(numResults)) {
9
- return null;
10
- }
11
-
12
- return (
13
- <Chip
14
- color={numResults > 0 ? 'primary' : 'default'}
15
- label={`${numResults} node${numResults === 1 ? '' : 's'}`}
16
- size={'small'}
17
- sx={{
18
- margin: 0,
19
- padding: 0,
20
- }}
21
- />
22
- );
23
- };
@@ -1,51 +0,0 @@
1
- import {
2
- Box,
3
- Typography,
4
- } from '@mui/material';
5
- import { t } from 'i18next';
6
-
7
- export type ErrorPageCommonProps = {
8
- error: unknown;
9
- };
10
-
11
- export const ErrorPageCommon = ({ error }: ErrorPageCommonProps) => {
12
- return (
13
- <Box
14
- sx={{
15
- alignItems: 'center',
16
- display: 'flex',
17
- flexDirection: 'column',
18
- justifyContent: 'center',
19
- width: '100%',
20
- }}
21
- >
22
- <Box sx={{ padding: 1 }}>
23
- <Typography
24
- variant={'h1'}
25
- >
26
- {t`Something went wrong`}
27
- </Typography>
28
- </Box>
29
- <Box sx={{ padding: 1 }}>
30
- <Typography
31
- variant={'body2'}
32
- >
33
- {error instanceof Error ? error.message : t`An unexpected error occurred.`}
34
- </Typography>
35
- </Box>
36
- <Box sx={{ padding: 1 }}>
37
- <Typography variant={'h6'}>
38
- {t`Details for our technicians`}
39
- </Typography>
40
- <Box
41
- component={'pre'}
42
- sx={{
43
- fontSize: '0.8rem',
44
- }}
45
- >
46
- {(error as Error)?.stack}
47
- </Box>
48
- </Box>
49
- </Box>
50
- );
51
- };
@@ -1,76 +0,0 @@
1
- import {
2
- Box,
3
- useTheme,
4
- } from '@mui/material';
5
- import {
6
- use,
7
- useEffect,
8
- } from 'react';
9
- import type { ReactNode } from 'react';
10
-
11
- import { DRAWER_WIDTH } from '../../constants/page';
12
-
13
- import { PageCommonContext } from './PageCommonContext';
14
-
15
- export type PageCommonProps = {
16
- readonly children: ReactNode;
17
- readonly drawerComponent?: ReactNode;
18
- readonly headerComponent?: ReactNode;
19
- readonly isNoInteraction?: boolean;
20
- };
21
-
22
-
23
- export const PageCommon = ({ children, drawerComponent, headerComponent, isNoInteraction }: PageCommonProps) => {
24
- const theme = useTheme();
25
- const { isDrawerOpen, setIsNoInteraction } = use(PageCommonContext);
26
-
27
- useEffect(() => {
28
- setIsNoInteraction(!!isNoInteraction);
29
- }, [isNoInteraction, setIsNoInteraction]);
30
-
31
- return (
32
- <Box
33
- sx={{
34
- display: 'flex',
35
- flexDirection: 'column',
36
- height: '100vh',
37
- overflow: 'hidden',
38
- position: 'relative',
39
- width: '100vw',
40
- }}
41
- >
42
- {headerComponent}
43
- {/* Main Body */}
44
- <Box
45
- sx={{
46
- display: 'flex',
47
- flex: 1,
48
- height: 'calc(100vh - 56px)',
49
- overflow: 'hidden',
50
- position: 'relative',
51
- width: '100%',
52
- }}
53
- >
54
- {drawerComponent}
55
- <Box
56
- component={'main'}
57
- sx={{
58
- flexGrow: 1,
59
- height: '100%',
60
- overflow: 'hidden',
61
- position: 'relative',
62
- transition: () =>
63
- theme.transitions.create(['margin', 'width'], {
64
- duration: theme.transitions.duration.leavingScreen,
65
- easing: theme.transitions.easing.sharp,
66
- }),
67
- width: isDrawerOpen ? `calc(100% - ${DRAWER_WIDTH}px)` : '100%',
68
- }}
69
- >
70
- {children}
71
- </Box>
72
-
73
- </Box>
74
- </Box>
75
- );
76
- };
@@ -1,15 +0,0 @@
1
- import { createContext } from 'react';
2
-
3
- export type PageCommonContextData = {
4
- readonly isDrawerOpen: boolean;
5
- readonly isNoInteraction: boolean;
6
- readonly setIsDrawerOpen: (open: boolean) => void;
7
- readonly setIsNoInteraction: (open: boolean) => void;
8
- };
9
-
10
- export const PageCommonContext = createContext<PageCommonContextData>({
11
- isDrawerOpen: false,
12
- isNoInteraction: false,
13
- setIsDrawerOpen: () => null,
14
- setIsNoInteraction: () => null,
15
- });
@@ -1,30 +0,0 @@
1
- import {
2
- useMemo,
3
- useState,
4
- } from 'react';
5
- import type { PropsWithChildren } from 'react';
6
-
7
- import type { PageCommonContextData } from './PageCommonContext';
8
- import { PageCommonContext } from './PageCommonContext';
9
-
10
- export type PageCommonContextProviderProps = PropsWithChildren;
11
-
12
- export const PageCommonContextProvider = ({ children }: PageCommonContextProviderProps) => {
13
- const [isDrawerOpen, setIsDrawerOpen] = useState(false);
14
- const [isNoInteraction, setIsNoInteraction] = useState(false);
15
-
16
- const contextValue = useMemo<PageCommonContextData>(() => {
17
- return {
18
- isDrawerOpen,
19
- isNoInteraction,
20
- setIsDrawerOpen,
21
- setIsNoInteraction,
22
- };
23
- }, [isDrawerOpen, isNoInteraction]);
24
-
25
- return (
26
- <PageCommonContext value={contextValue}>
27
- { children }
28
- </PageCommonContext>
29
- );
30
- };
@@ -1,35 +0,0 @@
1
- import { Drawer } from '@mui/material';
2
- import { use } from 'react';
3
- import type { ReactNode } from 'react';
4
-
5
- import { DRAWER_WIDTH } from '../../constants/page';
6
-
7
- import { PageCommonContext } from './PageCommonContext';
8
-
9
- export type PageCommonDrawerProps = {
10
- readonly children: ReactNode;
11
- };
12
-
13
- export const PageCommonDrawer = ({ children }: PageCommonDrawerProps) => {
14
- const { isDrawerOpen } = use(PageCommonContext);
15
-
16
- return (
17
- <Drawer
18
- anchor={'left'}
19
- open={isDrawerOpen}
20
- sx={{
21
- '& .MuiDrawer-paper': {
22
- height: 'calc(100% - 56px)',
23
- overflowY: 'auto',
24
- top: '56px',
25
- width: DRAWER_WIDTH,
26
- },
27
- flexShrink: 0,
28
- width: isDrawerOpen ? DRAWER_WIDTH : 0,
29
- }}
30
- variant={'persistent'}
31
- >
32
- {children}
33
- </Drawer>
34
- );
35
- };
@@ -1,99 +0,0 @@
1
- import type { ReactNode } from 'react';
2
- import {
3
- use,
4
- useCallback,
5
- } from 'react';
6
- import {
7
- AppBar,
8
- Box,
9
- IconButton,
10
- Toolbar,
11
- Typography,
12
- } from '@mui/material';
13
- import MenuIcon from '@mui/icons-material/Menu';
14
-
15
- import { PageCommonContext } from './PageCommonContext';
16
-
17
- export type PageCommonHeaderProps = {
18
- readonly centerComponent?: ReactNode;
19
- readonly icon?: ReactNode;
20
- readonly rightComponent?: ReactNode;
21
- readonly title: string;
22
- };
23
-
24
- export const PageCommonHeader = ({ centerComponent, icon, rightComponent, title }: PageCommonHeaderProps) => {
25
- const { isDrawerOpen, isNoInteraction, setIsDrawerOpen } = use(PageCommonContext);
26
-
27
- const onToggleDrawerButtonClick = useCallback(() => {
28
- setIsDrawerOpen(!isDrawerOpen);
29
- }, [isDrawerOpen, setIsDrawerOpen]);
30
-
31
- return (
32
- <AppBar
33
- elevation={1}
34
- position={'static'}
35
- sx={{
36
- backgroundColor: 'primary.main',
37
- color: '#FFFFFF',
38
- height: 56,
39
- justifyContent: 'center',
40
- zIndex: (theme) => theme.zIndex.drawer + 1,
41
- }}
42
- >
43
- <Toolbar
44
- sx={{ display: 'flex', justifyContent: 'space-between', px: 2 }}
45
- variant={'dense'}
46
- >
47
- {/* Left: Menu toggle and App Branding */}
48
- <Box sx={{ alignItems: 'center', display: 'flex', gap: 1.5 }}>
49
- {!isNoInteraction && (
50
- <IconButton
51
- aria-label={'open drawer'}
52
- color={'inherit'}
53
- edge={'start'}
54
- onClick={onToggleDrawerButtonClick}
55
- size={'small'}
56
- >
57
- <MenuIcon />
58
- </IconButton>
59
- )}
60
- {icon && (
61
- <>
62
- {icon}
63
- </>
64
- )}
65
- <Typography
66
- component={'div'}
67
- noWrap
68
- sx={{ color: 'inherit', fontSize: '1.05rem', fontWeight: 700, letterSpacing: '-0.01em' }}
69
- variant={'h6'}
70
- >
71
- {title}
72
- </Typography>
73
- <Typography
74
- sx={{
75
- backgroundColor: 'rgba(255, 255, 255, 0.15)',
76
- borderRadius: 1,
77
- display: { sm: 'inline-block', xs: 'none' },
78
- fontSize: '0.7rem',
79
- fontWeight: 600,
80
- px: 1,
81
- py: 0.25,
82
- }}
83
- variant={'caption'}
84
- >
85
- {'Loculus Tool'}
86
- </Typography>
87
- </Box>
88
- <Box sx={{ alignItems: 'center', display: 'flex', gap: 1 }}>
89
- {centerComponent}
90
- </Box>
91
- {!isNoInteraction && (
92
- <Box sx={{ alignItems: 'center', display: 'flex', gap: 1 }}>
93
- {rightComponent}
94
- </Box>
95
- )}
96
- </Toolbar>
97
- </AppBar>
98
- );
99
- };
@@ -1 +0,0 @@
1
- export const DRAWER_WIDTH = 340;
package/src/index.ts DELETED
@@ -1,21 +0,0 @@
1
- export * from './classes/services/FastaDataEventBusService';
2
- export * from './components/FastaDataImportDialog';
3
- export * from './components/FastaDataImportDialogLoader';
4
- export * from './components/FastaNotLoaded';
5
- export * from './components/FastaPageHeaderCenterComponent';
6
- export * from './components/FastaPageHeaderImportButton';
7
- export * from './components/FastaPageHeaderResetButton';
8
- export * from './components/I18nWrapper';
9
- export * from './components/page';
10
- export * from './components/PageHeaderDocumentationButton';
11
- export * from './components/SearchBar';
12
- export * from './constants/page';
13
- export * from './models/fasta';
14
- export * from './models/metadata';
15
- export * from './stores/fastaDataStore';
16
- export * from './theme';
17
- export * from './utils/DownloadUtil';
18
- export * from './utils/ErrorUtil';
19
- export * from './utils/FastaUtil';
20
- export * from './utils/MetaDataUtil';
21
- export * from './utils/UrlUtil';
@@ -1,22 +0,0 @@
1
- export enum LOADING_STATUS {
2
- ERROR = 'ERROR',
3
- IDLE = 'IDLE',
4
- LOADING = 'LOADING',
5
- SUCCESS = 'SUCCESS',
6
- }
7
-
8
- export type FastaParseResult = {
9
- error?: string;
10
- expectedLength: number;
11
- invalidSequences?: { id: string; length: number }[];
12
- isAligned: boolean;
13
- sequences: FastaSequence[];
14
- };
15
-
16
- export type FastaSequence = {
17
- accessionVersion: string;
18
- header: string;
19
- id: string;
20
- length: number;
21
- sequence: string;
22
- };
@@ -1,10 +0,0 @@
1
- export interface MetadataParseResult {
2
- columns: string[];
3
- error?: string;
4
- records: MetadataRecord[];
5
- recordsByAccession: Record<string, MetadataRecord>;
6
- recordsByColumn: Record<string, Record<string, MetadataRecord>>;
7
- recordsBySampleId: Record<string, MetadataRecord>;
8
- }
9
-
10
- export type MetadataRecord = Record<string, string>;