@apollo-annotation/jbrowse-plugin-apollo 0.3.10 → 0.3.12

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 (395) hide show
  1. package/dist/ApolloInternetAccount/components/AuthTypeSelector.d.ts +6 -0
  2. package/dist/ApolloInternetAccount/components/AuthTypeSelector.d.ts.map +1 -0
  3. package/dist/ApolloInternetAccount/components/LoginButtons.d.ts +5 -0
  4. package/dist/ApolloInternetAccount/components/LoginButtons.d.ts.map +1 -0
  5. package/dist/ApolloInternetAccount/components/LoginIcons.d.ts +4 -0
  6. package/dist/ApolloInternetAccount/components/LoginIcons.d.ts.map +1 -0
  7. package/dist/ApolloInternetAccount/index.d.ts +3 -0
  8. package/dist/ApolloInternetAccount/index.d.ts.map +1 -0
  9. package/dist/ApolloJobModel.d.ts +53 -0
  10. package/dist/ApolloJobModel.d.ts.map +1 -0
  11. package/dist/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.d.ts +12 -0
  12. package/dist/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.d.ts.map +1 -0
  13. package/dist/ApolloRefNameAliasAdapter/index.d.ts +3 -0
  14. package/dist/ApolloRefNameAliasAdapter/index.d.ts.map +1 -0
  15. package/dist/ApolloSequenceAdapter/ApolloSequenceAdapter.d.ts +27 -0
  16. package/dist/ApolloSequenceAdapter/ApolloSequenceAdapter.d.ts.map +1 -0
  17. package/dist/ApolloSequenceAdapter/index.d.ts +3 -0
  18. package/dist/ApolloSequenceAdapter/index.d.ts.map +1 -0
  19. package/dist/ApolloTextSearchAdapter/ApolloTextSearchAdapter.d.ts +13 -0
  20. package/dist/ApolloTextSearchAdapter/ApolloTextSearchAdapter.d.ts.map +1 -0
  21. package/dist/ApolloTextSearchAdapter/index.d.ts +3 -0
  22. package/dist/ApolloTextSearchAdapter/index.d.ts.map +1 -0
  23. package/dist/BackendDrivers/BackendDriver.d.ts +26 -0
  24. package/dist/BackendDrivers/BackendDriver.d.ts.map +1 -0
  25. package/dist/BackendDrivers/CollaborationServerDriver.d.ts +206 -0
  26. package/dist/BackendDrivers/CollaborationServerDriver.d.ts.map +1 -0
  27. package/dist/BackendDrivers/DesktopFileDriver.d.ts +160 -0
  28. package/dist/BackendDrivers/DesktopFileDriver.d.ts.map +1 -0
  29. package/dist/BackendDrivers/InMemoryFileDriver.d.ts +162 -0
  30. package/dist/BackendDrivers/InMemoryFileDriver.d.ts.map +1 -0
  31. package/dist/BackendDrivers/index.d.ts +5 -0
  32. package/dist/BackendDrivers/index.d.ts.map +1 -0
  33. package/dist/ChangeManager.d.ts +24 -0
  34. package/dist/ChangeManager.d.ts.map +1 -0
  35. package/dist/FeatureDetailsWidget/ApolloFeatureDetailsWidget.d.ts +6 -0
  36. package/dist/FeatureDetailsWidget/ApolloFeatureDetailsWidget.d.ts.map +1 -0
  37. package/dist/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.d.ts +12 -0
  38. package/dist/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.d.ts.map +1 -0
  39. package/dist/FeatureDetailsWidget/AttributeKey.d.ts +4 -0
  40. package/dist/FeatureDetailsWidget/AttributeKey.d.ts.map +1 -0
  41. package/dist/FeatureDetailsWidget/AttributeKeySelector.d.ts +6 -0
  42. package/dist/FeatureDetailsWidget/AttributeKeySelector.d.ts.map +1 -0
  43. package/dist/FeatureDetailsWidget/Attributes.d.ts +9 -0
  44. package/dist/FeatureDetailsWidget/Attributes.d.ts.map +1 -0
  45. package/dist/FeatureDetailsWidget/BasicInformation.d.ts +8 -0
  46. package/dist/FeatureDetailsWidget/BasicInformation.d.ts.map +1 -0
  47. package/dist/FeatureDetailsWidget/DefaultAttributeEditor.d.ts +9 -0
  48. package/dist/FeatureDetailsWidget/DefaultAttributeEditor.d.ts.map +1 -0
  49. package/dist/FeatureDetailsWidget/DefaultAttributeViewer.d.ts +5 -0
  50. package/dist/FeatureDetailsWidget/DefaultAttributeViewer.d.ts.map +1 -0
  51. package/dist/FeatureDetailsWidget/FeatureDetailsNavigation.d.ts +7 -0
  52. package/dist/FeatureDetailsWidget/FeatureDetailsNavigation.d.ts.map +1 -0
  53. package/dist/FeatureDetailsWidget/NumberTextField.d.ts +8 -0
  54. package/dist/FeatureDetailsWidget/NumberTextField.d.ts.map +1 -0
  55. package/dist/FeatureDetailsWidget/Sequence.d.ts +10 -0
  56. package/dist/FeatureDetailsWidget/Sequence.d.ts.map +1 -0
  57. package/dist/FeatureDetailsWidget/StringTextField.d.ts +8 -0
  58. package/dist/FeatureDetailsWidget/StringTextField.d.ts.map +1 -0
  59. package/dist/FeatureDetailsWidget/TranscriptSequence.d.ts +10 -0
  60. package/dist/FeatureDetailsWidget/TranscriptSequence.d.ts.map +1 -0
  61. package/dist/FeatureDetailsWidget/TranscriptWidgetEditLocation.d.ts +9 -0
  62. package/dist/FeatureDetailsWidget/TranscriptWidgetEditLocation.d.ts.map +1 -0
  63. package/dist/FeatureDetailsWidget/TranscriptWidgetSummary.d.ts +6 -0
  64. package/dist/FeatureDetailsWidget/TranscriptWidgetSummary.d.ts.map +1 -0
  65. package/dist/FeatureDetailsWidget/index.d.ts +5 -0
  66. package/dist/FeatureDetailsWidget/index.d.ts.map +1 -0
  67. package/dist/FeatureDetailsWidget/model.d.ts +123 -0
  68. package/dist/FeatureDetailsWidget/model.d.ts.map +1 -0
  69. package/dist/LinearApolloDisplay/components/CheckResultWarnings.d.ts +5 -0
  70. package/dist/LinearApolloDisplay/components/CheckResultWarnings.d.ts.map +1 -0
  71. package/dist/LinearApolloDisplay/components/LinearApolloDisplay.d.ts +7 -0
  72. package/dist/LinearApolloDisplay/components/LinearApolloDisplay.d.ts.map +1 -0
  73. package/dist/LinearApolloDisplay/components/index.d.ts +2 -0
  74. package/dist/LinearApolloDisplay/components/index.d.ts.map +1 -0
  75. package/dist/LinearApolloDisplay/glyphs/BoxGlyph.d.ts +4 -0
  76. package/dist/LinearApolloDisplay/glyphs/BoxGlyph.d.ts.map +1 -0
  77. package/dist/LinearApolloDisplay/glyphs/GeneGlyph.d.ts +3 -0
  78. package/dist/LinearApolloDisplay/glyphs/GeneGlyph.d.ts.map +1 -0
  79. package/dist/LinearApolloDisplay/glyphs/GenericChildGlyph.d.ts +3 -0
  80. package/dist/LinearApolloDisplay/glyphs/GenericChildGlyph.d.ts.map +1 -0
  81. package/dist/LinearApolloDisplay/glyphs/Glyph.d.ts +26 -0
  82. package/dist/LinearApolloDisplay/glyphs/Glyph.d.ts.map +1 -0
  83. package/dist/LinearApolloDisplay/glyphs/index.d.ts +4 -0
  84. package/dist/LinearApolloDisplay/glyphs/index.d.ts.map +1 -0
  85. package/dist/LinearApolloDisplay/glyphs/util.d.ts +12 -0
  86. package/dist/LinearApolloDisplay/glyphs/util.d.ts.map +1 -0
  87. package/dist/LinearApolloDisplay/index.d.ts +3 -0
  88. package/dist/LinearApolloDisplay/index.d.ts.map +1 -0
  89. package/dist/LinearApolloDisplay/stateModel/base.d.ts +254 -0
  90. package/dist/LinearApolloDisplay/stateModel/base.d.ts.map +1 -0
  91. package/dist/LinearApolloDisplay/stateModel/index.d.ts +349 -0
  92. package/dist/LinearApolloDisplay/stateModel/index.d.ts.map +1 -0
  93. package/dist/LinearApolloDisplay/stateModel/layouts.d.ts +273 -0
  94. package/dist/LinearApolloDisplay/stateModel/layouts.d.ts.map +1 -0
  95. package/dist/LinearApolloDisplay/stateModel/mouseEvents.d.ts +656 -0
  96. package/dist/LinearApolloDisplay/stateModel/mouseEvents.d.ts.map +1 -0
  97. package/dist/LinearApolloDisplay/stateModel/rendering.d.ts +300 -0
  98. package/dist/LinearApolloDisplay/stateModel/rendering.d.ts.map +1 -0
  99. package/dist/LinearApolloDisplay/types.d.ts +2 -0
  100. package/dist/LinearApolloDisplay/types.d.ts.map +1 -0
  101. package/dist/LinearApolloReferenceSequenceDisplay/components/LinearApolloReferenceSequenceDisplay.d.ts +7 -0
  102. package/dist/LinearApolloReferenceSequenceDisplay/components/LinearApolloReferenceSequenceDisplay.d.ts.map +1 -0
  103. package/dist/LinearApolloReferenceSequenceDisplay/components/index.d.ts +2 -0
  104. package/dist/LinearApolloReferenceSequenceDisplay/components/index.d.ts.map +1 -0
  105. package/dist/LinearApolloReferenceSequenceDisplay/drawSequenceOverlay.d.ts +6 -0
  106. package/dist/LinearApolloReferenceSequenceDisplay/drawSequenceOverlay.d.ts.map +1 -0
  107. package/dist/LinearApolloReferenceSequenceDisplay/drawSequenceTrack.d.ts +5 -0
  108. package/dist/LinearApolloReferenceSequenceDisplay/drawSequenceTrack.d.ts.map +1 -0
  109. package/dist/LinearApolloReferenceSequenceDisplay/index.d.ts +4 -0
  110. package/dist/LinearApolloReferenceSequenceDisplay/index.d.ts.map +1 -0
  111. package/dist/LinearApolloReferenceSequenceDisplay/stateModel/base.d.ts +236 -0
  112. package/dist/LinearApolloReferenceSequenceDisplay/stateModel/base.d.ts.map +1 -0
  113. package/dist/LinearApolloReferenceSequenceDisplay/stateModel/index.d.ts +245 -0
  114. package/dist/LinearApolloReferenceSequenceDisplay/stateModel/index.d.ts.map +1 -0
  115. package/dist/LinearApolloReferenceSequenceDisplay/stateModel/rendering.d.ts +246 -0
  116. package/dist/LinearApolloReferenceSequenceDisplay/stateModel/rendering.d.ts.map +1 -0
  117. package/dist/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.d.ts +7 -0
  118. package/dist/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.d.ts.map +1 -0
  119. package/dist/LinearApolloSixFrameDisplay/components/TrackLines.d.ts +8 -0
  120. package/dist/LinearApolloSixFrameDisplay/components/TrackLines.d.ts.map +1 -0
  121. package/dist/LinearApolloSixFrameDisplay/components/index.d.ts +3 -0
  122. package/dist/LinearApolloSixFrameDisplay/components/index.d.ts.map +1 -0
  123. package/dist/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.d.ts +3 -0
  124. package/dist/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.d.ts.map +1 -0
  125. package/dist/LinearApolloSixFrameDisplay/glyphs/Glyph.d.ts +20 -0
  126. package/dist/LinearApolloSixFrameDisplay/glyphs/Glyph.d.ts.map +1 -0
  127. package/dist/LinearApolloSixFrameDisplay/glyphs/index.d.ts +2 -0
  128. package/dist/LinearApolloSixFrameDisplay/glyphs/index.d.ts.map +1 -0
  129. package/dist/LinearApolloSixFrameDisplay/index.d.ts +3 -0
  130. package/dist/LinearApolloSixFrameDisplay/index.d.ts.map +1 -0
  131. package/dist/LinearApolloSixFrameDisplay/stateModel/base.d.ts +257 -0
  132. package/dist/LinearApolloSixFrameDisplay/stateModel/base.d.ts.map +1 -0
  133. package/dist/LinearApolloSixFrameDisplay/stateModel/index.d.ts +355 -0
  134. package/dist/LinearApolloSixFrameDisplay/stateModel/index.d.ts.map +1 -0
  135. package/dist/LinearApolloSixFrameDisplay/stateModel/layouts.d.ts +283 -0
  136. package/dist/LinearApolloSixFrameDisplay/stateModel/layouts.d.ts.map +1 -0
  137. package/dist/LinearApolloSixFrameDisplay/stateModel/mouseEvents.d.ts +668 -0
  138. package/dist/LinearApolloSixFrameDisplay/stateModel/mouseEvents.d.ts.map +1 -0
  139. package/dist/LinearApolloSixFrameDisplay/stateModel/rendering.d.ts +306 -0
  140. package/dist/LinearApolloSixFrameDisplay/stateModel/rendering.d.ts.map +1 -0
  141. package/dist/LinearApolloSixFrameDisplay/types.d.ts +2 -0
  142. package/dist/LinearApolloSixFrameDisplay/types.d.ts.map +1 -0
  143. package/dist/OntologyManager/OntologyStore/fulltext-stopwords.d.ts +8 -0
  144. package/dist/OntologyManager/OntologyStore/fulltext-stopwords.d.ts.map +1 -0
  145. package/dist/OntologyManager/OntologyStore/fulltext.d.ts +27 -0
  146. package/dist/OntologyManager/OntologyStore/fulltext.d.ts.map +1 -0
  147. package/dist/OntologyManager/OntologyStore/index.d.ts +93 -0
  148. package/dist/OntologyManager/OntologyStore/index.d.ts.map +1 -0
  149. package/dist/OntologyManager/OntologyStore/indexeddb-schema.d.ts +71 -0
  150. package/dist/OntologyManager/OntologyStore/indexeddb-schema.d.ts.map +1 -0
  151. package/dist/OntologyManager/OntologyStore/indexeddb-storage.d.ts +11 -0
  152. package/dist/OntologyManager/OntologyStore/indexeddb-storage.d.ts.map +1 -0
  153. package/dist/OntologyManager/OntologyStore/obo-graph-json-schema.d.ts +107 -0
  154. package/dist/OntologyManager/OntologyStore/obo-graph-json-schema.d.ts.map +1 -0
  155. package/dist/OntologyManager/OntologyStore/prefixes.d.ts +20 -0
  156. package/dist/OntologyManager/OntologyStore/prefixes.d.ts.map +1 -0
  157. package/dist/OntologyManager/util.d.ts +4 -0
  158. package/dist/OntologyManager/util.d.ts.map +1 -0
  159. package/dist/TabularEditor/HybridGrid/ChangeHandling.d.ts +6 -0
  160. package/dist/TabularEditor/HybridGrid/ChangeHandling.d.ts.map +1 -0
  161. package/dist/TabularEditor/HybridGrid/Feature.d.ts +13 -0
  162. package/dist/TabularEditor/HybridGrid/Feature.d.ts.map +1 -0
  163. package/dist/TabularEditor/HybridGrid/FeatureAttributes.d.ts +6 -0
  164. package/dist/TabularEditor/HybridGrid/FeatureAttributes.d.ts.map +1 -0
  165. package/dist/TabularEditor/HybridGrid/Highlight.d.ts +6 -0
  166. package/dist/TabularEditor/HybridGrid/Highlight.d.ts.map +1 -0
  167. package/dist/TabularEditor/HybridGrid/HybridGrid.d.ts +14 -0
  168. package/dist/TabularEditor/HybridGrid/HybridGrid.d.ts.map +1 -0
  169. package/dist/TabularEditor/HybridGrid/NumberCell.d.ts +8 -0
  170. package/dist/TabularEditor/HybridGrid/NumberCell.d.ts.map +1 -0
  171. package/dist/TabularEditor/HybridGrid/ToolBar.d.ts +5 -0
  172. package/dist/TabularEditor/HybridGrid/ToolBar.d.ts.map +1 -0
  173. package/dist/TabularEditor/HybridGrid/featureContextMenuItems.d.ts +11 -0
  174. package/dist/TabularEditor/HybridGrid/featureContextMenuItems.d.ts.map +1 -0
  175. package/dist/TabularEditor/HybridGrid/index.d.ts +2 -0
  176. package/dist/TabularEditor/HybridGrid/index.d.ts.map +1 -0
  177. package/dist/TabularEditor/TabularEditorPane.d.ts +5 -0
  178. package/dist/TabularEditor/TabularEditorPane.d.ts.map +1 -0
  179. package/dist/TabularEditor/index.d.ts +3 -0
  180. package/dist/TabularEditor/index.d.ts.map +1 -0
  181. package/dist/TabularEditor/model.d.ts +17 -0
  182. package/dist/TabularEditor/model.d.ts.map +1 -0
  183. package/dist/TabularEditor/types.d.ts +4 -0
  184. package/dist/TabularEditor/types.d.ts.map +1 -0
  185. package/dist/components/AddAssembly.d.ts +10 -0
  186. package/dist/components/AddAssembly.d.ts.map +1 -0
  187. package/dist/components/AddAssemblyAliases.d.ts +10 -0
  188. package/dist/components/AddAssemblyAliases.d.ts.map +1 -0
  189. package/dist/components/AddChildFeature.d.ts +13 -0
  190. package/dist/components/AddChildFeature.d.ts.map +1 -0
  191. package/dist/components/AddFeature.d.ts +12 -0
  192. package/dist/components/AddFeature.d.ts.map +1 -0
  193. package/dist/components/AddRefSeqAliases.d.ts +10 -0
  194. package/dist/components/AddRefSeqAliases.d.ts.map +1 -0
  195. package/dist/components/CopyFeature.d.ts +13 -0
  196. package/dist/components/CopyFeature.d.ts.map +1 -0
  197. package/dist/components/CreateApolloAnnotation.d.ts +20 -0
  198. package/dist/components/CreateApolloAnnotation.d.ts.map +1 -0
  199. package/dist/components/DeleteAssembly.d.ts +10 -0
  200. package/dist/components/DeleteAssembly.d.ts.map +1 -0
  201. package/dist/components/DeleteFeature.d.ts +15 -0
  202. package/dist/components/DeleteFeature.d.ts.map +1 -0
  203. package/dist/components/Dialog.d.ts +7 -0
  204. package/dist/components/Dialog.d.ts.map +1 -0
  205. package/dist/components/DownloadGFF3.d.ts +8 -0
  206. package/dist/components/DownloadGFF3.d.ts.map +1 -0
  207. package/dist/components/DuplicateTranscript.d.ts +15 -0
  208. package/dist/components/DuplicateTranscript.d.ts.map +1 -0
  209. package/dist/components/EditZoomThresholdDialog.d.ts +11 -0
  210. package/dist/components/EditZoomThresholdDialog.d.ts.map +1 -0
  211. package/dist/components/FilterFeatures.d.ts +10 -0
  212. package/dist/components/FilterFeatures.d.ts.map +1 -0
  213. package/dist/components/FilterTranscripts.d.ts +10 -0
  214. package/dist/components/FilterTranscripts.d.ts.map +1 -0
  215. package/dist/components/ImportFeatures.d.ts +10 -0
  216. package/dist/components/ImportFeatures.d.ts.map +1 -0
  217. package/dist/components/LogOut.d.ts +8 -0
  218. package/dist/components/LogOut.d.ts.map +1 -0
  219. package/dist/components/ManageChecks.d.ts +8 -0
  220. package/dist/components/ManageChecks.d.ts.map +1 -0
  221. package/dist/components/ManageUsers.d.ts +10 -0
  222. package/dist/components/ManageUsers.d.ts.map +1 -0
  223. package/dist/components/MergeExons.d.ts +15 -0
  224. package/dist/components/MergeExons.d.ts.map +1 -0
  225. package/dist/components/MergeTranscripts.d.ts +15 -0
  226. package/dist/components/MergeTranscripts.d.ts.map +1 -0
  227. package/dist/components/OntologyTermAutocomplete.d.ts +25 -0
  228. package/dist/components/OntologyTermAutocomplete.d.ts.map +1 -0
  229. package/dist/components/OntologyTermMultiSelect.d.ts +12 -0
  230. package/dist/components/OntologyTermMultiSelect.d.ts.map +1 -0
  231. package/dist/components/OpenLocalFile.d.ts +15 -0
  232. package/dist/components/OpenLocalFile.d.ts.map +1 -0
  233. package/dist/components/SplitExon.d.ts +15 -0
  234. package/dist/components/SplitExon.d.ts.map +1 -0
  235. package/dist/components/ViewChangeLog.d.ts +8 -0
  236. package/dist/components/ViewChangeLog.d.ts.map +1 -0
  237. package/dist/components/ViewCheckResults.d.ts +8 -0
  238. package/dist/components/ViewCheckResults.d.ts.map +1 -0
  239. package/dist/components/index.d.ts +21 -0
  240. package/dist/components/index.d.ts.map +1 -0
  241. package/dist/extensions/annotationFromJBrowseFeature.d.ts +6 -0
  242. package/dist/extensions/annotationFromJBrowseFeature.d.ts.map +1 -0
  243. package/dist/extensions/annotationFromPileup.d.ts +3 -0
  244. package/dist/extensions/annotationFromPileup.d.ts.map +1 -0
  245. package/dist/extensions/index.d.ts +3 -0
  246. package/dist/extensions/index.d.ts.map +1 -0
  247. package/dist/index.esm.js +843 -1330
  248. package/dist/index.esm.js.map +1 -1
  249. package/dist/jbrowse-plugin-apollo.cjs.development.js +919 -1455
  250. package/dist/jbrowse-plugin-apollo.cjs.development.js.map +1 -1
  251. package/dist/jbrowse-plugin-apollo.cjs.production.min.js +1 -1
  252. package/dist/jbrowse-plugin-apollo.cjs.production.min.js.map +1 -1
  253. package/dist/jbrowse-plugin-apollo.umd.development.js +46351 -63619
  254. package/dist/jbrowse-plugin-apollo.umd.development.js.map +1 -1
  255. package/dist/jbrowse-plugin-apollo.umd.production.min.js +1 -1
  256. package/dist/jbrowse-plugin-apollo.umd.production.min.js.map +1 -1
  257. package/dist/makeDisplayComponent.d.ts +9 -0
  258. package/dist/makeDisplayComponent.d.ts.map +1 -0
  259. package/dist/menus/index.d.ts +2 -0
  260. package/dist/menus/index.d.ts.map +1 -0
  261. package/dist/menus/topLevelMenu.d.ts +3 -0
  262. package/dist/menus/topLevelMenu.d.ts.map +1 -0
  263. package/dist/menus/topLevelMenuAdmin.d.ts +3 -0
  264. package/dist/menus/topLevelMenuAdmin.d.ts.map +1 -0
  265. package/dist/session/index.d.ts +2 -0
  266. package/dist/session/index.d.ts.map +1 -0
  267. package/dist/types.d.ts +10 -0
  268. package/dist/types.d.ts.map +1 -0
  269. package/dist/util/annotationFeatureUtils.d.ts +7 -0
  270. package/dist/util/annotationFeatureUtils.d.ts.map +1 -0
  271. package/dist/util/copyToClipboard.d.ts +2 -0
  272. package/dist/util/copyToClipboard.d.ts.map +1 -0
  273. package/dist/util/glyphUtils.d.ts +31 -0
  274. package/dist/util/glyphUtils.d.ts.map +1 -0
  275. package/dist/util/index.d.ts +10 -0
  276. package/dist/util/index.d.ts.map +1 -0
  277. package/dist/util/loadAssemblyIntoClient.d.ts +5 -0
  278. package/dist/util/loadAssemblyIntoClient.d.ts.map +1 -0
  279. package/dist/util/mouseEventsUtils.d.ts +25 -0
  280. package/dist/util/mouseEventsUtils.d.ts.map +1 -0
  281. package/package.json +48 -25
  282. package/src/ApolloInternetAccount/components/AuthTypeSelector.tsx +7 -2
  283. package/src/ApolloInternetAccount/components/LoginButtons.tsx +1 -1
  284. package/src/ApolloInternetAccount/configSchema.ts +1 -1
  285. package/src/ApolloInternetAccount/model.ts +13 -6
  286. package/src/ApolloJobModel.ts +3 -3
  287. package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +2 -2
  288. package/src/ApolloSequenceAdapter/ApolloSequenceAdapter.ts +2 -2
  289. package/src/ApolloTextSearchAdapter/ApolloTextSearchAdapter.ts +28 -5
  290. package/src/BackendDrivers/BackendDriver.ts +8 -8
  291. package/src/BackendDrivers/CollaborationServerDriver.ts +6 -6
  292. package/src/BackendDrivers/DesktopFileDriver.ts +4 -4
  293. package/src/BackendDrivers/InMemoryFileDriver.ts +5 -8
  294. package/src/ChangeManager.ts +8 -3
  295. package/src/FeatureDetailsWidget/ApolloFeatureDetailsWidget.tsx +3 -3
  296. package/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx +7 -7
  297. package/src/FeatureDetailsWidget/AttributeKey.tsx +1 -1
  298. package/src/FeatureDetailsWidget/AttributeKeySelector.tsx +1 -1
  299. package/src/FeatureDetailsWidget/Attributes.tsx +4 -4
  300. package/src/FeatureDetailsWidget/BasicInformation.tsx +3 -3
  301. package/src/FeatureDetailsWidget/DefaultAttributeEditor.tsx +1 -1
  302. package/src/FeatureDetailsWidget/FeatureDetailsNavigation.tsx +2 -2
  303. package/src/FeatureDetailsWidget/Sequence.tsx +3 -3
  304. package/src/FeatureDetailsWidget/TranscriptSequence.tsx +2 -2
  305. package/src/FeatureDetailsWidget/TranscriptWidgetEditLocation.tsx +3 -6
  306. package/src/FeatureDetailsWidget/TranscriptWidgetSummary.tsx +1 -1
  307. package/src/FeatureDetailsWidget/model.ts +3 -3
  308. package/src/LinearApolloDisplay/components/CheckResultWarnings.tsx +2 -2
  309. package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +6 -4
  310. package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +7 -7
  311. package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +56 -30
  312. package/src/LinearApolloDisplay/glyphs/GenericChildGlyph.ts +6 -6
  313. package/src/LinearApolloDisplay/glyphs/Glyph.ts +7 -7
  314. package/src/LinearApolloDisplay/glyphs/util.ts +2 -2
  315. package/src/LinearApolloDisplay/stateModel/base.ts +17 -8
  316. package/src/LinearApolloDisplay/stateModel/index.ts +2 -2
  317. package/src/LinearApolloDisplay/stateModel/layouts.ts +4 -4
  318. package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +6 -6
  319. package/src/LinearApolloDisplay/stateModel/rendering.ts +3 -3
  320. package/src/LinearApolloReferenceSequenceDisplay/components/LinearApolloReferenceSequenceDisplay.tsx +4 -2
  321. package/src/LinearApolloReferenceSequenceDisplay/drawSequenceOverlay.ts +4 -4
  322. package/src/LinearApolloReferenceSequenceDisplay/drawSequenceTrack.ts +3 -3
  323. package/src/LinearApolloReferenceSequenceDisplay/stateModel/base.ts +11 -8
  324. package/src/LinearApolloReferenceSequenceDisplay/stateModel/index.ts +2 -2
  325. package/src/LinearApolloReferenceSequenceDisplay/stateModel/rendering.ts +2 -2
  326. package/src/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.tsx +17 -9
  327. package/src/LinearApolloSixFrameDisplay/components/TrackLines.tsx +1 -1
  328. package/src/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.ts +36 -23
  329. package/src/LinearApolloSixFrameDisplay/glyphs/Glyph.ts +6 -6
  330. package/src/LinearApolloSixFrameDisplay/stateModel/base.ts +17 -8
  331. package/src/LinearApolloSixFrameDisplay/stateModel/index.ts +2 -2
  332. package/src/LinearApolloSixFrameDisplay/stateModel/layouts.ts +12 -8
  333. package/src/LinearApolloSixFrameDisplay/stateModel/mouseEvents.ts +11 -10
  334. package/src/LinearApolloSixFrameDisplay/stateModel/rendering.ts +3 -3
  335. package/src/OntologyManager/OntologyStore/fulltext.test.ts +1 -1
  336. package/src/OntologyManager/OntologyStore/fulltext.ts +11 -4
  337. package/src/OntologyManager/OntologyStore/index.test.ts +3 -0
  338. package/src/OntologyManager/OntologyStore/indexeddb-schema.ts +6 -6
  339. package/src/OntologyManager/OntologyStore/indexeddb-storage.ts +2 -1
  340. package/src/OntologyManager/index.ts +4 -4
  341. package/src/OntologyManager/util.ts +1 -1
  342. package/src/TabularEditor/HybridGrid/ChangeHandling.ts +2 -2
  343. package/src/TabularEditor/HybridGrid/Feature.tsx +6 -6
  344. package/src/TabularEditor/HybridGrid/FeatureAttributes.tsx +2 -2
  345. package/src/TabularEditor/HybridGrid/Highlight.tsx +1 -1
  346. package/src/TabularEditor/HybridGrid/HybridGrid.tsx +2 -2
  347. package/src/TabularEditor/HybridGrid/NumberCell.tsx +1 -1
  348. package/src/TabularEditor/HybridGrid/ToolBar.tsx +3 -2
  349. package/src/TabularEditor/HybridGrid/featureContextMenuItems.ts +26 -4
  350. package/src/TabularEditor/TabularEditorPane.tsx +1 -1
  351. package/src/TabularEditor/model.ts +2 -2
  352. package/src/TabularEditor/types.ts +2 -2
  353. package/src/components/AddAssembly.tsx +61 -42
  354. package/src/components/AddAssemblyAliases.tsx +5 -5
  355. package/src/components/AddChildFeature.tsx +3 -3
  356. package/src/components/AddFeature.tsx +4 -4
  357. package/src/components/AddRefSeqAliases.tsx +7 -7
  358. package/src/components/CopyFeature.tsx +8 -8
  359. package/src/components/CreateApolloAnnotation.tsx +5 -5
  360. package/src/components/DeleteAssembly.tsx +8 -8
  361. package/src/components/DeleteFeature.tsx +4 -4
  362. package/src/components/Dialog.tsx +1 -1
  363. package/src/components/DownloadGFF3.tsx +8 -8
  364. package/src/components/DuplicateTranscript.tsx +132 -0
  365. package/src/components/FilterFeatures.tsx +1 -1
  366. package/src/components/FilterTranscripts.tsx +1 -1
  367. package/src/components/ImportFeatures.tsx +51 -33
  368. package/src/components/LogOut.tsx +4 -4
  369. package/src/components/ManageChecks.tsx +8 -8
  370. package/src/components/ManageUsers.tsx +18 -26
  371. package/src/components/MergeExons.tsx +4 -4
  372. package/src/components/MergeTranscripts.tsx +4 -4
  373. package/src/components/OntologyTermAutocomplete.tsx +14 -4
  374. package/src/components/OntologyTermMultiSelect.tsx +12 -5
  375. package/src/components/OpenLocalFile.tsx +2 -2
  376. package/src/components/SplitExon.tsx +6 -6
  377. package/src/components/ViewChangeLog.tsx +8 -8
  378. package/src/components/ViewCheckResults.tsx +4 -4
  379. package/src/components/index.ts +1 -0
  380. package/src/config.ts +1 -1
  381. package/src/extensions/annotationFromJBrowseFeature.ts +29 -24
  382. package/src/extensions/annotationFromPileup.ts +8 -6
  383. package/src/index.ts +25 -1
  384. package/src/makeDisplayComponent.tsx +8 -5
  385. package/src/menus/topLevelMenu.ts +4 -4
  386. package/src/menus/topLevelMenuAdmin.ts +4 -4
  387. package/src/session/ClientDataStore.ts +20 -15
  388. package/src/session/session.ts +30 -19
  389. package/src/types.ts +10 -4
  390. package/src/util/annotationFeatureUtils.ts +1 -1
  391. package/src/util/displayUtils.ts +3 -3
  392. package/src/util/glyphUtils.ts +10 -10
  393. package/src/util/index.ts +4 -4
  394. package/src/util/loadAssemblyIntoClient.ts +4 -4
  395. package/src/util/mouseEventsUtils.ts +2 -2
package/dist/index.esm.js CHANGED
@@ -5,22 +5,23 @@ import { ConfigurationSchema, readConfObject, getConf, ConfigurationReference }
5
5
  import { BaseInternetAccountConfig, InternetAccount, TextSearchAdapterType, BaseDisplay, WidgetType, createBaseTrackConfig, TrackType, createBaseTrackModel, InternetAccountType, DisplayType } from '@jbrowse/core/pluggableElementTypes';
6
6
  import { isSessionModelWithWidgets, getContainingView, isUriLocation, isLocalPathLocation, getSession, isElectron, isAbstractMenuManager, getEnv, revcom, defaultCodonTable, getFrame, intersection2, doesIntersect2, measureText } from '@jbrowse/core/util';
7
7
  import AddIcon from '@mui/icons-material/Add';
8
- import { DialogTitle, IconButton, DialogContent, LinearProgress, TextField, Accordion, AccordionSummary, Typography, AccordionDetails, FormGroup, FormControlLabel, Checkbox, Box, Tooltip, Table, TableBody, TableRow, TableCell, InputAdornment, DialogActions, Button, DialogContentText, Autocomplete, FormControl, InputLabel, Select, MenuItem, RadioGroup, Radio, TableContainer, Paper, TableHead, useTheme, FormHelperText, Grid, SvgIcon, Divider, Chip, List, ListItem, ListItemText, Menu, ListItemIcon, alpha, createTheme, Alert, Badge, Avatar, CircularProgress } from '@mui/material';
9
- import { autorun, entries, observable } from 'mobx';
10
- import { getSnapshot, getParent, getRoot, types, addDisposer, flow, isAlive, cast, resolveIdentifier, getParentOfType, applySnapshot } from 'mobx-state-tree';
8
+ import { DialogTitle, IconButton, DialogContent, LinearProgress, TextField, Accordion, AccordionSummary, Typography, AccordionDetails, FormGroup, FormControlLabel, Box, Tooltip, Checkbox, Table, TableBody, TableRow, TableCell, InputAdornment, FormHelperText, DialogActions, Button, DialogContentText, Autocomplete, FormControl, InputLabel, Select, MenuItem, RadioGroup, Radio, TableContainer, Paper, TableHead, useTheme, Grid, SvgIcon, Divider, Chip, List, ListItem, ListItemText, Menu, ListItemIcon, alpha, createTheme, Alert, Badge, Avatar, CircularProgress } from '@mui/material';
9
+ import { getSnapshot, getParent, getRoot, types, addDisposer, flow, isAlive, cast, resolveIdentifier, getParentOfType, applySnapshot } from '@jbrowse/mobx-state-tree';
10
+ import { autorun, entries, observable, flow as flow$1, when } from 'mobx';
11
11
  import { io } from 'socket.io-client';
12
12
  import AdminPanelSettingsIcon from '@mui/icons-material/AdminPanelSettings';
13
13
  import DeleteIcon from '@mui/icons-material/Delete';
14
14
  import InputIcon from '@mui/icons-material/Input';
15
15
  import PersonIcon from '@mui/icons-material/Person';
16
16
  import RuleIcon from '@mui/icons-material/Rule';
17
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
18
+ import { makeStyles } from '@jbrowse/core/util/tss-react';
17
19
  import InfoIcon from '@mui/icons-material/Info';
18
20
  import LinkIcon from '@mui/icons-material/Link';
19
21
  import RadioButtonCheckedIcon from '@mui/icons-material/RadioButtonChecked';
20
22
  import RadioButtonUncheckedIcon from '@mui/icons-material/RadioButtonUnchecked';
21
23
  import ObjectID from 'bson-objectid';
22
24
  import React, { useState, useCallback, useEffect, useRef, useMemo } from 'react';
23
- import { makeStyles } from 'tss-react/mui';
24
25
  import { parseStringSync, formatSync } from '@gmod/gff';
25
26
  import SkipNextRoundedIcon from '@mui/icons-material/SkipNextRounded';
26
27
  import SkipPreviousRoundedIcon from '@mui/icons-material/SkipPreviousRounded';
@@ -35,9 +36,6 @@ import jsonpath from 'jsonpath';
35
36
  import { openLocation } from '@jbrowse/core/util/io';
36
37
  import equal from 'fast-deep-equal/es6';
37
38
  import { saveAs } from 'file-saver';
38
- import Checkbox$1 from '@mui/material/Checkbox';
39
- import FormControlLabel$1 from '@mui/material/FormControlLabel';
40
- import LinearProgress$1 from '@mui/material/LinearProgress';
41
39
  import { nanoid } from 'nanoid';
42
40
  import AccountCircleIcon from '@mui/icons-material/AccountCircle';
43
41
  import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType';
@@ -49,7 +47,7 @@ import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
49
47
  import EditIcon from '@mui/icons-material/Edit';
50
48
  import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
51
49
  import AddBoxIcon from '@mui/icons-material/AddBox';
52
- import { AnnotationFeatureModel, ApolloAssembly, CheckResult, ApolloRefSeq } from '@apollo-annotation/mst';
50
+ import { AnnotationFeatureModel, CheckResult, ApolloAssembly, ApolloRefSeq } from '@apollo-annotation/mst';
53
51
  import styled from '@emotion/styled';
54
52
  import ContentCopyIcon from '@mui/icons-material/ContentCopy';
55
53
  import ContentCutIcon from '@mui/icons-material/ContentCut';
@@ -69,7 +67,7 @@ import TrackChangesIcon from '@mui/icons-material/TrackChanges';
69
67
  import UndoIcon from '@mui/icons-material/Undo';
70
68
  import SaveIcon from '@mui/icons-material/Save';
71
69
 
72
- var version = "0.3.10";
70
+ var version = "0.3.12";
73
71
 
74
72
  const ApolloConfigSchema = ConfigurationSchema('ApolloInternetAccount', {
75
73
  baseURL: {
@@ -624,7 +622,6 @@ function getApolloInternetAccount(session) {
624
622
  return internetAccounts.find((ia) => ia.type === 'ApolloInternetAccount');
625
623
  }
626
624
 
627
- /* eslint-disable @typescript-eslint/unbound-method */
628
625
  const useStyles$g = makeStyles()((theme) => ({
629
626
  dialogTitle: {
630
627
  background: theme.palette.primary.main,
@@ -641,13 +638,9 @@ const useStyles$g = makeStyles()((theme) => ({
641
638
  const Dialog = observer(function JBrowseDialog(props) {
642
639
  const { classes } = useStyles$g();
643
640
  const { handleClose, title, ...other } = props;
644
- return (React.createElement(Dialog$1, { ...other, header: React.createElement(React.Fragment, null,
645
- React.createElement(DialogTitle, { className: classes.dialogTitle }, title),
646
- React.createElement(IconButton, { "aria-label": "close", onClick: handleClose, className: classes.closeButton },
647
- React.createElement(CloseIcon, null))) }));
641
+ return (jsx(Dialog$1, { ...other, header: jsxs(Fragment, { children: [jsx(DialogTitle, { className: classes.dialogTitle, children: title }), jsx(IconButton, { "aria-label": "close", onClick: handleClose, className: classes.closeButton, children: jsx(CloseIcon, {}) })] }) }));
648
642
  });
649
643
 
650
- /* eslint-disable @typescript-eslint/unbound-method */
651
644
  var FileType;
652
645
  (function (FileType) {
653
646
  FileType["GFF3"] = "text/x-gff3";
@@ -713,6 +706,7 @@ function AddAssembly({ changeManager, handleClose, session, }) {
713
706
  const [importFeatures, setImportFeatures] = useState(true);
714
707
  const [sequenceIsEditable, setSequenceIsEditable] = useState(false);
715
708
  const [submitted, setSubmitted] = useState(false);
709
+ const [strict, setStrict] = useState(true);
716
710
  const [fastaFile, setFastaFile] = useState(null);
717
711
  const [fastaIndexFile, setFastaIndexFile] = useState(null);
718
712
  const [fastaGziIndexFile, setFastaGziIndexFile] = useState(null);
@@ -759,36 +753,33 @@ function AddAssembly({ changeManager, handleClose, session, }) {
759
753
  locationType: 'UriLocation',
760
754
  uri,
761
755
  });
762
- if (apolloFetchFile) {
763
- const job = {
764
- name: `UploadAssemblyFile for ${assemblyName}`,
765
- statusMessage: 'Pre-validating',
766
- progressPct: 0,
767
- cancelCallback: () => {
768
- controller.abort('AddAssembly');
769
- jobsManager.abortJob(job.name);
770
- },
771
- };
772
- jobsManager.runJob(job);
773
- jobsManager.update(job.name, `Uploading ${file.name}, this may take awhile`);
774
- const { signal } = controller;
775
- const response = await apolloFetchFile(uri, {
776
- method: 'POST',
777
- body: formData,
778
- signal,
779
- });
780
- if (!response.ok) {
781
- const newErrorMessage = await createFetchErrorMessage(response, 'Error when inserting new assembly (while uploading file)');
782
- jobsManager.abortJob(job.name, newErrorMessage);
783
- setErrorMessage(newErrorMessage);
784
- return '';
785
- }
786
- const result = await response.json();
787
- const fileId = result._id;
788
- jobsManager.done(job);
789
- return fileId;
756
+ const job = {
757
+ name: `UploadAssemblyFile for ${assemblyName}`,
758
+ statusMessage: 'Pre-validating',
759
+ progressPct: 0,
760
+ cancelCallback: () => {
761
+ controller.abort(new DOMException(`Canceling adding of assembly "${assemblyName}"`, 'AbortError'));
762
+ jobsManager.abortJob(job.name);
763
+ },
764
+ };
765
+ jobsManager.runJob(job);
766
+ jobsManager.update(job.name, `Uploading ${file.name}, this may take awhile`);
767
+ const { signal } = controller;
768
+ const response = await apolloFetchFile(uri, {
769
+ method: 'POST',
770
+ body: formData,
771
+ signal,
772
+ });
773
+ if (!response.ok) {
774
+ const newErrorMessage = await createFetchErrorMessage(response, 'Error when inserting new assembly (while uploading file)');
775
+ jobsManager.abortJob(job.name, newErrorMessage);
776
+ setErrorMessage(newErrorMessage);
777
+ return '';
790
778
  }
791
- throw new Error('Failed to fetch');
779
+ const result = await response.json();
780
+ const fileId = result._id;
781
+ jobsManager.done(job);
782
+ return fileId;
792
783
  }
793
784
  async function onSubmit(event) {
794
785
  event.preventDefault();
@@ -822,6 +813,7 @@ function AddAssembly({ changeManager, handleClose, session, }) {
822
813
  assembly: new ObjectID().toHexString(),
823
814
  assemblyName,
824
815
  fileIds: { fa: faId },
816
+ parseOptions: { strict },
825
817
  });
826
818
  }
827
819
  else if (fileType === FileType.GFF3) {
@@ -909,151 +901,76 @@ function AddAssembly({ changeManager, handleClose, session, }) {
909
901
  setExpanded(panel);
910
902
  }
911
903
  };
912
- return (React.createElement(Dialog, { open: true, handleClose: handleClose, "data-testid": "add-assembly-dialog", title: "Add new assembly", maxWidth: false },
913
- React.createElement("form", { onSubmit: onSubmit, "data-testid": "submit-form" },
914
- React.createElement(DialogContent, { className: classes.dialog },
915
- loading ? React.createElement(LinearProgress, null) : null,
916
- React.createElement(TextField, { margin: "dense", id: "name", label: "Assembly name", type: "TextField", fullWidth: true, variant: "outlined", onChange: (e) => {
917
- setSubmitted(false);
918
- setAssemblyName(e.target.value);
919
- checkAssemblyName(e.target.value);
920
- }, disabled: submitted && !errorMessage }),
921
- React.createElement(Accordion, { disableGutters: true, elevation: 0, square: true, className: classes.accordion, expanded: expanded === 'panelFastaInput', onChange: handleAccordionChange('panelFastaInput') },
922
- React.createElement(AccordionSummary, { className: classes.accordionSummary, expandIcon: expanded === 'panelFastaInput' ? (React.createElement(RadioButtonCheckedIcon, { className: classes.radioIcon, sx: { fontSize: '1.2rem', ml: 5 } })) : (React.createElement(RadioButtonUncheckedIcon, { className: classes.radioIcon, sx: { fontSize: '1.2rem', mr: 5 } })), "aria-controls": "panelFastaInputd-content", id: "panelFastaInputd-header" },
923
- React.createElement(Typography, { component: "span" }, "FASTA input")),
924
- React.createElement(AccordionDetails, { className: classes.accordionDetails },
925
- React.createElement(FormGroup, null,
926
- React.createElement(FormControlLabel, { "data-testid": "files-on-url-checkbox", control: React.createElement(Checkbox, { onChange: () => {
927
- setFileType(fileType === FileType.EXTERNAL
928
- ? FileType.BGZIP_FASTA
929
- : FileType.EXTERNAL);
930
- if (fileType === FileType.EXTERNAL) {
931
- setSequenceIsEditable(false);
932
- }
933
- }, checked: fileType === FileType.EXTERNAL, disabled: sequenceIsEditable && fileType !== FileType.GFF3 }), label: React.createElement(Box, { display: "flex", alignItems: "center" },
934
- "Use external URLs",
935
- React.createElement(Tooltip, { title: "Use external URLs to provide FASTA and index files. Does not copy the files to the Apollo collaboration server, so ensure the URLs are stable.", placement: "top-start" },
936
- React.createElement(IconButton, { size: "small" },
937
- React.createElement(InfoIcon, { sx: { fontSize: 18 } })))) }),
938
- React.createElement(FormControlLabel, { "data-testid": "sequence-is-editable-checkbox", control: React.createElement(Checkbox, { onChange: () => {
939
- setSequenceIsEditable(!sequenceIsEditable);
940
- } }), checked: sequenceIsEditable, disabled: fileType === FileType.EXTERNAL, label: React.createElement(Box, { display: "flex", alignItems: "center" },
941
- "Store sequence in database",
942
- React.createElement(Tooltip, { title: "Enables users to edit the genomic sequence, but comes with performance impacts. Use with care.", placement: "top-start" },
943
- React.createElement(IconButton, { size: "small" },
944
- React.createElement(InfoIcon, { sx: { fontSize: 18 } })))) }),
945
- React.createElement(FormControlLabel, { "data-testid": "fasta-is-gzip-checkbox", control: React.createElement(Checkbox, { checked: !sequenceIsEditable || fastaGzipChecked, onChange: () => {
946
- if (sequenceIsEditable) {
947
- setFastaGzipChecked(!fastaGzipChecked);
948
- }
949
- else {
950
- setFastaGzipChecked(true);
951
- }
952
- }, disabled: !sequenceIsEditable }), label: "FASTA is gzip compressed" }),
953
- fileType === FileType.BGZIP_FASTA ||
954
- fileType === FileType.GFF3 ? (React.createElement(Table, { size: "small", sx: { mt: 2 } },
955
- React.createElement(TableBody, null,
956
- React.createElement(TableRow, null,
957
- React.createElement(TableCell, { style: { borderBottomWidth: 0 } },
958
- React.createElement(Box, { display: "flex", alignItems: "center" },
959
- React.createElement("span", null, "FASTA"),
960
- React.createElement(Tooltip, { title: 'Unless "Store sequence in database" enabled, FASTA input must be compressed with bgzip and indexed with samtools faidx (or equivalent). Compression is optional for sequences stored in the database.' },
961
- React.createElement(IconButton, { size: "small" },
962
- React.createElement(InfoIcon, { sx: { fontSize: 18 } }))))),
963
- React.createElement(TableCell, { style: { borderBottomWidth: 0 } },
964
- React.createElement("input", { "data-testid": "fasta-input-file", type: "file", onChange: (e) => {
965
- const file = e.target.files?.item(0);
966
- if (file) {
967
- setFastaFile(file);
968
- if (file.name.endsWith('.gz')) {
969
- setFastaGzipChecked(true);
904
+ return (jsxs(Dialog, { open: true, handleClose: handleClose, "data-testid": "add-assembly-dialog", title: "Add new assembly", maxWidth: false, children: [jsxs("form", { onSubmit: onSubmit, "data-testid": "submit-form", children: [jsxs(DialogContent, { className: classes.dialog, children: [loading ? jsx(LinearProgress, {}) : null, jsx(TextField, { margin: "dense", id: "name", label: "Assembly name", type: "TextField", fullWidth: true, variant: "outlined", onChange: (e) => {
905
+ setSubmitted(false);
906
+ setAssemblyName(e.target.value);
907
+ checkAssemblyName(e.target.value);
908
+ }, disabled: submitted && !errorMessage }), jsxs(Accordion, { disableGutters: true, elevation: 0, square: true, className: classes.accordion, expanded: expanded === 'panelFastaInput', onChange: handleAccordionChange('panelFastaInput'), children: [jsx(AccordionSummary, { className: classes.accordionSummary, expandIcon: expanded === 'panelFastaInput' ? (jsx(RadioButtonCheckedIcon, { className: classes.radioIcon, sx: { fontSize: '1.2rem', ml: 5 } })) : (jsx(RadioButtonUncheckedIcon, { className: classes.radioIcon, sx: { fontSize: '1.2rem', mr: 5 } })), "aria-controls": "panelFastaInputd-content", id: "panelFastaInputd-header", children: jsx(Typography, { component: "span", children: "FASTA input" }) }), jsx(AccordionDetails, { className: classes.accordionDetails, children: jsxs(FormGroup, { children: [jsx(FormControlLabel, { "data-testid": "files-on-url-checkbox", control: jsx(Checkbox, { onChange: () => {
909
+ setFileType(fileType === FileType.EXTERNAL
910
+ ? FileType.BGZIP_FASTA
911
+ : FileType.EXTERNAL);
912
+ if (fileType === FileType.EXTERNAL) {
913
+ setSequenceIsEditable(false);
914
+ }
915
+ }, checked: fileType === FileType.EXTERNAL, disabled: sequenceIsEditable && fileType !== FileType.GFF3 }), label: jsxs(Box, { display: "flex", alignItems: "center", children: ["Use external URLs", jsx(Tooltip, { title: "Use external URLs to provide FASTA and index files. Does not copy the files to the Apollo collaboration server, so ensure the URLs are stable.", placement: "top-start", children: jsx(IconButton, { size: "small", children: jsx(InfoIcon, { sx: { fontSize: 18 } }) }) })] }) }), jsx(FormControlLabel, { "data-testid": "sequence-is-editable-checkbox", control: jsx(Checkbox, { onChange: () => {
916
+ setSequenceIsEditable(!sequenceIsEditable);
917
+ } }), checked: sequenceIsEditable, disabled: fileType === FileType.EXTERNAL, label: jsxs(Box, { display: "flex", alignItems: "center", children: ["Store sequence in database", jsx(Tooltip, { title: "Enables users to edit the genomic sequence, but comes with performance impacts. Use with care.", placement: "top-start", children: jsx(IconButton, { size: "small", children: jsx(InfoIcon, { sx: { fontSize: 18 } }) }) })] }) }), jsx(FormControlLabel, { "data-testid": "fasta-is-gzip-checkbox", control: jsx(Checkbox, { checked: !sequenceIsEditable || fastaGzipChecked, onChange: () => {
918
+ if (sequenceIsEditable) {
919
+ setFastaGzipChecked(!fastaGzipChecked);
920
+ }
921
+ else {
922
+ setFastaGzipChecked(true);
923
+ }
924
+ }, disabled: !sequenceIsEditable }), label: "FASTA is gzip compressed" }), fileType === FileType.BGZIP_FASTA ||
925
+ fileType === FileType.GFF3 ? (jsx(Table, { size: "small", sx: { mt: 2 }, children: jsxs(TableBody, { children: [jsxs(TableRow, { children: [jsx(TableCell, { style: { borderBottomWidth: 0 }, children: jsxs(Box, { display: "flex", alignItems: "center", children: [jsx("span", { children: "FASTA" }), jsx(Tooltip, { title: 'Unless "Store sequence in database" enabled, FASTA input must be compressed with bgzip and indexed with samtools faidx (or equivalent). Compression is optional for sequences stored in the database.', children: jsx(IconButton, { size: "small", children: jsx(InfoIcon, { sx: { fontSize: 18 } }) }) })] }) }), jsx(TableCell, { style: { borderBottomWidth: 0 }, children: jsx("input", { "data-testid": "fasta-input-file", type: "file", onChange: (e) => {
926
+ const file = e.target.files?.item(0);
927
+ if (file) {
928
+ setFastaFile(file);
929
+ if (file.name.endsWith('.gz')) {
930
+ setFastaGzipChecked(true);
931
+ }
932
+ }
933
+ }, disabled: submitted && !errorMessage }) })] }), jsxs(TableRow, { children: [jsx(TableCell, { style: { borderBottomWidth: 0 }, children: "FASTA index (.fai)" }), jsx(TableCell, { style: { borderBottomWidth: 0 }, children: jsx("input", { "data-testid": "fai-input-file", type: "file", onChange: (e) => {
934
+ setFastaIndexFile(e.target.files?.item(0) ?? null);
935
+ }, disabled: (submitted && !errorMessage) || sequenceIsEditable }) })] }), jsxs(TableRow, { children: [jsx(TableCell, { style: { borderBottomWidth: 0 }, children: "FASTA binary index (.gzi)" }), jsx(TableCell, { style: { borderBottomWidth: 0 }, children: jsx("input", { "data-testid": "gzi-input-file", type: "file", onChange: (e) => {
936
+ setFastaGziIndexFile(e.target.files?.item(0) ?? null);
937
+ }, disabled: (submitted && !errorMessage) || sequenceIsEditable }) })] })] }) })) : (jsx(Table, { size: "small", sx: { mt: 2 }, children: jsxs(TableBody, { children: [jsxs(TableRow, { children: [jsx(TableCell, { style: { borderBottomWidth: 0 }, children: jsxs(Box, { display: "flex", alignItems: "center", children: [jsx("span", { children: "FASTA" }), jsx(Tooltip, { title: "Remote FASTA input must be compressed with bgzip and indexed with samtools faidx (or equivalent)", children: jsx(IconButton, { size: "small", children: jsx(InfoIcon, { sx: { fontSize: 18 } }) }) })] }) }), jsx(TableCell, { style: { borderBottomWidth: 0 }, children: jsx(TextField, { "data-testid": "fasta-input-url", variant: "outlined", value: fastaUrl, error: !validFastaUrl, onChange: (e) => {
938
+ const { value } = e.target;
939
+ setFastaUrl(value);
940
+ setFastaIndexUrl(value ? `${value}.fai` : '');
941
+ setFastaGziIndexUrl(value ? `${value}.gzi` : '');
942
+ }, disabled: submitted && !errorMessage, slotProps: {
943
+ input: {
944
+ startAdornment: (jsx(InputAdornment, { position: "start", children: jsx(LinkIcon, {}) })),
945
+ },
946
+ } }) })] }), jsxs(TableRow, { children: [jsx(TableCell, { style: { borderBottomWidth: 0 }, children: "FASTA index (.fai)" }), jsx(TableCell, { style: { borderBottomWidth: 0 }, children: jsx(TextField, { "data-testid": "fai-input-url", variant: "outlined", value: fastaIndexUrl, error: !validFastaIndexUrl, onChange: (e) => {
947
+ setFastaIndexUrl(e.target.value);
948
+ }, disabled: submitted && !errorMessage, slotProps: {
949
+ input: {
950
+ startAdornment: (jsx(InputAdornment, { position: "start", children: jsx(LinkIcon, {}) })),
951
+ },
952
+ } }) })] }), jsxs(TableRow, { children: [jsx(TableCell, { style: { borderBottomWidth: 0 }, children: "FASTA binary index (.gzi)" }), jsx(TableCell, { style: { borderBottomWidth: 0 }, children: jsx(TextField, { "data-testid": "gzi-input-url", variant: "outlined", value: fastaGziIndexUrl, error: !validFastaGziIndexUrl, onChange: (e) => {
953
+ setFastaGziIndexUrl(e.target.value);
954
+ }, disabled: submitted && !errorMessage, slotProps: {
955
+ input: {
956
+ startAdornment: (jsx(InputAdornment, { position: "start", children: jsx(LinkIcon, {}) })),
957
+ },
958
+ } }) })] })] }) }))] }) })] }), jsxs(Accordion, { disableGutters: true, elevation: 0, square: true, className: classes.accordion, expanded: expanded === 'panelGffInput', onChange: handleAccordionChange('panelGffInput'), children: [jsx(AccordionSummary, { className: classes.accordionSummary, expandIcon: expanded === 'panelGffInput' ? (jsx(RadioButtonCheckedIcon, { className: classes.radioIcon, sx: { fontSize: '1.2rem', ml: 5 } })) : (jsx(RadioButtonUncheckedIcon, { className: classes.radioIcon, sx: { fontSize: '1.2rem', mr: 5 } })), "aria-controls": "panelGffInputd-content", children: jsxs(Typography, { component: "span", children: ["GFF3 input", jsx(Tooltip, { title: "GFF3 must includes FASTA sequences. File can be gzip compressed.", children: jsx(InfoIcon, { className: classes.radioIcon, sx: { fontSize: 18 } }) })] }) }), jsx(AccordionDetails, { className: classes.accordionDetails, children: jsxs(Box, { style: { marginTop: 20 }, children: [jsx("input", { "data-testid": "gff3-input-file", type: "file", disabled: submitted && !errorMessage, onChange: (e) => {
959
+ const file = e.target.files?.item(0);
960
+ if (file) {
961
+ setFastaFile(file);
962
+ setFileType(FileType.GFF3);
963
+ if (file.name.endsWith('.gz')) {
964
+ setGff3GzipChecked(true);
965
+ }
970
966
  }
971
- }
972
- }, disabled: submitted && !errorMessage }))),
973
- React.createElement(TableRow, null,
974
- React.createElement(TableCell, { style: { borderBottomWidth: 0 } }, "FASTA index (.fai)"),
975
- React.createElement(TableCell, { style: { borderBottomWidth: 0 } },
976
- React.createElement("input", { "data-testid": "fai-input-file", type: "file", onChange: (e) => {
977
- setFastaIndexFile(e.target.files?.item(0) ?? null);
978
- }, disabled: (submitted && !errorMessage) || sequenceIsEditable }))),
979
- React.createElement(TableRow, null,
980
- React.createElement(TableCell, { style: { borderBottomWidth: 0 } }, "FASTA binary index (.gzi)"),
981
- React.createElement(TableCell, { style: { borderBottomWidth: 0 } },
982
- React.createElement("input", { "data-testid": "gzi-input-file", type: "file", onChange: (e) => {
983
- setFastaGziIndexFile(e.target.files?.item(0) ?? null);
984
- }, disabled: (submitted && !errorMessage) || sequenceIsEditable })))))) : (React.createElement(Table, { size: "small", sx: { mt: 2 } },
985
- React.createElement(TableBody, null,
986
- React.createElement(TableRow, null,
987
- React.createElement(TableCell, { style: { borderBottomWidth: 0 } },
988
- React.createElement(Box, { display: "flex", alignItems: "center" },
989
- React.createElement("span", null, "FASTA"),
990
- React.createElement(Tooltip, { title: "Remote FASTA input must be compressed with bgzip and indexed with samtools faidx (or equivalent)" },
991
- React.createElement(IconButton, { size: "small" },
992
- React.createElement(InfoIcon, { sx: { fontSize: 18 } }))))),
993
- React.createElement(TableCell, { style: { borderBottomWidth: 0 } },
994
- React.createElement(TextField, { "data-testid": "fasta-input-url", variant: "outlined", value: fastaUrl, error: !validFastaUrl, onChange: (e) => {
995
- const { value } = e.target;
996
- setFastaUrl(value);
997
- setFastaIndexUrl(value ? `${value}.fai` : '');
998
- setFastaGziIndexUrl(value ? `${value}.gzi` : '');
999
- }, disabled: submitted && !errorMessage, slotProps: {
1000
- input: {
1001
- startAdornment: (React.createElement(InputAdornment, { position: "start" },
1002
- React.createElement(LinkIcon, null))),
1003
- },
1004
- } }))),
1005
- React.createElement(TableRow, null,
1006
- React.createElement(TableCell, { style: { borderBottomWidth: 0 } }, "FASTA index (.fai)"),
1007
- React.createElement(TableCell, { style: { borderBottomWidth: 0 } },
1008
- React.createElement(TextField, { "data-testid": "fai-input-url", variant: "outlined", value: fastaIndexUrl, error: !validFastaIndexUrl, onChange: (e) => {
1009
- setFastaIndexUrl(e.target.value);
1010
- }, disabled: submitted && !errorMessage, slotProps: {
1011
- input: {
1012
- startAdornment: (React.createElement(InputAdornment, { position: "start" },
1013
- React.createElement(LinkIcon, null))),
1014
- },
1015
- } }))),
1016
- React.createElement(TableRow, null,
1017
- React.createElement(TableCell, { style: { borderBottomWidth: 0 } }, "FASTA binary index (.gzi)"),
1018
- React.createElement(TableCell, { style: { borderBottomWidth: 0 } },
1019
- React.createElement(TextField, { "data-testid": "gzi-input-url", variant: "outlined", value: fastaGziIndexUrl, error: !validFastaGziIndexUrl, onChange: (e) => {
1020
- setFastaGziIndexUrl(e.target.value);
1021
- }, disabled: submitted && !errorMessage, slotProps: {
1022
- input: {
1023
- startAdornment: (React.createElement(InputAdornment, { position: "start" },
1024
- React.createElement(LinkIcon, null))),
1025
- },
1026
- } }))))))))),
1027
- React.createElement(Accordion, { disableGutters: true, elevation: 0, square: true, className: classes.accordion, expanded: expanded === 'panelGffInput', onChange: handleAccordionChange('panelGffInput') },
1028
- React.createElement(AccordionSummary, { className: classes.accordionSummary, expandIcon: expanded === 'panelGffInput' ? (React.createElement(RadioButtonCheckedIcon, { className: classes.radioIcon, sx: { fontSize: '1.2rem', ml: 5 } })) : (React.createElement(RadioButtonUncheckedIcon, { className: classes.radioIcon, sx: { fontSize: '1.2rem', mr: 5 } })), "aria-controls": "panelGffInputd-content" },
1029
- React.createElement(Typography, { component: "span" },
1030
- "GFF3 input",
1031
- React.createElement(Tooltip, { title: "GFF3 must includes FASTA sequences. File can be gzip compressed." },
1032
- React.createElement(InfoIcon, { className: classes.radioIcon, sx: { fontSize: 18 } })))),
1033
- React.createElement(AccordionDetails, { className: classes.accordionDetails },
1034
- React.createElement(Box, { style: { marginTop: 20 } },
1035
- React.createElement("input", { "data-testid": "gff3-input-file", type: "file", disabled: submitted && !errorMessage, onChange: (e) => {
1036
- const file = e.target.files?.item(0);
1037
- if (file) {
1038
- setFastaFile(file);
1039
- setFileType(FileType.GFF3);
1040
- if (file.name.endsWith('.gz')) {
1041
- setGff3GzipChecked(true);
1042
- }
1043
- }
1044
- } }),
1045
- React.createElement(FormGroup, { style: { display: 'grid' } },
1046
- React.createElement(FormControlLabel, { control: React.createElement(Checkbox, { checked: importFeatures, onChange: () => {
1047
- setImportFeatures(!importFeatures);
1048
- }, disabled: submitted && !errorMessage }), label: "Load features from GFF3 file" }),
1049
- React.createElement(FormControlLabel, { "data-testid": "gff3-is-gzip-checkbox", control: React.createElement(Checkbox, { checked: gff3GzipChecked, onChange: () => {
1050
- setGff3GzipChecked(!gff3GzipChecked);
1051
- }, disabled: submitted && !errorMessage }), label: "GFF3 is gzip compressed" })))))),
1052
- React.createElement(DialogActions, null,
1053
- React.createElement(Button, { disabled: !checkSumbission(validAsm, sequenceIsEditable, fileType, fastaFile, fastaIndexFile, fastaGziIndexFile, validFastaUrl, validFastaIndexUrl, validFastaGziIndexUrl) || submitted, variant: "contained", type: "submit", "data-testid": "submit-button" }, submitted ? 'Submitting...' : 'Submit'),
1054
- React.createElement(Button, { variant: "outlined", type: "submit", onClick: handleClose }, "Cancel"))),
1055
- errorMessage ? (React.createElement(DialogContent, null,
1056
- React.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
967
+ } }), jsxs(FormGroup, { style: { display: 'grid' }, children: [jsx(FormControlLabel, { control: jsx(Checkbox, { checked: importFeatures, onChange: () => {
968
+ setImportFeatures(!importFeatures);
969
+ }, disabled: submitted && !errorMessage }), label: "Load features from GFF3 file" }), jsx(FormControlLabel, { label: "Strict parsing", disabled: !importFeatures || (submitted && !errorMessage), control: jsx(Checkbox, { checked: strict, onChange: (e) => {
970
+ setStrict(e.target.checked);
971
+ } }) }), jsx(FormHelperText, { children: "Don't import any features if any lines in the GFF3 are unable to be processed" }), jsx(FormControlLabel, { "data-testid": "gff3-is-gzip-checkbox", control: jsx(Checkbox, { checked: gff3GzipChecked, onChange: () => {
972
+ setGff3GzipChecked(!gff3GzipChecked);
973
+ }, disabled: submitted && !errorMessage }), label: "GFF3 is gzip compressed" })] })] }) })] })] }), jsxs(DialogActions, { children: [jsx(Button, { disabled: !checkSumbission(validAsm, sequenceIsEditable, fileType, fastaFile, fastaIndexFile, fastaGziIndexFile, validFastaUrl, validFastaIndexUrl, validFastaGziIndexUrl) || submitted, variant: "contained", type: "submit", "data-testid": "submit-button", children: submitted ? 'Submitting...' : 'Submit' }), jsx(Button, { variant: "outlined", type: "submit", onClick: handleClose, children: "Cancel" })] })] }), errorMessage ? (jsx(DialogContent, { children: jsx(DialogContentText, { color: "error", children: errorMessage }) })) : null] }));
1057
974
  }
1058
975
 
1059
976
  const columns$1 = [
@@ -1094,18 +1011,13 @@ function AddAssemblyAliases({ changeManager, handleClose, session, }) {
1094
1011
  handleClose();
1095
1012
  return newRow;
1096
1013
  };
1097
- return (React.createElement(Dialog, { open: true, title: "Add assembly aliases", handleClose: handleClose, maxWidth: 'sm', "data-testid": "add-assembly-alias", fullWidth: true },
1098
- React.createElement(DialogContent, { style: { display: 'flex', flexDirection: 'column' } },
1099
- React.createElement(Box, { sx: { height: 400, width: '100%' } },
1100
- React.createElement(DataGrid, { rows: rows, columns: columns$1, initialState: {
1101
- pagination: {
1102
- paginationModel: {
1103
- pageSize: 5,
1014
+ return (jsxs(Dialog, { open: true, title: "Add assembly aliases", handleClose: handleClose, maxWidth: 'sm', "data-testid": "add-assembly-alias", fullWidth: true, children: [jsx(DialogContent, { style: { display: 'flex', flexDirection: 'column' }, children: jsx(Box, { sx: { height: 400, width: '100%' }, children: jsx(DataGrid, { rows: rows, columns: columns$1, initialState: {
1015
+ pagination: {
1016
+ paginationModel: {
1017
+ pageSize: 5,
1018
+ },
1104
1019
  },
1105
- },
1106
- }, pageSizeOptions: [5], processRowUpdate: processRowUpdate, disableRowSelectionOnClick: true }))),
1107
- errorMessage ? (React.createElement(DialogContent, null,
1108
- React.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
1020
+ }, pageSizeOptions: [5], processRowUpdate: processRowUpdate, disableRowSelectionOnClick: true }) }) }), errorMessage ? (jsx(DialogContent, { children: jsx(DialogContentText, { color: "error", children: errorMessage }) })) : null] }));
1109
1021
  }
1110
1022
 
1111
1023
  /** set of words that should be ignored by fulltext indexing */
@@ -1289,6 +1201,8 @@ function expandPrefixes(uri, prefixes) {
1289
1201
  }
1290
1202
 
1291
1203
  /* eslint-disable @typescript-eslint/no-unnecessary-condition */
1204
+ /* eslint-disable @typescript-eslint/no-unsafe-return */
1205
+ // jsonpath triggers this rule for some reason. import { query } from 'jsonpath' does not work
1292
1206
  /** special value of jsonPath that gets the IRI (that is, ID) of the node with the configured prefixes applied */
1293
1207
  const PREFIXED_ID_PATH = '$PREFIXED_ID';
1294
1208
  /** small wrapper for jsonpath.query that intercepts requests for the special prefixed ID path */
@@ -1296,7 +1210,15 @@ function jsonPathQuery(node, path, prefixes) {
1296
1210
  if (path === PREFIXED_ID_PATH) {
1297
1211
  return [applyPrefixes(node.id, prefixes)];
1298
1212
  }
1299
- return jsonpath.query(node, path);
1213
+ let response;
1214
+ try {
1215
+ response = jsonpath.query(node, path);
1216
+ }
1217
+ catch {
1218
+ // eslint-disable-next-line unicorn/prefer-structured-clone
1219
+ response = jsonpath.query(JSON.parse(JSON.stringify(node)), path);
1220
+ }
1221
+ return response;
1300
1222
  }
1301
1223
  function wordsInString(str) {
1302
1224
  return str
@@ -1637,6 +1559,7 @@ async function isDatabaseCurrent(db) {
1637
1559
  }
1638
1560
 
1639
1561
  /* eslint-disable @typescript-eslint/only-throw-error */
1562
+ /* eslint-disable unicorn/no-await-expression-member */
1640
1563
  async function arrayFromAsync(iter) {
1641
1564
  const a = [];
1642
1565
  for await (const i of iter) {
@@ -2132,7 +2055,6 @@ async function fetchValidDescendantTerms(parentFeature, ontologyStore, _signal)
2132
2055
  return subpartTerms;
2133
2056
  }
2134
2057
 
2135
- /* eslint-disable @typescript-eslint/no-unnecessary-condition */
2136
2058
  function OntologyTermAutocomplete({ fetchValidTerms, filterTerms: filterTermsProp, includeDeprecated, onChange, ontologyName, ontologyVersion, renderInput, session, style, value: valueString, }) {
2137
2059
  const [open, setOpen] = useState(false);
2138
2060
  const [termChoices, setTermChoices] = useState();
@@ -2163,7 +2085,7 @@ function OntologyTermAutocomplete({ fetchValidTerms, filterTerms: filterTermsPro
2163
2085
  });
2164
2086
  }
2165
2087
  return () => {
2166
- controller.abort('OntologyTermAutocomplete matcher');
2088
+ controller.abort(new DOMException('Cancel getting current term from ontology store', 'AbortError'));
2167
2089
  };
2168
2090
  }, [session, valueString, filterTerms, ontologyStore, needToLoadCurrentTerm]);
2169
2091
  // effect for loading term autocompletions
@@ -2182,7 +2104,7 @@ function OntologyTermAutocomplete({ fetchValidTerms, filterTerms: filterTermsPro
2182
2104
  });
2183
2105
  }
2184
2106
  return () => {
2185
- controller.abort('OntologyTermAutocomplete loader');
2107
+ controller.abort(new DOMException('Canceling getting valid terms from ontology store', 'AbortError'));
2186
2108
  };
2187
2109
  }, [
2188
2110
  needToLoadTermChoices,
@@ -2210,14 +2132,14 @@ function OntologyTermAutocomplete({ fetchValidTerms, filterTerms: filterTermsPro
2210
2132
  extraTextFieldParams.error = true;
2211
2133
  extraTextFieldParams.helperText = currentOntologyTermInvalid;
2212
2134
  }
2213
- return (React.createElement(Autocomplete, { style: style, autoComplete: true, filterSelectedOptions: true, disableClearable: true, selectOnFocus: true, clearOnBlur: true, handleHomeEndKeys: true, freeSolo: true, value: valueString, options: termChoices ?? [], onOpen: () => {
2135
+ return (jsx(Autocomplete, { style: style, autoComplete: true, filterSelectedOptions: true, disableClearable: true, selectOnFocus: true, clearOnBlur: true, handleHomeEndKeys: true, freeSolo: true, value: valueString, options: termChoices ?? [], onOpen: () => {
2214
2136
  setOpen(true);
2215
2137
  }, onClose: () => {
2216
2138
  setOpen(false);
2217
2139
  },
2218
2140
  // noOptionsText={valueString ? 'No matches' : 'Start typing to search'}
2219
2141
  loading: needToLoadTermChoices, renderInput: renderInput ??
2220
- ((params) => React.createElement(TextField, { ...params, ...extraTextFieldParams })), getOptionLabel: (option) => {
2142
+ ((params) => jsx(TextField, { ...params, ...extraTextFieldParams })), getOptionLabel: (option) => {
2221
2143
  if (typeof option === 'string') {
2222
2144
  return option;
2223
2145
  }
@@ -2250,7 +2172,6 @@ async function getValidTerms(ontologyStore, fetchValidTerms, filterTerms, signal
2250
2172
  return filterTerms ? result.filter((element) => filterTerms(element)) : result;
2251
2173
  }
2252
2174
 
2253
- /* eslint-disable @typescript-eslint/unbound-method */
2254
2175
  function AddChildFeature({ changeManager, handleClose, session, sourceAssemblyId, sourceFeature, }) {
2255
2176
  const [end, setEnd] = useState(String(sourceFeature.max));
2256
2177
  const [start, setStart] = useState(String(sourceFeature.min + 1));
@@ -2293,25 +2214,15 @@ function AddChildFeature({ changeManager, handleClose, session, sourceAssemblyId
2293
2214
  setType(newType);
2294
2215
  }
2295
2216
  const error = Number(end) <= Number(start);
2296
- return (React.createElement(Dialog, { open: true, title: "Add new child feature", handleClose: handleClose, maxWidth: false, "data-testid": "add-feature-dialog" },
2297
- React.createElement("form", { onSubmit: onSubmit },
2298
- React.createElement(DialogContent, { style: { display: 'flex', flexDirection: 'column' } },
2299
- React.createElement(TextField, { margin: "dense", id: "start", label: "Start", type: "number", fullWidth: true, variant: "outlined", value: start, onChange: (e) => {
2300
- setStart(e.target.value);
2301
- } }),
2302
- React.createElement(TextField, { margin: "dense", id: "end", label: "End", type: "number", fullWidth: true, variant: "outlined", value: end, onChange: (e) => {
2303
- setEnd(e.target.value);
2304
- }, error: error, helperText: error ? '"End" must be greater than "Start"' : null }),
2305
- React.createElement(OntologyTermAutocomplete, { session: session, ontologyName: "Sequence Ontology", style: { width: 170 }, value: type, filterTerms: isOntologyClass, fetchValidTerms: fetchValidTerms.bind(null, sourceFeature), renderInput: (params) => (React.createElement(TextField, { ...params, label: "Type", variant: "outlined", fullWidth: true, error: Boolean(typeWarningText), helperText: typeWarningText })), onChange: (oldValue, newValue) => {
2306
- if (newValue) {
2307
- handleChangeType(newValue);
2308
- }
2309
- } })),
2310
- React.createElement(DialogActions, null,
2311
- React.createElement(Button, { variant: "contained", type: "submit", disabled: error || !(start && end && type) }, "Submit"),
2312
- React.createElement(Button, { variant: "outlined", type: "submit", onClick: handleClose }, "Cancel"))),
2313
- errorMessage ? (React.createElement(DialogContent, null,
2314
- React.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
2217
+ return (jsxs(Dialog, { open: true, title: "Add new child feature", handleClose: handleClose, maxWidth: false, "data-testid": "add-feature-dialog", children: [jsxs("form", { onSubmit: onSubmit, children: [jsxs(DialogContent, { style: { display: 'flex', flexDirection: 'column' }, children: [jsx(TextField, { margin: "dense", id: "start", label: "Start", type: "number", fullWidth: true, variant: "outlined", value: start, onChange: (e) => {
2218
+ setStart(e.target.value);
2219
+ } }), jsx(TextField, { margin: "dense", id: "end", label: "End", type: "number", fullWidth: true, variant: "outlined", value: end, onChange: (e) => {
2220
+ setEnd(e.target.value);
2221
+ }, error: error, helperText: error ? '"End" must be greater than "Start"' : null }), jsx(OntologyTermAutocomplete, { session: session, ontologyName: "Sequence Ontology", style: { width: 170 }, value: type, filterTerms: isOntologyClass, fetchValidTerms: fetchValidTerms.bind(null, sourceFeature), renderInput: (params) => (jsx(TextField, { ...params, label: "Type", variant: "outlined", fullWidth: true, error: Boolean(typeWarningText), helperText: typeWarningText })), onChange: (oldValue, newValue) => {
2222
+ if (newValue) {
2223
+ handleChangeType(newValue);
2224
+ }
2225
+ } })] }), jsxs(DialogActions, { children: [jsx(Button, { variant: "contained", type: "submit", disabled: error || !(start && end && type), children: "Submit" }), jsx(Button, { variant: "outlined", type: "submit", onClick: handleClose, children: "Cancel" })] })] }), errorMessage ? (jsx(DialogContent, { children: jsx(DialogContentText, { color: "error", children: errorMessage }) })) : null] }));
2315
2226
  }
2316
2227
 
2317
2228
  class BackendDriver {
@@ -2322,6 +2233,8 @@ class BackendDriver {
2322
2233
  }
2323
2234
 
2324
2235
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
2236
+ /* eslint-disable @typescript-eslint/no-unsafe-call */
2237
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
2325
2238
  class ChangeManager {
2326
2239
  dataStore;
2327
2240
  constructor(dataStore) {
@@ -2351,7 +2264,7 @@ class ChangeManager {
2351
2264
  statusMessage: 'Pre-validating',
2352
2265
  progressPct: 0,
2353
2266
  cancelCallback: () => {
2354
- controller.abort('ChangeManager');
2267
+ controller.abort(new DOMException(`Cancelling change "${change.typeName}"`, 'AbortError'));
2355
2268
  },
2356
2269
  };
2357
2270
  if (updateJobsManager) {
@@ -2466,6 +2379,11 @@ class ChangeManager {
2466
2379
  }
2467
2380
 
2468
2381
  /* eslint-disable @typescript-eslint/no-base-to-string */
2382
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
2383
+ /* eslint-disable @typescript-eslint/no-unsafe-return */
2384
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
2385
+ /* eslint-disable @typescript-eslint/no-unsafe-call */
2386
+ /* eslint-disable @typescript-eslint/no-unnecessary-condition */
2469
2387
  class CollaborationServerDriver extends BackendDriver {
2470
2388
  inFlight = new Map();
2471
2389
  refSeqMaps = new Map();
@@ -2963,7 +2881,6 @@ class DesktopFileDriver extends BackendDriver {
2963
2881
  }
2964
2882
  }
2965
2883
 
2966
- /* eslint-disable @typescript-eslint/unbound-method */
2967
2884
  var NewFeature;
2968
2885
  (function (NewFeature) {
2969
2886
  NewFeature["GENE_AND_SUBFEATURES"] = "GENE_AND_SUBFEATURES";
@@ -3122,45 +3039,16 @@ function AddFeature({ changeManager, handleClose, region, session, }) {
3122
3039
  (!strand && type === NewFeature.TRANSCRIPT_AND_SUBFEATURES)) {
3123
3040
  submitDisabled = true;
3124
3041
  }
3125
- return (React.createElement(Dialog, { open: true, title: "Add new feature", handleClose: handleClose, maxWidth: false, "data-testid": "add-feature-dialog" },
3126
- React.createElement("form", { onSubmit: onSubmit, "data-testid": "submit-form" },
3127
- React.createElement(DialogContent, { style: { display: 'flex', flexDirection: 'column' } },
3128
- React.createElement(TextField, { margin: "dense", id: "start", label: "Start", type: "number", fullWidth: true, variant: "outlined", value: Number(start), onChange: (e) => {
3129
- setStart(e.target.value);
3130
- } }),
3131
- React.createElement(TextField, { margin: "dense", id: "end", label: "End", type: "number", fullWidth: true, variant: "outlined", value: end, onChange: (e) => {
3132
- setEnd(e.target.value);
3133
- }, error: error, helperText: error ? '"End" must be greater than "Start"' : null }),
3134
- React.createElement(FormControl, null,
3135
- React.createElement(InputLabel, { id: "demo-simple-select-label" }, "Strand"),
3136
- React.createElement(Select, { labelId: "demo-simple-select-label", id: "demo-simple-select", label: "Strand", value: strand?.toString(), onChange: handleChangeStrand },
3137
- React.createElement(MenuItem, { value: undefined }),
3138
- React.createElement(MenuItem, { value: 1 }, "+"),
3139
- React.createElement(MenuItem, { value: -1 }, "-"))),
3140
- React.createElement(FormControl, { style: { marginTop: 20 } },
3141
- React.createElement(RadioGroup, { "aria-labelledby": "demo-radio-buttons-group-label", defaultValue: NewFeature.GENE_AND_SUBFEATURES, name: "radio-buttons-group", value: type, onChange: handleTypeChange },
3142
- React.createElement(FormControlLabel, { value: NewFeature.GENE_AND_SUBFEATURES, control: React.createElement(Radio, null), label: React.createElement(Box, { display: "flex", alignItems: "center" },
3143
- "Add gene and sub-features",
3144
- React.createElement(Tooltip, { title: "This is a shortcut to create a gene with a single mRNA, exon, and CDS" },
3145
- React.createElement(IconButton, { size: "small" },
3146
- React.createElement(InfoIcon, { sx: { fontSize: 18 } })))) }),
3147
- React.createElement(FormControlLabel, { value: NewFeature.TRANSCRIPT_AND_SUBFEATURES, control: React.createElement(Radio, null), label: React.createElement(Box, { display: "flex", alignItems: "center" },
3148
- "Add transcript and sub-features",
3149
- React.createElement(Tooltip, { title: "This is a shortcut to create a single mRNA with exon and CDS, but without a parent gene" },
3150
- React.createElement(IconButton, { size: "small" },
3151
- React.createElement(InfoIcon, { sx: { fontSize: 18 } })))) }),
3152
- React.createElement(FormControlLabel, { value: NewFeature.CUSTOM, checked: type !== NewFeature.GENE_AND_SUBFEATURES &&
3153
- type !== NewFeature.TRANSCRIPT_AND_SUBFEATURES, control: React.createElement(Radio, null), label: "Add feature with a sequence ontology type" }))),
3154
- type === NewFeature.CUSTOM ? (React.createElement(OntologyTermAutocomplete, { session: session, ontologyName: "Sequence Ontology", style: { width: 170 }, value: customType, filterTerms: isOntologyClass, renderInput: (params) => (React.createElement(TextField, { ...params, label: "Type", variant: "outlined", fullWidth: true })), onChange: (_oldValue, newValue) => {
3155
- if (newValue) {
3156
- handleChangeOntologyType(newValue);
3157
- }
3158
- } })) : null),
3159
- React.createElement(DialogActions, null,
3160
- React.createElement(Button, { variant: "contained", type: "submit", disabled: submitDisabled }, "Submit"),
3161
- React.createElement(Button, { variant: "outlined", type: "submit", onClick: handleClose }, "Cancel"))),
3162
- errorMessage ? (React.createElement(DialogContent, null,
3163
- React.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
3042
+ return (jsxs(Dialog, { open: true, title: "Add new feature", handleClose: handleClose, maxWidth: false, "data-testid": "add-feature-dialog", children: [jsxs("form", { onSubmit: onSubmit, "data-testid": "submit-form", children: [jsxs(DialogContent, { style: { display: 'flex', flexDirection: 'column' }, children: [jsx(TextField, { margin: "dense", id: "start", label: "Start", type: "number", fullWidth: true, variant: "outlined", value: Number(start), onChange: (e) => {
3043
+ setStart(e.target.value);
3044
+ } }), jsx(TextField, { margin: "dense", id: "end", label: "End", type: "number", fullWidth: true, variant: "outlined", value: end, onChange: (e) => {
3045
+ setEnd(e.target.value);
3046
+ }, error: error, helperText: error ? '"End" must be greater than "Start"' : null }), jsxs(FormControl, { children: [jsx(InputLabel, { id: "demo-simple-select-label", children: "Strand" }), jsxs(Select, { labelId: "demo-simple-select-label", id: "demo-simple-select", label: "Strand", value: strand?.toString(), onChange: handleChangeStrand, children: [jsx(MenuItem, { value: undefined }), jsx(MenuItem, { value: 1, children: "+" }), jsx(MenuItem, { value: -1, children: "-" })] })] }), jsx(FormControl, { style: { marginTop: 20 }, children: jsxs(RadioGroup, { "aria-labelledby": "demo-radio-buttons-group-label", defaultValue: NewFeature.GENE_AND_SUBFEATURES, name: "radio-buttons-group", value: type, onChange: handleTypeChange, children: [jsx(FormControlLabel, { value: NewFeature.GENE_AND_SUBFEATURES, control: jsx(Radio, {}), label: jsxs(Box, { display: "flex", alignItems: "center", children: ["Add gene and sub-features", jsx(Tooltip, { title: "This is a shortcut to create a gene with a single mRNA, exon, and CDS", children: jsx(IconButton, { size: "small", children: jsx(InfoIcon, { sx: { fontSize: 18 } }) }) })] }) }), jsx(FormControlLabel, { value: NewFeature.TRANSCRIPT_AND_SUBFEATURES, control: jsx(Radio, {}), label: jsxs(Box, { display: "flex", alignItems: "center", children: ["Add transcript and sub-features", jsx(Tooltip, { title: "This is a shortcut to create a single mRNA with exon and CDS, but without a parent gene", children: jsx(IconButton, { size: "small", children: jsx(InfoIcon, { sx: { fontSize: 18 } }) }) })] }) }), jsx(FormControlLabel, { value: NewFeature.CUSTOM, checked: type !== NewFeature.GENE_AND_SUBFEATURES &&
3047
+ type !== NewFeature.TRANSCRIPT_AND_SUBFEATURES, control: jsx(Radio, {}), label: "Add feature with a sequence ontology type" })] }) }), type === NewFeature.CUSTOM ? (jsx(OntologyTermAutocomplete, { session: session, ontologyName: "Sequence Ontology", style: { width: 170 }, value: customType, filterTerms: isOntologyClass, renderInput: (params) => (jsx(TextField, { ...params, label: "Type", variant: "outlined", fullWidth: true })), onChange: (_oldValue, newValue) => {
3048
+ if (newValue) {
3049
+ handleChangeOntologyType(newValue);
3050
+ }
3051
+ } })) : null] }), jsxs(DialogActions, { children: [jsx(Button, { variant: "contained", type: "submit", disabled: submitDisabled, children: "Submit" }), jsx(Button, { variant: "outlined", type: "submit", onClick: handleClose, children: "Cancel" })] })] }), errorMessage ? (jsx(DialogContent, { children: jsx(DialogContentText, { color: "error", children: errorMessage }) })) : null] }));
3164
3052
  }
3165
3053
 
3166
3054
  /**
@@ -3326,27 +3214,13 @@ function CopyFeature({ changeManager, handleClose, session, sourceAssemblyId, so
3326
3214
  _id: id,
3327
3215
  };
3328
3216
  }
3329
- return (React.createElement(Dialog, { open: true, title: "Copy features and annotations", handleClose: handleClose, maxWidth: false, "data-testid": "copy-feature" },
3330
- React.createElement("form", { onSubmit: onSubmit },
3331
- React.createElement(DialogContent, { style: { display: 'flex', flexDirection: 'column' } },
3332
- React.createElement(DialogContentText, null, "Target assembly"),
3333
- React.createElement(Select, { labelId: "label", value: selectedAssemblyId, onChange: handleChangeAssembly }, assemblies
3334
- .filter((option) => option.name !== sourceAssemblyId)
3335
- .map((option) => (React.createElement(MenuItem, { key: option.name, value: option.name }, readConfObject(option, 'displayName'))))),
3336
- React.createElement(DialogContentText, null, "Target reference sequence"),
3337
- React.createElement(Select, { labelId: "label", value: selectedRefSeqId, onChange: handleChangeRefSeq }, refNames.map((option) => (React.createElement(MenuItem, { key: option._id, value: option._id }, option.name)))),
3338
- React.createElement(DialogContentText, null, "Start position in target reference sequence"),
3339
- React.createElement(TextField, { margin: "dense", type: "number", fullWidth: true, variant: "outlined", value: start, onChange: (e) => {
3340
- setStart(Number(e.target.value));
3341
- } })),
3342
- React.createElement(DialogActions, null,
3343
- React.createElement(Button, { disabled: !selectedAssemblyId || !selectedRefSeqId || !start, variant: "contained", type: "submit" }, "Submit"),
3344
- React.createElement(Button, { variant: "outlined", type: "submit", onClick: handleClose }, "Cancel"))),
3345
- errorMessage ? (React.createElement(DialogContent, null,
3346
- React.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
3217
+ return (jsxs(Dialog, { open: true, title: "Copy features and annotations", handleClose: handleClose, maxWidth: false, "data-testid": "copy-feature", children: [jsxs("form", { onSubmit: onSubmit, children: [jsxs(DialogContent, { style: { display: 'flex', flexDirection: 'column' }, children: [jsx(DialogContentText, { children: "Target assembly" }), jsx(Select, { labelId: "label", value: selectedAssemblyId, onChange: handleChangeAssembly, children: assemblies
3218
+ .filter((option) => option.name !== sourceAssemblyId)
3219
+ .map((option) => (jsx(MenuItem, { value: option.name, children: readConfObject(option, 'displayName') }, option.name))) }), jsx(DialogContentText, { children: "Target reference sequence" }), jsx(Select, { labelId: "label", value: selectedRefSeqId, onChange: handleChangeRefSeq, children: refNames.map((option) => (jsx(MenuItem, { value: option._id, children: option.name }, option._id))) }), jsx(DialogContentText, { children: "Start position in target reference sequence" }), jsx(TextField, { margin: "dense", type: "number", fullWidth: true, variant: "outlined", value: start, onChange: (e) => {
3220
+ setStart(Number(e.target.value));
3221
+ } })] }), jsxs(DialogActions, { children: [jsx(Button, { disabled: !selectedAssemblyId || !selectedRefSeqId || !start, variant: "contained", type: "submit", children: "Submit" }), jsx(Button, { variant: "outlined", type: "submit", onClick: handleClose, children: "Cancel" })] })] }), errorMessage ? (jsx(DialogContent, { children: jsx(DialogContentText, { color: "error", children: errorMessage }) })) : null] }));
3347
3222
  }
3348
3223
 
3349
- /* eslint-disable @typescript-eslint/unbound-method */
3350
3224
  function DeleteAssembly({ changeManager, handleClose, session, }) {
3351
3225
  const { internetAccounts } = getRoot(session);
3352
3226
  const [errorMessage, setErrorMessage] = useState('');
@@ -3390,28 +3264,11 @@ function DeleteAssembly({ changeManager, handleClose, session, }) {
3390
3264
  handleClose();
3391
3265
  event.preventDefault();
3392
3266
  }
3393
- return (React.createElement(Dialog, { open: true, title: "Delete Assembly", handleClose: handleClose, maxWidth: false, "data-testid": "delete-assembly" },
3394
- React.createElement("form", { onSubmit: onSubmit },
3395
- React.createElement(DialogContent, { style: { display: 'flex', flexDirection: 'column' } },
3396
- apolloInternetAccounts.length > 1 ? (React.createElement(React.Fragment, null,
3397
- React.createElement(DialogContentText, null, "Select account"),
3398
- React.createElement(Select, { value: selectedInternetAccount.internetAccountId, onChange: handleChangeInternetAccount, disabled: submitted && !errorMessage }, internetAccounts.map((option) => (React.createElement(MenuItem, { key: option.id, value: option.internetAccountId }, option.name)))))) : null,
3399
- React.createElement(DialogContentText, null, "Select assembly"),
3400
- React.createElement(Select, { labelId: "label", value: selectedAssembly?.name ?? '', onChange: handleChangeAssembly, disabled: assemblies.length === 0 }, assemblies.map((option) => (React.createElement(MenuItem, { key: option.name, value: option.name }, option.displayName)))),
3401
- React.createElement(DialogContentText, null,
3402
- React.createElement("strong", { style: { color: 'red' } }, "NOTE: All assembly data will be deleted and this operation cannot be undone!")),
3403
- React.createElement(FormGroup, null,
3404
- React.createElement(FormControlLabel, { control: React.createElement(Checkbox, { checked: confirmDelete, onChange: () => {
3405
- setconfirmDelete(!confirmDelete);
3406
- } }), label: "I understand that all assembly data will be deleted" }))),
3407
- React.createElement(DialogActions, null,
3408
- React.createElement(Button, { disabled: !selectedAssembly || !confirmDelete, variant: "contained", type: "submit" }, "Delete"),
3409
- React.createElement(Button, { variant: "outlined", type: "submit", onClick: handleClose }, "Cancel"))),
3410
- errorMessage ? (React.createElement(DialogContent, null,
3411
- React.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
3267
+ return (jsxs(Dialog, { open: true, title: "Delete Assembly", handleClose: handleClose, maxWidth: false, "data-testid": "delete-assembly", children: [jsxs("form", { onSubmit: onSubmit, children: [jsxs(DialogContent, { style: { display: 'flex', flexDirection: 'column' }, children: [apolloInternetAccounts.length > 1 ? (jsxs(Fragment, { children: [jsx(DialogContentText, { children: "Select account" }), jsx(Select, { value: selectedInternetAccount.internetAccountId, onChange: handleChangeInternetAccount, disabled: submitted && !errorMessage, children: internetAccounts.map((option) => (jsx(MenuItem, { value: option.internetAccountId, children: option.name }, option.id))) })] })) : null, jsx(DialogContentText, { children: "Select assembly" }), jsx(Select, { labelId: "label", value: selectedAssembly?.name ?? '', onChange: handleChangeAssembly, disabled: assemblies.length === 0, children: assemblies.map((option) => (jsx(MenuItem, { value: option.name, children: option.displayName }, option.name))) }), jsx(DialogContentText, { children: jsx("strong", { style: { color: 'red' }, children: "NOTE: All assembly data will be deleted and this operation cannot be undone!" }) }), jsx(FormGroup, { children: jsx(FormControlLabel, { control: jsx(Checkbox, { checked: confirmDelete, onChange: () => {
3268
+ setconfirmDelete(!confirmDelete);
3269
+ } }), label: "I understand that all assembly data will be deleted" }) })] }), jsxs(DialogActions, { children: [jsx(Button, { disabled: !selectedAssembly || !confirmDelete, variant: "contained", type: "submit", children: "Delete" }), jsx(Button, { variant: "outlined", type: "submit", onClick: handleClose, children: "Cancel" })] })] }), errorMessage ? (jsx(DialogContent, { children: jsx(DialogContentText, { color: "error", children: errorMessage }) })) : null] }));
3412
3270
  }
3413
3271
 
3414
- /* eslint-disable @typescript-eslint/unbound-method */
3415
3272
  function lumpLocationChanges(changes, assembly) {
3416
3273
  if (changes.length === 0) {
3417
3274
  return;
@@ -3719,17 +3576,9 @@ function DeleteFeature({ changeManager, handleClose, selectedFeature, session, s
3719
3576
  handleClose();
3720
3577
  event.preventDefault();
3721
3578
  }
3722
- return (React.createElement(Dialog, { open: true, title: "Delete feature", handleClose: handleClose, maxWidth: false, "data-testid": "delete-feature" },
3723
- React.createElement("form", { onSubmit: (event) => {
3724
- void onSubmit(event);
3725
- } },
3726
- React.createElement(DialogContent, { style: { display: 'flex', flexDirection: 'column' } },
3727
- React.createElement(DialogContentText, null, "Are you sure you want to delete the selected feature?")),
3728
- React.createElement(DialogActions, null,
3729
- React.createElement(Button, { variant: "contained", type: "submit" }, "Yes"),
3730
- React.createElement(Button, { variant: "outlined", type: "submit", onClick: handleClose }, "Cancel"))),
3731
- errorMessage ? (React.createElement(DialogContent, null,
3732
- React.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
3579
+ return (jsxs(Dialog, { open: true, title: "Delete feature", handleClose: handleClose, maxWidth: false, "data-testid": "delete-feature", children: [jsxs("form", { onSubmit: (event) => {
3580
+ void onSubmit(event);
3581
+ }, children: [jsx(DialogContent, { style: { display: 'flex', flexDirection: 'column' }, children: jsx(DialogContentText, { children: "Are you sure you want to delete the selected feature?" }) }), jsxs(DialogActions, { children: [jsx(Button, { variant: "contained", type: "submit", children: "Yes" }), jsx(Button, { variant: "outlined", type: "submit", onClick: handleClose, children: "Cancel" })] })] }), errorMessage ? (jsx(DialogContent, { children: jsx(DialogContentText, { color: "error", children: errorMessage }) })) : null] }));
3733
3582
  }
3734
3583
 
3735
3584
  function DownloadGFF3({ handleClose, session }) {
@@ -3839,24 +3688,11 @@ function DownloadGFF3({ handleClose, session }) {
3839
3688
  const gff3Blob = new Blob([gff3], { type: 'text/plain;charset=utf-8' });
3840
3689
  saveAs(gff3Blob, `${selectedAssembly.displayName ?? selectedAssembly.name}.gff3`);
3841
3690
  }
3842
- return (React.createElement(Dialog, { open: true, title: "Export GFF3", handleClose: handleClose, maxWidth: false, "data-testid": "download-gff3" },
3843
- React.createElement("form", { onSubmit: onSubmit },
3844
- React.createElement(DialogContent, { style: { display: 'flex', flexDirection: 'column' } },
3845
- React.createElement(DialogContentText, null, "Select assembly"),
3846
- React.createElement(Select, { labelId: "label", value: selectedAssembly?.name ?? '', onChange: handleChangeAssembly, disabled: assemblies.length === 0 }, assemblies.map((option) => (React.createElement(MenuItem, { key: option.name, value: option.name }, option.displayName ?? option.name)))),
3847
- React.createElement(DialogContentText, null, "Select assembly to export to GFF3"),
3848
- React.createElement(FormGroup, null,
3849
- React.createElement(FormControlLabel, { "data-testid": "include-fasta-checkbox", control: React.createElement(Checkbox, { checked: includeFASTA, onChange: () => {
3850
- setincludeFASTA(!includeFASTA);
3851
- } }), label: "Include fasta sequence in GFF output" }))),
3852
- React.createElement(DialogActions, null,
3853
- React.createElement(Button, { disabled: !selectedAssembly, variant: "contained", type: "submit" }, "Download"),
3854
- React.createElement(Button, { variant: "outlined", type: "submit", onClick: handleClose }, "Cancel"))),
3855
- errorMessage ? (React.createElement(DialogContent, null,
3856
- React.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
3691
+ return (jsxs(Dialog, { open: true, title: "Export GFF3", handleClose: handleClose, maxWidth: false, "data-testid": "download-gff3", children: [jsxs("form", { onSubmit: onSubmit, children: [jsxs(DialogContent, { style: { display: 'flex', flexDirection: 'column' }, children: [jsx(DialogContentText, { children: "Select assembly" }), jsx(Select, { labelId: "label", value: selectedAssembly?.name ?? '', onChange: handleChangeAssembly, disabled: assemblies.length === 0, children: assemblies.map((option) => (jsx(MenuItem, { value: option.name, children: option.displayName ?? option.name }, option.name))) }), jsx(DialogContentText, { children: "Select assembly to export to GFF3" }), jsx(FormGroup, { children: jsx(FormControlLabel, { "data-testid": "include-fasta-checkbox", control: jsx(Checkbox, { checked: includeFASTA, onChange: () => {
3692
+ setincludeFASTA(!includeFASTA);
3693
+ } }), label: "Include fasta sequence in GFF output" }) })] }), jsxs(DialogActions, { children: [jsx(Button, { disabled: !selectedAssembly, variant: "contained", type: "submit", children: "Download" }), jsx(Button, { variant: "outlined", type: "submit", onClick: handleClose, children: "Cancel" })] })] }), errorMessage ? (jsx(DialogContent, { children: jsx(DialogContentText, { color: "error", children: errorMessage }) })) : null] }));
3857
3694
  }
3858
3695
 
3859
- /* eslint-disable @typescript-eslint/use-unknown-in-catch-callback-variable */
3860
3696
  function ImportFeatures({ changeManager, handleClose, session, }) {
3861
3697
  const { apolloDataStore } = session;
3862
3698
  const [file, setFile] = useState();
@@ -3866,6 +3702,7 @@ function ImportFeatures({ changeManager, handleClose, session, }) {
3866
3702
  // default is -1, submit button should be disabled until count is set
3867
3703
  const [featuresCount, setFeaturesCount] = useState();
3868
3704
  const [deleteFeatures, setDeleteFeatures] = useState(false);
3705
+ const [strict, setStrict] = useState(true);
3869
3706
  const [loading, setLoading] = useState(false);
3870
3707
  const { collaborationServerDriver, getInternetAccount } = apolloDataStore;
3871
3708
  const assemblies = collaborationServerDriver.getAssemblies();
@@ -3877,6 +3714,9 @@ function ImportFeatures({ changeManager, handleClose, session, }) {
3877
3714
  function handleDeleteFeatures(e) {
3878
3715
  setDeleteFeatures(e.target.checked);
3879
3716
  }
3717
+ function handleSetStrict(e) {
3718
+ setStrict(e.target.checked);
3719
+ }
3880
3720
  // fetch and set features count for selected assembly
3881
3721
  useEffect(() => {
3882
3722
  if (!selectedAssembly) {
@@ -3966,7 +3806,7 @@ function ImportFeatures({ changeManager, handleClose, session, }) {
3966
3806
  statusMessage: 'Uploading file, this may take awhile',
3967
3807
  progressPct: 0,
3968
3808
  cancelCallback: () => {
3969
- controller.abort('ImportFeatures');
3809
+ controller.abort(new DOMException(`Canceling importing of features to ${selectedAssembly.displayName}`, 'AbortError'));
3970
3810
  jobsManager.abortJob(job.name);
3971
3811
  },
3972
3812
  };
@@ -3993,35 +3833,16 @@ function ImportFeatures({ changeManager, handleClose, session, }) {
3993
3833
  typeName: 'AddFeaturesFromFileChange',
3994
3834
  assembly: selectedAssembly.name,
3995
3835
  fileId,
3836
+ parseOptions: { strict },
3996
3837
  deleteExistingFeatures: deleteFeatures,
3997
3838
  });
3998
3839
  jobsManager.done(job);
3999
3840
  await changeManager.submit(change, { updateJobsManager: true });
4000
3841
  }
4001
- return (React.createElement(Dialog, { open: true, title: "Import Features from GFF3 file", handleClose: handleClose, maxWidth: false, "data-testid": "import-features-dialog" },
4002
- loading ? React.createElement(LinearProgress$1, null) : null,
4003
- React.createElement("form", { onSubmit: onSubmit },
4004
- React.createElement(DialogContent, { style: { display: 'flex', flexDirection: 'column' } },
4005
- React.createElement(DialogContentText, null, "Select assembly"),
4006
- React.createElement(Select, { labelId: "label", value: selectedAssembly?.name ?? '', onChange: handleChangeAssembly, disabled: submitted && !errorMessage }, assemblies.map((option) => (React.createElement(MenuItem, { key: option.name, value: option.name }, option.displayName ?? option.name))))),
4007
- React.createElement(DialogContent, { style: { display: 'flex', flexDirection: 'column' } },
4008
- React.createElement(DialogContentText, null, "Upload GFF3 to load features"),
4009
- React.createElement("input", { type: "file", onChange: handleChangeFile, disabled: submitted && !errorMessage })),
4010
- featuresCount && featuresCount > 0 ? (React.createElement(DialogContent, null,
4011
- React.createElement(DialogContentText, null,
4012
- "This assembly already has ",
4013
- featuresCount,
4014
- " features, would you like to delete the existing features before importing new ones?"),
4015
- React.createElement(FormControlLabel$1, { label: "Yes, delete existing features", disabled: submitted && !errorMessage, control: React.createElement(Checkbox$1, { checked: deleteFeatures, onChange: handleDeleteFeatures, slotProps: { input: { 'aria-label': 'controlled' } }, color: "warning" }) }))) : null,
4016
- React.createElement(DialogActions, null,
4017
- React.createElement(Button, { disabled: !(selectedAssembly && file && featuresCount !== undefined) ||
4018
- submitted, variant: "contained", type: "submit" }, submitted ? 'Submitting...' : 'Submit'),
4019
- React.createElement(Button, { variant: "outlined", type: "submit", onClick: handleClose }, "Close"))),
4020
- errorMessage ? (React.createElement(DialogContent, null,
4021
- React.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
3842
+ return (jsxs(Dialog, { open: true, title: "Import Features from GFF3 file", handleClose: handleClose, maxWidth: false, "data-testid": "import-features-dialog", children: [loading ? jsx(LinearProgress, {}) : null, jsxs("form", { onSubmit: onSubmit, children: [jsxs(DialogContent, { style: { display: 'flex', flexDirection: 'column' }, children: [jsx(DialogContentText, { children: "Select assembly" }), jsx(Select, { labelId: "label", value: selectedAssembly?.name ?? '', onChange: handleChangeAssembly, disabled: submitted && !errorMessage, children: assemblies.map((option) => (jsx(MenuItem, { value: option.name, children: option.displayName ?? option.name }, option.name))) }), jsx(DialogContentText, { children: "Upload GFF3 to load features" }), jsx("input", { type: "file", onChange: handleChangeFile, disabled: submitted && !errorMessage }), jsx(FormControlLabel, { label: "Strict parsing", disabled: submitted && !errorMessage, control: jsx(Checkbox, { checked: strict, onChange: handleSetStrict }) }), jsx(FormHelperText, { children: "Don't import any features if any lines in the GFF3 are unable to be processed" }), featuresCount && featuresCount > 0 ? (jsxs(Fragment, { children: [jsx(FormControlLabel, { label: "Delete existing features", disabled: submitted && !errorMessage, control: jsx(Checkbox, { checked: deleteFeatures, onChange: handleDeleteFeatures, slotProps: { input: { 'aria-label': 'controlled' } }, color: "warning" }) }), jsxs(FormHelperText, { children: ["This assembly has ", featuresCount, " features that will be deleted"] })] })) : null] }), jsxs(DialogActions, { children: [jsx(Button, { disabled: !(selectedAssembly && file && featuresCount !== undefined) ||
3843
+ submitted, variant: "contained", type: "submit", children: submitted ? 'Submitting...' : 'Submit' }), jsx(Button, { variant: "outlined", type: "submit", onClick: handleClose, children: "Close" })] })] }), errorMessage ? (jsx(DialogContent, { children: jsx(DialogContentText, { color: "error", children: errorMessage }) })) : null] }));
4022
3844
  }
4023
3845
 
4024
- /* eslint-disable @typescript-eslint/unbound-method */
4025
3846
  function LogOut({ handleClose, session }) {
4026
3847
  const { internetAccounts } = getRoot(session);
4027
3848
  const [errorMessage, setErrorMessage] = useState('');
@@ -4043,18 +3864,7 @@ function LogOut({ handleClose, session }) {
4043
3864
  selectedInternetAccount.removeToken();
4044
3865
  globalThis.location.reload();
4045
3866
  }
4046
- return (React.createElement(Dialog, { open: true, title: "Log out", handleClose: handleClose, maxWidth: false, "data-testid": "log-out" },
4047
- React.createElement("form", { onSubmit: onSubmit },
4048
- React.createElement(DialogContent, { style: { display: 'flex', flexDirection: 'column' } },
4049
- apolloInternetAccounts.length > 1 ? (React.createElement(React.Fragment, null,
4050
- React.createElement(DialogContentText, null, "Select account"),
4051
- React.createElement(Select, { value: selectedInternetAccount.internetAccountId, onChange: handleChangeInternetAccount }, internetAccounts.map((option) => (React.createElement(MenuItem, { key: option.id, value: option.internetAccountId }, option.name)))))) : null,
4052
- React.createElement(DialogContentText, null, "Are you sure you want to log out?")),
4053
- React.createElement(DialogActions, null,
4054
- React.createElement(Button, { disabled: !selectedInternetAccount, variant: "contained", type: "submit" }, "Log Out"),
4055
- React.createElement(Button, { variant: "outlined", type: "submit", onClick: handleClose }, "Cancel"))),
4056
- errorMessage ? (React.createElement(DialogContent, null,
4057
- React.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
3867
+ return (jsxs(Dialog, { open: true, title: "Log out", handleClose: handleClose, maxWidth: false, "data-testid": "log-out", children: [jsxs("form", { onSubmit: onSubmit, children: [jsxs(DialogContent, { style: { display: 'flex', flexDirection: 'column' }, children: [apolloInternetAccounts.length > 1 ? (jsxs(Fragment, { children: [jsx(DialogContentText, { children: "Select account" }), jsx(Select, { value: selectedInternetAccount.internetAccountId, onChange: handleChangeInternetAccount, children: internetAccounts.map((option) => (jsx(MenuItem, { value: option.internetAccountId, children: option.name }, option.id))) })] })) : null, jsx(DialogContentText, { children: "Are you sure you want to log out?" })] }), jsxs(DialogActions, { children: [jsx(Button, { disabled: !selectedInternetAccount, variant: "contained", type: "submit", children: "Log Out" }), jsx(Button, { variant: "outlined", type: "submit", onClick: handleClose, children: "Cancel" })] })] }), errorMessage ? (jsx(DialogContent, { children: jsx(DialogContentText, { color: "error", children: errorMessage }) })) : null] }));
4058
3868
  }
4059
3869
 
4060
3870
  function ManageChecks({ handleClose, session }) {
@@ -4171,37 +3981,18 @@ function ManageChecks({ handleClose, session }) {
4171
3981
  }
4172
3982
  setSelectedInternetAccount(newlySelectedInternetAccount);
4173
3983
  }
4174
- return (React.createElement(Dialog, { open: true, title: "Manage Checks", handleClose: handleClose, "data-testid": "manage-checks" },
4175
- React.createElement("form", { onSubmit: onSubmit },
4176
- React.createElement(DialogContent, null,
4177
- apolloInternetAccounts.length > 1 ? (React.createElement(React.Fragment, null,
4178
- React.createElement(DialogContentText, null, "Select account"),
4179
- React.createElement(Select, { value: selectedInternetAccount.internetAccountId, onChange: handleChangeInternetAccount, disabled: submitted && !errorMessage }, internetAccounts.map((option) => (React.createElement(MenuItem, { key: option.id, value: option.internetAccountId }, option.name)))))) : null,
4180
- React.createElement(DialogContentText, null, "Select assembly"),
4181
- React.createElement(Select, { style: { width: 300 }, labelId: "label", value: selectedAssembly?.name ?? '', onChange: handleChangeAssembly, disabled: assemblies.length === 0 }, assemblies.map((option) => (React.createElement(MenuItem, { key: option.name, value: option.name }, option.displayName)))),
4182
- React.createElement("br", null),
4183
- React.createElement("br", null),
4184
- React.createElement(TableContainer, { component: Paper },
4185
- React.createElement(Table, null,
4186
- React.createElement(TableHead, null,
4187
- React.createElement(TableRow, null,
4188
- React.createElement(TableCell, null, "Check name"),
4189
- React.createElement(TableCell, null, "Use check"))),
4190
- React.createElement(TableBody, null, checks.map((check) => (React.createElement(TableRow, { key: check._id },
4191
- React.createElement(TableCell, null, check.name),
4192
- React.createElement(TableCell, null,
4193
- React.createElement(Checkbox, { value: check._id, checked: selectedChecks.includes(check._id), onChange: handleCheckboxChange }))))))))),
4194
- React.createElement(DialogActions, null,
4195
- React.createElement(Button, { variant: "contained", type: "submit" }, "Submit"),
4196
- React.createElement(Button, { variant: "outlined", type: "submit", onClick: handleClose }, "Cancel"))),
4197
- errorMessage ? (React.createElement(DialogContent, null,
4198
- React.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
3984
+ return (jsxs(Dialog, { open: true, title: "Manage Checks", handleClose: handleClose, "data-testid": "manage-checks", children: [jsxs("form", { onSubmit: onSubmit, children: [jsxs(DialogContent, { children: [apolloInternetAccounts.length > 1 ? (jsxs(Fragment, { children: [jsx(DialogContentText, { children: "Select account" }), jsx(Select, { value: selectedInternetAccount.internetAccountId, onChange: handleChangeInternetAccount, disabled: submitted && !errorMessage, children: internetAccounts.map((option) => (jsx(MenuItem, { value: option.internetAccountId, children: option.name }, option.id))) })] })) : null, jsx(DialogContentText, { children: "Select assembly" }), jsx(Select, { style: { width: 300 }, labelId: "label", value: selectedAssembly?.name ?? '', onChange: handleChangeAssembly, disabled: assemblies.length === 0, children: assemblies.map((option) => (jsx(MenuItem, { value: option.name, children: option.displayName }, option.name))) }), jsx("br", {}), jsx("br", {}), jsx(TableContainer, { component: Paper, children: jsxs(Table, { children: [jsx(TableHead, { children: jsxs(TableRow, { children: [jsx(TableCell, { children: "Check name" }), jsx(TableCell, { children: "Use check" })] }) }), jsx(TableBody, { children: checks.map((check) => (jsxs(TableRow, { children: [jsx(TableCell, { children: check.name }), jsx(TableCell, { children: jsx(Checkbox, { value: check._id, checked: selectedChecks.includes(check._id), onChange: handleCheckboxChange }) })] }, check._id))) })] }) })] }), jsxs(DialogActions, { children: [jsx(Button, { variant: "contained", type: "submit", children: "Submit" }), jsx(Button, { variant: "outlined", type: "submit", onClick: handleClose, children: "Cancel" })] })] }), errorMessage ? (jsx(DialogContent, { children: jsx(DialogContentText, { color: "error", children: errorMessage }) })) : null] }));
3985
+ }
3986
+
3987
+ function isApolloInternetAccount(internetAccount) {
3988
+ return internetAccount.type === 'ApolloInternetAccount';
4199
3989
  }
4200
3990
 
4201
- /* eslint-disable @typescript-eslint/unbound-method */
4202
3991
  function ManageUsers({ changeManager, handleClose, session, }) {
4203
3992
  const { internetAccounts } = getRoot(session);
4204
- const apolloInternetAccounts = internetAccounts.filter((ia) => ia.type === 'ApolloInternetAccount' && ia.role?.includes('admin'));
3993
+ const apolloInternetAccounts = internetAccounts
3994
+ .filter((ia) => isApolloInternetAccount(ia))
3995
+ .filter((ia) => ia.role?.includes('admin'));
4205
3996
  if (apolloInternetAccounts.length === 0) {
4206
3997
  throw new Error('No Apollo internet account found');
4207
3998
  }
@@ -4216,16 +4007,14 @@ function ManageUsers({ changeManager, handleClose, session, }) {
4216
4007
  locationType: 'UriLocation',
4217
4008
  uri,
4218
4009
  });
4219
- if (apolloFetch) {
4220
- const response = await apolloFetch(uri, { method: 'GET' });
4221
- if (!response.ok) {
4222
- const newErrorMessage = await createFetchErrorMessage(response, 'Error when getting user data from db');
4223
- setErrorMessage(newErrorMessage);
4224
- return;
4225
- }
4226
- const data = (await response.json());
4227
- setUsers(data.map((u) => (u.role === undefined ? { ...u, role: '' } : u)));
4010
+ const response = await apolloFetch(uri, { method: 'GET' });
4011
+ if (!response.ok) {
4012
+ const newErrorMessage = await createFetchErrorMessage(response, 'Error when getting user data from db');
4013
+ setErrorMessage(newErrorMessage);
4014
+ return;
4228
4015
  }
4016
+ const data = (await response.json());
4017
+ setUsers(data.map((u) => (u.role === undefined ? { ...u, role: '' } : u)));
4229
4018
  }
4230
4019
  getUsers().catch((error) => {
4231
4020
  setErrorMessage(String(error));
@@ -4281,11 +4070,11 @@ function ManageUsers({ changeManager, handleClose, session, }) {
4281
4070
  field: 'actions',
4282
4071
  type: 'actions',
4283
4072
  getActions: (params) => [
4284
- React.createElement(GridActionsCellItem, { key: `delete-${params.id}`, icon: React.createElement(DeleteIcon, null), onClick: async () => {
4073
+ jsx(GridActionsCellItem, { icon: jsx(DeleteIcon, {}), onClick: async () => {
4285
4074
  if (globalThis.confirm('Delete this user?')) {
4286
4075
  await deleteUser(params.id);
4287
4076
  }
4288
- }, disabled: isCurrentUser(params.id), label: "Delete" }),
4077
+ }, disabled: isCurrentUser(params.id), label: "Delete" }, `delete-${params.id}`),
4289
4078
  ],
4290
4079
  },
4291
4080
  ];
@@ -4307,22 +4096,11 @@ function ManageUsers({ changeManager, handleClose, session, }) {
4307
4096
  });
4308
4097
  return newRow;
4309
4098
  }
4310
- return (React.createElement(Dialog, { open: true, fullScreen: true, title: "Manage users", handleClose: handleClose, "data-testid": "manage-users" },
4311
- React.createElement(DialogContent, null,
4312
- apolloInternetAccounts.length > 1 ? (React.createElement(React.Fragment, null,
4313
- React.createElement(DialogContentText, null, "Select account"),
4314
- React.createElement(Select, { value: selectedInternetAccount.internetAccountId, onChange: handleChangeInternetAccount, disabled: !errorMessage }, internetAccounts.map((option) => (React.createElement(MenuItem, { key: option.id, value: option.internetAccountId }, option.name)))))) : null,
4315
- React.createElement("div", { style: { height: '100%', width: '100%' } },
4316
- React.createElement(DataGrid, { pagination: true, rows: users, columns: gridColumns, getRowId: (row) => row._id, slots: { toolbar: GridToolbar }, getRowHeight: () => 'auto', isCellEditable: (params) => !isCurrentUser(params.id), processRowUpdate: processRowUpdate, onProcessRowUpdateError: (error) => {
4317
- setErrorMessage(String(error));
4318
- } }))),
4319
- React.createElement(DialogActions, null,
4320
- React.createElement(Button, { variant: "outlined", type: "submit", onClick: handleClose }, "Close")),
4321
- errorMessage ? (React.createElement(DialogContent, null,
4322
- React.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
4099
+ return (jsxs(Dialog, { open: true, fullScreen: true, title: "Manage users", handleClose: handleClose, "data-testid": "manage-users", children: [jsxs(DialogContent, { children: [apolloInternetAccounts.length > 1 ? (jsxs(Fragment, { children: [jsx(DialogContentText, { children: "Select account" }), jsx(Select, { value: selectedInternetAccount.internetAccountId, onChange: handleChangeInternetAccount, disabled: !errorMessage, children: internetAccounts.map((option) => (jsx(MenuItem, { value: option.internetAccountId, children: option.name }, option.id))) })] })) : null, jsx("div", { style: { height: '100%', width: '100%' }, children: jsx(DataGrid, { pagination: true, rows: users, columns: gridColumns, getRowId: (row) => row._id, slots: { toolbar: GridToolbar }, getRowHeight: () => 'auto', isCellEditable: (params) => !isCurrentUser(params.id), processRowUpdate: processRowUpdate, onProcessRowUpdateError: (error) => {
4100
+ setErrorMessage(String(error));
4101
+ } }) })] }), jsx(DialogActions, { children: jsx(Button, { variant: "outlined", type: "submit", onClick: handleClose, children: "Close" }) }), errorMessage ? (jsx(DialogContent, { children: jsx(DialogContentText, { color: "error", children: errorMessage }) })) : null] }));
4323
4102
  }
4324
4103
 
4325
- /* eslint-disable @typescript-eslint/unbound-method */
4326
4104
  function getNeighboringExons(referenceExon) {
4327
4105
  const neighboringExons = {};
4328
4106
  const tx = referenceExon.parent;
@@ -4406,20 +4184,10 @@ function MergeExons({ changeManager, handleClose, selectedFeature, setSelectedFe
4406
4184
  setSelectedExon(neighboringExons[value]);
4407
4185
  };
4408
4186
  const neighboringExons = getNeighboringExons(sourceFeature);
4409
- return (React.createElement(Dialog, { open: true, title: "Merge exons", handleClose: handleClose, maxWidth: false, "data-testid": "merge-exons" },
4410
- React.createElement("form", { onSubmit: onSubmit },
4411
- React.createElement(DialogContent, { style: { display: 'flex', flexDirection: 'column' } },
4412
- Object.keys(neighboringExons).length === 0
4413
- ? 'There are no neighbouring exons to merge with'
4414
- : 'Merge with exon on:',
4415
- React.createElement(FormControl, { style: { marginTop: 5 } },
4416
- React.createElement(RadioGroup, { "aria-labelledby": "demo-radio-buttons-group-label", name: "radio-buttons-group", value: selectedExon, onChange: handleTypeChange }, Object.keys(neighboringExons).map((key) => (React.createElement(FormControlLabel, { value: key, key: key, control: React.createElement(Radio, null), label: React.createElement(Box, { display: "flex", alignItems: "center" }, makeRadioButtonName$1(key, neighboringExons)) })))))),
4417
- React.createElement(DialogActions, null,
4418
- React.createElement(Button, { variant: "contained", type: "submit", disabled: Object.keys(neighboringExons).length === 0 ||
4419
- selectedExon === undefined }, "Submit"),
4420
- React.createElement(Button, { variant: "outlined", type: "submit", onClick: handleClose }, "Cancel"))),
4421
- errorMessage ? (React.createElement(DialogContent, null,
4422
- React.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
4187
+ return (jsxs(Dialog, { open: true, title: "Merge exons", handleClose: handleClose, maxWidth: false, "data-testid": "merge-exons", children: [jsxs("form", { onSubmit: onSubmit, children: [jsxs(DialogContent, { style: { display: 'flex', flexDirection: 'column' }, children: [Object.keys(neighboringExons).length === 0
4188
+ ? 'There are no neighbouring exons to merge with'
4189
+ : 'Merge with exon on:', jsx(FormControl, { style: { marginTop: 5 }, children: jsx(RadioGroup, { "aria-labelledby": "demo-radio-buttons-group-label", name: "radio-buttons-group", value: selectedExon, onChange: handleTypeChange, children: Object.keys(neighboringExons).map((key) => (jsx(FormControlLabel, { value: key, control: jsx(Radio, {}), label: jsx(Box, { display: "flex", alignItems: "center", children: makeRadioButtonName$1(key, neighboringExons) }) }, key))) }) })] }), jsxs(DialogActions, { children: [jsx(Button, { variant: "contained", type: "submit", disabled: Object.keys(neighboringExons).length === 0 ||
4190
+ selectedExon === undefined, children: "Submit" }), jsx(Button, { variant: "outlined", type: "submit", onClick: handleClose, children: "Cancel" })] })] }), errorMessage ? (jsx(DialogContent, { children: jsx(DialogContentText, { color: "error", children: errorMessage }) })) : null] }));
4423
4191
  }
4424
4192
 
4425
4193
  function getTranscripts(referenceTranscript, session) {
@@ -4489,23 +4257,12 @@ function MergeTranscripts({ changeManager, handleClose, selectedFeature, session
4489
4257
  const { value } = e.target;
4490
4258
  setSelectedTranscriptId(value);
4491
4259
  };
4492
- return (React.createElement(Dialog, { open: true, title: "Merge transcripts", handleClose: handleClose, maxWidth: false, "data-testid": "merge-transcripts" },
4493
- React.createElement("form", { onSubmit: onSubmit },
4494
- React.createElement(DialogContent, { style: { display: 'flex', flexDirection: 'column' } },
4495
- Object.keys(transcripts).length === 0
4496
- ? 'There are no transcripts to merge with'
4497
- : 'Merge with transcript:',
4498
- React.createElement(FormControl, { style: { marginTop: 5 } },
4499
- React.createElement(RadioGroup, { "aria-labelledby": "demo-radio-buttons-group-label", name: "radio-buttons-group", value: selectedTranscriptId, onChange: handleTypeChange }, Object.keys(transcripts).map((key) => (React.createElement(FormControlLabel, { value: key, key: key, control: React.createElement(Radio, null), label: React.createElement(Box, { display: "flex", alignItems: "center" }, makeRadioButtonName(transcripts[key])) })))))),
4500
- React.createElement(DialogActions, null,
4501
- React.createElement(Button, { variant: "contained", type: "submit", disabled: Object.keys(transcripts).length === 0 ||
4502
- selectedTranscriptId === undefined }, "Submit"),
4503
- React.createElement(Button, { variant: "outlined", type: "submit", onClick: handleClose }, "Cancel"))),
4504
- errorMessage ? (React.createElement(DialogContent, null,
4505
- React.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
4260
+ return (jsxs(Dialog, { open: true, title: "Merge transcripts", handleClose: handleClose, maxWidth: false, "data-testid": "merge-transcripts", children: [jsxs("form", { onSubmit: onSubmit, children: [jsxs(DialogContent, { style: { display: 'flex', flexDirection: 'column' }, children: [Object.keys(transcripts).length === 0
4261
+ ? 'There are no transcripts to merge with'
4262
+ : 'Merge with transcript:', jsx(FormControl, { style: { marginTop: 5 }, children: jsx(RadioGroup, { "aria-labelledby": "demo-radio-buttons-group-label", name: "radio-buttons-group", value: selectedTranscriptId, onChange: handleTypeChange, children: Object.keys(transcripts).map((key) => (jsx(FormControlLabel, { value: key, control: jsx(Radio, {}), label: jsx(Box, { display: "flex", alignItems: "center", children: makeRadioButtonName(transcripts[key]) }) }, key))) }) })] }), jsxs(DialogActions, { children: [jsx(Button, { variant: "contained", type: "submit", disabled: Object.keys(transcripts).length === 0 ||
4263
+ selectedTranscriptId === undefined, children: "Submit" }), jsx(Button, { variant: "outlined", type: "submit", onClick: handleClose, children: "Cancel" })] })] }), errorMessage ? (jsx(DialogContent, { children: jsx(DialogContentText, { color: "error", children: errorMessage }) })) : null] }));
4506
4264
  }
4507
4265
 
4508
- /* eslint-disable @typescript-eslint/no-unsafe-call */
4509
4266
  function OpenLocalFile({ handleClose, session }) {
4510
4267
  const { apolloDataStore } = session;
4511
4268
  const { addAssembly, addSessionAssembly, assemblyManager, notify } = session;
@@ -4587,25 +4344,9 @@ function OpenLocalFile({ handleClose, session }) {
4587
4344
  function handleAssemblyNameChange(event) {
4588
4345
  setAssemblyName(event.target.value);
4589
4346
  }
4590
- return (React.createElement(Dialog, { open: true, title: "Open local GFF3 file", handleClose: handleClose, maxWidth: false, "data-testid": "open-local-file" },
4591
- React.createElement("form", { onSubmit: onSubmit },
4592
- React.createElement(DialogContent, { style: { display: 'flex', flexDirection: 'column' } },
4593
- React.createElement(FormControl, null,
4594
- React.createElement("div", { style: { flexDirection: 'row' } },
4595
- React.createElement(Button, { variant: "contained", component: "label", style: { marginRight: theme.spacing() } },
4596
- "Choose File",
4597
- React.createElement("input", { type: "file", required: true, hidden: true, onChange: handleChangeFile })),
4598
- file ? file.name : 'No file chosen'),
4599
- React.createElement(FormHelperText, null, "Make sure your GFF3 has an embedded FASTA section")),
4600
- React.createElement(TextField, { required: true, label: "Assembly name", value: assemblyName, onChange: handleAssemblyNameChange })),
4601
- React.createElement(DialogActions, null,
4602
- React.createElement(Button, { disabled: false, variant: "contained", type: "submit" }, submitted ? 'Submitting...' : 'Submit'),
4603
- React.createElement(Button, { disabled: submitted, variant: "outlined", type: "submit", onClick: handleClose }, "Cancel"))),
4604
- errorMessage ? (React.createElement(DialogContent, null,
4605
- React.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
4347
+ return (jsxs(Dialog, { open: true, title: "Open local GFF3 file", handleClose: handleClose, maxWidth: false, "data-testid": "open-local-file", children: [jsxs("form", { onSubmit: onSubmit, children: [jsxs(DialogContent, { style: { display: 'flex', flexDirection: 'column' }, children: [jsxs(FormControl, { children: [jsxs("div", { style: { flexDirection: 'row' }, children: [jsxs(Button, { variant: "contained", component: "label", style: { marginRight: theme.spacing() }, children: ["Choose File", jsx("input", { type: "file", required: true, hidden: true, onChange: handleChangeFile })] }), file ? file.name : 'No file chosen'] }), jsx(FormHelperText, { children: "Make sure your GFF3 has an embedded FASTA section" })] }), jsx(TextField, { required: true, label: "Assembly name", value: assemblyName, onChange: handleAssemblyNameChange })] }), jsxs(DialogActions, { children: [jsx(Button, { disabled: false, variant: "contained", type: "submit", children: submitted ? 'Submitting...' : 'Submit' }), jsx(Button, { disabled: submitted, variant: "outlined", type: "submit", onClick: handleClose, children: "Cancel" })] })] }), errorMessage ? (jsx(DialogContent, { children: jsx(DialogContentText, { color: "error", children: errorMessage }) })) : null] }));
4606
4348
  }
4607
4349
 
4608
- /* eslint-disable @typescript-eslint/unbound-method */
4609
4350
  const useStyles$e = makeStyles()((theme) => ({
4610
4351
  changeTextarea: {
4611
4352
  fontFamily: 'monospace',
@@ -4642,7 +4383,7 @@ function ViewChangeLog({ handleClose, session }) {
4642
4383
  field: 'changes',
4643
4384
  headerName: 'Change JSON',
4644
4385
  width: 600,
4645
- renderCell: ({ value }) => (React.createElement("textarea", { className: classes.changeTextarea, value: JSON.stringify(value), readOnly: true })),
4386
+ renderCell: ({ value }) => (jsx("textarea", { className: classes.changeTextarea, value: JSON.stringify(value), readOnly: true })),
4646
4387
  },
4647
4388
  { field: 'user', headerName: 'User', width: 140 },
4648
4389
  {
@@ -4690,20 +4431,12 @@ function ViewChangeLog({ handleClose, session }) {
4690
4431
  const newAssembly = assemblies.find((asm) => asm.name === e.target.value);
4691
4432
  setSelectedAssembly(newAssembly);
4692
4433
  }
4693
- return (React.createElement(Dialog, { open: true, fullScreen: true, title: "View change log", handleClose: handleClose, "data-testid": "view-changelog" },
4694
- React.createElement(Select, { style: { width: 200, marginLeft: 40 }, value: selectedAssembly?.name ?? '', onChange: handleChangeAssembly }, assemblies.map((option) => (React.createElement(MenuItem, { key: option.name, value: option.name }, option.displayName || option.name)))),
4695
- React.createElement(DialogContent, null,
4696
- React.createElement(DataGrid, { pagination: true, rows: displayGridData, columns: gridColumns, getRowId: (row) => row._id, slots: { toolbar: GridToolbar }, initialState: {
4697
- sorting: { sortModel: [{ field: 'sequence', sort: 'desc' }] },
4698
- columns: { columnVisibilityModel: { sequence: false } },
4699
- } })),
4700
- React.createElement(DialogActions, null,
4701
- React.createElement(Button, { variant: "outlined", type: "submit", onClick: handleClose }, "Close")),
4702
- errorMessage ? (React.createElement(DialogContent, null,
4703
- React.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
4434
+ return (jsxs(Dialog, { open: true, fullScreen: true, title: "View change log", handleClose: handleClose, "data-testid": "view-changelog", children: [jsx(Select, { style: { width: 200, marginLeft: 40 }, value: selectedAssembly?.name ?? '', onChange: handleChangeAssembly, children: assemblies.map((option) => (jsx(MenuItem, { value: option.name, children: option.displayName || option.name }, option.name))) }), jsx(DialogContent, { children: jsx(DataGrid, { pagination: true, rows: displayGridData, columns: gridColumns, getRowId: (row) => row._id, slots: { toolbar: GridToolbar }, initialState: {
4435
+ sorting: { sortModel: [{ field: 'sequence', sort: 'desc' }] },
4436
+ columns: { columnVisibilityModel: { sequence: false } },
4437
+ } }) }), jsx(DialogActions, { children: jsx(Button, { variant: "outlined", type: "submit", onClick: handleClose, children: "Close" }) }), errorMessage ? (jsx(DialogContent, { children: jsx(DialogContentText, { color: "error", children: errorMessage }) })) : null] }));
4704
4438
  }
4705
4439
 
4706
- /* eslint-disable @typescript-eslint/unbound-method */
4707
4440
  const columns = [
4708
4441
  { field: 'refName', headerName: 'Ref Name' },
4709
4442
  { field: 'aliases', headerName: 'Aliases', editable: true, flex: 1 },
@@ -4847,31 +4580,13 @@ const AddRefSeqAliases = observer(function AddRefSeqAliases({ changeManager, han
4847
4580
  });
4848
4581
  handleClose();
4849
4582
  };
4850
- return (React.createElement(Dialog, { open: true, title: "Add reference sequence aliases", handleClose: handleClose, maxWidth: 'sm', "data-testid": "add-refseq-alias", fullWidth: true },
4851
- React.createElement(DialogContent, { style: { display: 'flex', flexDirection: 'column' } },
4852
- React.createElement(Grid, { container: true, spacing: 2 },
4853
- React.createElement(Grid, null,
4854
- React.createElement(FormControl, { disabled: enableSubmit && !errorMessage, fullWidth: true },
4855
- React.createElement(InputLabel, { id: "demo-simple-select-label" }, "Assembly"),
4856
- React.createElement(Select, { labelId: "demo-simple-select-label", id: "demo-simple-select", label: "Assembly", value: selectedAssembly?.name ?? '', onChange: handleChangeAssembly, style: { minWidth: 150 } }, assemblies.map((option) => (React.createElement(MenuItem, { key: option.name, value: option.name }, option.displayName)))))),
4857
- React.createElement(Grid, null,
4858
- React.createElement(InputLabel, null, "Load RefName alias"),
4859
- React.createElement("input", { type: "file", onChange: handleChangeFileHandler, ref: fileRef, disabled: (enableSubmit && !errorMessage) || !selectedAssembly }))),
4860
- selectedAssembly && refNameAliasMap.size > 0 ? (React.createElement("div", { style: { height: 200, width: '100%', marginTop: 20 } },
4861
- React.createElement(InputLabel, null, "Refname aliases found for selected assembly."),
4862
- React.createElement(DataGrid, { rows: getTableRows(), columns: columns, initialState: {
4863
- pagination: {
4864
- paginationModel: { page: 0, pageSize: 5 },
4865
- },
4866
- }, pageSizeOptions: [5, 10], onRowSelectionModelChange: rowSelectionChange, processRowUpdate: processRowUpdate, checkboxSelection: true, disableRowSelectionExcludeModel: true }))) : null),
4867
- React.createElement(DialogActions, null,
4868
- React.createElement(Button, { variant: "contained", type: "submit", disabled: !enableSubmit, onClick: handleSubmit }, "Submit"),
4869
- React.createElement(Button, { variant: "outlined", type: "submit", onClick: handleClose }, "Close")),
4870
- errorMessage ? (React.createElement(DialogContent, null,
4871
- React.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
4583
+ return (jsxs(Dialog, { open: true, title: "Add reference sequence aliases", handleClose: handleClose, maxWidth: 'sm', "data-testid": "add-refseq-alias", fullWidth: true, children: [jsxs(DialogContent, { style: { display: 'flex', flexDirection: 'column' }, children: [jsxs(Grid, { container: true, spacing: 2, children: [jsx(Grid, { children: jsxs(FormControl, { disabled: enableSubmit && !errorMessage, fullWidth: true, children: [jsx(InputLabel, { id: "demo-simple-select-label", children: "Assembly" }), jsx(Select, { labelId: "demo-simple-select-label", id: "demo-simple-select", label: "Assembly", value: selectedAssembly?.name ?? '', onChange: handleChangeAssembly, style: { minWidth: 150 }, children: assemblies.map((option) => (jsx(MenuItem, { value: option.name, children: option.displayName }, option.name))) })] }) }), jsxs(Grid, { children: [jsx(InputLabel, { children: "Load RefName alias" }), jsx("input", { type: "file", onChange: handleChangeFileHandler, ref: fileRef, disabled: (enableSubmit && !errorMessage) || !selectedAssembly })] })] }), selectedAssembly && refNameAliasMap.size > 0 ? (jsxs("div", { style: { height: 200, width: '100%', marginTop: 20 }, children: [jsx(InputLabel, { children: "Refname aliases found for selected assembly." }), jsx(DataGrid, { rows: getTableRows(), columns: columns, initialState: {
4584
+ pagination: {
4585
+ paginationModel: { page: 0, pageSize: 5 },
4586
+ },
4587
+ }, pageSizeOptions: [5, 10], onRowSelectionModelChange: rowSelectionChange, processRowUpdate: processRowUpdate, checkboxSelection: true, disableRowSelectionExcludeModel: true })] })) : null] }), jsxs(DialogActions, { children: [jsx(Button, { variant: "contained", type: "submit", disabled: !enableSubmit, onClick: handleSubmit, children: "Submit" }), jsx(Button, { variant: "outlined", type: "submit", onClick: handleClose, children: "Close" })] }), errorMessage ? (jsx(DialogContent, { children: jsx(DialogContentText, { color: "error", children: errorMessage }) })) : null] }));
4872
4588
  });
4873
4589
 
4874
- /* eslint-disable @typescript-eslint/unbound-method */
4875
4590
  function ViewCheckResults({ handleClose, session, }) {
4876
4591
  const { internetAccounts } = getRoot(session);
4877
4592
  const { collaborationServerDriver } = session.apolloDataStore;
@@ -4930,20 +4645,12 @@ function ViewCheckResults({ handleClose, session, }) {
4930
4645
  const newAssembly = assemblies.find((asm) => asm.name === e.target.value);
4931
4646
  setSelectedAssembly(newAssembly);
4932
4647
  }
4933
- return (React.createElement(Dialog, { open: true, fullScreen: true, title: "View check results", handleClose: handleClose, "data-testid": "view-check-results" },
4934
- React.createElement(Select, { style: { width: 200, marginLeft: 40 }, value: selectedAssembly?.name ?? '', onChange: handleChangeAssembly, disabled: assemblies.length === 0 }, assemblies.map((option) => (React.createElement(MenuItem, { key: option.name, value: option.name }, option.displayName)))),
4935
- React.createElement(DialogContent, null,
4936
- React.createElement(DataGrid, { pagination: true, rows: displayGridData, columns: gridColumns, getRowId: (row) => row._id, slots: { toolbar: GridToolbar }, initialState: {
4937
- sorting: { sortModel: [{ field: 'name', sort: 'asc' }] },
4938
- columns: { columnVisibilityModel: { name: true } },
4939
- } })),
4940
- React.createElement(DialogActions, null,
4941
- React.createElement(Button, { variant: "outlined", type: "submit", onClick: handleClose }, "Close")),
4942
- errorMessage ? (React.createElement(DialogContent, null,
4943
- React.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
4648
+ return (jsxs(Dialog, { open: true, fullScreen: true, title: "View check results", handleClose: handleClose, "data-testid": "view-check-results", children: [jsx(Select, { style: { width: 200, marginLeft: 40 }, value: selectedAssembly?.name ?? '', onChange: handleChangeAssembly, disabled: assemblies.length === 0, children: assemblies.map((option) => (jsx(MenuItem, { value: option.name, children: option.displayName }, option.name))) }), jsx(DialogContent, { children: jsx(DataGrid, { pagination: true, rows: displayGridData, columns: gridColumns, getRowId: (row) => row._id, slots: { toolbar: GridToolbar }, initialState: {
4649
+ sorting: { sortModel: [{ field: 'name', sort: 'asc' }] },
4650
+ columns: { columnVisibilityModel: { name: true } },
4651
+ } }) }), jsx(DialogActions, { children: jsx(Button, { variant: "outlined", type: "submit", onClick: handleClose, children: "Close" }) }), errorMessage ? (jsx(DialogContent, { children: jsx(DialogContentText, { color: "error", children: errorMessage }) })) : null] }));
4944
4652
  }
4945
4653
 
4946
- /* eslint-disable @typescript-eslint/unbound-method */
4947
4654
  function exonIsSplittable(exonToBeSplit) {
4948
4655
  if (exonToBeSplit.max - exonToBeSplit.min < 2) {
4949
4656
  return {
@@ -4990,15 +4697,61 @@ function SplitExon({ changeManager, handleClose, selectedFeature, setSelectedFea
4990
4697
  handleClose();
4991
4698
  event.preventDefault();
4992
4699
  }
4993
- return (React.createElement(Dialog, { open: true, title: "Split exon", handleClose: handleClose, maxWidth: false, "data-testid": "split-exon" },
4994
- React.createElement("form", { onSubmit: onSubmit },
4995
- React.createElement(DialogContent, { style: { display: 'flex', flexDirection: 'column' } },
4996
- React.createElement(DialogContentText, null, makeDialogText(exonToBeSplit))),
4997
- React.createElement(DialogActions, null,
4998
- React.createElement(Button, { variant: "contained", type: "submit", disabled: !exonIsSplittable(exonToBeSplit).isSplittable }, "Yes"),
4999
- React.createElement(Button, { variant: "outlined", type: "submit", onClick: handleClose }, "Cancel"))),
5000
- errorMessage ? (React.createElement(DialogContent, null,
5001
- React.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
4700
+ return (jsxs(Dialog, { open: true, title: "Split exon", handleClose: handleClose, maxWidth: false, "data-testid": "split-exon", children: [jsxs("form", { onSubmit: onSubmit, children: [jsx(DialogContent, { style: { display: 'flex', flexDirection: 'column' }, children: jsx(DialogContentText, { children: makeDialogText(exonToBeSplit) }) }), jsxs(DialogActions, { children: [jsx(Button, { variant: "contained", type: "submit", disabled: !exonIsSplittable(exonToBeSplit).isSplittable, children: "Yes" }), jsx(Button, { variant: "outlined", type: "submit", onClick: handleClose, children: "Cancel" })] })] }), errorMessage ? (jsx(DialogContent, { children: jsx(DialogContentText, { color: "error", children: errorMessage }) })) : null] }));
4701
+ }
4702
+
4703
+ function DuplicateTranscript({ changeManager, handleClose, session, sourceAssemblyId, sourceFeature, setSelectedFeature, }) {
4704
+ const [errorMessage, setErrorMessage] = useState('');
4705
+ const { notify } = session;
4706
+ async function onSubmit(event) {
4707
+ event.preventDefault();
4708
+ setErrorMessage('');
4709
+ try {
4710
+ const parentGene = sourceFeature.parent;
4711
+ if (!parentGene) {
4712
+ setErrorMessage('No parent gene found for this transcript');
4713
+ return;
4714
+ }
4715
+ const transcriptSnapshot = getSnapshot(sourceFeature);
4716
+ const newTranscriptId = new ObjectID().toHexString();
4717
+ const duplicateTranscript = {
4718
+ ...transcriptSnapshot,
4719
+ _id: newTranscriptId,
4720
+ };
4721
+ if (duplicateTranscript.children) {
4722
+ const newChildren = {};
4723
+ for (const [, child] of Object.entries(duplicateTranscript.children)) {
4724
+ const newChildId = new ObjectID().toHexString();
4725
+ newChildren[newChildId] = {
4726
+ ...child,
4727
+ _id: newChildId,
4728
+ };
4729
+ }
4730
+ duplicateTranscript.children = newChildren;
4731
+ }
4732
+ const change = new AddFeatureChange({
4733
+ parentFeatureId: parentGene._id,
4734
+ changedIds: [parentGene._id],
4735
+ typeName: 'AddFeatureChange',
4736
+ assembly: sourceAssemblyId,
4737
+ addedFeature: duplicateTranscript,
4738
+ });
4739
+ await changeManager.submit(change).then(() => {
4740
+ setSelectedFeature(undefined);
4741
+ session.apolloSetSelectedFeature(newTranscriptId);
4742
+ notify('Successfully duplicated transcript', 'success');
4743
+ });
4744
+ handleClose();
4745
+ }
4746
+ catch (error) {
4747
+ setErrorMessage(error instanceof Error
4748
+ ? error.message
4749
+ : 'Failed to duplicate transcript');
4750
+ }
4751
+ }
4752
+ return (jsxs(Dialog, { open: true, title: "Duplicate transcript", handleClose: handleClose, maxWidth: false, "data-testid": "duplicate-transcript", children: [jsxs("form", { onSubmit: (event) => {
4753
+ void onSubmit(event);
4754
+ }, children: [jsx(DialogContent, { style: { display: 'flex', flexDirection: 'column' }, children: jsx(DialogContentText, { children: "Are you sure you want to create a duplicate of this transcript?" }) }), jsxs(DialogActions, { children: [jsx(Button, { variant: "contained", type: "submit", children: "Yes" }), jsx(Button, { variant: "outlined", type: "button", onClick: handleClose, children: "Cancel" })] })] }), errorMessage ? (jsx(DialogContent, { children: jsx(DialogContentText, { color: "error", children: errorMessage }) })) : null] }));
5002
4755
  }
5003
4756
 
5004
4757
  function addTopLevelAdminMenus(rootModel) {
@@ -5123,20 +4876,12 @@ function addTopLevelAdminMenus(rootModel) {
5123
4876
  // Icon source: https://developers.google.com/identity/branding-guidelines
5124
4877
  function Google(props) {
5125
4878
  const { color } = props;
5126
- return (React.createElement(SvgIcon, { viewBox: "0 0 18 18", style: { fontSize: 18, marginRight: 4 }, ...props }, color === 'disabled' ? (React.createElement("path", { d: "M9.001,10.71 l0,-3.348 l8.424,0 c0.126,0.567,0.225,1.098,0.225,1.845 c0,5.139,-3.447,8.793,-8.64,8.793 c-4.968,0,-9,-4.032,-9,-9 c0,-4.968,4.032,-9,9,-9 c2.43,0,4.464,0.891,6.021,2.349 l-2.556,2.484 c-0.648,-0.612,-1.782,-1.332,-3.465,-1.332 c-2.979,0,-5.409,2.475,-5.409,5.508 c0,3.033,2.43,5.508,5.409,5.508 c3.447,0,4.716,-2.385,4.95,-3.798 l-4.959,0 l0,-0.009 z" })) : (React.createElement(React.Fragment, null,
5127
- React.createElement("path", { d: "M17.64,9.20454545 c0,-0.638,-0.057,-1.252,-0.164,-1.841 l-8.476,0 l0,3.481 l4.844,0 c-0.209,1.125,-0.843,2.079,-1.796,2.717 l0,2.258 l2.908,0 c1.702,-1.567,2.684,-3.874,2.684,-6.615 l0,0 z", fill: "#4285F4" }),
5128
- React.createElement("path", { d: "M9,18 c2.43,0,4.467,-0.806,5.956,-2.18 l-2.908,-2.259 c-0.806,0.54,-1.837,0.859,-3.048,0.859 c-2.344,0,-4.328,-1.583,-5.036,-3.71 l-3.007,0 l0,2.332 c1.481,2.941,4.525,4.958,8.043,4.958 l0,0 z", fill: "#34A853" }),
5129
- React.createElement("path", { d: "M3.96409091,10.71 c-0.18,-0.54,-0.282,-1.117,-0.282,-1.71 c0,-0.593,0.102,-1.17,0.282,-1.71 l0,-2.332 l-3.007,0 c-0.609,1.215,-0.957,2.59,-0.957,4.042 c0,1.452,0.348,2.827,0.957,4.042 l3.007,-2.332 l0,0 z", fill: "#FBBC05" }),
5130
- React.createElement("path", { d: "M9,3.57954545 c1.321,0,2.508,0.454,3.44,1.346 l2.582,-2.581 c-1.559,-1.453,-3.596,-2.345,-6.022,-2.345 c-3.518,0,-6.562,2.017,-8.043,4.959 l3.007,2.331 c0.708,-2.127,2.692,-3.71,5.036,-3.71 l0,0 z", fill: "#EA4335" })))));
4879
+ return (jsx(SvgIcon, { viewBox: "0 0 18 18", style: { fontSize: 18, marginRight: 4 }, ...props, children: color === 'disabled' ? (jsx("path", { d: "M9.001,10.71 l0,-3.348 l8.424,0 c0.126,0.567,0.225,1.098,0.225,1.845 c0,5.139,-3.447,8.793,-8.64,8.793 c-4.968,0,-9,-4.032,-9,-9 c0,-4.968,4.032,-9,9,-9 c2.43,0,4.464,0.891,6.021,2.349 l-2.556,2.484 c-0.648,-0.612,-1.782,-1.332,-3.465,-1.332 c-2.979,0,-5.409,2.475,-5.409,5.508 c0,3.033,2.43,5.508,5.409,5.508 c3.447,0,4.716,-2.385,4.95,-3.798 l-4.959,0 l0,-0.009 z" })) : (jsxs(Fragment, { children: [jsx("path", { d: "M17.64,9.20454545 c0,-0.638,-0.057,-1.252,-0.164,-1.841 l-8.476,0 l0,3.481 l4.844,0 c-0.209,1.125,-0.843,2.079,-1.796,2.717 l0,2.258 l2.908,0 c1.702,-1.567,2.684,-3.874,2.684,-6.615 l0,0 z", fill: "#4285F4" }), jsx("path", { d: "M9,18 c2.43,0,4.467,-0.806,5.956,-2.18 l-2.908,-2.259 c-0.806,0.54,-1.837,0.859,-3.048,0.859 c-2.344,0,-4.328,-1.583,-5.036,-3.71 l-3.007,0 l0,2.332 c1.481,2.941,4.525,4.958,8.043,4.958 l0,0 z", fill: "#34A853" }), jsx("path", { d: "M3.96409091,10.71 c-0.18,-0.54,-0.282,-1.117,-0.282,-1.71 c0,-0.593,0.102,-1.17,0.282,-1.71 l0,-2.332 l-3.007,0 c-0.609,1.215,-0.957,2.59,-0.957,4.042 c0,1.452,0.348,2.827,0.957,4.042 l3.007,-2.332 l0,0 z", fill: "#FBBC05" }), jsx("path", { d: "M9,3.57954545 c1.321,0,2.508,0.454,3.44,1.346 l2.582,-2.581 c-1.559,-1.453,-3.596,-2.345,-6.022,-2.345 c-3.518,0,-6.562,2.017,-8.043,4.959 l3.007,2.331 c0.708,-2.127,2.692,-3.71,5.036,-3.71 l0,0 z", fill: "#EA4335" })] })) }));
5131
4880
  }
5132
4881
  // Icon source: https://learn.microsoft.com/en-us/azure/active-directory/develop/howto-add-branding-in-azure-ad-apps
5133
4882
  function Microsoft(props) {
5134
4883
  const { color } = props;
5135
- return (React.createElement(SvgIcon, { viewBox: "0 0 21 21", style: { fontSize: 21 }, ...props },
5136
- React.createElement("rect", { x: "1", y: "1", width: "9", height: "9", fill: color === 'disabled' ? '#7B7B7B' : '#F25022' }),
5137
- React.createElement("rect", { x: "1", y: "11", width: "9", height: "9", fill: color === 'disabled' ? '#7B7B7B' : '#00A4EF' }),
5138
- React.createElement("rect", { x: "11", y: "1", width: "9", height: "9", fill: color === 'disabled' ? '#939393' : '#7FBA00' }),
5139
- React.createElement("rect", { x: "11", y: "11", width: "9", height: "9", fill: color === 'disabled' ? '#B9B9B9' : '#FFB900' })));
4884
+ return (jsxs(SvgIcon, { viewBox: "0 0 21 21", style: { fontSize: 21 }, ...props, children: [jsx("rect", { x: "1", y: "1", width: "9", height: "9", fill: color === 'disabled' ? '#7B7B7B' : '#F25022' }), jsx("rect", { x: "1", y: "11", width: "9", height: "9", fill: color === 'disabled' ? '#7B7B7B' : '#00A4EF' }), jsx("rect", { x: "11", y: "1", width: "9", height: "9", fill: color === 'disabled' ? '#939393' : '#7FBA00' }), jsx("rect", { x: "11", y: "11", width: "9", height: "9", fill: color === 'disabled' ? '#B9B9B9' : '#FFB900' })] }));
5140
4885
  }
5141
4886
 
5142
4887
  const useStyles$d = makeStyles()((theme) => ({
@@ -5153,19 +4898,18 @@ const useStyles$d = makeStyles()((theme) => ({
5153
4898
  function GoogleButton(props) {
5154
4899
  const { classes } = useStyles$d();
5155
4900
  const { disabled } = props;
5156
- return (React.createElement(Button, { className: classes.loginButton, variant: "outlined", startIcon: React.createElement(Google, { color: disabled ? 'disabled' : undefined }), ...props }, "Sign in with Google"));
4901
+ return (jsx(Button, { className: classes.loginButton, variant: "outlined", startIcon: jsx(Google, { color: disabled ? 'disabled' : undefined }), ...props, children: "Sign in with Google" }));
5157
4902
  }
5158
4903
  function MicrosoftButton(props) {
5159
4904
  const { classes } = useStyles$d();
5160
4905
  const { disabled } = props;
5161
- return (React.createElement(Button, { className: classes.loginButton, variant: "outlined", startIcon: React.createElement(Microsoft, { color: disabled ? 'disabled' : undefined }), ...props }, "Sign in with Microsoft"));
4906
+ return (jsx(Button, { className: classes.loginButton, variant: "outlined", startIcon: jsx(Microsoft, { color: disabled ? 'disabled' : undefined }), ...props, children: "Sign in with Microsoft" }));
5162
4907
  }
5163
4908
  function GuestButton(props) {
5164
4909
  const { classes } = useStyles$d();
5165
- return (React.createElement(Button, { className: classes.loginButton, variant: "outlined", startIcon: React.createElement(AccountCircleIcon, { fontSize: "small" }), ...props }, "Continue as Guest"));
4910
+ return (jsx(Button, { className: classes.loginButton, variant: "outlined", startIcon: jsx(AccountCircleIcon, { fontSize: "small" }), ...props, children: "Continue as Guest" }));
5166
4911
  }
5167
4912
 
5168
- /* eslint-disable @typescript-eslint/use-unknown-in-catch-callback-variable */
5169
4913
  const useStyles$c = makeStyles()((theme) => ({
5170
4914
  divider: {
5171
4915
  marginTop: theme.spacing(4),
@@ -5196,7 +4940,7 @@ const AuthTypeSelector = ({ baseURL, handleClose, name, }) => {
5196
4940
  }
5197
4941
  });
5198
4942
  return () => {
5199
- controller.abort('AuthTypeSelector');
4943
+ controller.abort(new DOMException('Error retrieving valid authentication types', 'AbortError'));
5200
4944
  };
5201
4945
  }, [baseURL]);
5202
4946
  function handleClick(authType) {
@@ -5213,28 +4957,24 @@ const AuthTypeSelector = ({ baseURL, handleClose, name, }) => {
5213
4957
  const allowGoogle = loginTypes.includes('google');
5214
4958
  const allowMicrosoft = loginTypes.includes('microsoft');
5215
4959
  const allowGuest = loginTypes.includes('guest');
5216
- return (React.createElement(Dialog, { open: true, title: `Log in to ${name}`, handleClose: handleClose, maxWidth: false, "data-testid": "login-apollo" },
5217
- React.createElement(DialogContent, { style: { display: 'flex', flexDirection: 'column', paddingTop: 8 } },
5218
- allowGoogle ? (React.createElement(GoogleButton, { disabled: !allowGoogle, onClick: () => {
5219
- handleClick('google');
5220
- } })) : null,
5221
- allowMicrosoft ? (React.createElement(MicrosoftButton, { disabled: !allowMicrosoft, onClick: () => {
5222
- handleClick('microsoft');
5223
- } })) : null,
5224
- allowGuest ? (React.createElement(React.Fragment, null,
5225
- React.createElement(Divider, { className: classes.divider }),
5226
- React.createElement(GuestButton, { onClick: () => {
5227
- handleClick('guest');
5228
- } }))) : null),
5229
- React.createElement(DialogActions, null,
5230
- React.createElement(Button, { variant: "outlined", type: "submit", onClick: () => {
5231
- handleClose();
5232
- } }, "Cancel")),
5233
- errorMessage ? (React.createElement(DialogContent, null,
5234
- React.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
4960
+ return (jsxs(Dialog, { open: true, title: `Log in to ${name}`, handleClose: handleClose, maxWidth: false, "data-testid": "login-apollo", children: [jsxs(DialogContent, { style: { display: 'flex', flexDirection: 'column', paddingTop: 8 }, children: [allowGoogle ? (jsx(GoogleButton, { disabled: !allowGoogle, onClick: () => {
4961
+ handleClick('google');
4962
+ } })) : null, allowMicrosoft ? (jsx(MicrosoftButton, { disabled: !allowMicrosoft, onClick: () => {
4963
+ handleClick('microsoft');
4964
+ } })) : null, allowGuest ? (jsxs(Fragment, { children: [jsx(Divider, { className: classes.divider }), jsx(GuestButton, { onClick: () => {
4965
+ handleClick('guest');
4966
+ } })] })) : null] }), jsx(DialogActions, { children: jsx(Button, { variant: "outlined", type: "submit", onClick: () => {
4967
+ handleClose();
4968
+ }, children: "Cancel" }) }), errorMessage ? (jsx(DialogContent, { children: jsx(DialogContentText, { color: "error", children: errorMessage }) })) : null] }));
5235
4969
  };
5236
4970
 
5237
4971
  /* eslint-disable @typescript-eslint/no-unsafe-return */
4972
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
4973
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
4974
+ /* eslint-disable @typescript-eslint/no-unsafe-call */
4975
+ /* eslint-disable @typescript-eslint/no-unsafe-argument */
4976
+ /* eslint-disable @typescript-eslint/unbound-method */
4977
+ /* eslint-disable @typescript-eslint/no-misused-promises */
5238
4978
  const inWebWorker$1 = typeof sessionStorage === 'undefined';
5239
4979
  const stateModelFactory$3 = (configSchema) => {
5240
4980
  return InternetAccount.named('ApolloInternetAccount')
@@ -5287,7 +5027,6 @@ const stateModelFactory$3 = (configSchema) => {
5287
5027
  },
5288
5028
  finishOAuthWindow(event, resolve, reject) {
5289
5029
  if (event.data.name !== `JBrowseAuthWindow-${self.internetAccountId}`) {
5290
- this.deleteMessageChannel();
5291
5030
  return;
5292
5031
  }
5293
5032
  const redirectUriWithInfo = event.data.redirectUri;
@@ -5646,7 +5385,7 @@ const stateModelFactory$3 = (configSchema) => {
5646
5385
  beforeDestroy() {
5647
5386
  self.removeBeforeUnloadListener();
5648
5387
  self.removeVisibilityChangeListener();
5649
- self.controller.abort('internet account beforeDestroy');
5388
+ self.controller.abort(new DOMException('Cleaning up Apollo connection', 'AbortError'));
5650
5389
  self.socket.close();
5651
5390
  },
5652
5391
  }));
@@ -5730,6 +5469,10 @@ function installApolloRefNameAliasAdapter(pluginManager) {
5730
5469
  }
5731
5470
 
5732
5471
  /* eslint-disable @typescript-eslint/prefer-promise-reject-errors */
5472
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
5473
+ /* eslint-disable @typescript-eslint/no-unsafe-argument */
5474
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
5475
+ /* eslint-disable @typescript-eslint/no-unsafe-call */
5733
5476
  function isApolloMessageData$1(data) {
5734
5477
  return (typeof data === 'object' &&
5735
5478
  data !== null &&
@@ -5890,6 +5633,23 @@ function installApolloSequenceAdapter(pluginManager) {
5890
5633
  }));
5891
5634
  }
5892
5635
 
5636
+ function getMatchedFeature(query, feature) {
5637
+ // @ts-expect-error this actually has a bit more info that a plain snapshot
5638
+ const { children, indexedIds, ...featureWithoutChildren } = feature;
5639
+ const featureString = JSON.stringify(featureWithoutChildren);
5640
+ if (featureString.includes(query)) {
5641
+ return feature;
5642
+ }
5643
+ if (!children) {
5644
+ return undefined;
5645
+ }
5646
+ for (const subFeature of Object.values(children)) {
5647
+ const matchedFeature = getMatchedFeature(query, subFeature);
5648
+ if (matchedFeature) {
5649
+ return matchedFeature;
5650
+ }
5651
+ }
5652
+ }
5893
5653
  class ApolloTextSearchAdapter extends BaseAdapter {
5894
5654
  get baseURL() {
5895
5655
  return readConfObject(this.config, 'baseURL').uri;
@@ -5902,11 +5662,13 @@ class ApolloTextSearchAdapter extends BaseAdapter {
5902
5662
  }
5903
5663
  mapBaseResult(features, assembly, query) {
5904
5664
  return features.map((feature) => {
5665
+ const matchedObject = getMatchedFeature(query, feature) ?? feature;
5905
5666
  const refName = assembly.getCanonicalRefName(feature.refSeq);
5906
5667
  return new BaseResult({
5907
5668
  label: query,
5908
5669
  trackId: this.trackId,
5909
- locString: `${refName}:${feature.min + 1}..${feature.max}`,
5670
+ locString: `${refName}:${matchedObject.min + 1}..${matchedObject.max}`,
5671
+ matchedObject,
5910
5672
  });
5911
5673
  });
5912
5674
  }
@@ -5988,10 +5750,7 @@ function AttributeKey({ attributeKey: key }) {
5988
5750
  titleText =
5989
5751
  'On GFF3 export, this attribute will be changed to start with a lower-case letter because attributes starting with an upper-case letter are reserved in GFF3';
5990
5752
  }
5991
- return (React.createElement("div", { style: { display: 'flex' } },
5992
- React.createElement(Typography, { className: classes.attributeKey }, displayKey),
5993
- titleText ? (React.createElement(Tooltip, { title: titleText },
5994
- React.createElement(Chip, { icon: React.createElement(InfoIcon, null), label: "GFF3", size: "small", variant: "outlined" }))) : null));
5753
+ return (jsxs("div", { style: { display: 'flex' }, children: [jsx(Typography, { className: classes.attributeKey, children: displayKey }), titleText ? (jsx(Tooltip, { title: titleText, children: jsx(Chip, { icon: jsx(InfoIcon, {}), label: "GFF3", size: "small", variant: "outlined" }) })) : null] }));
5995
5754
  }
5996
5755
 
5997
5756
  const customKeyName = 'Custom';
@@ -6022,22 +5781,13 @@ const AttributeKeySelector = observer(function AttributeKeySelector({ setKey, se
6022
5781
  function handleCancel() {
6023
5782
  setKey();
6024
5783
  }
6025
- return (React.createElement("form", { onSubmit: handleSubmit },
6026
- React.createElement("div", { style: { display: 'flex', flexDirection: 'column', margin: 8 } },
6027
- React.createElement(FormControl, { variant: "outlined" },
6028
- React.createElement(InputLabel, { id: "attribute-key-select-label" }, "Key"),
6029
- React.createElement(Select, { labelId: "attribute-key-select-label", value: selectedKey, label: "Key", onChange: (event) => {
6030
- setSelectedKey(event.target.value);
6031
- } }, Object.keys(reservedKeys).map((val) => (React.createElement(MenuItem, { key: val, value: val }, val))))),
6032
- isCustom ? (React.createElement(TextField, { label: "Attribute key", variant: "outlined", id: "attributeKey", onChange: (event) => {
6033
- setCustomKey(event.target.value);
6034
- } })) : null),
6035
- React.createElement(DialogActions, null,
6036
- React.createElement(Button, { color: "primary", variant: "contained", type: "submit", disabled: isCustom && !customKey }, "Add"),
6037
- React.createElement(Button, { variant: "outlined", onClick: handleCancel }, "Cancel"))));
5784
+ return (jsxs("form", { onSubmit: handleSubmit, children: [jsxs("div", { style: { display: 'flex', flexDirection: 'column', margin: 8 }, children: [jsxs(FormControl, { variant: "outlined", children: [jsx(InputLabel, { id: "attribute-key-select-label", children: "Key" }), jsx(Select, { labelId: "attribute-key-select-label", value: selectedKey, label: "Key", onChange: (event) => {
5785
+ setSelectedKey(event.target.value);
5786
+ }, children: Object.keys(reservedKeys).map((val) => (jsx(MenuItem, { value: val, children: val }, val))) })] }), isCustom ? (jsx(TextField, { label: "Attribute key", variant: "outlined", id: "attributeKey", onChange: (event) => {
5787
+ setCustomKey(event.target.value);
5788
+ } })) : null] }), jsxs(DialogActions, { children: [jsx(Button, { color: "primary", variant: "contained", type: "submit", disabled: isCustom && !customKey, children: "Add" }), jsx(Button, { variant: "outlined", onClick: handleCancel, children: "Cancel" })] })] }));
6038
5789
  });
6039
5790
 
6040
- /* eslint-disable @typescript-eslint/unbound-method */
6041
5791
  const StringTextField = observer(function StringTextField({ onChangeCommitted, value: initialValue, ...props }) {
6042
5792
  const [value, setValue] = useState(String(initialValue));
6043
5793
  const [blur, setBlur] = useState(false);
@@ -6054,7 +5804,7 @@ const StringTextField = observer(function StringTextField({ onChangeCommitted, v
6054
5804
  function onChange(event) {
6055
5805
  setValue(event.target.value);
6056
5806
  }
6057
- return (React.createElement(TextField, { ...props, type: "text", onChange: onChange, value: value, onKeyDown: (event) => {
5807
+ return (jsx(TextField, { ...props, type: "text", onChange: onChange, value: value, onKeyDown: (event) => {
6058
5808
  if (event.key === 'Enter') {
6059
5809
  inputNode?.blur();
6060
5810
  }
@@ -6094,28 +5844,19 @@ const DefaultAttributeEditor = observer(function DefaultAttributeEditor({ attrib
6094
5844
  return newValues;
6095
5845
  });
6096
5846
  }
6097
- return (React.createElement(React.Fragment, null,
6098
- newValues.map((value, idx) => (React.createElement("div", { key: `${idx}-${value}`, style: { display: 'flex' } },
6099
- React.createElement(StringTextField, { value: value, onChangeCommitted: (editedValue) => {
6100
- updateValue(idx, editedValue);
6101
- }, variant: "outlined", fullWidth: true }),
6102
- React.createElement(IconButton, { "aria-label": "delete", size: "medium", edge: "end", onClick: () => {
6103
- deleteValue(idx);
6104
- } },
6105
- React.createElement(DeleteIcon, { fontSize: "inherit" }))))),
6106
- React.createElement(IconButton, { "aria-label": "add", size: "medium", color: "secondary", edge: "start", onClick: addValue },
6107
- React.createElement(AddBoxIcon, { fontSize: "inherit" })),
6108
- React.createElement(DialogActions, null,
6109
- React.createElement(Button, { color: "primary", variant: "contained", onClick: () => {
6110
- setAttribute(newValues.filter(Boolean));
6111
- } }, isNew ? 'Add' : 'Update'),
6112
- React.createElement(Button, { variant: "outlined", type: "submit", onClick: () => {
6113
- setAttribute();
6114
- } }, "Cancel"))));
5847
+ return (jsxs(Fragment, { children: [newValues.map((value, idx) => (jsxs("div", { style: { display: 'flex' }, children: [jsx(StringTextField, { value: value, onChangeCommitted: (editedValue) => {
5848
+ updateValue(idx, editedValue);
5849
+ }, variant: "outlined", fullWidth: true }), jsx(IconButton, { "aria-label": "delete", size: "medium", edge: "end", onClick: () => {
5850
+ deleteValue(idx);
5851
+ }, children: jsx(DeleteIcon, { fontSize: "inherit" }) })] }, `${idx}-${value}`))), jsx(IconButton, { "aria-label": "add", size: "medium", color: "secondary", edge: "start", onClick: addValue, children: jsx(AddBoxIcon, { fontSize: "inherit" }) }), jsxs(DialogActions, { children: [jsx(Button, { color: "primary", variant: "contained", onClick: () => {
5852
+ setAttribute(newValues.filter(Boolean));
5853
+ }, children: isNew ? 'Add' : 'Update' }), jsx(Button, { variant: "outlined", type: "submit", onClick: () => {
5854
+ setAttribute();
5855
+ }, children: "Cancel" })] })] }));
6115
5856
  });
6116
5857
 
6117
5858
  function DefaultAttributeViewer({ values }) {
6118
- return (React.createElement(React.Fragment, null, values?.map((value, idx) => (React.createElement(Typography, { key: `${idx}.${value}`, variant: "body2", color: "textSecondary" }, value)))));
5859
+ return (jsx(Fragment, { children: values?.map((value, idx) => (jsx(Typography, { variant: "body2", color: "textSecondary", children: value }, `${idx}.${value}`))) }));
6119
5860
  }
6120
5861
 
6121
5862
  const useStyles$a = makeStyles()((theme) => ({
@@ -6214,49 +5955,30 @@ const Attributes = observer(function Attributes({ assembly, editable, feature, s
6214
5955
  void changeManager.submit(change);
6215
5956
  }
6216
5957
  const NewKeyAttributeEditor = pluginManager.evaluateExtensionPoint('Apollo-AttributeEditorComponent', DefaultAttributeEditor, { key: newKey });
6217
- return (React.createElement(React.Fragment, null,
6218
- React.createElement(List, { className: classes.list },
6219
- entries(attributes).map(([key, values]) => {
6220
- const AttributeEditor = pluginManager.evaluateExtensionPoint('Apollo-AttributeEditorComponent', DefaultAttributeEditor, { key });
6221
- const AttributeViewer = pluginManager.evaluateExtensionPoint('Apollo-AttributeViewerComponent', DefaultAttributeViewer, { key });
6222
- return (React.createElement(ListItem, { key: key, secondaryAction: editable && !editingKey ? (React.createElement(IconButton, { edge: "end", onClick: (event) => {
6223
- handleListMenuClick(event, key);
6224
- } },
6225
- React.createElement(MoreHorizIcon, null))) : null },
6226
- React.createElement(ListItemText, { disableTypography: true, primary: React.createElement(AttributeKey, { attributeKey: key }), secondary: editingKey === key ? (React.createElement(AttributeEditor, { session: session, attributeValues: values, setAttribute: (newValues) => {
6227
- setEditingKey(null);
6228
- if (newValues) {
6229
- modifyFeatureAttribute(key, newValues);
6230
- }
6231
- } })) : (React.createElement(AttributeViewer, { values: values })) })));
6232
- }),
6233
- newKey ? (React.createElement(ListItem, null,
6234
- React.createElement(ListItemText, { disableTypography: true, primary: React.createElement(AttributeKey, { attributeKey: newKey }), secondary: React.createElement(NewKeyAttributeEditor, { session: session, attributeValues: [], setAttribute: (newValues) => {
6235
- if (newValues) {
6236
- addFeatureAttribute(newKey, newValues);
6237
- }
6238
- setNewKey(undefined);
6239
- }, isNew: true }) }))) : null),
6240
- editable ? (React.createElement(Button, { color: "primary", variant: "contained", disabled: showAddNewForm || Boolean(newKey), onClick: () => {
6241
- setShowAddNewForm(true);
6242
- } }, "Add new")) : null,
6243
- showAddNewForm ? (React.createElement(Paper, { variant: "outlined", style: { marginTop: 8 } },
6244
- React.createElement(AttributeKeySelector, { session: session, setKey: (newKey) => {
6245
- setNewKey(newKey);
6246
- setShowAddNewForm(false);
6247
- } }))) : null,
6248
- React.createElement(Menu, { anchorEl: anchorEl, open: open, onClose: handleClose },
6249
- React.createElement(MenuItem, { onClick: handleDelete },
6250
- React.createElement(ListItemIcon, null,
6251
- React.createElement(DeleteIcon, { fontSize: "small" })),
6252
- React.createElement(Typography, { variant: "inherit" }, "Delete")),
6253
- React.createElement(MenuItem, { onClick: handleEdit },
6254
- React.createElement(ListItemIcon, null,
6255
- React.createElement(EditIcon, { fontSize: "small" })),
6256
- React.createElement(Typography, { variant: "inherit" }, "Edit")))));
5958
+ return (jsxs(Fragment, { children: [jsxs(List, { className: classes.list, children: [entries(attributes).map(([key, values]) => {
5959
+ const AttributeEditor = pluginManager.evaluateExtensionPoint('Apollo-AttributeEditorComponent', DefaultAttributeEditor, { key });
5960
+ const AttributeViewer = pluginManager.evaluateExtensionPoint('Apollo-AttributeViewerComponent', DefaultAttributeViewer, { key });
5961
+ return (jsx(ListItem, { secondaryAction: editable && !editingKey ? (jsx(IconButton, { edge: "end", onClick: (event) => {
5962
+ handleListMenuClick(event, key);
5963
+ }, children: jsx(MoreHorizIcon, {}) })) : null, children: jsx(ListItemText, { disableTypography: true, primary: jsx(AttributeKey, { attributeKey: key }), secondary: editingKey === key ? (jsx(AttributeEditor, { session: session, attributeValues: values, setAttribute: (newValues) => {
5964
+ setEditingKey(null);
5965
+ if (newValues) {
5966
+ modifyFeatureAttribute(key, newValues);
5967
+ }
5968
+ } })) : (jsx(AttributeViewer, { values: values })) }) }, key));
5969
+ }), newKey ? (jsx(ListItem, { children: jsx(ListItemText, { disableTypography: true, primary: jsx(AttributeKey, { attributeKey: newKey }), secondary: jsx(NewKeyAttributeEditor, { session: session, attributeValues: [], setAttribute: (newValues) => {
5970
+ if (newValues) {
5971
+ addFeatureAttribute(newKey, newValues);
5972
+ }
5973
+ setNewKey(undefined);
5974
+ }, isNew: true }) }) })) : null] }), editable ? (jsx(Button, { color: "primary", variant: "contained", disabled: showAddNewForm || Boolean(newKey), onClick: () => {
5975
+ setShowAddNewForm(true);
5976
+ }, children: "Add new" })) : null, showAddNewForm ? (jsx(Paper, { variant: "outlined", style: { marginTop: 8 }, children: jsx(AttributeKeySelector, { session: session, setKey: (newKey) => {
5977
+ setNewKey(newKey);
5978
+ setShowAddNewForm(false);
5979
+ } }) })) : null, jsxs(Menu, { anchorEl: anchorEl, open: open, onClose: handleClose, children: [jsxs(MenuItem, { onClick: handleDelete, children: [jsx(ListItemIcon, { children: jsx(DeleteIcon, { fontSize: "small" }) }), jsx(Typography, { variant: "inherit", children: "Delete" })] }), jsxs(MenuItem, { onClick: handleEdit, children: [jsx(ListItemIcon, { children: jsx(EditIcon, { fontSize: "small" }) }), jsx(Typography, { variant: "inherit", children: "Edit" })] })] })] }));
6257
5980
  });
6258
5981
 
6259
- /* eslint-disable @typescript-eslint/unbound-method */
6260
5982
  const NumberTextField = observer(function NumberTextField({ onChangeCommitted, value: initialValue, ...props }) {
6261
5983
  const [value, setValue] = useState(String(initialValue));
6262
5984
  const [blur, setBlur] = useState(false);
@@ -6274,7 +5996,7 @@ const NumberTextField = observer(function NumberTextField({ onChangeCommitted, v
6274
5996
  setValue(event.target.value);
6275
5997
  }
6276
5998
  const error = Number.isNaN(Number(value));
6277
- return (React.createElement(TextField, { ...props, type: "text", onChange: onChange, value: value, onKeyDown: (event) => {
5999
+ return (jsx(TextField, { ...props, type: "text", onChange: onChange, value: value, onKeyDown: (event) => {
6278
6000
  if (event.key === 'Enter') {
6279
6001
  inputNode?.blur();
6280
6002
  }
@@ -6367,24 +6089,11 @@ const BasicInformation = observer(function BasicInformation({ assembly, feature,
6367
6089
  }
6368
6090
  return terms;
6369
6091
  }
6370
- return (React.createElement("div", { "data-testid": "basic_information" },
6371
- React.createElement(NumberTextField, { margin: "dense", id: "start", label: "Start", fullWidth: true, variant: "outlined", value: min + 1, onChangeCommitted: handleStartChange }),
6372
- React.createElement(NumberTextField, { margin: "dense", id: "end", label: "End", fullWidth: true, variant: "outlined", value: max, onChangeCommitted: handleEndChange }),
6373
- React.createElement(OntologyTermAutocomplete, { session: session, ontologyName: "Sequence Ontology", value: type, filterTerms: isOntologyClass, fetchValidTerms: fetchValidTerms.bind(null, feature), renderInput: (params) => (React.createElement(TextField, { ...params, label: "Type", variant: "outlined", fullWidth: true, error: Boolean(typeWarningText), helperText: typeWarningText })), onChange: (oldValue, newValue) => {
6374
- if (newValue) {
6375
- handleTypeChange(newValue).catch(notifyError);
6376
- }
6377
- } }),
6378
- React.createElement("label", null,
6379
- React.createElement("input", { type: "radio", value: "1", checked: strand === 1, onChange: handleStrandChange }),
6380
- "Positive Strand (+)"),
6381
- React.createElement("label", null,
6382
- React.createElement("input", { type: "radio", value: "-1", checked: strand === -1, onChange: handleStrandChange }),
6383
- "Negative Strand (-)"),
6384
- React.createElement("label", null,
6385
- React.createElement("input", { type: "radio", value: "", checked: strand === undefined, onChange: handleStrandChange }),
6386
- "No Strand Information"),
6387
- errorMessage ? (React.createElement(Typography, { color: "error" }, errorMessage)) : null));
6092
+ return (jsxs("div", { "data-testid": "basic_information", children: [jsx(NumberTextField, { margin: "dense", id: "start", label: "Start", fullWidth: true, variant: "outlined", value: min + 1, onChangeCommitted: handleStartChange }), jsx(NumberTextField, { margin: "dense", id: "end", label: "End", fullWidth: true, variant: "outlined", value: max, onChangeCommitted: handleEndChange }), jsx(OntologyTermAutocomplete, { session: session, ontologyName: "Sequence Ontology", value: type, filterTerms: isOntologyClass, fetchValidTerms: fetchValidTerms.bind(null, feature), renderInput: (params) => (jsx(TextField, { ...params, label: "Type", variant: "outlined", fullWidth: true, error: Boolean(typeWarningText), helperText: typeWarningText })), onChange: (oldValue, newValue) => {
6093
+ if (newValue) {
6094
+ handleTypeChange(newValue).catch(notifyError);
6095
+ }
6096
+ } }), jsxs("label", { children: [jsx("input", { type: "radio", value: "1", checked: strand === 1, onChange: handleStrandChange }), "Positive Strand (+)"] }), jsxs("label", { children: [jsx("input", { type: "radio", value: "-1", checked: strand === -1, onChange: handleStrandChange }), "Negative Strand (-)"] }), jsxs("label", { children: [jsx("input", { type: "radio", value: "", checked: strand === undefined, onChange: handleStrandChange }), "No Strand Information"] }), errorMessage ? (jsx(Typography, { color: "error", children: errorMessage })) : null] }));
6388
6097
  });
6389
6098
 
6390
6099
  const FeatureDetailsNavigation = observer(function FeatureDetailsNavigation(props) {
@@ -6399,39 +6108,16 @@ const FeatureDetailsNavigation = observer(function FeatureDetailsNavigation(prop
6399
6108
  if (!(parent ?? childFeatures.length > 0)) {
6400
6109
  return null;
6401
6110
  }
6402
- return (React.createElement("div", { style: { marginTop: 10 } },
6403
- parent && (React.createElement("div", null,
6404
- React.createElement(Typography, { variant: "h6" }, "Parent:"),
6405
- React.createElement(Button, { variant: "contained", onClick: () => {
6406
- model.setFeature(parent);
6407
- } },
6408
- parent.type,
6409
- getFeatureNameOrId$1(parent),
6410
- " (",
6411
- parent.min,
6412
- "..",
6413
- parent.max,
6414
- ")"))),
6415
- childFeatures.length > 0 && (React.createElement("div", null,
6416
- React.createElement(Typography, { variant: "h6" },
6417
- childFeatures.length === 1 ? 'Child' : 'Children',
6418
- ":"),
6419
- childFeatures.map((child) => (React.createElement("div", { key: child._id, style: { marginBottom: 5 } },
6420
- React.createElement(Button, { variant: "contained", onClick: () => {
6421
- model.setFeature(child);
6422
- } },
6423
- child.type,
6424
- getFeatureNameOrId$1(child),
6425
- " (",
6426
- child.min,
6427
- "..",
6428
- child.max,
6429
- ")"))))))));
6111
+ return (jsxs("div", { style: { marginTop: 10 }, children: [parent && (jsxs("div", { children: [jsx(Typography, { variant: "h6", children: "Parent:" }), jsxs(Button, { variant: "contained", onClick: () => {
6112
+ model.setFeature(parent);
6113
+ }, children: [parent.type, getFeatureNameOrId$1(parent), " (", parent.min, "..", parent.max, ")"] })] })), childFeatures.length > 0 && (jsxs("div", { children: [jsxs(Typography, { variant: "h6", children: [childFeatures.length === 1 ? 'Child' : 'Children', ":"] }), childFeatures.map((child) => (jsx("div", { style: { marginBottom: 5 }, children: jsxs(Button, { variant: "contained", onClick: () => {
6114
+ model.setFeature(child);
6115
+ }, children: [child.type, getFeatureNameOrId$1(child), " (", child.min, "..", child.max, ")"] }) }, child._id)))] }))] }));
6430
6116
  });
6431
6117
 
6432
6118
  function formatSequence(seq, refName, start, end, wrap) {
6433
6119
  const header = `>${refName}:${start + 1}–${end}\n`;
6434
- const body = wrap === undefined ? seq : splitStringIntoChunks(seq, wrap).join('\n');
6120
+ const body = seq ;
6435
6121
  return `${header}${body}`;
6436
6122
  }
6437
6123
  const useStyles$9 = makeStyles()({
@@ -6460,8 +6146,7 @@ const Sequence = observer(function Sequence({ assembly, feature, refName, sessio
6460
6146
  { assemblyName: assembly, refName, start: min, end: max },
6461
6147
  ]);
6462
6148
  }
6463
- return (React.createElement("div", null,
6464
- React.createElement("textarea", { readOnly: true, rows: 20, className: classes.sequence, value: sequence })));
6149
+ return (jsx("div", { children: jsx("textarea", { readOnly: true, rows: 20, className: classes.sequence, value: sequence }) }));
6465
6150
  });
6466
6151
 
6467
6152
  const useStyles$8 = makeStyles()((theme) => ({
@@ -6501,31 +6186,17 @@ const ApolloFeatureDetailsWidget = observer(function ApolloFeatureDetailsWidget(
6501
6186
  setPanelState(panelState.filter((p) => p !== panel));
6502
6187
  }
6503
6188
  }
6504
- return (React.createElement("div", { className: classes.root },
6505
- React.createElement(BasicInformation, { feature: feature, session: session, assembly: currentAssembly._id }),
6506
- React.createElement(Accordion, { style: { marginTop: 10 }, expanded: panelState.includes('attributes'), onChange: (e, expanded) => {
6507
- handlePanelChange(expanded, 'attributes');
6508
- } },
6509
- React.createElement(AccordionSummary, { expandIcon: React.createElement(ExpandMoreIcon, { style: { color: 'white' } }), "aria-controls": "panel1-content", id: "panel1-header" },
6510
- React.createElement(Typography, { component: "span" }, "Attributes")),
6511
- React.createElement(AccordionDetails, null,
6512
- React.createElement(Attributes, { feature: feature, session: session, assembly: currentAssembly._id, editable: true }))),
6513
- React.createElement(Accordion, { style: { marginTop: 10 }, expanded: panelState.includes('sequence'), onChange: (e, expanded) => {
6514
- handlePanelChange(expanded, 'sequence');
6515
- } },
6516
- React.createElement(AccordionSummary, { expandIcon: React.createElement(ExpandMoreIcon, { style: { color: 'white' } }), "aria-controls": "panel2-content", id: "panel2-header" },
6517
- React.createElement(Typography, { component: "span" }, "Sequence")),
6518
- React.createElement(AccordionDetails, null, panelState.includes('sequence') && (React.createElement(Sequence, { feature: feature, session: session, assembly: currentAssembly._id, refName: refName })))),
6519
- React.createElement(Accordion, { style: { marginTop: 10 }, expanded: panelState.includes('related_features'), onChange: (e, expanded) => {
6520
- handlePanelChange(expanded, 'related_features');
6521
- } },
6522
- React.createElement(AccordionSummary, { expandIcon: React.createElement(ExpandMoreIcon, { style: { color: 'white' } }), "aria-controls": "panel3-content", id: "panel3-header" },
6523
- React.createElement(Typography, { component: "span" }, "Related features")),
6524
- React.createElement(AccordionDetails, null,
6525
- React.createElement(FeatureDetailsNavigation, { model: model, feature: feature })))));
6189
+ return (jsxs("div", { className: classes.root, children: [jsx(BasicInformation, { feature: feature, session: session, assembly: currentAssembly._id }), jsxs(Accordion, { style: { marginTop: 10 }, expanded: panelState.includes('attributes'), onChange: (e, expanded) => {
6190
+ handlePanelChange(expanded, 'attributes');
6191
+ }, children: [jsx(AccordionSummary, { expandIcon: jsx(ExpandMoreIcon, { style: { color: 'white' } }), "aria-controls": "panel1-content", id: "panel1-header", children: jsx(Typography, { component: "span", children: "Attributes" }) }), jsx(AccordionDetails, { children: jsx(Attributes, { feature: feature, session: session, assembly: currentAssembly._id, editable: true }) })] }), jsxs(Accordion, { style: { marginTop: 10 }, expanded: panelState.includes('sequence'), onChange: (e, expanded) => {
6192
+ handlePanelChange(expanded, 'sequence');
6193
+ }, children: [jsx(AccordionSummary, { expandIcon: jsx(ExpandMoreIcon, { style: { color: 'white' } }), "aria-controls": "panel2-content", id: "panel2-header", children: jsx(Typography, { component: "span", children: "Sequence" }) }), jsx(AccordionDetails, { children: panelState.includes('sequence') && (jsx(Sequence, { feature: feature, session: session, assembly: currentAssembly._id, refName: refName })) })] }), jsxs(Accordion, { style: { marginTop: 10 }, expanded: panelState.includes('related_features'), onChange: (e, expanded) => {
6194
+ handlePanelChange(expanded, 'related_features');
6195
+ }, children: [jsx(AccordionSummary, { expandIcon: jsx(ExpandMoreIcon, { style: { color: 'white' } }), "aria-controls": "panel3-content", id: "panel3-header", children: jsx(Typography, { component: "span", children: "Related features" }) }), jsx(AccordionDetails, { children: jsx(FeatureDetailsNavigation, { model: model, feature: feature }) })] })] }));
6526
6196
  });
6527
6197
 
6528
6198
  /* eslint-disable @typescript-eslint/no-unsafe-call */
6199
+ /* eslint-disable @typescript-eslint/no-unnecessary-condition */
6529
6200
  const ApolloFeatureDetailsWidgetModel = types
6530
6201
  .model('ApolloFeatureDetailsWidget', {
6531
6202
  id: ElementId,
@@ -6835,38 +6506,24 @@ const TranscriptSequence = observer(function TranscriptSequence({ assembly, feat
6835
6506
  segment.sequence.slice(0, sequenceWrapLength - lastLineLength);
6836
6507
  const remainingLines = splitStringIntoChunks(segment.sequence.slice(firstLine.length), sequenceWrapLength);
6837
6508
  const printLines = [firstLine, ...remainingLines];
6838
- const span = (React.createElement("span", { key: `${segment.type}-${index}`, style: {
6509
+ const span = (jsx("span", { style: {
6839
6510
  background: getSegmentColor(segment.type),
6840
6511
  color: theme.palette.getContrastText(getSegmentColor(segment.type)),
6841
6512
  whiteSpace: 'pre-line',
6842
- } }, printLines.join('\n')));
6513
+ }, children: printLines.join('\n') }, `${segment.type}-${index}`));
6843
6514
  seqElements.push(span);
6844
6515
  }
6845
6516
  return seqElements;
6846
6517
  }
6847
- return (React.createElement(React.Fragment, null,
6848
- React.createElement(Select, { defaultValue: "genomic", value: selectedOption, onChange: handleChangeSeqOption, size: "small", "data-testid": "sequenceOptionSelector" }, sequenceOptions.map((option) => (React.createElement(MenuItem, { key: option, value: option, "data-testid": `sequenceOption-${option}` }, option)))),
6849
- React.createElement(Button, { variant: "contained", onClick: onCopyClick, style: { marginLeft: 10 }, size: "medium" }, "Copy sequence"),
6850
- React.createElement(Paper, { style: {
6851
- fontFamily: 'monospace',
6852
- padding: theme.spacing(),
6853
- overflowX: 'auto',
6854
- }, ref: seqRef },
6855
- ">",
6856
- refSeq.name,
6857
- ":",
6858
- locationIntervals
6859
- .map((interval) => feature.strand === 1
6860
- ? `${interval.min + 1}-${interval.max}`
6861
- : `${interval.max}-${interval.min + 1}`)
6862
- .join(';'),
6863
- "(strand=",
6864
- feature.strand === 1 ? '+' : '-',
6865
- ";length=",
6866
- getSequenceLength(sequenceSegments),
6867
- ")",
6868
- React.createElement("br", null),
6869
- wrapSequence(sequenceSegments, SEQUENCE_WRAP_LENGTH))));
6518
+ return (jsxs(Fragment, { children: [jsx(Select, { defaultValue: "genomic", value: selectedOption, onChange: handleChangeSeqOption, size: "small", "data-testid": "sequenceOptionSelector", children: sequenceOptions.map((option) => (jsx(MenuItem, { value: option, "data-testid": `sequenceOption-${option}`, children: option }, option))) }), jsx(Button, { variant: "contained", onClick: onCopyClick, style: { marginLeft: 10 }, size: "medium", children: "Copy sequence" }), jsxs(Paper, { style: {
6519
+ fontFamily: 'monospace',
6520
+ padding: theme.spacing(),
6521
+ overflowX: 'auto',
6522
+ }, ref: seqRef, children: [">", refSeq.name, ":", locationIntervals
6523
+ .map((interval) => feature.strand === 1
6524
+ ? `${interval.min + 1}-${interval.max}`
6525
+ : `${interval.max}-${interval.min + 1}`)
6526
+ .join(';'), "(strand=", feature.strand === 1 ? '+' : '-', ";length=", getSequenceLength(sequenceSegments), ")", jsx("br", {}), wrapSequence(sequenceSegments, SEQUENCE_WRAP_LENGTH)] })] }));
6870
6527
  });
6871
6528
 
6872
6529
  const StyledTextField = styled(NumberTextField)(() => ({
@@ -6897,7 +6554,7 @@ const SequenceContainer = styled('div')({
6897
6554
  });
6898
6555
  const Strand = (props) => {
6899
6556
  const { strand } = props;
6900
- return (React.createElement("div", null, strand === 1 ? (React.createElement(AddIcon, null)) : strand === -1 ? (React.createElement(RemoveIcon, null)) : (React.createElement(Typography, { component: 'span' }, "N/A"))));
6557
+ return (jsx("div", { children: strand === 1 ? (jsx(AddIcon, {})) : strand === -1 ? (jsx(RemoveIcon, {})) : (jsx(Typography, { component: 'span', children: "N/A" })) }));
6901
6558
  };
6902
6559
  const minMaxExonTranscriptLocation = (transcript, featureTypeOntology) => {
6903
6560
  const { transcriptExonParts } = transcript;
@@ -7361,11 +7018,11 @@ const TranscriptWidgetEditLocation = observer(function TranscriptWidgetEditLocat
7361
7018
  const protein = defaultCodonTable[codonSeq] || '&';
7362
7019
  // highlight start codon and stop codons
7363
7020
  if (codonSeq === 'ATG') {
7364
- elements.push(React.createElement(Typography, { component: 'span', style: {
7021
+ elements.push(jsx(Typography, { component: 'span', style: {
7365
7022
  backgroundColor: changeInProgress ? 'lightgray' : 'yellow',
7366
7023
  cursor: 'pointer',
7367
7024
  border: '1px solid black',
7368
- }, key: codonGenomicPos, onClick: () => {
7025
+ }, onClick: () => {
7369
7026
  if (changeInProgress) {
7370
7027
  return;
7371
7028
  }
@@ -7379,17 +7036,15 @@ const TranscriptWidgetEditLocation = observer(function TranscriptWidgetEditLocat
7379
7036
  if (startCodonGenomicLocation !== cdsMax && strand === -1) {
7380
7037
  updateCDSLocation(cdsMax, startCodonGenomicLocation, feature, false);
7381
7038
  }
7382
- } }, protein));
7039
+ }, children: protein }, codonGenomicPos));
7383
7040
  }
7384
7041
  else if (['TAA', 'TAG', 'TGA'].includes(codonSeq)) {
7385
- elements.push(React.createElement(Typography, { style: { backgroundColor: 'red', color: 'white' }, component: 'span',
7386
- // Pass the codonGenomicPos as the key to maintain the genomic position of the codon
7387
- key: codonGenomicPos }, protein));
7042
+ elements.push(jsx(Typography, { style: { backgroundColor: 'red', color: 'white' }, component: 'span', children: protein }, codonGenomicPos));
7388
7043
  }
7389
7044
  else {
7390
7045
  elements.push(
7391
7046
  // Pass the codonGenomicPos as the key to maintain the genomic position of the codon
7392
- React.createElement(Typography, { component: 'span', key: codonGenomicPos }, protein));
7047
+ jsx(Typography, { component: 'span', children: protein }, codonGenomicPos));
7393
7048
  }
7394
7049
  }
7395
7050
  return elements;
@@ -7520,69 +7175,33 @@ const TranscriptWidgetEditLocation = observer(function TranscriptWidgetEditLocat
7520
7175
  }
7521
7176
  void copyToClipboard(seqDiv);
7522
7177
  };
7523
- return (React.createElement("div", null,
7524
- cdsPresent && (React.createElement("div", null,
7525
- React.createElement(Accordion, null,
7526
- React.createElement(StyledAccordionSummary, { expandIcon: React.createElement(ExpandMoreIcon, { style: { color: 'white' } }), "aria-controls": "panel1-content", id: "panel1-header" },
7527
- React.createElement(Typography, { component: "span", fontWeight: 'bold' }, "Translation")),
7528
- React.createElement(AccordionDetails, null,
7529
- React.createElement(SequenceContainer, null,
7530
- React.createElement(Typography, { component: 'span', ref: seqRef, style: { maxHeight: 120, overflowY: 'scroll' } }, getTranslationSequence())),
7531
- React.createElement("div", { style: {
7532
- marginTop: 10,
7533
- display: 'flex',
7534
- flexDirection: 'row',
7535
- alignItems: 'center',
7536
- gap: 10,
7537
- } },
7538
- React.createElement(Tooltip, { title: "Copy" },
7539
- React.createElement("button", { onClick: onCopyClick, style: { border: 'none', background: 'none', padding: 0 }, disabled: changeInProgress },
7540
- React.createElement(ContentCopyIcon, { style: { fontSize: 15 } }))),
7541
- React.createElement(Tooltip, { title: "Trim" },
7542
- React.createElement("button", { onClick: trimTranslationSequence, style: { border: 'none', background: 'none', padding: 0 }, disabled: changeInProgress },
7543
- React.createElement(ContentCutIcon, { style: { fontSize: 15 } })))))),
7544
- React.createElement(Grid, { container: true, justifyContent: "center", alignItems: "center", style: { textAlign: 'center', marginTop: 10 } },
7545
- React.createElement(Grid, { size: 1 }),
7546
- strand === 1 ? (React.createElement(Grid, { size: 4 },
7547
- React.createElement(StyledTextField, { margin: "dense", variant: "outlined", value: cdsMin + 1, onChangeCommitted: (newLocation) => {
7548
- return updateCDSLocation(cdsMin, newLocation - 1, feature, true);
7549
- }, style: { border: '1px solid black', borderRadius: 5 }, disabled: changeInProgress }))) : (React.createElement(Grid, { size: 4 },
7550
- React.createElement(StyledTextField, { margin: "dense", variant: "outlined", value: cdsMax, onChangeCommitted: (newLocation) => {
7551
- return updateCDSLocation(cdsMax, newLocation, feature, false);
7552
- }, style: { border: '1px solid black', borderRadius: 5 }, disabled: changeInProgress }))),
7553
- React.createElement(Grid, { size: 2 },
7554
- React.createElement(Typography, { component: 'span' }, "CDS")),
7555
- strand === 1 ? (React.createElement(Grid, { size: 4 },
7556
- React.createElement(StyledTextField, { margin: "dense", variant: "outlined", value: cdsMax, onChangeCommitted: (newLocation) => {
7557
- return updateCDSLocation(cdsMax, newLocation, feature, false);
7558
- }, style: { border: '1px solid black', borderRadius: 5 }, disabled: changeInProgress }))) : (React.createElement(Grid, { size: 4 },
7559
- React.createElement(StyledTextField, { margin: "dense", variant: "outlined", value: cdsMin + 1, onChangeCommitted: (newLocation) => {
7560
- return updateCDSLocation(cdsMin, newLocation - 1, feature, true);
7561
- }, style: { border: '1px solid black', borderRadius: 5 }, disabled: changeInProgress }))),
7562
- React.createElement(Grid, { size: 1 })))),
7563
- React.createElement("div", { style: { marginTop: 5 } }, transcriptExonParts.map((loc, index) => {
7564
- return (React.createElement("div", { key: index }, loc.type === 'exon' && (React.createElement(Grid, { container: true, justifyContent: "center", alignItems: "center", style: { textAlign: 'center' } },
7565
- React.createElement(Grid, { size: 1 }, index !== 0 &&
7566
- getFivePrimeSpliceSite(loc, index).map((site, idx) => (React.createElement(Typography, { key: idx, component: 'span', color: site.color }, site.spliceSite)))),
7567
- strand === 1 ? (React.createElement(Grid, { size: 4, style: { padding: 0 } },
7568
- React.createElement(StyledTextField, { margin: "dense", variant: "outlined", value: loc.min + 1, onChangeCommitted: (newLocation) => {
7569
- return handleExonLocationChange(loc.min, newLocation - 1, feature, true);
7570
- }, disabled: changeInProgress }))) : (React.createElement(Grid, { size: 4, style: { padding: 0 } },
7571
- React.createElement(StyledTextField, { margin: "dense", variant: "outlined", value: loc.max, onChangeCommitted: (newLocation) => {
7572
- return handleExonLocationChange(loc.max, newLocation, feature, false);
7573
- }, disabled: changeInProgress }))),
7574
- React.createElement(Grid, { size: 2 },
7575
- React.createElement(Strand, { strand: feature.strand })),
7576
- strand === 1 ? (React.createElement(Grid, { size: 4, style: { padding: 0 } },
7577
- React.createElement(StyledTextField, { margin: "dense", variant: "outlined", value: loc.max, onChangeCommitted: (newLocation) => {
7578
- return handleExonLocationChange(loc.max, newLocation, feature, false);
7579
- }, disabled: changeInProgress }))) : (React.createElement(Grid, { size: 4, style: { padding: 0 } },
7580
- React.createElement(StyledTextField, { margin: "dense", variant: "outlined", value: loc.min + 1, onChangeCommitted: (newLocation) => {
7581
- return handleExonLocationChange(loc.min, newLocation - 1, feature, true);
7582
- }, disabled: changeInProgress }))),
7583
- React.createElement(Grid, { size: 1 }, index !== transcriptExonParts.length - 1 &&
7584
- getThreePrimeSpliceSite(loc, index).map((site, idx) => (React.createElement(Typography, { key: idx, component: 'span', color: site.color }, site.spliceSite))))))));
7585
- }))));
7178
+ return (jsxs("div", { children: [cdsPresent && (jsxs("div", { children: [jsxs(Accordion, { children: [jsx(StyledAccordionSummary, { expandIcon: jsx(ExpandMoreIcon, { style: { color: 'white' } }), "aria-controls": "panel1-content", id: "panel1-header", children: jsx(Typography, { component: "span", fontWeight: 'bold', children: "Translation" }) }), jsxs(AccordionDetails, { children: [jsx(SequenceContainer, { children: jsx(Typography, { component: 'span', ref: seqRef, style: { maxHeight: 120, overflowY: 'scroll' }, children: getTranslationSequence() }) }), jsxs("div", { style: {
7179
+ marginTop: 10,
7180
+ display: 'flex',
7181
+ flexDirection: 'row',
7182
+ alignItems: 'center',
7183
+ gap: 10,
7184
+ }, children: [jsx(Tooltip, { title: "Copy", children: jsx("button", { onClick: onCopyClick, style: { border: 'none', background: 'none', padding: 0 }, disabled: changeInProgress, children: jsx(ContentCopyIcon, { style: { fontSize: 15 } }) }) }), jsx(Tooltip, { title: "Trim", children: jsx("button", { onClick: trimTranslationSequence, style: { border: 'none', background: 'none', padding: 0 }, disabled: changeInProgress, children: jsx(ContentCutIcon, { style: { fontSize: 15 } }) }) })] })] })] }), jsxs(Grid, { container: true, justifyContent: "center", alignItems: "center", style: { textAlign: 'center', marginTop: 10 }, children: [jsx(Grid, { size: 1 }), strand === 1 ? (jsx(Grid, { size: 4, children: jsx(StyledTextField, { margin: "dense", variant: "outlined", value: cdsMin + 1, onChangeCommitted: (newLocation) => {
7185
+ return updateCDSLocation(cdsMin, newLocation - 1, feature, true);
7186
+ }, style: { border: '1px solid black', borderRadius: 5 }, disabled: changeInProgress }) })) : (jsx(Grid, { size: 4, children: jsx(StyledTextField, { margin: "dense", variant: "outlined", value: cdsMax, onChangeCommitted: (newLocation) => {
7187
+ return updateCDSLocation(cdsMax, newLocation, feature, false);
7188
+ }, style: { border: '1px solid black', borderRadius: 5 }, disabled: changeInProgress }) })), jsx(Grid, { size: 2, children: jsx(Typography, { component: 'span', children: "CDS" }) }), strand === 1 ? (jsx(Grid, { size: 4, children: jsx(StyledTextField, { margin: "dense", variant: "outlined", value: cdsMax, onChangeCommitted: (newLocation) => {
7189
+ return updateCDSLocation(cdsMax, newLocation, feature, false);
7190
+ }, style: { border: '1px solid black', borderRadius: 5 }, disabled: changeInProgress }) })) : (jsx(Grid, { size: 4, children: jsx(StyledTextField, { margin: "dense", variant: "outlined", value: cdsMin + 1, onChangeCommitted: (newLocation) => {
7191
+ return updateCDSLocation(cdsMin, newLocation - 1, feature, true);
7192
+ }, style: { border: '1px solid black', borderRadius: 5 }, disabled: changeInProgress }) })), jsx(Grid, { size: 1 })] })] })), jsx("div", { style: { marginTop: 5 }, children: transcriptExonParts.map((loc, index) => {
7193
+ return (jsx("div", { children: loc.type === 'exon' && (jsxs(Grid, { container: true, justifyContent: "center", alignItems: "center", style: { textAlign: 'center' }, children: [jsx(Grid, { size: 1, children: index !== 0 &&
7194
+ getFivePrimeSpliceSite(loc, index).map((site, idx) => (jsx(Typography, { component: 'span', color: site.color, children: site.spliceSite }, idx))) }), strand === 1 ? (jsx(Grid, { size: 4, style: { padding: 0 }, children: jsx(StyledTextField, { margin: "dense", variant: "outlined", value: loc.min + 1, onChangeCommitted: (newLocation) => {
7195
+ return handleExonLocationChange(loc.min, newLocation - 1, feature, true);
7196
+ }, disabled: changeInProgress }) })) : (jsx(Grid, { size: 4, style: { padding: 0 }, children: jsx(StyledTextField, { margin: "dense", variant: "outlined", value: loc.max, onChangeCommitted: (newLocation) => {
7197
+ return handleExonLocationChange(loc.max, newLocation, feature, false);
7198
+ }, disabled: changeInProgress }) })), jsx(Grid, { size: 2, children: jsx(Strand, { strand: feature.strand }) }), strand === 1 ? (jsx(Grid, { size: 4, style: { padding: 0 }, children: jsx(StyledTextField, { margin: "dense", variant: "outlined", value: loc.max, onChangeCommitted: (newLocation) => {
7199
+ return handleExonLocationChange(loc.max, newLocation, feature, false);
7200
+ }, disabled: changeInProgress }) })) : (jsx(Grid, { size: 4, style: { padding: 0 }, children: jsx(StyledTextField, { margin: "dense", variant: "outlined", value: loc.min + 1, onChangeCommitted: (newLocation) => {
7201
+ return handleExonLocationChange(loc.min, newLocation - 1, feature, true);
7202
+ }, disabled: changeInProgress }) })), jsx(Grid, { size: 1, children: index !== transcriptExonParts.length - 1 &&
7203
+ getThreePrimeSpliceSite(loc, index).map((site, idx) => (jsx(Typography, { component: 'span', color: site.color, children: site.spliceSite }, idx))) })] })) }, index));
7204
+ }) })] }));
7586
7205
  });
7587
7206
 
7588
7207
  const HeaderTableCell = styled(TableCell)(() => ({
@@ -7592,28 +7211,7 @@ const TranscriptWidgetSummary = observer(function TranscriptWidgetSummary(props)
7592
7211
  const { feature } = props;
7593
7212
  const name = getFeatureName$1(feature);
7594
7213
  const id = getFeatureId$1(feature);
7595
- return (React.createElement(Table, { size: "small", sx: { fontSize: '0.75rem', '& .MuiTableCell-root': { padding: '4px' } } },
7596
- React.createElement(TableBody, null,
7597
- name !== '' && (React.createElement(TableRow, null,
7598
- React.createElement(HeaderTableCell, null, "Name"),
7599
- React.createElement(TableCell, null, getFeatureName$1(feature)))),
7600
- id !== '' && (React.createElement(TableRow, null,
7601
- React.createElement(HeaderTableCell, null, "ID"),
7602
- React.createElement(TableCell, null, getFeatureId$1(feature)))),
7603
- React.createElement(TableRow, null,
7604
- React.createElement(HeaderTableCell, null, "Type"),
7605
- React.createElement(TableCell, null, feature.type)),
7606
- React.createElement(TableRow, null,
7607
- React.createElement(HeaderTableCell, null, "Location"),
7608
- React.createElement(TableCell, null,
7609
- props.refName,
7610
- ":",
7611
- feature.min,
7612
- "..",
7613
- feature.max)),
7614
- React.createElement(TableRow, null,
7615
- React.createElement(HeaderTableCell, null, "Strand"),
7616
- React.createElement(TableCell, null, getStrand(feature.strand))))));
7214
+ return (jsx(Table, { size: "small", sx: { fontSize: '0.75rem', '& .MuiTableCell-root': { padding: '4px' } }, children: jsxs(TableBody, { children: [name !== '' && (jsxs(TableRow, { children: [jsx(HeaderTableCell, { children: "Name" }), jsx(TableCell, { children: getFeatureName$1(feature) })] })), id !== '' && (jsxs(TableRow, { children: [jsx(HeaderTableCell, { children: "ID" }), jsx(TableCell, { children: getFeatureId$1(feature) })] })), jsxs(TableRow, { children: [jsx(HeaderTableCell, { children: "Type" }), jsx(TableCell, { children: feature.type })] }), jsxs(TableRow, { children: [jsx(HeaderTableCell, { children: "Location" }), jsxs(TableCell, { children: [props.refName, ":", feature.min, "..", feature.max] })] }), jsxs(TableRow, { children: [jsx(HeaderTableCell, { children: "Strand" }), jsx(TableCell, { children: getStrand(feature.strand) })] })] }) }));
7617
7215
  });
7618
7216
 
7619
7217
  const useStyles$7 = makeStyles()((theme) => ({
@@ -7680,48 +7278,15 @@ const ApolloTranscriptDetailsWidget = observer(function ApolloTranscriptDetails(
7680
7278
  const CustomComponentAfterAttributes = pluginManager.evaluateExtensionPoint('Apollo-TranscriptDetailsCustomComponent-AfterAttributes', NoOpCustomComponent, { feature, session });
7681
7279
  const CustomComponentInsideSequence = pluginManager.evaluateExtensionPoint('Apollo-TranscriptDetailsCustomComponent-InsideSequence', NoOpCustomComponent, { feature, session });
7682
7280
  const CustomComponentAfterSequence = pluginManager.evaluateExtensionPoint('Apollo-TranscriptDetailsCustomComponent-AfterSequence', NoOpCustomComponent, { feature, session });
7683
- return (React.createElement("div", { className: classes.root },
7684
- React.createElement(Accordion, { expanded: panelState.includes('summary'), onChange: (e, expanded) => {
7685
- handlePanelChange(expanded, 'summary');
7686
- } },
7687
- React.createElement(StyledAccordionSummary, { expandIcon: React.createElement(ExpandMoreIcon, { style: { color: 'white' } }), "aria-controls": "panel1-content", id: "panel1-header" },
7688
- React.createElement(Typography, { component: "span", fontWeight: 'bold' }, "Summary")),
7689
- React.createElement(AccordionDetails, null,
7690
- React.createElement(TranscriptWidgetSummary, { feature: feature, refName: refName }),
7691
- React.createElement(CustomComponentInsideSummary, { session: session, feature: feature }))),
7692
- React.createElement(CustomComponentAfterSummary, { session: session, feature: feature }),
7693
- React.createElement(Accordion, { style: { marginTop: 5 }, expanded: panelState.includes('location'), onChange: (e, expanded) => {
7694
- handlePanelChange(expanded, 'location');
7695
- } },
7696
- React.createElement(StyledAccordionSummary, { expandIcon: React.createElement(ExpandMoreIcon, { style: { color: 'white' } }), "aria-controls": "panel2-content", id: "panel2-header" },
7697
- React.createElement(Typography, { component: "span", fontWeight: 'bold' }, "Location")),
7698
- React.createElement(AccordionDetails, null,
7699
- React.createElement(TranscriptWidgetEditLocation, { feature: feature, refName: refName, session: apolloSession, assembly: currentAssembly._id || '' }),
7700
- React.createElement(CustomComponentInsideLocation, { session: session, feature: feature }))),
7701
- React.createElement(CustomComponentAfterLocation, { session: session, feature: feature }),
7702
- React.createElement(Accordion, { style: { marginTop: 5 }, expanded: panelState.includes('attrs'), onChange: (e, expanded) => {
7703
- handlePanelChange(expanded, 'attrs');
7704
- } },
7705
- React.createElement(StyledAccordionSummary, { expandIcon: React.createElement(ExpandMoreIcon, { style: { color: 'white' } }), "aria-controls": "panel3-content", id: "panel3-header" },
7706
- React.createElement("div", { style: { display: 'flex', alignItems: 'center' } },
7707
- React.createElement(Typography, { component: "span", fontWeight: 'bold' },
7708
- "Attributes",
7709
- ' '),
7710
- React.createElement(Tooltip, { title: "Separate multiple values for the attribute with commas" },
7711
- React.createElement(InfoIcon, { style: { color: 'white', fontSize: 15, marginLeft: 10 } })))),
7712
- React.createElement(AccordionDetails, null,
7713
- React.createElement(Attributes, { feature: feature, session: apolloSession, assembly: currentAssembly._id || '', editable: editable }),
7714
- React.createElement(CustomComponentInsideAttributes, { session: session, feature: feature }))),
7715
- React.createElement(CustomComponentAfterAttributes, { session: session, feature: feature }),
7716
- React.createElement(Accordion, { style: { marginTop: 5 }, expanded: panelState.includes('sequence'), onChange: (e, expanded) => {
7717
- handlePanelChange(expanded, 'sequence');
7718
- } },
7719
- React.createElement(StyledAccordionSummary, { expandIcon: React.createElement(ExpandMoreIcon, { style: { color: 'white' } }), "aria-controls": "panel4-content", id: "panel4-header" },
7720
- React.createElement(Typography, { component: "span", fontWeight: 'bold' }, "Sequence")),
7721
- React.createElement(AccordionDetails, null,
7722
- panelState.includes('sequence') && (React.createElement(TranscriptSequence, { feature: feature, session: apolloSession, assembly: currentAssembly._id || '', refName: refName })),
7723
- React.createElement(CustomComponentInsideSequence, { session: session, feature: feature }))),
7724
- React.createElement(CustomComponentAfterSequence, { feature: feature, session: session })));
7281
+ return (jsxs("div", { className: classes.root, children: [jsxs(Accordion, { expanded: panelState.includes('summary'), onChange: (e, expanded) => {
7282
+ handlePanelChange(expanded, 'summary');
7283
+ }, children: [jsx(StyledAccordionSummary, { expandIcon: jsx(ExpandMoreIcon, { style: { color: 'white' } }), "aria-controls": "panel1-content", id: "panel1-header", children: jsx(Typography, { component: "span", fontWeight: 'bold', children: "Summary" }) }), jsxs(AccordionDetails, { children: [jsx(TranscriptWidgetSummary, { feature: feature, refName: refName }), jsx(CustomComponentInsideSummary, { session: session, feature: feature })] })] }), jsx(CustomComponentAfterSummary, { session: session, feature: feature }), jsxs(Accordion, { style: { marginTop: 5 }, expanded: panelState.includes('location'), onChange: (e, expanded) => {
7284
+ handlePanelChange(expanded, 'location');
7285
+ }, children: [jsx(StyledAccordionSummary, { expandIcon: jsx(ExpandMoreIcon, { style: { color: 'white' } }), "aria-controls": "panel2-content", id: "panel2-header", children: jsx(Typography, { component: "span", fontWeight: 'bold', children: "Location" }) }), jsxs(AccordionDetails, { children: [jsx(TranscriptWidgetEditLocation, { feature: feature, refName: refName, session: apolloSession, assembly: currentAssembly._id || '' }), jsx(CustomComponentInsideLocation, { session: session, feature: feature })] })] }), jsx(CustomComponentAfterLocation, { session: session, feature: feature }), jsxs(Accordion, { style: { marginTop: 5 }, expanded: panelState.includes('attrs'), onChange: (e, expanded) => {
7286
+ handlePanelChange(expanded, 'attrs');
7287
+ }, children: [jsx(StyledAccordionSummary, { expandIcon: jsx(ExpandMoreIcon, { style: { color: 'white' } }), "aria-controls": "panel3-content", id: "panel3-header", children: jsxs("div", { style: { display: 'flex', alignItems: 'center' }, children: [jsxs(Typography, { component: "span", fontWeight: 'bold', children: ["Attributes", ' '] }), jsx(Tooltip, { title: "Separate multiple values for the attribute with commas", children: jsx(InfoIcon, { style: { color: 'white', fontSize: 15, marginLeft: 10 } }) })] }) }), jsxs(AccordionDetails, { children: [jsx(Attributes, { feature: feature, session: apolloSession, assembly: currentAssembly._id || '', editable: editable }), jsx(CustomComponentInsideAttributes, { session: session, feature: feature })] })] }), jsx(CustomComponentAfterAttributes, { session: session, feature: feature }), jsxs(Accordion, { style: { marginTop: 5 }, expanded: panelState.includes('sequence'), onChange: (e, expanded) => {
7288
+ handlePanelChange(expanded, 'sequence');
7289
+ }, children: [jsx(StyledAccordionSummary, { expandIcon: jsx(ExpandMoreIcon, { style: { color: 'white' } }), "aria-controls": "panel4-content", id: "panel4-header", children: jsx(Typography, { component: "span", fontWeight: 'bold', children: "Sequence" }) }), jsxs(AccordionDetails, { children: [panelState.includes('sequence') && (jsx(TranscriptSequence, { feature: feature, session: apolloSession, assembly: currentAssembly._id || '', refName: refName })), jsx(CustomComponentInsideSequence, { session: session, feature: feature })] })] }), jsx(CustomComponentAfterSequence, { feature: feature, session: session })] }));
7725
7290
  });
7726
7291
 
7727
7292
  const configSchema$2 = ConfigurationSchema('LinearApolloDisplay', {}, { explicitIdentifier: 'displayId', explicitlyTyped: true });
@@ -7771,19 +7336,17 @@ const useStyles$6 = makeStyles()({
7771
7336
  const Highlight = ({ highlight, text, }) => {
7772
7337
  const { classes } = useStyles$6();
7773
7338
  if (!highlight) {
7774
- return React.createElement(React.Fragment, null, text);
7339
+ return jsx(Fragment, { children: text });
7775
7340
  }
7776
7341
  const split = text.split(highlight);
7777
7342
  if (split.length === 1) {
7778
- return React.createElement(React.Fragment, null, text);
7343
+ return jsx(Fragment, { children: text });
7779
7344
  }
7780
7345
  const highlighted = [];
7781
7346
  for (let i = 0; i < split.length - 1; i++) {
7782
- highlighted.push(split[i], React.createElement("span", { className: classes.highlighted }, highlight));
7347
+ highlighted.push(split[i], jsx("span", { className: classes.highlighted, children: highlight }));
7783
7348
  }
7784
- return (React.createElement(React.Fragment, null,
7785
- highlighted,
7786
- split.at(-1)));
7349
+ return (jsxs(Fragment, { children: [highlighted, split.at(-1)] }));
7787
7350
  };
7788
7351
 
7789
7352
  const FeatureAttributes = observer(function FeatureAttributes({ feature, filterText, }) {
@@ -7802,10 +7365,9 @@ const FeatureAttributes = observer(function FeatureAttributes({ feature, filterT
7802
7365
  .filter(([key]) => key) // Leave empty keys off
7803
7366
  .map(([key, values]) => `${key}=${Array.isArray(values) ? values.join(', ') : values}`)
7804
7367
  .join(', ');
7805
- return React.createElement(Highlight, { text: attrString, highlight: filterText });
7368
+ return jsx(Highlight, { text: attrString, highlight: filterText });
7806
7369
  });
7807
7370
 
7808
- /* eslint-disable @typescript-eslint/unbound-method */
7809
7371
  const useStyles$5 = makeStyles()((theme) => ({
7810
7372
  inputWrapper: {
7811
7373
  position: 'relative',
@@ -7846,23 +7408,21 @@ const NumberCell = observer(function NumberCell({ initialValue, notifyError, onC
7846
7408
  setValue(newValue);
7847
7409
  }
7848
7410
  }
7849
- return (React.createElement("span", { className: classes.inputWrapper },
7850
- React.createElement("span", { className: classes.hiddenWidthSpan, "aria-hidden": true }, value),
7851
- React.createElement("input", { type: "text", value: value, className: classes.numberTextInput, onChange: onChange, onKeyDown: (event) => {
7852
- if (event.key === 'Enter') {
7853
- inputNode?.blur();
7854
- }
7855
- else if (event.key === 'Escape') {
7856
- setValue(initialValue);
7857
- setBlur(true);
7858
- }
7859
- }, onBlur: () => {
7860
- if (value !== initialValue) {
7861
- onChangeCommitted(value).catch(notifyError);
7862
- }
7863
- }, ref: (node) => {
7864
- setInputNode(node);
7865
- } })));
7411
+ return (jsxs("span", { className: classes.inputWrapper, children: [jsx("span", { className: classes.hiddenWidthSpan, "aria-hidden": true, children: value }), jsx("input", { type: "text", value: value, className: classes.numberTextInput, onChange: onChange, onKeyDown: (event) => {
7412
+ if (event.key === 'Enter') {
7413
+ inputNode?.blur();
7414
+ }
7415
+ else if (event.key === 'Escape') {
7416
+ setValue(initialValue);
7417
+ setBlur(true);
7418
+ }
7419
+ }, onBlur: () => {
7420
+ if (value !== initialValue) {
7421
+ onChangeCommitted(value).catch(notifyError);
7422
+ }
7423
+ }, ref: (node) => {
7424
+ setInputNode(node);
7425
+ } })] }));
7866
7426
  });
7867
7427
 
7868
7428
  function featureContextMenuItems(feature, region, getAssemblyId, selectedFeature, setSelectedFeature, session, changeManager, filteredTranscripts, updateFilteredTranscripts) {
@@ -8015,6 +7575,24 @@ function featureContextMenuItems(feature, region, getAssemblyId, selectedFeature
8015
7575
  });
8016
7576
  session.showWidget(apolloTranscriptWidget);
8017
7577
  },
7578
+ }, {
7579
+ label: 'Duplicate feature',
7580
+ onClick: () => {
7581
+ session.queueDialog((doneCallback) => [
7582
+ DuplicateTranscript,
7583
+ {
7584
+ session,
7585
+ handleClose: () => {
7586
+ doneCallback();
7587
+ },
7588
+ changeManager,
7589
+ sourceFeature: feature,
7590
+ sourceAssemblyId: currentAssemblyId,
7591
+ selectedFeature,
7592
+ setSelectedFeature,
7593
+ },
7594
+ ]);
7595
+ },
8018
7596
  }, {
8019
7597
  label: 'Visible',
8020
7598
  type: 'checkbox',
@@ -8033,7 +7611,6 @@ function featureContextMenuItems(feature, region, getAssemblyId, selectedFeature
8033
7611
  return menuItems;
8034
7612
  }
8035
7613
 
8036
- /* eslint-disable unicorn/no-nested-ternary */
8037
7614
  const useStyles$4 = makeStyles()((theme) => ({
8038
7615
  typeContent: {
8039
7616
  display: 'inline-block',
@@ -8089,70 +7666,55 @@ const Feature = observer(function Feature({ depth, feature, isHovered, isSelecte
8089
7666
  const notifyError = (e) => {
8090
7667
  session.notify(e.message, 'error');
8091
7668
  };
8092
- return (React.createElement(React.Fragment, null,
8093
- React.createElement("tr", { onMouseEnter: (_e) => {
8094
- displayState.setHoveredFeature({ feature, bp: min });
8095
- }, className: classes.feature +
8096
- (isSelected
8097
- ? ` ${selectedFeatureClass}`
8098
- : isHovered
8099
- ? ` ${classes.hoveredFeature}`
8100
- : ''), onClick: (e) => {
8101
- e.stopPropagation();
8102
- displayState.setSelectedFeature(feature);
8103
- }, onDoubleClick: () => {
8104
- displayState.setSelectedFeature(feature);
8105
- navigateHere(displayState, feature);
8106
- }, onContextMenu: (e) => {
8107
- e.preventDefault();
8108
- setContextMenu({
8109
- position: { left: e.clientX + 2, top: e.clientY - 6 },
8110
- items: makeContextMenuItems(displayState, feature),
8111
- });
8112
- return false;
8113
- } },
8114
- React.createElement("td", { style: {
8115
- whiteSpace: 'nowrap',
8116
- borderLeft: `${depth * 2}em solid transparent`,
8117
- } },
8118
- children?.size ? (
8119
- // TODO: a11y
8120
- // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
8121
- React.createElement("div", { onClick: toggleExpanded, className: classes.arrow + (expanded ? ` ${classes.arrowExpanded}` : '') }, "\u276F")) : null,
8122
- React.createElement("div", { className: classes.typeContent },
8123
- React.createElement(OntologyTermAutocomplete, { session: session, ontologyName: "Sequence Ontology", style: { width: 170 }, value: type, filterTerms: isOntologyClass, fetchValidTerms: fetchValidTypeTerms.bind(null, feature), renderInput: (params) => {
8124
- return (React.createElement("div", { ref: params.InputProps.ref },
8125
- React.createElement("input", { type: "text", ...params.inputProps, className: classes.typeInputElement, style: { width: 170 } }),
8126
- params.error ? (React.createElement("div", { className: classes.typeErrorMessage }, params.errorMessage ?? 'unknown error')) : null));
8127
- }, onChange: (oldValue, newValue) => {
8128
- if (newValue) {
8129
- handleFeatureTypeChange(changeManager, feature, oldValue, newValue).catch(notifyError);
8130
- }
8131
- } }))),
8132
- React.createElement("td", null,
8133
- React.createElement(NumberCell, { initialValue: min + 1, notifyError: notifyError, onChangeCommitted: (newStart) => handleFeatureStartChange(changeManager, feature, min, newStart - 1) })),
8134
- React.createElement("td", null,
8135
- React.createElement(NumberCell, { initialValue: max, notifyError: notifyError, onChangeCommitted: (newEnd) => handleFeatureEndChange(changeManager, feature, max, newEnd) })),
8136
- React.createElement("td", null, strand === 1 ? '+' : strand === -1 ? '-' : undefined),
8137
- React.createElement("td", null,
8138
- React.createElement(FeatureAttributes, { filterText: filterText, feature: feature }))),
8139
- expanded && children
8140
- ? [...children.entries()]
8141
- .filter((entry) => {
8142
- if (!filterText) {
8143
- return true;
8144
- }
8145
- const [, childFeature] = entry;
8146
- // search feature and its subfeatures for the text
8147
- const text = JSON.stringify(childFeature);
8148
- return text.includes(filterText);
8149
- })
8150
- .map(([featureId, childFeature]) => {
8151
- const childHovered = hoveredFeature?.feature._id === childFeature._id;
8152
- const childSelected = selectedFeature?._id === childFeature._id;
8153
- return (React.createElement(Feature, { isHovered: childHovered, isSelected: childSelected, selectedFeatureClass: selectedFeatureClass, key: featureId, depth: (depth || 0) + 1, feature: childFeature, model: displayState, setContextMenu: setContextMenu }));
8154
- })
8155
- : null));
7669
+ return (jsxs(Fragment, { children: [jsxs("tr", { onMouseEnter: (_e) => {
7670
+ displayState.setHoveredFeature({ feature, bp: min });
7671
+ }, className: classes.feature +
7672
+ (isSelected
7673
+ ? ` ${selectedFeatureClass}`
7674
+ : isHovered
7675
+ ? ` ${classes.hoveredFeature}`
7676
+ : ''), onClick: (e) => {
7677
+ e.stopPropagation();
7678
+ displayState.setSelectedFeature(feature);
7679
+ }, onDoubleClick: () => {
7680
+ displayState.setSelectedFeature(feature);
7681
+ navigateHere(displayState, feature);
7682
+ }, onContextMenu: (e) => {
7683
+ e.preventDefault();
7684
+ setContextMenu({
7685
+ position: { left: e.clientX + 2, top: e.clientY - 6 },
7686
+ items: makeContextMenuItems(displayState, feature),
7687
+ });
7688
+ return false;
7689
+ }, children: [jsxs("td", { style: {
7690
+ whiteSpace: 'nowrap',
7691
+ borderLeft: `${depth * 2}em solid transparent`,
7692
+ }, children: [children?.size ? (
7693
+ // TODO: a11y
7694
+ // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
7695
+ jsx("div", { onClick: toggleExpanded, className: classes.arrow + (expanded ? ` ${classes.arrowExpanded}` : ''), children: "\u276F" })) : null, jsx("div", { className: classes.typeContent, children: jsx(OntologyTermAutocomplete, { session: session, ontologyName: "Sequence Ontology", style: { width: 170 }, value: type, filterTerms: isOntologyClass, fetchValidTerms: fetchValidTypeTerms.bind(null, feature), renderInput: (params) => {
7696
+ return (jsxs("div", { ref: params.InputProps.ref, children: [jsx("input", { type: "text", ...params.inputProps, className: classes.typeInputElement, style: { width: 170 } }), params.error ? (jsx("div", { className: classes.typeErrorMessage, children: params.errorMessage ?? 'unknown error' })) : null] }));
7697
+ }, onChange: (oldValue, newValue) => {
7698
+ if (newValue) {
7699
+ handleFeatureTypeChange(changeManager, feature, oldValue, newValue).catch(notifyError);
7700
+ }
7701
+ } }) })] }), jsx("td", { children: jsx(NumberCell, { initialValue: min + 1, notifyError: notifyError, onChangeCommitted: (newStart) => handleFeatureStartChange(changeManager, feature, min, newStart - 1) }) }), jsx("td", { children: jsx(NumberCell, { initialValue: max, notifyError: notifyError, onChangeCommitted: (newEnd) => handleFeatureEndChange(changeManager, feature, max, newEnd) }) }), jsx("td", { children: strand === 1 ? '+' : strand === -1 ? '-' : undefined }), jsx("td", { children: jsx(FeatureAttributes, { filterText: filterText, feature: feature }) })] }), expanded && children
7702
+ ? [...children.entries()]
7703
+ .filter((entry) => {
7704
+ if (!filterText) {
7705
+ return true;
7706
+ }
7707
+ const [, childFeature] = entry;
7708
+ // search feature and its subfeatures for the text
7709
+ const text = JSON.stringify(childFeature);
7710
+ return text.includes(filterText);
7711
+ })
7712
+ .map(([featureId, childFeature]) => {
7713
+ const childHovered = hoveredFeature?.feature._id === childFeature._id;
7714
+ const childSelected = selectedFeature?._id === childFeature._id;
7715
+ return (jsx(Feature, { isHovered: childHovered, isSelected: childSelected, selectedFeatureClass: selectedFeatureClass, depth: (depth || 0) + 1, feature: childFeature, model: displayState, setContextMenu: setContextMenu }, featureId));
7716
+ })
7717
+ : null] }));
8156
7718
  });
8157
7719
  async function fetchValidTypeTerms(feature, ontologyStore, _signal) {
8158
7720
  const { parent: parentFeature } = feature;
@@ -8211,48 +7773,37 @@ const HybridGrid = observer(function HybridGrid({ model, }) {
8211
7773
  }
8212
7774
  }
8213
7775
  }, [selectedFeature, seenFeatures, classes.selectedFeature]);
8214
- return (React.createElement("div", { ref: scrollContainerRef, style: { width: '100%', overflowY: 'auto', height: '100%' } },
8215
- React.createElement("table", { className: classes.scrollableTable },
8216
- React.createElement("thead", null,
8217
- React.createElement("tr", null,
8218
- React.createElement("th", null, "Type"),
8219
- React.createElement("th", null, "Start"),
8220
- React.createElement("th", null, "End"),
8221
- React.createElement("th", null, "Strand"),
8222
- React.createElement("th", null, "Attributes"))),
8223
- React.createElement("tbody", null, [...seenFeatures.entries()]
8224
- .filter((entry) => {
8225
- if (!filterText) {
8226
- return true;
8227
- }
8228
- const [, feature] = entry;
8229
- // search feature and its subfeatures for the text
8230
- const text = JSON.stringify(feature);
8231
- return text.includes(filterText);
8232
- })
8233
- .sort((a, b) => {
8234
- return a[1].min - b[1].min;
8235
- })
8236
- .map(([featureId, feature]) => {
8237
- const isSelected = selectedFeature?._id === featureId;
8238
- const isHovered = hoveredFeature?.feature._id === featureId;
8239
- return (React.createElement(Feature, { key: featureId, isSelected: isSelected, isHovered: isHovered, selectedFeatureClass: classes.selectedFeature, feature: feature, model: model, depth: 0, setContextMenu: setContextMenu }));
8240
- }))),
8241
- React.createElement(Menu$1, { open: Boolean(contextMenu), onMenuItemClick: (_, callback) => {
8242
- callback();
8243
- setContextMenu(null);
8244
- }, onClose: () => {
8245
- setContextMenu(null);
8246
- }, slotProps: {
8247
- transition: {
8248
- onExit: () => {
8249
- setContextMenu(null);
7776
+ return (jsxs("div", { ref: scrollContainerRef, style: { width: '100%', overflowY: 'auto', height: '100%' }, children: [jsxs("table", { className: classes.scrollableTable, children: [jsx("thead", { children: jsxs("tr", { children: [jsx("th", { children: "Type" }), jsx("th", { children: "Start" }), jsx("th", { children: "End" }), jsx("th", { children: "Strand" }), jsx("th", { children: "Attributes" })] }) }), jsx("tbody", { children: [...seenFeatures.entries()]
7777
+ .filter((entry) => {
7778
+ if (!filterText) {
7779
+ return true;
7780
+ }
7781
+ const [, feature] = entry;
7782
+ // search feature and its subfeatures for the text
7783
+ const text = JSON.stringify(feature);
7784
+ return text.includes(filterText);
7785
+ })
7786
+ .sort((a, b) => {
7787
+ return a[1].min - b[1].min;
7788
+ })
7789
+ .map(([featureId, feature]) => {
7790
+ const isSelected = selectedFeature?._id === featureId;
7791
+ const isHovered = hoveredFeature?.feature._id === featureId;
7792
+ return (jsx(Feature, { isSelected: isSelected, isHovered: isHovered, selectedFeatureClass: classes.selectedFeature, feature: feature, model: model, depth: 0, setContextMenu: setContextMenu }, featureId));
7793
+ }) })] }), jsx(Menu$1, { open: Boolean(contextMenu), onMenuItemClick: (_, callback) => {
7794
+ callback();
7795
+ setContextMenu(null);
7796
+ }, onClose: () => {
7797
+ setContextMenu(null);
7798
+ }, slotProps: {
7799
+ transition: {
7800
+ onExit: () => {
7801
+ setContextMenu(null);
7802
+ },
8250
7803
  },
8251
- },
8252
- }, style: { zIndex: theme.zIndex.tooltip }, menuItems: contextMenu?.items ?? [], anchorReference: "anchorPosition", anchorPosition: contextMenu?.position })));
7804
+ }, style: { zIndex: theme.zIndex.tooltip }, menuItems: contextMenu?.items ?? [], anchorReference: "anchorPosition", anchorPosition: contextMenu?.position })] }));
8253
7805
  });
8254
7806
 
8255
- /* eslint-disable @typescript-eslint/unbound-method */
8256
7807
  const useStyles$2 = makeStyles()({
8257
7808
  toolbar: {
8258
7809
  width: '100%',
@@ -8268,21 +7819,15 @@ const useStyles$2 = makeStyles()({
8268
7819
  const ToolBar = observer(function ToolBar({ model: displayState, }) {
8269
7820
  const model = displayState.tabularEditor;
8270
7821
  const { classes } = useStyles$2();
8271
- return (React.createElement("div", { className: classes.toolbar },
8272
- React.createElement(Tooltip, { title: "Collapse all" },
8273
- React.createElement(IconButton, { "aria-label": "collapse", sx: { marginTop: 0 }, onClick: model.collapseAllFeatures },
8274
- React.createElement(UnfoldLessIcon, null))),
8275
- React.createElement(TextField, { className: classes.filterText, label: "Filter features", value: model.filterText, sx: { marginTop: 0 }, variant: "outlined", onChange: (event) => {
8276
- model.setFilterText(event.target.value);
8277
- }, slotProps: {
8278
- input: {
8279
- endAdornment: (React.createElement(InputAdornment, { position: "end" },
8280
- React.createElement(IconButton, { onClick: () => {
8281
- model.clearFilterText();
8282
- } },
8283
- React.createElement(ClearIcon, null)))),
8284
- },
8285
- } })));
7822
+ return (jsxs("div", { className: classes.toolbar, children: [jsx(Tooltip, { title: "Collapse all", children: jsx(IconButton, { "aria-label": "collapse", sx: { marginTop: 0 }, onClick: model.collapseAllFeatures, children: jsx(UnfoldLessIcon, {}) }) }), jsx(TextField, { className: classes.filterText, label: "Filter features", value: model.filterText, sx: { marginTop: 0 }, variant: "outlined", onChange: (event) => {
7823
+ model.setFilterText(event.target.value);
7824
+ }, slotProps: {
7825
+ input: {
7826
+ endAdornment: (jsx(InputAdornment, { position: "end", children: jsx(IconButton, { onClick: () => {
7827
+ model.clearFilterText();
7828
+ }, children: jsx(ClearIcon, {}) }) })),
7829
+ },
7830
+ } })] }));
8286
7831
  });
8287
7832
 
8288
7833
  function stopPropagation(e) {
@@ -8296,9 +7841,7 @@ const TabularEditorPane = observer(function TabularEditorPane({ model: displaySt
8296
7841
  return (
8297
7842
  // TODO: a11y
8298
7843
  // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
8299
- React.createElement("div", { onMouseDown: stopPropagation, onClick: stopPropagation, style: { width: '100%', height: '100%', position: 'relative' } },
8300
- React.createElement(ToolBar, { model: displayState }),
8301
- React.createElement(HybridGrid, { model: displayState })));
7844
+ jsxs("div", { onMouseDown: stopPropagation, onClick: stopPropagation, style: { width: '100%', height: '100%', position: 'relative' }, children: [jsx(ToolBar, { model: displayState }), jsx(HybridGrid, { model: displayState })] }));
8302
7845
  });
8303
7846
 
8304
7847
  const TabularEditorStateModelType = types
@@ -8652,10 +8195,7 @@ function drawBackground(ctx, feature, stateModel, displayedRegionIndex, row, col
8652
8195
  const topLevelFeatureTop = row * apolloRowHeight;
8653
8196
  const topLevelFeatureHeight = getRowCount$1(feature, featureTypeOntology) * apolloRowHeight;
8654
8197
  let selectedColor;
8655
- if (color) {
8656
- selectedColor = color;
8657
- }
8658
- else {
8198
+ {
8659
8199
  selectedColor = readConfObject(session.getPluginConfiguration(), 'geneBackgroundColor', { featureType: feature.type });
8660
8200
  if (!selectedColor) {
8661
8201
  selectedColor = alpha(theme.palette.background.paper, 0.6);
@@ -9246,6 +8786,26 @@ function getContextMenuItems$2(display, mousePosition) {
9246
8786
  },
9247
8787
  ]);
9248
8788
  },
8789
+ }, {
8790
+ label: 'Duplicate feature',
8791
+ onClick: () => {
8792
+ session.queueDialog((doneCallback) => [
8793
+ DuplicateTranscript,
8794
+ {
8795
+ session,
8796
+ handleClose: () => {
8797
+ doneCallback();
8798
+ },
8799
+ changeManager,
8800
+ sourceFeature: feature,
8801
+ sourceAssemblyId: currentAssemblyId,
8802
+ selectedFeature,
8803
+ setSelectedFeature: (feature) => {
8804
+ display.setSelectedFeature(feature);
8805
+ },
8806
+ },
8807
+ ]);
8808
+ },
9249
8809
  });
9250
8810
  if (isSessionModelWithWidgets(session)) {
9251
8811
  contextMenuItemsForFeature.splice(1, 0, {
@@ -9452,45 +9012,27 @@ const FilterFeatures = observer(function FilterFeatures({ featureTypes, handleCl
9452
9012
  onUpdate(newTypes);
9453
9013
  setSelectedFeatureTypes(newTypes);
9454
9014
  };
9455
- return (React.createElement(Dialog, { open: true, maxWidth: false, "data-testid": "filter-features-dialog", title: "Filter features by type", handleClose: handleClose },
9456
- React.createElement(DialogContent, null,
9457
- React.createElement(DialogContentText, null, "Select the feature types you want to display in the apollo track"),
9458
- React.createElement(Grid, { container: true, spacing: 2 },
9459
- React.createElement(Grid, { size: 8 },
9460
- React.createElement(OntologyTermAutocomplete, { session: session, ontologyName: "Sequence Ontology", style: { width: '100%' }, value: type, filterTerms: isOntologyClass, renderInput: (params) => (React.createElement(TextField, { ...params, label: "Feature type", variant: "outlined", fullWidth: true })), onChange: (oldValue, newValue) => {
9461
- if (newValue) {
9462
- handleChange(newValue);
9463
- }
9464
- } })),
9465
- React.createElement(Grid, { size: 4 },
9466
- React.createElement(Button, { variant: "contained", onClick: handleAddFeatureType, disabled: !type, style: { marginTop: 9 }, size: "medium" }, "Add"))),
9467
- selectedFeatureTypes.length > 0 && (React.createElement("div", null,
9468
- React.createElement("hr", null),
9469
- React.createElement("div", { style: { width: 300 } },
9470
- React.createElement(DialogContentText, null, "Selected feature types:"),
9471
- React.createElement(Box, { sx: { display: 'flex', flexWrap: 'wrap', gap: 0.5 } }, selectedFeatureTypes.map((value) => (React.createElement(Chip, { key: value, label: value, onDelete: () => {
9472
- handleFeatureTypeDelete(value);
9473
- } }))))))))));
9015
+ return (jsx(Dialog, { open: true, maxWidth: false, "data-testid": "filter-features-dialog", title: "Filter features by type", handleClose: handleClose, children: jsxs(DialogContent, { children: [jsx(DialogContentText, { children: "Select the feature types you want to display in the apollo track" }), jsxs(Grid, { container: true, spacing: 2, children: [jsx(Grid, { size: 8, children: jsx(OntologyTermAutocomplete, { session: session, ontologyName: "Sequence Ontology", style: { width: '100%' }, value: type, filterTerms: isOntologyClass, renderInput: (params) => (jsx(TextField, { ...params, label: "Feature type", variant: "outlined", fullWidth: true })), onChange: (oldValue, newValue) => {
9016
+ if (newValue) {
9017
+ handleChange(newValue);
9018
+ }
9019
+ } }) }), jsx(Grid, { size: 4, children: jsx(Button, { variant: "contained", onClick: handleAddFeatureType, disabled: !type, style: { marginTop: 9 }, size: "medium", children: "Add" }) })] }), selectedFeatureTypes.length > 0 && (jsxs("div", { children: [jsx("hr", {}), jsxs("div", { style: { width: 300 }, children: [jsx(DialogContentText, { children: "Selected feature types:" }), jsx(Box, { sx: { display: 'flex', flexWrap: 'wrap', gap: 0.5 }, children: selectedFeatureTypes.map((value) => (jsx(Chip, { label: value, onDelete: () => {
9020
+ handleFeatureTypeDelete(value);
9021
+ } }, value))) })] })] }))] }) }));
9474
9022
  });
9475
9023
 
9476
9024
  const EditZoomThresholdDialog = observer(function ({ model, handleClose, }) {
9477
9025
  const [zoomThreshold, setZoomThreshold] = useState(`${model.zoomThresholdSetting}`);
9478
- return (React.createElement(Dialog$1, { open: true, onClose: handleClose, title: "Edit zoom threshold setting" },
9479
- React.createElement(DialogContent, null,
9480
- React.createElement(Typography, null, "The zoom level in base pairs (bp) per pixel at which features are rendered in this Annotations track. Increasing the value will allow features to render when zooming out, but might impact performance."),
9481
- React.createElement(TextField, { label: "Threshold value (bpPerPx)", value: zoomThreshold, onChange: (event) => {
9482
- setZoomThreshold(event.target.value);
9483
- } }),
9484
- React.createElement(DialogActions, null,
9485
- React.createElement(Button, { variant: "contained", onClick: () => {
9486
- model.setZoomThresholdSetting({
9487
- zoomThreshold: +zoomThreshold,
9488
- });
9489
- handleClose();
9490
- } }, "Submit"),
9491
- React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => {
9492
- handleClose();
9493
- } }, "Cancel")))));
9026
+ return (jsx(Dialog$1, { open: true, onClose: handleClose, title: "Edit zoom threshold setting", children: jsxs(DialogContent, { children: [jsx(Typography, { children: "The zoom level in base pairs (bp) per pixel at which features are rendered in this Annotations track. Increasing the value will allow features to render when zooming out, but might impact performance." }), jsx(TextField, { label: "Threshold value (bpPerPx)", value: zoomThreshold, onChange: (event) => {
9027
+ setZoomThreshold(event.target.value);
9028
+ } }), jsxs(DialogActions, { children: [jsx(Button, { variant: "contained", onClick: () => {
9029
+ model.setZoomThresholdSetting({
9030
+ zoomThreshold: +zoomThreshold,
9031
+ });
9032
+ handleClose();
9033
+ }, children: "Submit" }), jsx(Button, { variant: "contained", color: "secondary", onClick: () => {
9034
+ handleClose();
9035
+ }, children: "Cancel" })] })] }) }));
9494
9036
  });
9495
9037
 
9496
9038
  const useStyles$1 = makeStyles()((theme) => ({
@@ -9547,7 +9089,7 @@ function clusterResultByMessage(items, width, touchesAsOverlap) {
9547
9089
  (byMsg.get(it.message) ?? byMsg.set(it.message, []).get(it.message)).push(it);
9548
9090
  }
9549
9091
  const clusters = [];
9550
- const overlaps = (aEnd, bStart) => touchesAsOverlap ? bStart <= aEnd : bStart < aEnd;
9092
+ const overlaps = (aEnd, bStart) => bStart <= aEnd ;
9551
9093
  for (const [message, arr] of byMsg.entries()) {
9552
9094
  if (arr.length === 0) {
9553
9095
  continue;
@@ -10921,7 +10463,6 @@ function stateModelFactory$1(pluginManager, configSchema) {
10921
10463
  return renderingModelFactory$1(pluginManager, configSchema).named('LinearApolloReferenceSequenceDisplay');
10922
10464
  }
10923
10465
 
10924
- /* eslint-disable @typescript-eslint/unbound-method */
10925
10466
  const LinearApolloReferenceSequenceDisplay = observer(function LinearApolloReferenceSequenceDisplay(props) {
10926
10467
  const theme = useTheme();
10927
10468
  const { model } = props;
@@ -10932,24 +10473,21 @@ const LinearApolloReferenceSequenceDisplay = observer(function LinearApolloRefer
10932
10473
  }, [theme, setTheme]);
10933
10474
  const lgv = getContainingView(model);
10934
10475
  const message = regionCannotBeRendered();
10476
+ // This type is wrong in @jbrowse/core
10935
10477
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
10936
10478
  if (message) {
10937
- return (React.createElement(Alert, { severity: "warning", classes: { message: classes.ellipses }, slotProps: { root: { className: classes.center } } },
10938
- React.createElement(Tooltip, { title: message },
10939
- React.createElement("div", null, message))));
10940
- }
10941
- return (React.createElement(React.Fragment, null, 3 / lgv.bpPerPx >= 1 ? (React.createElement("div", { className: classes.canvasContainer, style: {
10942
- width: lgv.dynamicBlocks.totalWidthPx,
10943
- height,
10944
- } },
10945
- React.createElement("canvas", { ref: async (node) => {
10946
- await Promise.resolve();
10947
- setSeqTrackCanvas(node);
10948
- }, width: lgv.dynamicBlocks.totalWidthPx, height: height, className: classes.canvas, "data-testid": "seqTrackCanvas" }),
10949
- React.createElement("canvas", { ref: async (node) => {
10950
- await Promise.resolve();
10951
- setSeqTrackOverlayCanvas(node);
10952
- }, width: lgv.dynamicBlocks.totalWidthPx, height: height, className: classes.canvas, "data-testid": "seqTrackOverlayCanvas" }))) : null));
10479
+ return (jsx(Alert, { severity: "warning", classes: { message: classes.ellipses }, slotProps: { root: { className: classes.center } }, children: jsx(Tooltip, { title: message, children: jsx("div", { children: message }) }) }));
10480
+ }
10481
+ return (jsx(Fragment, { children: 3 / lgv.bpPerPx >= 1 ? (jsxs("div", { className: classes.canvasContainer, style: {
10482
+ width: lgv.dynamicBlocks.totalWidthPx,
10483
+ height,
10484
+ }, children: [jsx("canvas", { ref: async (node) => {
10485
+ await Promise.resolve();
10486
+ setSeqTrackCanvas(node);
10487
+ }, width: lgv.dynamicBlocks.totalWidthPx, height: height, className: classes.canvas, "data-testid": "seqTrackCanvas" }), jsx("canvas", { ref: async (node) => {
10488
+ await Promise.resolve();
10489
+ setSeqTrackOverlayCanvas(node);
10490
+ }, width: lgv.dynamicBlocks.totalWidthPx, height: height, className: classes.canvas, "data-testid": "seqTrackOverlayCanvas" })] })) : null }));
10953
10491
  });
10954
10492
 
10955
10493
  const configSchema = ConfigurationSchema('LinearApolloSixFrameDisplay', {}, { explicitIdentifier: 'displayId', explicitlyTyped: true });
@@ -10974,16 +10512,11 @@ const FilterTranscripts = observer(function FilterTranscripts({ sourceFeature, f
10974
10512
  onUpdate(newForms);
10975
10513
  setExcludedTranscripts(newForms);
10976
10514
  };
10977
- return (React.createElement(Dialog, { open: true, maxWidth: false, "data-testid": "filter-transcripts-dialog", title: "Filter transcripts by ID", handleClose: handleClose },
10978
- React.createElement(DialogContent, null,
10979
- React.createElement(DialogContentText, null, "Select the alternate transcripts you want to display in the apollo track"),
10980
- React.createElement(Grid, { container: true, spacing: 2 },
10981
- React.createElement(Grid, { size: 8 },
10982
- React.createElement(FormGroup, null, allTranscripts.map((item) => (
10983
- // eslint-disable-next-line react/jsx-key
10984
- React.createElement(FormControlLabel, { control: React.createElement(Checkbox, { checked: !excludedTranscripts.includes(item), onChange: () => {
10985
- handleChange(item);
10986
- }, slotProps: { input: { 'aria-label': 'controlled' } } }), label: item })))))))));
10515
+ return (jsx(Dialog, { open: true, maxWidth: false, "data-testid": "filter-transcripts-dialog", title: "Filter transcripts by ID", handleClose: handleClose, children: jsxs(DialogContent, { children: [jsx(DialogContentText, { children: "Select the alternate transcripts you want to display in the apollo track" }), jsx(Grid, { container: true, spacing: 2, children: jsx(Grid, { size: 8, children: jsx(FormGroup, { children: allTranscripts.map((item) => (
10516
+ // eslint-disable-next-line react/jsx-key
10517
+ jsx(FormControlLabel, { control: jsx(Checkbox, { checked: !excludedTranscripts.includes(item), onChange: () => {
10518
+ handleChange(item);
10519
+ }, slotProps: { input: { 'aria-label': 'controlled' } } }), label: item }))) }) }) })] }) }));
10987
10520
  });
10988
10521
 
10989
10522
  let forwardFillLight = null;
@@ -11210,8 +10743,14 @@ function draw(ctx, topLevelFeature, _row, stateModel, displayedRegionIndex) {
11210
10743
  cdsStartPx = reversed ? minX - cdsWidthPx : minX;
11211
10744
  ctx.fillStyle = theme.palette.text.primary;
11212
10745
  const frame = getFrame(cds.min, cds.max, child.strand ?? 1, cds.phase);
11213
- const frameAdjust = (frame < 0 ? -1 * frame + 5 : frame) * featureLabelSpacer;
11214
- cdsTop = (frameAdjust - featureLabelSpacer) * rowHeight;
10746
+ const frameOffsets = showFeatureLabels
10747
+ ? [0, 4, 2, 0, 14, 12, 10]
10748
+ : [0, 2, 1, 0, 7, 6, 5];
10749
+ const row = frameOffsets.at(frame);
10750
+ if (row === undefined) {
10751
+ continue;
10752
+ }
10753
+ cdsTop = row * rowHeight;
11215
10754
  ctx.fillRect(cdsStartPx, cdsTop, cdsWidthPx, cdsHeight);
11216
10755
  // Draw lines to connect CDS features with shared mRNA parent
11217
10756
  if (counter > 1) {
@@ -11344,8 +10883,14 @@ function drawHover(stateModel, ctx) {
11344
10883
  })?.offsetPx ?? 0) - offsetPx;
11345
10884
  const cdsStartPx = reversed ? minX - cdsWidthPx : minX;
11346
10885
  const frame = getFrame(cds.min, cds.max, strand ?? 1, cds.phase);
11347
- const frameAdjust = (frame < 0 ? -1 * frame + 5 : frame) * featureLabelSpacer;
11348
- const cdsTop = (frameAdjust - featureLabelSpacer) * rowHeight;
10886
+ const frameOffsets = showFeatureLabels
10887
+ ? [0, 4, 2, 0, 14, 12, 10]
10888
+ : [0, 2, 1, 0, 7, 6, 5];
10889
+ const row = frameOffsets.at(frame);
10890
+ if (row === undefined) {
10891
+ continue;
10892
+ }
10893
+ const cdsTop = row * rowHeight;
11349
10894
  if (counter > 1) {
11350
10895
  // Mid-point for intron line "hat"
11351
10896
  const midPoint = [
@@ -11525,8 +11070,6 @@ function drawTooltip(display, context) {
11525
11070
  const displayedRegion = displayedRegions[layoutIndex];
11526
11071
  const { refName, reversed } = displayedRegion;
11527
11072
  const rowHeight = apolloRowHeight;
11528
- const cdsHeight = Math.round(0.7 * rowHeight);
11529
- const featureLabelSpacer = showFeatureLabels ? 2 : 1;
11530
11073
  let location = 'Loc: ';
11531
11074
  let cds = undefined;
11532
11075
  for (const loc of feature.cdsLocations) {
@@ -11548,8 +11091,14 @@ function drawTooltip(display, context) {
11548
11091
  regionNumber: layoutIndex,
11549
11092
  })?.offsetPx ?? 0) - offsetPx;
11550
11093
  const frame = getFrame(min, max, strand ?? 1, phase);
11551
- const frameAdjust = (frame < 0 ? -1 * frame + 5 : frame) * featureLabelSpacer;
11552
- const cdsTop = (frameAdjust - featureLabelSpacer) * rowHeight + (rowHeight - cdsHeight) / 2;
11094
+ const frameOffsets = showFeatureLabels
11095
+ ? [0, 4, 2, 0, 14, 12, 10]
11096
+ : [0, 2, 1, 0, 7, 6, 5];
11097
+ const row = frameOffsets.at(frame);
11098
+ if (row === undefined) {
11099
+ return;
11100
+ }
11101
+ const cdsTop = row * rowHeight;
11553
11102
  const cdsWidthPx = (max - min) / bpPerPx;
11554
11103
  const featureType = `Type: ${cds.type}`;
11555
11104
  const featureName = attributes.get('gff_name')?.find((name) => name !== '');
@@ -12137,8 +11686,14 @@ function layoutsModelFactory(pluginManager, configSchema) {
12137
11686
  }
12138
11687
  for (const cdsRow of cdsLocations) {
12139
11688
  for (const cds of cdsRow) {
12140
- let rowNum = getFrame(cds.min, cds.max, strand ?? 1, cds.phase);
12141
- rowNum = self.featureLabelSpacer(rowNum < 0 ? -1 * rowNum + 5 : rowNum);
11689
+ const frame = getFrame(cds.min, cds.max, strand ?? 1, cds.phase);
11690
+ const frameOffsets = self.showFeatureLabels
11691
+ ? [0, 5, 3, 1, 15, 13, 11]
11692
+ : [0, 2, 1, 0, 8, 7, 6];
11693
+ const rowNum = frameOffsets.at(frame);
11694
+ if (!rowNum) {
11695
+ continue;
11696
+ }
12142
11697
  if (!featureLayout.get(rowNum)) {
12143
11698
  featureLayout.set(rowNum, []);
12144
11699
  }
@@ -12409,8 +11964,11 @@ function mouseEventsModelIntermediateFactory(pluginManager, configSchema) {
12409
11964
  }
12410
11965
  for (const loc of feature.cdsLocations) {
12411
11966
  for (const cds of loc) {
12412
- let rowNum = getFrame(cds.min, cds.max, feature.strand ?? 1, cds.phase);
12413
- rowNum = self.featureLabelSpacer(rowNum < 0 ? -1 * rowNum + 5 : rowNum);
11967
+ const frame = getFrame(cds.min, cds.max, feature.strand ?? 1, cds.phase);
11968
+ const frameOffsets = self.showFeatureLabels
11969
+ ? [0, 5, 3, 1, 15, 13, 11]
11970
+ : [0, 2, 1, 0, 8, 7, 6];
11971
+ const rowNum = frameOffsets.at(frame);
12414
11972
  if (row === rowNum && bp >= cds.min && bp <= cds.max) {
12415
11973
  return (featureID === undefined ||
12416
11974
  !self.filteredTranscripts.includes(featureID));
@@ -12638,7 +12196,6 @@ const ApolloPluginConfigurationSchema = ConfigurationSchema('ApolloPlugin', {
12638
12196
  },
12639
12197
  });
12640
12198
 
12641
- /* eslint-disable react-hooks/exhaustive-deps */
12642
12199
  const isGeneOrTranscript = (annotationFeature, apolloSessionModel) => {
12643
12200
  const { featureTypeOntology } = apolloSessionModel.apolloDataStore.ontologyManager;
12644
12201
  if (!featureTypeOntology) {
@@ -12958,40 +12515,22 @@ function CreateApolloAnnotation({ annotationFeature, assembly, handleClose, refS
12958
12515
  const handleCreateNewGeneChange = (e) => {
12959
12516
  setCreateNewGene(e.target.checked);
12960
12517
  };
12961
- return (React.createElement(Dialog, { open: true, title: "Create Apollo Annotation", handleClose: handleClose, fullWidth: true, maxWidth: "sm" },
12962
- React.createElement(DialogTitle, { fontSize: 15 }, "Select the feature to be copied to apollo track"),
12963
- React.createElement(DialogContent, null,
12964
- React.createElement(Box, { sx: { ml: 3 } },
12965
- isGeneOrTranscript(annotationFeature, apolloSessionModel) && (React.createElement(FormControlLabel, { control: React.createElement(Checkbox, { size: "small", checked: parentFeatureChecked, onChange: handleParentFeatureCheck }), label: `${getFeatureNameOrId(annotationFeature)} (${annotationFeature.min + 1}..${annotationFeature.max})` })),
12966
- annotationFeature.children && (React.createElement(Box, { sx: { display: 'flex', flexDirection: 'column', ml: 3 } }, Object.values(annotationFeature.children)
12967
- .filter((child) => isTranscript(child, apolloSessionModel))
12968
- .map((child) => (React.createElement(FormControlLabel, { key: child._id, control: React.createElement(Checkbox, { size: "small", checked: checkedChildrens.includes(child._id), onChange: (e) => {
12969
- handleChildFeatureCheck(e, child);
12970
- } }), label: `${getFeatureNameOrId(child)} (${child.min + 1}..${child.max})` })))))),
12971
- destinationFeatures.length > 0 &&
12972
- ((!parentFeatureChecked && checkedChildrens.length > 0) ||
12973
- (parentFeatureChecked &&
12974
- isTranscript(annotationFeature, apolloSessionModel))) && (React.createElement("div", { style: {
12975
- border: '1px solid #ccc',
12976
- marginTop: 20,
12977
- padding: 10,
12978
- borderRadius: 5,
12979
- } },
12980
- React.createElement(Box, { sx: { ml: 3 } },
12981
- React.createElement(Typography, { variant: "caption", fontSize: 12 }, "Select the destination feature to copy the selected features"),
12982
- React.createElement(Box, { sx: { mt: 1 } },
12983
- React.createElement(Select, { labelId: "label", style: { width: '100%' }, value: selectedDestinationFeature?._id ?? '', onChange: handleDestinationFeatureChange, disabled: createNewGene }, destinationFeatures.map((f) => (React.createElement(MenuItem, { key: f._id, value: f._id }, `${getFeatureNameOrId(f)} (${f.min + 1}..${f.max})`)))))),
12984
- React.createElement(Box, { sx: { ml: 3 } },
12985
- React.createElement(FormGroup, null,
12986
- React.createElement(FormControlLabel, { control: React.createElement(Checkbox, { checked: createNewGene, onChange: handleCreateNewGeneChange }), label: "Create new gene" })))))),
12987
- React.createElement(DialogActions, null,
12988
- React.createElement(Button, { variant: "contained", type: "submit", disabled: checkedChildrens.length === 0 ||
12989
- (!parentFeatureChecked &&
12990
- checkedChildrens.length > 0 &&
12991
- !selectedDestinationFeature), onClick: handleCreateApolloAnnotation }, "Create"),
12992
- React.createElement(Button, { variant: "outlined", type: "submit", onClick: handleClose }, "Cancel")),
12993
- errorMessage ? (React.createElement(DialogContent, null,
12994
- React.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
12518
+ return (jsxs(Dialog, { open: true, title: "Create Apollo Annotation", handleClose: handleClose, fullWidth: true, maxWidth: "sm", children: [jsx(DialogTitle, { fontSize: 15, children: "Select the feature to be copied to apollo track" }), jsxs(DialogContent, { children: [jsxs(Box, { sx: { ml: 3 }, children: [isGeneOrTranscript(annotationFeature, apolloSessionModel) && (jsx(FormControlLabel, { control: jsx(Checkbox, { size: "small", checked: parentFeatureChecked, onChange: handleParentFeatureCheck }), label: `${getFeatureNameOrId(annotationFeature)} (${annotationFeature.min + 1}..${annotationFeature.max})` })), annotationFeature.children && (jsx(Box, { sx: { display: 'flex', flexDirection: 'column', ml: 3 }, children: Object.values(annotationFeature.children)
12519
+ .filter((child) => isTranscript(child, apolloSessionModel))
12520
+ .map((child) => (jsx(FormControlLabel, { control: jsx(Checkbox, { size: "small", checked: checkedChildrens.includes(child._id), onChange: (e) => {
12521
+ handleChildFeatureCheck(e, child);
12522
+ } }), label: `${getFeatureNameOrId(child)} (${child.min + 1}..${child.max})` }, child._id))) }))] }), destinationFeatures.length > 0 &&
12523
+ ((!parentFeatureChecked && checkedChildrens.length > 0) ||
12524
+ (parentFeatureChecked &&
12525
+ isTranscript(annotationFeature, apolloSessionModel))) && (jsxs("div", { style: {
12526
+ border: '1px solid #ccc',
12527
+ marginTop: 20,
12528
+ padding: 10,
12529
+ borderRadius: 5,
12530
+ }, children: [jsxs(Box, { sx: { ml: 3 }, children: [jsx(Typography, { variant: "caption", fontSize: 12, children: "Select the destination feature to copy the selected features" }), jsx(Box, { sx: { mt: 1 }, children: jsx(Select, { labelId: "label", style: { width: '100%' }, value: selectedDestinationFeature?._id ?? '', onChange: handleDestinationFeatureChange, disabled: createNewGene, children: destinationFeatures.map((f) => (jsx(MenuItem, { value: f._id, children: `${getFeatureNameOrId(f)} (${f.min + 1}..${f.max})` }, f._id))) }) })] }), jsx(Box, { sx: { ml: 3 }, children: jsx(FormGroup, { children: jsx(FormControlLabel, { control: jsx(Checkbox, { checked: createNewGene, onChange: handleCreateNewGeneChange }), label: "Create new gene" }) }) })] }))] }), jsxs(DialogActions, { children: [jsx(Button, { variant: "contained", type: "submit", disabled: checkedChildrens.length === 0 ||
12531
+ (!parentFeatureChecked &&
12532
+ checkedChildrens.length > 0 &&
12533
+ !selectedDestinationFeature), onClick: handleCreateApolloAnnotation, children: "Create" }), jsx(Button, { variant: "outlined", type: "submit", onClick: handleClose, children: "Cancel" })] }), errorMessage ? (jsx(DialogContent, { children: jsx(DialogContentText, { color: "error", children: errorMessage }) })) : null] }));
12995
12534
  }
12996
12535
 
12997
12536
  function parseCigar(cigar) {
@@ -13178,22 +12717,25 @@ function annotationFromPileup(pluggableElement) {
13178
12717
  }
13179
12718
 
13180
12719
  function simpleFeatureToGFF3Feature(feature, refSeqId) {
13181
- // eslint-disable-next-line unicorn/prefer-structured-clone
13182
- const xfeature = JSON.parse(JSON.stringify(feature));
13183
- const children = xfeature.subfeatures;
12720
+ const children = feature.get('subfeatures');
13184
12721
  const gff3Feature = [
13185
12722
  {
13186
- start: xfeature.start + 1,
13187
- end: xfeature.end,
12723
+ start: feature.get('start') + 1,
12724
+ end: feature.get('end'),
13188
12725
  seq_id: refSeqId,
13189
- source: xfeature.source ?? null,
13190
- type: xfeature.type ?? null,
13191
- score: xfeature.score ?? null,
13192
- strand: xfeature.strand ? (xfeature.strand === 1 ? '+' : '-') : null,
13193
- phase: xfeature.phase !== null || xfeature.phase !== undefined
13194
- ? xfeature.phase
12726
+ source: feature.get('source') ?? null,
12727
+ type: feature.get('type') ?? null,
12728
+ score: feature.get('score') ?? null,
12729
+ strand: feature.get('strand')
12730
+ ? // eslint-disable-next-line unicorn/no-nested-ternary
12731
+ feature.get('strand') === 1
12732
+ ? '+'
12733
+ : '-'
13195
12734
  : null,
13196
- attributes: convertFeatureAttributes(xfeature),
12735
+ phase: feature.get('phase') !== null || feature.get('phase') !== undefined
12736
+ ? feature.get('phase')
12737
+ : null,
12738
+ attributes: convertFeatureAttributes(feature),
13197
12739
  derived_features: [],
13198
12740
  child_features: children
13199
12741
  ? children.map((x) => simpleFeatureToGFF3Feature(x, refSeqId))
@@ -13219,7 +12761,7 @@ function convertFeatureAttributes(feature) {
13219
12761
  'source',
13220
12762
  'score',
13221
12763
  ]);
13222
- for (const [key, value] of Object.entries(feature)) {
12764
+ for (const [key, value] of Object.entries(feature.toJSON())) {
13223
12765
  if (defaultFields.has(key)) {
13224
12766
  continue;
13225
12767
  }
@@ -13268,10 +12810,9 @@ function annotationFromJBrowseFeature(pluggableElement) {
13268
12810
  }
13269
12811
  return refSeqId;
13270
12812
  },
13271
- getAnnotationFeature(assembly) {
12813
+ getAnnotationFeature(assembly, feature) {
13272
12814
  const refSeqId = self.getRefSeqId(assembly);
13273
- const sfeature = self.contextMenuFeature.data;
13274
- return jbrowseFeatureToAnnotationFeature(sfeature, refSeqId);
12815
+ return jbrowseFeatureToAnnotationFeature(feature, refSeqId);
13275
12816
  },
13276
12817
  }))
13277
12818
  .views((self) => {
@@ -13298,7 +12839,7 @@ function annotationFromJBrowseFeature(pluggableElement) {
13298
12839
  handleClose: () => {
13299
12840
  doneCallback();
13300
12841
  },
13301
- annotationFeature: self.getAnnotationFeature(assembly),
12842
+ annotationFeature: self.getAnnotationFeature(assembly, feature),
13302
12843
  assembly,
13303
12844
  refSeqId: self.getRefSeqId(assembly),
13304
12845
  region,
@@ -13332,7 +12873,7 @@ const CheckResultWarnings = observer(function CheckResultWarnings({ display, })
13332
12873
  ].filter((checkResult) => assembly.isValidRefName(checkResult.refSeq) &&
13333
12874
  assembly.getCanonicalRefName(checkResult.refSeq) === block.refName &&
13334
12875
  doesIntersect2(block.start, block.end, checkResult.start, checkResult.end));
13335
- const checkResults = clusterResultByMessage(filteredCheckResults, widthBp, true);
12876
+ const checkResults = clusterResultByMessage(filteredCheckResults, widthBp);
13336
12877
  return checkResults.map((checkResult) => {
13337
12878
  const left = Math.round(getLeftPx(display, checkResult.range, block));
13338
12879
  const [feature] = checkResult.featureIds;
@@ -13346,22 +12887,17 @@ const CheckResultWarnings = observer(function CheckResultWarnings({ display, })
13346
12887
  }
13347
12888
  const top = row * apolloRowHeight;
13348
12889
  const height = apolloRowHeight;
13349
- return (React.createElement(Tooltip, { key: checkResult._id, title: checkResult.message },
13350
- React.createElement(Box, { className: classes.box, style: {
12890
+ return (jsx(Tooltip, { title: checkResult.message, children: jsx(Box, { className: classes.box, style: {
13351
12891
  top,
13352
12892
  left,
13353
12893
  height,
13354
12894
  width: height,
13355
12895
  pointerEvents: apolloDragging ? 'none' : 'auto',
13356
- } },
13357
- React.createElement(Badge, { className: classes.badge, badgeContent: checkResult.count, color: "primary", overlap: "circular", anchorOrigin: { vertical: 'bottom', horizontal: 'right' }, invisible: checkResult.count <= 1 },
13358
- React.createElement(Avatar, { className: classes.avatar },
13359
- React.createElement(ErrorIcon, { "data-testid": `ErrorIcon-${checkResult.start}` }))))));
12896
+ }, children: jsx(Badge, { className: classes.badge, badgeContent: checkResult.count, color: "primary", overlap: "circular", anchorOrigin: { vertical: 'bottom', horizontal: 'right' }, invisible: checkResult.count <= 1, children: jsx(Avatar, { className: classes.avatar, children: jsx(ErrorIcon, { "data-testid": `ErrorIcon-${checkResult.start}` }) }) }) }) }, checkResult._id));
13360
12897
  });
13361
12898
  });
13362
12899
  });
13363
12900
 
13364
- /* eslint-disable @typescript-eslint/unbound-method */
13365
12901
  // Lock icon when isLocked === true
13366
12902
  const LinearApolloDisplay = observer(function LinearApolloDisplay(props) {
13367
12903
  const theme = useTheme();
@@ -13378,8 +12914,7 @@ const LinearApolloDisplay = observer(function LinearApolloDisplay(props) {
13378
12914
  if (!isShown) {
13379
12915
  return null;
13380
12916
  }
13381
- return (React.createElement(React.Fragment, null,
13382
- React.createElement("div", { className: classes.canvasContainer, style: {
12917
+ return (jsx(Fragment, { children: jsxs("div", { className: classes.canvasContainer, style: {
13383
12918
  width: lgv.dynamicBlocks.totalWidthPx,
13384
12919
  height: featuresHeight,
13385
12920
  }, onContextMenu: (event) => {
@@ -13393,63 +12928,50 @@ const LinearApolloDisplay = observer(function LinearApolloDisplay(props) {
13393
12928
  setContextCoord(coord);
13394
12929
  setContextMenuItems(getContextMenuItems(event));
13395
12930
  }
13396
- } },
13397
- session.isLocked ? (React.createElement("div", { className: classes.locked, "data-testid": "lock-icon" },
13398
- React.createElement(LockIcon, null))) : null,
13399
- loading ? (React.createElement("div", { className: classes.loading },
13400
- React.createElement(CircularProgress, { size: "18px" }))) : null,
13401
- message ? (React.createElement(Alert, { severity: "warning", classes: { message: classes.ellipses }, slotProps: { root: { className: classes.center } } },
13402
- React.createElement(Tooltip, { title: message },
13403
- React.createElement("div", null, message)))) : (
13404
- // Promise.resolve() in these 3 callbacks is to avoid infinite rendering loop
13405
- // https://github.com/mobxjs/mobx/issues/3728#issuecomment-1715400931
13406
- React.createElement(React.Fragment, null,
13407
- React.createElement("canvas", { ref: async (node) => {
13408
- await Promise.resolve();
13409
- setCollaboratorCanvas(node);
13410
- }, width: lgv.dynamicBlocks.totalWidthPx, height: featuresHeight, className: classes.canvas, "data-testid": "collaboratorCanvas" }),
13411
- React.createElement("canvas", { ref: async (node) => {
13412
- await Promise.resolve();
13413
- setCanvas(node);
13414
- }, width: lgv.dynamicBlocks.totalWidthPx, height: featuresHeight, className: classes.canvas, "data-testid": "canvas" }),
13415
- React.createElement("canvas", { ref: async (node) => {
13416
- await Promise.resolve();
13417
- setOverlayCanvas(node);
13418
- }, width: lgv.dynamicBlocks.totalWidthPx, height: featuresHeight, onMouseMove: onMouseMove, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, className: classes.canvas, style: { cursor: cursor ?? 'default' }, "data-testid": "overlayCanvas" }),
13419
- React.createElement(CheckResultWarnings, { display: model }),
13420
- React.createElement(Menu$1, { open: contextMenuItems.length > 0, onMenuItemClick: (_, callback) => {
13421
- callback();
13422
- setContextMenuItems([]);
13423
- }, onClose: () => {
13424
- setContextMenuItems([]);
13425
- }, slotProps: {
13426
- transition: {
13427
- onExit: () => {
12931
+ }, children: [session.isLocked ? (jsx("div", { className: classes.locked, "data-testid": "lock-icon", children: jsx(LockIcon, {}) })) : null, loading ? (jsx("div", { className: classes.loading, children: jsx(CircularProgress, { size: "18px" }) })) : null, message ? (jsx(Alert, { severity: "warning", classes: { message: classes.ellipses }, slotProps: { root: { className: classes.center } }, children: jsx(Tooltip, { title: message, children: jsx("div", { children: message }) }) })) : (
12932
+ // Promise.resolve() in these 3 callbacks is to avoid infinite rendering loop
12933
+ // https://github.com/mobxjs/mobx/issues/3728#issuecomment-1715400931
12934
+ jsxs(Fragment, { children: [jsx("canvas", { ref: async (node) => {
12935
+ await Promise.resolve();
12936
+ setCollaboratorCanvas(node);
12937
+ }, width: lgv.dynamicBlocks.totalWidthPx, height: featuresHeight, className: classes.canvas, "data-testid": "collaboratorCanvas" }), jsx("canvas", { ref: async (node) => {
12938
+ await Promise.resolve();
12939
+ setCanvas(node);
12940
+ }, width: lgv.dynamicBlocks.totalWidthPx, height: featuresHeight, className: classes.canvas, "data-testid": "canvas" }), jsx("canvas", { ref: async (node) => {
12941
+ await Promise.resolve();
12942
+ setOverlayCanvas(node);
12943
+ }, width: lgv.dynamicBlocks.totalWidthPx, height: featuresHeight, onMouseMove: onMouseMove, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, className: classes.canvas, style: { cursor: cursor ?? 'default' }, "data-testid": "overlayCanvas" }), jsx(CheckResultWarnings, { display: model }), jsx(Menu$1, { open: contextMenuItems.length > 0, onMenuItemClick: (_, callback) => {
12944
+ callback();
13428
12945
  setContextMenuItems([]);
13429
- },
13430
- },
13431
- }, anchorReference: "anchorPosition", anchorPosition: contextCoord
13432
- ? { top: contextCoord[1], left: contextCoord[0] }
13433
- : undefined, style: { zIndex: theme.zIndex.tooltip }, menuItems: contextMenuItems }))))));
12946
+ }, onClose: () => {
12947
+ setContextMenuItems([]);
12948
+ }, slotProps: {
12949
+ transition: {
12950
+ onExit: () => {
12951
+ setContextMenuItems([]);
12952
+ },
12953
+ },
12954
+ }, anchorReference: "anchorPosition", anchorPosition: contextCoord
12955
+ ? { top: contextCoord[1], left: contextCoord[0] }
12956
+ : undefined, menuItems: contextMenuItems })] }))] }) }));
13434
12957
  });
13435
12958
 
13436
12959
  const TrackLines = observer(function TrackLines({ model, hrStyle = { margin: 0, top: 0, color: 'black' }, idx = 0, }) {
13437
12960
  const { apolloRowHeight, highestRow, showFeatureLabels } = model;
13438
12961
  const featureLabelSpacer = showFeatureLabels ? 2 : 1;
13439
- return (React.createElement("div", { style: {
12962
+ return (jsx("div", { style: {
13440
12963
  position: 'absolute',
13441
12964
  left: 0,
13442
12965
  top: (apolloRowHeight * featureLabelSpacer * (highestRow + 1)) / 2 +
13443
12966
  idx * featureLabelSpacer * apolloRowHeight,
13444
12967
  width: '100%',
13445
- } },
13446
- React.createElement("hr", { style: hrStyle })));
12968
+ }, children: jsx("hr", { style: hrStyle }) }));
13447
12969
  });
13448
12970
 
13449
12971
  const LinearApolloSixFrameDisplay = observer(function LinearApolloSixFrameDisplay(props, apolloDragging) {
13450
12972
  const theme = useTheme();
13451
12973
  const { model } = props;
13452
- const { apolloRowHeight, contextMenuItems: getContextMenuItems, cursor, featuresHeight, featureLabelSpacer, geneTrackRowNums, isShown, onMouseDown, onMouseLeave, onMouseMove, onMouseUp, regionCannotBeRendered, session, setCanvas, setCollaboratorCanvas, setOverlayCanvas, setTheme, showCheckResults, } = model;
12974
+ const { apolloRowHeight, contextMenuItems: getContextMenuItems, cursor, featuresHeight, geneTrackRowNums, isShown, onMouseDown, onMouseLeave, onMouseMove, onMouseUp, regionCannotBeRendered, session, setCanvas, setCollaboratorCanvas, setOverlayCanvas, setTheme, showCheckResults, showFeatureLabels, } = model;
13453
12975
  const { classes } = useStyles$1();
13454
12976
  const lgv = getContainingView(model);
13455
12977
  useEffect(() => {
@@ -13462,8 +12984,7 @@ const LinearApolloSixFrameDisplay = observer(function LinearApolloSixFrameDispla
13462
12984
  return null;
13463
12985
  }
13464
12986
  const { assemblyManager } = session;
13465
- return (React.createElement(React.Fragment, null,
13466
- React.createElement("div", { className: classes.canvasContainer, style: {
12987
+ return (jsx(Fragment, { children: jsxs("div", { className: classes.canvasContainer, style: {
13467
12988
  width: lgv.dynamicBlocks.totalWidthPx,
13468
12989
  height: featuresHeight,
13469
12990
  }, onContextMenu: (event) => {
@@ -13477,106 +12998,94 @@ const LinearApolloSixFrameDisplay = observer(function LinearApolloSixFrameDispla
13477
12998
  setContextCoord(coord);
13478
12999
  setContextMenuItems(getContextMenuItems(event));
13479
13000
  }
13480
- } },
13481
- session.isLocked ? (React.createElement("div", { className: classes.locked, "data-testid": "lock-icon" },
13482
- React.createElement(LockIcon, null))) : null,
13483
- message ? (React.createElement(Alert, { severity: "warning", classes: { message: classes.ellipses }, slotProps: { root: { className: classes.center } } },
13484
- React.createElement(Tooltip, { title: message },
13485
- React.createElement("div", null, message)))) : (
13486
- // Promise.resolve() in these 3 callbacks is to avoid infinite rendering loop
13487
- // https://github.com/mobxjs/mobx/issues/3728#issuecomment-1715400931
13488
- React.createElement(React.Fragment, null,
13489
- React.createElement(TrackLines, { model: model, idx: 0 }),
13490
- React.createElement(TrackLines, { model: model, hrStyle: { margin: 0, top: 0, color: 'grey', opacity: 0.4 }, idx: 1 }),
13491
- React.createElement(TrackLines, { model: model, idx: 2 }),
13492
- React.createElement("canvas", { ref: async (node) => {
13493
- await Promise.resolve();
13494
- setCollaboratorCanvas(node);
13495
- }, width: lgv.dynamicBlocks.totalWidthPx, height: featuresHeight, className: classes.canvas, "data-testid": "collaboratorCanvas" }),
13496
- React.createElement("canvas", { ref: async (node) => {
13497
- await Promise.resolve();
13498
- setCanvas(node);
13499
- }, width: lgv.dynamicBlocks.totalWidthPx, height: featuresHeight, className: classes.canvas, "data-testid": "canvas" }),
13500
- React.createElement("canvas", { ref: async (node) => {
13501
- await Promise.resolve();
13502
- setOverlayCanvas(node);
13503
- }, width: lgv.dynamicBlocks.totalWidthPx, height: featuresHeight, onMouseMove: onMouseMove, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, className: classes.canvas, style: { cursor: cursor ?? 'default' }, "data-testid": "overlayCanvas" }),
13504
- lgv.displayedRegions.flatMap((region, idx) => {
13505
- const widthBp = lgv.bpPerPx * apolloRowHeight;
13506
- const assembly = assemblyManager.get(region.assemblyName);
13507
- if (showCheckResults) {
13508
- const filteredCheckResults = [
13509
- ...session.apolloDataStore.checkResults.values(),
13510
- ].filter((checkResult) => assembly?.isValidRefName(checkResult.refSeq) &&
13511
- assembly.getCanonicalRefName(checkResult.refSeq) ===
13512
- region.refName &&
13513
- doesIntersect2(region.start, region.end, checkResult.start, checkResult.end));
13514
- const checkResults = clusterResultByMessage(filteredCheckResults, widthBp, true);
13515
- return checkResults.map((checkResult) => {
13516
- const left = (lgv.bpToPx({
13517
- refName: region.refName,
13518
- coord: checkResult.start,
13519
- regionNumber: idx,
13520
- })?.offsetPx ?? 0) - lgv.offsetPx;
13521
- const [feature] = checkResult.featureIds;
13522
- if (!feature || !feature.parent?.looksLikeGene) {
13523
- return null;
13524
- }
13525
- let row;
13526
- for (const loc of feature.cdsLocations) {
13527
- for (const cds of loc) {
13528
- let rowNum = getFrame(cds.min, cds.max, feature.strand ?? 1, cds.phase);
13529
- rowNum = featureLabelSpacer(rowNum < 0 ? -1 * rowNum + 5 : rowNum);
13530
- if (checkResult.start >= cds.min &&
13531
- checkResult.start <= cds.max) {
13001
+ }, children: [session.isLocked ? (jsx("div", { className: classes.locked, "data-testid": "lock-icon", children: jsx(LockIcon, {}) })) : null, message ? (jsx(Alert, { severity: "warning", classes: { message: classes.ellipses }, slotProps: { root: { className: classes.center } }, children: jsx(Tooltip, { title: message, children: jsx("div", { children: message }) }) })) : (
13002
+ // Promise.resolve() in these 3 callbacks is to avoid infinite rendering loop
13003
+ // https://github.com/mobxjs/mobx/issues/3728#issuecomment-1715400931
13004
+ jsxs(Fragment, { children: [jsx(TrackLines, { model: model, idx: 0 }), jsx(TrackLines, { model: model, hrStyle: { margin: 0, top: 0, color: 'grey', opacity: 0.4 }, idx: 1 }), jsx(TrackLines, { model: model, idx: 2 }), jsx("canvas", { ref: async (node) => {
13005
+ await Promise.resolve();
13006
+ setCollaboratorCanvas(node);
13007
+ }, width: lgv.dynamicBlocks.totalWidthPx, height: featuresHeight, className: classes.canvas, "data-testid": "collaboratorCanvas" }), jsx("canvas", { ref: async (node) => {
13008
+ await Promise.resolve();
13009
+ setCanvas(node);
13010
+ }, width: lgv.dynamicBlocks.totalWidthPx, height: featuresHeight, className: classes.canvas, "data-testid": "canvas" }), jsx("canvas", { ref: async (node) => {
13011
+ await Promise.resolve();
13012
+ setOverlayCanvas(node);
13013
+ }, width: lgv.dynamicBlocks.totalWidthPx, height: featuresHeight, onMouseMove: onMouseMove, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, className: classes.canvas, style: { cursor: cursor ?? 'default' }, "data-testid": "overlayCanvas" }), lgv.displayedRegions.flatMap((region, idx) => {
13014
+ const widthBp = lgv.bpPerPx * apolloRowHeight;
13015
+ const assembly = assemblyManager.get(region.assemblyName);
13016
+ if (showCheckResults) {
13017
+ const filteredCheckResults = [
13018
+ ...session.apolloDataStore.checkResults.values(),
13019
+ ].filter((checkResult) => assembly?.isValidRefName(checkResult.refSeq) &&
13020
+ assembly.getCanonicalRefName(checkResult.refSeq) ===
13021
+ region.refName &&
13022
+ doesIntersect2(region.start, region.end, checkResult.start, checkResult.end));
13023
+ const checkResults = clusterResultByMessage(filteredCheckResults, widthBp);
13024
+ return checkResults.map((checkResult) => {
13025
+ const left = (lgv.bpToPx({
13026
+ refName: region.refName,
13027
+ coord: checkResult.start,
13028
+ regionNumber: idx,
13029
+ })?.offsetPx ?? 0) - lgv.offsetPx;
13030
+ const [feature] = checkResult.featureIds;
13031
+ if (!feature || !feature.parent?.looksLikeGene) {
13032
+ return null;
13033
+ }
13034
+ let row;
13035
+ for (const loc of feature.cdsLocations) {
13036
+ for (const cds of loc) {
13037
+ const frame = getFrame(cds.min, cds.max, feature.strand ?? 1, cds.phase);
13038
+ const frameOffsets = showFeatureLabels
13039
+ ? [0, 5, 3, 1, 15, 13, 11]
13040
+ : [0, 2, 1, 0, 8, 7, 6];
13041
+ const rowNum = frameOffsets.at(frame);
13042
+ if (!rowNum) {
13043
+ continue;
13044
+ }
13045
+ if (checkResult.start >= cds.min &&
13046
+ checkResult.start <= cds.max) {
13047
+ row = rowNum - 1;
13048
+ break;
13049
+ }
13050
+ }
13051
+ }
13052
+ if (row === undefined) {
13053
+ const rowNum = feature.strand == 1
13054
+ ? geneTrackRowNums[0]
13055
+ : geneTrackRowNums[1];
13532
13056
  row = rowNum - 1;
13533
- break;
13534
13057
  }
13535
- }
13536
- }
13537
- if (row === undefined) {
13538
- const rowNum = feature.strand == 1
13539
- ? geneTrackRowNums[0]
13540
- : geneTrackRowNums[1];
13541
- row = rowNum - 1;
13058
+ const top = row * apolloRowHeight;
13059
+ const height = apolloRowHeight;
13060
+ return (jsx(Tooltip, { title: checkResult.message, children: jsx(Box, { className: classes.box, style: {
13061
+ top,
13062
+ left,
13063
+ height,
13064
+ width: height,
13065
+ pointerEvents: apolloDragging ? 'none' : 'auto',
13066
+ }, children: jsx(Badge, { className: classes.badge, badgeContent: checkResult.count, color: "primary", overlap: "circular", anchorOrigin: {
13067
+ vertical: 'bottom',
13068
+ horizontal: 'right',
13069
+ }, invisible: checkResult.count <= 1, children: jsx(Avatar, { className: classes.avatar, children: jsx(ErrorIcon, { "data-testid": `ErrorIcon-${checkResult.start}` }) }) }) }) }, checkResult._id));
13070
+ });
13542
13071
  }
13543
- const top = row * apolloRowHeight;
13544
- const height = apolloRowHeight;
13545
- return (React.createElement(Tooltip, { key: checkResult._id, title: checkResult.message },
13546
- React.createElement(Box, { className: classes.box, style: {
13547
- top,
13548
- left,
13549
- height,
13550
- width: height,
13551
- pointerEvents: apolloDragging ? 'none' : 'auto',
13552
- } },
13553
- React.createElement(Badge, { className: classes.badge, badgeContent: checkResult.count, color: "primary", overlap: "circular", anchorOrigin: {
13554
- vertical: 'bottom',
13555
- horizontal: 'right',
13556
- }, invisible: checkResult.count <= 1 },
13557
- React.createElement(Avatar, { className: classes.avatar },
13558
- React.createElement(ErrorIcon, { "data-testid": `ErrorIcon-${checkResult.start}` }))))));
13559
- });
13560
- }
13561
- return null;
13562
- }),
13563
- React.createElement(Menu$1, { open: contextMenuItems.length > 0, onMenuItemClick: (_, callback) => {
13564
- callback();
13565
- setContextMenuItems([]);
13566
- }, onClose: () => {
13567
- setContextMenuItems([]);
13568
- }, slotProps: {
13569
- transition: {
13570
- onExit: () => {
13072
+ return null;
13073
+ }), jsx(Menu$1, { open: contextMenuItems.length > 0, onMenuItemClick: (_, callback) => {
13074
+ callback();
13571
13075
  setContextMenuItems([]);
13572
- },
13573
- },
13574
- }, anchorReference: "anchorPosition", anchorPosition: contextCoord
13575
- ? { top: contextCoord[1], left: contextCoord[0] }
13576
- : undefined, style: { zIndex: theme.zIndex.tooltip }, menuItems: contextMenuItems }))))));
13076
+ }, onClose: () => {
13077
+ setContextMenuItems([]);
13078
+ }, slotProps: {
13079
+ transition: {
13080
+ onExit: () => {
13081
+ setContextMenuItems([]);
13082
+ },
13083
+ },
13084
+ }, anchorReference: "anchorPosition", anchorPosition: contextCoord
13085
+ ? { top: contextCoord[1], left: contextCoord[0] }
13086
+ : undefined, style: { zIndex: theme.zIndex.tooltip }, menuItems: contextMenuItems })] }))] }) }));
13577
13087
  });
13578
13088
 
13579
- /* eslint-disable @typescript-eslint/unbound-method */
13580
13089
  const accordionControlHeight = 12;
13581
13090
  const useStyles = makeStyles()((theme) => ({
13582
13091
  shading: {
@@ -13640,12 +13149,12 @@ const ResizeHandle = ({ onResize, }) => {
13640
13149
  return (
13641
13150
  // TODO: a11y
13642
13151
  // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
13643
- React.createElement("div", { onMouseDown: (event) => {
13152
+ jsx("div", { onMouseDown: (event) => {
13644
13153
  event.stopPropagation();
13645
13154
  const controller = new AbortController();
13646
13155
  const { signal } = controller;
13647
13156
  function abortDrag() {
13648
- controller.abort('makeDisplayComponent');
13157
+ controller.abort(new DOMException('Canceling drag event listener', 'AbortError'));
13649
13158
  }
13650
13159
  globalThis.addEventListener('mousemove', mouseMove, { signal });
13651
13160
  globalThis.addEventListener('mouseup', abortDrag, { signal });
@@ -13657,11 +13166,7 @@ const ResizeHandle = ({ onResize, }) => {
13657
13166
  };
13658
13167
  const AccordionControl = observer(function AccordionControl({ onClick, onResize, open, title, }) {
13659
13168
  const { classes } = useStyles();
13660
- return (React.createElement("div", { className: classes.accordionRoot },
13661
- open && onResize ? React.createElement(ResizeHandle, { onResize: onResize }) : null,
13662
- React.createElement("div", { className: classes.accordionControl, onClick: onClick },
13663
- open ? (React.createElement(ExpandLessIcon, { className: classes.expandIcon })) : (React.createElement(ExpandMoreIcon, { className: classes.expandIcon })),
13664
- title ? (React.createElement(Typography, { className: classes.title, variant: "caption", component: "span" }, title)) : null)));
13169
+ return (jsxs("div", { className: classes.accordionRoot, children: [open && onResize ? jsx(ResizeHandle, { onResize: onResize }) : null, jsxs("div", { className: classes.accordionControl, onClick: onClick, children: [open ? (jsx(ExpandLessIcon, { className: classes.expandIcon })) : (jsx(ExpandMoreIcon, { className: classes.expandIcon })), title ? (jsx(Typography, { className: classes.title, variant: "caption", component: "span", children: title })) : null] })] }));
13665
13170
  });
13666
13171
  const LinearApolloDisplayComponent = observer(function DisplayComponent({ model, ...other }) {
13667
13172
  const session = getSession(model);
@@ -13678,28 +13183,19 @@ const LinearApolloDisplayComponent = observer(function DisplayComponent({ model,
13678
13183
  model.setDetailsHeight(model.detailsHeight - delta);
13679
13184
  };
13680
13185
  if (!ontologyStore) {
13681
- return (React.createElement("div", { className: classes.alertContainer },
13682
- React.createElement(Alert, { severity: "error" }, "Could not load feature type ontology.")));
13186
+ return (jsx("div", { className: classes.alertContainer, children: jsx(Alert, { severity: "error", children: "Could not load feature type ontology." }) }));
13683
13187
  }
13684
13188
  if (graphical && table) {
13685
13189
  const tabularHeight = tabularEditor.isShown ? model.detailsHeight : 0;
13686
13190
  const featureAreaHeight = isShown
13687
13191
  ? overallHeight - model.detailsHeight - accordionControlHeight * 2
13688
13192
  : 0;
13689
- return (React.createElement("div", { style: { height: overallHeight } },
13690
- React.createElement(AccordionControl, { open: isShown, title: "Graphical", onClick: toggleShown }),
13691
- React.createElement("div", { className: classes.shading, ref: canvasScrollContainerRef, style: { height: featureAreaHeight } },
13692
- React.createElement(LinearApolloDisplay, { model: model, ...other })),
13693
- React.createElement(AccordionControl, { title: "Table", open: tabularEditor.isShown, onClick: tabularEditor.togglePane, onResize: onDetailsResize }),
13694
- React.createElement("div", { className: classes.details, style: { height: tabularHeight } },
13695
- React.createElement(TabularEditorPane, { model: model }))));
13193
+ return (jsxs("div", { style: { height: overallHeight }, children: [jsx(AccordionControl, { open: isShown, title: "Graphical", onClick: toggleShown }), jsx("div", { className: classes.shading, ref: canvasScrollContainerRef, style: { height: featureAreaHeight }, children: jsx(LinearApolloDisplay, { model: model, ...other }) }), jsx(AccordionControl, { title: "Table", open: tabularEditor.isShown, onClick: tabularEditor.togglePane, onResize: onDetailsResize }), jsx("div", { className: classes.details, style: { height: tabularHeight }, children: jsx(TabularEditorPane, { model: model }) })] }));
13696
13194
  }
13697
13195
  if (graphical) {
13698
- return (React.createElement("div", { className: classes.shading, ref: canvasScrollContainerRef, style: { height: overallHeight } },
13699
- React.createElement(LinearApolloDisplay, { model: model, ...other })));
13196
+ return (jsx("div", { className: classes.shading, ref: canvasScrollContainerRef, style: { height: overallHeight }, children: jsx(LinearApolloDisplay, { model: model, ...other }) }));
13700
13197
  }
13701
- return (React.createElement("div", { className: classes.details, style: { height: overallHeight } },
13702
- React.createElement(TabularEditorPane, { model: model })));
13198
+ return (jsx("div", { className: classes.details, style: { height: overallHeight }, children: jsx(TabularEditorPane, { model: model }) }));
13703
13199
  });
13704
13200
  const LinearApolloSixFrameDisplayComponent = observer(function DisplayComponent({ model, ...other }) {
13705
13201
  const session = getSession(model);
@@ -13716,28 +13212,19 @@ const LinearApolloSixFrameDisplayComponent = observer(function DisplayComponent(
13716
13212
  model.setDetailsHeight(detailsHeight - delta);
13717
13213
  };
13718
13214
  if (!ontologyStore) {
13719
- return (React.createElement("div", { className: classes.alertContainer },
13720
- React.createElement(Alert, { severity: "error" }, "Could not load feature type ontology.")));
13215
+ return (jsx("div", { className: classes.alertContainer, children: jsx(Alert, { severity: "error", children: "Could not load feature type ontology." }) }));
13721
13216
  }
13722
13217
  if (graphical && table) {
13723
13218
  const tabularHeight = tabularEditor.isShown ? detailsHeight : 0;
13724
13219
  const featureAreaHeight = isShown
13725
13220
  ? overallHeight - detailsHeight - accordionControlHeight * 2
13726
13221
  : 0;
13727
- return (React.createElement("div", { style: { height: overallHeight } },
13728
- React.createElement(AccordionControl, { open: isShown, title: "Graphical", onClick: toggleShown }),
13729
- React.createElement("div", { className: classes.shading, ref: canvasScrollContainerRef, style: { height: featureAreaHeight } },
13730
- React.createElement(LinearApolloSixFrameDisplay, { model: model, ...other })),
13731
- React.createElement(AccordionControl, { title: "Table", open: tabularEditor.isShown, onClick: tabularEditor.togglePane, onResize: onDetailsResize }),
13732
- React.createElement("div", { className: classes.details, style: { height: tabularHeight } },
13733
- React.createElement(TabularEditorPane, { model: model }))));
13222
+ return (jsxs("div", { style: { height: overallHeight }, children: [jsx(AccordionControl, { open: isShown, title: "Graphical", onClick: toggleShown }), jsx("div", { className: classes.shading, ref: canvasScrollContainerRef, style: { height: featureAreaHeight }, children: jsx(LinearApolloSixFrameDisplay, { model: model, ...other }) }), jsx(AccordionControl, { title: "Table", open: tabularEditor.isShown, onClick: tabularEditor.togglePane, onResize: onDetailsResize }), jsx("div", { className: classes.details, style: { height: tabularHeight }, children: jsx(TabularEditorPane, { model: model }) })] }));
13734
13223
  }
13735
13224
  if (graphical) {
13736
- return (React.createElement("div", { className: classes.shading, ref: canvasScrollContainerRef, style: { height: overallHeight } },
13737
- React.createElement(LinearApolloSixFrameDisplay, { model: model, ...other })));
13225
+ return (jsx("div", { className: classes.shading, ref: canvasScrollContainerRef, style: { height: overallHeight }, children: jsx(LinearApolloSixFrameDisplay, { model: model, ...other }) }));
13738
13226
  }
13739
- return (React.createElement("div", { className: classes.details, style: { height: overallHeight } },
13740
- React.createElement(TabularEditorPane, { model: model })));
13227
+ return (jsx("div", { className: classes.details, style: { height: overallHeight }, children: jsx(TabularEditorPane, { model: model }) }));
13741
13228
  });
13742
13229
 
13743
13230
  function addTopLevelMenus(rootModel) {
@@ -13842,6 +13329,7 @@ function addTopLevelMenus(rootModel) {
13842
13329
  }
13843
13330
 
13844
13331
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
13332
+ /* eslint-disable @typescript-eslint/no-confusing-void-expression */
13845
13333
  const ApolloJobModel = types
13846
13334
  .model('JobsManager', {})
13847
13335
  .views((self) => ({
@@ -14049,7 +13537,7 @@ function clientDataStoreFactory(AnnotationFeatureExtended) {
14049
13537
  statusMessage: `Loading ontology "${name}", version "${version}", this may take a while`,
14050
13538
  progressPct: 0,
14051
13539
  cancelCallback: () => {
14052
- controller.abort('ClientDataStore');
13540
+ controller.abort(new DOMException(`Canceling loading of ontology "${name}"`, 'AbortError'));
14053
13541
  jobsManager.abortJob(job.name);
14054
13542
  },
14055
13543
  };
@@ -14305,6 +13793,12 @@ function extendSession(pluginManager, sessionModel) {
14305
13793
  }
14306
13794
  }
14307
13795
  },
13796
+ }))
13797
+ .actions((self) => ({
13798
+ apolloSetEventualSelectedFeature: flow$1(function* apolloSetEventualSelectedFeature(featureId) {
13799
+ yield when(() => Boolean(self.apolloDataStore.getFeature(featureId)));
13800
+ self.apolloSetSelectedFeature(featureId);
13801
+ }),
14308
13802
  }))
14309
13803
  .volatile((self) => ({
14310
13804
  previousSnapshot: getSnapshot(self),
@@ -14410,6 +13904,10 @@ function extendSession(pluginManager, sessionModel) {
14410
13904
  console.error(error);
14411
13905
  continue;
14412
13906
  }
13907
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
13908
+ if (!jbrowseConfig.configuration.ApolloPlugin.hasRole) {
13909
+ continue;
13910
+ }
14413
13911
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call
14414
13912
  reloadPluginManagerCallback(jbrowseConfig, self.previousSnapshot);
14415
13913
  reaction.dispose();
@@ -14417,7 +13915,7 @@ function extendSession(pluginManager, sessionModel) {
14417
13915
  }, { name: 'ApolloSessionLoadConfig' }));
14418
13916
  },
14419
13917
  beforeDestroy() {
14420
- self.abortController.abort('destroying session model');
13918
+ self.abortController.abort(new DOMException('Clean up Apollo session', 'AbortError'));
14421
13919
  },
14422
13920
  }))
14423
13921
  .views((self) => {
@@ -14459,6 +13957,7 @@ function extendSession(pluginManager, sessionModel) {
14459
13957
  oldJBrowseConfig: filteredConfig,
14460
13958
  newJBrowseConfig: {
14461
13959
  ...filteredConfig,
13960
+ // @ts-expect-error The track types are in the snapshot
14462
13961
  tracks: filteredConfig?.tracks && [
14463
13962
  ...filteredConfig.tracks,
14464
13963
  newTrackConfigSnapshot,
@@ -14554,6 +14053,9 @@ function extendSession(pluginManager, sessionModel) {
14554
14053
  }
14555
14054
 
14556
14055
  /* eslint-disable @typescript-eslint/unbound-method */
14056
+ /* eslint-disable @typescript-eslint/no-unnecessary-condition */
14057
+ /* eslint-disable @typescript-eslint/no-misused-promises */
14058
+ /* eslint-disable @typescript-eslint/no-explicit-any */
14557
14059
  function isApolloMessageData(data) {
14558
14060
  return (typeof data === 'object' &&
14559
14061
  data !== null &&
@@ -14695,6 +14197,17 @@ class ApolloPlugin extends Plugin {
14695
14197
  });
14696
14198
  pluginManager.addToExtensionPoint('Core-extendPluggableElement', annotationFromPileup);
14697
14199
  pluginManager.addToExtensionPoint('Core-extendPluggableElement', annotationFromJBrowseFeature);
14200
+ pluginManager.addToExtensionPoint('LinearGenomeView-searchResultSelected', (_, props) => {
14201
+ const { session, result } = props;
14202
+ const trackId = result.getTrackId();
14203
+ const matchedFeature = result.matchedObject;
14204
+ if (trackId?.startsWith('apollo_track_') && matchedFeature) {
14205
+ const geneFeature = matchedFeature;
14206
+ void session.apolloSetEventualSelectedFeature(geneFeature._id);
14207
+ }
14208
+ /* eslint-disable-next-line @typescript-eslint/no-unsafe-return */
14209
+ return _;
14210
+ });
14698
14211
  if (!inWebWorker) {
14699
14212
  pluginManager.addToExtensionPoint('Core-extendWorker', (handle) => {
14700
14213
  if (!('on' in handle && handle.on)) {