@rivm-loculus-tools/common-frontend 0.9.0 → 0.11.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 +1055 -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 +66 -52
- package/dist/components/fasta/FastaDataImportDialogLoader/index.js.map +1 -1
- package/dist/components/fasta/FastaPageHeaderCenterComponent/FastaPageHeaderCenterComponent.d.ts +3 -4
- package/dist/components/fasta/FastaPageHeaderCenterComponent/index.js +18 -22
- package/dist/components/fasta/FastaPageHeaderCenterComponent/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 +19 -6
- package/dist/components/ui/PageCommon/index.js.map +1 -1
- package/dist/components/ui/PageCommonDrawer/index.js +18 -10
- package/dist/components/ui/PageCommonDrawer/index.js.map +1 -1
- package/dist/components/ui/PageCommonHeader/index.js +7 -6
- package/dist/components/ui/PageCommonHeader/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/context/pageCommonContext/PageCommonContext.d.ts +1 -0
- package/dist/context/pageCommonContext/index.js +7 -5
- package/dist/context/pageCommonContext/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
- package/dist/_chunks/react.js +0 -10
- package/dist/_chunks/react.js.map +0 -1
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
1
|
+
import { Box as e, Chip as t, styled as n } from "@mui/material";
|
|
2
|
+
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
4
3
|
// src/components/fasta/FastaPageHeaderCenterComponent/FastaPageHeaderCenterComponent.tsx
|
|
5
|
-
var
|
|
4
|
+
var a = n(t, {
|
|
6
5
|
name: "RivmLoculusToolsCommonFrontendFastaPageHeaderCenterComponent",
|
|
7
6
|
slot: "Root"
|
|
8
7
|
})({
|
|
@@ -10,23 +9,20 @@ var o = r(n, {
|
|
|
10
9
|
color: "#FFFFFF",
|
|
11
10
|
fontSize: "0.75rem",
|
|
12
11
|
fontWeight: 600
|
|
13
|
-
}),
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
});
|
|
29
|
-
};
|
|
30
|
-
export { s as FastaPageHeaderCenterComponent };
|
|
12
|
+
}), o = ({ metaDataCount: t, sequenceCount: n }) => /* @__PURE__ */ i(e, {
|
|
13
|
+
sx: {
|
|
14
|
+
alignItems: "center",
|
|
15
|
+
display: "flex",
|
|
16
|
+
gap: 1
|
|
17
|
+
},
|
|
18
|
+
children: [n > 0 && /* @__PURE__ */ r(a, {
|
|
19
|
+
label: `${n} Sequences`,
|
|
20
|
+
size: "small"
|
|
21
|
+
}), t > 0 && /* @__PURE__ */ r(a, {
|
|
22
|
+
label: `${t} Metadata Records`,
|
|
23
|
+
size: "small"
|
|
24
|
+
})]
|
|
25
|
+
});
|
|
26
|
+
export { o as FastaPageHeaderCenterComponent };
|
|
31
27
|
|
|
32
28
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["
|
|
1
|
+
{"version":3,"file":"index.js","names":["FastaPageHeaderCenterChip","styled","Chip","FastaPageHeaderCenterComponent","Box","sequenceCount","metaDataCount"],"sources":["../../../../src/components/fasta/FastaPageHeaderCenterComponent/FastaPageHeaderCenterComponent.tsx"],"sourcesContent":["import {\n Box,\n Chip,\n styled,\n} from '@mui/material';\nimport type {\n ComponentsOverrides,\n Theme,\n} from '@mui/material/styles';\n\n\nexport type FastaPageHeaderCenterComponentProps = {\n metaDataCount: number;\n sequenceCount: number;\n};\n\nexport type FastaPageHeaderCenterComponentTheme = {\n styleOverrides?: ComponentsOverrides<Theme>['MuiChip'];\n};\n\nconst FastaPageHeaderCenterChip = styled(Chip, {\n name: 'RivmLoculusToolsCommonFrontendFastaPageHeaderCenterComponent',\n slot: 'Root',\n})({\n backgroundColor: 'rgba(255, 255, 255, 0.2)',\n color: '#FFFFFF',\n fontSize: '0.75rem',\n fontWeight: 600,\n});\n\nexport const FastaPageHeaderCenterComponent = ({ metaDataCount, sequenceCount }: FastaPageHeaderCenterComponentProps) => {\n\n return (\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1 }}>\n {sequenceCount > 0 && (\n <FastaPageHeaderCenterChip\n label={`${sequenceCount} Sequences`}\n size={'small'}\n />\n )}\n {metaDataCount > 0 && (\n <FastaPageHeaderCenterChip\n label={`${metaDataCount} Metadata Records`}\n size={'small'}\n />\n )}\n </Box>\n );\n};\n"],"mappings":";;;AAoBA,IAAMA,IAA4BC,EAAOC,GAAM;CAC7C,MAAM;CACN,MAAM;AACR,CAAC,CAAC,CAAC;CACD,iBAAiB;CACjB,OAAO;CACP,UAAU;CACV,YAAY;AACd,CAAC,GAEYC,KAAkC,EAAE,kBAAe,uBAG5D,kBAACC,GAAD;CAAK,IAAI;EAAE,YAAY;EAAU,SAAS;EAAQ,KAAK;CAAE;CAAzD,UAAA,CACGC,IAAgB,KACf,kBAACL,GAAD;EACE,OAAO,GAAGK,EAAc;EACxB,MAAM;CACP,CAAA,GAEFC,IAAgB,KACf,kBAACN,GAAD;EACE,OAAO,GAAGM,EAAc;EACxB,MAAM;CACP,CAAA,CAEA"}
|
|
@@ -1,34 +1,37 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
1
|
+
import { UrlUtil as e } from "../../../utils/UrlUtil/index.js";
|
|
2
|
+
import { t } from "../../../_chunks/LoculusService.js";
|
|
3
|
+
import { container as n } from "tsyringe";
|
|
4
|
+
import { IconButton as r, Tooltip as i } from "@mui/material";
|
|
5
|
+
import { t as a } from "i18next";
|
|
6
|
+
import { Fragment as o, jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
7
|
+
import { useCallback as l, useRef as u } from "react";
|
|
8
|
+
import d from "@mui/icons-material/RestartAlt";
|
|
9
|
+
import { Confirmation as f } from "@gen-epix/ui-core-components/components/Confirmation";
|
|
7
10
|
// src/components/fasta/FastaPageHeaderResetButton/FastaPageHeaderResetButton.tsx
|
|
8
|
-
var
|
|
9
|
-
let
|
|
10
|
-
|
|
11
|
-
}, []),
|
|
12
|
-
|
|
13
|
-
}, [
|
|
14
|
-
return /* @__PURE__ */
|
|
11
|
+
var p = ({ onReset: p }) => {
|
|
12
|
+
let m = u(null), h = l(() => {
|
|
13
|
+
m.current?.open();
|
|
14
|
+
}, []), g = l(() => {
|
|
15
|
+
e.clearSearchParams(), n.resolve(t).clear(), p();
|
|
16
|
+
}, [p]);
|
|
17
|
+
return /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s(i, {
|
|
15
18
|
title: "Reset current session and dataset",
|
|
16
|
-
children: /* @__PURE__ */
|
|
19
|
+
children: /* @__PURE__ */ s(r, {
|
|
17
20
|
color: "inherit",
|
|
18
|
-
onClick:
|
|
21
|
+
onClick: h,
|
|
19
22
|
size: "small",
|
|
20
23
|
sx: { opacity: .85 },
|
|
21
|
-
children: /* @__PURE__ */
|
|
24
|
+
children: /* @__PURE__ */ s(d, { fontSize: "small" })
|
|
22
25
|
})
|
|
23
|
-
}), /* @__PURE__ */
|
|
24
|
-
body:
|
|
25
|
-
cancelLabel:
|
|
26
|
-
confirmLabel:
|
|
27
|
-
onConfirm:
|
|
28
|
-
ref:
|
|
29
|
-
title:
|
|
26
|
+
}), /* @__PURE__ */ s(f, {
|
|
27
|
+
body: a`Are you sure you want to reset the current session and dataset?`,
|
|
28
|
+
cancelLabel: a`Cancel`,
|
|
29
|
+
confirmLabel: a`Reset`,
|
|
30
|
+
onConfirm: g,
|
|
31
|
+
ref: m,
|
|
32
|
+
title: a`Reset current session and dataset?`
|
|
30
33
|
})] });
|
|
31
34
|
};
|
|
32
|
-
export {
|
|
35
|
+
export { p as FastaPageHeaderResetButton };
|
|
33
36
|
|
|
34
37
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["_Fragment","RestartAltIcon","FastaPageHeaderResetButton","confirmationRef","useRef","onClickResetSession","useCallback","onConfirm","onReset","Fragment","Tooltip","IconButton","Confirmation"],"sources":["../../../../src/components/fasta/FastaPageHeaderResetButton/FastaPageHeaderResetButton.tsx"],"sourcesContent":["import RestartAltIcon from '@mui/icons-material/RestartAlt';\nimport {\n IconButton,\n Tooltip,\n} from '@mui/material';\nimport {\n useCallback,\n useRef,\n} from 'react';\nimport { Confirmation } from '@gen-epix/ui-core-components/components/Confirmation';\nimport type { ConfirmationRefMethods } from '@gen-epix/ui-core-components/components/Confirmation';\nimport { t } from 'i18next';\n\nexport type FastaPageHeaderResetButtonProps = {\n onReset: () => void;\n};\n\nexport const FastaPageHeaderResetButton = ({ onReset }: FastaPageHeaderResetButtonProps) => {\n const confirmationRef = useRef<ConfirmationRefMethods>(null);\n const onClickResetSession = useCallback(() => {\n confirmationRef.current?.open();\n }, []);\n\n const onConfirm = useCallback(() => {\n onReset();\n }, [onReset]);\n\n return (\n <>\n <Tooltip title={'Reset current session and dataset'}>\n <IconButton\n color={'inherit'}\n onClick={onClickResetSession}\n size={'small'}\n sx={{ opacity: 0.85 }}\n >\n <RestartAltIcon fontSize={'small'} />\n </IconButton>\n </Tooltip>\n <Confirmation\n body={t`Are you sure you want to reset the current session and dataset?`}\n cancelLabel={t`Cancel`}\n confirmLabel={t`Reset`}\n onConfirm={onConfirm}\n ref={confirmationRef}\n title={t`Reset current session and dataset?`}\n />\n </>\n );\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","names":["_Fragment","RestartAltIcon","FastaPageHeaderResetButton","confirmationRef","useRef","onClickResetSession","useCallback","onConfirm","UrlUtil","container","LoculusService","onReset","Fragment","Tooltip","IconButton","Confirmation"],"sources":["../../../../src/components/fasta/FastaPageHeaderResetButton/FastaPageHeaderResetButton.tsx"],"sourcesContent":["import RestartAltIcon from '@mui/icons-material/RestartAlt';\nimport {\n IconButton,\n Tooltip,\n} from '@mui/material';\nimport {\n useCallback,\n useRef,\n} from 'react';\nimport { Confirmation } from '@gen-epix/ui-core-components/components/Confirmation';\nimport type { ConfirmationRefMethods } from '@gen-epix/ui-core-components/components/Confirmation';\nimport { t } from 'i18next';\nimport { container } from 'tsyringe';\n\nimport { UrlUtil } from '../../../utils/UrlUtil';\nimport { LoculusService } from '../../../classes/services/LoculusService';\n\nexport type FastaPageHeaderResetButtonProps = {\n onReset: () => void;\n};\n\nexport const FastaPageHeaderResetButton = ({ onReset }: FastaPageHeaderResetButtonProps) => {\n const confirmationRef = useRef<ConfirmationRefMethods>(null);\n const onClickResetSession = useCallback(() => {\n confirmationRef.current?.open();\n }, []);\n\n const onConfirm = useCallback(() => {\n UrlUtil.clearSearchParams();\n container.resolve(LoculusService).clear();\n onReset();\n }, [onReset]);\n\n return (\n <>\n <Tooltip title={'Reset current session and dataset'}>\n <IconButton\n color={'inherit'}\n onClick={onClickResetSession}\n size={'small'}\n sx={{ opacity: 0.85 }}\n >\n <RestartAltIcon fontSize={'small'} />\n </IconButton>\n </Tooltip>\n <Confirmation\n body={t`Are you sure you want to reset the current session and dataset?`}\n cancelLabel={t`Cancel`}\n confirmLabel={t`Reset`}\n onConfirm={onConfirm}\n ref={confirmationRef}\n title={t`Reset current session and dataset?`}\n />\n </>\n );\n};\n"],"mappings":";;;;;;;;;;AAqBA,IAAaE,KAA8B,EAAE,iBAA+C;CAC1F,IAAMC,IAAkBC,EAA+B,IAAI,GACrDC,IAAsBC,QAAkB;EAC5C,EAAgB,SAAS,KAAK;CAChC,GAAG,CAAC,CAAC,GAECC,IAAYD,QAAkB;EAGlC,AAFAE,EAAQ,kBAAkB,GAC1BC,EAAU,QAAQC,CAAc,CAAC,CAAC,MAAM,GACxCC,EAAQ;CACV,GAAG,CAACA,CAAO,CAAC;CAEZ,OACE,kBAAAX,GAAA,EAAA,UAAA,CACE,kBAACa,GAAD;EAAS,OAAO;EACd,UAAA,kBAACC,GAAD;GACE,OAAO;GACP,SAAST;GACT,MAAM;GACN,IAAI,EAAE,SAAS,IAAK;GAEpB,UAAA,kBAACJ,GAAD,EAAgB,UAAU,QAAU,CAAA;EAC1B,CAAA;CACL,CAAA,GACT,kBAACc,GAAD;EACE,MAAM,CAAC;EACP,aAAa,CAAC;EACd,cAAc,CAAC;EACJ;EACX,KAAKZ;EACL,OAAO,CAAC;CACT,CAAA,CACD,EAAA,CAAA;AAEN"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { WithDialogRefMethods, WithDialogRenderProps } from '@gen-epix/ui-core-components/hoc/withDialog';
|
|
2
|
+
import { MetadataParseResult } from '../../../models/metadata.models';
|
|
3
|
+
export interface UploadToLoculusModalOpenProps {
|
|
4
|
+
fasta: string;
|
|
5
|
+
metaData: MetadataParseResult | null;
|
|
6
|
+
rawFasta: string;
|
|
7
|
+
}
|
|
8
|
+
export interface UploadToLoculusModalProps extends WithDialogRenderProps<UploadToLoculusModalOpenProps> {
|
|
9
|
+
}
|
|
10
|
+
export type UploadToLoculusModalRefMethods = WithDialogRefMethods<UploadToLoculusModalProps, UploadToLoculusModalOpenProps>;
|
|
11
|
+
export declare const UploadToLoculusModal: import('react').ComponentClass<UploadToLoculusModalProps, import('@gen-epix/ui-core-components/hoc/withDialog').WithDialogState<UploadToLoculusModalOpenProps>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './UploadToLoculusModal';
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { FastaUtil as e } from "../../../utils/FastaUtil/index.js";
|
|
2
|
+
import { t } from "../../../_chunks/LoculusService.js";
|
|
3
|
+
import { UrlService as n } from "../../../classes/services/UrlService/index.js";
|
|
4
|
+
import { container as r } from "tsyringe";
|
|
5
|
+
import { Alert as i, Box as a, Paper as o, Table as s, TableBody as c, TableCell as l, TableContainer as u, TableHead as d, TableRow as f } from "@mui/material";
|
|
6
|
+
import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
7
|
+
import { useCallback as g, useEffect as _, useMemo as v, useRef as y, useState as b } from "react";
|
|
8
|
+
import { Spinner as x } from "@gen-epix/ui-core-components/components/Spinner";
|
|
9
|
+
import { withDialog as S } from "@gen-epix/ui-core-components/hoc/withDialog";
|
|
10
|
+
// src/components/loculus/UploadToLoculusModal/UploadToLoculusModal.tsx
|
|
11
|
+
var C = S(({ onActionsChange: S, onClose: C, openProps: w }) => {
|
|
12
|
+
let T = v(() => r.resolve(t), []), E = v(() => r.resolve(n), []), [D, O] = b(!1), [k, A] = b(!1), [j, M] = b(null), N = y(null), P = w?.fasta ?? "", F = w?.metaData ?? null, I = w?.rawFasta ?? "";
|
|
13
|
+
_(() => () => {
|
|
14
|
+
N.current?.abort();
|
|
15
|
+
}, []);
|
|
16
|
+
let L = v(() => {
|
|
17
|
+
let n = [];
|
|
18
|
+
T.data.authenticated || n.push("You must be authenticated to upload to Loculus."), E.hasReturnParams() || n.push("The Loculus return URL and organism must be provided."), F || n.push("Metadata must be loaded before uploading.");
|
|
19
|
+
let r = e.parseFasta(P);
|
|
20
|
+
if (r.error ? n.push(r.error) : r.sequences.length === 0 && n.push("At least one FASTA sequence is required."), F?.error && n.push(F.error), n.length > 0 || !F) return {
|
|
21
|
+
errors: n,
|
|
22
|
+
revisedSequences: null
|
|
23
|
+
};
|
|
24
|
+
try {
|
|
25
|
+
let e = t.createRevisedSequences(P, F, I);
|
|
26
|
+
return e.sequenceCount === 0 && n.push("No FASTA sequences match the metadata."), {
|
|
27
|
+
errors: n,
|
|
28
|
+
revisedSequences: e
|
|
29
|
+
};
|
|
30
|
+
} catch (e) {
|
|
31
|
+
return n.push(e instanceof Error ? e.message : "Failed to prepare the upload preview."), {
|
|
32
|
+
errors: n,
|
|
33
|
+
revisedSequences: null
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}, [
|
|
37
|
+
P,
|
|
38
|
+
T,
|
|
39
|
+
F,
|
|
40
|
+
I,
|
|
41
|
+
E
|
|
42
|
+
]), R = L.revisedSequences?.metadata.split("\n").slice(1).filter((e) => e.length > 0).reduce((e, t) => {
|
|
43
|
+
let n = e.filter((e) => e.key.startsWith(`${t}-`)).length;
|
|
44
|
+
return e.push({
|
|
45
|
+
key: `${t}-${n}`,
|
|
46
|
+
values: t.split(" ")
|
|
47
|
+
}), e;
|
|
48
|
+
}, []), z = g(async () => {
|
|
49
|
+
if (L.errors.length > 0 || !L.revisedSequences || !F || !E.hasReturnParams()) return;
|
|
50
|
+
M(null), O(!0);
|
|
51
|
+
let e = new AbortController();
|
|
52
|
+
N.current = e;
|
|
53
|
+
try {
|
|
54
|
+
let { organism: t, returnUrl: n } = E.data;
|
|
55
|
+
await T.reviseSequences(P, F, n, t, e), A(!0);
|
|
56
|
+
} catch (t) {
|
|
57
|
+
e.signal.aborted || M(t instanceof Error ? t.message : "Failed to upload sequences to Loculus.");
|
|
58
|
+
} finally {
|
|
59
|
+
e.signal.aborted || (N.current = null, O(!1));
|
|
60
|
+
}
|
|
61
|
+
}, [
|
|
62
|
+
P,
|
|
63
|
+
T,
|
|
64
|
+
F,
|
|
65
|
+
E,
|
|
66
|
+
L.errors.length,
|
|
67
|
+
L.revisedSequences
|
|
68
|
+
]), B = g(() => {
|
|
69
|
+
N.current?.abort(), N.current = null, O(!1), C?.();
|
|
70
|
+
}, [C]);
|
|
71
|
+
return _(() => {
|
|
72
|
+
let e = k ? [{
|
|
73
|
+
label: "Close tab",
|
|
74
|
+
onClick: () => window.close(),
|
|
75
|
+
variant: "contained"
|
|
76
|
+
}] : [...D ? [{
|
|
77
|
+
label: "Cancel",
|
|
78
|
+
onClick: B,
|
|
79
|
+
variant: "outlined"
|
|
80
|
+
}] : [], {
|
|
81
|
+
disabled: D || L.errors.length > 0 || L.revisedSequences === null,
|
|
82
|
+
label: j ? "Try again" : "Upload",
|
|
83
|
+
onClick: z,
|
|
84
|
+
variant: "contained"
|
|
85
|
+
}];
|
|
86
|
+
S?.(e);
|
|
87
|
+
}, [
|
|
88
|
+
k,
|
|
89
|
+
D,
|
|
90
|
+
S,
|
|
91
|
+
B,
|
|
92
|
+
z,
|
|
93
|
+
j,
|
|
94
|
+
L.errors.length,
|
|
95
|
+
L.revisedSequences
|
|
96
|
+
]), /* @__PURE__ */ m(a, {
|
|
97
|
+
sx: {
|
|
98
|
+
display: "grid",
|
|
99
|
+
gap: 2,
|
|
100
|
+
position: "relative"
|
|
101
|
+
},
|
|
102
|
+
children: D ? /* @__PURE__ */ m(x, {
|
|
103
|
+
inline: !0,
|
|
104
|
+
label: "Uploading sequences to Loculus"
|
|
105
|
+
}) : /* @__PURE__ */ h(p, { children: [
|
|
106
|
+
L.errors.length > 0 && /* @__PURE__ */ m(i, {
|
|
107
|
+
severity: "error",
|
|
108
|
+
children: L.errors.join(" ")
|
|
109
|
+
}),
|
|
110
|
+
j && /* @__PURE__ */ m(i, {
|
|
111
|
+
severity: "error",
|
|
112
|
+
children: j
|
|
113
|
+
}),
|
|
114
|
+
k && /* @__PURE__ */ m(i, {
|
|
115
|
+
severity: "success",
|
|
116
|
+
children: "Sequences successfully uploaded to Loculus. You can close this tab."
|
|
117
|
+
}),
|
|
118
|
+
!k && L.revisedSequences && /* @__PURE__ */ h(p, { children: [
|
|
119
|
+
/* @__PURE__ */ m(i, {
|
|
120
|
+
severity: "info",
|
|
121
|
+
children: `${L.revisedSequences.sequenceCount} sequence(s) and the matching metadata will be uploaded to Loculus.`
|
|
122
|
+
}),
|
|
123
|
+
L.revisedSequences.removedSequences.length > 0 && /* @__PURE__ */ m(i, {
|
|
124
|
+
severity: "warning",
|
|
125
|
+
children: `Sequences removed during editing and therefore not uploaded: ${L.revisedSequences.removedSequences.length}`
|
|
126
|
+
}),
|
|
127
|
+
L.revisedSequences.addedSequencesWithoutMetadata.length > 0 && /* @__PURE__ */ m(i, {
|
|
128
|
+
severity: "warning",
|
|
129
|
+
children: `Added sequences without matching metadata will not be uploaded: ${L.revisedSequences.addedSequencesWithoutMetadata.length}`
|
|
130
|
+
}),
|
|
131
|
+
/* @__PURE__ */ m(u, {
|
|
132
|
+
component: o,
|
|
133
|
+
sx: {
|
|
134
|
+
maxHeight: "400px",
|
|
135
|
+
overflowX: "auto"
|
|
136
|
+
},
|
|
137
|
+
children: /* @__PURE__ */ h(s, {
|
|
138
|
+
size: "small",
|
|
139
|
+
stickyHeader: !0,
|
|
140
|
+
sx: {
|
|
141
|
+
minWidth: "100%",
|
|
142
|
+
whiteSpace: "nowrap",
|
|
143
|
+
width: "max-content"
|
|
144
|
+
},
|
|
145
|
+
children: [/* @__PURE__ */ m(d, { children: /* @__PURE__ */ m(f, { children: F?.columns.map((e) => /* @__PURE__ */ m(l, { children: e }, e)) }) }), /* @__PURE__ */ m(c, { children: R?.map(({ key: e, values: t }) => /* @__PURE__ */ m(f, { children: t.map((t, n) => /* @__PURE__ */ m(l, { children: t }, `${e}-${F?.columns[n] ?? n}`)) }, e)) })]
|
|
146
|
+
})
|
|
147
|
+
})
|
|
148
|
+
] })
|
|
149
|
+
] })
|
|
150
|
+
});
|
|
151
|
+
}, {
|
|
152
|
+
defaultTitle: "Upload to Loculus",
|
|
153
|
+
fullWidth: !0,
|
|
154
|
+
maxWidth: "md",
|
|
155
|
+
testId: "UploadToLoculusModal"
|
|
156
|
+
});
|
|
157
|
+
export { C as UploadToLoculusModal };
|
|
158
|
+
|
|
159
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["_Fragment","UploadToLoculusModal","withDialog","loculusService","useMemo","container","LoculusService","urlService","UrlService","isUploading","setIsUploading","useState","didUpload","setDidUpload","uploadError","setUploadError","abortControllerRef","useRef","fasta","openProps","metaData","rawFasta","validation","errors","parsedFasta","FastaUtil","revisedSequences","error","previewMetadataRows","row","occurrence","rows","existingRow","onClickUpload","useCallback","abortController","returnUrl","organism","onCancelUpload","onClose","useEffect","actions","onActionsChange","Box","Spinner","Fragment","Alert","TableContainer","Paper","Table","TableHead","TableRow","TableCell","column","TableBody","values","value","key","columnIndex"],"sources":["../../../../src/components/loculus/UploadToLoculusModal/UploadToLoculusModal.tsx"],"sourcesContent":["import {\n Alert,\n Box,\n Paper,\n Table,\n TableBody,\n TableCell,\n TableContainer,\n TableHead,\n TableRow,\n} from '@mui/material';\nimport type { DialogAction } from '@gen-epix/ui-core-components/components/Dialog';\nimport { Spinner } from '@gen-epix/ui-core-components/components/Spinner';\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 { ReactElement } from 'react';\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { container } from 'tsyringe';\n\nimport { LoculusService } from '../../../classes/services/LoculusService';\nimport { UrlService } from '../../../classes/services/UrlService';\nimport type { MetadataParseResult } from '../../../models/metadata.models';\nimport { FastaUtil } from '../../../utils/FastaUtil';\n\nexport interface UploadToLoculusModalOpenProps {\n fasta: string;\n metaData: MetadataParseResult | null;\n rawFasta: string;\n}\n\nexport interface UploadToLoculusModalProps extends WithDialogRenderProps<UploadToLoculusModalOpenProps> {\n //\n}\n\nexport type UploadToLoculusModalRefMethods = WithDialogRefMethods<UploadToLoculusModalProps, UploadToLoculusModalOpenProps>;\n\nexport const UploadToLoculusModal = withDialog<UploadToLoculusModalProps, UploadToLoculusModalOpenProps>(({\n onActionsChange,\n onClose,\n openProps,\n}: UploadToLoculusModalProps): ReactElement => {\n const loculusService = useMemo(() => container.resolve(LoculusService), []);\n const urlService = useMemo(() => container.resolve(UrlService), []);\n const [isUploading, setIsUploading] = useState(false);\n const [didUpload, setDidUpload] = useState(false);\n const [uploadError, setUploadError] = useState<null | string>(null);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const fasta = openProps?.fasta ?? '';\n const metaData = openProps?.metaData ?? null;\n const rawFasta = openProps?.rawFasta ?? '';\n\n useEffect(() => () => {\n abortControllerRef.current?.abort();\n }, []);\n\n const validation = useMemo(() => {\n const errors: string[] = [];\n if (!loculusService.data.authenticated) {\n errors.push('You must be authenticated to upload to Loculus.');\n }\n if (!urlService.hasReturnParams()) {\n errors.push('The Loculus return URL and organism must be provided.');\n }\n if (!metaData) {\n errors.push('Metadata must be loaded before uploading.');\n }\n\n const parsedFasta = FastaUtil.parseFasta(fasta);\n if (parsedFasta.error) {\n errors.push(parsedFasta.error);\n } else if (parsedFasta.sequences.length === 0) {\n errors.push('At least one FASTA sequence is required.');\n }\n\n if (metaData?.error) {\n errors.push(metaData.error);\n }\n\n if (errors.length > 0 || !metaData) {\n return { errors, revisedSequences: null };\n }\n\n try {\n const revisedSequences = LoculusService.createRevisedSequences(fasta, metaData, rawFasta);\n if (revisedSequences.sequenceCount === 0) {\n errors.push('No FASTA sequences match the metadata.');\n }\n return {\n errors,\n revisedSequences,\n };\n } catch (error: unknown) {\n errors.push(error instanceof Error ? error.message : 'Failed to prepare the upload preview.');\n return { errors, revisedSequences: null };\n }\n }, [fasta, loculusService, metaData, rawFasta, urlService]);\n const previewMetadataRows = validation.revisedSequences?.metadata\n .split('\\n')\n .slice(1)\n .filter((row) => row.length > 0)\n .reduce<{ key: string; values: string[] }[]>((rows, row) => {\n const occurrence = rows.filter((existingRow) => existingRow.key.startsWith(`${row}-`)).length;\n rows.push({ key: `${row}-${occurrence}`, values: row.split('\\t') });\n return rows;\n }, []);\n\n const onClickUpload = useCallback(async () => {\n if (validation.errors.length > 0 || !validation.revisedSequences || !metaData || !urlService.hasReturnParams()) {\n return;\n }\n\n setUploadError(null);\n setIsUploading(true);\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n try {\n const { organism, returnUrl } = urlService.data;\n await loculusService.reviseSequences(fasta, metaData, returnUrl, organism, abortController);\n setDidUpload(true);\n } catch (error: unknown) {\n if (!abortController.signal.aborted) {\n setUploadError(error instanceof Error ? error.message : 'Failed to upload sequences to Loculus.');\n }\n } finally {\n if (!abortController.signal.aborted) {\n abortControllerRef.current = null;\n setIsUploading(false);\n }\n }\n }, [fasta, loculusService, metaData, urlService, validation.errors.length, validation.revisedSequences]);\n\n const onCancelUpload = useCallback(() => {\n abortControllerRef.current?.abort();\n abortControllerRef.current = null;\n setIsUploading(false);\n onClose?.();\n }, [onClose]);\n\n useEffect(() => {\n const actions: DialogAction[] = didUpload\n ? [{\n label: 'Close tab',\n onClick: () => window.close(),\n variant: 'contained',\n }]\n : [\n ...(isUploading ? [{\n label: 'Cancel',\n onClick: onCancelUpload,\n variant: 'outlined' as const,\n }] : []),\n {\n disabled: isUploading || validation.errors.length > 0 || validation.revisedSequences === null,\n label: uploadError ? 'Try again' : 'Upload',\n onClick: onClickUpload,\n variant: 'contained',\n },\n ];\n onActionsChange?.(actions);\n }, [didUpload, isUploading, onActionsChange, onCancelUpload, onClickUpload, uploadError, validation.errors.length, validation.revisedSequences]);\n\n return (\n <Box sx={{ display: 'grid', gap: 2, position: 'relative' }}>\n {isUploading ? (\n <Spinner\n inline\n label={'Uploading sequences to Loculus'}\n />\n ) : (\n <>\n {validation.errors.length > 0 && (\n <Alert severity={'error'}>\n {validation.errors.join(' ')}\n </Alert>\n )}\n {uploadError && (\n <Alert severity={'error'}>\n {uploadError}\n </Alert>\n )}\n {didUpload && (\n <Alert severity={'success'}>\n {'Sequences successfully uploaded to Loculus. You can close this tab.'}\n </Alert>\n )}\n {!didUpload && validation.revisedSequences && (\n <>\n <Alert severity={'info'}>\n {`${validation.revisedSequences.sequenceCount} sequence(s) and the matching metadata will be uploaded to Loculus.`}\n </Alert>\n {validation.revisedSequences.removedSequences.length > 0 && (\n <Alert severity={'warning'}>\n {`Sequences removed during editing and therefore not uploaded: ${validation.revisedSequences.removedSequences.length}`}\n </Alert>\n )}\n {validation.revisedSequences.addedSequencesWithoutMetadata.length > 0 && (\n <Alert severity={'warning'}>\n {`Added sequences without matching metadata will not be uploaded: ${validation.revisedSequences.addedSequencesWithoutMetadata.length}`}\n </Alert>\n )}\n <TableContainer\n component={Paper}\n sx={{ maxHeight: '400px', overflowX: 'auto' }}\n >\n <Table\n size={'small'}\n stickyHeader\n sx={{ minWidth: '100%', whiteSpace: 'nowrap', width: 'max-content' }}\n >\n <TableHead>\n <TableRow>\n {metaData?.columns.map((column) => (\n <TableCell key={column}>\n {column}\n </TableCell>\n ))}\n </TableRow>\n </TableHead>\n <TableBody>\n {previewMetadataRows?.map(({ key, values }) => (\n <TableRow key={key}>\n {values.map((value, columnIndex) => (\n <TableCell key={`${key}-${metaData?.columns[columnIndex] ?? columnIndex}`}>\n {value}\n </TableCell>\n ))}\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </TableContainer>\n </>\n )}\n </>\n )}\n </Box>\n );\n}, {\n defaultTitle: 'Upload to Loculus',\n fullWidth: true,\n maxWidth: 'md',\n testId: 'UploadToLoculusModal',\n});\n"],"mappings":";;;;;;;;;;AA6CA,IAAaC,IAAuBC,GAAsE,EACxG,oBACA,YACA,mBAC6C;CAC7C,IAAMC,IAAiBC,QAAcC,EAAU,QAAQC,CAAc,GAAG,CAAC,CAAC,GACpEC,IAAaH,QAAcC,EAAU,QAAQG,CAAU,GAAG,CAAC,CAAC,GAC5D,CAACC,GAAaC,KAAkBC,EAAS,EAAK,GAC9C,CAACC,GAAWC,KAAgBF,EAAS,EAAK,GAC1C,CAACG,GAAaC,KAAkBJ,EAAwB,IAAI,GAC5DK,IAAqBC,EAA+B,IAAI,GAExDC,IAAQC,GAAW,SAAS,IAC5BC,IAAWD,GAAW,YAAY,MAClCE,IAAWF,GAAW,YAAY;CAExC,cAAsB;EACpB,EAAmB,SAAS,MAAM;CACpC,GAAG,CAAC,CAAC;CAEL,IAAMG,IAAalB,QAAc;EAC/B,IAAMmB,IAAmB,CAAC;EAO1B,AANKpB,EAAe,KAAK,iBACvBoB,EAAO,KAAK,iDAAiD,GAE1DhB,EAAW,gBAAgB,KAC9BgB,EAAO,KAAK,uDAAuD,GAEhEH,KACHG,EAAO,KAAK,2CAA2C;EAGzD,IAAMC,IAAcC,EAAU,WAAWP,CAAK;EAW9C,IAVIM,EAAY,QACdD,EAAO,KAAKC,EAAY,KAAK,IACpBA,EAAY,UAAU,WAAW,KAC1CD,EAAO,KAAK,0CAA0C,GAGpDH,GAAU,SACZG,EAAO,KAAKH,EAAS,KAAK,GAGxBG,EAAO,SAAS,KAAK,CAACH,GACxB,OAAO;GAAE;GAAQ,kBAAkB;EAAK;EAG1C,IAAI;GACF,IAAMM,IAAmBpB,EAAe,uBAAuBY,GAAOE,GAAUC,CAAQ;GAIxF,OAHIK,EAAiB,kBAAkB,KACrCH,EAAO,KAAK,wCAAwC,GAE/C;IACL;IACA;GACF;EACF,SAASI,GAAgB;GAEvB,OADAJ,EAAO,KAAKI,aAAiB,QAAQA,EAAM,UAAU,uCAAuC,GACrF;IAAE;IAAQ,kBAAkB;GAAK;EAC1C;CACF,GAAG;EAACT;EAAOf;EAAgBiB;EAAUC;EAAUd;CAAU,CAAC,GACpDqB,IAAsBN,EAAW,kBAAkB,SACtD,MAAM,IAAI,CAAC,CACX,MAAM,CAAC,CAAC,CACR,QAAQ,MAAQO,EAAI,SAAS,CAAC,CAAC,CAC/B,QAA6C,GAAM,MAAQ;EAC1D,IAAMC,IAAaC,EAAK,QAAQ,MAAgBC,EAAY,IAAI,WAAW,GAAGH,EAAI,EAAE,CAAC,CAAC,CAAC;EAEvF,OADAE,EAAK,KAAK;GAAE,KAAK,GAAGF,EAAI,GAAGC;GAAc,QAAQD,EAAI,MAAM,GAAI;EAAE,CAAC,GAC3DE;CACT,GAAG,CAAC,CAAC,GAEDE,IAAgBC,EAAY,YAAY;EAC5C,IAAIZ,EAAW,OAAO,SAAS,KAAK,CAACA,EAAW,oBAAoB,CAACF,KAAY,CAACb,EAAW,gBAAgB,GAC3G;EAIF,AADAQ,EAAe,IAAI,GACnBL,EAAe,EAAI;EACnB,IAAMyB,IAAkB,IAAI,gBAAgB;EAC5C,EAAmB,UAAUA;EAC7B,IAAI;GACF,IAAM,EAAE,aAAU,iBAAc5B,EAAW;GAE3C,AADA,MAAMJ,EAAe,gBAAgBe,GAAOE,GAAUgB,GAAWC,GAAUF,CAAe,GAC1FtB,EAAa,EAAI;EACnB,SAASc,GAAgB;GACvB,AAAKQ,EAAgB,OAAO,WAC1BpB,EAAeY,aAAiB,QAAQA,EAAM,UAAU,wCAAwC;EAEpG,UAAU;GACR,AAAKQ,EAAgB,OAAO,YAC1B,EAAmB,UAAU,MAC7BzB,EAAe,EAAK;EAExB;CACF,GAAG;EAACQ;EAAOf;EAAgBiB;EAAUb;EAAYe,EAAW,OAAO;EAAQA,EAAW;CAAgB,CAAC,GAEjGgB,IAAiBJ,QAAkB;EAIvC,AAHAlB,EAAmB,SAAS,MAAM,GAClC,EAAmB,UAAU,MAC7BN,EAAe,EAAK,GACpB6B,IAAU;CACZ,GAAG,CAACA,CAAO,CAAC;CAyBZ,OAvBAC,QAAgB;EACd,IAAMC,IAA0B7B,IAC5B,CAAC;GACD,OAAO;GACP,eAAe,OAAO,MAAM;GAC5B,SAAS;EACX,CAAC,IACC,CACA,GAAIH,IAAc,CAAC;GACjB,OAAO;GACP,SAAS6B;GACT,SAAS;EACX,CAAC,IAAI,CAAC,GACN;GACE,UAAU7B,KAAea,EAAW,OAAO,SAAS,KAAKA,EAAW,qBAAqB;GACzF,OAAOR,IAAc,cAAc;GACnC,SAASmB;GACT,SAAS;EACX,CACF;EACF,IAAkBQ,CAAO;CAC3B,GAAG;EAAC7B;EAAWH;EAAaiC;EAAiBJ;EAAgBL;EAAenB;EAAaQ,EAAW,OAAO;EAAQA,EAAW;CAAgB,CAAC,GAG7I,kBAACqB,GAAD;EAAK,IAAI;GAAE,SAAS;GAAQ,KAAK;GAAG,UAAU;EAAW;EACtD,UAAAlC,IACC,kBAACmC,GAAD;GACE,QAAA;GACA,OAAO;EACR,CAAA,IAED,kBAAA5C,GAAA,EAAA,UAAA;GACGsB,EAAW,OAAO,SAAS,KAC1B,kBAACwB,GAAD;IAAO,UAAU;IACd,UAAAxB,EAAW,OAAO,KAAK,GAAG;GACtB,CAAA;GAERR,KACC,kBAACgC,GAAD;IAAO,UAAU;IACd,UAAAhC;GACI,CAAA;GAERF,KACC,kBAACkC,GAAD;IAAO,UAAU;IACd,UAAA;GACI,CAAA;GAER,CAAClC,KAAaU,EAAW,oBACxB,kBAAAtB,GAAA,EAAA,UAAA;IACE,kBAAC8C,GAAD;KAAO,UAAU;KACd,UAAA,GAAGxB,EAAW,iBAAiB,cAAc;IACzC,CAAA;IACNA,EAAW,iBAAiB,iBAAiB,SAAS,KACrD,kBAACwB,GAAD;KAAO,UAAU;KACd,UAAA,gEAAgExB,EAAW,iBAAiB,iBAAiB;IACzG,CAAA;IAERA,EAAW,iBAAiB,8BAA8B,SAAS,KAClE,kBAACwB,GAAD;KAAO,UAAU;KACd,UAAA,mEAAmExB,EAAW,iBAAiB,8BAA8B;IACzH,CAAA;IAET,kBAACyB,GAAD;KACE,WAAWC;KACX,IAAI;MAAE,WAAW;MAAS,WAAW;KAAO;KAE5C,UAAA,kBAACC,GAAD;MACE,MAAM;MACN,cAAA;MACA,IAAI;OAAE,UAAU;OAAQ,YAAY;OAAU,OAAO;MAAc;MAHrE,UAAA,CAKE,kBAACC,GAAD,EAAA,UACE,kBAACC,GAAD,EAAA,UACG/B,GAAU,QAAQ,KAAK,MACtB,kBAACgC,GAAD,EAAA,UACGC,EACQ,GAFKA,CAEL,CACZ,EACO,CAAA,EACD,CAAA,GACX,kBAACC,GAAD,EAAA,UACG1B,GAAqB,KAAK,EAAE,QAAK,gBAChC,kBAACuB,GAAD,EAAA,UACGI,EAAO,KAAK,GAAO,MAClB,kBAACH,GAAD,EAAA,UACGI,EACQ,GAFK,GAAGC,EAAI,GAAGrC,GAAU,QAAQsC,MAAgBA,GAEjD,CACZ,EACO,GANKD,CAML,CACX,EACQ,CAAA,CACN;;IACO,CAAA;GAChB,EAAA,CAAA;EAEJ,EAAA,CAAA;CAED,CAAA;AAET,GAAG;CACD,cAAc;CACd,WAAW;CACX,UAAU;CACV,QAAQ;AACV,CAAC"}
|
|
@@ -38,12 +38,13 @@ var f = a(e, {
|
|
|
38
38
|
horizontal: "right",
|
|
39
39
|
vertical: "top"
|
|
40
40
|
},
|
|
41
|
-
children: m.map(({
|
|
41
|
+
children: m.map(({ disabled: e, icon: r, label: a, onClick: o }) => /* @__PURE__ */ l(i, {
|
|
42
|
+
disabled: e,
|
|
42
43
|
onClick: () => {
|
|
43
|
-
x(),
|
|
44
|
+
x(), o();
|
|
44
45
|
},
|
|
45
|
-
children: [/* @__PURE__ */ c(t, { children:
|
|
46
|
-
},
|
|
46
|
+
children: [/* @__PURE__ */ c(t, { children: r }), /* @__PURE__ */ c(n, { primary: a })]
|
|
47
|
+
}, a))
|
|
47
48
|
})] });
|
|
48
49
|
};
|
|
49
50
|
export { p as ButtonWithMenu };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["_Fragment","ButtonWithMenuButton","styled","Button","ButtonWithMenu","useThemeProps","inProps","anchorElement","setAnchorElement","useState","isMenuOpen","onClickMenu","useCallback","event","onCloseMenu","Fragment","buttonColor","label","Menu","items","itemLabel","MenuItem","onClick","ListItemIcon","icon","ListItemText"],"sources":["../../../../src/components/ui/ButtonWithMenu/ButtonWithMenu.tsx"],"sourcesContent":["import {\n Button,\n ListItemIcon,\n ListItemText,\n Menu,\n MenuItem,\n styled,\n useThemeProps,\n} from '@mui/material';\nimport type { ButtonOwnProps } from '@mui/material';\nimport type {\n ComponentsOverrides,\n Theme,\n} from '@mui/material/styles';\nimport {\n useCallback,\n useState,\n} from 'react';\nimport type {\n MouseEvent,\n ReactElement,\n} from 'react';\n\nexport type ButtonWithMenuProps = {\n buttonColor?: ButtonOwnProps['color'];\n disabled?: boolean;\n items: Array<{\n icon: ReactElement;\n label: string;\n onClick: () => void;\n }>;\n label: string;\n startIcon?: ReactElement;\n};\n\nexport type ButtonWithMenuTheme = {\n styleOverrides?: ComponentsOverrides<Theme>['MuiButton'];\n};\n\nconst ButtonWithMenuButton = styled(Button, {\n name: 'RivmLoculusToolsCommonFrontendButtonWithMenu',\n slot: 'Root',\n})({\n '&:hover': {\n backgroundColor: 'rgba(255, 255, 255, 0.25)',\n },\n backgroundColor: 'rgba(255, 255, 255, 0.15)',\n color: '#FFFFFF',\n});\n\nexport const ButtonWithMenu = (inProps: ButtonWithMenuProps) => {\n const {\n buttonColor = 'inherit',\n disabled,\n items,\n label,\n startIcon,\n } = useThemeProps({ name: 'RivmLoculusToolsCommonFrontendButtonWithMenu', props: inProps });\n const [anchorElement, setAnchorElement] = useState<HTMLElement | null>(null);\n const isMenuOpen = Boolean(anchorElement);\n\n const onClickMenu = useCallback((event: MouseEvent<HTMLButtonElement>) => {\n setAnchorElement(event.currentTarget);\n }, []);\n\n const onCloseMenu = useCallback(() => {\n setAnchorElement(null);\n }, []);\n\n return (\n <>\n <ButtonWithMenuButton\n color={buttonColor}\n disabled={disabled}\n onClick={onClickMenu}\n size={'small'}\n startIcon={startIcon}\n variant={'contained'}\n >\n {label}\n </ButtonWithMenuButton>\n <Menu\n anchorEl={anchorElement}\n anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}\n onClose={onCloseMenu}\n open={isMenuOpen}\n transformOrigin={{ horizontal: 'right', vertical: 'top' }}\n >\n {items.map(({ icon, label: itemLabel, onClick }) => (\n <MenuItem\n key={itemLabel}\n // eslint-disable-next-line @eslint-react/kit/jsx-no-bind\n onClick={() => {\n onCloseMenu();\n onClick();\n }}\n >\n <ListItemIcon>\n {icon}\n </ListItemIcon>\n <ListItemText primary={itemLabel} />\n </MenuItem>\n ))}\n </Menu>\n </>\n );\n};\n"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"index.js","names":["_Fragment","ButtonWithMenuButton","styled","Button","ButtonWithMenu","useThemeProps","inProps","anchorElement","setAnchorElement","useState","isMenuOpen","onClickMenu","useCallback","event","onCloseMenu","Fragment","buttonColor","label","Menu","items","itemDisabled","itemLabel","MenuItem","onClick","ListItemIcon","icon","ListItemText"],"sources":["../../../../src/components/ui/ButtonWithMenu/ButtonWithMenu.tsx"],"sourcesContent":["import {\n Button,\n ListItemIcon,\n ListItemText,\n Menu,\n MenuItem,\n styled,\n useThemeProps,\n} from '@mui/material';\nimport type { ButtonOwnProps } from '@mui/material';\nimport type {\n ComponentsOverrides,\n Theme,\n} from '@mui/material/styles';\nimport {\n useCallback,\n useState,\n} from 'react';\nimport type {\n MouseEvent,\n ReactElement,\n} from 'react';\n\nexport type ButtonWithMenuProps = {\n buttonColor?: ButtonOwnProps['color'];\n disabled?: boolean;\n items: Array<{\n disabled?: boolean;\n icon: ReactElement;\n label: string;\n onClick: () => void;\n }>;\n label: string;\n startIcon?: ReactElement;\n};\n\nexport type ButtonWithMenuTheme = {\n styleOverrides?: ComponentsOverrides<Theme>['MuiButton'];\n};\n\nconst ButtonWithMenuButton = styled(Button, {\n name: 'RivmLoculusToolsCommonFrontendButtonWithMenu',\n slot: 'Root',\n})({\n '&:hover': {\n backgroundColor: 'rgba(255, 255, 255, 0.25)',\n },\n backgroundColor: 'rgba(255, 255, 255, 0.15)',\n color: '#FFFFFF',\n});\n\nexport const ButtonWithMenu = (inProps: ButtonWithMenuProps) => {\n const {\n buttonColor = 'inherit',\n disabled,\n items,\n label,\n startIcon,\n } = useThemeProps({ name: 'RivmLoculusToolsCommonFrontendButtonWithMenu', props: inProps });\n const [anchorElement, setAnchorElement] = useState<HTMLElement | null>(null);\n const isMenuOpen = Boolean(anchorElement);\n\n const onClickMenu = useCallback((event: MouseEvent<HTMLButtonElement>) => {\n setAnchorElement(event.currentTarget);\n }, []);\n\n const onCloseMenu = useCallback(() => {\n setAnchorElement(null);\n }, []);\n\n return (\n <>\n <ButtonWithMenuButton\n color={buttonColor}\n disabled={disabled}\n onClick={onClickMenu}\n size={'small'}\n startIcon={startIcon}\n variant={'contained'}\n >\n {label}\n </ButtonWithMenuButton>\n <Menu\n anchorEl={anchorElement}\n anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}\n onClose={onCloseMenu}\n open={isMenuOpen}\n transformOrigin={{ horizontal: 'right', vertical: 'top' }}\n >\n {items.map(({ disabled: itemDisabled, icon, label: itemLabel, onClick }) => (\n <MenuItem\n disabled={itemDisabled}\n key={itemLabel}\n // eslint-disable-next-line @eslint-react/kit/jsx-no-bind\n onClick={() => {\n onCloseMenu();\n onClick();\n }}\n >\n <ListItemIcon>\n {icon}\n </ListItemIcon>\n <ListItemText primary={itemLabel} />\n </MenuItem>\n ))}\n </Menu>\n </>\n );\n};\n"],"mappings":";;;;AAwCA,IAAMC,IAAuBC,EAAOC,GAAQ;CAC1C,MAAM;CACN,MAAM;AACR,CAAC,CAAC,CAAC;CACD,WAAW,EACT,iBAAiB,4BACnB;CACA,iBAAiB;CACjB,OAAO;AACT,CAAC,GAEYC,KAAkB,MAAiC;CAC9D,IAAM,EACJ,iBAAc,WACd,aACA,UACA,UACA,iBACEC,EAAc;EAAE,MAAM;EAAgD,OAAOC;CAAQ,CAAC,GACpF,CAACC,GAAeC,KAAoBC,EAA6B,IAAI,GACrEC,IAAa,EAAQH,GAErBI,IAAcC,GAAa,MAAyC;EACxE,EAAiBC,EAAM,aAAa;CACtC,GAAG,CAAC,CAAC,GAECC,IAAcF,QAAkB;EACpC,EAAiB,IAAI;CACvB,GAAG,CAAC,CAAC;CAEL,OACE,kBAAAZ,GAAA,EAAA,UAAA,CACE,kBAACC,GAAD;EACE,OAAOe;EACG;EACV,SAASL;EACT,MAAM;EACK;EACX,SAAS;EAER,UAAAM;CACmB,CAAA,GACtB,kBAACC,GAAD;EACE,UAAUX;EACV,cAAc;GAAE,YAAY;GAAS,UAAU;EAAS;EACxD,SAASO;EACT,MAAMJ;EACN,iBAAiB;GAAE,YAAY;GAAS,UAAU;EAAM;EAEvD,UAAAS,EAAM,KAAK,EAAE,UAAUC,GAAc,SAAM,OAAOC,GAAW,iBAC5D,kBAACC,GAAD;GACE,UAAUF;GAGV,eAAe;IAEb,AADAN,EAAY,GACZS,EAAQ;GACV;GAPF,UAAA,CASE,kBAACC,GAAD,EAAA,UACGC,EACW,CAAA,GACd,kBAACC,GAAD,EAAc,SAASL,EAAY,CAAA,CAC3B;EAXH,GAAAA,CAWG,CACX;CACG,CAAA,CACN,EAAA,CAAA;AAEN"}
|
|
@@ -9,20 +9,32 @@ import { use as s, useEffect as c } from "react";
|
|
|
9
9
|
var l = ({ children: l, isNoInteraction: u, title: d }) => {
|
|
10
10
|
let { drawerComponent: f, headerComponent: p } = t();
|
|
11
11
|
n(d);
|
|
12
|
-
let m = i(), {
|
|
12
|
+
let m = i(), { drawerButtonId: h, drawerContainerId: g, isDrawerOpen: _, setIsDrawerOpen: v, setIsNoInteraction: y } = s(e);
|
|
13
13
|
return c(() => {
|
|
14
|
-
|
|
15
|
-
}, [u,
|
|
14
|
+
y(!!u);
|
|
15
|
+
}, [u, y]), c(() => {
|
|
16
|
+
let e = (e) => {
|
|
17
|
+
e.key === "Escape" && _ && document.getElementById(g)?.contains(document.activeElement) && (v(!1), document.getElementById(h)?.focus());
|
|
18
|
+
};
|
|
19
|
+
return document.addEventListener("keydown", e), () => {
|
|
20
|
+
document.removeEventListener("keydown", e);
|
|
21
|
+
};
|
|
22
|
+
}, [
|
|
23
|
+
h,
|
|
24
|
+
g,
|
|
25
|
+
_,
|
|
26
|
+
v
|
|
27
|
+
]), /* @__PURE__ */ o(r, {
|
|
16
28
|
sx: {
|
|
17
29
|
display: "grid",
|
|
18
|
-
gridTemplateRows: "max-content auto",
|
|
30
|
+
gridTemplateRows: p ? "max-content auto" : "auto",
|
|
19
31
|
height: "100vh",
|
|
20
32
|
overflow: "hidden",
|
|
21
33
|
position: "relative",
|
|
22
34
|
width: "100vw"
|
|
23
35
|
},
|
|
24
36
|
children: [p && /* @__PURE__ */ a(p, {}), /* @__PURE__ */ o(r, {
|
|
25
|
-
id:
|
|
37
|
+
id: g,
|
|
26
38
|
sx: {
|
|
27
39
|
display: "flex",
|
|
28
40
|
flex: 1,
|
|
@@ -36,13 +48,14 @@ var l = ({ children: l, isNoInteraction: u, title: d }) => {
|
|
|
36
48
|
sx: {
|
|
37
49
|
flexGrow: 1,
|
|
38
50
|
height: "100%",
|
|
51
|
+
marginLeft: _ ? "540px" : 0,
|
|
39
52
|
overflow: "hidden",
|
|
40
53
|
position: "relative",
|
|
41
54
|
transition: () => m.transitions.create(["margin", "width"], {
|
|
42
55
|
duration: m.transitions.duration.leavingScreen,
|
|
43
56
|
easing: m.transitions.easing.sharp
|
|
44
57
|
}),
|
|
45
|
-
width:
|
|
58
|
+
width: _ ? "calc(100% - 540px)" : "100%"
|
|
46
59
|
},
|
|
47
60
|
children: l
|
|
48
61
|
})]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["PageCommon","DrawerComponent","HeaderComponent","useConfig","title","theme","useTheme","use","PageCommonContext","useEffect","isNoInteraction","setIsNoInteraction","
|
|
1
|
+
{"version":3,"file":"index.js","names":["PageCommon","DrawerComponent","HeaderComponent","useConfig","title","theme","useTheme","use","PageCommonContext","useEffect","isNoInteraction","setIsNoInteraction","handleKeyDown","event","isDrawerOpen","drawerContainerId","setIsDrawerOpen","drawerButtonId","Box"],"sources":["../../../../src/components/ui/PageCommon/PageCommon.tsx"],"sourcesContent":["import {\n Box,\n useTheme,\n} from '@mui/material';\nimport {\n use,\n useEffect,\n} from 'react';\nimport type { ReactNode } from 'react';\n\nimport { DRAWER_WIDTH } from '../../../constants/page.constants';\nimport { PageCommonContext } from '../../../context/pageCommonContext';\nimport { useUpdateDocumentTitle } from '../../../hooks/useUpdateDocumentTitle';\nimport { useConfig } from '../../../hooks/useConfig';\n\nexport type PageCommonProps = {\n readonly children: ReactNode;\n readonly isNoInteraction?: boolean;\n readonly title: string;\n};\n\n\nexport const PageCommon = ({ children, isNoInteraction, title }: PageCommonProps) => {\n const { drawerComponent: DrawerComponent, headerComponent: HeaderComponent } = useConfig();\n\n useUpdateDocumentTitle(title);\n const theme = useTheme();\n const { drawerButtonId, drawerContainerId, isDrawerOpen, setIsDrawerOpen, setIsNoInteraction } = use(PageCommonContext);\n\n useEffect(() => {\n setIsNoInteraction(!!isNoInteraction);\n }, [isNoInteraction, setIsNoInteraction]);\n\n\n useEffect(() => {\n // when the focus is inside the drawer and the drawer is open, pressing Escape should close the drawer\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && isDrawerOpen) {\n const drawer = document.getElementById(drawerContainerId);\n if (drawer?.contains(document.activeElement)) {\n setIsDrawerOpen(false);\n document.getElementById(drawerButtonId)?.focus();\n }\n }\n };\n document.addEventListener('keydown', handleKeyDown);\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [drawerButtonId, drawerContainerId, isDrawerOpen, setIsDrawerOpen]);\n\n return (\n <Box\n sx={{\n display: 'grid',\n gridTemplateRows: HeaderComponent ? 'max-content auto' : 'auto',\n height: '100vh',\n overflow: 'hidden',\n position: 'relative',\n width: '100vw',\n }}\n >\n {HeaderComponent && <HeaderComponent />}\n <Box\n id={drawerContainerId}\n sx={{\n display: 'flex',\n flex: 1,\n height: '100%',\n overflow: 'hidden',\n position: 'relative',\n width: '100%',\n }}\n >\n {DrawerComponent && <DrawerComponent />}\n <Box\n component={'main'}\n sx={{\n flexGrow: 1,\n height: '100%',\n marginLeft: isDrawerOpen ? `${DRAWER_WIDTH}px` : 0,\n overflow: 'hidden',\n position: 'relative',\n transition: () =>\n theme.transitions.create(['margin', 'width'], {\n duration: theme.transitions.duration.leavingScreen,\n easing: theme.transitions.easing.sharp,\n }),\n width: isDrawerOpen ? `calc(100% - ${DRAWER_WIDTH}px)` : '100%',\n }}\n >\n {children}\n </Box>\n\n </Box>\n </Box>\n );\n};\n"],"mappings":";;;;;;;;AAsBA,IAAaA,KAAc,EAAE,aAAU,oBAAiB,eAA6B;CACnF,IAAM,EAAE,iBAAiBC,GAAiB,iBAAiBC,MAAoBC,EAAU;CAEzF,EAAuBC,CAAK;CAC5B,IAAMC,IAAQC,EAAS,GACjB,EAAE,mBAAgB,sBAAmB,iBAAc,oBAAiB,0BAAuBC,EAAIC,CAAiB;CAwBtH,OAtBAC,QAAgB;EACd,EAAmB,CAAC,CAACC,CAAe;CACtC,GAAG,CAACA,GAAiBC,CAAkB,CAAC,GAGxCF,QAAgB;EAEd,IAAMG,KAAiB,MAAyB;GAC9C,AAAIC,EAAM,QAAQ,YAAYC,KACb,SAAS,eAAeC,CACnC,CAAA,EAAQ,SAAS,SAAS,aAAa,MACzCC,EAAgB,EAAK,GACrB,SAAS,eAAeC,CAAc,CAAC,EAAE,MAAM;EAGrD;EAEA,OADA,SAAS,iBAAiB,WAAWL,CAAa,SACrC;GACX,SAAS,oBAAoB,WAAWA,CAAa;EACvD;CACF,GAAG;EAACK;EAAgBF;EAAmBD;EAAcE;CAAe,CAAC,GAGnE,kBAACE,GAAD;EACE,IAAI;GACF,SAAS;GACT,kBAAkBhB,IAAkB,qBAAqB;GACzD,QAAQ;GACR,UAAU;GACV,UAAU;GACV,OAAO;EACT;EARF,UAAA,CAUGA,KAAmB,kBAACA,GAAD,CAAkB,CAAA,GACtC,kBAACgB,GAAD;GACE,IAAIH;GACJ,IAAI;IACF,SAAS;IACT,MAAM;IACN,QAAQ;IACR,UAAU;IACV,UAAU;IACV,OAAO;GACT;GATF,UAAA,CAWGd,KAAmB,kBAACA,GAAD,CAAkB,CAAA,GACtC,kBAACiB,GAAD;IACE,WAAW;IACX,IAAI;KACF,UAAU;KACV,QAAQ;KACR,YAAYJ,IAAe,UAAsB;KACjD,UAAU;KACV,UAAU;KACV,kBACET,EAAM,YAAY,OAAO,CAAC,UAAU,OAAO,GAAG;MAC5C,UAAUA,EAAM,YAAY,SAAS;MACrC,QAAQA,EAAM,YAAY,OAAO;KACnC,CAAC;KACH,OAAOS,IAAe,uBAAmC;IAC3D;IAEC;GACE,CAAA,CAEF;EACF,CAAA,CAAA;;AAET"}
|
|
@@ -2,28 +2,36 @@ import "../../../constants/page.constants.js";
|
|
|
2
2
|
import { PageCommonContext as e } from "../../../context/pageCommonContext/index.js";
|
|
3
3
|
import { Drawer as t } from "@mui/material";
|
|
4
4
|
import { jsx as n } from "react/jsx-runtime";
|
|
5
|
-
import { use as r } from "react";
|
|
5
|
+
import { use as r, useEffect as i } from "react";
|
|
6
6
|
// src/components/ui/PageCommonDrawer/PageCommonDrawer.tsx
|
|
7
|
-
var
|
|
8
|
-
let { drawerContainerId:
|
|
9
|
-
return
|
|
7
|
+
var a = ({ children: a }) => {
|
|
8
|
+
let { drawerContainerId: o, isDrawerOpen: s } = r(e);
|
|
9
|
+
return i(() => {
|
|
10
|
+
if (s) {
|
|
11
|
+
let e = document.getElementById(o);
|
|
12
|
+
if (e) {
|
|
13
|
+
let t = e.querySelector("button");
|
|
14
|
+
t && t.focus();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}, [o, s]), /* @__PURE__ */ n(t, {
|
|
10
18
|
anchor: "left",
|
|
11
19
|
ModalProps: {
|
|
12
|
-
container: () => document.getElementById(
|
|
20
|
+
container: () => document.getElementById(o),
|
|
13
21
|
style: { position: "absolute" }
|
|
14
22
|
},
|
|
15
|
-
open:
|
|
23
|
+
open: s,
|
|
16
24
|
sx: { "& .MuiDrawer-paper": {
|
|
17
25
|
flexShrink: 0,
|
|
18
26
|
height: "100%",
|
|
19
27
|
overflowY: "auto",
|
|
20
28
|
position: "absolute",
|
|
21
|
-
width:
|
|
29
|
+
width: s ? 540 : 0
|
|
22
30
|
} },
|
|
23
|
-
variant: "
|
|
24
|
-
children:
|
|
31
|
+
variant: "permanent",
|
|
32
|
+
children: a
|
|
25
33
|
});
|
|
26
34
|
};
|
|
27
|
-
export {
|
|
35
|
+
export { a as PageCommonDrawer };
|
|
28
36
|
|
|
29
37
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["PageCommonDrawer","use","PageCommonContext","
|
|
1
|
+
{"version":3,"file":"index.js","names":["PageCommonDrawer","use","PageCommonContext","useEffect","isDrawerOpen","drawer","drawerContainerId","firstButton","Drawer"],"sources":["../../../../src/components/ui/PageCommonDrawer/PageCommonDrawer.tsx"],"sourcesContent":["import { Drawer } from '@mui/material';\nimport {\n use,\n useEffect,\n} from 'react';\nimport type { ReactNode } from 'react';\n\nimport { DRAWER_WIDTH } from '../../../constants/page.constants';\nimport { PageCommonContext } from '../../../context/pageCommonContext';\n\nexport type PageCommonDrawerProps = {\n readonly children: ReactNode;\n};\n\nexport const PageCommonDrawer = ({ children }: PageCommonDrawerProps) => {\n const { drawerContainerId, isDrawerOpen } = use(PageCommonContext);\n\n useEffect(() => {\n if (isDrawerOpen) {\n // find the first button inside the drawer and focus it\n const drawer = document.getElementById(drawerContainerId);\n if (drawer) {\n const firstButton = drawer.querySelector('button');\n if (firstButton) {\n (firstButton as HTMLElement).focus();\n }\n }\n }\n }, [drawerContainerId, isDrawerOpen]);\n\n return (\n <Drawer\n anchor={'left'}\n ModalProps={{\n container: () => document.getElementById(drawerContainerId),\n style: { position: 'absolute' }, // Forces modal overlay to stay inside the container\n }}\n open={isDrawerOpen}\n sx={{\n '& .MuiDrawer-paper': {\n flexShrink: 0,\n height: '100%',\n overflowY: 'auto',\n position: 'absolute',\n width: isDrawerOpen ? DRAWER_WIDTH : 0,\n },\n }}\n variant={'permanent'}\n >\n {children}\n </Drawer>\n );\n};\n"],"mappings":";;;;;;AAcA,IAAaA,KAAoB,EAAE,kBAAsC;CACvE,IAAM,EAAE,sBAAmB,oBAAiBC,EAAIC,CAAiB;CAejE,OAbAC,QAAgB;EACd,IAAIC,GAAc;GAEhB,IAAMC,IAAS,SAAS,eAAeC,CAAiB;GACxD,IAAID,GAAQ;IACV,IAAME,IAAcF,EAAO,cAAc,QAAQ;IACjD,AAAIE,KACFA,EAA6B,MAAM;GAEvC;EACF;CACF,GAAG,CAACD,GAAmBF,CAAY,CAAC,GAGlC,kBAACI,GAAD;EACE,QAAQ;EACR,YAAY;GACV,iBAAiB,SAAS,eAAeF,CAAiB;GAC1D,OAAO,EAAE,UAAU,WAAW;EAChC;EACA,MAAMF;EACN,IAAI,EACF,sBAAsB;GACpB,YAAY;GACZ,QAAQ;GACR,WAAW;GACX,UAAU;GACV,OAAOA,IAAA,MAA8B;EACvC,EACF;EACA,SAAS;EAER;CACK,CAAA;AAEZ"}
|
|
@@ -12,9 +12,9 @@ var h = (h) => {
|
|
|
12
12
|
backgroundColor: y.palette.primary.main,
|
|
13
13
|
color: y.palette.primary.contrastText,
|
|
14
14
|
...y.components?.RivmLoculusToolsCommonFrontendPageCommonHeader ?? {}
|
|
15
|
-
}), [y]), { afterAppBarComponent: x, afterAppBarRightComponent: S, appBarHeight: C = 48, appBarIcon: w, beforeAppBarComponent: T, beforeAppBarRightComponent: E,
|
|
16
|
-
|
|
17
|
-
}, [
|
|
15
|
+
}), [y]), { afterAppBarComponent: x, afterAppBarRightComponent: S, appBarHeight: C = 48, appBarIcon: w, beforeAppBarComponent: T, beforeAppBarRightComponent: E, drawerButtonId: D, isDrawerOpen: O, isNoInteraction: k, setIsDrawerOpen: A } = d(e), j = f(() => {
|
|
16
|
+
A(!O);
|
|
17
|
+
}, [O, A]);
|
|
18
18
|
return /* @__PURE__ */ u(n, { children: [
|
|
19
19
|
T,
|
|
20
20
|
/* @__PURE__ */ l(t, {
|
|
@@ -41,11 +41,12 @@ var h = (h) => {
|
|
|
41
41
|
gap: 1.5
|
|
42
42
|
},
|
|
43
43
|
children: [
|
|
44
|
-
!
|
|
44
|
+
!k && /* @__PURE__ */ l(r, {
|
|
45
45
|
"aria-label": "open drawer",
|
|
46
46
|
color: "inherit",
|
|
47
47
|
edge: "start",
|
|
48
|
-
|
|
48
|
+
id: D,
|
|
49
|
+
onClick: j,
|
|
49
50
|
size: "small",
|
|
50
51
|
children: /* @__PURE__ */ l(m, {})
|
|
51
52
|
}),
|
|
@@ -63,7 +64,7 @@ var h = (h) => {
|
|
|
63
64
|
children: v
|
|
64
65
|
})
|
|
65
66
|
]
|
|
66
|
-
}), !
|
|
67
|
+
}), !k && /* @__PURE__ */ u(c, { children: [/* @__PURE__ */ l(n, {
|
|
67
68
|
sx: {
|
|
68
69
|
alignItems: "center",
|
|
69
70
|
display: "flex",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["_Fragment","MenuIcon","PageCommonHeader","useThemeProps","inProps","theme","useTheme","pageCommonHeaderTheme","useMemo","use","PageCommonContext","onToggleDrawerButtonClick","useCallback","isDrawerOpen","setIsDrawerOpen","Box","beforeAppBarComponent","AppBar","appBarHeight","Toolbar","isNoInteraction","IconButton","appBarIcon","Fragment","Typography","title","centerComponent","beforeAppBarRightComponent","rightComponent","afterAppBarRightComponent","afterAppBarComponent"],"sources":["../../../../src/components/ui/PageCommonHeader/PageCommonHeader.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport {\n use,\n useCallback,\n useMemo,\n} from 'react';\nimport {\n AppBar,\n Box,\n IconButton,\n Toolbar,\n Typography,\n useTheme,\n useThemeProps,\n} from '@mui/material';\nimport MenuIcon from '@mui/icons-material/Menu';\n\nimport { PageCommonContext } from '../../../context/pageCommonContext';\n\nexport type PageCommonHeaderProps = {\n readonly centerComponent?: ReactNode;\n readonly rightComponent?: ReactNode;\n readonly title: string;\n};\n\nexport interface PageCommonHeaderTheme {\n backgroundColor: string;\n color: string;\n}\n\nexport const PageCommonHeader = (inProps: PageCommonHeaderProps) => {\n const { centerComponent, rightComponent, title } = useThemeProps({ name: 'RivmLoculusToolsCommonFrontendPageCommonHeader', props: inProps });\n const theme = useTheme();\n const pageCommonHeaderTheme = useMemo<PageCommonHeaderTheme>(() => ({\n ...{\n backgroundColor: theme.palette.primary.main,\n color: theme.palette.primary.contrastText,\n } satisfies PageCommonHeaderTheme,\n ...(theme.components?.RivmLoculusToolsCommonFrontendPageCommonHeader ?? {}),\n }), [theme]);\n\n\n const { afterAppBarComponent, afterAppBarRightComponent, appBarHeight = 48, appBarIcon, beforeAppBarComponent, beforeAppBarRightComponent, isDrawerOpen, isNoInteraction, setIsDrawerOpen } = use(PageCommonContext);\n\n const onToggleDrawerButtonClick = useCallback(() => {\n setIsDrawerOpen(!isDrawerOpen);\n }, [isDrawerOpen, setIsDrawerOpen]);\n\n return (\n <Box>\n {beforeAppBarComponent}\n <AppBar\n elevation={1}\n position={'static'}\n sx={{\n backgroundColor: pageCommonHeaderTheme.backgroundColor,\n color: pageCommonHeaderTheme.color,\n height: appBarHeight,\n justifyContent: 'center',\n zIndex: theme.zIndex.drawer + 1,\n }}\n >\n <Toolbar\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n px: `${theme.spacing(1)} !important`, // using !important to override media queries\n }}\n variant={'dense'}\n >\n {/* Left: Menu toggle and App Branding */}\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1.5 }}>\n {!isNoInteraction && (\n <IconButton\n aria-label={'open drawer'}\n color={'inherit'}\n edge={'start'}\n onClick={onToggleDrawerButtonClick}\n size={'small'}\n >\n <MenuIcon />\n </IconButton>\n )}\n {appBarIcon && (\n <>\n {appBarIcon}\n </>\n )}\n <Typography\n component={'div'}\n noWrap\n sx={{ color: 'inherit', fontSize: '1.05rem', fontWeight: 700, letterSpacing: '-0.01em' }}\n variant={'h6'}\n >\n {title}\n </Typography>\n </Box>\n {!isNoInteraction && (\n <>\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1 }}>\n {centerComponent}\n </Box>\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1 }}>\n {beforeAppBarRightComponent && (\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1 }}>\n {beforeAppBarRightComponent}\n </Box>\n )}\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1 }}>\n {rightComponent}\n </Box>\n {afterAppBarRightComponent && (\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1 }}>\n {afterAppBarRightComponent}\n </Box>\n )}\n </Box>\n </>\n )}\n </Toolbar>\n </AppBar>\n {afterAppBarComponent}\n </Box>\n );\n};\n"],"mappings":";;;;;;AA8BA,IAAaE,KAAoB,MAAmC;CAClE,IAAM,EAAE,oBAAiB,mBAAgB,aAAUC,EAAc;EAAE,MAAM;EAAkD,OAAOC;CAAQ,CAAC,GACrIC,IAAQC,EAAS,GACjBC,IAAwBC,SAAsC;EAEhE,iBAAiBH,EAAM,QAAQ,QAAQ;EACvC,OAAOA,EAAM,QAAQ,QAAQ;EAE/B,GAAIA,EAAM,YAAY,kDAAkD,CAAC;CAC3E,IAAI,CAACA,CAAK,CAAC,GAGL,EAAE,yBAAsB,8BAA2B,kBAAe,IAAI,eAAY,0BAAuB,+BAA4B,iBAAc,oBAAiB,uBAAoBI,EAAIC,CAAiB,
|
|
1
|
+
{"version":3,"file":"index.js","names":["_Fragment","MenuIcon","PageCommonHeader","useThemeProps","inProps","theme","useTheme","pageCommonHeaderTheme","useMemo","use","PageCommonContext","onToggleDrawerButtonClick","useCallback","isDrawerOpen","setIsDrawerOpen","Box","beforeAppBarComponent","AppBar","appBarHeight","Toolbar","isNoInteraction","IconButton","drawerButtonId","appBarIcon","Fragment","Typography","title","centerComponent","beforeAppBarRightComponent","rightComponent","afterAppBarRightComponent","afterAppBarComponent"],"sources":["../../../../src/components/ui/PageCommonHeader/PageCommonHeader.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport {\n use,\n useCallback,\n useMemo,\n} from 'react';\nimport {\n AppBar,\n Box,\n IconButton,\n Toolbar,\n Typography,\n useTheme,\n useThemeProps,\n} from '@mui/material';\nimport MenuIcon from '@mui/icons-material/Menu';\n\nimport { PageCommonContext } from '../../../context/pageCommonContext';\n\nexport type PageCommonHeaderProps = {\n readonly centerComponent?: ReactNode;\n readonly rightComponent?: ReactNode;\n readonly title: string;\n};\n\nexport interface PageCommonHeaderTheme {\n backgroundColor: string;\n color: string;\n}\n\nexport const PageCommonHeader = (inProps: PageCommonHeaderProps) => {\n const { centerComponent, rightComponent, title } = useThemeProps({ name: 'RivmLoculusToolsCommonFrontendPageCommonHeader', props: inProps });\n const theme = useTheme();\n const pageCommonHeaderTheme = useMemo<PageCommonHeaderTheme>(() => ({\n ...{\n backgroundColor: theme.palette.primary.main,\n color: theme.palette.primary.contrastText,\n } satisfies PageCommonHeaderTheme,\n ...(theme.components?.RivmLoculusToolsCommonFrontendPageCommonHeader ?? {}),\n }), [theme]);\n\n\n const { afterAppBarComponent, afterAppBarRightComponent, appBarHeight = 48, appBarIcon, beforeAppBarComponent, beforeAppBarRightComponent, drawerButtonId, isDrawerOpen, isNoInteraction, setIsDrawerOpen } = use(PageCommonContext);\n\n const onToggleDrawerButtonClick = useCallback(() => {\n setIsDrawerOpen(!isDrawerOpen);\n }, [isDrawerOpen, setIsDrawerOpen]);\n\n return (\n <Box>\n {beforeAppBarComponent}\n <AppBar\n elevation={1}\n position={'static'}\n sx={{\n backgroundColor: pageCommonHeaderTheme.backgroundColor,\n color: pageCommonHeaderTheme.color,\n height: appBarHeight,\n justifyContent: 'center',\n zIndex: theme.zIndex.drawer + 1,\n }}\n >\n <Toolbar\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n px: `${theme.spacing(1)} !important`, // using !important to override media queries\n }}\n variant={'dense'}\n >\n {/* Left: Menu toggle and App Branding */}\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1.5 }}>\n {!isNoInteraction && (\n <IconButton\n aria-label={'open drawer'}\n color={'inherit'}\n edge={'start'}\n id={drawerButtonId}\n onClick={onToggleDrawerButtonClick}\n size={'small'}\n >\n <MenuIcon />\n </IconButton>\n )}\n {appBarIcon && (\n <>\n {appBarIcon}\n </>\n )}\n <Typography\n component={'div'}\n noWrap\n sx={{ color: 'inherit', fontSize: '1.05rem', fontWeight: 700, letterSpacing: '-0.01em' }}\n variant={'h6'}\n >\n {title}\n </Typography>\n </Box>\n {!isNoInteraction && (\n <>\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1 }}>\n {centerComponent}\n </Box>\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1 }}>\n {beforeAppBarRightComponent && (\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1 }}>\n {beforeAppBarRightComponent}\n </Box>\n )}\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1 }}>\n {rightComponent}\n </Box>\n {afterAppBarRightComponent && (\n <Box sx={{ alignItems: 'center', display: 'flex', gap: 1 }}>\n {afterAppBarRightComponent}\n </Box>\n )}\n </Box>\n </>\n )}\n </Toolbar>\n </AppBar>\n {afterAppBarComponent}\n </Box>\n );\n};\n"],"mappings":";;;;;;AA8BA,IAAaE,KAAoB,MAAmC;CAClE,IAAM,EAAE,oBAAiB,mBAAgB,aAAUC,EAAc;EAAE,MAAM;EAAkD,OAAOC;CAAQ,CAAC,GACrIC,IAAQC,EAAS,GACjBC,IAAwBC,SAAsC;EAEhE,iBAAiBH,EAAM,QAAQ,QAAQ;EACvC,OAAOA,EAAM,QAAQ,QAAQ;EAE/B,GAAIA,EAAM,YAAY,kDAAkD,CAAC;CAC3E,IAAI,CAACA,CAAK,CAAC,GAGL,EAAE,yBAAsB,8BAA2B,kBAAe,IAAI,eAAY,0BAAuB,+BAA4B,mBAAgB,iBAAc,oBAAiB,uBAAoBI,EAAIC,CAAiB,GAE7NC,IAA4BC,QAAkB;EAClD,EAAgB,CAACC,CAAY;CAC/B,GAAG,CAACA,GAAcC,CAAe,CAAC;CAElC,OACE,kBAACC,GAAD,EAAA,UAAA;EACGC;EACD,kBAACC,GAAD;GACE,WAAW;GACX,UAAU;GACV,IAAI;IACF,iBAAiBV,EAAsB;IACvC,OAAOA,EAAsB;IAC7B,QAAQW;IACR,gBAAgB;IAChB,QAAQb,EAAM,OAAO,SAAS;GAChC;GAEA,UAAA,kBAACc,GAAD;IACE,IAAI;KACF,SAAS;KACT,gBAAgB;KAChB,IAAI,GAAGd,EAAM,QAAQ,CAAC,EAAE;IAC1B;IACA,SAAS;IANX,UAAA,CASE,kBAACU,GAAD;KAAK,IAAI;MAAE,YAAY;MAAU,SAAS;MAAQ,KAAK;KAAI;KAA3D,UAAA;MACG,CAACK,KACA,kBAACC,GAAD;OACE,cAAY;OACZ,OAAO;OACP,MAAM;OACN,IAAIC;OACJ,SAASX;OACT,MAAM;OAEN,UAAA,kBAACV,GAAD,CAAW,CAAA;MACD,CAAA;MAEbsB,KACC,kBAAAvB,GAAA,EAAA,UACGuB,EACD,CAAA;MAEJ,kBAACE,GAAD;OACE,WAAW;OACX,QAAA;OACA,IAAI;QAAE,OAAO;QAAW,UAAU;QAAW,YAAY;QAAK,eAAe;OAAU;OACvF,SAAS;OAER,UAAAC;MACS,CAAA;KACT;IACJ,CAAA,GAAA,CAACN,KACA,kBAAApB,GAAA,EAAA,UAAA,CACE,kBAACe,GAAD;KAAK,IAAI;MAAE,YAAY;MAAU,SAAS;MAAQ,KAAK;KAAE;KACtD,UAAAY;IACE,CAAA,GACL,kBAACZ,GAAD;KAAK,IAAI;MAAE,YAAY;MAAU,SAAS;MAAQ,KAAK;KAAE;KAAzD,UAAA;MACGa,KACC,kBAACb,GAAD;OAAK,IAAI;QAAE,YAAY;QAAU,SAAS;QAAQ,KAAK;OAAE;OACtD,UAAAa;MACE,CAAA;MAEP,kBAACb,GAAD;OAAK,IAAI;QAAE,YAAY;QAAU,SAAS;QAAQ,KAAK;OAAE;OACtD,UAAAc;MACE,CAAA;MACJC,KACC,kBAACf,GAAD;OAAK,IAAI;QAAE,YAAY;QAAU,SAAS;QAAQ,KAAK;OAAE;OACtD,UAAAe;MACE,CAAA;KAEJ;IACL,CAAA,CAAA,EAAA,CAAA,CAEG;;EACH,CAAA;EACPC;CACE,EAAA,CAAA;AAET"}
|