@apollo-annotation/jbrowse-plugin-apollo 0.3.11 → 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.
- package/dist/ApolloInternetAccount/components/AuthTypeSelector.d.ts +6 -0
- package/dist/ApolloInternetAccount/components/AuthTypeSelector.d.ts.map +1 -0
- package/dist/ApolloInternetAccount/components/LoginButtons.d.ts +5 -0
- package/dist/ApolloInternetAccount/components/LoginButtons.d.ts.map +1 -0
- package/dist/ApolloInternetAccount/components/LoginIcons.d.ts +4 -0
- package/dist/ApolloInternetAccount/components/LoginIcons.d.ts.map +1 -0
- package/dist/ApolloInternetAccount/index.d.ts +3 -0
- package/dist/ApolloInternetAccount/index.d.ts.map +1 -0
- package/dist/ApolloJobModel.d.ts +53 -0
- package/dist/ApolloJobModel.d.ts.map +1 -0
- package/dist/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.d.ts +12 -0
- package/dist/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.d.ts.map +1 -0
- package/dist/ApolloRefNameAliasAdapter/index.d.ts +3 -0
- package/dist/ApolloRefNameAliasAdapter/index.d.ts.map +1 -0
- package/dist/ApolloSequenceAdapter/ApolloSequenceAdapter.d.ts +27 -0
- package/dist/ApolloSequenceAdapter/ApolloSequenceAdapter.d.ts.map +1 -0
- package/dist/ApolloSequenceAdapter/index.d.ts +3 -0
- package/dist/ApolloSequenceAdapter/index.d.ts.map +1 -0
- package/dist/ApolloTextSearchAdapter/ApolloTextSearchAdapter.d.ts +13 -0
- package/dist/ApolloTextSearchAdapter/ApolloTextSearchAdapter.d.ts.map +1 -0
- package/dist/ApolloTextSearchAdapter/index.d.ts +3 -0
- package/dist/ApolloTextSearchAdapter/index.d.ts.map +1 -0
- package/dist/BackendDrivers/BackendDriver.d.ts +26 -0
- package/dist/BackendDrivers/BackendDriver.d.ts.map +1 -0
- package/dist/BackendDrivers/CollaborationServerDriver.d.ts +206 -0
- package/dist/BackendDrivers/CollaborationServerDriver.d.ts.map +1 -0
- package/dist/BackendDrivers/DesktopFileDriver.d.ts +160 -0
- package/dist/BackendDrivers/DesktopFileDriver.d.ts.map +1 -0
- package/dist/BackendDrivers/InMemoryFileDriver.d.ts +162 -0
- package/dist/BackendDrivers/InMemoryFileDriver.d.ts.map +1 -0
- package/dist/BackendDrivers/index.d.ts +5 -0
- package/dist/BackendDrivers/index.d.ts.map +1 -0
- package/dist/ChangeManager.d.ts +24 -0
- package/dist/ChangeManager.d.ts.map +1 -0
- package/dist/FeatureDetailsWidget/ApolloFeatureDetailsWidget.d.ts +6 -0
- package/dist/FeatureDetailsWidget/ApolloFeatureDetailsWidget.d.ts.map +1 -0
- package/dist/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.d.ts +12 -0
- package/dist/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.d.ts.map +1 -0
- package/dist/FeatureDetailsWidget/AttributeKey.d.ts +4 -0
- package/dist/FeatureDetailsWidget/AttributeKey.d.ts.map +1 -0
- package/dist/FeatureDetailsWidget/AttributeKeySelector.d.ts +6 -0
- package/dist/FeatureDetailsWidget/AttributeKeySelector.d.ts.map +1 -0
- package/dist/FeatureDetailsWidget/Attributes.d.ts +9 -0
- package/dist/FeatureDetailsWidget/Attributes.d.ts.map +1 -0
- package/dist/FeatureDetailsWidget/BasicInformation.d.ts +8 -0
- package/dist/FeatureDetailsWidget/BasicInformation.d.ts.map +1 -0
- package/dist/FeatureDetailsWidget/DefaultAttributeEditor.d.ts +9 -0
- package/dist/FeatureDetailsWidget/DefaultAttributeEditor.d.ts.map +1 -0
- package/dist/FeatureDetailsWidget/DefaultAttributeViewer.d.ts +5 -0
- package/dist/FeatureDetailsWidget/DefaultAttributeViewer.d.ts.map +1 -0
- package/dist/FeatureDetailsWidget/FeatureDetailsNavigation.d.ts +7 -0
- package/dist/FeatureDetailsWidget/FeatureDetailsNavigation.d.ts.map +1 -0
- package/dist/FeatureDetailsWidget/NumberTextField.d.ts +8 -0
- package/dist/FeatureDetailsWidget/NumberTextField.d.ts.map +1 -0
- package/dist/FeatureDetailsWidget/Sequence.d.ts +10 -0
- package/dist/FeatureDetailsWidget/Sequence.d.ts.map +1 -0
- package/dist/FeatureDetailsWidget/StringTextField.d.ts +8 -0
- package/dist/FeatureDetailsWidget/StringTextField.d.ts.map +1 -0
- package/dist/FeatureDetailsWidget/TranscriptSequence.d.ts +10 -0
- package/dist/FeatureDetailsWidget/TranscriptSequence.d.ts.map +1 -0
- package/dist/FeatureDetailsWidget/TranscriptWidgetEditLocation.d.ts +9 -0
- package/dist/FeatureDetailsWidget/TranscriptWidgetEditLocation.d.ts.map +1 -0
- package/dist/FeatureDetailsWidget/TranscriptWidgetSummary.d.ts +6 -0
- package/dist/FeatureDetailsWidget/TranscriptWidgetSummary.d.ts.map +1 -0
- package/dist/FeatureDetailsWidget/index.d.ts +5 -0
- package/dist/FeatureDetailsWidget/index.d.ts.map +1 -0
- package/dist/FeatureDetailsWidget/model.d.ts +123 -0
- package/dist/FeatureDetailsWidget/model.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/components/CheckResultWarnings.d.ts +5 -0
- package/dist/LinearApolloDisplay/components/CheckResultWarnings.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/components/LinearApolloDisplay.d.ts +7 -0
- package/dist/LinearApolloDisplay/components/LinearApolloDisplay.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/components/index.d.ts +2 -0
- package/dist/LinearApolloDisplay/components/index.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/glyphs/BoxGlyph.d.ts +4 -0
- package/dist/LinearApolloDisplay/glyphs/BoxGlyph.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/glyphs/GeneGlyph.d.ts +3 -0
- package/dist/LinearApolloDisplay/glyphs/GeneGlyph.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/glyphs/GenericChildGlyph.d.ts +3 -0
- package/dist/LinearApolloDisplay/glyphs/GenericChildGlyph.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/glyphs/Glyph.d.ts +26 -0
- package/dist/LinearApolloDisplay/glyphs/Glyph.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/glyphs/index.d.ts +4 -0
- package/dist/LinearApolloDisplay/glyphs/index.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/glyphs/util.d.ts +12 -0
- package/dist/LinearApolloDisplay/glyphs/util.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/index.d.ts +3 -0
- package/dist/LinearApolloDisplay/index.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/stateModel/base.d.ts +254 -0
- package/dist/LinearApolloDisplay/stateModel/base.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/stateModel/index.d.ts +349 -0
- package/dist/LinearApolloDisplay/stateModel/index.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/stateModel/layouts.d.ts +273 -0
- package/dist/LinearApolloDisplay/stateModel/layouts.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/stateModel/mouseEvents.d.ts +656 -0
- package/dist/LinearApolloDisplay/stateModel/mouseEvents.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/stateModel/rendering.d.ts +300 -0
- package/dist/LinearApolloDisplay/stateModel/rendering.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/types.d.ts +2 -0
- package/dist/LinearApolloDisplay/types.d.ts.map +1 -0
- package/dist/LinearApolloReferenceSequenceDisplay/components/LinearApolloReferenceSequenceDisplay.d.ts +7 -0
- package/dist/LinearApolloReferenceSequenceDisplay/components/LinearApolloReferenceSequenceDisplay.d.ts.map +1 -0
- package/dist/LinearApolloReferenceSequenceDisplay/components/index.d.ts +2 -0
- package/dist/LinearApolloReferenceSequenceDisplay/components/index.d.ts.map +1 -0
- package/dist/LinearApolloReferenceSequenceDisplay/drawSequenceOverlay.d.ts +6 -0
- package/dist/LinearApolloReferenceSequenceDisplay/drawSequenceOverlay.d.ts.map +1 -0
- package/dist/LinearApolloReferenceSequenceDisplay/drawSequenceTrack.d.ts +5 -0
- package/dist/LinearApolloReferenceSequenceDisplay/drawSequenceTrack.d.ts.map +1 -0
- package/dist/LinearApolloReferenceSequenceDisplay/index.d.ts +4 -0
- package/dist/LinearApolloReferenceSequenceDisplay/index.d.ts.map +1 -0
- package/dist/LinearApolloReferenceSequenceDisplay/stateModel/base.d.ts +236 -0
- package/dist/LinearApolloReferenceSequenceDisplay/stateModel/base.d.ts.map +1 -0
- package/dist/LinearApolloReferenceSequenceDisplay/stateModel/index.d.ts +245 -0
- package/dist/LinearApolloReferenceSequenceDisplay/stateModel/index.d.ts.map +1 -0
- package/dist/LinearApolloReferenceSequenceDisplay/stateModel/rendering.d.ts +246 -0
- package/dist/LinearApolloReferenceSequenceDisplay/stateModel/rendering.d.ts.map +1 -0
- package/dist/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.d.ts +7 -0
- package/dist/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.d.ts.map +1 -0
- package/dist/LinearApolloSixFrameDisplay/components/TrackLines.d.ts +8 -0
- package/dist/LinearApolloSixFrameDisplay/components/TrackLines.d.ts.map +1 -0
- package/dist/LinearApolloSixFrameDisplay/components/index.d.ts +3 -0
- package/dist/LinearApolloSixFrameDisplay/components/index.d.ts.map +1 -0
- package/dist/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.d.ts +3 -0
- package/dist/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.d.ts.map +1 -0
- package/dist/LinearApolloSixFrameDisplay/glyphs/Glyph.d.ts +20 -0
- package/dist/LinearApolloSixFrameDisplay/glyphs/Glyph.d.ts.map +1 -0
- package/dist/LinearApolloSixFrameDisplay/glyphs/index.d.ts +2 -0
- package/dist/LinearApolloSixFrameDisplay/glyphs/index.d.ts.map +1 -0
- package/dist/LinearApolloSixFrameDisplay/index.d.ts +3 -0
- package/dist/LinearApolloSixFrameDisplay/index.d.ts.map +1 -0
- package/dist/LinearApolloSixFrameDisplay/stateModel/base.d.ts +257 -0
- package/dist/LinearApolloSixFrameDisplay/stateModel/base.d.ts.map +1 -0
- package/dist/LinearApolloSixFrameDisplay/stateModel/index.d.ts +355 -0
- package/dist/LinearApolloSixFrameDisplay/stateModel/index.d.ts.map +1 -0
- package/dist/LinearApolloSixFrameDisplay/stateModel/layouts.d.ts +283 -0
- package/dist/LinearApolloSixFrameDisplay/stateModel/layouts.d.ts.map +1 -0
- package/dist/LinearApolloSixFrameDisplay/stateModel/mouseEvents.d.ts +668 -0
- package/dist/LinearApolloSixFrameDisplay/stateModel/mouseEvents.d.ts.map +1 -0
- package/dist/LinearApolloSixFrameDisplay/stateModel/rendering.d.ts +306 -0
- package/dist/LinearApolloSixFrameDisplay/stateModel/rendering.d.ts.map +1 -0
- package/dist/LinearApolloSixFrameDisplay/types.d.ts +2 -0
- package/dist/LinearApolloSixFrameDisplay/types.d.ts.map +1 -0
- package/dist/OntologyManager/OntologyStore/fulltext-stopwords.d.ts +8 -0
- package/dist/OntologyManager/OntologyStore/fulltext-stopwords.d.ts.map +1 -0
- package/dist/OntologyManager/OntologyStore/fulltext.d.ts +27 -0
- package/dist/OntologyManager/OntologyStore/fulltext.d.ts.map +1 -0
- package/dist/OntologyManager/OntologyStore/index.d.ts +93 -0
- package/dist/OntologyManager/OntologyStore/index.d.ts.map +1 -0
- package/dist/OntologyManager/OntologyStore/indexeddb-schema.d.ts +71 -0
- package/dist/OntologyManager/OntologyStore/indexeddb-schema.d.ts.map +1 -0
- package/dist/OntologyManager/OntologyStore/indexeddb-storage.d.ts +11 -0
- package/dist/OntologyManager/OntologyStore/indexeddb-storage.d.ts.map +1 -0
- package/dist/OntologyManager/OntologyStore/obo-graph-json-schema.d.ts +107 -0
- package/dist/OntologyManager/OntologyStore/obo-graph-json-schema.d.ts.map +1 -0
- package/dist/OntologyManager/OntologyStore/prefixes.d.ts +20 -0
- package/dist/OntologyManager/OntologyStore/prefixes.d.ts.map +1 -0
- package/dist/OntologyManager/util.d.ts +4 -0
- package/dist/OntologyManager/util.d.ts.map +1 -0
- package/dist/TabularEditor/HybridGrid/ChangeHandling.d.ts +6 -0
- package/dist/TabularEditor/HybridGrid/ChangeHandling.d.ts.map +1 -0
- package/dist/TabularEditor/HybridGrid/Feature.d.ts +13 -0
- package/dist/TabularEditor/HybridGrid/Feature.d.ts.map +1 -0
- package/dist/TabularEditor/HybridGrid/FeatureAttributes.d.ts +6 -0
- package/dist/TabularEditor/HybridGrid/FeatureAttributes.d.ts.map +1 -0
- package/dist/TabularEditor/HybridGrid/Highlight.d.ts +6 -0
- package/dist/TabularEditor/HybridGrid/Highlight.d.ts.map +1 -0
- package/dist/TabularEditor/HybridGrid/HybridGrid.d.ts +14 -0
- package/dist/TabularEditor/HybridGrid/HybridGrid.d.ts.map +1 -0
- package/dist/TabularEditor/HybridGrid/NumberCell.d.ts +8 -0
- package/dist/TabularEditor/HybridGrid/NumberCell.d.ts.map +1 -0
- package/dist/TabularEditor/HybridGrid/ToolBar.d.ts +5 -0
- package/dist/TabularEditor/HybridGrid/ToolBar.d.ts.map +1 -0
- package/dist/TabularEditor/HybridGrid/featureContextMenuItems.d.ts +11 -0
- package/dist/TabularEditor/HybridGrid/featureContextMenuItems.d.ts.map +1 -0
- package/dist/TabularEditor/HybridGrid/index.d.ts +2 -0
- package/dist/TabularEditor/HybridGrid/index.d.ts.map +1 -0
- package/dist/TabularEditor/TabularEditorPane.d.ts +5 -0
- package/dist/TabularEditor/TabularEditorPane.d.ts.map +1 -0
- package/dist/TabularEditor/index.d.ts +3 -0
- package/dist/TabularEditor/index.d.ts.map +1 -0
- package/dist/TabularEditor/model.d.ts +17 -0
- package/dist/TabularEditor/model.d.ts.map +1 -0
- package/dist/TabularEditor/types.d.ts +4 -0
- package/dist/TabularEditor/types.d.ts.map +1 -0
- package/dist/components/AddAssembly.d.ts +10 -0
- package/dist/components/AddAssembly.d.ts.map +1 -0
- package/dist/components/AddAssemblyAliases.d.ts +10 -0
- package/dist/components/AddAssemblyAliases.d.ts.map +1 -0
- package/dist/components/AddChildFeature.d.ts +13 -0
- package/dist/components/AddChildFeature.d.ts.map +1 -0
- package/dist/components/AddFeature.d.ts +12 -0
- package/dist/components/AddFeature.d.ts.map +1 -0
- package/dist/components/AddRefSeqAliases.d.ts +10 -0
- package/dist/components/AddRefSeqAliases.d.ts.map +1 -0
- package/dist/components/CopyFeature.d.ts +13 -0
- package/dist/components/CopyFeature.d.ts.map +1 -0
- package/dist/components/CreateApolloAnnotation.d.ts +20 -0
- package/dist/components/CreateApolloAnnotation.d.ts.map +1 -0
- package/dist/components/DeleteAssembly.d.ts +10 -0
- package/dist/components/DeleteAssembly.d.ts.map +1 -0
- package/dist/components/DeleteFeature.d.ts +15 -0
- package/dist/components/DeleteFeature.d.ts.map +1 -0
- package/dist/components/Dialog.d.ts +7 -0
- package/dist/components/Dialog.d.ts.map +1 -0
- package/dist/components/DownloadGFF3.d.ts +8 -0
- package/dist/components/DownloadGFF3.d.ts.map +1 -0
- package/dist/components/DuplicateTranscript.d.ts +15 -0
- package/dist/components/DuplicateTranscript.d.ts.map +1 -0
- package/dist/components/EditZoomThresholdDialog.d.ts +11 -0
- package/dist/components/EditZoomThresholdDialog.d.ts.map +1 -0
- package/dist/components/FilterFeatures.d.ts +10 -0
- package/dist/components/FilterFeatures.d.ts.map +1 -0
- package/dist/components/FilterTranscripts.d.ts +10 -0
- package/dist/components/FilterTranscripts.d.ts.map +1 -0
- package/dist/components/ImportFeatures.d.ts +10 -0
- package/dist/components/ImportFeatures.d.ts.map +1 -0
- package/dist/components/LogOut.d.ts +8 -0
- package/dist/components/LogOut.d.ts.map +1 -0
- package/dist/components/ManageChecks.d.ts +8 -0
- package/dist/components/ManageChecks.d.ts.map +1 -0
- package/dist/components/ManageUsers.d.ts +10 -0
- package/dist/components/ManageUsers.d.ts.map +1 -0
- package/dist/components/MergeExons.d.ts +15 -0
- package/dist/components/MergeExons.d.ts.map +1 -0
- package/dist/components/MergeTranscripts.d.ts +15 -0
- package/dist/components/MergeTranscripts.d.ts.map +1 -0
- package/dist/components/OntologyTermAutocomplete.d.ts +25 -0
- package/dist/components/OntologyTermAutocomplete.d.ts.map +1 -0
- package/dist/components/OntologyTermMultiSelect.d.ts +12 -0
- package/dist/components/OntologyTermMultiSelect.d.ts.map +1 -0
- package/dist/components/OpenLocalFile.d.ts +15 -0
- package/dist/components/OpenLocalFile.d.ts.map +1 -0
- package/dist/components/SplitExon.d.ts +15 -0
- package/dist/components/SplitExon.d.ts.map +1 -0
- package/dist/components/ViewChangeLog.d.ts +8 -0
- package/dist/components/ViewChangeLog.d.ts.map +1 -0
- package/dist/components/ViewCheckResults.d.ts +8 -0
- package/dist/components/ViewCheckResults.d.ts.map +1 -0
- package/dist/components/index.d.ts +21 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/extensions/annotationFromJBrowseFeature.d.ts +6 -0
- package/dist/extensions/annotationFromJBrowseFeature.d.ts.map +1 -0
- package/dist/extensions/annotationFromPileup.d.ts +3 -0
- package/dist/extensions/annotationFromPileup.d.ts.map +1 -0
- package/dist/extensions/index.d.ts +3 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/index.esm.js +843 -1330
- package/dist/index.esm.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.development.js +919 -1455
- package/dist/jbrowse-plugin-apollo.cjs.development.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.production.min.js +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.production.min.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.umd.development.js +46351 -63687
- package/dist/jbrowse-plugin-apollo.umd.development.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.umd.production.min.js +1 -1
- package/dist/jbrowse-plugin-apollo.umd.production.min.js.map +1 -1
- package/dist/makeDisplayComponent.d.ts +9 -0
- package/dist/makeDisplayComponent.d.ts.map +1 -0
- package/dist/menus/index.d.ts +2 -0
- package/dist/menus/index.d.ts.map +1 -0
- package/dist/menus/topLevelMenu.d.ts +3 -0
- package/dist/menus/topLevelMenu.d.ts.map +1 -0
- package/dist/menus/topLevelMenuAdmin.d.ts +3 -0
- package/dist/menus/topLevelMenuAdmin.d.ts.map +1 -0
- package/dist/session/index.d.ts +2 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/util/annotationFeatureUtils.d.ts +7 -0
- package/dist/util/annotationFeatureUtils.d.ts.map +1 -0
- package/dist/util/copyToClipboard.d.ts +2 -0
- package/dist/util/copyToClipboard.d.ts.map +1 -0
- package/dist/util/glyphUtils.d.ts +31 -0
- package/dist/util/glyphUtils.d.ts.map +1 -0
- package/dist/util/index.d.ts +10 -0
- package/dist/util/index.d.ts.map +1 -0
- package/dist/util/loadAssemblyIntoClient.d.ts +5 -0
- package/dist/util/loadAssemblyIntoClient.d.ts.map +1 -0
- package/dist/util/mouseEventsUtils.d.ts +25 -0
- package/dist/util/mouseEventsUtils.d.ts.map +1 -0
- package/package.json +48 -25
- package/src/ApolloInternetAccount/components/AuthTypeSelector.tsx +7 -2
- package/src/ApolloInternetAccount/components/LoginButtons.tsx +1 -1
- package/src/ApolloInternetAccount/configSchema.ts +1 -1
- package/src/ApolloInternetAccount/model.ts +13 -6
- package/src/ApolloJobModel.ts +3 -3
- package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +2 -2
- package/src/ApolloSequenceAdapter/ApolloSequenceAdapter.ts +2 -2
- package/src/ApolloTextSearchAdapter/ApolloTextSearchAdapter.ts +28 -5
- package/src/BackendDrivers/BackendDriver.ts +8 -8
- package/src/BackendDrivers/CollaborationServerDriver.ts +6 -6
- package/src/BackendDrivers/DesktopFileDriver.ts +4 -4
- package/src/BackendDrivers/InMemoryFileDriver.ts +5 -8
- package/src/ChangeManager.ts +8 -3
- package/src/FeatureDetailsWidget/ApolloFeatureDetailsWidget.tsx +3 -3
- package/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx +7 -7
- package/src/FeatureDetailsWidget/AttributeKey.tsx +1 -1
- package/src/FeatureDetailsWidget/AttributeKeySelector.tsx +1 -1
- package/src/FeatureDetailsWidget/Attributes.tsx +4 -4
- package/src/FeatureDetailsWidget/BasicInformation.tsx +3 -3
- package/src/FeatureDetailsWidget/DefaultAttributeEditor.tsx +1 -1
- package/src/FeatureDetailsWidget/FeatureDetailsNavigation.tsx +2 -2
- package/src/FeatureDetailsWidget/Sequence.tsx +3 -3
- package/src/FeatureDetailsWidget/TranscriptSequence.tsx +2 -2
- package/src/FeatureDetailsWidget/TranscriptWidgetEditLocation.tsx +3 -6
- package/src/FeatureDetailsWidget/TranscriptWidgetSummary.tsx +1 -1
- package/src/FeatureDetailsWidget/model.ts +3 -3
- package/src/LinearApolloDisplay/components/CheckResultWarnings.tsx +2 -2
- package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +6 -4
- package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +7 -7
- package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +56 -30
- package/src/LinearApolloDisplay/glyphs/GenericChildGlyph.ts +6 -6
- package/src/LinearApolloDisplay/glyphs/Glyph.ts +7 -7
- package/src/LinearApolloDisplay/glyphs/util.ts +2 -2
- package/src/LinearApolloDisplay/stateModel/base.ts +17 -8
- package/src/LinearApolloDisplay/stateModel/index.ts +2 -2
- package/src/LinearApolloDisplay/stateModel/layouts.ts +4 -4
- package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +6 -6
- package/src/LinearApolloDisplay/stateModel/rendering.ts +3 -3
- package/src/LinearApolloReferenceSequenceDisplay/components/LinearApolloReferenceSequenceDisplay.tsx +4 -2
- package/src/LinearApolloReferenceSequenceDisplay/drawSequenceOverlay.ts +4 -4
- package/src/LinearApolloReferenceSequenceDisplay/drawSequenceTrack.ts +3 -3
- package/src/LinearApolloReferenceSequenceDisplay/stateModel/base.ts +11 -8
- package/src/LinearApolloReferenceSequenceDisplay/stateModel/index.ts +2 -2
- package/src/LinearApolloReferenceSequenceDisplay/stateModel/rendering.ts +2 -2
- package/src/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.tsx +17 -9
- package/src/LinearApolloSixFrameDisplay/components/TrackLines.tsx +1 -1
- package/src/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.ts +36 -23
- package/src/LinearApolloSixFrameDisplay/glyphs/Glyph.ts +6 -6
- package/src/LinearApolloSixFrameDisplay/stateModel/base.ts +17 -8
- package/src/LinearApolloSixFrameDisplay/stateModel/index.ts +2 -2
- package/src/LinearApolloSixFrameDisplay/stateModel/layouts.ts +12 -8
- package/src/LinearApolloSixFrameDisplay/stateModel/mouseEvents.ts +11 -10
- package/src/LinearApolloSixFrameDisplay/stateModel/rendering.ts +3 -3
- package/src/OntologyManager/OntologyStore/fulltext.test.ts +1 -1
- package/src/OntologyManager/OntologyStore/fulltext.ts +11 -4
- package/src/OntologyManager/OntologyStore/index.test.ts +3 -0
- package/src/OntologyManager/OntologyStore/indexeddb-schema.ts +6 -6
- package/src/OntologyManager/OntologyStore/indexeddb-storage.ts +2 -1
- package/src/OntologyManager/index.ts +4 -4
- package/src/OntologyManager/util.ts +1 -1
- package/src/TabularEditor/HybridGrid/ChangeHandling.ts +2 -2
- package/src/TabularEditor/HybridGrid/Feature.tsx +6 -6
- package/src/TabularEditor/HybridGrid/FeatureAttributes.tsx +2 -2
- package/src/TabularEditor/HybridGrid/Highlight.tsx +1 -1
- package/src/TabularEditor/HybridGrid/HybridGrid.tsx +2 -2
- package/src/TabularEditor/HybridGrid/NumberCell.tsx +1 -1
- package/src/TabularEditor/HybridGrid/ToolBar.tsx +3 -2
- package/src/TabularEditor/HybridGrid/featureContextMenuItems.ts +26 -4
- package/src/TabularEditor/TabularEditorPane.tsx +1 -1
- package/src/TabularEditor/model.ts +2 -2
- package/src/TabularEditor/types.ts +2 -2
- package/src/components/AddAssembly.tsx +61 -42
- package/src/components/AddAssemblyAliases.tsx +5 -5
- package/src/components/AddChildFeature.tsx +3 -3
- package/src/components/AddFeature.tsx +4 -4
- package/src/components/AddRefSeqAliases.tsx +7 -7
- package/src/components/CopyFeature.tsx +8 -8
- package/src/components/CreateApolloAnnotation.tsx +5 -5
- package/src/components/DeleteAssembly.tsx +8 -8
- package/src/components/DeleteFeature.tsx +4 -4
- package/src/components/Dialog.tsx +1 -1
- package/src/components/DownloadGFF3.tsx +8 -8
- package/src/components/DuplicateTranscript.tsx +132 -0
- package/src/components/FilterFeatures.tsx +1 -1
- package/src/components/FilterTranscripts.tsx +1 -1
- package/src/components/ImportFeatures.tsx +51 -33
- package/src/components/LogOut.tsx +4 -4
- package/src/components/ManageChecks.tsx +8 -8
- package/src/components/ManageUsers.tsx +18 -26
- package/src/components/MergeExons.tsx +4 -4
- package/src/components/MergeTranscripts.tsx +4 -4
- package/src/components/OntologyTermAutocomplete.tsx +14 -4
- package/src/components/OntologyTermMultiSelect.tsx +12 -5
- package/src/components/OpenLocalFile.tsx +2 -2
- package/src/components/SplitExon.tsx +6 -6
- package/src/components/ViewChangeLog.tsx +8 -8
- package/src/components/ViewCheckResults.tsx +4 -4
- package/src/components/index.ts +1 -0
- package/src/config.ts +1 -1
- package/src/extensions/annotationFromJBrowseFeature.ts +29 -24
- package/src/extensions/annotationFromPileup.ts +8 -6
- package/src/index.ts +25 -1
- package/src/makeDisplayComponent.tsx +8 -5
- package/src/menus/topLevelMenu.ts +4 -4
- package/src/menus/topLevelMenuAdmin.ts +4 -4
- package/src/session/ClientDataStore.ts +20 -15
- package/src/session/session.ts +30 -19
- package/src/types.ts +10 -4
- package/src/util/annotationFeatureUtils.ts +1 -1
- package/src/util/displayUtils.ts +3 -3
- package/src/util/glyphUtils.ts +10 -10
- package/src/util/index.ts +4 -4
- package/src/util/loadAssemblyIntoClient.ts +4 -4
- 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,
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
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,
|
|
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.
|
|
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 (
|
|
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
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
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
|
-
|
|
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 (
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
if (file
|
|
969
|
-
|
|
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
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
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 (
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
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
|
-
|
|
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('
|
|
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('
|
|
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 (
|
|
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) =>
|
|
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 (
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
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('
|
|
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 (
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
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 (
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
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 (
|
|
3394
|
-
|
|
3395
|
-
|
|
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 (
|
|
3723
|
-
|
|
3724
|
-
|
|
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 (
|
|
3843
|
-
|
|
3844
|
-
|
|
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('
|
|
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 (
|
|
4002
|
-
|
|
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 (
|
|
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 (
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
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
|
|
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
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
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
|
-
|
|
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 (
|
|
4311
|
-
|
|
4312
|
-
|
|
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 (
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
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 (
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
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 (
|
|
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 }) => (
|
|
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 (
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
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 (
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
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 (
|
|
4934
|
-
|
|
4935
|
-
|
|
4936
|
-
|
|
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 (
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
|
|
4997
|
-
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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('
|
|
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 (
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
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('
|
|
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}:${
|
|
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 (
|
|
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 (
|
|
6026
|
-
|
|
6027
|
-
|
|
6028
|
-
|
|
6029
|
-
|
|
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 (
|
|
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 (
|
|
6098
|
-
|
|
6099
|
-
|
|
6100
|
-
|
|
6101
|
-
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
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 (
|
|
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 (
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
|
|
6223
|
-
|
|
6224
|
-
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
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 (
|
|
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 (
|
|
6371
|
-
|
|
6372
|
-
|
|
6373
|
-
|
|
6374
|
-
|
|
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 (
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
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 =
|
|
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 (
|
|
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 (
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
6509
|
-
|
|
6510
|
-
|
|
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 = (
|
|
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
|
-
}
|
|
6513
|
+
}, children: printLines.join('\n') }, `${segment.type}-${index}`));
|
|
6843
6514
|
seqElements.push(span);
|
|
6844
6515
|
}
|
|
6845
6516
|
return seqElements;
|
|
6846
6517
|
}
|
|
6847
|
-
return (
|
|
6848
|
-
|
|
6849
|
-
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
|
|
6853
|
-
|
|
6854
|
-
|
|
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 (
|
|
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(
|
|
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
|
-
},
|
|
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
|
-
} },
|
|
7039
|
+
}, children: protein }, codonGenomicPos));
|
|
7383
7040
|
}
|
|
7384
7041
|
else if (['TAA', 'TAG', 'TGA'].includes(codonSeq)) {
|
|
7385
|
-
elements.push(
|
|
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
|
-
|
|
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 (
|
|
7524
|
-
|
|
7525
|
-
|
|
7526
|
-
|
|
7527
|
-
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
|
|
7532
|
-
|
|
7533
|
-
|
|
7534
|
-
|
|
7535
|
-
|
|
7536
|
-
|
|
7537
|
-
|
|
7538
|
-
|
|
7539
|
-
|
|
7540
|
-
|
|
7541
|
-
|
|
7542
|
-
|
|
7543
|
-
|
|
7544
|
-
|
|
7545
|
-
|
|
7546
|
-
|
|
7547
|
-
|
|
7548
|
-
|
|
7549
|
-
|
|
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 (
|
|
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 (
|
|
7684
|
-
|
|
7685
|
-
|
|
7686
|
-
|
|
7687
|
-
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
|
|
7691
|
-
|
|
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
|
|
7339
|
+
return jsx(Fragment, { children: text });
|
|
7775
7340
|
}
|
|
7776
7341
|
const split = text.split(highlight);
|
|
7777
7342
|
if (split.length === 1) {
|
|
7778
|
-
return
|
|
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],
|
|
7347
|
+
highlighted.push(split[i], jsx("span", { className: classes.highlighted, children: highlight }));
|
|
7783
7348
|
}
|
|
7784
|
-
return (
|
|
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
|
|
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 (
|
|
7850
|
-
|
|
7851
|
-
|
|
7852
|
-
|
|
7853
|
-
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
|
|
7857
|
-
|
|
7858
|
-
|
|
7859
|
-
|
|
7860
|
-
|
|
7861
|
-
|
|
7862
|
-
|
|
7863
|
-
|
|
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 (
|
|
8093
|
-
|
|
8094
|
-
|
|
8095
|
-
|
|
8096
|
-
|
|
8097
|
-
|
|
8098
|
-
|
|
8099
|
-
|
|
8100
|
-
|
|
8101
|
-
|
|
8102
|
-
|
|
8103
|
-
|
|
8104
|
-
|
|
8105
|
-
|
|
8106
|
-
|
|
8107
|
-
|
|
8108
|
-
|
|
8109
|
-
|
|
8110
|
-
|
|
8111
|
-
|
|
8112
|
-
|
|
8113
|
-
|
|
8114
|
-
|
|
8115
|
-
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
|
|
8119
|
-
|
|
8120
|
-
|
|
8121
|
-
|
|
8122
|
-
|
|
8123
|
-
|
|
8124
|
-
|
|
8125
|
-
|
|
8126
|
-
|
|
8127
|
-
|
|
8128
|
-
|
|
8129
|
-
|
|
8130
|
-
|
|
8131
|
-
|
|
8132
|
-
|
|
8133
|
-
|
|
8134
|
-
|
|
8135
|
-
|
|
8136
|
-
|
|
8137
|
-
|
|
8138
|
-
|
|
8139
|
-
|
|
8140
|
-
|
|
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 (
|
|
8215
|
-
|
|
8216
|
-
|
|
8217
|
-
|
|
8218
|
-
|
|
8219
|
-
|
|
8220
|
-
|
|
8221
|
-
|
|
8222
|
-
|
|
8223
|
-
|
|
8224
|
-
|
|
8225
|
-
|
|
8226
|
-
|
|
8227
|
-
|
|
8228
|
-
|
|
8229
|
-
|
|
8230
|
-
|
|
8231
|
-
|
|
8232
|
-
|
|
8233
|
-
|
|
8234
|
-
|
|
8235
|
-
|
|
8236
|
-
|
|
8237
|
-
|
|
8238
|
-
|
|
8239
|
-
|
|
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 (
|
|
8272
|
-
|
|
8273
|
-
|
|
8274
|
-
|
|
8275
|
-
|
|
8276
|
-
|
|
8277
|
-
|
|
8278
|
-
|
|
8279
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
9456
|
-
|
|
9457
|
-
|
|
9458
|
-
|
|
9459
|
-
|
|
9460
|
-
|
|
9461
|
-
|
|
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 (
|
|
9479
|
-
|
|
9480
|
-
|
|
9481
|
-
|
|
9482
|
-
|
|
9483
|
-
|
|
9484
|
-
|
|
9485
|
-
|
|
9486
|
-
|
|
9487
|
-
|
|
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) =>
|
|
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 (
|
|
10938
|
-
|
|
10939
|
-
|
|
10940
|
-
|
|
10941
|
-
|
|
10942
|
-
|
|
10943
|
-
|
|
10944
|
-
|
|
10945
|
-
|
|
10946
|
-
|
|
10947
|
-
|
|
10948
|
-
|
|
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 (
|
|
10978
|
-
|
|
10979
|
-
|
|
10980
|
-
|
|
10981
|
-
|
|
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
|
|
11214
|
-
|
|
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
|
|
11348
|
-
|
|
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
|
|
11552
|
-
|
|
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
|
-
|
|
12141
|
-
|
|
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
|
-
|
|
12413
|
-
|
|
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 (
|
|
12962
|
-
|
|
12963
|
-
|
|
12964
|
-
|
|
12965
|
-
|
|
12966
|
-
|
|
12967
|
-
|
|
12968
|
-
|
|
12969
|
-
|
|
12970
|
-
|
|
12971
|
-
|
|
12972
|
-
|
|
12973
|
-
|
|
12974
|
-
|
|
12975
|
-
|
|
12976
|
-
|
|
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
|
-
|
|
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:
|
|
13187
|
-
end:
|
|
12723
|
+
start: feature.get('start') + 1,
|
|
12724
|
+
end: feature.get('end'),
|
|
13188
12725
|
seq_id: refSeqId,
|
|
13189
|
-
source:
|
|
13190
|
-
type:
|
|
13191
|
-
score:
|
|
13192
|
-
strand:
|
|
13193
|
-
|
|
13194
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 (
|
|
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 (
|
|
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
|
-
|
|
13398
|
-
|
|
13399
|
-
|
|
13400
|
-
|
|
13401
|
-
|
|
13402
|
-
|
|
13403
|
-
|
|
13404
|
-
|
|
13405
|
-
|
|
13406
|
-
|
|
13407
|
-
|
|
13408
|
-
|
|
13409
|
-
|
|
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
|
-
|
|
13432
|
-
|
|
13433
|
-
|
|
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 (
|
|
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,
|
|
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 (
|
|
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
|
-
|
|
13482
|
-
|
|
13483
|
-
|
|
13484
|
-
|
|
13485
|
-
|
|
13486
|
-
|
|
13487
|
-
|
|
13488
|
-
|
|
13489
|
-
|
|
13490
|
-
|
|
13491
|
-
|
|
13492
|
-
|
|
13493
|
-
|
|
13494
|
-
|
|
13495
|
-
|
|
13496
|
-
|
|
13497
|
-
|
|
13498
|
-
|
|
13499
|
-
|
|
13500
|
-
|
|
13501
|
-
|
|
13502
|
-
|
|
13503
|
-
|
|
13504
|
-
|
|
13505
|
-
|
|
13506
|
-
|
|
13507
|
-
|
|
13508
|
-
|
|
13509
|
-
|
|
13510
|
-
|
|
13511
|
-
|
|
13512
|
-
|
|
13513
|
-
|
|
13514
|
-
|
|
13515
|
-
|
|
13516
|
-
|
|
13517
|
-
|
|
13518
|
-
|
|
13519
|
-
|
|
13520
|
-
|
|
13521
|
-
|
|
13522
|
-
|
|
13523
|
-
|
|
13524
|
-
|
|
13525
|
-
|
|
13526
|
-
|
|
13527
|
-
|
|
13528
|
-
|
|
13529
|
-
|
|
13530
|
-
|
|
13531
|
-
|
|
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
|
-
|
|
13538
|
-
|
|
13539
|
-
|
|
13540
|
-
|
|
13541
|
-
|
|
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
|
-
|
|
13544
|
-
|
|
13545
|
-
|
|
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
|
-
|
|
13575
|
-
|
|
13576
|
-
|
|
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
|
-
|
|
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('
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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('
|
|
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('
|
|
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)) {
|