@teselagen/ove 0.3.11 → 0.3.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +362 -209
- package/index.mjs +362 -209
- package/index.umd.js +339 -232
- package/package.json +1 -1
- package/src/AlignmentView/AlignmentVisibilityTool.js +1 -1
- package/src/AlignmentView/EditTrackNameDialog.js +1 -5
- package/src/AlignmentView/HorizontalPanelDragHandle.js +2 -2
- package/src/AlignmentView/Minimap.js +12 -12
- package/src/AlignmentView/PairwiseAlignmentView.js +1 -1
- package/src/AlignmentView/getGapMap.js +1 -1
- package/src/AlignmentView/getTrackFromEvent.js +1 -1
- package/src/AlignmentView/index.js +32 -37
- package/src/AutoAnnotate.js +48 -48
- package/src/CircularView/Cutsites.js +3 -3
- package/src/CircularView/Labels/index.js +7 -7
- package/src/CircularView/Labels/relaxLabels_DEPRECATED.js +5 -5
- package/src/CircularView/RotateCircularViewSlider.js +1 -1
- package/src/CircularView/SelectionLayer.js +2 -2
- package/src/CircularView/drawAnnotations.js +3 -3
- package/src/CircularView/getAngleForPositionMidpoint.js +1 -1
- package/src/CircularView/index.d.ts +11 -11
- package/src/CircularView/index.js +9 -9
- package/src/CreateAnnotationsPage.js +7 -5
- package/src/CreateCustomEnzyme/index.js +1 -5
- package/src/CutsiteFilter/AdditionalCutsiteInfoDialog.js +11 -11
- package/src/CutsiteFilter/index.js +12 -12
- package/src/DigestTool/AddLaddersDialog.js +1 -1
- package/src/DigestTool/DigestTool.js +3 -3
- package/src/DigestTool/Ladder.js +8 -8
- package/src/DigestTool/ladderDefaults.js +1 -2
- package/src/Editor/CommandHotkeyHandler.js +1 -1
- package/src/Editor/DropHandler.js +2 -2
- package/src/Editor/index.js +14 -14
- package/src/Editor/userDefinedHandlersAndOpts.js +2 -0
- package/src/FindBar/index.js +6 -6
- package/src/GlobalDialogUtils.js +6 -0
- package/src/LinearView/ZoomLinearView.js +1 -1
- package/src/LinearView/index.js +7 -7
- package/src/MenuBar/index.js +1 -1
- package/src/MenuBar/viewSubmenu.js +1 -1
- package/src/PCRTool/PCRTool.js +19 -19
- package/src/Reflex/Browser.js +4 -5
- package/src/Reflex/ReflexContainer.js +3 -3
- package/src/Reflex/ReflexElement.js +2 -2
- package/src/RowItem/Axis.js +1 -1
- package/src/RowItem/Caret/index.js +1 -1
- package/src/RowItem/Chromatograms/Chromatogram.js +3 -3
- package/src/RowItem/CutsiteSelectionLayers.js +1 -1
- package/src/RowItem/Cutsites.js +1 -1
- package/src/RowItem/Labels.js +2 -2
- package/src/RowItem/Orfs.js +2 -2
- package/src/RowItem/Sequence.js +4 -4
- package/src/RowItem/StackedAnnotations/PointedAnnotation.js +3 -3
- package/src/RowItem/StackedAnnotations/getStructuredBases.js +1 -1
- package/src/RowItem/Translations/AASliver.js +71 -75
- package/src/RowItem/Translations/index.js +1 -1
- package/src/RowItem/getCutsiteLabelHeights.js +1 -1
- package/src/RowItem/index.js +14 -8
- package/src/RowView/estimateRowHeight.js +5 -5
- package/src/RowView/index.d.ts +7 -7
- package/src/RowView/index.js +11 -12
- package/src/SimpleCircularOrLinearView.js +6 -6
- package/src/StatusBar/MeltingTemp.js +3 -3
- package/src/ToolBar/ToolbarItem.js +2 -2
- package/src/ToolBar/alignmentTool.js +9 -9
- package/src/ToolBar/editTool.js +1 -1
- package/src/ToolBar/findTool.js +2 -2
- package/src/ToolBar/importTool.js +1 -1
- package/src/ToolBar/index.js +2 -2
- package/src/ToolBar/oligoTool.js +1 -1
- package/src/ToolBar/orfTool.js +1 -6
- package/src/ToolBar/printTool.js +2 -2
- package/src/ToolBar/visibilityTool.js +1 -1
- package/src/VersionHistoryView/index.js +2 -2
- package/src/commands/index.js +236 -230
- package/src/createVectorEditor/index.js +4 -4
- package/src/fileUtils.js +18 -18
- package/src/helperComponents/AddOrEditAnnotationDialog/index.js +22 -15
- package/src/helperComponents/AddOrEditFeatureDialog/index.js +2 -2
- package/src/helperComponents/AddOrEditPartDialog/index.js +2 -2
- package/src/helperComponents/AddOrEditPrimerDialog/index.js +5 -5
- package/src/helperComponents/EnzymesDialog/index.js +17 -22
- package/src/helperComponents/GoToDialog.js +5 -1
- package/src/helperComponents/MergeFeaturesDialog/index.js +3 -3
- package/src/helperComponents/PinchHelper/PinchHelper.js +1 -1
- package/src/helperComponents/PrintDialog/index.js +4 -4
- package/src/helperComponents/PropertiesDialog/CutsiteProperties.js +3 -3
- package/src/helperComponents/PropertiesDialog/GenbankView.js +1 -1
- package/src/helperComponents/PropertiesDialog/GeneralProperties.js +5 -5
- package/src/helperComponents/PropertiesDialog/GenericAnnotationProperties.js +136 -138
- package/src/helperComponents/PropertiesDialog/OrfProperties.js +3 -3
- package/src/helperComponents/PropertiesDialog/PrimerProperties.js +1 -1
- package/src/helperComponents/PropertiesDialog/TranslationProperties.js +2 -2
- package/src/helperComponents/PropertiesDialog/index.js +3 -3
- package/src/helperComponents/RemoveDuplicates/index.js +3 -3
- package/src/helperComponents/SelectDialog.js +3 -3
- package/src/helperComponents/UncontrolledSliderWithPlusMinusBtns.js +5 -5
- package/src/helperComponents/createSimpleDialog.js +1 -1
- package/src/helperComponents/partTagSearch.js +2 -5
- package/src/helperComponents/withHover.js +3 -3
- package/src/redux/alignments.js +6 -6
- package/src/redux/annotationVisibility.js +4 -4
- package/src/redux/featureLengthsToHide.js +1 -1
- package/src/redux/frameTranslations.js +3 -3
- package/src/redux/middleware.js +2 -2
- package/src/redux/panelsShown.js +19 -19
- package/src/redux/partLengthsToHide.js +1 -1
- package/src/redux/primerLengthsToHide.js +1 -1
- package/src/redux/readOnly.js +1 -4
- package/src/redux/selectionLayer.js +1 -1
- package/src/redux/sequenceData/features.js +1 -1
- package/src/redux/sequenceData/upsertDeleteActionGenerator.js +1 -1
- package/src/redux/sequenceDataHistory.js +5 -5
- package/src/redux/toolBar.js +2 -4
- package/src/redux/utils/createMetaAction.js +2 -2
- package/src/redux/versionHistory.js +1 -2
- package/src/selectors/annotationSearchSelector.js +4 -4
- package/src/selectors/circularSelector.js +1 -1
- package/src/selectors/cutsiteLabelColorSelector.js +1 -1
- package/src/selectors/filteredCutsitesSelector.js +6 -6
- package/src/selectors/filteredFeaturesSelector.js +4 -4
- package/src/selectors/filteredPartsSelector.js +5 -5
- package/src/selectors/filteredPrimersSelector.js +3 -3
- package/src/selectors/isEnzymeFilterAndSelector.js +1 -1
- package/src/selectors/orfsSelector.js +1 -1
- package/src/selectors/restrictionEnzymesSelector.js +2 -2
- package/src/selectors/searchLayersSelector.js +7 -7
- package/src/selectors/sequenceLengthSelector.js +1 -1
- package/src/selectors/sequenceSelector.js +1 -1
- package/src/selectors/tagsToBoldSelector.js +1 -1
- package/src/selectors/translationsSelector.js +7 -7
- package/src/updateEditor.js +1 -1
- package/src/utils/PassThrough.js +1 -1
- package/src/utils/addWrappedAddons.js +1 -1
- package/src/utils/annotationTypes.js +2 -2
- package/src/utils/combineReducersDontIgnoreKeys.js +1 -1
- package/src/utils/editorUtils.js +2 -2
- package/src/utils/massageTickSpacing.js +1 -1
- package/src/utils/onlyUpdateForKeysDeep.js +1 -1
- package/src/utils/pureNoFunc.js +1 -1
- package/src/utils/shouldRerender.js +1 -1
- package/src/utils/showFileDialog.js +6 -7
- package/src/utils/updateLabelsForInViewFeatures.js +1 -1
- package/src/utils/useAnnotationLimits.js +1 -1
- package/src/withEditorInteractions/Keyboard.js +2 -3
- package/src/withEditorInteractions/createSequenceInputPopup.js +4 -4
- package/src/withEditorInteractions/index.js +93 -55
- package/src/withEditorProps/index.js +40 -37
package/src/commands/index.js
CHANGED
|
@@ -37,11 +37,11 @@ import {
|
|
|
37
37
|
} from "../GlobalDialogUtils";
|
|
38
38
|
import { partsSubmenu } from "../MenuBar/viewSubmenu";
|
|
39
39
|
|
|
40
|
-
const isProtein =
|
|
41
|
-
const isOligo =
|
|
42
|
-
const isRna =
|
|
40
|
+
const isProtein = props => props.sequenceData && props.sequenceData.isProtein;
|
|
41
|
+
const isOligo = props => props.sequenceData && props.sequenceData.isOligo;
|
|
42
|
+
const isRna = props => props.sequenceData && props.sequenceData.isRna;
|
|
43
43
|
const partsPrimersFeatures = ["Parts", "Features", "Primers"];
|
|
44
|
-
const getNewTranslationHandler =
|
|
44
|
+
const getNewTranslationHandler = isReverse => ({
|
|
45
45
|
handler: (props, state, ctxInfo) => {
|
|
46
46
|
const annotation =
|
|
47
47
|
get(ctxInfo, "context.annotation") || props.selectionLayer;
|
|
@@ -55,31 +55,31 @@ const getNewTranslationHandler = (isReverse) => ({
|
|
|
55
55
|
});
|
|
56
56
|
props.annotationVisibilityShow("translations");
|
|
57
57
|
},
|
|
58
|
-
isHidden:
|
|
58
|
+
isHidden: props =>
|
|
59
59
|
isProtein(props) ||
|
|
60
60
|
!props.annotationsToSupport ||
|
|
61
61
|
// props.readOnly ||
|
|
62
62
|
!props.annotationsToSupport.translations,
|
|
63
|
-
isDisabled:
|
|
63
|
+
isDisabled: props =>
|
|
64
64
|
/* (props.readOnly && readOnlyDisabledTooltip) || */ props.sequenceLength ===
|
|
65
65
|
0 || noSelection(props)
|
|
66
66
|
});
|
|
67
67
|
|
|
68
68
|
const fileCommandDefs = {
|
|
69
69
|
newSequence: {
|
|
70
|
-
isHidden:
|
|
70
|
+
isHidden: props => !props.onNew,
|
|
71
71
|
handler: (props, ...rest) => props.onNew(props, ...rest)
|
|
72
72
|
},
|
|
73
73
|
|
|
74
74
|
renameSequence: {
|
|
75
|
-
isHidden:
|
|
76
|
-
isDisabled:
|
|
77
|
-
handler:
|
|
75
|
+
isHidden: props => props.readOnly,
|
|
76
|
+
isDisabled: props => props.readOnly && readOnlyDisabledTooltip,
|
|
77
|
+
handler: props => {
|
|
78
78
|
showDialog({
|
|
79
79
|
dialogType: "RenameSequenceDialog",
|
|
80
80
|
props: {
|
|
81
81
|
initialValues: { newName: props.sequenceData.name },
|
|
82
|
-
onSubmit:
|
|
82
|
+
onSubmit: values => {
|
|
83
83
|
props.sequenceNameUpdate(values.newName);
|
|
84
84
|
props.onRename && props.onRename(values.newName, props);
|
|
85
85
|
}
|
|
@@ -90,15 +90,15 @@ const fileCommandDefs = {
|
|
|
90
90
|
|
|
91
91
|
saveSequence: {
|
|
92
92
|
name: "Save",
|
|
93
|
-
isDisabled:
|
|
93
|
+
isDisabled: props =>
|
|
94
94
|
props.alwaysAllowSave
|
|
95
95
|
? false
|
|
96
96
|
: (props.readOnly && readOnlyDisabledTooltip) ||
|
|
97
97
|
!props.sequenceData ||
|
|
98
98
|
props.sequenceData.stateTrackingId === "initialLoadId" ||
|
|
99
99
|
props.sequenceData.stateTrackingId === props.lastSavedId,
|
|
100
|
-
isHidden:
|
|
101
|
-
handler:
|
|
100
|
+
isHidden: props => props.readOnly || !props.handleSave,
|
|
101
|
+
handler: props => props.handleSave(),
|
|
102
102
|
hotkey: "mod+s"
|
|
103
103
|
},
|
|
104
104
|
saveSequenceAs: {
|
|
@@ -108,8 +108,8 @@ const fileCommandDefs = {
|
|
|
108
108
|
// !props.sequenceData ||
|
|
109
109
|
// (props.sequenceData.stateTrackingId === "initialLoadId" ||
|
|
110
110
|
// props.sequenceData.stateTrackingId === props.lastSavedId),
|
|
111
|
-
isHidden:
|
|
112
|
-
handler:
|
|
111
|
+
isHidden: props => !props.onSaveAs,
|
|
112
|
+
handler: props => props.handleSave({ isSaveAs: true }),
|
|
113
113
|
hotkey: "mod+shift+s"
|
|
114
114
|
},
|
|
115
115
|
toolsCmd: {
|
|
@@ -118,15 +118,17 @@ const fileCommandDefs = {
|
|
|
118
118
|
},
|
|
119
119
|
|
|
120
120
|
deleteSequence: {
|
|
121
|
-
isDisabled:
|
|
122
|
-
(props.
|
|
123
|
-
|
|
124
|
-
|
|
121
|
+
isDisabled: props =>
|
|
122
|
+
(props.disableBpEditing && bpEditingDisabledTooltip) ||
|
|
123
|
+
(props.readOnly && readOnlyDisabledTooltip) ||
|
|
124
|
+
!props.onDelete,
|
|
125
|
+
isHidden: props => !props.onDelete,
|
|
126
|
+
handler: props => props.onDelete(props.sequenceData)
|
|
125
127
|
},
|
|
126
128
|
|
|
127
129
|
duplicateSequence: {
|
|
128
|
-
isDisabled:
|
|
129
|
-
isHidden:
|
|
130
|
+
isDisabled: props => !props.onDuplicate,
|
|
131
|
+
isHidden: props => !props.onDuplicate,
|
|
130
132
|
handler: (props, ...rest) =>
|
|
131
133
|
props.onDuplicate(props.sequenceData, props, ...rest),
|
|
132
134
|
hotkey: "alt+shift+d"
|
|
@@ -134,28 +136,28 @@ const fileCommandDefs = {
|
|
|
134
136
|
|
|
135
137
|
toggleReadOnlyMode: {
|
|
136
138
|
toggle: [],
|
|
137
|
-
isDisabled:
|
|
138
|
-
isHidden:
|
|
139
|
-
isActive:
|
|
140
|
-
handler:
|
|
139
|
+
isDisabled: props => props.disableSetReadOnly || !props.onSave,
|
|
140
|
+
isHidden: props => !props.toggleReadOnlyMode,
|
|
141
|
+
isActive: props => props.readOnly,
|
|
142
|
+
handler: props => props.toggleReadOnlyMode()
|
|
141
143
|
},
|
|
142
144
|
|
|
143
145
|
importSequence: {
|
|
144
|
-
isHidden:
|
|
145
|
-
isDisabled:
|
|
146
|
-
handler:
|
|
146
|
+
isHidden: props => props.hideSingleImport,
|
|
147
|
+
isDisabled: props => props.readOnly,
|
|
148
|
+
handler: props => {
|
|
147
149
|
showFileDialog({
|
|
148
150
|
multiple: false,
|
|
149
|
-
onSelect:
|
|
151
|
+
onSelect: files => {
|
|
150
152
|
props.importSequenceFromFile(files[0]);
|
|
151
153
|
}
|
|
152
154
|
});
|
|
153
155
|
}
|
|
154
156
|
},
|
|
155
157
|
filterPartsByTagCmd: {
|
|
156
|
-
isHidden:
|
|
158
|
+
isHidden: props => !props.allPartTags,
|
|
157
159
|
name: "Search Parts By Tag",
|
|
158
|
-
component:
|
|
160
|
+
component: props => () => {
|
|
159
161
|
return (
|
|
160
162
|
// eslint-disable-next-line jsx-a11y/anchor-is-valid
|
|
161
163
|
<div
|
|
@@ -176,7 +178,7 @@ const fileCommandDefs = {
|
|
|
176
178
|
filterPartLengthsCmd: getFilterByLengthCmd("part"),
|
|
177
179
|
filterPrimerLengthsCmd: getFilterByLengthCmd("primer"),
|
|
178
180
|
featureTypesCmd: {
|
|
179
|
-
name:
|
|
181
|
+
name: props => {
|
|
180
182
|
const total = Object.keys(
|
|
181
183
|
reduce(
|
|
182
184
|
props.sequenceData.features,
|
|
@@ -199,9 +201,9 @@ const fileCommandDefs = {
|
|
|
199
201
|
</span>
|
|
200
202
|
);
|
|
201
203
|
},
|
|
202
|
-
submenu:
|
|
204
|
+
submenu: props => {
|
|
203
205
|
const types = {};
|
|
204
|
-
forEach(props.sequenceData.features,
|
|
206
|
+
forEach(props.sequenceData.features, feat => {
|
|
205
207
|
if (!feat.type) return;
|
|
206
208
|
const checked =
|
|
207
209
|
!props.annotationVisibility.featureTypesToHide[feat.type];
|
|
@@ -256,31 +258,31 @@ const fileCommandDefs = {
|
|
|
256
258
|
partFilterIndividualCmd: getFilterIndividualCmd("part"),
|
|
257
259
|
primerFilterIndividualCmd: getFilterIndividualCmd("primer"),
|
|
258
260
|
exportSequenceAsGenbank: {
|
|
259
|
-
name:
|
|
261
|
+
name: props =>
|
|
260
262
|
isProtein(props) ? "Download GenPept File" : "Download Genbank File",
|
|
261
|
-
handler:
|
|
263
|
+
handler: props =>
|
|
262
264
|
props.exportSequenceToFile(isProtein(props) ? "genpept" : "genbank")
|
|
263
265
|
},
|
|
264
266
|
exportSequenceAsFasta: {
|
|
265
267
|
name: "Download FASTA File",
|
|
266
|
-
handler:
|
|
268
|
+
handler: props => props.exportSequenceToFile("fasta")
|
|
267
269
|
},
|
|
268
270
|
exportSequenceAsTeselagenJson: {
|
|
269
271
|
name: "Download Teselagen JSON File",
|
|
270
|
-
handler:
|
|
272
|
+
handler: props => props.exportSequenceToFile("teselagenJson")
|
|
271
273
|
},
|
|
272
274
|
|
|
273
275
|
viewProperties: {
|
|
274
|
-
handler:
|
|
276
|
+
handler: props => props.propertiesViewOpen()
|
|
275
277
|
},
|
|
276
278
|
viewRevisionHistory: {
|
|
277
|
-
handler:
|
|
278
|
-
isHidden:
|
|
279
|
+
handler: props => props.toggleViewVersionHistory(),
|
|
280
|
+
isHidden: props => !props.getVersionList || !props.getSequenceAtVersion
|
|
279
281
|
},
|
|
280
282
|
|
|
281
283
|
print: {
|
|
282
284
|
hotkeyProps: { preventDefault: true },
|
|
283
|
-
handler:
|
|
285
|
+
handler: props =>
|
|
284
286
|
showDialog({
|
|
285
287
|
dialogType: "PrintDialog",
|
|
286
288
|
props
|
|
@@ -291,8 +293,8 @@ const fileCommandDefs = {
|
|
|
291
293
|
//showRemoveDuplicatesDialogFeatures showRemoveDuplicatesDialogParts showRemoveDuplicatesDialogPrimers
|
|
292
294
|
acc[`showRemoveDuplicatesDialog${type}`] = {
|
|
293
295
|
name: `Remove Duplicate ${startCase(type)}`,
|
|
294
|
-
isDisabled:
|
|
295
|
-
handler:
|
|
296
|
+
isDisabled: props => props.readOnly,
|
|
297
|
+
handler: props =>
|
|
296
298
|
showDialog({
|
|
297
299
|
dialogType: "RemoveDuplicates",
|
|
298
300
|
props: {
|
|
@@ -307,21 +309,21 @@ const fileCommandDefs = {
|
|
|
307
309
|
return acc;
|
|
308
310
|
}, {}),
|
|
309
311
|
autoAnnotateHolder: {
|
|
310
|
-
isHidden:
|
|
311
|
-
!some(partsPrimersFeatures,
|
|
312
|
+
isHidden: props =>
|
|
313
|
+
!some(partsPrimersFeatures, type => props[`autoAnnotate${type}`])
|
|
312
314
|
},
|
|
313
315
|
onConfigureFeatureTypesClick: {
|
|
314
316
|
name: "Configure Feature Types",
|
|
315
|
-
handler:
|
|
316
|
-
isHidden:
|
|
317
|
+
handler: p => p.onConfigureFeatureTypesClick(),
|
|
318
|
+
isHidden: props => !props.onConfigureFeatureTypesClick
|
|
317
319
|
},
|
|
318
320
|
...partsPrimersFeatures.reduce((acc, type) => {
|
|
319
321
|
const handlerName = `autoAnnotate${type}`;
|
|
320
322
|
acc[handlerName] = {
|
|
321
323
|
name: `Auto Annotate ${type}`,
|
|
322
|
-
isDisabled:
|
|
323
|
-
isHidden:
|
|
324
|
-
handler: async
|
|
324
|
+
isDisabled: props => props.readOnly,
|
|
325
|
+
isHidden: props => !props[handlerName],
|
|
326
|
+
handler: async props => {
|
|
325
327
|
if (props[handlerName]) {
|
|
326
328
|
const lowerType = type.toLowerCase();
|
|
327
329
|
const toAdd = await props[handlerName](props);
|
|
@@ -339,22 +341,23 @@ const fileCommandDefs = {
|
|
|
339
341
|
};
|
|
340
342
|
//copy options
|
|
341
343
|
const toggleCopyOptionCommandDefs = {};
|
|
342
|
-
Object.keys(defaultCopyOptions).forEach(
|
|
344
|
+
Object.keys(defaultCopyOptions).forEach(type => {
|
|
343
345
|
const cmdId = `toggleCopy${upperFirst(type)}`;
|
|
344
346
|
toggleCopyOptionCommandDefs[cmdId] = {
|
|
345
347
|
name: `Include ${startCase(type)}`,
|
|
346
|
-
handler:
|
|
347
|
-
isActive:
|
|
348
|
+
handler: props => props.toggleCopyOption(type),
|
|
349
|
+
isActive: props => props.copyOptions && props.copyOptions[type]
|
|
348
350
|
};
|
|
349
351
|
});
|
|
350
352
|
|
|
351
353
|
const readOnlyDisabledTooltip =
|
|
352
354
|
"Sorry this function is not allowed in Read-Only Mode";
|
|
355
|
+
const bpEditingDisabledTooltip = "Sequence Editing Disabled";
|
|
353
356
|
const noSelection = ({ selectionLayer = {} }) =>
|
|
354
357
|
!(selectionLayer.start > -1 && selectionLayer.end > -1) &&
|
|
355
358
|
"Selection Required";
|
|
356
359
|
|
|
357
|
-
const triggerClipboardCommand =
|
|
360
|
+
const triggerClipboardCommand = type => {
|
|
358
361
|
const wrapper = document.querySelector(".veVectorInteractionWrapper");
|
|
359
362
|
if (!wrapper) {
|
|
360
363
|
return window.toastr.info(`Cannot trigger a ${type} in the current view`);
|
|
@@ -382,13 +385,15 @@ const editCommandDefs = {
|
|
|
382
385
|
handler: noop
|
|
383
386
|
},
|
|
384
387
|
changeCircularityCmd: {
|
|
385
|
-
isHidden:
|
|
388
|
+
isHidden: p => p.readOnly || isProtein(p) || isOligo(p) || isRna(p),
|
|
386
389
|
handler: noop
|
|
387
390
|
},
|
|
388
391
|
cut: {
|
|
389
|
-
isDisabled:
|
|
390
|
-
(props.
|
|
391
|
-
|
|
392
|
+
isDisabled: props =>
|
|
393
|
+
(props.disableBpEditing && bpEditingDisabledTooltip) ||
|
|
394
|
+
(props.readOnly && readOnlyDisabledTooltip) ||
|
|
395
|
+
props.sequenceLength === 0,
|
|
396
|
+
isHidden: props => props.readOnly || props.disableBpEditing,
|
|
392
397
|
handler: () => {
|
|
393
398
|
triggerClipboardCommand("cut");
|
|
394
399
|
},
|
|
@@ -396,10 +401,10 @@ const editCommandDefs = {
|
|
|
396
401
|
},
|
|
397
402
|
createNewFromSubsequence: {
|
|
398
403
|
name: "New Sequence From Selected Range",
|
|
399
|
-
isDisabled:
|
|
404
|
+
isDisabled: props =>
|
|
400
405
|
props.sequenceLength === 0 || props.selectionLayer.start === -1,
|
|
401
|
-
isHidden:
|
|
402
|
-
handler:
|
|
406
|
+
isHidden: props => !props.onCreateNewFromSubsequence,
|
|
407
|
+
handler: props => {
|
|
403
408
|
props.onCreateNewFromSubsequence(
|
|
404
409
|
getSequenceDataBetweenRange(props.sequenceData, props.selectionLayer),
|
|
405
410
|
props
|
|
@@ -409,51 +414,51 @@ const editCommandDefs = {
|
|
|
409
414
|
},
|
|
410
415
|
|
|
411
416
|
copy: {
|
|
412
|
-
isDisabled:
|
|
417
|
+
isDisabled: props => props.sequenceLength === 0,
|
|
413
418
|
|
|
414
419
|
handler: () => triggerClipboardCommand("copy"),
|
|
415
420
|
hotkey: "mod+c"
|
|
416
421
|
},
|
|
417
422
|
|
|
418
423
|
paste: {
|
|
419
|
-
isDisabled:
|
|
420
|
-
isHidden:
|
|
424
|
+
isDisabled: props => props.readOnly && readOnlyDisabledTooltip,
|
|
425
|
+
isHidden: props => props.readOnly || props.disableBpEditing,
|
|
421
426
|
|
|
422
427
|
handler: () => triggerClipboardCommand("paste"),
|
|
423
428
|
hotkey: "mod+v"
|
|
424
429
|
},
|
|
425
430
|
|
|
426
431
|
undo: {
|
|
427
|
-
isHidden:
|
|
432
|
+
isHidden: props => props.readOnly,
|
|
428
433
|
|
|
429
|
-
isDisabled:
|
|
434
|
+
isDisabled: props =>
|
|
430
435
|
props.readOnly ||
|
|
431
436
|
!(
|
|
432
437
|
props.sequenceDataHistory &&
|
|
433
438
|
props.sequenceDataHistory.past &&
|
|
434
439
|
props.sequenceDataHistory.past.length
|
|
435
440
|
),
|
|
436
|
-
handler:
|
|
441
|
+
handler: props => props.undo(),
|
|
437
442
|
hotkey: "mod+z"
|
|
438
443
|
},
|
|
439
444
|
|
|
440
445
|
redo: {
|
|
441
|
-
isHidden:
|
|
446
|
+
isHidden: props => props.readOnly,
|
|
442
447
|
|
|
443
|
-
isDisabled:
|
|
448
|
+
isDisabled: props =>
|
|
444
449
|
props.readOnly ||
|
|
445
450
|
!(
|
|
446
451
|
props.sequenceDataHistory &&
|
|
447
452
|
props.sequenceDataHistory.future &&
|
|
448
453
|
props.sequenceDataHistory.future.length
|
|
449
454
|
),
|
|
450
|
-
handler:
|
|
455
|
+
handler: props => props.redo(),
|
|
451
456
|
hotkey: "mod+shift+z"
|
|
452
457
|
},
|
|
453
458
|
find: {
|
|
454
|
-
isDisabled:
|
|
459
|
+
isDisabled: props => props.sequenceLength === 0,
|
|
455
460
|
name: "Find...",
|
|
456
|
-
handler:
|
|
461
|
+
handler: props => {
|
|
457
462
|
if (props.findTool.isOpen) {
|
|
458
463
|
const inputEl =
|
|
459
464
|
document.querySelector("textarea.tg-find-tool-input") ||
|
|
@@ -469,7 +474,7 @@ const editCommandDefs = {
|
|
|
469
474
|
hotkeyProps: { preventDefault: true }
|
|
470
475
|
},
|
|
471
476
|
about: {
|
|
472
|
-
isDisabled:
|
|
477
|
+
isDisabled: props => props.sequenceLength === 0,
|
|
473
478
|
name: "About",
|
|
474
479
|
handler: () =>
|
|
475
480
|
showConfirmationDialog({
|
|
@@ -502,9 +507,9 @@ const editCommandDefs = {
|
|
|
502
507
|
},
|
|
503
508
|
|
|
504
509
|
goTo: {
|
|
505
|
-
isDisabled:
|
|
510
|
+
isDisabled: props => props.sequenceLength === 0,
|
|
506
511
|
name: "Go To...",
|
|
507
|
-
handler:
|
|
512
|
+
handler: props => {
|
|
508
513
|
showDialog({
|
|
509
514
|
dialogType: "GoToDialog",
|
|
510
515
|
props: {
|
|
@@ -520,7 +525,7 @@ const editCommandDefs = {
|
|
|
520
525
|
isProtein(props)
|
|
521
526
|
)
|
|
522
527
|
},
|
|
523
|
-
onSubmit:
|
|
528
|
+
onSubmit: values =>
|
|
524
529
|
props.caretPositionUpdate(
|
|
525
530
|
values.sequencePosition * (isProtein(props) ? 3 : 1)
|
|
526
531
|
)
|
|
@@ -532,9 +537,9 @@ const editCommandDefs = {
|
|
|
532
537
|
},
|
|
533
538
|
|
|
534
539
|
select: {
|
|
535
|
-
isDisabled:
|
|
540
|
+
isDisabled: props => props.sequenceLength === 0,
|
|
536
541
|
name: "Select...",
|
|
537
|
-
handler:
|
|
542
|
+
handler: props => {
|
|
538
543
|
let { start, end } = props.selectionLayer;
|
|
539
544
|
if (!(start > -1)) {
|
|
540
545
|
start = props.caretPosition;
|
|
@@ -569,7 +574,7 @@ const editCommandDefs = {
|
|
|
569
574
|
props.sequenceLength || 1,
|
|
570
575
|
isProtein(props)
|
|
571
576
|
),
|
|
572
|
-
onSubmit:
|
|
577
|
+
onSubmit: values => {
|
|
573
578
|
const newRange = convertRangeTo0Based({
|
|
574
579
|
start: isProtein(props) ? values.from * 3 : values.from,
|
|
575
580
|
end: isProtein(props) ? values.to * 3 : values.to
|
|
@@ -593,46 +598,48 @@ const editCommandDefs = {
|
|
|
593
598
|
}
|
|
594
599
|
props.selectAll();
|
|
595
600
|
},
|
|
596
|
-
isDisabled:
|
|
601
|
+
isDisabled: props => props.sequenceLength === 0,
|
|
597
602
|
hotkey: "mod+a"
|
|
598
603
|
//tnr: we can't pass the following because it will block inputs
|
|
599
604
|
// hotkeyProps: { preventDefault: true, stopPropagation: true }
|
|
600
605
|
},
|
|
601
606
|
|
|
602
607
|
selectInverse: {
|
|
603
|
-
isDisabled:
|
|
604
|
-
handler:
|
|
608
|
+
isDisabled: props => noSelection(props),
|
|
609
|
+
handler: props => props.handleInverse(),
|
|
605
610
|
hotkey: "mod+i"
|
|
606
611
|
},
|
|
607
612
|
|
|
608
613
|
complementSelection: {
|
|
609
|
-
isHidden:
|
|
614
|
+
isHidden: props =>
|
|
615
|
+
props.readOnly || isProtein(props) || props.disableBpEditing,
|
|
610
616
|
|
|
611
|
-
isDisabled:
|
|
617
|
+
isDisabled: props =>
|
|
612
618
|
(props.readOnly && readOnlyDisabledTooltip) || noSelection(props),
|
|
613
|
-
handler:
|
|
619
|
+
handler: props => props.handleComplementSelection()
|
|
614
620
|
},
|
|
615
621
|
|
|
616
622
|
complementEntireSequence: {
|
|
617
|
-
isHidden:
|
|
623
|
+
isHidden: props =>
|
|
624
|
+
props.readOnly || isProtein(props) || props.disableBpEditing,
|
|
618
625
|
|
|
619
|
-
isDisabled:
|
|
626
|
+
isDisabled: props =>
|
|
620
627
|
(props.readOnly && readOnlyDisabledTooltip) || props.sequenceLength === 0,
|
|
621
628
|
|
|
622
|
-
handler:
|
|
629
|
+
handler: props => props.handleComplementSequence()
|
|
623
630
|
},
|
|
624
631
|
sequenceCase: {
|
|
625
632
|
isHidden: isProtein
|
|
626
633
|
},
|
|
627
634
|
toggleCircular: {
|
|
628
635
|
name: "Circular",
|
|
629
|
-
isActive:
|
|
630
|
-
handler:
|
|
636
|
+
isActive: props => props.sequenceData.circular,
|
|
637
|
+
handler: props => props.updateCircular(true)
|
|
631
638
|
},
|
|
632
639
|
toggleLinear: {
|
|
633
640
|
name: "Linear",
|
|
634
|
-
isActive:
|
|
635
|
-
handler:
|
|
641
|
+
isActive: props => !props.sequenceData.circular,
|
|
642
|
+
handler: props => props.updateCircular(false)
|
|
636
643
|
},
|
|
637
644
|
...[
|
|
638
645
|
{ hotkey: "option + =", type: "flipCaseSequence" },
|
|
@@ -645,7 +652,7 @@ const editCommandDefs = {
|
|
|
645
652
|
|
|
646
653
|
acc[type] = {
|
|
647
654
|
isHidden: isProtein,
|
|
648
|
-
isDisabled:
|
|
655
|
+
isDisabled: props => {
|
|
649
656
|
if (props.readOnly) {
|
|
650
657
|
return "The sequence is read only. Try changing 'View > Sequence > Case'";
|
|
651
658
|
}
|
|
@@ -655,7 +662,7 @@ const editCommandDefs = {
|
|
|
655
662
|
},
|
|
656
663
|
name: startCase(type),
|
|
657
664
|
hotkey,
|
|
658
|
-
handler:
|
|
665
|
+
handler: props => {
|
|
659
666
|
const { sequence } = props.sequenceData;
|
|
660
667
|
const { selectionLayer } = props;
|
|
661
668
|
let toastFired;
|
|
@@ -701,31 +708,31 @@ const editCommandDefs = {
|
|
|
701
708
|
}, {}),
|
|
702
709
|
|
|
703
710
|
toggleShowGCContent: {
|
|
704
|
-
isActive:
|
|
705
|
-
handler:
|
|
711
|
+
isActive: props => props.showGCContent,
|
|
712
|
+
handler: props => {
|
|
706
713
|
props.toggleShowGCContent(!props.showGCContent);
|
|
707
714
|
}
|
|
708
715
|
},
|
|
709
716
|
|
|
710
717
|
toggleSequenceMapFontUpper: {
|
|
711
|
-
isActive:
|
|
712
|
-
handler:
|
|
718
|
+
isActive: props => props.uppercaseSequenceMapFont === "uppercase",
|
|
719
|
+
handler: props => {
|
|
713
720
|
props.updateSequenceCase("uppercase");
|
|
714
721
|
window.toastr.success(`Sequence Case View Changed`);
|
|
715
722
|
},
|
|
716
723
|
hotkey: "ctrl+option+plus"
|
|
717
724
|
},
|
|
718
725
|
toggleSequenceMapFontRaw: {
|
|
719
|
-
isActive:
|
|
720
|
-
handler:
|
|
726
|
+
isActive: props => props.uppercaseSequenceMapFont === "noPreference",
|
|
727
|
+
handler: props => {
|
|
721
728
|
props.updateSequenceCase("noPreference");
|
|
722
729
|
window.toastr.success(`Sequence Case View Changed`);
|
|
723
730
|
},
|
|
724
731
|
hotkey: "ctrl+option+="
|
|
725
732
|
},
|
|
726
733
|
toggleSequenceMapFontLower: {
|
|
727
|
-
isActive:
|
|
728
|
-
handler:
|
|
734
|
+
isActive: props => props.uppercaseSequenceMapFont === "lowercase",
|
|
735
|
+
handler: props => {
|
|
729
736
|
props.updateSequenceCase("lowercase");
|
|
730
737
|
window.toastr.success(`Sequence Case View Changed`);
|
|
731
738
|
},
|
|
@@ -733,14 +740,14 @@ const editCommandDefs = {
|
|
|
733
740
|
},
|
|
734
741
|
setRowViewSequenceSpacing: {
|
|
735
742
|
handler: noop,
|
|
736
|
-
name:
|
|
743
|
+
name: props => {
|
|
737
744
|
return (
|
|
738
745
|
<div data-test="setRowViewSequenceSpacing">
|
|
739
746
|
Spacing (in Sequence Map)
|
|
740
747
|
<div style={{ paddingLeft: 11, paddingRight: 11, paddingTop: 3 }}>
|
|
741
748
|
<Slider
|
|
742
749
|
stepSize={1}
|
|
743
|
-
onChange={
|
|
750
|
+
onChange={v => {
|
|
744
751
|
props.updateSequenceSpacing(v);
|
|
745
752
|
}}
|
|
746
753
|
value={Number(props.charWidth)}
|
|
@@ -755,9 +762,9 @@ const editCommandDefs = {
|
|
|
755
762
|
},
|
|
756
763
|
createMenuHolder: {
|
|
757
764
|
name: "Create",
|
|
758
|
-
isHidden:
|
|
765
|
+
isHidden: props => isProtein(props) && props.readOnly,
|
|
759
766
|
handler: noop,
|
|
760
|
-
submenu:
|
|
767
|
+
submenu: props => {
|
|
761
768
|
return [
|
|
762
769
|
"newFeature",
|
|
763
770
|
"newPart",
|
|
@@ -780,31 +787,34 @@ const editCommandDefs = {
|
|
|
780
787
|
// }
|
|
781
788
|
// },
|
|
782
789
|
reverseComplementSelection: {
|
|
783
|
-
isDisabled:
|
|
784
|
-
(props.readOnly && readOnlyDisabledTooltip) ||
|
|
785
|
-
|
|
790
|
+
isDisabled: props =>
|
|
791
|
+
(props.readOnly && readOnlyDisabledTooltip) ||
|
|
792
|
+
noSelection(props) ||
|
|
793
|
+
props.disableBpEditing,
|
|
794
|
+
isHidden: props => props.readOnly || isProtein(props),
|
|
786
795
|
|
|
787
|
-
handler:
|
|
796
|
+
handler: props => props.handleReverseComplementSelection(),
|
|
788
797
|
hotkey: "mod+e"
|
|
789
798
|
},
|
|
790
799
|
|
|
791
800
|
reverseComplementEntireSequence: {
|
|
792
|
-
isHidden:
|
|
801
|
+
isHidden: props =>
|
|
802
|
+
props.readOnly || isProtein(props) || props.disableBpEditing,
|
|
793
803
|
|
|
794
|
-
isDisabled:
|
|
804
|
+
isDisabled: props =>
|
|
795
805
|
(props.readOnly && readOnlyDisabledTooltip) || props.sequenceLength === 0,
|
|
796
|
-
handler:
|
|
806
|
+
handler: props => props.handleReverseComplementSequence()
|
|
797
807
|
},
|
|
798
808
|
fullSequenceTranslations: {
|
|
799
809
|
isHidden: isProtein,
|
|
800
810
|
handler: noop
|
|
801
811
|
},
|
|
802
812
|
sequenceAA_allFrames: {
|
|
803
|
-
isActive:
|
|
813
|
+
isActive: props =>
|
|
804
814
|
props.frameTranslations["1"] &&
|
|
805
815
|
props.frameTranslations["2"] &&
|
|
806
816
|
props.frameTranslations["3"],
|
|
807
|
-
handler:
|
|
817
|
+
handler: props => {
|
|
808
818
|
if (
|
|
809
819
|
props.frameTranslations["1"] &&
|
|
810
820
|
props.frameTranslations["2"] &&
|
|
@@ -824,11 +834,11 @@ const editCommandDefs = {
|
|
|
824
834
|
sequenceAAReverse_allFrames: {
|
|
825
835
|
isHidden: isProtein,
|
|
826
836
|
|
|
827
|
-
isActive:
|
|
837
|
+
isActive: props =>
|
|
828
838
|
props.frameTranslations["-1"] &&
|
|
829
839
|
props.frameTranslations["-2"] &&
|
|
830
840
|
props.frameTranslations["-3"],
|
|
831
|
-
handler:
|
|
841
|
+
handler: props => {
|
|
832
842
|
if (
|
|
833
843
|
props.frameTranslations["-1"] &&
|
|
834
844
|
props.frameTranslations["-2"] &&
|
|
@@ -846,8 +856,8 @@ const editCommandDefs = {
|
|
|
846
856
|
}
|
|
847
857
|
},
|
|
848
858
|
sequenceAA_frame1: {
|
|
849
|
-
isActive:
|
|
850
|
-
handler:
|
|
859
|
+
isActive: props => props.frameTranslations["1"],
|
|
860
|
+
handler: props => {
|
|
851
861
|
if (!props.frameTranslations["1"]) {
|
|
852
862
|
props.annotationVisibilityShow("translations");
|
|
853
863
|
}
|
|
@@ -855,8 +865,8 @@ const editCommandDefs = {
|
|
|
855
865
|
}
|
|
856
866
|
},
|
|
857
867
|
sequenceAA_frame2: {
|
|
858
|
-
isActive:
|
|
859
|
-
handler:
|
|
868
|
+
isActive: props => props.frameTranslations["2"],
|
|
869
|
+
handler: props => {
|
|
860
870
|
if (!props.frameTranslations["2"]) {
|
|
861
871
|
props.annotationVisibilityShow("translations");
|
|
862
872
|
}
|
|
@@ -864,8 +874,8 @@ const editCommandDefs = {
|
|
|
864
874
|
}
|
|
865
875
|
},
|
|
866
876
|
sequenceAA_frame3: {
|
|
867
|
-
isActive:
|
|
868
|
-
handler:
|
|
877
|
+
isActive: props => props.frameTranslations["3"],
|
|
878
|
+
handler: props => {
|
|
869
879
|
if (!props.frameTranslations["3"]) {
|
|
870
880
|
props.annotationVisibilityShow("translations");
|
|
871
881
|
}
|
|
@@ -873,8 +883,8 @@ const editCommandDefs = {
|
|
|
873
883
|
}
|
|
874
884
|
},
|
|
875
885
|
sequenceAAReverse_frame1: {
|
|
876
|
-
isActive:
|
|
877
|
-
handler:
|
|
886
|
+
isActive: props => props.frameTranslations["-1"],
|
|
887
|
+
handler: props => {
|
|
878
888
|
if (!props.frameTranslations["-1"]) {
|
|
879
889
|
props.annotationVisibilityShow("translations");
|
|
880
890
|
}
|
|
@@ -882,8 +892,8 @@ const editCommandDefs = {
|
|
|
882
892
|
}
|
|
883
893
|
},
|
|
884
894
|
sequenceAAReverse_frame2: {
|
|
885
|
-
isActive:
|
|
886
|
-
handler:
|
|
895
|
+
isActive: props => props.frameTranslations["-2"],
|
|
896
|
+
handler: props => {
|
|
887
897
|
if (!props.frameTranslations["-2"]) {
|
|
888
898
|
props.annotationVisibilityShow("translations");
|
|
889
899
|
}
|
|
@@ -892,8 +902,8 @@ const editCommandDefs = {
|
|
|
892
902
|
},
|
|
893
903
|
|
|
894
904
|
sequenceAAReverse_frame3: {
|
|
895
|
-
isActive:
|
|
896
|
-
handler:
|
|
905
|
+
isActive: props => props.frameTranslations["-3"],
|
|
906
|
+
handler: props => {
|
|
897
907
|
if (!props.frameTranslations["-3"]) {
|
|
898
908
|
props.annotationVisibilityShow("translations");
|
|
899
909
|
}
|
|
@@ -907,11 +917,11 @@ const editCommandDefs = {
|
|
|
907
917
|
handler: (props /* state, ctxInfo */) => {
|
|
908
918
|
props.handleNewFeature();
|
|
909
919
|
},
|
|
910
|
-
isHidden:
|
|
920
|
+
isHidden: props =>
|
|
911
921
|
props.readOnly ||
|
|
912
922
|
!props.annotationsToSupport ||
|
|
913
923
|
!props.annotationsToSupport.features,
|
|
914
|
-
isDisabled:
|
|
924
|
+
isDisabled: props =>
|
|
915
925
|
(props.readOnly && readOnlyDisabledTooltip) || props.sequenceLength === 0,
|
|
916
926
|
hotkey: "mod+k",
|
|
917
927
|
hotkeyProps: { preventDefault: true }
|
|
@@ -920,11 +930,11 @@ const editCommandDefs = {
|
|
|
920
930
|
isHidden: isProtein,
|
|
921
931
|
|
|
922
932
|
name: "Use GTG And CTG As Start Codons",
|
|
923
|
-
isActive:
|
|
924
|
-
handler:
|
|
933
|
+
isActive: props => props.useAdditionalOrfStartCodons,
|
|
934
|
+
handler: props => props.useAdditionalOrfStartCodonsToggle()
|
|
925
935
|
},
|
|
926
936
|
minOrfSizeCmd: {
|
|
927
|
-
name:
|
|
937
|
+
name: props => {
|
|
928
938
|
return (
|
|
929
939
|
<div data-test="min-orf-size" style={{ display: "flex" }}>
|
|
930
940
|
Minimum ORF Size:
|
|
@@ -949,39 +959,40 @@ const editCommandDefs = {
|
|
|
949
959
|
},
|
|
950
960
|
hotkeyDialog: {
|
|
951
961
|
name: "View Editor Hotkeys",
|
|
952
|
-
handler:
|
|
962
|
+
handler: props => props.openHotkeyDialog()
|
|
953
963
|
},
|
|
954
964
|
|
|
955
965
|
newPart: {
|
|
956
|
-
handler:
|
|
957
|
-
isHidden:
|
|
966
|
+
handler: props => props.handleNewPart(),
|
|
967
|
+
isHidden: props =>
|
|
958
968
|
props.readOnly ||
|
|
959
969
|
!props.annotationsToSupport ||
|
|
960
970
|
!props.annotationsToSupport.parts,
|
|
961
971
|
|
|
962
|
-
isDisabled:
|
|
972
|
+
isDisabled: props =>
|
|
963
973
|
(props.readOnly && readOnlyDisabledTooltip) || props.sequenceLength === 0,
|
|
964
974
|
hotkey: "mod+l",
|
|
965
975
|
hotkeyProps: { preventDefault: true }
|
|
966
976
|
},
|
|
967
977
|
newPrimer: {
|
|
968
|
-
handler:
|
|
969
|
-
isHidden:
|
|
978
|
+
handler: props => props.handleNewPrimer(),
|
|
979
|
+
isHidden: props =>
|
|
970
980
|
props.readOnly ||
|
|
971
981
|
!props.annotationsToSupport ||
|
|
972
982
|
!props.annotationsToSupport.primers,
|
|
973
|
-
isDisabled:
|
|
983
|
+
isDisabled: props =>
|
|
974
984
|
(props.readOnly && readOnlyDisabledTooltip) || props.sequenceLength === 0
|
|
975
985
|
},
|
|
976
986
|
|
|
977
987
|
rotateToCaretPosition: {
|
|
978
|
-
isHidden:
|
|
979
|
-
|
|
988
|
+
isHidden: props =>
|
|
989
|
+
props.readOnly || isProtein(props) || props.disableBpEditing,
|
|
990
|
+
isDisabled: props =>
|
|
980
991
|
(props.readOnly && readOnlyDisabledTooltip) ||
|
|
981
992
|
(props.caretPosition === -1 && "You must first place cursor") ||
|
|
982
993
|
(!props.sequenceData.circular && "Disabled for Linear Sequences") ||
|
|
983
994
|
props.sequenceLength === 0,
|
|
984
|
-
handler:
|
|
995
|
+
handler: props => props.handleRotateToCaretPosition(),
|
|
985
996
|
hotkey: "mod+b"
|
|
986
997
|
},
|
|
987
998
|
...toggleCopyOptionCommandDefs
|
|
@@ -989,72 +1000,67 @@ const editCommandDefs = {
|
|
|
989
1000
|
|
|
990
1001
|
const cirularityCommandDefs = {
|
|
991
1002
|
circular: {
|
|
992
|
-
isHidden:
|
|
993
|
-
|
|
994
|
-
isDisabled:
|
|
995
|
-
handler:
|
|
996
|
-
isActive:
|
|
1003
|
+
isHidden: props =>
|
|
1004
|
+
props.readOnly || isProtein(props) || props.disableBpEditing,
|
|
1005
|
+
isDisabled: props => props.readOnly && readOnlyDisabledTooltip,
|
|
1006
|
+
handler: props => props.updateCircular(true),
|
|
1007
|
+
isActive: props => props && props.sequenceData.circular
|
|
997
1008
|
},
|
|
998
1009
|
linear: {
|
|
999
|
-
isHidden:
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
isActive: (props) => props && !props.sequenceData.circular
|
|
1010
|
+
isHidden: props => props.readOnly || props.disableBpEditing,
|
|
1011
|
+
isDisabled: props => props.readOnly && readOnlyDisabledTooltip,
|
|
1012
|
+
handler: props => props.updateCircular(false),
|
|
1013
|
+
isActive: props => props && !props.sequenceData.circular
|
|
1004
1014
|
}
|
|
1005
1015
|
};
|
|
1006
1016
|
|
|
1007
1017
|
const nicheAnnotations = [
|
|
1008
1018
|
{
|
|
1009
1019
|
type: "warnings",
|
|
1010
|
-
isHidden:
|
|
1020
|
+
isHidden: p => {
|
|
1011
1021
|
return !map(p.sequenceData["warnings"]).length;
|
|
1012
1022
|
}
|
|
1013
1023
|
},
|
|
1014
1024
|
{
|
|
1015
1025
|
type: "assemblyPieces",
|
|
1016
|
-
isHidden:
|
|
1026
|
+
isHidden: p => {
|
|
1017
1027
|
return !map(p.sequenceData["assemblyPieces"]).length;
|
|
1018
1028
|
}
|
|
1019
1029
|
},
|
|
1020
1030
|
{
|
|
1021
1031
|
type: "lineageAnnotations",
|
|
1022
|
-
isHidden:
|
|
1032
|
+
isHidden: p => {
|
|
1023
1033
|
return !map(p.sequenceData["lineageAnnotations"]).length;
|
|
1024
1034
|
}
|
|
1025
1035
|
}
|
|
1026
1036
|
];
|
|
1027
1037
|
const labelToggleCommandDefs = {};
|
|
1028
|
-
["feature", "part", "cutsite", "primer", ...nicheAnnotations].forEach(
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
rest = _type;
|
|
1035
|
-
}
|
|
1036
|
-
const cmdId = `toggle${upperFirst(type)}Labels`;
|
|
1037
|
-
const plural = type + "s";
|
|
1038
|
-
labelToggleCommandDefs[cmdId] = {
|
|
1039
|
-
toggle: ["show", "hide"],
|
|
1040
|
-
handler: (props) => props.annotationLabelVisibilityToggle(plural),
|
|
1041
|
-
isHidden: (props) => {
|
|
1042
|
-
return (
|
|
1043
|
-
props && props.typesToOmit && props.typesToOmit[plural] === false
|
|
1044
|
-
);
|
|
1045
|
-
},
|
|
1046
|
-
...rest,
|
|
1047
|
-
isActive: (props) => {
|
|
1048
|
-
return props && props.annotationLabelVisibility[plural];
|
|
1049
|
-
}
|
|
1050
|
-
};
|
|
1038
|
+
["feature", "part", "cutsite", "primer", ...nicheAnnotations].forEach(_type => {
|
|
1039
|
+
let rest = {};
|
|
1040
|
+
let type = _type;
|
|
1041
|
+
if (_type.type) {
|
|
1042
|
+
type = _type.type.slice(0, -1);
|
|
1043
|
+
rest = _type;
|
|
1051
1044
|
}
|
|
1052
|
-
)
|
|
1045
|
+
const cmdId = `toggle${upperFirst(type)}Labels`;
|
|
1046
|
+
const plural = type + "s";
|
|
1047
|
+
labelToggleCommandDefs[cmdId] = {
|
|
1048
|
+
toggle: ["show", "hide"],
|
|
1049
|
+
handler: props => props.annotationLabelVisibilityToggle(plural),
|
|
1050
|
+
isHidden: props => {
|
|
1051
|
+
return props && props.typesToOmit && props.typesToOmit[plural] === false;
|
|
1052
|
+
},
|
|
1053
|
+
...rest,
|
|
1054
|
+
isActive: props => {
|
|
1055
|
+
return props && props.annotationLabelVisibility[plural];
|
|
1056
|
+
}
|
|
1057
|
+
};
|
|
1058
|
+
});
|
|
1053
1059
|
|
|
1054
1060
|
const editAnnotationCommandDefs = ["feature", "part", "primer"].reduce(
|
|
1055
1061
|
(acc, key) => {
|
|
1056
1062
|
acc[`edit${upperFirst(key)}`] = {
|
|
1057
|
-
name:
|
|
1063
|
+
name: props =>
|
|
1058
1064
|
props.readOnly
|
|
1059
1065
|
? `View ${upperFirst(key)} Details`
|
|
1060
1066
|
: `Edit ${upperFirst(key)}`,
|
|
@@ -1081,7 +1087,7 @@ const deleteAnnotationCommandDefs = [
|
|
|
1081
1087
|
const annotation = get(ctxInfo, "context.annotation");
|
|
1082
1088
|
props[`delete${upperFirst(key)}`](annotation);
|
|
1083
1089
|
},
|
|
1084
|
-
isHidden:
|
|
1090
|
+
isHidden: props => props.readOnly
|
|
1085
1091
|
};
|
|
1086
1092
|
return acc;
|
|
1087
1093
|
}, {});
|
|
@@ -1134,14 +1140,14 @@ const annotationToggleCommandDefs = {};
|
|
|
1134
1140
|
"axis",
|
|
1135
1141
|
{ type: "orfs", text: "ORFs", isHidden: isProtein },
|
|
1136
1142
|
{ type: "primers", isHidden: isProtein },
|
|
1137
|
-
{ type: "chromatogram", isHidden:
|
|
1143
|
+
{ type: "chromatogram", isHidden: p => !p.sequenceData.chromatogramData },
|
|
1138
1144
|
"translations",
|
|
1139
1145
|
|
|
1140
1146
|
{
|
|
1141
1147
|
type: "orfTranslations",
|
|
1142
1148
|
text: "ORF Translations",
|
|
1143
1149
|
isHidden: isProtein,
|
|
1144
|
-
isDisabled:
|
|
1150
|
+
isDisabled: props => {
|
|
1145
1151
|
return (
|
|
1146
1152
|
(!props.annotationVisibility.orfs &&
|
|
1147
1153
|
"ORFs must be visible to view their translations") ||
|
|
@@ -1154,7 +1160,7 @@ const annotationToggleCommandDefs = {};
|
|
|
1154
1160
|
type: "cdsFeatureTranslations",
|
|
1155
1161
|
text: "CDS Feature Translations",
|
|
1156
1162
|
isHidden: isProtein,
|
|
1157
|
-
isDisabled:
|
|
1163
|
+
isDisabled: props => {
|
|
1158
1164
|
return (
|
|
1159
1165
|
(!props.annotationVisibility.features &&
|
|
1160
1166
|
"Features must be visible to view their translations") ||
|
|
@@ -1174,11 +1180,11 @@ const annotationToggleCommandDefs = {};
|
|
|
1174
1180
|
type: "sequence",
|
|
1175
1181
|
name: "DNA Sequence",
|
|
1176
1182
|
noCount: true,
|
|
1177
|
-
isHidden:
|
|
1183
|
+
isHidden: props => !isProtein(props)
|
|
1178
1184
|
},
|
|
1179
1185
|
{
|
|
1180
1186
|
type: "reverseSequence",
|
|
1181
|
-
name:
|
|
1187
|
+
name: props =>
|
|
1182
1188
|
isProtein(props) ? "DNA Reverse Sequence" : "Reverse Sequence"
|
|
1183
1189
|
},
|
|
1184
1190
|
{
|
|
@@ -1188,12 +1194,12 @@ const annotationToggleCommandDefs = {};
|
|
|
1188
1194
|
{
|
|
1189
1195
|
type: "dnaColors",
|
|
1190
1196
|
name: () => "DNA Colors",
|
|
1191
|
-
isDisabled:
|
|
1197
|
+
isDisabled: props =>
|
|
1192
1198
|
!props.annotationVisibility.sequence &&
|
|
1193
1199
|
!props.annotationVisibility.reverseSequence &&
|
|
1194
1200
|
"The DNA sequence must be visible in order to color it"
|
|
1195
1201
|
}
|
|
1196
|
-
].forEach(
|
|
1202
|
+
].forEach(typeOrObj => {
|
|
1197
1203
|
let type = typeOrObj;
|
|
1198
1204
|
let obj = {};
|
|
1199
1205
|
if (typeOrObj.type) {
|
|
@@ -1203,7 +1209,7 @@ const annotationToggleCommandDefs = {};
|
|
|
1203
1209
|
const cmdId = `toggle${upperFirst(type)}`;
|
|
1204
1210
|
annotationToggleCommandDefs[cmdId] = {
|
|
1205
1211
|
toggle: ["show", "hide"],
|
|
1206
|
-
name:
|
|
1212
|
+
name: props => {
|
|
1207
1213
|
const sequenceData = props.sequenceData || {};
|
|
1208
1214
|
let count;
|
|
1209
1215
|
let hasCount = false;
|
|
@@ -1238,14 +1244,14 @@ const annotationToggleCommandDefs = {};
|
|
|
1238
1244
|
</span>
|
|
1239
1245
|
);
|
|
1240
1246
|
},
|
|
1241
|
-
handler:
|
|
1242
|
-
isActive:
|
|
1247
|
+
handler: props => props.annotationVisibilityToggle(type),
|
|
1248
|
+
isActive: props => {
|
|
1243
1249
|
return (
|
|
1244
1250
|
props && props.annotationVisibility && props.annotationVisibility[type]
|
|
1245
1251
|
);
|
|
1246
1252
|
},
|
|
1247
1253
|
...obj, //spread this here to override the above props if necessary
|
|
1248
|
-
isHidden:
|
|
1254
|
+
isHidden: props => {
|
|
1249
1255
|
return (
|
|
1250
1256
|
(props && props.typesToOmit && props.typesToOmit[type] === false) ||
|
|
1251
1257
|
(obj.isHidden && obj.isHidden(props))
|
|
@@ -1256,11 +1262,11 @@ const annotationToggleCommandDefs = {};
|
|
|
1256
1262
|
|
|
1257
1263
|
const additionalAnnotationCommandsDefs = {
|
|
1258
1264
|
limitsMenu: {
|
|
1259
|
-
isHidden:
|
|
1265
|
+
isHidden: props => props.maxAnnotationsToDisplay
|
|
1260
1266
|
},
|
|
1261
1267
|
showAll: {
|
|
1262
|
-
handler:
|
|
1263
|
-
annotationTypes.forEach(
|
|
1268
|
+
handler: props => {
|
|
1269
|
+
annotationTypes.forEach(type => {
|
|
1264
1270
|
if (props.isProtein) {
|
|
1265
1271
|
if (type === "translations" || type === "cutsites")
|
|
1266
1272
|
return props.annotationVisibilityHide(type);
|
|
@@ -1270,15 +1276,15 @@ const additionalAnnotationCommandsDefs = {
|
|
|
1270
1276
|
}
|
|
1271
1277
|
},
|
|
1272
1278
|
hideAll: {
|
|
1273
|
-
handler:
|
|
1274
|
-
annotationTypes.forEach(
|
|
1279
|
+
handler: props => {
|
|
1280
|
+
annotationTypes.forEach(type => {
|
|
1275
1281
|
props.annotationVisibilityHide(type);
|
|
1276
1282
|
});
|
|
1277
1283
|
}
|
|
1278
1284
|
},
|
|
1279
1285
|
showAllLabels: {
|
|
1280
|
-
handler:
|
|
1281
|
-
annotationTypes.forEach(
|
|
1286
|
+
handler: props => {
|
|
1287
|
+
annotationTypes.forEach(type => {
|
|
1282
1288
|
// if (props.isProtein) {
|
|
1283
1289
|
// if (type === "translations" || type === "cutsites")
|
|
1284
1290
|
// return props.annotationVisibilityHide(type);
|
|
@@ -1288,39 +1294,39 @@ const additionalAnnotationCommandsDefs = {
|
|
|
1288
1294
|
}
|
|
1289
1295
|
},
|
|
1290
1296
|
hideAllLabels: {
|
|
1291
|
-
handler:
|
|
1292
|
-
annotationTypes.forEach(
|
|
1297
|
+
handler: props => {
|
|
1298
|
+
annotationTypes.forEach(type => {
|
|
1293
1299
|
props.annotationLabelVisibilityHide(type);
|
|
1294
1300
|
});
|
|
1295
1301
|
}
|
|
1296
1302
|
},
|
|
1297
1303
|
toggleAminoAcidNumbers_dna: {
|
|
1298
1304
|
...annotationToggleCommandDefs.toggleAminoAcidNumbers,
|
|
1299
|
-
isHidden:
|
|
1305
|
+
isHidden: props => isProtein(props)
|
|
1300
1306
|
},
|
|
1301
1307
|
toggleAminoAcidNumbers_protein: {
|
|
1302
1308
|
...annotationToggleCommandDefs.toggleAminoAcidNumbers,
|
|
1303
|
-
isHidden:
|
|
1309
|
+
isHidden: props => isProtein(props)
|
|
1304
1310
|
}
|
|
1305
1311
|
};
|
|
1306
1312
|
|
|
1307
1313
|
const toolCommandDefs = {
|
|
1308
1314
|
simulateDigestion: {
|
|
1309
|
-
handler:
|
|
1315
|
+
handler: props => props.createNewDigest(),
|
|
1310
1316
|
hotkey: "mod+shift+d",
|
|
1311
1317
|
hotkeyProps: { preventDefault: true },
|
|
1312
|
-
isHidden:
|
|
1318
|
+
isHidden: props => isProtein(props)
|
|
1313
1319
|
},
|
|
1314
1320
|
simulatePCR: {
|
|
1315
|
-
handler:
|
|
1321
|
+
handler: props => props.createNewPCR(),
|
|
1316
1322
|
hotkey: "mod+shift+p",
|
|
1317
1323
|
hotkeyProps: { preventDefault: true },
|
|
1318
|
-
isHidden:
|
|
1324
|
+
isHidden: props => isProtein(props)
|
|
1319
1325
|
},
|
|
1320
1326
|
// TODO: enzyme manager (?)
|
|
1321
1327
|
restrictionEnzymesManager: {
|
|
1322
1328
|
name: "Manage Enzymes",
|
|
1323
|
-
handler:
|
|
1329
|
+
handler: props => {
|
|
1324
1330
|
if (props.enzymeManageOverride) {
|
|
1325
1331
|
props.enzymeManageOverride(props);
|
|
1326
1332
|
} else {
|
|
@@ -1335,14 +1341,14 @@ const toolCommandDefs = {
|
|
|
1335
1341
|
});
|
|
1336
1342
|
}
|
|
1337
1343
|
},
|
|
1338
|
-
isHidden:
|
|
1344
|
+
isHidden: props => isProtein(props)
|
|
1339
1345
|
},
|
|
1340
1346
|
openFilterCutsites: {
|
|
1341
1347
|
name: "Filter Cut Sites",
|
|
1342
|
-
handler:
|
|
1348
|
+
handler: props => {
|
|
1343
1349
|
props.openToolbarItemUpdate("cutsiteTool");
|
|
1344
1350
|
},
|
|
1345
|
-
isHidden:
|
|
1351
|
+
isHidden: props => isProtein(props)
|
|
1346
1352
|
},
|
|
1347
1353
|
openCreateCustomEnzyme: {
|
|
1348
1354
|
name: "Create Custom Enzyme",
|
|
@@ -1351,7 +1357,7 @@ const toolCommandDefs = {
|
|
|
1351
1357
|
dialogType: "CreateCustomEnzyme"
|
|
1352
1358
|
});
|
|
1353
1359
|
},
|
|
1354
|
-
isHidden:
|
|
1360
|
+
isHidden: props => props.overrideManageEnzymes
|
|
1355
1361
|
}
|
|
1356
1362
|
};
|
|
1357
1363
|
|
|
@@ -1372,8 +1378,8 @@ const labelSizes = {
|
|
|
1372
1378
|
const labelCommandDefs = {
|
|
1373
1379
|
adjustLabelLineIntensity: {
|
|
1374
1380
|
name: "Label Line Intensity",
|
|
1375
|
-
submenu:
|
|
1376
|
-
map(Object.keys(labelIntensities),
|
|
1381
|
+
submenu: props =>
|
|
1382
|
+
map(Object.keys(labelIntensities), key => ({
|
|
1377
1383
|
text: key,
|
|
1378
1384
|
checked: props.labelLineIntensity === labelIntensities[key],
|
|
1379
1385
|
onClick: () => props.changeLabelLineIntensity(labelIntensities[key])
|
|
@@ -1381,8 +1387,8 @@ const labelCommandDefs = {
|
|
|
1381
1387
|
},
|
|
1382
1388
|
adjustLabelSize: {
|
|
1383
1389
|
name: "Circular Label Size",
|
|
1384
|
-
submenu:
|
|
1385
|
-
map(Object.keys(labelSizes),
|
|
1390
|
+
submenu: props =>
|
|
1391
|
+
map(Object.keys(labelSizes), key => ({
|
|
1386
1392
|
text: key,
|
|
1387
1393
|
checked: props.labelSize === labelSizes[key],
|
|
1388
1394
|
onClick: () => props.changeLabelSize(labelSizes[key])
|
|
@@ -1392,7 +1398,7 @@ const labelCommandDefs = {
|
|
|
1392
1398
|
|
|
1393
1399
|
export const commandDefs = {
|
|
1394
1400
|
showChromQualScoresMenu: {
|
|
1395
|
-
isHidden:
|
|
1401
|
+
isHidden: props =>
|
|
1396
1402
|
!props.sequenceData.chromatogramData ||
|
|
1397
1403
|
!props.sequenceData.chromatogramData.baseTraces
|
|
1398
1404
|
},
|
|
@@ -1413,7 +1419,7 @@ export const commandDefs = {
|
|
|
1413
1419
|
...labelCommandDefs
|
|
1414
1420
|
};
|
|
1415
1421
|
|
|
1416
|
-
export default
|
|
1422
|
+
export default instance => oveCommandFactory(instance, commandDefs);
|
|
1417
1423
|
|
|
1418
1424
|
const invertString = function (str) {
|
|
1419
1425
|
let s = "";
|
|
@@ -1436,11 +1442,11 @@ const invertString = function (str) {
|
|
|
1436
1442
|
|
|
1437
1443
|
function getFilterByLengthCmd(type) {
|
|
1438
1444
|
return {
|
|
1439
|
-
name:
|
|
1445
|
+
name: props => {
|
|
1440
1446
|
return (
|
|
1441
1447
|
<div data-test={`filter-${type}-length`}>
|
|
1442
1448
|
Filter By Length
|
|
1443
|
-
<div onClick={
|
|
1449
|
+
<div onClick={e => e.stopPropagation()}>
|
|
1444
1450
|
<NumericInput
|
|
1445
1451
|
onValueChange={function (valueAsNumber) {
|
|
1446
1452
|
const minimumFilterLength = parseInt(valueAsNumber, 10);
|
|
@@ -1479,8 +1485,8 @@ function getFilterByLengthCmd(type) {
|
|
|
1479
1485
|
</div>
|
|
1480
1486
|
);
|
|
1481
1487
|
},
|
|
1482
|
-
isActive:
|
|
1483
|
-
handler:
|
|
1488
|
+
isActive: props => props[`${type}LengthsToHide`].enabled,
|
|
1489
|
+
handler: props => {
|
|
1484
1490
|
props[`toggle${startCase(type)}LengthsToHide`]();
|
|
1485
1491
|
}
|
|
1486
1492
|
};
|
|
@@ -1490,7 +1496,7 @@ function getFilterIndividualCmd(type) {
|
|
|
1490
1496
|
const pluralType = pluralize(type);
|
|
1491
1497
|
const upperType = startCase(type);
|
|
1492
1498
|
return {
|
|
1493
|
-
isHidden:
|
|
1499
|
+
isHidden: props => {
|
|
1494
1500
|
const total = Object.keys(
|
|
1495
1501
|
reduce(
|
|
1496
1502
|
props.sequenceData[pluralType],
|
|
@@ -1503,7 +1509,7 @@ function getFilterIndividualCmd(type) {
|
|
|
1503
1509
|
).length;
|
|
1504
1510
|
return total > 500;
|
|
1505
1511
|
},
|
|
1506
|
-
name:
|
|
1512
|
+
name: props => {
|
|
1507
1513
|
const total = Object.keys(
|
|
1508
1514
|
reduce(
|
|
1509
1515
|
props.sequenceData[pluralType],
|
|
@@ -1526,11 +1532,11 @@ function getFilterIndividualCmd(type) {
|
|
|
1526
1532
|
</span>
|
|
1527
1533
|
);
|
|
1528
1534
|
},
|
|
1529
|
-
submenu:
|
|
1535
|
+
submenu: props => {
|
|
1530
1536
|
const individualAnns = {};
|
|
1531
1537
|
forEach(
|
|
1532
1538
|
sortBy(props.sequenceData[pluralType], ({ start }) => start + 1),
|
|
1533
|
-
|
|
1539
|
+
ann => {
|
|
1534
1540
|
if (!ann.id) return;
|
|
1535
1541
|
const checked =
|
|
1536
1542
|
!props.annotationVisibility[`${type}IndividualToHide`][ann.id];
|