@teselagen/ove 0.3.10 → 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 +453 -319
- package/index.mjs +453 -319
- package/index.umd.js +397 -287
- package/package.json +2 -2
- 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/utils/pureNoFunc.js
CHANGED
|
@@ -18,7 +18,7 @@ const shouldRerender = (propKeys, stateKeys, that) => {
|
|
|
18
18
|
export default shouldRerender;
|
|
19
19
|
|
|
20
20
|
const isEq = (o1, o2) => {
|
|
21
|
-
const isEq = isEqualWith(o1, o2, function(val1, val2) {
|
|
21
|
+
const isEq = isEqualWith(o1, o2, function (val1, val2) {
|
|
22
22
|
if (isFunction(val1) && isFunction(val2)) {
|
|
23
23
|
return val1 === val2 || val1.toString() === val2.toString();
|
|
24
24
|
}
|
|
@@ -4,21 +4,20 @@ let callback;
|
|
|
4
4
|
|
|
5
5
|
function getInput(multiple) {
|
|
6
6
|
if (!hiddenInput) {
|
|
7
|
-
hiddenInput = document.createElement(
|
|
8
|
-
hiddenInput.type =
|
|
9
|
-
hiddenInput.style.position =
|
|
10
|
-
hiddenInput.style.visibility =
|
|
11
|
-
hiddenInput.addEventListener(
|
|
7
|
+
hiddenInput = document.createElement("input");
|
|
8
|
+
hiddenInput.type = "file";
|
|
9
|
+
hiddenInput.style.position = "absolute";
|
|
10
|
+
hiddenInput.style.visibility = "hidden";
|
|
11
|
+
hiddenInput.addEventListener("change", event => {
|
|
12
12
|
callback(event.target.files);
|
|
13
13
|
});
|
|
14
14
|
|
|
15
15
|
document.body.appendChild(hiddenInput);
|
|
16
16
|
}
|
|
17
|
-
hiddenInput.multiple = multiple ?
|
|
17
|
+
hiddenInput.multiple = multiple ? "multiple" : undefined;
|
|
18
18
|
return hiddenInput;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
|
|
22
21
|
export default function showFileDialog({ multiple = false, onSelect }) {
|
|
23
22
|
const input = getInput(multiple);
|
|
24
23
|
callback = onSelect;
|
|
@@ -20,7 +20,7 @@ export function updateLabelsForInViewFeatures({
|
|
|
20
20
|
.querySelector(rectElement)
|
|
21
21
|
.getBoundingClientRect();
|
|
22
22
|
|
|
23
|
-
els.forEach(
|
|
23
|
+
els.forEach(el => {
|
|
24
24
|
const elBounds = el.getBoundingClientRect();
|
|
25
25
|
const isElIn = isElWithinAnotherEl(elBounds, boundingRect);
|
|
26
26
|
|
|
@@ -20,7 +20,7 @@ export function LimitAnnotations({ type, ...rest }) {
|
|
|
20
20
|
const [limits = {}, setLimits] = useAnnotationLimits();
|
|
21
21
|
return (
|
|
22
22
|
<MenuItem icon="blank" shouldDismissPopover={false} {...rest}>
|
|
23
|
-
{[50, 100, 200, 400].map(
|
|
23
|
+
{[50, 100, 200, 400].map(n => (
|
|
24
24
|
<MenuItem
|
|
25
25
|
shouldDismissPopover={false}
|
|
26
26
|
icon={
|
|
@@ -24,7 +24,7 @@ class Clipboard extends React.Component {
|
|
|
24
24
|
this.node.parentNode.removeEventListener("keyup", this.handleKeyUp, false);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
handleKeyDown =
|
|
27
|
+
handleKeyDown = e => {
|
|
28
28
|
if (
|
|
29
29
|
document.activeElement &&
|
|
30
30
|
["input", "select", "textarea"].indexOf(
|
|
@@ -63,7 +63,7 @@ class Clipboard extends React.Component {
|
|
|
63
63
|
};
|
|
64
64
|
return (
|
|
65
65
|
<input
|
|
66
|
-
ref={
|
|
66
|
+
ref={c => {
|
|
67
67
|
if (c) {
|
|
68
68
|
this.node = c;
|
|
69
69
|
}
|
|
@@ -83,4 +83,3 @@ class Clipboard extends React.Component {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
export default Clipboard;
|
|
86
|
-
|
|
@@ -35,7 +35,7 @@ class SequenceInputNoHotkeys extends React.Component {
|
|
|
35
35
|
this.handleUnmountIfClickOustidePopup
|
|
36
36
|
);
|
|
37
37
|
}
|
|
38
|
-
handleUnmountIfClickOustidePopup =
|
|
38
|
+
handleUnmountIfClickOustidePopup = e => {
|
|
39
39
|
const n = findDOMNode(this);
|
|
40
40
|
if (!n) return;
|
|
41
41
|
const node = n.parentNode;
|
|
@@ -122,7 +122,7 @@ class SequenceInputNoHotkeys extends React.Component {
|
|
|
122
122
|
<div className="sequenceInputBubble">
|
|
123
123
|
<input
|
|
124
124
|
autoCorrect="off"
|
|
125
|
-
onKeyDown={
|
|
125
|
+
onKeyDown={e => {
|
|
126
126
|
if (e.keyCode === 27) {
|
|
127
127
|
this.handleUnmount();
|
|
128
128
|
}
|
|
@@ -135,9 +135,9 @@ class SequenceInputNoHotkeys extends React.Component {
|
|
|
135
135
|
value={charsToInsert}
|
|
136
136
|
autoFocus
|
|
137
137
|
style={hasTempError ? { borderColor: "red" } : {}}
|
|
138
|
-
onChange={
|
|
138
|
+
onChange={e => {
|
|
139
139
|
let sanitizedVal = "";
|
|
140
|
-
e.target.value.split("").forEach(
|
|
140
|
+
e.target.value.split("").forEach(letter => {
|
|
141
141
|
const lowerLetter = letter.toLowerCase();
|
|
142
142
|
if (replaceChars && replaceChars[lowerLetter]) {
|
|
143
143
|
const isUpper = lowerLetter !== letter;
|
|
@@ -79,7 +79,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
79
79
|
return class VectorInteractionWrapper extends React.Component {
|
|
80
80
|
constructor(props) {
|
|
81
81
|
super(props);
|
|
82
|
-
annotationClickHandlers.forEach(
|
|
82
|
+
annotationClickHandlers.forEach(handler => {
|
|
83
83
|
this[handler] = (...args) => {
|
|
84
84
|
const { clickOverrides = {} } = this.props;
|
|
85
85
|
let preventDefault;
|
|
@@ -93,7 +93,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
93
93
|
};
|
|
94
94
|
});
|
|
95
95
|
|
|
96
|
-
this.ConnectedMenu =
|
|
96
|
+
this.ConnectedMenu = p => {
|
|
97
97
|
return <ConnectedMenu {...props} {...p} />;
|
|
98
98
|
};
|
|
99
99
|
}
|
|
@@ -110,7 +110,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
110
110
|
// documentation: https://craig.is/killing/mice
|
|
111
111
|
this.combokeys.bind(
|
|
112
112
|
"-.*ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),
|
|
113
|
-
|
|
113
|
+
event => {
|
|
114
114
|
this.handleDnaInsert(event);
|
|
115
115
|
}
|
|
116
116
|
);
|
|
@@ -140,7 +140,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
140
140
|
];
|
|
141
141
|
|
|
142
142
|
moveCaretBindings.forEach(({ keyCombo, type }) => {
|
|
143
|
-
this.combokeys.bind(keyCombo,
|
|
143
|
+
this.combokeys.bind(keyCombo, event => {
|
|
144
144
|
const shiftHeld = event.shiftKey;
|
|
145
145
|
const bpsPerRow = getBpsPerRow(this.props);
|
|
146
146
|
const {
|
|
@@ -177,7 +177,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
177
177
|
});
|
|
178
178
|
});
|
|
179
179
|
|
|
180
|
-
this.combokeys.bind(["backspace", "del"],
|
|
180
|
+
this.combokeys.bind(["backspace", "del"], event => {
|
|
181
181
|
// Handle shortcut
|
|
182
182
|
this.handleDnaDelete(event);
|
|
183
183
|
});
|
|
@@ -206,14 +206,18 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
206
206
|
});
|
|
207
207
|
};
|
|
208
208
|
|
|
209
|
-
handlePaste =
|
|
209
|
+
handlePaste = e => {
|
|
210
210
|
const {
|
|
211
211
|
caretPosition = -1,
|
|
212
212
|
selectionLayer = { start: -1, end: -1 },
|
|
213
213
|
readOnly,
|
|
214
|
-
onPaste
|
|
214
|
+
onPaste,
|
|
215
|
+
disableBpEditing
|
|
215
216
|
} = this.props;
|
|
216
217
|
|
|
218
|
+
if (disableBpEditing) {
|
|
219
|
+
return window.toastr.warning("Sorry the underlying sequence is locked");
|
|
220
|
+
}
|
|
217
221
|
if (readOnly) {
|
|
218
222
|
return window.toastr.warning("Sorry the sequence is Read-Only");
|
|
219
223
|
}
|
|
@@ -253,12 +257,13 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
253
257
|
e.preventDefault();
|
|
254
258
|
};
|
|
255
259
|
|
|
256
|
-
handleCutOrCopy =
|
|
260
|
+
handleCutOrCopy = isCut => e => {
|
|
257
261
|
const {
|
|
258
262
|
onCopy = noop,
|
|
259
263
|
sequenceData,
|
|
260
264
|
selectionLayer,
|
|
261
265
|
copyOptions,
|
|
266
|
+
disableBpEditing,
|
|
262
267
|
readOnly
|
|
263
268
|
} = this.props;
|
|
264
269
|
const onCut = this.props.onCut || this.props.onCopy || noop;
|
|
@@ -289,7 +294,9 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
289
294
|
!seqData.sequence.length
|
|
290
295
|
)
|
|
291
296
|
return window.toastr.warning(
|
|
292
|
-
`No Sequence Selected To ${
|
|
297
|
+
`No Sequence Selected To ${
|
|
298
|
+
isCut && !(readOnly || disableBpEditing) ? "Cut" : "Copy"
|
|
299
|
+
}`
|
|
293
300
|
);
|
|
294
301
|
|
|
295
302
|
const clipboardData = e.clipboardData;
|
|
@@ -306,7 +313,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
306
313
|
clipboardData.setData("application/json", JSON.stringify(seqData));
|
|
307
314
|
e.preventDefault();
|
|
308
315
|
|
|
309
|
-
if (isCut && !readOnly) {
|
|
316
|
+
if (isCut && !(readOnly || disableBpEditing) && !disableBpEditing) {
|
|
310
317
|
this.handleDnaDelete(false);
|
|
311
318
|
onCut(
|
|
312
319
|
e,
|
|
@@ -319,7 +326,11 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
319
326
|
document.body.removeEventListener("copy", this.handleCopy);
|
|
320
327
|
}
|
|
321
328
|
window.toastr.success(
|
|
322
|
-
`Selection ${
|
|
329
|
+
`Selection ${
|
|
330
|
+
isCut && !(readOnly || disableBpEditing) && !disableBpEditing
|
|
331
|
+
? "Cut"
|
|
332
|
+
: "Copied"
|
|
333
|
+
}`
|
|
323
334
|
);
|
|
324
335
|
this.sequenceDataToCopy = undefined;
|
|
325
336
|
};
|
|
@@ -332,14 +343,18 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
332
343
|
caretPosition = -1,
|
|
333
344
|
selectionLayer = { start: -1, end: -1 },
|
|
334
345
|
sequenceData = { sequence: "" },
|
|
335
|
-
readOnly
|
|
346
|
+
readOnly,
|
|
347
|
+
disableBpEditing
|
|
336
348
|
// updateSequenceData,
|
|
337
349
|
// wrappedInsertSequenceDataAtPositionOrRange
|
|
338
350
|
// handleInsert
|
|
339
351
|
} = this.props;
|
|
340
352
|
const sequenceLength = sequenceData.sequence.length;
|
|
341
353
|
const isReplace = selectionLayer.start > -1;
|
|
342
|
-
if (
|
|
354
|
+
if (disableBpEditing) {
|
|
355
|
+
return window.toastr.warning("Sorry the underlying sequence is locked");
|
|
356
|
+
}
|
|
357
|
+
if (readOnly || disableBpEditing) {
|
|
343
358
|
window.toastr.warning("Sorry the sequence is Read-Only");
|
|
344
359
|
} else {
|
|
345
360
|
createSequenceInputPopup({
|
|
@@ -351,7 +366,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
351
366
|
selectionLayer,
|
|
352
367
|
sequenceLength,
|
|
353
368
|
caretPosition,
|
|
354
|
-
handleInsert:
|
|
369
|
+
handleInsert: seqDataToInsert => {
|
|
355
370
|
insertAndSelectHelper({
|
|
356
371
|
props: this.props,
|
|
357
372
|
seqDataToInsert
|
|
@@ -369,13 +384,17 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
369
384
|
selectionLayer = { start: -1, end: -1 },
|
|
370
385
|
sequenceData = { sequence: "" },
|
|
371
386
|
readOnly,
|
|
387
|
+
disableBpEditing,
|
|
372
388
|
updateSequenceData,
|
|
373
389
|
wrappedInsertSequenceDataAtPositionOrRange,
|
|
374
390
|
caretPositionUpdate
|
|
375
391
|
// handleInsert
|
|
376
392
|
} = this.props;
|
|
377
393
|
const sequenceLength = sequenceData.sequence.length;
|
|
378
|
-
if (
|
|
394
|
+
if (disableBpEditing) {
|
|
395
|
+
return window.toastr.warning("Sorry the underlying sequence is locked");
|
|
396
|
+
}
|
|
397
|
+
if (readOnly || disableBpEditing) {
|
|
379
398
|
return window.toastr.warning("Sorry the sequence is Read-Only");
|
|
380
399
|
}
|
|
381
400
|
if (sequenceLength > 0) {
|
|
@@ -421,7 +440,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
421
440
|
}
|
|
422
441
|
};
|
|
423
442
|
|
|
424
|
-
caretPositionUpdate =
|
|
443
|
+
caretPositionUpdate = position => {
|
|
425
444
|
const { caretPosition = -1 } = this.props;
|
|
426
445
|
if (caretPosition === position) {
|
|
427
446
|
return;
|
|
@@ -429,7 +448,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
429
448
|
//we only call caretPositionUpdate if we're actually changing something
|
|
430
449
|
this.props.caretPositionUpdate(position);
|
|
431
450
|
};
|
|
432
|
-
selectionLayerUpdate =
|
|
451
|
+
selectionLayerUpdate = newSelection => {
|
|
433
452
|
const { selectionLayer = { start: -1, end: -1 }, ignoreGapsOnHighlight } =
|
|
434
453
|
this.props;
|
|
435
454
|
if (!newSelection) return;
|
|
@@ -537,8 +556,9 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
537
556
|
};
|
|
538
557
|
|
|
539
558
|
// eslint-disable-next-line no-unused-vars
|
|
540
|
-
getCopyOptions =
|
|
541
|
-
const { sequenceData, readOnly, selectionLayer } =
|
|
559
|
+
getCopyOptions = annotation => {
|
|
560
|
+
const { sequenceData, readOnly, disableBpEditing, selectionLayer } =
|
|
561
|
+
this.props;
|
|
542
562
|
const { isProtein } = sequenceData;
|
|
543
563
|
const makeTextCopyable = (transformFunc, className, action = "copy") => {
|
|
544
564
|
return new Clipboard(`.${className}`, {
|
|
@@ -590,7 +610,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
590
610
|
this.openVeCopyAA && this.openVeCopyAA.destroy();
|
|
591
611
|
},
|
|
592
612
|
didMount: ({ className }) => {
|
|
593
|
-
this.openVeCopyAA = makeTextCopyable(
|
|
613
|
+
this.openVeCopyAA = makeTextCopyable(selectedSeqData => {
|
|
594
614
|
const textToCopy = isProtein
|
|
595
615
|
? selectedSeqData.proteinSequence.toUpperCase()
|
|
596
616
|
: getAminoAcidStringFromSequenceString(selectedSeqData.sequence);
|
|
@@ -604,7 +624,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
604
624
|
// TODO: maybe stop using Clipboard.js and unify clipboard handling with
|
|
605
625
|
// a more versatile approach
|
|
606
626
|
return [
|
|
607
|
-
...(readOnly
|
|
627
|
+
...(readOnly || disableBpEditing
|
|
608
628
|
? []
|
|
609
629
|
: [
|
|
610
630
|
{
|
|
@@ -620,7 +640,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
620
640
|
didMount: ({ className }) => {
|
|
621
641
|
// TODO: Maybe use a cut action instead
|
|
622
642
|
this.openVeCut = makeTextCopyable(
|
|
623
|
-
|
|
643
|
+
s => ({
|
|
624
644
|
...s,
|
|
625
645
|
textToCopy: isProtein ? s.proteinSequence : s.sequence
|
|
626
646
|
}),
|
|
@@ -645,7 +665,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
645
665
|
},
|
|
646
666
|
didMount: ({ className }) => {
|
|
647
667
|
this.openVeCopy2 = makeTextCopyable(
|
|
648
|
-
|
|
668
|
+
s => ({ ...s, textToCopy: s.sequence }),
|
|
649
669
|
className
|
|
650
670
|
);
|
|
651
671
|
}
|
|
@@ -688,24 +708,17 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
688
708
|
this.openVeCopyAAReverse && this.openVeCopyAAReverse.destroy();
|
|
689
709
|
},
|
|
690
710
|
didMount: ({ className }) => {
|
|
691
|
-
this.openVeCopyAAReverse = makeTextCopyable(
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
return {
|
|
703
|
-
...revSeqData,
|
|
704
|
-
textToCopy
|
|
705
|
-
};
|
|
706
|
-
},
|
|
707
|
-
className
|
|
708
|
-
);
|
|
711
|
+
this.openVeCopyAAReverse = makeTextCopyable(selectedSeqData => {
|
|
712
|
+
const revSeqData =
|
|
713
|
+
getReverseComplementSequenceAndAnnotations(selectedSeqData);
|
|
714
|
+
const textToCopy = isProtein
|
|
715
|
+
? revSeqData.proteinSequence.toUpperCase()
|
|
716
|
+
: getAminoAcidStringFromSequenceString(revSeqData.sequence);
|
|
717
|
+
return {
|
|
718
|
+
...revSeqData,
|
|
719
|
+
textToCopy
|
|
720
|
+
};
|
|
721
|
+
}, className);
|
|
709
722
|
}
|
|
710
723
|
},
|
|
711
724
|
{
|
|
@@ -728,7 +741,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
728
741
|
];
|
|
729
742
|
};
|
|
730
743
|
|
|
731
|
-
getSelectionMenuOptions =
|
|
744
|
+
getSelectionMenuOptions = annotation => {
|
|
732
745
|
const items = [
|
|
733
746
|
...this.getCopyOptions(annotation),
|
|
734
747
|
createNewAnnotationMenu,
|
|
@@ -756,7 +769,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
756
769
|
return handler({ event, ...rest }, this.props);
|
|
757
770
|
};
|
|
758
771
|
enhanceRightClickAction = (action, key) => {
|
|
759
|
-
return
|
|
772
|
+
return opts => {
|
|
760
773
|
const lastFocusedEl = document.activeElement;
|
|
761
774
|
const { rightClickOverrides = {} } = this.props;
|
|
762
775
|
const items = action(opts);
|
|
@@ -821,11 +834,12 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
821
834
|
({ nearestCaretPos, shiftHeld, event }) => {
|
|
822
835
|
this.updateSelectionOrCaret(shiftHeld, nearestCaretPos);
|
|
823
836
|
const {
|
|
824
|
-
readOnly
|
|
837
|
+
readOnly,
|
|
838
|
+
disableBpEditing
|
|
825
839
|
// sequenceData: { circular }
|
|
826
840
|
} = this.props;
|
|
827
841
|
const menu = [
|
|
828
|
-
...(readOnly
|
|
842
|
+
...(readOnly || disableBpEditing
|
|
829
843
|
? []
|
|
830
844
|
: [
|
|
831
845
|
{
|
|
@@ -875,8 +889,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
875
889
|
overlapsSelf: annotation.overlapsSelf
|
|
876
890
|
});
|
|
877
891
|
return [
|
|
878
|
-
"
|
|
879
|
-
"deletePart",
|
|
892
|
+
...getEditDeleteHandlers("Part", annotation),
|
|
880
893
|
"--",
|
|
881
894
|
...this.getSelectionMenuOptions(annotation),
|
|
882
895
|
"--",
|
|
@@ -894,7 +907,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
894
907
|
return [
|
|
895
908
|
{
|
|
896
909
|
text: "View Warning Details",
|
|
897
|
-
onClick:
|
|
910
|
+
onClick: event => {
|
|
898
911
|
this.warningDoubleClicked({
|
|
899
912
|
event,
|
|
900
913
|
annotation,
|
|
@@ -919,8 +932,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
919
932
|
event.persist();
|
|
920
933
|
const { readOnly, annotationsToSupport: { parts } = {} } = this.props;
|
|
921
934
|
return [
|
|
922
|
-
"
|
|
923
|
-
"deleteFeature",
|
|
935
|
+
...getEditDeleteHandlers("Feature", annotation),
|
|
924
936
|
...this.getSelectionMenuOptions(annotation),
|
|
925
937
|
...(readOnly
|
|
926
938
|
? []
|
|
@@ -932,7 +944,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
932
944
|
onClick: async () => {
|
|
933
945
|
const { sequenceData, upsertPart } = this.props;
|
|
934
946
|
if (
|
|
935
|
-
some(sequenceData.parts,
|
|
947
|
+
some(sequenceData.parts, part => {
|
|
936
948
|
if (
|
|
937
949
|
part.start === annotation.start &&
|
|
938
950
|
part.end === annotation.end
|
|
@@ -994,8 +1006,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
994
1006
|
end: annotation.end
|
|
995
1007
|
});
|
|
996
1008
|
return [
|
|
997
|
-
"
|
|
998
|
-
"deletePrimer",
|
|
1009
|
+
...getEditDeleteHandlers("Primer", annotation),
|
|
999
1010
|
...this.getSelectionMenuOptions(annotation),
|
|
1000
1011
|
"showRemoveDuplicatesDialogPrimers",
|
|
1001
1012
|
"viewPrimerProperties"
|
|
@@ -1127,7 +1138,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
1127
1138
|
acc[handler] = this[handler];
|
|
1128
1139
|
return acc;
|
|
1129
1140
|
}, {}),
|
|
1130
|
-
editorClicked:
|
|
1141
|
+
editorClicked: p => {
|
|
1131
1142
|
editorClicked({
|
|
1132
1143
|
...p,
|
|
1133
1144
|
updateSelectionOrCaret: this.updateSelectionOrCaret
|
|
@@ -1140,7 +1151,7 @@ function VectorInteractionHOC(Component /* options */) {
|
|
|
1140
1151
|
return (
|
|
1141
1152
|
<div
|
|
1142
1153
|
tabIndex={0} //this helps with focusing using Keyboard's parentElement.focus()
|
|
1143
|
-
ref={
|
|
1154
|
+
ref={c => (this.node = c)}
|
|
1144
1155
|
className="veVectorInteractionWrapper"
|
|
1145
1156
|
style={{ position: "relative", ...vectorInteractionWrapperStyle }}
|
|
1146
1157
|
onFocus={this.handleWrapperFocus}
|
|
@@ -1259,3 +1270,30 @@ const insertAndSelectHelper = ({ seqDataToInsert, props }) => {
|
|
|
1259
1270
|
end: newSelectionLayerEnd % newSeqData.sequence.length
|
|
1260
1271
|
});
|
|
1261
1272
|
};
|
|
1273
|
+
|
|
1274
|
+
function getEditDeleteHandlers(type, annotation) {
|
|
1275
|
+
return [
|
|
1276
|
+
...(annotation.isEditLocked
|
|
1277
|
+
? [
|
|
1278
|
+
{
|
|
1279
|
+
shouldDismissPopover: false,
|
|
1280
|
+
text: (
|
|
1281
|
+
<div
|
|
1282
|
+
style={{
|
|
1283
|
+
fontSize: 11,
|
|
1284
|
+
fontStyle: "italic",
|
|
1285
|
+
color: "rgba(0,0,0,.5)"
|
|
1286
|
+
}}
|
|
1287
|
+
>
|
|
1288
|
+
{typeof annotation.isEditLocked === "string"
|
|
1289
|
+
? annotation.isEditLocked
|
|
1290
|
+
: `Note: This Annotation is Locked`}
|
|
1291
|
+
</div>
|
|
1292
|
+
)
|
|
1293
|
+
}
|
|
1294
|
+
]
|
|
1295
|
+
: []),
|
|
1296
|
+
`edit${type}`,
|
|
1297
|
+
...(annotation.isEditLocked ? [] : [`delete${type}`])
|
|
1298
|
+
];
|
|
1299
|
+
}
|