@teselagen/ove 0.0.14 → 0.0.15

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 (362) hide show
  1. package/index.umd.js +164777 -135861
  2. package/package.json +78 -2
  3. package/src/AlignmentTool/index.js +16 -0
  4. package/src/AlignmentView/AlignmentVisibilityTool.js +105 -0
  5. package/src/AlignmentView/EditTrackNameDialog.js +34 -0
  6. package/src/AlignmentView/HorizontalPanelDragHandle.js +35 -0
  7. package/src/AlignmentView/Minimap.js +520 -0
  8. package/src/AlignmentView/Mismatches.js +134 -0
  9. package/src/AlignmentView/PairwiseAlignmentView.js +68 -0
  10. package/src/AlignmentView/PerformantSelectionLayer.js +32 -0
  11. package/src/AlignmentView/coerceInitialValue.js +7 -0
  12. package/src/AlignmentView/getGapMap.js +12 -0
  13. package/src/AlignmentView/getGaps.js +27 -0
  14. package/src/AlignmentView/getPairwiseOverviewLinearViewOptions.js +38 -0
  15. package/src/AlignmentView/getTrackFromEvent.js +25 -0
  16. package/src/AlignmentView/index.js +2058 -0
  17. package/src/AlignmentView/isTargetWithinEl.js +6 -0
  18. package/src/AlignmentView/style.css +100 -0
  19. package/src/AlignmentView/updateTrackHelper.js +58 -0
  20. package/src/AutoAnnotate.js +500 -0
  21. package/src/AutoAnnotateBpMatchingDialog.js +208 -0
  22. package/src/CircularView/Axis.js +40 -0
  23. package/src/CircularView/AxisNumbers.js +35 -0
  24. package/src/CircularView/Caret.js +63 -0
  25. package/src/CircularView/CircularDnaSequence.js +73 -0
  26. package/src/CircularView/CircularZoomMinimap.js +16 -0
  27. package/src/CircularView/Cutsite.js +18 -0
  28. package/src/CircularView/Cutsites.js +113 -0
  29. package/src/CircularView/DeletionLayer.js +28 -0
  30. package/src/CircularView/Feature.js +83 -0
  31. package/src/CircularView/Labels/index.js +536 -0
  32. package/src/CircularView/Labels/relaxLabelAngles.js +157 -0
  33. package/src/CircularView/Labels/relaxLabels_DEPRECATED.js +105 -0
  34. package/src/CircularView/Labels/style.css +55 -0
  35. package/src/CircularView/Orf.js +25 -0
  36. package/src/CircularView/Part.js +34 -0
  37. package/src/CircularView/PositionAnnotationOnCircle.js +26 -0
  38. package/src/CircularView/Primer.js +41 -0
  39. package/src/CircularView/RotateCircularViewSlider.js +82 -0
  40. package/src/CircularView/SelectionLayer.js +132 -0
  41. package/src/CircularView/VeTopRightContainer.js +12 -0
  42. package/src/CircularView/ZoomCircularViewSlider.js +62 -0
  43. package/src/CircularView/drawAnnotations.js +433 -0
  44. package/src/CircularView/drawDirectedPiePiece.js +142 -0
  45. package/src/CircularView/getAngleForPositionMidpoint.js +3 -0
  46. package/src/CircularView/getInternalLabel.js +40 -0
  47. package/src/CircularView/getRangeAnglesSpecial.js +12 -0
  48. package/src/CircularView/getYOffset.js +15 -0
  49. package/src/CircularView/index.d.ts +20 -0
  50. package/src/CircularView/index.js +930 -0
  51. package/src/CircularView/normalizeAngle.js +3 -0
  52. package/src/CircularView/normalizeAngleRange.js +9 -0
  53. package/src/CircularView/positionCutsites.js +6 -0
  54. package/src/CircularView/shouldFlipText.js +4 -0
  55. package/src/CircularView/style.css +47 -0
  56. package/src/CircularView/utils/polarToSpecialCartesian.js +7 -0
  57. package/src/CreateAnnotationsPage.js +96 -0
  58. package/src/CreateCustomEnzyme/index.js +337 -0
  59. package/src/CreateCustomEnzyme/style.css +100 -0
  60. package/src/CutsiteFilter/AdditionalCutsiteInfoDialog.js +599 -0
  61. package/src/CutsiteFilter/index.js +408 -0
  62. package/src/CutsiteFilter/style.css +23 -0
  63. package/src/CutsiteFilter/withRestrictionEnzymes.js +15 -0
  64. package/src/DigestTool/AddLaddersDialog.js +82 -0
  65. package/src/DigestTool/DigestTool.js +223 -0
  66. package/src/DigestTool/Ladder.css +20 -0
  67. package/src/DigestTool/Ladder.js +303 -0
  68. package/src/DigestTool/createFragmentLines.js +120 -0
  69. package/src/DigestTool/ladderDefaults.js +26 -0
  70. package/src/DigestTool/ruler.css +89 -0
  71. package/src/Editor/CommandHotkeyHandler.js +44 -0
  72. package/src/Editor/DropHandler.css +21 -0
  73. package/src/Editor/DropHandler.js +64 -0
  74. package/src/Editor/FillWindow.js +46 -0
  75. package/src/Editor/darkmode.css +98 -0
  76. package/src/Editor/index.js +1005 -0
  77. package/src/Editor/style.css +235 -0
  78. package/src/Editor/userDefinedHandlersAndOpts.js +56 -0
  79. package/src/EnzymeViewer/index.js +81 -0
  80. package/src/EnzymeViewer/style.css +6 -0
  81. package/src/FindBar/index.js +411 -0
  82. package/src/FindBar/style.css +46 -0
  83. package/src/GlobalDialog.js +66 -0
  84. package/src/GlobalDialogUtils.js +85 -0
  85. package/src/LinearView/SequenceName.js +15 -0
  86. package/src/LinearView/ZoomLinearView.js +47 -0
  87. package/src/LinearView/index.js +374 -0
  88. package/src/LinearView/style.css +12 -0
  89. package/src/ManageEnzymes/index.js +326 -0
  90. package/src/ManageEnzymes/style.css +100 -0
  91. package/src/MenuBar/defaultConfig.js +149 -0
  92. package/src/MenuBar/index.js +98 -0
  93. package/src/MenuBar/viewSubmenu.js +479 -0
  94. package/src/PCRTool/PCRTool.js +173 -0
  95. package/src/Reflex/Browser.js +107 -0
  96. package/src/Reflex/ReflexContainer.js +802 -0
  97. package/src/Reflex/ReflexElement.js +160 -0
  98. package/src/Reflex/ReflexEvents.js +77 -0
  99. package/src/Reflex/ReflexSplitter.js +205 -0
  100. package/src/Reflex/index.js +5 -0
  101. package/src/Reflex/reflex-styles.css +128 -0
  102. package/src/Reflex/reflex-styles.css.map +9 -0
  103. package/src/RowItem/AnnotationContainerHolder.js +20 -0
  104. package/src/RowItem/AnnotationPositioner.js +27 -0
  105. package/src/RowItem/Axis.js +149 -0
  106. package/src/RowItem/Caret/index.js +64 -0
  107. package/src/RowItem/Caret/style.css +8 -0
  108. package/src/RowItem/Chromatograms/Chromatogram.js +289 -0
  109. package/src/RowItem/CutsiteSelectionLayers.js +47 -0
  110. package/src/RowItem/Cutsites.js +271 -0
  111. package/src/RowItem/DeletionLayers/index.js +113 -0
  112. package/src/RowItem/DeletionLayers/style.css +5 -0
  113. package/src/RowItem/Labels.js +327 -0
  114. package/src/RowItem/Orf.js +109 -0
  115. package/src/RowItem/Orfs.js +35 -0
  116. package/src/RowItem/ReplacementLayers/style.css +5 -0
  117. package/src/RowItem/SelectionLayer/index.js +184 -0
  118. package/src/RowItem/SelectionLayer/style.css +21 -0
  119. package/src/RowItem/Sequence.js +269 -0
  120. package/src/RowItem/StackedAnnotations/PointedAnnotation.js +347 -0
  121. package/src/RowItem/StackedAnnotations/getStructuredBases.js +97 -0
  122. package/src/RowItem/StackedAnnotations/index.js +182 -0
  123. package/src/RowItem/StackedAnnotations/primerBases.js +218 -0
  124. package/src/RowItem/StackedAnnotations/style.css +14 -0
  125. package/src/RowItem/Translations/AASliver.js +190 -0
  126. package/src/RowItem/Translations/Translation.js +162 -0
  127. package/src/RowItem/Translations/index.js +54 -0
  128. package/src/RowItem/Translations/style.css +3 -0
  129. package/src/RowItem/constants.js +3 -0
  130. package/src/RowItem/getCutsiteLabelHeights.js +56 -0
  131. package/src/RowItem/getXStartAndWidthFromNonCircularRange.js +12 -0
  132. package/src/RowItem/getXStartAndWidthOfRangeWrtRow.js +27 -0
  133. package/src/RowItem/getXStartAndWidthOfRowAnnotation.js +19 -0
  134. package/src/RowItem/index.js +647 -0
  135. package/src/RowItem/partOverhangs.js +6 -0
  136. package/src/RowItem/style.css +103 -0
  137. package/src/RowItem/utils.js +32 -0
  138. package/src/RowView/estimateRowHeight.js +184 -0
  139. package/src/RowView/index.d.ts +10 -0
  140. package/src/RowView/index.js +554 -0
  141. package/src/RowView/style.css +12 -0
  142. package/src/SimpleCircularOrLinearView.js +379 -0
  143. package/src/SimpleOligoPreview.js +39 -0
  144. package/src/StatusBar/MeltingTemp.js +81 -0
  145. package/src/StatusBar/index.js +275 -0
  146. package/src/StatusBar/style.css +38 -0
  147. package/src/ToolBar/ToolbarItem.js +194 -0
  148. package/src/ToolBar/alignmentTool.js +503 -0
  149. package/src/ToolBar/array_move.js +10 -0
  150. package/src/ToolBar/cutsiteTool.js +88 -0
  151. package/src/ToolBar/downloadTool.js +38 -0
  152. package/src/ToolBar/editTool.js +26 -0
  153. package/src/ToolBar/featureTool.js +34 -0
  154. package/src/ToolBar/findTool.js +2 -0
  155. package/src/ToolBar/importTool.js +27 -0
  156. package/src/ToolBar/index.js +231 -0
  157. package/src/ToolBar/inlineFindTool.js +38 -0
  158. package/src/ToolBar/oligoTool.js +30 -0
  159. package/src/ToolBar/orfTool.js +141 -0
  160. package/src/ToolBar/partTool.js +47 -0
  161. package/src/ToolBar/printTool.js +31 -0
  162. package/src/ToolBar/redoTool.js +30 -0
  163. package/src/ToolBar/saveTool.js +48 -0
  164. package/src/ToolBar/style.css +138 -0
  165. package/src/ToolBar/undoTool.js +30 -0
  166. package/src/ToolBar/veToolbarIcons/find.png +0 -0
  167. package/src/ToolBar/veToolbarIcons/fullscreen.png +0 -0
  168. package/src/ToolBar/veToolbarIcons/linear.png +0 -0
  169. package/src/ToolBar/veToolbarIcons/pie.png +0 -0
  170. package/src/ToolBar/veToolbarIcons/print.png +0 -0
  171. package/src/ToolBar/veToolbarIcons/save.png +0 -0
  172. package/src/ToolBar/veToolbarIcons/show_cut_sites.png +0 -0
  173. package/src/ToolBar/veToolbarIcons/show_features.png +0 -0
  174. package/src/ToolBar/veToolbarIcons/show_orfs.png +0 -0
  175. package/src/ToolBar/veToolbarIcons/show_primers.png +0 -0
  176. package/src/ToolBar/veToolbarIcons/toggle_views.svg +1 -0
  177. package/src/ToolBar/versionHistoryTool.js +20 -0
  178. package/src/ToolBar/visibilityTool.js +39 -0
  179. package/src/VersionHistoryView/index.js +215 -0
  180. package/src/addAlignment.js +6 -0
  181. package/src/commands/getOveHotkeyDefs.js +12 -0
  182. package/src/commands/index.js +1585 -0
  183. package/src/constants/constants.js +2 -0
  184. package/src/constants/dnaToColor.js +17 -0
  185. package/src/constants/draggableClassnames.js +5 -0
  186. package/src/constants/findToolConstants.js +1 -0
  187. package/src/constants/orfFrameToColorMap.js +10 -0
  188. package/src/constants/rowviewContants.js +3 -0
  189. package/src/constants/specialCutsiteFilterOptions.js +22 -0
  190. package/src/constants.js +1 -0
  191. package/src/createVectorEditor/index.js +138 -0
  192. package/src/createVectorEditor/makeStore.js +34 -0
  193. package/src/fileUtils.js +103 -0
  194. package/src/helperComponents/AddOrEditAnnotationDialog/index.js +711 -0
  195. package/src/helperComponents/AddOrEditAnnotationDialog/style.css +11 -0
  196. package/src/helperComponents/AddOrEditFeatureDialog/index.js +58 -0
  197. package/src/helperComponents/AddOrEditPartDialog/index.js +101 -0
  198. package/src/helperComponents/AddOrEditPrimerDialog/EditCaretPosition.js +234 -0
  199. package/src/helperComponents/AddOrEditPrimerDialog/index.js +329 -0
  200. package/src/helperComponents/AddOrEditPrimerDialog/style.css +41 -0
  201. package/src/helperComponents/EnzymesDialog/index.js +904 -0
  202. package/src/helperComponents/EnzymesDialog/style.css +21 -0
  203. package/src/helperComponents/GoToDialog.js +21 -0
  204. package/src/helperComponents/MergeFeaturesDialog/index.js +253 -0
  205. package/src/helperComponents/MergeFeaturesDialog/style.css +3 -0
  206. package/src/helperComponents/MultipleSeqsDetectedOnImportDialog.js +74 -0
  207. package/src/helperComponents/PinchHelper/PinchHelper.js +24 -0
  208. package/src/helperComponents/PrintDialog/index.js +396 -0
  209. package/src/helperComponents/PrintDialog/style.css +4 -0
  210. package/src/helperComponents/PropertiesDialog/ColorPicker.js +30 -0
  211. package/src/helperComponents/PropertiesDialog/CutsiteProperties.js +185 -0
  212. package/src/helperComponents/PropertiesDialog/FeatureProperties.js +6 -0
  213. package/src/helperComponents/PropertiesDialog/GenbankView.js +74 -0
  214. package/src/helperComponents/PropertiesDialog/GeneralProperties.js +140 -0
  215. package/src/helperComponents/PropertiesDialog/GenericAnnotationProperties.js +406 -0
  216. package/src/helperComponents/PropertiesDialog/OrfProperties.js +117 -0
  217. package/src/helperComponents/PropertiesDialog/PartProperties.js +9 -0
  218. package/src/helperComponents/PropertiesDialog/PrimerProperties.js +19 -0
  219. package/src/helperComponents/PropertiesDialog/SingleEnzymeCutsiteInfo.js +131 -0
  220. package/src/helperComponents/PropertiesDialog/TranslationProperties.js +149 -0
  221. package/src/helperComponents/PropertiesDialog/index.js +166 -0
  222. package/src/helperComponents/PropertiesDialog/style.css +68 -0
  223. package/src/helperComponents/PropertiesDialog/typeField.js +24 -0
  224. package/src/helperComponents/PropertiesDialog/utils.js +37 -0
  225. package/src/helperComponents/RemoveDuplicates/index.js +194 -0
  226. package/src/helperComponents/RenameSequenceDialog.js +7 -0
  227. package/src/helperComponents/SelectDialog.js +150 -0
  228. package/src/helperComponents/UncontrolledSliderWithPlusMinusBtns.css +5 -0
  229. package/src/helperComponents/UncontrolledSliderWithPlusMinusBtns.js +134 -0
  230. package/src/helperComponents/VeWarning/index.js +22 -0
  231. package/src/helperComponents/VeWarning/style.css +10 -0
  232. package/src/helperComponents/createSimpleDialog.js +89 -0
  233. package/src/helperComponents/partTagSearch.js +72 -0
  234. package/src/helperComponents/simpleDialog.css +13 -0
  235. package/src/helperComponents/withHover.js +90 -0
  236. package/src/index.js +60 -0
  237. package/src/redux/alignments.js +373 -0
  238. package/src/redux/annotationLabelVisibility.js +53 -0
  239. package/src/redux/annotationVisibility.js +196 -0
  240. package/src/redux/annotationsToSupport.js +104 -0
  241. package/src/redux/caretPosition.js +27 -0
  242. package/src/redux/charWidth.js +22 -0
  243. package/src/redux/copyOptions.js +34 -0
  244. package/src/redux/createYourOwnEnzyme.js +39 -0
  245. package/src/redux/deletionLayers.js +36 -0
  246. package/src/redux/digestTool.js +34 -0
  247. package/src/redux/featureLengthsToHide.js +27 -0
  248. package/src/redux/findTool.js +79 -0
  249. package/src/redux/frameTranslations.js +52 -0
  250. package/src/redux/hoveredAnnotation.js +24 -0
  251. package/src/redux/index.js +196 -0
  252. package/src/redux/labelLineIntensity.js +25 -0
  253. package/src/redux/labelSize.js +23 -0
  254. package/src/redux/lastSavedId.js +20 -0
  255. package/src/redux/middleware.js +112 -0
  256. package/src/redux/minimumOrfSize.js +24 -0
  257. package/src/redux/modalActions.js +3 -0
  258. package/src/redux/panelsShown.js +273 -0
  259. package/src/redux/partLengthsToHide.js +23 -0
  260. package/src/redux/primerLengthsToHide.js +27 -0
  261. package/src/redux/propertiesTool.js +40 -0
  262. package/src/redux/readOnly.js +28 -0
  263. package/src/redux/replacementLayers.js +36 -0
  264. package/src/redux/restrictionEnzymes.js +52 -0
  265. package/src/redux/selectedAnnotations.js +89 -0
  266. package/src/redux/selectedPartTags.js +21 -0
  267. package/src/redux/selectionLayer.js +46 -0
  268. package/src/redux/sequenceData/circular.js +19 -0
  269. package/src/redux/sequenceData/description.js +21 -0
  270. package/src/redux/sequenceData/features.js +19 -0
  271. package/src/redux/sequenceData/index.js +81 -0
  272. package/src/redux/sequenceData/lineageLines.js +11 -0
  273. package/src/redux/sequenceData/materiallyAvailable.js +19 -0
  274. package/src/redux/sequenceData/name.js +19 -0
  275. package/src/redux/sequenceData/parts.js +19 -0
  276. package/src/redux/sequenceData/primers.js +19 -0
  277. package/src/redux/sequenceData/sequence.js +12 -0
  278. package/src/redux/sequenceData/sharedActionCreators.js +0 -0
  279. package/src/redux/sequenceData/translations.js +20 -0
  280. package/src/redux/sequenceData/upsertDeleteActionGenerator.js +31 -0
  281. package/src/redux/sequenceDataHistory.js +43 -0
  282. package/src/redux/showGCContent.js +23 -0
  283. package/src/redux/toolBar.js +25 -0
  284. package/src/redux/uppercaseSequenceMapFont.js +25 -0
  285. package/src/redux/useAdditionalOrfStartCodons.js +24 -0
  286. package/src/redux/utils/addDashesForMatchStartAndEndForTracks/index.js +71 -0
  287. package/src/redux/utils/addMetaToActionCreators.js +12 -0
  288. package/src/redux/utils/createMergedDefaultStateReducer.js +30 -0
  289. package/src/redux/utils/createMetaAction.js +12 -0
  290. package/src/redux/versionHistory.js +27 -0
  291. package/src/selectors/annotationLabelVisibility.js +2 -0
  292. package/src/selectors/annotationSearchSelector.js +24 -0
  293. package/src/selectors/cdsFeaturesSelector.js +9 -0
  294. package/src/selectors/circularSelector.js +4 -0
  295. package/src/selectors/cutsiteLabelColorSelector.js +6 -0
  296. package/src/selectors/cutsitesByRangeSelector.js +5 -0
  297. package/src/selectors/cutsitesSelector.js +61 -0
  298. package/src/selectors/editorSelector.js +2 -0
  299. package/src/selectors/featuresSelector.js +8 -0
  300. package/src/selectors/filteredCutsitesSelector.js +137 -0
  301. package/src/selectors/filteredFeaturesSelector.js +32 -0
  302. package/src/selectors/filteredPartsSelector.js +57 -0
  303. package/src/selectors/filteredPrimersSelector.js +27 -0
  304. package/src/selectors/filteredRestrictionEnzymesSelector.js +1 -0
  305. package/src/selectors/getAdditionalEnzymesSelector.js +46 -0
  306. package/src/selectors/index.js +41 -0
  307. package/src/selectors/isEnzymeFilterAndSelector.js +1 -0
  308. package/src/selectors/minimumOrfSizeSelector.js +2 -0
  309. package/src/selectors/orfsSelector.js +15 -0
  310. package/src/selectors/partsSelector.js +8 -0
  311. package/src/selectors/primersSelector.js +8 -0
  312. package/src/selectors/restrictionEnzymesSelector.js +34 -0
  313. package/src/selectors/searchLayersSelector.js +71 -0
  314. package/src/selectors/selectedAnnotationsSelector.js +1 -0
  315. package/src/selectors/selectedCutsitesSelector.js +21 -0
  316. package/src/selectors/sequenceDataSelector.js +2 -0
  317. package/src/selectors/sequenceLengthSelector.js +5 -0
  318. package/src/selectors/sequenceSelector.js +4 -0
  319. package/src/selectors/tagsToBoldSelector.js +2 -0
  320. package/src/selectors/translationSearchMatchesSelector.js +14 -0
  321. package/src/selectors/translationsRawSelector.js +8 -0
  322. package/src/selectors/translationsSelector.js +137 -0
  323. package/src/style.css +82 -0
  324. package/src/updateEditor.js +198 -0
  325. package/src/utils/PassThrough.js +3 -0
  326. package/src/utils/addWrappedAddons.js +20 -0
  327. package/src/utils/annotationTypes.js +37 -0
  328. package/src/utils/arrayUtils.js +19 -0
  329. package/src/utils/calculateTickMarkPositionsForGivenRange.js +47 -0
  330. package/src/utils/cleanSequenceData_DEPRECATED/arrayToObjWithIds.js +17 -0
  331. package/src/utils/combineReducersDontIgnoreKeys.js +12 -0
  332. package/src/utils/commandUtils.js +18 -0
  333. package/src/utils/editorUtils.js +223 -0
  334. package/src/utils/getAnnotationClassnames.js +12 -0
  335. package/src/utils/getAnnotationNameAndStartStopString.js +61 -0
  336. package/src/utils/getVisibleStartEnd.js +7 -0
  337. package/src/utils/massageTickSpacing.js +19 -0
  338. package/src/utils/onlyUpdateForKeysDeep.js +31 -0
  339. package/src/utils/prepareRowData.js +64 -0
  340. package/src/utils/proteinUtils.js +3 -0
  341. package/src/utils/pureNoFunc.js +18 -0
  342. package/src/utils/selectionLayer.js +25 -0
  343. package/src/utils/shouldRerender.js +27 -0
  344. package/src/utils/showFileDialog.js +26 -0
  345. package/src/utils/updateLabelsForInViewFeatures.js +55 -0
  346. package/src/utils/updateLabelsForInViewFeaturesCircView.js +41 -0
  347. package/src/utils/useAAColorType.js +8 -0
  348. package/src/utils/useAnnotationLimits.js +42 -0
  349. package/src/utils/useChromatogramPrefs.js +31 -0
  350. package/src/utils/useLadders.js +6 -0
  351. package/src/utils/useMeltingTemp.js +7 -0
  352. package/src/utils/useTmType.js +10 -0
  353. package/src/withEditorInteractions/Keyboard.js +86 -0
  354. package/src/withEditorInteractions/clickAndDragUtils.js +576 -0
  355. package/src/withEditorInteractions/createSequenceInputPopup.js +296 -0
  356. package/src/withEditorInteractions/createSequenceInputPopupStyle.css +85 -0
  357. package/src/withEditorInteractions/getBpsPerRow.js +19 -0
  358. package/src/withEditorInteractions/index.js +1252 -0
  359. package/src/withEditorInteractions/isElementInViewport.js +29 -0
  360. package/src/withEditorInteractions/moveCaret.js +58 -0
  361. package/src/withEditorProps/index.js +1010 -0
  362. package/index.mjs +0 -193228
@@ -0,0 +1,904 @@
1
+ import React from "react";
2
+ // import uuid from "uniqid";
3
+
4
+ // import { reduxForm, formValues } from "redux-form";
5
+
6
+ import {
7
+ InfoHelper,
8
+ showConfirmationDialog,
9
+ wrapDialog
10
+ } from "@teselagen/ui";
11
+ import { compose } from "redux";
12
+ import {
13
+ Classes,
14
+ ButtonGroup,
15
+ InputGroup,
16
+ Popover,
17
+ HTMLSelect,
18
+ Tooltip,
19
+ AnchorButton,
20
+ Intent,
21
+ Button
22
+ } from "@blueprintjs/core";
23
+ import classNames from "classnames";
24
+ import withEditorProps from "../../withEditorProps";
25
+
26
+ import EnzymeViewer from "../../EnzymeViewer";
27
+ import "./style.css";
28
+
29
+ import { map, flatMap, countBy, reduce, uniq, omitBy } from "lodash";
30
+ import {
31
+ aliasedEnzymesByName,
32
+ defaultEnzymesByName,
33
+ getCutsitesFromSequence
34
+ } from "@teselagen/sequence-utils";
35
+ import { store, view } from "@risingstack/react-easy-state";
36
+ import { showDialog } from "../../GlobalDialogUtils";
37
+
38
+ const upsertLocalEnzymeGroups = (newGroups) => {
39
+ const existingGroups = window.getExistingEnzymeGroups();
40
+ const toUpsert = omitBy(
41
+ //delete any groups that have a value of null/undefined
42
+ {
43
+ ...existingGroups,
44
+ ...newGroups
45
+ },
46
+ (val) => {
47
+ return !val;
48
+ }
49
+ );
50
+
51
+ localStorage.setItem("enzymeGroups", JSON.stringify(toUpsert));
52
+ };
53
+
54
+ window.createNewEnzymeGroup =
55
+ window.createNewEnzymeGroup ||
56
+ ((newName) => {
57
+ return upsertLocalEnzymeGroups({
58
+ [newName]: []
59
+ });
60
+ });
61
+ window.editEnzymeGroupName =
62
+ window.editEnzymeGroupName ||
63
+ ((oldName, newName) => {
64
+ upsertLocalEnzymeGroups({
65
+ [newName]: window.getExistingEnzymeGroups()[oldName]
66
+ });
67
+ window.deleteEnzymeGroup(oldName);
68
+ });
69
+ window.deleteEnzymeGroup =
70
+ window.deleteEnzymeGroup ||
71
+ ((nameToDelete) => {
72
+ return upsertLocalEnzymeGroups({
73
+ [nameToDelete]: null
74
+ });
75
+ });
76
+
77
+ window.updateEnzymeGroup =
78
+ window.updateEnzymeGroup ||
79
+ ((groupName, enzymes) => {
80
+ return upsertLocalEnzymeGroups({
81
+ [groupName]: enzymes
82
+ });
83
+ });
84
+
85
+ window.getExistingEnzymeGroups =
86
+ window.getExistingEnzymeGroups ||
87
+ (() => {
88
+ const existingGroups = JSON.parse(
89
+ localStorage.getItem("enzymeGroups") || "{}"
90
+ );
91
+ if (!Object.keys(existingGroups || {}).length) {
92
+ return {};
93
+ }
94
+ map(existingGroups, (g, k) => {
95
+ if (!g || !g.length) existingGroups[k] = [];
96
+ });
97
+ return existingGroups;
98
+ });
99
+
100
+ // window.getExistingEnzymeGroupsWithEnzymeData = () => {
101
+ // const toRet = {};
102
+ // forEach(window.getExistingEnzymeGroups(), (group, name) => {
103
+ // toRet[name] = flatMap(group, enzymeName => {
104
+ // const enzyme = this.getAllEnzymesByName()[enzymeName.toLowerCase()];
105
+ // if (!enzyme) {
106
+ // console.warn("ruh roh");
107
+ // return [];
108
+ // } else {
109
+ // return enzyme;
110
+ // }
111
+ // });
112
+ // });
113
+ // return toRet;
114
+ // };
115
+
116
+ const easyStore = store({ hoveredEnzyme: "" });
117
+ class EnzymesDialog extends React.Component {
118
+ state = {
119
+ selectedEnzymeGroup: "My Enzymes",
120
+ searchInput: ""
121
+ };
122
+ componentDidMount() {
123
+ this.refreshEnzymeGroups();
124
+ }
125
+ getAllEnzymesByName = () => {
126
+ return {
127
+ ...this.props.additionalEnzymes,
128
+ ...aliasedEnzymesByName
129
+ };
130
+ };
131
+ refreshEnzymeGroups = () => {
132
+ const { sequenceData, additionalEnzymes } = this.props;
133
+ const existingGroups = window.getExistingEnzymeGroups();
134
+ const orderedExistingGroups = {};
135
+ const groupedEnzymesNameMap = {};
136
+ Object.keys(existingGroups)
137
+ .sort()
138
+ .forEach(function (key) {
139
+ const group = existingGroups[key];
140
+ orderedExistingGroups[key] = group;
141
+ group.forEach((name) => {
142
+ const lowerName = name.toLowerCase();
143
+ groupedEnzymesNameMap[lowerName] =
144
+ aliasedEnzymesByName[lowerName] || additionalEnzymes[lowerName];
145
+ });
146
+ });
147
+ const myEnzymes = {
148
+ ...groupedEnzymesNameMap,
149
+ ...additionalEnzymes,
150
+ ...defaultEnzymesByName
151
+ };
152
+ const hiddenEnzymes = omitBy(aliasedEnzymesByName, (p, i) => {
153
+ return myEnzymes[i] || groupedEnzymesNameMap[i];
154
+ });
155
+ this.enzymeGroups = {
156
+ "My Enzymes": {
157
+ protected: true,
158
+ name: "My Enzymes",
159
+ enzymes: map(myEnzymes).sort((e) => e.name)
160
+ },
161
+ Hidden: {
162
+ protected: true,
163
+ name: "Hidden",
164
+ tooltipInfo:
165
+ "These less common enzymes are hidden by default. Adding them to a custom group will make them show up in the cutsite filter dropdown.",
166
+ enzymes: map(hiddenEnzymes).sort((e) => e.name)
167
+ },
168
+ ...reduce(
169
+ orderedExistingGroups,
170
+ (acc, val, key) => {
171
+ acc[key] = {
172
+ name: key,
173
+ enzymes: getEnzymesForNames(val, this.getAllEnzymesByName())
174
+ };
175
+ return acc;
176
+ },
177
+ {}
178
+ )
179
+
180
+ // "my special enzymes": {
181
+ // name: "my special enzymes",
182
+ // enzymes: getEnzymesForNames(["bamhi", "bsmbi"])
183
+ // },
184
+
185
+ // "my casual enzymes": {
186
+ // name: "my casual enzymes",
187
+ // enzymes: getEnzymesForNames(["bamhi", "bsmbi"])
188
+ // }
189
+ };
190
+ this.cutsitesByEnzymeName = getCutsitesFromSequence(
191
+ sequenceData.sequence,
192
+ sequenceData.circular,
193
+ map(this.getAllEnzymesByName())
194
+ );
195
+ this.forceUpdate();
196
+ };
197
+
198
+ clearSelection = () => {
199
+ const { selectedEnzymeGroup } = this.state;
200
+ const selectedEnzymesKey = `selectedEnzymes_${selectedEnzymeGroup}`;
201
+ this.setState({
202
+ [selectedEnzymesKey]: {}
203
+ });
204
+ };
205
+ render() {
206
+ const { hideModal } = this.props;
207
+ if (!this.enzymeGroups) return null;
208
+ const { selectedEnzymeGroup, searchInput, enzymeGroupToMoveTo } =
209
+ this.state;
210
+ const selectedEnzymesKey = `selectedEnzymes_${selectedEnzymeGroup}`;
211
+ const selectedEnzymesForGroup = this.state[selectedEnzymesKey] || {};
212
+ const selectedCount = countBy(selectedEnzymesForGroup, (e) => e).true || 0;
213
+ const fullSelectedEnzGroup = this.enzymeGroups[selectedEnzymeGroup] || {};
214
+
215
+ const enzymeList = flatMap(fullSelectedEnzGroup.enzymes, (enz, i) => {
216
+ const name = `${enz.name} (${
217
+ (this.cutsitesByEnzymeName &&
218
+ this.cutsitesByEnzymeName[enz.name] &&
219
+ this.cutsitesByEnzymeName[enz.name].length) ||
220
+ 0
221
+ })`;
222
+ if (
223
+ searchInput &&
224
+ !name.toLowerCase().includes(searchInput.toLowerCase())
225
+ ) {
226
+ return [];
227
+ }
228
+ return (
229
+ <div
230
+ onMouseOver={() => {
231
+ easyStore.hoveredEnzyme = enz.name;
232
+ clearTimeout(this.clearId);
233
+ }}
234
+ onMouseLeave={() => {
235
+ this.clearId = setTimeout(() => {
236
+ easyStore.hoveredEnzyme = "";
237
+ }, 100);
238
+ }}
239
+ onClick={() => {
240
+ this.setState({
241
+ [selectedEnzymesKey]: {
242
+ ...selectedEnzymesForGroup,
243
+ [enz.name]: !selectedEnzymesForGroup[enz.name]
244
+ }
245
+ });
246
+ }}
247
+ className={classNames(Classes.MENU_ITEM, "veEnzymeDialogEnzyme", {
248
+ [`${Classes.ACTIVE} ${Classes.INTENT_PRIMARY}`]:
249
+ selectedEnzymesForGroup[enz.name]
250
+ })}
251
+ key={i}
252
+ >
253
+ {name}
254
+ </div>
255
+ );
256
+ });
257
+ // const enzymesForGroup =
258
+ return (
259
+ <div
260
+ style={{ height: 500 }}
261
+ className={classNames(
262
+ Classes.DIALOG_BODY,
263
+ "tg-min-width-dialog veEnzymeDialog"
264
+ )}
265
+ >
266
+ <div
267
+ className="veEnzymeDialogInner"
268
+ style={{ display: "flex", height: "100%" }}
269
+ >
270
+ <div
271
+ className="veEnzymeDialogEnzymeGroups"
272
+ style={{
273
+ minWidth: 150,
274
+ height: "100%",
275
+ display: "flex",
276
+ flexDirection: "column",
277
+ borderRight: "1px solid lightgrey",
278
+ paddingRight: 5
279
+ }}
280
+ >
281
+ <h5>Enzyme Groups:</h5>
282
+ <div style={{ overflowY: "auto" }}>
283
+ {map(this.enzymeGroups, (group, i) => {
284
+ return (
285
+ <React.Fragment>
286
+ <div
287
+ onClick={() => {
288
+ this.setState({
289
+ selectedEnzymeGroup: group.name
290
+ });
291
+ }}
292
+ className={classNames(Classes.MENU_ITEM, {
293
+ [Classes.ACTIVE]: selectedEnzymeGroup === group.name
294
+ })}
295
+ style={{ marginBottom: 5, cursor: "pointer" }}
296
+ key={i}
297
+ >
298
+ &nbsp; {group.name} &nbsp;{" "}
299
+ {group.tooltipInfo && (
300
+ <InfoHelper
301
+ color="grey"
302
+ isInline
303
+ content={group.tooltipInfo}
304
+ ></InfoHelper>
305
+ )}
306
+ </div>
307
+ {group.name === "Hidden" && (
308
+ <div className={Classes.MENU_DIVIDER}></div>
309
+ )}
310
+ </React.Fragment>
311
+ );
312
+ })}
313
+ </div>
314
+ <ButtonGroup style={{ width: "fit-content" }}>
315
+ <Tooltip
316
+ disabled={window.Cypress}
317
+ position="bottom"
318
+ content="Create New Group"
319
+ >
320
+ <Popover
321
+ content={
322
+ <div
323
+ className="veNewEnzymeGroupPopover"
324
+ style={{ padding: 10 }}
325
+ >
326
+ <h5>Create new enzyme group</h5>
327
+ <div style={{ display: "flex" }}>
328
+ <InputGroup
329
+ autoFocus
330
+ className="veNewEnzymeGroupName"
331
+ ></InputGroup>
332
+ <AnchorButton
333
+ className={Classes.POPOVER_DISMISS}
334
+ onClick={() => {
335
+ const newName = document.querySelector(
336
+ ".veNewEnzymeGroupName input"
337
+ ).value;
338
+ if (!newName) {
339
+ return window.toastr.error("Invalid name");
340
+ }
341
+ if (this.enzymeGroups[newName]) {
342
+ window.toastr.error(
343
+ "Choose a different group name"
344
+ );
345
+ } else {
346
+ window.toastr.success(
347
+ "Created New Enzyme Group " + newName
348
+ );
349
+ window.createNewEnzymeGroup(newName);
350
+ this.refreshEnzymeGroups();
351
+ this.setState({
352
+ selectedEnzymeGroup: newName
353
+ });
354
+ }
355
+ }}
356
+ icon="tick"
357
+ intent="success"
358
+ ></AnchorButton>
359
+ </div>
360
+ </div>
361
+ }
362
+ >
363
+ <AnchorButton
364
+ className="veEnzymeDialogAddGroupBtn"
365
+ minimal
366
+ icon="add"
367
+ ></AnchorButton>
368
+ </Popover>
369
+ </Tooltip>
370
+ <Popover
371
+ content={
372
+ <div
373
+ className="veEditEnzymeGroupPopover"
374
+ style={{ padding: 10 }}
375
+ >
376
+ <h5>Edit group name</h5>
377
+ <div style={{ display: "flex" }}>
378
+ <InputGroup
379
+ defaultValue={selectedEnzymeGroup}
380
+ autoFocus
381
+ className="veEditEnzymeGroupName"
382
+ ></InputGroup>
383
+ <AnchorButton
384
+ className={Classes.POPOVER_DISMISS}
385
+ onClick={() => {
386
+ const newName = document.querySelector(
387
+ ".veEditEnzymeGroupName input"
388
+ ).value;
389
+ if (!newName) {
390
+ return window.toastr.error("Invalid name");
391
+ }
392
+ if (this.enzymeGroups[newName]) {
393
+ window.toastr.error(
394
+ "Choose a different group name"
395
+ );
396
+ } else {
397
+ window.toastr.success("Edit Successful");
398
+ window.editEnzymeGroupName(
399
+ selectedEnzymeGroup,
400
+ newName
401
+ );
402
+ this.refreshEnzymeGroups();
403
+ this.setState({
404
+ selectedEnzymeGroup: newName
405
+ });
406
+ }
407
+ }}
408
+ icon="tick"
409
+ intent="success"
410
+ ></AnchorButton>
411
+ </div>
412
+ </div>
413
+ }
414
+ >
415
+ <Tooltip
416
+ disabled={window.Cypress}
417
+ position="bottom"
418
+ content="Edit Group Name"
419
+ >
420
+ <AnchorButton
421
+ disabled={fullSelectedEnzGroup.protected}
422
+ minimal
423
+ icon="edit"
424
+ ></AnchorButton>
425
+ </Tooltip>
426
+ </Popover>
427
+ <Tooltip
428
+ disabled={window.Cypress}
429
+ position="bottom"
430
+ content="Delete Group"
431
+ >
432
+ <AnchorButton
433
+ disabled={fullSelectedEnzGroup.protected}
434
+ onClick={async () => {
435
+ const confirm = await showConfirmationDialog({
436
+ text: `Are you sure you want to delete this group, ${selectedEnzymeGroup}?`,
437
+ intent: Intent.DANGER
438
+ });
439
+ if (confirm) {
440
+ window.deleteEnzymeGroup(selectedEnzymeGroup);
441
+ this.refreshEnzymeGroups();
442
+ this.setState({
443
+ selectedEnzymeGroup: "My Enzymes"
444
+ });
445
+ }
446
+ }}
447
+ minimal
448
+ icon="trash"
449
+ ></AnchorButton>
450
+ </Tooltip>
451
+ </ButtonGroup>
452
+ </div>
453
+ <div className="veEnzymeDialogEnzymes">
454
+ <div
455
+ className="veEnzymeDialogSearch"
456
+ style={{ width: 250, paddingBottom: 5 }}
457
+ >
458
+ <InputGroup
459
+ round
460
+ placeholder="Search by name or # of cuts"
461
+ onChange={(e) => {
462
+ this.setState({
463
+ searchInput: e.target.value
464
+ });
465
+ }}
466
+ value={searchInput}
467
+ rightElement={
468
+ searchInput && (
469
+ <AnchorButton
470
+ icon="cross"
471
+ minimal
472
+ intent="danger"
473
+ onClick={(e) => {
474
+ this.setState({ searchInput: "" });
475
+ e.stopPropagation();
476
+ }}
477
+ ></AnchorButton>
478
+ )
479
+ }
480
+ leftIcon="search"
481
+ ></InputGroup>
482
+ </div>
483
+ <div
484
+ style={{
485
+ height: "84%",
486
+ display: "flex",
487
+ flexFlow: "column",
488
+ justifyContent: "space-between"
489
+ }}
490
+ >
491
+ <div
492
+ className="veEnzymeDialogEnzymesList"
493
+ style={{
494
+ height: "fit-parent",
495
+ overflowY: "auto",
496
+ display: "flex",
497
+ flexWrap: "wrap",
498
+ maxWidth: "100%"
499
+ }}
500
+ >
501
+ {/* <span style={{fontSize: 10}}>{fullSelectedEnzGroup.message || "Enzymes added here can be filtered for in the Cutsite Filter"} </span> */}
502
+ {enzymeList.length
503
+ ? enzymeList
504
+ : "Copy enzymes from other groups to your custom group"}
505
+ </div>
506
+ <HoverView
507
+ allEnzymesByName={this.getAllEnzymesByName()}
508
+ ></HoverView>
509
+ </div>
510
+ <div style={{ display: "flex", justifyContent: "space-between" }}>
511
+ <ButtonGroup>
512
+ <div>
513
+ <Tooltip
514
+ position="left"
515
+ content="Copy Selection To Another Group"
516
+ >
517
+ <Popover
518
+ canEscapeKeyClose
519
+ disabled={!selectedCount}
520
+ // targetClassName={"veEnzymeDialogEnzymeAddIcon"}
521
+ // targetProps={{style: {flex: "0 0 auto"}}}
522
+ // wrapperTagName="div"
523
+ position="top"
524
+ content={
525
+ <MoveToInner
526
+ {...{
527
+ clearSelection: this.clearSelection,
528
+ refreshEnzymeGroups: this.refreshEnzymeGroups,
529
+ selectedEnzymeGroup,
530
+ enzymeGroupToMoveTo,
531
+ selectedCount,
532
+ selectedEnzymesForGroup,
533
+ enzymeGroups: this.enzymeGroups,
534
+ setStateAbove: (val) => {
535
+ this.setState(val);
536
+ }
537
+ }}
538
+ ></MoveToInner>
539
+ }
540
+ target={
541
+ <AnchorButton
542
+ className="veEnzymeGroupAddEnzymesBtn"
543
+ disabled={!selectedCount}
544
+ icon="duplicate"
545
+ ></AnchorButton>
546
+ }
547
+ ></Popover>
548
+ </Tooltip>
549
+ </div>
550
+ <div>
551
+ <Tooltip
552
+ disabled={window.Cypress}
553
+ position="bottom"
554
+ content="Remove Enzymes"
555
+ >
556
+ <AnchorButton
557
+ className="veRemoveEnzymeFromGroupBtn"
558
+ onClick={async () => {
559
+ const confirm = await showConfirmationDialog({
560
+ text: `Are you sure you want to remove ${selectedCount} enzyme(s) from ${selectedEnzymeGroup}`,
561
+ intent: Intent.DANGER
562
+ });
563
+ if (confirm) {
564
+ const enzymes = flatMap(
565
+ fullSelectedEnzGroup.enzymes,
566
+ (e) =>
567
+ selectedEnzymesForGroup[e.name] ? [] : e.name
568
+ );
569
+ window.updateEnzymeGroup(
570
+ selectedEnzymeGroup,
571
+ enzymes
572
+ );
573
+ this.setState({ [selectedEnzymesKey]: {} });
574
+ this.refreshEnzymeGroups();
575
+ window.toastr.success(
576
+ `${selectedCount} enzyme(s) removed`
577
+ );
578
+ }
579
+ }}
580
+ disabled={
581
+ fullSelectedEnzGroup.protected || !selectedCount
582
+ }
583
+ icon="trash"
584
+ ></AnchorButton>
585
+ </Tooltip>
586
+ </div>
587
+
588
+ <div>
589
+ {/* <Popover
590
+ autoFocus={false}
591
+ captureDismiss
592
+ content={
593
+ <Menu>
594
+ {createMenu([
595
+ {
596
+ text: "All",
597
+ onClick: () => {
598
+ const selectedEnzymes = {};
599
+ forEach(
600
+ fullSelectedEnzGroup.enzymes,
601
+ enzyme => {
602
+ selectedEnzymes[enzyme.name] = true;
603
+ }
604
+ );
605
+
606
+ this.setState({
607
+ [selectedEnzymesKey]: selectedEnzymes
608
+ });
609
+ }
610
+ },
611
+ {
612
+ text: "Single cutters"
613
+ },
614
+ {
615
+ text: "Double cutters"
616
+ },
617
+ {
618
+ text: "Cut X times",
619
+ submenu: [
620
+ 3,
621
+ 4,
622
+ 5,
623
+ 6,
624
+ 7,
625
+ 8,
626
+ 9,
627
+ 10,
628
+ 11,
629
+ 12,
630
+ 13,
631
+ 14,
632
+ 15,
633
+ 16
634
+ ].map(n => {
635
+ return {
636
+ text: `Cut ${n} times`
637
+ };
638
+ })
639
+ },
640
+ {
641
+ text: "Cut >X times",
642
+ submenu: [
643
+ 1,
644
+ 2,
645
+ 3,
646
+ 4,
647
+ 5,
648
+ 6,
649
+ 7,
650
+ 8,
651
+ 9,
652
+ 10,
653
+ 11,
654
+ 12,
655
+ 13,
656
+ 14,
657
+ 15,
658
+ 16
659
+ ].map(n => {
660
+ return {
661
+ text: `Cut >${n} times`
662
+ };
663
+ })
664
+ },
665
+ {
666
+ text: "Cut <X times",
667
+ submenu: [
668
+ 1,
669
+ 2,
670
+ 3,
671
+ 4,
672
+ 5,
673
+ 6,
674
+ 7,
675
+ 8,
676
+ 9,
677
+ 10,
678
+ 11,
679
+ 12,
680
+ 13,
681
+ 14,
682
+ 15,
683
+ 16
684
+ ].map(n => {
685
+ return {
686
+ text: `Cut <${n} times`
687
+ };
688
+ })
689
+ },
690
+ {
691
+ text: "Blunt cutters"
692
+ },
693
+ {
694
+ text: "3' cutters"
695
+ },
696
+ {
697
+ text: "5' cutters"
698
+ },
699
+ {
700
+ text: "4 bp Recognition Site"
701
+ },
702
+ {
703
+ text: "5 bp Recognition Site"
704
+ },
705
+ {
706
+ text: "6 bp Recognition Site"
707
+ },
708
+ {
709
+ text: "Degenerate Recognition Site"
710
+ },
711
+ {
712
+ text: "Degenerate Cut"
713
+ }
714
+ ])}
715
+ </Menu>
716
+ }
717
+ position={Position.RIGHT_TOP}
718
+ >
719
+ <AnchorButton>Select...</AnchorButton>
720
+ </Popover> */}
721
+ </div>
722
+ <AnchorButton
723
+ onClick={() => {
724
+ this.setState({ [selectedEnzymesKey]: {} });
725
+ }}
726
+ disabled={!selectedCount}
727
+ >
728
+ Deselect {selectedCount}
729
+ </AnchorButton>
730
+ </ButtonGroup>
731
+ {selectedEnzymeGroup === "My Enzymes" && (
732
+ <div>
733
+ <Tooltip
734
+ disabled={window.Cypress}
735
+ position="left"
736
+ content="Create Custom Enzyme"
737
+ >
738
+ <Button
739
+ minimal
740
+ onClick={() => {
741
+ hideModal();
742
+ showDialog({
743
+ dialogType: "CreateCustomEnzyme"
744
+ });
745
+ }}
746
+ className="veEnzymeCreateCustomEnzyme"
747
+ icon="add"
748
+ ></Button>
749
+ </Tooltip>
750
+ </div>
751
+ )}
752
+ </div>
753
+ </div>
754
+ </div>
755
+ </div>
756
+ );
757
+ }
758
+ }
759
+
760
+ export default compose(
761
+ wrapDialog({ title: "Manage Enzymes" }),
762
+ withEditorProps
763
+ // reduxForm({
764
+ // form: "EnzymesDialog",
765
+ // validate: ({ id1, id2 }) => {
766
+ // const errors = {};
767
+ // if (!id1 || Array.isArray(id1)) {
768
+ // errors.id1 = "Please select a feature";
769
+ // }
770
+ // if (!id2 || Array.isArray(id2)) {
771
+ // errors.id2 = "Please select a feature";
772
+ // }
773
+ // return errors;
774
+ // }
775
+ // }),
776
+ // formValues("id1", "id2")
777
+ )(EnzymesDialog);
778
+
779
+ function getEnzymesForNames(names, allEnzymesByName) {
780
+ return names.map((n) => {
781
+ return (n && allEnzymesByName[n.toLowerCase()]) || { name: "Not Found!" };
782
+ });
783
+ }
784
+
785
+ class MoveToInner extends React.Component {
786
+ componentDidMount() {
787
+ const {
788
+ selectedEnzymeGroup,
789
+ enzymeGroupToMoveTo,
790
+ setStateAbove,
791
+ enzymeGroups
792
+ } = this.props;
793
+ const enzymeOpts = flatMap(enzymeGroups, (g) => {
794
+ if (g.protected || g.name === selectedEnzymeGroup) return [];
795
+ return {
796
+ value: g.name
797
+ };
798
+ });
799
+ if (!enzymeGroupToMoveTo && enzymeOpts.length) {
800
+ setStateAbove({ enzymeGroupToMoveTo: enzymeOpts[0].value });
801
+ }
802
+ this.setState({
803
+ enzymeOpts
804
+ });
805
+ }
806
+ state = { enzymeOpts: [] };
807
+ render() {
808
+ const {
809
+ clearSelection,
810
+ setStateAbove,
811
+ selectedCount,
812
+ enzymeGroupToMoveTo,
813
+ enzymeGroups,
814
+ refreshEnzymeGroups,
815
+ selectedEnzymesForGroup
816
+ } = this.props;
817
+ const { enzymeOpts } = this.state;
818
+ return (
819
+ <div className="veEnzymeGroupMoveEnzymePopover" style={{ padding: 10 }}>
820
+ {enzymeOpts && !enzymeOpts.length ? (
821
+ <div style={{ maxWidth: 150 }}>
822
+ No other custom enzyme groups exist. Please create a new enzyme
823
+ group to add enzymes to it.
824
+ </div>
825
+ ) : (
826
+ <div>
827
+ <h5>Copy {selectedCount} Enzyme(s) To:</h5>
828
+
829
+ <HTMLSelect
830
+ onChange={(e) => {
831
+ setStateAbove({
832
+ enzymeGroupToMoveTo: e.target.value
833
+ });
834
+ }}
835
+ value={enzymeGroupToMoveTo}
836
+ options={enzymeOpts}
837
+ ></HTMLSelect>
838
+ <AnchorButton
839
+ className={Classes.POPOVER_DISMISS}
840
+ onClick={() => {
841
+ const enzymes = uniq([
842
+ ...map(
843
+ enzymeGroups[enzymeGroupToMoveTo].enzymes,
844
+ (e) => e.name
845
+ ),
846
+ ...flatMap(selectedEnzymesForGroup, (selected, name) =>
847
+ selected ? name : []
848
+ )
849
+ ]);
850
+
851
+ window.updateEnzymeGroup(enzymeGroupToMoveTo, enzymes);
852
+ // setStateAbove({
853
+ // enzymeGroupToMoveTo: e.target.value
854
+ // });
855
+ refreshEnzymeGroups();
856
+ clearSelection();
857
+ window.toastr.success(
858
+ `${selectedCount} enzyme(s) moved to ${enzymeGroupToMoveTo}`
859
+ );
860
+ }}
861
+ intent="success"
862
+ icon="tick"
863
+ ></AnchorButton>
864
+ </div>
865
+ )}
866
+ </div>
867
+ );
868
+ }
869
+ }
870
+
871
+ const HoverView = view(({ allEnzymesByName }) => {
872
+ const { hoveredEnzyme } = easyStore;
873
+ return (
874
+ <div
875
+ className="hoveredEnzymeContainer"
876
+ style={{
877
+ overflow: "hidden",
878
+ // maxWidth: "100%",
879
+ minWidth: 0,
880
+ // width: "100%",
881
+ margin: "20px",
882
+ minHeight: 30,
883
+ maxHeight: 30,
884
+ display: "flex",
885
+ justifyContent: "space-between"
886
+ }}
887
+ >
888
+ {hoveredEnzyme}{" "}
889
+ {hoveredEnzyme && (
890
+ <EnzymeViewer
891
+ {...{
892
+ paddingEnd: "--",
893
+ paddingStart: "--",
894
+ sequence: allEnzymesByName[hoveredEnzyme.toLowerCase()].site,
895
+ reverseSnipPosition:
896
+ allEnzymesByName[hoveredEnzyme.toLowerCase()].bottomSnipOffset,
897
+ forwardSnipPosition:
898
+ allEnzymesByName[hoveredEnzyme.toLowerCase()].topSnipOffset
899
+ }}
900
+ ></EnzymeViewer>
901
+ )}
902
+ </div>
903
+ );
904
+ });