@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,1005 @@
1
+ import { debounce, find, get, some, isArray } from "lodash";
2
+ // import sizeMe from "react-sizeme";
3
+ import { showContextMenu } from "@teselagen/ui";
4
+ import {
5
+ Button,
6
+ ButtonGroup,
7
+ Intent,
8
+ Icon,
9
+ Tooltip,
10
+ ContextMenu
11
+ } from "@blueprintjs/core";
12
+ import PropTypes from "prop-types";
13
+
14
+ import VersionHistoryView from "../VersionHistoryView";
15
+ import { importSequenceFromFile } from "../withEditorProps";
16
+ import getAdditionalEnzymesSelector from "../selectors/getAdditionalEnzymesSelector";
17
+ import { showAddOrEditAnnotationDialog } from "../GlobalDialogUtils";
18
+
19
+ import "../Reflex/reflex-styles.css";
20
+
21
+ import React from "react";
22
+ import AlignmentView from "../AlignmentView";
23
+ // import * as customIcons from "@teselagen/ui";
24
+ // import { Button } from "@blueprintjs/core";
25
+ import { compose } from "redux";
26
+ //tnr: this can be removed once https://github.com/leefsmp/Re-Flex/pull/30 is merged and deployed
27
+ /* eslint-disable */
28
+ import { connectToEditor, handleSave } from "../withEditorProps";
29
+ import { withHandlers } from "recompose";
30
+
31
+ import CommandHotkeyHandler from "./CommandHotkeyHandler";
32
+
33
+ import { ReflexContainer, ReflexSplitter, ReflexElement } from "../Reflex";
34
+ /* eslint-enable */
35
+
36
+ import { flatMap, map, filter, pick, camelCase } from "lodash";
37
+
38
+ import { ToolBar } from "../ToolBar";
39
+ import CircularView from "../CircularView";
40
+ import LinearView from "../LinearView";
41
+ import RowView from "../RowView";
42
+ import StatusBar from "../StatusBar";
43
+ import DropHandler from "./DropHandler";
44
+ import Properties from "../helperComponents/PropertiesDialog";
45
+ import "./style.css";
46
+ import { DragDropContext, Droppable, Draggable } from "@hello-pangea/dnd";
47
+ import DigestTool from "../DigestTool/DigestTool";
48
+ import { insertItem, removeItem } from "../utils/arrayUtils";
49
+ import Mismatches from "../AlignmentView/Mismatches";
50
+ import SimpleCircularOrLinearView from "../SimpleCircularOrLinearView";
51
+ import { userDefinedHandlersAndOpts } from "./userDefinedHandlersAndOpts";
52
+ import { GlobalDialog } from "../GlobalDialog";
53
+ import isMobile from "is-mobile";
54
+ import { getClientX, getClientY } from "../utils/editorUtils";
55
+ import PCRTool from "../PCRTool/PCRTool";
56
+ import classNames from "classnames";
57
+
58
+ // if (process.env.NODE_ENV !== 'production') {
59
+ // const {whyDidYouUpdate} = require('why-did-you-update');
60
+ // whyDidYouUpdate(React);
61
+ // }
62
+
63
+ const _panelMap = {
64
+ circular: {
65
+ comp: CircularView,
66
+ panelSpecificProps: ["extraAnnotationProps"]
67
+ },
68
+ sequence: {
69
+ comp: RowView,
70
+ panelSpecificProps: ["extraAnnotationProps"]
71
+ },
72
+ rail: { comp: LinearView, panelSpecificProps: ["extraAnnotationProps"] },
73
+ // alignmentTool: AlignmentTool,
74
+ alignment: AlignmentView,
75
+ digestTool: DigestTool,
76
+ pcrTool: PCRTool,
77
+ properties: {
78
+ comp: Properties,
79
+ panelSpecificPropsToSpread: ["PropertiesProps"]
80
+ },
81
+ mismatches: Mismatches
82
+ };
83
+
84
+ // fake data generator
85
+ // a little function to help us with reordering the result
86
+ const reorder = (list, startIndex, endIndex) => {
87
+ const result = Array.from(list);
88
+ const [removed] = result.splice(startIndex, 1);
89
+ result.splice(endIndex, 0, removed);
90
+
91
+ return result;
92
+ };
93
+ const tabHeight = 34;
94
+
95
+ const getSplitScreenListStyle = (isDraggingOver, isDragging) => {
96
+ return {
97
+ position: "absolute",
98
+ // top: "-20px",
99
+ height: "100%",
100
+ // background: "lightgreen",
101
+ width: "50%",
102
+ textOverflow: "ellipsis",
103
+ whiteSpace: "nowrap",
104
+ wordWrap: "normal",
105
+ opacity: 0,
106
+ ...(isDragging && { opacity: 0.7, zIndex: 10000, background: "lightgrey" }),
107
+ ...(isDraggingOver && { background: "lightblue" }),
108
+ left: "50%"
109
+ };
110
+ };
111
+
112
+ export class Editor extends React.Component {
113
+ state = {
114
+ rotationRadians: 0,
115
+ zoomLevel: 1,
116
+ isHotkeyDialogOpen: false,
117
+ tabDragging: false,
118
+ previewModeFullscreen: false
119
+ };
120
+
121
+ getExtraPanel = (/*panelOptions */) => {
122
+ return [];
123
+ };
124
+
125
+ getChildContext() {
126
+ //tnrtodo this will need to be updated once blueprint uses the react 16 api
127
+ return { blueprintPortalClassName: "ove-portal" };
128
+ }
129
+ componentDidUpdate(prevProps) {
130
+ if (
131
+ this.props.initialAnnotationToEdit &&
132
+ !this.hasShownInitialAnnotationToEditDialog &&
133
+ !this.inPreviewMode
134
+ ) {
135
+ ["part", "feature", "primer"].forEach((type) => {
136
+ if (this.props.initialAnnotationToEdit.startsWith(type)) {
137
+ const annid = this.props.initialAnnotationToEdit.replace(
138
+ type + "-",
139
+ ""
140
+ );
141
+ const anns = this.props.sequenceData[type + "s"];
142
+ const annotation = find(anns, (a) => a.id === annid);
143
+ if (annotation) {
144
+ showAddOrEditAnnotationDialog({ type, annotation });
145
+ this.hasShownInitialAnnotationToEditDialog = true;
146
+ }
147
+ }
148
+ });
149
+ }
150
+ //autosave if necessary!
151
+ if (
152
+ this.props.shouldAutosave &&
153
+ prevProps.sequenceData &&
154
+ prevProps.sequenceData.stateTrackingId &&
155
+ this.props.sequenceData.stateTrackingId !==
156
+ prevProps.sequenceData.stateTrackingId
157
+ ) {
158
+ this.props.handleSave();
159
+ }
160
+ }
161
+ updateDimensions = debounce(() => {
162
+ // (this.hasFullscreenPanel || this.fitHeight) &&
163
+ this.setState({ randomRerenderTrigger: Math.random() });
164
+ }, 100);
165
+
166
+ componentDidMount() {
167
+ if (isMobile()) {
168
+ let firstActivePanelId;
169
+ some(this.getPanelsToShow()[0], (panel) => {
170
+ if (panel.active) {
171
+ firstActivePanelId = panel.id;
172
+ return true;
173
+ }
174
+ });
175
+ this.props.collapseSplitScreen(firstActivePanelId);
176
+ }
177
+ if (this.props.sequenceData?.id) {
178
+ let hasSetSpecificFilter;
179
+ try {
180
+ try {
181
+ const cutsiteFilterDefaultForThisSpecificSeq = JSON.parse(
182
+ localStorage.getItem(
183
+ `tgInitialCutsiteFilter-${this.props.sequenceData?.id}`
184
+ )
185
+ );
186
+ if (
187
+ cutsiteFilterDefaultForThisSpecificSeq &&
188
+ isArray(cutsiteFilterDefaultForThisSpecificSeq)
189
+ ) {
190
+ hasSetSpecificFilter = true;
191
+ this.props.filteredRestrictionEnzymesUpdate(
192
+ cutsiteFilterDefaultForThisSpecificSeq
193
+ );
194
+ }
195
+ // eslint-disable-next-line no-empty
196
+ } catch (e) {}
197
+ const cutsiteFilterDefaultForAllSeqs = JSON.parse(
198
+ localStorage.getItem(`tgInitialCutsiteFilter`)
199
+ );
200
+
201
+ if (
202
+ !hasSetSpecificFilter &&
203
+ cutsiteFilterDefaultForAllSeqs &&
204
+ isArray(cutsiteFilterDefaultForAllSeqs)
205
+ ) {
206
+ this.props.filteredRestrictionEnzymesUpdate(
207
+ cutsiteFilterDefaultForAllSeqs
208
+ );
209
+ }
210
+ // eslint-disable-next-line no-empty
211
+ } catch (e) {}
212
+ }
213
+ window.addEventListener("resize", this.updateDimensions);
214
+ this.forceUpdate(); //we need to do this to get an accurate height measurement on first render
215
+ }
216
+ componentWillUnmount() {
217
+ window.removeEventListener("resize", this.updateDimensions);
218
+ }
219
+
220
+ onTabDragStart = () => {
221
+ this.setState({ tabDragging: true });
222
+ };
223
+
224
+ onTabDragEnd = (result) => {
225
+ this.setState({ tabDragging: false });
226
+ const { panelsShownUpdate, panelsShown } = this.props;
227
+ // dropped outside the list
228
+ if (!result.destination) {
229
+ return;
230
+ }
231
+
232
+ let newPanelsShown;
233
+ if (result.destination.droppableId !== result.source.droppableId) {
234
+ //we're moving a tab from one group to another group
235
+ const secondPanel = panelsShown.length === 1 ? [[]] : [];
236
+ const panelsToMapOver = [...panelsShown, ...secondPanel];
237
+ newPanelsShown = map(panelsToMapOver, (panelGroup, groupIndex) => {
238
+ const panelToMove =
239
+ panelsShown[
240
+ Number(result.source.droppableId.replace("droppable-id-", ""))
241
+ ][result.source.index];
242
+ if (
243
+ Number(groupIndex) ===
244
+ Number(result.destination.droppableId.replace("droppable-id-", ""))
245
+ ) {
246
+ //we're adding to this group
247
+ return insertItem(
248
+ panelGroup.map((tabPanel) => ({ ...tabPanel, active: false })),
249
+ { ...panelToMove, active: true },
250
+ result.destination.index
251
+ );
252
+ } else if (
253
+ Number(groupIndex) ===
254
+ Number(result.source.droppableId.replace("droppable-id-", ""))
255
+ ) {
256
+ // we're removing from this group
257
+ return removeItem(panelGroup, result.source.index).map(
258
+ (tabPanel, index) => {
259
+ return {
260
+ ...tabPanel,
261
+ ...(panelToMove.active && index === 0 && { active: true })
262
+ };
263
+ }
264
+ );
265
+ } else {
266
+ return panelGroup;
267
+ }
268
+ });
269
+ } else {
270
+ //we're moving tabs within the same group
271
+ newPanelsShown = map(panelsShown, (panelGroup, groupIndex) => {
272
+ if (
273
+ Number(groupIndex) ===
274
+ Number(result.destination.droppableId.replace("droppable-id-", ""))
275
+ ) {
276
+ //we'removing a tab around in this group
277
+ return reorder(
278
+ panelGroup.map((tabPanel, i) => {
279
+ return {
280
+ ...tabPanel,
281
+ active: result.source.index === i
282
+ };
283
+ }),
284
+ result.source.index,
285
+ result.destination.index
286
+ );
287
+ }
288
+ return panelGroup;
289
+ });
290
+ }
291
+ filter(newPanelsShown, (panelGroup) => {
292
+ return panelGroup.length;
293
+ });
294
+ panelsShownUpdate(newPanelsShown);
295
+ };
296
+
297
+ getPanelsToShow = () => {
298
+ const { panelsShown } = this.props;
299
+ if (isMobile()) return [flatMap(panelsShown)];
300
+ return map(panelsShown);
301
+ };
302
+
303
+ onPreviewModeButtonContextMenu = (event) => {
304
+ const { previewModeButtonMenu } = this.props;
305
+ event.preventDefault();
306
+ if (previewModeButtonMenu) {
307
+ ContextMenu.show(previewModeButtonMenu, {
308
+ left: getClientX(event),
309
+ top: getClientY(event)
310
+ });
311
+ }
312
+ };
313
+
314
+ closeHotkeyDialog = () => {
315
+ this.setState({ isHotkeyDialogOpen: false });
316
+ };
317
+ openHotkeyDialog = () => {
318
+ this.setState({ isHotkeyDialogOpen: true });
319
+ };
320
+
321
+ togglePreviewFullscreen = () => {
322
+ const {
323
+ togglePreviewFullscreen,
324
+ onPreviewModeFullscreenClose,
325
+ previewModeFullscreen: controlledPreviewModeFullscreen
326
+ } = this.props;
327
+ if (togglePreviewFullscreen) togglePreviewFullscreen();
328
+ const previewModeFullscreen = this.state.previewModeFullscreen;
329
+ if (
330
+ controlledPreviewModeFullscreen === undefined
331
+ ? previewModeFullscreen
332
+ : controlledPreviewModeFullscreen
333
+ ) {
334
+ onPreviewModeFullscreenClose && onPreviewModeFullscreenClose();
335
+ }
336
+ this.setState({
337
+ previewModeFullscreen: !previewModeFullscreen
338
+ });
339
+ };
340
+
341
+ render() {
342
+ const { previewModeFullscreen: uncontrolledPreviewModeFullscreen } =
343
+ this.state;
344
+ const {
345
+ ToolBarProps = {},
346
+ StatusBarProps = {},
347
+ extraRightSidePanel,
348
+ editorName,
349
+ height: _height,
350
+ showCircularity,
351
+ hideSingleImport,
352
+ minHeight = 400,
353
+ showMenuBar,
354
+ annotationsToSupport,
355
+ withRotateCircularView = true,
356
+ withZoomCircularView = true,
357
+ withZoomLinearView = true,
358
+ displayMenuBarAboveTools = true,
359
+ updateSequenceData,
360
+ readOnly,
361
+ setPanelAsActive,
362
+ style = {},
363
+ maxAnnotationsToDisplay,
364
+ togglePanelFullScreen,
365
+ collapseSplitScreen,
366
+ expandTabToSplitScreen,
367
+ closePanel,
368
+ onSave,
369
+ hideStatusBar,
370
+ caretPositionUpdate,
371
+ getVersionList,
372
+ getSequenceAtVersion,
373
+ selectionLayer,
374
+ VersionHistoryViewProps,
375
+ sequenceData = {},
376
+ fullScreenOffsets,
377
+ withPreviewMode,
378
+ isFullscreen,
379
+ hoveredId,
380
+ handleFullscreenClose,
381
+ onlyShowLabelsThatDoNotFit = true,
382
+ previewModeFullscreen: controlledPreviewModeFullscreen,
383
+ previewModeButtonMenu,
384
+ allowPanelTabDraggable = true
385
+ } = this.props;
386
+ if (
387
+ !this.props.noVersionHistory &&
388
+ this.props.versionHistory &&
389
+ this.props.versionHistory.viewVersionHistory
390
+ ) {
391
+ return (
392
+ <VersionHistoryView
393
+ {...{
394
+ onSave, //we need to pass this user defined handler
395
+ updateSequenceData,
396
+ caretPositionUpdate,
397
+ editorName,
398
+ sequenceData,
399
+ getVersionList,
400
+ getSequenceAtVersion,
401
+ ...VersionHistoryViewProps
402
+ }}
403
+ />
404
+ );
405
+ }
406
+ const previewModeFullscreen = !!(
407
+ (controlledPreviewModeFullscreen === undefined
408
+ ? uncontrolledPreviewModeFullscreen
409
+ : controlledPreviewModeFullscreen) || isFullscreen
410
+ );
411
+ const editorNode =
412
+ document.querySelector(".veEditor") ||
413
+ document.querySelector(".preview-mode-container");
414
+
415
+ let height = Math.max(
416
+ minHeight,
417
+ (editorNode &&
418
+ editorNode.parentNode &&
419
+ editorNode.parentNode.clientHeight) ||
420
+ 0
421
+ );
422
+
423
+ if (_height) height = Math.max(minHeight, _height);
424
+
425
+ let editorDimensions = {
426
+ height,
427
+ dimensions: {
428
+ height
429
+ }
430
+ };
431
+ try {
432
+ //tnr: fixes https://github.com/TeselaGen/openVectorEditor/issues/689
433
+ if (previewModeFullscreen) {
434
+ window.document.body.classList.add("tg-no-scroll-body");
435
+ } else {
436
+ window.document.body.classList.remove("tg-no-scroll-body");
437
+ }
438
+ } catch (e) {
439
+ console.warn(`Error 3839458:`, e);
440
+ }
441
+
442
+ if (withPreviewMode && !previewModeFullscreen) {
443
+ this.inPreviewMode = true;
444
+ return (
445
+ <div style={{ ...style }} className="preview-mode-container">
446
+ <div style={{ position: "relative" }}>
447
+ <div className="preview-mode-buttons">
448
+ <ButtonGroup className="preview-mode-view-fullscreen">
449
+ <Button
450
+ text="Open Editor"
451
+ intent={Intent.PRIMARY}
452
+ onClick={this.togglePreviewFullscreen}
453
+ />
454
+ {previewModeButtonMenu && (
455
+ <Button
456
+ icon="caret-down"
457
+ intent={Intent.PRIMARY}
458
+ onClick={this.onPreviewModeButtonContextMenu}
459
+ />
460
+ )}
461
+ </ButtonGroup>
462
+ </div>
463
+ <div
464
+ style={{ padding: 40 }}
465
+ className="preview-mode-simple-sequence-view"
466
+ >
467
+ <SimpleCircularOrLinearView
468
+ sequenceData={sequenceData}
469
+ hoveredId={hoveredId}
470
+ tabHeight={tabHeight}
471
+ selectionLayer={selectionLayer}
472
+ editorName={editorName}
473
+ height={null}
474
+ isProtein={sequenceData.isProtein}
475
+ annotationLabelVisibility={{
476
+ features: false,
477
+ parts: false,
478
+ cutsites: false,
479
+ primers: false
480
+ }}
481
+ />
482
+ </div>
483
+ </div>
484
+ </div>
485
+ );
486
+ } else {
487
+ this.inPreviewMode = false;
488
+ }
489
+
490
+ const tabDraggable = allowPanelTabDraggable && !isMobile();
491
+ const { tabDragging } = this.state;
492
+ let xOffset = 0;
493
+ let yOffset = 0;
494
+ if (fullScreenOffsets && previewModeFullscreen) {
495
+ xOffset = fullScreenOffsets.xOffset || 0;
496
+ yOffset = fullScreenOffsets.yOffset || 0;
497
+ }
498
+ const w = window,
499
+ d = document,
500
+ e = d.documentElement,
501
+ g = d.getElementsByTagName("body")[0],
502
+ x = w.innerWidth || e.clientWidth || g.clientWidth,
503
+ y = w.innerHeight || e.clientHeight || g.clientHeight;
504
+ const windowDimensions = {
505
+ width: x - xOffset,
506
+ height: Math.max(y, minHeight) - yOffset
507
+ };
508
+ const reflexElementProps = {
509
+ propagateDimensions: true,
510
+ // resizeHeight: true,
511
+ renderOnResizeRate: 50,
512
+ renderOnResize: true,
513
+ className: "ve-panel"
514
+ };
515
+
516
+ const panelsToShow = this.getPanelsToShow();
517
+ this.hasFullscreenPanel = false;
518
+ map(panelsToShow, (panelGroup) => {
519
+ panelGroup.forEach(({ fullScreen }) => {
520
+ if (fullScreen) this.hasFullscreenPanel = true;
521
+ });
522
+ });
523
+ const pickedUserDefinedHandlersAndOpts = pick(
524
+ this.props,
525
+ userDefinedHandlersAndOpts
526
+ );
527
+ const panels = flatMap(panelsToShow, (panelGroup, index) => {
528
+ // let activePanelId
529
+ let activePanelId;
530
+ let activePanelType;
531
+ let isFullScreen;
532
+ let panelPropsToSpread = {};
533
+ panelGroup.forEach((panelProps) => {
534
+ const { type, id, active, fullScreen } = panelProps;
535
+ if (fullScreen) isFullScreen = true;
536
+ if (active) {
537
+ activePanelType = type || id;
538
+ activePanelId = id;
539
+ panelPropsToSpread = panelProps;
540
+ }
541
+ });
542
+ if (this.hasFullscreenPanel && !isFullScreen) {
543
+ return;
544
+ }
545
+
546
+ if (isFullScreen) {
547
+ editorDimensions = {
548
+ ...editorDimensions,
549
+ ...windowDimensions,
550
+ dimensions: windowDimensions
551
+ };
552
+ }
553
+ const panelMap = {
554
+ ..._panelMap,
555
+ ...this.props.panelMap
556
+ };
557
+
558
+ const Panel =
559
+ (panelMap[activePanelType] && panelMap[activePanelType].comp) ||
560
+ panelMap[activePanelType];
561
+ const panelSpecificProps =
562
+ panelMap[activePanelType] &&
563
+ panelMap[activePanelType].panelSpecificProps;
564
+ const panelSpecificPropsToSpread =
565
+ panelMap[activePanelType] &&
566
+ panelMap[activePanelType].panelSpecificPropsToSpread;
567
+ const panel = Panel ? (
568
+ <Panel
569
+ withZoomLinearView={withZoomLinearView}
570
+ withRotateCircularView={withRotateCircularView}
571
+ withZoomCircularView={withZoomCircularView}
572
+ {...pickedUserDefinedHandlersAndOpts}
573
+ {...(panelSpecificProps && pick(this.props, panelSpecificProps))}
574
+ {...(panelSpecificPropsToSpread &&
575
+ panelSpecificPropsToSpread.reduce((acc, key) => {
576
+ acc = { ...acc, ...get(this.props, key) };
577
+ return acc;
578
+ }, {}))}
579
+ circ_rotationRadians={this.state.rotationRadians}
580
+ circ_setRotationRadians={(val) => {
581
+ this.setState({ rotationRadians: val });
582
+ }}
583
+ circ_zoomLevel={this.state.zoomLevel}
584
+ circ_setZoomLevel={(val) => {
585
+ this.setState({ zoomLevel: val });
586
+ }}
587
+ maxAnnotationsToDisplay={maxAnnotationsToDisplay}
588
+ key={activePanelId}
589
+ fontHeightMultiplier={this.props.fontHeightMultiplier}
590
+ rightClickOverrides={this.props.rightClickOverrides}
591
+ clickOverrides={this.props.clickOverrides}
592
+ {...panelPropsToSpread}
593
+ editorName={editorName}
594
+ isProtein={sequenceData.isProtein}
595
+ onlyShowLabelsThatDoNotFit={onlyShowLabelsThatDoNotFit}
596
+ tabHeight={tabHeight}
597
+ nameFontSizeCircularView={this.props.nameFontSizeCircularView}
598
+ {...editorDimensions}
599
+ isInsideEditor //pass this prop to let the sub components know they're being rendered as an editor tab
600
+ />
601
+ ) : (
602
+ <div> No Panel Found!</div>
603
+ );
604
+
605
+ const showTabRightClickContextMenu = (e, id) => {
606
+ const tabIdToUse = id || activePanelId;
607
+ showContextMenu(
608
+ [
609
+ {
610
+ onClick: () => {
611
+ panelsToShow.length > 1
612
+ ? collapseSplitScreen(tabIdToUse)
613
+ : expandTabToSplitScreen(tabIdToUse);
614
+ },
615
+ text:
616
+ panelsToShow.length > 1
617
+ ? "Collapse Split Screen"
618
+ : "View in Split Screen"
619
+ },
620
+ {
621
+ onClick: () => {
622
+ togglePanelFullScreen(tabIdToUse);
623
+ },
624
+ text: "View in Fullscreen"
625
+ }
626
+ ],
627
+ undefined,
628
+ e
629
+ );
630
+ e.preventDefault();
631
+ e.stopPropagation();
632
+ };
633
+
634
+ const toReturn = [];
635
+ if (index > 0) {
636
+ toReturn.push(
637
+ <ReflexSplitter
638
+ key={activePanelId + "splitter"}
639
+ style={{
640
+ // height: height + 38,
641
+ zIndex: 1
642
+ }}
643
+ propagate
644
+ />
645
+ );
646
+ }
647
+ toReturn.push(
648
+ <ReflexElement
649
+ key={activePanelId}
650
+ activePanelId={activePanelId}
651
+ minSize="200"
652
+ {...reflexElementProps}
653
+ >
654
+ {[
655
+ <Droppable //the tab holder
656
+ key={"droppable-id-" + index.toString()}
657
+ direction="horizontal"
658
+ droppableId={"droppable-id-" + index.toString()}
659
+ >
660
+ {(drop_provided, drop_snapshot) => (
661
+ <div
662
+ className={classNames("ve-draggable-tabs", {
663
+ "is-dragging-over": drop_snapshot.isDraggingOver
664
+ })}
665
+ data-test={"ve-draggable-tabs" + index}
666
+ ref={drop_provided.innerRef}
667
+ style={{
668
+ height: tabHeight,
669
+ paddingLeft: 3
670
+ }}
671
+ >
672
+ {panelGroup.map(({ id, name, canClose }, index) => {
673
+ let nameToShow = name || id;
674
+ if (isMobile()) {
675
+ nameToShow = nameToShow.replace("Map", "");
676
+ }
677
+ return (
678
+ <Draggable
679
+ isDragDisabled={!tabDraggable}
680
+ key={id}
681
+ index={index}
682
+ draggableId={id}
683
+ >
684
+ {(provided) => (
685
+ <div
686
+ style={{
687
+ wordWrap: "normal",
688
+ flex: "0 0 auto",
689
+ maxWidth: "100%",
690
+ fontSize: "14px"
691
+ }}
692
+ onClick={() => {
693
+ setPanelAsActive(id);
694
+ }}
695
+ >
696
+ <div
697
+ onContextMenu={(e) => {
698
+ showTabRightClickContextMenu(e, id);
699
+ }}
700
+ ref={provided.innerRef}
701
+ {...provided.draggableProps}
702
+ {...provided.dragHandleProps}
703
+ style={{
704
+ // some basic styles to make the items look a bit nicer
705
+ userSelect: "none",
706
+ cursor: tabDraggable ? "move" : "pointer",
707
+ flex: "0 0 auto",
708
+ ...provided.draggableProps.style
709
+ }}
710
+ >
711
+ <div
712
+ style={{
713
+ padding: 3,
714
+ borderBottom:
715
+ id === activePanelId
716
+ ? "2px solid #106ba3"
717
+ : "none",
718
+ color:
719
+ id === activePanelId
720
+ ? "#106ba3"
721
+ : "undefined",
722
+ marginLeft: 13,
723
+ marginRight: 13
724
+ }}
725
+ className={
726
+ (id === activePanelId ? "veTabActive " : "") +
727
+ camelCase("veTab-" + nameToShow)
728
+ }
729
+ >
730
+ {isFullScreen && (
731
+ <div //we need this div to wrap the tooltip to help the tooltip stay in the correct position https://github.com/TeselaGen/openVectorEditor/issues/436
732
+ style={{
733
+ zIndex: 15002,
734
+ position: "fixed",
735
+ top: 15,
736
+ right: 25
737
+ }}
738
+ >
739
+ <Tooltip
740
+ position="left"
741
+ content="Minimize Tab"
742
+ >
743
+ <Button
744
+ minimal
745
+ icon="minimize"
746
+ onClick={(e) => {
747
+ e.stopPropagation();
748
+ togglePanelFullScreen(activePanelId);
749
+ }}
750
+ />
751
+ </Tooltip>
752
+ </div>
753
+ )}
754
+ {nameToShow}
755
+ {canClose && (
756
+ <Icon
757
+ icon="small-cross"
758
+ onClick={() => {
759
+ closePanel(id);
760
+ }}
761
+ style={{ paddingLeft: 5 }}
762
+ className="ve-clickable"
763
+ />
764
+ )}
765
+ </div>
766
+ </div>
767
+ </div>
768
+ )}
769
+ </Draggable>
770
+ );
771
+ })}
772
+ {drop_provided.placeholder}
773
+ </div>
774
+ )}
775
+ </Droppable>,
776
+ ...(panelsToShow.length === 1
777
+ ? [
778
+ <Droppable //extra add tab box (only shown when there is 1 tab being shown)!
779
+ key="extra-drop-box"
780
+ direction="horizontal"
781
+ droppableId={"droppable-id-" + (index + 1).toString()}
782
+ >
783
+ {(drop_provided, drop_snapshot) => (
784
+ <div
785
+ ref={drop_provided.innerRef}
786
+ style={getSplitScreenListStyle(
787
+ drop_snapshot.isDraggingOver,
788
+ tabDragging
789
+ )}
790
+ >
791
+ <div
792
+ style={{
793
+ position: "absolute",
794
+ left: "45%",
795
+ top: "45%",
796
+ fontSize: 26
797
+ }}
798
+ >
799
+ {" "}
800
+ + Add Tab
801
+ </div>
802
+ {drop_provided.placeholder}
803
+ </div>
804
+ )}
805
+ </Droppable>
806
+ ]
807
+ : []),
808
+ isFullScreen ? (
809
+ <div
810
+ key="veWhiteBackground"
811
+ className="veWhiteBackground"
812
+ style={{
813
+ zIndex: 15000,
814
+ position: "fixed",
815
+ top: 0,
816
+ left: 0,
817
+ ...windowDimensions
818
+ }}
819
+ >
820
+ {panel}
821
+ </div>
822
+ ) : (
823
+ panel
824
+ )
825
+ ]}
826
+ </ReflexElement>
827
+ );
828
+ return toReturn;
829
+ });
830
+ if (extraRightSidePanel) {
831
+ panels.push(
832
+ <ReflexSplitter
833
+ key="extraRightSidePanelSplitter"
834
+ style={{
835
+ zIndex: 1
836
+ }}
837
+ propagate
838
+ />
839
+ );
840
+
841
+ panels.push(
842
+ <ReflexElement
843
+ key="extraRightSidePanel"
844
+ minSize="350"
845
+ maxSize="350"
846
+ {...reflexElementProps}
847
+ >
848
+ {extraRightSidePanel}
849
+ </ReflexElement>
850
+ );
851
+ }
852
+ return (
853
+ <React.Fragment>
854
+ <DropHandler
855
+ key="dropHandler"
856
+ importSequenceFromFile={this.props.importSequenceFromFile}
857
+ disabled={readOnly || hideSingleImport}
858
+ style={{
859
+ width: "100%",
860
+ maxWidth: "100%",
861
+ // ...(fitHeight && {
862
+ // height: "100%",
863
+ // }),
864
+ position: "relative",
865
+ // height: "100%",
866
+ // ...(fitHeight && {
867
+ height,
868
+ minHeight,
869
+ display: "flex",
870
+ flexDirection: "column",
871
+ ...(previewModeFullscreen && {
872
+ background: "white",
873
+ zIndex: 15000,
874
+ position: "fixed",
875
+ // paddingTop: 20,
876
+ top: yOffset || 0,
877
+ left: xOffset || 0,
878
+ ...windowDimensions
879
+ }),
880
+ ...style
881
+ }}
882
+ className={`veEditor ${editorName} ${
883
+ previewModeFullscreen ? "previewModeFullscreen" : ""
884
+ }`}
885
+ >
886
+ <ToolBar
887
+ {...pickedUserDefinedHandlersAndOpts}
888
+ openHotkeyDialog={this.openHotkeyDialog}
889
+ key="toolbar"
890
+ showMenuBar={showMenuBar}
891
+ displayMenuBarAboveTools={displayMenuBarAboveTools}
892
+ handleFullscreenClose={
893
+ handleFullscreenClose || this.togglePreviewFullscreen
894
+ }
895
+ isProtein={sequenceData.isProtein}
896
+ userDefinedHandlersAndOpts={userDefinedHandlersAndOpts}
897
+ annotationsToSupport={annotationsToSupport}
898
+ closeFullscreen={
899
+ !!(isFullscreen ? handleFullscreenClose : previewModeFullscreen)
900
+ }
901
+ {...{
902
+ modifyTools: this.props.modifyTools,
903
+ contentLeft: this.props.contentLeft,
904
+ editorName
905
+ }}
906
+ withDigestTool
907
+ {...ToolBarProps}
908
+ />
909
+
910
+ <CommandHotkeyHandler
911
+ menuSearchHotkey={this.props.menuSearchHotkey}
912
+ hotkeyDialogProps={{
913
+ isOpen: this.state.isHotkeyDialogOpen,
914
+ onClose: this.closeHotkeyDialog
915
+ }}
916
+ {...pickedUserDefinedHandlersAndOpts}
917
+ editorName={editorName}
918
+ />
919
+
920
+ <div
921
+ style={{
922
+ position: "relative",
923
+ flexGrow: "1",
924
+ minHeight: 0,
925
+ display: "flex"
926
+ }}
927
+ className="tg-editor-container"
928
+ id="section-to-print"
929
+ >
930
+ <DragDropContext
931
+ onDragStart={this.onTabDragStart}
932
+ onDragEnd={this.onTabDragEnd}
933
+ >
934
+ <ReflexContainer
935
+ onPanelCollapse={({ activePanelId }) => {
936
+ this.props.collapsePanel(activePanelId);
937
+ }}
938
+ /* style={{}} */ orientation="vertical"
939
+ >
940
+ {panels}
941
+ </ReflexContainer>
942
+ </DragDropContext>
943
+ </div>
944
+ {!hideStatusBar && (
945
+ <StatusBar
946
+ {...pickedUserDefinedHandlersAndOpts}
947
+ isProtein={sequenceData.isProtein}
948
+ showCircularity={
949
+ !!(
950
+ showCircularity &&
951
+ !sequenceData.isProtein &&
952
+ !sequenceData.isOligo &&
953
+ !sequenceData.isRna
954
+ )
955
+ }
956
+ editorName={editorName}
957
+ {...StatusBarProps}
958
+ />
959
+ )}
960
+ </DropHandler>
961
+ <GlobalDialog
962
+ editorName={editorName}
963
+ {...pickedUserDefinedHandlersAndOpts}
964
+ dialogOverrides={pick(this.props, [
965
+ "AddOrEditFeatureDialogOverride",
966
+ "AddOrEditPartDialogOverride",
967
+ "AddOrEditPrimerDialogOverride"
968
+ ])}
969
+ />
970
+ </React.Fragment>
971
+ );
972
+ }
973
+ }
974
+
975
+ Editor.childContextTypes = {
976
+ blueprintPortalClassName: PropTypes.string
977
+ };
978
+
979
+ export default compose(
980
+ connectToEditor(
981
+ (
982
+ {
983
+ panelsShown,
984
+ annotationsToSupport,
985
+ versionHistory,
986
+ sequenceData = {},
987
+ selectionLayer
988
+ },
989
+ { additionalEnzymes }
990
+ ) => {
991
+ return {
992
+ additionalEnzymes: getAdditionalEnzymesSelector(
993
+ null,
994
+ additionalEnzymes
995
+ ),
996
+ annotationsToSupport,
997
+ selectionLayer,
998
+ panelsShown,
999
+ versionHistory,
1000
+ sequenceData
1001
+ };
1002
+ }
1003
+ ),
1004
+ withHandlers({ handleSave, importSequenceFromFile })
1005
+ )(Editor);