@rivm-loculus-tools/common-frontend 0.2.0 → 0.4.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/EmotionCacheService.js +33 -0
- package/dist/_chunks/EmotionCacheService.js.map +1 -0
- package/dist/_chunks/decorate.js +9 -0
- package/dist/classes/services/EmotionCacheService/EmotionCacheService.d.ts +7 -0
- package/dist/classes/services/EmotionCacheService/index.d.ts +1 -0
- package/dist/classes/services/EmotionCacheService/index.js +1 -0
- package/dist/classes/services/FastaDataEventBusService/FastaDataEventBusService.d.ts +1 -3
- package/dist/classes/services/FastaDataEventBusService/index.js +6 -8
- package/dist/classes/services/FastaDataEventBusService/index.js.map +1 -1
- package/dist/components/app/App/App.d.ts +6 -0
- package/dist/components/app/App/index.d.ts +1 -0
- package/dist/components/app/App/index.js +104 -0
- package/dist/components/app/App/index.js.map +1 -0
- package/dist/{_chunks/FastaDataImportDialog.js → components/fasta/FastaDataImportDialog/index.js} +3 -3
- package/dist/components/fasta/FastaDataImportDialog/index.js.map +1 -0
- package/dist/components/{FastaDataImportDialogLoader → fasta/FastaDataImportDialogLoader}/FastaDataImportDialogLoader.d.ts +2 -2
- package/dist/components/fasta/FastaDataImportDialogLoader/index.js +71 -0
- package/dist/components/fasta/FastaDataImportDialogLoader/index.js.map +1 -0
- package/dist/components/fasta/FastaNotLoaded/index.js +54 -0
- package/dist/components/fasta/FastaNotLoaded/index.js.map +1 -0
- package/dist/components/{FastaPageHeaderCenterComponent → fasta/FastaPageHeaderCenterComponent}/FastaPageHeaderCenterComponent.d.ts +1 -1
- package/dist/components/{FastaPageHeaderCenterComponent → fasta/FastaPageHeaderCenterComponent}/index.js +2 -2
- package/dist/components/fasta/FastaPageHeaderCenterComponent/index.js.map +1 -0
- package/dist/components/fasta/FastaPageHeaderImportButton/index.js +27 -0
- package/dist/components/fasta/FastaPageHeaderImportButton/index.js.map +1 -0
- package/dist/components/{FastaPageHeaderResetButton → fasta/FastaPageHeaderResetButton}/index.js +1 -1
- package/dist/components/fasta/FastaPageHeaderResetButton/index.js.map +1 -0
- package/dist/components/ui/ButtonWithMenu/ButtonWithMenu.d.ts +12 -0
- package/dist/components/ui/ButtonWithMenu/index.d.ts +1 -0
- package/dist/components/ui/ButtonWithMenu/index.js +47 -0
- package/dist/components/ui/ButtonWithMenu/index.js.map +1 -0
- package/dist/components/ui/GenericErrorMessage/GenericErrorMessage.d.ts +4 -0
- package/dist/components/ui/GenericErrorMessage/index.d.ts +1 -0
- package/dist/components/ui/GenericErrorMessage/index.js +44 -0
- package/dist/components/ui/GenericErrorMessage/index.js.map +1 -0
- package/dist/components/ui/I18nWrapper/index.js +21 -0
- package/dist/components/ui/I18nWrapper/index.js.map +1 -0
- package/dist/components/ui/PageCommon/PageCommon.d.ts +7 -0
- package/dist/components/ui/PageCommon/index.d.ts +1 -0
- package/dist/components/ui/PageCommon/index.js +55 -0
- package/dist/components/ui/PageCommon/index.js.map +1 -0
- package/dist/components/ui/PageCommonDrawer/index.d.ts +1 -0
- package/dist/components/ui/PageCommonDrawer/index.js +30 -0
- package/dist/components/ui/PageCommonDrawer/index.js.map +1 -0
- package/dist/components/{page → ui/PageCommonHeader}/PageCommonHeader.d.ts +1 -2
- package/dist/components/ui/PageCommonHeader/index.d.ts +1 -0
- package/dist/components/ui/PageCommonHeader/index.js +107 -0
- package/dist/components/ui/PageCommonHeader/index.js.map +1 -0
- package/dist/constants/config.constants.d.ts +9 -0
- package/dist/constants/config.constants.js +6 -0
- package/dist/constants/config.constants.js.map +1 -0
- package/dist/constants/page.constants.js +6 -0
- package/dist/constants/page.constants.js.map +1 -0
- package/dist/context/commonConfigContext/CommonConfigContext.d.ts +9 -0
- package/dist/context/commonConfigContext/CommonConfigContextProvider.d.ts +6 -0
- package/dist/context/commonConfigContext/index.d.ts +3 -0
- package/dist/context/commonConfigContext/index.js +34 -0
- package/dist/context/commonConfigContext/index.js.map +1 -0
- package/dist/context/commonConfigContext/useCommonConfigContext.d.ts +3 -0
- package/dist/context/pageCommonContext/PageCommonContext.d.ts +17 -0
- package/dist/context/pageCommonContext/PageCommonContextProvider.d.ts +4 -0
- package/dist/context/pageCommonContext/index.d.ts +2 -0
- package/dist/context/pageCommonContext/index.js +26 -0
- package/dist/context/pageCommonContext/index.js.map +1 -0
- package/dist/hooks/useConfig/index.d.ts +1 -0
- package/dist/hooks/useConfig/index.js +7 -0
- package/dist/hooks/useConfig/index.js.map +1 -0
- package/dist/hooks/useConfig/useConfig.d.ts +2 -0
- package/dist/hooks/useUpdateDocumentTitle/index.d.ts +1 -0
- package/dist/hooks/useUpdateDocumentTitle/index.js +13 -0
- package/dist/hooks/useUpdateDocumentTitle/index.js.map +1 -0
- package/dist/hooks/useUpdateDocumentTitle/useUpdateDocumentTitle.d.ts +1 -0
- package/dist/models/config.models.d.ts +16 -0
- package/dist/models/{fasta.js → fasta.models.js} +2 -2
- package/dist/models/fasta.models.js.map +1 -0
- package/dist/models/metadata.models.js +0 -0
- package/dist/pages/ErrorPage/ErrorPage.d.ts +4 -0
- package/dist/pages/ErrorPage/index.d.ts +1 -0
- package/dist/pages/ErrorPage/index.js +17 -0
- package/dist/pages/ErrorPage/index.js.map +1 -0
- package/dist/stores/fastaDataStore/fastaDataStore.d.ts +2 -2
- package/dist/stores/fastaDataStore/index.js +17 -15
- package/dist/stores/fastaDataStore/index.js.map +1 -1
- package/dist/theme/index.js +17 -17
- package/dist/theme/index.js.map +1 -1
- package/dist/utils/DependencyContainerUtil/DependencyContainerUtil.d.ts +6 -0
- package/dist/utils/DependencyContainerUtil/index.d.ts +1 -0
- package/dist/utils/DependencyContainerUtil/index.js +18 -0
- package/dist/utils/DependencyContainerUtil/index.js.map +1 -0
- package/dist/utils/ExportUtil/ExportUtil.d.ts +6 -0
- package/dist/utils/ExportUtil/index.d.ts +1 -0
- package/dist/utils/ExportUtil/index.js +42 -0
- package/dist/utils/ExportUtil/index.js.map +1 -0
- package/dist/utils/FastaUtil/FastaUtil.d.ts +1 -1
- package/dist/utils/FastaUtil/index.js.map +1 -1
- package/dist/utils/MetaDataUtil/MetaDataUtil.d.ts +1 -1
- package/dist/utils/MetaDataUtil/index.js.map +1 -1
- package/dist/utils/StandardConfigUtil/StandardConfigUtil.d.ts +4 -0
- package/dist/utils/StandardConfigUtil/index.d.ts +1 -0
- package/dist/utils/StandardConfigUtil/index.js +18 -0
- package/dist/utils/StandardConfigUtil/index.js.map +1 -0
- package/dist/utils/UrlUtil/index.js +6 -5
- package/dist/utils/UrlUtil/index.js.map +1 -1
- package/package.json +111 -47
- package/dist/_chunks/FastaDataImportDialog.js.map +0 -1
- package/dist/components/FastaDataImportDialog/index.js +0 -1
- package/dist/components/FastaDataImportDialogLoader/index.js +0 -70
- package/dist/components/FastaDataImportDialogLoader/index.js.map +0 -1
- package/dist/components/FastaNotLoaded/index.js +0 -53
- package/dist/components/FastaNotLoaded/index.js.map +0 -1
- package/dist/components/FastaPageHeaderCenterComponent/index.js.map +0 -1
- package/dist/components/FastaPageHeaderImportButton/index.js +0 -26
- package/dist/components/FastaPageHeaderImportButton/index.js.map +0 -1
- package/dist/components/FastaPageHeaderResetButton/index.js.map +0 -1
- package/dist/components/I18nWrapper/index.js +0 -21
- package/dist/components/I18nWrapper/index.js.map +0 -1
- package/dist/components/PageHeaderDocumentationButton/PageHeaderDocumentationButton.d.ts +0 -1
- package/dist/components/PageHeaderDocumentationButton/index.d.ts +0 -1
- package/dist/components/PageHeaderDocumentationButton/index.js +0 -24
- package/dist/components/PageHeaderDocumentationButton/index.js.map +0 -1
- package/dist/components/page/ErrorPageCommon.d.ts +0 -4
- package/dist/components/page/PageCommon.d.ts +0 -8
- package/dist/components/page/PageCommonContext.d.ts +0 -7
- package/dist/components/page/PageCommonContextProvider.d.ts +0 -3
- package/dist/components/page/index.d.ts +0 -6
- package/dist/components/page/index.js +0 -207
- package/dist/components/page/index.js.map +0 -1
- package/dist/constants/page.js +0 -6
- package/dist/constants/page.js.map +0 -1
- package/dist/models/fasta.js.map +0 -1
- /package/dist/components/{FastaDataImportDialog → fasta/FastaDataImportDialog}/FastaDataImportDialog.d.ts +0 -0
- /package/dist/components/{FastaDataImportDialog → fasta/FastaDataImportDialog}/index.d.ts +0 -0
- /package/dist/components/{FastaDataImportDialogLoader → fasta/FastaDataImportDialogLoader}/index.d.ts +0 -0
- /package/dist/components/{FastaNotLoaded → fasta/FastaNotLoaded}/FastaNotLoaded.d.ts +0 -0
- /package/dist/components/{FastaNotLoaded → fasta/FastaNotLoaded}/index.d.ts +0 -0
- /package/dist/components/{FastaPageHeaderCenterComponent → fasta/FastaPageHeaderCenterComponent}/index.d.ts +0 -0
- /package/dist/components/{FastaPageHeaderImportButton → fasta/FastaPageHeaderImportButton}/FastaPageHeaderImportButton.d.ts +0 -0
- /package/dist/components/{FastaPageHeaderImportButton → fasta/FastaPageHeaderImportButton}/index.d.ts +0 -0
- /package/dist/components/{FastaPageHeaderResetButton → fasta/FastaPageHeaderResetButton}/FastaPageHeaderResetButton.d.ts +0 -0
- /package/dist/components/{FastaPageHeaderResetButton → fasta/FastaPageHeaderResetButton}/index.d.ts +0 -0
- /package/dist/components/{I18nWrapper → ui/I18nWrapper}/I18nWrapper.d.ts +0 -0
- /package/dist/components/{I18nWrapper → ui/I18nWrapper}/index.d.ts +0 -0
- /package/dist/components/{page → ui/PageCommonDrawer}/PageCommonDrawer.d.ts +0 -0
- /package/dist/constants/{page.d.ts → page.constants.d.ts} +0 -0
- /package/dist/models/{metadata.js → config.models.js} +0 -0
- /package/dist/models/{fasta.d.ts → fasta.models.d.ts} +0 -0
- /package/dist/models/{metadata.d.ts → metadata.models.d.ts} +0 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { DependencyContainer } from 'tsyringe';
|
|
2
|
+
import { ConfigBase } from '../../models/config.models';
|
|
3
|
+
export declare class DependencyContainerUtil {
|
|
4
|
+
static createContainer(): DependencyContainer;
|
|
5
|
+
static resolveConfig<TConfig extends ConfigBase = ConfigBase>(dependencyContainer?: DependencyContainer): TConfig;
|
|
6
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DependencyContainerUtil';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { CONFIG_TOKEN as e, DEVICE_PIXEL_RATIO_SERVICE_TOKEN as t, KEYBOARD_SHORTCUT_SERVICE_TOKEN as n, WINDOW_SERVICE_TOKEN as r } from "../../constants/config.constants.js";
|
|
2
|
+
import { container as i } from "tsyringe";
|
|
3
|
+
import { WindowService as a } from "@gen-epix/ui-core/classes/services/WindowService";
|
|
4
|
+
import { DevicePixelRatioService as o } from "@gen-epix/ui-core/classes/services/DevicePixelRatioService";
|
|
5
|
+
import { KeyboardShortcutService as s } from "@gen-epix/ui-core/classes/services/KeyboardShortcutService";
|
|
6
|
+
//#region src/utils/DependencyContainerUtil/DependencyContainerUtil.ts
|
|
7
|
+
var c = class {
|
|
8
|
+
static createContainer() {
|
|
9
|
+
return i.registerInstance(r, a.getInstance()), i.registerInstance(t, o.getInstance()), i.registerInstance(n, s.getInstance()), i;
|
|
10
|
+
}
|
|
11
|
+
static resolveConfig(t = i) {
|
|
12
|
+
return t.resolve(e);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
export { c as DependencyContainerUtil };
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["DependencyContainerUtil","container","WINDOW_SERVICE_TOKEN","WindowService","DEVICE_PIXEL_RATIO_SERVICE_TOKEN","DevicePixelRatioService","KEYBOARD_SHORTCUT_SERVICE_TOKEN","KeyboardShortcutService","dependencyContainer","CONFIG_TOKEN"],"sources":["../../../src/utils/DependencyContainerUtil/DependencyContainerUtil.ts"],"sourcesContent":["import { container } from 'tsyringe';\nimport type { DependencyContainer } from 'tsyringe';\nimport { WindowService } from '@gen-epix/ui-core/classes/services/WindowService';\nimport { DevicePixelRatioService } from '@gen-epix/ui-core/classes/services/DevicePixelRatioService';\nimport { KeyboardShortcutService } from '@gen-epix/ui-core/classes/services/KeyboardShortcutService';\n\nimport {\n CONFIG_TOKEN,\n DEVICE_PIXEL_RATIO_SERVICE_TOKEN,\n KEYBOARD_SHORTCUT_SERVICE_TOKEN,\n WINDOW_SERVICE_TOKEN,\n} from '../../constants/config.constants';\nimport type { ConfigBase } from '../../models/config.models';\n\nexport class DependencyContainerUtil {\n public static createContainer(): DependencyContainer {\n container.registerInstance(WINDOW_SERVICE_TOKEN, WindowService.getInstance());\n container.registerInstance(DEVICE_PIXEL_RATIO_SERVICE_TOKEN, DevicePixelRatioService.getInstance());\n container.registerInstance(KEYBOARD_SHORTCUT_SERVICE_TOKEN, KeyboardShortcutService.getInstance());\n\n return container;\n }\n\n public static resolveConfig<TConfig extends ConfigBase = ConfigBase>(dependencyContainer: DependencyContainer = container): TConfig {\n return dependencyContainer.resolve(CONFIG_TOKEN) as TConfig;\n }\n}\n"],"mappings":";;;;;;AAcA,IAAaA,IAAb,MAAqC;CACnC,OAAc,kBAAuC;EAKnD,OAJAC,EAAU,iBAAiBC,GAAsBC,EAAc,YAAY,CAAC,GAC5EF,EAAU,iBAAiBG,GAAkCC,EAAwB,YAAY,CAAC,GAClGJ,EAAU,iBAAiBK,GAAiCC,EAAwB,YAAY,CAAC,GAE1FN;CACT;CAEA,OAAc,cAAuD,IAA2CA,GAAoB;EAClI,OAAOO,EAAoB,QAAQC,CAAY;CACjD;AACF"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare class ExportUtil {
|
|
2
|
+
static downloadCanvasAsImage(canvas: HTMLCanvasElement | null, format: 'jpeg' | 'png', filename?: string): void;
|
|
3
|
+
static downloadCanvasAsSvg(canvas: HTMLCanvasElement | null, filename?: string): void;
|
|
4
|
+
static downloadFastaFile(fasta: string, filename?: string): void;
|
|
5
|
+
static downloadNewickFile(newick: string, filename?: string): void;
|
|
6
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ExportUtil';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { DownloadUtil as e } from "@gen-epix/ui-core/utils/DownloadUtil";
|
|
2
|
+
//#region src/utils/ExportUtil/ExportUtil.ts
|
|
3
|
+
var t = class {
|
|
4
|
+
static downloadCanvasAsImage(t, n, r = "phylogenetic_tree") {
|
|
5
|
+
if (!t) {
|
|
6
|
+
console.error("No canvas available for export.");
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
let i = n === "jpeg" ? "image/jpeg" : "image/png", a = n === "jpeg" ? "jpg" : "png", o = t;
|
|
10
|
+
if (n === "jpeg") {
|
|
11
|
+
o = document.createElement("canvas"), o.width = t.width, o.height = t.height;
|
|
12
|
+
let e = o.getContext("2d");
|
|
13
|
+
e && (e.fillStyle = "#FFFFFF", e.fillRect(0, 0, o.width, o.height), e.drawImage(t, 0, 0));
|
|
14
|
+
}
|
|
15
|
+
let s = o.toDataURL(i, .95);
|
|
16
|
+
e.createDownloadUrl(s, `${r}.${a}`);
|
|
17
|
+
}
|
|
18
|
+
static downloadCanvasAsSvg(t, n = "phylogenetic_tree.svg") {
|
|
19
|
+
if (!t) {
|
|
20
|
+
console.error("No canvas available for export.");
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
let r = t.toDataURL("image/png"), i = t.width, a = t.height, o = `<?xml version="1.0" standalone="no"?>
|
|
24
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
25
|
+
<svg width="${i}" height="${a}" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
26
|
+
<image xlink:href="${r}" x="0" y="0" height="${a}" width="${i}" />
|
|
27
|
+
</svg>`, s = new Blob([o], { type: "image/svg+xml;charset=utf-8" }), c = URL.createObjectURL(s);
|
|
28
|
+
e.createDownloadUrl(c, n), URL.revokeObjectURL(c);
|
|
29
|
+
}
|
|
30
|
+
static downloadFastaFile(t, n = "sequence.fasta") {
|
|
31
|
+
let r = new Blob([t], { type: "text/plain;charset=utf-8" }), i = URL.createObjectURL(r);
|
|
32
|
+
e.createDownloadUrl(i, n), URL.revokeObjectURL(i);
|
|
33
|
+
}
|
|
34
|
+
static downloadNewickFile(t, n = "phylogenetic_tree.nwk") {
|
|
35
|
+
let r = new Blob([t], { type: "text/plain;charset=utf-8" }), i = URL.createObjectURL(r);
|
|
36
|
+
e.createDownloadUrl(i, n), URL.revokeObjectURL(i);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
//#endregion
|
|
40
|
+
export { t as ExportUtil };
|
|
41
|
+
|
|
42
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["ExportUtil","canvas","mimeType","format","extension","exportCanvas","ctx","dataUrl","filename","imgData","width","height","svgContent","blob","url","DownloadUtil","fasta","newick"],"sources":["../../../src/utils/ExportUtil/ExportUtil.ts"],"sourcesContent":["import { DownloadUtil } from '@gen-epix/ui-core/utils/DownloadUtil';\n\nexport class ExportUtil {\n public static downloadCanvasAsImage(\n canvas: HTMLCanvasElement | null,\n format: 'jpeg' | 'png',\n filename = 'phylogenetic_tree',\n ): void {\n if (!canvas) {\n console.error('No canvas available for export.');\n return;\n }\n\n const mimeType = format === 'jpeg' ? 'image/jpeg' : 'image/png';\n const extension = format === 'jpeg' ? 'jpg' : 'png';\n\n let exportCanvas = canvas;\n if (format === 'jpeg') {\n exportCanvas = document.createElement('canvas');\n exportCanvas.width = canvas.width;\n exportCanvas.height = canvas.height;\n const ctx = exportCanvas.getContext('2d');\n if (ctx) {\n ctx.fillStyle = '#FFFFFF';\n ctx.fillRect(0, 0, exportCanvas.width, exportCanvas.height);\n ctx.drawImage(canvas, 0, 0);\n }\n }\n\n const dataUrl = exportCanvas.toDataURL(mimeType, 0.95);\n DownloadUtil.createDownloadUrl(dataUrl, `${filename}.${extension}`);\n }\n\n public static downloadCanvasAsSvg(\n canvas: HTMLCanvasElement | null,\n filename = 'phylogenetic_tree.svg',\n ): void {\n if (!canvas) {\n console.error('No canvas available for export.');\n return;\n }\n\n const imgData = canvas.toDataURL('image/png');\n const width = canvas.width;\n const height = canvas.height;\n\n const svgContent = `<?xml version=\"1.0\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg width=\"${width}\" height=\"${height}\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n <image xlink:href=\"${imgData}\" x=\"0\" y=\"0\" height=\"${height}\" width=\"${width}\" />\n</svg>`;\n\n const blob = new Blob([svgContent], { type: 'image/svg+xml;charset=utf-8' });\n const url = URL.createObjectURL(blob);\n DownloadUtil.createDownloadUrl(url, filename);\n URL.revokeObjectURL(url);\n }\n\n public static downloadFastaFile(fasta: string, filename = 'sequence.fasta'): void {\n const blob = new Blob([fasta], { type: 'text/plain;charset=utf-8' });\n const url = URL.createObjectURL(blob);\n DownloadUtil.createDownloadUrl(url, filename);\n URL.revokeObjectURL(url);\n }\n\n public static downloadNewickFile(newick: string, filename = 'phylogenetic_tree.nwk'): void {\n const blob = new Blob([newick], { type: 'text/plain;charset=utf-8' });\n const url = URL.createObjectURL(blob);\n DownloadUtil.createDownloadUrl(url, filename);\n URL.revokeObjectURL(url);\n }\n}\n"],"mappings":";;AAEA,IAAaA,IAAb,MAAwB;CACtB,OAAc,sBACZ,GACA,GACA,IAAW,qBACL;EACN,IAAI,CAACC,GAAQ;GACX,QAAQ,MAAM,iCAAiC;GAC/C;EACF;EAEA,IAAMC,IAAWC,MAAW,SAAS,eAAe,aAC9CC,IAAYD,MAAW,SAAS,QAAQ,OAE1CE,IAAeJ;EACnB,IAAIE,MAAW,QAAQ;GAGrB,AAFA,IAAe,SAAS,cAAc,QAAQ,GAC9C,EAAa,QAAQF,EAAO,OAC5B,EAAa,SAASA,EAAO;GAC7B,IAAMK,IAAMD,EAAa,WAAW,IAAI;GACxC,AAAIC,MACF,EAAI,YAAY,WAChBA,EAAI,SAAS,GAAG,GAAGD,EAAa,OAAOA,EAAa,MAAM,GAC1DC,EAAI,UAAUL,GAAQ,GAAG,CAAC;EAE9B;EAEA,IAAMM,IAAUF,EAAa,UAAUH,GAAU,GAAI;EACrD,EAAa,kBAAkBK,GAAS,GAAGC,EAAS,GAAGJ,GAAW;CACpE;CAEA,OAAc,oBACZ,GACA,IAAW,yBACL;EACN,IAAI,CAACH,GAAQ;GACX,QAAQ,MAAM,iCAAiC;GAC/C;EACF;EAEA,IAAMQ,IAAUR,EAAO,UAAU,WAAW,GACtCS,IAAQT,EAAO,OACfU,IAASV,EAAO,QAEhBW,IAAa;;cAETF,EAAM,YAAYC,EAAO;uBAChBF,EAAQ,wBAAwBE,EAAO,WAAWD,EAAM;SAGrEG,IAAO,IAAI,KAAK,CAACD,CAAU,GAAG,EAAE,MAAM,8BAA8B,CAAC,GACrEE,IAAM,IAAI,gBAAgBD,CAAI;EAEpC,AADAE,EAAa,kBAAkBD,GAAKN,CAAQ,GAC5C,IAAI,gBAAgBM,CAAG;CACzB;CAEA,OAAc,kBAAkB,GAAe,IAAW,kBAAwB;EAChF,IAAMD,IAAO,IAAI,KAAK,CAACG,CAAK,GAAG,EAAE,MAAM,2BAA2B,CAAC,GAC7DF,IAAM,IAAI,gBAAgBD,CAAI;EAEpC,AADAE,EAAa,kBAAkBD,GAAKN,CAAQ,GAC5C,IAAI,gBAAgBM,CAAG;CACzB;CAEA,OAAc,mBAAmB,GAAgB,IAAW,yBAA+B;EACzF,IAAMD,IAAO,IAAI,KAAK,CAACI,CAAM,GAAG,EAAE,MAAM,2BAA2B,CAAC,GAC9DH,IAAM,IAAI,gBAAgBD,CAAI;EAEpC,AADAE,EAAa,kBAAkBD,GAAKN,CAAQ,GAC5C,IAAI,gBAAgBM,CAAG;CACzB;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["FastaUtil","content","lines","sequences","currentHeader","currentSeqParts","commitSequence","fullSeq","safeId","sourceLine","line","firstLength","invalidSequences","s","isAligned","fastaContent"],"sources":["../../../src/utils/FastaUtil/FastaUtil.ts"],"sourcesContent":["import type {\n FastaParseResult,\n FastaSequence,\n} from '../../models/fasta';\n\nexport class FastaUtil {\n public static parseFasta(content: string): FastaParseResult {\n if (!content?.trim()) {\n return FastaUtil.createErrorResult('The FASTA input is empty.');\n }\n\n const lines = content.split(/\\r?\\n/);\n const sequences: FastaSequence[] = [];\n let currentHeader = '';\n let currentSeqParts: string[] = [];\n\n const commitSequence = (): void => {\n if (currentHeader) {\n const fullSeq = currentSeqParts.join('').replace(/\\s/g, '').toUpperCase();\n\n // Empty records (a header with no following sequence) are retained with\n // a length of zero rather than being discarded or rejected.\n\n // Extract ID: part before pipe or tab, sanitized for Newick compatibility\n const firstPart = currentHeader.split(/[|\\t]/)[0].trim();\n const safeId = firstPart.replace(/[():;,']/g, '_');\n\n sequences.push({\n accessionVersion: safeId,\n header: currentHeader,\n id: safeId,\n length: fullSeq.length,\n sequence: fullSeq,\n });\n }\n };\n\n for (const sourceLine of lines) {\n const line = sourceLine.trim();\n if (!line) {\n continue;\n }\n\n if (line.startsWith('>')) {\n commitSequence();\n currentHeader = line.slice(1).trim();\n if (!currentHeader) {\n return FastaUtil.createErrorResult('Every FASTA record needs a non-empty header.');\n }\n currentSeqParts = [];\n } else {\n if (!currentHeader) {\n return FastaUtil.createErrorResult('FASTA sequence data appeared before its first header.');\n }\n currentSeqParts.push(line);\n }\n }\n commitSequence();\n\n if (sequences.length === 0) {\n return FastaUtil.createErrorResult('No FASTA records were found.');\n }\n\n // Pre-alignment validation: verify all sequence lengths are equal\n const firstLength = sequences[0].length;\n const invalidSequences = sequences.filter((s) => s.length !== firstLength).map((s) => ({ id: s.id, length: s.length }));\n\n const isAligned = invalidSequences.length === 0;\n\n return {\n expectedLength: firstLength,\n invalidSequences: isAligned ? undefined : invalidSequences,\n isAligned,\n sequences,\n };\n }\n\n public static stripFastaHeaders(fastaContent: string): string {\n const lines = fastaContent.split('\\n');\n const strippedLines = lines.map((line) => {\n if (line.startsWith('>')) {\n const cleanHeader = line.substring(1).trim();\n const firstPart = cleanHeader.split(/[|\\t]/)[0].trim();\n const safeId = firstPart.replace(/[():;,']/g, '_');\n return `>${safeId}`;\n }\n return line;\n });\n return strippedLines.join('\\n');\n }\n\n\n private static createErrorResult(error: string): FastaParseResult {\n return {\n error,\n expectedLength: 0,\n isAligned: false,\n sequences: [],\n };\n }\n\n}\n"],"mappings":";AAKA,IAAaA,IAAb,MAAaA,EAAU;CACrB,OAAc,WAAW,GAAmC;EAC1D,IAAI,CAACC,GAAS,KAAK,GACjB,OAAOD,EAAU,kBAAkB,2BAA2B;EAGhE,IAAME,IAAQD,EAAQ,MAAM,OAAO,GAC7BE,IAA6B,CAAC,GAChCC,IAAgB,IAChBC,IAA4B,CAAC,GAE3BC,UAA6B;GACjC,IAAIF,GAAe;IACjB,IAAMG,IAAUF,EAAgB,KAAK,EAAE,CAAC,CAAC,QAAQ,OAAO,EAAE,CAAC,CAAC,YAAY,GAOlEG,IADYJ,EAAc,MAAM,OAAO,CAAC,CAAC,EAAE,CAAC,KACnC,CAAA,CAAU,QAAQ,aAAa,GAAG;IAEjD,EAAU,KAAK;KACb,kBAAkBI;KAClB,QAAQJ;KACR,IAAII;KACJ,QAAQD,EAAQ;KAChB,UAAUA;IACZ,CAAC;GACH;EACF;EAEA,KAAK,IAAME,KAAcP,GAAO;GAC9B,IAAMQ,IAAOD,EAAW,KAAK;GAC7B,IAAKC,GAIL;QAAIA,EAAK,WAAW,GAAG,GAAG;KAGxB,IAFAJ,EAAe,GACf,IAAgBI,EAAK,MAAM,CAAC,CAAC,CAAC,KAAK,GAC/B,CAACN,GACH,OAAOJ,EAAU,kBAAkB,8CAA8C;KAEnF,IAAkB,CAAC;IACrB,OAAO;KACL,IAAI,CAACI,GACH,OAAOJ,EAAU,kBAAkB,uDAAuD;KAE5F,EAAgB,KAAKU,CAAI;IAC3B;;EACF;EAGA,IAFAJ,EAAe,GAEXH,EAAU,WAAW,GACvB,OAAOH,EAAU,kBAAkB,8BAA8B;EAInE,IAAMW,IAAcR,EAAU,EAAE,CAAC,QAC3BS,IAAmBT,EAAU,QAAQ,MAAMU,EAAE,WAAWF,CAAW,CAAC,CAAC,KAAK,OAAO;GAAE,IAAIE,EAAE;GAAI,QAAQA,EAAE;EAAO,EAAE,GAEhHC,IAAYF,EAAiB,WAAW;EAE9C,OAAO;GACL,gBAAgBD;GAChB,kBAAkBG,IAAY,KAAA,IAAYF;GAC1C;GACA;EACF;CACF;CAEA,OAAc,kBAAkB,GAA8B;EAW5D,OAVcG,EAAa,MAAM,IACX,CAAA,CAAM,KAAK,MAC3BL,EAAK,WAAW,GAAG,IAId,IAHaA,EAAK,UAAU,CAAC,CAAC,CAAC,KACpB,CAAA,CAAY,MAAM,OAAO,CAAC,CAAC,EAAE,CAAC,KACjC,CAAA,CAAU,QAAQ,aAAa,GACnC,MAENA,CAEF,CAAA,CAAc,KAAK,IAAI;CAChC;CAGA,OAAe,kBAAkB,GAAiC;EAChE,OAAO;GACL;GACA,gBAAgB;GAChB,WAAW;GACX,WAAW,CAAC;EACd;CACF;AAEF"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["FastaUtil","content","lines","sequences","currentHeader","currentSeqParts","commitSequence","fullSeq","safeId","sourceLine","line","firstLength","invalidSequences","s","isAligned","fastaContent"],"sources":["../../../src/utils/FastaUtil/FastaUtil.ts"],"sourcesContent":["import type {\n FastaParseResult,\n FastaSequence,\n} from '../../models/fasta.models';\n\nexport class FastaUtil {\n public static parseFasta(content: string): FastaParseResult {\n if (!content?.trim()) {\n return FastaUtil.createErrorResult('The FASTA input is empty.');\n }\n\n const lines = content.split(/\\r?\\n/);\n const sequences: FastaSequence[] = [];\n let currentHeader = '';\n let currentSeqParts: string[] = [];\n\n const commitSequence = (): void => {\n if (currentHeader) {\n const fullSeq = currentSeqParts.join('').replace(/\\s/g, '').toUpperCase();\n\n // Empty records (a header with no following sequence) are retained with\n // a length of zero rather than being discarded or rejected.\n\n // Extract ID: part before pipe or tab, sanitized for Newick compatibility\n const firstPart = currentHeader.split(/[|\\t]/)[0].trim();\n const safeId = firstPart.replace(/[():;,']/g, '_');\n\n sequences.push({\n accessionVersion: safeId,\n header: currentHeader,\n id: safeId,\n length: fullSeq.length,\n sequence: fullSeq,\n });\n }\n };\n\n for (const sourceLine of lines) {\n const line = sourceLine.trim();\n if (!line) {\n continue;\n }\n\n if (line.startsWith('>')) {\n commitSequence();\n currentHeader = line.slice(1).trim();\n if (!currentHeader) {\n return FastaUtil.createErrorResult('Every FASTA record needs a non-empty header.');\n }\n currentSeqParts = [];\n } else {\n if (!currentHeader) {\n return FastaUtil.createErrorResult('FASTA sequence data appeared before its first header.');\n }\n currentSeqParts.push(line);\n }\n }\n commitSequence();\n\n if (sequences.length === 0) {\n return FastaUtil.createErrorResult('No FASTA records were found.');\n }\n\n // Pre-alignment validation: verify all sequence lengths are equal\n const firstLength = sequences[0].length;\n const invalidSequences = sequences.filter((s) => s.length !== firstLength).map((s) => ({ id: s.id, length: s.length }));\n\n const isAligned = invalidSequences.length === 0;\n\n return {\n expectedLength: firstLength,\n invalidSequences: isAligned ? undefined : invalidSequences,\n isAligned,\n sequences,\n };\n }\n\n public static stripFastaHeaders(fastaContent: string): string {\n const lines = fastaContent.split('\\n');\n const strippedLines = lines.map((line) => {\n if (line.startsWith('>')) {\n const cleanHeader = line.substring(1).trim();\n const firstPart = cleanHeader.split(/[|\\t]/)[0].trim();\n const safeId = firstPart.replace(/[():;,']/g, '_');\n return `>${safeId}`;\n }\n return line;\n });\n return strippedLines.join('\\n');\n }\n\n\n private static createErrorResult(error: string): FastaParseResult {\n return {\n error,\n expectedLength: 0,\n isAligned: false,\n sequences: [],\n };\n }\n\n}\n"],"mappings":";AAKA,IAAaA,IAAb,MAAaA,EAAU;CACrB,OAAc,WAAW,GAAmC;EAC1D,IAAI,CAACC,GAAS,KAAK,GACjB,OAAOD,EAAU,kBAAkB,2BAA2B;EAGhE,IAAME,IAAQD,EAAQ,MAAM,OAAO,GAC7BE,IAA6B,CAAC,GAChCC,IAAgB,IAChBC,IAA4B,CAAC,GAE3BC,UAA6B;GACjC,IAAIF,GAAe;IACjB,IAAMG,IAAUF,EAAgB,KAAK,EAAE,CAAC,CAAC,QAAQ,OAAO,EAAE,CAAC,CAAC,YAAY,GAOlEG,IADYJ,EAAc,MAAM,OAAO,CAAC,CAAC,EAAE,CAAC,KACnC,CAAA,CAAU,QAAQ,aAAa,GAAG;IAEjD,EAAU,KAAK;KACb,kBAAkBI;KAClB,QAAQJ;KACR,IAAII;KACJ,QAAQD,EAAQ;KAChB,UAAUA;IACZ,CAAC;GACH;EACF;EAEA,KAAK,IAAME,KAAcP,GAAO;GAC9B,IAAMQ,IAAOD,EAAW,KAAK;GAC7B,IAAKC,GAIL;QAAIA,EAAK,WAAW,GAAG,GAAG;KAGxB,IAFAJ,EAAe,GACf,IAAgBI,EAAK,MAAM,CAAC,CAAC,CAAC,KAAK,GAC/B,CAACN,GACH,OAAOJ,EAAU,kBAAkB,8CAA8C;KAEnF,IAAkB,CAAC;IACrB,OAAO;KACL,IAAI,CAACI,GACH,OAAOJ,EAAU,kBAAkB,uDAAuD;KAE5F,EAAgB,KAAKU,CAAI;IAC3B;;EACF;EAGA,IAFAJ,EAAe,GAEXH,EAAU,WAAW,GACvB,OAAOH,EAAU,kBAAkB,8BAA8B;EAInE,IAAMW,IAAcR,EAAU,EAAE,CAAC,QAC3BS,IAAmBT,EAAU,QAAQ,MAAMU,EAAE,WAAWF,CAAW,CAAC,CAAC,KAAK,OAAO;GAAE,IAAIE,EAAE;GAAI,QAAQA,EAAE;EAAO,EAAE,GAEhHC,IAAYF,EAAiB,WAAW;EAE9C,OAAO;GACL,gBAAgBD;GAChB,kBAAkBG,IAAY,KAAA,IAAYF;GAC1C;GACA;EACF;CACF;CAEA,OAAc,kBAAkB,GAA8B;EAW5D,OAVcG,EAAa,MAAM,IACX,CAAA,CAAM,KAAK,MAC3BL,EAAK,WAAW,GAAG,IAId,IAHaA,EAAK,UAAU,CAAC,CAAC,CAAC,KACpB,CAAA,CAAY,MAAM,OAAO,CAAC,CAAC,EAAE,CAAC,KACjC,CAAA,CAAU,QAAQ,aAAa,GACnC,MAENA,CAEF,CAAA,CAAc,KAAK,IAAI;CAChC;CAGA,OAAe,kBAAkB,GAAiC;EAChE,OAAO;GACL;GACA,gBAAgB;GAChB,WAAW;GACX,WAAW,CAAC;EACd;CACF;AAEF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MetadataParseResult, MetadataRecord } from '../../models/metadata';
|
|
1
|
+
import { MetadataParseResult, MetadataRecord } from '../../models/metadata.models';
|
|
2
2
|
export declare class MetaDataUtil {
|
|
3
3
|
/**
|
|
4
4
|
* Compute the best matching metadata column for the given FASTA sequence IDs.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["MetaDataUtil","matchCounts","columns","recordsByColumn","fastaIds","bestColumn","maxMatches","prioritizedKeys","col","count","currentPriority","newPriority","pKey","found","c","trimmed","query","matched","allAccessions","acc","metadataRecords","matchKeyField","rec","val","colDict","id","metadata","sampleId","\"displayName\"","\"accessionVersion\"","match","content","lines","headerLine","delimiter","records","recordsByAccession","recordsBySampleId","i","line","values","record","colIdx","accessionKey","sampleIdKey"],"sources":["../../../src/utils/MetaDataUtil/MetaDataUtil.ts"],"sourcesContent":["import type {\n MetadataParseResult,\n MetadataRecord,\n} from '../../models/metadata';\n\nexport class MetaDataUtil {\n /**\n * Compute the best matching metadata column for the given FASTA sequence IDs.\n */\n public static findBestMatchingColumn = (\n columns: string[],\n recordsByColumn: Record<string, Record<string, MetadataRecord>>,\n fastaIds: string[],\n ): { bestColumn: null | string; matchCounts: Record<string, number> } => {\n const matchCounts = MetaDataUtil.getMatchCounts(columns, recordsByColumn, fastaIds);\n let bestColumn: null | string = null;\n let maxMatches = -1;\n\n if (!columns || !recordsByColumn || !fastaIds || fastaIds.length === 0) {\n return { bestColumn: null, matchCounts: {} };\n }\n\n const prioritizedKeys = [\n 'displayname',\n 'accessionversion',\n 'accession',\n 'sampleid',\n 'sample_id',\n 'id',\n 'strain',\n 'isolate',\n 'submissionid',\n 'name',\n ];\n\n for (const col of columns) {\n const colDict = recordsByColumn[col];\n if (!colDict) {\n continue;\n }\n\n const count = matchCounts[col];\n\n if (count > maxMatches) {\n maxMatches = count;\n bestColumn = col;\n } else if (count === maxMatches && count > 0 && bestColumn) {\n // Tie-breaker: prioritize standard ID column names\n const currentPriority = prioritizedKeys.indexOf(bestColumn.toLowerCase());\n const newPriority = prioritizedKeys.indexOf(col.toLowerCase());\n if (newPriority !== -1 && (currentPriority === -1 || newPriority < currentPriority)) {\n bestColumn = col;\n }\n }\n }\n\n if (maxMatches <= 0) {\n // If no matches, default to highest priority known ID column if available\n for (const pKey of prioritizedKeys) {\n const found = columns.find((c) => c.toLowerCase() === pKey);\n if (found) {\n bestColumn = found;\n break;\n }\n }\n if (!bestColumn && columns.length > 0) {\n bestColumn = columns[0];\n }\n }\n\n return { bestColumn, matchCounts };\n };\n\n public static getHighlightedIds(query: string, allAccessions: string[], metadataRecords: MetadataRecord[], matchKeyField: null | string = null): string[] {\n const trimmed = query.trim().toLowerCase();\n if (!trimmed) {\n return [];\n }\n\n const matched = new Set<string>();\n\n // Check accession names / fasta IDs\n allAccessions.forEach((acc) => {\n if (acc.toLowerCase().includes(trimmed)) {\n matched.add(acc);\n }\n });\n\n // Check metadata records\n metadataRecords.forEach((rec) => {\n const acc =\n (matchKeyField && rec[matchKeyField]) ||\n rec.displayName ||\n rec.accessionVersion ||\n rec.accession ||\n rec.id ||\n rec.submissionId ||\n rec.SampleID;\n if (acc) {\n const matchesAnyField = Object.values(rec).some(\n (val) => typeof val === 'string' && val.toLowerCase().includes(trimmed),\n );\n if (matchesAnyField) {\n matched.add(acc);\n }\n }\n });\n\n return Array.from(matched);\n }\n /**\n * Count FASTA sequence ID matches for each metadata column.\n */\n public static getMatchCounts = (\n columns: string[],\n recordsByColumn: Record<string, Record<string, MetadataRecord>>,\n fastaIds: string[],\n ): Record<string, number> => {\n const matchCounts: Record<string, number> = {};\n\n if (!columns || !recordsByColumn || !fastaIds || fastaIds.length === 0) {\n return matchCounts;\n }\n\n for (const col of columns) {\n const colDict = recordsByColumn[col];\n if (!colDict) {\n continue;\n }\n\n let count = 0;\n for (const id of fastaIds) {\n if (colDict[id]) {\n count++;\n }\n }\n matchCounts[col] = count;\n }\n\n return matchCounts;\n };\n\n /**\n * Retrieve metadata record for a given sample/node name with fallback strategies.\n */\n public static readonly getRecordForSample = (\n metadata: MetadataParseResult | null | undefined,\n sampleId: string,\n matchKeyField?: null | string,\n ): MetadataRecord | undefined => {\n if (!metadata || !sampleId) {\n return undefined;\n }\n\n // 1. If matchKeyField is specified and exists, check it first\n if (matchKeyField && metadata.recordsByColumn?.[matchKeyField]) {\n const rec = metadata.recordsByColumn[matchKeyField][sampleId];\n if (rec) {\n return rec;\n }\n }\n\n // 2. Check displayName\n if (metadata.recordsByColumn?.['displayName']?.[sampleId]) {\n return metadata.recordsByColumn['displayName'][sampleId];\n }\n\n // 3. Check accessionVersion\n if (metadata.recordsByColumn?.['accessionVersion']?.[sampleId]) {\n return metadata.recordsByColumn['accessionVersion'][sampleId];\n }\n\n // 4. Check accession maps\n if (metadata.recordsByAccession[sampleId]) {\n return metadata.recordsByAccession[sampleId];\n }\n if (metadata.recordsBySampleId[sampleId]) {\n return metadata.recordsBySampleId[sampleId];\n }\n\n // 5. Broad search through all indexed columns\n if (metadata.recordsByColumn) {\n for (const col of Object.keys(metadata.recordsByColumn)) {\n const match = metadata.recordsByColumn[col][sampleId];\n if (match) {\n return match;\n }\n }\n }\n\n return undefined;\n };\n\n public static parseTsv = (content: string): MetadataParseResult => {\n if (!content?.trim()) {\n return {\n columns: [],\n error: 'Empty metadata content provided.',\n records: [],\n recordsByAccession: {},\n recordsByColumn: {},\n recordsBySampleId: {},\n };\n }\n\n const lines = content.trim().split('\\n');\n if (lines.length < 2) {\n return {\n columns: [],\n error: 'Metadata file must contain at least a header row and one data row.',\n records: [],\n recordsByAccession: {},\n recordsByColumn: {},\n recordsBySampleId: {},\n };\n }\n\n // Parse header row\n const headerLine = lines[0].trim();\n let delimiter = '\\t';\n if (!headerLine.includes('\\t') && headerLine.includes(',')) {\n delimiter = ',';\n }\n const columns = headerLine\n .split(delimiter)\n .map((col) => col.trim().replace(/^[\"']|[\"']$/g, ''))\n .filter((c) => c.length > 0);\n\n const records: MetadataRecord[] = [];\n const recordsByAccession: Record<string, MetadataRecord> = {};\n const recordsBySampleId: Record<string, MetadataRecord> = {};\n const recordsByColumn: Record<string, Record<string, MetadataRecord>> = {};\n\n columns.forEach((col) => {\n recordsByColumn[col] = {};\n });\n\n for (let i = 1; i < lines.length; i++) {\n const line = lines[i].trim();\n if (!line) {\n continue;\n }\n\n const values = line.split(delimiter).map((val) => val.trim().replace(/^[\"']|[\"']$/g, ''));\n const record: MetadataRecord = {};\n\n columns.forEach((col, colIdx) => {\n const val = values[colIdx] ?? '';\n record[col] = val;\n if (val) {\n recordsByColumn[col][val] = record;\n }\n });\n\n records.push(record);\n\n // Index by potential ID keys\n const accessionKey =\n record.displayName ||\n record.accessionVersion ||\n record.accession ||\n record.id ||\n record.submissionId ||\n record.strain ||\n record.isolate ||\n record.name;\n\n if (accessionKey) {\n recordsByAccession[accessionKey] = record;\n }\n\n const sampleIdKey =\n record.SampleID ||\n record.sampleId ||\n record.sample_id ||\n record.specimenCollectorSampleId ||\n record.id;\n\n if (sampleIdKey) {\n recordsBySampleId[sampleIdKey] = record;\n }\n }\n\n return {\n columns,\n records,\n recordsByAccession,\n recordsByColumn,\n recordsBySampleId,\n };\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["MetaDataUtil","matchCounts","columns","recordsByColumn","fastaIds","bestColumn","maxMatches","prioritizedKeys","col","count","currentPriority","newPriority","pKey","found","c","trimmed","query","matched","allAccessions","acc","metadataRecords","matchKeyField","rec","val","colDict","id","metadata","sampleId","\"displayName\"","\"accessionVersion\"","match","content","lines","headerLine","delimiter","records","recordsByAccession","recordsBySampleId","i","line","values","record","colIdx","accessionKey","sampleIdKey"],"sources":["../../../src/utils/MetaDataUtil/MetaDataUtil.ts"],"sourcesContent":["import type {\n MetadataParseResult,\n MetadataRecord,\n} from '../../models/metadata.models';\n\nexport class MetaDataUtil {\n /**\n * Compute the best matching metadata column for the given FASTA sequence IDs.\n */\n public static findBestMatchingColumn = (\n columns: string[],\n recordsByColumn: Record<string, Record<string, MetadataRecord>>,\n fastaIds: string[],\n ): { bestColumn: null | string; matchCounts: Record<string, number> } => {\n const matchCounts = MetaDataUtil.getMatchCounts(columns, recordsByColumn, fastaIds);\n let bestColumn: null | string = null;\n let maxMatches = -1;\n\n if (!columns || !recordsByColumn || !fastaIds || fastaIds.length === 0) {\n return { bestColumn: null, matchCounts: {} };\n }\n\n const prioritizedKeys = [\n 'displayname',\n 'accessionversion',\n 'accession',\n 'sampleid',\n 'sample_id',\n 'id',\n 'strain',\n 'isolate',\n 'submissionid',\n 'name',\n ];\n\n for (const col of columns) {\n const colDict = recordsByColumn[col];\n if (!colDict) {\n continue;\n }\n\n const count = matchCounts[col];\n\n if (count > maxMatches) {\n maxMatches = count;\n bestColumn = col;\n } else if (count === maxMatches && count > 0 && bestColumn) {\n // Tie-breaker: prioritize standard ID column names\n const currentPriority = prioritizedKeys.indexOf(bestColumn.toLowerCase());\n const newPriority = prioritizedKeys.indexOf(col.toLowerCase());\n if (newPriority !== -1 && (currentPriority === -1 || newPriority < currentPriority)) {\n bestColumn = col;\n }\n }\n }\n\n if (maxMatches <= 0) {\n // If no matches, default to highest priority known ID column if available\n for (const pKey of prioritizedKeys) {\n const found = columns.find((c) => c.toLowerCase() === pKey);\n if (found) {\n bestColumn = found;\n break;\n }\n }\n if (!bestColumn && columns.length > 0) {\n bestColumn = columns[0];\n }\n }\n\n return { bestColumn, matchCounts };\n };\n\n public static getHighlightedIds(query: string, allAccessions: string[], metadataRecords: MetadataRecord[], matchKeyField: null | string = null): string[] {\n const trimmed = query.trim().toLowerCase();\n if (!trimmed) {\n return [];\n }\n\n const matched = new Set<string>();\n\n // Check accession names / fasta IDs\n allAccessions.forEach((acc) => {\n if (acc.toLowerCase().includes(trimmed)) {\n matched.add(acc);\n }\n });\n\n // Check metadata records\n metadataRecords.forEach((rec) => {\n const acc =\n (matchKeyField && rec[matchKeyField]) ||\n rec.displayName ||\n rec.accessionVersion ||\n rec.accession ||\n rec.id ||\n rec.submissionId ||\n rec.SampleID;\n if (acc) {\n const matchesAnyField = Object.values(rec).some(\n (val) => typeof val === 'string' && val.toLowerCase().includes(trimmed),\n );\n if (matchesAnyField) {\n matched.add(acc);\n }\n }\n });\n\n return Array.from(matched);\n }\n /**\n * Count FASTA sequence ID matches for each metadata column.\n */\n public static getMatchCounts = (\n columns: string[],\n recordsByColumn: Record<string, Record<string, MetadataRecord>>,\n fastaIds: string[],\n ): Record<string, number> => {\n const matchCounts: Record<string, number> = {};\n\n if (!columns || !recordsByColumn || !fastaIds || fastaIds.length === 0) {\n return matchCounts;\n }\n\n for (const col of columns) {\n const colDict = recordsByColumn[col];\n if (!colDict) {\n continue;\n }\n\n let count = 0;\n for (const id of fastaIds) {\n if (colDict[id]) {\n count++;\n }\n }\n matchCounts[col] = count;\n }\n\n return matchCounts;\n };\n\n /**\n * Retrieve metadata record for a given sample/node name with fallback strategies.\n */\n public static readonly getRecordForSample = (\n metadata: MetadataParseResult | null | undefined,\n sampleId: string,\n matchKeyField?: null | string,\n ): MetadataRecord | undefined => {\n if (!metadata || !sampleId) {\n return undefined;\n }\n\n // 1. If matchKeyField is specified and exists, check it first\n if (matchKeyField && metadata.recordsByColumn?.[matchKeyField]) {\n const rec = metadata.recordsByColumn[matchKeyField][sampleId];\n if (rec) {\n return rec;\n }\n }\n\n // 2. Check displayName\n if (metadata.recordsByColumn?.['displayName']?.[sampleId]) {\n return metadata.recordsByColumn['displayName'][sampleId];\n }\n\n // 3. Check accessionVersion\n if (metadata.recordsByColumn?.['accessionVersion']?.[sampleId]) {\n return metadata.recordsByColumn['accessionVersion'][sampleId];\n }\n\n // 4. Check accession maps\n if (metadata.recordsByAccession[sampleId]) {\n return metadata.recordsByAccession[sampleId];\n }\n if (metadata.recordsBySampleId[sampleId]) {\n return metadata.recordsBySampleId[sampleId];\n }\n\n // 5. Broad search through all indexed columns\n if (metadata.recordsByColumn) {\n for (const col of Object.keys(metadata.recordsByColumn)) {\n const match = metadata.recordsByColumn[col][sampleId];\n if (match) {\n return match;\n }\n }\n }\n\n return undefined;\n };\n\n public static parseTsv = (content: string): MetadataParseResult => {\n if (!content?.trim()) {\n return {\n columns: [],\n error: 'Empty metadata content provided.',\n records: [],\n recordsByAccession: {},\n recordsByColumn: {},\n recordsBySampleId: {},\n };\n }\n\n const lines = content.trim().split('\\n');\n if (lines.length < 2) {\n return {\n columns: [],\n error: 'Metadata file must contain at least a header row and one data row.',\n records: [],\n recordsByAccession: {},\n recordsByColumn: {},\n recordsBySampleId: {},\n };\n }\n\n // Parse header row\n const headerLine = lines[0].trim();\n let delimiter = '\\t';\n if (!headerLine.includes('\\t') && headerLine.includes(',')) {\n delimiter = ',';\n }\n const columns = headerLine\n .split(delimiter)\n .map((col) => col.trim().replace(/^[\"']|[\"']$/g, ''))\n .filter((c) => c.length > 0);\n\n const records: MetadataRecord[] = [];\n const recordsByAccession: Record<string, MetadataRecord> = {};\n const recordsBySampleId: Record<string, MetadataRecord> = {};\n const recordsByColumn: Record<string, Record<string, MetadataRecord>> = {};\n\n columns.forEach((col) => {\n recordsByColumn[col] = {};\n });\n\n for (let i = 1; i < lines.length; i++) {\n const line = lines[i].trim();\n if (!line) {\n continue;\n }\n\n const values = line.split(delimiter).map((val) => val.trim().replace(/^[\"']|[\"']$/g, ''));\n const record: MetadataRecord = {};\n\n columns.forEach((col, colIdx) => {\n const val = values[colIdx] ?? '';\n record[col] = val;\n if (val) {\n recordsByColumn[col][val] = record;\n }\n });\n\n records.push(record);\n\n // Index by potential ID keys\n const accessionKey =\n record.displayName ||\n record.accessionVersion ||\n record.accession ||\n record.id ||\n record.submissionId ||\n record.strain ||\n record.isolate ||\n record.name;\n\n if (accessionKey) {\n recordsByAccession[accessionKey] = record;\n }\n\n const sampleIdKey =\n record.SampleID ||\n record.sampleId ||\n record.sample_id ||\n record.specimenCollectorSampleId ||\n record.id;\n\n if (sampleIdKey) {\n recordsBySampleId[sampleIdKey] = record;\n }\n }\n\n return {\n columns,\n records,\n recordsByAccession,\n recordsByColumn,\n recordsBySampleId,\n };\n };\n}\n"],"mappings":";AAKA,IAAaA,IAAb,MAAaA,EAAa;CAIxB,OAAc,0BACZ,GACA,GACA,MACuE;EACvE,IAAMC,IAAcD,EAAa,eAAeE,GAASC,GAAiBC,CAAQ,GAC9EC,IAA4B,MAC5BC,IAAa;EAEjB,IAAI,CAACJ,KAAW,CAACC,KAAmB,CAACC,KAAYA,EAAS,WAAW,GACnE,OAAO;GAAE,YAAY;GAAM,aAAa,CAAC;EAAE;EAG7C,IAAMG,IAAkB;GACtB;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EAEA,KAAK,IAAMC,KAAON,GAAS;GAEzB,IAAI,CADYC,EAAgBK,IAE9B;GAGF,IAAMC,IAAQR,EAAYO;GAE1B,IAAIC,IAAQH,GAEV,AADA,IAAaG,GACb,IAAaD;QACR,IAAIC,MAAUH,KAAcG,IAAQ,KAAKJ,GAAY;IAE1D,IAAMK,IAAkBH,EAAgB,QAAQF,EAAW,YAAY,CAAC,GAClEM,IAAcJ,EAAgB,QAAQC,EAAI,YAAY,CAAC;IAC7D,AAAIG,MAAgB,OAAOD,MAAoB,MAAMC,IAAcD,OACjE,IAAaF;GAEjB;EACF;EAEA,IAAIF,KAAc,GAAG;GAEnB,KAAK,IAAMM,KAAQL,GAAiB;IAClC,IAAMM,IAAQX,EAAQ,MAAM,MAAMY,EAAE,YAAY,MAAMF,CAAI;IAC1D,IAAIC,GAAO;KACT,IAAaA;KACb;IACF;GACF;GACA,AAAI,CAACR,KAAcH,EAAQ,SAAS,MAClC,IAAaA,EAAQ;EAEzB;EAEA,OAAO;GAAE;GAAY;EAAY;CACnC;CAEA,OAAc,kBAAkB,GAAe,GAAyB,GAAmC,IAA+B,MAAgB;EACxJ,IAAMa,IAAUC,EAAM,KAAK,CAAC,CAAC,YAAY;EACzC,IAAI,CAACD,GACH,OAAO,CAAC;EAGV,IAAME,oBAAU,IAAI,IAAY;EA6BhC,OA1BAC,EAAc,SAAS,MAAQ;GAC7B,AAAIC,EAAI,YAAY,CAAC,CAAC,SAASJ,CAAO,KACpCE,EAAQ,IAAIE,CAAG;EAEnB,CAAC,GAGDC,EAAgB,SAAS,MAAQ;GAC/B,IAAMD,IACHE,KAAiBC,EAAID,MACtBC,EAAI,eACJA,EAAI,oBACJA,EAAI,aACJA,EAAI,MACJA,EAAI,gBACJA,EAAI;GACN,AAAIH,KACsB,OAAO,OAAOG,CAAG,CAAC,CAAC,MACxC,MAAQ,OAAOC,KAAQ,YAAYA,EAAI,YAAY,CAAC,CAAC,SAASR,CAAO,CAEpE,KACFE,EAAQ,IAAIE,CAAG;EAGrB,CAAC,GAEM,MAAM,KAAKF,CAAO;CAC3B;CAIA,OAAc,kBACZ,GACA,GACA,MAC2B;EAC3B,IAAMhB,IAAsC,CAAC;EAE7C,IAAI,CAACC,KAAW,CAACC,KAAmB,CAACC,KAAYA,EAAS,WAAW,GACnE,OAAOH;EAGT,KAAK,IAAMO,KAAON,GAAS;GACzB,IAAMsB,IAAUrB,EAAgBK;GAChC,IAAI,CAACgB,GACH;GAGF,IAAIf,IAAQ;GACZ,KAAK,IAAMgB,KAAMrB,GACf,AAAIoB,EAAQC,MACV;GAGJ,EAAYjB,KAAOC;EACrB;EAEA,OAAOR;CACT;CAKA,OAAuB,sBACrB,GACA,GACA,MAC+B;EAC/B,IAAKyB,KAAaC,GAKlB;OAAIN,KAAiBK,EAAS,kBAAkBL,IAAgB;IAC9D,IAAMC,IAAMI,EAAS,gBAAgBL,EAAc,CAACM;IACpD,IAAIL,GACF,OAAOA;GAEX;GAGA,IAAII,EAAS,iBAAkBE,cAAiBD,IAC9C,OAAOD,EAAS,gBAAgBE,YAAeD;GAIjD,IAAID,EAAS,iBAAkBG,mBAAsBF,IACnD,OAAOD,EAAS,gBAAgBG,iBAAoBF;GAItD,IAAID,EAAS,mBAAmBC,IAC9B,OAAOD,EAAS,mBAAmBC;GAErC,IAAID,EAAS,kBAAkBC,IAC7B,OAAOD,EAAS,kBAAkBC;GAIpC,IAAID,EAAS,iBACX,KAAK,IAAMlB,KAAO,OAAO,KAAKkB,EAAS,eAAe,GAAG;IACvD,IAAMI,IAAQJ,EAAS,gBAAgBlB,EAAI,CAACmB;IAC5C,IAAIG,GACF,OAAOA;GAEX;EA3BF;CA+BF;CAEA,OAAc,YAAY,MAAyC;EACjE,IAAI,CAACC,GAAS,KAAK,GACjB,OAAO;GACL,SAAS,CAAC;GACV,OAAO;GACP,SAAS,CAAC;GACV,oBAAoB,CAAC;GACrB,iBAAiB,CAAC;GAClB,mBAAmB,CAAC;EACtB;EAGF,IAAMC,IAAQD,EAAQ,KAAK,CAAC,CAAC,MAAM,IAAI;EACvC,IAAIC,EAAM,SAAS,GACjB,OAAO;GACL,SAAS,CAAC;GACV,OAAO;GACP,SAAS,CAAC;GACV,oBAAoB,CAAC;GACrB,iBAAiB,CAAC;GAClB,mBAAmB,CAAC;EACtB;EAIF,IAAMC,IAAaD,EAAM,EAAE,CAAC,KAAK,GAC7BE,IAAY;EAChB,AAAI,CAACD,EAAW,SAAS,GAAI,KAAKA,EAAW,SAAS,GAAG,MACvD,IAAY;EAEd,IAAM/B,IAAU+B,EACb,MAAMC,CAAS,CAAC,CAChB,KAAK,MAAQ1B,EAAI,KAAK,CAAC,CAAC,QAAQ,gBAAgB,EAAE,CAAC,CAAC,CACpD,QAAQ,MAAMM,EAAE,SAAS,CAAC,GAEvBqB,IAA4B,CAAC,GAC7BC,IAAqD,CAAC,GACtDC,IAAoD,CAAC,GACrDlC,IAAkE,CAAC;EAEzE,EAAQ,SAAS,MAAQ;GACvB,EAAgBK,KAAO,CAAC;EAC1B,CAAC;EAED,KAAK,IAAI8B,IAAI,GAAGA,IAAIN,EAAM,QAAQ,KAAK;GACrC,IAAMO,IAAOP,EAAMM,EAAE,CAAC,KAAK;GAC3B,IAAI,CAACC,GACH;GAGF,IAAMC,IAASD,EAAK,MAAML,CAAS,CAAC,CAAC,KAAK,MAAQX,EAAI,KAAK,CAAC,CAAC,QAAQ,gBAAgB,EAAE,CAAC,GAClFkB,IAAyB,CAAC;GAUhC,AARAvC,EAAQ,SAAS,GAAK,MAAW;IAC/B,IAAMqB,IAAMiB,EAAOE,MAAW;IAE9B,AADA,EAAOlC,KAAOe,GACVA,MACF,EAAgBf,EAAI,CAACe,KAAOkB;GAEhC,CAAC,GAEDN,EAAQ,KAAKM,CAAM;GAGnB,IAAME,IACJF,EAAO,eACPA,EAAO,oBACPA,EAAO,aACPA,EAAO,MACPA,EAAO,gBACPA,EAAO,UACPA,EAAO,WACPA,EAAO;GAET,AAAIE,MACF,EAAmBA,KAAgBF;GAGrC,IAAMG,IACJH,EAAO,YACPA,EAAO,YACPA,EAAO,aACPA,EAAO,6BACPA,EAAO;GAET,AAAIG,MACF,EAAkBA,KAAeH;EAErC;EAEA,OAAO;GACL;GACA;GACA;GACA;GACA;EACF;CACF;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './StandardConfigUtil';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { WindowService as e } from "@gen-epix/ui-core/classes/services/WindowService";
|
|
2
|
+
//#region src/utils/StandardConfigUtil/StandardConfigUtil.ts
|
|
3
|
+
var t = class {
|
|
4
|
+
static createConfig() {
|
|
5
|
+
return {
|
|
6
|
+
nonce: e.getInstance().document.querySelector("meta[name=\"csp-nonce\"]")?.getAttribute("content") ?? void 0,
|
|
7
|
+
pageConfig: { appBarHeight: 48 },
|
|
8
|
+
spinner: {
|
|
9
|
+
DEFAULT_CIRCULAR_PROGRESS_SIZE: 40,
|
|
10
|
+
DEFAULT_TAKING_LONGER_TIMEOUT_MS: 5e3
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
export { t as StandardConfigUtil };
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["StandardConfigUtil","WindowService"],"sources":["../../../src/utils/StandardConfigUtil/StandardConfigUtil.ts"],"sourcesContent":["import { WindowService } from '@gen-epix/ui-core/classes/services/WindowService';\n\nimport type { ConfigBase } from '../../models/config.models';\n\nexport class StandardConfigUtil {\n public static createConfig(): Pick<ConfigBase, 'nonce' | 'pageConfig' | 'spinner'> {\n return {\n nonce: WindowService.getInstance().document.querySelector('meta[name=\"csp-nonce\"]')?.getAttribute('content') ?? undefined,\n pageConfig: {\n appBarHeight: 48,\n },\n spinner: {\n DEFAULT_CIRCULAR_PROGRESS_SIZE: 40,\n DEFAULT_TAKING_LONGER_TIMEOUT_MS: 5000,\n },\n };\n }\n}\n"],"mappings":";;AAIA,IAAaA,IAAb,MAAgC;CAC9B,OAAc,eAAqE;EACjF,OAAO;GACL,OAAOC,EAAc,YAAY,CAAC,CAAC,SAAS,cAAc,0BAAwB,CAAC,EAAE,aAAa,SAAS,KAAK,KAAA;GAChH,YAAY,EACV,cAAc,GAChB;GACA,SAAS;IACP,gCAAgC;IAChC,kCAAkC;GACpC;EACF;CACF;AACF"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { WINDOW_SERVICE_TOKEN as e } from "../../constants/config.constants.js";
|
|
2
|
+
import { container as t } from "tsyringe";
|
|
2
3
|
//#region src/utils/UrlUtil/UrlUtil.ts
|
|
3
|
-
var
|
|
4
|
+
var n = class {
|
|
4
5
|
static clearSearchParams() {
|
|
5
|
-
let
|
|
6
|
-
|
|
6
|
+
let n = new URL(t.resolve(e).window.location.href);
|
|
7
|
+
n.search = "", t.resolve(e).window.history.replaceState(null, "", n.toString());
|
|
7
8
|
}
|
|
8
9
|
static fastaLabelFromUrl(e) {
|
|
9
10
|
try {
|
|
@@ -25,6 +26,6 @@ var t = class {
|
|
|
25
26
|
}
|
|
26
27
|
};
|
|
27
28
|
//#endregion
|
|
28
|
-
export {
|
|
29
|
+
export { n as UrlUtil };
|
|
29
30
|
|
|
30
31
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["UrlUtil","url","
|
|
1
|
+
{"version":3,"file":"index.js","names":["UrlUtil","url","container","WINDOW_SERVICE_TOKEN","urlObject","segment"],"sources":["../../../src/utils/UrlUtil/UrlUtil.ts"],"sourcesContent":["import { container } from 'tsyringe';\nimport type { WindowService } from '@gen-epix/ui-core/classes/services/WindowService';\n\nimport { WINDOW_SERVICE_TOKEN } from '../../constants/config.constants';\n\nexport class UrlUtil {\n public static clearSearchParams(): void {\n const url = new URL(container.resolve<WindowService>(WINDOW_SERVICE_TOKEN).window.location.href);\n url.search = '';\n container.resolve<WindowService>(WINDOW_SERVICE_TOKEN).window.history.replaceState(null, '', url.toString());\n }\n\n public static fastaLabelFromUrl(url: string): string {\n try {\n const urlObject = new URL(url);\n const segment = urlObject.pathname.split('/').filter(Boolean).pop();\n if (segment) {\n return decodeURIComponent(segment);\n }\n return `${urlObject.hostname}.fasta`;\n } catch {\n return 'remote-alignment.fasta';\n }\n }\n\n public static validateFastaUrl(url: string): string {\n let urlObject: URL;\n try {\n urlObject = new URL(url.trim());\n } catch {\n throw new Error('Enter a valid FASTA URL.');\n }\n if (urlObject.protocol !== 'http:' && urlObject.protocol !== 'https:') {\n throw new Error('FASTA URLs must use HTTP or HTTPS.');\n }\n return urlObject.href;\n }\n}\n"],"mappings":";;;AAKA,IAAaA,IAAb,MAAqB;CACnB,OAAc,oBAA0B;EACtC,IAAMC,IAAM,IAAI,IAAIC,EAAU,QAAuBC,CAAoB,CAAC,CAAC,OAAO,SAAS,IAAI;EAE/F,AADA,EAAI,SAAS,IACbD,EAAU,QAAuBC,CAAoB,CAAC,CAAC,OAAO,QAAQ,aAAa,MAAM,IAAIF,EAAI,SAAS,CAAC;CAC7G;CAEA,OAAc,kBAAkB,GAAqB;EACnD,IAAI;GACF,IAAMG,IAAY,IAAI,IAAIH,CAAG,GACvBI,IAAUD,EAAU,SAAS,MAAM,GAAG,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,IAAI;GAIlE,OAHIC,IACK,mBAAmBA,CAAO,IAE5B,GAAGD,EAAU,SAAS;EAC/B,QAAQ;GACN,OAAO;EACT;CACF;CAEA,OAAc,iBAAiB,GAAqB;EAClD,IAAIA;EACJ,IAAI;GACF,IAAY,IAAI,IAAIH,EAAI,KAAK,CAAC;EAChC,QAAQ;GACN,MAAU,MAAM,0BAA0B;EAC5C;EACA,IAAIG,EAAU,aAAa,WAAWA,EAAU,aAAa,UAC3D,MAAU,MAAM,oCAAoC;EAEtD,OAAOA,EAAU;CACnB;AACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rivm-loculus-tools/common-frontend",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"license": "EUPL-1.2",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
"@emotion/cache": "*",
|
|
12
12
|
"@emotion/react": "*",
|
|
13
13
|
"@emotion/styled": "*",
|
|
14
|
-
"@gen-epix/ui-core-components": "^4.
|
|
15
|
-
"@gen-epix/ui-core-form": "^4.4.
|
|
16
|
-
"@gen-epix/ui-core": "^3.9.
|
|
14
|
+
"@gen-epix/ui-core-components": "^4.5.0",
|
|
15
|
+
"@gen-epix/ui-core-form": "^4.4.1",
|
|
16
|
+
"@gen-epix/ui-core": "^3.9.1",
|
|
17
17
|
"@mui/icons-material": "*",
|
|
18
18
|
"@mui/material": "*",
|
|
19
19
|
"@mui/styled-engine": "*",
|
|
@@ -23,7 +23,9 @@
|
|
|
23
23
|
"react-dom": "*",
|
|
24
24
|
"react-hook-form": "*",
|
|
25
25
|
"react-i18next": "*",
|
|
26
|
-
"react": "*"
|
|
26
|
+
"react": "*",
|
|
27
|
+
"reflect-metadata": "*",
|
|
28
|
+
"tsyringe": "*"
|
|
27
29
|
},
|
|
28
30
|
"dependencies": {
|
|
29
31
|
"lodash": "4.18.1",
|
|
@@ -34,9 +36,9 @@
|
|
|
34
36
|
"@emotion/react": "11.14.0",
|
|
35
37
|
"@emotion/styled": "11.14.1",
|
|
36
38
|
"@gen-epix/eslint-config": "0.8.0",
|
|
37
|
-
"@gen-epix/ui-core-components": "4.
|
|
38
|
-
"@gen-epix/ui-core-form": "4.4.
|
|
39
|
-
"@gen-epix/ui-core": "3.9.
|
|
39
|
+
"@gen-epix/ui-core-components": "4.5.0",
|
|
40
|
+
"@gen-epix/ui-core-form": "4.4.1",
|
|
41
|
+
"@gen-epix/ui-core": "3.9.1",
|
|
40
42
|
"@mui/icons-material": "9.5.0",
|
|
41
43
|
"@mui/material": "9.5.0",
|
|
42
44
|
"@mui/styled-engine": "9.5.0",
|
|
@@ -54,6 +56,8 @@
|
|
|
54
56
|
"react-hook-form": "7.90.0",
|
|
55
57
|
"react-i18next": "17.0.16",
|
|
56
58
|
"react": "19.3.0",
|
|
59
|
+
"reflect-metadata": "0.2.2",
|
|
60
|
+
"tsyringe": "4.10.0",
|
|
57
61
|
"typescript": "6.0.3",
|
|
58
62
|
"vite-plugin-dts": "5.1.2",
|
|
59
63
|
"vite-plugin-static-copy": "4.1.1",
|
|
@@ -63,61 +67,109 @@
|
|
|
63
67
|
"dist"
|
|
64
68
|
],
|
|
65
69
|
"exports": {
|
|
70
|
+
"./classes/services/EmotionCacheService": {
|
|
71
|
+
"types": "./dist/classes/services/EmotionCacheService/index.d.ts",
|
|
72
|
+
"import": "./dist/classes/services/EmotionCacheService/index.js"
|
|
73
|
+
},
|
|
66
74
|
"./classes/services/FastaDataEventBusService": {
|
|
67
75
|
"types": "./dist/classes/services/FastaDataEventBusService/index.d.ts",
|
|
68
76
|
"import": "./dist/classes/services/FastaDataEventBusService/index.js"
|
|
69
77
|
},
|
|
70
|
-
"./components/
|
|
71
|
-
"types": "./dist/components/
|
|
72
|
-
"import": "./dist/components/
|
|
78
|
+
"./components/SearchBar": {
|
|
79
|
+
"types": "./dist/components/SearchBar/index.d.ts",
|
|
80
|
+
"import": "./dist/components/SearchBar/index.js"
|
|
73
81
|
},
|
|
74
|
-
"./components/
|
|
75
|
-
"types": "./dist/components/
|
|
76
|
-
"import": "./dist/components/
|
|
82
|
+
"./components/app/App": {
|
|
83
|
+
"types": "./dist/components/app/App/index.d.ts",
|
|
84
|
+
"import": "./dist/components/app/App/index.js"
|
|
77
85
|
},
|
|
78
|
-
"./components/
|
|
79
|
-
"types": "./dist/components/
|
|
80
|
-
"import": "./dist/components/
|
|
86
|
+
"./components/fasta/FastaDataImportDialog": {
|
|
87
|
+
"types": "./dist/components/fasta/FastaDataImportDialog/index.d.ts",
|
|
88
|
+
"import": "./dist/components/fasta/FastaDataImportDialog/index.js"
|
|
81
89
|
},
|
|
82
|
-
"./components/
|
|
83
|
-
"types": "./dist/components/
|
|
84
|
-
"import": "./dist/components/
|
|
90
|
+
"./components/fasta/FastaDataImportDialogLoader": {
|
|
91
|
+
"types": "./dist/components/fasta/FastaDataImportDialogLoader/index.d.ts",
|
|
92
|
+
"import": "./dist/components/fasta/FastaDataImportDialogLoader/index.js"
|
|
85
93
|
},
|
|
86
|
-
"./components/
|
|
87
|
-
"types": "./dist/components/
|
|
88
|
-
"import": "./dist/components/
|
|
94
|
+
"./components/fasta/FastaNotLoaded": {
|
|
95
|
+
"types": "./dist/components/fasta/FastaNotLoaded/index.d.ts",
|
|
96
|
+
"import": "./dist/components/fasta/FastaNotLoaded/index.js"
|
|
89
97
|
},
|
|
90
|
-
"./components/
|
|
91
|
-
"types": "./dist/components/
|
|
92
|
-
"import": "./dist/components/
|
|
98
|
+
"./components/fasta/FastaPageHeaderCenterComponent": {
|
|
99
|
+
"types": "./dist/components/fasta/FastaPageHeaderCenterComponent/index.d.ts",
|
|
100
|
+
"import": "./dist/components/fasta/FastaPageHeaderCenterComponent/index.js"
|
|
93
101
|
},
|
|
94
|
-
"./components/
|
|
95
|
-
"types": "./dist/components/
|
|
96
|
-
"import": "./dist/components/
|
|
102
|
+
"./components/fasta/FastaPageHeaderImportButton": {
|
|
103
|
+
"types": "./dist/components/fasta/FastaPageHeaderImportButton/index.d.ts",
|
|
104
|
+
"import": "./dist/components/fasta/FastaPageHeaderImportButton/index.js"
|
|
97
105
|
},
|
|
98
|
-
"./components/
|
|
99
|
-
"types": "./dist/components/
|
|
100
|
-
"import": "./dist/components/
|
|
106
|
+
"./components/fasta/FastaPageHeaderResetButton": {
|
|
107
|
+
"types": "./dist/components/fasta/FastaPageHeaderResetButton/index.d.ts",
|
|
108
|
+
"import": "./dist/components/fasta/FastaPageHeaderResetButton/index.js"
|
|
101
109
|
},
|
|
102
|
-
"./components/
|
|
103
|
-
"types": "./dist/components/
|
|
104
|
-
"import": "./dist/components/
|
|
110
|
+
"./components/ui/ButtonWithMenu": {
|
|
111
|
+
"types": "./dist/components/ui/ButtonWithMenu/index.d.ts",
|
|
112
|
+
"import": "./dist/components/ui/ButtonWithMenu/index.js"
|
|
113
|
+
},
|
|
114
|
+
"./components/ui/GenericErrorMessage": {
|
|
115
|
+
"types": "./dist/components/ui/GenericErrorMessage/index.d.ts",
|
|
116
|
+
"import": "./dist/components/ui/GenericErrorMessage/index.js"
|
|
117
|
+
},
|
|
118
|
+
"./components/ui/I18nWrapper": {
|
|
119
|
+
"types": "./dist/components/ui/I18nWrapper/index.d.ts",
|
|
120
|
+
"import": "./dist/components/ui/I18nWrapper/index.js"
|
|
121
|
+
},
|
|
122
|
+
"./components/ui/PageCommon": {
|
|
123
|
+
"types": "./dist/components/ui/PageCommon/index.d.ts",
|
|
124
|
+
"import": "./dist/components/ui/PageCommon/index.js"
|
|
125
|
+
},
|
|
126
|
+
"./components/ui/PageCommonDrawer": {
|
|
127
|
+
"types": "./dist/components/ui/PageCommonDrawer/index.d.ts",
|
|
128
|
+
"import": "./dist/components/ui/PageCommonDrawer/index.js"
|
|
105
129
|
},
|
|
106
|
-
"./components/
|
|
107
|
-
"types": "./dist/components/
|
|
108
|
-
"import": "./dist/components/
|
|
130
|
+
"./components/ui/PageCommonHeader": {
|
|
131
|
+
"types": "./dist/components/ui/PageCommonHeader/index.d.ts",
|
|
132
|
+
"import": "./dist/components/ui/PageCommonHeader/index.js"
|
|
109
133
|
},
|
|
110
|
-
"./constants/
|
|
111
|
-
"types": "./dist/constants/
|
|
112
|
-
"import": "./dist/constants/
|
|
134
|
+
"./constants/config.constants": {
|
|
135
|
+
"types": "./dist/constants/config.constants.d.ts",
|
|
136
|
+
"import": "./dist/constants/config.constants.js"
|
|
113
137
|
},
|
|
114
|
-
"./
|
|
115
|
-
"types": "./dist/
|
|
116
|
-
"import": "./dist/
|
|
138
|
+
"./constants/page.constants": {
|
|
139
|
+
"types": "./dist/constants/page.constants.d.ts",
|
|
140
|
+
"import": "./dist/constants/page.constants.js"
|
|
117
141
|
},
|
|
118
|
-
"./
|
|
119
|
-
"types": "./dist/
|
|
120
|
-
"import": "./dist/
|
|
142
|
+
"./context/commonConfigContext": {
|
|
143
|
+
"types": "./dist/context/commonConfigContext/index.d.ts",
|
|
144
|
+
"import": "./dist/context/commonConfigContext/index.js"
|
|
145
|
+
},
|
|
146
|
+
"./context/pageCommonContext": {
|
|
147
|
+
"types": "./dist/context/pageCommonContext/index.d.ts",
|
|
148
|
+
"import": "./dist/context/pageCommonContext/index.js"
|
|
149
|
+
},
|
|
150
|
+
"./hooks/useConfig": {
|
|
151
|
+
"types": "./dist/hooks/useConfig/index.d.ts",
|
|
152
|
+
"import": "./dist/hooks/useConfig/index.js"
|
|
153
|
+
},
|
|
154
|
+
"./hooks/useUpdateDocumentTitle": {
|
|
155
|
+
"types": "./dist/hooks/useUpdateDocumentTitle/index.d.ts",
|
|
156
|
+
"import": "./dist/hooks/useUpdateDocumentTitle/index.js"
|
|
157
|
+
},
|
|
158
|
+
"./models/config.models": {
|
|
159
|
+
"types": "./dist/models/config.models.d.ts",
|
|
160
|
+
"import": "./dist/models/config.models.js"
|
|
161
|
+
},
|
|
162
|
+
"./models/fasta.models": {
|
|
163
|
+
"types": "./dist/models/fasta.models.d.ts",
|
|
164
|
+
"import": "./dist/models/fasta.models.js"
|
|
165
|
+
},
|
|
166
|
+
"./models/metadata.models": {
|
|
167
|
+
"types": "./dist/models/metadata.models.d.ts",
|
|
168
|
+
"import": "./dist/models/metadata.models.js"
|
|
169
|
+
},
|
|
170
|
+
"./pages/ErrorPage": {
|
|
171
|
+
"types": "./dist/pages/ErrorPage/index.d.ts",
|
|
172
|
+
"import": "./dist/pages/ErrorPage/index.js"
|
|
121
173
|
},
|
|
122
174
|
"./stores/fastaDataStore": {
|
|
123
175
|
"types": "./dist/stores/fastaDataStore/index.d.ts",
|
|
@@ -127,6 +179,10 @@
|
|
|
127
179
|
"types": "./dist/theme/index.d.ts",
|
|
128
180
|
"import": "./dist/theme/index.js"
|
|
129
181
|
},
|
|
182
|
+
"./utils/DependencyContainerUtil": {
|
|
183
|
+
"types": "./dist/utils/DependencyContainerUtil/index.d.ts",
|
|
184
|
+
"import": "./dist/utils/DependencyContainerUtil/index.js"
|
|
185
|
+
},
|
|
130
186
|
"./utils/DownloadUtil": {
|
|
131
187
|
"types": "./dist/utils/DownloadUtil/index.d.ts",
|
|
132
188
|
"import": "./dist/utils/DownloadUtil/index.js"
|
|
@@ -135,6 +191,10 @@
|
|
|
135
191
|
"types": "./dist/utils/ErrorUtil/index.d.ts",
|
|
136
192
|
"import": "./dist/utils/ErrorUtil/index.js"
|
|
137
193
|
},
|
|
194
|
+
"./utils/ExportUtil": {
|
|
195
|
+
"types": "./dist/utils/ExportUtil/index.d.ts",
|
|
196
|
+
"import": "./dist/utils/ExportUtil/index.js"
|
|
197
|
+
},
|
|
138
198
|
"./utils/FastaUtil": {
|
|
139
199
|
"types": "./dist/utils/FastaUtil/index.d.ts",
|
|
140
200
|
"import": "./dist/utils/FastaUtil/index.js"
|
|
@@ -143,6 +203,10 @@
|
|
|
143
203
|
"types": "./dist/utils/MetaDataUtil/index.d.ts",
|
|
144
204
|
"import": "./dist/utils/MetaDataUtil/index.js"
|
|
145
205
|
},
|
|
206
|
+
"./utils/StandardConfigUtil": {
|
|
207
|
+
"types": "./dist/utils/StandardConfigUtil/index.d.ts",
|
|
208
|
+
"import": "./dist/utils/StandardConfigUtil/index.js"
|
|
209
|
+
},
|
|
146
210
|
"./utils/UrlUtil": {
|
|
147
211
|
"types": "./dist/utils/UrlUtil/index.d.ts",
|
|
148
212
|
"import": "./dist/utils/UrlUtil/index.js"
|
|
@@ -1 +0,0 @@
|
|
|
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 +0,0 @@
|
|
|
1
|
-
export { t as FastaDataImportDialog } from "../../_chunks/FastaDataImportDialog.js";
|