lhcb-ntuple-wizard 2.0.3 → 2.1.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/App.js +2 -1
- package/dist/components/DecayCard.d.ts +1 -0
- package/dist/components/{DttNameInput.js → DecayCard.js} +9 -5
- package/dist/components/DecayLatex.js +1 -1
- package/dist/components/DecayTreeCard.js +7 -10
- package/dist/components/DecayTreeGraph.d.ts +1 -2
- package/dist/components/DecayTreeGraph.js +132 -46
- package/dist/components/DeleteButton.d.ts +2 -1
- package/dist/components/DeleteButton.js +2 -2
- package/dist/components/NtupleWizard.d.ts +2 -1
- package/dist/components/NtupleWizard.js +8 -2
- package/dist/components/RequestButtonGroup.d.ts +1 -7
- package/dist/components/RequestButtonGroup.js +5 -3
- package/dist/components/RequestRow.d.ts +1 -7
- package/dist/components/RequestRow.js +6 -5
- package/dist/components/StrippingLineBadge.js +1 -1
- package/dist/components/{TupleToolDropdown.d.ts → TupleToolClassDropdown.d.ts} +2 -5
- package/dist/components/{TupleToolDropdown.js → TupleToolClassDropdown.js} +10 -4
- package/dist/components/TupleToolGroup.d.ts +1 -2
- package/dist/components/TupleToolGroup.js +5 -5
- package/dist/components/TupleToolList.d.ts +1 -2
- package/dist/components/TupleToolList.js +11 -7
- package/dist/components/VerticalLine.d.ts +7 -0
- package/dist/components/VerticalLine.js +4 -0
- package/dist/components/modals/AddTupleToolModal.d.ts +3 -4
- package/dist/components/modals/AddTupleToolModal.js +12 -12
- package/dist/components/modals/ConfigureTupleToolModal.d.ts +2 -2
- package/dist/components/modals/ConfigureTupleToolModal.js +28 -11
- package/dist/components/modals/ReasonForRequestModal.d.ts +1 -3
- package/dist/components/modals/ReasonForRequestModal.js +6 -4
- package/dist/config.d.ts +18 -47
- package/dist/config.js +26 -39
- package/dist/pages/DecaySearchPage.d.ts +1 -5
- package/dist/pages/DecaySearchPage.js +3 -1
- package/dist/pages/DecayTreeConfigPage.d.ts +1 -5
- package/dist/pages/DecayTreeConfigPage.js +16 -14
- package/dist/pages/RequestPage.d.ts +1 -20
- package/dist/pages/RequestPage.js +15 -16
- package/dist/providers/DttProvider.d.ts +2 -0
- package/dist/providers/DttProvider.js +4 -1
- package/dist/providers/WizardConfigProvider.d.ts +21 -0
- package/dist/providers/WizardConfigProvider.js +21 -0
- package/dist/utils/utils.js +36 -3
- package/package.json +10 -5
- package/dist/components/DttNameInput.d.ts +0 -9
|
@@ -1,7 +1,6 @@
|
|
|
1
|
+
import { TupleTool } from "../../models/tupleTool";
|
|
1
2
|
interface Props {
|
|
2
|
-
|
|
3
|
-
filterToolTags: string[];
|
|
4
|
-
onClose: () => void;
|
|
3
|
+
onClose: (newTool: TupleTool | null) => void;
|
|
5
4
|
}
|
|
6
|
-
export declare function AddTupleToolModal({
|
|
5
|
+
export declare function AddTupleToolModal({ onClose }: Props): import("react/jsx-runtime").JSX.Element;
|
|
7
6
|
export {};
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Button, FormControl, InputGroup, Modal } from "react-bootstrap";
|
|
3
|
-
import {
|
|
2
|
+
import { Button, ButtonGroup, FormControl, InputGroup, Modal } from "react-bootstrap";
|
|
3
|
+
import { TupleToolClassDropdown } from "../TupleToolClassDropdown";
|
|
4
4
|
import { TupleToolDocsAccordion } from "../TupleToolDocsAccordion";
|
|
5
5
|
import { useDtt } from "../../providers/DttProvider";
|
|
6
6
|
import { TupleTool } from "../../models/tupleTool";
|
|
7
7
|
import { useEffect, useRef, useState } from "react";
|
|
8
|
-
export function AddTupleToolModal({
|
|
9
|
-
const { dtt, addTool } = useDtt();
|
|
8
|
+
export function AddTupleToolModal({ onClose }) {
|
|
9
|
+
const { dtt, addTool, selectedBranch } = useDtt();
|
|
10
10
|
const nameInputRef = useRef(null);
|
|
11
11
|
const [selectedTool, setSelectedTool] = useState(null);
|
|
12
12
|
useEffect(() => {
|
|
13
13
|
nameInputRef.current?.focus();
|
|
14
14
|
}, [selectedTool]);
|
|
15
|
-
return (_jsxs(Modal, { show: true, onHide: onClose, children: [_jsx(Modal.Header, { closeButton: true, children: "Add TupleTool" }), _jsxs(Modal.Body, { className: "gap-3 d-flex flex-column", children: [_jsxs(InputGroup, { hasValidation: true, children: [_jsx(
|
|
15
|
+
return (_jsxs(Modal, { show: true, onHide: () => onClose(null), children: [_jsx(Modal.Header, { closeButton: true, children: "Add TupleTool" }), _jsxs(Modal.Body, { className: "gap-3 d-flex flex-column", children: [_jsxs(InputGroup, { hasValidation: true, children: [_jsx(TupleToolClassDropdown, { onChange: (option) => {
|
|
16
16
|
if (option) {
|
|
17
17
|
setSelectedTool((prev) => new TupleTool(option.value, prev?.name || ""));
|
|
18
18
|
}
|
|
@@ -20,13 +20,13 @@ export function AddTupleToolModal({ branch, filterToolTags, onClose }) {
|
|
|
20
20
|
// Remove all non-word characters
|
|
21
21
|
const name = event.target.value.replaceAll(/[^\w]/g, "");
|
|
22
22
|
setSelectedTool((prev) => new TupleTool(prev.class, name));
|
|
23
|
-
}, value: selectedTool?.name || "", disabled: !selectedTool, isInvalid: !!selectedTool && dtt.toolExists(selectedTool,
|
|
23
|
+
}, value: selectedTool?.name || "", disabled: !selectedTool, isInvalid: !!selectedTool && dtt.toolExists(selectedTool, selectedBranch), onKeyDown: (event) => {
|
|
24
24
|
if (event.key === "Enter") {
|
|
25
|
-
addTool(
|
|
26
|
-
onClose();
|
|
25
|
+
addTool(selectedBranch, selectedTool);
|
|
26
|
+
onClose(selectedTool);
|
|
27
27
|
}
|
|
28
|
-
} }), selectedTool && (_jsxs(FormControl.Feedback, { type: "invalid", children: ["A ", selectedTool.class, " with the name \"", selectedTool.name, "\" already exists"] }))] }), selectedTool && _jsx(TupleToolDocsAccordion, { toolClass: selectedTool.class }),
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
} }), selectedTool && (_jsxs(FormControl.Feedback, { type: "invalid", children: ["A ", selectedTool.class, " with the name \"", selectedTool.name, "\" already exists"] }))] }), selectedTool && _jsx(TupleToolDocsAccordion, { toolClass: selectedTool.class }), _jsxs(ButtonGroup, { className: "align-self-end", children: [_jsx(Button, { variant: "outline-dark", onClick: () => onClose(null), children: "Cancel" }), _jsx(Button, { disabled: !selectedTool || dtt.toolExists(selectedTool, selectedBranch), onClick: () => {
|
|
29
|
+
addTool(selectedBranch, selectedTool);
|
|
30
|
+
onClose(selectedTool);
|
|
31
|
+
}, children: "Add tool" })] })] })] }));
|
|
32
32
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { TupleTool } from "../../models/tupleTool";
|
|
2
2
|
interface Props {
|
|
3
|
-
branch: string[];
|
|
4
3
|
tool: TupleTool;
|
|
4
|
+
deleteIfCancelled: boolean;
|
|
5
5
|
onClose: () => void;
|
|
6
6
|
}
|
|
7
|
-
export declare function ConfigureTupleToolModal({
|
|
7
|
+
export declare function ConfigureTupleToolModal({ tool, deleteIfCancelled, onClose }: Props): import("react/jsx-runtime").JSX.Element;
|
|
8
8
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Button, Col, Form, Modal, OverlayTrigger, Row, Tooltip } from "react-bootstrap";
|
|
2
|
+
import { Button, ButtonGroup, Col, Form, Modal, OverlayTrigger, Row, Tooltip } from "react-bootstrap";
|
|
3
3
|
import { StrParamInput } from "../tupleToolParams/StrParamInput";
|
|
4
4
|
import { BoolParamInput } from "../tupleToolParams/BoolParamInput";
|
|
5
5
|
import { NumParamInput } from "../tupleToolParams/NumParamInput";
|
|
@@ -8,36 +8,53 @@ import { DictParamInput } from "../tupleToolParams/DictParamInput";
|
|
|
8
8
|
import { QuestionCircle } from "react-bootstrap-icons";
|
|
9
9
|
import { TupleToolDocsAccordion } from "../TupleToolDocsAccordion";
|
|
10
10
|
import { useDtt } from "../../providers/DttProvider";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
import { config } from "../../config";
|
|
12
|
+
import { toast } from "react-toastify";
|
|
13
|
+
export function ConfigureTupleToolModal({ tool, deleteIfCancelled, onClose }) {
|
|
14
|
+
const { dtt, updateToolParam, removeTool, selectedBranch } = useDtt();
|
|
15
|
+
const toolConfig = dtt.getToolConfig(selectedBranch, tool);
|
|
16
|
+
return (_jsxs(Modal, { show: true, size: "xl", fullscreen: "lg-down", backdrop: "static", keyboard: false, children: [_jsxs(Modal.Header, { children: ["Configure ", tool.toString()] }), _jsxs(Modal.Body, { className: "gap-3 d-flex flex-column", children: [_jsx(Form, { children: Object.entries(toolConfig).map(([paramName, param]) => {
|
|
14
17
|
const { description, type, default: defaultValue, value } = param;
|
|
15
18
|
let inputComponent;
|
|
16
19
|
switch (type) {
|
|
17
20
|
case "str":
|
|
18
|
-
inputComponent = (_jsx(StrParamInput, { value: value, defaultValue: defaultValue, onChange: (newValue) => updateToolParam(
|
|
21
|
+
inputComponent = (_jsx(StrParamInput, { value: value, defaultValue: defaultValue, onChange: (newValue) => updateToolParam(selectedBranch, tool, paramName, newValue), param: paramName }));
|
|
19
22
|
break;
|
|
20
23
|
case "bool":
|
|
21
|
-
inputComponent = (_jsx(BoolParamInput, { value: value, onChange: (newValue) => updateToolParam(
|
|
24
|
+
inputComponent = (_jsx(BoolParamInput, { value: value, onChange: (newValue) => updateToolParam(selectedBranch, tool, paramName, newValue) }));
|
|
22
25
|
break;
|
|
23
26
|
case "int":
|
|
24
27
|
case "uint":
|
|
25
28
|
case "float":
|
|
26
|
-
inputComponent = (_jsx(NumParamInput, { type: type, value: value, defaultValue: defaultValue, onChange: (newValue) => updateToolParam(
|
|
29
|
+
inputComponent = (_jsx(NumParamInput, { type: type, value: value, defaultValue: defaultValue, onChange: (newValue) => updateToolParam(selectedBranch, tool, paramName, newValue) }));
|
|
27
30
|
break;
|
|
28
31
|
case "text":
|
|
29
|
-
inputComponent = (_jsx(ListParamInput, { initialValues: value, defaultValues: defaultValue, newItemValue: "", onChange: (newValue) => updateToolParam(
|
|
32
|
+
inputComponent = (_jsx(ListParamInput, { initialValues: value, defaultValues: defaultValue, newItemValue: "", onChange: (newValue) => updateToolParam(selectedBranch, tool, paramName, newValue), buildInnerInput: (props) => _jsx(StrParamInput, { ...props, param: paramName }) }));
|
|
30
33
|
break;
|
|
31
34
|
case "[int]":
|
|
32
35
|
case "[uint]":
|
|
33
36
|
case "[float]":
|
|
34
|
-
inputComponent = (_jsx(ListParamInput, { initialValues: value, defaultValues: defaultValue, newItemValue: 0, onChange: (newValue) => updateToolParam(
|
|
37
|
+
inputComponent = (_jsx(ListParamInput, { initialValues: value, defaultValues: defaultValue, newItemValue: 0, onChange: (newValue) => updateToolParam(selectedBranch, tool, paramName, newValue), buildInnerInput: (props) => (_jsx(NumParamInput, { type: type.slice(1, -1), ...props })) }));
|
|
35
38
|
break;
|
|
36
39
|
case "{str:str}":
|
|
37
40
|
case "{str:[str]}":
|
|
38
|
-
inputComponent = (_jsx(DictParamInput, { value: value, onChange: (newValue) => updateToolParam(
|
|
41
|
+
inputComponent = (_jsx(DictParamInput, { value: value, onChange: (newValue) => updateToolParam(selectedBranch, tool, paramName, newValue) }));
|
|
39
42
|
break;
|
|
40
43
|
}
|
|
41
44
|
return (_jsxs(Form.Group, { as: Row, className: "mb-2", children: [_jsxs(Form.Label, { column: true, sm: 3, children: [_jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: description }), children: _jsx(QuestionCircle, {}) }), _jsxs("code", { children: [" ", paramName, " "] })] }), _jsx(Form.Label, { column: true, sm: 2, children: _jsxs("code", { children: [" ", type, " "] }) }), _jsx(Col, { sm: 7, children: inputComponent })] }, paramName));
|
|
42
|
-
}) })
|
|
45
|
+
}) }), _jsx(TupleToolDocsAccordion, { toolClass: tool.class }), _jsxs(ButtonGroup, { className: "align-self-end", children: [_jsx(Button, { variant: deleteIfCancelled ? "outline-danger" : "outline-dark", onClick: () => {
|
|
46
|
+
if (deleteIfCancelled) {
|
|
47
|
+
removeTool(selectedBranch, tool);
|
|
48
|
+
}
|
|
49
|
+
onClose();
|
|
50
|
+
}, children: "Cancel" }), _jsx(Button, { onClick: () => {
|
|
51
|
+
if (Object.keys(config.tupleToolValidation).includes(tool.class)) {
|
|
52
|
+
const errorMsg = config.tupleToolValidation[tool.class].validate(toolConfig);
|
|
53
|
+
if (errorMsg) {
|
|
54
|
+
toast(errorMsg, { type: "error" });
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
onClose();
|
|
59
|
+
}, children: "Save & close" })] })] })] }));
|
|
43
60
|
}
|
|
@@ -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({
|
|
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
|
-
|
|
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 = (
|
|
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(
|
|
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:
|
|
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
|
}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { DagreLayoutOptions } from "cytoscape-dagre";
|
|
2
|
+
import { ToolConfig } from "./models/dtt";
|
|
1
3
|
export declare const config: {
|
|
2
4
|
metadata_baseurl: string;
|
|
3
5
|
metadata_files: {
|
|
@@ -21,58 +23,27 @@ export declare const config: {
|
|
|
21
23
|
lifetime: string;
|
|
22
24
|
};
|
|
23
25
|
dttGraphOptions: {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
height: string;
|
|
27
|
+
zoomMin: number;
|
|
28
|
+
zoomMax: number;
|
|
29
|
+
zoomStep: number;
|
|
30
|
+
layout: DagreLayoutOptions;
|
|
29
31
|
nodes: {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
strokeWidth: number;
|
|
35
|
-
background: string;
|
|
36
|
-
};
|
|
37
|
-
color: {
|
|
38
|
-
background: string;
|
|
39
|
-
highlight: {
|
|
40
|
-
background: string;
|
|
41
|
-
};
|
|
42
|
-
hover: {
|
|
43
|
-
background: string;
|
|
44
|
-
};
|
|
45
|
-
};
|
|
46
|
-
scaling: {
|
|
47
|
-
min: number;
|
|
48
|
-
max: number;
|
|
49
|
-
};
|
|
50
|
-
value: number;
|
|
51
|
-
shape: string;
|
|
52
|
-
shapeProperties: {
|
|
53
|
-
useBorderWithImage: boolean;
|
|
54
|
-
useImageSize: boolean;
|
|
55
|
-
};
|
|
32
|
+
draggable: boolean;
|
|
33
|
+
width: number;
|
|
34
|
+
height: number;
|
|
35
|
+
hoverColor: string;
|
|
56
36
|
};
|
|
57
37
|
edges: {
|
|
58
38
|
color: string;
|
|
59
39
|
width: number;
|
|
60
|
-
selectionWidth: number;
|
|
61
|
-
hoverWidth: number;
|
|
62
|
-
};
|
|
63
|
-
physics: {
|
|
64
|
-
enabled: boolean;
|
|
65
40
|
};
|
|
66
|
-
interaction: {
|
|
67
|
-
dragNodes: boolean;
|
|
68
|
-
multiselect: boolean;
|
|
69
|
-
selectConnectedEdges: boolean;
|
|
70
|
-
hoverConnectedEdges: boolean;
|
|
71
|
-
hover: boolean;
|
|
72
|
-
zoomView: boolean;
|
|
73
|
-
};
|
|
74
|
-
height: string;
|
|
75
|
-
autoResize: boolean;
|
|
76
|
-
width: string;
|
|
77
41
|
};
|
|
42
|
+
tupleToolValidation: TupleToolValidation;
|
|
78
43
|
};
|
|
44
|
+
interface TupleToolValidation {
|
|
45
|
+
[toolClass: string]: {
|
|
46
|
+
validate: (config: ToolConfig) => string | null;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export {};
|
package/dist/config.js
CHANGED
|
@@ -21,52 +21,39 @@ export const config = {
|
|
|
21
21
|
lifetime: "secondary",
|
|
22
22
|
},
|
|
23
23
|
dttGraphOptions: {
|
|
24
|
+
height: "500px",
|
|
25
|
+
zoomMin: 0.2,
|
|
26
|
+
zoomMax: 3.0,
|
|
27
|
+
zoomStep: 0.018,
|
|
24
28
|
layout: {
|
|
25
|
-
|
|
29
|
+
rankDir: "TB", // top -> bottom
|
|
30
|
+
nodeSep: 50,
|
|
31
|
+
rankSep: 80,
|
|
32
|
+
animate: false,
|
|
26
33
|
},
|
|
27
34
|
nodes: {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
strokeWidth: 20,
|
|
33
|
-
background: "white",
|
|
34
|
-
},
|
|
35
|
-
color: {
|
|
36
|
-
background: "white",
|
|
37
|
-
highlight: { background: "white" },
|
|
38
|
-
hover: { background: "#eee" },
|
|
39
|
-
},
|
|
40
|
-
scaling: {
|
|
41
|
-
min: 32,
|
|
42
|
-
max: 32,
|
|
43
|
-
},
|
|
44
|
-
value: 1,
|
|
45
|
-
shape: "image",
|
|
46
|
-
shapeProperties: {
|
|
47
|
-
useBorderWithImage: true,
|
|
48
|
-
useImageSize: false,
|
|
49
|
-
},
|
|
35
|
+
draggable: false,
|
|
36
|
+
width: 80,
|
|
37
|
+
height: 30,
|
|
38
|
+
hoverColor: "royalblue",
|
|
50
39
|
},
|
|
51
40
|
edges: {
|
|
52
|
-
color: "
|
|
41
|
+
color: "#222",
|
|
53
42
|
width: 1,
|
|
54
|
-
selectionWidth: 0,
|
|
55
|
-
hoverWidth: 0,
|
|
56
43
|
},
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
44
|
+
},
|
|
45
|
+
tupleToolValidation: {
|
|
46
|
+
["LoKi__Hybrid__TupleTool"]: {
|
|
47
|
+
validate: (config) => {
|
|
48
|
+
const hasVariables = Object.entries(config["Variables"].value).length > 0;
|
|
49
|
+
const hasBoolVariables = Object.entries(config["BoolVariables"].value).length > 0;
|
|
50
|
+
const hasFloatVariables = Object.entries(config["FloatVariables"].value).length > 0;
|
|
51
|
+
const hasIntVariables = Object.entries(config["IntVariables"].value).length > 0;
|
|
52
|
+
if (!hasVariables && !hasBoolVariables && !hasFloatVariables && !hasIntVariables) {
|
|
53
|
+
return "Please add at least one variable";
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
},
|
|
67
57
|
},
|
|
68
|
-
height: "500px",
|
|
69
|
-
autoResize: true,
|
|
70
|
-
width: "100%",
|
|
71
58
|
},
|
|
72
59
|
};
|
|
@@ -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(
|
|
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([]);
|
|
@@ -9,7 +9,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
9
9
|
* granted to it by virtue of its status as an Intergovernmental Organization *
|
|
10
10
|
* or submit itself to any jurisdiction. *
|
|
11
11
|
\*****************************************************************************/
|
|
12
|
-
import { Button,
|
|
12
|
+
import { Button, OverlayTrigger, Stack, Tooltip } from "react-bootstrap";
|
|
13
13
|
import { useNavigate } from "react-router-dom";
|
|
14
14
|
import { useMetadata } from "../providers/MetadataProvider";
|
|
15
15
|
import { DecayTreeCard } from "../components/DecayTreeCard";
|
|
@@ -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
|
-
|
|
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(() => {
|
|
@@ -39,18 +41,18 @@ export function DecayTreeConfigPage({ basePath }) {
|
|
|
39
41
|
return _jsx(LoadingIndicator, { height: "70vh" });
|
|
40
42
|
}
|
|
41
43
|
const rowsToEdit = rows.filter((row) => !!row.editTree);
|
|
42
|
-
return (_jsxs(_Fragment, { children: [_jsx("h3", { children: "DecayTreeTuple configuration" }), _jsx(Stack, { gap: 5, children: rowsToEdit.map((row) => (_jsx(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
44
|
+
return (_jsxs(_Fragment, { children: [_jsx("h3", { className: "mb-4", children: "DecayTreeTuple configuration" }), _jsx(Stack, { gap: 5, children: rowsToEdit.map((row) => (_jsx(DttProvider, { metadata: metadata, decay: row.decay, initialConfig: row.dtt.config, children: _jsx(DecayTreeCard, { onConfigSaved: (newConfig) => {
|
|
45
|
+
updateRow(row.id, (r) => ({ ...r, dtt: new Dtt(newConfig, {}) }));
|
|
46
|
+
}, onDirtyUpdated: (dttName, dirty) => setDirtyDtts((prev) => {
|
|
47
|
+
if (dirty) {
|
|
48
|
+
return new Set(prev.add(dttName));
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
const newSet = new Set(prev);
|
|
52
|
+
newSet.delete(dttName);
|
|
53
|
+
return newSet;
|
|
54
|
+
}
|
|
55
|
+
}) }) }, row.id))) }), _jsx(OverlayTrigger, { placement: "right", overlay: _jsx(Tooltip, { children: "Return to Stripping line and dataset selection" }), children: _jsx(Button, { className: "mt-2 mb-4", type: "submit", onClick: () => {
|
|
54
56
|
if (dirtyDtts.size > 0) {
|
|
55
57
|
if (!confirm("You have unsaved changes. Are you sure you want to discard them?")) {
|
|
56
58
|
return;
|
|
@@ -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;
|
|
@@ -12,7 +12,6 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
12
12
|
import { useEffect, useState } from "react";
|
|
13
13
|
import { Alert, Button, Col, Row, Stack } from "react-bootstrap";
|
|
14
14
|
import { Download, Send } from "react-bootstrap-icons";
|
|
15
|
-
import { useLocation } from "react-router-dom";
|
|
16
15
|
import { downloadZip, processProductionFiles } from "../utils/utils";
|
|
17
16
|
import { DeleteButton } from "../components/DeleteButton";
|
|
18
17
|
import { useMetadata } from "../providers/MetadataProvider";
|
|
@@ -27,27 +26,25 @@ import { RowProvider } from "../providers/RowProvider";
|
|
|
27
26
|
import { ProductionNameInput } from "../components/ProductionNameInput";
|
|
28
27
|
import { RequestEmailInput } from "../components/RequestEmailInput";
|
|
29
28
|
import { RequestButtonGroup } from "../components/RequestButtonGroup";
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
import { useWizardConfig } from "../providers/WizardConfigProvider";
|
|
30
|
+
export function RequestPage() {
|
|
32
31
|
const metadata = useMetadata();
|
|
33
32
|
const { rows, setRows, generateAllFiles } = useRows();
|
|
34
33
|
const { emailIsKnown, productionName, setProductionName, validation, showErrors, clearAll, trySubmit } = useRequest();
|
|
34
|
+
const { variant, requestSubmittedMessage, onRequestSubmitted } = useWizardConfig();
|
|
35
35
|
const [showProdUploadModal, setShowProdUploadModal] = useState(false);
|
|
36
36
|
const [prodUploadLoading, setProdUploadLoading] = useState(false);
|
|
37
37
|
const [requestSubmitted, setRequestSubmitted] = useState(false);
|
|
38
38
|
const [showReasonForRequestModal, setShowReasonForRequestModal] = useState(false);
|
|
39
|
-
const
|
|
39
|
+
const [checkedIfCloneNeeded, setCheckedIfCloneNeeded] = useState(false);
|
|
40
40
|
useEffect(() => {
|
|
41
41
|
if (!metadata) {
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (!dttConfigsString) {
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
44
|
+
// If the localStorage has been set, we should clone the configuration
|
|
45
|
+
const infoYamlString = localStorage.getItem("infoYamlToClone");
|
|
46
|
+
const dttConfigsString = localStorage.getItem("dttConfigsToClone");
|
|
47
|
+
if (dttConfigsString) {
|
|
51
48
|
setProdUploadLoading(true);
|
|
52
49
|
setRows([]);
|
|
53
50
|
try {
|
|
@@ -68,7 +65,8 @@ export function RequestPage({ basePath, submitLocation, requestReasonMessage, re
|
|
|
68
65
|
localStorage.removeItem("dttConfigsToClone");
|
|
69
66
|
}
|
|
70
67
|
}
|
|
71
|
-
|
|
68
|
+
setCheckedIfCloneNeeded(true);
|
|
69
|
+
}, [metadata]);
|
|
72
70
|
const handlePrimaryAction = async () => {
|
|
73
71
|
if (trySubmit()) {
|
|
74
72
|
if (variant === "standalone") {
|
|
@@ -80,22 +78,23 @@ export function RequestPage({ basePath, submitLocation, requestReasonMessage, re
|
|
|
80
78
|
}
|
|
81
79
|
}
|
|
82
80
|
};
|
|
83
|
-
if (!metadata) {
|
|
81
|
+
if (!metadata || !checkedIfCloneNeeded) {
|
|
84
82
|
return _jsx(LoadingIndicator, { height: "70vh" });
|
|
85
83
|
}
|
|
86
84
|
if (requestSubmitted) {
|
|
87
85
|
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
86
|
}
|
|
89
|
-
return (_jsxs(_Fragment, { children: [showReasonForRequestModal && (_jsx(ReasonForRequestModal, {
|
|
87
|
+
return (_jsxs(_Fragment, { children: [showReasonForRequestModal && (_jsx(ReasonForRequestModal, { onClose: (submitted) => {
|
|
90
88
|
setShowReasonForRequestModal(false);
|
|
91
89
|
if (submitted) {
|
|
92
90
|
setRequestSubmitted(true);
|
|
91
|
+
onRequestSubmitted?.();
|
|
93
92
|
}
|
|
94
|
-
} })), showProdUploadModal && _jsx(UploadDttConfigModal, { onClose: () => setShowProdUploadModal(false) }), _jsxs("div", { className: "d-flex flex-column gap-
|
|
93
|
+
} })), showProdUploadModal && _jsx(UploadDttConfigModal, { onClose: () => setShowProdUploadModal(false) }), _jsxs("div", { className: "d-flex flex-column gap-4", children: [rows.map((row) => (_jsx(RowProvider, { row: row, children: _jsx(RequestRow, {}, row.id) }, row.id))), prodUploadLoading && _jsx(ConfigFilesUploadingAlert, {}), showErrors &&
|
|
95
94
|
(rows.length === 0 ||
|
|
96
95
|
!validation.allRowsHaveDtt ||
|
|
97
96
|
!validation.allRowsHaveStrippingLine ||
|
|
98
97
|
!validation.allRowsHavePaths) && (_jsx(Alert, { variant: "danger", className: "mb-0", children: rows.length === 0
|
|
99
98
|
? "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, {
|
|
99
|
+
: "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: "auto", 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
100
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { createContext, useCallback, useContext, useReducer } from "react";
|
|
2
|
+
import { createContext, useCallback, useContext, useReducer, useState } from "react";
|
|
3
3
|
import Dtt from "../models/dtt";
|
|
4
4
|
const DttContext = createContext(null);
|
|
5
5
|
function reducer(state, action) {
|
|
@@ -31,6 +31,7 @@ function reducer(state, action) {
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
export function DttProvider({ initialConfig, decay, metadata, children }) {
|
|
34
|
+
const [selectedBranch, setSelectedBranch] = useState([]);
|
|
34
35
|
const [state, dispatch] = useReducer(reducer, null, () => ({
|
|
35
36
|
dtt: new Dtt(structuredClone(initialConfig), metadata.tupleTools.tupleTools),
|
|
36
37
|
decay,
|
|
@@ -66,6 +67,8 @@ export function DttProvider({ initialConfig, decay, metadata, children }) {
|
|
|
66
67
|
removeTool,
|
|
67
68
|
save,
|
|
68
69
|
revert,
|
|
70
|
+
selectedBranch,
|
|
71
|
+
setSelectedBranch,
|
|
69
72
|
};
|
|
70
73
|
return _jsx(DttContext.Provider, { value: value, children: children });
|
|
71
74
|
}
|
|
@@ -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 {};
|