lhcb-ntuple-wizard-test 2.1.0 → 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 (178) hide show
  1. package/dist/components/AddTupleToolButton.d.ts +1 -0
  2. package/dist/components/AddTupleToolButton.js +16 -0
  3. package/dist/components/BookkeepingPathDropdown.d.ts +1 -1
  4. package/dist/components/BookkeepingPathDropdown.js +1 -4
  5. package/dist/components/DatasetEventTypeBadge.js +1 -1
  6. package/dist/components/DatasetInfo.js +3 -3
  7. package/dist/components/DecayCard.d.ts +1 -1
  8. package/dist/components/DecayCard.js +12 -40
  9. package/dist/components/DecayLatex.d.ts +1 -1
  10. package/dist/components/DecayLatex.js +4 -87
  11. package/dist/components/DecayListItem.js +2 -2
  12. package/dist/components/DecayTagBadge.d.ts +1 -1
  13. package/dist/components/DecayTagBadge.js +0 -3
  14. package/dist/components/DecayTreeCard.d.ts +1 -7
  15. package/dist/components/DecayTreeCard.js +13 -18
  16. package/dist/components/DecayTreeCardHeader.d.ts +2 -3
  17. package/dist/components/DecayTreeCardHeader.js +2 -2
  18. package/dist/components/DecayTreeGraph.d.ts +1 -4
  19. package/dist/components/DecayTreeGraph.js +66 -41
  20. package/dist/components/DeleteButton.d.ts +2 -1
  21. package/dist/components/DeleteButton.js +2 -2
  22. package/dist/components/DttNameInput.d.ts +9 -0
  23. package/dist/components/DttNameInput.js +43 -0
  24. package/dist/components/GuideLinkButton.d.ts +15 -0
  25. package/dist/components/GuideLinkButton.js +16 -0
  26. package/dist/components/NtupleWizard.js +1 -7
  27. package/dist/components/ParticleDropdown.d.ts +11 -1
  28. package/dist/components/ParticleDropdown.js +3 -6
  29. package/dist/components/ParticleLatex.d.ts +6 -0
  30. package/dist/components/ParticleLatex.js +13 -0
  31. package/dist/components/ParticleTagBadge.d.ts +2 -1
  32. package/dist/components/ParticleTagBadge.js +5 -7
  33. package/dist/components/ParticleTagFilters.d.ts +1 -6
  34. package/dist/components/ParticleTagFilters.js +16 -17
  35. package/dist/components/RequestButtonGroup.d.ts +1 -1
  36. package/dist/components/RequestButtonGroup.js +0 -3
  37. package/dist/components/RequestRow.d.ts +1 -1
  38. package/dist/components/RequestRow.js +4 -9
  39. package/dist/components/StrippingLineDropdown.js +14 -16
  40. package/dist/components/StrippingLineInfo.d.ts +5 -5
  41. package/dist/components/StrippingLineInfo.js +14 -4
  42. package/dist/components/StrippingLineInfoButton.d.ts +6 -0
  43. package/dist/components/StrippingLineInfoButton.js +7 -0
  44. package/dist/components/StrippingLineVersionBadge.d.ts +7 -0
  45. package/dist/components/{StrippingLineBadge.js → StrippingLineVersionBadge.js} +5 -5
  46. package/dist/components/StrippingLinesCountBadge.d.ts +8 -0
  47. package/dist/components/StrippingLinesCountBadge.js +11 -0
  48. package/dist/components/TagDropdown.d.ts +3 -3
  49. package/dist/components/TagDropdown.js +2 -2
  50. package/dist/components/TupleToolClassDropdown.js +11 -14
  51. package/dist/components/TupleToolDocsAccordion.d.ts +1 -1
  52. package/dist/components/TupleToolDocsAccordion.js +4 -8
  53. package/dist/components/TupleToolGroupsAccordion.d.ts +5 -0
  54. package/dist/components/TupleToolGroupsAccordion.js +31 -0
  55. package/dist/components/TupleToolLabel.d.ts +1 -1
  56. package/dist/components/TupleToolLabel.js +2 -5
  57. package/dist/components/TupleToolsAccordion.d.ts +1 -0
  58. package/dist/components/TupleToolsAccordion.js +22 -0
  59. package/dist/components/modals/AddTupleToolModal.js +3 -2
  60. package/dist/components/modals/ConfigureTupleToolModal.js +1 -1
  61. package/dist/components/modals/UploadDttConfigModal.d.ts +1 -1
  62. package/dist/components/modals/UploadDttConfigModal.js +1 -4
  63. package/dist/config.d.ts +1 -0
  64. package/dist/config.js +3 -2
  65. package/dist/models/bkPath.js +1 -1
  66. package/dist/models/dtt.d.ts +5 -2
  67. package/dist/models/dtt.js +37 -18
  68. package/dist/models/rowData.d.ts +1 -1
  69. package/dist/models/yamlFile.js +1 -1
  70. package/dist/pages/DecaySearchPage.js +4 -9
  71. package/dist/pages/DecayTreeConfigPage.js +4 -38
  72. package/dist/pages/RequestPage.js +2 -4
  73. package/dist/providers/DttProvider.d.ts +3 -3
  74. package/dist/providers/DttProvider.js +30 -55
  75. package/dist/providers/MetadataProvider.d.ts +1 -1
  76. package/dist/providers/MetadataProvider.js +11 -5
  77. package/dist/providers/RequestProvider.js +2 -2
  78. package/dist/providers/RowProvider.d.ts +2 -2
  79. package/dist/providers/RowProvider.js +10 -9
  80. package/dist/providers/RowsProvider.js +0 -3
  81. package/dist/tests/components/BookkeepingPathDropdown.test.d.ts +1 -0
  82. package/dist/tests/components/BookkeepingPathDropdown.test.js +118 -0
  83. package/dist/tests/components/DatasetInfo.test.d.ts +1 -0
  84. package/dist/tests/components/DatasetInfo.test.js +38 -0
  85. package/dist/tests/components/DecayCard.test.d.ts +1 -0
  86. package/dist/tests/components/DecayCard.test.js +115 -0
  87. package/dist/tests/components/DecayLatex.test.d.ts +1 -0
  88. package/dist/tests/components/DecayLatex.test.js +31 -0
  89. package/dist/tests/components/DecayList.test.d.ts +1 -0
  90. package/dist/tests/components/DecayList.test.js +76 -0
  91. package/dist/tests/components/DecayListItem.test.d.ts +1 -0
  92. package/dist/tests/components/DecayListItem.test.js +51 -0
  93. package/dist/tests/components/DecayTreeCard.test.d.ts +1 -0
  94. package/dist/tests/components/DecayTreeCard.test.js +119 -0
  95. package/dist/tests/components/DecayTreeGraph.test.d.ts +1 -0
  96. package/dist/tests/components/DecayTreeGraph.test.js +125 -0
  97. package/dist/tests/components/DeleteButton.test.d.ts +1 -0
  98. package/dist/tests/components/DeleteButton.test.js +45 -0
  99. package/dist/tests/components/DttNameInput.test.d.ts +1 -0
  100. package/dist/tests/components/DttNameInput.test.js +75 -0
  101. package/dist/tests/components/NtupleWizard.test.d.ts +1 -0
  102. package/dist/tests/components/NtupleWizard.test.js +57 -0
  103. package/dist/tests/components/ParticleDropdown.test.d.ts +1 -0
  104. package/dist/tests/components/ParticleDropdown.test.js +23 -0
  105. package/dist/tests/components/ParticleTagFilters.test.d.ts +1 -0
  106. package/dist/tests/components/ParticleTagFilters.test.js +87 -0
  107. package/dist/tests/components/RequestButtonGroup.test.d.ts +1 -0
  108. package/dist/tests/components/RequestButtonGroup.test.js +132 -0
  109. package/dist/tests/components/RequestRow.test.d.ts +1 -0
  110. package/dist/tests/components/RequestRow.test.js +58 -0
  111. package/dist/tests/components/StrippingLineDropdown.test.d.ts +1 -0
  112. package/dist/tests/components/StrippingLineDropdown.test.js +88 -0
  113. package/dist/tests/components/badges.test.d.ts +1 -0
  114. package/dist/tests/components/badges.test.js +120 -0
  115. package/dist/tests/components/dropdowns.test.d.ts +1 -0
  116. package/dist/tests/components/dropdowns.test.js +110 -0
  117. package/dist/tests/components/dttComponents.test.d.ts +1 -0
  118. package/dist/tests/components/dttComponents.test.js +287 -0
  119. package/dist/tests/components/formInputs.test.d.ts +1 -0
  120. package/dist/tests/components/formInputs.test.js +96 -0
  121. package/dist/tests/components/metadataComponents.test.d.ts +1 -0
  122. package/dist/tests/components/metadataComponents.test.js +137 -0
  123. package/dist/tests/components/miscComponents.test.d.ts +1 -0
  124. package/dist/tests/components/miscComponents.test.js +134 -0
  125. package/dist/tests/components/modals.test.d.ts +1 -0
  126. package/dist/tests/components/modals.test.js +554 -0
  127. package/dist/tests/components/tupleToolParams.test.d.ts +1 -0
  128. package/dist/tests/components/tupleToolParams.test.js +213 -0
  129. package/dist/tests/config.test.d.ts +1 -0
  130. package/dist/tests/config.test.js +31 -0
  131. package/dist/tests/mockSetup.d.ts +1 -0
  132. package/dist/tests/mockSetup.js +30 -0
  133. package/dist/tests/models/BkPath.test.d.ts +1 -0
  134. package/dist/tests/models/BkPath.test.js +87 -0
  135. package/dist/tests/models/Dtt.test.d.ts +1 -0
  136. package/dist/tests/models/Dtt.test.js +376 -0
  137. package/dist/tests/models/TupleTool.test.d.ts +1 -0
  138. package/dist/tests/models/TupleTool.test.js +80 -0
  139. package/dist/tests/models/YamlFile.test.d.ts +1 -0
  140. package/dist/tests/models/YamlFile.test.js +123 -0
  141. package/dist/tests/pages/DecaySearchPage.test.d.ts +1 -0
  142. package/dist/tests/pages/DecaySearchPage.test.js +228 -0
  143. package/dist/tests/pages/DecayTreeConfigPage.test.d.ts +1 -0
  144. package/dist/tests/pages/DecayTreeConfigPage.test.js +105 -0
  145. package/dist/tests/pages/RequestPage.test.d.ts +1 -0
  146. package/dist/tests/pages/RequestPage.test.js +439 -0
  147. package/dist/tests/providers/DttProvider.test.d.ts +1 -0
  148. package/dist/tests/providers/DttProvider.test.js +105 -0
  149. package/dist/tests/providers/MetadataProvider.test.d.ts +1 -0
  150. package/dist/tests/providers/MetadataProvider.test.js +129 -0
  151. package/dist/tests/providers/RequestProvider.test.d.ts +1 -0
  152. package/dist/tests/providers/RequestProvider.test.js +306 -0
  153. package/dist/tests/providers/RowProvider.test.d.ts +1 -0
  154. package/dist/tests/providers/RowProvider.test.js +110 -0
  155. package/dist/tests/providers/RowsProvider.test.d.ts +1 -0
  156. package/dist/tests/providers/RowsProvider.test.js +84 -0
  157. package/dist/tests/providers/WizardConfigProvider.test.d.ts +1 -0
  158. package/dist/tests/providers/WizardConfigProvider.test.js +36 -0
  159. package/dist/tests/setupTests.d.ts +1 -0
  160. package/dist/tests/setupTests.js +15 -0
  161. package/dist/tests/testUtils.d.ts +33 -0
  162. package/dist/tests/testUtils.js +196 -0
  163. package/dist/tests/utils/latexUtils.test.d.ts +1 -0
  164. package/dist/tests/utils/latexUtils.test.js +62 -0
  165. package/dist/tests/utils/utils.test.d.ts +1 -0
  166. package/dist/tests/utils/utils.test.js +394 -0
  167. package/dist/utils/latexUtils.d.ts +13 -0
  168. package/dist/utils/latexUtils.js +86 -0
  169. package/dist/utils/utils.d.ts +1 -0
  170. package/dist/utils/utils.js +4 -1
  171. package/package.json +16 -7
  172. package/dist/components/NumStrippingLinesBadge.d.ts +0 -8
  173. package/dist/components/NumStrippingLinesBadge.js +0 -10
  174. package/dist/components/StrippingLineBadge.d.ts +0 -7
  175. package/dist/components/TupleToolGroup.d.ts +0 -5
  176. package/dist/components/TupleToolGroup.js +0 -22
  177. package/dist/components/TupleToolList.d.ts +0 -6
  178. package/dist/components/TupleToolList.js +0 -42
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Accordion, Button, ListGroup, OverlayTrigger, Tooltip } from "react-bootstrap";
3
+ import { CircleSquare, PencilSquare, PlusLg } from "react-bootstrap-icons";
4
+ import { getControlKey } from "../utils/utils";
5
+ import { useDtt } from "../providers/DttProvider";
6
+ import { ParticleLatex } from "./ParticleLatex";
7
+ import _ from "lodash";
8
+ import { AddTupleToolButton } from "./AddTupleToolButton";
9
+ export function TupleToolGroupsAccordion({ setActiveKey }) {
10
+ const { dtt, selectedBranch, setSelectedBranch, hoveredBranch, setHoveredBranch, highlightedBranch } = useDtt();
11
+ function handleGroupSelected(branchGroup) {
12
+ setActiveKey("0");
13
+ setSelectedBranch(branchGroup);
14
+ setHoveredBranch([]);
15
+ }
16
+ const groupsWithTools = dtt.getGroupsWithTools();
17
+ return (_jsxs(Accordion.Item, { eventKey: "1", children: [_jsx(Accordion.Header, { children: _jsxs("div", { className: "d-flex align-items-center gap-2", children: [_jsx(CircleSquare, {}), groupsWithTools.length, " group", groupsWithTools.length === 1 ? "" : "s"] }) }), _jsx(Accordion.Body, { style: { padding: 4 }, children: groupsWithTools.length > 0 ? (_jsxs(ListGroup, { variant: "flush", children: [groupsWithTools.map((group) => {
18
+ const branchGroup = group.split(",");
19
+ return (_jsx(ListGroup.Item, { onMouseEnter: () => setHoveredBranch(branchGroup), onMouseLeave: () => setHoveredBranch([]), onClick: () => handleGroupSelected(branchGroup), style: {
20
+ cursor: "pointer",
21
+ backgroundColor: _.isEqual(hoveredBranch, branchGroup)
22
+ ? "var(--bs-gray-100)"
23
+ : "transparent",
24
+ }, children: _jsxs("div", { className: "d-flex justify-content-between align-items-center", children: [_jsx("div", { className: "d-flex flex-wrap align-items-center gap-3", children: branchGroup.map((pid, i) => (_jsx(ParticleLatex, { particleId: pid, highlighted: _.isEqual(highlightedBranch, branchGroup) }, i))) }), _jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: "Edit group TupleTools" }), children: _jsx(Button, { size: "sm", variant: "outline-secondary", onClick: () => handleGroupSelected(branchGroup), children: _jsx(PencilSquare, {}) }) })] }) }, group));
25
+ }), selectedBranch.length > 1 && !groupsWithTools.includes(selectedBranch.join(",")) && (_jsx(ListGroup.Item, { onMouseEnter: () => setHoveredBranch(selectedBranch), onMouseLeave: () => setHoveredBranch([]), onClick: () => handleGroupSelected(selectedBranch), style: {
26
+ cursor: "pointer",
27
+ backgroundColor: _.isEqual(hoveredBranch, selectedBranch)
28
+ ? "var(--bs-gray-100)"
29
+ : "transparent",
30
+ }, children: _jsxs("div", { className: "d-flex justify-content-between align-items-center", children: [_jsx("div", { className: "d-flex flex-wrap align-items-center gap-3", children: selectedBranch.map((pid, i) => (_jsx(ParticleLatex, { particleId: pid, highlighted: true }, i))) }), _jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: "Create group" }), children: _jsx(Button, { size: "sm", variant: "success", onClick: () => handleGroupSelected(selectedBranch), children: _jsx(PlusLg, {}) }) })] }) }, selectedBranch.join(",")))] })) : (_jsxs("div", { className: "text-muted d-flex flex-column gap-2 p-3", children: [selectedBranch.length === 0 ? (_jsxs("div", { children: ["No groups have been created yet. Select multiple particles (", _jsx("code", { children: getControlKey() }), " + click) and add a TupleTool to create a group."] })) : selectedBranch.length === 1 ? (_jsxs("div", { children: ["Select multiple particles (", _jsx("code", { children: getControlKey() }), " + click) to create a group."] })) : (_jsxs("div", { children: ["No groups include the selected particle", selectedBranch.length > 1 ? "s" : "", ". Add a TupleTool to create a group."] })), selectedBranch.length > 1 && _jsx(AddTupleToolButton, {})] })) })] }));
31
+ }
@@ -2,5 +2,5 @@ import { TupleTool } from "../models/tupleTool";
2
2
  interface Props {
3
3
  tool: TupleTool;
4
4
  }
5
- export declare function TupleToolLabel({ tool }: Props): import("react/jsx-runtime").JSX.Element | null;
5
+ export declare function TupleToolLabel({ tool }: Props): import("react/jsx-runtime").JSX.Element;
6
6
  export {};
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /*****************************************************************************\
3
3
  * (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration *
4
4
  * *
@@ -13,8 +13,5 @@ import { OverlayTrigger, Tooltip } from "react-bootstrap";
13
13
  import { useMetadata } from "../providers/MetadataProvider.js";
14
14
  export function TupleToolLabel({ tool }) {
15
15
  const metadata = useMetadata();
16
- if (!metadata) {
17
- return null;
18
- }
19
- return (_jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: metadata.tupleTools.tupleTools[tool.class].description }), children: _jsx("span", { children: tool.toString() }) }));
16
+ return (_jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: metadata.tupleTools.tupleTools[tool.class].description }), children: _jsxs("div", { className: "d-flex flex-column gap-1", children: [_jsx("code", { style: { textOverflow: "ellipsis", overflow: "hidden", whiteSpace: "nowrap" }, children: tool.class }), _jsx("p", { className: "m-0 text-muted", style: { textOverflow: "ellipsis", overflow: "hidden", whiteSpace: "nowrap" }, children: tool.name })] }) }));
20
17
  }
@@ -0,0 +1 @@
1
+ export declare function TupleToolsAccordion(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Accordion, Button, ButtonGroup, ListGroup, OverlayTrigger, Tooltip } from "react-bootstrap";
3
+ import { PencilSquare, Tools } from "react-bootstrap-icons";
4
+ import { ConfigureTupleToolModal } from "./modals/ConfigureTupleToolModal";
5
+ import { useState } from "react";
6
+ import { useDtt } from "../providers/DttProvider";
7
+ import { TupleToolLabel } from "./TupleToolLabel";
8
+ import { DeleteButton } from "./DeleteButton";
9
+ import { AddTupleToolButton } from "./AddTupleToolButton";
10
+ import { GuideLinkButton } from "./GuideLinkButton";
11
+ export function TupleToolsAccordion() {
12
+ const [showConfigModal, setShowConfigModal] = useState(null);
13
+ const { dtt, removeTool, selectedBranch } = useDtt();
14
+ const tools = dtt.listTools(selectedBranch);
15
+ return (_jsxs(_Fragment, { children: [showConfigModal && (_jsx(ConfigureTupleToolModal, { tool: showConfigModal.tool, deleteIfCancelled: false, onClose: () => setShowConfigModal(null) })), _jsxs(Accordion.Item, { eventKey: "0", children: [_jsx(Accordion.Header, { children: _jsxs("div", { className: "d-flex align-items-center gap-2", children: [_jsx(Tools, {}), tools.length, " TupleTool", tools.length === 1 ? "" : "s", selectedBranch.length === 0 ? " (global)" : selectedBranch.length > 1 ? " (group)" : "", _jsx(GuideLinkButton, { page: "tupleTools", topic: "TupleTools" })] }) }), _jsxs(Accordion.Body, { style: { padding: 4 }, children: [tools.length === 0 ? (_jsxs("div", { className: "text-muted pt-3 pb-2", style: { paddingLeft: "1rem", paddingRight: "1rem" }, children: ["No TupleTools have been added", " ", selectedBranch.length === 0
16
+ ? "to the decay"
17
+ : selectedBranch.length === 1
18
+ ? "to this particle"
19
+ : "to this group", " ", "yet."] })) : (_jsx(ListGroup, { variant: "flush", children: tools.map((tool) => {
20
+ return (_jsxs(ListGroup.Item, { className: "d-flex justify-content-between align-items-start", children: [_jsx("div", { style: { width: 240 }, children: _jsx(TupleToolLabel, { tool: tool }) }), _jsxs(ButtonGroup, { size: "sm", children: [_jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: "Configure TupleTool" }), children: _jsx(Button, { variant: "outline-secondary", onClick: () => setShowConfigModal({ tool }), children: _jsx(PencilSquare, {}) }) }), _jsx(DeleteButton, { outline: true, action: () => removeTool(selectedBranch, tool), popupMessage: "Remove?", placement: "right" })] })] }, tool.toString()));
21
+ }) })), _jsx("div", { className: "pb-2", style: { paddingLeft: "1rem", paddingRight: "1rem" }, children: _jsx(AddTupleToolButton, {}) })] })] })] }));
22
+ }
@@ -1,10 +1,11 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Button, ButtonGroup, FormControl, InputGroup, Modal } from "react-bootstrap";
2
+ import { Button, ButtonGroup, FormControl, Modal } from "react-bootstrap";
3
3
  import { TupleToolClassDropdown } from "../TupleToolClassDropdown";
4
4
  import { TupleToolDocsAccordion } from "../TupleToolDocsAccordion";
5
5
  import { useDtt } from "../../providers/DttProvider";
6
6
  import { TupleTool } from "../../models/tupleTool";
7
7
  import { useEffect, useRef, useState } from "react";
8
+ import { ParticleLatex } from "../ParticleLatex";
8
9
  export function AddTupleToolModal({ onClose }) {
9
10
  const { dtt, addTool, selectedBranch } = useDtt();
10
11
  const nameInputRef = useRef(null);
@@ -12,7 +13,7 @@ export function AddTupleToolModal({ onClose }) {
12
13
  useEffect(() => {
13
14
  nameInputRef.current?.focus();
14
15
  }, [selectedTool]);
15
- return (_jsxs(Modal, { show: true, onHide: () => onClose(null), children: [_jsx(Modal.Header, { closeButton: true, children: "Add TupleTool" }), _jsxs(Modal.Body, { className: "gap-3 d-flex flex-column", children: [_jsxs(InputGroup, { hasValidation: true, children: [_jsx(TupleToolClassDropdown, { onChange: (option) => {
16
+ return (_jsxs(Modal, { show: true, onHide: () => onClose(null), size: "lg", children: [_jsx(Modal.Header, { closeButton: true, children: _jsx(Modal.Title, { children: "Add TupleTool" }) }), _jsxs(Modal.Body, { className: "gap-3 d-flex flex-column", children: [selectedBranch.length > 0 && (_jsxs("div", { className: "d-flex flex-row gap-2", children: [_jsx("h6", { className: "my-auto", children: "Target:" }), selectedBranch.map((pid, i) => (_jsx(ParticleLatex, { particleId: pid }, i)))] })), _jsxs("div", { className: "d-flex flex-row gap-2", children: [_jsx(TupleToolClassDropdown, { onChange: (option) => {
16
17
  if (option) {
17
18
  setSelectedTool((prev) => new TupleTool(option.value, prev?.name || ""));
18
19
  }
@@ -13,7 +13,7 @@ import { toast } from "react-toastify";
13
13
  export function ConfigureTupleToolModal({ tool, deleteIfCancelled, onClose }) {
14
14
  const { dtt, updateToolParam, removeTool, selectedBranch } = useDtt();
15
15
  const toolConfig = dtt.getToolConfig(selectedBranch, tool);
16
- return (_jsxs(Modal, { show: true, size: "xl", fullscreen: "lg-down", backdrop: "static", keyboard: false, children: [_jsxs(Modal.Header, { children: ["Configure ", tool.toString()] }), _jsxs(Modal.Body, { className: "gap-3 d-flex flex-column", children: [_jsx(Form, { children: Object.entries(toolConfig).map(([paramName, param]) => {
16
+ return (_jsxs(Modal, { show: true, size: "xl", fullscreen: "lg-down", backdrop: "static", keyboard: false, children: [_jsx(Modal.Header, { children: _jsxs(Modal.Title, { style: { textOverflow: "ellipsis", overflow: "hidden", whiteSpace: "nowrap" }, children: ["Configure ", tool.toString()] }) }), _jsxs(Modal.Body, { className: "gap-3 d-flex flex-column", children: [_jsx(Form, { children: Object.entries(toolConfig).map(([paramName, param]) => {
17
17
  const { description, type, default: defaultValue, value } = param;
18
18
  let inputComponent;
19
19
  switch (type) {
@@ -3,5 +3,5 @@ interface Props {
3
3
  onClose: () => void;
4
4
  currentRow?: RowData;
5
5
  }
6
- export declare function UploadDttConfigModal({ onClose, currentRow }: Props): import("react/jsx-runtime").JSX.Element | null;
6
+ export declare function UploadDttConfigModal({ onClose, currentRow }: Props): import("react/jsx-runtime").JSX.Element;
7
7
  export {};
@@ -28,7 +28,7 @@ export function UploadDttConfigModal({ onClose, currentRow }) {
28
28
  if (importedConfig.descriptorTemplate === currentRow.decay.descriptors.template) {
29
29
  updateRow(currentRow.id, (r) => ({
30
30
  ...r,
31
- dtt: importedRow.dtt.withInputsFromLines(currentRow.lines),
31
+ dtt: currentRow.line ? importedRow.dtt.withInputFromLine(currentRow.line) : importedRow.dtt,
32
32
  }));
33
33
  onClose();
34
34
  }
@@ -42,9 +42,6 @@ export function UploadDttConfigModal({ onClose, currentRow }) {
42
42
  onClose();
43
43
  }
44
44
  }
45
- if (!metadata) {
46
- return null;
47
- }
48
45
  return (_jsxs(Modal, { show: true, animation: false, children: [_jsx(Modal.Header, { children: _jsx(Modal.Title, { children: " Upload configuration file " }) }), _jsxs(Modal.Body, { children: [_jsx(Form.Group, { controlId: "formFile2", className: "mb-3", children: _jsx(Form.Control, { type: "file", multiple: !currentRow, accept: ".yaml", onChange: (event) => {
49
46
  const files = event.target.files;
50
47
  if (files) {
package/dist/config.d.ts CHANGED
@@ -39,6 +39,7 @@ export declare const config: {
39
39
  width: number;
40
40
  };
41
41
  };
42
+ disabledTupleTools: string[];
42
43
  tupleToolValidation: TupleToolValidation;
43
44
  };
44
45
  interface TupleToolValidation {
package/dist/config.js CHANGED
@@ -22,8 +22,8 @@ export const config = {
22
22
  },
23
23
  dttGraphOptions: {
24
24
  height: "500px",
25
- zoomMin: 0.2,
26
- zoomMax: 3.0,
25
+ zoomMin: 0.5, // multiplier
26
+ zoomMax: 2.0, // multiplier
27
27
  zoomStep: 0.018,
28
28
  layout: {
29
29
  rankDir: "TB", // top -> bottom
@@ -42,6 +42,7 @@ export const config = {
42
42
  width: 1,
43
43
  },
44
44
  },
45
+ disabledTupleTools: ["LoKi__Hybrid__ArrayTupleTool"],
45
46
  tupleToolValidation: {
46
47
  ["LoKi__Hybrid__TupleTool"]: {
47
48
  validate: (config) => {
@@ -8,7 +8,7 @@ export class BkPath {
8
8
  fileName;
9
9
  constructor(path) {
10
10
  if (!BkPath.isValid(path)) {
11
- throw new Error(`Invalid bookkeeping path: ${path}`);
11
+ throw new Error(`Invalid dataset: ${path}`);
12
12
  }
13
13
  const parts = path.split("/");
14
14
  const [, type, year] = parts;
@@ -81,7 +81,7 @@ export interface DttConfig {
81
81
  [particleId: string]: BranchConfig;
82
82
  };
83
83
  descriptorTemplate?: string;
84
- inputs?: string[];
84
+ input?: string;
85
85
  groups: {
86
86
  [particleGroup: string]: GroupConfig;
87
87
  };
@@ -117,7 +117,7 @@ export default class Dtt {
117
117
  toSavedConfig(): SavedDttConfig;
118
118
  private static getBranchConfigs;
119
119
  static create(descriptorTemplate: string, branchItemsList: BranchMapItem[], inputs: string[], name: string, toolMetadata: ToolMetadata): Dtt;
120
- withInputsFromLines(lines: StrippingLine[]): Dtt;
120
+ withInputFromLine(line: StrippingLine): Dtt;
121
121
  withName(name: string): Dtt;
122
122
  withConfig(config: DttConfig): Dtt;
123
123
  withAddedTool(tool: TupleTool, branch?: string[]): Dtt;
@@ -128,11 +128,14 @@ export default class Dtt {
128
128
  getToolsByBranch(branch?: string[]): {
129
129
  [toolString: string]: ToolConfig;
130
130
  };
131
+ getBranchTools(branch?: string[]): string[];
131
132
  private static getToolsByBranchFromConfig;
132
133
  getParticlesByBranchId(branchIds: string[]): string[];
133
134
  private static getDefaultToolConfig;
134
135
  getToolConfig(branch: string[], tool: TupleTool): ToolConfig;
135
136
  listTools(branch?: string[]): TupleTool[];
137
+ getGroupsWithTools(): string[];
138
+ getGroupsThatIncludeBranch(branch: string[]): string[];
136
139
  toolExists(tool: TupleTool, branch?: string[]): boolean;
137
140
  }
138
141
  export {};
@@ -15,20 +15,28 @@ export default class Dtt {
15
15
  }));
16
16
  }
17
17
  static formatToolsForLoading(tools, toolMetadata) {
18
- return Object.fromEntries(tools.map((toolConfig) => {
19
- const toolName = Object.keys(toolConfig)[0];
20
- const params = toolConfig[toolName];
18
+ return Object.fromEntries(tools
19
+ .map((toolConfig) => {
20
+ const toolClass = Object.keys(toolConfig)[0];
21
+ const params = toolConfig[toolClass];
22
+ const toolInterface = toolMetadata[toolClass]?.interface;
23
+ if (!toolInterface) {
24
+ return null;
25
+ }
21
26
  return [
22
- toolName,
23
- Object.fromEntries(Object.entries(params).map(([paramName, value]) => {
24
- const paramMetadata = toolMetadata[toolName].interface.find((param) => param.name === paramName);
27
+ toolClass,
28
+ Object.fromEntries(Object.entries(params)
29
+ .map(([paramName, value]) => {
30
+ const paramMetadata = toolInterface.find((param) => param.name === paramName);
25
31
  if (!paramMetadata) {
26
- throw new Error(`No metadata for param ${paramName} of tool ${toolName}`);
32
+ return null;
27
33
  }
28
34
  return [paramName, { value, ...paramMetadata }];
29
- })),
35
+ })
36
+ .filter(Boolean)),
30
37
  ];
31
- }));
38
+ })
39
+ .filter(Boolean));
32
40
  }
33
41
  static fromSavedConfig(savedConfig, toolMetadata) {
34
42
  const config = {
@@ -95,7 +103,7 @@ export default class Dtt {
95
103
  "TupleToolEventInfo",
96
104
  ];
97
105
  return new Dtt({
98
- inputs,
106
+ input: inputs.length > 0 ? inputs[0] : undefined,
99
107
  descriptorTemplate,
100
108
  tools: Object.fromEntries(defaultTools.map((tool) => [tool, Dtt.getDefaultToolConfig(toolMetadata, tool)])),
101
109
  branches: Dtt.getBranchConfigs(branchItemsList),
@@ -103,12 +111,10 @@ export default class Dtt {
103
111
  name,
104
112
  }, toolMetadata);
105
113
  }
106
- withInputsFromLines(lines) {
107
- const inputs = lines.map(({ stream, line }) => {
108
- const lineLocation = String(line).replace("Stripping", "");
109
- return `/Event/${stream}/Phys/${lineLocation}/Particles`;
110
- });
111
- return new Dtt({ ...this.config, inputs }, this.metadata);
114
+ withInputFromLine(line) {
115
+ const lineLocation = String(line.line).replace("Stripping", "");
116
+ const input = `/Event/${line.stream}/Phys/${lineLocation}/Particles`;
117
+ return new Dtt({ ...this.config, input }, this.metadata);
112
118
  }
113
119
  // Set the class+name combination
114
120
  withName(name) {
@@ -144,7 +150,10 @@ export default class Dtt {
144
150
  if (!this.config.name) {
145
151
  return "";
146
152
  }
147
- return this.config.name.split("/")[1];
153
+ if (this.config.name.includes("/")) {
154
+ return this.config.name.split("/")[1];
155
+ }
156
+ return this.config.name;
148
157
  }
149
158
  // Delete all groups with an empty tool list
150
159
  pruneGroups() {
@@ -154,11 +163,13 @@ export default class Dtt {
154
163
  }
155
164
  }
156
165
  }
157
- // Find the appropriate object which has a "tools" list
158
166
  getToolsByBranch(branch) {
159
167
  this.pruneGroups();
160
168
  return Dtt.getToolsByBranchFromConfig(this.config, branch);
161
169
  }
170
+ getBranchTools(branch) {
171
+ return Object.keys(Dtt.getToolsByBranchFromConfig(this.config, branch));
172
+ }
162
173
  static getToolsByBranchFromConfig(config, branch) {
163
174
  if (!branch || branch?.length === 0) {
164
175
  return config.tools;
@@ -205,6 +216,14 @@ export default class Dtt {
205
216
  listTools(branch) {
206
217
  return Object.keys(this.getToolsByBranch(branch)).map((toolString) => TupleTool.fromString(toolString));
207
218
  }
219
+ getGroupsWithTools() {
220
+ return Object.entries(this.config.groups)
221
+ .filter(([, groupConfig]) => Object.keys(groupConfig.tools).length > 0)
222
+ .map(([key]) => key);
223
+ }
224
+ getGroupsThatIncludeBranch(branch) {
225
+ return this.getGroupsWithTools().filter((group) => branch.every((particle) => group.split(",").includes(particle)));
226
+ }
208
227
  toolExists(tool, branch) {
209
228
  return tool.toString() in this.getToolsByBranch(branch);
210
229
  }
@@ -6,7 +6,7 @@ export interface RowData {
6
6
  decay: DecayData;
7
7
  dtt: Dtt | null;
8
8
  editTree?: boolean;
9
- lines: StrippingLine[];
9
+ line: StrippingLine | null;
10
10
  paths: string[];
11
11
  pathOptions: string[];
12
12
  }
@@ -33,7 +33,7 @@ export class YamlFile {
33
33
  options: [dttFile],
34
34
  };
35
35
  if (path.includes("MDST")) {
36
- const stream = row.lines[0]?.stream;
36
+ const stream = row.line?.stream;
37
37
  if (stream)
38
38
  job.root_in_tes = `/Event/${stream}`;
39
39
  }
@@ -21,6 +21,7 @@ import { getSelectTagOptions, TagDropdown } from "../components/TagDropdown";
21
21
  import { useRows } from "../providers/RowsProvider";
22
22
  import { LoadingIndicator } from "../components/LoadingIndicator";
23
23
  import { useWizardConfig } from "../providers/WizardConfigProvider";
24
+ import { GuideLinkButton } from "../components/GuideLinkButton";
24
25
  var MatchType;
25
26
  (function (MatchType) {
26
27
  MatchType["any"] = "any";
@@ -57,15 +58,9 @@ export function DecaySearchPage() {
57
58
  });
58
59
  }, []);
59
60
  useEffect(() => {
60
- if (!metadata) {
61
- return;
62
- }
63
61
  // Set default value for selectedTags when metadata is loaded
64
62
  setSelectedTags(getSelectTagOptions(metadata.userHints.decayTags, (tag) => tag.hide));
65
63
  }, [metadata]);
66
- if (!metadata) {
67
- return _jsx(LoadingIndicator, { height: "70vh" });
68
- }
69
64
  const sendData = () => {
70
65
  const selectedDecaySet = new Set(selectedDecays.map((d) => d.descriptors.plain));
71
66
  // Keep only rows whose decay is still selected
@@ -88,7 +83,7 @@ export function DecaySearchPage() {
88
83
  id: getNextId(),
89
84
  decay,
90
85
  dtt: null,
91
- lines: [],
86
+ line: null,
92
87
  paths: [],
93
88
  pathOptions: [],
94
89
  });
@@ -191,9 +186,9 @@ export function DecaySearchPage() {
191
186
  const getExtraInputs = () => {
192
187
  return (_jsx(_Fragment, { children: _jsxs(InputGroup, { size: "sm", children: [_jsx(DropdownButton, { title: "Tags (" + tagMatchType + " of):", variant: "outline-secondary", children: _jsx(DropdownMatchTypes, { options: Object.values(MatchType), stateItem: tagMatchType, stateSetter: setTagMatchType }) }), _jsx(TagDropdown, { type: "decayTags", placeholder: "DecayLatex tags", value: selectedTags, onChange: (values) => setSelectedTags([...values]), closeMenuOnSelect: false }), _jsx("div", { className: "react-select form-control p-0", children: _jsx(Select, { placeholder: "Stripping line", isClearable: true, options: metadata
193
188
  ? allStrippingLines().map((line) => ({ value: line, label: line }))
194
- : [], onChange: setSelectedLine, isLoading: !metadata }) })] }) }));
189
+ : [], onChange: setSelectedLine }) })] }) }));
195
190
  };
196
- return (_jsxs(_Fragment, { children: [_jsx("h3", { children: "Decay search" }), _jsxs(InputGroup, { size: "sm", children: [_jsxs(DropdownButton, { title: "Head (" +
191
+ return (_jsxs(_Fragment, { children: [_jsxs("h3", { className: "d-flex align-items-center gap-2", children: ["Decay search", _jsx(GuideLinkButton, { page: "selectingDecays", topic: "Selecting decays" })] }), _jsxs(InputGroup, { size: "sm", children: [_jsxs(DropdownButton, { title: "Head (" +
197
192
  (headMatchType === HeadMatchType.exactly ? headMatchType : headTagMatchType + " of") +
198
193
  "):", variant: "outline-secondary", children: [_jsx(DropdownMatchTypes, { options: Object.values(HeadMatchType), stateItem: headMatchType, stateSetter: setHeadMatchType }), _jsx(Dropdown.Divider, {}), headMatchType === HeadMatchType.exactly ? (_jsx(DropdownChargeConjugate, { stateItem: chargeConjugateHeads, stateSetter: setChargeConjugateHeads })) : (_jsx(DropdownMatchTypes, { options: Object.values(MatchType), stateItem: headTagMatchType, stateSetter: setHeadTagMatchType }))] }), headMatchType === HeadMatchType.exactly ? (_jsx(ParticleDropdown, { isClearable: true, onlyHeads: true, placeholder: "DecayLatex head", onChange: (value) => setSelectedHead(value) })) : (_jsx(TagDropdown, { type: "particleTags", placeholder: "DecayLatex head", filter: (tag) => !tag.hide, onChange: (values) => setSelectedHeadTags([...values]) })), _jsxs(DropdownButton, { title: "Contains (" + containsMatchType + " of):", variant: "outline-secondary", children: [_jsx(DropdownMatchTypes, { options: Object.values(MatchType), stateItem: containsMatchType, stateSetter: setContainsMatchType }), _jsx(Dropdown.Divider, {}), _jsx(DropdownChargeConjugate, { stateItem: chargeConjugateContains, stateSetter: setChargeConjugateContains })] }), _jsx(ParticleDropdown, { isMulti: true, onlyKnown: true, placeholder: "Particles in decay...", onChange: (values) => setSelectedContains(values), closeMenuOnSelect: false }), _jsx(InputGroup.Text, { children: "Show only selected:" }), _jsx(InputGroup.Checkbox, { onChange: () => setOnlySelected(!onlySelected) })] }), getExtraInputs(), getDecayList(), _jsx(Link, { to: basePath, children: _jsx(OverlayTrigger, { overlay: _jsx(Tooltip, { children: "Return to production configuration" }), children: _jsxs(Button, { variant: "success", type: "submit", onClick: sendData, children: ["Select ", _jsx(Badge, { pill: true, bg: "secondary", children: selectedDecays.length })] }) }) })] }));
199
194
  }
@@ -14,50 +14,16 @@ import { useNavigate } from "react-router-dom";
14
14
  import { useMetadata } from "../providers/MetadataProvider";
15
15
  import { DecayTreeCard } from "../components/DecayTreeCard";
16
16
  import { useRows } from "../providers/RowsProvider";
17
- import Dtt from "../models/dtt";
18
17
  import { DttProvider } from "../providers/DttProvider";
19
- import { LoadingIndicator } from "../components/LoadingIndicator";
20
- import { useEffect, useState } from "react";
21
18
  import { useWizardConfig } from "../providers/WizardConfigProvider";
19
+ import { RowProvider } from "../providers/RowProvider";
22
20
  export function DecayTreeConfigPage() {
23
21
  const navigate = useNavigate();
24
22
  const metadata = useMetadata();
25
- const { rows, updateRow } = useRows();
23
+ const { rows } = useRows();
26
24
  const { basePath } = useWizardConfig();
27
- const [dirtyDtts, setDirtyDtts] = useState(new Set());
28
- // Listen for when the user is about to leave the page and alert them if there are unsaved changes
29
- useEffect(() => {
30
- const handleBeforeUnload = (event) => {
31
- if (dirtyDtts.size > 0) {
32
- event.preventDefault();
33
- }
34
- };
35
- window.addEventListener("beforeunload", handleBeforeUnload);
36
- return () => {
37
- window.removeEventListener("beforeunload", handleBeforeUnload);
38
- };
39
- }, [dirtyDtts]);
40
- if (!metadata) {
41
- return _jsx(LoadingIndicator, { height: "70vh" });
42
- }
43
25
  const rowsToEdit = rows.filter((row) => !!row.editTree);
44
- return (_jsxs(_Fragment, { children: [_jsx("h3", { className: "mb-4", children: "DecayTreeTuple configuration" }), _jsx(Stack, { gap: 5, children: rowsToEdit.map((row) => (_jsx(DttProvider, { metadata: metadata, decay: row.decay, initialConfig: row.dtt.config, children: _jsx(DecayTreeCard, { onConfigSaved: (newConfig) => {
45
- updateRow(row.id, (r) => ({ ...r, dtt: new Dtt(newConfig, {}) }));
46
- }, onDirtyUpdated: (dttName, dirty) => setDirtyDtts((prev) => {
47
- if (dirty) {
48
- return new Set(prev.add(dttName));
49
- }
50
- else {
51
- const newSet = new Set(prev);
52
- newSet.delete(dttName);
53
- return newSet;
54
- }
55
- }) }) }, row.id))) }), _jsx(OverlayTrigger, { placement: "right", overlay: _jsx(Tooltip, { children: "Return to Stripping line and dataset selection" }), children: _jsx(Button, { className: "mt-2 mb-4", type: "submit", onClick: () => {
56
- if (dirtyDtts.size > 0) {
57
- if (!confirm("You have unsaved changes. Are you sure you want to discard them?")) {
58
- return;
59
- }
60
- }
26
+ return (_jsxs(_Fragment, { children: [_jsx("h3", { className: "mb-4", children: "DecayTreeTuple configuration" }), _jsx(Stack, { gap: 5, children: rowsToEdit.map((row) => (_jsx(RowProvider, { row: row, children: _jsx(DttProvider, { metadata: metadata, decay: row.decay, initialConfig: row.dtt.config, children: _jsx(DecayTreeCard, {}) }, row.id) }, row.id))) }), _jsx(OverlayTrigger, { placement: "right", overlay: _jsx(Tooltip, { children: "Return to Stripping line and dataset selection" }), children: _jsx(Button, { className: "mt-2 mb-4", type: "submit", onClick: () => {
61
27
  void navigate(basePath);
62
- }, variant: dirtyDtts.size > 0 ? "outline-danger" : "primary", children: dirtyDtts.size > 0 ? "Discard changes" : "Return" }) })] }));
28
+ }, children: "Return" }) })] }));
63
29
  }
@@ -26,6 +26,7 @@ import { RowProvider } from "../providers/RowProvider";
26
26
  import { ProductionNameInput } from "../components/ProductionNameInput";
27
27
  import { RequestEmailInput } from "../components/RequestEmailInput";
28
28
  import { RequestButtonGroup } from "../components/RequestButtonGroup";
29
+ import { GuideLinkButton } from "../components/GuideLinkButton";
29
30
  import { useWizardConfig } from "../providers/WizardConfigProvider";
30
31
  export function RequestPage() {
31
32
  const metadata = useMetadata();
@@ -38,9 +39,6 @@ export function RequestPage() {
38
39
  const [showReasonForRequestModal, setShowReasonForRequestModal] = useState(false);
39
40
  const [checkedIfCloneNeeded, setCheckedIfCloneNeeded] = useState(false);
40
41
  useEffect(() => {
41
- if (!metadata) {
42
- return;
43
- }
44
42
  // If the localStorage has been set, we should clone the configuration
45
43
  const infoYamlString = localStorage.getItem("infoYamlToClone");
46
44
  const dttConfigsString = localStorage.getItem("dttConfigsToClone");
@@ -96,5 +94,5 @@ export function RequestPage() {
96
94
  !validation.allRowsHaveStrippingLine ||
97
95
  !validation.allRowsHavePaths) && (_jsx(Alert, { variant: "danger", className: "mb-0", children: rows.length === 0
98
96
  ? "Please select at least one decay"
99
- : "Please name all DecayTreeTuples and select at least one stripping line and bookkeeping path for each decay" })), _jsx(Row, { children: _jsx(Col, { xs: "auto", children: _jsx(RequestButtonGroup, {}) }) }), _jsx(Row, { children: _jsxs(Col, { xs: "auto", children: [_jsx(ProductionNameInput, {}), !emailIsKnown && _jsx(RequestEmailInput, {}), _jsxs(Stack, { direction: "horizontal", gap: 1, className: "mt-3 mb-3", children: [_jsxs(Button, { className: "align-items-center d-flex gap-1", onClick: () => void handlePrimaryAction(), children: [variant === "standalone" ? _jsx(Download, {}) : _jsx(Send, {}), variant === "standalone" ? "Download" : "Submit"] }), _jsx(DeleteButton, { action: clearAll, disabled: validation.isEmptySession, outline: undefined, children: "Clear all" })] })] }) })] })] }));
97
+ : "Please name all DecayTreeTuples and select at least one stripping line and dataset for each decay" })), _jsx(Row, { children: _jsx(Col, { xs: "auto", children: _jsx(RequestButtonGroup, {}) }) }), _jsx(Row, { children: _jsxs(Col, { xs: "auto", children: [_jsxs("div", { className: "d-flex align-items-center flex-row gap-2", children: [_jsxs("div", { children: [_jsx(ProductionNameInput, {}), !emailIsKnown && _jsx(RequestEmailInput, {})] }), rows.length > 0 && (_jsx(GuideLinkButton, { page: "submittingRequests", topic: "Submitting requests" }))] }), _jsxs(Stack, { direction: "horizontal", gap: 2, className: "mt-3 mb-3", children: [_jsxs(Button, { className: "align-items-center d-flex gap-1", onClick: () => void handlePrimaryAction(), children: [variant === "standalone" ? _jsx(Download, {}) : _jsx(Send, {}), variant === "standalone" ? "Download" : "Submit"] }), _jsx(DeleteButton, { action: clearAll, disabled: validation.isEmptySession, outline: undefined, children: "Clear all" })] })] }) })] })] }));
100
98
  }
@@ -9,11 +9,11 @@ interface DttContextType {
9
9
  updateToolParam<K extends keyof ToolParamTypeMap>(this: void, branch: string[], tool: TupleTool, param: string, value: ToolParamTypeMap[K]): void;
10
10
  addTool(this: void, branch: string[], tool: TupleTool): void;
11
11
  removeTool(this: void, branch: string[], tool: TupleTool): void;
12
- dirty: boolean;
13
- save(this: void): void;
14
- revert(this: void): void;
15
12
  selectedBranch: string[];
16
13
  setSelectedBranch: (branch: string[]) => void;
14
+ hoveredBranch: string[];
15
+ setHoveredBranch: (branch: string[]) => void;
16
+ highlightedBranch: string[];
17
17
  }
18
18
  interface DttProviderProps {
19
19
  initialConfig: DttConfig;
@@ -1,74 +1,49 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { createContext, useCallback, useContext, useReducer, useState } from "react";
2
+ import { createContext, useCallback, useContext, useState } from "react";
3
3
  import Dtt from "../models/dtt";
4
+ import { useRows } from "./RowsProvider";
5
+ import { useRow } from "./RowProvider";
4
6
  const DttContext = createContext(null);
5
- function reducer(state, action) {
6
- switch (action.type) {
7
- case "INIT":
8
- return {
9
- dtt: action.dtt,
10
- lastSaved: structuredClone(action.config),
11
- dirty: false,
12
- };
13
- case "UPDATE":
14
- return {
15
- ...state,
16
- dtt: action.dtt,
17
- dirty: true,
18
- };
19
- case "SAVE":
20
- return {
21
- ...state,
22
- lastSaved: structuredClone(state.dtt.config),
23
- dirty: false,
24
- };
25
- case "REVERT":
26
- return {
27
- ...state,
28
- dtt: state.dtt.withConfig(state.lastSaved),
29
- dirty: false,
30
- };
31
- }
32
- }
33
7
  export function DttProvider({ initialConfig, decay, metadata, children }) {
8
+ const { row } = useRow();
9
+ const { updateRow } = useRows();
34
10
  const [selectedBranch, setSelectedBranch] = useState([]);
35
- const [state, dispatch] = useReducer(reducer, null, () => ({
36
- dtt: new Dtt(structuredClone(initialConfig), metadata.tupleTools.tupleTools),
37
- decay,
38
- lastSaved: structuredClone(initialConfig),
39
- dirty: false,
40
- }));
11
+ const [hoveredBranch, setHoveredBranch] = useState([]);
12
+ const [dtt, setDtt] = useState(() => new Dtt(structuredClone(initialConfig), metadata.tupleTools.tupleTools));
13
+ const save = useCallback((next) => {
14
+ updateRow(row.id, (r) => ({
15
+ ...r,
16
+ dtt: new Dtt(structuredClone(next.config), {}),
17
+ }));
18
+ }, [row.id, updateRow]);
41
19
  const updateToolParam = useCallback((branch, tool, param, value) => {
42
- const next = state.dtt.withUpdatedToolParam(branch, tool, param, value);
43
- if (next === state.dtt)
20
+ const next = dtt.withUpdatedToolParam(branch, tool, param, value);
21
+ if (next === dtt)
44
22
  return;
45
- dispatch({ type: "UPDATE", dtt: next });
46
- }, [state.dtt]);
23
+ setDtt(next);
24
+ save(next);
25
+ }, [dtt, save]);
47
26
  const addTool = useCallback((branch, tool) => {
48
- dispatch({
49
- type: "UPDATE",
50
- dtt: state.dtt.withAddedTool(tool, branch),
51
- });
52
- }, [state.dtt]);
27
+ const next = dtt.withAddedTool(tool, branch);
28
+ setDtt(next);
29
+ save(next);
30
+ }, [dtt, save]);
53
31
  const removeTool = useCallback((branch, tool) => {
54
- dispatch({
55
- type: "UPDATE",
56
- dtt: state.dtt.withRemovedTool(tool, branch),
57
- });
58
- }, [state.dtt]);
59
- const save = useCallback(() => dispatch({ type: "SAVE" }), []);
60
- const revert = useCallback(() => dispatch({ type: "REVERT" }), []);
32
+ const next = dtt.withRemovedTool(tool, branch);
33
+ setDtt(next);
34
+ save(next);
35
+ }, [dtt, save]);
61
36
  const value = {
62
- dtt: state.dtt,
37
+ dtt,
63
38
  decay,
64
- dirty: state.dirty,
65
39
  updateToolParam,
66
40
  addTool,
67
41
  removeTool,
68
- save,
69
- revert,
70
42
  selectedBranch,
71
43
  setSelectedBranch,
44
+ hoveredBranch,
45
+ setHoveredBranch,
46
+ highlightedBranch: hoveredBranch.length > 0 ? hoveredBranch : selectedBranch,
72
47
  };
73
48
  return _jsx(DttContext.Provider, { value: value, children: children });
74
49
  }
@@ -83,5 +83,5 @@ interface Props {
83
83
  children: ReactNode;
84
84
  }
85
85
  export declare function MetadataProvider({ children }: Props): import("react/jsx-runtime").JSX.Element;
86
- export declare const useMetadata: () => MetadataContext | null;
86
+ export declare const useMetadata: () => MetadataContext;
87
87
  export {};