lhcb-ntuple-wizard-test 2.0.7 → 2.2.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.
Files changed (184) hide show
  1. package/dist/App.js +2 -1
  2. package/dist/components/AddTupleToolButton.d.ts +1 -0
  3. package/dist/components/AddTupleToolButton.js +16 -0
  4. package/dist/components/BookkeepingPathDropdown.d.ts +1 -1
  5. package/dist/components/BookkeepingPathDropdown.js +1 -4
  6. package/dist/components/DatasetEventTypeBadge.js +1 -1
  7. package/dist/components/DatasetInfo.js +3 -3
  8. package/dist/components/DecayCard.d.ts +1 -0
  9. package/dist/components/DecayCard.js +47 -0
  10. package/dist/components/DecayLatex.d.ts +1 -1
  11. package/dist/components/DecayLatex.js +4 -87
  12. package/dist/components/DecayListItem.js +2 -2
  13. package/dist/components/DecayTagBadge.d.ts +1 -1
  14. package/dist/components/DecayTagBadge.js +0 -3
  15. package/dist/components/DecayTreeCard.d.ts +1 -7
  16. package/dist/components/DecayTreeCard.js +14 -22
  17. package/dist/components/DecayTreeCardHeader.d.ts +2 -3
  18. package/dist/components/DecayTreeCardHeader.js +2 -2
  19. package/dist/components/DecayTreeGraph.d.ts +1 -5
  20. package/dist/components/DecayTreeGraph.js +160 -49
  21. package/dist/components/DeleteButton.d.ts +3 -1
  22. package/dist/components/DeleteButton.js +2 -2
  23. package/dist/components/DttNameInput.d.ts +9 -1
  24. package/dist/components/DttNameInput.js +29 -61
  25. package/dist/components/GuideLinkButton.d.ts +15 -0
  26. package/dist/components/GuideLinkButton.js +16 -0
  27. package/dist/components/NtupleWizard.js +1 -2
  28. package/dist/components/ParticleDropdown.d.ts +11 -1
  29. package/dist/components/ParticleDropdown.js +3 -6
  30. package/dist/components/ParticleLatex.d.ts +6 -0
  31. package/dist/components/ParticleLatex.js +13 -0
  32. package/dist/components/ParticleTagBadge.d.ts +2 -1
  33. package/dist/components/ParticleTagBadge.js +5 -7
  34. package/dist/components/ParticleTagFilters.d.ts +1 -6
  35. package/dist/components/ParticleTagFilters.js +16 -17
  36. package/dist/components/RequestButtonGroup.d.ts +1 -1
  37. package/dist/components/RequestButtonGroup.js +2 -5
  38. package/dist/components/RequestRow.d.ts +1 -1
  39. package/dist/components/RequestRow.js +8 -12
  40. package/dist/components/StrippingLineDropdown.js +14 -16
  41. package/dist/components/StrippingLineInfo.d.ts +5 -5
  42. package/dist/components/StrippingLineInfo.js +14 -4
  43. package/dist/components/StrippingLineInfoButton.d.ts +6 -0
  44. package/dist/components/StrippingLineInfoButton.js +7 -0
  45. package/dist/components/StrippingLineVersionBadge.d.ts +7 -0
  46. package/dist/components/{StrippingLineBadge.js → StrippingLineVersionBadge.js} +5 -5
  47. package/dist/components/StrippingLinesCountBadge.d.ts +8 -0
  48. package/dist/components/StrippingLinesCountBadge.js +11 -0
  49. package/dist/components/TagDropdown.d.ts +3 -3
  50. package/dist/components/TagDropdown.js +2 -2
  51. package/dist/components/{TupleToolDropdown.d.ts → TupleToolClassDropdown.d.ts} +2 -5
  52. package/dist/components/{TupleToolDropdown.js → TupleToolClassDropdown.js} +16 -13
  53. package/dist/components/TupleToolDocsAccordion.d.ts +1 -1
  54. package/dist/components/TupleToolDocsAccordion.js +4 -8
  55. package/dist/components/TupleToolGroupsAccordion.d.ts +5 -0
  56. package/dist/components/TupleToolGroupsAccordion.js +31 -0
  57. package/dist/components/TupleToolLabel.d.ts +1 -1
  58. package/dist/components/TupleToolLabel.js +2 -5
  59. package/dist/components/TupleToolsAccordion.d.ts +1 -0
  60. package/dist/components/TupleToolsAccordion.js +22 -0
  61. package/dist/components/VerticalLine.d.ts +7 -0
  62. package/dist/components/VerticalLine.js +4 -0
  63. package/dist/components/modals/AddTupleToolModal.d.ts +3 -4
  64. package/dist/components/modals/AddTupleToolModal.js +13 -12
  65. package/dist/components/modals/ConfigureTupleToolModal.d.ts +2 -2
  66. package/dist/components/modals/ConfigureTupleToolModal.js +28 -11
  67. package/dist/components/modals/UploadDttConfigModal.d.ts +1 -1
  68. package/dist/components/modals/UploadDttConfigModal.js +1 -4
  69. package/dist/config.d.ts +19 -47
  70. package/dist/config.js +27 -39
  71. package/dist/models/bkPath.js +1 -1
  72. package/dist/models/dtt.d.ts +5 -2
  73. package/dist/models/dtt.js +37 -18
  74. package/dist/models/rowData.d.ts +1 -1
  75. package/dist/models/yamlFile.js +1 -1
  76. package/dist/pages/DecaySearchPage.js +4 -9
  77. package/dist/pages/DecayTreeConfigPage.js +5 -39
  78. package/dist/pages/RequestPage.js +11 -16
  79. package/dist/providers/DttProvider.d.ts +5 -3
  80. package/dist/providers/DttProvider.js +33 -55
  81. package/dist/providers/MetadataProvider.d.ts +1 -1
  82. package/dist/providers/MetadataProvider.js +11 -5
  83. package/dist/providers/RequestProvider.js +2 -2
  84. package/dist/providers/RowProvider.d.ts +2 -2
  85. package/dist/providers/RowProvider.js +10 -9
  86. package/dist/providers/RowsProvider.js +0 -3
  87. package/dist/tests/components/BookkeepingPathDropdown.test.d.ts +1 -0
  88. package/dist/tests/components/BookkeepingPathDropdown.test.js +118 -0
  89. package/dist/tests/components/DatasetInfo.test.d.ts +1 -0
  90. package/dist/tests/components/DatasetInfo.test.js +38 -0
  91. package/dist/tests/components/DecayCard.test.d.ts +1 -0
  92. package/dist/tests/components/DecayCard.test.js +115 -0
  93. package/dist/tests/components/DecayLatex.test.d.ts +1 -0
  94. package/dist/tests/components/DecayLatex.test.js +31 -0
  95. package/dist/tests/components/DecayList.test.d.ts +1 -0
  96. package/dist/tests/components/DecayList.test.js +76 -0
  97. package/dist/tests/components/DecayListItem.test.d.ts +1 -0
  98. package/dist/tests/components/DecayListItem.test.js +51 -0
  99. package/dist/tests/components/DecayTreeCard.test.d.ts +1 -0
  100. package/dist/tests/components/DecayTreeCard.test.js +119 -0
  101. package/dist/tests/components/DecayTreeGraph.test.d.ts +1 -0
  102. package/dist/tests/components/DecayTreeGraph.test.js +125 -0
  103. package/dist/tests/components/DeleteButton.test.d.ts +1 -0
  104. package/dist/tests/components/DeleteButton.test.js +45 -0
  105. package/dist/tests/components/DttNameInput.test.d.ts +1 -0
  106. package/dist/tests/components/DttNameInput.test.js +75 -0
  107. package/dist/tests/components/NtupleWizard.test.d.ts +1 -0
  108. package/dist/tests/components/NtupleWizard.test.js +57 -0
  109. package/dist/tests/components/ParticleDropdown.test.d.ts +1 -0
  110. package/dist/tests/components/ParticleDropdown.test.js +23 -0
  111. package/dist/tests/components/ParticleTagFilters.test.d.ts +1 -0
  112. package/dist/tests/components/ParticleTagFilters.test.js +87 -0
  113. package/dist/tests/components/RequestButtonGroup.test.d.ts +1 -0
  114. package/dist/tests/components/RequestButtonGroup.test.js +132 -0
  115. package/dist/tests/components/RequestRow.test.d.ts +1 -0
  116. package/dist/tests/components/RequestRow.test.js +58 -0
  117. package/dist/tests/components/StrippingLineDropdown.test.d.ts +1 -0
  118. package/dist/tests/components/StrippingLineDropdown.test.js +88 -0
  119. package/dist/tests/components/badges.test.d.ts +1 -0
  120. package/dist/tests/components/badges.test.js +120 -0
  121. package/dist/tests/components/dropdowns.test.d.ts +1 -0
  122. package/dist/tests/components/dropdowns.test.js +110 -0
  123. package/dist/tests/components/dttComponents.test.d.ts +1 -0
  124. package/dist/tests/components/dttComponents.test.js +287 -0
  125. package/dist/tests/components/formInputs.test.d.ts +1 -0
  126. package/dist/tests/components/formInputs.test.js +96 -0
  127. package/dist/tests/components/metadataComponents.test.d.ts +1 -0
  128. package/dist/tests/components/metadataComponents.test.js +137 -0
  129. package/dist/tests/components/miscComponents.test.d.ts +1 -0
  130. package/dist/tests/components/miscComponents.test.js +134 -0
  131. package/dist/tests/components/modals.test.d.ts +1 -0
  132. package/dist/tests/components/modals.test.js +554 -0
  133. package/dist/tests/components/tupleToolParams.test.d.ts +1 -0
  134. package/dist/tests/components/tupleToolParams.test.js +213 -0
  135. package/dist/tests/config.test.d.ts +1 -0
  136. package/dist/tests/config.test.js +31 -0
  137. package/dist/tests/mockSetup.d.ts +1 -0
  138. package/dist/tests/mockSetup.js +30 -0
  139. package/dist/tests/models/BkPath.test.d.ts +1 -0
  140. package/dist/tests/models/BkPath.test.js +87 -0
  141. package/dist/tests/models/Dtt.test.d.ts +1 -0
  142. package/dist/tests/models/Dtt.test.js +376 -0
  143. package/dist/tests/models/TupleTool.test.d.ts +1 -0
  144. package/dist/tests/models/TupleTool.test.js +80 -0
  145. package/dist/tests/models/YamlFile.test.d.ts +1 -0
  146. package/dist/tests/models/YamlFile.test.js +123 -0
  147. package/dist/tests/pages/DecaySearchPage.test.d.ts +1 -0
  148. package/dist/tests/pages/DecaySearchPage.test.js +228 -0
  149. package/dist/tests/pages/DecayTreeConfigPage.test.d.ts +1 -0
  150. package/dist/tests/pages/DecayTreeConfigPage.test.js +105 -0
  151. package/dist/tests/pages/RequestPage.test.d.ts +1 -0
  152. package/dist/tests/pages/RequestPage.test.js +439 -0
  153. package/dist/tests/providers/DttProvider.test.d.ts +1 -0
  154. package/dist/tests/providers/DttProvider.test.js +105 -0
  155. package/dist/tests/providers/MetadataProvider.test.d.ts +1 -0
  156. package/dist/tests/providers/MetadataProvider.test.js +129 -0
  157. package/dist/tests/providers/RequestProvider.test.d.ts +1 -0
  158. package/dist/tests/providers/RequestProvider.test.js +306 -0
  159. package/dist/tests/providers/RowProvider.test.d.ts +1 -0
  160. package/dist/tests/providers/RowProvider.test.js +110 -0
  161. package/dist/tests/providers/RowsProvider.test.d.ts +1 -0
  162. package/dist/tests/providers/RowsProvider.test.js +84 -0
  163. package/dist/tests/providers/WizardConfigProvider.test.d.ts +1 -0
  164. package/dist/tests/providers/WizardConfigProvider.test.js +36 -0
  165. package/dist/tests/setupTests.d.ts +1 -0
  166. package/dist/tests/setupTests.js +15 -0
  167. package/dist/tests/testUtils.d.ts +33 -0
  168. package/dist/tests/testUtils.js +196 -0
  169. package/dist/tests/utils/latexUtils.test.d.ts +1 -0
  170. package/dist/tests/utils/latexUtils.test.js +62 -0
  171. package/dist/tests/utils/utils.test.d.ts +1 -0
  172. package/dist/tests/utils/utils.test.js +394 -0
  173. package/dist/utils/latexUtils.d.ts +13 -0
  174. package/dist/utils/latexUtils.js +86 -0
  175. package/dist/utils/utils.d.ts +1 -0
  176. package/dist/utils/utils.js +40 -4
  177. package/package.json +24 -10
  178. package/dist/components/NumStrippingLinesBadge.d.ts +0 -8
  179. package/dist/components/NumStrippingLinesBadge.js +0 -10
  180. package/dist/components/StrippingLineBadge.d.ts +0 -7
  181. package/dist/components/TupleToolGroup.d.ts +0 -6
  182. package/dist/components/TupleToolGroup.js +0 -22
  183. package/dist/components/TupleToolList.d.ts +0 -7
  184. package/dist/components/TupleToolList.js +0 -38
@@ -3,7 +3,9 @@ interface Props {
3
3
  action: () => void;
4
4
  outline?: boolean;
5
5
  disabled?: boolean;
6
+ popupMessage?: string;
7
+ placement?: "auto" | "top" | "bottom" | "left" | "right";
6
8
  children?: ReactNode;
7
9
  }
8
- export declare function DeleteButton({ action, outline, disabled, children }: Props): import("react/jsx-runtime").JSX.Element | null;
10
+ export declare function DeleteButton({ action, outline, disabled, popupMessage, placement, children, }: Props): import("react/jsx-runtime").JSX.Element | null;
9
11
  export {};
@@ -11,9 +11,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
11
  \*****************************************************************************/
12
12
  import { Button, OverlayTrigger, Popover } from "react-bootstrap";
13
13
  import { Trash } from "react-bootstrap-icons";
14
- export function DeleteButton({ action, outline, disabled, children }) {
14
+ export function DeleteButton({ action, outline, disabled, popupMessage = "Confirm", placement = "auto", children, }) {
15
15
  if (disabled) {
16
16
  return null;
17
17
  }
18
- return (_jsx(OverlayTrigger, { trigger: "click", placement: "auto", rootClose: true, overlay: _jsx(Popover, { children: _jsx(Popover.Body, { children: _jsx(Button, { variant: "danger", onClick: action, children: "Confirm" }) }) }), children: _jsxs(Button, { variant: outline ? "outline-danger" : "danger", disabled: disabled, children: [_jsx(Trash, {}), " ", children] }) }));
18
+ return (_jsx(OverlayTrigger, { trigger: "click", placement: placement, rootClose: true, overlay: _jsx(Popover, { children: _jsx(Popover.Body, { children: _jsx(Button, { variant: "danger", onClick: action, children: popupMessage }) }) }), children: _jsxs(Button, { variant: outline ? "outline-danger" : "danger", disabled: disabled, children: [_jsx(Trash, {}), " ", children] }) }));
19
19
  }
@@ -1 +1,9 @@
1
- export declare function DttNameInput(): import("react/jsx-runtime").JSX.Element | null;
1
+ import Dtt from "../models/dtt";
2
+ interface Props {
3
+ dtt: Dtt;
4
+ rowId: number;
5
+ autoFocus?: boolean;
6
+ onNameValidated?: (valid: boolean) => void;
7
+ }
8
+ export declare function DttNameInput({ dtt, rowId, autoFocus, onNameValidated }: Props): import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -1,75 +1,43 @@
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";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { FormControl, InputGroup } from "react-bootstrap";
3
+ import { useEffect, useRef, useState } from "react";
8
4
  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 { YamlFile } from "../models/yamlFile";
13
- import { UploadDttConfigModal } from "./modals/UploadDttConfigModal";
14
- import { VARIABLES_PATH } from "../constants";
15
- import { useRow } from "../providers/RowProvider";
16
- import { useWizardConfig } from "../providers/WizardConfigProvider";
17
- export function DttNameInput() {
18
- const { row } = useRow();
5
+ export function DttNameInput({ dtt, rowId, autoFocus, onNameValidated }) {
19
6
  const { rows, updateRow } = useRows();
20
- const navigate = useNavigate();
21
- const metadata = useMetadata();
22
- const { basePath, variant } = useWizardConfig();
23
- const [showUploadModal, setShowUploadModal] = useState(false);
24
- const [dttName, setDttName] = useState(row.dtt?.getName() || "");
25
- const [dttNameValid, setDttNameValid] = useState(true);
26
- const [autoFocus, setAutoFocus] = useState(false);
27
- if (!metadata) {
28
- return null;
29
- }
7
+ const inputRef = useRef(null);
8
+ const [name, setName] = useState(dtt.getName());
9
+ const [valid, setValid] = useState(true);
30
10
  function allNameCharsValid(name) {
31
11
  const pattern = /^[a-zA-Z0-9_:-]+$/;
32
12
  return pattern.test(name);
33
13
  }
34
14
  function validateName() {
35
- const trimmedName = dttName.trim();
15
+ const trimmedName = name.trim();
36
16
  const isNameEmpty = trimmedName === "";
37
17
  const areCharsValid = allNameCharsValid(trimmedName);
38
- const otherRowNames = rows.filter((r) => r.id !== row.id).map((row) => row.dtt?.getName() || "");
18
+ const otherRowNames = rows.filter((r) => r.id !== rowId).map((row) => row.dtt?.getName() || "");
39
19
  const isNameDuplicate = otherRowNames.includes(trimmedName);
40
20
  const valid = !isNameEmpty && areCharsValid && !isNameDuplicate;
41
- setDttNameValid(valid);
21
+ setValid(valid);
22
+ onNameValidated?.(valid);
42
23
  return valid;
43
24
  }
44
- const handleCreateDTT = () => {
45
- const dtt = Dtt.create(row.decay.descriptors.template, row.decay.descriptors.mapped_list.flatMap((item) => (Array.isArray(item) ? item : [item])), [], "", metadata.tupleTools.tupleTools);
46
- updateRow(row.id, (r) => ({
47
- ...r,
48
- dtt: dtt.withInputsFromLines(row.lines),
49
- }));
50
- setAutoFocus(true);
51
- };
52
- const handleConfigureDtt = () => {
53
- updateRow(row.id, (r) => ({ ...r, editTree: true }));
54
- void navigate(`${basePath}${VARIABLES_PATH}`);
55
- };
56
- const handleDeleteDtt = () => {
57
- updateRow(row.id, (r) => ({ ...r, dtt: null }));
58
- setDttName("");
59
- };
60
- 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: () => {
61
- if (!validateName()) {
62
- return;
63
- }
64
- updateRow(row.id, (r) => ({ ...r, dtt: r.dtt.withName(dttName) }));
65
- }, onChange: (event) => {
66
- setDttName(event.target.value);
67
- setDttNameValid(true);
68
- }, isInvalid: !dttNameValid }), _jsx(FormControl.Feedback, { type: "invalid", children: dttName.trim() === ""
69
- ? "Name cannot be empty"
70
- : !allNameCharsValid(dttName.trim())
71
- ? "Name contains invalid characters"
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: () => {
73
- downloadText(YamlFile.fromDtt(row.dtt));
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 }) })] }));
25
+ useEffect(() => {
26
+ if (autoFocus) {
27
+ inputRef.current?.select();
28
+ }
29
+ }, [autoFocus]);
30
+ return (_jsxs(InputGroup, { hasValidation: true, children: [_jsx(FormControl, { ref: inputRef, placeholder: "MyDecayTree", value: name, onBlur: () => {
31
+ if (!validateName()) {
32
+ return;
33
+ }
34
+ updateRow(rowId, (r) => ({ ...r, dtt: r.dtt.withName(name) }));
35
+ }, onChange: (event) => {
36
+ setName(event.target.value);
37
+ setValid(true);
38
+ }, isInvalid: !valid }), _jsx(FormControl.Feedback, { type: "invalid", children: name.trim() === ""
39
+ ? "Name cannot be empty"
40
+ : !allNameCharsValid(name.trim())
41
+ ? "Name contains invalid characters"
42
+ : "Name is already taken" })] }));
75
43
  }
@@ -0,0 +1,15 @@
1
+ declare const GUIDE_URLS: {
2
+ readonly selectingDecays: "https://lhcb-opendata-guide.web.cern.ch/ntupling-service/dataset-discovery/selecting-decays/";
3
+ readonly strippingLines: "https://lhcb-opendata-guide.web.cern.ch/ntupling-service/dataset-discovery/stripping-lines/";
4
+ readonly datasets: "https://lhcb-opendata-guide.web.cern.ch/ntupling-service/dataset-discovery/bookkeeping-path/";
5
+ readonly ntupleCreation: "https://lhcb-opendata-guide.web.cern.ch/ntupling-service/ntuple-configuration/ntuple-creation/";
6
+ readonly nodeTree: "https://lhcb-opendata-guide.web.cern.ch/ntupling-service/ntuple-configuration/nodetree/";
7
+ readonly tupleTools: "https://lhcb-opendata-guide.web.cern.ch/ntupling-service/ntuple-configuration/tupletools/";
8
+ readonly submittingRequests: "https://lhcb-opendata-guide.web.cern.ch/ntupling-service/ntuple-configuration/submitting-requests/";
9
+ };
10
+ interface Props {
11
+ page: keyof typeof GUIDE_URLS;
12
+ topic: string;
13
+ }
14
+ export declare function GuideLinkButton({ page, topic }: Props): import("react/jsx-runtime").JSX.Element;
15
+ export {};
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { OverlayTrigger, Tooltip } from "react-bootstrap";
3
+ import { InfoCircleFill } from "react-bootstrap-icons";
4
+ const GUIDE_BASE_URL = "https://lhcb-opendata-guide.web.cern.ch/ntupling-service";
5
+ const GUIDE_URLS = {
6
+ selectingDecays: `${GUIDE_BASE_URL}/dataset-discovery/selecting-decays/`,
7
+ strippingLines: `${GUIDE_BASE_URL}/dataset-discovery/stripping-lines/`,
8
+ datasets: `${GUIDE_BASE_URL}/dataset-discovery/bookkeeping-path/`,
9
+ ntupleCreation: `${GUIDE_BASE_URL}/ntuple-configuration/ntuple-creation/`,
10
+ nodeTree: `${GUIDE_BASE_URL}/ntuple-configuration/nodetree/`,
11
+ tupleTools: `${GUIDE_BASE_URL}/ntuple-configuration/tupletools/`,
12
+ submittingRequests: `${GUIDE_BASE_URL}/ntuple-configuration/submitting-requests/`,
13
+ };
14
+ export function GuideLinkButton({ page, topic }) {
15
+ return (_jsx(OverlayTrigger, { overlay: _jsxs(Tooltip, { children: ["Guide: ", topic] }), children: _jsx("a", { href: GUIDE_URLS[page], target: "_blank", rel: "noreferrer", className: "text-muted", style: { lineHeight: 1, display: "inline-flex", alignItems: "center" }, children: _jsx(InfoCircleFill, { size: 14 }) }) }));
16
+ }
@@ -15,7 +15,6 @@ import { MetadataProvider } from "../providers/MetadataProvider.js";
15
15
  import { DecaySearchPage } from "../pages/DecaySearchPage";
16
16
  import { DecayTreeConfigPage } from "../pages/DecayTreeConfigPage";
17
17
  import { RequestPage } from "../pages/RequestPage";
18
- import { MathJaxContext } from "better-react-mathjax";
19
18
  import { RowsProvider } from "../providers/RowsProvider.js";
20
19
  import { RequestProvider } from "../providers/RequestProvider";
21
20
  import { SELECT_DECAYS_PATH, VARIABLES_PATH } from "../constants";
@@ -25,5 +24,5 @@ export function NtupleWizard({ basePath = "", contactEmail, submitLocation, requ
25
24
  if (contactEmail) {
26
25
  localStorage.setItem("email", contactEmail);
27
26
  }
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, {})) }) }) }) }) }));
27
+ 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: pathname.endsWith(SELECT_DECAYS_PATH) ? (_jsx(DecaySearchPage, {})) : pathname.endsWith(VARIABLES_PATH) ? (_jsx(DecayTreeConfigPage, {})) : (_jsx(RequestPage, {})) }) }) }) }));
29
28
  }
@@ -1,8 +1,18 @@
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
+ \*****************************************************************************/
1
11
  import { Props as SelectProps } from "react-select";
2
12
  import { DropdownOption } from "../models/dropdownOption";
3
13
  interface Props extends SelectProps<DropdownOption> {
4
14
  onlyHeads?: boolean;
5
15
  onlyKnown?: boolean;
6
16
  }
7
- export declare function ParticleDropdown({ onlyHeads, onlyKnown, ...props }: Props): import("react/jsx-runtime").JSX.Element | null;
17
+ export declare function ParticleDropdown({ onlyHeads, onlyKnown, ...props }: Props): import("react/jsx-runtime").JSX.Element;
8
18
  export {};
@@ -9,24 +9,21 @@ import { jsx as _jsx } from "react/jsx-runtime";
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 { MathJax } from "better-react-mathjax";
13
12
  import Select from "react-select";
14
13
  import { useMetadata } from "../providers/MetadataProvider.js";
14
+ import { InlineMath } from "react-katex";
15
15
  export function ParticleDropdown({ onlyHeads, onlyKnown, ...props }) {
16
16
  const metadata = useMetadata();
17
- if (!metadata) {
18
- return null;
19
- }
20
17
  const allowedParticles = () => onlyHeads
21
18
  ? [...new Set(Object.values(metadata.decays).map((decay) => decay.descriptors.list[0]))]
22
19
  : onlyKnown
23
20
  ? Object.keys(metadata.particleProperties).filter((key) => !metadata.particleProperties[key].hide)
24
21
  : Object.keys(metadata.particleProperties);
25
- const loaded = metadata && (!onlyHeads || metadata.decays);
22
+ const loaded = !onlyHeads || metadata.decays;
26
23
  const options = loaded
27
24
  ? allowedParticles().map((key) => ({
28
25
  value: key,
29
- label: _jsx(MathJax, { inline: true, children: `\\(${metadata.particleProperties[key]["latex"]}\\)` }),
26
+ label: _jsx(InlineMath, { math: metadata.particleProperties[key]["latex"] }),
30
27
  }))
31
28
  : [];
32
29
  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 }) }));
@@ -0,0 +1,6 @@
1
+ interface Props {
2
+ particleId: string;
3
+ highlighted?: boolean;
4
+ }
5
+ export declare function ParticleLatex({ particleId, highlighted }: Props): import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { convertParticleToLatex } from "../utils/latexUtils";
3
+ import { useMetadata } from "../providers/MetadataProvider";
4
+ import { useDtt } from "../providers/DttProvider";
5
+ import { InlineMath } from "react-katex";
6
+ export function ParticleLatex({ particleId, highlighted }) {
7
+ const metadata = useMetadata();
8
+ const { dtt } = useDtt();
9
+ const particleName = dtt.config.branches[particleId].particle;
10
+ return (
11
+ // pointerEvents: "none" prevents the node from absorbing clicks intended for the tree canvas
12
+ _jsx("div", { style: { pointerEvents: "none" }, children: _jsx(InlineMath, { math: convertParticleToLatex(metadata, particleName, highlighted) }) }));
13
+ }
@@ -3,7 +3,8 @@ import { ParticleTag } from "../models/particleTag";
3
3
  interface Props {
4
4
  tag: ParticleTag;
5
5
  as?: ElementType;
6
+ enabled?: boolean;
6
7
  onClick?: () => void;
7
8
  }
8
- export declare function ParticleTagBadge({ tag, as, onClick }: Props): import("react/jsx-runtime").JSX.Element;
9
+ export declare function ParticleTagBadge({ tag, as, enabled, onClick }: Props): import("react/jsx-runtime").JSX.Element;
9
10
  export {};
@@ -9,14 +9,12 @@ import { jsx as _jsx } from "react/jsx-runtime";
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 { Badge, OverlayTrigger, Spinner, Tooltip } from "react-bootstrap";
12
+ import { Badge, OverlayTrigger, Tooltip } from "react-bootstrap";
13
13
  import { useMetadata } from "../providers/MetadataProvider.js";
14
14
  import { config } from "../config.js";
15
- export function ParticleTagBadge({ tag, as, onClick }) {
15
+ export function ParticleTagBadge({ tag, as, enabled = true, onClick }) {
16
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 }) }));
17
+ const background = config.particleTagGroupStyles[tag.group];
18
+ const description = metadata.userHints.particleTags[tag.label].description;
19
+ return (_jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: description }), children: _jsx(Badge, { pill: true, bg: background, text: "light", as: as, onClick: onClick, style: { opacity: enabled ? 1 : 0.15, pointerEvents: enabled ? "auto" : "none" }, children: tag.label }) }));
22
20
  }
@@ -1,6 +1 @@
1
- interface Props {
2
- branch: string[];
3
- onSelectTag: (branches: string[]) => void;
4
- }
5
- export declare function ParticleTagFilters({ branch, onSelectTag }: Props): import("react/jsx-runtime").JSX.Element | null;
6
- export {};
1
+ export declare function ParticleTagFilters(): import("react/jsx-runtime").JSX.Element | null;
@@ -1,18 +1,14 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Card, Stack } from "react-bootstrap";
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Stack } from "react-bootstrap";
3
3
  import { ParticleTagBadge } from "./ParticleTagBadge";
4
4
  import { useMetadata } from "../providers/MetadataProvider";
5
5
  import { useDtt } from "../providers/DttProvider";
6
- import { useCallback, useMemo } from "react";
7
- export function ParticleTagFilters({ branch, onSelectTag }) {
6
+ import { useCallback, useMemo, useState } from "react";
7
+ export function ParticleTagFilters() {
8
8
  const metadata = useMetadata();
9
- const { dtt } = useDtt();
10
- if (!metadata) {
11
- return null;
12
- }
9
+ const { dtt, selectedBranch, setSelectedBranch } = useDtt();
10
+ const [allParticleTags, setAllParticleTags] = useState(null);
13
11
  const selectAllByTag = useCallback((tag) => {
14
- if (!metadata)
15
- return;
16
12
  const allBranches = dtt.config.branches;
17
13
  const matchingBranches = Object.keys(allBranches)
18
14
  .filter((branch) => {
@@ -21,14 +17,14 @@ export function ParticleTagFilters({ branch, onSelectTag }) {
21
17
  return particleTags.includes(tag.label);
22
18
  })
23
19
  .sort();
24
- onSelectTag(matchingBranches);
20
+ setSelectedBranch(matchingBranches);
25
21
  }, [dtt, metadata]);
26
22
  const particleTags = useMemo(() => {
27
23
  const tagInfo = metadata.userHints.particleTags;
28
24
  let particleTags;
29
- if (branch.length > 0) {
25
+ if (selectedBranch.length > 0) {
30
26
  const allParticles = dtt
31
- .getParticlesByBranchId(branch)
27
+ .getParticlesByBranchId(selectedBranch)
32
28
  .map((particle) => metadata.particleProperties[particle]);
33
29
  const allTags = new Set(allParticles.map((particle) => particle.tags.filter((tag) => !tagInfo[tag].hide)).flat());
34
30
  particleTags = Array.from(allTags)
@@ -41,11 +37,14 @@ export function ParticleTagFilters({ branch, onSelectTag }) {
41
37
  const uniqueTags = new Set(allParticles.map((particle) => particle.tags.filter((tag) => !tagInfo[tag].hide)).flat());
42
38
  particleTags = Array.from(uniqueTags).map((tag) => ({ label: tag, group: tagInfo[tag].group }));
43
39
  }
40
+ if (!allParticleTags) {
41
+ setAllParticleTags(particleTags);
42
+ }
44
43
  return particleTags;
45
- }, [dtt, metadata, branch]);
46
- if (particleTags.length === 0) {
44
+ }, [dtt, metadata, selectedBranch]);
45
+ if (!allParticleTags) {
47
46
  return null;
48
47
  }
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))) })] }));
48
+ const groupedTags = Object.groupBy([...allParticleTags].sort((a, b) => a.group.localeCompare(b.group)), (tag) => tag.group);
49
+ return (_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, enabled: particleTags.map((tag) => tag.label).includes(tag.label), onClick: () => selectAllByTag(tag) }, tag.label))) }, group))) }));
51
50
  }
@@ -1 +1 @@
1
- export declare function RequestButtonGroup(): import("react/jsx-runtime").JSX.Element | null;
1
+ export declare function RequestButtonGroup(): import("react/jsx-runtime").JSX.Element;
@@ -18,14 +18,11 @@ export function RequestButtonGroup() {
18
18
  const { rows, configuredRows, setRows } = useRows();
19
19
  const navigate = useNavigate();
20
20
  const [showProdUploadModal, setShowProdUploadModal] = useState(false);
21
- const handleSubmitRows = async () => {
21
+ const configureAllDtts = async () => {
22
22
  setRows((prev) => prev.map((r) => ({ ...r, editTree: true })));
23
23
  await navigate(`${basePath}${VARIABLES_PATH}`);
24
24
  };
25
- if (!metadata) {
26
- return null;
27
- }
28
25
  return (_jsxs(_Fragment, { children: [showProdUploadModal && _jsx(UploadDttConfigModal, { onClose: () => setShowProdUploadModal(false) }), _jsxs(ButtonGroup, { children: [_jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: "Select decays" }), children: _jsxs(Button, { type: "submit", variant: "success", onClick: () => void navigate(`${basePath}${SELECT_DECAYS_PATH}`), className: "align-items-center d-flex gap-1", children: [_jsx(PlusLg, {}), " Select decays"] }) }), variant === "standalone" && (_jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: "Upload Production configuration file" }), children: _jsx(Button, { className: "ms-auto align-items-center d-flex", type: "button", onClick: () => setShowProdUploadModal(true), children: _jsx(Upload, {}) }) })), _jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: "Configure all DecayTreeTuples" }), children: _jsxs(Button, { type: "submit", variant: "secondary", onClick: () => {
29
- handleSubmitRows().catch(console.error);
26
+ configureAllDtts().catch(console.error);
30
27
  }, disabled: !validation.allRowsHaveDtt, className: "align-items-center d-flex gap-1", children: [_jsx(GearWideConnected, {}), " ", _jsx(Badge, { pill: true, bg: "primary", children: configuredRows.length })] }) }), variant === "standalone" && (_jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: "Download Analysis Production configuration file (info.yaml)" }), children: _jsx(Button, { variant: "primary", type: "button", onClick: () => downloadText(YamlFile.createInfoYaml(rows, metadata)), disabled: !validation.allRowsHaveDtt || !validation.allRowsHavePaths || !validation.isEmailValid, className: "align-items-center d-flex", children: _jsx(Download, {}) }) }))] })] }));
31
28
  }
@@ -1 +1 @@
1
- export declare function RequestRow(): import("react/jsx-runtime").JSX.Element | null;
1
+ export declare function RequestRow(): import("react/jsx-runtime").JSX.Element;
@@ -1,20 +1,16 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Button, Col, OverlayTrigger, Popover, Row } from "react-bootstrap";
3
- import { InfoCircle } from "react-bootstrap-icons";
4
- import { StrippingLineInfo } from "./StrippingLineInfo";
5
- import { DeleteButton } from "./DeleteButton";
6
- import { DttNameInput } from "./DttNameInput";
7
- import { useMetadata } from "../providers/MetadataProvider";
8
- import { useRows } from "../providers/RowsProvider";
2
+ import { Col, Row } from "react-bootstrap";
3
+ import { DecayCard } from "./DecayCard";
9
4
  import { BookkeepingPathDropdown } from "./BookkeepingPathDropdown";
10
5
  import { StrippingLineDropdown } from "./StrippingLineDropdown";
11
6
  import { useRow } from "../providers/RowProvider";
7
+ import { VerticalLine } from "./VerticalLine";
8
+ import { DeleteButton } from "./DeleteButton";
9
+ import { useRows } from "../providers/RowsProvider";
10
+ import { StrippingLineInfoButton } from "./StrippingLineInfoButton";
11
+ import { GuideLinkButton } from "./GuideLinkButton";
12
12
  export function RequestRow() {
13
- const metadata = useMetadata();
14
13
  const { row } = useRow();
15
14
  const { removeRow } = useRows();
16
- if (!metadata) {
17
- return null;
18
- }
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) }) })] }));
15
+ return (_jsxs(Row, { className: "align-items-stretch mt-1", children: [_jsx(Col, { xs: 5, children: _jsx(DecayCard, {}) }), _jsxs(Col, { xs: 6, className: "d-flex flex-column gap-2", children: [_jsx(Row, { children: _jsxs("div", { className: "d-flex flex-row justify-content-between align-items-center gap-3", children: [_jsx("div", { style: { width: "100%" }, children: _jsx(StrippingLineDropdown, {}) }), _jsx("div", { className: "me-2", children: _jsx(StrippingLineInfoButton, { line: row.line }) }), _jsx(GuideLinkButton, { page: "strippingLines", topic: "Stripping lines" })] }) }), _jsx(Row, { children: _jsxs("div", { className: "d-flex flex-row align-items-center gap-2", children: [_jsx("div", { className: "me-3", style: { width: "100%" }, children: _jsx(BookkeepingPathDropdown, {}) }), _jsx(GuideLinkButton, { page: "datasets", topic: "Datasets" })] }) })] }), _jsxs(Col, { xs: 1, className: "d-flex align-items-center justify-content-start gap-4", children: [_jsx(VerticalLine, {}), _jsx(DeleteButton, { action: () => removeRow(row.id), popupMessage: "Delete row" })] })] }));
20
16
  }
@@ -8,18 +8,16 @@ export function StrippingLineDropdown() {
8
8
  const { row, updateBkPaths } = useRow();
9
9
  const { updateRow } = useRows();
10
10
  const handleStrippingLineChanged = useCallback((lineOption) => {
11
- const lines = [
12
- {
13
- stream: lineOption.group,
14
- line: lineOption.value,
15
- versions: row.decay.lines[`${lineOption.group}/${lineOption.value}`],
16
- },
17
- ];
18
- updateBkPaths(row.paths, lines);
11
+ const line = {
12
+ stream: lineOption.group,
13
+ line: lineOption.value,
14
+ versions: row.decay.lines[`${lineOption.group}/${lineOption.value}`],
15
+ };
16
+ updateBkPaths(row.paths, line);
19
17
  updateRow(row.id, (r) => ({
20
18
  ...r,
21
- lines,
22
- dtt: r.dtt ? r.dtt.withInputsFromLines(lines) : null,
19
+ line,
20
+ dtt: r.dtt ? r.dtt.withInputFromLine(line) : null,
23
21
  }));
24
22
  }, [row, updateBkPaths, updateRow]);
25
23
  const strippingLineOptions = useMemo(() => {
@@ -32,7 +30,7 @@ export function StrippingLineDropdown() {
32
30
  grouped[stream].push({
33
31
  value: line,
34
32
  group: stream,
35
- label: _jsx(StrippingLineInfo, { line: line, stream: stream, versions: versions }),
33
+ label: _jsx(StrippingLineInfo, { line: { line, stream, versions } }),
36
34
  });
37
35
  });
38
36
  return Object.entries(grouped).map(([label, options]) => ({
@@ -40,9 +38,9 @@ export function StrippingLineDropdown() {
40
38
  options,
41
39
  }));
42
40
  }, [row.decay.lines]);
43
- return (_jsx(Select, { options: strippingLineOptions, value: row.lines.map((l) => ({
44
- value: l.line,
45
- group: l.stream,
46
- label: _jsx(StrippingLineInfo, { line: l.line, stream: l.stream, versions: l.versions, showLink: false }),
47
- })), placeholder: "Stripping line", onChange: (v) => handleStrippingLineChanged(v), menuPortalTarget: document.body, menuPosition: "fixed", styles: { menuPortal: (b) => ({ ...b, zIndex: 9999 }) } }));
41
+ return (_jsx(Select, { options: strippingLineOptions, value: row.line && {
42
+ value: row.line.line,
43
+ group: row.line.stream,
44
+ label: _jsx(StrippingLineInfo, { line: row.line, showLink: false }),
45
+ }, placeholder: "Stripping line", onChange: (v) => handleStrippingLineChanged(v), menuPortalTarget: document.body, menuPosition: "fixed", styles: { menuPortal: (b) => ({ ...b, zIndex: 9999 }) } }));
48
46
  }
@@ -1,8 +1,8 @@
1
- import { StrippingBadgeProps } from "./StrippingLineBadge";
2
- interface Props extends Omit<StrippingBadgeProps, "version"> {
3
- versions: string[];
4
- line: string;
1
+ import { StrippingLine } from "../models/strippingLine";
2
+ interface Props {
3
+ line: StrippingLine;
5
4
  showLink?: boolean;
5
+ verbose?: boolean;
6
6
  }
7
- export declare function StrippingLineInfo({ versions, line, showLink, ...props }: Props): import("react/jsx-runtime").JSX.Element;
7
+ export declare function StrippingLineInfo({ line, showLink, verbose }: Props): import("react/jsx-runtime").JSX.Element;
8
8
  export {};
@@ -10,8 +10,18 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
10
  * or submit itself to any jurisdiction. *
11
11
  \*****************************************************************************/
12
12
  import { Stack } from "react-bootstrap";
13
- import { StrippingLineBadge } from "./StrippingLineBadge";
14
- export function StrippingLineInfo({ versions, line, showLink, ...props }) {
15
- const strippingInfo = versions.map((version) => (_jsx(StrippingLineBadge, { version: version, line: line, showLink: showLink, ...props }, `${line}-S${version}-badge`)));
16
- return (_jsxs("span", { children: [line, _jsx("br", {}), _jsx(Stack, { direction: "horizontal", style: { flexWrap: "wrap" }, gap: 1, children: strippingInfo })] }));
13
+ import { StrippingLineVersionBadge } from "./StrippingLineVersionBadge";
14
+ import { useMetadata } from "../providers/MetadataProvider";
15
+ import { BoxArrowUpRight } from "react-bootstrap-icons";
16
+ export function StrippingLineInfo({ line, showLink, verbose }) {
17
+ const metadata = useMetadata();
18
+ if (verbose) {
19
+ return (_jsxs("div", { children: [_jsxs("div", { className: "text-muted small mb-2", children: ["Stream: ", _jsx("strong", { children: line.stream })] }), _jsx("div", { className: "mb-1 small", children: _jsxs("strong", { children: ["Available in ", line.versions.length === 1 ? "stripping version" : "stripping versions", ":"] }) }), _jsx(Stack, { gap: 2, children: line.versions.map((version) => {
20
+ const info = metadata.stripping[version]?.[line.line];
21
+ const hint = metadata.strippingHints[version];
22
+ const url = info?.url?.[line.stream];
23
+ return (_jsxs("div", { className: "border rounded p-2 small", children: [_jsxs("div", { className: "d-flex align-items-start justify-content-between gap-2 mb-1", children: [_jsxs("span", { children: [_jsxs("strong", { children: ["S", version] }), hint?.description && _jsxs("span", { className: "text-muted", children: [" \u2014 ", hint.description] })] }), url && (_jsxs("a", { href: url, target: "_blank", rel: "noreferrer", className: "d-flex align-items-center gap-1 text-nowrap", children: ["Documentation", _jsx(BoxArrowUpRight, { size: 11 })] }))] }), hint?.davinci && _jsxs("div", { className: "text-muted", children: ["DaVinci version: ", hint.davinci] }), info?.prescale !== undefined && info.prescale !== 1 && (_jsxs("div", { className: "text-warning", children: ["Prescale: ", info.prescale] }))] }, version));
24
+ }) })] }));
25
+ }
26
+ return (_jsxs("span", { children: [line.line, _jsx("br", {}), _jsx(Stack, { direction: "horizontal", style: { flexWrap: "wrap" }, gap: 1, children: line.versions.map((version) => (_jsx(StrippingLineVersionBadge, { line: line, version: version, showLink: showLink }, `${line.line}-S${version}-badge`))) })] }));
17
27
  }
@@ -0,0 +1,6 @@
1
+ import { StrippingLine } from "../models/strippingLine";
2
+ interface Props {
3
+ line: StrippingLine | null;
4
+ }
5
+ export declare function StrippingLineInfoButton({ line }: Props): import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, OverlayTrigger, Popover } from "react-bootstrap";
3
+ import { StrippingLineInfo } from "./StrippingLineInfo";
4
+ import { InfoCircle } from "react-bootstrap-icons";
5
+ export function StrippingLineInfoButton({ line }) {
6
+ return (_jsx(OverlayTrigger, { trigger: "click", rootClose: true, placement: "left-start", overlay: _jsxs(Popover, { style: { minWidth: "360px" }, children: [_jsx(Popover.Header, { as: "h6", className: "fw-bold", children: line?.line ?? "Stripping line info" }), _jsx(Popover.Body, { children: line && _jsx(StrippingLineInfo, { line: line, verbose: true }, line.line) })] }), children: _jsx(Button, { disabled: !line, children: _jsx(InfoCircle, {}) }) }));
7
+ }
@@ -0,0 +1,7 @@
1
+ import { StrippingLine } from "../models/strippingLine";
2
+ export interface StrippingBadgeProps {
3
+ version: string;
4
+ line?: StrippingLine;
5
+ showLink?: boolean;
6
+ }
7
+ export declare function StrippingLineVersionBadge({ version, line, showLink }: StrippingBadgeProps): import("react/jsx-runtime").JSX.Element;
@@ -11,18 +11,18 @@ import { jsx as _jsx } from "react/jsx-runtime";
11
11
  \*****************************************************************************/
12
12
  import { Badge, OverlayTrigger, Tooltip } from "react-bootstrap";
13
13
  import { useMetadata } from "../providers/MetadataProvider.js";
14
- export function StrippingLineBadge({ version, line, stream, showLink }) {
14
+ export function StrippingLineVersionBadge({ version, line, showLink }) {
15
15
  const metadata = useMetadata();
16
16
  // TODO: configurable baseURL, remove baseURL from metadata (or make it a top-level key)
17
- const url = line && metadata && stream
18
- ? metadata.stripping[version][line].url[stream]
17
+ const url = line
18
+ ? metadata.stripping[version][line.line].url[line.stream]
19
19
  : `http://lhcbdoc.web.cern.ch/lhcbdoc/stripping/config/stripping${version}/index.html`;
20
- const badgeProps = showLink
20
+ const linkProps = showLink
21
21
  ? {
22
22
  as: "a",
23
23
  href: url,
24
24
  target: "_blank",
25
25
  }
26
26
  : {};
27
- return (_jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: metadata ? metadata.strippingHints[version].description : "..." }), children: _jsx(Badge, { pill: true, bg: "info", ...badgeProps, children: "S" + version }) }));
27
+ return (_jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { style: { zIndex: 9999 }, children: metadata.strippingHints[version].description }), children: _jsx(Badge, { pill: true, bg: "info", ...linkProps, children: "S" + version }) }));
28
28
  }
@@ -0,0 +1,8 @@
1
+ interface Props {
2
+ strippingLineVersions: {
3
+ [key: string]: string[];
4
+ };
5
+ selected: boolean;
6
+ }
7
+ export declare function StrippingLinesCountBadge({ strippingLineVersions, selected }: Props): import("react/jsx-runtime").JSX.Element;
8
+ export {};
@@ -0,0 +1,11 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { Badge, OverlayTrigger, Popover, Stack } from "react-bootstrap";
3
+ import { StrippingLineVersionBadge } from "./StrippingLineVersionBadge.js";
4
+ export function StrippingLinesCountBadge({ strippingLineVersions, selected }) {
5
+ const numLines = Object.keys(strippingLineVersions).length;
6
+ const entries = Object.keys(strippingLineVersions).map((lineName) => {
7
+ const [stream, line] = lineName.split("/");
8
+ return { stream, line, versions: strippingLineVersions[lineName] };
9
+ });
10
+ return (_jsx(OverlayTrigger, { placement: "right", overlay: _jsxs(Popover, { style: { minWidth: "300px" }, children: [_jsxs(Popover.Header, { as: "h6", className: "fw-bold", children: [numLines, " stripping line", numLines === 1 ? "" : "s"] }), _jsx(Popover.Body, { children: _jsx(Stack, { gap: 2, children: entries.map(({ stream, line, versions }, i) => (_jsxs("div", { children: [i > 0 && _jsx("hr", { className: "my-0 mb-2" }), _jsxs("div", { className: "small text-muted mb-1", children: ["Stream: ", stream] }), _jsx("div", { className: "small mb-1", children: line }), _jsx(Stack, { direction: "horizontal", style: { flexWrap: "wrap" }, gap: 1, children: versions.map((version) => (_jsx(StrippingLineVersionBadge, { line: { line, stream, versions }, version: version }, version))) })] }, `${stream}/${line}`))) }) })] }), children: _jsxs(Badge, { pill: true, bg: selected ? "primary" : "secondary", children: [numLines, " stripping line", numLines === 1 ? "" : "s"] }) }));
11
+ }