@apollo-annotation/jbrowse-plugin-apollo 1.0.0 → 1.1.0
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 +8 -2
- package/dist/ApolloInternetAccount/components/AuthTypeSelector.d.ts.map +1 -1
- package/dist/ApolloInternetAccount/components/LoginButtons.d.ts +8 -3
- package/dist/ApolloInternetAccount/components/LoginButtons.d.ts.map +1 -1
- package/dist/ApolloInternetAccount/configSchema.d.ts +44 -0
- package/dist/ApolloInternetAccount/configSchema.d.ts.map +1 -0
- package/dist/ApolloInternetAccount/model.d.ts +174 -0
- package/dist/ApolloInternetAccount/model.d.ts.map +1 -0
- package/dist/ApolloJobModel.d.ts.map +1 -1
- package/dist/ApolloRefNameAliasAdapter/configSchema.d.ts +8 -0
- package/dist/ApolloRefNameAliasAdapter/configSchema.d.ts.map +1 -0
- package/dist/ApolloSequenceAdapter/configSchema.d.ts +8 -0
- package/dist/ApolloSequenceAdapter/configSchema.d.ts.map +1 -0
- package/dist/ApolloTextSearchAdapter/configSchema.d.ts +20 -0
- package/dist/ApolloTextSearchAdapter/configSchema.d.ts.map +1 -0
- package/dist/BackendDrivers/CollaborationServerDriver.d.ts +1 -1
- package/dist/BackendDrivers/CollaborationServerDriver.d.ts.map +1 -1
- package/dist/BackendDrivers/LocalDriver/LocalDriver.d.ts.map +1 -1
- package/dist/FeatureDetailsWidget/ApolloFeatureDetailsWidget.d.ts.map +1 -1
- package/dist/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.d.ts.map +1 -1
- package/dist/FeatureDetailsWidget/Attributes.d.ts.map +1 -1
- package/dist/FeatureDetailsWidget/DefaultAttributeEditor.d.ts.map +1 -1
- package/dist/FeatureDetailsWidget/DefaultAttributeViewer.d.ts.map +1 -1
- package/dist/FeatureDetailsWidget/NumberTextField.d.ts.map +1 -1
- package/dist/FeatureDetailsWidget/StringTextField.d.ts.map +1 -1
- package/dist/FeatureDetailsWidget/TranscriptSequence.d.ts.map +1 -1
- package/dist/FeatureDetailsWidget/TranscriptWidgetEditLocation.d.ts.map +1 -1
- package/dist/FeatureDetailsWidget/Translation.d.ts +14 -0
- package/dist/FeatureDetailsWidget/Translation.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/components/CheckResultWarnings.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/configSchema.d.ts +2 -0
- package/dist/LinearApolloDisplay/configSchema.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/glyphs/ExonGlyph.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/glyphs/GeneGlyph.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/glyphs/TranscriptGlyph.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/stateModel/base.d.ts +1 -18
- package/dist/LinearApolloDisplay/stateModel/base.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/stateModel/index.d.ts +1 -17
- package/dist/LinearApolloDisplay/stateModel/index.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/stateModel/layouts.d.ts +2 -19
- package/dist/LinearApolloDisplay/stateModel/layouts.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/stateModel/mouseEvents.d.ts +2 -34
- package/dist/LinearApolloDisplay/stateModel/mouseEvents.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/stateModel/rendering.d.ts +2 -19
- package/dist/LinearApolloDisplay/stateModel/rendering.d.ts.map +1 -1
- package/dist/LinearApolloReferenceSequenceDisplay/configSchema.d.ts +2 -0
- package/dist/LinearApolloReferenceSequenceDisplay/configSchema.d.ts.map +1 -0
- package/dist/LinearApolloReferenceSequenceDisplay/stateModel/base.d.ts +1 -1
- package/dist/LinearApolloReferenceSequenceDisplay/stateModel/base.d.ts.map +1 -1
- package/dist/LinearApolloReferenceSequenceDisplay/stateModel/index.d.ts +1 -1
- package/dist/LinearApolloReferenceSequenceDisplay/stateModel/rendering.d.ts +1 -1
- package/dist/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.d.ts.map +1 -1
- package/dist/LinearApolloSixFrameDisplay/configSchema.d.ts +2 -0
- package/dist/LinearApolloSixFrameDisplay/configSchema.d.ts.map +1 -0
- package/dist/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.d.ts.map +1 -1
- package/dist/LinearApolloSixFrameDisplay/stateModel/base.d.ts +1 -1
- package/dist/LinearApolloSixFrameDisplay/stateModel/base.d.ts.map +1 -1
- package/dist/LinearApolloSixFrameDisplay/stateModel/index.d.ts +1 -1
- package/dist/LinearApolloSixFrameDisplay/stateModel/index.d.ts.map +1 -1
- package/dist/LinearApolloSixFrameDisplay/stateModel/layouts.d.ts +2 -3
- package/dist/LinearApolloSixFrameDisplay/stateModel/layouts.d.ts.map +1 -1
- package/dist/LinearApolloSixFrameDisplay/stateModel/mouseEvents.d.ts +2 -2
- package/dist/LinearApolloSixFrameDisplay/stateModel/mouseEvents.d.ts.map +1 -1
- package/dist/LinearApolloSixFrameDisplay/stateModel/rendering.d.ts +2 -3
- package/dist/LinearApolloSixFrameDisplay/stateModel/rendering.d.ts.map +1 -1
- package/dist/OntologyManager/OntologyStore/fulltext.d.ts.map +1 -1
- package/dist/OntologyManager/index.d.ts +734 -0
- package/dist/OntologyManager/index.d.ts.map +1 -0
- package/dist/TabularEditor/HybridGrid/NumberCell.d.ts.map +1 -1
- package/dist/components/AddCodingSequence.d.ts +14 -0
- package/dist/components/AddCodingSequence.d.ts.map +1 -0
- package/dist/components/AddRefSeqAliases.d.ts.map +1 -1
- package/dist/components/CopyFeature.d.ts.map +1 -1
- package/dist/components/CreateApolloAnnotation.d.ts.map +1 -1
- package/dist/components/DeleteFeature.d.ts.map +1 -1
- package/dist/components/DownloadGFF3.d.ts.map +1 -1
- package/dist/components/DuplicateFeatureDialog.d.ts +12 -0
- package/dist/components/DuplicateFeatureDialog.d.ts.map +1 -0
- package/dist/components/ImportAnnotations.d.ts +9 -0
- package/dist/components/ImportAnnotations.d.ts.map +1 -0
- package/dist/components/ManageUsers.d.ts.map +1 -1
- package/dist/components/OntologyTermMultiSelect.d.ts.map +1 -1
- package/dist/components/ViewChangeLog.d.ts.map +1 -1
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/extensions/annotationFromPileup.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +830 -434
- package/dist/index.esm.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.development.js +825 -429
- 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 +863 -468
- 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/session/ClientDataStore.d.ts +2194 -0
- package/dist/session/ClientDataStore.d.ts.map +1 -0
- package/dist/session/handleApolloFeaturesUrlParam.d.ts +8 -0
- package/dist/session/handleApolloFeaturesUrlParam.d.ts.map +1 -0
- package/dist/session/session.d.ts +6788 -0
- package/dist/session/session.d.ts.map +1 -0
- package/dist/util/displayUtils.d.ts +36 -0
- package/dist/util/displayUtils.d.ts.map +1 -0
- package/dist/util/sequenceUtils.d.ts +2 -0
- package/dist/util/sequenceUtils.d.ts.map +1 -0
- package/package.json +14 -14
- package/src/ApolloInternetAccount/components/AuthTypeSelector.tsx +73 -38
- package/src/ApolloInternetAccount/components/LoginButtons.tsx +31 -10
- package/src/ApolloInternetAccount/model.ts +8 -5
- package/src/ApolloJobModel.ts +3 -8
- package/src/ApolloTextSearchAdapter/ApolloTextSearchAdapter.ts +1 -1
- package/src/BackendDrivers/CollaborationServerDriver.ts +7 -11
- package/src/BackendDrivers/LocalDriver/LocalDriver.ts +13 -4
- package/src/FeatureDetailsWidget/ApolloFeatureDetailsWidget.tsx +1 -0
- package/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx +4 -2
- package/src/FeatureDetailsWidget/Attributes.tsx +1 -0
- package/src/FeatureDetailsWidget/DefaultAttributeEditor.tsx +1 -0
- package/src/FeatureDetailsWidget/DefaultAttributeViewer.tsx +1 -0
- package/src/FeatureDetailsWidget/NumberTextField.tsx +1 -0
- package/src/FeatureDetailsWidget/StringTextField.tsx +1 -0
- package/src/FeatureDetailsWidget/TranscriptSequence.tsx +2 -1
- package/src/FeatureDetailsWidget/TranscriptWidgetEditLocation.tsx +17 -354
- package/src/FeatureDetailsWidget/Translation.tsx +358 -0
- package/src/LinearApolloDisplay/components/CheckResultWarnings.tsx +4 -1
- package/src/LinearApolloDisplay/glyphs/ExonGlyph.ts +2 -5
- package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +4 -6
- package/src/LinearApolloDisplay/glyphs/TranscriptGlyph.ts +39 -6
- package/src/LinearApolloDisplay/stateModel/base.ts +47 -23
- package/src/LinearApolloDisplay/stateModel/layouts.ts +7 -5
- package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +4 -1
- package/src/LinearApolloDisplay/stateModel/rendering.ts +1 -5
- package/src/LinearApolloReferenceSequenceDisplay/stateModel/base.ts +10 -10
- package/src/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.tsx +5 -3
- package/src/LinearApolloSixFrameDisplay/components/TrackLines.tsx +1 -1
- package/src/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.ts +2 -3
- package/src/LinearApolloSixFrameDisplay/stateModel/base.ts +12 -20
- package/src/LinearApolloSixFrameDisplay/stateModel/layouts.ts +10 -6
- package/src/LinearApolloSixFrameDisplay/stateModel/mouseEvents.ts +38 -45
- package/src/LinearApolloSixFrameDisplay/stateModel/rendering.ts +1 -4
- package/src/OntologyManager/OntologyStore/fulltext.ts +0 -2
- package/src/OntologyManager/OntologyStore/index.ts +1 -1
- package/src/TabularEditor/HybridGrid/ChangeHandling.ts +2 -2
- package/src/TabularEditor/HybridGrid/NumberCell.tsx +2 -1
- package/src/components/AddAssemblyAliases.tsx +1 -1
- package/src/components/AddCodingSequence.tsx +255 -0
- package/src/components/AddFeature.tsx +1 -1
- package/src/components/AddRefSeqAliases.tsx +3 -2
- package/src/components/CopyFeature.tsx +9 -7
- package/src/components/CreateApolloAnnotation.tsx +28 -23
- package/src/components/DeleteAssembly.tsx +2 -2
- package/src/components/DeleteFeature.tsx +1 -4
- package/src/components/DownloadGFF3.tsx +4 -3
- package/src/components/DuplicateFeatureDialog.tsx +154 -0
- package/src/components/DuplicateTranscript.tsx +1 -1
- package/src/components/FilterTranscripts.tsx +1 -1
- package/src/components/ImportAnnotations.tsx +108 -0
- package/src/components/ManageUsers.tsx +1 -2
- package/src/components/OntologyTermAutocomplete.tsx +1 -3
- package/src/components/OntologyTermMultiSelect.tsx +3 -1
- package/src/components/ViewChangeLog.tsx +2 -1
- package/src/components/index.ts +2 -0
- package/src/extensions/annotationFromPileup.ts +34 -26
- package/src/index.ts +9 -8
- package/src/session/ClientDataStore.ts +16 -21
- package/src/session/handleApolloFeaturesUrlParam.ts +122 -0
- package/src/session/session.ts +49 -9
- package/src/util/annotationFeatureUtils.ts +1 -1
- package/src/util/displayUtils.ts +1 -1
- package/src/util/glyphUtils.ts +3 -3
- package/src/util/sequenceUtils.ts +29 -0
|
@@ -1,40 +1,22 @@
|
|
|
1
1
|
/* eslint-disable unicorn/no-nested-ternary */
|
|
2
2
|
/* eslint-disable unicorn/prefer-at */
|
|
3
|
-
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
4
|
-
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
5
|
-
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
6
3
|
import type { AnnotationFeature, TranscriptPart } from '@apollo-annotation/mst'
|
|
7
4
|
import {
|
|
8
5
|
LocationEndChange,
|
|
9
6
|
LocationStartChange,
|
|
10
7
|
} from '@apollo-annotation/shared'
|
|
11
8
|
import styled from '@emotion/styled'
|
|
12
|
-
import {
|
|
13
|
-
type AbstractSessionModel,
|
|
14
|
-
defaultCodonTable,
|
|
15
|
-
revcom,
|
|
16
|
-
} from '@jbrowse/core/util'
|
|
9
|
+
import { type AbstractSessionModel, revcom } from '@jbrowse/core/util'
|
|
17
10
|
import AddIcon from '@mui/icons-material/Add'
|
|
18
|
-
import ContentCopyIcon from '@mui/icons-material/ContentCopy'
|
|
19
|
-
import ContentCutIcon from '@mui/icons-material/ContentCut'
|
|
20
|
-
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
|
|
21
11
|
import RemoveIcon from '@mui/icons-material/Remove'
|
|
22
|
-
import {
|
|
23
|
-
Accordion,
|
|
24
|
-
AccordionDetails,
|
|
25
|
-
AccordionSummary,
|
|
26
|
-
Grid,
|
|
27
|
-
Tooltip,
|
|
28
|
-
Typography,
|
|
29
|
-
} from '@mui/material'
|
|
12
|
+
import { Grid, Typography } from '@mui/material'
|
|
30
13
|
import { observer } from 'mobx-react'
|
|
31
|
-
import React, { useRef } from 'react'
|
|
32
14
|
|
|
33
15
|
import type { OntologyRecord } from '../OntologyManager'
|
|
34
16
|
import type { ApolloSessionModel } from '../session'
|
|
35
|
-
import { copyToClipboard } from '../util/copyToClipboard'
|
|
36
17
|
|
|
37
18
|
import { NumberTextField } from './NumberTextField'
|
|
19
|
+
import { Translation } from './Translation'
|
|
38
20
|
|
|
39
21
|
const StyledTextField = styled(NumberTextField)(() => ({
|
|
40
22
|
'&.MuiFormControl-root': {
|
|
@@ -50,29 +32,6 @@ const StyledTextField = styled(NumberTextField)(() => ({
|
|
|
50
32
|
},
|
|
51
33
|
}))
|
|
52
34
|
|
|
53
|
-
const SequenceContainer = styled('div')({
|
|
54
|
-
display: 'flex',
|
|
55
|
-
justifyContent: 'center',
|
|
56
|
-
alignItems: 'center',
|
|
57
|
-
textAlign: 'left',
|
|
58
|
-
width: '100%',
|
|
59
|
-
overflowWrap: 'break-word',
|
|
60
|
-
wordWrap: 'break-word',
|
|
61
|
-
wordBreak: 'break-all',
|
|
62
|
-
'& span': {
|
|
63
|
-
fontSize: 12,
|
|
64
|
-
},
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
const StyledAccordionSummary = styled(AccordionSummary)(() => ({
|
|
68
|
-
minHeight: 30,
|
|
69
|
-
maxHeight: 30,
|
|
70
|
-
'&.Mui-expanded': {
|
|
71
|
-
minHeight: 30,
|
|
72
|
-
maxHeight: 30,
|
|
73
|
-
},
|
|
74
|
-
}))
|
|
75
|
-
|
|
76
35
|
const Strand = (props: { strand: 1 | -1 | undefined }) => {
|
|
77
36
|
const { strand } = props
|
|
78
37
|
|
|
@@ -118,7 +77,6 @@ export const TranscriptWidgetEditLocation = observer(
|
|
|
118
77
|
const currentAssembly = session.apolloDataStore.assemblies.get(assembly)
|
|
119
78
|
const refData = currentAssembly?.getByRefName(refName)
|
|
120
79
|
const { changeManager } = session.apolloDataStore
|
|
121
|
-
const seqRef = useRef<HTMLDivElement>(null)
|
|
122
80
|
const { changeInProgress } = session
|
|
123
81
|
|
|
124
82
|
if (!refData) {
|
|
@@ -699,263 +657,6 @@ export const TranscriptWidgetEditLocation = observer(
|
|
|
699
657
|
]
|
|
700
658
|
}
|
|
701
659
|
|
|
702
|
-
const getTranslationSequence = () => {
|
|
703
|
-
let wholeSequence = ''
|
|
704
|
-
const [firstLocation] = cdsLocations
|
|
705
|
-
const sortedCDSLocations = firstLocation.toSorted(
|
|
706
|
-
({ min: a }, { min: b }) => a - b,
|
|
707
|
-
)
|
|
708
|
-
for (const loc of sortedCDSLocations) {
|
|
709
|
-
wholeSequence += refData.getSequence(loc.min, loc.max)
|
|
710
|
-
}
|
|
711
|
-
if (strand === -1) {
|
|
712
|
-
// Original: ACGCAT
|
|
713
|
-
// Complement: TGCGTA
|
|
714
|
-
// Reverse complement: ATGCGT
|
|
715
|
-
wholeSequence = revcom(wholeSequence)
|
|
716
|
-
}
|
|
717
|
-
const elements = []
|
|
718
|
-
for (
|
|
719
|
-
let codonGenomicPos = 0;
|
|
720
|
-
codonGenomicPos < wholeSequence.length;
|
|
721
|
-
codonGenomicPos += 3
|
|
722
|
-
) {
|
|
723
|
-
const codonSeq = wholeSequence
|
|
724
|
-
.slice(codonGenomicPos, codonGenomicPos + 3)
|
|
725
|
-
.toUpperCase()
|
|
726
|
-
const protein =
|
|
727
|
-
defaultCodonTable[codonSeq as keyof typeof defaultCodonTable] || '&'
|
|
728
|
-
// highlight start codon and stop codons
|
|
729
|
-
if (codonSeq === 'ATG') {
|
|
730
|
-
elements.push(
|
|
731
|
-
<Typography
|
|
732
|
-
component={'span'}
|
|
733
|
-
style={{
|
|
734
|
-
backgroundColor: changeInProgress ? 'lightgray' : 'yellow',
|
|
735
|
-
cursor: 'pointer',
|
|
736
|
-
border: '1px solid black',
|
|
737
|
-
}}
|
|
738
|
-
key={codonGenomicPos}
|
|
739
|
-
onClick={() => {
|
|
740
|
-
if (changeInProgress) {
|
|
741
|
-
return
|
|
742
|
-
}
|
|
743
|
-
// NOTE: codonGenomicPos is important here for calculating the genomic location
|
|
744
|
-
// of the start codon. We are using the codonGenomicPos as the key in the typography
|
|
745
|
-
// elements to maintain the genomic postion of the codon start
|
|
746
|
-
const startCodonGenomicLocation =
|
|
747
|
-
getCodonGenomicLocation(codonGenomicPos)
|
|
748
|
-
if (startCodonGenomicLocation !== cdsMin && strand === 1) {
|
|
749
|
-
updateCDSLocation(
|
|
750
|
-
cdsMin,
|
|
751
|
-
startCodonGenomicLocation,
|
|
752
|
-
feature,
|
|
753
|
-
true,
|
|
754
|
-
)
|
|
755
|
-
}
|
|
756
|
-
if (startCodonGenomicLocation !== cdsMax && strand === -1) {
|
|
757
|
-
updateCDSLocation(
|
|
758
|
-
cdsMax,
|
|
759
|
-
startCodonGenomicLocation,
|
|
760
|
-
feature,
|
|
761
|
-
false,
|
|
762
|
-
)
|
|
763
|
-
}
|
|
764
|
-
}}
|
|
765
|
-
>
|
|
766
|
-
{protein}
|
|
767
|
-
</Typography>,
|
|
768
|
-
)
|
|
769
|
-
} else if (['TAA', 'TAG', 'TGA'].includes(codonSeq)) {
|
|
770
|
-
elements.push(
|
|
771
|
-
<Typography
|
|
772
|
-
style={{ backgroundColor: 'red', color: 'white' }}
|
|
773
|
-
component={'span'}
|
|
774
|
-
// Pass the codonGenomicPos as the key to maintain the genomic position of the codon
|
|
775
|
-
key={codonGenomicPos}
|
|
776
|
-
>
|
|
777
|
-
{protein}
|
|
778
|
-
</Typography>,
|
|
779
|
-
)
|
|
780
|
-
} else {
|
|
781
|
-
elements.push(
|
|
782
|
-
// Pass the codonGenomicPos as the key to maintain the genomic position of the codon
|
|
783
|
-
<Typography component={'span'} key={codonGenomicPos}>
|
|
784
|
-
{protein}
|
|
785
|
-
</Typography>,
|
|
786
|
-
)
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
return elements
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
// Codon position is the index of the start codon in the CDS genomic sequence
|
|
793
|
-
// Calculate the genomic location of the start codon based on the codon position in the CDS
|
|
794
|
-
const getCodonGenomicLocation = (codonGenomicPosition: number) => {
|
|
795
|
-
const [firstLocation] = cdsLocations
|
|
796
|
-
let cdsLen = 0
|
|
797
|
-
const sortedCDSLocations = firstLocation.toSorted(
|
|
798
|
-
({ min: a }, { min: b }) => a - b,
|
|
799
|
-
)
|
|
800
|
-
|
|
801
|
-
// Suppose CDS locations are [{min: 0, max: 10}, {min: 20, max: 30}, {min: 40, max: 50}]
|
|
802
|
-
// and codonGenomicPosition is 25
|
|
803
|
-
// ((10 - 0) + (30 - 20) + (50 - 40)) > 25
|
|
804
|
-
// So, start codon is in (40, 50)
|
|
805
|
-
// 40 + (25-20) = 45 is the genomic location of the start codon
|
|
806
|
-
if (strand === 1) {
|
|
807
|
-
for (const loc of sortedCDSLocations) {
|
|
808
|
-
const locLength = loc.max - loc.min
|
|
809
|
-
if (cdsLen + locLength > codonGenomicPosition) {
|
|
810
|
-
return loc.min + (codonGenomicPosition - cdsLen)
|
|
811
|
-
}
|
|
812
|
-
cdsLen += locLength
|
|
813
|
-
}
|
|
814
|
-
} else if (strand === -1) {
|
|
815
|
-
for (let i = sortedCDSLocations.length - 1; i >= 0; i--) {
|
|
816
|
-
const loc = sortedCDSLocations[i]
|
|
817
|
-
const locLength = loc.max - loc.min
|
|
818
|
-
if (cdsLen + locLength > codonGenomicPosition) {
|
|
819
|
-
return loc.max - (codonGenomicPosition - cdsLen)
|
|
820
|
-
}
|
|
821
|
-
cdsLen += locLength
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
if (strand === 1) {
|
|
826
|
-
return cdsMin
|
|
827
|
-
}
|
|
828
|
-
|
|
829
|
-
return cdsMax
|
|
830
|
-
}
|
|
831
|
-
|
|
832
|
-
const trimTranslationSequence = () => {
|
|
833
|
-
const sequenceElements = getTranslationSequence()
|
|
834
|
-
const translationSequence = sequenceElements
|
|
835
|
-
.map((el) => el.props.children)
|
|
836
|
-
.join('')
|
|
837
|
-
|
|
838
|
-
if (
|
|
839
|
-
translationSequence.startsWith('M') &&
|
|
840
|
-
translationSequence.endsWith('*')
|
|
841
|
-
) {
|
|
842
|
-
return
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
// NOTE: We are maintaining the genomic location of the codon start as the "key"
|
|
846
|
-
// in typography elements. See getTranslationSequence function
|
|
847
|
-
const translSeqCodonStartGenomicPosArr = []
|
|
848
|
-
for (const el of sequenceElements) {
|
|
849
|
-
translSeqCodonStartGenomicPosArr.push({
|
|
850
|
-
codonGenomicPos: el.key,
|
|
851
|
-
sequenceLetter: el.props.children,
|
|
852
|
-
})
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
if (translSeqCodonStartGenomicPosArr.length === 0) {
|
|
856
|
-
return
|
|
857
|
-
}
|
|
858
|
-
|
|
859
|
-
// Trim any sequence before first start codon and after stop codon
|
|
860
|
-
const startCodonIndex = translationSequence.indexOf('M')
|
|
861
|
-
const stopCodonIndex = translationSequence.indexOf('*')
|
|
862
|
-
|
|
863
|
-
const startCodonPos =
|
|
864
|
-
translSeqCodonStartGenomicPosArr[startCodonIndex].codonGenomicPos
|
|
865
|
-
const stopCodonPos =
|
|
866
|
-
translSeqCodonStartGenomicPosArr[stopCodonIndex].codonGenomicPos
|
|
867
|
-
|
|
868
|
-
if (!startCodonPos || !stopCodonPos) {
|
|
869
|
-
return
|
|
870
|
-
}
|
|
871
|
-
const startCodonGenomicLoc = getCodonGenomicLocation(
|
|
872
|
-
startCodonPos as unknown as number,
|
|
873
|
-
)
|
|
874
|
-
let stopCodonGenomicLoc = getCodonGenomicLocation(
|
|
875
|
-
stopCodonPos as unknown as number,
|
|
876
|
-
)
|
|
877
|
-
|
|
878
|
-
if (strand === 1) {
|
|
879
|
-
if (startCodonGenomicLoc > stopCodonGenomicLoc) {
|
|
880
|
-
notify(
|
|
881
|
-
'Start codon genomic location should be less than stop codon genomic location',
|
|
882
|
-
'error',
|
|
883
|
-
)
|
|
884
|
-
return
|
|
885
|
-
}
|
|
886
|
-
let promise
|
|
887
|
-
stopCodonGenomicLoc += 3 // move to end of stop codon
|
|
888
|
-
if (startCodonGenomicLoc !== cdsMin) {
|
|
889
|
-
promise = new Promise((resolve) => {
|
|
890
|
-
updateCDSLocation(
|
|
891
|
-
cdsMin,
|
|
892
|
-
startCodonGenomicLoc,
|
|
893
|
-
feature,
|
|
894
|
-
true,
|
|
895
|
-
() => {
|
|
896
|
-
resolve(true)
|
|
897
|
-
},
|
|
898
|
-
)
|
|
899
|
-
})
|
|
900
|
-
}
|
|
901
|
-
|
|
902
|
-
if (stopCodonGenomicLoc !== cdsMax) {
|
|
903
|
-
if (promise) {
|
|
904
|
-
void promise.then(() => {
|
|
905
|
-
updateCDSLocation(cdsMax, stopCodonGenomicLoc, feature, false)
|
|
906
|
-
})
|
|
907
|
-
} else {
|
|
908
|
-
updateCDSLocation(cdsMax, stopCodonGenomicLoc, feature, false)
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
}
|
|
912
|
-
|
|
913
|
-
if (strand === -1) {
|
|
914
|
-
// reverse strand
|
|
915
|
-
if (startCodonGenomicLoc < stopCodonGenomicLoc) {
|
|
916
|
-
notify(
|
|
917
|
-
'Start codon genomic location should be less than stop codon genomic location',
|
|
918
|
-
'error',
|
|
919
|
-
)
|
|
920
|
-
return
|
|
921
|
-
}
|
|
922
|
-
let promise
|
|
923
|
-
stopCodonGenomicLoc -= 3 // move to end of stop codon
|
|
924
|
-
if (startCodonGenomicLoc !== cdsMax) {
|
|
925
|
-
promise = new Promise((resolve) => {
|
|
926
|
-
updateCDSLocation(
|
|
927
|
-
cdsMax,
|
|
928
|
-
startCodonGenomicLoc,
|
|
929
|
-
feature,
|
|
930
|
-
false,
|
|
931
|
-
() => {
|
|
932
|
-
resolve(true)
|
|
933
|
-
},
|
|
934
|
-
)
|
|
935
|
-
})
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
if (stopCodonGenomicLoc !== cdsMin) {
|
|
939
|
-
if (promise) {
|
|
940
|
-
void promise.then(() => {
|
|
941
|
-
updateCDSLocation(cdsMin, stopCodonGenomicLoc, feature, true)
|
|
942
|
-
})
|
|
943
|
-
} else {
|
|
944
|
-
updateCDSLocation(cdsMin, stopCodonGenomicLoc, feature, true)
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
}
|
|
948
|
-
notify('Translation sequence trimmed to start and stop codons', 'success')
|
|
949
|
-
}
|
|
950
|
-
|
|
951
|
-
const onCopyClick = () => {
|
|
952
|
-
const seqDiv = seqRef.current
|
|
953
|
-
if (!seqDiv) {
|
|
954
|
-
return
|
|
955
|
-
}
|
|
956
|
-
void copyToClipboard(seqDiv)
|
|
957
|
-
}
|
|
958
|
-
|
|
959
660
|
return (
|
|
960
661
|
<div>
|
|
961
662
|
{cdsPresent && (
|
|
@@ -1054,6 +755,7 @@ export const TranscriptWidgetEditLocation = observer(
|
|
|
1054
755
|
</div>
|
|
1055
756
|
{transcriptExonParts.map((loc, index) => {
|
|
1056
757
|
return (
|
|
758
|
+
// eslint-disable-next-line @eslint-react/no-array-index-key
|
|
1057
759
|
<div key={index}>
|
|
1058
760
|
{loc.type === 'exon' && (
|
|
1059
761
|
<Grid
|
|
@@ -1066,6 +768,7 @@ export const TranscriptWidgetEditLocation = observer(
|
|
|
1066
768
|
{index !== 0 &&
|
|
1067
769
|
getFivePrimeSpliceSite(loc, index).map((site, idx) => (
|
|
1068
770
|
<Typography
|
|
771
|
+
// eslint-disable-next-line @eslint-react/no-array-index-key
|
|
1069
772
|
key={idx}
|
|
1070
773
|
component={'span'}
|
|
1071
774
|
color={site.color}
|
|
@@ -1151,6 +854,7 @@ export const TranscriptWidgetEditLocation = observer(
|
|
|
1151
854
|
{index !== transcriptExonParts.length - 1 &&
|
|
1152
855
|
getThreePrimeSpliceSite(loc, index).map((site, idx) => (
|
|
1153
856
|
<Typography
|
|
857
|
+
// eslint-disable-next-line @eslint-react/no-array-index-key
|
|
1154
858
|
key={idx}
|
|
1155
859
|
component={'span'}
|
|
1156
860
|
color={site.color}
|
|
@@ -1166,58 +870,17 @@ export const TranscriptWidgetEditLocation = observer(
|
|
|
1166
870
|
})}
|
|
1167
871
|
</div>
|
|
1168
872
|
{cdsPresent && (
|
|
1169
|
-
<
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
<AccordionDetails>
|
|
1181
|
-
<SequenceContainer>
|
|
1182
|
-
<Typography
|
|
1183
|
-
component={'span'}
|
|
1184
|
-
ref={seqRef}
|
|
1185
|
-
style={{ maxHeight: 120, overflowY: 'scroll' }}
|
|
1186
|
-
>
|
|
1187
|
-
{getTranslationSequence()}
|
|
1188
|
-
</Typography>
|
|
1189
|
-
</SequenceContainer>
|
|
1190
|
-
<div
|
|
1191
|
-
style={{
|
|
1192
|
-
marginTop: 10,
|
|
1193
|
-
display: 'flex',
|
|
1194
|
-
flexDirection: 'row',
|
|
1195
|
-
alignItems: 'center',
|
|
1196
|
-
gap: 10,
|
|
1197
|
-
}}
|
|
1198
|
-
>
|
|
1199
|
-
<Tooltip title="Copy">
|
|
1200
|
-
<button
|
|
1201
|
-
onClick={onCopyClick}
|
|
1202
|
-
style={{ border: 'none', background: 'none', padding: 0 }}
|
|
1203
|
-
disabled={changeInProgress}
|
|
1204
|
-
>
|
|
1205
|
-
<ContentCopyIcon style={{ fontSize: 15 }} />
|
|
1206
|
-
</button>
|
|
1207
|
-
</Tooltip>
|
|
1208
|
-
<Tooltip title="Trim">
|
|
1209
|
-
<button
|
|
1210
|
-
onClick={trimTranslationSequence}
|
|
1211
|
-
style={{ border: 'none', background: 'none', padding: 0 }}
|
|
1212
|
-
disabled={changeInProgress}
|
|
1213
|
-
>
|
|
1214
|
-
<ContentCutIcon style={{ fontSize: 15 }} />
|
|
1215
|
-
</button>
|
|
1216
|
-
</Tooltip>
|
|
1217
|
-
</div>
|
|
1218
|
-
</AccordionDetails>
|
|
1219
|
-
</Accordion>
|
|
1220
|
-
</div>
|
|
873
|
+
<Translation
|
|
874
|
+
changeInProgress={changeInProgress}
|
|
875
|
+
cdsLocations={cdsLocations}
|
|
876
|
+
refData={refData}
|
|
877
|
+
strand={strand}
|
|
878
|
+
updateCDSLocation={updateCDSLocation}
|
|
879
|
+
cdsMin={cdsMin}
|
|
880
|
+
cdsMax={cdsMax}
|
|
881
|
+
feature={feature}
|
|
882
|
+
session={session}
|
|
883
|
+
/>
|
|
1221
884
|
)}
|
|
1222
885
|
</div>
|
|
1223
886
|
)
|