@rivm-loculus-tools/common-frontend 0.9.0 → 0.10.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/LoculusService.js +1049 -0
- package/dist/_chunks/LoculusService.js.map +1 -0
- package/dist/_chunks/decorateParam.js +7 -0
- package/dist/_chunks/keycloak-dpop.js +241 -0
- package/dist/_chunks/keycloak-dpop.js.map +1 -0
- package/dist/classes/services/EmotionCacheService/index.js +27 -1
- package/dist/classes/services/EmotionCacheService/index.js.map +1 -0
- package/dist/classes/services/LoculusService/LoculusService.d.ts +26 -0
- package/dist/classes/services/LoculusService/index.d.ts +1 -0
- package/dist/classes/services/LoculusService/index.js +1 -0
- package/dist/classes/services/UrlService/UrlService.d.ts +18 -0
- package/dist/classes/services/UrlService/index.d.ts +1 -0
- package/dist/classes/services/UrlService/index.js +45 -0
- package/dist/classes/services/UrlService/index.js.map +1 -0
- package/dist/components/app/App/App.d.ts +4 -2
- package/dist/components/app/App/index.js +35 -34
- package/dist/components/app/App/index.js.map +1 -1
- package/dist/components/authentication/AuthenticationLoader/AuthenticationLoader.d.ts +3 -0
- package/dist/components/authentication/AuthenticationLoader/index.d.ts +1 -0
- package/dist/components/authentication/AuthenticationLoader/index.js +31 -0
- package/dist/components/authentication/AuthenticationLoader/index.js.map +1 -0
- package/dist/components/fasta/FastaDataImportDialog/FastaDataImportDialog.d.ts +1 -0
- package/dist/components/fasta/FastaDataImportDialog/index.js +77 -77
- package/dist/components/fasta/FastaDataImportDialog/index.js.map +1 -1
- package/dist/components/fasta/FastaDataImportDialogLoader/FastaDataImportDialogLoader.d.ts +2 -1
- package/dist/components/fasta/FastaDataImportDialogLoader/index.js +61 -52
- package/dist/components/fasta/FastaDataImportDialogLoader/index.js.map +1 -1
- package/dist/components/fasta/FastaPageHeaderResetButton/index.js +27 -24
- package/dist/components/fasta/FastaPageHeaderResetButton/index.js.map +1 -1
- package/dist/components/loculus/UploadToLoculusModal/UploadToLoculusModal.d.ts +11 -0
- package/dist/components/loculus/UploadToLoculusModal/index.d.ts +1 -0
- package/dist/components/loculus/UploadToLoculusModal/index.js +159 -0
- package/dist/components/loculus/UploadToLoculusModal/index.js.map +1 -0
- package/dist/components/ui/ButtonWithMenu/ButtonWithMenu.d.ts +1 -0
- package/dist/components/ui/ButtonWithMenu/index.js +5 -4
- package/dist/components/ui/ButtonWithMenu/index.js.map +1 -1
- package/dist/components/ui/PageCommon/index.js +1 -1
- package/dist/components/ui/PageCommon/index.js.map +1 -1
- package/dist/components/ui/SearchBar/index.js +1 -0
- package/dist/components/ui/SearchBar/index.js.map +1 -1
- package/dist/models/url.models.d.ts +9 -0
- package/dist/models/url.models.js +0 -0
- package/dist/utils/MetaDataUtil/MetaDataUtil.d.ts +2 -1
- package/dist/utils/MetaDataUtil/index.js +5 -2
- package/dist/utils/MetaDataUtil/index.js.map +1 -1
- package/dist/utils/UrlUtil/UrlUtil.d.ts +1 -1
- package/dist/utils/UrlUtil/index.js +5 -6
- package/dist/utils/UrlUtil/index.js.map +1 -1
- package/package.json +23 -2
- package/dist/_chunks/EmotionCacheService.js +0 -32
- package/dist/_chunks/EmotionCacheService.js.map +0 -1
|
@@ -1,93 +1,93 @@
|
|
|
1
1
|
import { Alert as e, Box as t, CircularProgress as n, Paper as r, Tab as i, Tabs as a, TextField as o, Typography as s } from "@mui/material";
|
|
2
2
|
import { Fragment as c, jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
3
3
|
import { useCallback as d, useEffect as f, useState as p } from "react";
|
|
4
|
-
import m from "@
|
|
5
|
-
import h from "@mui/icons-material/
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
4
|
+
import { withDialog as m } from "@gen-epix/ui-core-components/hoc/withDialog";
|
|
5
|
+
import h from "@mui/icons-material/Biotech";
|
|
6
|
+
import g from "@mui/icons-material/TableChart";
|
|
7
|
+
import { FileDropZone as _ } from "@gen-epix/ui-core-components/components/FileDropZone";
|
|
8
8
|
// src/components/fasta/FastaDataImportDialog/FastaDataImportDialog.tsx
|
|
9
|
-
var v =
|
|
10
|
-
let [
|
|
9
|
+
var v = m(({ extraActions: m, fastaDescription: v = "Pre-aligned nucleotide or amino-acid sequence data.", onActionsChange: y, onClose: b, onDataChange: x, onDisableBackdropClickChange: S, onError: C, onNoCloseButtonChange: w, openProps: T }) => {
|
|
10
|
+
let [E, D] = p(0), [O, k] = p(null), [A, j] = p(""), [M, N] = p(""), [P, ee] = p(0), [F, I] = p(null), [L, R] = p(""), [z, B] = p(""), [V, H] = p(!1), [U, W] = p(null);
|
|
11
11
|
f(() => {
|
|
12
|
-
|
|
13
|
-
}, [
|
|
14
|
-
|
|
12
|
+
W(T?.initialErrorMessage ?? null);
|
|
13
|
+
}, [T]), f(() => {
|
|
14
|
+
w && w(!!T?.initialErrorMessage), S && S(!!T?.initialErrorMessage);
|
|
15
15
|
}, [
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
S,
|
|
17
|
+
w,
|
|
18
|
+
T?.initialErrorMessage
|
|
19
19
|
]);
|
|
20
|
-
let
|
|
21
|
-
|
|
22
|
-
}, []),
|
|
20
|
+
let G = d(() => W(null), []), K = d((e, t) => {
|
|
21
|
+
D(t);
|
|
22
|
+
}, []), q = d((e, t) => {
|
|
23
23
|
ee(t);
|
|
24
|
-
}, []),
|
|
25
|
-
|
|
26
|
-
}, []), X = d((e) => {
|
|
27
|
-
M(e.target.value);
|
|
24
|
+
}, []), J = d((e) => k(e), []), Y = d((e) => I(e), []), X = d((e) => {
|
|
25
|
+
j(e.target.value);
|
|
28
26
|
}, []), Z = d((e) => {
|
|
29
|
-
|
|
27
|
+
N(e.target.value);
|
|
30
28
|
}, []), Q = d((e) => {
|
|
31
|
-
|
|
29
|
+
R(e.target.value);
|
|
30
|
+
}, []), te = d((e) => {
|
|
31
|
+
B(e.target.value);
|
|
32
32
|
}, []), $ = d(async () => {
|
|
33
|
-
|
|
33
|
+
W(null), H(!0);
|
|
34
34
|
try {
|
|
35
35
|
let e = "";
|
|
36
|
-
if (
|
|
37
|
-
else if (
|
|
38
|
-
let t = await fetch(
|
|
36
|
+
if (E === 0 && O) e = await O[0].text();
|
|
37
|
+
else if (E === 1 && A.trim()) {
|
|
38
|
+
let t = await fetch(A.trim());
|
|
39
39
|
if (!t.ok) throw Error(`Failed to fetch FASTA from URL (${t.status} ${t.statusText})`);
|
|
40
40
|
e = await t.text();
|
|
41
|
-
} else
|
|
41
|
+
} else E === 2 && M.trim() && (e = M.trim());
|
|
42
42
|
if (!e?.trim()) throw Error("Please provide FASTA sequence data via file, URL, or paste.");
|
|
43
43
|
let t = "";
|
|
44
|
-
if (
|
|
45
|
-
else if (
|
|
46
|
-
let e = await fetch(
|
|
44
|
+
if (P === 0 && F) t = await F[0].text();
|
|
45
|
+
else if (P === 1 && L.trim()) {
|
|
46
|
+
let e = await fetch(L.trim());
|
|
47
47
|
if (!e.ok) throw Error(`Failed to fetch Metadata from URL (${e.status} ${e.statusText})`);
|
|
48
48
|
t = await e.text();
|
|
49
|
-
} else
|
|
50
|
-
|
|
49
|
+
} else P === 2 && z.trim() && (t = z.trim());
|
|
50
|
+
x(e, t), b && b();
|
|
51
51
|
} catch (e) {
|
|
52
|
-
console.error("Data import failed:", e),
|
|
52
|
+
console.error("Data import failed:", e), C(e);
|
|
53
53
|
} finally {
|
|
54
|
-
|
|
54
|
+
H(!1);
|
|
55
55
|
}
|
|
56
56
|
}, [
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
O,
|
|
58
|
+
E,
|
|
59
|
+
M,
|
|
60
|
+
A,
|
|
61
|
+
F,
|
|
61
62
|
P,
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
I,
|
|
65
|
-
y,
|
|
63
|
+
z,
|
|
64
|
+
L,
|
|
66
65
|
b,
|
|
67
|
-
|
|
66
|
+
x,
|
|
67
|
+
C
|
|
68
68
|
]);
|
|
69
69
|
return f(() => {
|
|
70
70
|
let e = [{
|
|
71
|
-
disabled:
|
|
72
|
-
label:
|
|
71
|
+
disabled: V,
|
|
72
|
+
label: V ? "Processing..." : "Load & Calculate",
|
|
73
73
|
onClick: $,
|
|
74
|
-
startIcon:
|
|
74
|
+
startIcon: V ? /* @__PURE__ */ l(n, {
|
|
75
75
|
color: "inherit",
|
|
76
76
|
size: 18
|
|
77
77
|
}) : void 0,
|
|
78
78
|
variant: "contained"
|
|
79
79
|
}];
|
|
80
|
-
|
|
80
|
+
m?.length && e.unshift(...m), y && y(e);
|
|
81
81
|
}, [
|
|
82
|
-
|
|
82
|
+
y,
|
|
83
83
|
$,
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
]), /* @__PURE__ */ u(c, { children: [
|
|
87
|
-
onClose:
|
|
84
|
+
V,
|
|
85
|
+
m
|
|
86
|
+
]), /* @__PURE__ */ u(c, { children: [U && /* @__PURE__ */ l(e, {
|
|
87
|
+
onClose: G,
|
|
88
88
|
severity: "error",
|
|
89
89
|
sx: { marginBottom: 2 },
|
|
90
|
-
children:
|
|
90
|
+
children: U
|
|
91
91
|
}), /* @__PURE__ */ u(t, {
|
|
92
92
|
sx: {
|
|
93
93
|
display: "grid",
|
|
@@ -111,7 +111,7 @@ var v = _(({ extraActions: _, onActionsChange: v, onClose: y, onDataChange: b, o
|
|
|
111
111
|
gap: 1,
|
|
112
112
|
mb: 1.5
|
|
113
113
|
},
|
|
114
|
-
children: [/* @__PURE__ */ l(
|
|
114
|
+
children: [/* @__PURE__ */ l(h, { color: "primary" }), /* @__PURE__ */ l(s, {
|
|
115
115
|
sx: { fontWeight: 700 },
|
|
116
116
|
variant: "subtitle1",
|
|
117
117
|
children: "1. FASTA Sequences (required)"
|
|
@@ -124,15 +124,15 @@ var v = _(({ extraActions: _, onActionsChange: v, onClose: y, onDataChange: b, o
|
|
|
124
124
|
mb: 2
|
|
125
125
|
},
|
|
126
126
|
variant: "caption",
|
|
127
|
-
children:
|
|
127
|
+
children: v
|
|
128
128
|
}),
|
|
129
129
|
/* @__PURE__ */ u(a, {
|
|
130
|
-
onChange:
|
|
130
|
+
onChange: K,
|
|
131
131
|
sx: {
|
|
132
132
|
mb: 2,
|
|
133
133
|
minHeight: 36
|
|
134
134
|
},
|
|
135
|
-
value:
|
|
135
|
+
value: E,
|
|
136
136
|
children: [
|
|
137
137
|
/* @__PURE__ */ l(i, {
|
|
138
138
|
label: "File Upload",
|
|
@@ -157,13 +157,13 @@ var v = _(({ extraActions: _, onActionsChange: v, onClose: y, onDataChange: b, o
|
|
|
157
157
|
})
|
|
158
158
|
]
|
|
159
159
|
}),
|
|
160
|
-
|
|
160
|
+
E === 0 && /* @__PURE__ */ l(_, {
|
|
161
161
|
accept: ".fasta,.fa,.fna,.aln",
|
|
162
|
-
files:
|
|
162
|
+
files: O,
|
|
163
163
|
helperText: "Drag & drop .fasta / .fa alignment file",
|
|
164
|
-
onFilesSelected:
|
|
164
|
+
onFilesSelected: J
|
|
165
165
|
}),
|
|
166
|
-
|
|
166
|
+
E === 1 && /* @__PURE__ */ l(t, {
|
|
167
167
|
sx: {
|
|
168
168
|
display: "flex",
|
|
169
169
|
flexDirection: "column",
|
|
@@ -175,23 +175,23 @@ var v = _(({ extraActions: _, onActionsChange: v, onClose: y, onDataChange: b, o
|
|
|
175
175
|
fullWidth: !0,
|
|
176
176
|
helperText: "Enter a publicly accessible URL to a FASTA alignment",
|
|
177
177
|
label: "FASTA URL",
|
|
178
|
-
onChange:
|
|
178
|
+
onChange: X,
|
|
179
179
|
placeholder: "https://example.com/sequences.fasta",
|
|
180
|
-
value:
|
|
180
|
+
value: A,
|
|
181
181
|
variant: "outlined"
|
|
182
182
|
})
|
|
183
183
|
}),
|
|
184
|
-
|
|
184
|
+
E === 2 && /* @__PURE__ */ l(t, {
|
|
185
185
|
sx: { minHeight: 180 },
|
|
186
186
|
children: /* @__PURE__ */ l(o, {
|
|
187
187
|
fullWidth: !0,
|
|
188
188
|
label: "Paste FASTA Content",
|
|
189
189
|
multiline: !0,
|
|
190
|
-
onChange:
|
|
190
|
+
onChange: Z,
|
|
191
191
|
placeholder: ">seq1 ACTG... >seq2 ACTG...",
|
|
192
192
|
rows: 6,
|
|
193
193
|
sx: { fontFamily: "monospace" },
|
|
194
|
-
value:
|
|
194
|
+
value: M,
|
|
195
195
|
variant: "outlined"
|
|
196
196
|
})
|
|
197
197
|
})
|
|
@@ -210,7 +210,7 @@ var v = _(({ extraActions: _, onActionsChange: v, onClose: y, onDataChange: b, o
|
|
|
210
210
|
gap: 1,
|
|
211
211
|
mb: 1.5
|
|
212
212
|
},
|
|
213
|
-
children: [/* @__PURE__ */ l(
|
|
213
|
+
children: [/* @__PURE__ */ l(g, { color: "primary" }), /* @__PURE__ */ l(s, {
|
|
214
214
|
sx: { fontWeight: 700 },
|
|
215
215
|
variant: "subtitle1",
|
|
216
216
|
children: "2. TSV Metadata (optional)"
|
|
@@ -226,12 +226,12 @@ var v = _(({ extraActions: _, onActionsChange: v, onClose: y, onDataChange: b, o
|
|
|
226
226
|
children: "Sample attributes for coloring, search & custom leaf labels."
|
|
227
227
|
}),
|
|
228
228
|
/* @__PURE__ */ u(a, {
|
|
229
|
-
onChange:
|
|
229
|
+
onChange: q,
|
|
230
230
|
sx: {
|
|
231
231
|
mb: 2,
|
|
232
232
|
minHeight: 36
|
|
233
233
|
},
|
|
234
|
-
value:
|
|
234
|
+
value: P,
|
|
235
235
|
children: [
|
|
236
236
|
/* @__PURE__ */ l(i, {
|
|
237
237
|
label: "File Upload",
|
|
@@ -256,13 +256,13 @@ var v = _(({ extraActions: _, onActionsChange: v, onClose: y, onDataChange: b, o
|
|
|
256
256
|
})
|
|
257
257
|
]
|
|
258
258
|
}),
|
|
259
|
-
|
|
259
|
+
P === 0 && /* @__PURE__ */ l(_, {
|
|
260
260
|
accept: ".tsv,.txt,.csv",
|
|
261
|
-
files:
|
|
261
|
+
files: F,
|
|
262
262
|
label: "TSV Metadata File",
|
|
263
|
-
onFilesSelected:
|
|
263
|
+
onFilesSelected: Y
|
|
264
264
|
}),
|
|
265
|
-
|
|
265
|
+
P === 1 && /* @__PURE__ */ l(t, {
|
|
266
266
|
sx: {
|
|
267
267
|
display: "flex",
|
|
268
268
|
flexDirection: "column",
|
|
@@ -274,23 +274,23 @@ var v = _(({ extraActions: _, onActionsChange: v, onClose: y, onDataChange: b, o
|
|
|
274
274
|
fullWidth: !0,
|
|
275
275
|
helperText: "Enter a publicly accessible URL to a TSV metadata file",
|
|
276
276
|
label: "Metadata TSV URL",
|
|
277
|
-
onChange:
|
|
277
|
+
onChange: Q,
|
|
278
278
|
placeholder: "https://example.com/metadata.tsv",
|
|
279
|
-
value:
|
|
279
|
+
value: L,
|
|
280
280
|
variant: "outlined"
|
|
281
281
|
})
|
|
282
282
|
}),
|
|
283
|
-
|
|
283
|
+
P === 2 && /* @__PURE__ */ l(t, {
|
|
284
284
|
sx: { minHeight: 180 },
|
|
285
285
|
children: /* @__PURE__ */ l(o, {
|
|
286
286
|
fullWidth: !0,
|
|
287
287
|
label: "Paste TSV Content",
|
|
288
288
|
multiline: !0,
|
|
289
|
-
onChange:
|
|
289
|
+
onChange: te,
|
|
290
290
|
placeholder: "SampleID	Country	Date Sample1	NL	2024-01-01",
|
|
291
291
|
rows: 6,
|
|
292
292
|
sx: { fontFamily: "monospace" },
|
|
293
|
-
value:
|
|
293
|
+
value: z,
|
|
294
294
|
variant: "outlined"
|
|
295
295
|
})
|
|
296
296
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.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/fasta/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":"index.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","fastaDescription","Tabs","Tab","FileDropZone","TextField"],"sources":["../../../../src/components/fasta/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 fastaDescription?: string;\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 fastaDescription = 'Pre-aligned nucleotide or amino-acid sequence data.',\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 {fastaDescription}\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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"}
|
|
@@ -3,6 +3,7 @@ import { StoreApi } from 'zustand';
|
|
|
3
3
|
import { FastaDataStore } from '../../../stores/fastaDataStore';
|
|
4
4
|
export type FastaDataImportDialogLoaderProps = {
|
|
5
5
|
extraActions?: DialogAction[];
|
|
6
|
+
fastaDescription?: string;
|
|
6
7
|
store: StoreApi<FastaDataStore>;
|
|
7
8
|
};
|
|
8
|
-
export declare const FastaDataImportDialogLoader: ({ extraActions, store }: FastaDataImportDialogLoaderProps) => import('react').JSX.Element;
|
|
9
|
+
export declare const FastaDataImportDialogLoader: ({ extraActions, fastaDescription, store }: FastaDataImportDialogLoaderProps) => import('react').JSX.Element;
|
|
@@ -1,70 +1,79 @@
|
|
|
1
1
|
import { UrlUtil as e } from "../../../utils/UrlUtil/index.js";
|
|
2
2
|
import { ErrorUtil as t } from "../../../utils/ErrorUtil/index.js";
|
|
3
3
|
import { LOADING_STATUS as n } from "../../../models/fasta.models.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
4
|
+
import { t as r } from "../../../_chunks/LoculusService.js";
|
|
5
|
+
import { UrlService as i } from "../../../classes/services/UrlService/index.js";
|
|
6
|
+
import { FastaDataEventBusService as a } from "../../../classes/services/FastaDataEventBusService/index.js";
|
|
7
|
+
import { t as o } from "../../../_chunks/react.js";
|
|
8
|
+
import { FastaDataImportDialog as s } from "../FastaDataImportDialog/index.js";
|
|
9
|
+
import { container as c } from "tsyringe";
|
|
10
|
+
import { Fragment as l, jsx as u } from "react/jsx-runtime";
|
|
11
|
+
import { useCallback as d, useEffect as f, useRef as p } from "react";
|
|
10
12
|
// src/components/fasta/FastaDataImportDialogLoader/FastaDataImportDialogLoader.tsx
|
|
11
|
-
var
|
|
12
|
-
let
|
|
13
|
-
|
|
14
|
-
let e = [
|
|
15
|
-
|
|
16
|
-
}),
|
|
17
|
-
|
|
13
|
+
var m = ({ extraActions: m, fastaDescription: h, store: g }) => {
|
|
14
|
+
let _ = o(g, (e) => e.setData), v = o(g, (e) => e.setLoadingStatus), y = p(null);
|
|
15
|
+
f(() => {
|
|
16
|
+
let e = [c.resolve(a).addEventListener("onShowImportDialog", (e) => {
|
|
17
|
+
y.current?.open(e ? { initialErrorMessage: e } : void 0);
|
|
18
|
+
}), c.resolve(a).addEventListener("onCloseImportDialog", () => {
|
|
19
|
+
y.current?.close();
|
|
18
20
|
})];
|
|
19
21
|
return () => {
|
|
20
22
|
e.forEach((e) => e());
|
|
21
23
|
};
|
|
22
|
-
}, []),
|
|
23
|
-
let
|
|
24
|
+
}, []), f(() => {
|
|
25
|
+
let { inputFastaUrl: t, inputMetadataUrl: r } = i.getParamsFromUrl(window.location.href), o = async () => {
|
|
26
|
+
if (!t || !e.isValidResourceUrl(t)) throw Error("Invalid input-fasta URL.");
|
|
27
|
+
let r = await fetch(t);
|
|
28
|
+
if (!r.ok) throw Error(`FASTA fetch failed (${r.status})`);
|
|
29
|
+
let i = await r.text();
|
|
30
|
+
if (!i.trim()) throw v(n.ERROR), Error("The input-fasta URL returned no sequence data. Check that the URL and requested accession(s) are correct.");
|
|
31
|
+
return i;
|
|
32
|
+
}, s = async () => {
|
|
33
|
+
if (r) try {
|
|
34
|
+
if (!e.isValidResourceUrl(r)) throw Error("Invalid input-metadata URL.");
|
|
35
|
+
let t = await fetch(r);
|
|
36
|
+
return t.ok ? await t.text() : void 0;
|
|
37
|
+
} catch (e) {
|
|
38
|
+
console.warn("[App] Failed to auto-fetch metadata:", e);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
}, l = async () => {
|
|
42
|
+
v(n.LOADING);
|
|
43
|
+
try {
|
|
44
|
+
let e = await o(), t = await s();
|
|
45
|
+
await _(e, t);
|
|
46
|
+
} catch (e) {
|
|
47
|
+
console.error("[App] Failed to auto-load FASTA:", e);
|
|
48
|
+
let t = e instanceof Error ? e.message : "Failed to auto-load FASTA from the provided URL.";
|
|
49
|
+
c.resolve(a).emit("onShowImportDialog", t);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
24
52
|
(async () => {
|
|
25
|
-
|
|
26
|
-
h(n.LOADING);
|
|
27
|
-
try {
|
|
28
|
-
let e = await fetch(t);
|
|
29
|
-
if (!e.ok) throw Error(`FASTA fetch failed (${e.status})`);
|
|
30
|
-
let r = await e.text();
|
|
31
|
-
if (!r.trim()) throw h(n.ERROR), Error("The input-fasta URL returned no sequence data. Check that the URL and requested accession(s) are correct.");
|
|
32
|
-
let a;
|
|
33
|
-
if (i) try {
|
|
34
|
-
let e = await fetch(i);
|
|
35
|
-
e.ok && (a = await e.text());
|
|
36
|
-
} catch (e) {
|
|
37
|
-
console.warn("[App] Failed to auto-fetch metadata:", e);
|
|
38
|
-
}
|
|
39
|
-
await m(r, a);
|
|
40
|
-
} catch (e) {
|
|
41
|
-
console.error("[App] Failed to auto-load FASTA:", e);
|
|
42
|
-
let t = e instanceof Error ? e.message : "Failed to auto-load FASTA from the provided URL.";
|
|
43
|
-
o.resolve(r).emit("onShowImportDialog", t);
|
|
44
|
-
}
|
|
45
|
-
} else o.resolve(r).emit("onShowImportDialog");
|
|
53
|
+
t ? await l() : c.resolve(a).emit("onShowImportDialog");
|
|
46
54
|
})();
|
|
47
|
-
}, [
|
|
48
|
-
let
|
|
49
|
-
|
|
50
|
-
}, []),
|
|
55
|
+
}, [_, v]);
|
|
56
|
+
let b = d((e) => {
|
|
57
|
+
y.current?.close(), c.resolve(a).emit("onShowImportDialog", e);
|
|
58
|
+
}, []), x = d(async (n, i) => {
|
|
51
59
|
try {
|
|
52
|
-
await
|
|
60
|
+
await _(n, i), y.current?.close();
|
|
53
61
|
} catch (e) {
|
|
54
|
-
|
|
62
|
+
b(t.getErrorMessage(e, "Unknown error"));
|
|
55
63
|
} finally {
|
|
56
|
-
e.clearSearchParams();
|
|
64
|
+
e.clearSearchParams(), c.resolve(r).clear();
|
|
57
65
|
}
|
|
58
|
-
}, [
|
|
59
|
-
|
|
60
|
-
}, [
|
|
61
|
-
return /* @__PURE__ */
|
|
62
|
-
extraActions:
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
}, [b, _]), S = d((e) => {
|
|
67
|
+
b(t.getErrorMessage(e, "Unknown error"));
|
|
68
|
+
}, [b]);
|
|
69
|
+
return /* @__PURE__ */ u(l, { children: /* @__PURE__ */ u(s, {
|
|
70
|
+
extraActions: m,
|
|
71
|
+
fastaDescription: h,
|
|
72
|
+
onDataChange: x,
|
|
73
|
+
onError: S,
|
|
74
|
+
ref: y
|
|
66
75
|
}) });
|
|
67
76
|
};
|
|
68
|
-
export {
|
|
77
|
+
export { m as FastaDataImportDialogLoader };
|
|
69
78
|
|
|
70
79
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["_Fragment","useStore","FastaDataImportDialogLoader","setData","store","state","setLoadingStatus","fastaDataImportDialogRef","useRef","useEffect","removers","container","FastaDataEventBusService","initialErrorMessage","remove","
|
|
1
|
+
{"version":3,"file":"index.js","names":["_Fragment","LoculusService","useStore","FastaDataImportDialogLoader","setData","store","state","setLoadingStatus","fastaDataImportDialogRef","useRef","useEffect","removers","container","FastaDataEventBusService","initialErrorMessage","remove","UrlService","fetchFasta","inputFastaUrl","UrlUtil","fastaRes","fastaText","LOADING_STATUS","fetchMetadata","inputMetadataUrl","metaRes","metaErr","loadDeepLinkedData","metaText","fastaErr","message","handleError","useCallback","errorMessage","onDataChange","fastaContent","metadataContent","ErrorUtil","onError","Fragment","FastaDataImportDialog"],"sources":["../../../../src/components/fasta/FastaDataImportDialogLoader/FastaDataImportDialogLoader.tsx"],"sourcesContent":["import { container } from 'tsyringe';\nimport 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 { UrlService } from '../../../classes/services/UrlService';\nimport { LOADING_STATUS } from '../../../models/fasta.models';\nimport type { FastaDataStore } from '../../../stores/fastaDataStore';\nimport { UrlUtil } from '../../../utils/UrlUtil';\nimport type { FastaDataImportDialogRefMethods } from '../FastaDataImportDialog';\nimport { FastaDataImportDialog } from '../FastaDataImportDialog';\nimport { ErrorUtil } from '../../../utils/ErrorUtil';\nimport { LoculusService } from '../../../classes/services/LoculusService';\n\n\nexport type FastaDataImportDialogLoaderProps = {\n extraActions?: DialogAction[];\n fastaDescription?: string;\n store: StoreApi<FastaDataStore>;\n};\n\nexport const FastaDataImportDialogLoader = ({ extraActions, fastaDescription, 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 container.resolve(FastaDataEventBusService).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 container.resolve(FastaDataEventBusService).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 { inputFastaUrl, inputMetadataUrl } = UrlService.getParamsFromUrl(window.location.href);\n\n const fetchFasta = async () => {\n if (!inputFastaUrl || !UrlUtil.isValidResourceUrl(inputFastaUrl)) {\n throw new Error('Invalid input-fasta URL.');\n }\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 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 return fastaText;\n };\n\n const fetchMetadata = async () => {\n if (!inputMetadataUrl) {\n return undefined;\n }\n try {\n if (!UrlUtil.isValidResourceUrl(inputMetadataUrl)) {\n throw new Error('Invalid input-metadata URL.');\n }\n const metaRes = await fetch(inputMetadataUrl);\n return metaRes.ok ? await metaRes.text() : undefined;\n } catch (metaErr) {\n console.warn('[App] Failed to auto-fetch metadata:', metaErr);\n return undefined;\n }\n };\n\n const loadDeepLinkedData = async () => {\n setLoadingStatus(LOADING_STATUS.LOADING);\n try {\n const fastaText = await fetchFasta();\n const metaText = await fetchMetadata();\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 container.resolve(FastaDataEventBusService).emit('onShowImportDialog', message);\n }\n };\n\n const handleDeepLinking = async () => {\n if (inputFastaUrl) {\n await loadDeepLinkedData();\n return;\n }\n // PV1-02: Show data loading modal if no data provided via URL query params\n container.resolve(FastaDataEventBusService).emit('onShowImportDialog');\n };\n\n void handleDeepLinking();\n }, [setData, setLoadingStatus]);\n\n const handleError = useCallback((errorMessage: string) => {\n fastaDataImportDialogRef.current?.close();\n container.resolve(FastaDataEventBusService).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 container.resolve(LoculusService).clear();\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 fastaDescription={fastaDescription}\n onDataChange={onDataChange}\n onError={onError}\n ref={fastaDataImportDialogRef}\n />\n </>\n );\n};\n"],"mappings":"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"}
|