lhcb-ntuple-wizard-test 1.3.3 → 2.0.1
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/README.md +1 -2
- package/dist/App.d.ts +12 -0
- package/dist/App.js +22 -0
- package/dist/components/ConfigFilesUploadingAlert.d.ts +1 -0
- package/dist/components/ConfigFilesUploadingAlert.js +5 -0
- package/dist/components/DatasetEventTypeBadge.d.ts +5 -0
- package/dist/components/DatasetEventTypeBadge.js +23 -0
- package/dist/components/DatasetInfo.d.ts +5 -0
- package/dist/components/DatasetInfo.js +21 -0
- package/dist/components/DecayLatex.d.ts +7 -0
- package/dist/components/DecayLatex.js +103 -0
- package/dist/components/DecayList.d.ts +8 -0
- package/dist/components/DecayList.js +37 -0
- package/dist/components/DecayListItem.d.ts +11 -0
- package/dist/components/DecayListItem.js +23 -0
- package/dist/components/DecayTagBadge.d.ts +5 -0
- package/dist/components/DecayTagBadge.js +21 -0
- package/dist/components/DecayTreeCard.d.ts +7 -0
- package/dist/components/DecayTreeCard.js +43 -0
- package/dist/components/DecayTreeCardHeader.d.ts +7 -0
- package/dist/components/DecayTreeCardHeader.js +5 -0
- package/dist/components/DecayTreeGraph.d.ts +9 -0
- package/dist/components/DecayTreeGraph.js +89 -0
- package/dist/components/DeleteButton.d.ts +9 -0
- package/dist/components/DeleteButton.js +16 -53
- package/dist/components/DttNameInput.d.ts +9 -0
- package/dist/components/DttNameInput.js +73 -0
- package/dist/components/LineTableRow.d.ts +9 -0
- package/dist/components/LineTableRow.js +123 -0
- package/dist/components/LoadingIndicator.d.ts +6 -0
- package/dist/components/LoadingIndicator.js +5 -0
- package/dist/components/NtupleWizard.d.ts +26 -0
- package/dist/components/NtupleWizard.js +28 -137
- package/dist/components/NumStrippingLinesBadge.d.ts +8 -0
- package/dist/components/NumStrippingLinesBadge.js +10 -0
- package/dist/components/ParticleDropdown.d.ts +8 -0
- package/dist/components/ParticleDropdown.js +33 -0
- package/dist/components/ParticleTagBadge.d.ts +9 -0
- package/dist/components/ParticleTagBadge.js +22 -0
- package/dist/components/ParticleTagFilters.d.ts +6 -0
- package/dist/components/ParticleTagFilters.js +51 -0
- package/dist/components/PolarityBadge.d.ts +5 -0
- package/dist/components/PolarityBadge.js +13 -33
- package/dist/components/StrippingLineBadge.d.ts +7 -0
- package/dist/components/StrippingLineBadge.js +29 -0
- package/dist/components/StrippingLineInfo.d.ts +8 -0
- package/dist/components/StrippingLineInfo.js +17 -0
- package/dist/components/SubmitRequestButton.d.ts +11 -0
- package/dist/components/SubmitRequestButton.js +39 -0
- package/dist/components/TagDropdown.d.ts +12 -0
- package/dist/components/TagDropdown.js +31 -0
- package/dist/components/TupleToolDocsAccordion.d.ts +5 -0
- package/dist/components/TupleToolDocsAccordion.js +14 -0
- package/dist/components/TupleToolDropdown.d.ts +21 -0
- package/dist/components/TupleToolDropdown.js +29 -0
- package/dist/components/TupleToolGroup.d.ts +6 -0
- package/dist/components/TupleToolGroup.js +22 -0
- package/dist/components/TupleToolLabel.d.ts +6 -0
- package/dist/components/TupleToolLabel.js +20 -0
- package/dist/components/TupleToolList.d.ts +7 -0
- package/dist/components/TupleToolList.js +38 -0
- package/dist/components/YearBadge.d.ts +5 -0
- package/dist/components/YearBadge.js +13 -33
- package/dist/components/modals/AddTupleToolModal.d.ts +7 -0
- package/dist/components/modals/AddTupleToolModal.js +32 -0
- package/dist/components/modals/ConfigureTupleToolModal.d.ts +8 -0
- package/dist/components/modals/ConfigureTupleToolModal.js +43 -0
- package/dist/components/modals/ReasonForRequestModal.d.ts +8 -0
- package/dist/components/modals/ReasonForRequestModal.js +49 -0
- package/dist/components/modals/UploadDttConfigModal.d.ts +7 -0
- package/dist/components/modals/UploadDttConfigModal.js +35 -0
- package/dist/components/modals/UploadProdConfigModal.d.ts +5 -0
- package/dist/components/modals/UploadProdConfigModal.js +27 -0
- package/dist/components/tupleToolParams/BoolParamInput.d.ts +16 -0
- package/dist/components/tupleToolParams/BoolParamInput.js +15 -0
- package/dist/components/tupleToolParams/DictParamInput.d.ts +14 -0
- package/dist/components/tupleToolParams/DictParamInput.js +31 -0
- package/dist/components/tupleToolParams/ListParamInput.d.ts +14 -0
- package/dist/components/tupleToolParams/ListParamInput.js +46 -0
- package/dist/components/tupleToolParams/NumParamInput.d.ts +18 -0
- package/dist/components/tupleToolParams/NumParamInput.js +25 -0
- package/dist/components/tupleToolParams/StrParamInput.d.ts +19 -0
- package/dist/components/tupleToolParams/StrParamInput.js +22 -0
- package/dist/config.d.ts +78 -0
- package/dist/config.js +72 -0
- package/dist/{style/DecaysList.css → index.d.ts} +2 -6
- package/dist/index.js +2 -11
- package/dist/models/bkPath.d.ts +11 -0
- package/dist/models/bkPath.js +40 -0
- package/dist/models/blobFile.d.ts +12 -0
- package/dist/models/blobFile.js +1 -0
- package/dist/models/decayData.d.ts +15 -0
- package/dist/models/decayData.js +1 -0
- package/dist/models/dropdownOption.d.ts +5 -0
- package/dist/models/dropdownOption.js +1 -0
- package/dist/models/dtt.d.ts +108 -0
- package/dist/models/dtt.js +149 -0
- package/dist/models/jobConfig.d.ts +7 -0
- package/dist/models/jobConfig.js +1 -0
- package/dist/models/particle.d.ts +12 -0
- package/dist/models/particle.js +1 -0
- package/dist/models/particleTag.d.ts +4 -0
- package/dist/models/particleTag.js +1 -0
- package/dist/models/rowData.d.ts +15 -0
- package/dist/models/rowData.js +1 -0
- package/dist/models/strippingLine.d.ts +5 -0
- package/dist/models/strippingLine.js +1 -0
- package/dist/models/strippingLineOption.d.ts +6 -0
- package/dist/models/strippingLineOption.js +1 -0
- package/dist/models/tupleTool.d.ts +8 -0
- package/dist/models/tupleTool.js +18 -0
- package/dist/models/tupleTreeGraphData.d.ts +20 -0
- package/dist/models/tupleTreeGraphData.js +1 -0
- package/dist/models/yamlFile.d.ts +11 -0
- package/dist/models/yamlFile.js +78 -0
- package/dist/pages/DecaySearchPage.d.ts +5 -0
- package/dist/pages/DecaySearchPage.js +197 -0
- package/dist/pages/DecayTreeConfigPage.d.ts +5 -0
- package/dist/pages/DecayTreeConfigPage.js +63 -0
- package/dist/pages/LinesTablePage.d.ts +14 -0
- package/dist/pages/LinesTablePage.js +120 -0
- package/dist/providers/DttProvider.d.ts +24 -0
- package/dist/providers/DttProvider.js +77 -0
- package/dist/providers/MetadataProvider.d.ts +87 -0
- package/dist/providers/MetadataProvider.js +50 -0
- package/dist/providers/ProductionConfigProvider.d.ts +14 -0
- package/dist/providers/ProductionConfigProvider.js +76 -0
- package/dist/providers/RequestProvider.d.ts +15 -0
- package/dist/providers/RequestProvider.js +35 -0
- package/dist/providers/RowsProvider.d.ts +14 -0
- package/dist/providers/RowsProvider.js +31 -0
- package/dist/utils/mathjaxUtils.d.ts +12 -0
- package/dist/utils/mathjaxUtils.js +24 -0
- package/dist/utils/utils.d.ts +31 -0
- package/dist/utils/utils.js +80 -0
- package/package.json +43 -21
- package/dist/components/App.js +0 -99
- package/dist/components/ConfigDict.js +0 -103
- package/dist/components/ConfigList.js +0 -94
- package/dist/components/ConfigNode.js +0 -320
- package/dist/components/ConfigValue.js +0 -86
- package/dist/components/Dataset.js +0 -67
- package/dist/components/Decay.js +0 -50
- package/dist/components/DecayItem.js +0 -101
- package/dist/components/DecayTag.js +0 -52
- package/dist/components/DecayTree.js +0 -451
- package/dist/components/DecaysList.js +0 -107
- package/dist/components/DescriptorsSearch.js +0 -352
- package/dist/components/EventTypeBadge.js +0 -45
- package/dist/components/ItemSearch.js +0 -120
- package/dist/components/LinesTable.js +0 -1105
- package/dist/components/ParticleTag.js +0 -54
- package/dist/components/SearchItem.js +0 -99
- package/dist/components/SelectParticle.js +0 -61
- package/dist/components/SelectTag.js +0 -66
- package/dist/components/SelectTool.js +0 -59
- package/dist/components/SelectVariables.js +0 -106
- package/dist/components/StrippingBadge.js +0 -64
- package/dist/components/StrippingLine.js +0 -50
- package/dist/components/TupleTool.js +0 -46
- package/dist/components/VariablesSearch.js +0 -128
- package/dist/config.json +0 -72
- package/dist/contexts/MetadataContext.js +0 -135
- package/dist/lib/BKPath.js +0 -58
- package/dist/lib/DTTConfig.js +0 -178
- package/dist/lib/mathjax.js +0 -35
- package/dist/lib/utils.js +0 -191
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Button, ButtonGroup, Card, FormControl, InputGroup, OverlayTrigger, Tooltip } from "react-bootstrap";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { Download, ExclamationCircle, GearWideConnected, PlusLg, Upload } from "react-bootstrap-icons";
|
|
5
|
+
import { DeleteButton } from "./DeleteButton";
|
|
6
|
+
import { DecayLatex } from "./DecayLatex";
|
|
7
|
+
import Dtt from "../models/dtt";
|
|
8
|
+
import { useRows } from "../providers/RowsProvider";
|
|
9
|
+
import { useNavigate } from "react-router-dom";
|
|
10
|
+
import { useMetadata } from "../providers/MetadataProvider";
|
|
11
|
+
import { downloadText } from "../utils/utils";
|
|
12
|
+
import { UploadDttConfigModal } from "./modals/UploadDttConfigModal";
|
|
13
|
+
import { YamlFile } from "../models/yamlFile";
|
|
14
|
+
export function DttNameInput({ row, hideDownloadButtons, hideUploadButtons, variablesPath }) {
|
|
15
|
+
const { rows, setRows } = useRows();
|
|
16
|
+
const navigate = useNavigate();
|
|
17
|
+
const metadata = useMetadata();
|
|
18
|
+
const [showUploadModal, setShowUploadModal] = useState(false);
|
|
19
|
+
const [dttName, setDttName] = useState(row.dtt?.getName() || "");
|
|
20
|
+
const [dttNameValid, setDttNameValid] = useState(true);
|
|
21
|
+
const [autoFocus, setAutoFocus] = useState(false);
|
|
22
|
+
if (!metadata) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
function allNameCharsValid(name) {
|
|
26
|
+
const pattern = /^[a-zA-Z0-9_:-]+$/;
|
|
27
|
+
return pattern.test(name);
|
|
28
|
+
}
|
|
29
|
+
function validateName() {
|
|
30
|
+
const trimmedName = dttName.trim();
|
|
31
|
+
const isNameEmpty = trimmedName === "";
|
|
32
|
+
const areCharsValid = allNameCharsValid(trimmedName);
|
|
33
|
+
const otherRowNames = rows.filter((r) => r.id !== row.id).map((row) => row.dtt?.getName() || "");
|
|
34
|
+
const isNameDuplicate = otherRowNames.includes(trimmedName);
|
|
35
|
+
const valid = !isNameEmpty && areCharsValid && !isNameDuplicate;
|
|
36
|
+
setDttNameValid(valid);
|
|
37
|
+
return valid;
|
|
38
|
+
}
|
|
39
|
+
const handleCreateDTT = () => {
|
|
40
|
+
const dtt = Dtt.create(row.decay.descriptors.template, row.decay.descriptors.mapped_list.flatMap((item) => (Array.isArray(item) ? item : [item])), [], "", metadata.tupleTools.tupleTools);
|
|
41
|
+
setRows((prev) => {
|
|
42
|
+
return prev.map((r) => (r.id === row.id ? { ...r, dtt: dtt.withInputsFromLines(row.lines) } : r));
|
|
43
|
+
});
|
|
44
|
+
setAutoFocus(true);
|
|
45
|
+
};
|
|
46
|
+
const handleConfigureDtt = (id) => {
|
|
47
|
+
setRows(rows.map((row) => ({ ...row, editTree: row.id === id })));
|
|
48
|
+
void navigate(variablesPath);
|
|
49
|
+
};
|
|
50
|
+
const handleDeleteDtt = (id) => {
|
|
51
|
+
setRows((prev) => prev.map((r) => (r.id === id ? { ...r, dtt: null } : r)));
|
|
52
|
+
setDttName("");
|
|
53
|
+
};
|
|
54
|
+
return (_jsxs(Card, { children: [_jsxs(Card.Header, { className: "d-flex justify-content-between align-items-start gap-2", children: [row.dtt && (_jsxs(InputGroup, { hasValidation: true, children: [_jsx(FormControl, { autoFocus: autoFocus, placeholder: "DecayTree", value: dttName, onBlur: () => {
|
|
55
|
+
if (!validateName()) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
setRows((prev) => {
|
|
59
|
+
return prev.map((r) => r.id === row.id ? { ...r, dtt: r.dtt.withName(dttName) } : r);
|
|
60
|
+
});
|
|
61
|
+
}, onChange: (event) => {
|
|
62
|
+
setDttName(event.target.value);
|
|
63
|
+
setDttNameValid(true);
|
|
64
|
+
}, isInvalid: !dttNameValid }), _jsx(FormControl.Feedback, { type: "invalid", children: dttName.trim() === ""
|
|
65
|
+
? "Name cannot be empty"
|
|
66
|
+
: !allNameCharsValid(dttName.trim())
|
|
67
|
+
? "Name contains invalid characters"
|
|
68
|
+
: "Must give a unique name" })] })), _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: () => {
|
|
69
|
+
handleConfigureDtt(row.id);
|
|
70
|
+
}, 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: () => {
|
|
71
|
+
downloadText(YamlFile.fromDtt(row.dtt));
|
|
72
|
+
}, disabled: !dttNameValid, children: _jsx(Download, {}) }) }) })), _jsx(DeleteButton, { action: () => handleDeleteDtt(row.id) })] })) : (_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, { row: row, onClose: () => setShowUploadModal(false) }))] })) })] }), _jsx(Card.Body, { children: _jsx(DecayLatex, { decay: row.decay }) })] }));
|
|
73
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { RowData } from "../models/rowData";
|
|
2
|
+
interface Props {
|
|
3
|
+
row: RowData;
|
|
4
|
+
hideDownloadButtons: boolean;
|
|
5
|
+
hideUploadButtons: boolean;
|
|
6
|
+
variablesPath: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function LineTableRow({ row, hideDownloadButtons, hideUploadButtons, variablesPath }: Props): import("react/jsx-runtime").JSX.Element | null;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button, Col, OverlayTrigger, Popover, Row } from "react-bootstrap";
|
|
3
|
+
import { StrippingLineInfo } from "./StrippingLineInfo";
|
|
4
|
+
import { useMetadata } from "../providers/MetadataProvider";
|
|
5
|
+
import { useRows } from "../providers/RowsProvider";
|
|
6
|
+
import { DatasetInfo } from "./DatasetInfo";
|
|
7
|
+
import BkPath from "../models/bkPath";
|
|
8
|
+
import { QuestionCircle } from "react-bootstrap-icons";
|
|
9
|
+
import { DeleteButton } from "./DeleteButton";
|
|
10
|
+
import Select from "react-select";
|
|
11
|
+
import Creatable from "react-select/creatable";
|
|
12
|
+
import { DttNameInput } from "./DttNameInput";
|
|
13
|
+
export function LineTableRow({ row, hideDownloadButtons, hideUploadButtons, variablesPath }) {
|
|
14
|
+
const metadata = useMetadata();
|
|
15
|
+
const { rows, setRows } = useRows();
|
|
16
|
+
if (!metadata) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
function getStrippingLineOptions() {
|
|
20
|
+
let opts = {};
|
|
21
|
+
let streams = [];
|
|
22
|
+
let lines = [];
|
|
23
|
+
let groups = [];
|
|
24
|
+
Object.keys(row.decay.lines).forEach((streamLine) => {
|
|
25
|
+
const [stream, line] = streamLine.split("/");
|
|
26
|
+
streams.push(stream);
|
|
27
|
+
lines.push(line);
|
|
28
|
+
});
|
|
29
|
+
const uniqueStreams = [...new Set(streams)];
|
|
30
|
+
uniqueStreams.forEach((uniqueStream) => {
|
|
31
|
+
opts[uniqueStream] = [];
|
|
32
|
+
lines.forEach((line, i) => {
|
|
33
|
+
if (streams[i] === uniqueStream) {
|
|
34
|
+
let duplicate = false;
|
|
35
|
+
const option = {
|
|
36
|
+
value: line,
|
|
37
|
+
label: (_jsx(StrippingLineInfo, { line: line, stream: uniqueStream, versions: row.decay.lines[uniqueStream + "/" + line] })),
|
|
38
|
+
group: uniqueStream,
|
|
39
|
+
};
|
|
40
|
+
// Check for duplicates
|
|
41
|
+
for (const option of opts[uniqueStream]) {
|
|
42
|
+
if (option.label === line) {
|
|
43
|
+
duplicate = true;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (!duplicate) {
|
|
47
|
+
opts[uniqueStream].push(option);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
groups.push({ label: uniqueStream, options: opts[uniqueStream] });
|
|
52
|
+
});
|
|
53
|
+
return groups;
|
|
54
|
+
}
|
|
55
|
+
function getOptionFromPath(path) {
|
|
56
|
+
return {
|
|
57
|
+
value: path,
|
|
58
|
+
label: _jsx(DatasetInfo, { pathString: path }),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const validatePath = (choice) => {
|
|
62
|
+
const path = new BkPath(choice);
|
|
63
|
+
if (!path.isValid()) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
return row.lines.every((line) => {
|
|
67
|
+
const streamName = line.stream.toLowerCase();
|
|
68
|
+
const fileName = path.getFilename().split(".")[0].toLowerCase();
|
|
69
|
+
const matchingVersion = line.versions.some((version) => path.getStrippingVersion() === version);
|
|
70
|
+
return ["allstreams", streamName].includes(fileName) && matchingVersion;
|
|
71
|
+
});
|
|
72
|
+
};
|
|
73
|
+
const handlePathChoice = (choices) => {
|
|
74
|
+
const validPaths = choices.filter((choice) => validatePath(choice)).map((choice) => choice);
|
|
75
|
+
const validPathOptions = row.pathOptions.filter((choice) => validatePath(choice));
|
|
76
|
+
setRows((prev) => {
|
|
77
|
+
return prev.map((r) => (r.id === row.id ? { ...r, paths: validPaths, pathOptions: validPathOptions } : r));
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
const handleRemoveRow = () => {
|
|
81
|
+
setRows(rows.filter((r) => r.id !== row.id));
|
|
82
|
+
};
|
|
83
|
+
const changeSelStrLines = (choices) => {
|
|
84
|
+
if (choices.length > 1) {
|
|
85
|
+
alert("Choosing multiple stripping lines per row can result in duplication of candidates within a given event and is therefore forbidden. To choose a different stripping line, remove the current selection.");
|
|
86
|
+
choices.pop();
|
|
87
|
+
}
|
|
88
|
+
const lines = choices.map((choice) => ({
|
|
89
|
+
stream: choice.group,
|
|
90
|
+
line: choice.value,
|
|
91
|
+
versions: row.decay.lines[choice.group + "/" + choice.value],
|
|
92
|
+
}));
|
|
93
|
+
setRows((prev) => {
|
|
94
|
+
return prev.map((r) => r.id === row.id ? { ...r, lines, dtt: r.dtt ? r.dtt.withInputsFromLines(lines) : null } : r);
|
|
95
|
+
});
|
|
96
|
+
handlePathChoice(row.paths);
|
|
97
|
+
};
|
|
98
|
+
const handleCreatePath = (choice) => {
|
|
99
|
+
if (!validatePath(choice)) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const paths = [...row.paths, choice];
|
|
103
|
+
const pathOptions = [...row.pathOptions, choice];
|
|
104
|
+
setRows((prev) => {
|
|
105
|
+
return prev.map((r) => (r.id === row.id ? { ...r, paths, pathOptions } : r));
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
const getDefaultBkPaths = () => {
|
|
109
|
+
const defaultOptions = metadata.dataset
|
|
110
|
+
.filter((path) => validatePath(path))
|
|
111
|
+
.map((path) => getOptionFromPath(path));
|
|
112
|
+
return [...defaultOptions, ...row.pathOptions.map(getOptionFromPath)];
|
|
113
|
+
};
|
|
114
|
+
return (_jsxs(Row, { className: "align-items-center", children: [_jsx(Col, { lg: true, children: _jsx(DttNameInput, { row: row, hideDownloadButtons: hideDownloadButtons, hideUploadButtons: hideUploadButtons, variablesPath: variablesPath }) }), _jsx(Col, { lg: true, children: _jsx(Select, { isMulti: true, options: getStrippingLineOptions(), defaultValue: row.lines.map((lineInfo) => ({
|
|
115
|
+
value: lineInfo.line,
|
|
116
|
+
label: (_jsx(StrippingLineInfo, { line: lineInfo.line, stream: lineInfo.stream, versions: lineInfo.versions, showLink: false })),
|
|
117
|
+
group: lineInfo.stream,
|
|
118
|
+
})), placeholder: "Stripping line", onChange: (newValue) => changeSelStrLines(newValue),
|
|
119
|
+
// Display the dropdown above text inputs and other elements
|
|
120
|
+
menuPortalTarget: document.body, menuPosition: "fixed", styles: {
|
|
121
|
+
menuPortal: (base) => ({ ...base, zIndex: 9999 }),
|
|
122
|
+
} }) }), _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, { className: "ms-auto", type: "button", disabled: row.lines.length === 0, children: _jsx(QuestionCircle, {}) }) }) }), _jsx(Col, { children: _jsx(Creatable, { isMulti: true, options: getDefaultBkPaths() /*TODO: use ODP records when ready*/, value: row.paths.map(getOptionFromPath), isDisabled: row.lines.length === 0, placeholder: "Bookkeeping path", onChange: (newValue) => handlePathChoice(newValue.map((item) => item.value)), onCreateOption: (inputValue) => handleCreatePath(inputValue), closeMenuOnSelect: false }) }), _jsx(Col, { xs: "auto", children: _jsx(DeleteButton, { action: handleRemoveRow }) })] }, row.id));
|
|
123
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Spinner } from "react-bootstrap";
|
|
3
|
+
export function LoadingIndicator({ message, height }) {
|
|
4
|
+
return (_jsx("div", { className: "d-flex justify-content-center align-items-center", style: { height: height || "auto" }, children: _jsxs("div", { className: "d-flex flex-column align-items-center", children: [_jsx(Spinner, { "data-testid": "loading-spinner", animation: "border", role: "status" }), message && _jsx("p", { className: "mt-2", children: message })] }) }));
|
|
5
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*****************************************************************************\
|
|
2
|
+
* (c) Copyright 2021 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 "bootstrap/dist/css/bootstrap.css";
|
|
12
|
+
import { ReactNode } from "react";
|
|
13
|
+
interface Props {
|
|
14
|
+
basePath: string;
|
|
15
|
+
decaysPath: string;
|
|
16
|
+
variablesPath: string;
|
|
17
|
+
contactEmail?: string;
|
|
18
|
+
submitLocation?: string;
|
|
19
|
+
hideDownloadButtons?: boolean;
|
|
20
|
+
hideUploadButtons?: boolean;
|
|
21
|
+
requestReasonMessage?: string;
|
|
22
|
+
requestSubmittedMessage?: ReactNode;
|
|
23
|
+
csrfToken?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function NtupleWizard({ basePath, decaysPath, variablesPath, submitLocation, hideDownloadButtons, hideUploadButtons, requestReasonMessage, requestSubmittedMessage, csrfToken, ...props }: Props): import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
export {};
|
|
@@ -1,142 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
function
|
|
23
|
-
|
|
24
|
-
* *
|
|
25
|
-
* This software is distributed under the terms of the GNU General Public *
|
|
26
|
-
* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". *
|
|
27
|
-
* *
|
|
28
|
-
* In applying this licence, CERN does not waive the privileges and immunities *
|
|
29
|
-
* granted to it by virtue of its status as an Intergovernmental Organization *
|
|
30
|
-
* or submit itself to any jurisdiction. *
|
|
31
|
-
\*****************************************************************************/
|
|
32
|
-
class NtupleWizard extends _react.default.Component {
|
|
33
|
-
constructor() {
|
|
34
|
-
super(...arguments);
|
|
35
|
-
_defineProperty(this, "state", {
|
|
36
|
-
rows: JSON.parse(localStorage.getItem("rows") || "[]"),
|
|
37
|
-
productionName: localStorage.getItem("name") || "",
|
|
38
|
-
contactEmail: (localStorage.getItem("email") || "").split(/,/).filter(s => s),
|
|
39
|
-
reasonForRequest: localStorage.getItem("reasonForRequest") || ""
|
|
40
|
-
});
|
|
41
|
-
_defineProperty(this, "callbackUpdateRows", rows => {
|
|
42
|
-
const newRows = rows.map(row => _objectSpread(_objectSpread({}, row), {}, {
|
|
43
|
-
dtt: row.dtt ? _lodash.default.cloneDeep(row.dtt.config) : false
|
|
44
|
-
}));
|
|
45
|
-
this.setState({
|
|
46
|
-
rows: newRows
|
|
47
|
-
});
|
|
48
|
-
const rowString = JSON.stringify(newRows);
|
|
49
|
-
localStorage.setItem("rows", rowString);
|
|
50
|
-
});
|
|
51
|
-
_defineProperty(this, "callbackUpdateInfo", (name, email, reasonForRequest) => {
|
|
52
|
-
this.setState({
|
|
53
|
-
productionName: name,
|
|
54
|
-
contactEmail: email,
|
|
55
|
-
reasonForRequest: reasonForRequest
|
|
56
|
-
});
|
|
57
|
-
localStorage.setItem("name", name);
|
|
58
|
-
localStorage.setItem("email", email.join(","));
|
|
59
|
-
localStorage.setItem("reasonForRequest", reasonForRequest);
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
render() {
|
|
63
|
-
let {
|
|
64
|
-
basePath,
|
|
65
|
-
decaysPath,
|
|
66
|
-
variablesPath,
|
|
67
|
-
contactEmail,
|
|
68
|
-
submitLocation,
|
|
69
|
-
hideDownloadButtons,
|
|
70
|
-
hideUploadButtons,
|
|
71
|
-
requestReasonMessage,
|
|
72
|
-
requestSubmittedMessage
|
|
73
|
-
} = this.props;
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/*****************************************************************************\
|
|
3
|
+
* (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration *
|
|
4
|
+
* *
|
|
5
|
+
* This software is distributed under the terms of the GNU General Public *
|
|
6
|
+
* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". *
|
|
7
|
+
* *
|
|
8
|
+
* In applying this licence, CERN does not waive the privileges and immunities *
|
|
9
|
+
* granted to it by virtue of its status as an Intergovernmental Organization *
|
|
10
|
+
* or submit itself to any jurisdiction. *
|
|
11
|
+
\*****************************************************************************/
|
|
12
|
+
import "bootstrap/dist/css/bootstrap.css";
|
|
13
|
+
import { useLocation } from "react-router-dom";
|
|
14
|
+
import { MetadataProvider } from "../providers/MetadataProvider.js";
|
|
15
|
+
import { DecaySearchPage } from "../pages/DecaySearchPage";
|
|
16
|
+
import { DecayTreeConfigPage } from "../pages/DecayTreeConfigPage";
|
|
17
|
+
import { LinesTablePage } from "../pages/LinesTablePage";
|
|
18
|
+
import { MathJaxContext } from "better-react-mathjax";
|
|
19
|
+
import { RowsProvider } from "../providers/RowsProvider.js";
|
|
20
|
+
import { RequestProvider } from "../providers/RequestProvider";
|
|
21
|
+
import { ProductionConfigProvider } from "../providers/ProductionConfigProvider";
|
|
22
|
+
export function NtupleWizard({ basePath, decaysPath, variablesPath, submitLocation, hideDownloadButtons, hideUploadButtons, requestReasonMessage, requestSubmittedMessage, csrfToken = "", ...props }) {
|
|
23
|
+
const { pathname } = useLocation();
|
|
74
24
|
let emailIsKnown = false;
|
|
75
|
-
if (contactEmail) {
|
|
76
|
-
|
|
77
|
-
|
|
25
|
+
if (props.contactEmail) {
|
|
26
|
+
localStorage.setItem("email", props.contactEmail);
|
|
27
|
+
emailIsKnown = true;
|
|
78
28
|
}
|
|
79
29
|
if (!submitLocation) {
|
|
80
|
-
|
|
30
|
+
hideDownloadButtons = false;
|
|
81
31
|
}
|
|
82
|
-
return
|
|
83
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactRouterDom.BrowserRouter, {
|
|
84
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactRouterDom.Switch, {
|
|
85
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactRouterDom.Route, {
|
|
86
|
-
exact: true,
|
|
87
|
-
path: basePath,
|
|
88
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_LinesTable.default, {
|
|
89
|
-
parentCallbackRows: this.callbackUpdateRows,
|
|
90
|
-
parentCallbackInfo: this.callbackUpdateInfo,
|
|
91
|
-
rows: this.state.rows,
|
|
92
|
-
name: this.state.productionName,
|
|
93
|
-
email: this.state.contactEmail,
|
|
94
|
-
reasonForRequest: this.state.reasonForRequest,
|
|
95
|
-
decaysPath: decaysPath,
|
|
96
|
-
variablesPath: variablesPath,
|
|
97
|
-
submitLocation: submitLocation,
|
|
98
|
-
hideDownloadButtons: hideDownloadButtons,
|
|
99
|
-
hideUploadButtons: hideUploadButtons,
|
|
100
|
-
emailIsKnown: emailIsKnown,
|
|
101
|
-
requestReasonMessage: requestReasonMessage,
|
|
102
|
-
requestSubmittedMessage: requestSubmittedMessage,
|
|
103
|
-
csrfToken: this.props.csrfToken
|
|
104
|
-
})
|
|
105
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactRouterDom.Route, {
|
|
106
|
-
exact: true,
|
|
107
|
-
path: decaysPath,
|
|
108
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_DescriptorsSearch.default, {
|
|
109
|
-
parentCallback: this.callbackUpdateRows,
|
|
110
|
-
rows: this.state.rows,
|
|
111
|
-
basePath: basePath
|
|
112
|
-
})
|
|
113
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactRouterDom.Route, {
|
|
114
|
-
exact: true,
|
|
115
|
-
path: variablesPath,
|
|
116
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_SelectVariables.default, {
|
|
117
|
-
parentCallback: this.callbackUpdateRows,
|
|
118
|
-
rows: this.state.rows,
|
|
119
|
-
basePath: basePath
|
|
120
|
-
})
|
|
121
|
-
})]
|
|
122
|
-
})
|
|
123
|
-
})
|
|
124
|
-
});
|
|
125
|
-
}
|
|
32
|
+
return (_jsx(MetadataProvider, { children: _jsx(ProductionConfigProvider, { children: _jsx(RowsProvider, { children: _jsx(RequestProvider, { children: _jsx(MathJaxContext, { children: pathname.endsWith("/select-decays") ? (_jsx(DecaySearchPage, { basePath: basePath })) : pathname.endsWith("/variables") ? (_jsx(DecayTreeConfigPage, { basePath: basePath })) : (_jsx(LinesTablePage, { decaysPath: decaysPath, variablesPath: variablesPath, submitLocation: submitLocation, hideDownloadButtons: hideDownloadButtons, hideUploadButtons: hideUploadButtons, emailIsKnown: emailIsKnown, requestReasonMessage: requestReasonMessage, requestSubmittedMessage: requestSubmittedMessage, csrfToken: csrfToken })) }) }) }) }) }));
|
|
126
33
|
}
|
|
127
|
-
NtupleWizard.propTypes = {
|
|
128
|
-
basePath: _propTypes.default.string.isRequired,
|
|
129
|
-
decaysPath: _propTypes.default.string.isRequired,
|
|
130
|
-
variablesPath: _propTypes.default.string.isRequired,
|
|
131
|
-
contactEmail: _propTypes.default.string,
|
|
132
|
-
submitLocation: _propTypes.default.string,
|
|
133
|
-
hideDownloadButtons: _propTypes.default.bool,
|
|
134
|
-
hideUploadButtons: _propTypes.default.bool,
|
|
135
|
-
requestReasonMessage: _propTypes.default.string,
|
|
136
|
-
requestSubmittedMessage: _propTypes.default.object,
|
|
137
|
-
csrfToken: _propTypes.default.string
|
|
138
|
-
};
|
|
139
|
-
NtupleWizard.defaultProps = {
|
|
140
|
-
csrfToken: ""
|
|
141
|
-
};
|
|
142
|
-
var _default = exports.default = NtupleWizard;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Badge, OverlayTrigger, Popover } from "react-bootstrap";
|
|
3
|
+
import { StrippingLineInfo } from "./StrippingLineInfo.js";
|
|
4
|
+
export function NumStrippingLinesBadge({ strippingLines, selected }) {
|
|
5
|
+
const numStrippingLines = Object.keys(strippingLines).length;
|
|
6
|
+
return (_jsx(OverlayTrigger, { placement: "right", overlay: _jsxs(Popover, { children: [_jsx(Popover.Header, { children: "Stripping lines" }), _jsx(Popover.Body, { children: Object.keys(strippingLines).map((line) => {
|
|
7
|
+
const [stream, name] = line.split("/");
|
|
8
|
+
return (_jsx(StrippingLineInfo, { line: name, stream: stream, versions: strippingLines[line] }, line));
|
|
9
|
+
}) })] }), children: _jsxs(Badge, { pill: true, bg: selected ? "primary" : "secondary", children: [numStrippingLines, " stripping line", numStrippingLines === 1 ? "" : "s"] }) }));
|
|
10
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Props as SelectProps } from "react-select";
|
|
2
|
+
import { DropdownOption } from "../models/dropdownOption";
|
|
3
|
+
interface Props extends SelectProps<DropdownOption> {
|
|
4
|
+
onlyHeads?: boolean;
|
|
5
|
+
onlyKnown?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function ParticleDropdown({ onlyHeads, onlyKnown, ...props }: Props): import("react/jsx-runtime").JSX.Element | null;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/*****************************************************************************\
|
|
3
|
+
* (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration *
|
|
4
|
+
* *
|
|
5
|
+
* This software is distributed under the terms of the GNU General Public *
|
|
6
|
+
* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". *
|
|
7
|
+
* *
|
|
8
|
+
* In applying this licence, CERN does not waive the privileges and immunities *
|
|
9
|
+
* granted to it by virtue of its status as an Intergovernmental Organization *
|
|
10
|
+
* or submit itself to any jurisdiction. *
|
|
11
|
+
\*****************************************************************************/
|
|
12
|
+
import { MathJax } from "better-react-mathjax";
|
|
13
|
+
import Select from "react-select";
|
|
14
|
+
import { useMetadata } from "../providers/MetadataProvider.js";
|
|
15
|
+
export function ParticleDropdown({ onlyHeads, onlyKnown, ...props }) {
|
|
16
|
+
const metadata = useMetadata();
|
|
17
|
+
if (!metadata) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
const allowedParticles = () => onlyHeads
|
|
21
|
+
? [...new Set(Object.values(metadata.decays).map((decay) => decay.descriptors.list[0]))]
|
|
22
|
+
: onlyKnown
|
|
23
|
+
? Object.keys(metadata.particleProperties).filter((key) => !metadata.particleProperties[key].hide)
|
|
24
|
+
: Object.keys(metadata.particleProperties);
|
|
25
|
+
const loaded = metadata && (!onlyHeads || metadata.decays);
|
|
26
|
+
const options = loaded
|
|
27
|
+
? allowedParticles().map((key) => ({
|
|
28
|
+
value: key,
|
|
29
|
+
label: _jsx(MathJax, { inline: true, children: `\\(${metadata.particleProperties[key]["latex"]}\\)` }),
|
|
30
|
+
}))
|
|
31
|
+
: [];
|
|
32
|
+
return (_jsx("div", { className: "react-select form-control p-0", children: _jsx(Select, { options: options, isLoading: !loaded, filterOption: (candidate, input) => candidate.value.toLowerCase().startsWith(input.toLowerCase()), ...props }) }));
|
|
33
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ElementType } from "react";
|
|
2
|
+
import { ParticleTag } from "../models/particleTag";
|
|
3
|
+
interface Props {
|
|
4
|
+
tag: ParticleTag;
|
|
5
|
+
as?: ElementType;
|
|
6
|
+
onClick?: () => void;
|
|
7
|
+
}
|
|
8
|
+
export declare function ParticleTagBadge({ tag, as, onClick }: Props): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/*****************************************************************************\
|
|
3
|
+
* (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration *
|
|
4
|
+
* *
|
|
5
|
+
* This software is distributed under the terms of the GNU General Public *
|
|
6
|
+
* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". *
|
|
7
|
+
* *
|
|
8
|
+
* In applying this licence, CERN does not waive the privileges and immunities *
|
|
9
|
+
* granted to it by virtue of its status as an Intergovernmental Organization *
|
|
10
|
+
* or submit itself to any jurisdiction. *
|
|
11
|
+
\*****************************************************************************/
|
|
12
|
+
import { Badge, OverlayTrigger, Spinner, Tooltip } from "react-bootstrap";
|
|
13
|
+
import { useMetadata } from "../providers/MetadataProvider.js";
|
|
14
|
+
import { config } from "../config.js";
|
|
15
|
+
export function ParticleTagBadge({ tag, as, onClick }) {
|
|
16
|
+
const metadata = useMetadata();
|
|
17
|
+
const background = metadata
|
|
18
|
+
? config.particleTagGroupStyles[tag.group]
|
|
19
|
+
: "dark";
|
|
20
|
+
const description = metadata ? (metadata.userHints.particleTags[tag.label].description) : (_jsx(Spinner, { animation: "border" }));
|
|
21
|
+
return (_jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: description }), children: _jsx(Badge, { pill: true, bg: background, text: "light", as: as, onClick: onClick, children: tag.label }) }));
|
|
22
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Card, Stack } from "react-bootstrap";
|
|
3
|
+
import { ParticleTagBadge } from "./ParticleTagBadge";
|
|
4
|
+
import { useMetadata } from "../providers/MetadataProvider";
|
|
5
|
+
import { useDtt } from "../providers/DttProvider";
|
|
6
|
+
import { useCallback, useMemo } from "react";
|
|
7
|
+
export function ParticleTagFilters({ branch, onSelectTag }) {
|
|
8
|
+
const metadata = useMetadata();
|
|
9
|
+
const { dtt } = useDtt();
|
|
10
|
+
if (!metadata) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
const selectAllByTag = useCallback((tag) => {
|
|
14
|
+
if (!metadata)
|
|
15
|
+
return;
|
|
16
|
+
const allBranches = dtt.config.branches;
|
|
17
|
+
const matchingBranches = Object.keys(allBranches)
|
|
18
|
+
.filter((branch) => {
|
|
19
|
+
const particle = allBranches[branch].particle;
|
|
20
|
+
const particleTags = metadata.particleProperties[particle].tags;
|
|
21
|
+
return particleTags.includes(tag.label);
|
|
22
|
+
})
|
|
23
|
+
.sort();
|
|
24
|
+
onSelectTag(matchingBranches);
|
|
25
|
+
}, [dtt, metadata]);
|
|
26
|
+
const particleTags = useMemo(() => {
|
|
27
|
+
const tagInfo = metadata.userHints.particleTags;
|
|
28
|
+
let particleTags;
|
|
29
|
+
if (branch.length > 0) {
|
|
30
|
+
const allParticles = dtt
|
|
31
|
+
.getParticlesByBranchId(branch)
|
|
32
|
+
.map((particle) => metadata.particleProperties[particle]);
|
|
33
|
+
const allTags = new Set(allParticles.map((particle) => particle.tags.filter((tag) => !tagInfo[tag].hide)).flat());
|
|
34
|
+
particleTags = Array.from(allTags)
|
|
35
|
+
.map((tag) => ({ label: tag, group: tagInfo[tag].group }))
|
|
36
|
+
.filter((tag) => allParticles.every((particle) => particle.tags.includes(tag.label)));
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
const allBranches = dtt.config.branches;
|
|
40
|
+
const allParticles = Object.keys(allBranches).map((branch) => metadata.particleProperties[allBranches[branch].particle]);
|
|
41
|
+
const uniqueTags = new Set(allParticles.map((particle) => particle.tags.filter((tag) => !tagInfo[tag].hide)).flat());
|
|
42
|
+
particleTags = Array.from(uniqueTags).map((tag) => ({ label: tag, group: tagInfo[tag].group }));
|
|
43
|
+
}
|
|
44
|
+
return particleTags;
|
|
45
|
+
}, [dtt, metadata, branch]);
|
|
46
|
+
if (particleTags.length === 0) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const groupedTags = Object.groupBy([...particleTags].sort((a, b) => a.group.localeCompare(b.group)), (tag) => tag.group);
|
|
50
|
+
return (_jsxs(_Fragment, { children: [_jsx(Card.Title, { children: "Select by category" }), _jsx(Stack, { className: "mt-1", direction: "horizontal", style: { flexWrap: "wrap", justifyContent: "center" }, gap: 2, children: Object.entries(groupedTags).map(([group, tags]) => (_jsx(Stack, { direction: "horizontal", style: { flexWrap: "wrap" }, gap: 1, children: tags.map((tag) => (_jsx(ParticleTagBadge, { as: "button", tag: tag, onClick: () => selectAllByTag(tag) }, tag.label))) }, group))) })] }));
|
|
51
|
+
}
|