@apollo-annotation/jbrowse-plugin-apollo 0.1.5 → 0.1.7
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/index.esm.js +206 -115
- package/dist/index.esm.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.development.js +206 -115
- 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 +257 -117
- 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/package.json +6 -6
- package/src/ApolloInternetAccount/addMenuItems.ts +2 -4
- package/src/ApolloInternetAccount/components/AuthTypeSelector.tsx +14 -6
- package/src/ApolloInternetAccount/model.ts +24 -16
- package/src/ApolloJobModel.ts +2 -0
- package/src/ApolloSequenceAdapter/ApolloSequenceAdapter.ts +4 -0
- package/src/ApolloSixFrameRenderer/ApolloSixFrameRenderer.tsx +1 -0
- package/src/ApolloSixFrameRenderer/components/ApolloRendering.tsx +16 -3
- package/src/ApolloTextSearchAdapter/ApolloTextSearchAdapter.ts +5 -0
- package/src/BackendDrivers/CollaborationServerDriver.ts +10 -4
- package/src/BackendDrivers/DesktopFileDriver.ts +1 -0
- package/src/BackendDrivers/InMemoryFileDriver.ts +1 -0
- package/src/ChangeManager.ts +3 -0
- package/src/FeatureDetailsWidget/Attributes.tsx +4 -1
- package/src/FeatureDetailsWidget/BasicInformation.tsx +4 -2
- package/src/FeatureDetailsWidget/NumberTextField.tsx +4 -1
- package/src/FeatureDetailsWidget/RelatedFeature.tsx +16 -3
- package/src/FeatureDetailsWidget/Sequence.tsx +1 -0
- package/src/FeatureDetailsWidget/StringTextField.tsx +4 -1
- package/src/FeatureDetailsWidget/model.ts +2 -0
- package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +9 -2
- package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +2 -0
- package/src/LinearApolloDisplay/glyphs/CanonicalGeneGlyph.ts +9 -4
- package/src/LinearApolloDisplay/glyphs/GenericChildGlyph.ts +4 -1
- package/src/LinearApolloDisplay/glyphs/Glyph.ts +5 -1
- package/src/LinearApolloDisplay/glyphs/ImplicitExonGeneGlyph.ts +8 -2
- package/src/LinearApolloDisplay/stateModel/base.ts +7 -2
- package/src/LinearApolloDisplay/stateModel/getGlyph.ts +1 -0
- package/src/LinearApolloDisplay/stateModel/glyphs.ts +2 -0
- package/src/LinearApolloDisplay/stateModel/layouts.ts +3 -0
- package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +3 -1
- package/src/LinearApolloDisplay/stateModel/rendering.ts +3 -2
- package/src/LinearApolloDisplay/types.ts +1 -1
- package/src/OntologyManager/OntologyStore/fulltext.ts +1 -0
- package/src/OntologyManager/OntologyStore/index.test.ts +3 -1
- package/src/OntologyManager/OntologyStore/index.ts +4 -5
- package/src/OntologyManager/OntologyStore/indexeddb-storage.ts +3 -2
- package/src/SixFrameFeatureDisplay/stateModel.ts +17 -5
- package/src/TabularEditor/HybridGrid/Feature.tsx +7 -2
- package/src/TabularEditor/HybridGrid/FeatureAttributes.tsx +1 -0
- package/src/TabularEditor/HybridGrid/HybridGrid.tsx +2 -2
- package/src/TabularEditor/HybridGrid/NumberCell.tsx +3 -1
- package/src/TabularEditor/HybridGrid/ToolBar.tsx +9 -2
- package/src/components/AddAssembly.tsx +16 -8
- package/src/components/AddChildFeature.tsx +9 -4
- package/src/components/AddFeature.tsx +11 -5
- package/src/components/CopyFeature.tsx +11 -6
- package/src/components/DeleteAssembly.tsx +7 -4
- package/src/components/DeleteFeature.tsx +4 -1
- package/src/components/Dialog.tsx +1 -0
- package/src/components/DownloadGFF3.tsx +7 -2
- package/src/components/ImportFeatures.tsx +9 -3
- package/src/components/ManageChecks.tsx +10 -4
- package/src/components/ManageUsers.tsx +13 -4
- package/src/components/ModifyFeatureAttribute.tsx +4 -1
- package/src/components/OntologyTermAutocomplete.tsx +7 -4
- package/src/components/OntologyTermMultiSelect.tsx +2 -2
- package/src/components/OpenLocalFile.tsx +6 -3
- package/src/components/ViewChangeLog.tsx +13 -4
- package/src/components/ViewCheckResults.tsx +8 -2
- package/src/extensions/annotationFromPileup.ts +7 -2
- package/src/index.ts +4 -0
- package/src/makeDisplayComponent.tsx +4 -4
- package/src/session/ClientDataStore.ts +5 -0
- package/src/session/session.ts +9 -17
- package/src/util/loadAssemblyIntoClient.ts +4 -3
package/dist/index.esm.js
CHANGED
|
@@ -48,7 +48,7 @@ import ExpandLessIcon from '@mui/icons-material/ExpandLess';
|
|
|
48
48
|
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
|
49
49
|
import ErrorIcon from '@mui/icons-material/Error';
|
|
50
50
|
|
|
51
|
-
var version = "0.1.
|
|
51
|
+
var version = "0.1.7";
|
|
52
52
|
|
|
53
53
|
const ApolloConfigSchema = ConfigurationSchema('ApolloInternetAccount', {
|
|
54
54
|
baseURL: {
|
|
@@ -120,7 +120,7 @@ async function checkFeatures(assembly) {
|
|
|
120
120
|
for (const ref of assembly.refSeqs.values()) {
|
|
121
121
|
for (const feature of ref.features.values()) {
|
|
122
122
|
for (const check of checkRegistry.getChecks().values()) {
|
|
123
|
-
const result = await check.checkFeature(getSnapshot(feature),
|
|
123
|
+
const result = await check.checkFeature(getSnapshot(feature), (start, stop) => Promise.resolve(ref.getSequence(start, stop)));
|
|
124
124
|
checkResults.push(...result);
|
|
125
125
|
}
|
|
126
126
|
}
|
|
@@ -212,14 +212,14 @@ function createFeature(gff3Feature) {
|
|
|
212
212
|
}
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
|
-
if (childFeatures
|
|
215
|
+
if (childFeatures.length > 0) {
|
|
216
216
|
const children = {};
|
|
217
217
|
for (const childFeature of childFeatures) {
|
|
218
218
|
const child = createFeature(childFeature);
|
|
219
219
|
children[child._id] = child;
|
|
220
220
|
// Add value to gffId
|
|
221
221
|
child.attributes?._id
|
|
222
|
-
? (child.gffId = child.attributes
|
|
222
|
+
? (child.gffId = child.attributes._id.toString())
|
|
223
223
|
: (child.gffId = child._id);
|
|
224
224
|
}
|
|
225
225
|
feature.children = children;
|
|
@@ -321,6 +321,7 @@ function getApolloInternetAccount(session) {
|
|
|
321
321
|
return internetAccounts.find((ia) => ia.type === 'ApolloInternetAccount');
|
|
322
322
|
}
|
|
323
323
|
|
|
324
|
+
/* eslint-disable @typescript-eslint/unbound-method */
|
|
324
325
|
const useStyles$f = makeStyles()((theme) => ({
|
|
325
326
|
dialogTitle: {
|
|
326
327
|
background: theme.palette.primary.main,
|
|
@@ -343,6 +344,7 @@ const Dialog = observer(function JBrowseDialog(props) {
|
|
|
343
344
|
React__default.createElement(CloseIcon, null))) }));
|
|
344
345
|
});
|
|
345
346
|
|
|
347
|
+
/* eslint-disable @typescript-eslint/no-unsafe-enum-comparison */
|
|
346
348
|
var FileType;
|
|
347
349
|
(function (FileType) {
|
|
348
350
|
FileType["GFF3"] = "text/x-gff3";
|
|
@@ -550,21 +552,29 @@ function AddAssembly({ changeManager, handleClose, session, }) {
|
|
|
550
552
|
React__default.createElement(FormControlLabel, { value: FileType.EXTERNAL, control: React__default.createElement(Radio, null), label: "External", disabled: submitted && !errorMessage }))),
|
|
551
553
|
fileType === FileType.EXTERNAL ? (React__default.createElement(Box, { style: { marginTop: 20 } },
|
|
552
554
|
React__default.createElement(Typography, { variant: "caption" }, "Enter FASTA and FASTA index(es) URL"),
|
|
553
|
-
React__default.createElement(TextField, { margin: "dense", helperText: "Can be bgz-compressed", id: "fasta", label: "FASTA", type: "TextField", fullWidth: true, variant: "outlined", error: !validFastaFile, onChange: (e) =>
|
|
555
|
+
React__default.createElement(TextField, { margin: "dense", helperText: "Can be bgz-compressed", id: "fasta", label: "FASTA", type: "TextField", fullWidth: true, variant: "outlined", error: !validFastaFile, onChange: (e) => {
|
|
556
|
+
setFastaFile(e.target.value);
|
|
557
|
+
}, disabled: submitted && !errorMessage, InputProps: {
|
|
554
558
|
startAdornment: (React__default.createElement(InputAdornment, { position: "start" },
|
|
555
559
|
React__default.createElement(LinkIcon, null))),
|
|
556
560
|
} }),
|
|
557
|
-
React__default.createElement(TextField, { margin: "dense", id: "fasta-index", label: "FASTA Index", helperText: ".fai or .gz.fai", type: "TextField", fullWidth: true, variant: "outlined", error: !validFastaIndexFile, onChange: (e) =>
|
|
561
|
+
React__default.createElement(TextField, { margin: "dense", id: "fasta-index", label: "FASTA Index", helperText: ".fai or .gz.fai", type: "TextField", fullWidth: true, variant: "outlined", error: !validFastaIndexFile, onChange: (e) => {
|
|
562
|
+
setFastaIndexFile(e.target.value);
|
|
563
|
+
}, disabled: submitted && !errorMessage, InputProps: {
|
|
558
564
|
startAdornment: (React__default.createElement(InputAdornment, { position: "start" },
|
|
559
565
|
React__default.createElement(LinkIcon, null))),
|
|
560
566
|
} }),
|
|
561
|
-
React__default.createElement(TextField, { margin: "dense", id: "fasta-gzi-index", label: "FASTA GZI Index", helperText: "Only for bgz-compressed FASTA, .gz.gzi", type: "TextField", fullWidth: true, variant: "outlined", error: Boolean(fastaGziIndexFile) && !validFastaGziIndexFile, onChange: (e) =>
|
|
567
|
+
React__default.createElement(TextField, { margin: "dense", id: "fasta-gzi-index", label: "FASTA GZI Index", helperText: "Only for bgz-compressed FASTA, .gz.gzi", type: "TextField", fullWidth: true, variant: "outlined", error: Boolean(fastaGziIndexFile) && !validFastaGziIndexFile, onChange: (e) => {
|
|
568
|
+
setFastaGziIndexFile(e.target.value);
|
|
569
|
+
}, disabled: submitted && !errorMessage, InputProps: {
|
|
562
570
|
startAdornment: (React__default.createElement(InputAdornment, { position: "start" },
|
|
563
571
|
React__default.createElement(LinkIcon, null))),
|
|
564
572
|
} }))) : (React__default.createElement(Box, { style: { marginTop: 20 } },
|
|
565
573
|
React__default.createElement("input", { type: "file", onChange: handleChangeFile, disabled: submitted && !errorMessage }),
|
|
566
574
|
React__default.createElement(FormGroup, null,
|
|
567
|
-
React__default.createElement(FormControlLabel, { control: React__default.createElement(Checkbox, { checked: fileType === FileType.GFF3 && importFeatures, onChange: () =>
|
|
575
|
+
React__default.createElement(FormControlLabel, { control: React__default.createElement(Checkbox, { checked: fileType === FileType.GFF3 && importFeatures, onChange: () => {
|
|
576
|
+
setImportFeatures(!importFeatures);
|
|
577
|
+
}, disabled: fileType !== FileType.GFF3 ||
|
|
568
578
|
(submitted && !errorMessage) }), label: "Also load features from GFF3 file" }))))),
|
|
569
579
|
React__default.createElement(DialogActions, null,
|
|
570
580
|
React__default.createElement(Button, { disabled: !validAsm ||
|
|
@@ -751,7 +761,7 @@ function expandPrefixes(uri, prefixes) {
|
|
|
751
761
|
return uri;
|
|
752
762
|
}
|
|
753
763
|
|
|
754
|
-
/* eslint-disable
|
|
764
|
+
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
755
765
|
/** special value of jsonPath that gets the IRI (that is, ID) of the node with the configured prefixes applied */
|
|
756
766
|
const PREFIXED_ID_PATH = '$PREFIXED_ID';
|
|
757
767
|
/** small wrapper for jsonpath.query that intercepts requests for the special prefixed ID path */
|
|
@@ -935,6 +945,7 @@ function isDeprecated(thing) {
|
|
|
935
945
|
return Boolean(thing.meta?.deprecated);
|
|
936
946
|
}
|
|
937
947
|
|
|
948
|
+
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
938
949
|
/** schema version we are currently on, used for the IndexedDB schema open call */
|
|
939
950
|
const schemaVersion = 2;
|
|
940
951
|
/** open the IndexedDB and create the DB schema if necessary */
|
|
@@ -1064,10 +1075,11 @@ async function isDatabaseCurrent(db) {
|
|
|
1064
1075
|
return false;
|
|
1065
1076
|
}
|
|
1066
1077
|
// check that the index paths and prefixes are the same as our current ones
|
|
1067
|
-
return (equal(this.options.prefixes, meta.storeOptions
|
|
1068
|
-
equal(this.options.textIndexing, meta.storeOptions
|
|
1078
|
+
return (equal(this.options.prefixes, meta.storeOptions.prefixes) &&
|
|
1079
|
+
equal(this.options.textIndexing, meta.storeOptions.textIndexing));
|
|
1069
1080
|
}
|
|
1070
1081
|
|
|
1082
|
+
/* eslint-disable @typescript-eslint/no-throw-literal */
|
|
1071
1083
|
/**
|
|
1072
1084
|
* @deprecated use the one from jbrowse core when it is published
|
|
1073
1085
|
**/
|
|
@@ -1162,7 +1174,7 @@ class OntologyStore {
|
|
|
1162
1174
|
const myTx = tx ?? db.transaction('nodes');
|
|
1163
1175
|
return myTx.objectStore('nodes').count();
|
|
1164
1176
|
}
|
|
1165
|
-
|
|
1177
|
+
unique(nodes) {
|
|
1166
1178
|
const seen = new Map();
|
|
1167
1179
|
const result = [];
|
|
1168
1180
|
for (const node of nodes) {
|
|
@@ -1227,10 +1239,7 @@ class OntologyStore {
|
|
|
1227
1239
|
const resultIds = new Set();
|
|
1228
1240
|
async function recur(queryIds) {
|
|
1229
1241
|
await Promise.all([...queryIds].map(async (queryId) => {
|
|
1230
|
-
const theseResults = (await myTx
|
|
1231
|
-
.objectStore('edges')
|
|
1232
|
-
.index(queryIndex)
|
|
1233
|
-
.getAll(queryId))
|
|
1242
|
+
const theseResults = (await myTx.objectStore('edges').index(queryIndex).getAll(queryId))
|
|
1234
1243
|
.filter((element) => filterEdge(element))
|
|
1235
1244
|
.map((edge) => edge[resultProp]);
|
|
1236
1245
|
if (theseResults.length > 0) {
|
|
@@ -1497,13 +1506,13 @@ async function fetchValidDescendantTerms(parentFeature, ontologyStore, _signal)
|
|
|
1497
1506
|
return subpartTerms;
|
|
1498
1507
|
}
|
|
1499
1508
|
|
|
1509
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
1500
1510
|
function OntologyTermAutocomplete({ fetchValidTerms, filterTerms: filterTermsProp, includeDeprecated, onChange, ontologyName, ontologyVersion, renderInput, session, style, value: valueString, }) {
|
|
1501
1511
|
const [open, setOpen] = useState(false);
|
|
1502
1512
|
const [termChoices, setTermChoices] = useState();
|
|
1503
1513
|
const [currentOntologyTermInvalid, setCurrentOntologyTermInvalid] = useState('');
|
|
1504
1514
|
const [currentOntologyTerm, setCurrentOntologyTerm] = useState();
|
|
1505
|
-
const ontologyManager = session.apolloDataStore
|
|
1506
|
-
.ontologyManager;
|
|
1515
|
+
const { ontologyManager } = session.apolloDataStore;
|
|
1507
1516
|
const ontologyStore = ontologyManager.findOntology(ontologyName, ontologyVersion)?.dataStore;
|
|
1508
1517
|
const needToLoadTermChoices = ontologyStore && open && !termChoices;
|
|
1509
1518
|
const needToLoadCurrentTerm = ontologyStore && !currentOntologyTerm;
|
|
@@ -1563,7 +1572,7 @@ function OntologyTermAutocomplete({ fetchValidTerms, filterTerms: filterTermsPro
|
|
|
1563
1572
|
session,
|
|
1564
1573
|
fetchValidTerms,
|
|
1565
1574
|
]);
|
|
1566
|
-
const handleChange =
|
|
1575
|
+
const handleChange = (event, newValue) => {
|
|
1567
1576
|
if (!newValue) {
|
|
1568
1577
|
return;
|
|
1569
1578
|
}
|
|
@@ -1669,7 +1678,7 @@ function AddChildFeature({ changeManager, handleClose, session, sourceAssemblyId
|
|
|
1669
1678
|
},
|
|
1670
1679
|
parentFeatureId: sourceFeature._id,
|
|
1671
1680
|
});
|
|
1672
|
-
await changeManager.submit
|
|
1681
|
+
await changeManager.submit(change);
|
|
1673
1682
|
notify('Feature added successfully', 'success');
|
|
1674
1683
|
handleClose();
|
|
1675
1684
|
event.preventDefault();
|
|
@@ -1685,7 +1694,7 @@ function AddChildFeature({ changeManager, handleClose, session, sourceAssemblyId
|
|
|
1685
1694
|
setShowPhase(false);
|
|
1686
1695
|
}
|
|
1687
1696
|
}
|
|
1688
|
-
|
|
1697
|
+
function handleChangePhase(e) {
|
|
1689
1698
|
setErrorMessage('');
|
|
1690
1699
|
setPhase(e.target.value);
|
|
1691
1700
|
switch (Number(e.target.value)) {
|
|
@@ -1711,8 +1720,12 @@ function AddChildFeature({ changeManager, handleClose, session, sourceAssemblyId
|
|
|
1711
1720
|
return (React__default.createElement(Dialog, { open: true, title: "Add new child feature", handleClose: handleClose, maxWidth: false, "data-testid": "add-feature-dialog" },
|
|
1712
1721
|
React__default.createElement("form", { onSubmit: onSubmit },
|
|
1713
1722
|
React__default.createElement(DialogContent, { style: { display: 'flex', flexDirection: 'column' } },
|
|
1714
|
-
React__default.createElement(TextField, { margin: "dense", id: "start", label: "Start", type: "number", fullWidth: true, variant: "outlined", value: start, onChange: (e) =>
|
|
1715
|
-
|
|
1723
|
+
React__default.createElement(TextField, { margin: "dense", id: "start", label: "Start", type: "number", fullWidth: true, variant: "outlined", value: start, onChange: (e) => {
|
|
1724
|
+
setStart(e.target.value);
|
|
1725
|
+
} }),
|
|
1726
|
+
React__default.createElement(TextField, { margin: "dense", id: "end", label: "End", type: "number", fullWidth: true, variant: "outlined", value: end, onChange: (e) => {
|
|
1727
|
+
setEnd(e.target.value);
|
|
1728
|
+
}, error: error, helperText: error ? '"End" must be greater than "Start"' : null }),
|
|
1716
1729
|
React__default.createElement(OntologyTermAutocomplete, { session: session, ontologyName: "Sequence Ontology", style: { width: 170 }, value: type, filterTerms: isOntologyClass, fetchValidTerms: fetchValidTerms.bind(null, sourceFeature), renderInput: (params) => (React__default.createElement(TextField, { ...params, label: "Type", variant: "outlined", fullWidth: true, error: Boolean(typeWarningText), helperText: typeWarningText })), onChange: (oldValue, newValue) => {
|
|
1717
1730
|
if (newValue) {
|
|
1718
1731
|
handleChangeType(newValue);
|
|
@@ -1766,7 +1779,7 @@ function CopyFeature({ changeManager, handleClose, session, sourceAssemblyId, so
|
|
|
1766
1779
|
const [selectedRefSeqId, setSelectedRefSeqId] = useState('');
|
|
1767
1780
|
const [start, setStart] = useState(sourceFeature.start);
|
|
1768
1781
|
const [errorMessage, setErrorMessage] = useState('');
|
|
1769
|
-
|
|
1782
|
+
function handleChangeAssembly(e) {
|
|
1770
1783
|
setSelectedAssemblyId(e.target.value);
|
|
1771
1784
|
}
|
|
1772
1785
|
useEffect(() => {
|
|
@@ -1790,9 +1803,11 @@ function CopyFeature({ changeManager, handleClose, session, sourceAssemblyId, so
|
|
|
1790
1803
|
setRefNames(newRefNames);
|
|
1791
1804
|
setSelectedRefSeqId(newRefNames[0]?._id || '');
|
|
1792
1805
|
}
|
|
1793
|
-
getRefNames().catch((error) =>
|
|
1806
|
+
getRefNames().catch((error) => {
|
|
1807
|
+
setErrorMessage(String(error));
|
|
1808
|
+
});
|
|
1794
1809
|
}, [selectedAssemblyId, assemblyManager]);
|
|
1795
|
-
|
|
1810
|
+
function handleChangeRefSeq(e) {
|
|
1796
1811
|
const refSeq = e.target.value;
|
|
1797
1812
|
setSelectedRefSeqId(refSeq);
|
|
1798
1813
|
}
|
|
@@ -1808,7 +1823,7 @@ function CopyFeature({ changeManager, handleClose, session, sourceAssemblyId, so
|
|
|
1808
1823
|
setErrorMessage(`Assembly not found: ${selectedAssemblyId}.`);
|
|
1809
1824
|
return;
|
|
1810
1825
|
}
|
|
1811
|
-
const canonicalRefName = assembly
|
|
1826
|
+
const canonicalRefName = assembly.getCanonicalRefName(selectedRefSeqId);
|
|
1812
1827
|
const region = assembly.regions?.find((r) => r.refName === canonicalRefName);
|
|
1813
1828
|
if (!region) {
|
|
1814
1829
|
setErrorMessage(`RefSeq not found: ${selectedRefSeqId}.`);
|
|
@@ -1864,7 +1879,7 @@ function CopyFeature({ changeManager, handleClose, session, sourceAssemblyId, so
|
|
|
1864
1879
|
copyFeature: true,
|
|
1865
1880
|
allIds: featureIds,
|
|
1866
1881
|
});
|
|
1867
|
-
await changeManager.submit
|
|
1882
|
+
await changeManager.submit(change);
|
|
1868
1883
|
notify('Feature copied successfully', 'success');
|
|
1869
1884
|
handleClose();
|
|
1870
1885
|
event.preventDefault();
|
|
@@ -1924,6 +1939,7 @@ function CopyFeature({ changeManager, handleClose, session, sourceAssemblyId, so
|
|
|
1924
1939
|
React__default.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
|
|
1925
1940
|
}
|
|
1926
1941
|
|
|
1942
|
+
/* eslint-disable @typescript-eslint/no-misused-promises */
|
|
1927
1943
|
function DeleteAssembly({ changeManager, handleClose, session, }) {
|
|
1928
1944
|
const { internetAccounts } = getRoot(session);
|
|
1929
1945
|
const [selectedAssembly, setSelectedAssembly] = useState();
|
|
@@ -1966,7 +1982,7 @@ function DeleteAssembly({ changeManager, handleClose, session, }) {
|
|
|
1966
1982
|
typeName: 'DeleteAssemblyChange',
|
|
1967
1983
|
assembly: selectedAssembly.name,
|
|
1968
1984
|
});
|
|
1969
|
-
await changeManager.submit
|
|
1985
|
+
await changeManager.submit(change, {
|
|
1970
1986
|
internetAccountId: selectedInternetAccount.internetAccountId,
|
|
1971
1987
|
});
|
|
1972
1988
|
handleClose();
|
|
@@ -1983,7 +1999,9 @@ function DeleteAssembly({ changeManager, handleClose, session, }) {
|
|
|
1983
1999
|
React__default.createElement(DialogContentText, null,
|
|
1984
2000
|
React__default.createElement("strong", { style: { color: 'red' } }, "NOTE: All assembly data will be deleted and this operation cannot be undone!")),
|
|
1985
2001
|
React__default.createElement(FormGroup, null,
|
|
1986
|
-
React__default.createElement(FormControlLabel, { control: React__default.createElement(Checkbox, { checked: confirmDelete, onChange: () =>
|
|
2002
|
+
React__default.createElement(FormControlLabel, { control: React__default.createElement(Checkbox, { checked: confirmDelete, onChange: () => {
|
|
2003
|
+
setconfirmDelete(!confirmDelete);
|
|
2004
|
+
} }), label: "I understand that all assembly data will be deleted" }))),
|
|
1987
2005
|
React__default.createElement(DialogActions, null,
|
|
1988
2006
|
React__default.createElement(Button, { disabled: !selectedAssembly || !confirmDelete, variant: "contained", type: "submit" }, "Delete"),
|
|
1989
2007
|
React__default.createElement(Button, { variant: "outlined", type: "submit", onClick: handleClose }, "Cancel"))),
|
|
@@ -2008,7 +2026,7 @@ function DeleteFeature({ changeManager, handleClose, selectedFeature, session, s
|
|
|
2008
2026
|
deletedFeature: getSnapshot(sourceFeature),
|
|
2009
2027
|
parentFeatureId: sourceFeature.parent?._id,
|
|
2010
2028
|
});
|
|
2011
|
-
await changeManager.submit
|
|
2029
|
+
await changeManager.submit(change);
|
|
2012
2030
|
notify('Feature deleted successfully', 'success');
|
|
2013
2031
|
handleClose();
|
|
2014
2032
|
event.preventDefault();
|
|
@@ -2110,7 +2128,7 @@ function DownloadGFF3({ handleClose, session }) {
|
|
|
2110
2128
|
});
|
|
2111
2129
|
}
|
|
2112
2130
|
for (const [, refSeq] of refSeqs) {
|
|
2113
|
-
const features = refSeq
|
|
2131
|
+
const { features } = refSeq;
|
|
2114
2132
|
if (!features) {
|
|
2115
2133
|
continue;
|
|
2116
2134
|
}
|
|
@@ -2139,6 +2157,7 @@ function DownloadGFF3({ handleClose, session }) {
|
|
|
2139
2157
|
React__default.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
|
|
2140
2158
|
}
|
|
2141
2159
|
|
|
2160
|
+
/* eslint-disable @typescript-eslint/unbound-method */
|
|
2142
2161
|
function ImportFeatures({ changeManager, handleClose, session, }) {
|
|
2143
2162
|
const { apolloDataStore } = session;
|
|
2144
2163
|
const [file, setFile] = useState();
|
|
@@ -2180,7 +2199,7 @@ function ImportFeatures({ changeManager, handleClose, session, }) {
|
|
|
2180
2199
|
assemblyId: selectedAssembly.name,
|
|
2181
2200
|
});
|
|
2182
2201
|
uri.search = searchParams.toString();
|
|
2183
|
-
const fetch = apolloInternetAccount
|
|
2202
|
+
const fetch = apolloInternetAccount.getFetcher({
|
|
2184
2203
|
locationType: 'UriLocation',
|
|
2185
2204
|
uri: uri.toString(),
|
|
2186
2205
|
});
|
|
@@ -2234,7 +2253,7 @@ function ImportFeatures({ changeManager, handleClose, session, }) {
|
|
|
2234
2253
|
formData.append('file', file);
|
|
2235
2254
|
formData.append('fileName', file.name);
|
|
2236
2255
|
formData.append('type', 'text/x-gff3');
|
|
2237
|
-
const apolloFetchFile = apolloInternetAccount
|
|
2256
|
+
const apolloFetchFile = apolloInternetAccount.getFetcher({
|
|
2238
2257
|
locationType: 'UriLocation',
|
|
2239
2258
|
uri: url,
|
|
2240
2259
|
});
|
|
@@ -2329,7 +2348,9 @@ function ManageChecks({ handleClose, session }) {
|
|
|
2329
2348
|
const data = (await response.json());
|
|
2330
2349
|
setChecks(data);
|
|
2331
2350
|
}
|
|
2332
|
-
getChecks().catch((error) =>
|
|
2351
|
+
getChecks().catch((error) => {
|
|
2352
|
+
setErrorMessage(String(error));
|
|
2353
|
+
});
|
|
2333
2354
|
}, [selectedInternetAccount]);
|
|
2334
2355
|
useEffect(() => {
|
|
2335
2356
|
if (assemblies.length > 0 && selectedAssembly === undefined) {
|
|
@@ -2353,7 +2374,9 @@ function ManageChecks({ handleClose, session }) {
|
|
|
2353
2374
|
const assembly = (await response.json());
|
|
2354
2375
|
setSelectedChecks(assembly.checks);
|
|
2355
2376
|
}
|
|
2356
|
-
getChecks().catch((error) =>
|
|
2377
|
+
getChecks().catch((error) => {
|
|
2378
|
+
setErrorMessage(String(error));
|
|
2379
|
+
});
|
|
2357
2380
|
}, [selectedAssembly, selectedInternetAccount]);
|
|
2358
2381
|
function handleChangeAssembly(e) {
|
|
2359
2382
|
const newAssembly = assemblies.find((asm) => asm.name === e.target.value);
|
|
@@ -2443,6 +2466,7 @@ function ManageChecks({ handleClose, session }) {
|
|
|
2443
2466
|
React__default.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
|
|
2444
2467
|
}
|
|
2445
2468
|
|
|
2469
|
+
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
2446
2470
|
function ManageUsers({ changeManager, handleClose, session, }) {
|
|
2447
2471
|
const { internetAccounts } = getRoot(session);
|
|
2448
2472
|
const apolloInternetAccounts = internetAccounts.filter((ia) => ia.type === 'ApolloInternetAccount' && ia.role?.includes('admin'));
|
|
@@ -2455,7 +2479,7 @@ function ManageUsers({ changeManager, handleClose, session, }) {
|
|
|
2455
2479
|
const getUsers = useCallback(async () => {
|
|
2456
2480
|
const { baseURL } = selectedInternetAccount;
|
|
2457
2481
|
const uri = new URL('/users', baseURL).href;
|
|
2458
|
-
const apolloFetch = selectedInternetAccount
|
|
2482
|
+
const apolloFetch = selectedInternetAccount.getFetcher({
|
|
2459
2483
|
locationType: 'UriLocation',
|
|
2460
2484
|
uri,
|
|
2461
2485
|
});
|
|
@@ -2471,7 +2495,9 @@ function ManageUsers({ changeManager, handleClose, session, }) {
|
|
|
2471
2495
|
}
|
|
2472
2496
|
}, [selectedInternetAccount]);
|
|
2473
2497
|
useEffect(() => {
|
|
2474
|
-
getUsers().catch((error) =>
|
|
2498
|
+
getUsers().catch((error) => {
|
|
2499
|
+
setErrorMessage(String(error));
|
|
2500
|
+
});
|
|
2475
2501
|
}, [getUsers]);
|
|
2476
2502
|
async function deleteUser(id) {
|
|
2477
2503
|
const change = new DeleteUserChange({
|
|
@@ -2536,13 +2562,16 @@ function ManageUsers({ changeManager, handleClose, session, }) {
|
|
|
2536
2562
|
React__default.createElement(DialogContentText, null, "Select account"),
|
|
2537
2563
|
React__default.createElement(Select, { value: selectedInternetAccount.internetAccountId, onChange: handleChangeInternetAccount, disabled: !errorMessage }, internetAccounts.map((option) => (React__default.createElement(MenuItem, { key: option.id, value: option.internetAccountId }, option.name)))))) : null,
|
|
2538
2564
|
React__default.createElement("div", { style: { height: '100%', width: '100%' } },
|
|
2539
|
-
React__default.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) =>
|
|
2565
|
+
React__default.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) => {
|
|
2566
|
+
setErrorMessage(String(error));
|
|
2567
|
+
} }))),
|
|
2540
2568
|
React__default.createElement(DialogActions, null,
|
|
2541
2569
|
React__default.createElement(Button, { variant: "outlined", type: "submit", onClick: handleClose }, "Close")),
|
|
2542
2570
|
errorMessage ? (React__default.createElement(DialogContent, null,
|
|
2543
2571
|
React__default.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
|
|
2544
2572
|
}
|
|
2545
2573
|
|
|
2574
|
+
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
2546
2575
|
// interface TermAutocompleteResult extends TermValue {
|
|
2547
2576
|
// label: string[]
|
|
2548
2577
|
// match: string
|
|
@@ -2591,8 +2620,7 @@ function TermTagWithTooltip({ getTagProps, index, ontology, termId, }) {
|
|
|
2591
2620
|
React.createElement(Chip, { label: errorMessage || manager.applyPrefixes(termId), color: errorMessage ? 'error' : 'default', size: "small", ...getTagProps({ index }) }))));
|
|
2592
2621
|
}
|
|
2593
2622
|
function OntologyTermMultiSelect({ includeDeprecated, onChange, ontologyName, ontologyVersion, session, value: initialValue, }) {
|
|
2594
|
-
const ontologyManager = session.apolloDataStore
|
|
2595
|
-
.ontologyManager;
|
|
2623
|
+
const { ontologyManager } = session.apolloDataStore;
|
|
2596
2624
|
const ontology = ontologyManager.findOntology(ontologyName, ontologyVersion);
|
|
2597
2625
|
const [value, setValue] = React.useState(initialValue.map((id) => ({ term: { id, type: 'CLASS' } })));
|
|
2598
2626
|
const [inputValue, setInputValue] = React.useState('');
|
|
@@ -2851,7 +2879,7 @@ function ModifyFeatureAttribute({ changeManager, handleClose, session, sourceAss
|
|
|
2851
2879
|
featureId: sourceFeature._id,
|
|
2852
2880
|
attributes: attrs,
|
|
2853
2881
|
});
|
|
2854
|
-
await changeManager.submit
|
|
2882
|
+
await changeManager.submit(change);
|
|
2855
2883
|
notify('Feature attributes modified successfully', 'success');
|
|
2856
2884
|
handleClose();
|
|
2857
2885
|
event.preventDefault();
|
|
@@ -2955,6 +2983,7 @@ function ModifyFeatureAttribute({ changeManager, handleClose, session, sourceAss
|
|
|
2955
2983
|
React__default.createElement(Button, { variant: "outlined", type: "submit", disabled: showAddNewForm, onClick: handleClose }, "Cancel")))));
|
|
2956
2984
|
}
|
|
2957
2985
|
|
|
2986
|
+
/* eslint-disable @typescript-eslint/unbound-method */
|
|
2958
2987
|
function OpenLocalFile({ handleClose, session }) {
|
|
2959
2988
|
const { addApolloTrackConfig, apolloDataStore } = session;
|
|
2960
2989
|
const { addAssembly, addSessionAssembly, assemblyManager, notify } = session;
|
|
@@ -2963,7 +2992,7 @@ function OpenLocalFile({ handleClose, session }) {
|
|
|
2963
2992
|
const [errorMessage, setErrorMessage] = useState('');
|
|
2964
2993
|
const [submitted, setSubmitted] = useState(false);
|
|
2965
2994
|
const theme = useTheme();
|
|
2966
|
-
|
|
2995
|
+
function handleChangeFile(e) {
|
|
2967
2996
|
const selectedFile = e.target.files?.item(0);
|
|
2968
2997
|
if (!selectedFile) {
|
|
2969
2998
|
return;
|
|
@@ -3020,10 +3049,10 @@ function OpenLocalFile({ handleClose, session }) {
|
|
|
3020
3049
|
if (a) {
|
|
3021
3050
|
// @ts-expect-error MST type coercion problem?
|
|
3022
3051
|
addApolloTrackConfig(a);
|
|
3023
|
-
notify(`Loaded GFF3 ${file
|
|
3052
|
+
notify(`Loaded GFF3 ${file.name}`, 'success');
|
|
3024
3053
|
}
|
|
3025
3054
|
else {
|
|
3026
|
-
notify(`Error loading GFF3 ${file
|
|
3055
|
+
notify(`Error loading GFF3 ${file.name}`, 'error');
|
|
3027
3056
|
}
|
|
3028
3057
|
handleClose();
|
|
3029
3058
|
}
|
|
@@ -3048,6 +3077,7 @@ function OpenLocalFile({ handleClose, session }) {
|
|
|
3048
3077
|
React__default.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
|
|
3049
3078
|
}
|
|
3050
3079
|
|
|
3080
|
+
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
3051
3081
|
const useStyles$d = makeStyles()((theme) => ({
|
|
3052
3082
|
changeTextarea: {
|
|
3053
3083
|
fontFamily: 'monospace',
|
|
@@ -3113,7 +3143,9 @@ function ViewChangeLog({ handleClose, session }) {
|
|
|
3113
3143
|
setAssemblyCollection(data);
|
|
3114
3144
|
}
|
|
3115
3145
|
}
|
|
3116
|
-
getAssemblies().catch((error) =>
|
|
3146
|
+
getAssemblies().catch((error) => {
|
|
3147
|
+
setErrorMessage(String(error));
|
|
3148
|
+
});
|
|
3117
3149
|
}, [apolloInternetAccount, baseURL]);
|
|
3118
3150
|
useEffect(() => {
|
|
3119
3151
|
if (!assemblyId && assemblyCollection.length > 0) {
|
|
@@ -3147,9 +3179,11 @@ function ViewChangeLog({ handleClose, session }) {
|
|
|
3147
3179
|
setDisplayGridData(data);
|
|
3148
3180
|
}
|
|
3149
3181
|
}
|
|
3150
|
-
getGridData().catch((error) =>
|
|
3182
|
+
getGridData().catch((error) => {
|
|
3183
|
+
setErrorMessage(String(error));
|
|
3184
|
+
});
|
|
3151
3185
|
}, [assemblyId, apolloInternetAccount, baseURL]);
|
|
3152
|
-
|
|
3186
|
+
function handleChangeAssembly(e) {
|
|
3153
3187
|
setAssemblyId(e.target.value);
|
|
3154
3188
|
}
|
|
3155
3189
|
return (React__default.createElement(Dialog, { open: true, fullScreen: true, title: "View change log", handleClose: handleClose, "data-testid": "view-changelog" },
|
|
@@ -3206,8 +3240,7 @@ function addMenuItems(rootModel) {
|
|
|
3206
3240
|
handleClose: () => {
|
|
3207
3241
|
doneCallback();
|
|
3208
3242
|
},
|
|
3209
|
-
changeManager: session.apolloDataStore
|
|
3210
|
-
.changeManager,
|
|
3243
|
+
changeManager: session.apolloDataStore.changeManager,
|
|
3211
3244
|
},
|
|
3212
3245
|
]);
|
|
3213
3246
|
},
|
|
@@ -3222,8 +3255,7 @@ function addMenuItems(rootModel) {
|
|
|
3222
3255
|
handleClose: () => {
|
|
3223
3256
|
doneCallback();
|
|
3224
3257
|
},
|
|
3225
|
-
changeManager: session.apolloDataStore
|
|
3226
|
-
.changeManager,
|
|
3258
|
+
changeManager: session.apolloDataStore.changeManager,
|
|
3227
3259
|
},
|
|
3228
3260
|
]);
|
|
3229
3261
|
},
|
|
@@ -3312,7 +3344,9 @@ const AuthTypeSelector = ({ baseURL, handleClose, name, }) => {
|
|
|
3312
3344
|
const data = (await response.json());
|
|
3313
3345
|
setLoginTypes(data);
|
|
3314
3346
|
}
|
|
3315
|
-
getAuthTypes().catch((error) =>
|
|
3347
|
+
getAuthTypes().catch((error) => {
|
|
3348
|
+
isAbortException(error) ? '' : setErrorMessage(String(error));
|
|
3349
|
+
});
|
|
3316
3350
|
return () => {
|
|
3317
3351
|
controller.abort();
|
|
3318
3352
|
};
|
|
@@ -3333,11 +3367,17 @@ const AuthTypeSelector = ({ baseURL, handleClose, name, }) => {
|
|
|
3333
3367
|
const allowGuest = loginTypes.includes('guest');
|
|
3334
3368
|
return (React__default.createElement(Dialog, { open: true, title: `Log in to ${name}`, handleClose: handleClose, maxWidth: false, "data-testid": "login-apollo" },
|
|
3335
3369
|
React__default.createElement(DialogContent, { style: { display: 'flex', flexDirection: 'column', paddingTop: 8 } },
|
|
3336
|
-
allowGoogle ? (React__default.createElement(GoogleButton, { disabled: !allowGoogle, onClick: () =>
|
|
3337
|
-
|
|
3370
|
+
allowGoogle ? (React__default.createElement(GoogleButton, { disabled: !allowGoogle, onClick: () => {
|
|
3371
|
+
handleClick('google');
|
|
3372
|
+
} })) : null,
|
|
3373
|
+
allowMicrosoft ? (React__default.createElement(MicrosoftButton, { disabled: !allowMicrosoft, onClick: () => {
|
|
3374
|
+
handleClick('microsoft');
|
|
3375
|
+
} })) : null,
|
|
3338
3376
|
allowGuest ? (React__default.createElement(React__default.Fragment, null,
|
|
3339
3377
|
React__default.createElement(Divider, { className: classes.divider }),
|
|
3340
|
-
React__default.createElement(GuestButton, { onClick: () =>
|
|
3378
|
+
React__default.createElement(GuestButton, { onClick: () => {
|
|
3379
|
+
handleClick('guest');
|
|
3380
|
+
} }))) : null),
|
|
3341
3381
|
React__default.createElement(DialogActions, null,
|
|
3342
3382
|
React__default.createElement(Button, { variant: "outlined", type: "submit", onClick: () => {
|
|
3343
3383
|
handleClose();
|
|
@@ -3346,6 +3386,7 @@ const AuthTypeSelector = ({ baseURL, handleClose, name, }) => {
|
|
|
3346
3386
|
React__default.createElement(DialogContentText, { color: "error" }, errorMessage))) : null));
|
|
3347
3387
|
};
|
|
3348
3388
|
|
|
3389
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
3349
3390
|
const inWebWorker$1 = typeof sessionStorage === 'undefined';
|
|
3350
3391
|
const stateModelFactory$2 = (configSchema) => {
|
|
3351
3392
|
return InternetAccount.named('ApolloInternetAccount')
|
|
@@ -3397,8 +3438,6 @@ const stateModelFactory$2 = (configSchema) => {
|
|
|
3397
3438
|
return {
|
|
3398
3439
|
addMessageChannel(resolve, reject) {
|
|
3399
3440
|
listener = (event) => {
|
|
3400
|
-
// this should probably get better handling, but ignored for now
|
|
3401
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
3402
3441
|
this.finishOAuthWindow(event, resolve, reject);
|
|
3403
3442
|
};
|
|
3404
3443
|
window.addEventListener('message', listener);
|
|
@@ -3406,9 +3445,10 @@ const stateModelFactory$2 = (configSchema) => {
|
|
|
3406
3445
|
deleteMessageChannel() {
|
|
3407
3446
|
window.removeEventListener('message', listener);
|
|
3408
3447
|
},
|
|
3409
|
-
|
|
3448
|
+
finishOAuthWindow(event, resolve, reject) {
|
|
3410
3449
|
if (event.data.name !== `JBrowseAuthWindow-${self.internetAccountId}`) {
|
|
3411
|
-
|
|
3450
|
+
this.deleteMessageChannel();
|
|
3451
|
+
return;
|
|
3412
3452
|
}
|
|
3413
3453
|
const redirectUriWithInfo = event.data.redirectUri;
|
|
3414
3454
|
const fixedQueryString = redirectUriWithInfo.replace('#', '?');
|
|
@@ -3418,11 +3458,12 @@ const stateModelFactory$2 = (configSchema) => {
|
|
|
3418
3458
|
const token = urlParams.get('access_token');
|
|
3419
3459
|
this.deleteMessageChannel();
|
|
3420
3460
|
if (!token) {
|
|
3421
|
-
|
|
3461
|
+
reject(new Error('Error with token endpoint'));
|
|
3462
|
+
return;
|
|
3422
3463
|
}
|
|
3423
3464
|
self.storeToken(token);
|
|
3424
3465
|
self.setRole();
|
|
3425
|
-
|
|
3466
|
+
resolve(token);
|
|
3426
3467
|
},
|
|
3427
3468
|
async openAuthWindow(type, resolve, reject) {
|
|
3428
3469
|
const redirectUri = isElectron
|
|
@@ -3445,7 +3486,6 @@ const stateModelFactory$2 = (configSchema) => {
|
|
|
3445
3486
|
const eventFromDesktop = new MessageEvent('message', {
|
|
3446
3487
|
data: { name: eventName, redirectUri: redirectUriFromElectron },
|
|
3447
3488
|
});
|
|
3448
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
3449
3489
|
this.finishOAuthWindow(eventFromDesktop, resolve, reject);
|
|
3450
3490
|
}
|
|
3451
3491
|
else {
|
|
@@ -3493,7 +3533,8 @@ const stateModelFactory$2 = (configSchema) => {
|
|
|
3493
3533
|
const response = await fetch(uri);
|
|
3494
3534
|
if (!response.ok) {
|
|
3495
3535
|
const errorMessage = await createFetchErrorMessage(response, 'Error when logging in');
|
|
3496
|
-
|
|
3536
|
+
reject(new Error(errorMessage));
|
|
3537
|
+
return;
|
|
3497
3538
|
}
|
|
3498
3539
|
const { token } = await response.json();
|
|
3499
3540
|
resolve(token);
|
|
@@ -3529,8 +3570,7 @@ const stateModelFactory$2 = (configSchema) => {
|
|
|
3529
3570
|
}),
|
|
3530
3571
|
getMissingChanges: flow(function* getMissingChanges() {
|
|
3531
3572
|
const { session } = getRoot(self);
|
|
3532
|
-
const { changeManager } = session
|
|
3533
|
-
.apolloDataStore;
|
|
3573
|
+
const { changeManager } = session.apolloDataStore;
|
|
3534
3574
|
if (!self.lastChangeSequenceNumber) {
|
|
3535
3575
|
throw new Error('No LastChangeSequence stored in session. Please, refresh you browser to get last updates from server');
|
|
3536
3576
|
}
|
|
@@ -3554,7 +3594,7 @@ const stateModelFactory$2 = (configSchema) => {
|
|
|
3554
3594
|
const serializedChanges = yield response.json();
|
|
3555
3595
|
for (const serializedChange of serializedChanges) {
|
|
3556
3596
|
const change = Change.fromJSON(serializedChange);
|
|
3557
|
-
void changeManager
|
|
3597
|
+
void changeManager.submit(change, { submitToBackend: false });
|
|
3558
3598
|
}
|
|
3559
3599
|
}),
|
|
3560
3600
|
}))
|
|
@@ -3593,7 +3633,7 @@ const stateModelFactory$2 = (configSchema) => {
|
|
|
3593
3633
|
return; // we did this change, no need to apply it again
|
|
3594
3634
|
}
|
|
3595
3635
|
const change = Change.fromJSON(message.changeInfo);
|
|
3596
|
-
void changeManager
|
|
3636
|
+
void changeManager.submit(change, { submitToBackend: false });
|
|
3597
3637
|
});
|
|
3598
3638
|
socket.on('USER_LOCATION', (message) => {
|
|
3599
3639
|
const { channel, locations, userName, userSessionId } = message;
|
|
@@ -3648,7 +3688,9 @@ const stateModelFactory$2 = (configSchema) => {
|
|
|
3648
3688
|
let timeoutId;
|
|
3649
3689
|
return (userLocation) => {
|
|
3650
3690
|
clearTimeout(timeoutId);
|
|
3651
|
-
timeoutId = setTimeout(() =>
|
|
3691
|
+
timeoutId = setTimeout(() => {
|
|
3692
|
+
fn(userLocation);
|
|
3693
|
+
}, debounceTimeout);
|
|
3652
3694
|
};
|
|
3653
3695
|
};
|
|
3654
3696
|
return { postUserLocation: debouncePostUserLocation(postUserLocation) };
|
|
@@ -3705,6 +3747,7 @@ const stateModelFactory$2 = (configSchema) => {
|
|
|
3705
3747
|
}));
|
|
3706
3748
|
};
|
|
3707
3749
|
|
|
3750
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
3708
3751
|
function isApolloMessageData$1(data) {
|
|
3709
3752
|
return (typeof data === 'object' &&
|
|
3710
3753
|
data !== null &&
|
|
@@ -3893,8 +3936,9 @@ function ApolloRendering(props) {
|
|
|
3893
3936
|
const { session } = displayModel;
|
|
3894
3937
|
const { collaborators: collabs } = session;
|
|
3895
3938
|
// bridging mobx observability and React useEffect observability
|
|
3896
|
-
|
|
3897
|
-
|
|
3939
|
+
useEffect(() => autorun(() => {
|
|
3940
|
+
setCollaborators(toJS(collabs));
|
|
3941
|
+
}), []);
|
|
3898
3942
|
const [region] = regions;
|
|
3899
3943
|
const totalWidth = (region.end - region.start) / bpPerPx;
|
|
3900
3944
|
const { apolloFeatureUnderMouse, apolloRowHeight: height, apolloRowUnderMouse, changeManager, codonLayout, featureLayout, features, featuresHeight: totalHeight, getAssemblyId, selectedFeature, setApolloFeatureUnderMouse, setApolloRowUnderMouse, setSelectedFeature, showIntronLines: showLines, showStartCodons: showStarts, showStopCodons: showStops, } = displayModel;
|
|
@@ -4275,7 +4319,7 @@ function ApolloRendering(props) {
|
|
|
4275
4319
|
assembly,
|
|
4276
4320
|
});
|
|
4277
4321
|
}
|
|
4278
|
-
await changeManager
|
|
4322
|
+
await changeManager.submit(change);
|
|
4279
4323
|
}
|
|
4280
4324
|
// eslint-disable-next-line unicorn/no-useless-undefined
|
|
4281
4325
|
setDragging(undefined);
|
|
@@ -4376,6 +4420,7 @@ var ApolloSixFrameRendererReactComponent = observer(ApolloRendering);
|
|
|
4376
4420
|
|
|
4377
4421
|
var apolloSixFrameRendererConfigSchema = ConfigurationSchema('ApolloSixFrameRenderer', {}, { explicitlyTyped: true });
|
|
4378
4422
|
|
|
4423
|
+
/* eslint-disable @typescript-eslint/require-await */
|
|
4379
4424
|
class ApolloSixFrameRenderer extends RendererType {
|
|
4380
4425
|
async renderInClient(_rpcManager, args) {
|
|
4381
4426
|
return this.render(args);
|
|
@@ -4385,6 +4430,7 @@ class ApolloSixFrameRenderer extends RendererType {
|
|
|
4385
4430
|
}
|
|
4386
4431
|
}
|
|
4387
4432
|
|
|
4433
|
+
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
4388
4434
|
class ApolloTextSearchAdapter extends BaseAdapter {
|
|
4389
4435
|
get baseURL() {
|
|
4390
4436
|
return readConfObject(this.config, 'baseURL').uri;
|
|
@@ -4449,6 +4495,7 @@ function installApolloTextSearchAdapter(pluginManager) {
|
|
|
4449
4495
|
}));
|
|
4450
4496
|
}
|
|
4451
4497
|
|
|
4498
|
+
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
4452
4499
|
var PhaseEnum;
|
|
4453
4500
|
(function (PhaseEnum) {
|
|
4454
4501
|
PhaseEnum[PhaseEnum["zero"] = 0] = "zero";
|
|
@@ -4502,7 +4549,7 @@ function AddFeature({ changeManager, handleClose, region, session, }) {
|
|
|
4502
4549
|
strand,
|
|
4503
4550
|
},
|
|
4504
4551
|
});
|
|
4505
|
-
await changeManager.submit
|
|
4552
|
+
await changeManager.submit(change);
|
|
4506
4553
|
notify('Feature added successfully', 'success');
|
|
4507
4554
|
handleClose();
|
|
4508
4555
|
event.preventDefault();
|
|
@@ -4535,7 +4582,7 @@ function AddFeature({ changeManager, handleClose, region, session, }) {
|
|
|
4535
4582
|
}
|
|
4536
4583
|
}
|
|
4537
4584
|
}
|
|
4538
|
-
|
|
4585
|
+
function handleChangePhase(e) {
|
|
4539
4586
|
setErrorMessage('');
|
|
4540
4587
|
setPhase(e.target.value);
|
|
4541
4588
|
switch (Number(e.target.value)) {
|
|
@@ -4561,8 +4608,12 @@ function AddFeature({ changeManager, handleClose, region, session, }) {
|
|
|
4561
4608
|
return (React__default.createElement(Dialog, { open: true, title: "Add new feature", handleClose: handleClose, maxWidth: false, "data-testid": "add-feature-dialog" },
|
|
4562
4609
|
React__default.createElement("form", { onSubmit: onSubmit },
|
|
4563
4610
|
React__default.createElement(DialogContent, { style: { display: 'flex', flexDirection: 'column' } },
|
|
4564
|
-
React__default.createElement(TextField, { margin: "dense", id: "start", label: "Start", type: "number", fullWidth: true, variant: "outlined", value: Number(start), onChange: (e) =>
|
|
4565
|
-
|
|
4611
|
+
React__default.createElement(TextField, { margin: "dense", id: "start", label: "Start", type: "number", fullWidth: true, variant: "outlined", value: Number(start), onChange: (e) => {
|
|
4612
|
+
setStart(e.target.value);
|
|
4613
|
+
} }),
|
|
4614
|
+
React__default.createElement(TextField, { margin: "dense", id: "end", label: "End", type: "number", fullWidth: true, variant: "outlined", value: end, onChange: (e) => {
|
|
4615
|
+
setEnd(e.target.value);
|
|
4616
|
+
}, error: error, helperText: error ? '"End" must be greater than "Start"' : null }),
|
|
4566
4617
|
React__default.createElement(OntologyTermAutocomplete, { session: session, ontologyName: "Sequence Ontology", style: { width: 170 }, value: type, filterTerms: isOntologyClass, renderInput: (params) => (React__default.createElement(TextField, { ...params, label: "Type", variant: "outlined", fullWidth: true })), onChange: (oldValue, newValue) => {
|
|
4567
4618
|
if (newValue) {
|
|
4568
4619
|
handleChangeType(newValue);
|
|
@@ -4642,7 +4693,9 @@ function ViewCheckResults({ handleClose, session, }) {
|
|
|
4642
4693
|
setDisplayGridData(data);
|
|
4643
4694
|
}
|
|
4644
4695
|
}
|
|
4645
|
-
getGridData().catch((error) =>
|
|
4696
|
+
getGridData().catch((error) => {
|
|
4697
|
+
setErrorMessage(String(error));
|
|
4698
|
+
});
|
|
4646
4699
|
}, [selectedAssembly, apolloInternetAccount, baseURL]);
|
|
4647
4700
|
function handleChangeAssembly(e) {
|
|
4648
4701
|
const newAssembly = assemblies.find((asm) => asm.name === e.target.value);
|
|
@@ -4795,7 +4848,7 @@ function annotationFromPileup(pluggableElement) {
|
|
|
4795
4848
|
cdsFeature.start = Math.min(cdsFeature.start, exon.start);
|
|
4796
4849
|
cdsFeature.end = Math.max(cdsFeature.end, exon.end);
|
|
4797
4850
|
const { end, start } = exon;
|
|
4798
|
-
discontinuousLocations
|
|
4851
|
+
discontinuousLocations.push({ start, end, phase });
|
|
4799
4852
|
const localPhase = (end - start) % 3;
|
|
4800
4853
|
phase = ((phase + localPhase) % 3);
|
|
4801
4854
|
const newExon = {
|
|
@@ -4823,7 +4876,7 @@ function annotationFromPileup(pluggableElement) {
|
|
|
4823
4876
|
addedFeature: newFeature,
|
|
4824
4877
|
});
|
|
4825
4878
|
const session = getSession(self);
|
|
4826
|
-
await session.apolloDataStore.changeManager.submit
|
|
4879
|
+
await session.apolloDataStore.changeManager.submit(change);
|
|
4827
4880
|
session.notify('Annotation added successfully', 'success');
|
|
4828
4881
|
},
|
|
4829
4882
|
}))
|
|
@@ -4850,6 +4903,7 @@ function annotationFromPileup(pluggableElement) {
|
|
|
4850
4903
|
return pluggableElement;
|
|
4851
4904
|
}
|
|
4852
4905
|
|
|
4906
|
+
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
4853
4907
|
const StringTextField = observer(function StringTextField({ onChangeCommitted, value: initialValue, ...props }) {
|
|
4854
4908
|
const [value, setValue] = useState(String(initialValue));
|
|
4855
4909
|
const [blur, setBlur] = useState(false);
|
|
@@ -4878,7 +4932,9 @@ const StringTextField = observer(function StringTextField({ onChangeCommitted, v
|
|
|
4878
4932
|
if (value !== String(initialValue)) {
|
|
4879
4933
|
onChangeCommitted(value);
|
|
4880
4934
|
}
|
|
4881
|
-
}, inputRef: (node) =>
|
|
4935
|
+
}, inputRef: (node) => {
|
|
4936
|
+
setInputNode(node);
|
|
4937
|
+
} }));
|
|
4882
4938
|
});
|
|
4883
4939
|
|
|
4884
4940
|
const reservedKeys = new Map([
|
|
@@ -5015,7 +5071,7 @@ const Attributes = observer(function Attributes({ assembly, editable, feature, s
|
|
|
5015
5071
|
featureId: feature._id,
|
|
5016
5072
|
attributes: attrs,
|
|
5017
5073
|
});
|
|
5018
|
-
await changeManager.submit
|
|
5074
|
+
await changeManager.submit(change);
|
|
5019
5075
|
notify('Feature attributes modified successfully', 'success');
|
|
5020
5076
|
}
|
|
5021
5077
|
function handleAddNewAttributeChange() {
|
|
@@ -5098,6 +5154,7 @@ const Attributes = observer(function Attributes({ assembly, editable, feature, s
|
|
|
5098
5154
|
errorMessage ? (React__default.createElement(Typography, { color: "error" }, errorMessage)) : null));
|
|
5099
5155
|
});
|
|
5100
5156
|
|
|
5157
|
+
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
5101
5158
|
const NumberTextField = observer(function NumberTextField({ onChangeCommitted, value: initialValue, ...props }) {
|
|
5102
5159
|
const [value, setValue] = useState(String(initialValue));
|
|
5103
5160
|
const [blur, setBlur] = useState(false);
|
|
@@ -5133,14 +5190,18 @@ const NumberTextField = observer(function NumberTextField({ onChangeCommitted, v
|
|
|
5133
5190
|
onChangeCommitted(valueAsNumber);
|
|
5134
5191
|
}
|
|
5135
5192
|
}
|
|
5136
|
-
}, inputRef: (node) =>
|
|
5193
|
+
}, inputRef: (node) => {
|
|
5194
|
+
setInputNode(node);
|
|
5195
|
+
}, error: error, helperText: error ? 'Not a valid number' : undefined }));
|
|
5137
5196
|
});
|
|
5138
5197
|
|
|
5139
5198
|
const BasicInformation = observer(function BasicInformation({ assembly, feature, session, }) {
|
|
5140
5199
|
const [errorMessage, setErrorMessage] = useState('');
|
|
5141
5200
|
const [typeWarningText, setTypeWarningText] = useState('');
|
|
5142
5201
|
const { _id, assemblyId, end, start, strand, type } = feature;
|
|
5143
|
-
const notifyError = (e) =>
|
|
5202
|
+
const notifyError = (e) => {
|
|
5203
|
+
session.notify(e.message, 'error');
|
|
5204
|
+
};
|
|
5144
5205
|
const { changeManager } = session.apolloDataStore;
|
|
5145
5206
|
function handleTypeChange(newType) {
|
|
5146
5207
|
setErrorMessage('');
|
|
@@ -5236,7 +5297,7 @@ const RelatedFeatures = observer(function RelatedFeatures({ assembly, feature, r
|
|
|
5236
5297
|
assembly,
|
|
5237
5298
|
refName,
|
|
5238
5299
|
});
|
|
5239
|
-
session.showWidget
|
|
5300
|
+
session.showWidget(apolloFeatureWidget);
|
|
5240
5301
|
}
|
|
5241
5302
|
};
|
|
5242
5303
|
if (!(parent || (children && children.size > 0))) {
|
|
@@ -5248,12 +5309,16 @@ const RelatedFeatures = observer(function RelatedFeatures({ assembly, feature, r
|
|
|
5248
5309
|
React__default.createElement(Typography, { variant: "h5" }, "Parent"),
|
|
5249
5310
|
React__default.createElement(Paper, { elevation: 6, className: classes.paper },
|
|
5250
5311
|
`Start: ${parent.start}, End: ${parent.end}, Type: ${parent.type}`,
|
|
5251
|
-
React__default.createElement(Button, { variant: "contained", onClick: () =>
|
|
5312
|
+
React__default.createElement(Button, { variant: "contained", onClick: () => {
|
|
5313
|
+
onButtonClick(parent);
|
|
5314
|
+
} }, "Go to parent")))),
|
|
5252
5315
|
children && children.size > 0 && (React__default.createElement(React__default.Fragment, null,
|
|
5253
5316
|
React__default.createElement(Typography, { variant: "h5" }, "Children"),
|
|
5254
5317
|
[...children.values()].map((child) => (React__default.createElement(Paper, { elevation: 6, className: classes.paper, key: child._id },
|
|
5255
5318
|
`Start: ${child.start}, End: ${child.end}, Type: ${child.type}`,
|
|
5256
|
-
React__default.createElement(Button, { variant: "contained", onClick: () =>
|
|
5319
|
+
React__default.createElement(Button, { variant: "contained", onClick: () => {
|
|
5320
|
+
onButtonClick(child);
|
|
5321
|
+
} }, "Go to child"))))))));
|
|
5257
5322
|
});
|
|
5258
5323
|
|
|
5259
5324
|
function formatSequence(seq, refName, start, end, wrap) {
|
|
@@ -5341,6 +5406,7 @@ const ApolloFeatureDetailsWidget = observer(function ApolloFeatureDetailsWidget(
|
|
|
5341
5406
|
React__default.createElement(RelatedFeatures, { feature: feature, refName: refName, session: session, assembly: currentAssembly._id })));
|
|
5342
5407
|
});
|
|
5343
5408
|
|
|
5409
|
+
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
5344
5410
|
const ApolloFeatureDetailsWidgetModel = types
|
|
5345
5411
|
.model('ApolloFeatureDetailsWidget', {
|
|
5346
5412
|
id: ElementId,
|
|
@@ -5623,7 +5689,9 @@ const NumberCell = observer(function NumberCell({ initialValue, notifyError, onC
|
|
|
5623
5689
|
if (value !== initialValue) {
|
|
5624
5690
|
onChangeCommitted(value).catch(notifyError);
|
|
5625
5691
|
}
|
|
5626
|
-
}, ref: (node) =>
|
|
5692
|
+
}, ref: (node) => {
|
|
5693
|
+
setInputNode(node);
|
|
5694
|
+
} })));
|
|
5627
5695
|
});
|
|
5628
5696
|
|
|
5629
5697
|
const useStyles$4 = makeStyles()((theme) => ({
|
|
@@ -5682,7 +5750,9 @@ const Feature = observer(function Feature({ depth, feature, isHovered, isSelecte
|
|
|
5682
5750
|
tabularEditorState.setFeatureCollapsed(_id, expanded);
|
|
5683
5751
|
};
|
|
5684
5752
|
// pop up a snackbar in the session notifying user of an error
|
|
5685
|
-
const notifyError = (e) =>
|
|
5753
|
+
const notifyError = (e) => {
|
|
5754
|
+
session.notify(e.message, 'error');
|
|
5755
|
+
};
|
|
5686
5756
|
return (React__default.createElement(React__default.Fragment, null,
|
|
5687
5757
|
React__default.createElement("tr", { onMouseEnter: (_e) => {
|
|
5688
5758
|
displayState.setApolloHover({
|
|
@@ -5844,6 +5914,7 @@ const HybridGrid = observer(function HybridGrid({ model, }) {
|
|
|
5844
5914
|
}, style: { zIndex: theme.zIndex.tooltip }, menuItems: contextMenu?.items ?? [], anchorReference: "anchorPosition", anchorPosition: contextMenu?.position })));
|
|
5845
5915
|
});
|
|
5846
5916
|
|
|
5917
|
+
/* eslint-disable @typescript-eslint/unbound-method */
|
|
5847
5918
|
const useStyles$2 = makeStyles()({
|
|
5848
5919
|
toolbar: {
|
|
5849
5920
|
width: '100%',
|
|
@@ -5863,9 +5934,13 @@ const ToolBar = observer(function ToolBar({ model: displayState, }) {
|
|
|
5863
5934
|
React__default.createElement(Tooltip, { title: "Collapse all" },
|
|
5864
5935
|
React__default.createElement(IconButton, { "aria-label": "collapse", sx: { marginTop: 0 }, onClick: model.collapseAllFeatures },
|
|
5865
5936
|
React__default.createElement(UnfoldLessIcon, null))),
|
|
5866
|
-
React__default.createElement(TextField, { className: classes.filterText, label: "Filter features", value: model.filterText, sx: { marginTop: 0 }, variant: "outlined", onChange: (event) =>
|
|
5937
|
+
React__default.createElement(TextField, { className: classes.filterText, label: "Filter features", value: model.filterText, sx: { marginTop: 0 }, variant: "outlined", onChange: (event) => {
|
|
5938
|
+
model.setFilterText(event.target.value);
|
|
5939
|
+
}, InputProps: {
|
|
5867
5940
|
endAdornment: (React__default.createElement(InputAdornment$1, { position: "end" },
|
|
5868
|
-
React__default.createElement(IconButton, { onClick: () =>
|
|
5941
|
+
React__default.createElement(IconButton, { onClick: () => {
|
|
5942
|
+
model.clearFilterText();
|
|
5943
|
+
} },
|
|
5869
5944
|
React__default.createElement(ClearIcon, null)))),
|
|
5870
5945
|
} })));
|
|
5871
5946
|
});
|
|
@@ -6167,7 +6242,7 @@ class Glyph {
|
|
|
6167
6242
|
assembly: currentAssemblyId,
|
|
6168
6243
|
refName: region.refName,
|
|
6169
6244
|
});
|
|
6170
|
-
session.showWidget
|
|
6245
|
+
session.showWidget(apolloFeatureWidget);
|
|
6171
6246
|
},
|
|
6172
6247
|
});
|
|
6173
6248
|
}
|
|
@@ -6581,7 +6656,7 @@ function baseModelFactory(_pluginManager, configSchema) {
|
|
|
6581
6656
|
},
|
|
6582
6657
|
get changeManager() {
|
|
6583
6658
|
return self.session.apolloDataStore
|
|
6584
|
-
|
|
6659
|
+
.changeManager;
|
|
6585
6660
|
},
|
|
6586
6661
|
getAssemblyId(assemblyName) {
|
|
6587
6662
|
const { assemblyManager } = self.session;
|
|
@@ -6598,7 +6673,7 @@ function baseModelFactory(_pluginManager, configSchema) {
|
|
|
6598
6673
|
}))
|
|
6599
6674
|
.actions((self) => ({
|
|
6600
6675
|
setSelectedFeature(feature) {
|
|
6601
|
-
|
|
6676
|
+
self.session.apolloSetSelectedFeature(feature);
|
|
6602
6677
|
},
|
|
6603
6678
|
afterAttach() {
|
|
6604
6679
|
addDisposer(self, autorun(() => {
|
|
@@ -6893,8 +6968,8 @@ function codonColorCode(letter, rowColorCode, bpPerPx) {
|
|
|
6893
6968
|
M: '#33ee33',
|
|
6894
6969
|
'*': '#f44336',
|
|
6895
6970
|
};
|
|
6896
|
-
if (colorMap[letter
|
|
6897
|
-
return colorMap[letter
|
|
6971
|
+
if (colorMap[letter.toUpperCase()] !== undefined) {
|
|
6972
|
+
return colorMap[letter.toUpperCase()];
|
|
6898
6973
|
}
|
|
6899
6974
|
return bpPerPx <= 0.1 ? rowColorCode : 'lightgray';
|
|
6900
6975
|
}
|
|
@@ -7274,7 +7349,7 @@ class CanonicalGeneGlyph extends Glyph {
|
|
|
7274
7349
|
let featureRow;
|
|
7275
7350
|
let i = 0;
|
|
7276
7351
|
for (const [, f] of children ?? new Map()) {
|
|
7277
|
-
if (f._id === apolloSelectedFeature
|
|
7352
|
+
if (f._id === apolloSelectedFeature._id) {
|
|
7278
7353
|
featureEntry = f;
|
|
7279
7354
|
featureRow = i;
|
|
7280
7355
|
}
|
|
@@ -7343,7 +7418,7 @@ class CanonicalGeneGlyph extends Glyph {
|
|
|
7343
7418
|
let featureRow;
|
|
7344
7419
|
let i = 0;
|
|
7345
7420
|
for (const [, f] of topLevelFeature.children ?? new Map()) {
|
|
7346
|
-
if (f._id === feature
|
|
7421
|
+
if (f._id === feature._id) {
|
|
7347
7422
|
featureEntry = f;
|
|
7348
7423
|
featureRow = i;
|
|
7349
7424
|
}
|
|
@@ -7705,10 +7780,10 @@ class CanonicalGeneGlyph extends Glyph {
|
|
|
7705
7780
|
}
|
|
7706
7781
|
if (feature.type !== 'CDS') {
|
|
7707
7782
|
const adjacentExons = this.adjacentExonsOfExon(feature, topLevelFeature);
|
|
7708
|
-
if (adjacentExons?.nextExon && bp >= adjacentExons
|
|
7783
|
+
if (adjacentExons?.nextExon && bp >= adjacentExons.nextExon.start - 1) {
|
|
7709
7784
|
return;
|
|
7710
7785
|
}
|
|
7711
|
-
if (adjacentExons?.prevExon && bp <= adjacentExons
|
|
7786
|
+
if (adjacentExons?.prevExon && bp <= adjacentExons.prevExon.end + 1) {
|
|
7712
7787
|
return;
|
|
7713
7788
|
}
|
|
7714
7789
|
const dls = this.cdsDlsForExon(feature, topLevelFeature);
|
|
@@ -7982,7 +8057,7 @@ class GenericChildGlyph extends BoxGlyph {
|
|
|
7982
8057
|
}
|
|
7983
8058
|
getFeatureFromLayout(feature, bp, row) {
|
|
7984
8059
|
const layoutRow = this.featuresForRow(feature)[row];
|
|
7985
|
-
return layoutRow
|
|
8060
|
+
return layoutRow.find((f) => bp >= f.start && bp <= f.end);
|
|
7986
8061
|
}
|
|
7987
8062
|
getRowForFeature(feature, childFeature) {
|
|
7988
8063
|
const rows = this.featuresForRow(feature);
|
|
@@ -8142,7 +8217,7 @@ class ImplicitExonGeneGlyph extends Glyph {
|
|
|
8142
8217
|
let featureRow;
|
|
8143
8218
|
let i = 0;
|
|
8144
8219
|
for (const [, f] of children ?? new Map()) {
|
|
8145
|
-
if (f._id === apolloSelectedFeature
|
|
8220
|
+
if (f._id === apolloSelectedFeature._id) {
|
|
8146
8221
|
featureEntry = f;
|
|
8147
8222
|
featureRow = i;
|
|
8148
8223
|
}
|
|
@@ -8400,7 +8475,7 @@ class ImplicitExonGeneGlyph extends Glyph {
|
|
|
8400
8475
|
}
|
|
8401
8476
|
getFeatureFromLayout(feature, bp, row) {
|
|
8402
8477
|
const layoutRow = this.featuresForRow(feature)[row];
|
|
8403
|
-
return layoutRow
|
|
8478
|
+
return layoutRow.find((f) => bp >= f.start && bp <= f.end);
|
|
8404
8479
|
}
|
|
8405
8480
|
getRowForFeature(feature, childFeature) {
|
|
8406
8481
|
const rows = this.featuresForRow(feature);
|
|
@@ -8639,7 +8714,7 @@ function mouseEventsSeqHightlightModelFactory(pluginManager, configSchema) {
|
|
|
8639
8714
|
const LinearApolloDisplayRendering = mouseEventsModelIntermediateFactory(pluginManager, configSchema);
|
|
8640
8715
|
return LinearApolloDisplayRendering.actions((self) => ({
|
|
8641
8716
|
afterAttach() {
|
|
8642
|
-
addDisposer(self, autorun(
|
|
8717
|
+
addDisposer(self, autorun(() => {
|
|
8643
8718
|
if (!self.lgv.initialized || self.regionCannotBeRendered()) {
|
|
8644
8719
|
return;
|
|
8645
8720
|
}
|
|
@@ -8884,6 +8959,7 @@ function stateModelFactory$1(pluginManager, configSchema) {
|
|
|
8884
8959
|
.named('LinearApolloDisplay');
|
|
8885
8960
|
}
|
|
8886
8961
|
|
|
8962
|
+
/* eslint-disable @typescript-eslint/unbound-method */
|
|
8887
8963
|
const useStyles$1 = makeStyles()((theme) => ({
|
|
8888
8964
|
canvasContainer: {
|
|
8889
8965
|
position: 'relative',
|
|
@@ -8909,7 +8985,9 @@ const LinearApolloDisplay = observer(function LinearApolloDisplay(props) {
|
|
|
8909
8985
|
const { apolloRowHeight, contextMenuItems: getContextMenuItems, cursor, featuresHeight, isShown, onMouseDown, onMouseLeave, onMouseMove, onMouseUp, regionCannotBeRendered, session, setCanvas, setCollaboratorCanvas, setOverlayCanvas, setSeqTrackCanvas, setSeqTrackOverlayCanvas, setTheme, tabularEditor, } = model;
|
|
8910
8986
|
const { classes } = useStyles$1();
|
|
8911
8987
|
const lgv = getContainingView(model);
|
|
8912
|
-
useEffect(() =>
|
|
8988
|
+
useEffect(() => {
|
|
8989
|
+
setTheme(theme);
|
|
8990
|
+
}, [theme, setTheme]);
|
|
8913
8991
|
const [contextCoord, setContextCoord] = useState();
|
|
8914
8992
|
const [contextMenuItems, setContextMenuItems] = useState([]);
|
|
8915
8993
|
const message = regionCannotBeRendered();
|
|
@@ -8968,7 +9046,7 @@ const LinearApolloDisplay = observer(function LinearApolloDisplay(props) {
|
|
|
8968
9046
|
const assembly = assemblyManager.get(region.assemblyName);
|
|
8969
9047
|
return [...session.apolloDataStore.checkResults.values()]
|
|
8970
9048
|
.filter((checkResult) => assembly?.isValidRefName(checkResult.refSeq) &&
|
|
8971
|
-
assembly
|
|
9049
|
+
assembly.getCanonicalRefName(checkResult.refSeq) ===
|
|
8972
9050
|
region.refName &&
|
|
8973
9051
|
doesIntersect2(region.start, region.end, checkResult.start, checkResult.end))
|
|
8974
9052
|
.map((checkResult) => {
|
|
@@ -9108,7 +9186,9 @@ const DisplayComponent = observer(function DisplayComponent({ model, ...other })
|
|
|
9108
9186
|
model.setDetailsHeight(model.detailsHeight - delta);
|
|
9109
9187
|
};
|
|
9110
9188
|
const canvasScrollContainerRef = useRef(null);
|
|
9111
|
-
useEffect(() =>
|
|
9189
|
+
useEffect(() => {
|
|
9190
|
+
scrollSelectedFeatureIntoView(model, canvasScrollContainerRef);
|
|
9191
|
+
}, [model, selectedFeature]);
|
|
9112
9192
|
return (React__default.createElement("div", { className: classes.details, style: { height: overallHeight } },
|
|
9113
9193
|
React__default.createElement(AccordionControl, { open: isShown, title: "Graphical", onClick: toggleShown }),
|
|
9114
9194
|
React__default.createElement("div", { className: classes.shading, ref: canvasScrollContainerRef, style: { height: featureAreaHeight } },
|
|
@@ -9140,6 +9220,7 @@ function makeSixFrameDisplayComponent(pluginManager) {
|
|
|
9140
9220
|
return observer(ApolloDisplayComponent);
|
|
9141
9221
|
}
|
|
9142
9222
|
|
|
9223
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
9143
9224
|
const ApolloJobModel = types
|
|
9144
9225
|
.model('JobsManager', {})
|
|
9145
9226
|
.views((self) => ({
|
|
@@ -9227,6 +9308,7 @@ class BackendDriver {
|
|
|
9227
9308
|
}
|
|
9228
9309
|
}
|
|
9229
9310
|
|
|
9311
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
9230
9312
|
class ChangeManager {
|
|
9231
9313
|
dataStore;
|
|
9232
9314
|
constructor(dataStore) {
|
|
@@ -9338,6 +9420,7 @@ class ChangeManager {
|
|
|
9338
9420
|
}
|
|
9339
9421
|
}
|
|
9340
9422
|
|
|
9423
|
+
/* eslint-disable @typescript-eslint/no-base-to-string */
|
|
9341
9424
|
class CollaborationServerDriver extends BackendDriver {
|
|
9342
9425
|
inFlight = new Map();
|
|
9343
9426
|
async fetch(internetAccount, info, init) {
|
|
@@ -9396,7 +9479,7 @@ class CollaborationServerDriver extends BackendDriver {
|
|
|
9396
9479
|
const errorMessage = await createFetchErrorMessage(response, 'getFeatures failed');
|
|
9397
9480
|
throw new Error(errorMessage);
|
|
9398
9481
|
}
|
|
9399
|
-
|
|
9482
|
+
this.checkSocket(assemblyName, refName, internetAccount);
|
|
9400
9483
|
return response.json();
|
|
9401
9484
|
}
|
|
9402
9485
|
/**
|
|
@@ -9405,7 +9488,7 @@ class CollaborationServerDriver extends BackendDriver {
|
|
|
9405
9488
|
* @param refSeq - refSeqName
|
|
9406
9489
|
* @param internetAccount - internet account
|
|
9407
9490
|
*/
|
|
9408
|
-
|
|
9491
|
+
checkSocket(assembly, refSeq, internetAccount) {
|
|
9409
9492
|
const { socket } = internetAccount;
|
|
9410
9493
|
const token = internetAccount.retrieveToken();
|
|
9411
9494
|
const channel = `${assembly}-${refSeq}`;
|
|
@@ -9448,7 +9531,7 @@ class CollaborationServerDriver extends BackendDriver {
|
|
|
9448
9531
|
if (!apolloAssembly) {
|
|
9449
9532
|
apolloAssembly = this.clientStore.addAssembly(assemblyName);
|
|
9450
9533
|
}
|
|
9451
|
-
let apolloRefSeq = apolloAssembly
|
|
9534
|
+
let apolloRefSeq = apolloAssembly.refSeqs.get(refSeq);
|
|
9452
9535
|
if (!apolloRefSeq) {
|
|
9453
9536
|
apolloRefSeq = apolloAssembly.addRefSeq(refSeq, refName);
|
|
9454
9537
|
}
|
|
@@ -9469,7 +9552,7 @@ class CollaborationServerDriver extends BackendDriver {
|
|
|
9469
9552
|
const seqPromise = this.getSeqFromServer(internetAccount, uri, apolloRefSeq, start, end);
|
|
9470
9553
|
this.inFlight.set(inFlightKey, seqPromise);
|
|
9471
9554
|
const seq = await seqPromise;
|
|
9472
|
-
|
|
9555
|
+
this.checkSocket(assemblyName, refName, internetAccount);
|
|
9473
9556
|
this.inFlight.delete(inFlightKey);
|
|
9474
9557
|
return { seq, refSeq };
|
|
9475
9558
|
}
|
|
@@ -9607,6 +9690,7 @@ class InMemoryFileDriver extends BackendDriver {
|
|
|
9607
9690
|
}
|
|
9608
9691
|
}
|
|
9609
9692
|
|
|
9693
|
+
/* eslint-disable @typescript-eslint/require-await */
|
|
9610
9694
|
class DesktopFileDriver extends BackendDriver {
|
|
9611
9695
|
async loadAssembly(assemblyName) {
|
|
9612
9696
|
const { assemblyManager } = getSession(this.clientStore);
|
|
@@ -10321,7 +10405,7 @@ function stateModelFactory(pluginManager, configSchema) {
|
|
|
10321
10405
|
},
|
|
10322
10406
|
get changeManager() {
|
|
10323
10407
|
const session = getSession(self);
|
|
10324
|
-
return session.apolloDataStore
|
|
10408
|
+
return session.apolloDataStore.changeManager;
|
|
10325
10409
|
},
|
|
10326
10410
|
get sequence() {
|
|
10327
10411
|
const { regions } = self;
|
|
@@ -10515,7 +10599,7 @@ function stateModelFactory(pluginManager, configSchema) {
|
|
|
10515
10599
|
.actions((self) => ({
|
|
10516
10600
|
setSelectedFeature(feature) {
|
|
10517
10601
|
const session = getSession(self);
|
|
10518
|
-
|
|
10602
|
+
session.apolloSetSelectedFeature(feature);
|
|
10519
10603
|
},
|
|
10520
10604
|
setApolloFeatureUnderMouse(feature) {
|
|
10521
10605
|
self.apolloFeatureUnderMouse = feature;
|
|
@@ -10552,25 +10636,32 @@ function stateModelFactory(pluginManager, configSchema) {
|
|
|
10552
10636
|
label: 'Show start codons',
|
|
10553
10637
|
type: 'checkbox',
|
|
10554
10638
|
checked: self.showStartCodons,
|
|
10555
|
-
onClick: () =>
|
|
10639
|
+
onClick: () => {
|
|
10640
|
+
self.toggleShowStartCodons();
|
|
10641
|
+
},
|
|
10556
10642
|
},
|
|
10557
10643
|
{
|
|
10558
10644
|
label: 'Show stop codons',
|
|
10559
10645
|
type: 'checkbox',
|
|
10560
10646
|
checked: self.showStopCodons,
|
|
10561
|
-
onClick: () =>
|
|
10647
|
+
onClick: () => {
|
|
10648
|
+
self.toggleShowStopCodons();
|
|
10649
|
+
},
|
|
10562
10650
|
},
|
|
10563
10651
|
{
|
|
10564
10652
|
label: 'Show intron lines',
|
|
10565
10653
|
type: 'checkbox',
|
|
10566
10654
|
checked: self.showIntronLines,
|
|
10567
|
-
onClick: () =>
|
|
10655
|
+
onClick: () => {
|
|
10656
|
+
self.toggleShowIntronLines();
|
|
10657
|
+
},
|
|
10568
10658
|
},
|
|
10569
10659
|
];
|
|
10570
10660
|
},
|
|
10571
10661
|
}));
|
|
10572
10662
|
}
|
|
10573
10663
|
|
|
10664
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
10574
10665
|
function isApolloMessageData(data) {
|
|
10575
10666
|
return (typeof data === 'object' &&
|
|
10576
10667
|
data !== null &&
|