jbrowse-plugin-protein3d 0.4.5 → 0.4.6
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/LaunchProteinView/components/AlphaFoldDBSearch.js +1 -3
- package/dist/LaunchProteinView/components/FoldseekSearch.js +6 -2
- package/dist/LaunchProteinView/components/IdentifierSelector.d.ts +1 -2
- package/dist/LaunchProteinView/components/IdentifierSelector.js +2 -8
- package/dist/LaunchProteinView/components/UserProvidedStructure.js +9 -7
- package/dist/LaunchProteinView/hooks/useAlphaFoldDBSearch.d.ts +1 -5
- package/dist/LaunchProteinView/hooks/useAlphaFoldDBSearch.js +11 -22
- package/dist/LaunchProteinView/hooks/useAlphaFoldData.d.ts +1 -6
- package/dist/LaunchProteinView/hooks/useAlphaFoldData.js +7 -23
- package/dist/LaunchProteinView/hooks/useTranscriptSelection.d.ts +2 -1
- package/dist/LaunchProteinView/hooks/useTranscriptSelection.js +12 -4
- package/dist/LaunchProteinView/hooks/useUniProtSearch.d.ts +1 -2
- package/dist/LaunchProteinView/hooks/useUniProtSearch.js +5 -25
- package/dist/LaunchProteinView/utils/launchViewUtils.js +1 -10
- package/dist/jbrowse-plugin-protein3d.umd.production.min.js +15 -15
- package/dist/jbrowse-plugin-protein3d.umd.production.min.js.map +4 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/src/LaunchProteinView/components/AlphaFoldDBSearch.tsx +0 -8
- package/src/LaunchProteinView/components/FoldseekSearch.tsx +13 -2
- package/src/LaunchProteinView/components/IdentifierSelector.tsx +1 -10
- package/src/LaunchProteinView/components/UserProvidedStructure.tsx +12 -9
- package/src/LaunchProteinView/hooks/useAlphaFoldDBSearch.ts +7 -23
- package/src/LaunchProteinView/hooks/useAlphaFoldData.ts +7 -45
- package/src/LaunchProteinView/hooks/useTranscriptSelection.ts +16 -4
- package/src/LaunchProteinView/hooks/useUniProtSearch.ts +4 -28
- package/src/LaunchProteinView/utils/launchViewUtils.ts +1 -12
- package/src/ProteinView/components/ProteinFeatureTrack.tsx +4 -1
- package/src/ProteinView/components/ProteinViewHeader.tsx +11 -9
- package/src/version.ts +1 -1
- package/dist/LaunchProteinView/components/AlphaFoldEntrySelector.d.ts +0 -12
- package/dist/LaunchProteinView/components/AlphaFoldEntrySelector.js +0 -17
- package/dist/LaunchProteinView/hooks/useAlphaFoldUrl.d.ts +0 -13
- package/dist/LaunchProteinView/hooks/useAlphaFoldUrl.js +0 -17
- package/src/LaunchProteinView/components/AlphaFoldEntrySelector.tsx +0 -47
- package/src/LaunchProteinView/hooks/useAlphaFoldUrl.ts +0 -31
|
@@ -5,7 +5,6 @@ import { DialogActions, DialogContent, Typography } from '@mui/material';
|
|
|
5
5
|
import { observer } from 'mobx-react';
|
|
6
6
|
import { makeStyles } from 'tss-react/mui';
|
|
7
7
|
import AlphaFoldDBSearchStatus from './AlphaFoldDBSearchStatus';
|
|
8
|
-
import AlphaFoldEntrySelector from './AlphaFoldEntrySelector';
|
|
9
8
|
import IdentifierSelector from './IdentifierSelector';
|
|
10
9
|
import ProteinViewActions from './ProteinViewActions';
|
|
11
10
|
import SequenceSearchStatus from './SequenceSearchStatus';
|
|
@@ -62,8 +61,7 @@ const AlphaFoldDBSearch = observer(function AlphaFoldDBSearch({ feature, model,
|
|
|
62
61
|
"directly and use \"Enter manually\" above, or use \"Search sequence against AlphaFoldDB API\" if available.")),
|
|
63
62
|
state.showStructureSelectors && (React.createElement(React.Fragment, null,
|
|
64
63
|
React.createElement("div", { className: classes.selectorsRow },
|
|
65
|
-
React.createElement(TranscriptSelector, { val: state.userSelection, setVal: state.setUserSelection, structureSequence: state.structureSequence, feature: feature, isoforms: state.transcriptOptions, isoformSequences: state.isoformSequences }),
|
|
66
|
-
state.showAlphaFoldEntrySelector && (React.createElement(AlphaFoldEntrySelector, { predictions: state.predictions, selectedEntryIndex: state.selectedEntryIndex, onSelectionChange: state.setSelectedEntryIndex }))),
|
|
64
|
+
React.createElement(TranscriptSelector, { val: state.userSelection, setVal: state.setUserSelection, structureSequence: state.structureSequence, feature: feature, isoforms: state.transcriptOptions, isoformSequences: state.isoformSequences })),
|
|
67
65
|
state.showSequenceSearchStatus && (React.createElement(SequenceSearchStatus, { isLoading: state.isSequenceSearchLoading, uniprotId: state.uniprotId, url: state.url, hasProteinSequence: !!state.userSelectedProteinSequence, sequenceSearchType: state.sequenceSearchType })),
|
|
68
66
|
state.showAlphaFoldDBSearchStatus && (React.createElement(AlphaFoldDBSearchStatus, { uniprotId: state.uniprotId, selectedTranscript: state.selectedTranscript, structureSequence: state.structureSequence, isoformSequences: state.isoformSequences, url: state.url }))))),
|
|
69
67
|
React.createElement(DialogActions, null,
|
|
@@ -76,8 +76,12 @@ const FoldseekSearch = observer(function FoldseekSearch({ feature, model, handle
|
|
|
76
76
|
statusMessage ? (React.createElement(LoadingEllipses, { variant: "subtitle2", message: statusMessage })) : null,
|
|
77
77
|
results ? (React.createElement(FoldseekResultsTable, { results: results, session: session, view: view, feature: feature, selectedTranscript: selectedTranscript, userProvidedTranscriptSequence: sequence, onClose: handleClose })) : null),
|
|
78
78
|
React.createElement(DialogActions, null,
|
|
79
|
-
React.createElement(Button, { variant: "contained", color: "secondary", onClick:
|
|
80
|
-
|
|
79
|
+
React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => {
|
|
80
|
+
handleClose();
|
|
81
|
+
} }, "Cancel"),
|
|
82
|
+
results ? (React.createElement(Button, { variant: "outlined", onClick: () => {
|
|
83
|
+
reset();
|
|
84
|
+
} }, "New search")) : null,
|
|
81
85
|
!di3Sequence ? (React.createElement(Button, { variant: "contained", color: "primary", disabled: !canPredict, onClick: () => {
|
|
82
86
|
if (sequence.trim()) {
|
|
83
87
|
void predictStructure(sequence.trim());
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
interface IdentifierSelectorProps {
|
|
3
3
|
recognizedIds: string[];
|
|
4
|
-
uniprotId?: string;
|
|
5
4
|
geneName?: string;
|
|
6
5
|
selectedId: string;
|
|
7
6
|
onSelectedIdChange: (id: string) => void;
|
|
8
7
|
}
|
|
9
|
-
export default function IdentifierSelector({ recognizedIds,
|
|
8
|
+
export default function IdentifierSelector({ recognizedIds, geneName, selectedId, onSelectedIdChange, }: IdentifierSelectorProps): React.JSX.Element | null;
|
|
10
9
|
export {};
|
|
@@ -35,26 +35,20 @@ function getIdLabel(id) {
|
|
|
35
35
|
}
|
|
36
36
|
return id;
|
|
37
37
|
}
|
|
38
|
-
export default function IdentifierSelector({ recognizedIds,
|
|
38
|
+
export default function IdentifierSelector({ recognizedIds, geneName, selectedId, onSelectedIdChange, }) {
|
|
39
39
|
const [expanded, setExpanded] = useState(false);
|
|
40
40
|
// Build list of selectable options
|
|
41
41
|
const options = [
|
|
42
42
|
{ value: 'auto', label: 'Auto (try all)' },
|
|
43
43
|
...recognizedIds.map(id => ({ value: id, label: getIdLabel(id) })),
|
|
44
44
|
];
|
|
45
|
-
if (uniprotId) {
|
|
46
|
-
options.push({
|
|
47
|
-
value: `uniprot:${uniprotId}`,
|
|
48
|
-
label: `${uniprotId} (UniProt)`,
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
45
|
if (geneName) {
|
|
52
46
|
options.push({
|
|
53
47
|
value: `gene:${geneName}`,
|
|
54
48
|
label: `${geneName} (gene name)`,
|
|
55
49
|
});
|
|
56
50
|
}
|
|
57
|
-
if (recognizedIds.length === 0 && !
|
|
51
|
+
if (recognizedIds.length === 0 && !geneName) {
|
|
58
52
|
return null;
|
|
59
53
|
}
|
|
60
54
|
if (!expanded) {
|
|
@@ -40,16 +40,18 @@ const UserProvidedStructure = observer(function UserProvidedStructure({ feature,
|
|
|
40
40
|
const [submitError, setSubmitError] = useState();
|
|
41
41
|
const [structureURL, setStructureURL] = useState('');
|
|
42
42
|
const [showAllProteinSequences, setShowAllProteinSequences] = useState(false);
|
|
43
|
+
const activeFile = choice === 'file' ? file : undefined;
|
|
44
|
+
const activeURL = choice === 'file' ? '' : structureURL;
|
|
43
45
|
const options = getTranscriptFeatures(feature);
|
|
44
46
|
const view = getContainingView(model);
|
|
45
47
|
const { isoformSequences, error: isoformError } = useIsoformProteinSequences({
|
|
46
48
|
feature,
|
|
47
49
|
view,
|
|
48
50
|
});
|
|
49
|
-
const { sequences:
|
|
50
|
-
const { sequences:
|
|
51
|
-
const structureName =
|
|
52
|
-
const structureSequences =
|
|
51
|
+
const { sequences: localSequences, error: localFileError } = useLocalStructureFileSequence({ file: activeFile });
|
|
52
|
+
const { sequences: remoteSequences, error: remoteFileError } = useRemoteStructureFileSequence({ url: activeURL });
|
|
53
|
+
const structureName = activeFile?.name ?? activeURL.slice(activeURL.lastIndexOf('/') + 1);
|
|
54
|
+
const structureSequences = activeFile ? localSequences : remoteSequences;
|
|
53
55
|
const structureSequence = structureSequences?.[0];
|
|
54
56
|
const { userSelection, setUserSelection } = useTranscriptSelection({
|
|
55
57
|
options,
|
|
@@ -59,7 +61,7 @@ const UserProvidedStructure = observer(function UserProvidedStructure({ feature,
|
|
|
59
61
|
const selectedTranscript = options.find(val => getId(val) === userSelection);
|
|
60
62
|
const protein = userSelection ? isoformSequences?.[userSelection] : undefined;
|
|
61
63
|
const error = isoformError ?? submitError ?? localFileError ?? remoteFileError;
|
|
62
|
-
const canLaunch = !!(
|
|
64
|
+
const canLaunch = !!(activeURL || activeFile) && !!protein && !!selectedTranscript;
|
|
63
65
|
const sequencesDiffer = !!protein?.seq &&
|
|
64
66
|
!!structureSequence &&
|
|
65
67
|
stripStopCodon(protein.seq) !== structureSequence;
|
|
@@ -68,8 +70,8 @@ const UserProvidedStructure = observer(function UserProvidedStructure({ feature,
|
|
|
68
70
|
return;
|
|
69
71
|
}
|
|
70
72
|
try {
|
|
71
|
-
const structureData =
|
|
72
|
-
const url =
|
|
73
|
+
const structureData = activeFile ? await activeFile.text() : undefined;
|
|
74
|
+
const url = activeURL ? activeURL : undefined;
|
|
73
75
|
if (!url && !structureData) {
|
|
74
76
|
return;
|
|
75
77
|
}
|
|
@@ -15,7 +15,7 @@ export default function useAlphaFoldDBSearch({ feature, view, }: {
|
|
|
15
15
|
sequenceSearchType: SequenceSearchType;
|
|
16
16
|
setSequenceSearchType: import("react").Dispatch<import("react").SetStateAction<SequenceSearchType>>;
|
|
17
17
|
selectedUniprotId: string | undefined;
|
|
18
|
-
setSelectedUniprotId: (
|
|
18
|
+
setSelectedUniprotId: import("react").Dispatch<import("react").SetStateAction<string | undefined>>;
|
|
19
19
|
userSelection: string | undefined;
|
|
20
20
|
setUserSelection: import("react").Dispatch<import("react").SetStateAction<string | undefined>>;
|
|
21
21
|
transcriptOptions: Feature[];
|
|
@@ -29,9 +29,6 @@ export default function useAlphaFoldDBSearch({ feature, view, }: {
|
|
|
29
29
|
seq: string;
|
|
30
30
|
} | undefined;
|
|
31
31
|
uniprotEntries: import("../services/lookupMethods").UniProtEntry[];
|
|
32
|
-
predictions: import("./useAlphaFoldUrl").AlphaFoldPrediction[] | undefined;
|
|
33
|
-
selectedEntryIndex: number;
|
|
34
|
-
setSelectedEntryIndex: import("react").Dispatch<import("react").SetStateAction<number>>;
|
|
35
32
|
recognizedIds: string[];
|
|
36
33
|
geneName: string | undefined;
|
|
37
34
|
featureUniprotId: string | undefined;
|
|
@@ -50,7 +47,6 @@ export default function useAlphaFoldDBSearch({ feature, view, }: {
|
|
|
50
47
|
selectedTableAccession: string | undefined;
|
|
51
48
|
showUniprotResults: boolean;
|
|
52
49
|
showNoResults: boolean;
|
|
53
|
-
showAlphaFoldEntrySelector: boolean;
|
|
54
50
|
showSequenceSearchStatus: boolean;
|
|
55
51
|
showAlphaFoldDBSearchStatus: boolean;
|
|
56
52
|
isLoading: boolean;
|
|
@@ -3,9 +3,10 @@ import useAlphaFoldData from './useAlphaFoldData';
|
|
|
3
3
|
import useAlphaFoldSequenceSearch from './useAlphaFoldSequenceSearch';
|
|
4
4
|
import useDebouncedValue from './useDebouncedValue';
|
|
5
5
|
import useIsoformProteinSequences from './useIsoformProteinSequences';
|
|
6
|
+
import useTranscriptSelection from './useTranscriptSelection';
|
|
6
7
|
import useUniProtSearch from './useUniProtSearch';
|
|
7
8
|
import getSearchDescription from '../utils/getSearchDescription';
|
|
8
|
-
import { extractFeatureIdentifiers, getId, getTranscriptFeatures,
|
|
9
|
+
import { extractFeatureIdentifiers, getId, getTranscriptFeatures, stripStopCodon, } from '../utils/util';
|
|
9
10
|
export default function useAlphaFoldDBSearch({ feature, view, }) {
|
|
10
11
|
const [lookupMode, setLookupMode] = useState('auto');
|
|
11
12
|
const [manualUniprotId, setManualUniprotId] = useState('');
|
|
@@ -13,7 +14,6 @@ export default function useAlphaFoldDBSearch({ feature, view, }) {
|
|
|
13
14
|
const [selectedQueryId, setSelectedQueryId] = useState(geneIds.recognizedIds[0] ?? 'auto');
|
|
14
15
|
const [sequenceSearchType, setSequenceSearchType] = useState('md5');
|
|
15
16
|
const [selectedUniprotId, setSelectedUniprotId] = useState();
|
|
16
|
-
const [userTranscriptId, setUserTranscriptId] = useState();
|
|
17
17
|
const transcriptOptions = getTranscriptFeatures(feature);
|
|
18
18
|
const featureUniprotId = geneIds.uniprotId;
|
|
19
19
|
const effectiveLookupMode = lookupMode === 'auto' && featureUniprotId ? 'feature' : lookupMode;
|
|
@@ -38,18 +38,15 @@ export default function useAlphaFoldDBSearch({ feature, view, }) {
|
|
|
38
38
|
: effectiveLookupMode === 'manual'
|
|
39
39
|
? debouncedManualUniprotId
|
|
40
40
|
: undefined;
|
|
41
|
-
const {
|
|
41
|
+
const { isLoading: isAlphaFoldLoading, error: alphaFoldError, url: alphaFoldUrl, confidenceUrl: alphaFoldConfidenceUrl, structureSequence: alphaFoldStructureSequence, } = useAlphaFoldData({
|
|
42
42
|
uniprotId: isSequenceMode ? undefined : uniprotId,
|
|
43
43
|
});
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
})?.id();
|
|
51
|
-
}
|
|
52
|
-
const effectiveTranscriptId = userTranscriptId ?? autoTranscriptId;
|
|
44
|
+
const { userSelection: effectiveTranscriptId, setUserSelection } = useTranscriptSelection({
|
|
45
|
+
options: transcriptOptions,
|
|
46
|
+
isoformSequences,
|
|
47
|
+
structureSequence: alphaFoldStructureSequence,
|
|
48
|
+
resetKey: uniprotId,
|
|
49
|
+
});
|
|
53
50
|
const selectedTranscript = transcriptOptions.find(f => getId(f) === effectiveTranscriptId);
|
|
54
51
|
const userSelectedProteinSequence = effectiveTranscriptId
|
|
55
52
|
? isoformSequences?.[effectiveTranscriptId]
|
|
@@ -68,10 +65,6 @@ export default function useAlphaFoldDBSearch({ feature, view, }) {
|
|
|
68
65
|
? seqSearchStructureSequence
|
|
69
66
|
: alphaFoldStructureSequence;
|
|
70
67
|
const finalUniprotId = isSequenceMode ? seqSearchUniprotId : uniprotId;
|
|
71
|
-
const setSelectedUniprotIdWithReset = (id) => {
|
|
72
|
-
setSelectedUniprotId(id);
|
|
73
|
-
setUserTranscriptId(undefined);
|
|
74
|
-
};
|
|
75
68
|
const loadingStatuses = [
|
|
76
69
|
isLookupLoading && 'Looking up UniProt ID',
|
|
77
70
|
isIsoformLoading && 'Loading protein sequences from transcript isoforms',
|
|
@@ -96,17 +89,14 @@ export default function useAlphaFoldDBSearch({ feature, view, }) {
|
|
|
96
89
|
sequenceSearchType,
|
|
97
90
|
setSequenceSearchType,
|
|
98
91
|
selectedUniprotId,
|
|
99
|
-
setSelectedUniprotId
|
|
92
|
+
setSelectedUniprotId,
|
|
100
93
|
userSelection: effectiveTranscriptId,
|
|
101
|
-
setUserSelection
|
|
94
|
+
setUserSelection,
|
|
102
95
|
transcriptOptions,
|
|
103
96
|
selectedTranscript,
|
|
104
97
|
isoformSequences,
|
|
105
98
|
userSelectedProteinSequence,
|
|
106
99
|
uniprotEntries,
|
|
107
|
-
predictions,
|
|
108
|
-
selectedEntryIndex,
|
|
109
|
-
setSelectedEntryIndex,
|
|
110
100
|
recognizedIds: geneIds.recognizedIds,
|
|
111
101
|
geneName: geneIds.geneName,
|
|
112
102
|
featureUniprotId,
|
|
@@ -144,7 +134,6 @@ export default function useAlphaFoldDBSearch({ feature, view, }) {
|
|
|
144
134
|
isAutoMode &&
|
|
145
135
|
!isLookupLoading &&
|
|
146
136
|
uniprotEntries.length === 0,
|
|
147
|
-
showAlphaFoldEntrySelector: !!predictions && !isSequenceMode,
|
|
148
137
|
showSequenceSearchStatus: isSequenceMode,
|
|
149
138
|
showAlphaFoldDBSearchStatus: !!finalStructureSequence && !!finalUniprotId && !isSequenceMode,
|
|
150
139
|
isLoading,
|
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
export default function useAlphaFoldData({ uniprotId
|
|
1
|
+
export default function useAlphaFoldData({ uniprotId }: {
|
|
2
2
|
uniprotId?: string;
|
|
3
|
-
useApiSearch?: boolean;
|
|
4
3
|
}): {
|
|
5
|
-
predictions: import("./useAlphaFoldUrl").AlphaFoldPrediction[] | undefined;
|
|
6
4
|
isLoading: boolean;
|
|
7
5
|
error: any;
|
|
8
|
-
selectedEntryIndex: number;
|
|
9
|
-
setSelectedEntryIndex: import("react").Dispatch<import("react").SetStateAction<number>>;
|
|
10
|
-
selectedPrediction: import("./useAlphaFoldUrl").AlphaFoldPrediction | undefined;
|
|
11
6
|
url: string | undefined;
|
|
12
7
|
confidenceUrl: string | undefined;
|
|
13
8
|
structureSequence: string | undefined;
|
|
@@ -1,34 +1,18 @@
|
|
|
1
|
-
import { useState } from 'react';
|
|
2
|
-
import useAlphaFoldUrl from './useAlphaFoldUrl';
|
|
3
1
|
import useRemoteStructureFileSequence from './useRemoteStructureFileSequence';
|
|
4
2
|
import { getAlphaFoldConfidenceUrl, getAlphaFoldStructureUrl, } from '../utils/launchViewUtils';
|
|
5
|
-
export default function useAlphaFoldData({ uniprotId
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
? getAlphaFoldStructureUrl(uniprotId)
|
|
9
|
-
: undefined;
|
|
10
|
-
const hardcodedConfidenceUrl = uniprotId
|
|
3
|
+
export default function useAlphaFoldData({ uniprotId }) {
|
|
4
|
+
const url = uniprotId ? getAlphaFoldStructureUrl(uniprotId) : undefined;
|
|
5
|
+
const confidenceUrl = uniprotId
|
|
11
6
|
? getAlphaFoldConfidenceUrl(uniprotId)
|
|
12
7
|
: undefined;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const url = useApiSearch ? selectedPrediction?.cifUrl : hardcodedUrl;
|
|
17
|
-
const confidenceUrl = selectedPrediction?.plddtDocUrl ?? hardcodedConfidenceUrl;
|
|
18
|
-
// Always fetch sequence from structure file
|
|
19
|
-
const { sequences, isLoading: isSequenceLoading, error: sequenceError, } = useRemoteStructureFileSequence({ url });
|
|
20
|
-
const structureSequence = sequences?.[0];
|
|
21
|
-
const isLoading = isApiLoading || isSequenceLoading;
|
|
22
|
-
const error = apiError ?? sequenceError;
|
|
8
|
+
const { sequences, isLoading, error } = useRemoteStructureFileSequence({
|
|
9
|
+
url,
|
|
10
|
+
});
|
|
23
11
|
return {
|
|
24
|
-
predictions,
|
|
25
12
|
isLoading,
|
|
26
13
|
error,
|
|
27
|
-
selectedEntryIndex,
|
|
28
|
-
setSelectedEntryIndex,
|
|
29
|
-
selectedPrediction,
|
|
30
14
|
url,
|
|
31
15
|
confidenceUrl,
|
|
32
|
-
structureSequence,
|
|
16
|
+
structureSequence: sequences?.[0],
|
|
33
17
|
};
|
|
34
18
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { Feature } from '@jbrowse/core/util';
|
|
2
|
-
export default function useTranscriptSelection({ options, isoformSequences, structureSequence, }: {
|
|
2
|
+
export default function useTranscriptSelection({ options, isoformSequences, structureSequence, resetKey, }: {
|
|
3
3
|
options: Feature[];
|
|
4
4
|
isoformSequences?: Record<string, {
|
|
5
5
|
feature: Feature;
|
|
6
6
|
seq: string;
|
|
7
7
|
}>;
|
|
8
8
|
structureSequence?: string;
|
|
9
|
+
resetKey?: string;
|
|
9
10
|
}): {
|
|
10
11
|
userSelection: string | undefined;
|
|
11
12
|
setUserSelection: import("react").Dispatch<import("react").SetStateAction<string | undefined>>;
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { useMemo, useState } from 'react';
|
|
2
2
|
import { selectBestTranscript } from '../utils/util';
|
|
3
|
-
export default function useTranscriptSelection({ options, isoformSequences, structureSequence, }) {
|
|
3
|
+
export default function useTranscriptSelection({ options, isoformSequences, structureSequence, resetKey, }) {
|
|
4
4
|
const [userSelection, setUserSelection] = useState();
|
|
5
|
+
const [prevResetKey, setPrevResetKey] = useState(resetKey);
|
|
6
|
+
if (resetKey !== prevResetKey) {
|
|
7
|
+
setPrevResetKey(resetKey);
|
|
8
|
+
setUserSelection(undefined);
|
|
9
|
+
}
|
|
5
10
|
const autoSelection = useMemo(() => isoformSequences !== undefined
|
|
6
|
-
? selectBestTranscript({
|
|
11
|
+
? selectBestTranscript({
|
|
12
|
+
options,
|
|
13
|
+
isoformSequences,
|
|
14
|
+
structureSequence,
|
|
15
|
+
})?.id()
|
|
7
16
|
: undefined, [options, structureSequence, isoformSequences]);
|
|
8
|
-
|
|
9
|
-
return { userSelection: effectiveSelection, setUserSelection };
|
|
17
|
+
return { userSelection: userSelection ?? autoSelection, setUserSelection };
|
|
10
18
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { UniProtEntry } from '../services/lookupMethods';
|
|
2
|
-
export default function useUniProtSearch({ recognizedIds,
|
|
2
|
+
export default function useUniProtSearch({ recognizedIds, geneId, geneName, selectedQueryId, enabled, }: {
|
|
3
3
|
recognizedIds?: string[];
|
|
4
|
-
uniprotId?: string;
|
|
5
4
|
geneId?: string;
|
|
6
5
|
geneName?: string;
|
|
7
6
|
selectedQueryId?: string;
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import useSWR from 'swr';
|
|
2
2
|
import { searchUniProtEntries } from '../services/lookupMethods';
|
|
3
3
|
import { isRecognizedDatabaseId } from '../utils/util';
|
|
4
|
-
export default function useUniProtSearch({ recognizedIds = [],
|
|
5
|
-
// If selected ID is a UniProt accession (prefixed with uniprot:), return it directly
|
|
6
|
-
const isDirectUniProt = selectedQueryId.startsWith('uniprot:');
|
|
7
|
-
const directUniProtId = isDirectUniProt
|
|
8
|
-
? selectedQueryId.replace('uniprot:', '')
|
|
9
|
-
: undefined;
|
|
4
|
+
export default function useUniProtSearch({ recognizedIds = [], geneId, geneName, selectedQueryId = 'auto', enabled = true, }) {
|
|
10
5
|
// Determine what to search based on selectedQueryId
|
|
11
6
|
let idsToSearch = [];
|
|
12
7
|
let geneNameToSearch;
|
|
@@ -20,16 +15,10 @@ export default function useUniProtSearch({ recognizedIds = [], uniprotId, geneId
|
|
|
20
15
|
else if (isRecognizedDatabaseId(selectedQueryId)) {
|
|
21
16
|
idsToSearch = [selectedQueryId];
|
|
22
17
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
? [
|
|
28
|
-
'uniprotSearch',
|
|
29
|
-
selectedQueryId,
|
|
30
|
-
idsToSearch.join(','),
|
|
31
|
-
geneNameToSearch,
|
|
32
|
-
]
|
|
18
|
+
const hasValidId = idsToSearch.some(id => isRecognizedDatabaseId(id)) ||
|
|
19
|
+
Boolean(geneNameToSearch);
|
|
20
|
+
const { data, error, isLoading } = useSWR(enabled && hasValidId
|
|
21
|
+
? ['uniprotSearch', selectedQueryId, idsToSearch.join(','), geneNameToSearch]
|
|
33
22
|
: null, async () => searchUniProtEntries({
|
|
34
23
|
recognizedIds: idsToSearch,
|
|
35
24
|
geneId,
|
|
@@ -40,15 +29,6 @@ export default function useUniProtSearch({ recognizedIds = [], uniprotId, geneId
|
|
|
40
29
|
revalidateIfStale: false,
|
|
41
30
|
keepPreviousData: true,
|
|
42
31
|
});
|
|
43
|
-
// If direct UniProt accession selected, return it as a synthetic entry
|
|
44
|
-
if (isDirectUniProt && directUniProtId) {
|
|
45
|
-
return {
|
|
46
|
-
entries: [{ accession: directUniProtId, isReviewed: true }],
|
|
47
|
-
isLoading: false,
|
|
48
|
-
error: undefined,
|
|
49
|
-
hasValidId: true,
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
32
|
return {
|
|
53
33
|
entries: data ?? [],
|
|
54
34
|
isLoading,
|
|
@@ -75,16 +75,7 @@ export function launch3DProteinView({ session, view, feature, selectedTranscript
|
|
|
75
75
|
displayName: displayName ??
|
|
76
76
|
formatViewName('Protein view', feature, selectedTranscript, uniprotId),
|
|
77
77
|
};
|
|
78
|
-
|
|
79
|
-
console.log('[protein3d debug] addView ProteinView snapshot:', JSON.stringify(snap, (_k, v) => (typeof v === 'function' ? '<fn>' : v), 2));
|
|
80
|
-
try {
|
|
81
|
-
return session.addView('ProteinView', snap);
|
|
82
|
-
}
|
|
83
|
-
catch (e) {
|
|
84
|
-
// eslint-disable-next-line no-console
|
|
85
|
-
console.log('[protein3d debug] addView threw:', e.message);
|
|
86
|
-
throw e;
|
|
87
|
-
}
|
|
78
|
+
return session.addView('ProteinView', snap);
|
|
88
79
|
}
|
|
89
80
|
export async function launch1DProteinView({ session, view, feature, selectedTranscript, uniprotId, confidenceUrl, }) {
|
|
90
81
|
if (!uniprotId || !isSessionWithAddTracks(session)) {
|