@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,554 @@
1
+ import { Button } from "@blueprintjs/core";
2
+ import draggableClassnames from "../constants/draggableClassnames";
3
+ import { some, debounce, noop } from "lodash";
4
+ import prepareRowData from "../utils/prepareRowData";
5
+ import React from "react";
6
+ import Draggable from "react-draggable";
7
+ import RowItem from "../RowItem";
8
+ import ReactList from "@teselagen/react-list";
9
+ import withEditorInteractions from "../withEditorInteractions";
10
+ import estimateRowHeight, { rowHeights } from "./estimateRowHeight";
11
+ import {
12
+ defaultContainerWidth,
13
+ defaultMarginWidth,
14
+ defaultCharWidth
15
+ } from "../constants/rowviewContants";
16
+ import getBpsPerRow from "../withEditorInteractions/getBpsPerRow";
17
+ import "./style.css";
18
+ import { getClientX, getClientY, getEmptyText } from "../utils/editorUtils";
19
+ import isMobile from "is-mobile";
20
+ import classnames from "classnames";
21
+ import {
22
+ editorDragged,
23
+ editorDragStarted,
24
+ editorDragStopped
25
+ } from "../withEditorInteractions/clickAndDragUtils";
26
+ import { defaultMemoize } from "reselect";
27
+ import { connect } from "react-redux";
28
+
29
+
30
+ const rowJumpButtonStyle = {
31
+ height: rowHeights.rowJumpButtons.height
32
+ };
33
+
34
+ const bounds = { top: 0, left: 0, right: 0, bottom: 0 };
35
+ class _RowView extends React.Component {
36
+ static defaultProps = {
37
+ sequenceData: { sequence: "" },
38
+ selectionLayer: {},
39
+ // bpToJumpTo:0,
40
+ editorClicked: noop,
41
+ backgroundRightClicked: noop,
42
+ // onScroll: noop,
43
+ width: defaultContainerWidth,
44
+ marginWidth: defaultMarginWidth,
45
+ height: 400,
46
+ charWidth: defaultCharWidth,
47
+ RowItemProps: {}
48
+ };
49
+
50
+ //this function gives a fairly rough height estimate for the rows so that the ReactList can give a good guess of how much space to leave for scrolling and where to jump to in the sequence
51
+ estimateRowHeight = (index, cache) => {
52
+ const { annotationVisibility, annotationLabelVisibility, sequenceData } =
53
+ this.props;
54
+ return estimateRowHeight({
55
+ index,
56
+ cache,
57
+ chromatogramData: sequenceData.chromatogramData,
58
+ showJumpButtons: this.showJumpButtons,
59
+ row: this.rowData[index],
60
+ rowCount: this.rowData.length,
61
+ annotationVisibility,
62
+ annotationLabelVisibility
63
+ });
64
+ };
65
+ getNearestCursorPositionToMouseEvent = (rowData, event, callback) => {
66
+ const { charWidth = defaultCharWidth, sequenceData } = this.props;
67
+ const sequenceLength = sequenceData.noSequence
68
+ ? sequenceData.size
69
+ : sequenceData.sequence.length;
70
+ let rowNotFound = true;
71
+ const visibleRowsContainer =
72
+ this.InfiniteScroller && this.InfiniteScroller.items;
73
+ //loop through all the rendered rows to see if the click event lands in one of them
74
+ let nearestCaretPos = 0;
75
+
76
+ const selectionStartGrabbed = event.target.classList.contains(
77
+ draggableClassnames.selectionStart
78
+ );
79
+ const selectionEndGrabbed = event.target.classList.contains(
80
+ draggableClassnames.selectionEnd
81
+ );
82
+ some(visibleRowsContainer.childNodes, function (rowDomNode) {
83
+ const boundingRowRect = rowDomNode.getBoundingClientRect();
84
+ if (
85
+ getClientY(event) > boundingRowRect.top &&
86
+ getClientY(event) < boundingRowRect.top + boundingRowRect.height
87
+ ) {
88
+ //then the click is falls within this row
89
+ rowNotFound = false;
90
+ const row = rowData[Number(rowDomNode.getAttribute("data-row-number"))];
91
+ if (getClientX(event) - boundingRowRect.left < 0) {
92
+ nearestCaretPos = row.start;
93
+ } else {
94
+ const clickXPositionRelativeToRowContainer =
95
+ getClientX(event) - boundingRowRect.left;
96
+ const numberOfBPsInFromRowStart = Math.floor(
97
+ (clickXPositionRelativeToRowContainer + charWidth / 2) / charWidth
98
+ );
99
+ nearestCaretPos = numberOfBPsInFromRowStart + row.start;
100
+ if (nearestCaretPos > row.end + 1) {
101
+ nearestCaretPos = row.end + 1;
102
+ }
103
+ }
104
+ return true; //break the loop early because we found the row the click event landed in
105
+ }
106
+ });
107
+ if (rowNotFound) {
108
+ const { top, bottom } = visibleRowsContainer.getBoundingClientRect();
109
+ const numbers = [top, bottom];
110
+ const target = getClientY(event);
111
+ const topOrBottom = numbers
112
+ .map(function (value, index) {
113
+ return [Math.abs(value - target), index];
114
+ })
115
+ .sort()
116
+ .map(function (value) {
117
+ return numbers[value[1]];
118
+ })[0];
119
+ let rowDomNode;
120
+ if (topOrBottom === top) {
121
+ rowDomNode = visibleRowsContainer.childNodes[0];
122
+ } else {
123
+ rowDomNode =
124
+ visibleRowsContainer.childNodes[
125
+ visibleRowsContainer.childNodes.length - 1
126
+ ];
127
+ }
128
+ if (rowDomNode) {
129
+ const row = rowData[Number(rowDomNode.getAttribute("data-row-number"))];
130
+ //return the last bp index in the rendered rows
131
+ nearestCaretPos = row.end;
132
+ } else {
133
+ nearestCaretPos = 0;
134
+ }
135
+ }
136
+ if (this.props.sequenceData.isProtein) {
137
+ nearestCaretPos = Math.round(nearestCaretPos / 3) * 3;
138
+ }
139
+ if (sequenceLength === 0) nearestCaretPos = 0;
140
+ const {
141
+ updateSelectionOrCaret,
142
+ caretPosition,
143
+ selectionLayer,
144
+ caretPositionUpdate,
145
+ selectionLayerUpdate
146
+ } = this.props;
147
+ callback({
148
+ updateSelectionOrCaret,
149
+ caretPosition,
150
+ selectionLayer,
151
+ caretPositionUpdate,
152
+ selectionLayerUpdate,
153
+ sequenceLength,
154
+ doNotWrapOrigin: !(
155
+ this.props.sequenceData && this.props.sequenceData.circular
156
+ ),
157
+ selectionStartGrabbed,
158
+ selectionEndGrabbed,
159
+ event,
160
+ className: event.target.className,
161
+ shiftHeld: event.shiftKey,
162
+ nearestCaretPos
163
+ });
164
+ };
165
+
166
+ UNSAFE_componentWillReceiveProps(props) {
167
+ //we haven't yet called this function yet, so to make sure it jumps to the selected bps we just set a variable on the class
168
+ this.updateScrollPosition(
169
+ this.calledUpdateScrollOnce ? this.props : {},
170
+ props
171
+ );
172
+ }
173
+ updateScrollPosition = (oldProps, newProps) => {
174
+ this.cache = {};
175
+ if (this.dragging === true) {
176
+ return;
177
+ }
178
+ const {
179
+ caretPosition = -1,
180
+ selectionLayer = {},
181
+ matchedSearchLayer = {}
182
+ } = newProps;
183
+ const {
184
+ caretPosition: caretPositionOld = -1,
185
+ selectionLayer: selectionLayerOld = {},
186
+ matchedSearchLayer: matchedSearchLayerOld = {}
187
+ } = oldProps;
188
+
189
+ const bpsPerRow = getBpsPerRow(newProps);
190
+ //UPDATE THE ROW VIEW'S POSITION BASED ON CARET OR SELECTION CHANGES
191
+ // let previousBp;
192
+ let scrollToBp = -1;
193
+ if (
194
+ matchedSearchLayer.start > -1 &&
195
+ ((matchedSearchLayer.forceUpdate &&
196
+ matchedSearchLayer.forceUpdate !== matchedSearchLayerOld.forceUpdate) ||
197
+ matchedSearchLayer.start !== matchedSearchLayerOld.start)
198
+ ) {
199
+ // previousBp = matchedSearchLayerOld.start;
200
+ scrollToBp = matchedSearchLayer.start;
201
+ } else if (
202
+ matchedSearchLayer.end > -1 &&
203
+ ((matchedSearchLayer.forceUpdate &&
204
+ matchedSearchLayer.forceUpdate !== matchedSearchLayerOld.forceUpdate) ||
205
+ matchedSearchLayer.end !== matchedSearchLayerOld.end)
206
+ ) {
207
+ // previousBp = selectionLayerOld.end;
208
+ scrollToBp = matchedSearchLayer.end;
209
+ } else if (caretPosition > -1 && caretPosition !== caretPositionOld) {
210
+ // previousBp = caretPositionOld;
211
+ scrollToBp = caretPosition;
212
+ } else if (
213
+ selectionLayer.start > -1 &&
214
+ ((selectionLayer.forceUpdate &&
215
+ selectionLayer.forceUpdate !== selectionLayerOld.forceUpdate &&
216
+ selectionLayer.forceUpdate !== "end") ||
217
+ (selectionLayer.start !== selectionLayerOld.start &&
218
+ !selectionLayer.isFromRowView))
219
+ ) {
220
+ // previousBp = selectionLayerOld.start;
221
+ scrollToBp = selectionLayer.start;
222
+ } else if (
223
+ selectionLayer.end > -1 &&
224
+ ((selectionLayer.forceUpdate &&
225
+ selectionLayer.forceUpdate !== selectionLayerOld.forceUpdate &&
226
+ selectionLayer.forceUpdate !== "start") ||
227
+ (selectionLayer.end !== selectionLayerOld.end &&
228
+ !selectionLayer.isFromRowView))
229
+ ) {
230
+ // previousBp = selectionLayerOld.end;
231
+ scrollToBp = selectionLayer.end;
232
+ }
233
+ if (
234
+ scrollToBp > -1 &&
235
+ this.InfiniteScroller &&
236
+ this.InfiniteScroller.scrollTo
237
+ ) {
238
+ this.calledUpdateScrollOnce = true;
239
+ const rowToScrollTo = Math.floor(scrollToBp / bpsPerRow);
240
+ const [start, end] = this.InfiniteScroller.getVisibleRange();
241
+ // const jumpToBottomOfRow = scrollToBp > previousBp;
242
+ if (rowToScrollTo < start || rowToScrollTo > end) {
243
+ //wrap this in a set timeout to give onDoubleClick enough time to fire before jumping the rowview around
244
+ setTimeout(() => {
245
+ this.InfiniteScroller &&
246
+ this.InfiniteScroller.scrollTo(rowToScrollTo);
247
+ }, 0);
248
+ clearInterval(this.jumpIntervalId); //tnr this was triggering a nasty error in cypress related to sinon -
249
+ //this will try to run the following logic at most 10 times with a 100ms pause between each
250
+ this.jumpIntervalId = setIntervalX(
251
+ () => {
252
+ if (!this.InfiniteScroller) return; //this might be undefined if we've already unmounted
253
+ const [el] = this.InfiniteScroller.items.querySelectorAll(
254
+ `[data-row-number="${rowToScrollTo}"]`
255
+ );
256
+ if (!el) {
257
+ //sometimes the el isn't on the page even after the jump because of drawing issues, so we'll try the scroll one more time
258
+ this.InfiniteScroller &&
259
+ this.InfiniteScroller.scrollTo(rowToScrollTo);
260
+ return;
261
+ } else {
262
+ el.scrollIntoView &&
263
+ el.scrollIntoView({
264
+ behavior: "auto",
265
+ block: "nearest",
266
+ inline: "nearest"
267
+ });
268
+ try {
269
+ //djr I think there is some double clearing going on here causing cypress to fail so now its in a try block
270
+ clearInterval(this.jumpIntervalId);
271
+ } catch {
272
+ console.error();
273
+ }
274
+ }
275
+ //tnr: we can't use the following because it messes up the scroll of the Reflex panels
276
+ //causing the tabs to not be shown
277
+ // el.scrollIntoView && el.scrollIntoView();
278
+ },
279
+ 100,
280
+ 10 //tnr: we could run this more than 5 times.. doesn't really matter
281
+ );
282
+ }
283
+ }
284
+ };
285
+
286
+ cache = {};
287
+
288
+ renderItem = (index) => {
289
+ // if (this.cache[index]) return this.cache[index];
290
+ const {
291
+ //currently found in props
292
+ sequenceData,
293
+ // bpToJumpTo,
294
+ editorClicked,
295
+ caretPosition,
296
+ backgroundRightClicked,
297
+ // onScroll,
298
+ width,
299
+ marginWidth,
300
+ height,
301
+ truncateLabelsThatDoNotFit,
302
+ RowItemProps,
303
+ ...rest
304
+ } = this.props;
305
+
306
+ let rowTopComp;
307
+ let rowBottomComp;
308
+ const rowData = this.rowData;
309
+ const bpsPerRow = this.bpsPerRow;
310
+
311
+ this.showJumpButtons = rowData.length > 15;
312
+ if (this.showJumpButtons) {
313
+ if (index === 0) {
314
+ rowTopComp = (
315
+ <div style={rowJumpButtonStyle}>
316
+ <Button
317
+ style={{ fontStyle: "italic" }}
318
+ intent="primary"
319
+ icon="arrow-down"
320
+ minimal
321
+ data-test="jumpToEndButton"
322
+ onClick={(e) => {
323
+ e.stopPropagation();
324
+ this.InfiniteScroller &&
325
+ this.InfiniteScroller.scrollTo(rowData.length);
326
+ }}
327
+ >
328
+ Jump to end
329
+ </Button>
330
+ </div>
331
+ );
332
+ } else if (index === rowData.length - 1) {
333
+ rowBottomComp = (
334
+ <div style={rowJumpButtonStyle}>
335
+ <Button
336
+ style={{ fontStyle: "italic" }}
337
+ intent="primary"
338
+ icon="arrow-up"
339
+ minimal
340
+ data-test="jumpToStartButton"
341
+ onClick={(e) => {
342
+ e.stopPropagation();
343
+ this.InfiniteScroller && this.InfiniteScroller.scrollTo(0);
344
+ }}
345
+ >
346
+ Jump to start
347
+ </Button>
348
+ </div>
349
+ );
350
+ }
351
+ }
352
+
353
+ if (rowData[index]) {
354
+ const rowItem = (
355
+ <div data-row-number={index} key={index}>
356
+ <div className="veRowItemSpacer" />
357
+
358
+ <RowItem
359
+ {...{
360
+ ...rest,
361
+ rowTopComp,
362
+ truncateLabelsThatDoNotFit,
363
+ rowBottomComp,
364
+ scalePct: this.state?.scalePct,
365
+ setScalePct: (scalePct) => {
366
+ this.setState({ scalePct });
367
+ },
368
+ isRowView: true,
369
+ isProtein: sequenceData.isProtein,
370
+ chromatogramData: sequenceData.chromatogramData,
371
+ sequenceLength: sequenceData.sequence.length,
372
+ bpsPerRow,
373
+ caretPosition,
374
+ emptyText: getEmptyText({ sequenceData, caretPosition }),
375
+ fullSequence: sequenceData.sequence,
376
+ ...RowItemProps
377
+ }}
378
+ row={rowData[index]}
379
+ />
380
+ {index === rowData.length - 1 ? (
381
+ <div className="veRowItemSpacer" />
382
+ ) : null}
383
+ </div>
384
+ );
385
+ // this.cache[index] = rowItem;
386
+ return rowItem;
387
+ } else {
388
+ return null;
389
+ }
390
+ };
391
+ onDrag = (event) => {
392
+ if (isMobile({ tablet: true })) {
393
+ if (
394
+ //only allow dragging on mobile if the user is grabbing the cursor
395
+ !some(draggableClassnames, (cn) => {
396
+ if (event.target.classList.contains(cn)) {
397
+ return true;
398
+ }
399
+ })
400
+ ) {
401
+ return;
402
+ }
403
+ }
404
+
405
+ this.dragging = true;
406
+ const rowData = this.rowData;
407
+ this.getNearestCursorPositionToMouseEvent(rowData, event, editorDragged);
408
+ };
409
+ onStart = (event) => {
410
+ this.dragging = true;
411
+ const rowData = this.rowData;
412
+ this.getNearestCursorPositionToMouseEvent(
413
+ rowData,
414
+ event,
415
+ editorDragStarted
416
+ );
417
+ };
418
+
419
+ onStop = () => {
420
+ this.dragging = false;
421
+ editorDragStopped();
422
+ };
423
+
424
+ getRef = (ref) => (this.node = ref);
425
+
426
+ onContextMenu = (event) => {
427
+ this.getNearestCursorPositionToMouseEvent(
428
+ this.rowData,
429
+ event,
430
+ this.props.backgroundRightClicked
431
+ );
432
+ };
433
+ onClick = (event) => {
434
+ this.getNearestCursorPositionToMouseEvent(
435
+ this.rowData,
436
+ event,
437
+ this.props.editorClicked
438
+ );
439
+ };
440
+
441
+ getReactListRef = (c) => {
442
+ this.InfiniteScroller = c;
443
+ !this.calledUpdateScrollOnce && this.updateScrollPosition({}, this.props); //trigger the scroll here as well because now we actually have the infinite scroller component accessible
444
+ };
445
+
446
+ render() {
447
+ let {
448
+ //currently found in props
449
+ width,
450
+ marginWidth,
451
+ height,
452
+ className,
453
+ bpsPerRow,
454
+ rowData
455
+ } = this.props;
456
+ if (width === "100%") {
457
+ //we can't render an actual 100% width row view (we need a pixel measurement but we get passed width=100% by react-measure)
458
+ return <div style={{ width, height: height || 300 }} />;
459
+ }
460
+ if (marginWidth < defaultMarginWidth) {
461
+ marginWidth = defaultMarginWidth;
462
+ }
463
+ const containerWidthMinusMargin = width - marginWidth;
464
+
465
+ this.bpsPerRow = bpsPerRow;
466
+
467
+ this.rowData = rowData;
468
+
469
+ // const shouldClear = this.shouldClearCache();
470
+ return (
471
+ <Draggable
472
+ bounds={bounds}
473
+ onDrag={this.onDrag}
474
+ onStart={this.onStart}
475
+ onStop={this.onStop}
476
+ >
477
+ <div
478
+ ref={this.getRef}
479
+ className={classnames("veRowView", className)}
480
+ style={{
481
+ overflowY: "auto",
482
+ overflowX: "visible",
483
+ height: height || 300,
484
+ width: containerWidthMinusMargin + marginWidth,
485
+ paddingLeft: marginWidth / 2,
486
+ paddingRight: marginWidth / 2,
487
+ ...(isMobile && { touchAction: "inherit" })
488
+ }}
489
+ onContextMenu={this.onContextMenu}
490
+ onScroll={onScroll}
491
+ onClick={this.onClick}
492
+ >
493
+ <ReactList
494
+ clearCache
495
+ ref={this.getReactListRef}
496
+ itemRenderer={this.renderItem}
497
+ length={rowData.length}
498
+ itemSizeEstimator={this.estimateRowHeight}
499
+ type="variable"
500
+ />
501
+ </div>
502
+ </Draggable>
503
+ );
504
+ }
505
+ }
506
+ export const RowView = connect((state, ownProps) => {
507
+ const bpsPerRow = getBpsPerRow(ownProps);
508
+ //the width we pass to the rowitem needs to be the exact width of the bps so we need to trim off any extra space:
509
+ const rowData = getRowData(ownProps.sequenceData, bpsPerRow);
510
+ return {
511
+ bpsPerRow,
512
+ rowData
513
+ };
514
+ })(_RowView);
515
+
516
+ export default withEditorInteractions(RowView);
517
+
518
+ function onScroll() {
519
+ window.__veScrolling = true;
520
+ setTimeout(endScroll);
521
+ }
522
+
523
+ const endScroll = debounce(() => {
524
+ window.__veScrolling = false;
525
+ }, 100);
526
+
527
+ function setIntervalX(callback, delay, repetitions) {
528
+ let x = 0;
529
+ const intervalID = window.setInterval(function () {
530
+ callback();
531
+
532
+ if (++x === repetitions) {
533
+ try {
534
+ //djr I think there is some double clearing going on here so I put it in a try block
535
+ window.clearInterval(intervalID);
536
+ } catch {
537
+ console.error();
538
+ }
539
+ }
540
+ }, delay);
541
+ return intervalID;
542
+ }
543
+
544
+ const getRowData = defaultMemoize((sequenceData, bpsPerRow) => {
545
+ return prepareRowData(
546
+ {
547
+ ...sequenceData,
548
+ primers: sequenceData.filteredPrimers || sequenceData.primers,
549
+ features: sequenceData.filteredFeatures || sequenceData.features,
550
+ parts: sequenceData.filteredParts || sequenceData.parts
551
+ },
552
+ bpsPerRow
553
+ );
554
+ });
@@ -0,0 +1,12 @@
1
+ .veRowItemSpacer {
2
+ height: 10px;
3
+ }
4
+
5
+ .veRowItem svg:not(:root) {
6
+ overflow: visible;
7
+ }
8
+ .veEmptySeqText {
9
+ margin-left: 13px;
10
+ font-size: 20px;
11
+ color: gray;
12
+ }