lhcb-ntuple-wizard-test 2.0.5 → 2.0.7

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.
@@ -1,9 +1 @@
1
- import { RowData } from "../models/rowData";
2
- interface Props {
3
- row: RowData;
4
- hideDownloadButtons: boolean;
5
- hideUploadButtons: boolean;
6
- basePath: string;
7
- }
8
- export declare function DttNameInput({ row, hideDownloadButtons, hideUploadButtons, basePath }: Props): import("react/jsx-runtime").JSX.Element | null;
9
- export {};
1
+ export declare function DttNameInput(): import("react/jsx-runtime").JSX.Element | null;
@@ -12,10 +12,14 @@ import { downloadText } from "../utils/utils";
12
12
  import { YamlFile } from "../models/yamlFile";
13
13
  import { UploadDttConfigModal } from "./modals/UploadDttConfigModal";
14
14
  import { VARIABLES_PATH } from "../constants";
15
- export function DttNameInput({ row, hideDownloadButtons, hideUploadButtons, basePath }) {
15
+ import { useRow } from "../providers/RowProvider";
16
+ import { useWizardConfig } from "../providers/WizardConfigProvider";
17
+ export function DttNameInput() {
18
+ const { row } = useRow();
16
19
  const { rows, updateRow } = useRows();
17
20
  const navigate = useNavigate();
18
21
  const metadata = useMetadata();
22
+ const { basePath, variant } = useWizardConfig();
19
23
  const [showUploadModal, setShowUploadModal] = useState(false);
20
24
  const [dttName, setDttName] = useState(row.dtt?.getName() || "");
21
25
  const [dttNameValid, setDttNameValid] = useState(true);
@@ -65,7 +69,7 @@ export function DttNameInput({ row, hideDownloadButtons, hideUploadButtons, base
65
69
  ? "Name cannot be empty"
66
70
  : !allNameCharsValid(dttName.trim())
67
71
  ? "Name contains invalid characters"
68
- : "Name is already taken" })] })), _jsx(ButtonGroup, { children: row.dtt ? (_jsxs(_Fragment, { children: [_jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: "Configure this DecayTreeTuple" }), children: _jsx(Button, { type: "submit", variant: "secondary", onClick: handleConfigureDtt, disabled: !dttNameValid, className: "align-items-center d-flex", children: _jsx(GearWideConnected, {}) }) }), !hideDownloadButtons && (_jsx(_Fragment, { children: _jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: "Download DecayTreeTuple YAML configuration file" }), children: _jsx(Button, { className: "align-items-center d-flex ms-auto", type: "button", onClick: () => {
72
+ : "Name is already taken" })] })), _jsx(ButtonGroup, { children: row.dtt ? (_jsxs(_Fragment, { children: [_jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: "Configure this DecayTreeTuple" }), children: _jsx(Button, { type: "submit", variant: "secondary", onClick: handleConfigureDtt, disabled: !dttNameValid, className: "align-items-center d-flex", children: _jsx(GearWideConnected, {}) }) }), variant === "standalone" && (_jsx(_Fragment, { children: _jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: "Download DecayTreeTuple YAML configuration file" }), children: _jsx(Button, { className: "align-items-center d-flex ms-auto", type: "button", onClick: () => {
69
73
  downloadText(YamlFile.fromDtt(row.dtt));
70
- }, disabled: !dttNameValid, children: _jsx(Download, {}) }) }) })), _jsx(DeleteButton, { action: handleDeleteDtt })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "d-flex align-items-center gap-2", children: [_jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: "Please add a DecayTreeTuple in order to complete the production configuration" }), children: _jsx(ExclamationCircle, { width: 20, height: 20, className: "text-danger me-2" }) }), _jsxs(ButtonGroup, { children: [_jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: "Add a DecayTreeTuple" }), children: _jsx(Button, { type: "submit", variant: "success", onClick: handleCreateDTT, disabled: !metadata, children: _jsx(PlusLg, {}) }) }), !hideUploadButtons && (_jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: "Upload DecayTreeTuple configuration file" }), children: _jsx(Button, { className: "ms-auto", type: "button", onClick: () => setShowUploadModal(true), children: _jsx(Upload, {}) }) }))] })] }), showUploadModal && (_jsx(UploadDttConfigModal, { currentRow: row, onClose: () => setShowUploadModal(false) }))] })) })] }), _jsx(Card.Body, { children: _jsx(DecayLatex, { decay: row.decay }) })] }));
74
+ }, disabled: !dttNameValid, children: _jsx(Download, {}) }) }) })), _jsx(DeleteButton, { action: handleDeleteDtt })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "d-flex align-items-center gap-2", children: [_jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: "Please add a DecayTreeTuple in order to complete the production configuration" }), children: _jsx(ExclamationCircle, { width: 20, height: 20, className: "text-danger me-2" }) }), _jsxs(ButtonGroup, { children: [_jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: "Add a DecayTreeTuple" }), children: _jsx(Button, { type: "submit", variant: "success", onClick: handleCreateDTT, disabled: !metadata, children: _jsx(PlusLg, {}) }) }), variant === "standalone" && (_jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: "Upload DecayTreeTuple configuration file" }), children: _jsx(Button, { className: "ms-auto", type: "button", onClick: () => setShowUploadModal(true), children: _jsx(Upload, {}) }) }))] })] }), showUploadModal && (_jsx(UploadDttConfigModal, { currentRow: row, onClose: () => setShowUploadModal(false) }))] })) })] }), _jsx(Card.Body, { children: _jsx(DecayLatex, { decay: row.decay }) })] }));
71
75
  }
@@ -16,6 +16,7 @@ interface Props {
16
16
  submitLocation?: string;
17
17
  requestReasonMessage?: string;
18
18
  requestSubmittedMessage?: ReactNode;
19
+ onRequestSubmitted?: () => void;
19
20
  }
20
- export declare function NtupleWizard({ basePath, contactEmail, submitLocation, requestReasonMessage, requestSubmittedMessage, }: Props): import("react/jsx-runtime").JSX.Element;
21
+ export declare function NtupleWizard({ basePath, contactEmail, submitLocation, requestReasonMessage, requestSubmittedMessage, onRequestSubmitted, }: Props): import("react/jsx-runtime").JSX.Element;
21
22
  export {};
@@ -19,10 +19,11 @@ import { MathJaxContext } from "better-react-mathjax";
19
19
  import { RowsProvider } from "../providers/RowsProvider.js";
20
20
  import { RequestProvider } from "../providers/RequestProvider";
21
21
  import { SELECT_DECAYS_PATH, VARIABLES_PATH } from "../constants";
22
- export function NtupleWizard({ basePath = "", contactEmail, submitLocation, requestReasonMessage, requestSubmittedMessage, }) {
22
+ import { WizardConfigProvider } from "../providers/WizardConfigProvider";
23
+ export function NtupleWizard({ basePath = "", contactEmail, submitLocation, requestReasonMessage, requestSubmittedMessage, onRequestSubmitted, }) {
23
24
  const { pathname } = useLocation();
24
25
  if (contactEmail) {
25
26
  localStorage.setItem("email", contactEmail);
26
27
  }
27
- return (_jsx(MetadataProvider, { children: _jsx(RowsProvider, { children: _jsx(RequestProvider, { emailIsKnown: !!contactEmail, children: _jsx(MathJaxContext, { children: pathname.endsWith(SELECT_DECAYS_PATH) ? (_jsx(DecaySearchPage, { basePath: basePath })) : pathname.endsWith(VARIABLES_PATH) ? (_jsx(DecayTreeConfigPage, { basePath: basePath })) : (_jsx(RequestPage, { basePath: basePath, submitLocation: submitLocation, requestReasonMessage: requestReasonMessage, requestSubmittedMessage: requestSubmittedMessage })) }) }) }) }));
28
+ return (_jsx(MetadataProvider, { children: _jsx(WizardConfigProvider, { basePath: basePath, submitLocation: submitLocation, requestReasonMessage: requestReasonMessage, requestSubmittedMessage: requestSubmittedMessage, onRequestSubmitted: onRequestSubmitted, children: _jsx(RowsProvider, { children: _jsx(RequestProvider, { emailIsKnown: !!contactEmail, children: _jsx(MathJaxContext, { children: pathname.endsWith(SELECT_DECAYS_PATH) ? (_jsx(DecaySearchPage, {})) : pathname.endsWith(VARIABLES_PATH) ? (_jsx(DecayTreeConfigPage, {})) : (_jsx(RequestPage, {})) }) }) }) }) }));
28
29
  }
@@ -1,7 +1 @@
1
- import { NtupleWizardVariant } from "../pages/RequestPage";
2
- interface Props {
3
- variant: NtupleWizardVariant;
4
- basePath: string;
5
- }
6
- export declare function RequestButtonGroup({ variant, basePath }: Props): import("react/jsx-runtime").JSX.Element | null;
7
- export {};
1
+ export declare function RequestButtonGroup(): import("react/jsx-runtime").JSX.Element | null;
@@ -10,7 +10,9 @@ import { useRows } from "../providers/RowsProvider";
10
10
  import { useMetadata } from "../providers/MetadataProvider";
11
11
  import { useRequest } from "../providers/RequestProvider";
12
12
  import { useState } from "react";
13
- export function RequestButtonGroup({ variant, basePath }) {
13
+ import { useWizardConfig } from "../providers/WizardConfigProvider";
14
+ export function RequestButtonGroup() {
15
+ const { variant, basePath } = useWizardConfig();
14
16
  const metadata = useMetadata();
15
17
  const { validation } = useRequest();
16
18
  const { rows, configuredRows, setRows } = useRows();
@@ -1,7 +1 @@
1
- interface Props {
2
- hideDownloadButtons: boolean;
3
- hideUploadButtons: boolean;
4
- basePath: string;
5
- }
6
- export declare function RequestRow({ hideDownloadButtons, hideUploadButtons, basePath }: Props): import("react/jsx-runtime").JSX.Element | null;
7
- export {};
1
+ export declare function RequestRow(): import("react/jsx-runtime").JSX.Element | null;
@@ -9,12 +9,12 @@ import { useRows } from "../providers/RowsProvider";
9
9
  import { BookkeepingPathDropdown } from "./BookkeepingPathDropdown";
10
10
  import { StrippingLineDropdown } from "./StrippingLineDropdown";
11
11
  import { useRow } from "../providers/RowProvider";
12
- export function RequestRow({ hideDownloadButtons, hideUploadButtons, basePath }) {
12
+ export function RequestRow() {
13
13
  const metadata = useMetadata();
14
14
  const { row } = useRow();
15
15
  const { removeRow } = useRows();
16
16
  if (!metadata) {
17
17
  return null;
18
18
  }
19
- return (_jsxs(Row, { className: "align-items-center", children: [_jsx(Col, { lg: true, children: _jsx(DttNameInput, { row: row, hideDownloadButtons: hideDownloadButtons, hideUploadButtons: hideUploadButtons, basePath: basePath }) }), _jsx(Col, { lg: true, children: _jsx(StrippingLineDropdown, {}) }), _jsx(Col, { xs: "auto", children: _jsx(OverlayTrigger, { trigger: "click", placement: "right", rootClose: true, overlay: _jsx(Popover, { children: _jsx(Popover.Body, { children: row.lines.map((line) => (_jsx(StrippingLineInfo, { line: line.line, stream: line.stream, versions: line.versions, showLink: true }, line.line))) }) }), children: _jsx(Button, { disabled: row.lines.length === 0, children: _jsx(InfoCircle, {}) }) }) }), _jsx(Col, { children: _jsx(BookkeepingPathDropdown, {}) }), _jsx(Col, { xs: "auto", children: _jsx(DeleteButton, { action: () => removeRow(row.id) }) })] }));
19
+ return (_jsxs(Row, { className: "align-items-center", children: [_jsx(Col, { lg: true, children: _jsx(DttNameInput, {}) }), _jsx(Col, { lg: true, children: _jsx(StrippingLineDropdown, {}) }), _jsx(Col, { xs: "auto", children: _jsx(OverlayTrigger, { trigger: "click", placement: "right", rootClose: true, overlay: _jsx(Popover, { children: _jsx(Popover.Body, { children: row.lines.map((line) => (_jsx(StrippingLineInfo, { line: line.line, stream: line.stream, versions: line.versions, showLink: true }, line.line))) }) }), children: _jsx(Button, { disabled: row.lines.length === 0, children: _jsx(InfoCircle, {}) }) }) }), _jsx(Col, { children: _jsx(BookkeepingPathDropdown, {}) }), _jsx(Col, { xs: "auto", children: _jsx(DeleteButton, { action: () => removeRow(row.id) }) })] }));
20
20
  }
@@ -1,7 +1,5 @@
1
1
  interface Props {
2
- submitLocation: string;
3
2
  onClose: (submitted: boolean) => void;
4
- requestReasonMessage: string;
5
3
  }
6
- export declare function ReasonForRequestModal({ submitLocation, onClose, requestReasonMessage }: Props): import("react/jsx-runtime").JSX.Element;
4
+ export declare function ReasonForRequestModal({ onClose }: Props): import("react/jsx-runtime").JSX.Element;
7
5
  export {};
@@ -3,12 +3,14 @@ import { Alert, Button, FormControl, InputGroup, Modal, OverlayTrigger, Spinner,
3
3
  import { useRequest } from "../../providers/RequestProvider";
4
4
  import { useState } from "react";
5
5
  import { useRows } from "../../providers/RowsProvider";
6
- export function ReasonForRequestModal({ submitLocation, onClose, requestReasonMessage }) {
6
+ import { useWizardConfig } from "../../providers/WizardConfigProvider";
7
+ export function ReasonForRequestModal({ onClose }) {
7
8
  const { generateAllFiles } = useRows();
8
9
  const { productionName, reasonForRequest, setReasonForRequest } = useRequest();
10
+ const { requestReasonMessage, submitLocation } = useWizardConfig();
9
11
  const [requestLoading, setRequestLoading] = useState(false);
10
12
  const [requestError, setRequestError] = useState(null);
11
- const submitRequest = (url) => {
13
+ const submitRequest = () => {
12
14
  setRequestLoading(true);
13
15
  setRequestError(null);
14
16
  const allFiles = generateAllFiles();
@@ -19,7 +21,7 @@ export function ReasonForRequestModal({ submitLocation, onClose, requestReasonMe
19
21
  formData.append("email", localStorage.getItem("email") || "");
20
22
  formData.append("name", productionName);
21
23
  formData.append("reasonForRequest", reasonForRequest);
22
- fetch(url, {
24
+ fetch(submitLocation, {
23
25
  method: "POST",
24
26
  body: formData,
25
27
  credentials: "include",
@@ -38,5 +40,5 @@ export function ReasonForRequestModal({ submitLocation, onClose, requestReasonMe
38
40
  setRequestLoading(false);
39
41
  });
40
42
  };
41
- return (_jsxs(Modal, { show: true, onHide: () => onClose(false), size: "lg", children: [_jsx(Modal.Header, { closeButton: true, children: _jsx(Modal.Title, { children: "Reason for request" }) }), _jsxs(Modal.Body, { children: [_jsx(Alert, { children: requestReasonMessage }), requestError && _jsx(Alert, { variant: "danger", children: requestError }), _jsxs(InputGroup, { hasValidation: true, children: [_jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: "Reason for requesting the chosen ntuples" }), children: _jsx(InputGroup.Text, { children: "Reason for request" }) }), _jsx(FormControl, { as: "textarea", rows: 3, value: reasonForRequest, onChange: (event) => setReasonForRequest(event.target.value), isValid: !!reasonForRequest, placeholder: "I need these ntuples for..." })] })] }), _jsx(Modal.Footer, { children: _jsx(Button, { variant: "primary", disabled: !reasonForRequest || requestLoading, onClick: () => submitRequest(submitLocation), children: requestLoading ? (_jsxs(_Fragment, { children: [_jsx(Spinner, { animation: "border", size: "sm" }), " Submitting..."] })) : ("Submit request") }) })] }));
43
+ return (_jsxs(Modal, { show: true, onHide: () => onClose(false), size: "lg", children: [_jsx(Modal.Header, { closeButton: true, children: _jsx(Modal.Title, { children: "Reason for request" }) }), _jsxs(Modal.Body, { children: [_jsx(Alert, { children: requestReasonMessage }), requestError && _jsx(Alert, { variant: "danger", children: requestError }), _jsxs(InputGroup, { hasValidation: true, children: [_jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: "Reason for requesting the chosen ntuples" }), children: _jsx(InputGroup.Text, { children: "Reason for request" }) }), _jsx(FormControl, { as: "textarea", rows: 3, value: reasonForRequest, onChange: (event) => setReasonForRequest(event.target.value), isValid: !!reasonForRequest, placeholder: "I need these ntuples for..." })] })] }), _jsx(Modal.Footer, { children: _jsx(Button, { variant: "primary", disabled: !reasonForRequest || requestLoading, onClick: submitRequest, children: requestLoading ? (_jsxs(_Fragment, { children: [_jsx(Spinner, { animation: "border", size: "sm" }), " Submitting..."] })) : ("Submit request") }) })] }));
42
44
  }
@@ -9,9 +9,11 @@ interface InfoYamlDefaults {
9
9
  automatically_configure: boolean;
10
10
  output: string;
11
11
  }
12
- export type InfoYamlType = {
12
+ export type InfoYaml = {
13
13
  defaults: InfoYamlDefaults;
14
- } & Record<string, JobConfig>;
14
+ } & {
15
+ [K in string as K extends "defaults" ? never : K]?: JobConfig;
16
+ };
15
17
  export declare class YamlFile {
16
18
  name: string;
17
19
  content: string;
@@ -14,15 +14,7 @@ export class YamlFile {
14
14
  const uniquePathSet = new Set(rows.flatMap((row) => row.paths));
15
15
  const uniquePaths = [...uniquePathSet].sort();
16
16
  const pathIndex = new Map(uniquePaths.map((p, i) => [p, i]));
17
- const info = {
18
- defaults: {
19
- application: `DaVinci/${metadata.tupleTools.applicationInfo.DaVinci}`,
20
- wg: "OpenData",
21
- inform: [],
22
- automatically_configure: true,
23
- output: "DVNtuple.root",
24
- },
25
- };
17
+ const jobs = {};
26
18
  for (const row of rows) {
27
19
  if (!row.dtt)
28
20
  continue;
@@ -32,8 +24,8 @@ export class YamlFile {
32
24
  continue;
33
25
  const key = `job${jobID}`;
34
26
  const dttFile = row.dtt.getName();
35
- if (key in info) {
36
- info[key].options.push(dttFile);
27
+ if (jobs[key]) {
28
+ jobs[key].options.push(dttFile);
37
29
  }
38
30
  else {
39
31
  const job = {
@@ -42,14 +34,23 @@ export class YamlFile {
42
34
  };
43
35
  if (path.includes("MDST")) {
44
36
  const stream = row.lines[0]?.stream;
45
- if (stream) {
37
+ if (stream)
46
38
  job.root_in_tes = `/Event/${stream}`;
47
- }
48
39
  }
49
- info[key] = job;
40
+ jobs[key] = job;
50
41
  }
51
42
  }
52
43
  }
44
+ const info = {
45
+ defaults: {
46
+ application: `DaVinci/${metadata.tupleTools.applicationInfo.DaVinci}`,
47
+ wg: "OpenData",
48
+ inform: [],
49
+ automatically_configure: true,
50
+ output: "DVNtuple.root",
51
+ },
52
+ ...jobs,
53
+ };
53
54
  return new YamlFile("info.yaml", yaml.dump(info));
54
55
  }
55
56
  }
@@ -1,5 +1 @@
1
- interface Props {
2
- basePath: string;
3
- }
4
- export declare function DecaySearchPage({ basePath }: Props): import("react/jsx-runtime").JSX.Element;
5
- export {};
1
+ export declare function DecaySearchPage(): import("react/jsx-runtime").JSX.Element;
@@ -20,6 +20,7 @@ import { ParticleDropdown } from "../components/ParticleDropdown";
20
20
  import { getSelectTagOptions, TagDropdown } from "../components/TagDropdown";
21
21
  import { useRows } from "../providers/RowsProvider";
22
22
  import { LoadingIndicator } from "../components/LoadingIndicator";
23
+ import { useWizardConfig } from "../providers/WizardConfigProvider";
23
24
  var MatchType;
24
25
  (function (MatchType) {
25
26
  MatchType["any"] = "any";
@@ -31,9 +32,10 @@ var HeadMatchType;
31
32
  HeadMatchType["exactly"] = "exactly";
32
33
  HeadMatchType["category"] = "category";
33
34
  })(HeadMatchType || (HeadMatchType = {}));
34
- export function DecaySearchPage({ basePath }) {
35
+ export function DecaySearchPage() {
35
36
  const metadata = useMetadata();
36
37
  const { rows, setRows } = useRows();
38
+ const { basePath } = useWizardConfig();
37
39
  const [selectedContains, setSelectedContains] = useState([]);
38
40
  const [selectedHead, setSelectedHead] = useState(null);
39
41
  const [selectedHeadTags, setSelectedHeadTags] = useState([]);
@@ -1,5 +1 @@
1
- interface Props {
2
- basePath: string;
3
- }
4
- export declare function DecayTreeConfigPage({ basePath }: Props): import("react/jsx-runtime").JSX.Element;
5
- export {};
1
+ export declare function DecayTreeConfigPage(): import("react/jsx-runtime").JSX.Element;
@@ -18,10 +18,12 @@ import Dtt from "../models/dtt";
18
18
  import { DttProvider } from "../providers/DttProvider";
19
19
  import { LoadingIndicator } from "../components/LoadingIndicator";
20
20
  import { useEffect, useState } from "react";
21
- export function DecayTreeConfigPage({ basePath }) {
21
+ import { useWizardConfig } from "../providers/WizardConfigProvider";
22
+ export function DecayTreeConfigPage() {
22
23
  const navigate = useNavigate();
23
24
  const metadata = useMetadata();
24
25
  const { rows, updateRow } = useRows();
26
+ const { basePath } = useWizardConfig();
25
27
  const [dirtyDtts, setDirtyDtts] = useState(new Set());
26
28
  // Listen for when the user is about to leave the page and alert them if there are unsaved changes
27
29
  useEffect(() => {
@@ -1,20 +1 @@
1
- /*****************************************************************************\
2
- * (c) Copyright 2021-2024 CERN for the benefit of the LHCb Collaboration *
3
- * *
4
- * This software is distributed under the terms of the GNU General Public *
5
- * Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". *
6
- * *
7
- * In applying this licence, CERN does not waive the privileges and immunities *
8
- * granted to it by virtue of its status as an Intergovernmental Organization *
9
- * or submit itself to any jurisdiction. *
10
- \*****************************************************************************/
11
- import { ReactNode } from "react";
12
- export type NtupleWizardVariant = "standalone" | "embedded";
13
- interface Props {
14
- basePath: string;
15
- submitLocation?: string;
16
- requestReasonMessage?: string;
17
- requestSubmittedMessage?: ReactNode;
18
- }
19
- export declare function RequestPage({ basePath, submitLocation, requestReasonMessage, requestSubmittedMessage }: Props): import("react/jsx-runtime").JSX.Element;
20
- export {};
1
+ export declare function RequestPage(): import("react/jsx-runtime").JSX.Element;
@@ -27,16 +27,17 @@ import { RowProvider } from "../providers/RowProvider";
27
27
  import { ProductionNameInput } from "../components/ProductionNameInput";
28
28
  import { RequestEmailInput } from "../components/RequestEmailInput";
29
29
  import { RequestButtonGroup } from "../components/RequestButtonGroup";
30
- export function RequestPage({ basePath, submitLocation, requestReasonMessage, requestSubmittedMessage }) {
30
+ import { useWizardConfig } from "../providers/WizardConfigProvider";
31
+ export function RequestPage() {
31
32
  const location = useLocation();
32
33
  const metadata = useMetadata();
33
34
  const { rows, setRows, generateAllFiles } = useRows();
34
35
  const { emailIsKnown, productionName, setProductionName, validation, showErrors, clearAll, trySubmit } = useRequest();
36
+ const { variant, requestSubmittedMessage, onRequestSubmitted } = useWizardConfig();
35
37
  const [showProdUploadModal, setShowProdUploadModal] = useState(false);
36
38
  const [prodUploadLoading, setProdUploadLoading] = useState(false);
37
39
  const [requestSubmitted, setRequestSubmitted] = useState(false);
38
40
  const [showReasonForRequestModal, setShowReasonForRequestModal] = useState(false);
39
- const variant = submitLocation ? "embedded" : "standalone";
40
41
  useEffect(() => {
41
42
  if (!metadata) {
42
43
  return;
@@ -86,16 +87,17 @@ export function RequestPage({ basePath, submitLocation, requestReasonMessage, re
86
87
  if (requestSubmitted) {
87
88
  return (_jsx(Row, { className: "mt-3", children: _jsx(Col, { children: _jsxs(Alert, { variant: "success", dismissible: true, onClose: () => setRequestSubmitted(false), children: [_jsx(Alert.Heading, { children: "Request submitted!" }), requestSubmittedMessage] }) }) }));
88
89
  }
89
- return (_jsxs(_Fragment, { children: [showReasonForRequestModal && (_jsx(ReasonForRequestModal, { submitLocation: submitLocation, requestReasonMessage: requestReasonMessage, onClose: (submitted) => {
90
+ return (_jsxs(_Fragment, { children: [showReasonForRequestModal && (_jsx(ReasonForRequestModal, { onClose: (submitted) => {
90
91
  setShowReasonForRequestModal(false);
91
92
  if (submitted) {
92
93
  setRequestSubmitted(true);
94
+ onRequestSubmitted?.();
93
95
  }
94
- } })), showProdUploadModal && _jsx(UploadDttConfigModal, { onClose: () => setShowProdUploadModal(false) }), _jsxs("div", { className: "d-flex flex-column gap-3", children: [rows.map((row) => (_jsx(RowProvider, { row: row, children: _jsx(RequestRow, { hideDownloadButtons: variant === "standalone", hideUploadButtons: variant === "standalone", basePath: basePath }, row.id) }, row.id))), prodUploadLoading && _jsx(ConfigFilesUploadingAlert, {}), requestSubmitted && (_jsxs(Alert, { variant: "success", dismissible: true, onClose: () => setRequestSubmitted(false), children: [_jsx(Alert.Heading, { children: "Request submitted!" }), requestSubmittedMessage] })), showErrors &&
96
+ } })), showProdUploadModal && _jsx(UploadDttConfigModal, { onClose: () => setShowProdUploadModal(false) }), _jsxs("div", { className: "d-flex flex-column gap-3", children: [rows.map((row) => (_jsx(RowProvider, { row: row, children: _jsx(RequestRow, {}, row.id) }, row.id))), prodUploadLoading && _jsx(ConfigFilesUploadingAlert, {}), showErrors &&
95
97
  (rows.length === 0 ||
96
98
  !validation.allRowsHaveDtt ||
97
99
  !validation.allRowsHaveStrippingLine ||
98
100
  !validation.allRowsHavePaths) && (_jsx(Alert, { variant: "danger", className: "mb-0", children: rows.length === 0
99
101
  ? "Please select at least one decay"
100
- : "Please name all DecayTreeTuples and select at least one stripping line and bookkeeping path for each decay" })), _jsx(Row, { children: _jsx(Col, { xs: "auto", children: _jsx(RequestButtonGroup, { variant: variant, basePath: basePath }) }) }), _jsx(Row, { children: _jsxs(Col, { xs: 4, children: [_jsx(ProductionNameInput, {}), !emailIsKnown && _jsx(RequestEmailInput, {}), _jsxs(Stack, { direction: "horizontal", gap: 1, className: "mt-3 mb-3", children: [_jsxs(Button, { className: "align-items-center d-flex gap-1", onClick: () => void handlePrimaryAction(), children: [variant === "standalone" ? _jsx(Download, {}) : _jsx(Send, {}), variant === "standalone" ? "Download" : "Submit"] }), _jsx(DeleteButton, { action: clearAll, disabled: validation.isEmptySession, outline: undefined, children: "Clear all" })] })] }) })] })] }));
102
+ : "Please name all DecayTreeTuples and select at least one stripping line and bookkeeping path for each decay" })), _jsx(Row, { children: _jsx(Col, { xs: "auto", children: _jsx(RequestButtonGroup, {}) }) }), _jsx(Row, { children: _jsxs(Col, { xs: 4, children: [_jsx(ProductionNameInput, {}), !emailIsKnown && _jsx(RequestEmailInput, {}), _jsxs(Stack, { direction: "horizontal", gap: 1, className: "mt-3 mb-3", children: [_jsxs(Button, { className: "align-items-center d-flex gap-1", onClick: () => void handlePrimaryAction(), children: [variant === "standalone" ? _jsx(Download, {}) : _jsx(Send, {}), variant === "standalone" ? "Download" : "Submit"] }), _jsx(DeleteButton, { action: clearAll, disabled: validation.isEmptySession, outline: undefined, children: "Clear all" })] })] }) })] })] }));
101
103
  }
@@ -0,0 +1,21 @@
1
+ import { ReactNode } from "react";
2
+ type NtupleWizardVariant = "standalone" | "embedded";
3
+ interface WizardConfigContextType {
4
+ variant: NtupleWizardVariant;
5
+ basePath: string;
6
+ submitLocation?: string;
7
+ requestReasonMessage?: string;
8
+ requestSubmittedMessage?: ReactNode;
9
+ onRequestSubmitted?: () => void;
10
+ }
11
+ interface WizardConfigProviderProps {
12
+ basePath: string;
13
+ submitLocation?: string;
14
+ requestReasonMessage?: string;
15
+ requestSubmittedMessage?: ReactNode;
16
+ onRequestSubmitted?: () => void;
17
+ children: ReactNode;
18
+ }
19
+ export declare const WizardConfigProvider: ({ basePath, submitLocation, requestReasonMessage, requestSubmittedMessage, onRequestSubmitted, children, }: WizardConfigProviderProps) => import("react/jsx-runtime").JSX.Element;
20
+ export declare const useWizardConfig: () => WizardConfigContextType;
21
+ export {};
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext } from "react";
3
+ const WizardConfigContext = createContext(null);
4
+ export const WizardConfigProvider = ({ basePath, submitLocation, requestReasonMessage, requestSubmittedMessage, onRequestSubmitted, children, }) => {
5
+ const variant = submitLocation ? "embedded" : "standalone";
6
+ return (_jsx(WizardConfigContext.Provider, { value: {
7
+ variant,
8
+ basePath,
9
+ submitLocation,
10
+ requestReasonMessage,
11
+ requestSubmittedMessage,
12
+ onRequestSubmitted,
13
+ }, children: children }));
14
+ };
15
+ export const useWizardConfig = () => {
16
+ const ctx = useContext(WizardConfigContext);
17
+ if (!ctx) {
18
+ throw new Error("useWizardConfig must be used within a WizardConfigProvider");
19
+ }
20
+ return ctx;
21
+ };
@@ -1,4 +1,4 @@
1
- import { InfoYamlType, YamlFile } from "../models/yamlFile";
1
+ import { InfoYaml, YamlFile } from "../models/yamlFile";
2
2
  import { SavedDttConfig } from "../models/dtt";
3
3
  import { RowData } from "../models/rowData";
4
4
  import { MetadataContext } from "../providers/MetadataProvider";
@@ -6,7 +6,7 @@ export declare function parseProductionFiles(files: File[], metadata: MetadataCo
6
6
  rows: RowData[];
7
7
  emails: string[];
8
8
  }>;
9
- export declare function processProductionFiles(metadata: MetadataContext, configs: SavedDttConfig[], infoYaml: InfoYamlType | null): string | {
9
+ export declare function processProductionFiles(metadata: MetadataContext, configs: SavedDttConfig[], infoYaml: InfoYaml | null): string | {
10
10
  rows: RowData[];
11
11
  emails: string[];
12
12
  };
@@ -61,7 +61,7 @@ async function parseInfoYamlFile(file) {
61
61
  const value = input[key];
62
62
  if (undefined === value)
63
63
  return true;
64
- return "object" === typeof value && null !== value && _io2(value);
64
+ return undefined === value || "object" === typeof value && null !== value && _io2(value);
65
65
  }); const _io1 = input => "string" === typeof input.application && "string" === typeof input.wg && (Array.isArray(input.inform) && input.inform.every(elem => "string" === typeof elem)) && "boolean" === typeof input.automatically_configure && "string" === typeof input.output; const _io2 = input => Array.isArray(input.options) && input.options.every(elem => "string" === typeof elem) && ("object" === typeof input.input && null !== input.input && _io3(input.input)) && (undefined === input.root_in_tes || "string" === typeof input.root_in_tes); const _io3 = input => "string" === typeof input.bk_query; const _vo0 = (input, _path, _exceptionable = true) => [("object" === typeof input.defaults && null !== input.defaults || _report(_exceptionable, {
66
66
  path: _path + ".defaults",
67
67
  expected: "InfoYamlDefaults",
@@ -76,13 +76,13 @@ async function parseInfoYamlFile(file) {
76
76
  const value = input[key];
77
77
  if (undefined === value)
78
78
  return true;
79
- return ("object" === typeof value && null !== value || _report(_exceptionable, {
79
+ return undefined === value || ("object" === typeof value && null !== value || _report(_exceptionable, {
80
80
  path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key),
81
- expected: "JobConfig",
81
+ expected: "(JobConfig | undefined)",
82
82
  value: value
83
83
  })) && _vo2(value, _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key), true && _exceptionable) || _report(_exceptionable, {
84
84
  path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key),
85
- expected: "JobConfig",
85
+ expected: "(JobConfig | undefined)",
86
86
  value: value
87
87
  });
88
88
  }).every(flag => flag)].every(flag => flag); const _vo1 = (input, _path, _exceptionable = true) => ["string" === typeof input.application || _report(_exceptionable, {
@@ -147,11 +147,11 @@ async function parseInfoYamlFile(file) {
147
147
  _report = __typia_transform__validateReport._validateReport(errors);
148
148
  ((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
149
149
  path: _path + "",
150
- expected: "InfoYamlType",
150
+ expected: "InfoYaml",
151
151
  value: input
152
152
  })) && _vo0(input, _path + "", true) || _report(true, {
153
153
  path: _path + "",
154
- expected: "InfoYamlType",
154
+ expected: "InfoYaml",
155
155
  value: input
156
156
  }))(input, "$input", true);
157
157
  const success = 0 === errors.length;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lhcb-ntuple-wizard-test",
3
- "version": "2.0.5",
3
+ "version": "2.0.7",
4
4
  "description": "An application to access large-scale open data from LHCb",
5
5
  "url": "https://gitlab.cern.ch/lhcb-dpa/wp6-analysis-preservation-and-open-data/lhcb-ntuple-wizard-frontend/issues",
6
6
  "private": false,
@@ -1,12 +0,0 @@
1
- export interface BlobFileDefaults {
2
- application: string;
3
- wg: string;
4
- inform: string[];
5
- automatically_configure: boolean;
6
- output: string;
7
- }
8
- export interface BlobFile {
9
- name: string;
10
- defaults: BlobFileDefaults;
11
- blob: Blob;
12
- }
@@ -1 +0,0 @@
1
- export {};